function getTags()
 {
     $profile = Profile::current();
     $keypart = sprintf('Inbox:notice_tag:%d:%d', $this->user->id, $profile->id);
     $tag = Memcached_DataObject::cacheGet($keypart);
     if ($tag === false) {
         $stream = new InboxNoticeStream($this->user, $profile);
         $ids = $stream->getNoticeIds(0, Inbox::MAX_NOTICES, null, null);
         if (empty($ids)) {
             $tag = array();
         } else {
             $weightexpr = common_sql_weight('notice_tag.created', common_config('tag', 'dropoff'));
             // @fixme should we use the cutoff too? Doesn't help with indexing per-user.
             $qry = 'SELECT notice_tag.tag, ' . $weightexpr . ' as weight ' . 'FROM notice_tag JOIN notice ' . 'ON notice_tag.notice_id = notice.id ' . 'WHERE notice.id in (' . implode(',', $ids) . ')' . 'GROUP BY notice_tag.tag ' . 'ORDER BY weight DESC ';
             $limit = TAGS_PER_SECTION;
             $offset = 0;
             if (common_config('db', 'type') == 'pgsql') {
                 $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
             } else {
                 $qry .= ' LIMIT ' . $offset . ', ' . $limit;
             }
             $t = new Notice_tag();
             $t->query($qry);
             $tag = array();
             while ($t->fetch()) {
                 $tag[] = clone $t;
             }
         }
         Memcached_DataObject::cacheSet($keypart, $tag, 3600);
     }
     return new ArrayWrapper($tag);
 }
 function getTags()
 {
     $notice_tag = new Notice_tag();
     $query = 'select tag,count(tag) as weight from notice_tag join file_to_post on (notice_tag.notice_id=post_id) join notice on notice_id = notice.id where file_id=' . $notice_tag->escape($this->out->attachment->id) . ' group by tag order by weight desc';
     $notice_tag->query($query);
     return $notice_tag;
 }
 function getTags($lst, $usr)
 {
     $profile_tag = new Notice_tag();
     $profile_tag->query('SELECT DISTINCT(tag) ' . 'FROM profile_tag, subscription ' . 'WHERE tagger = ' . $this->target->id . ' ' . 'AND ' . $usr . ' = ' . $this->target->id . ' ' . 'AND ' . $lst . ' = tagged ' . 'AND tagger != tagged');
     $tags = array();
     while ($profile_tag->fetch()) {
         $tags[] = $profile_tag->tag;
     }
     $profile_tag->free();
     return $tags;
 }
Example #4
0
function ping_notice_tags($notice)
{
    $tag = new Notice_tag();
    $tag->notice_id = $notice->id;
    $tags = array();
    if ($tag->find()) {
        while ($tag->fetch()) {
            $tags[] = $tag->tag;
        }
        $tag->free();
        unset($tag);
        return implode('|', $tags);
    }
    return NULL;
}
Example #5
0
 function showContent()
 {
     $notice = Notice_tag::getStream($this->tag, ($this->page - 1) * NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
     $nl = new NoticeList($notice, $this);
     $cnt = $nl->show();
     $this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE, $this->page, 'tag', array('tag' => $this->tag));
 }
Example #6
0
 function getNotices($limit = 0)
 {
     $tag = $this->tag;
     if (is_null($tag)) {
         return null;
     }
     $notice = Notice_tag::getStream($tag->tag)->getNotices(0, $limit == 0 ? NOTICES_PER_PAGE : $limit);
     return $notice->fetchAll();
 }
Example #7
0
 function showContent()
 {
     # This should probably be cached rather than recalculated
     $tags = new Notice_tag();
     #Need to clear the selection and then only re-add the field
     #we are grouping by, otherwise it's not a valid 'group by'
     #even though MySQL seems to let it slide...
     $tags->selectAdd();
     $tags->selectAdd('tag');
     #Add the aggregated columns...
     $tags->selectAdd('max(notice_id) as last_notice_id');
     if (common_config('db', 'type') == 'pgsql') {
         $calc = 'sum(exp(-extract(epoch from (now()-created))/%s)) as weight';
     } else {
         $calc = 'sum(exp(-(now() - created)/%s)) as weight';
     }
     $tags->selectAdd(sprintf($calc, common_config('tag', 'dropoff')));
     $tags->groupBy('tag');
     $tags->orderBy('weight DESC');
     $tags->limit(TAGS_PER_PAGE);
     $cnt = $tags->find();
     if ($cnt > 0) {
         $this->elementStart('div', array('id' => 'tagcloud', 'class' => 'section'));
         $tw = array();
         $sum = 0;
         while ($tags->fetch()) {
             $tw[$tags->tag] = $tags->weight;
             $sum += $tags->weight;
         }
         ksort($tw);
         $this->elementStart('dl');
         $this->element('dt', null, _('Tag cloud'));
         $this->elementStart('dd');
         $this->elementStart('ul', 'tags xoxo tag-cloud');
         foreach ($tw as $tag => $weight) {
             $this->showTag($tag, $weight, $weight / $sum);
         }
         $this->elementEnd('ul');
         $this->elementEnd('dd');
         $this->elementEnd('dl');
         $this->elementEnd('div');
     }
 }
