Full-Text Search 4.0

From Cloudrexx Development Wiki
Jump to: navigation, search

Note: This documentation refers to version 4 or older. For newer versions of Cloudrexx, please refer to Full-Text Search.

Contrexx contains a Full-Text Search application that is used to look up content in the available applications by a certain keyword. As of version 4, the following applications have been integrated into the Full-Text Search application:

Application Integrated since
Calendar 1.2.0
Content 1.0.0
Directory 1.1.0
DocSys 1.0.0
Forum 2.0.0
Gallery 1.0.5
MemberDir 1.1.0
News 1.0.0
Podcast 1.0.9
Shop 1.0.0

Functionality

This shall be changed, by moving those code snippets to the related component's directory and then get them included using the Contrexx Event System. Study the documentation of the Contrexx Event System. The component Search shall therefore register an Event (called SearchFindContent) to which each component then registers an EventListener through which the search operation shall get performed. The Search component has already been extended by registering the new Event SearchFindContent (do update to newest SVN revision) in method preContentLoad in its ComponentController. Additionally, the Search component has been extended to now use the Event System for fetching the search results of each component instead of doing it on its own in method \Cx\Core_Modules\Search\Controller\Search::getPage().


Application Integration

Register an Event Listener to the _Event_ SearchFindContent in the method preContentParse the component's ComponentController. Example for News component:

public function preContentParse(\Cx\Core\ContentManager\Model\Entity\Page $page) {
    $this->cx->getEvents()->addEventListener('SearchFindContent', new \Cx\Core_Modules\News\Model\Event\NewsEventListener());
}

When the Event SearchFindContent is triggered, the instance of Full-Text Search component (\Cx\Core_Modules\Search\Controller\Search) is passed as the second argument $eventArgs to the registered Event Listeners.

$search->getTerm()
$search->getResultArray()
$search->appendResult()


Example of EventListener for News component
<?php
/**
 * EventListener for News
 * 
 * @copyright   Comvation AG
 * @author      Project Team SS4U <info@comvation.com>
 * @package     contrexx
 * @subpackage  coremodule_news
 */

namespace Cx\Core_Modules\News\Model\Event;

/**
 * EventListener for News
 * 
 * @copyright   Comvation AG
 * @author      Project Team SS4U <info@comvation.com>
 * @package     contrexx
 * @subpackage  coremodule_news
 */
class NewsEventListener implements \Cx\Core\Event\Model\Entity\EventListener
{
    public function onEvent($eventName, $eventArgs) 
    {
        switch ($eventName) {
            case 'SearchFindContent':
                return self::performSearch($eventArgs);
                break;

            default:
                break;
        }
    }

    public static function performSearch($search)
    {
        $term_db = $search->getTerm();
        $query = "SELECT id, text AS content, title, date, redirect,
               MATCH (text,title,teaser_text) AGAINST ('%$term_db%') AS score
          FROM ".DBPREFIX."module_news AS tblN
         INNER JOIN ".DBPREFIX."module_news_locale AS tblL ON tblL.news_id = tblN.id
         WHERE (   text LIKE ('%$term_db%')
                OR title LIKE ('%$term_db%')
                OR teaser_text LIKE ('%$term_db%'))
           AND lang_id=".FRONTEND_LANG_ID."
           AND status=1
           AND is_active=1
           AND (startdate<='".date('Y-m-d')."' OR startdate='0000-00-00')
           AND (enddate>='".date('Y-m-d')."' OR enddate='0000-00-00')";

        $result = new \Cx\Core_Modules\Listing\Model\Entity\DataSet($search->getResultArray($query, 'News', 'details', 'newsid=', $search->getTerm()));
        $search->appendResult($result);
    }
}

I suggest to extend this method to allow the argument $pagevar to be either a String (as of now) or an Anonymous Function (new).

If an Anonymous Function is passed as argument $pagevar, the anonymous function must accept the two arguments $pageUri and $searchData. An example (for component Calendar) of such an Anonymous Function follows :

function($pageUri, $searchData) {
    return $pageUri . '?id=' . $searchData['id'] . '&date=' . intval($searchData['startdate']);
}

The other parts of the component specific operations are to manipulate the actual search data. To move that code to each component's own Event Listener I suggest to extend the method getResultArray() by an additional argument $parseSearchData (default null). The argument $parseSearchData shall accept an Anonymous Functions to be called to process the search data. Such an Anonymous Function must accept the argument $searchData. An usage example follows:

$parseSearchData = function(&$searchData) {
    $searchData['title'] = $searchData['name'];
    ...
}
$search->getResultArray($query, 'Shop', 'details', 'productId=', $search->getTerm(), $parseSearchData);

Search Other Files

To create an indexer that searches other files.

See: Indexer