function asString() { if (!empty($this->formatted)) { $xs = new XMLStringer(true); $xs->elementStart('poco:address'); $xs->element('poco:formatted', null, common_xml_safe_str($this->formatted)); $xs->elementEnd('poco:address'); return $xs->getString(); } return null; }
function asString() { $attribs = array(); if ($this->term !== null) { $attribs['term'] = $this->term; } if ($this->scheme !== null) { $attribs['scheme'] = $this->scheme; } if ($this->label !== null) { $attribs['label'] = $this->label; } $xs = new XMLStringer(); $xs->element('category', $attribs); return $xs->asString(); }
function asString() { $xs = new XMLStringer(true); $xs->elementStart('poco:urls'); $xs->element('poco:type', null, $this->type); $xs->element('poco:value', null, $this->value); if (!empty($this->primary)) { $xs->element('poco:primary', null, 'true'); } $xs->elementEnd('poco:urls'); return $xs->getString(); }
public function toXML($env) { $xs = new XMLStringer(); $xs->startXML(); $xs->elementStart('me:env', array('xmlns:me' => MagicEnvelope::NS)); $xs->element('me:data', array('type' => $env['data_type']), $env['data']); $xs->element('me:encoding', null, $env['encoding']); $xs->element('me:alg', null, $env['alg']); $xs->element('me:sig', null, $env['sig']); $xs->elementEnd('me:env'); $string = $xs->getString(); common_debug($string); return $string; }
/** * extra information for XMPP messages, as defined by Twitter * * @param Profile $profile Profile of the sending user * @param Notice $notice Notice being sent * * @return string Extra information (Atom, HTML, addresses) in string format */ protected function format_entry(Notice $notice) { $profile = $notice->getProfile(); $entry = $notice->asAtomEntry(true, true); $xs = new XMLStringer(); $xs->elementStart('html', array('xmlns' => 'http://jabber.org/protocol/xhtml-im')); $xs->elementStart('body', array('xmlns' => 'http://www.w3.org/1999/xhtml')); $xs->element('a', array('href' => $profile->profileurl), $profile->nickname); try { $parent = $notice->getParent(); $orig_profile = $parent->getProfile(); $orig_profurl = $orig_profile->getUrl(); $xs->text(" => "); $xs->element('a', array('href' => $orig_profurl), $orig_profile->nickname); $xs->text(": "); } catch (InvalidUrlException $e) { $xs->text(sprintf(' => %s', $orig_profile->nickname)); } catch (NoParentNoticeException $e) { $xs->text(": "); } if (!empty($notice->rendered)) { $notice->rendered = str_replace("\t", "", $notice->rendered); $xs->raw($notice->rendered); } else { $xs->raw(common_render_content($notice->content, $notice)); } $xs->text(" "); $xs->element('a', array('href' => common_local_url('conversation', array('id' => $notice->conversation)) . '#notice-' . $notice->id), sprintf(_m('[%u]'), $notice->id)); $xs->elementEnd('body'); $xs->elementEnd('html'); $html = $xs->getString(); return $html . ' ' . $entry; }
/** * 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'); } }
/** * Create an <me:env> XML representation of the envelope. * * @return string representation of XML document */ public function toXML(Profile $target = null, $flavour = null) { $xs = new XMLStringer(); $xs->startXML(); // header, to point out it's not HTML or anything... if (Event::handle('StartMagicEnvelopeToXML', array($this, $xs, $flavour, $target))) { // fall back to our default, normal Magic Envelope XML. // the $xs element _may_ have had elements added, or could get in the end event $xs->elementStart('me:env', array('xmlns:me' => self::NS)); $xs->element('me:data', array('type' => $this->data_type), $this->data); $xs->element('me:encoding', null, $this->encoding); $xs->element('me:alg', null, $this->alg); $xs->element('me:sig', null, $this->getSignature()); $xs->elementEnd('me:env'); Event::handle('EndMagicEnvelopeToXML', array($this, $xs, $flavour, $target)); } return $xs->getString(); }
/** * Send a summary email to the user * * @param mixed $object * @return boolean true on success, false on failure */ function handle($user_id) { // Skip if they've asked not to get summaries $ess = Email_summary_status::staticGet('user_id', $user_id); if (!empty($ess) && !$ess->send_summary) { common_log(LOG_INFO, sprintf('Not sending email summary for user %s by request.', $user_id)); return true; } $since_id = null; if (!empty($ess)) { $since_id = $ess->last_summary_id; } $user = User::staticGet('id', $user_id); if (empty($user)) { common_log(LOG_INFO, sprintf('Not sending email summary for user %s; no such user.', $user_id)); return true; } if (empty($user->email)) { common_log(LOG_INFO, sprintf('Not sending email summary for user %s; no email address.', $user_id)); return true; } $profile = $user->getProfile(); if (empty($profile)) { common_log(LOG_WARNING, sprintf('Not sending email summary for user %s; no profile.', $user_id)); return true; } $stream = new InboxNoticeStream($user, $user->getProfile()); $notice = $stream->getNotices(0, self::MAX_NOTICES, $since_id); if (empty($notice) || $notice->N == 0) { common_log(LOG_WARNING, sprintf('Not sending email summary for user %s; no notices.', $user_id)); return true; } // XXX: This is risky fingerpoken in der objektvars, but I didn't feel like // figuring out a better way. -ESP $new_top = null; if ($notice instanceof ArrayWrapper) { $new_top = $notice->_items[0]->id; } // TRANS: Subject for e-mail. $subject = sprintf(_m('Your latest updates from %s'), common_config('site', 'name')); $out = new XMLStringer(true); $out->elementStart('html'); $out->elementStart('head'); $out->element('title', null, $subject); $out->elementEnd('head'); $out->elementStart('body'); $out->elementStart('div', array('width' => '100%', 'style' => 'background-color: #ffffff; border: 4px solid #4c609a; padding: 10px;')); $out->elementStart('div', array('style' => 'color: #ffffff; background-color: #4c609a; font-weight: bold; margin-bottom: 10px; padding: 4px;')); // TRANS: Text in e-mail summary. // TRANS: %1$s is the StatusNet sitename, %2$s is the recipient's profile name. $out->raw(sprintf(_m('Recent updates from %1$s for %2$s:'), common_config('site', 'name'), $profile->getBestName())); $out->elementEnd('div'); $out->elementStart('table', array('width' => '550px', 'style' => 'border: none; border-collapse: collapse;', 'cellpadding' => '6')); while ($notice->fetch()) { $profile = Profile::staticGet('id', $notice->profile_id); if (empty($profile)) { continue; } $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE); $out->elementStart('tr'); $out->elementStart('td', array('width' => AVATAR_STREAM_SIZE, 'height' => AVATAR_STREAM_SIZE, 'align' => 'left', 'valign' => 'top', 'style' => 'border-bottom: 1px dotted #C5CEE3; padding: 10px 6px 10px 6px;')); $out->element('img', array('src' => $avatar ? $avatar->displayUrl() : Avatar::defaultImage(AVATAR_STREAM_SIZE), 'width' => AVATAR_STREAM_SIZE, 'height' => AVATAR_STREAM_SIZE, 'alt' => $profile->getBestName())); $out->elementEnd('td'); $out->elementStart('td', array('align' => 'left', 'valign' => 'top', 'style' => 'border-bottom: 1px dotted #C5CEE3; padding: 10px 6px 10px 6px;')); $out->element('a', array('href' => $profile->profileurl), $profile->nickname); $out->text(' '); $out->raw($notice->rendered); $out->elementStart('div', array('style' => 'font-size: 0.8em; padding-top: 4px;')); $noticeurl = $notice->bestUrl(); // above should always return an URL assert(!empty($noticeurl)); $out->elementStart('a', array('rel' => 'bookmark', 'href' => $noticeurl)); $dt = common_date_iso8601($notice->created); $out->element('abbr', array('style' => 'border-bottom: none;', 'title' => $dt), common_date_string($notice->created)); $out->elementEnd('a'); if ($notice->hasConversation()) { $conv = Conversation::staticGet('id', $notice->conversation); $convurl = $conv->uri; if (!empty($convurl)) { $out->text(' '); $out->element('a', array('href' => $convurl . '#notice-' . $notice->id), _m('in context')); } } $out->elementEnd('div'); $out->elementEnd('td'); $out->elementEnd('tr'); } $out->elementEnd('table'); // TRANS: Link text for link to e-mail settings. // TRANS: %1$s is a link to the e-mail settings, %2$s is the StatusNet sitename. $out->raw("<p>" . sprintf(_m('<a href="%1$s">change your email settings for %2$s</a>'), common_local_url('emailsettings'), common_config('site', 'name')) . "</p>"); $out->elementEnd('div'); $out->elementEnd('body'); $out->elementEnd('html'); $body = $out->getString(); // FIXME: do something for people who don't like HTML email mail_to_user($user, $subject, $body, array('Content-Type' => 'text/html; charset=utf-8', 'Mime-Version' => '1.0')); if (empty($ess)) { $ess = new Email_summary_status(); $ess->user_id = $user_id; $ess->created = common_sql_now(); $ess->last_summary_id = $new_top; $ess->modified = common_sql_now(); $ess->insert(); } else { $orig = clone $ess; $ess->last_summary_id = $new_top; $ess->modified = common_sql_now(); $ess->update($orig); } return true; }
/** * 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'); } }
/** * Create an <me:env> XML representation of the envelope. * * @return string representation of XML document */ public function toXML() { $xs = new XMLStringer(); $xs->startXML(); $xs->elementStart('me:env', array('xmlns:me' => self::NS)); $xs->element('me:data', array('type' => $this->data_type), $this->data); $xs->element('me:encoding', null, $this->encoding); $xs->element('me:alg', null, $this->alg); $xs->element('me:sig', null, $this->getSignature()); $xs->elementEnd('me:env'); $string = $xs->getString(); return $string; }
/** * Send an Activity Streams notification to the remote Salmon endpoint, * if so configured. * * @param Profile $actor Actor who did the activity * @param string $verb Activity::SUBSCRIBE or Activity::JOIN * @param Object $object object of the action; must define asActivityNoun($tag) */ public function notify($actor, $verb, $object = null, $target = null) { if (!$actor instanceof Profile) { $type = gettype($actor); if ($type == 'object') { $type = get_class($actor); } // TRANS: Server exception. // TRANS: %1$s is the method name the exception occured in, %2$s is the actor type. throw new ServerException(sprintf(_m('Invalid actor passed to %1$s: %2$s.'), __METHOD__, $type)); } if ($object == null) { $object = $this; } if ($this->salmonuri) { $text = 'update'; $id = TagURI::mint('%s:%s:%s', $verb, $actor->getURI(), common_date_iso8601(time())); // @todo FIXME: Consolidate all these NS settings somewhere. $attributes = array('xmlns' => Activity::ATOM, 'xmlns:activity' => 'http://activitystrea.ms/spec/1.0/', 'xmlns:thr' => 'http://purl.org/syndication/thread/1.0', 'xmlns:georss' => 'http://www.georss.org/georss', 'xmlns:ostatus' => 'http://ostatus.org/schema/1.0', 'xmlns:poco' => 'http://portablecontacts.net/spec/1.0', 'xmlns:media' => 'http://purl.org/syndication/atommedia'); $entry = new XMLStringer(); $entry->elementStart('entry', $attributes); $entry->element('id', null, $id); $entry->element('title', null, $text); $entry->element('summary', null, $text); $entry->element('published', null, common_date_w3dtf(common_sql_now())); $entry->element('activity:verb', null, $verb); $entry->raw($actor->asAtomAuthor()); $entry->raw($actor->asActivityActor()); $entry->raw($object->asActivityNoun('object')); if ($target != null) { $entry->raw($target->asActivityNoun('target')); } $entry->elementEnd('entry'); $xml = $entry->getString(); common_log(LOG_INFO, "Posting to Salmon endpoint {$this->salmonuri}: {$xml}"); $salmon = new Salmon(); // ? return $salmon->post($this->salmonuri, $xml, $actor); } return false; }
function asString($namespace = false) { $xs = new XMLStringer(true); if ($namespace) { $attrs = array('xmlns' => 'http://www.w3.org/2005/Atom', 'xmlns:activity' => 'http://activitystrea.ms/spec/1.0/', 'xmlns:georss' => 'http://www.georss.org/georss', 'xmlns:ostatus' => 'http://ostatus.org/schema/1.0', 'xmlns:poco' => 'http://portablecontacts.net/spec/1.0', 'xmlns:media' => 'http://purl.org/syndication/atommedia'); } else { $attrs = array(); } $xs->elementStart('entry', $attrs); $xs->element('id', null, $this->id); $xs->element('title', null, $this->title); $xs->element('published', null, common_date_iso8601($this->time)); $xs->element('content', array('type' => 'html'), $this->content); if (!empty($this->summary)) { $xs->element('summary', null, $this->summary); } if (!empty($this->link)) { $xs->element('link', array('rel' => 'alternate', 'type' => 'text/html'), $this->link); } // XXX: add context $xs->elementStart('author'); $xs->element('uri', array(), $this->actor->id); if ($this->actor->title) { $xs->element('name', array(), $this->actor->title); } $xs->elementEnd('author'); $xs->raw($this->actor->asString('activity:actor')); $xs->element('activity:verb', null, $this->verb); if (!empty($this->objects)) { foreach ($this->objects as $object) { $xs->raw($object->asString()); } } if ($this->target) { $xs->raw($this->target->asString('activity:target')); } foreach ($this->categories as $cat) { $xs->raw($cat->asString()); } $xs->elementEnd('entry'); return $xs->getString(); }
/** * Returns an XML string fragment with limited profile information * as an Atom <author> element. * * Assumes that Atom has been previously set up as the base namespace. * * @param Profile $cur the current authenticated user * * @return string */ function asAtomAuthor($cur = null) { $xs = new XMLStringer(true); $xs->elementStart('author'); $xs->element('name', null, $this->nickname); $xs->element('uri', null, $this->getUri()); if ($cur != null) { $attrs = array(); $attrs['following'] = $cur->isSubscribed($this) ? 'true' : 'false'; $attrs['blocking'] = $cur->hasBlocked($this) ? 'true' : 'false'; $xs->element('statusnet:profile_info', $attrs, null); } $xs->elementEnd('author'); return $xs->getString(); }
function asAtomEntry($namespace = false, $source = false, $author = true, $cur = null) { $profile = $this->getProfile(); $xs = new XMLStringer(true); if ($namespace) { $attrs = array('xmlns' => 'http://www.w3.org/2005/Atom', 'xmlns:thr' => 'http://purl.org/syndication/thread/1.0', 'xmlns:georss' => 'http://www.georss.org/georss', 'xmlns:activity' => 'http://activitystrea.ms/spec/1.0/', 'xmlns:media' => 'http://purl.org/syndication/atommedia', 'xmlns:poco' => 'http://portablecontacts.net/spec/1.0', 'xmlns:ostatus' => 'http://ostatus.org/schema/1.0', 'xmlns:statusnet' => 'http://status.net/schema/api/1/'); } else { $attrs = array(); } if (Event::handle('StartActivityStart', array(&$this, &$xs, &$attrs))) { $xs->elementStart('entry', $attrs); Event::handle('EndActivityStart', array(&$this, &$xs, &$attrs)); } if (Event::handle('StartActivitySource', array(&$this, &$xs))) { if ($source) { $atom_feed = $profile->getAtomFeed(); if (!empty($atom_feed)) { $xs->elementStart('source'); // XXX: we should store the actual feed ID $xs->element('id', null, $atom_feed); // XXX: we should store the actual feed title $xs->element('title', null, $profile->getBestName()); $xs->element('link', array('rel' => 'alternate', 'type' => 'text/html', 'href' => $profile->profileurl)); $xs->element('link', array('rel' => 'self', 'type' => 'application/atom+xml', 'href' => $atom_feed)); $xs->element('icon', null, $profile->avatarUrl(AVATAR_PROFILE_SIZE)); $notice = $profile->getCurrentNotice(); if (!empty($notice)) { $xs->element('updated', null, self::utcDate($notice->created)); } $user = User::staticGet('id', $profile->id); if (!empty($user)) { $xs->element('link', array('rel' => 'license', 'href' => common_config('license', 'url'))); } $xs->elementEnd('source'); } } Event::handle('EndActivitySource', array(&$this, &$xs)); } $title = common_xml_safe_str($this->content); if (Event::handle('StartActivityTitle', array(&$this, &$xs, &$title))) { $xs->element('title', null, $title); Event::handle('EndActivityTitle', array($this, &$xs, $title)); } $atomAuthor = ''; if ($author) { $atomAuthor = $profile->asAtomAuthor($cur); } if (Event::handle('StartActivityAuthor', array(&$this, &$xs, &$atomAuthor))) { if (!empty($atomAuthor)) { $xs->raw($atomAuthor); Event::handle('EndActivityAuthor', array(&$this, &$xs, &$atomAuthor)); } } $actor = ''; if ($author) { $actor = $profile->asActivityActor(); } if (Event::handle('StartActivityActor', array(&$this, &$xs, &$actor))) { if (!empty($actor)) { $xs->raw($actor); Event::handle('EndActivityActor', array(&$this, &$xs, &$actor)); } } $url = $this->bestUrl(); if (Event::handle('StartActivityLink', array(&$this, &$xs, &$url))) { $xs->element('link', array('rel' => 'alternate', 'type' => 'text/html', 'href' => $url)); Event::handle('EndActivityLink', array(&$this, &$xs, $url)); } $id = $this->uri; if (Event::handle('StartActivityId', array(&$this, &$xs, &$id))) { $xs->element('id', null, $id); Event::handle('EndActivityId', array(&$this, &$xs, $id)); } $published = self::utcDate($this->created); if (Event::handle('StartActivityPublished', array(&$this, &$xs, &$published))) { $xs->element('published', null, $published); Event::handle('EndActivityPublished', array(&$this, &$xs, $published)); } $updated = $published; // XXX: notices are usually immutable if (Event::handle('StartActivityUpdated', array(&$this, &$xs, &$updated))) { $xs->element('updated', null, $updated); Event::handle('EndActivityUpdated', array(&$this, &$xs, $updated)); } $content = common_xml_safe_str($this->rendered); if (Event::handle('StartActivityContent', array(&$this, &$xs, &$content))) { $xs->element('content', array('type' => 'html'), $content); Event::handle('EndActivityContent', array(&$this, &$xs, $content)); } // Most of our notices represent POSTing a NOTE. This is the default verb // for activity streams, so we normally just leave it out. $verb = ActivityVerb::POST; if (Event::handle('StartActivityVerb', array(&$this, &$xs, &$verb))) { $xs->element('activity:verb', null, $verb); Event::handle('EndActivityVerb', array(&$this, &$xs, $verb)); } // We use the default behavior for activity streams: if there's no activity:object, // then treat the entry itself as the object. Here, you can set the type of that object, // which is normally a NOTE. $type = ActivityObject::NOTE; if (Event::handle('StartActivityDefaultObjectType', array(&$this, &$xs, &$type))) { $xs->element('activity:object-type', null, $type); Event::handle('EndActivityDefaultObjectType', array(&$this, &$xs, $type)); } // Since we usually use the entry itself as an object, we don't have an explicit // object. Some extensions may want to add them (for photo, event, music, etc.). $objects = array(); if (Event::handle('StartActivityObjects', array(&$this, &$xs, &$objects))) { foreach ($objects as $object) { $xs->raw($object->asString()); } Event::handle('EndActivityObjects', array(&$this, &$xs, $objects)); } $noticeInfoAttr = array('local_id' => $this->id); // local notice ID (useful to clients for ordering) $ns = $this->getSource(); if (!empty($ns)) { $noticeInfoAttr['source'] = $ns->code; if (!empty($ns->url)) { $noticeInfoAttr['source_link'] = $ns->url; if (!empty($ns->name)) { $noticeInfoAttr['source'] = '<a href="' . htmlspecialchars($ns->url) . '" rel="nofollow">' . htmlspecialchars($ns->name) . '</a>'; } } } if (!empty($cur)) { $noticeInfoAttr['favorite'] = $cur->hasFave($this) ? "true" : "false"; $profile = $cur->getProfile(); $noticeInfoAttr['repeated'] = $profile->hasRepeated($this->id) ? "true" : "false"; } if (!empty($this->repeat_of)) { $noticeInfoAttr['repeat_of'] = $this->repeat_of; } if (Event::handle('StartActivityNoticeInfo', array(&$this, &$xs, &$noticeInfoAttr))) { $xs->element('statusnet:notice_info', $noticeInfoAttr, null); Event::handle('EndActivityNoticeInfo', array(&$this, &$xs, $noticeInfoAttr)); } $replyNotice = null; if ($this->reply_to) { $replyNotice = Notice::staticGet('id', $this->reply_to); } if (Event::handle('StartActivityInReplyTo', array(&$this, &$xs, &$replyNotice))) { if (!empty($replyNotice)) { $xs->element('link', array('rel' => 'related', 'href' => $replyNotice->bestUrl())); $xs->element('thr:in-reply-to', array('ref' => $replyNotice->uri, 'href' => $replyNotice->bestUrl())); Event::handle('EndActivityInReplyTo', array(&$this, &$xs, $replyNotice)); } } $conv = null; if (!empty($this->conversation)) { $conv = Conversation::staticGet('id', $this->conversation); } if (Event::handle('StartActivityConversation', array(&$this, &$xs, &$conv))) { if (!empty($conv)) { $xs->element('link', array('rel' => 'ostatus:conversation', 'href' => $conv->uri)); } Event::handle('EndActivityConversation', array(&$this, &$xs, $conv)); } $replyProfiles = array(); $reply_ids = $this->getReplies(); foreach ($reply_ids as $id) { $profile = Profile::staticGet('id', $id); if (!empty($profile)) { $replyProfiles[] = $profile; } } if (Event::handle('StartActivityAttentionProfiles', array(&$this, &$xs, &$replyProfiles))) { foreach ($replyProfiles as $profile) { $xs->element('link', array('rel' => 'ostatus:attention', 'href' => $profile->getUri())); $xs->element('link', array('rel' => 'mentioned', 'href' => $profile->getUri())); } Event::handle('EndActivityAttentionProfiles', array(&$this, &$xs, $replyProfiles)); } $groups = $this->getGroups(); if (Event::handle('StartActivityAttentionGroups', array(&$this, &$xs, &$groups))) { foreach ($groups as $group) { $xs->element('link', array('rel' => 'ostatus:attention', 'href' => $group->permalink())); $xs->element('link', array('rel' => 'mentioned', 'href' => $group->permalink())); } Event::handle('EndActivityAttentionGroups', array(&$this, &$xs, $groups)); } $repeat = null; if (!empty($this->repeat_of)) { $repeat = Notice::staticGet('id', $this->repeat_of); } if (Event::handle('StartActivityForward', array(&$this, &$xs, &$repeat))) { if (!empty($repeat)) { $xs->element('ostatus:forward', array('ref' => $repeat->uri, 'href' => $repeat->bestUrl())); } Event::handle('EndActivityForward', array(&$this, &$xs, $repeat)); } $tags = $this->getTags(); if (Event::handle('StartActivityCategories', array(&$this, &$xs, &$tags))) { foreach ($tags as $tag) { $xs->element('category', array('term' => $tag)); } Event::handle('EndActivityCategories', array(&$this, &$xs, $tags)); } // Enclosures $enclosures = array(); $attachments = $this->attachments(); foreach ($attachments as $attachment) { $enclosure = $attachment->getEnclosure(); if ($enclosure) { $enclosures[] = $enclosure; } } if (Event::handle('StartActivityEnclosures', array(&$this, &$xs, &$enclosures))) { foreach ($enclosures as $enclosure) { $attributes = array('rel' => 'enclosure', 'href' => $enclosure->url, 'type' => $enclosure->mimetype, 'length' => $enclosure->size); if ($enclosure->title) { $attributes['title'] = $enclosure->title; } $xs->element('link', $attributes, null); } Event::handle('EndActivityEnclosures', array(&$this, &$xs, $enclosures)); } $lat = $this->lat; $lon = $this->lon; if (Event::handle('StartActivityGeo', array(&$this, &$xs, &$lat, &$lon))) { if (!empty($lat) && !empty($lon)) { $xs->element('georss:point', null, $lat . ' ' . $lon); } Event::handle('EndActivityGeo', array(&$this, &$xs, $lat, $lon)); } if (Event::handle('StartActivityEnd', array(&$this, &$xs))) { $xs->elementEnd('entry'); Event::handle('EndActivityEnd', array(&$this, &$xs)); } return $xs->getString(); }
/** * extra information for XMPP messages, as defined by Twitter * * @param Profile $profile Profile of the sending user * @param Notice $notice Notice being sent * * @return string Extra information (Atom, HTML, addresses) in string format */ function jabber_format_entry($profile, $notice) { $entry = $notice->asAtomEntry(true, true); $xs = new XMLStringer(); $xs->elementStart('html', array('xmlns' => 'http://jabber.org/protocol/xhtml-im')); $xs->elementStart('body', array('xmlns' => 'http://www.w3.org/1999/xhtml')); $xs->element('a', array('href' => $profile->profileurl), $profile->nickname); $xs->text(": "); if (!empty($notice->rendered)) { $xs->raw($notice->rendered); } else { $xs->raw(common_render_content($notice->content, $notice)); } $xs->text(" "); $xs->element('a', array('href' => common_local_url('conversation', array('id' => $notice->conversation)) . '#notice-' . $notice->id), sprintf(_('[%s]'), $notice->id)); $xs->elementEnd('body'); $xs->elementEnd('html'); $html = $xs->getString(); return $html . ' ' . $entry; }
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; }
function asAtomEntry($namespace = false, $source = false, $author = true) { $profile = $this->getProfile(); $xs = new XMLStringer(true); if ($namespace) { $attrs = array('xmlns' => 'http://www.w3.org/2005/Atom', 'xmlns:thr' => 'http://purl.org/syndication/thread/1.0', 'xmlns:georss' => 'http://www.georss.org/georss', 'xmlns:activity' => 'http://activitystrea.ms/spec/1.0/', 'xmlns:media' => 'http://purl.org/syndication/atommedia', 'xmlns:poco' => 'http://portablecontacts.net/spec/1.0', 'xmlns:ostatus' => 'http://ostatus.org/schema/1.0'); } else { $attrs = array(); } $xs->elementStart('entry', $attrs); if ($source) { $xs->elementStart('source'); $xs->element('id', null, $profile->profileurl); $xs->element('title', null, $profile->nickname . " - " . common_config('site', 'name')); $xs->element('link', array('href' => $profile->profileurl)); $user = User::staticGet('id', $profile->id); if (!empty($user)) { $atom_feed = common_local_url('ApiTimelineUser', array('format' => 'atom', 'id' => $profile->nickname)); $xs->element('link', array('rel' => 'self', 'type' => 'application/atom+xml', 'href' => $profile->profileurl)); $xs->element('link', array('rel' => 'license', 'href' => common_config('license', 'url'))); } $xs->element('icon', null, $profile->avatarUrl(AVATAR_PROFILE_SIZE)); $xs->element('updated', null, common_date_w3dtf($this->created)); } if ($source) { $xs->elementEnd('source'); } $xs->element('title', null, common_xml_safe_str($this->content)); if ($author) { $xs->raw($profile->asAtomAuthor()); $xs->raw($profile->asActivityActor()); } $xs->element('link', array('rel' => 'alternate', 'type' => 'text/html', 'href' => $this->bestUrl())); $xs->element('id', null, $this->uri); $xs->element('published', null, common_date_w3dtf($this->created)); $xs->element('updated', null, common_date_w3dtf($this->created)); if ($this->reply_to) { $reply_notice = Notice::staticGet('id', $this->reply_to); if (!empty($reply_notice)) { $xs->element('link', array('rel' => 'related', 'href' => $reply_notice->bestUrl())); $xs->element('thr:in-reply-to', array('ref' => $reply_notice->uri, 'href' => $reply_notice->bestUrl())); } } if (!empty($this->conversation)) { $conv = Conversation::staticGet('id', $this->conversation); if (!empty($conv)) { $xs->element('link', array('rel' => 'ostatus:conversation', 'href' => $conv->uri)); } } $reply_ids = $this->getReplies(); foreach ($reply_ids as $id) { $profile = Profile::staticGet('id', $id); if (!empty($profile)) { $xs->element('link', array('rel' => 'ostatus:attention', 'href' => $profile->getUri())); } } $groups = $this->getGroups(); foreach ($groups as $group) { $xs->element('link', array('rel' => 'ostatus:attention', 'href' => $group->permalink())); } if (!empty($this->repeat_of)) { $repeat = Notice::staticGet('id', $this->repeat_of); if (!empty($repeat)) { $xs->element('ostatus:forward', array('ref' => $repeat->uri, 'href' => $repeat->bestUrl())); } } $xs->element('content', array('type' => 'html'), common_xml_safe_str($this->rendered)); $tag = new Notice_tag(); $tag->notice_id = $this->id; if ($tag->find()) { while ($tag->fetch()) { $xs->element('category', array('term' => $tag->tag)); } } $tag->free(); # Enclosures $attachments = $this->attachments(); if ($attachments) { foreach ($attachments as $attachment) { $enclosure = $attachment->getEnclosure(); if ($enclosure) { $attributes = array('rel' => 'enclosure', 'href' => $enclosure->url, 'type' => $enclosure->mimetype, 'length' => $enclosure->size); if ($enclosure->title) { $attributes['title'] = $enclosure->title; } $xs->element('link', $attributes, null); } } } if (!empty($this->lat) && !empty($this->lon)) { $xs->element('georss:point', null, $this->lat . ' ' . $this->lon); } $xs->elementEnd('entry'); return $xs->getString(); }
function asString() { $xs = new XMLStringer(true); $xs->element('poco:preferredUsername', null, $this->preferredUsername); $xs->element('poco:displayName', null, $this->displayName); if (!empty($this->note)) { $xs->element('poco:note', null, common_xml_safe_str($this->note)); } if (!empty($this->address)) { $xs->raw($this->address->asString()); } foreach ($this->urls as $url) { $xs->raw($url->asString()); } return $xs->getString(); }
static function estring($tag, $attrs = null, $content = null) { $xs = new XMLStringer(); $xs->element($tag, $attrs, $content); return $xs->getString(); }
static function toHTML($profile, $question, $answer) { $notice = $question->getNotice(); $out = new XMLStringer(); $cls = array('qna_answer'); if (!empty($answer->best)) { $cls[] = 'best'; } $out->elementStart('p', array('class' => implode(' ', $cls))); $out->elementStart('span', 'answer-content'); $out->raw(common_render_text($answer->content)); $out->elementEnd('span'); if (!empty($answer->revisions)) { $out->elementstart('span', 'answer-revisions'); $out->text(htmlspecialchars(sprintf(_m('%s revision', '%s revisions', $answer->revisions), $answer->revisions))); $out->elementEnd('span'); } $out->elementEnd('p'); return $out->getString(); }
/** * show the notice location * * shows the notice location in the correct language. * * If an URL is available, makes a link. Otherwise, just a span. * * @return void */ function showNoticeLocation() { $id = $this->notice->id; $location = $this->notice->getLocation(); if (empty($location)) { return; } $name = $location->getName(); $lat = $this->notice->lat; $lon = $this->notice->lon; $latlon = !empty($lat) && !empty($lon) ? $lat . ';' . $lon : ''; if (empty($name)) { $latdms = $this->decimalDegreesToDMS(abs($lat)); $londms = $this->decimalDegreesToDMS(abs($lon)); // TRANS: Used in coordinates as abbreviation of north $north = _('N'); // TRANS: Used in coordinates as abbreviation of south $south = _('S'); // TRANS: Used in coordinates as abbreviation of east $east = _('E'); // TRANS: Used in coordinates as abbreviation of west $west = _('W'); $name = sprintf(_('%1$u°%2$u\'%3$u"%4$s %5$u°%6$u\'%7$u"%8$s'), $latdms['deg'], $latdms['min'], $latdms['sec'], $lat > 0 ? $north : $south, $londms['deg'], $londms['min'], $londms['sec'], $lon > 0 ? $east : $west); } $url = $location->getUrl(); $this->out->text(' '); $this->out->elementStart('span', array('class' => 'location')); $this->out->text(_('at')); $this->out->text(' '); if (empty($url)) { $this->out->element('abbr', array('class' => 'geo', 'title' => $latlon), $name); } else { $xstr = new XMLStringer(false); $xstr->elementStart('a', array('href' => $url, 'rel' => 'external')); $xstr->element('abbr', array('class' => 'geo', 'title' => $latlon), $name); $xstr->elementEnd('a'); $this->out->raw($xstr->getString()); } $this->out->elementEnd('span'); }
function common_group_link($sender_id, $nickname) { $sender = Profile::staticGet($sender_id); $group = User_group::getForNickname($nickname, $sender); if ($sender && $group && $sender->isMember($group)) { $attrs = array('href' => $group->permalink(), 'class' => 'url'); if (!empty($group->fullname)) { $attrs['title'] = $group->fullname . ' (' . $group->nickname . ')'; } $xs = new XMLStringer(); $xs->elementStart('span', 'vcard'); $xs->elementStart('a', $attrs); $xs->element('span', 'fn nickname', $nickname); $xs->elementEnd('a'); $xs->elementEnd('span'); return $xs->getString(); } else { return $nickname; } }
function common_tag_link($tag) { $canonical = common_canonical_tag($tag); if (common_config('singleuser', 'enabled')) { // regular TagAction isn't set up in 1user mode $nickname = User::singleUserNickname(); $url = common_local_url('showstream', array('nickname' => $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(); }
function asAtomAuthor() { $xs = new XMLStringer(true); $xs->elementStart('author'); $xs->element('name', null, $this->nickname); $xs->element('uri', null, $this->permalink()); $xs->elementEnd('author'); return $xs->getString(); }
/** * extra information for XMPP messages, as defined by Twitter * * @param Profile $profile Profile of the sending user * @param Notice $notice Notice being sent * * @return string Extra information (Atom, HTML, addresses) in string format */ protected function format_entry(Notice $notice) { $profile = $notice->getProfile(); $entry = $notice->asAtomEntry(true, true); $xs = new XMLStringer(); $xs->elementStart('html', array('xmlns' => 'http://jabber.org/protocol/xhtml-im')); $xs->elementStart('body', array('xmlns' => 'http://www.w3.org/1999/xhtml')); $xs->element('a', array('href' => $profile->profileurl), $profile->nickname); try { $parent = $notice->getParent(); $orig_profile = $parent->getProfile(); $orig_profurl = $orig_profile->getUrl(); $xs->text(" => "); $xs->element('a', array('href' => $orig_profurl), $orig_profile->nickname); $xs->text(": "); } catch (InvalidUrlException $e) { $xs->text(sprintf(' => %s', $orig_profile->nickname)); } catch (NoParentNoticeException $e) { $xs->text(": "); } catch (NoResultException $e) { // Parent notice was probably deleted. $xs->text(": "); } // FIXME: Why do we replace \t with ''? is it just to make it pretty? shouldn't whitespace be handled well...? $xs->raw(str_replace("\t", "", $notice->getRendered())); $xs->text(" "); $xs->element('a', array('href' => common_local_url('conversation', array('id' => $notice->conversation)) . '#notice-' . $notice->id), sprintf(_m('[%u]'), $notice->id)); $xs->elementEnd('body'); $xs->elementEnd('html'); $html = $xs->getString(); return $html . ' ' . $entry; }
function common_at_hash_link($sender_id, $tag) { $user = User::staticGet($sender_id); if (!$user) { return $tag; } $tagged = Profile_tag::getTagged($user->id, common_canonical_tag($tag)); if ($tagged) { $url = common_local_url('subscriptions', array('nickname' => $user->nickname, 'tag' => $tag)); $xs = new XMLStringer(); $xs->elementStart('span', 'tag'); $xs->element('a', array('href' => $url, 'rel' => $tag), $tag); $xs->elementEnd('span'); return $xs->getString(); } else { return $tag; } }
/** * Send an Activity Streams notification to the remote Salmon endpoint, * if so configured. * * @param Profile $actor Actor who did the activity * @param string $verb Activity::SUBSCRIBE or Activity::JOIN * @param Object $object object of the action; must define asActivityNoun($tag) */ public function notify(Profile $actor, $verb, $object = null, $target = null) { if ($object == null) { $object = $this; } if (empty($this->salmonuri)) { return false; } $text = 'update'; $id = TagURI::mint('%s:%s:%s', $verb, $actor->getURI(), common_date_iso8601(time())); // @todo FIXME: Consolidate all these NS settings somewhere. $attributes = array('xmlns' => Activity::ATOM, 'xmlns:activity' => 'http://activitystrea.ms/spec/1.0/', 'xmlns:thr' => 'http://purl.org/syndication/thread/1.0', 'xmlns:georss' => 'http://www.georss.org/georss', 'xmlns:ostatus' => 'http://ostatus.org/schema/1.0', 'xmlns:poco' => 'http://portablecontacts.net/spec/1.0', 'xmlns:media' => 'http://purl.org/syndication/atommedia'); $entry = new XMLStringer(); $entry->elementStart('entry', $attributes); $entry->element('id', null, $id); $entry->element('title', null, $text); $entry->element('summary', null, $text); $entry->element('published', null, common_date_w3dtf(common_sql_now())); $entry->element('activity:verb', null, $verb); $entry->raw($actor->asAtomAuthor()); $entry->raw($actor->asActivityActor()); $entry->raw($object->asActivityNoun('object')); if ($target != null) { $entry->raw($target->asActivityNoun('target')); } $entry->elementEnd('entry'); $xml = $entry->getString(); common_log(LOG_INFO, "Posting to Salmon endpoint {$this->salmonuri}: {$xml}"); Salmon::post($this->salmonuri, $xml, $actor); }
/** * 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'); } }
/** * 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; }
function addAuthor($name, $uri = null, $email = null) { $xs = new XMLStringer(true); $xs->elementStart('author'); if (!empty($name)) { $xs->element('name', null, $name); } else { throw new Atom10FeedException(_('Author element must contain a name element.')); } if (isset($uri)) { $xs->element('uri', null, $uri); } if (isset($email)) { $xs->element('email', null, $email); } $xs->elementEnd('author'); array_push($this->authors, $xs->getString()); }