Exemplo n.º 1
0
 /**
  * Moves existing tags associated with an item type to another tag collection
  *
  * @param string $component
  * @param string $itemtype
  * @param int $tagcollid
  */
 public static function move_tags($component, $itemtype, $tagcollid)
 {
     global $DB;
     $params = array('itemtype1' => $itemtype, 'component1' => $component, 'itemtype2' => $itemtype, 'component2' => $component, 'tagcollid1' => $tagcollid, 'tagcollid2' => $tagcollid);
     // Find all collections that need to be cleaned later.
     $sql = "SELECT DISTINCT t.tagcollid " . "FROM {tag_instance} ti " . "JOIN {tag} t ON t.id = ti.tagid AND t.tagcollid <> :tagcollid1 " . "WHERE ti.itemtype = :itemtype2 AND ti.component = :component2 ";
     $cleanupcollections = $DB->get_fieldset_sql($sql, $params);
     // Find all tags that are related to the tags being moved and make sure they are present in the target tagcoll.
     // This query is a little complicated because Oracle does not allow to run SELECT DISTINCT on CLOB fields.
     $sql = "SELECT name, rawname, description, descriptionformat, userid, tagtype, flag " . "FROM {tag} WHERE id IN " . "(SELECT r.id " . "FROM {tag_instance} ti " . "JOIN {tag} t ON t.id = ti.tagid AND t.tagcollid <> :tagcollid1 " . "JOIN {tag_instance} tr ON tr.itemtype = 'tag' and tr.component = 'core' AND tr.itemid = t.id " . "JOIN {tag} r ON r.id = tr.tagid " . "LEFT JOIN {tag} re ON re.name = r.name AND re.tagcollid = :tagcollid2 " . "WHERE ti.itemtype = :itemtype2 AND ti.component = :component2 " . "    AND re.id IS NULL)";
     // We need related tags that ARE NOT present in the target tagcoll.
     $result = $DB->get_records_sql($sql, $params);
     foreach ($result as $tag) {
         $tag->tagcollid = $tagcollid;
         $tag->id = $DB->insert_record('tag', $tag);
         \core\event\tag_created::create_from_tag($tag);
     }
     // Find all tags that need moving and have related tags, remember their related tags.
     $sql = "SELECT t.name AS tagname, r.rawname AS relatedtag " . "FROM {tag_instance} ti " . "JOIN {tag} t ON t.id = ti.tagid AND t.tagcollid <> :tagcollid1 " . "JOIN {tag_instance} tr ON t.id = tr.tagid AND tr.itemtype = 'tag' and tr.component = 'core' " . "JOIN {tag} r ON r.id = tr.itemid " . "WHERE ti.itemtype = :itemtype2 AND ti.component = :component2 " . "ORDER BY t.id, tr.ordering ";
     $relatedtags = array();
     $result = $DB->get_recordset_sql($sql, $params);
     foreach ($result as $record) {
         $relatedtags[$record->tagname][] = $record->relatedtag;
     }
     $result->close();
     // Find all tags that are used for this itemtype/component and are not present in the target tag collection.
     // This query is a little complicated because Oracle does not allow to run SELECT DISTINCT on CLOB fields.
     $sql = "SELECT id, name, rawname, description, descriptionformat, userid, tagtype, flag\n                FROM {tag} WHERE id IN\n                (SELECT t.id\n                FROM {tag_instance} ti\n                JOIN {tag} t ON t.id = ti.tagid AND t.tagcollid <> :tagcollid1\n                LEFT JOIN {tag} tt ON tt.name = t.name AND tt.tagcollid = :tagcollid2\n                WHERE ti.itemtype = :itemtype2 AND ti.component = :component2\n                    AND tt.id IS NULL)";
     $movedtags = array();
     // Keep track of moved tags so we don't hit DB index violation.
     $result = $DB->get_records_sql($sql, $params);
     foreach ($result as $tag) {
         $originaltagid = $tag->id;
         if (array_key_exists($tag->name, $movedtags)) {
             // Case of corrupted data when the same tag was in several collections.
             $tag->id = $movedtags[$tag->name];
         } else {
             // Copy the tag into the new collection.
             unset($tag->id);
             $tag->tagcollid = $tagcollid;
             $tag->id = $DB->insert_record('tag', $tag);
             \core\event\tag_created::create_from_tag($tag);
             $movedtags[$tag->name] = $tag->id;
         }
         $DB->execute("UPDATE {tag_instance} SET tagid = ? WHERE tagid = ? AND itemtype = ? AND component = ?", array($tag->id, $originaltagid, $itemtype, $component));
     }
     // Find all tags that are used for this itemtype/component and are already present in the target tag collection.
     $sql = "SELECT DISTINCT t.id, tt.id AS targettagid\n                FROM {tag_instance} ti\n                JOIN {tag} t ON t.id = ti.tagid AND t.tagcollid <> :tagcollid1\n                JOIN {tag} tt ON tt.name = t.name AND tt.tagcollid = :tagcollid2\n                WHERE ti.itemtype = :itemtype2 AND ti.component = :component2";
     $result = $DB->get_records_sql($sql, $params);
     foreach ($result as $tag) {
         $DB->execute("UPDATE {tag_instance} SET tagid = ? WHERE tagid = ? AND itemtype = ? AND component = ?", array($tag->targettagid, $tag->id, $itemtype, $component));
     }
     // Add related tags to the moved tags.
     if ($relatedtags) {
         $tags = core_tag_tag::get_by_name_bulk($tagcollid, array_keys($relatedtags));
         foreach ($tags as $tag) {
             $tag->add_related_tags($relatedtags[$tag->name]);
         }
     }
     if ($cleanupcollections) {
         core_tag_collection::cleanup_unused_tags($cleanupcollections);
     }
     // Reset caches.
     cache::make('core', 'tags')->delete('tag_area');
 }
