2008-07-10 00:00:17 +01:00
< ? php
2009-01-23 01:22:17 +00:00
/**
* Notice search action class .
*
* PHP version 5
*
* @ category Action
2009-08-25 23:12:20 +01:00
* @ package StatusNet
2009-08-25 23:19:04 +01:00
* @ author Evan Prodromou < evan @ status . net >
* @ author Robin Millette < millette @ status . net >
* @ author Sarven Capadisli < csarven @ status . net >
2009-01-23 01:22:17 +00:00
* @ license http :// www . fsf . org / licensing / licenses / agpl . html AGPLv3
2009-08-25 23:16:46 +01:00
* @ link http :// status . net /
2009-01-23 01:22:17 +00:00
*
2009-08-25 23:14:12 +01:00
* StatusNet - the distributed open - source microblogging tool
2009-08-25 23:12:20 +01:00
* Copyright ( C ) 2008 , 2009 , StatusNet , Inc .
2008-07-10 00:00:17 +01:00
*
* 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 />.
*/
2009-08-26 15:41:36 +01:00
if ( ! defined ( 'STATUSNET' ) && ! defined ( 'LACONICA' )) {
2009-01-23 01:22:17 +00:00
exit ( 1 );
}
2008-07-10 00:00:17 +01:00
2009-01-23 01:22:17 +00:00
require_once INSTALLDIR . '/lib/searchaction.php' ;
2008-07-10 00:00:17 +01:00
2009-01-23 01:22:17 +00:00
/**
* Notice search action class .
*
* @ category Action
2009-08-25 23:12:20 +01:00
* @ package StatusNet
2009-08-25 23:19:04 +01:00
* @ author Evan Prodromou < evan @ status . net >
* @ author Robin Millette < millette @ status . net >
2009-01-23 01:22:17 +00:00
* @ license http :// www . fsf . org / licensing / licenses / agpl . html AGPLv3
2009-08-25 23:16:46 +01:00
* @ link http :// status . net /
2009-01-23 01:22:17 +00:00
* @ todo common parent for people and content search ?
*/
2008-12-23 19:49:23 +00:00
class NoticesearchAction extends SearchAction
{
2011-04-09 22:30:59 +01:00
protected $q = null ;
2009-02-06 00:16:10 +00:00
function prepare ( $args )
{
parent :: prepare ( $args );
2011-04-09 22:30:59 +01:00
$this -> q = $this -> trimmed ( 'q' );
// FIXME: very dependent on tag format
if ( preg_match ( '/^#([\pL\pN_\-\.]{1,64})/ue' , $this -> q )) {
common_redirect ( common_local_url ( 'tag' ,
array ( 'tag' => common_canonical_tag ( substr ( $this -> q , 1 )))),
303 );
}
2011-04-11 23:59:58 +01:00
if ( ! empty ( $this -> q )) {
$profile = Profile :: current ();
$stream = new SearchNoticeStream ( $this -> q , $profile );
$page = $this -> trimmed ( 'page' );
if ( empty ( $page )) {
$page = 1 ;
} else {
$page = ( int ) $page ;
}
$this -> notice = $stream -> getNotices ((( $page - 1 ) * NOTICES_PER_PAGE ), NOTICES_PER_PAGE + 1 );
}
2009-02-06 00:16:10 +00:00
common_set_returnto ( $this -> selfUrl ());
return true ;
}
2009-02-11 16:37:50 +00:00
2009-01-23 01:22:17 +00:00
/**
* Get instructions
2009-02-11 16:37:50 +00:00
*
* @ return string instruction text
2009-01-23 01:22:17 +00:00
*/
function getInstructions ()
2008-12-23 19:33:23 +00:00
{
2011-02-17 19:58:22 +00:00
// TRANS: Instructions for Notice search page.
// TRANS: %%site.name%% is the name of the StatusNet site.
2008-12-23 19:19:07 +00:00
return _ ( 'Search for notices on %%site.name%% by their contents. Separate search terms by spaces; they must be 3 characters or more.' );
}
2008-07-10 06:12:01 +01:00
2009-01-23 01:22:17 +00:00
/**
* Get title
2009-02-11 16:37:50 +00:00
*
2009-01-23 01:22:17 +00:00
* @ return string title
*/
function title ()
2008-12-23 19:33:23 +00:00
{
2011-02-17 19:58:22 +00:00
// TRANS: Title of the page where users can search for notices.
2008-12-23 19:19:07 +00:00
return _ ( 'Text search' );
}
2008-07-10 06:12:01 +01:00
2009-02-11 16:37:50 +00:00
function getFeeds ()
2009-02-10 22:04:47 +00:00
{
$q = $this -> trimmed ( 'q' );
if ( ! $q ) {
2009-02-11 16:37:50 +00:00
return null ;
2009-02-10 22:04:47 +00:00
}
2009-02-11 16:37:50 +00:00
return array ( new Feed ( Feed :: RSS1 , common_local_url ( 'noticesearchrss' ,
array ( 'q' => $q )),
2011-02-17 19:58:22 +00:00
// TRANS: Test in RSS notice search.
// TRANS: %1$s is the query, %2$s is the StatusNet site name.
2010-01-10 00:45:58 +00:00
sprintf ( _ ( 'Search results for "%1$s" on %2$s' ),
2009-02-11 16:37:50 +00:00
$q , common_config ( 'site' , 'name' ))));
2009-02-10 22:04:47 +00:00
}
2009-01-23 01:22:17 +00:00
/**
* Show results
*
* @ param string $q search query
* @ param integer $page page number
*
* @ return void
*/
function showResults ( $q , $page )
2008-12-23 19:33:23 +00:00
{
2011-04-11 23:59:58 +01:00
if ( $this -> notice -> N === 0 ) {
$this -> showEmptyResults ( $q , $page );
2008-11-23 18:51:36 +00:00
}
2011-04-11 23:59:58 +01:00
if ( Event :: handle ( 'StartNoticeSearchShowResults' , array ( $this , $q , $this -> notice ))) {
$terms = preg_split ( '/[\s,]+/' , $q );
$nl = new SearchNoticeList ( $this -> notice , $this , $terms );
$cnt = $nl -> show ();
$this -> pagination ( $page > 1 ,
$cnt > NOTICES_PER_PAGE ,
$page ,
'noticesearch' ,
array ( 'q' => $q ));
Event :: handle ( 'EndNoticeSearchShowResults' , array ( $this , $q , $this -> notice ));
}
}
function showEmptyResults ( $q , $page )
{
2011-02-17 19:58:22 +00:00
// TRANS: Text for notice search results is the query had no results.
2009-04-07 04:26:33 +01:00
$this -> element ( 'p' , 'error' , _ ( 'No results.' ));
$this -> searchSuggestions ( $q );
if ( common_logged_in ()) {
2011-02-17 19:58:22 +00:00
// TRANS: Text for logged in users making a query for notices without results.
// TRANS: This message contains a Markdown link.
2009-04-07 04:26:33 +01:00
$message = sprintf ( _ ( 'Be the first to [post on this topic](%%%%action.newnotice%%%%?status_textarea=%s)!' ), urlencode ( $q ));
}
else {
2011-02-17 19:58:22 +00:00
// TRANS: Text for not logged in users making a query for notices without results.
// TRANS: This message contains Markdown links.
2009-11-11 12:24:02 +00:00
$message = sprintf ( _ ( 'Why not [register an account](%%%%action.register%%%%) and be the first to [post on this topic](%%%%action.newnotice%%%%?status_textarea=%s)!' ), urlencode ( $q ));
2009-04-07 04:26:33 +01:00
}
2009-04-07 22:09:27 +01:00
$this -> elementStart ( 'div' , 'guide' );
2009-04-07 04:26:33 +01:00
$this -> raw ( common_markup_to_html ( $message ));
$this -> elementEnd ( 'div' );
2009-02-22 13:02:17 +00:00
return ;
2008-12-23 19:19:07 +00:00
}
2009-09-03 20:42:50 +01:00
function showScripts ()
{
parent :: showScripts ();
$this -> autofocus ( 'q' );
}
2009-02-22 13:02:17 +00:00
}
2008-12-23 19:19:07 +00:00
2009-02-22 13:02:17 +00:00
class SearchNoticeList extends NoticeList {
function __construct ( $notice , $out = null , $terms )
2008-12-23 19:33:23 +00:00
{
2009-02-22 13:02:17 +00:00
parent :: __construct ( $notice , $out );
$this -> terms = $terms ;
}
2009-01-24 00:58:12 +00:00
2009-02-22 13:02:17 +00:00
function newListItem ( $notice )
{
return new SearchNoticeListItem ( $notice , $this -> out , $this -> terms );
}
}
2009-01-24 00:58:12 +00:00
2009-02-22 13:02:17 +00:00
class SearchNoticeListItem extends NoticeListItem {
function __construct ( $notice , $out = null , $terms )
{
parent :: __construct ( $notice , $out );
$this -> terms = $terms ;
}
function showContent ()
{
2009-01-23 01:22:17 +00:00
// FIXME: URL, image, video, audio
2009-02-22 13:02:17 +00:00
$this -> out -> elementStart ( 'p' , array ( 'class' => 'entry-content' ));
if ( $this -> notice -> rendered ) {
$this -> out -> raw ( $this -> highlight ( $this -> notice -> rendered , $this -> terms ));
2008-12-23 19:19:07 +00:00
} else {
2009-01-23 01:22:17 +00:00
// XXX: may be some uncooked notices in the DB,
// we cook them right now. This should probably disappear in future
// versions (>> 0.4.x)
2009-02-22 13:02:17 +00:00
$this -> out -> raw ( $this -> highlight ( common_render_content ( $this -> notice -> content , $this -> notice ), $this -> terms ));
2008-12-23 19:19:07 +00:00
}
2009-02-22 13:02:17 +00:00
$this -> out -> elementEnd ( 'p' );
2009-01-24 00:58:12 +00:00
2008-12-23 19:19:07 +00:00
}
2009-01-23 01:22:17 +00:00
/**
* Highlist query terms
*
* @ param string $text notice text
* @ param array $terms terms to highlight
*
* @ return void
*/
2008-12-23 19:33:23 +00:00
function highlight ( $text , $terms )
{
2009-02-22 13:02:17 +00:00
/* Highligh search terms */
2009-04-15 12:29:52 +01:00
$options = implode ( '|' , array_map ( 'preg_quote' , array_map ( 'htmlspecialchars' , $terms ),
array_fill ( 0 , sizeof ( $terms ), '/' )));
$pattern = " /( $options )/i " ;
2011-02-21 22:14:32 +00:00
$result = '' ;
/* Divide up into text (highlight me) and tags (don't touch) */
$chunks = preg_split ( '/(<[^>]+>)/' , $text , 0 , PREG_SPLIT_DELIM_CAPTURE );
foreach ( $chunks as $i => $chunk ) {
if ( $i % 2 == 1 ) {
// odd: delimiter (tag)
$result .= $chunk ;
} else {
// even: freetext between tags
$result .= preg_replace ( $pattern , '<strong>\\1</strong>' , $chunk );
}
}
2008-12-23 19:19:07 +00:00
return $result ;
}
2008-07-10 00:00:17 +01:00
}