Exemple #1
0
function common_linkify($url)
{
    // It comes in special'd, so we unspecial it before passing to the stringifying
    // functions
    $url = htmlspecialchars_decode($url);
    if (strpos($url, '@') !== false && strpos($url, ':') === false) {
        //url is an email address without the mailto: protocol
        $canon = "mailto:{$url}";
        $longurl = "mailto:{$url}";
    } else {
        $canon = File_redirection::_canonUrl($url);
        $longurl_data = File_redirection::where($canon);
        if (is_array($longurl_data)) {
            $longurl = $longurl_data['url'];
        } elseif (is_string($longurl_data)) {
            $longurl = $longurl_data;
        } else {
            throw new ServerException("Can't linkify url '{$url}'");
        }
    }
    $attrs = array('href' => $canon, 'title' => $longurl, 'rel' => 'external');
    $is_attachment = false;
    $attachment_id = null;
    $has_thumb = false;
    // Check to see whether this is a known "attachment" URL.
    $f = File::staticGet('url', $longurl);
    if (empty($f)) {
        // XXX: this writes to the database. :<
        $f = File::processNew($longurl);
    }
    if (!empty($f)) {
        if ($f->getEnclosure()) {
            $is_attachment = true;
            $attachment_id = $f->id;
            $thumb = File_thumbnail::staticGet('file_id', $f->id);
            if (!empty($thumb)) {
                $has_thumb = true;
            }
        }
    }
    // Add clippy
    if ($is_attachment) {
        $attrs['class'] = 'attachment';
        if ($has_thumb) {
            $attrs['class'] = 'attachment thumbnail';
        }
        $attrs['id'] = "attachment-{$attachment_id}";
    }
    return XMLStringer::estring('a', $attrs, $url);
}
Exemple #2
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;
 }
Exemple #3
0
function common_linkify($url)
{
    // It comes in special'd, so we unspecial it before passing to the stringifying
    // functions
    $url = htmlspecialchars_decode($url);
    if (strpos($url, '@') !== false && strpos($url, ':') === false && Validate::email($url)) {
        //url is an email address without the mailto: protocol
        $canon = "mailto:{$url}";
        $longurl = "mailto:{$url}";
    } else {
        $canon = File_redirection::_canonUrl($url);
        $longurl_data = File_redirection::where($canon, common_config('attachments', 'process_links'));
        if (is_array($longurl_data)) {
            $longurl = $longurl_data['url'];
        } elseif (is_string($longurl_data)) {
            $longurl = $longurl_data;
        } else {
            // Unable to reach the server to verify contents, etc
            // Just pass the link on through for now.
            common_log(LOG_ERR, "Can't linkify url '{$url}'");
            $longurl = $url;
        }
    }
    $attrs = array('href' => $canon, 'title' => $longurl);
    $is_attachment = false;
    $attachment_id = null;
    $has_thumb = false;
    // Check to see whether this is a known "attachment" URL.
    $f = File::staticGet('url', $longurl);
    if (empty($f)) {
        if (common_config('attachments', 'process_links')) {
            // XXX: this writes to the database. :<
            $f = File::processNew($longurl);
        }
    }
    if (!empty($f)) {
        if ($f->getEnclosure()) {
            $is_attachment = true;
            $attachment_id = $f->id;
            $thumb = File_thumbnail::staticGet('file_id', $f->id);
            if (!empty($thumb)) {
                $has_thumb = true;
            }
        }
    }
    // Add clippy
    if ($is_attachment) {
        $attrs['class'] = 'attachment';
        if ($has_thumb) {
            $attrs['class'] = 'attachment thumbnail';
        }
        $attrs['id'] = "attachment-{$attachment_id}";
    }
    // Whether to nofollow
    $nf = common_config('nofollow', 'external');
    if ($nf == 'never') {
        $attrs['rel'] = 'external';
    } else {
        $attrs['rel'] = 'nofollow external';
    }
    return XMLStringer::estring('a', $attrs, $url);
}
Exemple #4
0
 /**
  * show a link to the author of repeat
  *
  * @return void
  */
 function showRepeat()
 {
     if (!empty($this->repeat)) {
         // FIXME: this code is almost identical to default; need to refactor
         $attrs = array('href' => $this->profile->profileurl, 'class' => 'url');
         if (!empty($this->profile->fullname)) {
             $attrs['title'] = $this->profile->getFancyName();
         }
         $this->out->elementStart('span', 'repeat');
         $text_link = XMLStringer::estring('a', $attrs, $this->profile->nickname);
         // TRANS: Link to the author of a repeated notice. %s is a linked nickname.
         $this->out->raw(sprintf(_('Repeat of %s'), $text_link));
         $this->out->elementEnd('span');
     }
 }
