From dac617d95ad98932604c3f07f1c038e25c5669c6 Mon Sep 17 00:00:00 2001 From: Mikael Nordfeldth Date: Sat, 3 Oct 2015 12:26:09 +0200 Subject: [PATCH] I think all the notice deletion calls are event-compatible now This means we can handle DeleteNoticeAsProfile in plugins, such as the ActivityModeration plugin. --- actions/apistatusesdestroy.php | 2 +- actions/apistatusesshow.php | 2 +- actions/deletenotice.php | 2 +- classes/Notice.php | 25 +++++++++++-------- lib/activitymover.php | 2 +- .../ActivityModerationPlugin.php | 16 +++++++++--- .../classes/Deleted_notice.php | 14 ++++++----- plugins/Event/actions/cancelrsvp.php | 2 +- plugins/GNUsocialPhotos/actions/editphoto.php | 2 +- 9 files changed, 41 insertions(+), 26 deletions(-) diff --git a/actions/apistatusesdestroy.php b/actions/apistatusesdestroy.php index db41c87ad0..2d32124c42 100644 --- a/actions/apistatusesdestroy.php +++ b/actions/apistatusesdestroy.php @@ -124,7 +124,7 @@ class ApiStatusesDestroyAction extends ApiAuthAction if ($this->user->id == $this->notice->profile_id) { if (Event::handle('StartDeleteOwnNotice', array($this->user, $this->notice))) { - $this->notice->delete(); + $this->notice->deleteAs($this->scoped); Event::handle('EndDeleteOwnNotice', array($this->user, $this->notice)); } $this->showNotice(); diff --git a/actions/apistatusesshow.php b/actions/apistatusesshow.php index 8b9cc34779..70b9a9c27a 100644 --- a/actions/apistatusesshow.php +++ b/actions/apistatusesshow.php @@ -236,7 +236,7 @@ class ApiStatusesShowAction extends ApiPrivateAuthAction } if (Event::handle('StartDeleteOwnNotice', array($this->auth_user, $this->notice))) { - $this->notice->delete(); + $this->notice->deleteAs($this->scoped); Event::handle('EndDeleteOwnNotice', array($this->auth_user, $this->notice)); } diff --git a/actions/deletenotice.php b/actions/deletenotice.php index 40b276a348..f0aa767916 100644 --- a/actions/deletenotice.php +++ b/actions/deletenotice.php @@ -65,7 +65,7 @@ class DeletenoticeAction extends FormAction { if ($this->arg('yes')) { if (Event::handle('StartDeleteOwnNotice', array($this->scoped->getUser(), $this->notice))) { - $this->notice->delete(); + $this->notice->deleteAs($this->scoped); Event::handle('EndDeleteOwnNotice', array($this->scoped->getUser(), $this->notice)); } } else { diff --git a/classes/Notice.php b/classes/Notice.php index 737f186a10..8f98abd306 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -158,20 +158,14 @@ class Notice extends Managed_DataObject $this->_profile[$this->profile_id] = $profile; } - public function deleteAs(Profile $actor) + public function deleteAs(Profile $actor, $delete_event=true) { - if ($this->getProfile()->sameAs($actor) || $actor->hasRight(Right::DELETEOTHERSNOTICE)) { - return $this->delete(); + if (!$this->getProfile()->sameAs($actor) && !$actor->hasRight(Right::DELETEOTHERSNOTICE)) { + throw new AuthorizationException(_('You are not allowed to delete another user\'s notice.')); } - throw new AuthorizationException(_('You are not allowed to delete other user\'s notices')); - } - public function delete($useWhere=false) - { if (Event::handle('NoticeDeleteRelated', array($this))) { - // Clear related records - $this->clearReplies(); $this->clearLocation(); $this->clearRepeats(); @@ -179,10 +173,21 @@ class Notice extends Managed_DataObject $this->clearGroupInboxes(); $this->clearFiles(); $this->clearAttentions(); - // NOTE: we don't clear queue items } + $result = null; + if (!$delete_event || Event::handle('DeleteNoticeAsProfile', array($this, $actor, &$result))) { + // If $delete_event is true, we run the event. If the Event then + // returns false it is assumed everything was handled properly + // and the notice was deleted. + $result = $this->delete(); + } + return $result; + } + + public function delete($useWhere=false) + { $result = parent::delete($useWhere); $this->blowOnDelete(); diff --git a/lib/activitymover.php b/lib/activitymover.php index ac828d9491..74c5c68ad6 100644 --- a/lib/activitymover.php +++ b/lib/activitymover.php @@ -114,7 +114,7 @@ class ActivityMover extends QueueHandler $sink->postActivity($act); $notice = Notice::getKV('uri', $act->objects[0]->id); if (!empty($notice)) { - $notice->delete(); + $notice->deleteAs($user->getProfile(), false); } break; case ActivityVerb::JOIN: diff --git a/plugins/ActivityModeration/ActivityModerationPlugin.php b/plugins/ActivityModeration/ActivityModerationPlugin.php index 1494833992..4422310e58 100644 --- a/plugins/ActivityModeration/ActivityModerationPlugin.php +++ b/plugins/ActivityModeration/ActivityModerationPlugin.php @@ -59,13 +59,21 @@ class ActivityModerationPlugin extends ActivityVerbHandlerPlugin public function deleteRelated(Notice $notice) { - if ($notice->getProfile()->hasRole(Profile_role::DELETED)) { - // Don't save a new Deleted_notice entry if the profile is being deleted + // pass + } + + public function onDeleteNoticeAsProfile(Notice $stored, Profile $actor, &$result) { + // By adding a new 'delete' verb we will eventually trigger $this->saveObjectFromActivity + 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) return true; } - // For auditing purposes, save a record that the notice was deleted. - return Deleted_notice::addNew($notice); + // 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. + return false; } /** diff --git a/plugins/ActivityModeration/classes/Deleted_notice.php b/plugins/ActivityModeration/classes/Deleted_notice.php index c450c0eb63..790e2ab38d 100644 --- a/plugins/ActivityModeration/classes/Deleted_notice.php +++ b/plugins/ActivityModeration/classes/Deleted_notice.php @@ -54,13 +54,15 @@ class Deleted_notice extends Managed_DataObject ); } - public static function addNew(Notice $notice) + public static function addNew(Notice $notice, Profile $actor=null) { - $actor = $notice->getProfile(); + if (is_null($actor)) { + $actor = $notice->getProfile(); + } - if ($actor->hasRole(Profile_role::DELETED)) { - // Don't emit notices if the user is deleted - return true; + if ($notice->getProfile()->hasRole(Profile_role::DELETED)) { + // Don't emit notices if the notice author is (being) deleted + return false; } $act = new Activity(); @@ -80,7 +82,7 @@ class Deleted_notice extends Managed_DataObject ); $act->actor = $actor->asActivityObject(); - $act->target = new ActivityObject(); + $act->target = new ActivityObject(); // We don't save the notice object, as it's supposed to be removed! $act->target->id = $notice->getUri(); $act->objects = array(clone($act->target)); diff --git a/plugins/Event/actions/cancelrsvp.php b/plugins/Event/actions/cancelrsvp.php index 1f8e6fde71..83f6a73ae0 100644 --- a/plugins/Event/actions/cancelrsvp.php +++ b/plugins/Event/actions/cancelrsvp.php @@ -138,7 +138,7 @@ class CancelrsvpAction extends Action // NB: this will delete the rsvp, too if (!empty($notice)) { common_log(LOG_DEBUG, "Deleting notice..."); - $notice->delete(); + $notice->deleteAs($this->scoped); } else { common_log(LOG_DEBUG, "Deleting RSVP alone..."); $this->rsvp->delete(); diff --git a/plugins/GNUsocialPhotos/actions/editphoto.php b/plugins/GNUsocialPhotos/actions/editphoto.php index 8f719919f9..35dac7bf3f 100644 --- a/plugins/GNUsocialPhotos/actions/editphoto.php +++ b/plugins/GNUsocialPhotos/actions/editphoto.php @@ -192,7 +192,7 @@ class EditphotoAction extends Action $this->photo->delete(); if (Event::handle('StartDeleteOwnNotice', array($this->user, $notice))) { - $notice->delete(); + $notice->deleteAs($this->scoped); Event::handle('EndDeleteOwnNotice', array($this->user, $notice)); } $this->showForm(_('Success!')); -- 2.39.5