From a09cf51b99b71010f358924d419100d75ec2ea03 Mon Sep 17 00:00:00 2001 From: Mikael Nordfeldth Date: Tue, 29 Sep 2015 15:17:38 +0200 Subject: [PATCH] Move Ostatus_profile->processPost function into plugin --- classes/Notice.php | 4 +- lib/activityhandlerplugin.php | 14 +- lib/default.php | 1 + lib/noticelistitem.php | 4 +- .../ActivityVerbPostPlugin.php | 135 +++++++++++++ plugins/Favorite/FavoritePlugin.php | 2 +- plugins/OStatus/classes/Ostatus_profile.php | 188 +----------------- plugins/Share/SharePlugin.php | 2 +- 8 files changed, 151 insertions(+), 199 deletions(-) create mode 100644 plugins/ActivityVerbPost/ActivityVerbPostPlugin.php diff --git a/classes/Notice.php b/classes/Notice.php index 13b86ce4c5..e4d10a5bad 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -866,7 +866,7 @@ class Notice extends Managed_DataObject $conv = Conversation::getKV('uri', $act->context->conversation); if ($conv instanceof Conversation) { common_debug('Conversation stitched together from (probably) a reply activity to unknown remote user. Activity creation time ('.$stored->created.') should maybe be compared to conversation creation time ('.$conv->created.').'); - $stored->conversation = $conv->id; + $stored->conversation = $conv->getID(); } else { // Conversation URI was not found, so we must create it. But we can't create it // until we have a Notice ID because of the database layout... @@ -926,7 +926,7 @@ class Notice extends Managed_DataObject // $act->context->conversation will be null if it was not provided common_debug('Creating a new conversation for stored notice ID='.$stored->getID().' with URI: '.$act->context->conversation); $conv = Conversation::create($stored, $act->context->conversation); - $stored->conversation = $conv->id; + $stored->conversation = $conv->getID(); } $stored->update($orig); diff --git a/lib/activityhandlerplugin.php b/lib/activityhandlerplugin.php index 6639e27822..c403e55a93 100644 --- a/lib/activityhandlerplugin.php +++ b/lib/activityhandlerplugin.php @@ -593,17 +593,9 @@ abstract class ActivityHandlerPlugin extends Plugin protected function showNoticeListItem(NoticeListItem $nli) { - $nli->showNotice(); - $nli->showNoticeAttachments(); - $nli->showNoticeInfo(); - $nli->showNoticeOptions(); - - $nli->showNoticeLink(); - $nli->showNoticeSource(); - $nli->showNoticeLocation(); - $nli->showPermalink(); - - $nli->showNoticeOptions(); + $nli->showNoticeHeaders(); + $nli->showContent(); + $nli->showNoticeFooter(); } public function onStartShowNoticeItemNotice(NoticeListItem $nli) diff --git a/lib/default.php b/lib/default.php index 5bec29cc52..38b8bcb1af 100644 --- a/lib/default.php +++ b/lib/default.php @@ -305,6 +305,7 @@ $default = 'plugins' => array('core' => array( 'ActivityVerb' => array(), + 'ActivityVerbPost' => array(), 'AuthCrypt' => array(), 'Cronish' => array(), 'Favorite' => array(), diff --git a/lib/noticelistitem.php b/lib/noticelistitem.php index dc171409f4..130821de15 100644 --- a/lib/noticelistitem.php +++ b/lib/noticelistitem.php @@ -166,7 +166,7 @@ class NoticeListItem extends Widget function showNoticeTitle() { if (Event::handle('StartShowNoticeTitle', array($this))) { - $this->element('a', array('href' => $this->notice->getUrl(), + $this->element('a', array('href' => $this->notice->getUrl(true), 'class' => 'notice-title'), $this->notice->getTitle()); Event::handle('EndShowNoticeTitle', array($this)); @@ -518,7 +518,7 @@ class NoticeListItem extends Widget } try { $this->out->element('a', - array('href' => $this->notice->getUrl(), + array('href' => $this->notice->getUrl(true), 'class' => $class), // TRANS: Addition in notice list item for single-notice view. _('permalink')); diff --git a/plugins/ActivityVerbPost/ActivityVerbPostPlugin.php b/plugins/ActivityVerbPost/ActivityVerbPostPlugin.php new file mode 100644 index 0000000000..b1abd616c5 --- /dev/null +++ b/plugins/ActivityVerbPost/ActivityVerbPostPlugin.php @@ -0,0 +1,135 @@ +. + */ + +if (!defined('GNUSOCIAL')) { exit(1); } + +/** + * @package Activity + * @maintainer Mikael Nordfeldth + */ +class ActivityVerbPostPlugin extends ActivityVerbHandlerPlugin +{ + public function tag() + { + return 'post'; + } + + public function types() + { + return array(ActivityObject::ARTICLE, + ActivityObject::BLOGENTRY, + ActivityObject::NOTE, + ActivityObject::STATUS, + ActivityObject::COMMENT, + // null, // if we want to follow the original Ostatus_profile::processActivity code + ); + } + + public function verbs() + { + return array(ActivityVerb::POST); + } + + // FIXME: Set this to abstract public in lib/activityhandlerplugin.php when all plugins have migrated! + protected function saveObjectFromActivity(Activity $act, Notice $stored, array $options=array()) + { + assert($this->isMyActivity($act)); + + $stored->object_type = ActivityUtils::resolveUri($act->objects[0]->type); + + // We don't have to do just about anything for a new, remote notice since the fields + // are handled in the main Notice::saveActivity function. Such as content, attachments, + // parent/conversation etc. + + // By returning true here instead of something that evaluates + // to false, we show that we have processed everything properly. + return true; + } + + public function activityObjectFromNotice(Notice $notice) + { + $object = new ActivityObject(); + + $object->type = $notice->object_type ?: ActivityObject::NOTE; + $object->id = $notice->getUri(); + $object->title = sprintf('New %1$s by %2$s', ActivityObject::canonicalType($object->type), $notice->getProfile()->getNickname()); + $object->content = $notice->rendered; + $object->link = $notice->getUrl(); + + $object->extra[] = array('status_net', array('notice_id' => $notice->getID())); + + return $object; + } + + public function deleteRelated(Notice $notice) + { + // No action needed as the table for data storage _is_ the notice table. + return true; + } + + + /** + * Command stuff + */ + + // FIXME: Move stuff from lib/command.php to here just as with Share etc. + + + /** + * Layout stuff + */ + + protected function showNoticeContent(Notice $stored, HTMLOutputter $out, Profile $scoped=null) + { + $out->raw($stored->rendered); + } + + protected function getActionTitle(ManagedAction $action, $verb, Notice $target, Profile $scoped) + { + // return page title + } + + protected function doActionPreparation(ManagedAction $action, $verb, Notice $target, Profile $scoped) + { + // prepare Action? + } + + protected function doActionPost(ManagedAction $action, $verb, Notice $target, Profile $scoped) + { + // handle repeat POST + } + + protected function getActivityForm(ManagedAction $action, $verb, Notice $target, Profile $scoped) + { + return new NoticeForm($action, array()); + } + + public function onPluginVersion(array &$versions) + { + $versions[] = array('name' => 'Post verb', + 'version' => GNUSOCIAL_VERSION, + 'author' => 'Mikael Nordfeldth', + 'homepage' => 'https://gnu.io/', + 'rawdescription' => + // TRANS: Plugin description. + _m('Post handling with ActivityStreams.')); + + return true; + } +} diff --git a/plugins/Favorite/FavoritePlugin.php b/plugins/Favorite/FavoritePlugin.php index aa6cdc9359..c7a66fe751 100644 --- a/plugins/Favorite/FavoritePlugin.php +++ b/plugins/Favorite/FavoritePlugin.php @@ -332,7 +332,7 @@ class FavoritePlugin extends ActivityVerbHandlerPlugin } } - public function showNoticeListItem(NoticeListItem $nli) + protected function showNoticeListItem(NoticeListItem $nli) { // pass } diff --git a/plugins/OStatus/classes/Ostatus_profile.php b/plugins/OStatus/classes/Ostatus_profile.php index 1c4428b16d..8fc9f6c5f6 100644 --- a/plugins/OStatus/classes/Ostatus_profile.php +++ b/plugins/OStatus/classes/Ostatus_profile.php @@ -495,26 +495,7 @@ class Ostatus_profile extends Managed_DataObject if (Event::handle('StartHandleFeedEntryWithProfile', array($activity, $this->localProfile(), &$notice)) && Event::handle('StartHandleFeedEntry', array($activity))) { - switch ($activity->verb) { - case ActivityVerb::POST: - // @todo process all activity objects - switch ($activity->objects[0]->type) { - case ActivityObject::ARTICLE: - case ActivityObject::BLOGENTRY: - case ActivityObject::NOTE: - case ActivityObject::STATUS: - case ActivityObject::COMMENT: - case null: - $notice = $this->processPost($activity, $source); - break; - default: - // TRANS: Client exception. - throw new ClientException(_m('Cannot handle that kind of post.')); - } - break; - default: - common_log(LOG_INFO, "Ignoring activity with unrecognized verb $activity->verb"); - } + common_log(LOG_INFO, "Ignoring activity with unrecognized verb $activity->verb"); Event::handle('EndHandleFeedEntry', array($activity)); Event::handle('EndHandleFeedEntryWithProfile', array($activity, $this, $notice)); @@ -528,178 +509,21 @@ class Ostatus_profile extends Managed_DataObject * @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; - - $profile = ActivityUtils::checkAuthorship($activity, $this->localProfile()); - - // 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 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::getKV('uri', $sourceUri); - if ($dupe instanceof Notice) { - 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 = common_purify($sourceContent); - $content = common_strip_html($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 = common_strip_html($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. - - // @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) . - '' . - '…' . - ''; - } - } - - $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) { - // TODO: context->attention - list($options['groups'], $options['replies']) - = self::filterAttention($profile, $activity->context->attention); - - // Maintain direct reply associations - // @todo 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; - } - } - if (!empty($activity->context->conversation)) { - // we store the URI here, Notice class can look it up later - $options['conversation'] = $activity->context->conversation; - } - - $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; - } - } - } + $actor = ActivityUtils::checkAuthorship($activity, $this->localProfile()); - // Atom enclosures -> attachment URLs - foreach ($activity->enclosures as $href) { - // @todo FIXME: Save these locally or....? - $options['urls'][] = $href; - } + $options = array('is_local' => Notice::REMOTE); try { - $saved = Notice::saveNew($profile->id, - $content, - 'ostatus', - $options); - if ($saved instanceof Notice) { - Ostatus_source::saveNew($saved, $this, $method); - if ($attachment instanceof File) { - File_to_post::processNew($attachment, $saved); - } - } + $stored = Notice::saveActivity($activity, $actor, $options); + Ostatus_source::saveNew($stored, $this, $method); } 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; + return $stored; } /** diff --git a/plugins/Share/SharePlugin.php b/plugins/Share/SharePlugin.php index c337efbaec..70e1395792 100644 --- a/plugins/Share/SharePlugin.php +++ b/plugins/Share/SharePlugin.php @@ -256,7 +256,7 @@ class SharePlugin extends ActivityVerbHandlerPlugin } } - public function showNoticeListItem(NoticeListItem $nli) + protected function showNoticeListItem(NoticeListItem $nli) { // pass } -- 2.39.5