Exemple #5
0
 /**
  * Show version information
  *
  * @return void
  */
 function showContent()
 {
     $this->elementStart('p');
     // TRANS: Content part of StatusNet version page.
     // TRANS: %1$s is the engine name (StatusNet) and %2$s is the StatusNet version.
     $this->raw(sprintf(_('This site is powered by %1$s version %2$s, ' . 'Copyright 2008-2011 StatusNet, Inc. ' . 'and contributors.'), XMLStringer::estring('a', array('href' => 'http://status.net/'), _('StatusNet')), STATUSNET_VERSION));
     $this->elementEnd('p');
     // TRANS: Header for StatusNet contributors section on the version page.
     $this->element('h2', null, _('Contributors'));
     sort($this->contributors);
     $this->element('p', null, implode(', ', $this->contributors));
     // TRANS: Header for StatusNet license section on the version page.
     $this->element('h2', null, _('License'));
     $this->element('p', null, _('StatusNet is free software: you can redistribute it and/or modify ' . 'it under the terms of the GNU Affero General Public License as published by ' . 'the Free Software Foundation, either version 3 of the License, or ' . '(at your option) any later version.'));
     $this->element('p', null, _('This program is distributed in the hope that it will be useful, ' . 'but WITHOUT ANY WARRANTY; without even the implied warranty of ' . 'MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the ' . 'GNU Affero General Public License for more details.'));
     $this->elementStart('p');
     // TRANS: Content part of StatusNet version page.
     // TRANS: %s is a link to the AGPL license with link description "http://www.gnu.org/licenses/agpl.html".
     $this->raw(sprintf(_('You should have received a copy of the GNU Affero General Public License ' . 'along with this program.  If not, see %s.'), XMLStringer::estring('a', array('href' => 'http://www.gnu.org/licenses/agpl.html'), 'http://www.gnu.org/licenses/agpl.html')));
     $this->elementEnd('p');
     // XXX: Theme information?
     if (count($this->pluginVersions)) {
         // TRANS: Header for StatusNet plugins section on the version page.
         $this->element('h2', null, _('Plugins'));
         $this->elementStart('table', array('id' => 'plugins_enabled'));
         $this->elementStart('thead');
         $this->elementStart('tr');
         // TRANS: Column header for plugins table on version page.
         $this->element('th', array('id' => 'plugin_name'), _m('HEADER', 'Name'));
         // TRANS: Column header for plugins table on version page.
         $this->element('th', array('id' => 'plugin_version'), _m('HEADER', 'Version'));
         // TRANS: Column header for plugins table on version page.
         $this->element('th', array('id' => 'plugin_authors'), _m('HEADER', 'Author(s)'));
         // TRANS: Column header for plugins table on version page.
         $this->element('th', array('id' => 'plugin_description'), _m('HEADER', 'Description'));
         $this->elementEnd('tr');
         $this->elementEnd('thead');
         $this->elementStart('tbody');
         foreach ($this->pluginVersions as $plugin) {
             $this->elementStart('tr');
             if (array_key_exists('homepage', $plugin)) {
                 $this->elementStart('th');
                 $this->element('a', array('href' => $plugin['homepage']), $plugin['name']);
                 $this->elementEnd('th');
             } else {
                 $this->element('th', null, $plugin['name']);
             }
             $this->element('td', null, $plugin['version']);
             if (array_key_exists('author', $plugin)) {
                 $this->element('td', null, $plugin['author']);
             }
             if (array_key_exists('rawdescription', $plugin)) {
                 $this->elementStart('td');
                 $this->raw($plugin['rawdescription']);
                 $this->elementEnd('td');
             } else {
                 if (array_key_exists('description', $plugin)) {
                     $this->element('td', null, $plugin['description']);
                 }
             }
             $this->elementEnd('tr');
         }
         $this->elementEnd('tbody');
         $this->elementEnd('table');
     }
 }
