Esempio n. 1
0
 public function process_block($data)
 {
     global $DB, $CFG;
     $data = (object) $data;
     // Handy
     $oldcontextid = $data->contextid;
     $oldid = $data->id;
     $positions = isset($data->block_positions['block_position']) ? $data->block_positions['block_position'] : array();
     // Look for the parent contextid
     if (!($data->parentcontextid = $this->get_mappingid('context', $data->parentcontextid))) {
         throw new restore_step_exception('restore_block_missing_parent_ctx', $data->parentcontextid);
     }
     // TODO: it would be nice to use standard plugin supports instead of this instance_allow_multiple()
     // If there is already one block of that type in the parent context
     // and the block is not multiple, stop processing
     // Use blockslib loader / method executor
     if (!($bi = block_instance($data->blockname))) {
         return false;
     }
     if (!$bi->instance_allow_multiple()) {
         // The block cannot be added twice, so we will check if the same block is already being
         // displayed on the same page. For this, rather than mocking a page and using the block_manager
         // we use a similar query to the one in block_manager::load_blocks(), this will give us
         // a very good idea of the blocks already displayed in the context.
         $params = array('blockname' => $data->blockname);
         // Context matching test.
         $context = context::instance_by_id($data->parentcontextid);
         $contextsql = 'bi.parentcontextid = :contextid';
         $params['contextid'] = $context->id;
         $parentcontextids = $context->get_parent_context_ids();
         if ($parentcontextids) {
             list($parentcontextsql, $parentcontextparams) = $DB->get_in_or_equal($parentcontextids, SQL_PARAMS_NAMED);
             $contextsql = "({$contextsql} OR (bi.showinsubcontexts = 1 AND bi.parentcontextid {$parentcontextsql}))";
             $params = array_merge($params, $parentcontextparams);
         }
         // Page type pattern test.
         $pagetypepatterns = matching_page_type_patterns_from_pattern($data->pagetypepattern);
         list($pagetypepatternsql, $pagetypepatternparams) = $DB->get_in_or_equal($pagetypepatterns, SQL_PARAMS_NAMED);
         $params = array_merge($params, $pagetypepatternparams);
         // Sub page pattern test.
         $subpagepatternsql = 'bi.subpagepattern IS NULL';
         if ($data->subpagepattern !== null) {
             $subpagepatternsql = "({$subpagepatternsql} OR bi.subpagepattern = :subpagepattern)";
             $params['subpagepattern'] = $data->subpagepattern;
         }
         $exists = $DB->record_exists_sql("SELECT bi.id\n                                                FROM {block_instances} bi\n                                                JOIN {block} b ON b.name = bi.blockname\n                                               WHERE bi.blockname = :blockname\n                                                 AND {$contextsql}\n                                                 AND bi.pagetypepattern {$pagetypepatternsql}\n                                                 AND {$subpagepatternsql}", $params);
         if ($exists) {
             // There is at least one very similar block visible on the page where we
             // are trying to restore the block. In these circumstances the block API
             // would not allow the user to add another instance of the block, so we
             // apply the same rule here.
             return false;
         }
     }
     // If there is already one block of that type in the parent context
     // with the same showincontexts, pagetypepattern, subpagepattern, defaultregion and configdata
     // stop processing
     $params = array('blockname' => $data->blockname, 'parentcontextid' => $data->parentcontextid, 'showinsubcontexts' => $data->showinsubcontexts, 'pagetypepattern' => $data->pagetypepattern, 'subpagepattern' => $data->subpagepattern, 'defaultregion' => $data->defaultregion);
     if ($birecs = $DB->get_records('block_instances', $params)) {
         foreach ($birecs as $birec) {
             if ($birec->configdata == $data->configdata) {
                 return false;
             }
         }
     }
     // Set task old contextid, blockid and blockname once we know them
     $this->task->set_old_contextid($oldcontextid);
     $this->task->set_old_blockid($oldid);
     $this->task->set_blockname($data->blockname);
     // Let's look for anything within configdata neededing processing
     // (nulls and uses of legacy file.php)
     if ($attrstotransform = $this->task->get_configdata_encoded_attributes()) {
         $configdata = (array) unserialize(base64_decode($data->configdata));
         foreach ($configdata as $attribute => $value) {
             if (in_array($attribute, $attrstotransform)) {
                 $configdata[$attribute] = $this->contentprocessor->process_cdata($value);
             }
         }
         $data->configdata = base64_encode(serialize((object) $configdata));
     }
     // Create the block instance
     $newitemid = $DB->insert_record('block_instances', $data);
     // Save the mapping (with restorefiles support)
     $this->set_mapping('block_instance', $oldid, $newitemid, true);
     // Create the block context
     $newcontextid = context_block::instance($newitemid)->id;
     // Save the block contexts mapping and sent it to task
     $this->set_mapping('context', $oldcontextid, $newcontextid);
     $this->task->set_contextid($newcontextid);
     $this->task->set_blockid($newitemid);
     // Restore block fileareas if declared
     $component = 'block_' . $this->task->get_blockname();
     foreach ($this->task->get_fileareas() as $filearea) {
         // Simple match by contextid. No itemname needed
         $this->add_related_files($component, $filearea, null);
     }
     // Process block positions, creating them or accumulating for final step
     foreach ($positions as $position) {
         $position = (object) $position;
         $position->blockinstanceid = $newitemid;
         // The instance is always the restored one
         // If position is for one already mapped (known) contextid
         // process it now, creating the position
         if ($newpositionctxid = $this->get_mappingid('context', $position->contextid)) {
             $position->contextid = $newpositionctxid;
             // Create the block position
             $DB->insert_record('block_positions', $position);
             // The position belongs to an unknown context, send it to backup_ids
             // to process them as part of the final steps of restore. We send the
             // whole $position object there, hence use the low level method.
         } else {
             restore_dbops::set_backup_ids_record($this->get_restoreid(), 'block_position', $position->id, 0, null, $position);
         }
     }
 }
