X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=classes%2FProfile_tag.php;h=6d6f49bedc634abf174d6d5d663da38e18d35302;hb=refs%2Fheads%2Fsazius-nightly;hp=bd45ce0b457b16a0148cde22e5bd4e7b31e3faca;hpb=fd8dad39633870d2d71c3829a756e724acb45c2a;p=quix0rs-gnu-social.git diff --git a/classes/Profile_tag.php b/classes/Profile_tag.php index bd45ce0b45..6d6f49bedc 100644 --- a/classes/Profile_tag.php +++ b/classes/Profile_tag.php @@ -4,7 +4,7 @@ */ require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; -class Profile_tag extends Memcached_DataObject +class Profile_tag extends Managed_DataObject { ###START_AUTOCODE /* the code below is auto generated do not remove the above tag */ @@ -15,38 +15,114 @@ class Profile_tag extends Memcached_DataObject public $tag; // varchar(64) primary_key not_null public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP - /* Static get */ - function staticGet($k,$v=null) - { return Memcached_DataObject::staticGet('Profile_tag',$k,$v); } - /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE - static function getTags($tagger, $tagged) { - $tags = array(); + public static function schemaDef() + { + return array( + + 'fields' => array( + 'tagger' => array('type' => 'int', 'not null' => true, 'description' => 'user making the tag'), + 'tagged' => array('type' => 'int', 'not null' => true, 'description' => 'profile tagged'), + 'tag' => array('type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'hash tag associated with this notice'), + 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date the tag was added'), + ), + 'primary key' => array('tagger', 'tagged', 'tag'), + 'foreign keys' => array( + 'profile_tag_tagger_fkey' => array('profile', array('tagger' => 'id')), + 'profile_tag_tagged_fkey' => array('profile', array('tagged' => 'id')), + 'profile_tag_tag_fkey' => array('profile_list', array('tag' => 'tag')), + ), + 'indexes' => array( + 'profile_tag_modified_idx' => array('modified'), + 'profile_tag_tagger_tag_idx' => array('tagger', 'tag'), + 'profile_tag_tagged_idx' => array('tagged'), + ), + ); + } - // XXX: store this in memcached + function links() + { + return array('tagger,tag' => 'profile_list:tagger,tag'); + } - $profile_tag = new Profile_tag(); - $profile_tag->tagger = $tagger; - $profile_tag->tagged = $tagged; + function getMeta() + { + return Profile_list::pkeyGet(array('tagger' => $this->tagger, 'tag' => $this->tag)); + } - $profile_tag->find(); + static function getTags($tagger, $tagged, $auth_user=null) { - while ($profile_tag->fetch()) { - $tags[] = $profile_tag->tag; + $profile_list = new Profile_list(); + $include_priv = 1; + + if (!($auth_user instanceof User || + $auth_user instanceof Profile) || + ($auth_user->id !== $tagger)) { + + $profile_list->private = false; + $include_priv = 0; } - $profile_tag->free(); + $key = sprintf('profile_tag:tagger_tagged_privacy:%d-%d-%d', $tagger, $tagged, $include_priv); + $tags = Profile_list::getCached($key); + if ($tags !== false) { + return $tags; + } + + $qry = 'select profile_list.* from profile_list left join '. + 'profile_tag on (profile_list.tag = profile_tag.tag and '. + 'profile_list.tagger = profile_tag.tagger) where '. + 'profile_tag.tagger = %d and profile_tag.tagged = %d '; + $qry = sprintf($qry, $tagger, $tagged); + + if (!$include_priv) { + $qry .= ' and profile_list.private = 0'; + } + + $profile_list->query($qry); + + Profile_list::setCache($key, $profile_list); + + return $profile_list; + } + + static function getTagsArray($tagger, $tagged, $auth_user_id=null) + { + $ptag = new Profile_tag(); + + $qry = sprintf('select profile_tag.tag '. + 'from profile_tag join profile_list '. + ' on (profile_tag.tagger = profile_list.tagger ' . + ' and profile_tag.tag = profile_list.tag) ' . + 'where profile_tag.tagger = %d ' . + 'and profile_tag.tagged = %d ', + $tagger, $tagged); + + if ($auth_user_id != $tagger) { + $qry .= 'and profile_list.private = 0'; + } + + $tags = array(); + + $ptag->query($qry); + + while ($ptag->fetch()) { + $tags[] = $ptag->tag; + } return $tags; } - static function setTags($tagger, $tagged, $newtags) { + static function setTags($tagger, $tagged, $newtags, $privacy=array()) { + $newtags = array_unique($newtags); - $oldtags = Profile_tag::getTags($tagger, $tagged); + $oldtags = self::getTagsArray($tagger, $tagged, $tagger); - // Delete stuff that's old that not in new + $ptag = new Profile_tag(); + + // Delete stuff that's in old and not in new $to_delete = array_diff($oldtags, $newtags); @@ -54,33 +130,169 @@ class Profile_tag extends Memcached_DataObject $to_insert = array_diff($newtags, $oldtags); - $profile_tag = new Profile_tag(); + foreach ($to_delete as $deltag) { + self::unTag($tagger, $tagged, $deltag); + } + + foreach ($to_insert as $instag) { + $private = isset($privacy[$instag]) ? $privacy[$instag] : false; + self::setTag($tagger, $tagged, $instag, null, $private); + } + return true; + } + + # set a single tag + static function setTag($tagger, $tagged, $tag, $desc=null, $private=false) { + + $ptag = Profile_tag::pkeyGet(array('tagger' => $tagger, + 'tagged' => $tagged, + 'tag' => $tag)); - $profile_tag->tagger = $tagger; - $profile_tag->tagged = $tagged; + # if tag already exists, return it + if(!empty($ptag)) { + return $ptag; + } + + $tagger_profile = Profile::getKV('id', $tagger); + $tagged_profile = Profile::getKV('id', $tagged); + + if (Event::handle('StartTagProfile', array($tagger_profile, $tagged_profile, $tag))) { + + if (!$tagger_profile->canTag($tagged_profile)) { + // TRANS: Client exception thrown trying to set a tag for a user that cannot be tagged. + throw new ClientException(_('You cannot tag this user.')); + return false; + } + + $tags = new Profile_list(); + $tags->tagger = $tagger; + $count = (int) $tags->count('distinct tag'); + + if ($count >= common_config('peopletag', 'maxtags')) { + // TRANS: Client exception thrown trying to set more tags than allowed. + throw new ClientException(sprintf(_('You already have created %d or more tags ' . + 'which is the maximum allowed number of tags. ' . + 'Try using or deleting some existing tags.'), + common_config('peopletag', 'maxtags'))); + return false; + } + + $plist = new Profile_list(); + $plist->query('BEGIN'); + + $profile_list = Profile_list::ensureTag($tagger, $tag, $desc, $private); + + if ($profile_list->taggedCount() >= common_config('peopletag', 'maxpeople')) { + // TRANS: Client exception thrown when trying to add more people than allowed to a list. + throw new ClientException(sprintf(_('You already have %1$d or more people in list %2$s, ' . + 'which is the maximum allowed number. ' . + 'Try unlisting others first.'), + common_config('peopletag', 'maxpeople'), $tag)); + return false; + } + + $newtag = new Profile_tag(); + + $newtag->tagger = $tagger; + $newtag->tagged = $tagged; + $newtag->tag = $tag; + + $result = $newtag->insert(); - $profile_tag->query('BEGIN'); - foreach ($to_delete as $deltag) { - $profile_tag->tag = $deltag; - $result = $profile_tag->delete(); if (!$result) { - common_log_db_error($profile_tag, 'DELETE', __FILE__); + common_log_db_error($newtag, 'INSERT', __FILE__); + return false; + } + + try { + $plist->query('COMMIT'); + Event::handle('EndTagProfile', array($newtag)); + } catch (Exception $e) { + $newtag->delete(); + $profile_list->delete(); + throw $e; return false; } + + $profile_list->taggedCount(true); + self::blowCaches($tagger, $tagged); } - foreach ($to_insert as $instag) { - $profile_tag->tag = $instag; - $result = $profile_tag->insert(); + return $newtag; + } + + static function unTag($tagger, $tagged, $tag) { + $ptag = Profile_tag::pkeyGet(array('tagger' => $tagger, + 'tagged' => $tagged, + 'tag' => $tag)); + if (!$ptag) { + return true; + } + + if (Event::handle('StartUntagProfile', array($ptag))) { + $orig = clone($ptag); + $result = $ptag->delete(); if (!$result) { - common_log_db_error($profile_tag, 'INSERT', __FILE__); + common_log_db_error($this, 'DELETE', __FILE__); return false; } + Event::handle('EndUntagProfile', array($orig)); + if ($result) { + $profile_list = Profile_list::pkeyGet(array('tag' => $tag, 'tagger' => $tagger)); + if (!empty($profile_list)) { + $profile_list->taggedCount(true); + } + self::blowCaches($tagger, $tagged); + return true; + } + return false; + } + } + + // @fixme: move this to Profile_list? + static function cleanup($profile_list) { + $ptag = new Profile_tag(); + $ptag->tagger = $profile_list->tagger; + $ptag->tag = $profile_list->tag; + $ptag->find(); + + while($ptag->fetch()) { + if (Event::handle('StartUntagProfile', array($ptag))) { + $orig = clone($ptag); + $result = $ptag->delete(); + if (!$result) { + common_log_db_error($this, 'DELETE', __FILE__); + } + Event::handle('EndUntagProfile', array($orig)); + } } + } + + // move a tag! + static function moveTag($orig, $new) { + $tags = new Profile_tag(); + $qry = 'UPDATE profile_tag SET ' . + 'tag = "%s", tagger = "%s" ' . + 'WHERE tag = "%s" ' . + 'AND tagger = "%s"'; + $result = $tags->query(sprintf($qry, + $tags->escape($new->tag), + $tags->escape($new->tagger), + $tags->escape($orig->tag), + $tags->escape($orig->tagger))); - $profile_tag->query('COMMIT'); + if ($result === false) { + common_log_db_error($tags, 'UPDATE', __FILE__); + throw new Exception('Could not move Profile_tag, see db log for details.'); + } + return $result; + } + static function blowCaches($tagger, $tagged) { + foreach (array(0, 1) as $perm) { + self::blow(sprintf('profile_tag:tagger_tagged_privacy:%d-%d-%d', $tagger, $tagged, $perm)); + } return true; } @@ -90,12 +302,34 @@ class Profile_tag extends Memcached_DataObject $profile->query('SELECT profile.* ' . 'FROM profile JOIN profile_tag ' . 'ON profile.id = profile_tag.tagged ' . - 'WHERE profile_tag.tagger = ' . $tagger . ' ' . - 'AND profile_tag.tag = "' . $tag . '" '); + 'WHERE profile_tag.tagger = ' . $profile->escape($tagger) . ' ' . + 'AND profile_tag.tag = "' . $profile->escape($tag) . '" '); $tagged = array(); while ($profile->fetch()) { $tagged[] = clone($profile); } - return $tagged; + return true; + } + + function insert() + { + $result = parent::insert(); + if ($result) { + self::blow('profile_list:tagged_count:%d:%s', + $this->tagger, + $this->tag); + } + return $result; + } + + function delete($useWhere=false) + { + $result = parent::delete($useWhere); + if ($result !== false) { + self::blow('profile_list:tagged_count:%d:%s', + $this->tagger, + $this->tag); + } + return $result; } }