summaryrefslogtreecommitdiffstats
path: root/lib/class/tag.class.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/class/tag.class.php')
-rw-r--r--lib/class/tag.class.php308
1 files changed, 193 insertions, 115 deletions
diff --git a/lib/class/tag.class.php b/lib/class/tag.class.php
index a3fc2b1e..9f079102 100644
--- a/lib/class/tag.class.php
+++ b/lib/class/tag.class.php
@@ -28,6 +28,11 @@ class Tag extends database_object {
public $id;
public $name;
+ // constructed
+ public $weight=0;
+ public $count=0;
+ public $owner=0;
+
/**
* constructor
* This takes a tag id and returns all of the relevent information
@@ -50,25 +55,68 @@ class Tag extends database_object {
*/
public static function construct_from_name($name) {
- $name = Dba::escape($name);
+ $tag_id = self::tag_exists($name);
- $sql = "SELECT * FROM `tag` WHERE `name`='$name'";
- $db_results = Dba::query($sql);
+ $tag = new Tag($tag_id);
- $row = Dba::fetch_assoc($db_results);
+ return $tag;
+
+ } // construct_from_name
- if (!$row['id']) { return false; }
+ /**
+ * format
+ * This makes the tag presentable to the great humans that use this program, other life forms
+ * will just have to fend for themselves
+ */
+ public function format($type=0,$object_id=0) {
- parent::add_to_cache('tag',$row['id'],$row);
+ if (!self::validate_type($type)) { return false; }
- $tag = new Tag(0);
- foreach ($row as $key=>$value) {
- $tag->$key = $value;
+ if ($type) {
+ $this->set_object($type,$object_id);
}
- return $tag;
+ $size = 3 + ($this->weight-1) - ($this->count-1);
+ if ($size > 4) { $size = 4; }
+
+ if ($this->owner == $GLOBALS['user']->id) {
+ $action = '?page=tag&action=remove_tag&type=' . scrub_out($type) . '&tag_id=' . intval($this->id) . '&object_id=' . intval($object_id);
+ $class = "hover-remove ";
+ }
+ else {
+ $action = '?page=tag&action=add_tag&type=' . scrub_out($type) . '&tag_id=' . intval($this->id) . '&object_id=' . intval($object_id);
+ $class = "hover-add ";
+ }
+
+ $class .= 'tag_size' . $size;
+
+ $this->f_name = Ajax::text($action,$this->name,'modify_tag_' . $this->id . '_' . $object_id,'',$class);
+
+ } // format
+
+ /**
+ * set_object
+ * This assoicates the tag with a specified object, we try to get the data
+ * from the map cache, otherwise I guess we'll just have to look it up
+ */
+ public function set_object($type,$object_id) {
+
+ if (parent::is_cached('tag_top_' . $type,$object_id)) {
+ $data = parent::get_from_cache('tag_top_' . $type,$object_id);
+ }
+ else {
+ $data = self::get_top_tags($type,$object_id);
+ }
+
+ $this->weight = $data[$this->id]['count'];
+
+ if (in_array($GLOBALS['user']->id,$data[$this->id]['users'])) {
+ $this->owner = $GLOBALS['user']->id;
+ }
- } // construct_from_name
+ $this->count = count($data);
+
+ } // set_object
/**
* build_cache
@@ -76,13 +124,13 @@ class Tag extends database_object {
* in a single query, cuts down on the connections
*/
public static function build_cache($ids) {
-
+
if (!is_array($ids) OR !count($ids)) { return false; }
$idlist = '(' . implode(',',$ids) . ')';
$sql = "SELECT * FROM `tag` WHERE `id` IN $idlist";
- $db_results = Dba::query($sql);
+ $db_results = Dba::read($sql);
while ($row = Dba::fetch_assoc($db_results)) {
parent::add_to_cache('tag',$row['id'],$row);
@@ -102,18 +150,20 @@ class Tag extends database_object {
$type = self::validate_type($type);
$idlist = '(' . implode(',',$ids) . ')';
- $sql = "SELECT COUNT(`tag_map`.`id`) AS `count`,`tag`.`id`,`tag_map`.`object_id` FROM `tag_map` " .
- "INNER JOIN `tag` ON `tag`.`id`=`tag_map`.`tag_id` " .
- "WHERE `tag_map`.`object_type`='$type' AND `tag_map`.`object_id` IN $idlist " .
- "GROUP BY `tag_map`.`object_id` ORDER BY `count` DESC";
+ $sql = "SELECT `tag_map`.`tag_id`,`tag_map`.`object_id`,`tag_map`.`user` FROM `tag_map` " .
+ "WHERE `tag_map`.`object_type`='$type' AND `tag_map`.`object_id` IN $idlist ";
$db_results = Dba::query($sql);
+ $tags = array();
+
while ($row = Dba::fetch_assoc($db_results)) {
- $tags[$row['object_id']][] = $row;
+ $tags[$row['object_id']][$row['tag_id']]['users'][] = $row['user'];
+ $tags[$row['object_id']][$row['tag_id']]['count']++;
}
- foreach ($tags as $id=>$entry) {
- parent::add_to_cache('tag_map_' . $type,$id,$entry);
+ // Run through our origional ids as we want to cache NULL results
+ foreach ($ids as $id) {
+ parent::add_to_cache('tag_top_' . $type,$id,$tags[$id]);
}
return true;
@@ -121,61 +171,60 @@ class Tag extends database_object {
} // build_map_cache
/**
- * has_object
- * This checks to see if the current tag element has the specified object
- * of the specified type
+ * add
+ * This is a wrapper function, it figures out what we need to add, be it a tag
+ * and map, or just the mapping
*/
- public function has_object($object_type,$object_id) {
+ public static function add($type,$id,$value,$user='') {
- $object_type = self::validate_type($object_type);
- $object_id = intval($object_id);
- $tag_id = intval($this->id);
-
- $sql = "SELECT * FROM `tag_map` WHERE `object_type`='$object_type' AND `object_id`='$object_id' " .
- " AND `tag_id`='$tag_id'";
- $db_results = Dba::query($sql);
+ // Validate the tag type
+ if (!self::validate_type($type)) { return false; }
+
+ if (!is_numeric($id)) { return false; }
+
+ $cleaned_value = self::clean_tag($value);
+
+ if (!strlen($cleaned_value)) { return false; }
+
+ $uid = ($user == '') ? intval($user) : intval($GLOBALS['user']->id);
+
+ // Check and see if the tag exists, if not create it, we need the tag id from this
+ if (!$tag_id = self::tag_exists($cleaned_value)) {
+ $tag_id = self::add_tag($cleaned_value);
+ }
+
+ if (!$tag_id) {
+ debug_event('Error','Error unable to create tag value:' . $cleaned_value . ' unknown error','1');
+ return false;
+ }
+
+ // We've got the tag id, let's see if it's already got a map, if not then create the map and return the value
+ if (!$map_id = self::tag_map_exists($type,$id,$tag_id,$user)) {
+ $map_id = self::add_tag_map($type,$id,$tag_id,$user);
+ }
- return Dba::num_rows($db_results);
+ return $map_id;
- } // has_object
+ } // add
/**
* add_tag
* This function adds a new tag, for now we're going to limit the tagging a bit
*/
- public static function add_tag($type, $id, $tagval,$user='') {
+ public static function add_tag($value) {
- if (!self::validate_type($type)) {
- return false;
- }
- if (!is_numeric($id)) {
- return false;
- }
-
// Clean it up and make it tagish
- $tagval = self::clean_tag($tagval);
+ $value = self::clean_tag($value);
- if (!strlen($tagval)) { return false; }
+ if (!strlen($value)) { return false; }
- $uid = ($user == '') ? intval($user) : intval($GLOBALS['user']->id);
- $tagval = Dba::escape($tagval);
- $type = Dba::escape($type);
- $id = intval($id);
-
- // Check if tag object exists
- $sql = "SELECT `tag`.`id` FROM `tag` WHERE `name`='$tagval'";
- $db_results = Dba::query($sql) ;
- $row = Dba::fetch_assoc($db_results);
- $insert_id = $row['id'];
-
- // If the tag doesn't exist create it.
- if (!count($row)) {
- $sql = "INSERT INTO `tag` SET `name`='$tagval'";
- $db_results = Dba::query($sql) ;
- $insert_id = Dba::insert_id();
- }
+ $value = Dba::escape($value);
+
+ $sql = "REPLACE INTO `tag` SET `name`='$value'";
+ $db_results = Dba::write($sql);
+ $insert_id = Dba::insert_id();
- self::add_tag_map($insert_id,$type,$id);
+ parent::add_to_cache('tag_name',$value,$insert_id);
return $insert_id;
@@ -185,98 +234,107 @@ class Tag extends database_object {
* add_tag_map
* This adds a specific tag to the map for specified object
*/
- public static function add_tag_map($tag_id,$object_type,$object_id,$user='') {
+ public static function add_tag_map($type,$object_id,$tag_id,$user='') {
$uid = ($user == '') ? intval($GLOBALS['user']->id) : intval($user);
$tag_id = intval($tag_id);
- $type = self::validate_type($object_type);
+ if (!self::validate_type($type)) { return false; }
$id = intval($object_id);
+
+ if (!$tag_id || !$id) { return false; }
+
+ $sql = "INSERT INTO `tag_map` (`tag_id`,`user`,`object_type`,`object_id`) " .
+ "VALUES ('$tag_id','$uid','$type','$id')";
+ $db_results = Dba::write($sql);
+ $insert_id = Dba::insert_id();
- // Now make sure this isn't a duplicate
- $sql = "SELECT * FROM `tag_map " .
- "WHERE `tag_id`='$insert_id' AND `user`='$uid' AND `object_type`='$type' AND `object_id`='$id'";
- $db_results = Dba::query($sql);
-
- $row = Dba::fetch_assoc($db_results);
-
- // Only insert it if the current tag for this user doesn't exist
- if (!count($row)) {
- $sql = "INSERT INTO `tag_map` (`tag_id`,`user`,`object_type`,`object_id`) " .
- "VALUES ('$tag_id','$uid','$type','$id')";
- $db_results = Dba::query($sql);
- $insert_id = Dba::insert_id();
- }
- else {
- $insert_id = $row['id'];
- }
+ parent::add_to_cache('tag_map_' . $type,$insert_id,array('tag_id'=>$tag_id,'user'=>$uid,'object_type'=>$type,'object_id'=>$id));
return $insert_id;
} // add_tag_map
/**
- * get_many_tags
- * This builds a cache of all of the tags contained by the specified object ids
- * of the specified type
+ * tag_exists
+ * This checks to see if a tag exists, this has nothing to do with objects or maps
*/
- public static function get_many_tags($type, $object_ids) {
+ public static function tag_exists($value) {
+
+ if (parent::is_cached('tag_name',$value)) {
+ return parent::get_from_cache('tag_name',$value);
+ }
+
+ $value = Dba::escape($value);
+ $sql = "SELECT * FROM `tag` WHERE `name`='$value'";
+ $db_results = Dba::read($sql);
- // If they pass us nothing, they get nothing
- if (!count($object_ids)) { return array(); }
- if (!self::validate_type($type)) { return array(); }
+ $results = Dba::fetch_assoc($db_results);
- $lid = '(' . implode(',',$id) . ')';
- $orsql = '';
+ parent::add_to_cache('tag_name',$results['name'],$results['id']);
+
+ return $results['id'];
+
+ } // tag_exists
+
+ /**
+ * tag_map_exists
+ * This looks to see if the current mapping of the current object of the current tag of the current
+ * user exists, lots of currents... taste good in scones.
+ */
+ public static function tag_map_exists($type,$object_id,$tag_id,$user) {
+
+ if (!self::validate_type($type)) { return false; }
- if ($objType == 'artist' || $objType == 'album')
- $orsql=" or (tag_map.object_id = song.id AND tag_map.object_type='song' and song.$objType in $lid )";
- if ($objType == 'artist')
- $orsql .= "or (tag_map.object_id = album.id AND tag_map.object_type='album' and $objType.id in $lid )";
- $sql = "SELECT DISTINCT tag.id, tag.name, tag_map.user, $objType.id as oid FROM tag, tag_map, song, artist, album WHERE " .
- "tag_map.tag_id = tag.id AND ( (tag_map.object_type='$objType' AND $objType.id in $lid AND tag_map.object_id = $objType.id) $orsql) " .
- "AND song.album = album.id AND song.artist = artist.id;";
-return array();
- $results = array();
-
- $db_results = Dba::query($sql) or die(Dba::error());
-
- while ($r = Dba::fetch_assoc($db_results)) {
- $uid = intval($r['oid']);
- $results[] = $r;
+ if (parent::is_cached('tag_map_' . $type,$object_id)) {
+ $data = parent::get_from_cache('tag_map_' . $type,$object_id);
+ return $data['id'];
}
- //return self::filter_with_prefs($results);
- return $results;
+ $object_id = Dba::escape($object_id);
+ $tag_id = Dba::escape($tag_id);
+ $user = Dba::escape($user);
+ $type = Dba::escape($type);
- } // get_man_tags
+ $sql = "SELECT * FROM `tag_map` WHERE `tag_id`='$tag_id' AND `user`='$user' AND `object_id`='$object_id' AND `object_type`='$type'";
+ $db_results = Dba::read($sql);
+
+ $results = Dba::fetch_assoc($db_results);
+
+ parent::add_to_cache('tag_map_' . $type,$results['id'],$results);
+
+ return $results['id'];
+
+ } // tag_map_exists
/**
* get_top_tags
* This gets the top tags for the specified object using limit
*/
- public static function get_top_tags($type,$object_id,$limit='2') {
+ public static function get_top_tags($type,$object_id,$limit='10') {
- $type = self::validate_type($type);
+ if (!self::validate_type($type)) { return false; }
- if (parent::is_cached('tag_map_' . $type,$object_id)) {
- return parent::get_from_cache('tag_map_' . $type,$object_id);
+ if (parent::is_cached('tag_top_' . $type,$object_id)) {
+ return parent::get_from_cache('tag_top_' . $type,$object_id);
}
$object_id = intval($object_id);
$limit = intval($limit);
- $sql = "SELECT COUNT(`tag_map`.`id`) AS `count`,`tag`.`id` FROM `tag_map` " .
- "INNER JOIN `tag` ON `tag`.`id`=`tag_map`.`tag_id` " .
+ $sql = "SELECT `tag_map`.`tag_id`,`tag_map`.`user` FROM `tag_map` " .
"WHERE `tag_map`.`object_type`='$type' AND `tag_map`.`object_id`='$object_id' " .
- "GROUP BY `tag_map`.`object_id` ORDER BY `count` DESC LIMIT $limit";
+ "LIMIT $limit";
$db_results = Dba::query($sql);
$results = array();
while ($row = Dba::fetch_assoc($db_results)) {
- $results[] = $row['id'];
+ $results[$row['tag_id']]['users'][] = $row['user'];
+ $results[$row['tag_id']]['count']++;
}
+ parent::add_to_cache('tag_top_' . $type,$object_id,$results);
+
return $results;
} // get_top_tags
@@ -365,6 +423,26 @@ return array();
} // filter_with_prefs
/**
+ * remove_map
+ * This will only remove tag maps for the current user
+ */
+ public function remove_map($type,$object_id) {
+
+ if (!self::validate_type($type)) { return false; }
+
+ $type = Dba::escape($type);
+ $tag_id = Dba::escape($this->id);
+ $object_id = Dba::escape($object_id);
+ $user_id = Dba::escape($GLOBALS['user']->id);
+
+ $sql = "DELETE FROM `tag_map` WHERE `tag_id`='$tag_id' AND `object_type`='$type' AND `object_id`='$object_id' AND `user`='$user_id'";
+ $db_results = Dba::write($sql);
+
+ return true;
+
+ } // remove_map
+
+ /**
* validate_type
* This validates the type of the object the user wants to tag, we limit this to types
* we currently support