///////////////////////////////////////////////////////
/////////////////// PUBLIC TAG API ////////////////////
+/// Functions for settings tags //////////////////////
+
/**
- * Delete one or more tag, and all their instances if there are any left.
+ * Set the tags assigned to a record. This overwrites the current tags.
*
- * @param mixed $tagids one tagid (int), or one array of tagids to delete
- * @return bool true on success, false otherwise
+ * This function is meant to be fed the string coming up from the user
+ * interface, which contains all tags assigned to a record.
+ *
+ * @param string $record_type the type of record to tag ('post' for blogs,
+ * 'user' for users, 'tag' for tags, etc.
+ * @param int $record_id the id of the record to tag
+ * @param array $tags the array of tags to set on the record. If
+ * given an empty array, all tags will be removed.
+ * @return void
*/
-function tag_delete($tagids) {
+function tag_set($record_type, $record_id, $tags) {
+ global $db;
- if (!is_array($tagids)) {
- $tagids = array($tagids);
+ $record = array('type' => $record_type, 'id' => $record_id);
+
+ $tags_ids = tag_get_id($tags, TAG_RETURN_ARRAY); // force an array, even if we only have one tag.
+ $cleaned_tags = tag_normalize($tags);
+ //echo 'tags-in-tag_set'; var_dump($tags); var_dump($tags_ids); var_dump($cleaned_tags);
+
+ $current_ids = tag_get_tags_ids($record['type'], $record['id']);
+ //var_dump($current_ids);
+ $tags_to_assign = array();
+
+ // for data coherence reasons, it's better to remove deleted tags
+ // before adding new data: ordering could be duplicated.
+ foreach($current_ids as $current_id) {
+ if (!in_array($current_id, $tags_ids)) {
+ tag_delete_instance($record, $current_id);
+ }
}
- $success = true;
- foreach( $tagids as $tagid ) {
- if (is_null($tagid)) { // can happen if tag doesn't exists
+ foreach($tags as $ordering => $tag) {
+ $tag = trim($tag);
+ if (!$tag) {
continue;
}
- // only delete the main entry if there were no problems deleting all the
- // instances - that (and the fact we won't often delete lots of tags)
- // is the reason for not using delete_records_select()
- if ( delete_records('tag_instance', 'tagid', $tagid) ) {
- $success &= (bool) delete_records('tag', 'id', $tagid);
+
+ $clean_tag = $cleaned_tags[$tag];
+ $tag_current_id = $tags_ids[$clean_tag];
+
+ if ( is_null($tag_current_id) ) {
+ // create new tags
+ //echo "call to add tag $tag\n";
+ $new_tag = tag_add($tag);
+ tag_assign($record, $new_tag[$clean_tag], $ordering);
+ }
+ elseif ( empty($current_ids) || !in_array($tag_current_id, $current_ids) ) {
+ // assign existing tags
+ tag_assign($record, $tag_current_id, $ordering);
+ }
+ elseif ( isset($current_ids[$ordering]) && $current_ids[$ordering] != $tag_current_id ) {
+ // this actually checks if the ordering number points to the same tag
+ //recompute ordering, if necessary
+ //echo 'ordering changed for ', $tag, ':', $ordering, "\n";
+ tag_assign($record, $tag_current_id, $ordering);
}
}
+}
- return $success;
+/**
+ * Adds a tag to a record, without overwriting the current tags.
+ *
+ * @param string $record_type the type of record to tag ('post' for blogs,
+ * 'user' for users, etc.
+ * @param int $record_id the id of the record to tag
+ * @param string $tag the tag to add
+ * @return void
+ */
+function tag_set_add($record_type, $record_id, $tag) {
+
+ $new_tags = array();
+ foreach( tag_get_tags($record_type, $record_id) as $current_tag ) {
+ $new_tags[] = $current_tag->rawname;
+ }
+ $new_tags[] = $tag;
+
+ return tag_set($record_type, $record_id, $new_tags);
}
/**
- * Delete one instance of a tag. If the last instance was deleted, it will
- * also delete the tag, unless it's type is 'official'.
- *
- * @param array $record the record for which to remove the instance
- * @param int $tagid the tagid that needs to be removed
- * @return bool true on success, false otherwise
+ * Removes a tag from a record, without overwriting other current tags.
+ *
+ * @param string $record_type the type of record to tag ('post' for blogs,
+ * 'user' for users, etc.
+ * @param int $record_id the id of the record to tag
+ * @param string $tag the tag to delete
+ * @return void
*/
-function tag_delete_instance($record, $tagid) {
- global $CFG;
+function tag_set_delete($record_type, $record_id, $tag) {
- if ( delete_records('tag_instance', 'tagid', $tagid, 'itemtype', $record['type'], 'itemid', $record['id']) ) {
- if ( !record_exists_sql("SELECT * FROM {$CFG->prefix}tag tg, {$CFG->prefix}tag_instance ti ".
- "WHERE (tg.id = ti.tagid AND ti.tagid = {$tagid} ) OR ".
- "(tg.id = {$tagid} AND tg.tagtype = 'official')") ) {
- return tag_delete($tagid);
+ $new_tags = array();
+ foreach( tag_get_tags($record_type, $record_id) as $current_tag ) {
+ if ($current_tag->name != $tag) { // Keep all tags but the one specified
+ $new_tags[] = $current_tag->name;
}
- } else {
- return false;
}
+
+ return tag_set($record_type, $record_id, $new_tags);
+}
+
+/**
+ * Set the type of a tag. At this time (version 1.9) the possible values
+ * are 'default' or 'official'. Official tags will be displayed separately "at
+ * tagging time" (while selecting the tags to apply to a record).
+ *
+ * @param string $tagid tagid to modify
+ * @param string $type either 'default' or 'official'
+ * @return true on success, false otherwise
+ */
+function tag_type_set($tagid, $type) {
+ if ($tag = get_record('tag', 'id', $tagid, '', '', '', '', 'id')) {
+ $tag->tagtype = addslashes($type);
+ $tag->timemodified = time();
+ return update_record('tag', $tag);
+ }
+ return false;
}
+
/**
* Set the description of a tag
*
return false;
}
-/**
- * Function that returns the name that should be displayed for a specific tag
- *
- * @param object $tag_object a line out of tag table, as returned by the adobd functions
- * @return string
- */
-function tag_display_name($tag_object) {
- global $CFG;
- if(!isset($tag_object->name)) {
- return '';
- }
- if( empty($CFG->keeptagnamecase) ) {
- //this is the normalized tag name
- $textlib = textlib_get_instance();
- return htmlspecialchars($textlib->strtotitle($tag_object->name));
- }
- else {
- //original casing of the tag name
- return htmlspecialchars($tag_object->rawname);
- }
-}
-/**
- * Find all records tagged with a tag of a given type ('post', 'user', etc.)
- *
- * @param string $tag tag to look for
- * @param string $type type to restrict search to. If null, every matching
- * record will be returned
- * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
- * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
- * @return array of matching objects, indexed by record id, from the table containing the type requested
- */
-function tag_find_records($tag, $type, $limitfrom='', $limitnum='') {
-
- global $CFG;
-
- if (!$tag || !$type) {
- return array();
- }
-
- $tagid = tag_get_id($tag);
-
- $query = "SELECT it.* ".
- "FROM {$CFG->prefix}{$type} it INNER JOIN {$CFG->prefix}tag_instance tt ON it.id = tt.itemid ".
- "WHERE tt.itemtype = '{$type}' AND tt.tagid = '{$tagid}'";
-
- return get_records_sql($query, $limitfrom, $limitnum);
-}
+/// Functions for getting information about tags //////
/**
- * Simple function to just return a single tag object
+ * Simple function to just return a single tag object when you know the name or something
*
* @param string $field which field do we use to identify the tag: id, name or rawname
* @param string $value the required value of the aforementioned field
*
**/
function tag_get($field, $value, $returnfields='id, name, rawname') {
+ if ($field == 'name') {
+ $value = moodle_strtolower($value); // To cope with input that might just be wrong case
+ }
return get_record('tag', $field, $value, '', '', '', '', $returnfields);
}
global $CFG;
$tags_names = array();
- foreach( tag_get_tags($record_type, $record_id, $type) as $tag ) {
+ foreach(tag_get_tags($record_type, $record_id, $type) as $tag) {
if ($html == TAG_RETURN_TEXT) {
$tags_names[] = tag_display_name($tag);
} else { // TAG_RETURN_HTML
function tag_get_tags_ids($record_type, $record_id) {
$tag_ids = array();
- foreach( tag_get_tags($record_type, $record_id) as $tag ) {
+ foreach (tag_get_tags($record_type, $record_id) as $tag) {
$tag_ids[$tag->ordering] = $tag->id;
}
ksort($tag_ids);
return $result;
}
-/**
- * Get a tag as an object (line) returned by get_recordset_sql
- *
- * @param int $tagid a tag id
- * @return object a line returned from get_recordset_sql, or false
- */
-function tag_get_tag_by_id($tagid) {
- return get_record('tag', 'id', $tagid);
-}
/**
* Returns tags related to a tag
return false;
}
+
/**
- * Set the tags assigned to a record. This overwrites the current tags.
+ * Delete one or more tag, and all their instances if there are any left.
*
- * This function is meant to be fed the string coming up from the user
- * interface, which contains all tags assigned to a record.
- *
- * @param string $record_type the type of record to tag ('post' for blogs,
- * 'user' for users, 'tag' for tags, etc.
- * @param int $record_id the id of the record to tag
- * @param array $tags the array of tags to set on the record. If
- * given an empty array, all tags will be removed.
- * @return void
+ * @param mixed $tagids one tagid (int), or one array of tagids to delete
+ * @return bool true on success, false otherwise
*/
-function tag_set($record_type, $record_id, $tags) {
- global $db;
-
- $record = array('type' => $record_type, 'id' => $record_id);
-
- $tags_ids = tag_get_id($tags, TAG_RETURN_ARRAY); // force an array, even if we only have one tag.
- $cleaned_tags = tag_normalize($tags);
- //echo 'tags-in-tag_set'; var_dump($tags); var_dump($tags_ids); var_dump($cleaned_tags);
-
- $current_ids = tag_get_tags_ids($record['type'], $record['id']);
- //var_dump($current_ids);
- $tags_to_assign = array();
+function tag_delete($tagids) {
- // for data coherence reasons, it's better to remove deleted tags
- // before adding new data: ordering could be duplicated.
- foreach($current_ids as $current_id) {
- if (!in_array($current_id, $tags_ids)) {
- tag_delete_instance($record, $current_id);
- }
+ if (!is_array($tagids)) {
+ $tagids = array($tagids);
}
- foreach($tags as $ordering => $tag) {
- $tag = trim($tag);
- if (!$tag) {
+ $success = true;
+ foreach( $tagids as $tagid ) {
+ if (is_null($tagid)) { // can happen if tag doesn't exists
continue;
}
-
- $clean_tag = $cleaned_tags[$tag];
- $tag_current_id = $tags_ids[$clean_tag];
-
- if ( is_null($tag_current_id) ) {
- // create new tags
- //echo "call to add tag $tag\n";
- $new_tag = tag_add($tag);
- tag_assign($record, $new_tag[$clean_tag], $ordering);
- }
- elseif ( empty($current_ids) || !in_array($tag_current_id, $current_ids) ) {
- // assign existing tags
- tag_assign($record, $tag_current_id, $ordering);
- }
- elseif ( isset($current_ids[$ordering]) && $current_ids[$ordering] != $tag_current_id ) {
- // this actually checks if the ordering number points to the same tag
- //recompute ordering, if necessary
- //echo 'ordering changed for ', $tag, ':', $ordering, "\n";
- tag_assign($record, $tag_current_id, $ordering);
+ // only delete the main entry if there were no problems deleting all the
+ // instances - that (and the fact we won't often delete lots of tags)
+ // is the reason for not using delete_records_select()
+ if ( delete_records('tag_instance', 'tagid', $tagid) ) {
+ $success &= (bool) delete_records('tag', 'id', $tagid);
}
}
+
+ return $success;
}
/**
- * Adds a tag to a record, without overwriting the current tags.
- *
- * @param string $record_type the type of record to tag ('post' for blogs,
- * 'user' for users, etc.
- * @param int $record_id the id of the record to tag
- * @param string $tag the tag to add
- * @return void
+ * Delete one instance of a tag. If the last instance was deleted, it will
+ * also delete the tag, unless it's type is 'official'.
+ *
+ * @param array $record the record for which to remove the instance
+ * @param int $tagid the tagid that needs to be removed
+ * @return bool true on success, false otherwise
*/
-function tag_set_add($record_type, $record_id, $tag) {
+function tag_delete_instance($record, $tagid) {
+ global $CFG;
- $new_tags = array();
- foreach( tag_get_tags($record_type, $record_id) as $current_tag ) {
- $new_tags[] = $current_tag->rawname;
+ if ( delete_records('tag_instance', 'tagid', $tagid, 'itemtype', $record['type'], 'itemid', $record['id']) ) {
+ if ( !record_exists_sql("SELECT * FROM {$CFG->prefix}tag tg, {$CFG->prefix}tag_instance ti ".
+ "WHERE (tg.id = ti.tagid AND ti.tagid = {$tagid} ) OR ".
+ "(tg.id = {$tagid} AND tg.tagtype = 'official')") ) {
+ return tag_delete($tagid);
+ }
+ } else {
+ return false;
}
- $new_tags[] = $tag;
-
- return tag_set($record_type, $record_id, $new_tags);
}
+
/**
- * Removes a tag from a record, without overwriting other current tags.
- *
- * @param string $record_type the type of record to tag ('post' for blogs,
- * 'user' for users, etc.
- * @param int $record_id the id of the record to tag
- * @param string $tag the tag to delete
- * @return void
+ * Function that returns the name that should be displayed for a specific tag
+ *
+ * @param object $tag_object a line out of tag table, as returned by the adobd functions
+ * @return string
*/
-function tag_set_delete($record_type, $record_id, $tag) {
+function tag_display_name($tag_object) {
- $new_tags = array();
- foreach( tag_get_tags($record_type, $record_id) as $current_tag ) {
- if ($current_tag->name != $tag) { // Keep all tags but the one specified
- $new_tags[] = $current_tag->name;
- }
+ global $CFG;
+
+ if(!isset($tag_object->name)) {
+ return '';
+ }
+
+ if (empty($CFG->keeptagnamecase)) {
+ //this is the normalized tag name
+ $textlib = textlib_get_instance();
+ return htmlspecialchars($textlib->strtotitle($tag_object->name));
+ } else {
+ //original casing of the tag name
+ return htmlspecialchars($tag_object->rawname);
}
-
- return tag_set($record_type, $record_id, $new_tags);
}
/**
- * Set the type of a tag. At this time (version 1.9) the possible values
- * are 'default' or 'official'. Official tags will be displayed separately "at
- * tagging time" (while selecting the tags to apply to a record).
+ * Find all records tagged with a tag of a given type ('post', 'user', etc.)
*
- * @param string $tagid tagid to modify
- * @param string $type either 'default' or 'official'
- * @return true on success, false otherwise
+ * @param string $tag tag to look for
+ * @param string $type type to restrict search to. If null, every matching
+ * record will be returned
+ * @param int $limitfrom return a subset of records, starting at this point (optional, required if $limitnum is set).
+ * @param int $limitnum return a subset comprising this many records (optional, required if $limitfrom is set).
+ * @return array of matching objects, indexed by record id, from the table containing the type requested
*/
-function tag_type_set($tagid, $type) {
- if ($tag = get_record('tag', 'id', $tagid, '', '', '', '', 'id')) {
- $tag->tagtype = addslashes($type);
- $tag->timemodified = time();
- return update_record('tag', $tag);
+function tag_find_records($tag, $type, $limitfrom='', $limitnum='') {
+
+ global $CFG;
+
+ if (!$tag || !$type) {
+ return array();
}
- return false;
+
+ $tagid = tag_get_id($tag);
+
+ $query = "SELECT it.* ".
+ "FROM {$CFG->prefix}{$type} it INNER JOIN {$CFG->prefix}tag_instance tt ON it.id = tt.itemid ".
+ "WHERE tt.itemtype = '{$type}' AND tt.tagid = '{$tagid}'";
+
+ return get_records_sql($query, $limitfrom, $limitnum);
}
+
+
+
///////////////////////////////////////////////////////
/////////////////// PRIVATE TAG API ///////////////////