Permalink
Browse files

upgrades Zend engine to version 1.5.0

  • Loading branch information...
1 parent 185441d commit 3702d88a6e1be0093fdf32578dea77abfb34a94a diml committed Apr 7, 2008
View
48 search/Zend/Search/Lucene/Analysis/Analyzer/Common/Utf8/CaseInsensitive.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Search_Lucene
+ * @subpackage Analysis
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+
+/** Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8 */
+require_once 'Zend/Search/Lucene/Analysis/Analyzer/Common/Utf8.php';
+
+/** Zend_Search_Lucene_Analysis_TokenFilter_LowerCaseUtf8 */
+require_once 'Zend/Search/Lucene/Analysis/TokenFilter/LowerCaseUtf8.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Search_Lucene
+ * @subpackage Analysis
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+
+class Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8_CaseInsensitive extends Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8
+{
+ public function __construct()
+ {
+ parent::__construct();
+
+ $this->addFilter(new Zend_Search_Lucene_Analysis_TokenFilter_LowerCaseUtf8());
+ }
+}
+
View
48 search/Zend/Search/Lucene/Analysis/Analyzer/Common/Utf8Num/CaseInsensitive.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Search_Lucene
+ * @subpackage Analysis
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+
+/** Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num */
+require_once 'Zend/Search/Lucene/Analysis/Analyzer/Common/Utf8Num.php';
+
+/** Zend_Search_Lucene_Analysis_TokenFilter_LowerCaseUtf8 */
+require_once 'Zend/Search/Lucene/Analysis/TokenFilter/LowerCaseUtf8.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Search_Lucene
+ * @subpackage Analysis
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+
+class Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num_CaseInsensitive extends Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num
+{
+ public function __construct()
+ {
+ parent::__construct();
+
+ $this->addFilter(new Zend_Search_Lucene_Analysis_TokenFilter_LowerCaseUtf8());
+ }
+}
+
View
69 search/Zend/Search/Lucene/Analysis/TokenFilter/LowerCaseUtf8.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Search_Lucene
+ * @subpackage Analysis
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+
+/** Zend_Search_Lucene_Analysis_TokenFilter */
+require_once 'Zend/Search/Lucene/Analysis/TokenFilter.php';
+
+
+/**
+ * Lower case Token filter.
+ *
+ * @category Zend
+ * @package Zend_Search_Lucene
+ * @subpackage Analysis
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+class Zend_Search_Lucene_Analysis_TokenFilter_LowerCaseUtf8 extends Zend_Search_Lucene_Analysis_TokenFilter
+{
+ /**
+ * Object constructor
+ */
+ public function __construct()
+ {
+ if (!function_exists('mb_strtolower')) {
+ // mbstring extension is disabled
+ require_once 'Zend/Search/Lucene/Exception.php';
+ throw new Zend_Search_Lucene_Exception('Utf8 compatible lower case filter needs mbstring extension to be enabled.');
+ }
+ }
+
+ /**
+ * Normalize Token or remove it (if null is returned)
+ *
+ * @param Zend_Search_Lucene_Analysis_Token $srcToken
+ * @return Zend_Search_Lucene_Analysis_Token
+ */
+ public function normalize(Zend_Search_Lucene_Analysis_Token $srcToken)
+ {
+ $newToken = new Zend_Search_Lucene_Analysis_Token(
+ mb_strtolower($srcToken->getTermText(), 'UTF-8'),
+ $srcToken->getStartOffset(),
+ $srcToken->getEndOffset());
+
+ $newToken->setPositionIncrement($srcToken->getPositionIncrement());
+
+ return $newToken;
+ }
+}
+
View
32 search/Zend/Search/Lucene/EncodingConverter.php
@@ -1,32 +0,0 @@
-<?php
-
-class EncodingConverter {
- private $last_error,
- $in_encoding,
- $out_encoding;
-
- function __construct($in_encoding, $out_encoding) {
- $this->in_encoding = $in_encoding;
- $this->out_encoding = $out_encoding;
- } //constructor
-
- function handleError($err, $msg) {
- $this->last_error = $msg;
- } //handleError
-
- function convert($str) {
- $this->last_error = FALSE;
-
- set_error_handler(array(&$this, 'handleError'));
- $ret = iconv($this->in_encoding, $this->out_encoding, $str);
- restore_error_handler();
-
- return $ret;
- } //convert
-
- function getLastError() {
- return $this->last_error;
- } //getLastError
-} //EncodingConverter
-
-?>
View
161 search/Zend/Search/Lucene/LockManager.php
@@ -0,0 +1,161 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Search_Lucene
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+
+/** Zend_Search_Lucene_Exception */
+require_once 'Zend/Search/Lucene/Exception.php';
+
+/** Zend_Search_Lucene_Storage_Directory */
+require_once 'Zend/Search/Lucene/Storage/Directory.php';
+
+/** Zend_Search_Lucene_Storage_File */
+require_once 'Zend/Search/Lucene/Storage/File.php';
+
+
+
+/**
+ * This is an utility class which provides index locks processing functionality
+ *
+ * @category Zend
+ * @package Zend_Search_Lucene
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Search_Lucene_LockManager
+{
+ const WRITE_LOCK_FILE = 'write.lock.file';
+ const READ_LOCK_FILE = 'read.lock.file';
+ const OPTIMIZATION_LOCK_FILE = 'optimization.lock.file';
+
+ /**
+ * Obtain exclusive write lock on the index
+ *
+ * @param Zend_Search_Lucene_Storage_Directory $lockDirectory
+ * @return Zend_Search_Lucene_Storage_File
+ * @throws Zend_Search_Lucene_Exception
+ */
+ public static function obtainWriteLock(Zend_Search_Lucene_Storage_Directory $lockDirectory)
+ {
+ $lock = $lockDirectory->createFile(self::WRITE_LOCK_FILE);
+ if (!$lock->lock(LOCK_EX)) {
+ throw new Zend_Search_Lucene_Exception('Can\'t obtain exclusive index lock');
+ }
+ return $lock;
+ }
+
+ /**
+ * Release exclusive write lock
+ *
+ * @param Zend_Search_Lucene_Storage_Directory $lockDirectory
+ */
+ public static function releaseWriteLock(Zend_Search_Lucene_Storage_Directory $lockDirectory)
+ {
+ $lock = $lockDirectory->getFileObject(self::WRITE_LOCK_FILE);
+ $lock->unlock();
+ }
+
+ /**
+ * Obtain shared read lock on the index
+ *
+ * It doesn't block other read or update processes, but prevent index from the premature cleaning-up
+ *
+ * @param Zend_Search_Lucene_Storage_Directory $defaultLockDirectory
+ * @return Zend_Search_Lucene_Storage_File
+ * @throws Zend_Search_Lucene_Exception
+ */
+ public static function obtainReadLock(Zend_Search_Lucene_Storage_Directory $lockDirectory)
+ {
+ $lock = $lockDirectory->createFile(self::READ_LOCK_FILE);
+ if (!$lock->lock(LOCK_SH)) {
+ throw new Zend_Search_Lucene_Exception('Can\'t obtain shared reading index lock');
+ }
+ return $lock;
+ }
+
+ /**
+ * Release shared read lock
+ *
+ * @param Zend_Search_Lucene_Storage_Directory $lockDirectory
+ */
+ public static function releaseReadLock(Zend_Search_Lucene_Storage_Directory $lockDirectory)
+ {
+ $lock = $lockDirectory->getFileObject(self::READ_LOCK_FILE);
+ $lock->unlock();
+ }
+
+ /**
+ * Escalate Read lock to exclusive level
+ *
+ * @param Zend_Search_Lucene_Storage_Directory $lockDirectory
+ * @return boolean
+ */
+ public static function escalateReadLock(Zend_Search_Lucene_Storage_Directory $lockDirectory)
+ {
+ $lock = $lockDirectory->getFileObject(self::READ_LOCK_FILE);
+
+ // Try to escalate read lock
+ if (!$lock->lock(LOCK_EX, true)) {
+ // Restore lock state
+ $lock->lock(LOCK_SH);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * De-escalate Read lock to shared level
+ *
+ * @param Zend_Search_Lucene_Storage_Directory $lockDirectory
+ */
+ public static function deEscalateReadLock(Zend_Search_Lucene_Storage_Directory $lockDirectory)
+ {
+ $lock = $lockDirectory->getFileObject(self::READ_LOCK_FILE);
+ $lock->lock(LOCK_SH);
+ }
+
+ /**
+ * Obtain exclusive optimization lock on the index
+ *
+ * Returns lock object on success and false otherwise (doesn't block execution)
+ *
+ * @param Zend_Search_Lucene_Storage_Directory $lockDirectory
+ * @return mixed
+ */
+ public static function obtainOptimizationLock(Zend_Search_Lucene_Storage_Directory $lockDirectory)
+ {
+ $lock = $lockDirectory->createFile(self::OPTIMIZATION_LOCK_FILE);
+ if (!$lock->lock(LOCK_EX, true)) {
+ return false;
+ }
+ return $lock;
+ }
+
+ /**
+ * Release exclusive optimization lock
+ *
+ * @param Zend_Search_Lucene_Storage_Directory $lockDirectory
+ */
+ public static function releaseOptimizationLock(Zend_Search_Lucene_Storage_Directory $lockDirectory)
+ {
+ $lock = $lockDirectory->getFileObject(self::OPTIMIZATION_LOCK_FILE);
+ $lock->unlock();
+ }
+
+}
View
390 search/Zend/Search/Lucene/Search/Query/Fuzzy.php
@@ -0,0 +1,390 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Search_Lucene
+ * @subpackage Search
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+
+/** Zend_Search_Lucene_Search_Query */
+require_once 'Zend/Search/Lucene/Search/Query.php';
+
+/** Zend_Search_Lucene_Search_Query_MultiTerm */
+require_once 'Zend/Search/Lucene/Search/Query/MultiTerm.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Search_Lucene
+ * @subpackage Search
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Search_Lucene_Search_Query_Fuzzy extends Zend_Search_Lucene_Search_Query
+{
+ /** Default minimum similarity */
+ const DEFAULT_MIN_SIMILARITY = 0.5;
+
+ /**
+ * Maximum number of matched terms.
+ * Apache Lucene defines this limitation as boolean query maximum number of clauses:
+ * org.apache.lucene.search.BooleanQuery.getMaxClauseCount()
+ */
+ const MAX_CLAUSE_COUNT = 1024;
+
+ /**
+ * Array of precalculated max distances
+ *
+ * keys are integers representing a word size
+ */
+ private $_maxDistances = array();
+
+ /**
+ * Base searching term.
+ *
+ * @var Zend_Search_Lucene_Index_Term
+ */
+ private $_term;
+
+ /**
+ * A value between 0 and 1 to set the required similarity
+ * between the query term and the matching terms. For example, for a
+ * _minimumSimilarity of 0.5 a term of the same length
+ * as the query term is considered similar to the query term if the edit distance
+ * between both terms is less than length(term)*0.5
+ *
+ * @var float
+ */
+ private $_minimumSimilarity;
+
+ /**
+ * The length of common (non-fuzzy) prefix
+ *
+ * @var integer
+ */
+ private $_prefixLength;
+
+ /**
+ * Matched terms.
+ *
+ * Matched terms list.
+ * It's filled during the search (rewrite operation) and may be used for search result
+ * post-processing
+ *
+ * Array of Zend_Search_Lucene_Index_Term objects
+ *
+ * @var array
+ */
+ private $_matches = null;
+
+ /**
+ * Matched terms scores
+ *
+ * @var array
+ */
+ private $_scores = null;
+
+ /**
+ * Array of the term keys.
+ * Used to sort terms in alphabetical order if terms have the same socres
+ *
+ * @var array
+ */
+ private $_termKeys = null;
+
+ /**
+ * Zend_Search_Lucene_Search_Query_Wildcard constructor.
+ *
+ * @param Zend_Search_Lucene_Index_Term $pattern
+ * @throws Zend_Search_Lucene_Exception
+ */
+ public function __construct(Zend_Search_Lucene_Index_Term $term, $minimumSimilarity = self::DEFAULT_MIN_SIMILARITY, $prefixLength = 0)
+ {
+ if ($minimumSimilarity < 0) {
+ throw new Zend_Search_Lucene_Exception('minimumSimilarity cannot be less than 0');
+ }
+ if ($minimumSimilarity >= 1) {
+ throw new Zend_Search_Lucene_Exception('minimumSimilarity cannot be greater than or equal to 1');
+ }
+ if ($prefixLength < 0) {
+ throw new Zend_Search_Lucene_Exception('prefixLength cannot be less than 0');
+ }
+
+ $this->_term = $term;
+ $this->_minimumSimilarity = $minimumSimilarity;
+ $this->_prefixLength = $prefixLength;
+ }
+
+ /**
+ * Calculate maximum distance for specified word length
+ *
+ * @param integer $prefixLength
+ * @param integer $termLength
+ * @param integer $length
+ * @return integer
+ */
+ private function _calculateMaxDistance($prefixLength, $termLength, $length)
+ {
+ $this->_maxDistances[$length] = (int) ((1 - $this->_minimumSimilarity)*(min($termLength, $length) + $prefixLength));
+ return $this->_maxDistances[$length];
+ }
+
+ /**
+ * Re-write query into primitive queries in the context of specified index
+ *
+ * @param Zend_Search_Lucene_Interface $index
+ * @return Zend_Search_Lucene_Search_Query
+ */
+ public function rewrite(Zend_Search_Lucene_Interface $index)
+ {
+ $this->_matches = array();
+ $this->_scores = array();
+ $this->_termKeys = array();
+
+ if ($this->_term->field === null) {
+ // Search through all fields
+ $fields = $index->getFieldNames(true /* indexed fields list */);
+ } else {
+ $fields = array($this->_term->field);
+ }
+
+ $prefix = Zend_Search_Lucene_Index_Term::getPrefix($this->_term->text, $this->_prefixLength);
+ $prefixByteLength = strlen($prefix);
+ $prefixUtf8Length = Zend_Search_Lucene_Index_Term::getLength($prefix);
+
+ $termLength = Zend_Search_Lucene_Index_Term::getLength($this->_term->text);
+
+ $termRest = substr($this->_term->text, $prefixByteLength);
+ // we calculate length of the rest in bytes since levenshtein() is not UTF-8 compatible
+ $termRestLength = strlen($termRest);
+
+ $scaleFactor = 1/(1 - $this->_minimumSimilarity);
+
+ foreach ($fields as $field) {
+ $index->resetTermsStream();
+
+ if ($prefix != '') {
+ $index->skipTo(new Zend_Search_Lucene_Index_Term($prefix, $field));
+
+ while ($index->currentTerm() !== null &&
+ $index->currentTerm()->field == $field &&
+ substr($index->currentTerm()->text, 0, $prefixByteLength) == $prefix) {
+ // Calculate similarity
+ $target = substr($index->currentTerm()->text, $prefixByteLength);
+
+ $maxDistance = isset($this->_maxDistances[strlen($target)])?
+ $this->_maxDistances[strlen($target)] :
+ $this->_calculateMaxDistance($prefixUtf8Length, $termRestLength, strlen($target));
+
+ if ($termRestLength == 0) {
+ // we don't have anything to compare. That means if we just add
+ // the letters for current term we get the new word
+ $similarity = (($prefixUtf8Length == 0)? 0 : 1 - strlen($target)/$prefixUtf8Length);
+ } else if (strlen($target) == 0) {
+ $similarity = (($prefixUtf8Length == 0)? 0 : 1 - $termRestLength/$prefixUtf8Length);
+ } else if ($maxDistance < abs($termRestLength - strlen($target))){
+ //just adding the characters of term to target or vice-versa results in too many edits
+ //for example "pre" length is 3 and "prefixes" length is 8. We can see that
+ //given this optimal circumstance, the edit distance cannot be less than 5.
+ //which is 8-3 or more precisesly abs(3-8).
+ //if our maximum edit distance is 4, then we can discard this word
+ //without looking at it.
+ $similarity = 0;
+ } else {
+ $similarity = 1 - levenshtein($termRest, $target)/($prefixUtf8Length + min($termRestLength, strlen($target)));
+ }
+
+ if ($similarity > $this->_minimumSimilarity) {
+ $this->_matches[] = $index->currentTerm();
+ $this->_termKeys[] = $index->currentTerm()->key();
+ $this->_scores[] = ($similarity - $this->_minimumSimilarity)*$scaleFactor;
+ }
+
+ $index->nextTerm();
+ }
+ } else {
+ $index->skipTo(new Zend_Search_Lucene_Index_Term('', $field));
+
+ while ($index->currentTerm() !== null && $index->currentTerm()->field == $field) {
+ // Calculate similarity
+ $target = $index->currentTerm()->text;
+
+ $maxDistance = isset($this->_maxDistances[strlen($target)])?
+ $this->_maxDistances[strlen($target)] :
+ $this->_calculateMaxDistance(0, $termRestLength, strlen($target));
+
+ if ($maxDistance < abs($termRestLength - strlen($target))){
+ //just adding the characters of term to target or vice-versa results in too many edits
+ //for example "pre" length is 3 and "prefixes" length is 8. We can see that
+ //given this optimal circumstance, the edit distance cannot be less than 5.
+ //which is 8-3 or more precisesly abs(3-8).
+ //if our maximum edit distance is 4, then we can discard this word
+ //without looking at it.
+ $similarity = 0;
+ } else {
+ $similarity = 1 - levenshtein($termRest, $target)/min($termRestLength, strlen($target));
+ }
+
+ if ($similarity > $this->_minimumSimilarity) {
+ $this->_matches[] = $index->currentTerm();
+ $this->_termKeys[] = $index->currentTerm()->key();
+ $this->_scores[] = ($similarity - $this->_minimumSimilarity)*$scaleFactor;
+ }
+
+ $index->nextTerm();
+ }
+ }
+
+ $index->closeTermsStream();
+ }
+
+ if (count($this->_matches) == 0) {
+ return new Zend_Search_Lucene_Search_Query_Empty();
+ } else if (count($this->_matches) == 1) {
+ return new Zend_Search_Lucene_Search_Query_Term(reset($this->_matches));
+ } else {
+ $rewrittenQuery = new Zend_Search_Lucene_Search_Query_Boolean();
+
+ array_multisort($this->_scores, SORT_DESC, SORT_NUMERIC,
+ $this->_termKeys, SORT_ASC, SORT_STRING,
+ $this->_matches);
+
+ $termCount = 0;
+ foreach ($this->_matches as $id => $matchedTerm) {
+ $subquery = new Zend_Search_Lucene_Search_Query_Term($matchedTerm);
+ $subquery->setBoost($this->_scores[$id]);
+
+ $rewrittenQuery->addSubquery($subquery);
+
+ $termCount++;
+ if ($termCount >= self::MAX_CLAUSE_COUNT) {
+ break;
+ }
+ }
+
+ return $rewrittenQuery;
+ }
+ }
+
+ /**
+ * Optimize query in the context of specified index
+ *
+ * @param Zend_Search_Lucene_Interface $index
+ * @return Zend_Search_Lucene_Search_Query
+ */
+ public function optimize(Zend_Search_Lucene_Interface $index)
+ {
+ throw new Zend_Search_Lucene_Exception('Wildcard query should not be directly used for search. Use $query->rewrite($index)');
+ }
+
+ /**
+ * Return query terms
+ *
+ * @return array
+ * @throws Zend_Search_Lucene_Exception
+ */
+ public function getQueryTerms()
+ {
+ if ($this->_matches === null) {
+ throw new Zend_Search_Lucene_Exception('Search has to be performed first to get matched terms');
+ }
+
+ return $this->_matches;
+ }
+
+ /**
+ * Constructs an appropriate Weight implementation for this query.
+ *
+ * @param Zend_Search_Lucene_Interface $reader
+ * @return Zend_Search_Lucene_Search_Weight
+ * @throws Zend_Search_Lucene_Exception
+ */
+ public function createWeight(Zend_Search_Lucene_Interface $reader)
+ {
+ throw new Zend_Search_Lucene_Exception('Wildcard query should not be directly used for search. Use $query->rewrite($index)');
+ }
+
+
+ /**
+ * Execute query in context of index reader
+ * It also initializes necessary internal structures
+ *
+ * @param Zend_Search_Lucene_Interface $reader
+ * @throws Zend_Search_Lucene_Exception
+ */
+ public function execute(Zend_Search_Lucene_Interface $reader)
+ {
+ throw new Zend_Search_Lucene_Exception('Wildcard query should not be directly used for search. Use $query->rewrite($index)');
+ }
+
+ /**
+ * Get document ids likely matching the query
+ *
+ * It's an array with document ids as keys (performance considerations)
+ *
+ * @return array
+ * @throws Zend_Search_Lucene_Exception
+ */
+ public function matchedDocs()
+ {
+ throw new Zend_Search_Lucene_Exception('Wildcard query should not be directly used for search. Use $query->rewrite($index)');
+ }
+
+ /**
+ * Score specified document
+ *
+ * @param integer $docId
+ * @param Zend_Search_Lucene_Interface $reader
+ * @return float
+ * @throws Zend_Search_Lucene_Exception
+ */
+ public function score($docId, Zend_Search_Lucene_Interface $reader)
+ {
+ throw new Zend_Search_Lucene_Exception('Wildcard query should not be directly used for search. Use $query->rewrite($index)');
+ }
+
+ /**
+ * Highlight query terms
+ *
+ * @param integer &$colorIndex
+ * @param Zend_Search_Lucene_Document_Html $doc
+ */
+ public function highlightMatchesDOM(Zend_Search_Lucene_Document_Html $doc, &$colorIndex)
+ {
+ $words = array();
+
+ foreach ($this->_matches as $term) {
+ $words[] = $term->text;
+ }
+
+ $doc->highlight($words, $this->_getHighlightColor($colorIndex));
+ }
+
+ /**
+ * Print a query
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ // It's used only for query visualisation, so we don't care about characters escaping
+ return (($this->_term->field === null)? '' : $this->_term->field . ':')
+ . $this->_term->text . '~'
+ . (($this->_minimumSimilarity != self::DEFAULT_MIN_SIMILARITY)? round($this->_minimumSimilarity, 4) : '');
+ }
+}
+
View
140 search/Zend/Search/Lucene/Search/Query/Insignificant.php
@@ -0,0 +1,140 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Search_Lucene
+ * @subpackage Search
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+
+/** Zend_Search_Lucene_Search_Query */
+require_once 'Zend/Search/Lucene/Search/Query.php';
+
+/** Zend_Search_Lucene_Search_Weight_Empty */
+require_once 'Zend/Search/Lucene/Search/Weight/Empty.php';
+
+
+/**
+ * The insignificant query returns empty result, but doesn't limit result set as a part of other queries
+ *
+ * @category Zend
+ * @package Zend_Search_Lucene
+ * @subpackage Search
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Search_Lucene_Search_Query_Insignificant extends Zend_Search_Lucene_Search_Query
+{
+ /**
+ * Re-write query into primitive queries in the context of specified index
+ *
+ * @param Zend_Search_Lucene_Interface $index
+ * @return Zend_Search_Lucene_Search_Query
+ */
+ public function rewrite(Zend_Search_Lucene_Interface $index)
+ {
+ return $this;
+ }
+
+ /**
+ * Optimize query in the context of specified index
+ *
+ * @param Zend_Search_Lucene_Interface $index
+ * @return Zend_Search_Lucene_Search_Query
+ */
+ public function optimize(Zend_Search_Lucene_Interface $index)
+ {
+ return $this;
+ }
+
+ /**
+ * Constructs an appropriate Weight implementation for this query.
+ *
+ * @param Zend_Search_Lucene_Interface $reader
+ * @return Zend_Search_Lucene_Search_Weight
+ */
+ public function createWeight(Zend_Search_Lucene_Interface $reader)
+ {
+ return new Zend_Search_Lucene_Search_Weight_Empty();
+ }
+
+ /**
+ * Execute query in context of index reader
+ * It also initializes necessary internal structures
+ *
+ * @param Zend_Search_Lucene_Interface $reader
+ */
+ public function execute(Zend_Search_Lucene_Interface $reader)
+ {
+ // Do nothing
+ }
+
+ /**
+ * Get document ids likely matching the query
+ *
+ * It's an array with document ids as keys (performance considerations)
+ *
+ * @return array
+ */
+ public function matchedDocs()
+ {
+ return array();
+ }
+
+ /**
+ * Score specified document
+ *
+ * @param integer $docId
+ * @param Zend_Search_Lucene_Interface $reader
+ * @return float
+ */
+ public function score($docId, Zend_Search_Lucene_Interface $reader)
+ {
+ return 0;
+ }
+
+ /**
+ * Return query terms
+ *
+ * @return array
+ */
+ public function getQueryTerms()
+ {
+ return array();
+ }
+
+ /**
+ * Highlight query terms
+ *
+ * @param integer &$colorIndex
+ * @param Zend_Search_Lucene_Document_Html $doc
+ */
+ public function highlightMatchesDOM(Zend_Search_Lucene_Document_Html $doc, &$colorIndex)
+ {
+ // Do nothing
+ }
+
+ /**
+ * Print a query
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return '<InsignificantQuery>';
+ }
+}
+
View
331 search/Zend/Search/Lucene/Search/Query/Range.php
@@ -0,0 +1,331 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Search_Lucene
+ * @subpackage Search
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+
+/** Zend_Search_Lucene_Search_Query */
+require_once 'Zend/Search/Lucene/Search/Query.php';
+
+/** Zend_Search_Lucene_Search_Query_MultiTerm */
+require_once 'Zend/Search/Lucene/Search/Query/MultiTerm.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Search_Lucene
+ * @subpackage Search
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Search_Lucene_Search_Query_Range extends Zend_Search_Lucene_Search_Query
+{
+ /**
+ * Lower term.
+ *
+ * @var Zend_Search_Lucene_Index_Term
+ */
+ private $_lowerTerm;
+
+ /**
+ * Upper term.
+ *
+ * @var Zend_Search_Lucene_Index_Term
+ */
+ private $_upperTerm;
+
+
+ /**
+ * Search field
+ *
+ * @var string
+ */
+ private $_field;
+
+ /**
+ * Inclusive
+ *
+ * @var boolean
+ */
+ private $_inclusive;
+
+ /**
+ * Matched terms.
+ *
+ * Matched terms list.
+ * It's filled during the search (rewrite operation) and may be used for search result
+ * post-processing
+ *
+ * Array of Zend_Search_Lucene_Index_Term objects
+ *
+ * @var array
+ */
+ private $_matches;
+
+
+ /**
+ * Zend_Search_Lucene_Search_Query_Range constructor.
+ *
+ * @param Zend_Search_Lucene_Index_Term|null $lowerTerm
+ * @param Zend_Search_Lucene_Index_Term|null $upperTerm
+ * @param boolean $inclusive
+ * @throws Zend_Search_Lucene_Exception
+ */
+ public function __construct($lowerTerm, $upperTerm, $inclusive)
+ {
+ if ($lowerTerm === null && $upperTerm === null) {
+ throw new Zend_Search_Lucene_Exception('At least one term must be non-null');
+ }
+ if ($lowerTerm !== null && $upperTerm !== null && $lowerTerm->field != $upperTerm->field) {
+ throw new Zend_Search_Lucene_Exception('Both terms must be for the same field');
+ }
+
+ $this->_field = ($lowerTerm !== null)? $lowerTerm->field : $upperTerm->field;
+ $this->_lowerTerm = $lowerTerm;
+ $this->_upperTerm = $upperTerm;
+ $this->_inclusive = $inclusive;
+ }
+
+ /**
+ * Get query field name
+ *
+ * @return string|null
+ */
+ public function getField()
+ {
+ return $this->_field;
+ }
+
+ /**
+ * Get lower term
+ *
+ * @return Zend_Search_Lucene_Index_Term|null
+ */
+ public function getLowerTerm()
+ {
+ return $this->_lowerTerm;
+ }
+
+ /**
+ * Get upper term
+ *
+ * @return Zend_Search_Lucene_Index_Term|null
+ */
+ public function getUpperTerm()
+ {
+ return $this->_upperTerm;
+ }
+
+ /**
+ * Get upper term
+ *
+ * @return boolean
+ */
+ public function isInclusive()
+ {
+ return $this->_inclusive;
+ }
+
+ /**
+ * Re-write query into primitive queries in the context of specified index
+ *
+ * @param Zend_Search_Lucene_Interface $index
+ * @return Zend_Search_Lucene_Search_Query
+ */
+ public function rewrite(Zend_Search_Lucene_Interface $index)
+ {
+ $this->_matches = array();
+
+ if ($this->_field === null) {
+ // Search through all fields
+ $fields = $index->getFieldNames(true /* indexed fields list */);
+ } else {
+ $fields = array($this->_field);
+ }
+
+ foreach ($fields as $field) {
+ $index->resetTermsStream();
+
+ if ($this->_lowerTerm !== null) {
+ $lowerTerm = new Zend_Search_Lucene_Index_Term($this->_lowerTerm->text, $field);
+
+ $index->skipTo($lowerTerm);
+
+ if (!$this->_inclusive &&
+ $index->currentTerm() == $lowerTerm) {
+ // Skip lower term
+ $index->nextTerm();
+ }
+ } else {
+ $index->skipTo(new Zend_Search_Lucene_Index_Term('', $field));
+ }
+
+
+ if ($this->_upperTerm !== null) {
+ // Walk up to the upper term
+ $upperTerm = new Zend_Search_Lucene_Index_Term($this->_upperTerm->text, $field);
+
+ while ($index->currentTerm() !== null &&
+ $index->currentTerm()->field == $field &&
+ $index->currentTerm()->text < $upperTerm->text) {
+ $this->_matches[] = $index->currentTerm();
+ $index->nextTerm();
+ }
+
+ if ($this->_inclusive && $index->currentTerm() == $upperTerm) {
+ // Include upper term into result
+ $this->_matches[] = $upperTerm;
+ }
+ } else {
+ // Walk up to the end of field data
+ while ($index->currentTerm() !== null && $index->currentTerm()->field == $field) {
+ $this->_matches[] = $index->currentTerm();
+ $index->nextTerm();
+ }
+ }
+
+ $index->closeTermsStream();
+ }
+
+ if (count($this->_matches) == 0) {
+ return new Zend_Search_Lucene_Search_Query_Empty();
+ } else if (count($this->_matches) == 1) {
+ return new Zend_Search_Lucene_Search_Query_Term(reset($this->_matches));
+ } else {
+ $rewrittenQuery = new Zend_Search_Lucene_Search_Query_MultiTerm();
+
+ foreach ($this->_matches as $matchedTerm) {
+ $rewrittenQuery->addTerm($matchedTerm);
+ }
+
+ return $rewrittenQuery;
+ }
+ }
+
+ /**
+ * Optimize query in the context of specified index
+ *
+ * @param Zend_Search_Lucene_Interface $index
+ * @return Zend_Search_Lucene_Search_Query
+ */
+ public function optimize(Zend_Search_Lucene_Interface $index)
+ {
+ throw new Zend_Search_Lucene_Exception('Range query should not be directly used for search. Use $query->rewrite($index)');
+ }
+
+ /**
+ * Return query terms
+ *
+ * @return array
+ * @throws Zend_Search_Lucene_Exception
+ */
+ public function getQueryTerms()
+ {
+ if ($this->_matches === null) {
+ throw new Zend_Search_Lucene_Exception('Search has to be performed first to get matched terms');
+ }
+
+ return $this->_matches;
+ }
+
+ /**
+ * Constructs an appropriate Weight implementation for this query.
+ *
+ * @param Zend_Search_Lucene_Interface $reader
+ * @return Zend_Search_Lucene_Search_Weight
+ * @throws Zend_Search_Lucene_Exception
+ */
+ public function createWeight(Zend_Search_Lucene_Interface $reader)
+ {
+ throw new Zend_Search_Lucene_Exception('Range query should not be directly used for search. Use $query->rewrite($index)');
+ }
+
+
+ /**
+ * Execute query in context of index reader
+ * It also initializes necessary internal structures
+ *
+ * @param Zend_Search_Lucene_Interface $reader
+ * @throws Zend_Search_Lucene_Exception
+ */
+ public function execute(Zend_Search_Lucene_Interface $reader)
+ {
+ throw new Zend_Search_Lucene_Exception('Range query should not be directly used for search. Use $query->rewrite($index)');
+ }
+
+ /**
+ * Get document ids likely matching the query
+ *
+ * It's an array with document ids as keys (performance considerations)
+ *
+ * @return array
+ * @throws Zend_Search_Lucene_Exception
+ */
+ public function matchedDocs()
+ {
+ throw new Zend_Search_Lucene_Exception('Range query should not be directly used for search. Use $query->rewrite($index)');
+ }
+
+ /**
+ * Score specified document
+ *
+ * @param integer $docId
+ * @param Zend_Search_Lucene_Interface $reader
+ * @return float
+ * @throws Zend_Search_Lucene_Exception
+ */
+ public function score($docId, Zend_Search_Lucene_Interface $reader)
+ {
+ throw new Zend_Search_Lucene_Exception('Range query should not be directly used for search. Use $query->rewrite($index)');
+ }
+
+ /**
+ * Highlight query terms
+ *
+ * @param integer &$colorIndex
+ * @param Zend_Search_Lucene_Document_Html $doc
+ */
+ public function highlightMatchesDOM(Zend_Search_Lucene_Document_Html $doc, &$colorIndex)
+ {
+ $words = array();
+
+ foreach ($this->_matches as $term) {
+ $words[] = $term->text;
+ }
+
+ $doc->highlight($words, $this->_getHighlightColor($colorIndex));
+ }
+
+ /**
+ * Print a query
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ // It's used only for query visualisation, so we don't care about characters escaping
+ return (($this->_field === null)? '' : $this->_field . ':')
+ . (($this->_inclusive)? '[' : '{')
+ . (($this->_lowerTerm !== null)? $this->_lowerTerm->text : 'null')
+ . ' TO '
+ . (($this->_upperTerm !== null)? $this->_upperTerm->text : 'null')
+ . (($this->_inclusive)? ']' : '}');
+ }
+}
+
View
297 search/Zend/Search/Lucene/Search/Query/Wildcard.php
@@ -0,0 +1,297 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Search_Lucene
+ * @subpackage Search
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+
+
+/** Zend_Search_Lucene_Search_Query */
+require_once 'Zend/Search/Lucene/Search/Query.php';
+
+/** Zend_Search_Lucene_Search_Query_MultiTerm */
+require_once 'Zend/Search/Lucene/Search/Query/MultiTerm.php';
+
+
+/**
+ * @category Zend
+ * @package Zend_Search_Lucene
+ * @subpackage Search
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Search_Lucene_Search_Query_Wildcard extends Zend_Search_Lucene_Search_Query
+{
+ /**
+ * Search pattern.
+ *
+ * Field has to be fully specified or has to be null
+ * Text may contain '*' or '?' symbols
+ *
+ * @var Zend_Search_Lucene_Index_Term
+ */
+ private $_pattern;
+
+ /**
+ * Matched terms.
+ *
+ * Matched terms list.
+ * It's filled during the search (rewrite operation) and may be used for search result
+ * post-processing
+ *
+ * Array of Zend_Search_Lucene_Index_Term objects
+ *
+ * @var array
+ */
+ private $_matches = null;
+
+ /**
+ * Zend_Search_Lucene_Search_Query_Wildcard constructor.
+ *
+ * @param Zend_Search_Lucene_Index_Term $pattern
+ */
+ public function __construct(Zend_Search_Lucene_Index_Term $pattern)
+ {
+ $this->_pattern = $pattern;
+ }
+
+ /**
+ * Get terms prefix
+ *
+ * @param string $word
+ * @return string
+ */
+ private static function _getPrefix($word)
+ {
+ $questionMarkPosition = strpos($word, '?');
+ $astrericPosition = strpos($word, '*');
+
+ if ($questionMarkPosition !== false) {
+ if ($astrericPosition !== false) {
+ return substr($word, 0, min($questionMarkPosition, $astrericPosition));
+ }
+
+ return substr($word, 0, $questionMarkPosition);
+ } else if ($astrericPosition !== false) {
+ return substr($word, 0, $astrericPosition);
+ }
+
+ return $word;
+ }
+
+ /**
+ * Re-write query into primitive queries in the context of specified index
+ *
+ * @param Zend_Search_Lucene_Interface $index
+ * @return Zend_Search_Lucene_Search_Query
+ */
+ public function rewrite(Zend_Search_Lucene_Interface $index)
+ {
+ $this->_matches = array();
+
+ if ($this->_pattern->field === null) {
+ // Search through all fields
+ $fields = $index->getFieldNames(true /* indexed fields list */);
+ } else {
+ $fields = array($this->_pattern->field);
+ }
+
+ $prefix = self::_getPrefix($this->_pattern->text);
+ $prefixLength = strlen($prefix);
+ $matchExpression = '/^' . str_replace(array('\\?', '\\*'), array('.', '.*') , preg_quote($this->_pattern->text, '/')) . '$/';
+
+ /** @todo check for PCRE unicode support may be performed through Zend_Environment in some future */
+ if (@preg_match('/\pL/u', 'a') == 1) {
+ // PCRE unicode support is turned on
+ // add Unicode modifier to the match expression
+ $matchExpression .= 'u';
+ }
+
+
+ foreach ($fields as $field) {
+ $index->resetTermsStream();
+
+ if ($prefix != '') {
+ $index->skipTo(new Zend_Search_Lucene_Index_Term($prefix, $field));
+
+ while ($index->currentTerm() !== null &&
+ $index->currentTerm()->field == $field &&
+ substr($index->currentTerm()->text, 0, $prefixLength) == $prefix) {
+ if (preg_match($matchExpression, $index->currentTerm()->text) === 1) {
+ $this->_matches[] = $index->currentTerm();
+ }
+
+ $index->nextTerm();
+ }
+ } else {
+ $index->skipTo(new Zend_Search_Lucene_Index_Term('', $field));
+
+ while ($index->currentTerm() !== null && $index->currentTerm()->field == $field) {
+ if (preg_match($matchExpression, $index->currentTerm()->text) === 1) {
+ $this->_matches[] = $index->currentTerm();
+ }
+
+ $index->nextTerm();
+ }
+ }
+
+ $index->closeTermsStream();
+ }
+
+ if (count($this->_matches) == 0) {
+ return new Zend_Search_Lucene_Search_Query_Empty();
+ } else if (count($this->_matches) == 1) {
+ return new Zend_Search_Lucene_Search_Query_Term(reset($this->_matches));
+ } else {
+ $rewrittenQuery = new Zend_Search_Lucene_Search_Query_MultiTerm();
+
+ foreach ($this->_matches as $matchedTerm) {
+ $rewrittenQuery->addTerm($matchedTerm);
+ }
+
+ return $rewrittenQuery;
+ }
+ }
+
+ /**
+ * Optimize query in the context of specified index
+ *
+ * @param Zend_Search_Lucene_Interface $index
+ * @return Zend_Search_Lucene_Search_Query
+ */
+ public function optimize(Zend_Search_Lucene_Interface $index)
+ {
+ throw new Zend_Search_Lucene_Exception('Wildcard query should not be directly used for search. Use $query->rewrite($index)');
+ }
+
+
+ /**
+ * Returns query pattern
+ *
+ * @return Zend_Search_Lucene_Index_Term
+ */
+ public function getPattern()
+ {
+ return $this->_pattern;
+ }
+
+
+ /**
+ * Return query terms
+ *
+ * @return array
+ * @throws Zend_Search_Lucene_Exception
+ */
+ public function getQueryTerms()
+ {
+ if ($this->_matches === null) {
+ throw new Zend_Search_Lucene_Exception('Search has to be performed first to get matched terms');
+ }
+
+ return $this->_matches;
+ }
+
+ /**
+ * Constructs an appropriate Weight implementation for this query.
+ *
+ * @param Zend_Search_Lucene_Interface $reader
+ * @return Zend_Search_Lucene_Search_Weight
+ * @throws Zend_Search_Lucene_Exception
+ */
+ public function createWeight(Zend_Search_Lucene_Interface $reader)
+ {
+ throw new Zend_Search_Lucene_Exception('Wildcard query should not be directly used for search. Use $query->rewrite($index)');
+ }
+
+
+ /**
+ * Execute query in context of index reader
+ * It also initializes necessary internal structures
+ *
+ * @param Zend_Search_Lucene_Interface $reader
+ * @throws Zend_Search_Lucene_Exception
+ */
+ public function execute(Zend_Search_Lucene_Interface $reader)
+ {
+ throw new Zend_Search_Lucene_Exception('Wildcard query should not be directly used for search. Use $query->rewrite($index)');
+ }
+
+ /**
+ * Get document ids likely matching the query
+ *
+ * It's an array with document ids as keys (performance considerations)
+ *
+ * @return array
+ * @throws Zend_Search_Lucene_Exception
+ */
+ public function matchedDocs()
+ {
+ throw new Zend_Search_Lucene_Exception('Wildcard query should not be directly used for search. Use $query->rewrite($index)');
+ }
+
+ /**
+ * Score specified document
+ *
+ * @param integer $docId
+ * @param Zend_Search_Lucene_Interface $reader
+ * @return float
+ * @throws Zend_Search_Lucene_Exception
+ */
+ public function score($docId, Zend_Search_Lucene_Interface $reader)
+ {
+ throw new Zend_Search_Lucene_Exception('Wildcard query should not be directly used for search. Use $query->rewrite($index)');
+ }
+
+ /**
+ * Highlight query terms
+ *
+ * @param integer &$colorIndex
+ * @param Zend_Search_Lucene_Document_Html $doc
+ */
+ public function highlightMatchesDOM(Zend_Search_Lucene_Document_Html $doc, &$colorIndex)
+ {
+ $words = array();
+
+ $matchExpression = '/^' . str_replace(array('\\?', '\\*'), array('.', '.*') , preg_quote($this->_pattern->text, '/')) . '$/';
+ if (@preg_match('/\pL/u', 'a') == 1) {
+ // PCRE unicode support is turned on
+ // add Unicode modifier to the match expression
+ $matchExpression .= 'u';
+ }
+
+ $tokens = Zend_Search_Lucene_Analysis_Analyzer::getDefault()->tokenize($doc->getFieldUtf8Value('body'), 'UTF-8');
+ foreach ($tokens as $token) {
+ if (preg_match($matchExpression, $token->getTermText()) === 1) {
+ $words[] = $token->getTermText();
+ }
+ }
+
+ $doc->highlight($words, $this->_getHighlightColor($colorIndex));
+ }
+
+ /**
+ * Print a query
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ // It's used only for query visualisation, so we don't care about characters escaping
+ return (($this->_pattern->field === null)? '' : $this->_pattern->field . ':') . $this->_pattern->text;
+ }
+}
+

0 comments on commit 3702d88

Please sign in to comment.