Exemplo n.º 2
0
 /**
  * Adds one or more tag in the database.  This function should not be called directly : you should
  * use tag_set.
  *
  * @param   int      $tagcollid
  * @param   string|array $tags     one tag, or an array of tags, to be created
  * @param   bool     $isofficial type of tag to be created. An official tag is kept even if there are no records tagged with it.
  * @return  array    tag objects indexed by their lowercase normalized names. Any boolean false in the array
  *                             indicates an error while adding the tag.
  */
 protected static function add($tagcollid, $tags, $isofficial = false)
 {
     global $USER, $DB;
     $tagobject = new stdClass();
     $tagobject->tagtype = $isofficial ? 'official' : 'default';
     $tagobject->userid = $USER->id;
     $tagobject->timemodified = time();
     $tagobject->tagcollid = $tagcollid;
     $rv = array();
     foreach ($tags as $veryrawname) {
         $rawname = clean_param($veryrawname, PARAM_TAG);
         if (!$rawname) {
             $rv[$rawname] = false;
         } else {
             $obj = (object) (array) $tagobject;
             $obj->rawname = $rawname;
             $obj->name = core_text::strtolower($rawname);
             $obj->id = $DB->insert_record('tag', $obj);
             $rv[$obj->name] = new static($obj);
             \core\event\tag_created::create_from_tag($rv[$obj->name])->trigger();
         }
     }
     return $rv;
 }
Exemplo n.º 3
0
/**
 * Adds one or more tag in the database.  This function should not be called directly : you should
 * use tag_set.
 *
 * @package core_tag
 * @access  private
 * @param   mixed    $tags     one tag, or an array of tags, to be created
 * @param   string   $type     type of tag to be created ("default" is the default value and "official" is the only other supported
 *                             value at this time). An official tag is kept even if there are no records tagged with it.
 * @return array     $tags ids indexed by their lowercase normalized names. Any boolean false in the array indicates an error while
 *                             adding the tag.
 */
function tag_add($tags, $type = "default")
{
    global $USER, $DB;
    if (!is_array($tags)) {
        $tags = array($tags);
    }
    $tag_object = new StdClass();
    $tag_object->tagtype = $type;
    $tag_object->userid = $USER->id;
    $tag_object->timemodified = time();
    $clean_tags = tag_normalize($tags, TAG_CASE_ORIGINAL);
    $tags_ids = array();
    foreach ($clean_tags as $tag) {
        $tag = trim($tag);
        if (!$tag) {
            $tags_ids[$tag] = false;
        } else {
            // note that the difference between rawname and name is only
            // capitalization : the rawname is NOT the same at the rawtag.
            $tag_object->rawname = $tag;
            $tag_name_lc = core_text::strtolower($tag);
            $tag_object->name = $tag_name_lc;
            //var_dump($tag_object);
            $tags_ids[$tag_name_lc] = $DB->insert_record('tag', $tag_object);
            $event = \core\event\tag_created::create(array('objectid' => $tags_ids[$tag_name_lc], 'relateduserid' => $tag_object->userid, 'context' => context_system::instance(), 'other' => array('name' => $tag_object->name, 'rawname' => $tag_object->rawname)));
            $event->trigger();
        }
    }
    return $tags_ids;
}