123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951 |
- <?php
- defined('GNUSOCIAL') || die();
- class Profile_list extends Managed_DataObject
- {
- public $__table = 'profile_list';
- public $id;
- public $tagger;
- public $tag;
- public $description;
- public $private;
- public $created;
- public $modified;
- public $uri;
- public $mainpage;
- public $tagged_count;
- public $subscriber_count;
- public static function schemaDef()
- {
- return array(
- 'fields' => array(
- 'id' => array('type' => 'serial', 'not null' => true, 'description' => 'unique identifier'),
- 'tagger' => array('type' => 'int', 'not null' => true, 'description' => 'user making the tag'),
- 'tag' => array('type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'people tag'),
- 'description' => array('type' => 'text', 'description' => 'description of the people tag'),
- 'private' => array('type' => 'bool', 'default' => false, 'description' => 'is this tag private'),
- 'created' => array('type' => 'datetime', 'description' => 'date the tag was added'),
- 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date the tag was modified'),
- 'uri' => array('type' => 'varchar', 'length' => 191, 'description' => 'universal identifier'),
- 'mainpage' => array('type' => 'varchar', 'length' => 191, 'description' => 'page to link to'),
- 'tagged_count' => array('type' => 'int', 'default' => 0, 'description' => 'number of people tagged with this tag by this user'),
- 'subscriber_count' => array('type' => 'int', 'default' => 0, 'description' => 'number of subscribers to this tag'),
- ),
- 'primary key' => array('tagger', 'tag'),
- 'unique keys' => array(
- 'profile_list_id_key' => array('id'),
- ),
- 'foreign keys' => array(
- 'profile_list_tagger_fkey' => array('profile', array('tagger' => 'id')),
- ),
- 'indexes' => array(
- 'profile_list_modified_idx' => array('modified'),
- 'profile_list_tag_idx' => array('tag'),
- 'profile_list_tagger_tag_idx' => array('tagger', 'tag'),
- 'profile_list_tagged_count_idx' => array('tagged_count'),
- 'profile_list_subscriber_count_idx' => array('subscriber_count'),
- ),
- );
- }
-
- public function getTagger()
- {
- return Profile::getByID($this->tagger);
- }
-
- public function getBestName()
- {
- return $this->tag;
- }
-
- public function getUri()
- {
- $uri = null;
- if (Event::handle('StartProfiletagGetUri', array($this, &$uri))) {
- if (!empty($this->uri)) {
- $uri = $this->uri;
- } else {
- $uri = common_local_url(
- 'profiletagbyid',
- ['id' => $this->id, 'tagger_id' => $this->tagger]
- );
- }
- }
- Event::handle('EndProfiletagGetUri', array($this, &$uri));
- return $uri;
- }
-
- public function homeUrl()
- {
- $url = null;
- if (Event::handle('StartUserPeopletagHomeUrl', array($this, &$url))) {
-
- if (!empty($this->mainpage)) {
- $url = $this->mainpage;
- } else {
- $url = common_local_url(
- 'showprofiletag',
- [
- 'nickname' => $this->getTagger()->nickname,
- 'tag' => $this->tag,
- ]
- );
- }
- }
- Event::handle('EndUserPeopletagHomeUrl', array($this, &$url));
- return $url;
- }
-
- public function permalink()
- {
- $url = null;
- if (Event::handle('StartProfiletagPermalink', array($this, &$url))) {
- $url = common_local_url(
- 'profiletagbyid',
- ['id' => $this->id]
- );
- }
- Event::handle('EndProfiletagPermalink', array($this, &$url));
- return $url;
- }
-
- public function getNotices($offset, $limit, $since_id = null, $max_id = null)
- {
-
-
- $stream = new PeopletagNoticeStream($this, Profile::current());
- return $stream->getNotices($offset, $limit, $since_id, $max_id);
- }
-
- public function getSubscribers(int $offset = 0, ?int $limit = null, int $since = 0, int $upto = 0)
- {
- $subs = new Profile();
- $subs->joinAdd(
- array('id', 'profile_tag_subscription:profile_id')
- );
- $subs->whereAdd('profile_tag_subscription.profile_tag_id = ' . $this->id);
- if (common_config('db', 'type') !== 'mysql') {
- $subs->selectAdd(sprintf(
- '((EXTRACT(DAY %1$s) * 24 + EXTRACT(HOUR %1$s)) * 60 + ' .
- 'EXTRACT(MINUTE %1$s)) * 60 + FLOOR(EXTRACT(SECOND %1$s)) AS "cursor"',
- "FROM (profile_tag_subscription.created - TIMESTAMP '1970-01-01 00:00:00')"
- ));
- } else {
- $subs->selectAdd("timestampdiff(SECOND, '1970-01-01', profile_tag_subscription.created) AS `cursor`");
- }
- if ($since != 0) {
- $subs->whereAdd('cursor > ' . $since);
- }
- if ($upto != 0) {
- $subs->whereAdd('cursor <= ' . $upto);
- }
- if ($limit != null) {
- $subs->limit($offset, $limit);
- }
- $subs->orderBy('profile_tag_subscription.created DESC');
- $subs->find();
- return $subs;
- }
-
- public function getUserSubscribers()
- {
-
- $user = new User();
- $user->query(sprintf(
- 'SELECT id ' .
- 'FROM %1$s INNER JOIN profile_tag_subscription ' .
- 'ON %1$s.id = profile_tag_subscription.profile_id ' .
- 'WHERE profile_tag_subscription.profile_tag_id = %2$d ',
- $user->escapedTableName(),
- $this->id
- ));
- $ids = [];
- while ($user->fetch()) {
- $ids[] = $user->id;
- }
- $user->free();
- return $ids;
- }
-
- public function hasSubscriber($id)
- {
- if (!is_numeric($id)) {
- $id = $id->id;
- }
- $sub = Profile_tag_subscription::pkeyGet(array('profile_tag_id' => $this->id,
- 'profile_id' => $id));
- return !empty($sub);
- }
-
- public function getTagged(int $offset = 0, ?int $limit = null, int $since = 0, int $upto = 0)
- {
- $tagged = new Profile();
- $tagged->joinAdd(['id', 'profile_tag:tagged']);
- if (common_config('db', 'type') !== 'mysql') {
- $tagged->selectAdd(sprintf(
- '((EXTRACT(DAY %1$s) * 24 + EXTRACT(HOUR %1$s)) * 60 + ' .
- 'EXTRACT(MINUTE %1$s)) * 60 + FLOOR(EXTRACT(SECOND %1$s)) AS "cursor"',
- "FROM (profile_tag.modified - TIMESTAMP '1970-01-01 00:00:00')"
- ));
- } else {
- $tagged->selectAdd("timestampdiff(SECOND, '1970-01-01', profile_tag.modified) AS `cursor`");
- }
- $tagged->whereAdd('profile_tag.tagger = '.$this->tagger);
- $tagged->whereAdd("profile_tag.tag = '{$this->tag}'");
- if ($since != 0) {
- $tagged->whereAdd('cursor > ' . $since);
- }
- if ($upto != 0) {
- $tagged->whereAdd('cursor <= ' . $upto);
- }
- if ($limit != null) {
- $tagged->limit($offset, $limit);
- }
- $tagged->orderBy('profile_tag.modified DESC');
- $tagged->find();
- return $tagged;
- }
-
- public function delete($useWhere = false)
- {
-
- if (empty($this->id)) {
- $this->find();
- while ($this->fetch()) {
- $this->delete();
- }
- }
- Profile_tag::cleanup($this);
- Profile_tag_subscription::cleanup($this);
- self::blow('profile:lists:%d', $this->tagger);
- return parent::delete($useWhere);
- }
-
- public function update($dataObject = false)
- {
- if (!is_object($dataObject) && !$dataObject instanceof Profile_list) {
- return parent::update($dataObject);
- }
- $result = true;
-
-
-
- if ($dataObject->tag != $this->tag || $dataObject->tagger != $this->tagger) {
- $existing = Profile_list::getByTaggerAndTag($this->tagger, $this->tag);
- if (!empty($existing)) {
-
- throw new ServerException(_('The tag you are trying to rename ' .
- 'to already exists.'));
- }
-
-
- $result = Profile_tag::moveTag($dataObject, $this);
- }
- return parent::update($dataObject);
- }
-
- public function asAtomAuthor()
- {
- $xs = new XMLStringer(true);
- $tagger = $this->getTagger();
- $xs->elementStart('author');
- $xs->element('name', null, '@' . $tagger->nickname . '/' . $this->tag);
- $xs->element('uri', null, $this->permalink());
- $xs->elementEnd('author');
- return $xs->getString();
- }
-
- public function asActivityNoun($element)
- {
- $noun = ActivityObject::fromPeopletag($this);
- return $noun->asString('activity:' . $element);
- }
-
- public function taggedCount($recount = false)
- {
- $keypart = sprintf(
- 'profile_list:tagged_count:%d:%s',
- $this->tagger,
- $this->tag
- );
- $count = self::cacheGet($keypart);
- if ($count === false) {
- $tags = new Profile_tag();
- $tags->tag = $this->tag;
- $tags->tagger = $this->tagger;
- $count = $tags->count('distinct tagged');
- self::cacheSet($keypart, $count);
- }
- return $count;
- }
-
- public function subscriberCount($recount = false)
- {
- $keypart = sprintf(
- 'profile_list:subscriber_count:%d',
- $this->id
- );
- $count = self::cacheGet($keypart);
- if ($count === false) {
- $sub = new Profile_tag_subscription();
- $sub->profile_tag_id = $this->id;
- $count = (int) $sub->count('distinct profile_id');
- self::cacheSet($keypart, $count);
- }
- return $count;
- }
-
- public function blowNoticeStreamCache($all = false)
- {
- self::blow('profile_list:notice_ids:%d', $this->id);
- if ($all) {
- self::blow('profile_list:notice_ids:%d;last', $this->id);
- }
- }
-
- public static function getByTaggerAndTag($tagger, $tag)
- {
- $ptag = Profile_list::pkeyGet(array('tagger' => $tagger, 'tag' => $tag));
- return $ptag;
- }
-
- public static function ensureTag($tagger, $tag, $description = null, $private = false)
- {
- $ptag = Profile_list::getByTaggerAndTag($tagger, $tag);
- if (empty($ptag->id)) {
- $args = array(
- 'tag' => $tag,
- 'tagger' => $tagger,
- 'description' => $description,
- 'private' => $private
- );
- $new_tag = Profile_list::saveNew($args);
- return $new_tag;
- }
- return $ptag;
- }
-
- public static function maxDescription()
- {
- $desclimit = common_config('peopletag', 'desclimit');
-
- if (is_null($desclimit)) {
- $desclimit = common_config('site', 'textlimit');
- }
- return $desclimit;
- }
-
- public static function descriptionTooLong($desc)
- {
- $desclimit = self::maxDescription();
- return ($desclimit > 0 && !empty($desc) && (mb_strlen($desc) > $desclimit));
- }
-
- public static function saveNew(array $fields)
- {
- extract($fields);
- $ptag = new Profile_list();
- $ptag->query('START TRANSACTION');
- if (empty($tagger)) {
-
- throw new Exception(_('No tagger specified.'));
- }
- if (empty($tag)) {
-
- throw new Exception(_('No tag specified.'));
- }
- if (empty($mainpage)) {
- $mainpage = null;
- }
- if (empty($uri)) {
-
- $uri = null;
- }
- if (empty($mainpage)) {
- $mainpage = null;
- }
- if (empty($description)) {
- $description = null;
- }
- if (empty($private)) {
- $private = false;
- }
- $ptag->tagger = $tagger;
- $ptag->tag = $tag;
- $ptag->description = $description;
- $ptag->private = $private;
- $ptag->uri = $uri;
- $ptag->mainpage = $mainpage;
- $ptag->created = common_sql_now();
- $ptag->modified = common_sql_now();
- $result = $ptag->insert();
- if (!$result) {
- common_log_db_error($ptag, 'INSERT', __FILE__);
-
- throw new ServerException(_('Could not create profile tag.'));
- }
- if (!isset($uri) || empty($uri)) {
- $orig = clone($ptag);
- $ptag->uri = common_local_url('profiletagbyid', array('id' => $ptag->id, 'tagger_id' => $ptag->tagger));
- $result = $ptag->update($orig);
- if (!$result) {
- common_log_db_error($ptag, 'UPDATE', __FILE__);
-
- throw new ServerException(_('Could not set profile tag URI.'));
- }
- }
- if (!isset($mainpage) || empty($mainpage)) {
- $orig = clone($ptag);
- $user = User::getKV('id', $ptag->tagger);
- if (!empty($user)) {
- $ptag->mainpage = common_local_url('showprofiletag', array('tag' => $ptag->tag, 'nickname' => $user->getNickname()));
- } else {
- $ptag->mainpage = $uri;
- }
- $result = $ptag->update($orig);
- if (!$result) {
- common_log_db_error($ptag, 'UPDATE', __FILE__);
-
- throw new ServerException(_('Could not set profile tag mainpage.'));
- }
- }
- return $ptag;
- }
-
-
- public static function getAtCursor($fn, array $args, $cursor, $count = 20)
- {
- $items = array();
- $since_id = 0;
- $max_id = 0;
- $next_cursor = 0;
- $prev_cursor = 0;
- if ($cursor > 0) {
-
- $max_id = $cursor;
- $fn_args = array_merge($args, array(0, $count+2, 0, $max_id));
- $list = call_user_func_array($fn, $fn_args);
- while ($list->fetch()) {
- $items[] = clone($list);
- }
- if ((isset($items[0]->cursor) && $items[0]->cursor == $cursor) ||
- $items[0]->id == $cursor) {
- array_shift($items);
- $prev_cursor = isset($items[0]->cursor) ?
- -$items[0]->cursor : -$items[0]->id;
- } else {
- if (count($items) > $count+1) {
- array_shift($items);
- }
-
- $fn_args = array_merge($args, array(0, 1, $cursor));
- $more = call_user_func($fn, $fn_args);
- if (!$more->fetch() || empty($more)) {
-
- $prev_cursor = 0;
- } else {
- $prev_cursor = isset($items[0]->cursor) ?
- -$items[0]->cursor : -$items[0]->id;
- }
- }
- if (count($items)==$count+1) {
-
- $next = array_pop($items);
- $next_cursor = isset($next->cursor) ?
- $items[$count-1]->cursor : $items[$count-1]->id;
- }
- } elseif ($cursor < -1) {
-
- $cursor = abs($cursor);
- $since_id = $cursor-1;
- $fn_args = array_merge($args, array(0, $count+2, $since_id));
- $list = call_user_func_array($fn, $fn_args);
- while ($list->fetch()) {
- $items[] = clone($list);
- }
- $end = count($items)-1;
- if ((isset($items[$end]->cursor) && $items[$end]->cursor == $cursor) ||
- $items[$end]->id == $cursor) {
- array_pop($items);
- $next_cursor = isset($items[$end-1]->cursor) ?
- $items[$end-1]->cursor : $items[$end-1]->id;
- } else {
- $next_cursor = isset($items[$end]->cursor) ?
- $items[$end]->cursor : $items[$end]->id;
- if ($end > $count) {
-
- array_pop($items);
- }
-
- $fn_args = array_merge($args, array(0, 1, 0, $cursor));
- $more = call_user_func_array($fn, $fn_args);
- if (!$more->fetch() || empty($more)) {
- $next_cursor = 0;
- }
- }
- if (count($items) == $count+1) {
-
- $prev = array_shift($items);
- $prev_cursor = isset($prev->cursor) ?
- -$items[0]->cursor : -$items[0]->id;
- }
- } elseif ($cursor == -1) {
- $fn_args = array_merge($args, array(0, $count+1));
- $list = call_user_func_array($fn, $fn_args);
- while ($list->fetch()) {
- $items[] = clone($list);
- }
- if (count($items)==$count+1) {
- $next = array_pop($items);
- if (isset($next->cursor)) {
- $next_cursor = $items[$count-1]->cursor;
- } else {
- $next_cursor = $items[$count-1]->id;
- }
- }
- }
- return array($items, $next_cursor, $prev_cursor);
- }
-
- public static function setCache($ckey, &$tag, $offset = 0, $limit = null)
- {
- $cache = Cache::instance();
- if (empty($cache)) {
- return false;
- }
- $str = '';
- $tags = array();
- while ($tag->fetch()) {
- $str .= $tag->tagger . ':' . $tag->tag . ';';
- $tags[] = clone($tag);
- }
- $str = substr($str, 0, -1);
- if ($offset>=0 && !is_null($limit)) {
- $tags = array_slice($tags, $offset, $limit);
- }
- $tag = new ArrayWrapper($tags);
- return self::cacheSet($ckey, $str);
- }
-
- public static function getCached($ckey, $offset = 0, $limit = null)
- {
- $keys_str = self::cacheGet($ckey);
- if ($keys_str === false) {
- return false;
- }
- $pairs = explode(';', $keys_str);
- $keys = array();
- foreach ($pairs as $pair) {
- $keys[] = explode(':', $pair);
- }
- if ($offset>=0 && !is_null($limit)) {
- $keys = array_slice($keys, $offset, $limit);
- }
- return self::getByKeys($keys);
- }
-
- public static function getByKeys(array $keys)
- {
- $cache = Cache::instance();
- if (!empty($cache)) {
- $tags = array();
- foreach ($keys as $key) {
- $t = Profile_list::getByTaggerAndTag($key[0], $key[1]);
- if (!empty($t)) {
- $tags[] = $t;
- }
- }
- return new ArrayWrapper($tags);
- } else {
- $tag = new Profile_list();
- if (empty($keys)) {
-
- return $tag;
- }
- $pairs = array();
- foreach ($keys as $key) {
- $pairs[] = '(' . $key[0] . ', "' . $key[1] . '")';
- }
- $tag->whereAdd('(tagger, tag) in (' . implode(', ', $pairs) . ')');
- $tag->find();
- $temp = array();
- while ($tag->fetch()) {
- $temp[$tag->tagger.'-'.$tag->tag] = clone($tag);
- }
- $wrapped = array();
- foreach ($keys as $key) {
- $id = $key[0].'-'.$key[1];
- if (array_key_exists($id, $temp)) {
- $wrapped[] = $temp[$id];
- }
- }
- return new ArrayWrapper($wrapped);
- }
- }
- public function insert()
- {
- $result = parent::insert();
- if ($result) {
- self::blow('profile:lists:%d', $this->tagger);
- }
- return $result;
- }
- }
|