FavorAction now uses Notice::saveActivity
This commit is contained in:
parent
aa33b7f21c
commit
fffacaa27c
@ -647,54 +647,21 @@ class Notice extends Managed_DataObject
|
||||
|
||||
// XXX: some of these functions write to the DB
|
||||
|
||||
$id = $notice->insert();
|
||||
|
||||
if (!$id) {
|
||||
common_log_db_error($notice, 'INSERT', __FILE__);
|
||||
// TRANS: Server exception thrown when a notice cannot be saved.
|
||||
throw new ServerException(_('Problem saving notice.'));
|
||||
}
|
||||
|
||||
// Update ID-dependent columns: URI, conversation
|
||||
|
||||
$orig = clone($notice);
|
||||
|
||||
$changed = false;
|
||||
|
||||
// We can only get here if it's a local notice, since remote notices
|
||||
// should've bailed out earlier due to lacking a URI.
|
||||
if (empty($notice->uri)) {
|
||||
$notice->uri = sprintf('%s%s=%d:%s=%s',
|
||||
TagURI::mint(),
|
||||
'noticeId', $notice->id,
|
||||
'objectType', $notice->get_object_type(true));
|
||||
$changed = true;
|
||||
}
|
||||
|
||||
// If it's not part of a conversation, it's
|
||||
// the beginning of a new conversation.
|
||||
|
||||
if (empty($notice->conversation)) {
|
||||
$conv = Conversation::create($notice);
|
||||
$notice->conversation = $conv->id;
|
||||
$changed = true;
|
||||
}
|
||||
|
||||
if ($changed) {
|
||||
if ($notice->update($orig) === false) {
|
||||
common_log_db_error($notice, 'UPDATE', __FILE__);
|
||||
// TRANS: Server exception thrown when a notice cannot be updated.
|
||||
throw new ServerException(_('Problem saving notice.'));
|
||||
try {
|
||||
$notice->insert(); // throws exception on failure
|
||||
} catch (Exception $e) {
|
||||
// Let's test if we managed initial insert, which would imply
|
||||
// failing on some update-part (check 'insert()'). Delete if
|
||||
// something had been stored to the database.
|
||||
if (!empty($notice->id)) {
|
||||
$notice->delete();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Clear the cache for subscribed users, so they'll update at next request
|
||||
// XXX: someone clever could prepend instead of clearing the cache
|
||||
|
||||
$notice->blowOnInsert();
|
||||
|
||||
// Save per-notice metadata...
|
||||
|
||||
if (isset($replies)) {
|
||||
@ -905,6 +872,9 @@ class Notice extends Managed_DataObject
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
if (!$stored instanceof Notice) {
|
||||
throw new ServerException('StartNoticeSave did not give back a Notice');
|
||||
}
|
||||
|
||||
// Save per-notice metadata...
|
||||
$mentions = array();
|
||||
@ -1798,7 +1768,7 @@ class Notice extends Managed_DataObject
|
||||
$act->objects[] = $repeated->asActivity($cur);
|
||||
}
|
||||
} else {
|
||||
$act->objects[] = ActivityObject::fromNotice($this);
|
||||
$act->objects[] = $this->asActivityObject();
|
||||
}
|
||||
|
||||
// XXX: should this be handled by default processing for object entry?
|
||||
@ -2005,10 +1975,29 @@ class Notice extends Managed_DataObject
|
||||
|
||||
function asActivityNoun($element)
|
||||
{
|
||||
$noun = ActivityObject::fromNotice($this);
|
||||
$noun = $this->asActivityObject();
|
||||
return $noun->asString('activity:' . $element);
|
||||
}
|
||||
|
||||
public function asActivityObject()
|
||||
{
|
||||
$object = new ActivityObject();
|
||||
|
||||
if (Event::handle('StartActivityObjectFromNotice', array($this, &$object))) {
|
||||
$object->type = $this->object_type ?: ActivityObject::NOTE;
|
||||
$object->id = $this->getUri();
|
||||
$object->title = sprintf('New %1$s by %2$s', $object->type, $this->getProfile()->getNickname());
|
||||
$object->content = $this->rendered;
|
||||
$object->link = $this->getUrl();
|
||||
|
||||
$object->extra[] = array('status_net', array('notice_id' => $this->id));
|
||||
|
||||
Event::handle('EndActivityObjectFromNotice', array($this, &$object));
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine which notice, if any, a new notice is in reply to.
|
||||
*
|
||||
@ -2335,20 +2324,55 @@ class Notice extends Managed_DataObject
|
||||
{
|
||||
$result = parent::insert();
|
||||
|
||||
if ($result !== false) {
|
||||
// Profile::hasRepeated() abuses pkeyGet(), so we
|
||||
// have to clear manually
|
||||
if (!empty($this->repeat_of)) {
|
||||
$c = self::memcache();
|
||||
if (!empty($c)) {
|
||||
$ck = self::multicacheKey('Notice',
|
||||
array('profile_id' => $this->profile_id,
|
||||
'repeat_of' => $this->repeat_of));
|
||||
$c->delete($ck);
|
||||
}
|
||||
if ($result === false) {
|
||||
common_log_db_error($this, 'INSERT', __FILE__);
|
||||
// TRANS: Server exception thrown when a stored object entry cannot be saved.
|
||||
throw new ServerException('Could not save Notice');
|
||||
}
|
||||
|
||||
// Profile::hasRepeated() abuses pkeyGet(), so we
|
||||
// have to clear manually
|
||||
if (!empty($this->repeat_of)) {
|
||||
$c = self::memcache();
|
||||
if (!empty($c)) {
|
||||
$ck = self::multicacheKey('Notice',
|
||||
array('profile_id' => $this->profile_id,
|
||||
'repeat_of' => $this->repeat_of));
|
||||
$c->delete($ck);
|
||||
}
|
||||
}
|
||||
|
||||
// Update possibly ID-dependent columns: URI, conversation
|
||||
// (now that INSERT has added the notice's local id)
|
||||
$orig = clone($this);
|
||||
$changed = false;
|
||||
|
||||
// We can only get here if it's a local notice, since remote notices
|
||||
// should've bailed out earlier due to lacking a URI.
|
||||
if (empty($this->uri)) {
|
||||
$this->uri = sprintf('%s%s=%d:%s=%s',
|
||||
TagURI::mint(),
|
||||
'noticeId', $this->id,
|
||||
'objectType', $this->get_object_type(true));
|
||||
$changed = true;
|
||||
}
|
||||
|
||||
// If it's not part of a conversation, it's
|
||||
// the beginning of a new conversation.
|
||||
if (empty($this->conversation)) {
|
||||
$conv = Conversation::create($this);
|
||||
$this->conversation = $conv->id;
|
||||
$changed = true;
|
||||
}
|
||||
|
||||
if ($changed && $this->update($orig) === false) {
|
||||
common_log_db_error($notice, 'UPDATE', __FILE__);
|
||||
// TRANS: Server exception thrown when a notice cannot be updated.
|
||||
throw new ServerException(_('Problem saving notice.'));
|
||||
}
|
||||
|
||||
$this->blowOnInsert();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
@ -431,32 +431,6 @@ class ActivityObject
|
||||
}
|
||||
}
|
||||
|
||||
static function fromNotice(Notice $notice)
|
||||
{
|
||||
$object = new ActivityObject();
|
||||
|
||||
if (Event::handle('StartActivityObjectFromNotice', array($notice, &$object))) {
|
||||
|
||||
$object->type = (empty($notice->object_type)) ? ActivityObject::NOTE : $notice->object_type;
|
||||
|
||||
$object->id = $notice->uri;
|
||||
$object->title = 'New ' . self::canonicalType($object->type) . ' by ';
|
||||
try {
|
||||
$object->title .= $notice->getProfile()->getAcctUri();
|
||||
} catch (ProfileNoAcctUriException $e) {
|
||||
$object->title .= $e->profile->nickname;
|
||||
}
|
||||
$object->content = $notice->rendered;
|
||||
$object->link = $notice->getUrl();
|
||||
|
||||
$object->extra[] = array('status_net', array('notice_id' => $notice->id));
|
||||
|
||||
Event::handle('EndActivityObjectFromNotice', array($notice, &$object));
|
||||
}
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
static function fromGroup(User_group $group)
|
||||
{
|
||||
$object = new ActivityObject();
|
||||
|
@ -433,4 +433,14 @@ class ActivityUtils
|
||||
|
||||
return $profile;
|
||||
}
|
||||
|
||||
static public function typeToTitle($type)
|
||||
{
|
||||
return ucfirst(self::resolveUri($type, true));
|
||||
}
|
||||
|
||||
static public function verbToTitle($verb)
|
||||
{
|
||||
return ucfirst(self::resolveUri($verb, true));
|
||||
}
|
||||
}
|
||||
|
@ -142,50 +142,6 @@ class ActivityPlugin extends Plugin
|
||||
return true;
|
||||
}
|
||||
|
||||
function onEndFavorNotice($profile, $notice)
|
||||
{
|
||||
// Only do this if config is enabled
|
||||
if(!$this->StartLike) return true;
|
||||
|
||||
if (!$profile->isLocal()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$author = $notice->getProfile();
|
||||
$fave = Fave::pkeyGet(array('user_id' => $profile->id,
|
||||
'notice_id' => $notice->id));
|
||||
|
||||
// TRANS: Text for "liked" item in activity plugin.
|
||||
// TRANS: %1$s is a profile URL, %2$s is a profile name,
|
||||
// TRANS: %3$s is a notice URL, %4$s is an author name.
|
||||
$rendered = sprintf(_m('<a href="%1$s">%2$s</a> liked <a href="%3$s">%4$s\'s update</a>.'),
|
||||
$profile->getUrl(),
|
||||
$profile->getBestName(),
|
||||
$notice->getUrl(),
|
||||
$author->getBestName());
|
||||
// TRANS: Text for "liked" item in activity plugin.
|
||||
// TRANS: %1$s is a profile name, %2$s is a profile URL,
|
||||
// TRANS: %3$s is an author name, %4$s is a notice URL.
|
||||
$content = sprintf(_m('%1$s (%2$s) liked %3$s\'s status (%4$s).'),
|
||||
$profile->getBestName(),
|
||||
$profile->getUrl(),
|
||||
$author->getBestName(),
|
||||
$notice->getUrl());
|
||||
|
||||
$notice = Notice::saveNew($profile->id,
|
||||
$content,
|
||||
ActivityPlugin::SOURCE,
|
||||
array('rendered' => $rendered,
|
||||
'urls' => array(),
|
||||
'replies' => array($author->getUri()),
|
||||
'uri' => $fave->getURI(),
|
||||
'verb' => ActivityVerb::FAVORITE,
|
||||
'object_type' => (($notice->verb == ActivityVerb::POST) ?
|
||||
$notice->object_type : ActivityObject::ACTIVITY)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function onEndDisfavorNotice($profile, $notice)
|
||||
{
|
||||
// Only do this if config is enabled
|
||||
|
@ -63,7 +63,7 @@ class FavoritePlugin extends ActivityHandlerPlugin
|
||||
' modified = "%s" '.
|
||||
'WHERE user_id = %d '.
|
||||
'AND notice_id = %d',
|
||||
Fave::newURI($fave->user_id, $fave->notice_id, $fave->modified),
|
||||
Fave::newUri($fave->user_id, $fave->notice_id, $fave->modified),
|
||||
common_sql_date(strtotime($fave->modified)),
|
||||
$fave->user_id,
|
||||
$fave->notice_id));
|
||||
@ -171,7 +171,6 @@ class FavoritePlugin extends ActivityHandlerPlugin
|
||||
// more explicit catch-statement.
|
||||
return null;
|
||||
}
|
||||
common_debug(get_called_class().' returning '.get_class($object).' object with uri: '.$object->uri);
|
||||
return $object;
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ class AtompubfavoritefeedAction extends ApiAuthAction
|
||||
$feed->setUpdated('now');
|
||||
|
||||
$feed->addAuthor($this->_profile->getBestName(),
|
||||
$this->_profile->getURI());
|
||||
$this->_profile->getUri());
|
||||
|
||||
// TRANS: Title for Atom favorites feed.
|
||||
// TRANS: %s is a user nickname.
|
||||
|
@ -48,40 +48,61 @@ class FavorAction extends FormAction
|
||||
{
|
||||
protected $needPost = true;
|
||||
|
||||
protected $object = null;
|
||||
|
||||
protected function prepare(array $args=array())
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$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 reply to 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 reply to notice %2$d.'), $this->scoped->getNickname(), $this->target->id), 403);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function handlePost()
|
||||
{
|
||||
$id = $this->trimmed('notice');
|
||||
$notice = Notice::getKV($id);
|
||||
if (!($notice instanceof Notice)) {
|
||||
$this->serverError(_('Notice not found'));
|
||||
}
|
||||
if (Fave::existsForProfile($notice, $this->scoped)) {
|
||||
parent::handlePost();
|
||||
|
||||
if (Fave::existsForProfile($this->target, $this->scoped)) {
|
||||
// TRANS: Client error displayed when trying to mark a notice as favorite that already is a favorite.
|
||||
throw new AlreadyFulfilledException(_('This notice is already a favorite!'));
|
||||
throw new AlreadyFulfilledException(_('You have already favorited this!'));
|
||||
}
|
||||
$fave = Fave::addNew($this->scoped, $notice);
|
||||
if (!$fave instanceof Fave) {
|
||||
// TRANS: Server error displayed when trying to mark a notice as favorite fails in the database.
|
||||
$this->serverError(_('Could not create favorite.'));
|
||||
}
|
||||
$this->notify($notice, $this->scoped->getUser());
|
||||
|
||||
$now = common_sql_now();
|
||||
|
||||
$act = new Activity();
|
||||
$act->id = Fave::newUri($this->scoped, $this->target, $now);
|
||||
$act->type = Fave::getObjectType();
|
||||
$act->actor = $this->scoped->asActivityObject();
|
||||
$act->target = $this->target->asActivityObject();
|
||||
$act->objects = array(clone($act->target));
|
||||
$act->verb = ActivityVerb::FAVORITE;
|
||||
$act->title = ActivityUtils::verbToTitle($act->verb);
|
||||
$act->time = strtotime($now);
|
||||
|
||||
$stored = Notice::saveActivity($act, $this->scoped,
|
||||
array('uri'=>$act->id));
|
||||
|
||||
$this->notify($stored, $this->scoped->getUser());
|
||||
Fave::blowCacheForProfileId($this->scoped->id);
|
||||
if (StatusNet::isAjax()) {
|
||||
$this->startHTML('text/xml;charset=utf-8');
|
||||
$this->elementStart('head');
|
||||
// TRANS: Page title for page on which favorite notices can be unfavourited.
|
||||
$this->element('title', null, _('Disfavor favorite.'));
|
||||
$this->elementEnd('head');
|
||||
$this->elementStart('body');
|
||||
$disfavor = new DisFavorForm($this, $notice);
|
||||
|
||||
return _('Favorited the notice');
|
||||
}
|
||||
|
||||
protected function showContent()
|
||||
{
|
||||
if ($this->target instanceof Notice) {
|
||||
$disfavor = new DisfavorForm($this, $this->target);
|
||||
$disfavor->show();
|
||||
$this->elementEnd('body');
|
||||
$this->endHTML();
|
||||
exit;
|
||||
}
|
||||
common_redirect(common_local_url('showfavorites',
|
||||
array('nickname' => $this->scoped->nickname)),
|
||||
303);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,7 +58,7 @@ class Fave extends Managed_DataObject
|
||||
$fave->notice_id = $notice->id;
|
||||
$fave->created = common_sql_now();
|
||||
$fave->modified = common_sql_now();
|
||||
$fave->uri = self::newURI($profile,
|
||||
$fave->uri = self::newUri($profile,
|
||||
$notice,
|
||||
$fave->created);
|
||||
|
||||
@ -128,17 +128,8 @@ class Fave extends Managed_DataObject
|
||||
|
||||
function asActivity()
|
||||
{
|
||||
$notice = Notice::getKV('id', $this->notice_id);
|
||||
|
||||
if (!$notice) {
|
||||
throw new Exception("Fave for non-existent notice: " . $this->notice_id);
|
||||
}
|
||||
|
||||
$profile = Profile::getKV('id', $this->user_id);
|
||||
|
||||
if (!$profile) {
|
||||
throw new Exception("Fave by non-existent profile: " . $this->user_id);
|
||||
}
|
||||
$notice = $this->getTarget();
|
||||
$profile = $this->getActor();
|
||||
|
||||
$act = new Activity();
|
||||
|
||||
@ -146,7 +137,7 @@ class Fave extends Managed_DataObject
|
||||
|
||||
// FIXME: rationalize this with URL below
|
||||
|
||||
$act->id = $this->getURI();
|
||||
$act->id = $this->getUri();
|
||||
|
||||
$act->time = strtotime($this->modified);
|
||||
// TRANS: Activity title when marking a notice as favorite.
|
||||
@ -158,11 +149,13 @@ class Fave extends Managed_DataObject
|
||||
$notice->getUrl());
|
||||
|
||||
$act->actor = $profile->asActivityObject();
|
||||
$act->objects[] = ActivityObject::fromNotice($notice);
|
||||
// $act->target = $notice->asActivityObject();
|
||||
// $act->objects = array(clone($act->target));
|
||||
$act->objects[] = $notice->asActivityObject();
|
||||
|
||||
$url = common_local_url('AtomPubShowFavorite',
|
||||
array('profile' => $this->user_id,
|
||||
'notice' => $this->notice_id));
|
||||
array('profile' => $profile->id,
|
||||
'notice' => $notice->id));
|
||||
|
||||
$act->selfLink = $url;
|
||||
$act->editLink = $url;
|
||||
@ -283,11 +276,6 @@ class Fave extends Managed_DataObject
|
||||
return $object;
|
||||
}
|
||||
|
||||
static public function verbToTitle($verb)
|
||||
{
|
||||
return ucfirst($verb);
|
||||
}
|
||||
|
||||
static public function getObjectType()
|
||||
{
|
||||
return 'activity';
|
||||
@ -297,22 +285,22 @@ class Fave extends Managed_DataObject
|
||||
{
|
||||
$actobj = new ActivityObject();
|
||||
$actobj->id = $this->getUri();
|
||||
$actobj->type = ActivityUtils::resolveUri($this->getObjectType());
|
||||
$actobj->type = ActivityUtils::resolveUri(self::getObjectType());
|
||||
$actobj->actor = $this->getActorObject();
|
||||
$actobj->target = $this->getTarget()->asActivityObject();
|
||||
$actobj->objects = array(clone($actobj->target));
|
||||
$actobj->title = Stored_ActivityVerb::verbToTitle($this->verb);
|
||||
$actobj->verb = ActivityVerb::FAVORITE;
|
||||
$actobj->title = ActivityUtils::verbToTitle($actobj->verb);
|
||||
return $actobj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ActivityObject $actobj The _favored_ notice (which we're "in-reply-to")
|
||||
* @param Notice $stored The _activity_ notice, i.e. the favor itself.
|
||||
*/
|
||||
static public function parseActivityObject(ActivityObject $actobj, Notice $stored)
|
||||
{
|
||||
// The ActivityObject we get here is the _favored_ notice (kind of what we're "in-reply-to")
|
||||
// The Notice we get is the _activity_ stored in our Notice table
|
||||
|
||||
$type = isset($actobj->type) ? ActivityUtils::resolveUri($actobj->type, true) : ActivityObject::NOTE;
|
||||
$local = ActivityUtils::findLocalObject($actobj->getIdentifiers(), $type);
|
||||
$local = ActivityUtils::findLocalObject($actobj->getIdentifiers());
|
||||
if (!$local instanceof Notice) {
|
||||
// $local always returns something, but this was not what we expected. Something is wrong.
|
||||
throw new Exception('Something other than a Notice was returned from findLocalObject');
|
||||
@ -332,6 +320,7 @@ class Fave extends Managed_DataObject
|
||||
{
|
||||
$object = self::parseActivityObject($actobj, $stored);
|
||||
$object->insert(); // exception throwing!
|
||||
Event::handle('EndFavorNotice', array($stored->getProfile(), $object->getTarget()));
|
||||
return $object;
|
||||
}
|
||||
|
||||
@ -339,7 +328,13 @@ class Fave extends Managed_DataObject
|
||||
public function getTarget()
|
||||
{
|
||||
// throws exception on failure
|
||||
return ActivityUtils::findLocalObject(array($this->uri));
|
||||
$target = new Notice();
|
||||
$target->id = $this->notice_id;
|
||||
if (!$target->find(true)) {
|
||||
throw new NoResultException($target);
|
||||
}
|
||||
|
||||
return $target;
|
||||
}
|
||||
|
||||
public function getTargetObject()
|
||||
@ -377,17 +372,17 @@ class Fave extends Managed_DataObject
|
||||
return $this->getActor()->asActivityObject();
|
||||
}
|
||||
|
||||
public function getURI()
|
||||
public function getUri()
|
||||
{
|
||||
if (!empty($this->uri)) {
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
// We (should've in this case) created it ourselves, so we tag it ourselves
|
||||
return self::newURI($this->getActor(), $this->getTarget(), $this->created);
|
||||
return self::newUri($this->getActor(), $this->getTarget(), $this->created);
|
||||
}
|
||||
|
||||
static function newURI(Profile $actor, Managed_DataObject $target, $created=null)
|
||||
static function newUri(Profile $actor, Managed_DataObject $target, $created=null)
|
||||
{
|
||||
if (is_null($created)) {
|
||||
$created = common_sql_now();
|
||||
|
@ -1044,7 +1044,7 @@ class OStatusPlugin extends Plugin
|
||||
$notice->getUrl());
|
||||
|
||||
$act->actor = $profile->asActivityObject();
|
||||
$act->object = ActivityObject::fromNotice($notice);
|
||||
$act->object = $notice->asActivityObject();
|
||||
|
||||
$oprofile->notifyActivity($act, $profile);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user