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()); } }
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()); } }