<?php
/*
* This file is part of the pwp package.
* (c) 2009-2010 Victor Rad' <victor.v.rad[at]gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Search actions
*
* @package pwp
* @subpackage search
* @author Victor Rad'
*/
class searchActions extends sfActions
{
/**
* Forming of friendly URL from the POST query of search string
*/
public function preExecute()
{
// prepare data
$request = sfContext::getInstance()->getRequest();
$query = $request->getParameter('query');
// forming friendly URL and redirect
if ($request->isMethod('post') and strlen($query)){
$this->redirect('@search_query?query='.$query);
}
elseif ($request->isMethod('post') and !strlen($query)){
$this->redirect('@homepage');
}
}
/**
* Executes index action
*
* @param sfRequest $request A request object
*/
public function executeIndex(sfWebRequest $request)
{
// do search
$query = $request->getParameter('query');
$search = new Search_Composite(new Search_Resume(), new Search_Portfolio(), new Search_News());
$foundIds = $search->find($query);
// pager
$this->pager = new SearchPager('Search_Composite', sfConfig::get('app_search_per_page'));
$this->pager->setFoundIds($foundIds);
$this->pager->setPage($request->getParameter('page', 1));
$this->pager->init();
// pager slice
$foundIdsSlice = $this->pager->getResults();
$search->setFoundIds($foundIdsSlice);
// get found data
$this->foundRendered = $search->render();
$this->foundData = $search->getFoundData();
// count items for current page
$this->countFoundSlice = 0;
foreach ($foundIdsSlice as $ids){
$this->countFoundSlice += count($ids);
}
// HTML meta tags
$this->getResponse()->setTitle('Search');
$this->getResponse()->addMeta('description', 'Results for "'. $query .'"');
}
/**
* First column on page
*/
public function postExecute()
{
$this->getResponse()->setSlot('colOne', $this->getPartial('colOne'));
}
}
<?php
/*
* This file is part of the pwp package.
* (c) 2009-2010 Victor Rad' <victor.v.rad[at]gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Search collection
* Represent of Composite pattern
*
* @package pwp
* @subpackage Search
* @author Victor Rad'
*/
class Search_Composite extends Search
{
protected $instances = array();
/**
* Register new instances of search collection
*
* @param array of search $instances
*/
public function __construct()
{
$searchInstances = func_get_args();
$this->register($searchInstances);
}
/**
* Setter found ids for search collection
*/
public function setFoundIds($foundIds)
{
foreach ($foundIds as $key => $ids){
$this->instances[$key]->setFoundIds($ids);
}
}
/**
* Getter found ids for search collection
*/
public function getFoundIds()
{
foreach ($this->instances as $instance){
$foundIds[] = $instance->getFoundIds();
}
return $foundIds;
}
/**
* Getter found data for search collection
*/
public function getFoundData()
{
foreach ($this->instances as $instance){
$foundData[] = $instance->getFoundData();
}
return $foundData;
}
/**
* Register new instances of search collection
*
* @param array of search $instances
*/
public function register($instances)
{
foreach ($instances as $instance) {
if ($instance instanceof Search){
array_push($this->instances, $instance);
}
else{
throw new Exception(sprintf('Instance %s must implements of Search class', $instance));
}
}
}
/**
* Find words in search collection
*
* @param string $query
*/
public function find($query)
{
$foundIds = array();
foreach ($this->instances as $instance){
$foundIds[] = $instance->find($query);
}
return $foundIds;
}
/**
* Render templates in search collection
*
* @return string
*/
public function render()
{
$rendered = '';
foreach ($this->instances as $instance){
$rendered .= $instance->render();
}
return $rendered;
}
/**
* Delete indexes and load
* all data from scratch in search collection
*
* @return <type>
*/
public function rebuildIndex()
{
foreach ($this->instances as $instance){
$instance->rebuildIndex();
}
}
}
<?php
/*
* This file is part of the pwp package.
* (c) 2009-2010 Victor Rad' <victor.v.rad[at]gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Class of news for search system
*
* @package pwp
* @subpackage Search
* @author Victor Rad'
*/
class Search_News extends Search
{
// added to $indexPath
protected $indexName = 'news';
/**
* Update or insert document into index
*
* @param mixed $obj with data
*/
public function update($obj)
{
// remove existing entries
foreach ($this->index->find('pk:'.$obj->getId()) as $hit){
$this->index->delete($hit->id);
}
$doc = new Zend_Search_Lucene_Document();
// index fields
$doc->addField(Zend_Search_Lucene_Field::Keyword('pk', $obj->getId()));
$doc->addField(Zend_Search_Lucene_Field::UnStored('title', $obj->getTitle(), 'utf-8'));
$doc->addField(Zend_Search_Lucene_Field::UnStored('description', $obj->getDescription(), 'utf-8'));
// add item to the index
$this->index->addDocument($doc);
$this->index->commit();
}
/**
* See Search::render()
*/
public function render()
{
// prepare data
$newsRendered = '';
$newsList = null;
sfContext::getInstance()->getConfiguration()->loadHelpers('Partial');
sfContext::getInstance()->getConfiguration()->loadHelpers('Text');
$highlighter = new My_Zend_Search_Lucene_Search_Highlighter_Default();
$highlighter->setHighlightColors(sfConfig::get('app_search_highlight_color'));
// get data
$newsList = $this->loadData();
if ($newsList) {
// highlight found strings and render the partial
foreach ($newsList as $newsOne) {
$newsOne->setTitle('News: '.$newsOne->getTitle());
$newsOne->setDescription(truncate_text($newsOne->getDescription(), 400, '...', true));
$newsOne->setDescription($this->query->htmlFragmentHighlightMatches( $newsOne->getDescription(), '', $highlighter));
$newsRendered .= get_partial('news/item', array('news' => $newsOne));
}
}
return $newsRendered;
}
/**
* See Search::find()
*/
public function find($query)
{
return $this->_find($query);
}
/**
* Get data by found ids
*
* @return Doctrine_Collection
*/
public function loadData()
{
$newsList = null;
$foundIds = $this->getFoundIds();
if ($foundIds) {
$newsList = DFactory::get('News')
->getBuilder()
->joinProvides()
->getQuery()
->whereIn('n.id', $foundIds)
->execute();
$this->setFoundData($newsList);
}
return $newsList;
}
/**
* See Search::rebuildIndex()
*/
public function rebuildIndex()
{
// delete index files
sfContext::getInstance()->getConfiguration()->loadHelpers('MyUtil');
my_unlink($this->indexPath, true);
// prepare data
$index = $this->getIndex('create');
$doc = new Zend_Search_Lucene_Document();
// get all news from db
$news = DFactory::get('News')->getTable()->findAll();
foreach ($news as $newsOne) {
// index fields
$doc->addField(Zend_Search_Lucene_Field::Keyword('pk', $newsOne->getId()));
$doc->addField(Zend_Search_Lucene_Field::UnStored('title', $newsOne->getTitle(), 'utf-8'));
$doc->addField(Zend_Search_Lucene_Field::UnStored('description', $newsOne->getDescription(), 'utf-8'));
// add to the index
$index->addDocument($doc);
$index->commit();
}
}
}