FavoritePlugin is now an "ActivityVerbHandlerPlugin"
This commit is contained in:
parent
e338931ffa
commit
af67f15cf2
@ -31,6 +31,7 @@ if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
|
||||
class ActivityVerbPlugin extends Plugin
|
||||
{
|
||||
|
||||
public function onRouterInitialized(URLMapper $m)
|
||||
{
|
||||
$m->connect('notice/:id/:verb',
|
||||
|
@ -35,8 +35,15 @@ class ActivityverbAction extends ManagedAction
|
||||
protected $canPost = true;
|
||||
|
||||
protected $verb = null;
|
||||
|
||||
protected function doPreparation($args)
|
||||
|
||||
public function title()
|
||||
{
|
||||
$title = null;
|
||||
Event::handle('ActivityVerbTitle', array($this, $this->verb, $this->notice, $this->scoped, &$title));
|
||||
return $title;
|
||||
}
|
||||
|
||||
protected function doPreparation()
|
||||
{
|
||||
$this->verb = $this->trimmed('verb');
|
||||
if (empty($this->verb)) {
|
||||
@ -50,13 +57,15 @@ class ActivityverbAction extends ManagedAction
|
||||
throw new ClientException(sprintf(_('%1$s has no access to notice %2$d.'),
|
||||
$this->scoped->getNickname(), $this->notice->getID()), 403);
|
||||
}
|
||||
|
||||
Event::handle('ActivityVerbDoPreparation', array($this, $this->verb, $this->notice, $this->scoped));
|
||||
}
|
||||
|
||||
protected function doPost()
|
||||
{
|
||||
if (Event::handle('ActivityVerbDoPost', array($this, $this->verb, $this->notice, $this->scoped))) {
|
||||
// TRANS: Error when a POST method for an activity verb has not been handled by a plugin.
|
||||
throw new ClientException(_('Could not show content for verb "%1$s".'));
|
||||
throw new ClientException(sprintf(_('Could not handle POST for verb "%1$s".'), $this->verb));
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,7 +73,7 @@ class ActivityverbAction extends ManagedAction
|
||||
{
|
||||
if (Event::handle('ActivityVerbShowContent', array($this, $this->verb, $this->notice, $this->scoped))) {
|
||||
// TRANS: Error when a page for an activity verb has not been handled by a plugin.
|
||||
throw new ClientException(_('Could not show content for verb "%1$s".'));
|
||||
$this->element('div', 'error', sprintf(_('Could not show content for verb "%1$s".'), $this->verb));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
82
plugins/ActivityVerb/lib/activityverbhandlerplugin.php
Normal file
82
plugins/ActivityVerb/lib/activityverbhandlerplugin.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/*
|
||||
* GNU Social - a federating social network
|
||||
* Copyright (C) 2014, Free Software Foundation, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
|
||||
/**
|
||||
* @package Activity
|
||||
* @maintainer Mikael Nordfeldth <mmn@hethane.se>
|
||||
*/
|
||||
abstract class ActivityVerbHandlerPlugin extends ActivityHandlerPlugin
|
||||
{
|
||||
public function onActivityVerbTitle(ManagedAction $action, $verb, Notice $target, Profile $scoped, &$title)
|
||||
{
|
||||
if (!$this->isMyVerb($verb)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$title = $this->getActionTitle($action, $verb, $target, $scoped);
|
||||
return false;
|
||||
}
|
||||
abstract protected function getActionTitle(ManagedAction $action, $verb, Notice $target, Profile $scoped);
|
||||
|
||||
public function onActivityVerbShowContent(ManagedAction $action, $verb, Notice $target, Profile $scoped)
|
||||
{
|
||||
if (!$this->isMyVerb($verb)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->showActionContent($action, $verb, $target, $scoped);
|
||||
}
|
||||
protected function showActionContent(ManagedAction $action, $verb, Notice $target, Profile $scoped)
|
||||
{
|
||||
if (!GNUsocial::isAjax()) {
|
||||
$nl = new NoticeListItem($target, $action, array('options'=>false, 'attachments'=>false,
|
||||
'item_tag'=>'div', 'id_prefix'=>'fave'));
|
||||
$nl->show();
|
||||
}
|
||||
|
||||
$form = $this->getActivityForm($action, $verb, $target, $scoped);
|
||||
$form->show();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function onActivityVerbDoPreparation(ManagedAction $action, $verb, Notice $target, Profile $scoped)
|
||||
{
|
||||
if (!$this->isMyVerb($verb)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->doActionPreparation($action, $verb, $target, $scoped);
|
||||
}
|
||||
abstract protected function doActionPreparation(ManagedAction $action, $verb, Notice $target, Profile $scoped);
|
||||
|
||||
public function onActivityVerbDoPost(ManagedAction $action, $verb, Notice $target, Profile $scoped)
|
||||
{
|
||||
if (!$this->isMyVerb($verb)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->doActionPost($action, $verb, $target, $scoped);
|
||||
}
|
||||
abstract protected function doActionPost(ManagedAction $action, $verb, Notice $target, Profile $scoped);
|
||||
|
||||
abstract protected function getActivityForm(ManagedAction $action, $verb, Notice $target, Profile $scoped);
|
||||
}
|
@ -23,7 +23,7 @@ if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
* @package Activity
|
||||
* @maintainer Mikael Nordfeldth <mmn@hethane.se>
|
||||
*/
|
||||
class FavoritePlugin extends ActivityHandlerPlugin
|
||||
class FavoritePlugin extends ActivityVerbHandlerPlugin
|
||||
{
|
||||
protected $email_notify_fave = 1;
|
||||
|
||||
@ -39,9 +39,10 @@ class FavoritePlugin extends ActivityHandlerPlugin
|
||||
|
||||
public function verbs()
|
||||
{
|
||||
return array(ActivityVerb::FAVORITE);
|
||||
return array(ActivityVerb::FAVORITE, ActivityVerb::LIKE,
|
||||
ActivityVerb::UNFAVORITE, ActivityVerb::UNLIKE);
|
||||
}
|
||||
|
||||
|
||||
public function onCheckSchema()
|
||||
{
|
||||
$schema = Schema::get();
|
||||
@ -78,14 +79,14 @@ class FavoritePlugin extends ActivityHandlerPlugin
|
||||
printfnq("DONE.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function onEndUpgrade()
|
||||
{
|
||||
printfnq("Ensuring all faves have a URI...");
|
||||
|
||||
|
||||
$fave = new Fave();
|
||||
$fave->whereAdd('uri IS NULL');
|
||||
|
||||
|
||||
if ($fave->find()) {
|
||||
while ($fave->fetch()) {
|
||||
try {
|
||||
@ -104,7 +105,7 @@ class FavoritePlugin extends ActivityHandlerPlugin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
printfnq("DONE.\n");
|
||||
}
|
||||
|
||||
@ -180,7 +181,7 @@ class FavoritePlugin extends ActivityHandlerPlugin
|
||||
}
|
||||
|
||||
// FIXME: Set this to abstract public in lib/activityhandlerplugin.php ddwhen all plugins have migrated!
|
||||
protected function saveObjectFromActivity(Activity $act, Notice $stored, array $options=array())
|
||||
protected function saveObjectFromActivity(Activity $act, Notice $stored, array $options=array())
|
||||
{
|
||||
assert($this->isMyActivity($act));
|
||||
|
||||
@ -263,7 +264,7 @@ class FavoritePlugin extends ActivityHandlerPlugin
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public function onNoticeDeleteRelated(Notice $notice)
|
||||
{
|
||||
parent::onNoticeDeleteRelated($notice);
|
||||
@ -503,6 +504,62 @@ class FavoritePlugin extends ActivityHandlerPlugin
|
||||
}
|
||||
}
|
||||
|
||||
protected function getActionTitle(ManagedAction $action, $verb, Notice $target, Profile $scoped)
|
||||
{
|
||||
return Fave::existsForProfile($target, $scoped)
|
||||
// TRANS: Page/dialog box title when a notice is marked as favorite already
|
||||
? _m('TITLE', 'Unmark notice as favorite')
|
||||
// TRANS: Page/dialog box title when a notice is not marked as favorite
|
||||
: _m('TITLE', 'Mark notice as favorite');
|
||||
}
|
||||
|
||||
protected function doActionPreparation(ManagedAction $action, $verb, Notice $target, Profile $scoped)
|
||||
{
|
||||
if ($action->isPost()) {
|
||||
// The below tests are only for presenting to the user. POSTs which inflict
|
||||
// duplicate favorite entries are handled with AlreadyFulfilledException.
|
||||
return false;
|
||||
}
|
||||
|
||||
$exists = Fave::existsForProfile($target, $scoped);
|
||||
$expected_verb = $exists ? ActivityVerb::UNFAVORITE : ActivityVerb::FAVORITE;
|
||||
|
||||
switch (true) {
|
||||
case $exists && ActivityUtils::compareTypes($verb, array(ActivityVerb::FAVORITE, ActivityVerb::LIKE)):
|
||||
case !$exists && ActivityUtils::compareTypes($verb, array(ActivityVerb::UNFAVORITE, ActivityVerb::UNLIKE)):
|
||||
common_redirect(common_local_url('activityverb',
|
||||
array('id' => $target->getID(),
|
||||
'verb' => ActivityUtils::resolveUri($expected_verb, true))));
|
||||
break;
|
||||
default:
|
||||
// No need to redirect as we are on the correct action already.
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function doActionPost(ManagedAction $action, $verb, Notice $target, Profile $scoped)
|
||||
{
|
||||
switch (true) {
|
||||
case ActivityUtils::compareTypes($verb, array(ActivityVerb::FAVORITE, ActivityVerb::LIKE)):
|
||||
Fave::addNew($scoped, $target);
|
||||
break;
|
||||
case ActivityUtils::compareTypes($verb, array(ActivityVerb::UNFAVORITE, ActivityVerb::UNLIKE)):
|
||||
Fave::removeEntry($scoped, $target);
|
||||
break;
|
||||
default:
|
||||
throw new ServerException('ActivityVerb POST not handled by plugin that was supposed to do it.');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function getActivityForm(ManagedAction $action, $verb, Notice $target, Profile $scoped)
|
||||
{
|
||||
return Fave::existsForProfile($target, $scoped)
|
||||
? new DisfavorForm($action, $target)
|
||||
: new FavorForm($action, $target);
|
||||
}
|
||||
|
||||
public function onPluginVersion(array &$versions)
|
||||
{
|
||||
$versions[] = array('name' => 'Favorite',
|
||||
|
@ -1,84 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Disfavor action.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Action
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Robin Millette <millette@status.net>
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://www.gnu.org/software/social/
|
||||
*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
|
||||
/**
|
||||
* DisfavorAction class.
|
||||
*
|
||||
* @category Action
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Robin Millette <millette@status.net>
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://www.gnu.org/software/social/
|
||||
*/
|
||||
class DisfavorAction extends FormAction
|
||||
{
|
||||
protected $needPost = true;
|
||||
|
||||
protected function doPreparation()
|
||||
{
|
||||
$this->target = Notice::getKV($this->trimmed('notice'));
|
||||
if (!$this->target instanceof Notice) {
|
||||
throw new ServerException(_m('No such notice.'));
|
||||
}
|
||||
}
|
||||
|
||||
protected function doPost()
|
||||
{
|
||||
$fave = new Fave();
|
||||
$fave->user_id = $this->scoped->getID();
|
||||
$fave->notice_id = $this->target->getID();
|
||||
if (!$fave->find(true)) {
|
||||
// TRANS: Client error displayed when trying to remove a 'favor' when there is none in the first place.
|
||||
throw new AlreadyFulfilledException(_('This is already not favorited.'));
|
||||
}
|
||||
$result = $fave->delete();
|
||||
if ($result === false) {
|
||||
common_log_db_error($fave, 'DELETE', __FILE__);
|
||||
// TRANS: Server error displayed when removing a favorite from the database fails.
|
||||
throw new ServerException(_('Could not delete favorite.'));
|
||||
}
|
||||
Fave::blowCacheForProfileId($this->scoped->getID());
|
||||
|
||||
// TRANS: Message when a disfavor action has been taken for a notice.
|
||||
return _('Disfavored the notice.');
|
||||
}
|
||||
|
||||
protected function showContent()
|
||||
{
|
||||
// We show the 'Favor' form because right now all calls to Disfavor will directly disfavor a notice.
|
||||
$disfavor = new FavorForm($this, $this->target);
|
||||
$disfavor->show();
|
||||
}
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Favor action.
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Action
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Robin Millette <millette@status.net>
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://www.gnu.org/software/social/
|
||||
*
|
||||
* StatusNet - the distributed open-source microblogging tool
|
||||
* Copyright (C) 2008, 2009, StatusNet, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||
|
||||
/**
|
||||
* FavorAction class.
|
||||
*
|
||||
* @category Action
|
||||
* @package GNUsocial
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Robin Millette <millette@status.net>
|
||||
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://www.gnu.org/software/social/
|
||||
*/
|
||||
class FavorAction extends FormAction
|
||||
{
|
||||
protected $needPost = true;
|
||||
|
||||
protected function doPreparation()
|
||||
{
|
||||
$this->target = Notice::getKV($this->trimmed('notice'));
|
||||
if (!$this->target instanceof Notice) {
|
||||
throw new ServerException(_m('No such notice.'));
|
||||
}
|
||||
if (!$this->target->inScope($this->scoped)) {
|
||||
// TRANS: Client error displayed when trying to interact with a notice a the target has no access to.
|
||||
// TRANS: %1$s is a user nickname, %2$d is a notice ID (number).
|
||||
throw new ClientException(sprintf(_m('%1$s has no right to interact with notice %2$d.'), $this->scoped->getNickname(), $this->target->getID()), 403);
|
||||
}
|
||||
}
|
||||
|
||||
protected function doPost()
|
||||
{
|
||||
// throws exception on failure, might be an AlreadyFulfilledException
|
||||
$stored = Fave::addNew($this->scoped, $this->target);
|
||||
|
||||
// TRANS: Message when a favor action has been taken for a notice.
|
||||
return _('Favorited the notice');
|
||||
}
|
||||
|
||||
protected function showContent()
|
||||
{
|
||||
$disfavor = new DisfavorForm($this, $this->target);
|
||||
$disfavor->show();
|
||||
}
|
||||
}
|
@ -79,6 +79,27 @@ class Fave extends Managed_DataObject
|
||||
return $stored;
|
||||
}
|
||||
|
||||
public function removeEntry(Profile $actor, Notice $target)
|
||||
{
|
||||
$fave = new Fave();
|
||||
$fave->user_id = $actor->getID();
|
||||
$fave->notice_id = $target->getID();
|
||||
if (!$fave->find(true)) {
|
||||
// TRANS: Client error displayed when trying to remove a 'favor' when there is none in the first place.
|
||||
throw new AlreadyFulfilledException(_('This is already not favorited.'));
|
||||
}
|
||||
|
||||
$result = $fave->delete();
|
||||
if ($result === false) {
|
||||
common_log_db_error($fave, 'DELETE', __FILE__);
|
||||
// TRANS: Server error displayed when removing a favorite from the database fails.
|
||||
throw new ServerException(_('Could not delete favorite.'));
|
||||
}
|
||||
|
||||
Fave::blowCacheForProfileId($actor->getID());
|
||||
Fave::blowCacheForNoticeId($target->getID());
|
||||
}
|
||||
|
||||
// exception throwing takeover!
|
||||
public function insert()
|
||||
{
|
||||
|
@ -81,7 +81,9 @@ class DisfavorForm extends Form
|
||||
*/
|
||||
function action()
|
||||
{
|
||||
return common_local_url('disfavor');
|
||||
return common_local_url('activityverb',
|
||||
array('id' => $this->notice->getID(),
|
||||
'verb' => ActivityUtils::resolveUri(ActivityVerb::UNFAVORITE, true)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -81,7 +81,9 @@ class FavorForm extends Form
|
||||
*/
|
||||
function action()
|
||||
{
|
||||
return common_local_url('favor');
|
||||
return common_local_url('activityverb',
|
||||
array('id' => $this->notice->getID(),
|
||||
'verb' => ActivityUtils::resolveUri(ActivityVerb::FAVORITE, true)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user