Пример #1
0
/**
 * Clean up the tag tables, making sure all tagged object still exists.
 *
 * This should normally not be necessary, but in case related tags are not deleted when the tagged record is removed, this should be
 * done once in a while, perhaps on an occasional cron run.  On a site with lots of tags, this could become an expensive function to
 * call: don't run at peak time.
 *
 * @package core_tag
 * @access  private
 * @todo    MDL-31212 Update tag cleanup sql so that it supports multiple types of tags
 */
function tag_cleanup()
{
    global $DB;
    // Get ids to delete from instances where the tag has been deleted. This should never happen apparently.
    $sql = "SELECT ti.id\n              FROM {tag_instance} ti\n         LEFT JOIN {tag} t ON t.id = ti.tagid\n             WHERE t.id IS null";
    $tagids = $DB->get_records_sql($sql);
    $tagarray = array();
    foreach ($tagids as $tagid) {
        $tagarray[] = $tagid->id;
    }
    // Next get ids from instances that have an owner that has been deleted.
    $sql = "SELECT ti.id\n              FROM {tag_instance} ti, {user} u\n             WHERE ti.itemid = u.id\n               AND ti.itemtype = 'user'\n               AND u.deleted = 1";
    $tagids = $DB->get_records_sql($sql);
    foreach ($tagids as $tagid) {
        $tagarray[] = $tagid->id;
    }
    // Get the other itemtypes.
    $sql = "SELECT itemtype\n              FROM {tag_instance}\n             WHERE itemtype <> 'user'\n          GROUP BY itemtype";
    $tagitemtypes = $DB->get_records_sql($sql);
    foreach ($tagitemtypes as $key => $notused) {
        $sql = 'SELECT ti.id
                  FROM {tag_instance} ti
             LEFT JOIN {' . $key . '} it ON it.id = ti.itemid
                 WHERE it.id IS null
                 AND ti.itemtype = \'' . $key . '\'';
        $tagids = $DB->get_records_sql($sql);
        foreach ($tagids as $tagid) {
            $tagarray[] = $tagid->id;
        }
    }
    // Get instances for each of the ids to be deleted.
    if (count($tagarray) > 0) {
        list($sqlin, $params) = $DB->get_in_or_equal($tagarray);
        $sql = "SELECT ti.*, COALESCE(t.name, 'deleted') AS name, COALESCE(t.rawname, 'deleted') AS rawname\n                  FROM {tag_instance} ti\n             LEFT JOIN {tag} t ON t.id = ti.tagid\n                 WHERE ti.id {$sqlin}";
        $instances = $DB->get_records_sql($sql, $params);
        tag_bulk_delete_instances($instances);
    }
    // TODO MDL-31212 this will only clean tags of type 'default'.  This is good as
    // it won't delete 'official' tags, but the day we get more than two
    // types, we need to fix this.
    $unused_tags = $DB->get_recordset_sql("SELECT tg.id\n                                             FROM {tag} tg\n                                            WHERE tg.tagtype = 'default'\n                                                  AND NOT EXISTS (\n                                                      SELECT 'x'\n                                                        FROM {tag_instance} ti\n                                                       WHERE ti.tagid = tg.id\n                                                  )");
    // cleanup tags
    foreach ($unused_tags as $unused_tag) {
        tag_delete($unused_tag->id);
        //debugging('deleting unused tag #'. $unused_tag->id,  DEBUG_DEVELOPER);
    }
    $unused_tags->close();
}
Пример #2
0
 /**
  * Test deleting a group of tag instances.
  */
 public function test_tag_bulk_delete_instances()
 {
     global $DB;
     // Setup.
     $user = $this->getDataGenerator()->create_user();
     $course = $this->getDataGenerator()->create_course();
     $context = context_course::instance($course->id);
     // Create some tag instances.
     for ($i = 0; $i < 10; $i++) {
         $tag = $this->getDataGenerator()->create_tag(array('userid' => $user->id));
         tag_assign('course', $course->id, $tag->id, 0, 0, 'core', $context->id);
     }
     // Get tag instances. tag name and rawname are required for the event fired in this function.
     $sql = "SELECT ti.*, t.name, t.rawname\n                  FROM {tag_instance} ti\n                  JOIN {tag} t ON t.id = ti.tagid";
     $taginstances = $DB->get_records_sql($sql);
     $this->assertCount(10, $taginstances);
     // Run the function.
     tag_bulk_delete_instances($taginstances);
     // Make sure they are gone.
     $instancecount = $DB->count_records('tag_instance');
     $this->assertEquals(0, $instancecount);
 }