Esempio n. 2
0
 public function test_matching_page_type_patterns_from_pattern()
 {
     $pattern = '*';
     $expected = array('*');
     $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
     $pattern = 'admin-*';
     $expected = array('admin-*', 'admin', '*');
     $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
     $pattern = 'blog-index';
     $expected = array('blog-index', 'blog-index-*', 'blog-*', '*');
     $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
     $pattern = 'course-index-*';
     $expected = array('course-index-*', 'course-index', 'course-*', '*');
     $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
     $pattern = 'course-index-category';
     $expected = array('course-index-category', 'course-index-category-*', 'course-index-*', 'course-*', '*');
     $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
     $pattern = 'mod-assign-view';
     $expected = array('mod-assign-view', 'mod-*-view', 'mod-assign-view-*', 'mod-assign-*', 'mod-*', '*');
     $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
     $pattern = 'mod-assign-index';
     $expected = array('mod-assign-index', 'mod-*-index', 'mod-assign-index-*', 'mod-assign-*', 'mod-*', '*');
     $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
     $pattern = 'mod-forum-*';
     $expected = array('mod-forum-*', 'mod-forum', 'mod-*', '*');
     $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
     $pattern = 'mod-*-view';
     $expected = array('mod-*-view', 'mod', 'mod-*', '*');
     $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
     $pattern = 'mod-*-index';
     $expected = array('mod-*-index', 'mod', 'mod-*', '*');
     $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
     $pattern = 'my-index';
     $expected = array('my-index', 'my-index-*', 'my-*', '*');
     $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
     $pattern = 'user-profile';
     $expected = array('user-profile', 'user-profile-*', 'user-*', '*');
     $this->assertEquals($expected, array_values(matching_page_type_patterns_from_pattern($pattern)));
 }