Пример #1
0
function blocks_execute_action($page, &$pageblocks, $blockaction, $instanceorid, $pinned = false, $redirect = true)
{
    global $CFG;
    if (is_int($instanceorid)) {
        $blockid = $instanceorid;
    } else {
        if (is_object($instanceorid)) {
            $instance = $instanceorid;
        }
    }
    switch ($blockaction) {
        case 'config':
            global $USER;
            $block = blocks_get_record($instance->blockid);
            // Hacky hacky tricky stuff to get the original human readable block title,
            // even if the block has configured its title to be something else.
            // Create the object WITHOUT instance data.
            $blockobject = block_instance($block->name);
            if ($blockobject === false) {
                break;
            }
            // First of all check to see if the block wants to be edited
            if (!$blockobject->user_can_edit()) {
                break;
            }
            // Now get the title and AFTER that load up the instance
            $blocktitle = $blockobject->get_title();
            $blockobject->_load_instance($instance);
            optional_param('submitted', 0, PARAM_INT);
            // Define the data we're going to silently include in the instance config form here,
            // so we can strip them from the submitted data BEFORE serializing it.
            $hiddendata = array('sesskey' => $USER->sesskey, 'instanceid' => $instance->id, 'blockaction' => 'config');
            // To this data, add anything the page itself needs to display
            $hiddendata = array_merge($hiddendata, $page->url_get_parameters());
            if ($data = data_submitted()) {
                $remove = array_keys($hiddendata);
                foreach ($remove as $item) {
                    unset($data->{$item});
                }
                if (!$blockobject->instance_config_save($data, $pinned)) {
                    error('Error saving block configuration');
                }
                // And nothing more, continue with displaying the page
            } else {
                // We need to show the config screen, so we highjack the display logic and then die
                $strheading = get_string('blockconfiga', 'moodle', $blocktitle);
                $page->print_header(get_string('pageheaderconfigablock', 'moodle'), array($strheading => ''));
                echo '<div class="block-config" id="' . $block->name . '">';
                /// Make CSS easier
                print_heading($strheading);
                echo '<form method="post" name="block-config" action="' . $page->url_get_path() . '">';
                echo '<p>';
                foreach ($hiddendata as $name => $val) {
                    echo '<input type="hidden" name="' . $name . '" value="' . $val . '" />';
                }
                echo '</p>';
                $blockobject->instance_config_print();
                echo '</form>';
                echo '</div>';
                $CFG->pagepath = 'blocks/' . $block->name;
                print_footer();
                die;
                // Do not go on with the other page-related stuff
            }
            break;
        case 'toggle':
            if (empty($instance)) {
                error('Invalid block instance for ' . $blockaction);
            }
            $instance->visible = $instance->visible ? 0 : 1;
            if (!empty($pinned)) {
                update_record('block_pinned', $instance);
            } else {
                update_record('block_instance', $instance);
            }
            break;
        case 'delete':
            if (empty($instance)) {
                error('Invalid block instance for ' . $blockaction);
            }
            blocks_delete_instance($instance, $pinned);
            break;
        case 'moveup':
            if (empty($instance)) {
                error('Invalid block instance for ' . $blockaction);
            }
            if ($instance->weight == 0) {
                // The block is the first one, so a move "up" probably means it changes position
                // Where is the instance going to be moved?
                $newpos = $page->blocks_move_position($instance, BLOCK_MOVE_UP);
                $newweight = empty($pageblocks[$newpos]) ? 0 : max(array_keys($pageblocks[$newpos])) + 1;
                blocks_execute_repositioning($instance, $newpos, $newweight, $pinned);
            } else {
                // The block is just moving upwards in the same position.
                // This configuration will make sure that even if somehow the weights
                // become not continuous, block move operations will eventually bring
                // the situation back to normal without printing any warnings.
                if (!empty($pageblocks[$instance->position][$instance->weight - 1])) {
                    //define instance's position in the array
                    foreach ($pageblocks[$instance->position] as $instancekeysindex => $index) {
                        if ($pageblocks[$instance->position][$instancekeysindex]->id == $instance->id) {
                            $instanceindex = $instancekeysindex;
                        }
                    }
                    $other = $pageblocks[$instance->position][$instanceindex - 1];
                }
                if (!empty($other)) {
                    ++$other->weight;
                    if (!empty($pinned)) {
                        update_record('block_pinned', $other);
                    } else {
                        update_record('block_instance', $other);
                    }
                }
                --$instance->weight;
                if (!empty($pinned)) {
                    update_record('block_pinned', $instance);
                } else {
                    update_record('block_instance', $instance);
                }
            }
            break;
        case 'movedown':
            if (empty($instance)) {
                error('Invalid block instance for ' . $blockaction);
            }
            if ($instance->weight == max(array_keys($pageblocks[$instance->position]))) {
                // The block is the last one, so a move "down" probably means it changes position
                // Where is the instance going to be moved?
                $newpos = $page->blocks_move_position($instance, BLOCK_MOVE_DOWN);
                $newweight = empty($pageblocks[$newpos]) ? 0 : max(array_keys($pageblocks[$newpos])) + 1;
                blocks_execute_repositioning($instance, $newpos, $newweight, $pinned);
            } else {
                // The block is just moving downwards in the same position.
                // This configuration will make sure that even if somehow the weights
                // become not continuous, block move operations will eventually bring
                // the situation back to normal without printing any warnings.
                if (!empty($pageblocks[$instance->position][$instance->weight + 1])) {
                    //define instance's position in the array
                    foreach ($pageblocks[$instance->position] as $instancekeysindex => $index) {
                        if ($pageblocks[$instance->position][$instancekeysindex]->id == $instance->id) {
                            $instanceindex = $instancekeysindex;
                        }
                    }
                    $other = $pageblocks[$instance->position][$instanceindex + 1];
                }
                if (!empty($other)) {
                    --$other->weight;
                    if (!empty($pinned)) {
                        update_record('block_pinned', $other);
                    } else {
                        update_record('block_instance', $other);
                    }
                }
                ++$instance->weight;
                if (!empty($pinned)) {
                    update_record('block_pinned', $instance);
                } else {
                    update_record('block_instance', $instance);
                }
            }
            break;
        case 'moveleft':
            if (empty($instance)) {
                error('Invalid block instance for ' . $blockaction);
            }
            // Where is the instance going to be moved?
            $newpos = $page->blocks_move_position($instance, BLOCK_MOVE_LEFT);
            $newweight = 0;
            if (!empty($pinned) && !empty($pageblocks[$newpos])) {
                $newweight = $pageblocks[$newpos][max(array_keys($pageblocks[$newpos]))]->weight + 1;
            } else {
                if (!empty($pageblocks[$newpos]) && !array_key_exists('pinned', $pageblocks[$newpos][max(array_keys($pageblocks[$newpos]))])) {
                    $newweight = $pageblocks[$newpos][max(array_keys($pageblocks[$newpos]))]->weight + 1;
                }
            }
            blocks_execute_repositioning($instance, $newpos, $newweight, $pinned);
            break;
        case 'moveright':
            if (empty($instance)) {
                error('Invalid block instance for ' . $blockaction);
            }
            // Where is the instance going to be moved?
            $newpos = $page->blocks_move_position($instance, BLOCK_MOVE_RIGHT);
            $newweight = 0;
            if (!empty($pinned) && !empty($pageblocks[$newpos])) {
                $newweight = $pageblocks[$newpos][max(array_keys($pageblocks[$newpos]))]->weight + 1;
            } else {
                if (!empty($pageblocks[$newpos]) && !array_key_exists('pinned', $pageblocks[$newpos][max(array_keys($pageblocks[$newpos]))])) {
                    $newweight = $pageblocks[$newpos][max(array_keys($pageblocks[$newpos]))]->weight + 1;
                }
            }
            blocks_execute_repositioning($instance, $newpos, $newweight, $pinned);
            break;
        case 'add':
            // Add a new instance of this block, if allowed
            $block = blocks_get_record($blockid);
            if (empty($block) || !$block->visible) {
                // Only allow adding if the block exists and is enabled
                break;
            }
            if (!$block->multiple && blocks_find_block($blockid, $pageblocks) !== false) {
                // If no multiples are allowed and we already have one, return now
                break;
            }
            if (!block_method_result($block->name, 'user_can_addto', $page)) {
                // If the block doesn't want to be added...
                break;
            }
            $newpos = $page->blocks_default_position();
            if (!empty($pinned)) {
                $sql = 'SELECT 1, max(weight) + 1 AS nextfree FROM ' . $CFG->prefix . 'block_pinned WHERE ' . ' pagetype = \'' . $page->get_type() . '\' AND position = \'' . $newpos . '\'';
            } else {
                $sql = 'SELECT 1, max(weight) + 1 AS nextfree FROM ' . $CFG->prefix . 'block_instance WHERE pageid = ' . $page->get_id() . ' AND pagetype = \'' . $page->get_type() . '\' AND position = \'' . $newpos . '\'';
            }
            $weight = get_record_sql($sql);
            $newinstance = new stdClass();
            $newinstance->blockid = $blockid;
            if (empty($pinned)) {
                $newinstance->pageid = $page->get_id();
            }
            $newinstance->pagetype = $page->get_type();
            $newinstance->position = $newpos;
            $newinstance->weight = empty($weight->nextfree) ? 0 : $weight->nextfree;
            $newinstance->visible = 1;
            $newinstance->configdata = '';
            if (!empty($pinned)) {
                $newinstance->id = insert_record('block_pinned', $newinstance);
            } else {
                $newinstance->id = insert_record('block_instance', $newinstance);
            }
            // If the new instance was created, allow it to do additional setup
            if ($newinstance && ($obj = block_instance($block->name, $newinstance))) {
                // Return value ignored
                $obj->instance_create();
            }
            break;
    }
    if ($redirect) {
        // In order to prevent accidental duplicate actions, redirect to a page with a clean url
        redirect($page->url_get_full());
    }
}
Пример #2
0
function blocks_execute_action($page, &$blockmanager, $blockaction, $instanceorid, $pinned = false, $redirect = true)
{
    global $CFG, $USER, $DB;
    if (!in_array($blockaction, array('config', 'add', 'delete'))) {
        throw new moodle_exception('Sorry, blocks editing is currently broken. Will be fixed. See MDL-19010.');
    }
    if (is_int($instanceorid)) {
        $blockid = $instanceorid;
    } else {
        if (is_object($instanceorid)) {
            $instance = $instanceorid;
        }
    }
    switch ($blockaction) {
        case 'config':
            // First of all check to see if the block wants to be edited
            if (!$instance->user_can_edit()) {
                break;
            }
            // Now get the title and AFTER that load up the instance
            $blocktitle = $instance->get_title();
            // Define the data we're going to silently include in the instance config form here,
            // so we can strip them from the submitted data BEFORE serializing it.
            $hiddendata = array('sesskey' => sesskey(), 'instanceid' => $instance->instance->id, 'blockaction' => 'config');
            // To this data, add anything the page itself needs to display
            $hiddendata = $page->url->params($hiddendata);
            if ($data = data_submitted()) {
                $remove = array_keys($hiddendata);
                foreach ($remove as $item) {
                    unset($data->{$item});
                }
                $instance->instance_config_save($data);
                redirect($page->url->out());
            } else {
                // We need to show the config screen, so we highjack the display logic and then die
                $strheading = get_string('blockconfiga', 'moodle', $blocktitle);
                $nav = build_navigation($strheading, $page->cm);
                print_header($strheading, $strheading, $nav);
                echo '<div class="block-config" id="' . $instance->name() . '">';
                /// Make CSS easier
                print_heading($strheading);
                echo '<form method="post" name="block-config" action="' . $page->url->out(false) . '">';
                echo '<p>';
                echo $page->url->hidden_params_out(array(), 0, $hiddendata);
                echo '</p>';
                $instance->instance_config_print();
                echo '</form>';
                echo '</div>';
                global $PAGE;
                $PAGE->set_docs_path('blocks/' . $instance->name());
                print_footer();
                die;
                // Do not go on with the other page-related stuff
            }
            break;
        case 'toggle':
            if (empty($instance)) {
                print_error('invalidblockinstance', '', '', $blockaction);
            }
            $instance->visible = $instance->visible ? 0 : 1;
            if (!empty($pinned)) {
                $DB->update_record('block_pinned_old', $instance);
            } else {
                $DB->update_record('block_instance_old', $instance);
            }
            break;
        case 'delete':
            if (empty($instance)) {
                print_error('invalidblockinstance', '', '', $blockaction);
            }
            blocks_delete_instance($instance->instance, $pinned);
            break;
        case 'moveup':
            if (empty($instance)) {
                print_error('invalidblockinstance', '', '', $blockaction);
            }
            if ($instance->weight == 0) {
                // The block is the first one, so a move "up" probably means it changes position
                // Where is the instance going to be moved?
                $newpos = $page->blocks_move_position($instance, BLOCK_MOVE_UP);
                $newweight = empty($blockmanager[$newpos]) ? 0 : max(array_keys($blockmanager[$newpos])) + 1;
                blocks_execute_repositioning($instance, $newpos, $newweight, $pinned);
            } else {
                // The block is just moving upwards in the same position.
                // This configuration will make sure that even if somehow the weights
                // become not continuous, block move operations will eventually bring
                // the situation back to normal without printing any warnings.
                if (!empty($blockmanager[$instance->position][$instance->weight - 1])) {
                    $other = $blockmanager[$instance->position][$instance->weight - 1];
                }
                if (!empty($other)) {
                    ++$other->weight;
                    if (!empty($pinned)) {
                        $DB->update_record('block_pinned_old', $other);
                    } else {
                        $DB->update_record('block_instance_old', $other);
                    }
                }
                --$instance->weight;
                if (!empty($pinned)) {
                    $DB->update_record('block_pinned_old', $instance);
                } else {
                    $DB->update_record('block_instance_old', $instance);
                }
            }
            break;
        case 'movedown':
            if (empty($instance)) {
                print_error('invalidblockinstance', '', '', $blockaction);
            }
            if ($instance->weight == max(array_keys($blockmanager[$instance->position]))) {
                // The block is the last one, so a move "down" probably means it changes position
                // Where is the instance going to be moved?
                $newpos = $page->blocks_move_position($instance, BLOCK_MOVE_DOWN);
                $newweight = empty($blockmanager[$newpos]) ? 0 : max(array_keys($blockmanager[$newpos])) + 1;
                blocks_execute_repositioning($instance, $newpos, $newweight, $pinned);
            } else {
                // The block is just moving downwards in the same position.
                // This configuration will make sure that even if somehow the weights
                // become not continuous, block move operations will eventually bring
                // the situation back to normal without printing any warnings.
                if (!empty($blockmanager[$instance->position][$instance->weight + 1])) {
                    $other = $blockmanager[$instance->position][$instance->weight + 1];
                }
                if (!empty($other)) {
                    --$other->weight;
                    if (!empty($pinned)) {
                        $DB->update_record('block_pinned_old', $other);
                    } else {
                        $DB->update_record('block_instance_old', $other);
                    }
                }
                ++$instance->weight;
                if (!empty($pinned)) {
                    $DB->update_record('block_pinned_old', $instance);
                } else {
                    $DB->update_record('block_instance_old', $instance);
                }
            }
            break;
        case 'moveleft':
            if (empty($instance)) {
                print_error('invalidblockinstance', '', '', $blockaction);
            }
            // Where is the instance going to be moved?
            $newpos = $page->blocks_move_position($instance, BLOCK_MOVE_LEFT);
            $newweight = empty($blockmanager[$newpos]) ? 0 : max(array_keys($blockmanager[$newpos])) + 1;
            blocks_execute_repositioning($instance, $newpos, $newweight, $pinned);
            break;
        case 'moveright':
            if (empty($instance)) {
                print_error('invalidblockinstance', '', '', $blockaction);
            }
            // Where is the instance going to be moved?
            $newpos = $page->blocks_move_position($instance, BLOCK_MOVE_RIGHT);
            $newweight = empty($blockmanager[$newpos]) ? 0 : max(array_keys($blockmanager[$newpos])) + 1;
            blocks_execute_repositioning($instance, $newpos, $newweight, $pinned);
            break;
        case 'add':
            // Add a new instance of this block, if allowed
            $block = blocks_get_record($blockid);
            if (empty($block) || !$block->visible) {
                // Only allow adding if the block exists and is enabled
                break;
            }
            if (!$block->multiple && blocks_find_block($blockid, $blockmanager) !== false) {
                // If no multiples are allowed and we already have one, return now
                break;
            }
            if (!block_method_result($block->name, 'user_can_addto', $page)) {
                // If the block doesn't want to be added...
                break;
            }
            $region = $page->blocks->get_default_region();
            $weight = $DB->get_field_sql("SELECT MAX(defaultweight) FROM {block_instances} \n                    WHERE contextid = ? AND defaultregion = ?", array($page->context->id, $region));
            $pagetypepattern = $page->pagetype;
            if (strpos($pagetypepattern, 'course-view') === 0) {
                $pagetypepattern = 'course-view-*';
            }
            $page->blocks->add_block($block->name, $region, $weight, false, $pagetypepattern);
            break;
    }
    if ($redirect) {
        // In order to prevent accidental duplicate actions, redirect to a page with a clean url
        redirect($page->url->out());
    }
}