From f500d4ea5be3583e7c2e9ad21d0c300bceda83f2 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 8 Feb 2011 11:11:21 -0500 Subject: [PATCH] Create and use MessageList widget Our mailbox actions (inbox and outbox) were doing their own display of messages. This was causing issues with especially showmessage, which since the more rigourous nickname checks were added, no longer works as a mailbox subclass. I've taken the time to rip out the message listing code from MailboxAction and moved it to a MessageList widget. The different mailboxes now have their own subclasses that show the correct profile in the list. --- actions/inbox.php | 34 ++++++---- actions/outbox.php | 37 +++++++---- lib/mailbox.php | 121 ++++------------------------------ lib/messagelist.php | 107 ++++++++++++++++++++++++++++++ lib/messagelistitem.php | 140 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 306 insertions(+), 133 deletions(-) create mode 100644 lib/messagelist.php create mode 100644 lib/messagelistitem.php diff --git a/actions/inbox.php b/actions/inbox.php index 3a50f4964f..6ab58f9751 100644 --- a/actions/inbox.php +++ b/actions/inbox.php @@ -90,18 +90,9 @@ class InboxAction extends MailboxAction } } - /** - * Returns the profile we want to show with the message - * - * For inboxes, we show the sender; for outboxes, the recipient. - * - * @param Message $message The message to get the profile for - * - * @return Profile The profile that matches the message - */ - function getMessageProfile($message) + function getMessageList($message) { - return $message->getFrom(); + return new InboxMessageList($this, $message); } /** @@ -115,3 +106,24 @@ class InboxAction extends MailboxAction return _('This is your inbox, which lists your incoming private messages.'); } } + +class InboxMessageList extends MessageList +{ + function newItem($message) + { + return new InboxMessageListItem($this->out, $message); + } +} + +class InboxMessageListItem extends MessageListItem +{ + /** + * Returns the profile we want to show with the message + * + * @return Profile The profile that matches the message + */ + function getMessageProfile() + { + return $this->message->getFrom(); + } +} \ No newline at end of file diff --git a/actions/outbox.php b/actions/outbox.php index b81d4b9d0d..cad19bba24 100644 --- a/actions/outbox.php +++ b/actions/outbox.php @@ -88,21 +88,9 @@ class OutboxAction extends MailboxAction } } - /** - * returns the profile we want to show with the message - * - * For outboxes, we show the recipient. - * - * @param Message $message The message to get the profile for - * - * @return Profile The profile of the message recipient - * - * @see MailboxAction::getMessageProfile() - */ - - function getMessageProfile($message) + function getMessageList($message) { - return $message->getTo(); + return new OutboxMessageList($this, $message); } /** @@ -116,3 +104,24 @@ class OutboxAction extends MailboxAction return _('This is your outbox, which lists private messages you have sent.'); } } + +class OutboxMessageList extends MessageList +{ + function newItem($message) + { + return new OutboxMessageListItem($this->out, $message); + } +} + +class OutboxMessageListItem extends MessageListItem +{ + /** + * Returns the profile we want to show with the message + * + * @return Profile The profile that matches the message + */ + function getMessageProfile() + { + return $this->message->getTo(); + } +} \ No newline at end of file diff --git a/lib/mailbox.php b/lib/mailbox.php index 63bffa75cc..bbcf2ef5dd 100644 --- a/lib/mailbox.php +++ b/lib/mailbox.php @@ -109,32 +109,22 @@ class MailboxAction extends CurrentUserDesignAction $message = $this->getMessages(); if ($message) { - $cnt = 0; - $this->elementStart('div', array('id' =>'notices_primary')); - $this->element('h2', null, _('Notices')); - $this->elementStart('ul', 'notices'); - while ($message->fetch() && $cnt <= MESSAGES_PER_PAGE) { - $cnt++; + $ml = $this->getMessageList($message); - if ($cnt > MESSAGES_PER_PAGE) { - break; - } + $cnt = $ml->show(); - $this->showMessage($message); - } - - $this->elementEnd('ul'); - - $this->pagination($this->page > 1, $cnt > MESSAGES_PER_PAGE, - $this->page, $this->trimmed('action'), + $this->pagination($this->page > 1, + $cnt > MESSAGES_PER_PAGE, + $this->page, + $this->trimmed('action'), array('nickname' => $this->user->nickname)); - $this->elementEnd('div'); - $message->free(); - unset($message); - } - else { - $this->element('p', 'guide', _('You have no private messages. You can send private message to engage other users in conversation. People can send you messages for your eyes only.')); + } else { + $this->element('p', + 'guide', + _('You have no private messages. '. + 'You can send private message to engage other users in conversation. '. + 'People can send you messages for your eyes only.')); } } @@ -143,95 +133,11 @@ class MailboxAction extends CurrentUserDesignAction return null; } - /** - * returns the profile we want to show with the message - * - * For inboxes, we show the sender; for outboxes, the recipient. - * - * @param Message $message The message to get the profile for - * - * @return Profile The profile that matches the message - */ - - function getMessageProfile($message) + function getMessageList($message) { return null; } - /** - * show a single message in the list format - * - * XXX: This needs to be extracted out into a MessageList similar - * to NoticeList. - * - * @param Message $message the message to show - * - * @return void - */ - - function showMessage($message) - { - $this->elementStart('li', array('class' => 'hentry notice', - 'id' => 'message-' . $message->id)); - - $profile = $this->getMessageProfile($message); - - $this->elementStart('div', 'entry-title'); - $this->elementStart('span', 'vcard author'); - $this->elementStart('a', array('href' => $profile->profileurl, - 'class' => 'url')); - $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE); - $this->element('img', array('src' => ($avatar) ? - $avatar->displayUrl() : - Avatar::defaultImage(AVATAR_STREAM_SIZE), - 'class' => 'photo avatar', - 'width' => AVATAR_STREAM_SIZE, - 'height' => AVATAR_STREAM_SIZE, - 'alt' => - ($profile->fullname) ? $profile->fullname : - $profile->nickname)); - $this->element('span', array('class' => 'nickname fn'), - $profile->nickname); - $this->elementEnd('a'); - $this->elementEnd('span'); - - // FIXME: URL, image, video, audio - $this->elementStart('p', array('class' => 'entry-content')); - $this->raw($message->rendered); - $this->elementEnd('p'); - $this->elementEnd('div'); - - $messageurl = common_local_url('showmessage', - array('message' => $message->id)); - - // XXX: we need to figure this out better. Is this right? - if (strcmp($message->uri, $messageurl) != 0 && - preg_match('/^http/', $message->uri)) { - $messageurl = $message->uri; - } - - $this->elementStart('div', 'entry-content'); - $this->elementStart('a', array('rel' => 'bookmark', - 'class' => 'timestamp', - 'href' => $messageurl)); - $dt = common_date_iso8601($message->created); - $this->element('abbr', array('class' => 'published', - 'title' => $dt), - common_date_string($message->created)); - $this->elementEnd('a'); - - if ($message->source) { - $this->elementStart('span', 'source'); - // FIXME: bad i18n. Device should be a parameter (from %s). - $this->text(_('from')); - $this->element('span', 'device', $this->showSource($message->source)); - $this->elementEnd('span'); - } - $this->elementEnd('div'); - - $this->elementEnd('li'); - } - /** * Show the page notice * @@ -300,5 +206,4 @@ class MailboxAction extends CurrentUserDesignAction { return true; } - } diff --git a/lib/messagelist.php b/lib/messagelist.php new file mode 100644 index 0000000000..da7e9a6c27 --- /dev/null +++ b/lib/messagelist.php @@ -0,0 +1,107 @@ +. + * + * @category Widget + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * Message list widget + * + * @category Widget + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +abstract class MessageList extends Widget +{ + var $message; + + /** + * Constructor + * + * @param HTMLOutputter $out Output context + * @param Message $message Stream of messages to show + */ + function __construct($out, $message) + { + parent::__construct($out); + $this->message = $message; + } + + /** + * Show the widget + * + * Uses newItem() to create each new item. + * + * @return integer count of messages seen. + */ + function show() + { + $cnt = 0; + + $this->out->elementStart('div', array('id' =>'notices_primary')); + + $this->out->element('h2', null, _('Messages')); + + $this->out->elementStart('ul', 'notices messages'); + + while ($this->message->fetch() && $cnt <= MESSAGES_PER_PAGE) { + + $cnt++; + + if ($cnt > MESSAGES_PER_PAGE) { + break; + } + + $mli = $this->newItem($this->message); + + $mli->show(); + } + + $this->out->elementEnd('ul'); + + $this->out->elementEnd('div'); + } + + /** + * Create a new message item for a message + * + * @param Message $message The message to show + * + * @return MessageListItem an item to show + */ + abstract function newItem($message); +} diff --git a/lib/messagelistitem.php b/lib/messagelistitem.php new file mode 100644 index 0000000000..2907eab274 --- /dev/null +++ b/lib/messagelistitem.php @@ -0,0 +1,140 @@ +. + * + * @category Widget + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + // This check helps protect against security problems; + // your code file can't be executed directly from the web. + exit(1); +} + +/** + * A single item in a message list + * + * @category Widget + * @package StatusNet + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 + * @link http://status.net/ + */ +abstract class MessageListItem extends Widget +{ + var $message; + + /** + * Constructor + * + * @param HTMLOutputter $out Output context + * @param Message $message Message to show + */ + function __construct($out, $message) + { + parent::__construct($out); + $this->message = $message; + } + + /** + * Show the widget + * + * @return void + */ + + function show() + { + $this->out->elementStart('li', array('class' => 'hentry notice', + 'id' => 'message-' . $this->message->id)); + + $profile = $this->getMessageProfile(); + + $this->out->elementStart('div', 'entry-title'); + $this->out->elementStart('span', 'vcard author'); + $this->out->elementStart('a', array('href' => $profile->profileurl, + 'class' => 'url')); + $avatar = $profile->getAvatar(AVATAR_STREAM_SIZE); + $this->out->element('img', array('src' => ($avatar) ? + $avatar->displayUrl() : + Avatar::defaultImage(AVATAR_STREAM_SIZE), + 'class' => 'photo avatar', + 'width' => AVATAR_STREAM_SIZE, + 'height' => AVATAR_STREAM_SIZE, + 'alt' => + ($profile->fullname) ? $profile->fullname : + $profile->nickname)); + $this->out->element('span', array('class' => 'nickname fn'), + $profile->nickname); + $this->out->elementEnd('a'); + $this->out->elementEnd('span'); + + // FIXME: URL, image, video, audio + $this->out->elementStart('p', array('class' => 'entry-content')); + $this->out->raw($this->message->rendered); + $this->out->elementEnd('p'); + $this->out->elementEnd('div'); + + $messageurl = common_local_url('showmessage', + array('message' => $this->message->id)); + + // XXX: we need to figure this out better. Is this right? + if (strcmp($this->message->uri, $messageurl) != 0 && + preg_match('/^http/', $this->message->uri)) { + $messageurl = $this->message->uri; + } + + $this->out->elementStart('div', 'entry-content'); + $this->out->elementStart('a', array('rel' => 'bookmark', + 'class' => 'timestamp', + 'href' => $messageurl)); + $dt = common_date_iso8601($this->message->created); + $this->out->element('abbr', array('class' => 'published', + 'title' => $dt), + common_date_string($this->message->created)); + $this->out->elementEnd('a'); + + if ($this->message->source) { + $this->out->elementStart('span', 'source'); + // FIXME: bad i18n. Device should be a parameter (from %s). + $this->out->text(_('from')); + $this->out->element('span', 'device', $this->out->showSource($this->message->source)); + $this->out->elementEnd('span'); + } + $this->out->elementEnd('div'); + + $this->out->elementEnd('li'); + } + + /** + * Return the profile to show in the message item + * + * Overridden in sub-classes to show sender, receiver, or whatever + * + * @return Profile profile to show avatar and name of + */ + abstract function getMessageProfile(); +}