Exemple #6
0
function common_linkify($url)
{
    // It comes in special'd, so we unspecial it before passing to the stringifying
    // functions
    $url = htmlspecialchars_decode($url);
    if (strpos($url, '@') !== false && strpos($url, ':') === false && Validate::email($url)) {
        //url is an email address without the mailto: protocol
        $canon = "mailto:{$url}";
        $longurl = "mailto:{$url}";
    } else {
        $canon = File_redirection::_canonUrl($url);
        $longurl_data = File_redirection::where($canon, common_config('attachments', 'process_links'));
        if (isset($longurl_data->redir_url)) {
            $longurl = $longurl_data->redir_url;
        } else {
            // e.g. local files
            $longurl = $longurl_data->url;
        }
    }
    $attrs = array('href' => $longurl, 'title' => $longurl);
    $is_attachment = false;
    $attachment_id = null;
    $has_thumb = false;
    // Check to see whether this is a known "attachment" URL.
    try {
        $f = File::getByUrl($longurl);
    } catch (NoResultException $e) {
        if (common_config('attachments', 'process_links')) {
            // XXX: this writes to the database. :<
            try {
                $f = File::processNew($longurl);
            } catch (ServerException $e) {
                $f = null;
            }
        }
    }
    if ($f instanceof File) {
        try {
            $enclosure = $f->getEnclosure();
            $is_attachment = true;
            $attachment_id = $f->id;
            $thumb = File_thumbnail::getKV('file_id', $f->id);
            $has_thumb = $thumb instanceof File_thumbnail;
        } catch (ServerException $e) {
            // There was not enough metadata available
        }
    }
    // Add clippy
    if ($is_attachment) {
        $attrs['class'] = 'attachment';
        if ($has_thumb) {
            $attrs['class'] = 'attachment thumbnail';
        }
        $attrs['id'] = "attachment-{$attachment_id}";
    }
    // Whether to nofollow
    $nf = common_config('nofollow', 'external');
    if ($nf == 'never') {
        $attrs['rel'] = 'external';
    } else {
        $attrs['rel'] = 'nofollow external';
    }
    return XMLStringer::estring('a', $attrs, $url);
}
 /**
  * Show a list of people who've flagged this profile
  *
  * @return void
  */
 function showFlaggersList()
 {
     $flaggers = array();
     $ufp = new User_flag_profile();
     $ufp->selectAdd();
     $ufp->selectAdd('user_id');
     $ufp->profile_id = $this->profile->id;
     $ufp->orderBy('created');
     if ($ufp->find()) {
         // XXX: this should always happen
         while ($ufp->fetch()) {
             $user = User::staticGet('id', $ufp->user_id);
             if (!empty($user)) {
                 // XXX: this would also be unusual
                 $flaggers[] = clone $user;
             }
         }
     }
     $cnt = count($flaggers);
     $others = 0;
     if ($cnt > self::MAX_FLAGGERS) {
         $flaggers = array_slice($flaggers, 0, self::MAX_FLAGGERS);
         $others = $cnt - self::MAX_FLAGGERS;
     }
     $lnks = array();
     foreach ($flaggers as $flagger) {
         $url = common_local_url('showstream', array('nickname' => $flagger->nickname));
         $lnks[] = XMLStringer::estring('a', array('href' => $url, 'class' => 'flagger'), $flagger->nickname);
     }
     if ($cnt > 0) {
         if ($others > 0) {
             $flagging_users = implode(', ', $lnks);
             // TRANS: Message displayed on a profile if it has been flagged.
             // TRANS: %1$s is a comma separated list of at most 5 user nicknames that flagged.
             // TRANS: %2$d is a positive integer of additional flagging users. Also used for the plural.
             $text .= sprintf(_m('Flagged by %1$s and %2$d other', 'Flagged by %1$s and %2$d others', $others), $flagging_users, $others);
         } else {
             // TRANS: Message displayed on a profile if it has been flagged.
             // TRANS: %s is a comma separated list of at most 5 user nicknames that flagged.
             $text .= sprintf(_m('Flagged by %s'), $flagging_users);
         }
         $this->out->elementStart('p', array('class' => 'flaggers'));
         $this->out->raw($text);
         $this->out->elementEnd('p');
     }
 }
 static function saveNew($profile, $title, $content, $options = null)
 {
     if (is_null($options)) {
         $options = array();
     }
     $be = new Blog_entry();
     $be->id = (string) new UUID();
     $be->profile_id = $profile->id;
     $be->title = $title;
     // Note: not HTML-protected
     $be->content = self::purify($content);
     if (array_key_exists('summary', $options)) {
         $be->summary = self::purify($options['summary']);
     } else {
         // Already purified
         $be->summary = self::summarize($be->content);
     }
     // Don't save an identical summary
     if ($be->summary == $be->content) {
         $be->summary = null;
     }
     $url = common_local_url('showblogentry', array('id' => $be->id));
     if (!array_key_exists('uri', $options)) {
         $options['uri'] = $url;
     }
     $be->uri = $options['uri'];
     if (!array_key_exists('url', $options)) {
         $options['url'] = $url;
     }
     $be->url = $options['url'];
     if (!array_key_exists('created', $options)) {
         $be->created = common_sql_now();
     }
     $be->created = $options['created'];
     $be->modified = common_sql_now();
     $be->insert();
     // Use user's preferences for short URLs, if possible
     try {
         $user = $profile->getUser();
         $shortUrl = File_redirection::makeShort($url, empty($user) ? null : $user);
     } catch (Exception $e) {
         // Don't let this stop us.
         $shortUrl = $url;
     }
     // XXX: this might be too long.
     if (!empty($be->summary)) {
         $options['rendered'] = $be->summary . ' ' . XMLStringer::estring('a', array('href' => $url, 'class' => 'blog-entry'), _('More...'));
         $text = html_entity_decode(strip_tags($be->summary), ENT_QUOTES, 'UTF-8');
     } else {
         $options['rendered'] = $be->content;
         $text = html_entity_decode(strip_tags($be->content), ENT_QUOTES, 'UTF-8');
     }
     if (Notice::contentTooLong($text)) {
         $text = substr($text, 0, Notice::maxContent() - mb_strlen($shortUrl) - 2) . '… ' . $shortUrl;
     }
     // Override this no matter what.
     $options['object_type'] = self::TYPE;
     $source = array_key_exists('source', $options) ? $options['source'] : 'web';
     $saved = Notice::saveNew($profile->id, $text, $source, $options);
     return $saved;
 }
