X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=plugins%2FActivityModeration%2FActivityModerationPlugin.php;h=ba53a13a8af3437e06d6af5f78e77665024446fa;hb=93524c4be384a9d75cdb4cd3413894bb4e39de6b;hp=4422310e58af1abb680c3eccfd7f76664bea1003;hpb=dac617d95ad98932604c3f07f1c038e25c5669c6;p=quix0rs-gnu-social.git diff --git a/plugins/ActivityModeration/ActivityModerationPlugin.php b/plugins/ActivityModeration/ActivityModerationPlugin.php index 4422310e58..ba53a13a8a 100644 --- a/plugins/ActivityModeration/ActivityModerationPlugin.php +++ b/plugins/ActivityModeration/ActivityModerationPlugin.php @@ -34,6 +34,30 @@ class ActivityModerationPlugin extends ActivityVerbHandlerPlugin return true; } + public function onGetNoticeSqlTimestamp($id, &$timestamp) + { + try { + $deleted = Deleted_notice::getByID($id); + $timestamp = $deleted->act_created; + } catch (NoResultException $e) { + return true; + } + // we're done for the event, so return false to stop it + return false; + } + + public function onIsNoticeDeleted($id, &$deleted) + { + try { + $found = Deleted_notice::getByID($id); + $deleted = ($found instanceof Deleted_notice); + } catch (NoResultException $e) { + $deleted = false; + } + // return true (continue event) if $deleted is false, return false (stop event) if deleted notice was found + return !$deleted; + } + protected function getActionTitle(ManagedAction $action, $verb, Notice $target, Profile $scoped) { // FIXME: switch based on action type @@ -50,7 +74,7 @@ class ActivityModerationPlugin extends ActivityVerbHandlerPlugin switch (true) { case ActivityUtils::compareVerbs($verb, array(ActivityVerb::DELETE)): // do whatever preparation is necessary to delete a verb - $target->delete(); + $target->deleteAs($scoped); break; default: throw new ServerException('ActivityVerb POST not handled by plugin that was supposed to do it.'); @@ -63,7 +87,8 @@ class ActivityModerationPlugin extends ActivityVerbHandlerPlugin } public function onDeleteNoticeAsProfile(Notice $stored, Profile $actor, &$result) { - // By adding a new 'delete' verb we will eventually trigger $this->saveObjectFromActivity + // By adding a new object with the 'delete' verb we will trigger + // $this->saveObjectFromActivity that will do the actual ->delete() if (false === Deleted_notice::addNew($stored, $actor)) { // false is returned if we did not have an error, but did not create the object // (i.e. the author is currently being deleted) @@ -71,8 +96,8 @@ class ActivityModerationPlugin extends ActivityVerbHandlerPlugin } // We return false (to stop the event) if the deleted_notice entry was - // added, which means we have run $this->saveObjectFromActivity which - // in turn has called the delete function of the notice. + // added, which means we have already run $this->saveObjectFromActivity + // which in turn has called the delete function of the notice. return false; } @@ -83,31 +108,94 @@ class ActivityModerationPlugin extends ActivityVerbHandlerPlugin */ protected function saveObjectFromActivity(Activity $act, Notice $stored, array $options=array()) { - // Let's see if this has been deleted already. - $deleted = Deleted_notice::getKV('uri', $act->id); - if ($deleted instanceof Deleted_notice) { - return $deleted; + // Everything is done in the StartNoticeSave event + return true; + } + + // FIXME: Put this in lib/activityhandlerplugin.php when we're ready + // with the other microapps/activityhandlers as well. + // Also it should be StartNoticeAsActivity (with a prepped Activity, including ->context etc.) + public function onEndNoticeAsActivity(Notice $stored, Activity $act, Profile $scoped=null) + { + if (!$this->isMyNotice($stored)) { + return true; } - common_debug('DELETING notice: ' . $act->objects[0]->id); - $target = Notice::getByUri($act->objects[0]->id); + common_debug('Extending activity '.$stored->id.' with '.get_called_class()); + $this->extendActivity($stored, $act, $scoped); + return false; + } - $deleted = new Deleted_notice(); + /** + * This is run before ->insert, so our task in this function is just to + * delete if it is the delete verb. + */ + public function onStartNoticeSave(Notice $stored) + { + // DELETE is a bit special, we have to remove the existing entry and then + // add a new one with the same URI in order to trigger the distribution. + // (that's why we don't use $this->isMyNotice(...)) + if (!ActivityUtils::compareVerbs($stored->verb, array(ActivityVerb::DELETE))) { + return true; + } + + try { + $target = Notice::getByUri($stored->uri); + } catch (NoResultException $e) { + throw new AlreadyFulfilledException('Notice URI not found, so we have nothing to delete.'); + } + + $actor = $stored->getProfile(); + $owner = $target->getProfile(); + + if ($owner->hasRole(Profile_role::DELETED)) { + // Don't bother with replacing notices if its author is being deleted. + // The later "StoreActivityObject" will pick this up and execute + // the deletion then. + // (the "delete verb notice" is too new to ever pass through Notice::saveNew + // which otherwise wouldn't execute the StoreActivityObject event) + return true; + } + + // Since the user deleting may not be the same as the notice's owner, + // double-check this and also set the "re-stored" notice profile_id. + if (!$actor->sameAs($owner) && !$actor->hasRight(Right::DELETEOTHERSNOTICE)) { + throw new AuthorizationException(_('You are not allowed to delete another user\'s notice.')); + } - $deleted->id = $target->getID(); - $deleted->profile_id = $target->getProfile()->getID(); - $deleted->uri = Deleted_notice::newUri($target->getProfile(), $target); - $deleted->act_uri = $target->getUri(); - $deleted->act_created = $target->created; - $deleted->created = common_sql_now(); + // We copy the identifying fields and replace the sensitive ones. + //$stored->id = $target->id; // We can't copy this since DB_DataObject won't inject it anyway + $props = array('uri', 'profile_id', 'conversation', 'reply_to', 'created', 'repeat_of', 'object_type', 'is_local', 'scope'); + foreach($props as $prop) { + $stored->$prop = $target->$prop; + } + + // Let's see if this has been deleted already. + try { + $deleted = Deleted_notice::getByKeys( ['uri' => $stored->getUri()] ); + return $deleted; + } catch (NoResultException $e) { + $deleted = new Deleted_notice(); + + $deleted->id = $target->getID(); + $deleted->profile_id = $actor->getID(); + $deleted->uri = $stored->getUri(); + $deleted->act_created = $stored->created; + $deleted->created = common_sql_now(); - common_debug('DELETING notice, storing Deleted_notice entry'); - $deleted->insert(); + // throws exception on error + $result = $deleted->insert(); + } - common_debug('DELETING notice, actually deleting now!'); + // Now we delete the original notice, leaving the id and uri free. $target->delete(); - return $deleted; + return true; + } + + public function extendActivity(Notice $stored, Activity $act, Profile $scoped=null) + { + Deleted_notice::extendActivity($stored, $act, $scoped); } public function activityObjectFromNotice(Notice $notice)