X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=lib%2Fmicroappplugin.php;h=53fe5e9995eab4d7bf467c7015d769c8122dbd04;hb=dd61ae8fbeee64c85f8186672292335592be1ff5;hp=cd325560d32f07d5eb5d4efc436d5271c5781f0d;hpb=fec3edee45b67205f7d6cebd33b35594d73525f7;p=quix0rs-gnu-social.git diff --git a/lib/microappplugin.php b/lib/microappplugin.php index cd325560d3..53fe5e9995 100644 --- a/lib/microappplugin.php +++ b/lib/microappplugin.php @@ -48,7 +48,7 @@ if (!defined('STATUSNET')) { * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ -abstract class MicroAppPlugin extends Plugin +abstract class MicroAppPlugin extends ActivityHandlerPlugin { /** * Returns a localized string which represents this micro-app, @@ -61,97 +61,6 @@ abstract class MicroAppPlugin extends Plugin */ abstract function appTitle(); - /** - * Returns a key string which represents this micro-app in HTML - * ids etc, as when offering selection of what type of post to make. - * This is paired with the user-visible localizable $this->appTitle(). - * - * All micro-app classes must override this method. - */ - abstract function tag(); - - /** - * Return a list of ActivityStreams object type URIs - * which this micro-app handles. Default implementations - * of the base class will use this list to check if a - * given ActivityStreams object belongs to us, via - * $this->isMyNotice() or $this->isMyActivity. - * - * All micro-app classes must override this method. - * - * @fixme can we confirm that these types are the same - * for Atom and JSON streams? Any limitations or issues? - * - * @return array of strings - */ - abstract function types(); - - /** - * Given a parsed ActivityStreams activity, your plugin - * gets to figure out how to actually save it into a notice - * and any additional data structures you require. - * - * This will handle things received via AtomPub, OStatus - * (PuSH and Salmon transports), or ActivityStreams-based - * backup/restore of account data. - * - * You should be able to accept as input the output from your - * $this->activityObjectFromNotice(). Where applicable, try to - * use existing ActivityStreams structures and object types, - * and be liberal in accepting input from what might be other - * compatible apps. - * - * All micro-app classes must override this method. - * - * @fixme are there any standard options? - * - * @param Activity $activity - * @param Profile $actor - * @param array $options=array() - * - * @return Notice the resulting notice - */ - abstract function saveNoticeFromActivity($activity, $actor, $options=array()); - - /** - * Given an existing Notice object, your plugin gets to - * figure out how to arrange it into an ActivityStreams - * object. - * - * This will be how your specialized notice gets output in - * Atom feeds and JSON-based ActivityStreams output, including - * account backup/restore and OStatus (PuSH and Salmon transports). - * - * You should be able to round-trip data from this format back - * through $this->saveNoticeFromActivity(). Where applicable, try - * to use existing ActivityStreams structures and object types, - * and consider interop with other compatible apps. - * - * All micro-app classes must override this method. - * - * @fixme this outputs an ActivityObject, not an Activity. Any compat issues? - * - * @param Notice $notice - * - * @return ActivityObject - */ - abstract function activityObjectFromNotice($notice); - - /** - * Custom HTML output for your special notice; called when a - * matching notice turns up in a NoticeListItem. - * - * All micro-app classes must override this method. - * - * @param Notice $notice - * @param HTMLOutputter $out - * - * @fixme WARNING WARNING WARNING base plugin stuff below tries to close - * a div that this function opens in the BookmarkPlugin child class. - * This is probably wrong. - */ - abstract function showNotice($notice, $out); - /** * When building the primary notice form, we'll fetch also some * alternate forms for specialized types -- that's you! @@ -168,102 +77,11 @@ abstract class MicroAppPlugin extends Plugin abstract function entryForm($out); /** - * When a notice is deleted, you'll be called here for a chance - * to clean up any related resources. - * - * All micro-app classes must override this method. - * - * @param Notice $notice - */ - abstract function deleteRelated($notice); - - /** - * Check if a given notice object should be handled by this micro-app - * plugin. - * - * The default implementation checks against the activity type list - * returned by $this->types(). You can override this method to expand - * your checks. - * - * @param Notice $notice - * @return boolean - */ - function isMyNotice($notice) { - $types = $this->types(); - return in_array($notice->object_type, $types); - } - - /** - * Check if a given ActivityStreams activity should be handled by this - * micro-app plugin. - * - * The default implementation checks against the activity type list - * returned by $this->types(), and requires that exactly one matching - * object be present. You can override this method to expand - * your checks or to compare the activity's verb, etc. - * - * @param Activity $activity - * @return boolean - */ - function isMyActivity($activity) { - $types = $this->types(); - return (count($activity->objects) == 1 && - in_array($activity->objects[0]->type, $types)); - } - - /** - * Called when generating Atom XML ActivityStreams output from an - * ActivityObject belonging to this plugin. Gives the plugin - * a chance to add custom output. - * - * Note that you can only add output of additional XML elements, - * not change existing stuff here. - * - * If output is already handled by the base Activity classes, - * you can leave this base implementation as a no-op. - * - * @param ActivityObject $obj - * @param XMLOutputter $out to add elements at end of object - */ - function activityObjectOutputAtom(ActivityObject $obj, XMLOutputter $out) - { - // default is a no-op - } - - /** - * Called when generating JSON ActivityStreams output from an - * ActivityObject belonging to this plugin. Gives the plugin - * a chance to add custom output. * - * Modify the array contents to your heart's content, and it'll - * all get serialized out as JSON. - * - * If output is already handled by the base Activity classes, - * you can leave this base implementation as a no-op. - * - * @param ActivityObject $obj - * @param array &$out JSON-targeted array which can be modified */ - public function activityObjectOutputJson(ActivityObject $obj, array &$out) - { - // default is a no-op - } - - /** - * When a notice is deleted, delete the related objects - * by calling the overridable $this->deleteRelated(). - * - * @param Notice $notice Notice being deleted - * - * @return boolean hook value - */ - function onNoticeDeleteRelated($notice) - { - if ($this->isMyNotice($notice)) { - $this->deleteRelated($notice); - } - - return true; + public function newFormAction() { + // such as 'newbookmark' or 'newevent' route + return 'new'.$this->tag(); } /** @@ -272,249 +90,43 @@ abstract class MicroAppPlugin extends Plugin * @param NoticeListItem $nli The list item being shown. * * @return boolean hook value - * - * @fixme WARNING WARNING WARNING this closes a 'div' that is implicitly opened in BookmarkPlugin's showNotice implementation */ - function onStartShowNoticeItem($nli) + function onStartShowNoticeItem(NoticeListItem $nli) { if (!$this->isMyNotice($nli->notice)) { return true; } - $out = $nli->out; - $notice = $nli->notice; - - $this->showNotice($notice, $out); - - $nli->showNoticeLink(); - $nli->showNoticeSource(); - $nli->showNoticeLocation(); - $nli->showContext(); - $nli->showRepeat(); + // Legacy use was creating a "NoticeListItemAdapter", but + // nowadays we solve that using event handling for microapps. + // This section will remain until all plugins are fixed. + $adapter = $this->adaptNoticeListItem($nli) ?: $nli; - $out->elementEnd('div'); - - $nli->showNoticeOptions(); + $adapter->showNotice(); + $adapter->showNoticeAttachments(); + $adapter->showNoticeFooter(); return false; } /** - * Render a notice as one of our objects - * - * @param Notice $notice Notice to render - * @param ActivityObject &$object Empty object to fill - * - * @return boolean hook value - */ - function onStartActivityObjectFromNotice($notice, &$object) - { - if ($this->isMyNotice($notice)) { - $object = $this->activityObjectFromNotice($notice); - return false; - } - - return true; - } - - /** - * Handle a posted object from PuSH - * - * @param Activity $activity activity to handle - * @param Ostatus_profile $oprofile Profile for the feed - * - * @return boolean hook value - */ - function onStartHandleFeedEntryWithProfile($activity, $oprofile) - { - if ($this->isMyActivity($activity)) { - - $actor = $oprofile->checkAuthorship($activity); - - if (empty($actor)) { - // TRANS: Client exception thrown when no author for an activity was found. - throw new ClientException(_('Cannot get author for activity.')); - } - - $object = $activity->objects[0]; - - $options = array('uri' => $object->id, - 'url' => $object->link, - 'is_local' => Notice::REMOTE_OMB, - 'source' => 'ostatus'); - - // $actor is an ostatus_profile - $this->saveNoticeFromActivity($activity, $actor->localProfile(), $options); - - return false; - } - - return true; - } - - /** - * Handle a posted object from Salmon - * - * @param Activity $activity activity to handle - * @param mixed $target user or group targeted - * - * @return boolean hook value - */ - - function onStartHandleSalmonTarget($activity, $target) - { - if ($this->isMyActivity($activity)) { - $this->log(LOG_INFO, "Checking {$activity->id} as a valid Salmon slap."); - - if ($target instanceof User_group) { - $uri = $target->getUri(); - if (!in_array($uri, $activity->context->attention)) { - // @todo FIXME: please document (i18n). - // TRANS: Client exception. - throw new ClientException(_('Bookmark not posted to this group.')); - } - } else if ($target instanceof User) { - $uri = $target->uri; - $original = null; - if (!empty($activity->context->replyToID)) { - $original = Notice::staticGet('uri', - $activity->context->replyToID); - } - if (!in_array($uri, $activity->context->attention) && - (empty($original) || - $original->profile_id != $target->id)) { - // @todo FIXME: Please document (i18n). - // TRANS: Client exception. - throw new ClientException(_('Object not posted to this user.')); - } - } else { - // TRANS: Server exception thrown when a micro app plugin uses a target that cannot be handled. - throw new ServerException(_('Do not know how to handle this kind of target.')); - } - - $actor = Ostatus_profile::ensureActivityObjectProfile($activity->actor); - - $object = $activity->objects[0]; - - $options = array('uri' => $object->id, - 'url' => $object->link, - 'is_local' => Notice::REMOTE_OMB, - 'source' => 'ostatus'); - - // $actor is an ostatus_profile - $this->saveNoticeFromActivity($activity, $actor->localProfile(), $options); - - return false; - } - - return true; - } - - /** - * Handle object posted via AtomPub - * - * @param Activity &$activity Activity that was posted - * @param User $user User that posted it - * @param Notice &$notice Resulting notice - * - * @return boolean hook value - */ - function onStartAtomPubNewActivity(&$activity, $user, &$notice) - { - if ($this->isMyActivity($activity)) { - - $options = array('source' => 'atompub'); - - // $user->getProfile() is a Profile - $this->saveNoticeFromActivity($activity, - $user->getProfile(), - $options); - - return false; - } - - return true; - } - - /** - * Handle object imported from a backup file - * - * @param User $user User to import for - * @param ActivityObject $author Original author per import file - * @param Activity $activity Activity to import - * @param boolean $trusted Is this a trusted user? - * @param boolean &$done Is this done (success or unrecoverable error) - * - * @return boolean hook value - */ - function onStartImportActivity($user, $author, $activity, $trusted, &$done) - { - if ($this->isMyActivity($activity)) { - - $obj = $activity->objects[0]; - - $options = array('uri' => $object->id, - 'url' => $object->link, - 'source' => 'restore'); - - // $user->getProfile() is a Profile - $saved = $this->saveNoticeFromActivity($activity, - $user->getProfile(), - $options); - - if (!empty($saved)) { - $done = true; - } - - return false; - } - - return true; - } - - /** - * Event handler gives the plugin a chance to add custom - * Atom XML ActivityStreams output from a previously filled-out - * ActivityObject. + * Given a notice list item, returns an adapter specific + * to this plugin. * - * The atomOutput method is called if it's one of - * our matching types. + * @param NoticeListItem $nli item to adapt * - * @param ActivityObject $obj - * @param XMLOutputter $out to add elements at end of object - * @return boolean hook return value + * @return NoticeListItemAdapter adapter or null */ - function onEndActivityObjectOutputAtom(ActivityObject $obj, XMLOutputter $out) + function adaptNoticeListItem($nli) { - if (in_array($obj->type, $this->types())) { - $this->activityObjectOutputAtom($obj, $out); - } - return true; - } - - /** - * Event handler gives the plugin a chance to add custom - * JSON ActivityStreams output from a previously filled-out - * ActivityObject. - * - * The activityObjectOutputJson method is called if it's one of - * our matching types. - * - * @param ActivityObject $obj - * @param array &$out JSON-targeted array which can be modified - * @return boolean hook return value - */ - function onEndActivityObjectOutputJson(ActivityObject $obj, array &$out) - { - if (in_array($obj->type, $this->types())) { - $this->activityObjectOutputJson($obj, $out); - } - return true; + return null; } function onStartShowEntryForms(&$tabs) { - $tabs[$this->tag()] = $this->appTitle(); + $tabs[$this->tag()] = array('title' => $this->appTitle(), + 'href' => common_local_url($this->newFormAction()), + ); return true; }