Source for file Query.php

Documentation is available at Query.php

  1. <?php
  2. /*
  3.  *  $Id: Hook.php 1939 2007-07-05 23:47:48Z zYne $
  4.  *
  5.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  6.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  7.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  8.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  9.  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  14.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  15.  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16.  *
  17.  * This software consists of voluntary contributions made by many individuals
  18.  * and is licensed under the LGPL. For more information, see
  19.  * <http://www.phpdoctrine.com>.
  20.  */
  21.  
  22. /**
  23.  * Doctrine_Search_Query
  24.  *
  25.  * @package     Doctrine
  26.  * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
  27.  * @category    Object Relational Mapping
  28.  * @link        www.phpdoctrine.com
  29.  * @since       1.0
  30.  * @version     $Revision: 1939 $
  31.  * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
  32.  */
  33. {
  34.     /**
  35.      * @var Doctrine_Query $query           the base query
  36.      */
  37.     protected $_query;
  38.     /**
  39.      * @var Doctrine_Table $_table          the index table
  40.      */
  41.     protected $_table = array();
  42.     
  43.     protected $_sql = '';
  44.     
  45.     protected $_params = array();
  46.     
  47.  
  48.     protected $_condition;
  49.     /**
  50.      * @param octrine_Table $_table         the index table
  51.      */
  52.     public function __construct($table)
  53.     {
  54.         if (is_string($table)) {
  55.            $table Doctrine_Manager::table($table);
  56.         }
  57.  
  58.         $this->_table = $table;
  59.  
  60.         $this->_query = new Doctrine_Query();
  61.         $foreignId current(array_diff($this->_table->getColumnNames()array('keyword''field''position')));
  62.  
  63.         $this->_condition = $foreignId ' %s (SELECT ' $foreignId ' FROM ' $this->_table->getTableName(' WHERE ';
  64.     }
  65.     /**
  66.      * getQuery
  67.      *
  68.      * @return Doctrine_Query       returns the query object associated with this object
  69.      */
  70.     public function getQuery()
  71.     {
  72.         return $this->_query;
  73.     }
  74.  
  75.     public function search($text)
  76.     {
  77.         $text trim($text);
  78.         
  79.         $foreignId current(array_diff($this->_table->getColumnNames()array('keyword''field''position')));
  80.  
  81.         $weighted false;
  82.         if (strpos($text'^'=== false{
  83.             $select 'SELECT COUNT(keyword) AS relevance, ' $foreignId;
  84.             $from 'FROM ' $this->_table->getTableName();
  85.         else {
  86.             // organize terms according weights
  87.             $weighted true;
  88.  
  89.             $select 'SELECT SUM(sub_relevance) AS relevance, ' $foreignId;
  90.             $from 'FROM ' ;
  91.         }
  92.         
  93.         $where 'WHERE ';
  94.         $where .= $this->parseClause($text);
  95.  
  96.         $groupby 'GROUP BY ' $foreignId;
  97.         $orderby 'ORDER BY relevance';
  98.  
  99.         $this->_sql = $select ' ' $from ' ' $where ' ' $groupby ' ' $orderby;
  100.     }
  101.  
  102.     public function parseClause($originalClause$recursive false)
  103.     {
  104.         $clause Doctrine_Tokenizer::bracketTrim($originalClause);
  105.         
  106.         $brackets false;
  107.  
  108.         if ($clause !== $originalClause{
  109.             $brackets true;
  110.         }
  111.  
  112.         $foreignId current(array_diff($this->_table->getColumnNames()array('keyword''field''position')));
  113.         
  114.         $terms Doctrine_Tokenizer::sqlExplode($clause' OR ''('')');
  115.  
  116.         $ret array();
  117.  
  118.         if (count($terms1{
  119.             $leavesOnly true;
  120.  
  121.             foreach ($terms as $k => $term{
  122.                 if ($this->isExpression($term)) {
  123.                     $ret[$k$this->parseClause($termtrue);
  124.                     $leavesOnly false;
  125.                 else {
  126.                     $ret[$k$this->parseTerm($term);
  127.                 }
  128.             }
  129.  
  130.             $return implode(' OR '$ret);
  131.  
  132.             if ($leavesOnly && $recursive{
  133.                 $return sprintf($this->_condition'IN'$return ')';
  134.                 $brackets false;
  135.             }
  136.         else {
  137.             $terms Doctrine_Tokenizer::sqlExplode($clause' ''('')');
  138.             
  139.             if (count($terms=== && $recursive{
  140.                 $return $this->parseTerm($clause);
  141.             else {
  142.                 foreach ($terms as $k => $term{
  143.                     $term trim($term);
  144.     
  145.                     if ($term === 'AND'{
  146.                         continue;
  147.                     }
  148.     
  149.                     if (substr($term01=== '-'{
  150.                         $operator 'NOT IN';
  151.                         $term substr($term1);
  152.                     else {
  153.                         $operator 'IN';
  154.                     }
  155.     
  156.                     if ($this->isExpression($term)) {
  157.                         $ret[$k$this->parseClause($termtrue);
  158.                     else {
  159.                         $ret[$ksprintf($this->_condition$operator$this->parseTerm($term')';
  160.                     }
  161.                 }
  162.                 $return implode(' AND '$ret);
  163.             }
  164.         }
  165.  
  166.         if ($brackets{
  167.             return '(' $return ')';
  168.         else {
  169.             return $return;
  170.         }
  171.     }
  172.     public function isExpression($term)
  173.     {
  174.         if (strpos($term'('!== false{
  175.             return true;
  176.         else {
  177.             $terms Doctrine_Tokenizer::quoteExplode($term);
  178.             
  179.             return (count($terms1);
  180.         }
  181.     }
  182.  
  183.     public function parseTerm($term)
  184.     {
  185.         $negation false;
  186.  
  187.         if (strpos($term"'"=== false{
  188.             $where $this->parseWord($term);
  189.         else {
  190.             $term trim($term"' ");
  191.  
  192.             $terms Doctrine_Tokenizer::quoteExplode($term);
  193.             $where $this->parseWord($terms[0]);
  194.  
  195.             foreach ($terms as $k => $word{
  196.                 if ($k === 0{
  197.                     continue;
  198.                 }
  199.                 $where .= ' AND (position + ' $k ') = (SELECT position FROM ' $this->_table->getTableName(' WHERE ' $this->parseWord($word')';
  200.             }
  201.         }
  202.         return $where;
  203.     }
  204.     public function parseWord($word
  205.     {
  206.         if (strpos($word'?'!== false ||
  207.             strpos($word'*'!== false{
  208.             
  209.             $word str_replace('*''%'$word);
  210.  
  211.             $where 'keyword LIKE ?';
  212.             
  213.             $params array($word);
  214.         else {
  215.             $where 'keyword = ?';
  216.         }
  217.         
  218.         $this->_params[$word;
  219.  
  220.         return $where;
  221.     }
  222.     public function getParams()
  223.     {
  224.         return $this->_params;
  225.     }
  226.     public function getSql()
  227.     {
  228.         return $this->_sql;
  229.     }
  230.     public function execute()
  231.     {
  232.         $resultSet $this->_query->execute()
  233.         
  234.         return $resultSet;
  235.     }
  236. }