Completely refactored noticesearch list, now using subclassing for highlighting. Fixes #1240 and probably other bugs.

This commit is contained in:
Adrian Lang 2009-02-22 14:02:17 +01:00 committed by Evan Prodromou
parent d005b37071
commit bdb8c12d97

View File

@ -113,123 +113,58 @@ class NoticesearchAction extends SearchAction
} else { } else {
$cnt = $notice->find(); $cnt = $notice->find();
} }
if ($cnt > 0) { if ($cnt === 0) {
$terms = preg_split('/[\s,]+/', $q);
$this->elementStart('ul', array('class' => 'notices'));
for ($i = 0; $i < min($cnt, NOTICES_PER_PAGE); $i++) {
if ($notice->fetch()) {
$this->showNotice($notice, $terms);
} else {
// shouldn't happen!
break;
}
}
$this->elementEnd('ul');
} else {
$this->element('p', 'error', _('No results')); $this->element('p', 'error', _('No results'));
}
$this->pagination($page > 1, $cnt > NOTICES_PER_PAGE,
$page, 'noticesearch', array('q' => $q));
}
/**
* Show notice
*
* @param class $notice notice
* @param array $terms terms to highlight
*
* @return void
*
* @todo refactor and combine with StreamAction::showNotice()
*/
function showNotice($notice, $terms)
{
$profile = $notice->getProfile();
if (!$profile) {
common_log_db_error($notice, 'SELECT', __FILE__);
$this->serverError(_('Notice without matching profile'));
return; return;
} }
// XXX: RDFa $terms = preg_split('/[\s,]+/', $q);
$this->elementStart('li', array('class' => 'hentry notice', $nl = new SearchNoticeList($notice, $this, $terms);
'id' => 'notice-' . $notice->id));
$this->elementStart('div', 'entry-title'); $cnt = $nl->show();
$this->elementStart('span', 'vcard author');
$avatar = $profile->getAvatar(AVATAR_STREAM_SIZE);
$this->elementStart('a', array('href' => $profile->profileurl,
'class' => 'url'));
$this->element('img', array('src' => ($avatar) ? $avatar->displayUrl() : Avatar::defaultImage(AVATAR_STREAM_SIZE),
'class' => 'avatar photo',
'width' => AVATAR_STREAM_SIZE,
'height' => AVATAR_STREAM_SIZE,
'alt' =>
($profile->fullname) ? $profile->fullname :
$profile->nickname));
$this->element('span', 'nickname fn', $profile->nickname);
$this->elementEnd('a');
$this->elementEnd('span');
$this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE,
$this->page, 'noticesearch', array('q' => $q));
}
function isReadOnly()
{
return true;
}
}
class SearchNoticeList extends NoticeList {
function __construct($notice, $out=null, $terms)
{
parent::__construct($notice, $out);
$this->terms = $terms;
}
function newListItem($notice)
{
return new SearchNoticeListItem($notice, $this->out, $this->terms);
}
}
class SearchNoticeListItem extends NoticeListItem {
function __construct($notice, $out=null, $terms)
{
parent::__construct($notice, $out);
$this->terms = $terms;
}
function showContent()
{
// FIXME: URL, image, video, audio // FIXME: URL, image, video, audio
$this->elementStart('p', array('class' => 'entry-content')); $this->out->elementStart('p', array('class' => 'entry-content'));
if ($notice->rendered) { if ($this->notice->rendered) {
$this->raw($this->highlight($notice->rendered, $terms)); $this->out->raw($this->highlight($this->notice->rendered, $this->terms));
} else { } else {
// XXX: may be some uncooked notices in the DB, // XXX: may be some uncooked notices in the DB,
// we cook them right now. This should probably disappear in future // we cook them right now. This should probably disappear in future
// versions (>> 0.4.x) // versions (>> 0.4.x)
$this->raw($this->highlight(common_render_content($notice->content, $notice), $terms)); $this->out->raw($this->highlight(common_render_content($this->notice->content, $this->notice), $this->terms));
} }
$this->elementEnd('p'); $this->out->elementEnd('p');
$this->elementEnd('div');
$noticeurl = common_local_url('shownotice', array('notice' => $notice->id));
$this->elementStart('div', 'entry-content');
$this->elementStart('dl', 'timestamp');
$this->element('dt', null, _('Published'));
$this->elementStart('dd', null);
$this->elementStart('a', array('rel' => 'bookmark',
'href' => $noticeurl));
$dt = common_date_iso8601($notice->created);
$this->element('abbr', array('class' => 'published',
'title' => $dt),
common_date_string($notice->created));
$this->elementEnd('a');
$this->elementEnd('dd');
$this->elementEnd('dl');
if ($notice->reply_to) {
$replyurl = common_local_url('shownotice',
array('notice' => $notice->reply_to));
$this->elementStart('dl', 'response');
$this->element('dt', null, _('To'));
$this->elementStart('dd');
$this->element('a', array('href' => $replyurl,
'rel' => 'in-reply-to'),
_('in reply to'));
$this->elementEnd('dd');
$this->elementEnd('dl');
}
$this->elementEnd('div');
$this->elementStart('div', 'notice-options');
$reply_url = common_local_url('newnotice',
array('replyto' => $profile->nickname));
$this->elementStart('dl', 'notice_reply');
$this->element('dt', null, _('Reply to this notice'));
$this->elementStart('dd');
$this->elementStart('a', array('href' => $reply_url,
'title' => _('Reply to this notice')));
$this->text(_('Reply'));
$this->element('span', 'notice_id', $notice->id);
$this->elementEnd('a');
$this->elementEnd('dd');
$this->elementEnd('dl');
$this->elementEnd('div');
$this->elementEnd('li');
} }
/** /**
@ -242,7 +177,7 @@ class NoticesearchAction extends SearchAction
*/ */
function highlight($text, $terms) function highlight($text, $terms)
{ {
/* Highligh serach terms */ /* Highligh search terms */
$pattern = '/('.implode('|', array_map('htmlspecialchars', $terms)).')/i'; $pattern = '/('.implode('|', array_map('htmlspecialchars', $terms)).')/i';
$result = preg_replace($pattern, '<strong>\\1</strong>', $text); $result = preg_replace($pattern, '<strong>\\1</strong>', $text);
@ -253,10 +188,5 @@ class NoticesearchAction extends SearchAction
} while ($count); } while ($count);
return $result; return $result;
} }
function isReadOnly()
{
return true;
}
} }