Exemple #9
0
function common_linkify($url)
{
    // It comes in special'd, so we unspecial it before passing to the stringifying
    // functions
    $url = htmlspecialchars_decode($url);
    $display = $url;
    $url = !preg_match('#^([a-z]+://|(mailto|aim|tel):)#i', $url) ? 'http://' . $url : $url;
    $attrs = array('href' => $url, 'rel' => 'external');
    if ($longurl = common_longurl($url)) {
        $attrs['title'] = $longurl;
    }
    return XMLStringer::estring('a', $attrs, $display);
}
Exemple #10
0
 /**
  * Show a list of people who've flagged this profile
  *
  * @return void
  */
 function showFlaggersList()
 {
     $flaggers = array();
     $ufp = new User_flag_profile();
     $ufp->selectAdd();
     $ufp->selectAdd('user_id');
     $ufp->profile_id = $this->profile->id;
     $ufp->orderBy('created');
     if ($ufp->find()) {
         // XXX: this should always happen
         while ($ufp->fetch()) {
             $user = User::staticGet('id', $ufp->user_id);
             if (!empty($user)) {
                 // XXX: this would also be unusual
                 $flaggers[] = clone $user;
             }
         }
     }
     $cnt = count($flaggers);
     $others = 0;
     if ($cnt > self::MAX_FLAGGERS) {
         $flaggers = array_slice($flaggers, 0, self::MAX_FLAGGERS);
         $others = $cnt - self::MAX_FLAGGERS;
     }
     $lnks = array();
     foreach ($flaggers as $flagger) {
         $url = common_local_url('showstream', array('nickname' => $flagger->nickname));
         $lnks[] = XMLStringer::estring('a', array('href' => $url, 'class' => 'flagger'), $flagger->nickname);
     }
     if ($cnt > 0) {
         $text = _('Flagged by ');
         $text .= implode(', ', $lnks);
         if ($others > 0) {
             $text .= sprintf(_(' and %d others'), $others);
         }
         $this->out->elementStart('p', array('class' => 'flaggers'));
         $this->out->raw($text);
         $this->out->elementEnd('p');
     }
 }
Exemple #11
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);
 }