Esempio n. 1
0
/**
 * Assigns a tag to a record; if the record already exists, the time and ordering will be updated.
 *
 * @package core_tag
 * @access private
 * @param string $record_type the type of the record that will be tagged
 * @param int $record_id the id of the record that will be tagged
 * @param string $tagid the tag id to set on the record.
 * @param int $ordering the order of the instance for this record
 * @param int $userid (optional) only required for course tagging
 * @param string|null $component the component that was tagged
 * @param int|null $contextid the context id of where this tag was assigned
 * @return bool true on success, false otherwise
 */
function tag_assign($record_type, $record_id, $tagid, $ordering, $userid = 0, $component = null, $contextid = null)
{
    global $DB;
    if ($component === null || $contextid === null) {
        debugging('You should specify the component and contextid of the item being tagged in your call to tag_assign.', DEBUG_DEVELOPER);
    }
    // Get the tag.
    $tag = $DB->get_record('tag', array('id' => $tagid), 'name, rawname', MUST_EXIST);
    if ($tag_instance_object = $DB->get_record('tag_instance', array('tagid' => $tagid, 'itemtype' => $record_type, 'itemid' => $record_id, 'tiuserid' => $userid), 'id')) {
        $tag_instance_object->ordering = $ordering;
        $tag_instance_object->timemodified = time();
        $DB->update_record('tag_instance', $tag_instance_object);
    } else {
        $tag_instance_object = new StdClass();
        $tag_instance_object->tagid = $tagid;
        $tag_instance_object->component = $component;
        $tag_instance_object->itemid = $record_id;
        $tag_instance_object->itemtype = $record_type;
        $tag_instance_object->contextid = $contextid;
        $tag_instance_object->ordering = $ordering;
        $tag_instance_object->timecreated = time();
        $tag_instance_object->timemodified = $tag_instance_object->timecreated;
        $tag_instance_object->tiuserid = $userid;
        $tag_instance_object->id = $DB->insert_record('tag_instance', $tag_instance_object);
    }
    // We can not fire an event with 'null' as the contextid.
    if (is_null($contextid)) {
        $contextid = context_system::instance()->id;
    }
    // Trigger tag added event.
    $event = \core\event\tag_added::create(array('objectid' => $tag_instance_object->id, 'contextid' => $contextid, 'other' => array('tagid' => $tagid, 'tagname' => $tag->name, 'tagrawname' => $tag->rawname, 'itemid' => $record_id, 'itemtype' => $record_type)));
    $event->trigger();
    return true;
}
Esempio n. 2
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;
 }
Esempio n. 3
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);
 }