function onStartShowSections($action) { $name = $action->trimmed('action'); if ($name == 'tag') { $taginput = $action->trimmed('tag'); $tag = common_canonical_tag($taginput); if (!empty($tag)) { $url = sprintf('http://hashtags.wikia.com/index.php?title=%s&action=render', urlencode($tag)); $editurl = sprintf('http://hashtags.wikia.com/index.php?title=%s&action=edit', urlencode($tag)); $context = stream_context_create(array('http' => array('method' => "GET", 'header' => "User-Agent: " . $this->userAgent()))); $html = @file_get_contents($url, false, $context); $action->elementStart('div', array('id' => 'wikihashtags', 'class' => 'section')); if (!empty($html)) { $action->element('style', null, "span.editsection { display: none }\n" . "table.toc { display: none }"); $action->raw($html); $action->elementStart('p'); $action->element('a', array('href' => $editurl, 'title' => sprintf(_('Edit the article for #%s on WikiHashtags'), $tag)), _('Edit')); $action->element('a', array('href' => 'http://www.gnu.org/copyleft/fdl.html', 'title' => _('Shared under the terms of the GNU Free Documentation License'), 'rel' => 'license'), 'GNU FDL'); $action->elementEnd('p'); } else { $action->element('a', array('href' => $editurl), sprintf(_('Start the article for #%s on WikiHashtags'), $tag)); } $action->elementEnd('div'); } } return true; }
function onStartShowSections($action) { $name = $action->trimmed('action'); if ($name == 'tag') { $taginput = $action->trimmed('tag'); $tag = common_canonical_tag($taginput); if (!empty($tag)) { $url = sprintf('http://hashtags.wikia.com/index.php?title=%s&action=render', urlencode($tag)); $editurl = sprintf('http://hashtags.wikia.com/index.php?title=%s&action=edit', urlencode($tag)); $request = HTTPClient::start(); $response = $request->get($url); $html = $response->getBody(); $action->elementStart('div', array('id' => 'wikihashtags', 'class' => 'section')); if ($response->isOk() && !empty($html)) { $action->element('style', null, "span.editsection { display: none }\n" . "table.toc { display: none }"); $action->raw($html); $action->elementStart('p'); $action->element('a', array('href' => $editurl, 'title' => sprintf(_m('Edit the article for #%s on WikiHashtags'), $tag)), _m('Edit')); $action->element('a', array('href' => 'http://www.gnu.org/copyleft/fdl.html', 'title' => _m('Shared under the terms of the GNU Free Documentation License'), 'rel' => 'license'), _m('GNU FDL')); $action->elementEnd('p'); } else { $action->element('a', array('href' => $editurl), sprintf(_m('Start the article for #%s on WikiHashtags'), $tag)); } $action->elementEnd('div'); } } return true; }
/** * Take arguments for running * * @param array $args $_REQUEST args * * @return boolean success flag */ function prepare($args) { parent::prepare($args); $taginput = $this->trimmed('tag'); $this->tag = common_canonical_tag($taginput); $this->notices = $this->getNotices(); return true; }
protected function doStreamPreparation() { $tag = common_canonical_tag($this->trimmed('tag')); $this->tag = Notice_tag::getKV('tag', $tag); if (!$this->tag instanceof Notice_tag) { // TRANS: Client error when requesting a tag feed for a non-existing tag. $this->clientError(_('No such tag.')); } }
function prepare($args) { parent::prepare($args); $tag = common_canonical_tag($this->trimmed('tag')); $this->tag = Notice_tag::staticGet('tag', $tag); if (!$this->tag) { $this->clientError(_('No such tag.')); return false; } else { return true; } }
function prepare($args) { parent::prepare($args); $tag = common_canonical_tag($this->trimmed('tag')); $this->tag = Notice_tag::getKV('tag', $tag); if (!$this->tag) { // TRANS: Client error when requesting a tag feed for a non-existing tag. $this->clientError(_('No such tag.')); } else { $this->notices = $this->getNotices($this->limit); return true; } }
function prepare($args) { parent::prepare($args); if (common_config('singleuser', 'enabled')) { $tagger_arg = User::singleUserNickname(); } else { $tagger_arg = $this->arg('tagger'); } $tag_arg = $this->arg('tag'); $tagger = common_canonical_nickname($tagger_arg); $tag = common_canonical_tag($tag_arg); // Permanent redirect on non-canonical nickname if ($tagger_arg != $tagger || $tag_arg != $tag) { $args = array('tagger' => $nickname, 'tag' => $tag); if ($this->page != 1) { $args['page'] = $this->page; } common_redirect(common_local_url('showprofiletag', $args), 301); return false; } if (!$tagger) { // TRANS: Client error displayed when a tagger is expected but not provided. $this->clientError(_('No tagger.'), 404); return false; } $user = User::staticGet('nickname', $tagger); if (!$user) { // TRANS: Client error displayed trying to perform an action related to a non-existing user. $this->clientError(_('No such user.'), 404); return false; } $this->tagger = $user->getProfile(); $this->peopletag = Profile_list::pkeyGet(array('tagger' => $user->id, 'tag' => $tag)); $current = common_current_user(); $can_see = !empty($this->peopletag) && (!$this->peopletag->private || $this->peopletag->private && $this->peopletag->tagger === $current->id); if (!$can_see) { // TRANS: Client error displayed trying to reference a non-existing list. $this->clientError(_('No such list.'), 404); return false; } $this->page = $this->arg('page') ? $this->arg('page') + 0 : 1; $this->userProfile = Profile::current(); $stream = new PeopletagNoticeStream($this->peopletag, $this->userProfile); $this->notice = $stream->getNotices(($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(_('No such page.'), $code = 404); } return true; }
protected function doStreamPreparation() { $tag = common_canonical_tag($this->arg('tag')); try { $this->peopletag = Profile_list::getByPK(array('tagger' => $this->target->getID(), 'tag' => $tag)); } catch (NoResultException $e) { // TRANS: Client error displayed trying to reference a non-existing list. throw new ClientException('No such list.'); } if ($this->peopletag->private && !$this->peopletag->getTagger()->sameAs($this->scoped)) { // TRANS: Client error displayed trying to reference a non-existing list. throw new AuthorizationException('You do not have permission to see this list.'); } }
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))); } $this->page = $this->arg('page') ? $this->arg('page') + 0 : 1; common_set_returnto($this->selfUrl()); return true; }
function prepare($args) { parent::prepare($args); $this->page = $this->arg('page') ? $this->arg('page') + 0 : 1; $tag_arg = $this->arg('tag'); $tag = common_canonical_tag($tag_arg); // Permanent redirect on non-canonical nickname if ($tag_arg != $tag) { $args = array('tag' => $nickname); if ($this->page && $this->page != 1) { $args['page'] = $this->page; } common_redirect(common_local_url('peopletag', $args), 301); } $this->tag = $tag; return true; }
function prepare($args) { parent::prepare($args); $this->page = $this->arg('page') ? $this->arg('page') + 0 : 1; if (common_config('singleuser', 'enabled')) { $tagger_arg = User::singleUserNickname(); } else { $tagger_arg = $this->arg('tagger'); } $tag_arg = $this->arg('tag'); $tagger = common_canonical_nickname($tagger_arg); $tag = common_canonical_tag($tag_arg); // Permanent redirect on non-canonical nickname if ($tagger_arg != $tagger || $tag_arg != $tag) { $args = array('tagger' => $nickname, 'tag' => $tag); if ($this->page != 1) { $args['page'] = $this->page; } common_redirect(common_local_url('peopletagged', $args), 301); return false; } if (!$tagger) { // TRANS: Client error displayed when a tagger is expected but not provided. $this->clientError(_('No tagger.'), 404); return false; } $user = User::staticGet('nickname', $tagger); if (!$user) { // TRANS: Client error displayed trying to perform an action related to a non-existing user. $this->clientError(_('No such user.'), 404); return false; } $this->tagger = $user->getProfile(); $this->peopletag = Profile_list::pkeyGet(array('tagger' => $user->id, 'tag' => $tag)); if (!$this->peopletag) { // TRANS: Client error displayed trying to reference a non-existing list. $this->clientError(_('No such list.'), 404); return false; } return true; }
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; }
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; }
function prepare($args) { parent::prepare($args); $this->q = $this->trimmed('q'); // FIXME: very dependent on tag format if (preg_match('/^#([\\pL\\pN_\\-\\.]{1,64})/ue', $this->q)) { common_redirect(common_local_url('tag', array('tag' => common_canonical_tag(substr($this->q, 1)))), 303); } if (!empty($this->q)) { $profile = Profile::current(); $stream = new SearchNoticeStream($this->q, $profile); $page = $this->trimmed('page'); if (empty($page)) { $page = 1; } else { $page = (int) $page; } $this->notice = $stream->getNotices(($page - 1) * NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); } common_set_returnto($this->selfUrl()); return true; }
function postNote($activity) { $note = $activity->objects[0]; // Use summary as fallback for content if (!empty($note->content)) { $sourceContent = $note->content; } else { if (!empty($note->summary)) { $sourceContent = $note->summary; } else { if (!empty($note->title)) { $sourceContent = $note->title; } else { // @fixme fetch from $sourceUrl? // TRANS: Client error displayed when posting a notice without content through the API. // TRANS: %d is the notice ID (number). $this->clientError(sprintf(_('No content for notice %d.'), $note->id)); } } } // Get (safe!) HTML and text versions of the content $rendered = common_purify($sourceContent); $content = common_strip_html($rendered); $shortened = $this->auth_user->shortenLinks($content); $options = array('is_local' => Notice::LOCAL_PUBLIC, 'rendered' => $rendered, 'replies' => array(), 'groups' => array(), 'tags' => array(), 'urls' => array()); // accept remote URI (not necessarily a good idea) common_debug("Note ID is {$note->id}"); if (!empty($note->id)) { $notice = Notice::getKV('uri', trim($note->id)); if (!empty($notice)) { // TRANS: Client error displayed when using another format than AtomPub. // TRANS: %s is the notice URI. $this->clientError(sprintf(_('Notice with URI "%s" already exists.'), $note->id)); } common_log(LOG_NOTICE, "Saving client-supplied notice URI '{$note->id}'"); $options['uri'] = $note->id; } // accept remote create time (also maybe not such a good idea) if (!empty($activity->time)) { common_log(LOG_NOTICE, "Saving client-supplied create time {$activity->time}"); $options['created'] = common_sql_date($activity->time); } // Check for optional attributes... if ($activity->context instanceof ActivityContext) { foreach ($activity->context->attention as $uri => $type) { try { $profile = Profile::fromUri($uri); if ($profile->isGroup()) { $options['groups'][] = $profile->id; } else { $options['replies'][] = $uri; } } catch (UnknownUriException $e) { common_log(LOG_WARNING, sprintf('AtomPub post with unknown attention URI %s', $uri)); } } // Maintain direct reply associations // @fixme what about conversation ID? if (!empty($activity->context->replyToID)) { $orig = Notice::getKV('uri', $activity->context->replyToID); if (!empty($orig)) { $options['reply_to'] = $orig->id; } } $location = $activity->context->location; if ($location) { $options['lat'] = $location->lat; $options['lon'] = $location->lon; if ($location->location_id) { $options['location_ns'] = $location->location_ns; $options['location_id'] = $location->location_id; } } } // Atom categories <-> hashtags foreach ($activity->categories as $cat) { if ($cat->term) { $term = common_canonical_tag($cat->term); if ($term) { $options['tags'][] = $term; } } } // Atom enclosures -> attachment URLs foreach ($activity->enclosures as $href) { // @fixme save these locally or....? $options['urls'][] = $href; } $saved = Notice::saveNew($this->target->id, $content, 'atompub', $options); return $saved; }
/** * Handle a post * * Validate input and save changes. Reload the form with a success * or error message. * * @return void */ function handlePost() { // CSRF protection $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { // TRANS: Form validation error. $this->showForm(_('There was a problem with your session token. ' . 'Try again, please.')); return; } if (Event::handle('StartProfileSaveForm', array($this))) { try { $nickname = Nickname::normalize($this->trimmed('nickname')); } catch (NicknameException $e) { $this->showForm($e->getMessage()); return; } $fullname = $this->trimmed('fullname'); $homepage = $this->trimmed('homepage'); $bio = $this->trimmed('bio'); $location = $this->trimmed('location'); $autosubscribe = $this->boolean('autosubscribe'); $subscribe_policy = $this->trimmed('subscribe_policy'); $private_stream = $this->boolean('private_stream'); $language = $this->trimmed('language'); $timezone = $this->trimmed('timezone'); $tagstring = $this->trimmed('tags'); // Some validation if (!User::allowed_nickname($nickname)) { // TRANS: Validation error in form for profile settings. $this->showForm(_('Not a valid nickname.')); return; } else { if (!is_null($homepage) && strlen($homepage) > 0 && !Validate::uri($homepage, array('allowed_schemes' => array('http', 'https')))) { // TRANS: Validation error in form for profile settings. $this->showForm(_('Homepage is not a valid URL.')); return; } else { if (!is_null($fullname) && mb_strlen($fullname) > 255) { // TRANS: Validation error in form for profile settings. $this->showForm(_('Full name is too long (maximum 255 characters).')); return; } else { if (Profile::bioTooLong($bio)) { // TRANS: Validation error in form for profile settings. // TRANS: Plural form is used based on the maximum number of allowed // TRANS: characters for the biography (%d). $this->showForm(sprintf(_m('Bio is too long (maximum %d character).', 'Bio is too long (maximum %d characters).', Profile::maxBio()), Profile::maxBio())); return; } else { if (!is_null($location) && mb_strlen($location) > 255) { // TRANS: Validation error in form for profile settings. $this->showForm(_('Location is too long (maximum 255 characters).')); return; } else { if (is_null($timezone) || !in_array($timezone, DateTimeZone::listIdentifiers())) { // TRANS: Validation error in form for profile settings. $this->showForm(_('Timezone not selected.')); return; } else { if ($this->nicknameExists($nickname)) { // TRANS: Validation error in form for profile settings. $this->showForm(_('Nickname already in use. Try another one.')); return; } else { if (!is_null($language) && strlen($language) > 50) { // TRANS: Validation error in form for profile settings. $this->showForm(_('Language is too long (maximum 50 characters).')); return; } } } } } } } } $tags = array(); $tag_priv = array(); if (is_string($tagstring) && strlen($tagstring) > 0) { $tags = preg_split('/[\\s,]+/', $tagstring); foreach ($tags as &$tag) { $private = @$tag[0] === '.'; $tag = common_canonical_tag($tag); if (!common_valid_profile_tag($tag)) { // TRANS: Validation error in form for profile settings. // TRANS: %s is an invalid tag. $this->showForm(sprintf(_('Invalid tag: "%s".'), $tag)); return; } $tag_priv[$tag] = $private; } } $user = common_current_user(); $user->query('BEGIN'); if ($user->nickname != $nickname || $user->language != $language || $user->timezone != $timezone) { common_debug('Updating user nickname from ' . $user->nickname . ' to ' . $nickname, __FILE__); common_debug('Updating user language from ' . $user->language . ' to ' . $language, __FILE__); common_debug('Updating user timezone from ' . $user->timezone . ' to ' . $timezone, __FILE__); $original = clone $user; $user->nickname = $nickname; $user->language = $language; $user->timezone = $timezone; $result = $user->updateKeys($original); if ($result === false) { common_log_db_error($user, 'UPDATE', __FILE__); // TRANS: Server error thrown when user profile settings could not be updated. $this->serverError(_('Could not update user.')); return; } else { // Re-initialize language environment if it changed common_init_language(); // Clear the site owner, in case nickname changed if ($user->hasRole(Profile_role::OWNER)) { User::blow('user:site_owner'); } } } // XXX: XOR if ($user->autosubscribe ^ $autosubscribe || $user->private_stream ^ $private_stream || $user->subscribe_policy != $subscribe_policy) { $original = clone $user; $user->autosubscribe = $autosubscribe; $user->private_stream = $private_stream; $user->subscribe_policy = $subscribe_policy; $result = $user->update($original); if ($result === false) { common_log_db_error($user, 'UPDATE', __FILE__); // TRANS: Server error thrown when user profile settings could not be updated to // TRANS: automatically subscribe to any subscriber. $this->serverError(_('Could not update user for autosubscribe or subscribe_policy.')); return; } } $profile = $user->getProfile(); $orig_profile = clone $profile; $profile->nickname = $user->nickname; $profile->fullname = $fullname; $profile->homepage = $homepage; $profile->bio = $bio; $profile->location = $location; $loc = Location::fromName($location); if (empty($loc)) { $profile->lat = null; $profile->lon = null; $profile->location_id = null; $profile->location_ns = null; } else { $profile->lat = $loc->lat; $profile->lon = $loc->lon; $profile->location_id = $loc->location_id; $profile->location_ns = $loc->location_ns; } $profile->profileurl = common_profile_url($nickname); if (common_config('location', 'share') == 'user') { $exists = false; $prefs = User_location_prefs::staticGet('user_id', $user->id); if (empty($prefs)) { $prefs = new User_location_prefs(); $prefs->user_id = $user->id; $prefs->created = common_sql_now(); } else { $exists = true; $orig = clone $prefs; } $prefs->share_location = $this->boolean('sharelocation'); if ($exists) { $result = $prefs->update($orig); } else { $result = $prefs->insert(); } if ($result === false) { common_log_db_error($prefs, $exists ? 'UPDATE' : 'INSERT', __FILE__); // TRANS: Server error thrown when user profile location preference settings could not be updated. $this->serverError(_('Could not save location prefs.')); return; } } common_debug('Old profile: ' . common_log_objstring($orig_profile), __FILE__); common_debug('New profile: ' . common_log_objstring($profile), __FILE__); $result = $profile->update($orig_profile); if ($result === false) { common_log_db_error($profile, 'UPDATE', __FILE__); // TRANS: Server error thrown when user profile settings could not be saved. $this->serverError(_('Could not save profile.')); return; } // Set the user tags $result = $user->setSelfTags($tags, $tag_priv); if (!$result) { // TRANS: Server error thrown when user profile settings tags could not be saved. $this->serverError(_('Could not save tags.')); return; } $user->query('COMMIT'); Event::handle('EndProfileSaveForm', array($this)); common_broadcast_profile($profile); // TRANS: Confirmation shown when user profile settings are saved. $this->showForm(_('Settings saved.'), true); } }
function handle($channel) { $profile = $this->getProfile($this->other); $cur = $this->user->getProfile(); if (!$profile) { // TRANS: Client error displayed trying to perform an action related to a non-existing profile. $channel->error($cur, _('No such profile.')); return; } if (!$cur->canTag($profile)) { // TRANS: Error displayed when trying to tag a user that cannot be tagged. $channel->error($cur, _('You cannot tag this user.')); return; } $privs = array(); $tags = preg_split('/[\\s,]+/', $this->tags); $clean_tags = array(); foreach ($tags as $tag) { $private = @$tag[0] === '.'; $tag = $clean_tags[] = common_canonical_tag($tag); if (!common_valid_profile_tag($tag)) { // TRANS: Error displayed if a given tag is invalid. // TRANS: %s is the invalid tag. $channel->error($cur, sprintf(_('Invalid tag: "%s".'), $tag)); return; } $privs[$tag] = $private; } try { foreach ($clean_tags as $tag) { Profile_tag::setTag($cur->id, $profile->id, $tag, null, $privs[$tag]); } } catch (Exception $e) { // TRANS: Error displayed if tagging a user fails. // TRANS: %1$s is the tagged user, %2$s is the error message (no punctuation). $channel->error($cur, sprintf(_('Error tagging %1$s: %2$s'), $profile->nickname, $e->getMessage())); return; } // TRANS: Succes message displayed if tagging a user succeeds. // TRANS: %1$s is the tagged user's nickname, %2$s is a list of tags. // TRANS: Plural is decided based on the number of tags added (not part of message). $channel->output($cur, sprintf(_m('%1$s was tagged %2$s', '%1$s was tagged %2$s', count($clean_tags)), $profile->nickname, implode(_(', '), $clean_tags))); }
function getTargetList($user = null, $id = null) { $tagger = $this->getTargetUser($user); $list = null; if (empty($id)) { $id = $this->arg('id'); } if ($id) { if (is_numeric($id)) { $list = Profile_list::staticGet('id', $id); // only if the list with the id belongs to the tagger if (empty($list) || $list->tagger != $tagger->id) { $list = null; } } if (empty($list)) { $tag = common_canonical_tag($id); $list = Profile_list::getByTaggerAndTag($tagger->id, $tag); } if (!empty($list) && $list->private) { if ($this->auth_user->id == $list->tagger) { return $list; } } else { return $list; } } return null; }
function common_tag_link($tag) { $canonical = common_canonical_tag($tag); if (common_config('singleuser', 'enabled')) { // regular TagAction isn't set up in 1user mode $url = common_local_url('showstream', array('nickname' => common_config('singleuser', 'nickname'), 'tag' => $canonical)); } else { $url = common_local_url('tag', array('tag' => $canonical)); } $xs = new XMLStringer(); $xs->elementStart('span', 'tag'); $xs->element('a', array('href' => $url, 'rel' => 'tag'), $tag); $xs->elementEnd('span'); return $xs->getString(); }
public static function provider() { return array(array('hello', 'hello'), array('#hello people', '#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('hello'))) . '" rel="tag">hello</a></span> people'), array('"#hello" people', '"#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('hello'))) . '" rel="tag">hello</a></span>" people'), array('say "#hello" people', 'say "#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('hello'))) . '" rel="tag">hello</a></span>" people'), array('say (#hello) people', 'say (#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('hello'))) . '" rel="tag">hello</a></span>) people'), array('say [#hello] people', 'say [#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('hello'))) . '" rel="tag">hello</a></span>] people'), array('say {#hello} people', 'say {#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('hello'))) . '" rel="tag">hello</a></span>} people'), array('say \'#hello\' people', 'say \'#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('hello'))) . '" rel="tag">hello</a></span>\' people'), array('#éclair yummy', '#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('éclair'))) . '" rel="tag">éclair</a></span> yummy'), array('#维基百科 zh.wikipedia!', '#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('维基百科'))) . '" rel="tag">维基百科</a></span> zh.wikipedia!'), array('#Россия russia', '#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('Россия'))) . '" rel="tag">Россия</a></span> russia'), array('#维基百科,zh.wikipedia!', '#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('维基百科'))) . '" rel="tag">维基百科</a></span>,zh.wikipedia!'), array('#维基百科,zh.wikipedia!', '#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('维基百科'))) . '" rel="tag">维基百科</a></span>,zh.wikipedia!')); }
/** * Process an incoming post activity from this remote feed. * @param Activity $activity * @param string $method 'push' or 'salmon' * @return mixed saved Notice or false * @fixme break up this function, it's getting nasty long */ public function processPost($activity, $method) { if ($this->isGroup()) { // A group feed will contain posts from multiple authors. // @fixme validate these profiles in some way! $oprofile = self::ensureActorProfile($activity); if ($oprofile->isGroup()) { // Groups can't post notices in StatusNet. common_log(LOG_WARNING, "OStatus: skipping post with group listed as author: {$oprofile->uri} in feed from {$this->uri}"); return false; } } else { $actor = $activity->actor; if (empty($actor)) { // OK here! assume the default } else { if ($actor->id == $this->uri || $actor->link == $this->uri) { $this->updateFromActivityObject($actor); } else { throw new Exception("Got an actor '{$actor->title}' ({$actor->id}) on single-user feed for {$this->uri}"); } } $oprofile = $this; } // It's not always an ActivityObject::NOTE, but... let's just say it is. $note = $activity->objects[0]; // The id URI will be used as a unique identifier for for the notice, // protecting against duplicate saves. It isn't required to be a URL; // tag: URIs for instance are found in Google Buzz feeds. $sourceUri = $note->id; $dupe = Notice::staticGet('uri', $sourceUri); if ($dupe) { common_log(LOG_INFO, "OStatus: ignoring duplicate post: {$sourceUri}"); return false; } // We'll also want to save a web link to the original notice, if provided. $sourceUrl = null; if ($note->link) { $sourceUrl = $note->link; } else { if ($activity->link) { $sourceUrl = $activity->link; } else { if (preg_match('!^https?://!', $note->id)) { $sourceUrl = $note->id; } } } // Use summary as fallback for content if (!empty($note->content)) { $sourceContent = $note->content; } else { if (!empty($note->summary)) { $sourceContent = $note->summary; } else { if (!empty($note->title)) { $sourceContent = $note->title; } else { // @fixme fetch from $sourceUrl? throw new ClientException("No content for notice {$sourceUri}"); } } } // Get (safe!) HTML and text versions of the content $rendered = $this->purify($sourceContent); $content = html_entity_decode(strip_tags($rendered)); $shortened = common_shorten_links($content); // If it's too long, try using the summary, and make the // HTML an attachment. $attachment = null; if (Notice::contentTooLong($shortened)) { $attachment = $this->saveHTMLFile($note->title, $rendered); $summary = html_entity_decode(strip_tags($note->summary)); if (empty($summary)) { $summary = $content; } $shortSummary = common_shorten_links($summary); if (Notice::contentTooLong($shortSummary)) { $url = common_shorten_url($sourceUrl); $shortSummary = substr($shortSummary, 0, Notice::maxContent() - (mb_strlen($url) + 2)); $content = $shortSummary . ' ' . $url; // We mark up the attachment link specially for the HTML output // so we can fold-out the full version inline. $attachUrl = common_local_url('attachment', array('attachment' => $attachment->id)); $rendered = common_render_text($shortSummary) . '<a href="' . htmlspecialchars($attachUrl) . '"' . ' class="attachment more"' . ' title="' . htmlspecialchars(_m('Show more')) . '">' . '…' . '</a>'; } } $options = array('is_local' => Notice::REMOTE_OMB, 'url' => $sourceUrl, 'uri' => $sourceUri, 'rendered' => $rendered, 'replies' => array(), 'groups' => array(), 'tags' => array(), 'urls' => array()); // Check for optional attributes... if (!empty($activity->time)) { $options['created'] = common_sql_date($activity->time); } if ($activity->context) { // Any individual or group attn: targets? $replies = $activity->context->attention; $options['groups'] = $this->filterReplies($oprofile, $replies); $options['replies'] = $replies; // Maintain direct reply associations // @fixme what about conversation ID? if (!empty($activity->context->replyToID)) { $orig = Notice::staticGet('uri', $activity->context->replyToID); if (!empty($orig)) { $options['reply_to'] = $orig->id; } } $location = $activity->context->location; if ($location) { $options['lat'] = $location->lat; $options['lon'] = $location->lon; if ($location->location_id) { $options['location_ns'] = $location->location_ns; $options['location_id'] = $location->location_id; } } } // Atom categories <-> hashtags foreach ($activity->categories as $cat) { if ($cat->term) { $term = common_canonical_tag($cat->term); if ($term) { $options['tags'][] = $term; } } } // Atom enclosures -> attachment URLs foreach ($activity->enclosures as $href) { // @fixme save these locally or....? $options['urls'][] = $href; } try { $saved = Notice::saveNew($oprofile->profile_id, $content, 'ostatus', $options); if ($saved) { Ostatus_source::saveNew($saved, $this, $method); if (!empty($attachment)) { File_to_post::processNew($attachment->id, $saved->id); } } } catch (Exception $e) { common_log(LOG_ERR, "OStatus save of remote message {$sourceUri} failed: " . $e->getMessage()); throw $e; } common_log(LOG_INFO, "OStatus saved remote message {$sourceUri} as notice id {$saved->id}"); return $saved; }
/** * Update a list * * @return boolean success */ function handlePut() { if ($this->auth_user->id != $this->list->tagger) { $this->clientError(_('You cannot update lists that do not belong to you.'), 401, $this->format); } $new_list = clone $this->list; $new_list->tag = common_canonical_tag($this->arg('name')); $new_list->description = common_canonical_tag($this->arg('description')); $new_list->private = $this->arg('mode') === 'private' ? true : false; $result = $new_list->update($this->list); if (!$result) { $this->clientError(_('An error occured.'), 503, $this->format); } switch ($this->format) { case 'xml': $this->showSingleXmlList($new_list); break; case 'json': $this->showSingleJsonList($new_list); break; default: $this->clientError(_('API method not found.'), 404, $this->format); break; } }
protected function doPost() { $tagstring = $this->trimmed('tags'); $token = $this->trimmed('token'); if (Event::handle('StartSavePeopletags', array($this, $tagstring))) { $tags = array(); $tag_priv = array(); if (is_string($tagstring) && strlen($tagstring) > 0) { $tags = preg_split('/[\\s,]+/', $tagstring); foreach ($tags as &$tag) { $private = @$tag[0] === '.'; $tag = common_canonical_tag($tag); if (!common_valid_profile_tag($tag)) { // TRANS: Form validation error displayed if a given tag is invalid. // TRANS: %s is the invalid tag. throw new ClientException(sprintf(_('Invalid tag: "%s".'), $tag)); } $tag_priv[$tag] = $private; } } $result = Profile_tag::setTags($this->scoped->getID(), $this->target->getID(), $tags, $tag_priv); if (!$result) { throw new ServerException('The tags could not be saved.'); } if ($this->boolean('ajax')) { $this->startHTML('text/xml;charset=utf-8'); $this->elementStart('head'); $this->element('title', null, _m('TITLE', 'Tags')); $this->elementEnd('head'); $this->elementStart('body'); if ($this->scoped->id == $this->target->id) { $widget = new SelftagsWidget($this, $this->scoped, $this->target); $widget->show(); } else { $widget = new PeopletagsWidget($this, $this->scoped, $this->target); $widget->show(); } $this->elementEnd('body'); $this->endHTML(); } else { // TRANS: Success message if lists are saved. $this->msg = _('Lists saved.'); $this->showForm(); } Event::handle('EndSavePeopletags', array($this, $tagstring)); } }
/** * Update a list * * @return boolean success */ function handlePut() { if ($this->auth_user->id != $this->list->tagger) { // TRANS: Client error displayed when trying to update another user's list. $this->clientError(_('You cannot update lists that do not belong to you.'), 401); } $new_list = clone $this->list; $new_list->tag = common_canonical_tag($this->arg('name')); $new_list->description = common_canonical_tag($this->arg('description')); $new_list->private = $this->arg('mode') === 'private' ? true : false; $result = $new_list->update($this->list); if (!$result) { // TRANS: Client error displayed when an unknown error occurs updating a list. $this->clientError(_('An error occured.'), 503); } switch ($this->format) { case 'xml': $this->showSingleXmlList($new_list); break; case 'json': $this->showSingleJsonList($new_list); break; default: // TRANS: Client error displayed when coming across a non-supported API method. $this->clientError(_('API method not found.'), 404); } }
/** * Process an incoming post activity from this remote feed. * @param Activity $activity * @param string $method 'push' or 'salmon' * @return mixed saved Notice or false * @todo FIXME: Break up this function, it's getting nasty long */ public function processPost($activity, $method) { $notice = null; $oprofile = $this->checkAuthorship($activity); if (empty($oprofile)) { return null; } // It's not always an ActivityObject::NOTE, but... let's just say it is. $note = $activity->objects[0]; // The id URI will be used as a unique identifier for for the notice, // protecting against duplicate saves. It isn't required to be a URL; // tag: URIs for instance are found in Google Buzz feeds. $sourceUri = $note->id; $dupe = Notice::staticGet('uri', $sourceUri); if ($dupe) { common_log(LOG_INFO, "OStatus: ignoring duplicate post: {$sourceUri}"); return $dupe; } // We'll also want to save a web link to the original notice, if provided. $sourceUrl = null; if ($note->link) { $sourceUrl = $note->link; } else { if ($activity->link) { $sourceUrl = $activity->link; } else { if (preg_match('!^https?://!', $note->id)) { $sourceUrl = $note->id; } } } // Use summary as fallback for content if (!empty($note->content)) { $sourceContent = $note->content; } else { if (!empty($note->summary)) { $sourceContent = $note->summary; } else { if (!empty($note->title)) { $sourceContent = $note->title; } else { // @todo FIXME: Fetch from $sourceUrl? // TRANS: Client exception. %s is a source URI. throw new ClientException(sprintf(_m('No content for notice %s.'), $sourceUri)); } } } // Get (safe!) HTML and text versions of the content $rendered = $this->purify($sourceContent); $content = html_entity_decode(strip_tags($rendered), ENT_QUOTES, 'UTF-8'); $shortened = common_shorten_links($content); // If it's too long, try using the summary, and make the // HTML an attachment. $attachment = null; if (Notice::contentTooLong($shortened)) { $attachment = $this->saveHTMLFile($note->title, $rendered); $summary = html_entity_decode(strip_tags($note->summary), ENT_QUOTES, 'UTF-8'); if (empty($summary)) { $summary = $content; } $shortSummary = common_shorten_links($summary); if (Notice::contentTooLong($shortSummary)) { $url = common_shorten_url($sourceUrl); $shortSummary = substr($shortSummary, 0, Notice::maxContent() - (mb_strlen($url) + 2)); $content = $shortSummary . ' ' . $url; // We mark up the attachment link specially for the HTML output // so we can fold-out the full version inline. // @todo FIXME i18n: This tooltip will be saved with the site's default language // TRANS: Shown when a notice is longer than supported and/or when attachments are present. At runtime // TRANS: this will usually be replaced with localised text from StatusNet core messages. $showMoreText = _m('Show more'); $attachUrl = common_local_url('attachment', array('attachment' => $attachment->id)); $rendered = common_render_text($shortSummary) . '<a href="' . htmlspecialchars($attachUrl) . '"' . ' class="attachment more"' . ' title="' . htmlspecialchars($showMoreText) . '">' . '…' . '</a>'; } } $options = array('is_local' => Notice::REMOTE, 'url' => $sourceUrl, 'uri' => $sourceUri, 'rendered' => $rendered, 'replies' => array(), 'groups' => array(), 'peopletags' => array(), 'tags' => array(), 'urls' => array()); // Check for optional attributes... if (!empty($activity->time)) { $options['created'] = common_sql_date($activity->time); } if ($activity->context) { // Any individual or group attn: targets? $replies = $activity->context->attention; $options['groups'] = $this->filterReplies($oprofile, $replies); $options['replies'] = $replies; // Maintain direct reply associations // @todo FIXME: What about conversation ID? if (!empty($activity->context->replyToID)) { $orig = Notice::staticGet('uri', $activity->context->replyToID); if (!empty($orig)) { $options['reply_to'] = $orig->id; } } $location = $activity->context->location; if ($location) { $options['lat'] = $location->lat; $options['lon'] = $location->lon; if ($location->location_id) { $options['location_ns'] = $location->location_ns; $options['location_id'] = $location->location_id; } } } if ($this->isPeopletag()) { $options['peopletags'][] = $this->localPeopletag(); } // Atom categories <-> hashtags foreach ($activity->categories as $cat) { if ($cat->term) { $term = common_canonical_tag($cat->term); if ($term) { $options['tags'][] = $term; } } } // Atom enclosures -> attachment URLs foreach ($activity->enclosures as $href) { // @todo FIXME: Save these locally or....? $options['urls'][] = $href; } try { $saved = Notice::saveNew($oprofile->profile_id, $content, 'ostatus', $options); if ($saved) { Ostatus_source::saveNew($saved, $this, $method); if (!empty($attachment)) { File_to_post::processNew($attachment->id, $saved->id); } } } catch (Exception $e) { common_log(LOG_ERR, "OStatus save of remote message {$sourceUri} failed: " . $e->getMessage()); throw $e; } common_log(LOG_INFO, "OStatus saved remote message {$sourceUri} as notice id {$saved->id}"); return $saved; }
/** * Record this notice to the given group inboxes for delivery. * Overrides the regular parsing of !group markup. * * @param string $group_ids * @fixme might prefer URIs as identifiers, as for replies? * best with generalizations on user_group to support * remote groups better. */ function saveKnownGroups(array $group_ids) { $groups = array(); foreach (array_unique($group_ids) as $id) { $group = User_group::getKV('id', $id); if ($group instanceof User_group) { common_log(LOG_DEBUG, "Local delivery to group id {$id}, {$group->nickname}"); $result = $this->addToGroupInbox($group); if (!$result) { common_log_db_error($gi, 'INSERT', __FILE__); } if (common_config('group', 'addtag')) { // we automatically add a tag for every group name, too $tag = Notice_tag::pkeyGet(array('tag' => common_canonical_tag($group->nickname), 'notice_id' => $this->id)); if (is_null($tag)) { $this->saveTag($group->nickname); } } $groups[] = clone $group; } else { common_log(LOG_ERR, "Local delivery to group id {$id} skipped, doesn't exist"); } } return $groups; }
function postNote($user, $author, $activity) { $note = $activity->objects[0]; $sourceUri = $note->id; $notice = Notice::getKV('uri', $sourceUri); if ($notice instanceof Notice) { common_log(LOG_INFO, "Notice {$sourceUri} already exists."); if ($this->trusted) { $profile = $notice->getProfile(); $uri = $profile->getUri(); if ($uri === $author->id) { common_log(LOG_INFO, sprintf('Updating notice author from %s to %s', $author->id, $user->getUri())); $orig = clone $notice; $notice->profile_id = $user->id; $notice->update($orig); return; } else { // TRANS: Client exception thrown when trying to import a notice by another user. // TRANS: %1$s is the source URI of the notice, %2$s is the URI of the author. throw new ClientException(sprintf(_('Already know about notice %1$s and ' . ' it has a different author %2$s.'), $sourceUri, $uri)); } } else { // TRANS: Client exception thrown when trying to overwrite the author information for a non-trusted user during import. throw new ClientException(_('Not overwriting author info for non-trusted user.')); } } // Use summary as fallback for content if (!empty($note->content)) { $sourceContent = $note->content; } else { if (!empty($note->summary)) { $sourceContent = $note->summary; } else { if (!empty($note->title)) { $sourceContent = $note->title; } else { // @fixme fetch from $sourceUrl? // TRANS: Client exception thrown when trying to import a notice without content. // TRANS: %s is the notice URI. throw new ClientException(sprintf(_('No content for notice %s.'), $sourceUri)); } } } // Get (safe!) HTML and text versions of the content $rendered = common_purify($sourceContent); $content = common_strip_html($rendered); $shortened = $user->shortenLinks($content); $options = array('is_local' => Notice::LOCAL_PUBLIC, 'uri' => $sourceUri, 'rendered' => $rendered, 'replies' => array(), 'groups' => array(), 'tags' => array(), 'urls' => array(), 'distribute' => false); // Check for optional attributes... if (!empty($activity->time)) { $options['created'] = common_sql_date($activity->time); } if ($activity->context) { // Any individual or group attn: targets? list($options['groups'], $options['replies']) = $this->filterAttention($activity->context->attention); // Maintain direct reply associations // @fixme what about conversation ID? if (!empty($activity->context->replyToID)) { $orig = Notice::getKV('uri', $activity->context->replyToID); if ($orig instanceof Notice) { $options['reply_to'] = $orig->id; } } $location = $activity->context->location; if ($location) { $options['lat'] = $location->lat; $options['lon'] = $location->lon; if ($location->location_id) { $options['location_ns'] = $location->location_ns; $options['location_id'] = $location->location_id; } } } // Atom categories <-> hashtags foreach ($activity->categories as $cat) { if ($cat->term) { $term = common_canonical_tag($cat->term); if ($term) { $options['tags'][] = $term; } } } // Atom enclosures -> attachment URLs foreach ($activity->enclosures as $href) { // @fixme save these locally or....? $options['urls'][] = $href; } common_log(LOG_INFO, "Saving notice {$options['uri']}"); $saved = Notice::saveNew($user->id, $content, 'restore', $options); return $saved; }
function trySave() { $tag = common_canonical_tag($this->trimmed('tag')); $description = $this->trimmed('description'); $private = $this->boolean('private'); $delete = $this->arg('delete'); $confirm = $this->arg('confirm'); $cancel = $this->arg('cancel'); if ($delete && $cancel) { // TRANS: Form validation error displayed if the form data for deleting a tag was incorrect. $this->showForm(_('Delete aborted.')); return; } $set_private = $private && $this->peopletag->private != $private; if ($delete && !$confirm) { // TRANS: Text in confirmation dialog for deleting a tag. $this->showConfirm(_('Deleting this tag will permanantly remove ' . 'all its subscription and membership records. ' . 'Do you still want to continue?'), array('delete' => 1)); return; } else { if (common_valid_tag($tag)) { // TRANS: Form validation error displayed if a given tag is invalid. $this->showForm(_('Invalid tag.')); return; } else { if ($tag != $this->peopletag->tag && $this->tagExists($tag)) { // TRANS: Form validation error displayed if a given tag is already present. // TRANS: %s is the already present tag. $this->showForm(sprintf(_('You already have a tag named %s.'), $tag)); return; } else { if (Profile_list::descriptionTooLong($description)) { $this->showForm(sprintf(_m('Description is too long (maximum %d character).', 'Description is too long (maximum %d characters).', Profile_list::maxDescription()), Profile_list::maxDescription())); return; } else { if ($set_private && !$confirm && !$cancel) { $fwd = array('tag' => $tag, 'description' => $description, 'private' => (int) $private); // TRANS: Text in confirmation dialog for setting a tag from public to private. $this->showConfirm(_('Setting a public tag as private will ' . 'permanently remove all the existing ' . 'subscriptions to it. Do you still want to continue?'), $fwd); return; } } } } } $this->peopletag->query('BEGIN'); $orig = clone $this->peopletag; $this->peopletag->tag = $tag; $this->peopletag->description = $description; if (!$set_private || $confirm) { $this->peopletag->private = $private; } $result = $this->peopletag->update($orig); if (!$result) { common_log_db_error($this->group, 'UPDATE', __FILE__); // TRANS: Server error displayed when updating a list fails. $this->serverError(_('Could not update list.')); } $this->peopletag->query('COMMIT'); if ($set_private && $confirm) { Profile_tag_subscription::cleanup($this->peopletag); } if ($delete) { // This might take quite a bit of time. $this->peopletag->delete(); // send home. common_redirect(common_local_url('all', array('nickname' => $this->tagger->nickname)), 303); } if ($tag != $orig->tag) { common_redirect(common_local_url('editpeopletag', array('tagger' => $this->tagger->nickname, 'tag' => $tag)), 303); } else { // TRANS: Edit list form success message. $this->showForm(_('Options saved.')); } }
/** * 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; }
public static function provider() { return array(array('not a link :: no way', 'not a link :: no way'), array('link http://www.somesite.com/xyz/35637563@N00/52803365/ link', 'link <a href="http://www.somesite.com/xyz/35637563@N00/52803365/" title="http://www.somesite.com/xyz/35637563@N00/52803365/" rel="external">http://www.somesite.com/xyz/35637563@N00/52803365/</a> link'), array('http://127.0.0.1', '<a href="http://127.0.0.1/" title="http://127.0.0.1/" rel="external">http://127.0.0.1</a>'), array('127.0.0.1', '<a href="http://127.0.0.1/" title="http://127.0.0.1/" rel="external">127.0.0.1</a>'), array('127.0.0.1:99', '<a href="http://127.0.0.1:99/" title="http://127.0.0.1:99/" rel="external">127.0.0.1:99</a>'), array('127.0.0.1/Name:test.php', '<a href="http://127.0.0.1/Name:test.php" title="http://127.0.0.1/Name:test.php" rel="external">127.0.0.1/Name:test.php</a>'), array('127.0.0.1/~test', '<a href="http://127.0.0.1/~test" title="http://127.0.0.1/~test" rel="external">127.0.0.1/~test</a>'), array('127.0.0.1/+test', '<a href="http://127.0.0.1/+test" title="http://127.0.0.1/+test" rel="external">127.0.0.1/+test</a>'), array('127.0.0.1/$test', '<a href="http://127.0.0.1/$test" title="http://127.0.0.1/$test" rel="external">127.0.0.1/$test</a>'), array('127.0.0.1/\'test', '<a href="http://127.0.0.1/\'test" title="http://127.0.0.1/\'test" rel="external">127.0.0.1/\'test</a>'), array('127.0.0.1/"test', '<a href="http://127.0.0.1/" title="http://127.0.0.1/" rel="external">127.0.0.1/</a>"test'), array('127.0.0.1/test"test', '<a href="http://127.0.0.1/test" title="http://127.0.0.1/test" rel="external">127.0.0.1/test</a>"test'), array('127.0.0.1/-test', '<a href="http://127.0.0.1/-test" title="http://127.0.0.1/-test" rel="external">127.0.0.1/-test</a>'), array('127.0.0.1/_test', '<a href="http://127.0.0.1/_test" title="http://127.0.0.1/_test" rel="external">127.0.0.1/_test</a>'), array('127.0.0.1/!test', '<a href="http://127.0.0.1/!test" title="http://127.0.0.1/!test" rel="external">127.0.0.1/!test</a>'), array('127.0.0.1/*test', '<a href="http://127.0.0.1/*test" title="http://127.0.0.1/*test" rel="external">127.0.0.1/*test</a>'), array('127.0.0.1/test%20stuff', '<a href="http://127.0.0.1/test%20stuff" title="http://127.0.0.1/test%20stuff" rel="external">127.0.0.1/test%20stuff</a>'), array('http://[::1]:99/test.php', '<a href="http://[::1]:99/test.php" title="http://[::1]:99/test.php" rel="external">http://[::1]:99/test.php</a>'), array('http://::1/test.php', '<a href="http://::1/test.php" title="http://::1/test.php" rel="external">http://::1/test.php</a>'), array('http://::1', '<a href="http://::1/" title="http://::1/" rel="external">http://::1</a>'), array('2001:4978:1b5:0:21d:e0ff:fe66:59ab/test.php', '<a href="http://*****:*****@example.com', '<a href="mailto:user@example.com" title="mailto:user@example.com" rel="external">user@example.com</a>'), array('*****@*****.**', '<a href="mailto:user_name+other@example.com" title="mailto:user_name+other@example.com" rel="external">user_name+other@example.com</a>'), array('mailto:user@example.com', '<a href="mailto:user@example.com" title="mailto:user@example.com" rel="external">mailto:user@example.com</a>'), array('mailto:user@example.com?subject=test', '<a href="mailto:user@example.com?subject=test" title="mailto:user@example.com?subject=test" rel="external">mailto:user@example.com?subject=test</a>'), array('xmpp:user@example.com', '<a href="xmpp:user@example.com" title="xmpp:user@example.com" rel="external">xmpp:user@example.com</a>'), array('#example', '#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('example'))) . '" rel="tag">example</a></span>'), array('#example.com', '#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('example.com'))) . '" rel="tag">example.com</a></span>'), array('#.net', '#<span class="tag"><a href="' . common_local_url('tag', array('tag' => common_canonical_tag('.net'))) . '" rel="tag">.net</a></span>'), array('http://example', '<a href="http://example/" title="http://example/" rel="external">http://example</a>'), array('http://3xampl3', '<a href="http://3xampl3/" title="http://3xampl3/" rel="external">http://3xampl3</a>'), array('http://example/', '<a href="http://example/" title="http://example/" rel="external">http://example/</a>'), array('http://example/path', '<a href="http://example/path" title="http://example/path" rel="external">http://example/path</a>'), array('http://example.com', '<a href="http://example.com/" title="http://example.com/" rel="external">http://example.com</a>'), array('https://example.com', '<a href="https://example.com/" title="https://example.com/" rel="external">https://example.com</a>'), array('ftp://example.com', '<a href="ftp://example.com/" title="ftp://example.com/" rel="external">ftp://example.com</a>'), array('ftps://example.com', '<a href="ftps://example.com/" title="ftps://example.com/" rel="external">ftps://example.com</a>'), array('http://user@example.com', '<a href="http://user@example.com/" title="http://user@example.com/" rel="external">http://user@example.com</a>'), array('http://*****:*****@example.com', '<a href="http://*****:*****@example.com/" title="http://*****:*****@example.com/" rel="external">http://user:pass@example.com</a>'), array('http://example.com:8080', '<a href="http://example.com:8080/" title="http://example.com:8080/" rel="external">http://example.com:8080</a>'), array('http://example.com:8080/test.php', '<a href="http://example.com:8080/test.php" title="http://example.com:8080/test.php" rel="external">http://example.com:8080/test.php</a>'), array('example.com:8080/test.php', '<a href="http://example.com:8080/test.php" title="http://example.com:8080/test.php" rel="external">example.com:8080/test.php</a>'), array('http://www.example.com', '<a href="http://www.example.com/" title="http://www.example.com/" rel="external">http://www.example.com</a>'), array('http://example.com/', '<a href="http://example.com/" title="http://example.com/" rel="external">http://example.com/</a>'), array('http://example.com/path', '<a href="http://example.com/path" title="http://example.com/path" rel="external">http://example.com/path</a>'), array('http://example.com/path.html', '<a href="http://example.com/path.html" title="http://example.com/path.html" rel="external">http://example.com/path.html</a>'), array('http://example.com/path.html#fragment', '<a href="http://example.com/path.html#fragment" title="http://example.com/path.html#fragment" rel="external">http://example.com/path.html#fragment</a>'), array('http://example.com/path.php?foo=bar&bar=foo', '<a href="http://example.com/path.php?foo=bar&bar=foo" title="http://example.com/path.php?foo=bar&bar=foo" rel="external">http://example.com/path.php?foo=bar&bar=foo</a>'), array('http://example.com.', '<a href="http://example.com/" title="http://example.com/" rel="external">http://example.com</a>.'), array('http://müllärör.de', '<a href="http://müllärör.de/" title="http://müllärör.de/" rel="external">http://müllärör.de</a>'), array('http://ﺱﺲﺷ.com', '<a href="http://ﺱﺲﺷ.com/" title="http://ﺱﺲﺷ.com/" rel="external">http://ﺱﺲﺷ.com</a>'), array('http://сделаткартинки.com', '<a href="http://сделаткартинки.com/" title="http://сделаткартинки.com/" rel="external">http://сделаткартинки.com</a>'), array('http://tūdaliņ.lv', '<a href="http://tūdaliņ.lv/" title="http://tūdaliņ.lv/" rel="external">http://tūdaliņ.lv</a>'), array('http://brændendekærlighed.com', '<a href="http://brændendekærlighed.com/" title="http://brændendekærlighed.com/" rel="external">http://brændendekærlighed.com</a>'), array('http://あーるいん.com', '<a href="http://あーるいん.com/" title="http://あーるいん.com/" rel="external">http://あーるいん.com</a>'), array('http://예비교사.com', '<a href="http://예비교사.com/" title="http://예비교사.com/" rel="external">http://예비교사.com</a>'), array('http://example.com.', '<a href="http://example.com/" title="http://example.com/" rel="external">http://example.com</a>.'), array('http://example.com?', '<a href="http://example.com/" title="http://example.com/" rel="external">http://example.com</a>?'), array('http://example.com!', '<a href="http://example.com/" title="http://example.com/" rel="external">http://example.com</a>!'), array('http://example.com,', '<a href="http://example.com/" title="http://example.com/" rel="external">http://example.com</a>,'), array('http://example.com;', '<a href="http://example.com/" title="http://example.com/" rel="external">http://example.com</a>;'), array('http://example.com:', '<a href="http://example.com/" title="http://example.com/" rel="external">http://example.com</a>:'), array('\'http://example.com\'', '\'<a href="http://example.com/" title="http://example.com/" rel="external">http://example.com</a>\''), array('"http://example.com"', '"<a href="http://example.com/" title="http://example.com/" rel="external">http://example.com</a>"'), array('"http://example.com/"', '"<a href="http://example.com/" title="http://example.com/" rel="external">http://example.com/</a>"'), array('http://example.com', '<a href="http://example.com/" title="http://example.com/" rel="external">http://example.com</a>'), array('(http://example.com)', '(<a href="http://example.com/" title="http://example.com/" rel="external">http://example.com</a>)'), array('[http://example.com]', '[<a href="http://example.com/" title="http://example.com/" rel="external">http://example.com</a>]'), array('<http://example.com>', '<<a href="http://example.com/" title="http://example.com/" rel="external">http://example.com</a>>'), array('http://example.com/path/(foo)/bar', '<a href="http://example.com/path/(foo)/bar" title="http://example.com/path/(foo)/bar" rel="external">http://example.com/path/(foo)/bar</a>'), array('http://example.com/path/[foo]/bar', '<a href="http://example.com/path/" title="http://example.com/path/" rel="external">http://example.com/path/</a>[foo]/bar'), array('http://example.com/path/foo/(bar)', '<a href="http://example.com/path/foo/(bar)" title="http://example.com/path/foo/(bar)" rel="external">http://example.com/path/foo/(bar)</a>'), array('http://example.com/path/foo/[bar]', '<a href="http://example.com/path/foo/" title="http://example.com/path/foo/" rel="external">http://example.com/path/foo/</a>[bar]'), array('Hey, check out my cool site http://example.com okay?', 'Hey, check out my cool site <a href="http://example.com/" title="http://example.com/" rel="external">http://example.com</a> okay?'), array('What about parens (e.g. http://example.com/path/foo/(bar))?', 'What about parens (e.g. <a href="http://example.com/path/foo/(bar)" title="http://example.com/path/foo/(bar)" rel="external">http://example.com/path/foo/(bar)</a>)?'), array('What about parens (e.g. http://example.com/path/foo/(bar)?', 'What about parens (e.g. <a href="http://example.com/path/foo/(bar)" title="http://example.com/path/foo/(bar)" rel="external">http://example.com/path/foo/(bar)</a>?'), array('What about parens (e.g. http://example.com/path/foo/(bar).)?', 'What about parens (e.g. <a href="http://example.com/path/foo/(bar)" title="http://example.com/path/foo/(bar)" rel="external">http://example.com/path/foo/(bar)</a>.)?'), array('What about parens (e.g. http://example.com/path/(foo,bar)?', 'What about parens (e.g. <a href="http://example.com/path/(foo,bar)" title="http://example.com/path/(foo,bar)" rel="external">http://example.com/path/(foo,bar)</a>?'), array('Unbalanced too (e.g. http://example.com/path/((((foo)/bar)?', 'Unbalanced too (e.g. <a href="http://example.com/path/((((foo)/bar)" title="http://example.com/path/((((foo)/bar)" rel="external">http://example.com/path/((((foo)/bar)</a>?'), array('Unbalanced too (e.g. http://example.com/path/(foo))))/bar)?', 'Unbalanced too (e.g. <a href="http://example.com/path/(foo))))/bar" title="http://example.com/path/(foo))))/bar" rel="external">http://example.com/path/(foo))))/bar</a>)?'), array('Unbalanced too (e.g. http://example.com/path/foo/((((bar)?', 'Unbalanced too (e.g. <a href="http://example.com/path/foo/((((bar)" title="http://example.com/path/foo/((((bar)" rel="external">http://example.com/path/foo/((((bar)</a>?'), array('Unbalanced too (e.g. http://example.com/path/foo/(bar))))?', 'Unbalanced too (e.g. <a href="http://example.com/path/foo/(bar)" title="http://example.com/path/foo/(bar)" rel="external">http://example.com/path/foo/(bar)</a>)))?'), array('example.com', '<a href="http://example.com/" title="http://example.com/" rel="external">example.com</a>'), array('example.org', '<a href="http://example.org/" title="http://example.org/" rel="external">example.org</a>'), array('example.co.uk', '<a href="http://example.co.uk/" title="http://example.co.uk/" rel="external">example.co.uk</a>'), array('www.example.co.uk', '<a href="http://www.example.co.uk/" title="http://www.example.co.uk/" rel="external">www.example.co.uk</a>'), array('farm1.images.example.co.uk', '<a href="http://farm1.images.example.co.uk/" title="http://farm1.images.example.co.uk/" rel="external">farm1.images.example.co.uk</a>'), array('example.museum', '<a href="http://example.museum/" title="http://example.museum/" rel="external">example.museum</a>'), array('example.travel', '<a href="http://example.travel/" title="http://example.travel/" rel="external">example.travel</a>'), array('example.com.', '<a href="http://example.com/" title="http://example.com/" rel="external">example.com</a>.'), array('example.com?', '<a href="http://example.com/" title="http://example.com/" rel="external">example.com</a>?'), array('example.com!', '<a href="http://example.com/" title="http://example.com/" rel="external">example.com</a>!'), array('example.com,', '<a href="http://example.com/" title="http://example.com/" rel="external">example.com</a>,'), array('example.com;', '<a href="http://example.com/" title="http://example.com/" rel="external">example.com</a>;'), array('example.com:', '<a href="http://example.com/" title="http://example.com/" rel="external">example.com</a>:'), array('\'example.com\'', '\'<a href="http://example.com/" title="http://example.com/" rel="external">example.com</a>\''), array('"example.com"', '"<a href="http://example.com/" title="http://example.com/" rel="external">example.com</a>"'), array('example.com', '<a href="http://example.com/" title="http://example.com/" rel="external">example.com</a>'), array('(example.com)', '(<a href="http://example.com/" title="http://example.com/" rel="external">example.com</a>)'), array('[example.com]', '[<a href="http://example.com/" title="http://example.com/" rel="external">example.com</a>]'), array('<example.com>', '<<a href="http://example.com/" title="http://example.com/" rel="external">example.com</a>>'), array('Hey, check out my cool site example.com okay?', 'Hey, check out my cool site <a href="http://example.com/" title="http://example.com/" rel="external">example.com</a> okay?'), array('Hey, check out my cool site example.com.I made it.', 'Hey, check out my cool site <a href="http://example.com/" title="http://example.com/" rel="external">example.com</a>.I made it.'), array('Hey, check out my cool site example.com.Funny thing...', 'Hey, check out my cool site <a href="http://example.com/" title="http://example.com/" rel="external">example.com</a>.Funny thing...'), array('Hey, check out my cool site example.com.You will love it.', 'Hey, check out my cool site <a href="http://example.com/" title="http://example.com/" rel="external">example.com</a>.You will love it.'), array('What about parens (e.g. example.com/path/foo/(bar))?', 'What about parens (e.g. <a href="http://example.com/path/foo/(bar)" title="http://example.com/path/foo/(bar)" rel="external">example.com/path/foo/(bar)</a>)?'), array('What about parens (e.g. example.com/path/foo/(bar)?', 'What about parens (e.g. <a href="http://example.com/path/foo/(bar)" title="http://example.com/path/foo/(bar)" rel="external">example.com/path/foo/(bar)</a>?'), array('What about parens (e.g. example.com/path/foo/(bar).)?', 'What about parens (e.g. <a href="http://example.com/path/foo/(bar)" title="http://example.com/path/foo/(bar)" rel="external">example.com/path/foo/(bar)</a>.)?'), array('What about parens (e.g. example.com/path/(foo,bar)?', 'What about parens (e.g. <a href="http://example.com/path/(foo,bar)" title="http://example.com/path/(foo,bar)" rel="external">example.com/path/(foo,bar)</a>?'), array('file.ext', 'file.ext'), array('file.html', 'file.html'), array('file.php', 'file.php')); }