Exemple #1
0
 /**
  * Adds a tag instance
  *
  * @param string $component
  * @param string $itemtype
  * @param string $itemid
  * @param context $context
  * @param int $ordering
  * @param int $tiuserid tag instance user id, only needed for tag areas with user tagging (such as core/course)
  * @return int id of tag_instance
  */
 protected function add_instance($component, $itemtype, $itemid, context $context, $ordering, $tiuserid = 0)
 {
     global $DB;
     $this->ensure_fields_exist(array('name', 'rawname'), 'add_instance');
     $taginstance = new StdClass();
     $taginstance->tagid = $this->id;
     $taginstance->component = $component ? $component : '';
     $taginstance->itemid = $itemid;
     $taginstance->itemtype = $itemtype;
     $taginstance->contextid = $context->id;
     $taginstance->ordering = $ordering;
     $taginstance->timecreated = time();
     $taginstance->timemodified = $taginstance->timecreated;
     $taginstance->tiuserid = $tiuserid;
     $taginstance->id = $DB->insert_record('tag_instance', $taginstance);
     // Trigger tag added event.
     \core\event\tag_added::create_from_tag_instance($taginstance, $this->name, $this->rawname, true)->trigger();
     return $taginstance->id;
 }
Exemple #2
0
 /**
  * Combines several other tags into this one
  *
  * Combining rules:
  * - current tag becomes the "main" one, all instances
  *   pointing to other tags are changed to point to it.
  * - if any of the tags is standard, the "main" tag becomes standard too
  * - all tags except for the current ("main") are deleted, even when they are standard
  *
  * @param core_tag_tag[] $tags tags to combine into this one
  */
 public function combine_tags($tags)
 {
     global $DB;
     $this->ensure_fields_exist(array('id', 'tagcollid', 'isstandard', 'name', 'rawname'), 'combine_tags');
     // Retrieve all tag objects, find if there are any standard tags in the set.
     $isstandard = false;
     $tagstocombine = array();
     $ids = array();
     $relatedtags = $this->get_manual_related_tags();
     foreach ($tags as $tag) {
         $tag->ensure_fields_exist(array('id', 'tagcollid', 'isstandard', 'tagcollid', 'name', 'rawname'), 'combine_tags');
         if ($tag && $tag->id != $this->id && $tag->tagcollid == $this->tagcollid) {
             $isstandard = $isstandard || $tag->isstandard;
             $tagstocombine[$tag->name] = $tag;
             $ids[] = $tag->id;
             $relatedtags = array_merge($relatedtags, $tag->get_manual_related_tags());
         }
     }
     if (empty($tagstocombine)) {
         // Nothing to do.
         return;
     }
     // Combine all manually set related tags, exclude itself all the tags it is about to be combined with.
     if ($relatedtags) {
         $relatedtags = array_map(function ($t) {
             return $t->name;
         }, $relatedtags);
         array_unique($relatedtags);
         $relatedtags = array_diff($relatedtags, [$this->name], array_keys($tagstocombine));
     }
     $this->set_related_tags($relatedtags);
     // Combine all correlated tags, exclude itself all the tags it is about to be combined with.
     $this->combine_correlated_tags($tagstocombine);
     // If any of the duplicate tags are standard, mark this one as standard too.
     if ($isstandard && !$this->isstandard) {
         $this->update(array('isstandard' => 1));
     }
     // Go through all instances of each tag that needs to be combined and make them point to this tag instead.
     // We go though the list one by one because otherwise looking-for-duplicates logic would be too complicated.
     foreach ($tagstocombine as $tag) {
         $params = array('tagid' => $tag->id, 'mainid' => $this->id);
         $mainsql = 'SELECT ti.*, t.name, t.rawname, tim.id AS alreadyhasmaintag ' . 'FROM {tag_instance} ti ' . 'LEFT JOIN {tag} t ON t.id = ti.tagid ' . 'LEFT JOIN {tag_instance} tim ON ti.component = tim.component AND ' . '    ti.itemtype = tim.itemtype AND ti.itemid = tim.itemid AND ' . '    ti.tiuserid = tim.tiuserid AND tim.tagid = :mainid ' . 'WHERE ti.tagid = :tagid';
         $records = $DB->get_records_sql($mainsql, $params);
         foreach ($records as $record) {
             if ($record->alreadyhasmaintag) {
                 // Item is tagged with both main tag and the duplicate tag.
                 // Remove instance pointing to the duplicate tag.
                 $tag->delete_instance_as_record($record, false);
                 $sql = "UPDATE {tag_instance} SET ordering = ordering - 1\n                            WHERE itemtype = :itemtype\n                        AND itemid = :itemid AND component = :component AND tiuserid = :tiuserid\n                        AND ordering > :ordering";
                 $DB->execute($sql, (array) $record);
             } else {
                 // Item is tagged only with duplicate tag but not the main tag.
                 // Replace tagid in the instance pointing to the duplicate tag with this tag.
                 $DB->update_record('tag_instance', array('id' => $record->id, 'tagid' => $this->id));
                 \core\event\tag_removed::create_from_tag_instance($record, $record->name, $record->rawname)->trigger();
                 $record->tagid = $this->id;
                 \core\event\tag_added::create_from_tag_instance($record, $this->name, $this->rawname)->trigger();
             }
         }
     }
     // Finally delete all tags that we combined into the current one.
     self::delete_tags($ids);
 }