Rewriting code for notice representation

Getting rid of NoticeListItemAdapter, putting more into ActivityHandlerPlugin
and relying on plugins to handle rendering code of the content. This gives us
a lot more structure and consistency in notice structure and allows activity
plugins to stop rendering certain kinds of notices more easily.

There should also be a property for an ActivityHandlerPlugin class to avoid
rendering notices in the ordinary stream, so we don't have to overload stuff.
This commit is contained in:
Mikael Nordfeldth 2014-07-04 14:14:49 +02:00
parent b9a8b2ad05
commit ffb9d7ad3f
12 changed files with 137 additions and 106 deletions

View File

@ -269,6 +269,11 @@ class Notice extends Managed_DataObject
return $title; return $title;
} }
public function getContent()
{
return $this->content;
}
/* /*
* Get the original representation URL of this notice. * Get the original representation URL of this notice.
*/ */

View File

@ -31,6 +31,15 @@ if (!defined('GNUSOCIAL')) { exit(1); }
*/ */
abstract class ActivityHandlerPlugin extends Plugin abstract class ActivityHandlerPlugin extends Plugin
{ {
/**
* Returns a key string which represents this activity in HTML classes,
* ids etc, as when offering selection of what type of post to make.
* In MicroAppPlugin, this is paired with the user-visible localizable appTitle().
*
* @return string (compatible with HTML classes)
*/
abstract function tag();
/** /**
* Return a list of ActivityStreams object type IRIs * Return a list of ActivityStreams object type IRIs
* which this micro-app handles. Default implementations * which this micro-app handles. Default implementations
@ -40,8 +49,6 @@ abstract class ActivityHandlerPlugin extends Plugin
* *
* An empty list means any type is ok. (Favorite verb etc.) * An empty list means any type is ok. (Favorite verb etc.)
* *
* All micro-app classes must override this method.
*
* @return array of strings * @return array of strings
*/ */
abstract function types(); abstract function types();
@ -57,7 +64,7 @@ abstract class ActivityHandlerPlugin extends Plugin
* *
* @return array of strings * @return array of strings
*/ */
function verbs() { public function verbs() {
return array(ActivityVerb::POST); return array(ActivityVerb::POST);
} }
@ -496,4 +503,88 @@ abstract class ActivityHandlerPlugin extends Plugin
} }
return true; return true;
} }
public function onStartOpenNoticeListItemElement(NoticeListItem $nli)
{
if (!$this->isMyNotice($nli->notice)) {
return true;
}
$this->openNoticeListItemElement($nli);
Event::handle('EndOpenNoticeListItemElement', array($nli));
return false;
}
public function onStartCloseNoticeListItemElement(NoticeListItem $nli)
{
if (!$this->isMyNotice($nli->notice)) {
return true;
}
$this->closeNoticeListItemElement($nli);
Event::handle('EndCloseNoticeListItemElement', array($nli));
return false;
}
protected function openNoticeListItemElement(NoticeListItem $nli)
{
$id = (empty($nli->repeat)) ? $nli->notice->id : $nli->repeat->id;
$class = 'h-entry notice ' . $this->tag();
if ($nli->notice->scope != 0 && $nli->notice->scope != 1) {
$class .= ' limited-scope';
}
$nli->out->elementStart('li', array('class' => $class,
'id' => 'notice-' . $id));
}
protected function closeNoticeListItemElement(NoticeListItem $nli)
{
$nli->out->elementEnd('li');
}
// FIXME: This is overriden in MicroAppPlugin but shouldn't have to be
public function onStartShowNoticeItem(NoticeListItem $nli)
{
if (!$this->isMyNotice($nli->notice)) {
return true;
}
try {
$this->showNoticeListItem($nli);
} catch (Exception $e) {
$nli->out->element('p', 'error', 'Error showing notice: '.htmlspecialchars($e->getMessage()));
}
Event::handle('EndShowNoticeItem', array($nli));
return false;
}
protected function showNoticeListItem(NoticeListItem $nli)
{
$nli->showNotice();
$nli->showNoticeAttachments();
$nli->showNoticeInfo();
$nli->showNoticeOptions();
$nli->showNoticeLink();
$nli->showNoticeSource();
$nli->showNoticeLocation();
$nli->showContext();
$nli->showRepeat();
$nli->showNoticeOptions();
}
public function onStartShowNoticeContent(Notice $stored, HTMLOutputter $out, Profile $scoped=null)
{
if (!$this->isMyNotice($stored)) {
return true;
}
$out->text($stored->getContent());
return false;
}
} }