Example #8
0
 function _streamDirect($tag, $offset, $limit, $since_id, $max_id)
 {
     $nt = new Notice_tag();
     $nt->tag = $tag;
     $nt->selectAdd();
     $nt->selectAdd('notice_id');
     Notice::addWhereSinceId($nt, $since_id, 'notice_id');
     Notice::addWhereMaxId($nt, $max_id, 'notice_id');
     $nt->orderBy('created DESC, notice_id DESC');
     if (!is_null($offset)) {
         $nt->limit($offset, $limit);
     }
     $ids = array();
     if ($nt->find()) {
         while ($nt->fetch()) {
             $ids[] = $nt->notice_id;
         }
     }
     return $ids;
 }
Example #9
0
 function getNotices($limit = 0)
 {
     $tag = $this->tag;
     if (is_null($tag)) {
         return null;
     }
     $notice = Notice_tag::getStream($tag->tag, 0, $limit == 0 ? NOTICES_PER_PAGE : $limit);
     while ($notice->fetch()) {
         $notices[] = clone $notice;
     }
     return $notices;
 }
 function showContent()
 {
     # This should probably be cached rather than recalculated
     $tags = new Notice_tag();
     #Need to clear the selection and then only re-add the field
     #we are grouping by, otherwise it's not a valid 'group by'
     #even though MySQL seems to let it slide...
     $tags->selectAdd();
     $tags->selectAdd('tag');
     #Add the aggregated columns...
     $tags->selectAdd('max(notice_id) as last_notice_id');
     $calc = common_sql_weight('created', common_config('tag', 'dropoff'));
     $cutoff = sprintf("notice_tag.created > '%s'", common_sql_date(time() - common_config('tag', 'cutoff')));
     $tags->selectAdd($calc . ' as weight');
     $tags->whereAdd($cutoff);
     $tags->groupBy('tag');
     $tags->orderBy('weight DESC');
     $tags->limit(TAGS_PER_PAGE);
     $cnt = $tags->find();
     if ($cnt > 0) {
         $this->elementStart('div', array('id' => 'tagcloud', 'class' => 'section'));
         $tw = array();
         $sum = 0;
         while ($tags->fetch()) {
             $tw[$tags->tag] = $tags->weight;
             $sum += $tags->weight;
         }
         ksort($tw);
         $this->elementStart('dl');
         $this->element('dt', null, _('Tag cloud'));
         $this->elementStart('dd');
         $this->elementStart('ul', 'tags xoxo tag-cloud');
         foreach ($tw as $tag => $weight) {
             if ($sum) {
                 $weightedSum = $weight / $sum;
             } else {
                 $weightedSum = 0.5;
             }
             $this->showTag($tag, $weight, $weightedSum);
         }
         $this->elementEnd('ul');
         $this->elementEnd('dd');
         $this->elementEnd('dl');
         $this->elementEnd('div');
     } else {
         $this->showEmptyList();
     }
 }
Example #11
0
 function timeline($args, $apidata)
 {
     parent::handle($args);
     common_debug("in tags api action");
     $this->auth_user = $apidata['user'];
     $tag = $apidata['api_arg'];
     if (empty($tag)) {
         $this->clientError('Not Found', 404, $apidata['content-type']);
         return;
     }
     $sitename = common_config('site', 'name');
     $title = sprintf(_("Notices tagged with %s"), $tag);
     $taguribase = common_config('integration', 'taguri');
     $id = "tag:{$taguribase}:TagTimeline:" . $tag;
     $link = common_local_url('tag', array('tag' => $tag));
     $subtitle = sprintf(_('Updates tagged with %1$s on %2$s!'), $tag, $sitename);
     $page = (int) $this->arg('page', 1);
     $count = (int) $this->arg('count', 20);
     $max_id = (int) $this->arg('max_id', 0);
     $since_id = (int) $this->arg('since_id', 0);
     $since = $this->arg('since');
     # XXX: support max_id, since_id, and since arguments
     $notice = Notice_tag::getStream($tag, ($page - 1) * $count, $count + 1);
     switch ($apidata['content-type']) {
         case 'xml':
             $this->show_xml_timeline($notice);
             break;
         case 'rss':
             $this->show_rss_timeline($notice, $title, $link, $subtitle, $suplink);
             break;
         case 'atom':
             if (isset($apidata['api_arg'])) {
                 $selfuri = common_root_url() . 'api/laconica/tags/timeline/' . $apidata['api_arg'] . '.atom';
             } else {
                 $selfuri = common_root_url() . 'api/laconica/tags/timeline.atom';
             }
             $this->show_atom_timeline($notice, $title, $id, $link, $subtitle, $suplink, $selfuri);
             break;
         case 'json':
             $this->show_json_timeline($notice);
             break;
         default:
             $this->clientError(_('API method not found!'), $code = 404);
     }
 }
