MediaSearch_Search
[ class tree: MediaSearch_Search ] [ index: MediaSearch_Search ] [ all elements ]

Source for file Engine.php

Documentation is available at Engine.php

  1. <?php
  2. /**
  3.  * MediaSearch
  4.  *
  5.  * LICENSE
  6.  *
  7.  * "THE BEER-WARE LICENSE" (Revision 42):
  8.  * "Sven Strittmatter" <ausserirdisch@sven-space.de> wrote this file.
  9.  * As long as you retain this notice you can do whatever you want with
  10.  * this stuff. If we meet some day, and you think this stuff is worth it,
  11.  * you can buy me a beer in return.
  12.  *
  13.  * $Author$
  14.  * $Revision$
  15.  *
  16.  * @category    MediaSearch
  17.  * @package     MediaSearch_Search
  18.  * @copyright   Copyright (c) 2009 Sven Strittmatter
  19.  */
  20.  
  21. /**
  22.   * @todo Write apidoc.
  23.   *
  24.   * @category   MediaSearch
  25.   * @package    MediaSearch_Search
  26.   * @copyright  Copyright (c) 2009 Sven Strittmatter
  27.   */
  28. class MediaSearch_Search_Engine implements Countable {
  29.     const TRACE_LEVEL = 51;
  30.  
  31.     const MOVIES    = 1;
  32.     const MUSIC     = 2;
  33.     const SOFTWARE  = 4;
  34.     const ALL       = 7;
  35.  
  36.     private $include;
  37.     private $query;
  38.     private $foundKeyWords;
  39.     private $hitList;
  40.     private $rankList;
  41.     private $searchResult;
  42.     
  43.     public function __construct() {
  44.         $this->setInclude();
  45.         $this->reset();
  46.     }
  47.  
  48.     public function setInclude($int = null) {
  49.         if (null === $int) {
  50.             $this->include = 0;
  51.             return;
  52.         }
  53.  
  54.         if (!is_int($int) || $int < 1 || $int > self::ALL) {
  55.             $message  = 'As include variable only a value between 1 ';
  56.             $message .= self::ALL . ' is allowed (Bitfield)!';
  57.             throw new InvalidArgumentException($message);
  58.         }
  59.  
  60.         MediaSearch_Log::debug('Set inclusion with: ', array($int));
  61.         $this->include = $this->include | $int;
  62.     }
  63.  
  64.     public function setQuery(MediaSearch_Search_Query $q) {
  65.         $this->query = $q;
  66.     }
  67.  
  68.     public function search() {
  69.         $this->reset();
  70.  
  71.         if ($this->query->isEmpty()) {
  72.             /**
  73.              * @todo Random search einbauen
  74.              */
  75.             return;
  76.         }
  77.  
  78.         $query = $this->query->get();
  79.         MediaSearch_Log::debug('prepared query:', array($query));
  80.         $keyWords = new MediaSearch_Model_KeyWord();
  81.         $result = $keyWords->findByKeyWords($query);
  82.         $this->processSearchResult($result);  
  83.     }
  84.  
  85.     public function getResults() {
  86.         return $this->searchResult;
  87.     }
  88.  
  89.     public function count() {
  90.         return count($this->searchResult);
  91.     }
  92.  
  93.     public function hasResults() {
  94.         return !empty($this->searchResult);
  95.     }
  96.  
  97.     public function toArray() {
  98.         $results = array();
  99.  
  100.         if ($this->hasResults()) {
  101.             foreach ($this->getResults() as $fileMeta) {
  102.                 $results[] = $fileMeta->toArray(false);
  103.             }
  104.         }
  105.         return $results;
  106.     }
  107.  
  108.     private function reset() {
  109.         MediaSearch_Log::trace('Resetting search!', self::TRACE_LEVEL);
  110.         $this->foundKeyWords = array();
  111.         $this->hitList       = array();
  112.         $this->rankList      = array();
  113.         $this->searchResult  = array();
  114.     }
  115.  
  116.     private function processSearchResult($resultsArray) {
  117.         if (empty($resultsArray)) {
  118.             return;
  119.         }
  120.         
  121.         foreach ($resultsArray as $resultsSet) {
  122.             $this->addFoundKeyWords($resultsSet);
  123.         }
  124.  
  125.         MediaSearch_Log::debug('Found keywords: ', array($this->foundKeyWords));
  126.         $this->generateHitList();
  127.         $this->generateRankList();
  128.         $this->loadFileInfo();
  129.     }
  130.  
  131.     private function addFoundKeyWords($resultSet) {
  132.         if (!$resultSet->getKeyWord()) {
  133.             MediaSearch_Log::warn('Doesnt have the "keyWord" in resultset!');
  134. //            MediaSearch_Log::debug('resultset: ', $resultSet);
  135.             return;
  136.         }
  137.  
  138.         $keyWord = strtolower($resultSet->getKeyWord());
  139.  
  140.         if (!array_key_exists($keyWord, $this->foundKeyWords)) {
  141.             $this->foundKeyWords[$keyWord] = array();
  142.         }
  143.  
  144.         $this->addFileMetaIdsToFoundKeys($keyWord, $resultSet);
  145.     }
  146.  
  147.     private function addFileMetaIdsToFoundKeys($keyWord, $resultSet) {
  148.         if (!$resultSet->getFileMetaIds()) {
  149.             MediaSearch_Log::warn('Doesnt have the "FileMetaIds" in resultset!');
  150. //            MediaSearch_Log::debug('resultset: ', $resultSet);
  151.             return;
  152.         }
  153.  
  154.         foreach ($resultSet->getFileMetaIds() as $id) {
  155.             $this->foundKeyWords[$keyWord][] = $id;
  156.         }
  157.     }
  158.  
  159.     private function generateHitList() {
  160.         foreach ($this->foundKeyWords as $fileMetaIds) {
  161.             $this->addFileMetaIdsToHitList($fileMetaIds);
  162.         }
  163.     }
  164.  
  165.     private function addFileMetaIdsToHitList($fileMetaIds) {
  166.         foreach ($fileMetaIds as $id) {
  167.             if (!array_key_exists($id, $this->hitList)) {
  168.                 $this->hitList[$id] = 0;
  169.             }
  170.  
  171.             $this->hitList[$id] += 1;
  172.         }
  173.     }
  174.  
  175.     private function generateRankList() {
  176.         $tmpRankList = array();
  177.  
  178.         foreach ($this->hitList as $fileMetaId => $hitCount) {
  179.             if (!array_key_exists($hitCount, $tmpRankList)) {
  180.                 $tmpRankList[$hitCount] = array();
  181.             }
  182.  
  183.             $tmpRankList[$hitCount][] = $fileMetaId;
  184.         }
  185.  
  186.         $rankIds = array_keys($tmpRankList);
  187.         rsort($rankIds);
  188.  
  189.         foreach ($rankIds as $rankId) {
  190.             $this->rankList = array_merge($this->rankList, $tmpRankList[$rankId]);
  191.         }
  192.     }
  193.  
  194.     private function loadFileInfo() {
  195.         MediaSearch_Log::trace('Loading file infos...', self::TRACE_LEVEL);
  196.         $fileMeta = new MediaSearch_Model_FileMeta();
  197.         $types = $this->determineFileTypes();
  198.         MediaSearch_Log::debug('Including file types.', array($types));
  199.         $searchResult = $fileMeta->findByIdAndTypes($this->rankList, $types);
  200.  
  201.         foreach ($searchResult as $fileMetaData) {
  202.             $fileMeta = new MediaSearch_Scan_FileMeta();
  203.             $fileMeta->fromObject($fileMetaData);
  204.             $rank = array_search($fileMetaData->getId(), $this->rankList);
  205.             $this->searchResult[$rank] = $fileMeta;
  206.             ksort($this->searchResult);
  207.         }
  208.     }
  209.  
  210.     private function determineFileTypes() {
  211.         MediaSearch_Log::trace('Determining file inclusions for: ' . $this->include);
  212.         $types = array();
  213.  
  214.         if (($this->include & self::MOVIES) === self::MOVIES) {
  215.             MediaSearch_Log::trace('Including movies.');
  216.             $types[] = MediaSearch_File_File::TYPE_MOVIE;
  217.         }
  218.  
  219.         if (($this->include & self::MUSIC) === self::MUSIC) {
  220.             MediaSearch_Log::trace('Including music.');
  221.             $types[] = MediaSearch_File_File::TYPE_MUSIC;
  222.         }
  223.  
  224.         if (($this->include & self::SOFTWARE) === self::SOFTWARE) {
  225.             MediaSearch_Log::trace('Including software.');
  226.             $types[] = MediaSearch_File_File::TYPE_SOFTWARE;
  227.         }
  228.  
  229.         return $types;
  230.     }
  231. }

Documentation generated on Mon, 17 Aug 2009 14:52:18 +0200 by phpDocumentor 1.4.2