View File

@ -61,15 +61,6 @@ abstract class MicroAppPlugin extends ActivityHandlerPlugin
*/ */
abstract function appTitle(); abstract function appTitle();
/**
* Returns a key string which represents this micro-app in HTML
* ids etc, as when offering selection of what type of post to make.
* This is paired with the user-visible localizable $this->appTitle().
*
* All micro-app classes must override this method.
*/
abstract function tag();
/** /**
* When building the primary notice form, we'll fetch also some * When building the primary notice form, we'll fetch also some
* alternate forms for specialized types -- that's you! * alternate forms for specialized types -- that's you!
@ -99,10 +90,8 @@ abstract class MicroAppPlugin extends ActivityHandlerPlugin
* @param NoticeListItem $nli The list item being shown. * @param NoticeListItem $nli The list item being shown.
* *
* @return boolean hook value * @return boolean hook value
*
* @fixme WARNING WARNING WARNING this closes a 'div' that is implicitly opened in BookmarkPlugin's showNotice implementation
*/ */
function onStartShowNoticeItem($nli) function onStartShowNoticeItem(NoticeListItem $nli)
{ {
if (!$this->isMyNotice($nli->notice)) { if (!$this->isMyNotice($nli->notice)) {
return true; return true;
@ -110,14 +99,14 @@ abstract class MicroAppPlugin extends ActivityHandlerPlugin
$adapter = $this->adaptNoticeListItem($nli); $adapter = $this->adaptNoticeListItem($nli);
if (!empty($adapter)) { if (empty($adapter)) {
throw new ServerException('Could not adapt NoticeListItem');
}
$adapter->showNotice(); $adapter->showNotice();
$adapter->showNoticeAttachments(); $adapter->showNoticeAttachments();
$adapter->showNoticeInfo(); $adapter->showNoticeInfo();
$adapter->showNoticeOptions(); $adapter->showNoticeOptions();
} else {
$this->oldShowNotice($nli);
}
return false; return false;
} }
@ -135,32 +124,6 @@ abstract class MicroAppPlugin extends ActivityHandlerPlugin
return null; return null;
} }
function oldShowNotice($nli)
{
$out = $nli->out;
$notice = $nli->notice;
try {
$this->showNotice($notice, $out);
} catch (Exception $e) {
common_log(LOG_ERR, $e->getMessage());
// try to fall back
$out->elementStart('div');
$nli->showAuthor();
$nli->showContent();
}
$nli->showNoticeLink();
$nli->showNoticeSource();
$nli->showNoticeLocation();
$nli->showContext();
$nli->showRepeat();
$out->elementEnd('div');
$nli->showNoticeOptions();
}
function onStartShowEntryForms(&$tabs) function onStartShowEntryForms(&$tabs)
{ {
$tabs[$this->tag()] = array('title' => $this->appTitle(), $tabs[$this->tag()] = array('title' => $this->appTitle(),
@ -178,10 +141,4 @@ abstract class MicroAppPlugin extends ActivityHandlerPlugin
return true; return true;
} }
function showNotice($notice, $out)
{
// TRANS: Server exception thrown when a micro app plugin developer has not done his job too well.
throw new ServerException(_('You must implement either adaptNoticeListItem() or showNotice().'));
}
} }

View File

@ -273,6 +273,7 @@ class NoticeListItem extends Widget
{ {
// FIXME: URL, image, video, audio // FIXME: URL, image, video, audio
$this->out->elementStart('div', array('class' => 'e-content')); $this->out->elementStart('div', array('class' => 'e-content'));
if (Event::handle('StartShowNoticeContent', array($this->notice, $this->out, $this->out->getScoped()))) {
if ($this->notice->rendered) { if ($this->notice->rendered) {
$this->out->raw($this->notice->rendered); $this->out->raw($this->notice->rendered);
} else { } else {
@ -281,6 +282,8 @@ class NoticeListItem extends Widget
// versions (>> 0.4.x) // versions (>> 0.4.x)
$this->out->raw(common_render_content($this->notice->content, $this->notice)); $this->out->raw(common_render_content($this->notice->content, $this->notice));
} }
Event::handle('EndShowNoticeContent', array($this->notice, $this->out, $this->out->getScoped()));
}
$this->out->elementEnd('div'); $this->out->elementEnd('div');
} }