Example #12
0
 function _streamDirect($tag, $offset, $limit, $since_id, $max_id)
 {
     $nt = new Notice_tag();
     $nt->tag = $tag;
     $nt->selectAdd();
     $nt->selectAdd('notice_id');
     if ($since_id != 0) {
         $nt->whereAdd('notice_id > ' . $since_id);
     }
     if ($max_id != 0) {
         $nt->whereAdd('notice_id < ' . $max_id);
     }
     $nt->orderBy('notice_id DESC');
     if (!is_null($offset)) {
         $nt->limit($offset, $limit);
     }
     $ids = array();
     if ($nt->find()) {
         while ($nt->fetch()) {
             $ids[] = $nt->notice_id;
         }
     }
     return $ids;
 }
Example #13
0
 protected function prepare(array $args = array())
 {
     parent::prepare($args);
     $taginput = $this->trimmed('tag');
     $this->tag = common_canonical_tag($taginput);
     if (empty($this->tag)) {
         common_redirect(common_local_url('publictagcloud'), 301);
     }
     // after common_canonical_tag we have a lowercase, no-specials tag string
     if ($this->tag !== $taginput) {
         common_redirect(common_local_url('tag', array('tag' => $this->tag)), 301);
     }
     $this->page = $this->arg('page') ? $this->arg('page') + 0 : 1;
     common_set_returnto($this->selfUrl());
     $this->notice = Notice_tag::getStream($this->tag)->getNotices(($this->page - 1) * NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
     if ($this->page > 1 && $this->notice->N == 0) {
         // TRANS: Client error when page not found (404).
         $this->clientError(_('No such page.'), 404);
     }
     return true;
 }
Example #14
0
File: tag.php Project: himmelex/NTW
 function prepare($args)
 {
     parent::prepare($args);
     $taginput = $this->trimmed('tag');
     $this->tag = common_canonical_tag($taginput);
     if (!$this->tag) {
         common_redirect(common_local_url('publictagcloud'), 301);
         return false;
     }
     if ($this->tag != $taginput) {
         common_redirect(common_local_url('tag', array('tag' => $this->tag)), 301);
         return false;
     }
     $this->page = $this->arg('page') ? $this->arg('page') + 0 : 1;
     common_set_returnto($this->selfUrl());
     $this->notice = Notice_tag::getStream($this->tag, ($this->page - 1) * NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
     if ($this->page > 1 && $this->notice->N == 0) {
         // TRANS: Server error when page not found (404)
         $this->serverError(_('您访问的网页不存在'), $code = 404);
     }
     return true;
 }
Example #15
0
 public function getTags()
 {
     $tags = array();
     $tag = new Notice_tag();
     $tag->notice_id = $this->id;
     if ($tag->find()) {
         while ($tag->fetch()) {
             $tags[] = $tag->tag;
         }
     }
     $tag->free();
     return $tags;
 }
Example #16
0
 function twitterRssEntryArray($notice)
 {
     $entry = array();
     if (Event::handle('StartRssEntryArray', array($notice, &$entry))) {
         $profile = $notice->getProfile();
         // We trim() to avoid extraneous whitespace in the output
         $entry['content'] = common_xml_safe_str(trim($notice->rendered));
         $entry['title'] = $profile->nickname . ': ' . common_xml_safe_str(trim($notice->content));
         $entry['link'] = common_local_url('shownotice', array('notice' => $notice->id));
         $entry['published'] = common_date_iso8601($notice->created);
         $taguribase = TagURI::base();
         $entry['id'] = "tag:{$taguribase}:{$entry['link']}";
         $entry['updated'] = $entry['published'];
         $entry['author'] = $profile->getBestName();
         // Enclosures
         $attachments = $notice->attachments();
         $enclosures = array();
         foreach ($attachments as $attachment) {
             $enclosure_o = $attachment->getEnclosure();
             if ($enclosure_o) {
                 $enclosure = array();
                 $enclosure['url'] = $enclosure_o->url;
                 $enclosure['mimetype'] = $enclosure_o->mimetype;
                 $enclosure['size'] = $enclosure_o->size;
                 $enclosures[] = $enclosure;
             }
         }
         if (!empty($enclosures)) {
             $entry['enclosures'] = $enclosures;
         }
         // Tags/Categories
         $tag = new Notice_tag();
         $tag->notice_id = $notice->id;
         if ($tag->find()) {
             $entry['tags'] = array();
             while ($tag->fetch()) {
                 $entry['tags'][] = $tag->tag;
             }
         }
         $tag->free();
         // RSS Item specific
         $entry['description'] = $entry['content'];
         $entry['pubDate'] = common_date_rfc2822($notice->created);
         $entry['guid'] = $entry['link'];
         if (isset($notice->lat) && isset($notice->lon)) {
             // This is the format that GeoJSON expects stuff to be in.
             // showGeoRSS() below uses it for XML output, so we reuse it
             $entry['geo'] = array('type' => 'Point', 'coordinates' => array((double) $notice->lat, (double) $notice->lon));
         } else {
             $entry['geo'] = null;
         }
         Event::handle('EndRssEntryArray', array($notice, &$entry));
     }
     return $entry;
 }
Example #17
0
 /**
  * Save a new notice bookmark
  *
  * @param Profile $profile     To save the bookmark for
  * @param string  $title       Title of the bookmark
  * @param string  $url         URL of the bookmark
  * @param array   $rawtags     array of tags
  * @param string  $description Description of the bookmark
  * @param array   $options     Options for the Notice::saveNew()
  *
  * @return Notice saved notice
  */
 static function addNew(Profile $actor, $title, $url, array $rawtags, $description, array $options = array())
 {
     $act = new Activity();
     $act->verb = ActivityVerb::POST;
     $act->time = time();
     $act->actor = $actor->asActivityObject();
     $actobj = new ActivityObject();
     $actobj->type = ActivityObject::BOOKMARK;
     $actobj->title = $title;
     $actobj->summary = $description;
     $actobj->extra[] = array('link', array('rel' => 'related', 'href' => $url), null);
     $act->objects[] = $actobj;
     $act->enclosures[] = $url;
     $tags = array();
     $replies = array();
     // filter "for:nickname" tags
     foreach ($rawtags as $tag) {
         if (strtolower(mb_substr($tag, 0, 4)) == 'for:') {
             // skip if done by caller
             if (!array_key_exists('replies', $options)) {
                 $nickname = mb_substr($tag, 4);
                 $other = common_relative_profile($actor, $nickname);
                 if (!empty($other)) {
                     $replies[] = $other->getUri();
                 }
             }
         } else {
             $tags[] = common_canonical_tag($tag);
         }
     }
     $hashtags = array();
     $taglinks = array();
     foreach ($tags as $tag) {
         $hashtags[] = '#' . $tag;
         $attrs = array('href' => Notice_tag::url($tag), 'rel' => $tag, 'class' => 'tag');
         $taglinks[] = XMLStringer::estring('a', $attrs, $tag);
     }
     // Use user's preferences for short URLs, if possible
     // FIXME: Should be possible to with the Profile object...
     try {
         $user = $actor->getUser();
         $shortUrl = File_redirection::makeShort($url, empty($user) ? null : $user);
     } catch (Exception $e) {
         // Don't let this stop us.
         $shortUrl = $url;
     }
     // TRANS: Rendered bookmark content.
     // TRANS: %1$s is a URL, %2$s the bookmark title, %3$s is the bookmark description,
     // TRANS: %4$s is space separated list of hash tags.
     $actobj->content = sprintf(_m('<span class="xfolkentry">' . '<a class="taggedlink" href="%1$s">%2$s</a> ' . '<span class="description">%3$s</span> ' . '<span class="meta">%4$s</span>' . '</span>'), htmlspecialchars($url), htmlspecialchars($title), htmlspecialchars($description), implode(' ', $taglinks));
     foreach ($tags as $term) {
         $catEl = new AtomCategory();
         $catEl->term = $term;
         $activity->categories[] = $catEl;
     }
     $options = array_merge(array('urls' => array($url), 'rendered' => $rendered, 'tags' => $tags, 'replies' => $replies, 'object_type' => ActivityObject::BOOKMARK), $options);
     return Notice::saveActivity($act, $actor, $options);
 }
Example #18
0
 /**
  * Get the list of hash tags saved with this notice.
  *
  * @return array of strings
  */
 public function getTags()
 {
     $tags = array();
     $keypart = sprintf('notice:tags:%d', $this->id);
     $tagstr = self::cacheGet($keypart);
     if ($tagstr !== false) {
         $tags = explode(',', $tagstr);
     } else {
         $tag = new Notice_tag();
         $tag->notice_id = $this->id;
         if ($tag->find()) {
             while ($tag->fetch()) {
                 $tags[] = $tag->tag;
             }
         }
         self::cacheSet($keypart, implode(',', $tags));
     }
     return $tags;
 }
 protected function showNoticeContent(Notice $stored, HTMLOutputter $out, Profile $scoped = null)
 {
     $nb = Bookmark::fromStored($stored);
     // Whether to nofollow
     $attrs = array('href' => $nb->getUrl(), 'class' => 'bookmark-title');
     $nf = common_config('nofollow', 'external');
     if ($nf == 'never' || ($nf == 'sometimes' and $out instanceof ShowstreamAction)) {
         $attrs['rel'] = 'external';
     } else {
         $attrs['rel'] = 'nofollow external';
     }
     $out->elementStart('h3');
     $out->element('a', $attrs, $nb->getTitle());
     $out->elementEnd('h3');
     // Replies look like "for:" tags
     $replies = $stored->getReplies();
     $tags = $stored->getTags();
     if (!empty($nb->description)) {
         $out->element('p', array('class' => 'bookmark-description'), $nb->description);
     }
     if (!empty($replies) || !empty($tags)) {
         $out->elementStart('ul', array('class' => 'bookmark-tags'));
         foreach ($replies as $reply) {
             $other = Profile::getByPK($reply);
             $out->elementStart('li');
             $out->element('a', array('rel' => 'tag', 'href' => $other->getUrl(), 'title' => $other->getBestName()), sprintf('for:%s', $other->getNickname()));
             $out->elementEnd('li');
             $out->text(' ');
         }
         foreach ($tags as $tag) {
             $tag = trim($tag);
             if (!empty($tag)) {
                 $out->elementStart('li');
                 $out->element('a', array('rel' => 'tag', 'href' => Notice_tag::url($tag)), $tag);
                 $out->elementEnd('li');
                 $out->text(' ');
             }
         }
         $out->elementEnd('ul');
     }
 }
 /**
  * Get notices
  *
  * @return array notices
  */
 function getNotices()
 {
     $notice = Notice_tag::getStream($this->tag)->getNotices(($this->page - 1) * $this->count, $this->count + 1, $this->since_id, $this->max_id);
     return $notice->fetchAll();
 }
 function getNoticeTags($notice)
 {
     $tags = null;
     $nt = new Notice_tag();
     $nt->notice_id = $notice->id;
     if ($nt->find()) {
         $tags = array();
         while ($nt->fetch()) {
             $tags[] = $nt->tag;
         }
     }
     $nt->free();
     $nt = null;
     return $tags;
 }
Example #22
0
 protected function getNotices()
 {
     $stream = Notice_tag::getStream($this->tag->tag)->getNotices(0, $this->limit);
     return $stream->fetchAll();
 }
 function showContent()
 {
     $notice = $this->nli->notice;
     $out = $this->nli->out;
     $out->elementStart('p', array('class' => 'entry-content'));
     $nb = Bookmark::getByNotice($notice);
     $profile = $notice->getProfile();
     $atts = $notice->attachments();
     if (count($atts) < 1) {
         // Something wrong; let default code deal with it.
         // TRANS: Exception thrown when a bookmark has no attachments.
         // TRANS: %1$s is a bookmark ID, %2$s is a notice ID (number).
         throw new Exception(sprintf(_m('Bookmark %1$s (notice %2$d) has no attachments.'), $nb->id, $notice->id));
     }
     $att = $atts[0];
     $out->elementStart('h3');
     $out->element('a', array('href' => $att->url, 'class' => 'bookmark-title'), $nb->title);
     $out->elementEnd('h3');
     // Replies look like "for:" tags
     $replies = $notice->getReplies();
     $tags = $notice->getTags();
     if (!empty($replies) || !empty($tags)) {
         $out->elementStart('ul', array('class' => 'bookmark-tags'));
         foreach ($replies as $reply) {
             $other = Profile::staticGet('id', $reply);
             if (!empty($other)) {
                 $out->elementStart('li');
                 $out->element('a', array('rel' => 'tag', 'href' => $other->profileurl, 'title' => $other->getBestName()), sprintf('for:%s', $other->nickname));
                 $out->elementEnd('li');
                 $out->text(' ');
             }
         }
         foreach ($tags as $tag) {
             $tag = trim($tag);
             if (!empty($tag)) {
                 $out->elementStart('li');
                 $out->element('a', array('rel' => 'tag', 'href' => Notice_tag::url($tag)), $tag);
                 $out->elementEnd('li');
                 $out->text(' ');
             }
         }
         $out->elementEnd('ul');
     }
     if (!empty($nb->description)) {
         $out->element('p', array('class' => 'bookmark-description'), $nb->description);
     }
     $out->elementEnd('p');
 }
Example #24
0
 /**
  * Get notices
  *
  * @return array notices
  */
 function getNotices()
 {
     $notices = array();
     $notice = Notice_tag::getStream($this->tag, ($this->page - 1) * $this->count, $this->count + 1);
     while ($notice->fetch()) {
         $notices[] = clone $notice;
     }
     return $notices;
 }
Example #25
0
 /**
  * Output the HTML for a bookmark in a list
  *
  * @param NoticeListItem $nli The list item being shown.
  *
  * @return boolean hook value
  */
 function onStartShowNoticeItem($nli)
 {
     $nb = Bookmark::getByNotice($nli->notice);
     if (!empty($nb)) {
         $out = $nli->out;
         $notice = $nli->notice;
         $profile = $nli->profile;
         $atts = $notice->attachments();
         if (count($atts) < 1) {
             // Something wrong; let default code deal with it.
             return true;
         }
         $att = $atts[0];
         // XXX: only show the bookmark URL for non-single-page stuff
         if ($out instanceof ShowbookmarkAction) {
         } else {
             $out->elementStart('h3');
             $out->element('a', array('href' => $att->url, 'class' => 'bookmark-title entry-title'), $nb->title);
             $out->elementEnd('h3');
             $countUrl = common_local_url('noticebyurl', array('id' => $att->id));
             $out->element('a', array('class' => 'bookmark-notice-count', 'href' => $countUrl), $att->noticeCount());
         }
         // Replies look like "for:" tags
         $replies = $nli->notice->getReplies();
         $tags = $nli->notice->getTags();
         if (!empty($replies) || !empty($tags)) {
             $out->elementStart('ul', array('class' => 'bookmark-tags'));
             foreach ($replies as $reply) {
                 $other = Profile::staticGet('id', $reply);
                 $out->elementStart('li');
                 $out->element('a', array('rel' => 'tag', 'href' => $other->profileurl, 'title' => $other->getBestName()), sprintf('for:%s', $other->nickname));
                 $out->elementEnd('li');
                 $out->text(' ');
             }
             foreach ($tags as $tag) {
                 $out->elementStart('li');
                 $out->element('a', array('rel' => 'tag', 'href' => Notice_tag::url($tag)), $tag);
                 $out->elementEnd('li');
                 $out->text(' ');
             }
             $out->elementEnd('ul');
         }
         if (!empty($nb->description)) {
             $out->element('p', array('class' => 'bookmark-description'), $nb->description);
         }
         if (common_config('attachments', 'show_thumbs')) {
             $haveThumbs = false;
             foreach ($atts as $check) {
                 $thumbnail = File_thumbnail::staticGet('file_id', $check->id);
                 if (!empty($thumbnail)) {
                     $haveThumbs = true;
                     break;
                 }
             }
             if ($haveThumbs) {
                 $al = new InlineAttachmentList($notice, $out);
                 $al->show();
             }
         }
         $out->elementStart('div', array('class' => 'bookmark-info entry-content'));
         $avatar = $profile->getAvatar(AVATAR_MINI_SIZE);
         $out->element('img', array('src' => $avatar ? $avatar->displayUrl() : Avatar::defaultImage(AVATAR_MINI_SIZE), 'class' => 'avatar photo bookmark-avatar', 'width' => AVATAR_MINI_SIZE, 'height' => AVATAR_MINI_SIZE, 'alt' => $profile->getBestName()));
         $out->raw('&nbsp;');
         $out->element('a', array('href' => $profile->profileurl, 'title' => $profile->getBestName()), $profile->nickname);
         $nli->showNoticeLink();
         $nli->showNoticeSource();
         $nli->showNoticeLocation();
         $nli->showContext();
         $nli->showRepeat();
         $out->elementEnd('div');
         $nli->showNoticeOptions();
         return false;
     }
     return true;
 }
 function showItem($notice)
 {
     $profile = Profile::staticGet($notice->profile_id);
     $nurl = common_local_url('shownotice', array('notice' => $notice->id));
     $creator_uri = common_profile_uri($profile);
     $this->elementStart('item', array('rdf:about' => $notice->uri, 'rdf:type' => 'http://rdfs.org/sioc/types#MicroblogPost'));
     $title = $profile->nickname . ': ' . common_xml_safe_str(trim($notice->content));
     $this->element('title', null, $title);
     $this->element('link', null, $nurl);
     $this->element('description', null, $profile->nickname . "'s status on " . common_exact_date($notice->created));
     if ($notice->rendered) {
         $this->element('content:encoded', null, common_xml_safe_str($notice->rendered));
     }
     $this->element('dc:date', null, common_date_w3dtf($notice->created));
     $this->element('dc:creator', null, $profile->fullname ? $profile->fullname : $profile->nickname);
     $this->element('foaf:maker', array('rdf:resource' => $creator_uri));
     $this->element('sioc:has_creator', array('rdf:resource' => $creator_uri . '#acct'));
     $location = $notice->getLocation();
     if ($location && isset($location->lat) && isset($location->lon)) {
         $location_uri = $location->getRdfURL();
         $attrs = array('geo:lat' => $location->lat, 'geo:long' => $location->lon);
         if (strlen($location_uri)) {
             $attrs['rdf:resource'] = $location_uri;
         }
         $this->element('statusnet:origin', $attrs);
     }
     $this->element('statusnet:postIcon', array('rdf:resource' => $profile->avatarUrl()));
     $this->element('cc:licence', array('rdf:resource' => common_config('license', 'url')));
     if ($notice->reply_to) {
         $replyurl = common_local_url('shownotice', array('notice' => $notice->reply_to));
         $this->element('sioc:reply_of', array('rdf:resource' => $replyurl));
     }
     if (!empty($notice->conversation)) {
         $conversationurl = common_local_url('conversation', array('id' => $notice->conversation));
         $this->element('sioc:has_discussion', array('rdf:resource' => $conversationurl));
     }
     $attachments = $notice->attachments();
     if ($attachments) {
         foreach ($attachments as $attachment) {
             $enclosure = $attachment->getEnclosure();
             if ($enclosure) {
                 $attribs = array('rdf:resource' => $enclosure->url);
                 if ($enclosure->title) {
                     $attribs['dc:title'] = $enclosure->title;
                 }
                 if ($enclosure->modified) {
                     $attribs['dc:date'] = common_date_w3dtf($enclosure->modified);
                 }
                 if ($enclosure->size) {
                     $attribs['enc:length'] = $enclosure->size;
                 }
                 if ($enclosure->mimetype) {
                     $attribs['enc:type'] = $enclosure->mimetype;
                 }
                 $this->element('enc:enclosure', $attribs);
             }
             $this->element('sioc:links_to', array('rdf:resource' => $attachment->url));
         }
     }
     $tag = new Notice_tag();
     $tag->notice_id = $notice->id;
     if ($tag->find()) {
         $entry['tags'] = array();
         while ($tag->fetch()) {
             $tagpage = common_local_url('tag', array('tag' => $tag->tag));
             if (in_array($tag, $this->tags_already_output)) {
                 $this->element('ctag:tagged', array('rdf:resource' => $tagpage . '#concept'));
                 continue;
             }
             $tagrss = common_local_url('tagrss', array('tag' => $tag->tag));
             $this->elementStart('ctag:tagged');
             $this->elementStart('ctag:Tag', array('rdf:about' => $tagpage . '#concept', 'ctag:label' => $tag->tag));
             $this->element('foaf:page', array('rdf:resource' => $tagpage));
             $this->element('rdfs:seeAlso', array('rdf:resource' => $tagrss));
             $this->elementEnd('ctag:Tag');
             $this->elementEnd('ctag:tagged');
             $this->tags_already_output[] = $tag->tag;
         }
     }
     $this->elementEnd('item');
     $this->creators[$creator_uri] = $profile;
 }
Example #27
0
 function clearTags()
 {
     $tag = new Notice_tag();
     $tag->notice_id = $this->id;
     if ($tag->find()) {
         while ($tag->fetch()) {
             self::blow('profile:notice_ids_tagged:%d:%s', $this->profile_id, common_keyize($tag->tag));
             self::blow('profile:notice_ids_tagged:%d:%s;last', $this->profile_id, common_keyize($tag->tag));
             self::blow('notice_tag:notice_ids:%s', common_keyize($tag->tag));
             self::blow('notice_tag:notice_ids:%s;last', common_keyize($tag->tag));
             $tag->delete();
         }
     }
     $tag->free();
 }
Example #28
0
 protected function showNoticeContent(Notice $stored, HTMLOutputter $out, Profile $scoped = null)
 {
     $nb = Bookmark::getByNotice($stored);
     if (empty($nb)) {
         common_log(LOG_ERR, "No bookmark for notice {$stored->id}");
         parent::showContent();
         return;
     } else {
         if (empty($nb->url)) {
             common_log(LOG_ERR, "No url for bookmark {$nb->id} for notice {$stored->id}");
             parent::showContent();
             return;
         }
     }
     $profile = $stored->getProfile();
     // Whether to nofollow
     $attrs = array('href' => $nb->url, 'class' => 'bookmark-title');
     $nf = common_config('nofollow', 'external');
     if ($nf == 'never' || ($nf == 'sometimes' and $out instanceof ShowstreamAction)) {
         $attrs['rel'] = 'external';
     } else {
         $attrs['rel'] = 'nofollow external';
     }
     $out->elementStart('h3');
     $out->element('a', $attrs, $nb->title);
     $out->elementEnd('h3');
     // Replies look like "for:" tags
     $replies = $stored->getReplies();
     $tags = $stored->getTags();
     if (!empty($nb->description)) {
         $out->element('p', array('class' => 'bookmark-description'), $nb->description);
     }
     if (!empty($replies) || !empty($tags)) {
         $out->elementStart('ul', array('class' => 'bookmark-tags'));
         foreach ($replies as $reply) {
             $other = Profile::getKV('id', $reply);
             if (!empty($other)) {
                 $out->elementStart('li');
                 $out->element('a', array('rel' => 'tag', 'href' => $other->profileurl, 'title' => $other->getBestName()), sprintf('for:%s', $other->nickname));
                 $out->elementEnd('li');
                 $out->text(' ');
             }
         }
         foreach ($tags as $tag) {
             $tag = trim($tag);
             if (!empty($tag)) {
                 $out->elementStart('li');
                 $out->element('a', array('rel' => 'tag', 'href' => Notice_tag::url($tag)), $tag);
                 $out->elementEnd('li');
                 $out->text(' ');
             }
         }
         $out->elementEnd('ul');
     }
 }
Example #29
0
 /**
  * Save a new notice bookmark
  *
  * @param Profile $profile     To save the bookmark for
  * @param string  $title       Title of the bookmark
  * @param string  $url         URL of the bookmark
  * @param mixed   $rawtags     array of tags or string
  * @param string  $description Description of the bookmark
  * @param array   $options     Options for the Notice::saveNew()
  *
  * @return Notice saved notice
  */
 static function saveNew($profile, $title, $url, $rawtags, $description, $options = null)
 {
     if (!common_valid_http_url($url)) {
         throw new ClientException(_m('Only web bookmarks can be posted (HTTP or HTTPS).'));
     }
     $nb = self::getByURL($profile, $url);
     if (!empty($nb)) {
         // TRANS: Client exception thrown when trying to save a new bookmark that already exists.
         throw new ClientException(_m('Bookmark already exists.'));
     }
     if (empty($options)) {
         $options = array();
     }
     if (array_key_exists('uri', $options)) {
         $other = Bookmark::getKV('uri', $options['uri']);
         if (!empty($other)) {
             // TRANS: Client exception thrown when trying to save a new bookmark that already exists.
             throw new ClientException(_m('Bookmark already exists.'));
         }
     }
     if (is_string($rawtags)) {
         if (empty($rawtags)) {
             $rawtags = array();
         } else {
             $rawtags = preg_split('/[\\s,]+/', $rawtags);
         }
     }
     $nb = new Bookmark();
     $nb->id = UUID::gen();
     $nb->profile_id = $profile->id;
     $nb->url = $url;
     $nb->title = $title;
     $nb->description = $description;
     if (array_key_exists('created', $options)) {
         $nb->created = $options['created'];
     } else {
         $nb->created = common_sql_now();
     }
     if (array_key_exists('uri', $options)) {
         $nb->uri = $options['uri'];
     } else {
         // FIXME: hacks to work around router bugs in
         // queue daemons
         $r = Router::get();
         $path = $r->build('showbookmark', array('id' => $nb->id));
         if (empty($path)) {
             $nb->uri = common_path('bookmark/' . $nb->id, false, false);
         } else {
             $nb->uri = common_local_url('showbookmark', array('id' => $nb->id), null, null, false);
         }
     }
     $nb->insert();
     $tags = array();
     $replies = array();
     // filter "for:nickname" tags
     foreach ($rawtags as $tag) {
         if (strtolower(mb_substr($tag, 0, 4)) == 'for:') {
             // skip if done by caller
             if (!array_key_exists('replies', $options)) {
                 $nickname = mb_substr($tag, 4);
                 $other = common_relative_profile($profile, $nickname);
                 if (!empty($other)) {
                     $replies[] = $other->getUri();
                 }
             }
         } else {
             $tags[] = common_canonical_tag($tag);
         }
     }
     $hashtags = array();
     $taglinks = array();
     foreach ($tags as $tag) {
         $hashtags[] = '#' . $tag;
         $attrs = array('href' => Notice_tag::url($tag), 'rel' => $tag, 'class' => 'tag');
         $taglinks[] = XMLStringer::estring('a', $attrs, $tag);
     }
     // Use user's preferences for short URLs, if possible
     try {
         $user = User::getKV('id', $profile->id);
         $shortUrl = File_redirection::makeShort($url, empty($user) ? null : $user);
     } catch (Exception $e) {
         // Don't let this stop us.
         $shortUrl = $url;
     }
     // TRANS: Bookmark content.
     // TRANS: %1$s is a title, %2$s is a short URL, %3$s is the bookmark description,
     // TRANS: %4$s is space separated list of hash tags.
     $content = sprintf(_m('"%1$s" %2$s %3$s %4$s'), $title, $shortUrl, $description, implode(' ', $hashtags));
     // TRANS: Rendered bookmark content.
     // TRANS: %1$s is a URL, %2$s the bookmark title, %3$s is the bookmark description,
     // TRANS: %4$s is space separated list of hash tags.
     $rendered = sprintf(_m('<span class="xfolkentry">' . '<a class="taggedlink" href="%1$s">%2$s</a> ' . '<span class="description">%3$s</span> ' . '<span class="meta">%4$s</span>' . '</span>'), htmlspecialchars($url), htmlspecialchars($title), htmlspecialchars($description), implode(' ', $taglinks));
     $options = array_merge(array('urls' => array($url), 'rendered' => $rendered, 'tags' => $tags, 'replies' => $replies, 'object_type' => ActivityObject::BOOKMARK), $options);
     if (!array_key_exists('uri', $options)) {
         $options['uri'] = $nb->uri;
     }
     try {
         $saved = Notice::saveNew($profile->id, $content, array_key_exists('source', $options) ? $options['source'] : 'web', $options);
     } catch (Exception $e) {
         $nb->delete();
         throw $e;
     }
     if (empty($saved)) {
         $nb->delete();
     }
     return $saved;
 }
Example #30
0
 function saveGroups()
 {
     $enabled = common_config('inboxes', 'enabled');
     if ($enabled !== true && $enabled !== 'transitional') {
         return;
     }
     /* extract all !group */
     $count = preg_match_all('/(?:^|\\s)!([A-Za-z0-9]{1,64})/', strtolower($this->content), $match);
     if (!$count) {
         return true;
     }
     $profile = $this->getProfile();
     /* Add them to the database */
     foreach (array_unique($match[1]) as $nickname) {
         /* XXX: remote groups. */
         $group = User_group::staticGet('nickname', $nickname);
         if (!$group) {
             continue;
         }
         // we automatically add a tag for every group name, too
         $tag = Notice_tag::pkeyGet(array('tag' => common_canonical_tag($nickname), 'notice_id' => $this->id));
         if (is_null($tag)) {
             $this->saveTag($nickname);
         }
         if ($profile->isMember($group)) {
             $gi = new Group_inbox();
             $gi->group_id = $group->id;
             $gi->notice_id = $this->id;
             $gi->created = common_sql_now();
             $result = $gi->insert();
             if (!$result) {
                 common_log_db_error($gi, 'INSERT', __FILE__);
             }
             // FIXME: do this in an offline daemon
             $inbox = new Notice_inbox();
             $UT = common_config('db', 'type') == 'pgsql' ? '"user"' : 'user';
             $qry = 'INSERT INTO notice_inbox (user_id, notice_id, created, source) ' . "SELECT {$UT}.id, " . $this->id . ", '" . $this->created . "', 2 " . "FROM {$UT} JOIN group_member ON {$UT}.id = group_member.profile_id " . 'WHERE group_member.group_id = ' . $group->id . ' ' . 'AND NOT EXISTS (SELECT user_id, notice_id ' . 'FROM notice_inbox ' . "WHERE user_id = {$UT}.id " . 'AND notice_id = ' . $this->id . ' )';
             if ($enabled === 'transitional') {
                 $qry .= " AND {$UT}.inboxed = 1";
             }
             $result = $inbox->query($qry);
         }
     }
 }