Commits

ad...@admin-PC.dic.md  committed c3b8870

Add Lucene plugin

  • Participants
  • Parent commits cb81256

Comments (0)

Files changed (3)

File library/DoctrineX/Record.php

+<?php
+class DoctrineX_Record extends Doctrine_Record
+{
+    public function getBaseQuery(Doctrine_Query $query = null, $alias = null)
+    {
+        if (null === $query) {
+            $query = $this->getTable()->createQuery($alias);
+        }
+        return $query;
+    }
+}

File library/DoctrineX/Template/Listener/Lucene.php

+<?php
+class DoctrineX_Template_Listener_Lucene extends Doctrine_Record_Listener
+{
+    public function __construct(array $options)
+    {
+        $this->_options = $options;
+    }
+
+    /**
+     *
+     * @param Doctrine_Event $event
+     */
+    public function postInsert(Doctrine_Event $event)
+    {
+        $invoker = $event->getInvoker();
+        $index = $invoker->getLuceneIndex();
+
+        if (method_exists($invoker, 'preLucene')) {
+            $invoker->preLucene();
+        }
+
+        $doc = $invoker->createLuceneDocument();
+        $index->addDocument($doc);
+        $index->commit();
+
+        if (method_exists($invoker, 'postLucene')) {
+            $invoker->postLucene();
+        }
+    }
+
+    public function postUpdate(Doctrine_Event $event)
+    {
+        $invoker = $event->getInvoker();
+        $index = $invoker->getLuceneIndex();
+
+        $hits = $invoker->findLuceneDocument();
+        foreach ($hits as $hit) {
+            $index->delete($hit->id);
+        }
+
+        $doc = $invoker->createLuceneDocument();
+        $index->addDocument($doc);
+        $index->commit();
+    }
+
+    public function postDelete(Doctrine_Event $event)
+    {
+        $invoker = $event->getInvoker();
+        $index = $invoker->getLuceneIndex();
+
+        $hits = $invoker->findLuceneDocument();
+        foreach ($hits as $hit) {
+            $index->delete($hit->id);
+        }
+        $index->commit();
+    }
+}

File library/DoctrineX/Template/Lucene.php

+<?php
+class DoctrineX_Template_Lucene extends Doctrine_Template
+{
+    /**
+     *
+     * @var Zend_Search_Lucene_Interface
+     */
+    protected $_index = null;
+
+    /**
+     *
+     * @var array
+     */
+    protected $_identifierFields = array();
+
+    /**
+     *
+     * @var array
+     */
+    protected $_userFields = array();
+
+    /**
+     *
+     * @var array
+     */
+    protected $_fields = array();
+
+    /**
+     *
+     * @var string
+     */
+    protected $_encoding = '';
+
+    public function __construct(array $options = array())
+    {
+        if (!isset($options['indexesPath']) && !isset($options['indexFile'])) {
+            throw new Doctrine_Record_Exception('Option "indexesPath" or "indexFile" is required');
+        }
+
+        if (!isset($options['fields'])) {
+            throw new Doctrine_Record_Exception('Option "fields" is required');
+        }
+
+        if (isset($options['encoding'])) {
+            $this->_encoding = $options['encoding'];
+            Zend_Search_Lucene_Search_QueryParser::setDefaultEncoding($this->_encoding);
+        }
+
+        if (isset($options['analyzer'])) {
+            Zend_Search_Lucene_Analysis_Analyzer::setDefault(
+                new $options['analyzer']()
+            );
+        }
+
+        if (isset($options['filters'])) {
+            $filters = $options['filters'];
+        } else {
+            $filters = array();
+        }
+        if (isset($options['stopWords'])) {
+            $filters[] = new Zend_Search_Lucene_Analysis_TokenFilter_StopWords($options['stopWords']);
+        }
+        if (isset($options['stopWordsFile'])) {
+            $stopWordsFilter = new Zend_Search_Lucene_Analysis_TokenFilter_StopWords();
+            $stopWordsFilter->loadFromFile($options['stopWordsFile']);
+            $filters[] = $stopWordsFilter;
+        }
+        if (!empty($filters)) {
+            $analyzer = Zend_Search_Lucene_Analysis_Analyzer::getDefault();
+            foreach ($filters as $filter) {
+                $analyzer->addFilter($filter);
+            }
+        }
+
+        parent::__construct($options);
+    }
+
+    public function setTableDefinition()
+    {
+        $this->addListener(new DoctrineX_Template_Listener_Lucene($this->_options));
+    }
+
+    /**
+     *
+     * @return string
+     */
+    public function getLuceneIndexFile()
+    {
+        if (isset($this->_options['indexFile'])) {
+            return $this->_options['indexFile'];
+        } else {
+            return $this->_options['indexesPath'] . '/' . get_class($this->_invoker);
+        }
+    }
+
+    /**
+     *
+     * @return Zend_Search_Lucene_Interface
+     */
+    public function getLuceneIndex()
+    {
+        if (null === $this->_index) {
+            if (file_exists($index = $this->getLuceneIndexFile())) {
+                $this->_index = Zend_Search_Lucene::open($index);
+            } else {
+                $this->_index = Zend_Search_Lucene::create($index);
+            }
+        }
+        return $this->_index;
+    }
+
+    public function findLuceneDocument()
+    {
+        $query = new Zend_Search_Lucene_Search_Query_MultiTerm();
+        foreach ($this->getLuceneIdentifierFields() as $field) {
+            $name = $field['name'];
+            $query->addTerm(new Zend_Search_Lucene_Index_Term($this->_invoker->$name, $name), true);
+        }
+        return $this->getLuceneIndex()->find($query);
+    }
+
+    public function createLuceneDocument()
+    {
+        $doc = new Zend_Search_Lucene_Document();
+        foreach ($this->getLuceneFields() as $field) {
+            $type = $field['type'];
+            $name = $field['name'];
+
+            $docField = Zend_Search_Lucene_Field::$type($name, $this->_invoker->$name, $this->_encoding);
+            if (isset($field['boost'])) {
+                $docField->boost = $field['boost'];
+            }
+            $doc->addField($docField);
+        }
+        return $doc;
+    }
+
+    /**
+     *
+     * @return array
+     */
+    public function getLuceneIdentifierFields()
+    {
+        if (array() === $this->_identifierFields) {
+            $identifier = $this->_invoker->getTable()->getIdentifier();
+            foreach ((array) $identifier as $id) {
+                $this->_identifierFields[] = array(
+                    'name' => $id,
+                    'type' => 'Keyword',
+                );
+            }
+        }
+        return $this->_identifierFields;
+    }
+
+    public function getLuceneUserFields()
+    {
+        if (array() === $this->_userFields) {
+            $this->_userFields = $this->_options['fields'];
+        }
+        return $this->_userFields;
+    }
+
+    /**
+     *
+     * @return array
+     */
+    public function getLuceneFields()
+    {
+        if (array() === $this->_fields) {
+            $this->_fields = array_merge($this->getLuceneIdentifierFields(), $this->getLuceneUserFields());
+        }
+        return $this->_fields;
+    }
+}