View File

@ -239,39 +239,6 @@ class BookmarkPlugin extends MicroAppPlugin
return true; return true;
} }
/**
* Output our CSS class for bookmark notice list elements
*
* @param NoticeListItem $nli The item being shown
*
* @return boolean hook value
*/
function onStartOpenNoticeListItemElement($nli)
{
if (!$this->isMyNotice($nli->notice)) {
return true;
}
$nb = Bookmark::getByNotice($nli->notice);
if (empty($nb)) {
$this->log(LOG_INFO, "Notice {$nli->notice->id} has bookmark class but no matching Bookmark record.");
return true;
}
$id = (empty($nli->repeat)) ? $nli->notice->id : $nli->repeat->id;
$class = 'h-entry notice bookmark';
if ($nli->notice->scope != 0 && $nli->notice->scope != 1) {
$class .= ' limited-scope';
}
$nli->out->elementStart('li', array('class' => $class,
'id' => 'notice-' . $id));
Event::handle('EndOpenNoticeListItemElement', array($nli));
return false;
}
/** /**
* Modify the default menu to link to our custom action * Modify the default menu to link to our custom action
* *

View File

@ -74,7 +74,7 @@ class BookmarkListItem extends NoticeListItemAdapter
$profile = $notice->getProfile(); $profile = $notice->getProfile();
$out->elementStart('p', array('class' => 'e-content')); $out->elementStart('div', array('class' => 'e-content'));
// Whether to nofollow // Whether to nofollow
@ -139,6 +139,6 @@ class BookmarkListItem extends NoticeListItemAdapter
$nb->description); $nb->description);
} }
$out->elementEnd('p'); $out->elementEnd('div');
} }
} }

View File

@ -44,7 +44,7 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class EventPlugin extends MicroappPlugin class EventPlugin extends MicroAppPlugin
{ {
/** /**
* Set up our tables (event and rsvp) * Set up our tables (event and rsvp)

View File

@ -289,6 +289,19 @@ class FavoritePlugin extends ActivityHandlerPlugin
} }
} }
public function showNoticeListItem(NoticeListItem $nli)
{
// pass
}
public function openNoticeListItemElement(NoticeListItem $nli)
{
// pass
}
public function closeNoticeListItemElement(NoticeListItem $nli)
{
// pass
}
public function onAppendUserActivityStreamObjects(UserActivityStream $uas, array &$objs) public function onAppendUserActivityStreamObjects(UserActivityStream $uas, array &$objs)
{ {
$faves = array(); $faves = array();

View File

@ -119,7 +119,7 @@ class GNUsocialPhotoPlugin extends MicroAppPlugin
} }
function showNotice($notice, $out) function showNoticeContent(Notice $notice, HTMLOutputter $out)
{ {
$photo = Photo::getByNotice($notice); $photo = Photo::getByNotice($notice);
if ($photo) { if ($photo) {

View File

@ -112,7 +112,7 @@ class GNUsocialVideoPlugin extends MicroAppPlugin
} }
function showNotice($notice, $out) function showNotice(Notice $notice, HTMLOutputter $out)
{ {
$vid = Video::getByNotice($notice); $vid = Video::getByNotice($notice);
if ($vid) { if ($vid) {

View File

@ -376,12 +376,7 @@ class PollPlugin extends MicroAppPlugin
} }
/** function showNoticeContent(Notice $notice, HTMLOutputter $out)
* @fixme WARNING WARNING WARNING parent class closes the final div that we
* open here, but we probably shouldn't open it here. Check parent class
* and Bookmark plugin for if that's right.
*/
function showNotice(Notice $notice, $out)
{ {
switch ($notice->object_type) { switch ($notice->object_type) {
case self::POLL_OBJECT: case self::POLL_OBJECT:

View File

@ -322,7 +322,7 @@ class QnAPlugin extends MicroAppPlugin
* @param Notice $notice * @param Notice $notice
* @param HTMLOutputter $out * @param HTMLOutputter $out
*/ */
function showNotice(Notice $notice, $out) function showNoticeContent(Notice $notice, $out)
{ {
switch ($notice->object_type) { switch ($notice->object_type) {
case QnA_Question::OBJECT_TYPE: case QnA_Question::OBJECT_TYPE: