X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=plugins%2FActivityModeration%2FActivityModerationPlugin.php;h=ba53a13a8af3437e06d6af5f78e77665024446fa;hb=93524c4be384a9d75cdb4cd3413894bb4e39de6b;hp=dc21b115526e7556c08102409c38736e241ab317;hpb=7c68537b06983293bdc5d0dd1e4ceb8846f2453c;p=quix0rs-gnu-social.git diff --git a/plugins/ActivityModeration/ActivityModerationPlugin.php b/plugins/ActivityModeration/ActivityModerationPlugin.php index dc21b11552..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,33 +108,8 @@ 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; - } - - $target = Notice::getByUri($act->objects[0]->id); - common_debug('DELETING notice: ' . $act->objects[0]->id . ' on behalf of profile id==' . $target->getProfile()->getID()); - - $deleted = new Deleted_notice(); - - $deleted->id = $target->getID(); - $deleted->profile_id = $target->getProfile()->getID(); - $deleted->uri = $act->id; - $deleted->act_uri = $target->getUri(); - $deleted->act_created = $target->created; - $deleted->created = common_sql_now(); - - $result = $deleted->insert(); - if ($result === false) { - throw new ServerException('Could not insert Deleted_notice entry into database!'); - } - - common_debug('DELETING notice, actually deleting now!'); - $target->delete(); - - return $deleted; + // Everything is done in the StartNoticeSave event + return true; } // FIXME: Put this in lib/activityhandlerplugin.php when we're ready @@ -126,6 +126,73 @@ class ActivityModerationPlugin extends ActivityVerbHandlerPlugin return false; } + /** + * 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.')); + } + + // 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(); + + // throws exception on error + $result = $deleted->insert(); + } + + // Now we delete the original notice, leaving the id and uri free. + $target->delete(); + + return true; + } + public function extendActivity(Notice $stored, Activity $act, Profile $scoped=null) { Deleted_notice::extendActivity($stored, $act, $scoped);