├── .gitignore
├── app
├── code
│ └── community
│ │ └── Asm
│ │ └── Solr
│ │ ├── Resources
│ │ ├── solr
│ │ │ ├── magentocores
│ │ │ │ └── conf
│ │ │ │ │ ├── french
│ │ │ │ │ ├── protwords.txt
│ │ │ │ │ ├── synonyms.txt
│ │ │ │ │ ├── stopwords.txt
│ │ │ │ │ └── schema.xml
│ │ │ │ │ ├── german
│ │ │ │ │ ├── protwords.txt
│ │ │ │ │ ├── synonyms.txt
│ │ │ │ │ └── stopwords.txt
│ │ │ │ │ ├── english
│ │ │ │ │ ├── protwords.txt
│ │ │ │ │ ├── synonyms.txt
│ │ │ │ │ ├── stopwords.txt
│ │ │ │ │ └── schema.xml
│ │ │ │ │ ├── elevate.xml
│ │ │ │ │ └── currency.xml
│ │ │ ├── zoo.cfg
│ │ │ └── solr.xml
│ │ └── tomcat
│ │ │ ├── solr.xml
│ │ │ ├── solr-tomcat
│ │ │ ├── README.txt
│ │ │ └── server.xml
│ │ ├── Block
│ │ ├── Form
│ │ │ └── Mini.php
│ │ ├── Filter.php
│ │ ├── Result
│ │ │ ├── File
│ │ │ │ └── List.php
│ │ │ ├── Page
│ │ │ │ └── List.php
│ │ │ ├── Page.php
│ │ │ └── File.php
│ │ ├── FiltersApplied.php
│ │ ├── Adminhtml
│ │ │ └── System
│ │ │ │ └── Config
│ │ │ │ ├── EmptyIndex.php
│ │ │ │ ├── SyncSynonyms.php
│ │ │ │ └── TestConnection.php
│ │ ├── Filter
│ │ │ ├── File.php
│ │ │ └── Page.php
│ │ ├── Abstract.php
│ │ ├── Facets.php
│ │ └── Result.php
│ │ ├── Model
│ │ ├── Resource
│ │ │ ├── Helper
│ │ │ │ └── Mysql4.php
│ │ │ ├── Setup.php
│ │ │ ├── Page
│ │ │ │ └── Collection.php
│ │ │ ├── Product
│ │ │ │ └── Collection.php
│ │ │ ├── Indexqueue
│ │ │ │ ├── File.php
│ │ │ │ └── File
│ │ │ │ │ └── Collection.php
│ │ │ ├── Indexer
│ │ │ │ ├── Fieldprocessor
│ │ │ │ │ ├── Default.php
│ │ │ │ │ ├── Abstract.php
│ │ │ │ │ ├── Factory.php
│ │ │ │ │ └── Tokenizer.php
│ │ │ │ ├── File.php
│ │ │ │ └── Cms.php
│ │ │ └── Search.php
│ │ ├── Page.php
│ │ ├── Observer
│ │ │ ├── Product.php
│ │ │ ├── Attribute.php
│ │ │ └── Index
│ │ │ │ └── Page.php
│ │ ├── Product.php
│ │ ├── GarbageCollector.php
│ │ ├── Cms
│ │ │ └── Page.php
│ │ ├── SynonymHandler.php
│ │ ├── Indexer
│ │ │ ├── Cms.php
│ │ │ ├── File.php
│ │ │ └── Catalog.php
│ │ ├── Solr
│ │ │ ├── Facet
│ │ │ │ ├── FacetOption.php
│ │ │ │ └── Facet.php
│ │ │ ├── Query
│ │ │ │ └── Modifier
│ │ │ │ │ ├── Faceting.php
│ │ │ │ │ └── Sorting.php
│ │ │ └── Response.php
│ │ └── Indexqueue
│ │ │ └── File.php
│ │ ├── controllers
│ │ ├── IndexController.php
│ │ ├── SuggestController.php
│ │ ├── ResultController.php
│ │ └── Adminhtml
│ │ │ └── Solr
│ │ │ └── System
│ │ │ └── Config
│ │ │ └── UtilityController.php
│ │ ├── Tests
│ │ └── Model
│ │ │ └── Solr
│ │ │ └── Asm_Solr_Model_Solr_QueryTest.php
│ │ ├── etc
│ │ ├── adminhtml.xml
│ │ └── config.xml
│ │ ├── Helper
│ │ ├── Logger.php
│ │ ├── ConnectionManager.php
│ │ ├── Schema.php
│ │ ├── ContentExtractor.php
│ │ └── Data.php
│ │ └── sql
│ │ └── solr_setup
│ │ └── mysql4-install-0.11.0.php
├── etc
│ └── modules
│ │ └── Asm_Solr.xml
└── design
│ ├── frontend
│ └── base
│ │ └── default
│ │ ├── template
│ │ └── solr
│ │ │ ├── filter.phtml
│ │ │ ├── breadcrumbs.phtml
│ │ │ ├── filter_menu.phtml
│ │ │ ├── form.mini.phtml
│ │ │ ├── result.phtml
│ │ │ ├── result
│ │ │ ├── file.phtml
│ │ │ ├── page.phtml
│ │ │ ├── page
│ │ │ │ └── list.phtml
│ │ │ └── file
│ │ │ │ └── list.phtml
│ │ │ ├── filters_applied.phtml
│ │ │ └── facets.phtml
│ │ └── layout
│ │ └── solr.xml
│ └── adminhtml
│ └── default
│ └── default
│ └── template
│ └── solr
│ └── system
│ └── config
│ ├── testconnection.phtml
│ ├── syncsynonyms.phtml
│ └── emptyindex.phtml
├── composer.json
├── modman
├── README.md
└── lib
└── Apache
└── Solr
├── Compatibility
├── CompatibilityLayer.php
├── Solr4CompatibilityLayer.php
└── Solr3CompatibilityLayer.php
├── Exception.php
├── ParserException.php
├── InvalidArgumentException.php
├── NoServiceAvailableException.php
├── HttpTransportException.php
└── HttpTransport
├── Abstract.php
└── Interface.php
/.gitignore:
--------------------------------------------------------------------------------
1 | /app/code/community/Asm/Solr/NOTES.txt
2 | .idea
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Resources/solr/magentocores/conf/french/protwords.txt:
--------------------------------------------------------------------------------
1 | Magento
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Resources/solr/magentocores/conf/german/protwords.txt:
--------------------------------------------------------------------------------
1 | Magento
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Resources/solr/magentocores/conf/english/protwords.txt:
--------------------------------------------------------------------------------
1 | Magento
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Block/Form/Mini.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | true
6 | community
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Resource/Helper/Mysql4.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/controllers/IndexController.php:
--------------------------------------------------------------------------------
1 |
6 |
7 |
/zoo_data
13 |
14 | # the port at which the clients will connect
15 | # clientPort=2181
16 | # NOTE: Solr sets this based on zkRun / zkHost params
17 |
18 |
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Block/Result/File/List.php:
--------------------------------------------------------------------------------
1 | getData('collection')) // if there isn't a page collection set...
14 | {
15 | $collection = Mage::getModel('solr/indexqueue_file')->getCollection(); // todo honestly this should not happen.
16 |
17 | $this->setData('collection', $collection);
18 | }
19 |
20 | return $this->getData('collection');
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Block/Result/Page/List.php:
--------------------------------------------------------------------------------
1 | getData('collection')) // if there isn't a page collection set...
16 | {
17 | $collection = Mage::getModel('solr/page')->getCollection(); // todo honestly this should not happen.
18 |
19 | $this->setData('collection', $collection);
20 | }
21 |
22 | return $this->getData('collection');
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/solr/form.mini.phtml:
--------------------------------------------------------------------------------
1 | helper('solr');
5 | ?>
6 |
19 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/solr/result.phtml:
--------------------------------------------------------------------------------
1 | getResultCount();
6 | $_resultType = $this->getResultType();
7 | ?>
8 | getMessagesBlock()->getGroupedHtml() ?>
9 |
10 |
11 |
getHeaderText() ?>
12 |
13 |
14 | getResultListHtml() ?>
15 |
16 |
17 |
getHeaderText() ?>
18 |
19 |
20 | getNoResultText() ?>
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/solr/result/file.phtml:
--------------------------------------------------------------------------------
1 | getResultCount();
6 | $_resultType = $this->getType();
7 | ?>
8 | getMessagesBlock()->getGroupedHtml() ?>
9 |
10 |
11 |
getHeaderText() ?>
12 |
13 |
14 | getResultListHtml() ?>
15 |
16 |
17 |
getHeaderText() ?>
18 |
19 |
20 | getNoResultText() ?>
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/solr/result/page.phtml:
--------------------------------------------------------------------------------
1 | getResultCount();
6 | $_resultType = $this->getResultType();
7 | ?>
8 | getMessagesBlock()->getGroupedHtml() ?>
9 |
10 |
11 |
getHeaderText() ?>
12 |
13 |
14 | getResultListHtml() ?>
15 |
16 |
17 |
getHeaderText() ?>
18 |
19 |
20 | getNoResultText() ?>
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Resource/Setup.php:
--------------------------------------------------------------------------------
1 | _isCollectionLoaded = true;
17 |
18 | return parent::_init($model, $entityModel);
19 | }
20 |
21 | /**
22 | * @param integer $size Collection size / total number of results found
23 | */
24 | public function setSize($size)
25 | {
26 | $this->_totalRecords = intval($size);
27 | }
28 |
29 | }
30 |
31 | ?>
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Resource/Product/Collection.php:
--------------------------------------------------------------------------------
1 | _isCollectionLoaded = true;
17 |
18 | return parent::_init($model, $entityModel);
19 | }
20 |
21 | /**
22 | * @param integer $size Collection size / total number of results found
23 | */
24 | public function setSize($size)
25 | {
26 | $this->_totalRecords = intval($size);
27 | }
28 |
29 | }
30 |
31 | ?>
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/etc/adminhtml.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Solr Search
13 |
14 |
15 | Indexing
16 |
17 |
18 | Search Queries
19 |
20 |
21 | Search Logging
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/solr/filters_applied.phtml:
--------------------------------------------------------------------------------
1 |
2 | getAppliedFilters() ?>
3 |
4 |
5 |
6 |
__('Currently Filtering by:') ?>
7 |
8 |
9 | -
10 |
11 | __($filter->getFacet()->getName()) ?>:
12 |
13 | stripTags($filter->getLabel()) ?>
14 |
15 |
18 | __('Remove This Item') ?>
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Block/FiltersApplied.php:
--------------------------------------------------------------------------------
1 | getResponse()->getFacetFields();
17 | /** @var Asm_Solr_Model_Solr_Facet_Facet[] $facets */
18 | $urlQuery = Mage::getModel('core/url')->getRequest()->getQuery();
19 |
20 | foreach ($facets as $facet) {
21 | $attributeCode = $facet->getAttributeCode();
22 | if (array_key_exists($attributeCode, $urlQuery)) {
23 | $optionValue = $urlQuery[$attributeCode];
24 | $facetOption = $facet->getOption($optionValue);
25 |
26 | $filters[$attributeCode] = $facetOption;
27 | }
28 | }
29 |
30 | return $filters;
31 | }
32 |
33 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Apache Solr for Magento
2 |
3 | A Magento module to use Apache Solr for search.
4 |
5 | Currently supports indexing and searching of simple and configurable products.
6 | Next up on our roadmap is adding facets (layered navigation), consider this a
7 | working beta version.
8 |
9 | ## Features
10 |
11 | * Index and search products
12 | * Facetted Search (layered navigation)
13 | * Index CMS pages (search coming soon)
14 | * Synonym handling through "Catalog" -> "Search Terms" admin module
15 | * Detailed logging
16 | * Automated Solr install script
17 |
18 | ## Installation
19 |
20 | Use [modman](https://github.com/colinmollenhour/modman) to install the module:
21 | ```
22 | modman clone git@github.com:infielddesign/magento-MagSolr.git
23 | ```
24 |
25 | ##Credits
26 |
27 | Infield Design
28 |
29 | http://www.infielddesign.com
30 |
31 | * Ingo Renner ingo@infielddesign.com
32 | * Kevin Mitchell kevin@infielddesign.com
33 | * Ian Anderson ian@infielddesign.com
34 |
35 | [](https://github.com/infielddesign/magento-MagSolr)
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Resource/Indexqueue/File.php:
--------------------------------------------------------------------------------
1 |
24 | */
25 | class Asm_Solr_Model_Resource_Indexqueue_File extends Mage_Core_Model_Resource_Db_Abstract {
26 |
27 | protected function _construct()
28 | {
29 | $this->_init('solr/indexqueue_file', 'file_id');
30 | }
31 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/GarbageCollector.php:
--------------------------------------------------------------------------------
1 | getProduct()->getEntityId();
13 | $productDocumentId = Mage::helper('solr')->getProductDocumentId($productId);
14 |
15 | $this->deleteIndexDocument($productDocumentId);
16 | }
17 |
18 | /**
19 | * Listens for event indexqueue_file_delete_after
20 | *
21 | * @param Varien_Event_Observer $event
22 | */
23 | public function deleteFile($event)
24 | {
25 | $fileId = $event->getIndexqueueFile()->getEntityId();
26 | $fileDocumentId = Mage::helper('solr')->getFileDocumentId($fileId);
27 |
28 | $this->deleteIndexDocument($fileDocumentId);
29 | }
30 |
31 | protected function deleteIndexDocument($documentId)
32 | {
33 | $connection = Mage::helper('solr/connectionManager')->getConnection();
34 | /** @var $connection Asm_Solr_Model_Solr_Connection */
35 |
36 | $connection->deleteById($documentId);
37 | $connection->commit();
38 | }
39 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Resources/tomcat/solr-tomcat:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # chkconfig: 345 99 1
3 | # description: Tomcat7 service
4 | # processname: java
5 |
6 | # Get LSB functions
7 | . /lib/lsb/init-functions
8 |
9 | export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64/
10 | export TOMCAT_USER=tomcat
11 | export CATALINA_HOME=/opt/solr-tomcat/tomcat
12 | export CATALINA_PID=$CATALINA_HOME/bin/tomcat7.pid
13 |
14 | [ -d "$CATALINA_HOME" ] || { echo "Tomcat requires $CATALINA_HOME."; exit 1; }
15 |
16 | case $1 in
17 |
18 | start|stop|run)
19 | if su $TOMCAT_USER bash -c "$CATALINA_HOME/bin/catalina.sh $1"; then
20 | log_success_msg "Tomcat $1 successful"
21 | [ $1 == "stop" ] && rm -f $CATALINA_PID
22 | else
23 | log_failure_msg "Error in Tomcat $1: $?"
24 | fi
25 | ;;
26 |
27 | restart)
28 | $0 stop
29 | sleep 10
30 | $0 start
31 | ;;
32 |
33 | status)
34 | if [ -f "$CATALINA_PID" ]; then
35 | read kpid < "$CATALINA_PID"
36 | if ps --pid $kpid 2>&1 1>/dev/null; then
37 | echo "$0 is already running at ${kpid}"
38 | else
39 | echo "$CATALINA_PID found, but $kpid is not running"
40 | fi
41 | unset kpid
42 | else
43 | echo "$0 is stopped"
44 | fi
45 | ;;
46 |
47 | esac
48 | exit 0
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/controllers/ResultController.php:
--------------------------------------------------------------------------------
1 | setKeywords($this->getRequest()->getParam('q'));
10 |
11 | $limit = 20;
12 | $offset = 0;
13 | $result->load($limit, $offset);
14 |
15 | $products = $result->getProductCollection();
16 |
17 | foreach ($products as $product)
18 | {
19 | echo $product->getName() . '
';
20 | }
21 | }
22 |
23 |
24 | public function productAction()
25 | {
26 | $this->loadLayout()
27 | ->renderLayout();
28 | }
29 |
30 | public function pageAction()
31 | {
32 | $this
33 | ->loadLayout()
34 | ->renderLayout();
35 |
36 | }
37 |
38 | public function fileAction()
39 | {
40 | $this
41 | ->loadLayout()
42 | ->renderLayout();
43 | }
44 |
45 | public function indexAction()
46 | {
47 |
48 | $this->_redirect('*/*/product', array('_query' => $this->getRequest()->getParams()));
49 | }
50 |
51 |
52 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Resources/tomcat/README.txt:
--------------------------------------------------------------------------------
1 | The Tomcat configuration files
2 | =================================
3 |
4 | server.xml
5 | ---------------------------------
6 | This is the Tomcat server configuration file. It is almost identical to the one distributed when downloading Tomcat.
7 | The only difference is that when using this server.xml file Tomcat will only listen to requests coming from localhost.
8 | Also, the AJP Connector on port 8009 has been turned off since it is not needed for using Solr.
9 |
10 | solr.xml
11 | ---------------------------------
12 | This file is a so-called Tomcat Context fragment defining the $SOLR_HOME environment variable and where to find
13 | the Solr web application archive (solr.war). This file goes into $CATALINA_HOME/conf/Catalina/localhost/
14 | where $CATALINA_HOME is the Tomcat installation directory.
15 |
16 | solr-tomcat
17 | ---------------------------------
18 | This is a simple start/stop script to keep Tomcat running as a service when rebooting the server. Make sure to adjust
19 | the variables at the top of the script as needed, especially JAVA_HOME and TOMCAT_USER might be different for your
20 | system. The script was written for a Ubuntu environment. Place this file into /etc/init.d
21 | Usage: 'service solr-tomcat start|stop|restart|status'
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Resources/solr/solr.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
38 |
39 |
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Resource/Indexqueue/File/Collection.php:
--------------------------------------------------------------------------------
1 |
24 | */
25 | class Asm_Solr_Model_Resource_Indexqueue_File_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
26 | {
27 |
28 | /**
29 | * Init model for collection
30 | *
31 | */
32 | protected function _construct()
33 | {
34 | $this->_init('solr/indexqueue_file');
35 | }
36 |
37 | /**
38 | * @param integer $size Collection size / total number of results found
39 | */
40 | public function setSize($size)
41 | {
42 | $this->_totalRecords = intval($size);
43 | }
44 | }
--------------------------------------------------------------------------------
/lib/Apache/Solr/Compatibility/CompatibilityLayer.php:
--------------------------------------------------------------------------------
1 | processEntityAction(
19 | $this, self::ENTITY, Mage_Index_Model_Event::TYPE_SAVE
20 | );
21 |
22 | return $result;
23 | }
24 |
25 | protected function _beforeDelete()
26 | {
27 | Mage::getSingleton('index/indexer')->logEvent(
28 | $this, self::ENTITY, Mage_Index_Model_Event::TYPE_DELETE
29 | );
30 | return parent::_beforeDelete();
31 | }
32 |
33 | protected function _afterDelete()
34 | {
35 | parent::_afterDelete();
36 | Mage::getSingleton('index/indexer')->indexEvents(
37 | self::ENTITY, Mage_Index_Model_Event::TYPE_DELETE
38 | );
39 | }
40 |
41 | /**
42 | * Init indexing process after cms page delete commit
43 | *
44 | */
45 | protected function _afterDeleteCommit()
46 | {
47 | parent::_afterDeleteCommit();
48 | Mage::getSingleton('index/indexer')->indexEvents(
49 | self::ENTITY, Mage_Index_Model_Event::TYPE_DELETE
50 | );
51 | }
52 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Helper/Logger.php:
--------------------------------------------------------------------------------
1 | log($message, Zend_Log::EMERG, $data);
25 | }
26 |
27 | public function alert($message, $data = null)
28 | {
29 | $this->log($message, Zend_Log::ALERT, $data);
30 | }
31 |
32 | public function critical($message, $data = null)
33 | {
34 | $this->log($message, Zend_Log::CRIT, $data);
35 | }
36 |
37 | public function error($message, $data = null)
38 | {
39 | $this->log($message, Zend_Log::ERR, $data);
40 | }
41 |
42 | public function warning($message, $data = null)
43 | {
44 | $this->log($message, Zend_Log::WARN, $data);
45 | }
46 |
47 | public function notice($message, $data = null)
48 | {
49 | $this->log($message, Zend_Log::NOTICE, $data);
50 | }
51 |
52 | public function info($message, $data = null)
53 | {
54 | $this->log($message, Zend_Log::INFO, $data);
55 | }
56 |
57 | public function debug($message, $data = null)
58 | {
59 | $this->log($message, Zend_Log::DEBUG, $data);
60 | }
61 | }
62 |
63 |
64 | ?>
--------------------------------------------------------------------------------
/app/design/adminhtml/default/default/template/solr/system/config/testconnection.phtml:
--------------------------------------------------------------------------------
1 | store = Mage::app()->getRequest()->getParam('store') ?: 0;
6 |
7 | ?>
8 |
35 |
39 |
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Block/Adminhtml/System/Config/EmptyIndex.php:
--------------------------------------------------------------------------------
1 | getTemplate()) {
13 | $this->setTemplate('solr/system/config/emptyindex.phtml');
14 | }
15 |
16 | return $this;
17 | }
18 |
19 | /**
20 | * Unset some non-related element parameters
21 | *
22 | * @param Varien_Data_Form_Element_Abstract $element
23 | * @return string
24 | */
25 | public function render(Varien_Data_Form_Element_Abstract $element)
26 | {
27 | $element->unsScope()
28 | ->unsCanUseWebsiteValue()
29 | ->unsCanUseDefaultValue();
30 |
31 | return parent::render($element);
32 | }
33 |
34 | /**
35 | * Get the button and scripts contents
36 | *
37 | * @param Varien_Data_Form_Element_Abstract $element
38 | * @return string
39 | */
40 | protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
41 | {
42 | $originalData = $element->getOriginalData();
43 | $this->addData(array(
44 | 'button_label' => Mage::helper('solr')->__($originalData['button_label']),
45 | 'html_id' => $element->getHtmlId(),
46 | 'ajax_url' => Mage::getSingleton('adminhtml/url')->getUrl('*/solr_system_config_utility/emptyindex')
47 | ));
48 |
49 | return $this->_toHtml();
50 | }
51 | }
52 |
53 | ?>
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Block/Adminhtml/System/Config/SyncSynonyms.php:
--------------------------------------------------------------------------------
1 | getTemplate()) {
15 | $this->setTemplate('solr/system/config/syncsynonyms.phtml');
16 | }
17 |
18 | return $this;
19 | }
20 |
21 | /**
22 | * Unset some non-related element parameters
23 | *
24 | * @param Varien_Data_Form_Element_Abstract $element
25 | * @return string
26 | */
27 | public function render(Varien_Data_Form_Element_Abstract $element)
28 | {
29 | $element->unsScope()
30 | ->unsCanUseWebsiteValue()
31 | ->unsCanUseDefaultValue();
32 |
33 | return parent::render($element);
34 | }
35 |
36 | /**
37 | * Get the button and scripts contents
38 | *
39 | * @param Varien_Data_Form_Element_Abstract $element
40 | * @return string
41 | */
42 | protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
43 | {
44 | $originalData = $element->getOriginalData();
45 | $this->addData(array(
46 | 'button_label' => Mage::helper('solr')->__($originalData['button_label']),
47 | 'html_id' => $element->getHtmlId(),
48 | 'ajax_url' => Mage::getSingleton('adminhtml/url')->getUrl('*/solr_system_config_utility/syncsynonyms')
49 | ));
50 |
51 | return $this->_toHtml();
52 | }
53 |
54 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Block/Adminhtml/System/Config/TestConnection.php:
--------------------------------------------------------------------------------
1 | getTemplate()) {
13 | $this->setTemplate('solr/system/config/testconnection.phtml');
14 | }
15 |
16 | return $this;
17 | }
18 |
19 | /**
20 | * Unset some non-related element parameters
21 | *
22 | * @param Varien_Data_Form_Element_Abstract $element
23 | * @return string
24 | */
25 | public function render(Varien_Data_Form_Element_Abstract $element)
26 | {
27 | $element->unsScope()
28 | ->unsCanUseWebsiteValue()
29 | ->unsCanUseDefaultValue();
30 |
31 | return parent::render($element);
32 | }
33 |
34 | /**
35 | * Get the button and scripts contents
36 | *
37 | * @param Varien_Data_Form_Element_Abstract $element
38 | * @return string
39 | */
40 | protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
41 | {
42 | $originalData = $element->getOriginalData();
43 | $this->addData(array(
44 | 'button_label' => Mage::helper('solr')->__($originalData['button_label']),
45 | 'html_id' => $element->getHtmlId(),
46 | 'ajax_url' => Mage::getSingleton('adminhtml/url')->getUrl('*/solr_system_config_utility/testconnection')
47 | ));
48 |
49 | return $this->_toHtml();
50 | }
51 | }
52 |
53 | ?>
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Resources/solr/magentocores/conf/elevate.xml:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Observer/Attribute.php:
--------------------------------------------------------------------------------
1 | getEvent()->getForm();
24 | $attribute = $event->getEvent()->getAttribute();
25 | $fieldset = $form->getElement('front_fieldset');
26 |
27 | $fieldset->addField('search_weight', 'select', array(
28 | 'name' => 'search_weight',
29 | 'label' => Mage::helper('catalog')->__('Search Weight'),
30 | 'values' => $this->getWeightOptions(),
31 | ), 'is_visible_in_advanced_search');
32 | /**
33 | * Disable default search fields
34 | */
35 | $attributeCode = $attribute->getAttributeCode();
36 |
37 | if ($attributeCode == 'name') {
38 | $form->getElement('is_searchable')->setDisabled(1);
39 | }
40 | }
41 |
42 | /**
43 | * Gets an array of value/label pairs for the search weight drop down field
44 | *
45 | * @return array
46 | */
47 | protected function getWeightOptions() {
48 | $options = array();
49 |
50 | foreach ($this->weights as $value) {
51 | $options[] = array(
52 | 'value' => $value,
53 | 'label' => $value
54 | );
55 | }
56 |
57 | return $options;
58 | }
59 |
60 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Resource/Indexer/Fieldprocessor/Default.php:
--------------------------------------------------------------------------------
1 |
22 | */
23 | class Asm_Solr_Model_Resource_Indexer_Fieldprocessor_Default extends Asm_Solr_Model_Resource_Indexer_Fieldprocessor_Abstract {
24 |
25 | /**
26 | * @inheritdoc
27 | */
28 | public function getFieldName() {
29 | $multiValue = false;
30 | if (is_array($this->attributeValue)) {
31 | $multiValue = true;
32 | }
33 |
34 | return Mage::helper('solr/schema')->getFieldNameByAttribute($this->attribute, $multiValue);
35 | }
36 |
37 | /**
38 | * @inheritdoc
39 | */
40 | public function getFieldValue() {
41 | $attributeValue = $this->attributeValue;
42 |
43 | if ($this->attribute->getBackendType() == 'datetime') {
44 | $attributeValue = Mage::helper('solr')->dateToIso($this->attributeValue);
45 | }
46 |
47 | return $attributeValue;
48 | }
49 |
50 | }
--------------------------------------------------------------------------------
/app/design/adminhtml/default/default/template/solr/system/config/syncsynonyms.phtml:
--------------------------------------------------------------------------------
1 | section = Mage::app()->getRequest()->getParam('section') ?: 0;
6 | $ajaxRequestParameters->website = Mage::app()->getRequest()->getParam('website') ?: 0;
7 | $ajaxRequestParameters->store = Mage::app()->getRequest()->getParam('store') ?: 0;
8 |
9 | ?>
10 |
37 |
42 |
--------------------------------------------------------------------------------
/app/design/adminhtml/default/default/template/solr/system/config/emptyindex.phtml:
--------------------------------------------------------------------------------
1 | section = Mage::app()->getRequest()->getParam('section') ?: 0;
6 | $ajaxRequestParameters->website = Mage::app()->getRequest()->getParam('website') ?: 0;
7 | $ajaxRequestParameters->store = Mage::app()->getRequest()->getParam('store') ?: 0;
8 |
9 | ?>
10 |
37 |
42 |
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Block/Filter/File.php:
--------------------------------------------------------------------------------
1 | getUrl('*/*/'.$this->getType(), array('_query' => $this->getRequest()->getParams()));
16 | }
17 |
18 | public function getType()
19 | {
20 | return $this->_type;
21 | }
22 |
23 | public function getSolrType()
24 | {
25 | return $this->_solrType;
26 | }
27 |
28 | public function getTitle(){
29 |
30 | $title = 'PDFs & Downloads';
31 |
32 | return $title;
33 | }
34 |
35 | public function getResultCount()
36 | {
37 | return $this->getResult()->getCount();
38 | }
39 |
40 | /**
41 | * @return Asm_Solr_Model_Result
42 | */
43 | public function getResult()
44 | {
45 | // if we don't have a result set for us, let's make one
46 | if (!$this->getData('result')) // todo should we be running like 30 searches?
47 | {
48 | /** @var Asm_Solr_Model_Result $result */
49 | $result = Mage::getModel('solr/result');
50 |
51 | $query = $result->getQuery();
52 | $query->setKeywords($this->getKeywords());
53 | $query->addFilter('type', $this->getSolrType());
54 |
55 | $result->load($this->getLimit(), $this->getOffset()); // todo is this even useful?
56 |
57 | $this->setData('result', $result);
58 | }
59 |
60 | return $this->getData('result');
61 | }
62 |
63 |
64 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Block/Filter/Page.php:
--------------------------------------------------------------------------------
1 | getUrl('*/*/'.$this->getType(), array('_query' => $this->getRequest()->getParams()));
16 | }
17 |
18 | public function getType()
19 | {
20 | return $this->_type;
21 | }
22 |
23 | public function getSolrType()
24 | {
25 | return $this->_solrType;
26 | }
27 |
28 | public function getTitle(){
29 |
30 | $title = 'Website Pages';
31 |
32 | return $title;
33 | }
34 |
35 | public function getResultCount()
36 | {
37 | return $this->getResult()->getCount();
38 | }
39 |
40 | /**
41 | * @return Asm_Solr_Model_Result
42 | */
43 | public function getResult()
44 | {
45 | // if we don't have a result set for us, let's make one
46 | if (!$this->getData('result')) // todo should we be running like 30 searches?
47 | {
48 | /** @var Asm_Solr_Model_Result $result */
49 | $result = Mage::getModel('solr/result');
50 |
51 | $query = $result->getQuery();
52 | $query->setKeywords($this->getKeywords());
53 | $query->addFilter('type', $this->getSolrType());
54 |
55 | $result->load($this->getLimit(), $this->getOffset()); // todo is this even useful?
56 |
57 | $this->setData('result', $result);
58 | }
59 |
60 | return $this->getData('result');
61 | }
62 |
63 |
64 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Resources/solr/magentocores/conf/french/stopwords.txt:
--------------------------------------------------------------------------------
1 | au
2 | aux
3 | avec
4 | ce
5 | ces
6 | dans
7 | de
8 | des
9 | du
10 | elle
11 | en
12 | et
13 | eux
14 | il
15 | je
16 | la
17 | le
18 | leur
19 | lui
20 | ma
21 | mais
22 | me
23 | même
24 | mes
25 | moi
26 | mon
27 | ne
28 | nos
29 | notre
30 | nous
31 | on
32 | ou
33 | par
34 | pas
35 | pour
36 | qu
37 | que
38 | qui
39 | sa
40 | se
41 | ses
42 | son
43 | sur
44 | ta
45 | te
46 | tes
47 | toi
48 | ton
49 | tu
50 | un
51 | une
52 | vos
53 | votre
54 | vous
55 | c
56 | d
57 | j
58 | l
59 | à
60 | m
61 | n
62 | s
63 | t
64 | y
65 | été
66 | étée
67 | étées
68 | étés
69 | étant
70 | suis
71 | es
72 | est
73 | sommes
74 | êtes
75 | sont
76 | serai
77 | seras
78 | sera
79 | serons
80 | serez
81 | seront
82 | serais
83 | serait
84 | serions
85 | seriez
86 | seraient
87 | étais
88 | était
89 | étions
90 | étiez
91 | étaient
92 | fus
93 | fut
94 | fûmes
95 | fûtes
96 | furent
97 | sois
98 | soit
99 | soyons
100 | soyez
101 | soient
102 | fusse
103 | fusses
104 | fût
105 | fussions
106 | fussiez
107 | fussent
108 | ayant
109 | eu
110 | eue
111 | eues
112 | eus
113 | ai
114 | as
115 | avons
116 | avez
117 | ont
118 | aurai
119 | auras
120 | aura
121 | aurons
122 | aurez
123 | auront
124 | aurais
125 | aurait
126 | aurions
127 | auriez
128 | auraient
129 | avais
130 | avait
131 | avions
132 | aviez
133 | avaient
134 | eut
135 | eûmes
136 | eûtes
137 | eurent
138 | aie
139 | aies
140 | ait
141 | ayons
142 | ayez
143 | aient
144 | eusse
145 | eusses
146 | eût
147 | eussions
148 | eussiez
149 | eussent
150 | ceci
151 | celà
152 | cet
153 | cette
154 | ici
155 | ils
156 | les
157 | leurs
158 | quel
159 | quels
160 | quelle
161 | quelles
162 | sans
163 | soi
164 |
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/SynonymHandler.php:
--------------------------------------------------------------------------------
1 | getConnection();
32 |
33 | $query = $event->getDataObject();
34 | /* @var $query Mage_CatalogSearch_Model_Query */
35 |
36 | $baseWord = $query->getData('query_text');
37 | $oldSynonyms = $query->getOrigData('synonym_for');
38 | $newSynonyms = $query->getData('synonym_for');
39 |
40 | $solrSynonyms = $connection->getSynonyms($baseWord);
41 | if (!empty($solrSynonyms) && $newSynonyms != $oldSynonyms) {
42 | // since there's no update/edit, simply remove previous mapping
43 | // otherwise synonyms only get added, but never removed to/from a base word
44 | $connection->deleteSynonym($baseWord);
45 | }
46 |
47 | $newSynonyms = Mage::helper('solr')->trimExplode(',', $newSynonyms);
48 | $connection->addSynonym($baseWord, $newSynonyms);
49 | }
50 |
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Indexer/Cms.php:
--------------------------------------------------------------------------------
1 | array(
8 | Mage_Index_Model_Event::TYPE_SAVE,
9 | Mage_Index_Model_Event::TYPE_MASS_ACTION,
10 | Mage_Index_Model_Event::TYPE_REINDEX,
11 | Mage_Index_Model_Event::TYPE_DELETE
12 | ),
13 | );
14 |
15 |
16 | protected function _construct()
17 | {
18 | $this->_init('solr/indexer_cms');
19 | }
20 |
21 | /**
22 | * Get Indexer name
23 | *
24 | * @return string
25 | */
26 | public function getName()
27 | {
28 | return Mage::helper('solr')->__('Solr CMS Search Index');
29 | }
30 |
31 | /**
32 | * Get Indexer description
33 | *
34 | * @return string
35 | */
36 | public function getDescription()
37 | {
38 | return Mage::helper('solr')->__('Rebuild Solr CMS search index');
39 | }
40 |
41 | /**
42 | * Register indexer required data inside event object
43 | *
44 | * @param Mage_Index_Model_Event $event
45 | */
46 | protected function _registerEvent(Mage_Index_Model_Event $event)
47 | {
48 | if ($event->getEntity() == Asm_Solr_Model_Cms_Page::ENTITY
49 | && $event->getType() == Mage_Index_Model_Event::TYPE_SAVE
50 | ) {
51 | $event->setData('solr_update_page_id', $event->getDataObject()->getId());
52 | }
53 | }
54 |
55 | /**
56 | * Process event based on event state data
57 | *
58 | * @param Mage_Index_Model_Event $event
59 | */
60 | protected function _processEvent(Mage_Index_Model_Event $event)
61 | {
62 | if ($event->getData('solr_update_page_id')) {
63 | $this->callEventHandler($event);
64 | }
65 | }
66 |
67 | public function reindexAll()
68 | {
69 | $resource = $this->_getResource();
70 | $resource->rebuildIndex();
71 | }
72 | }
--------------------------------------------------------------------------------
/lib/Apache/Solr/Compatibility/Solr4CompatibilityLayer.php:
--------------------------------------------------------------------------------
1 | ';
22 |
23 | return $rawPost;
24 | }
25 |
26 | /**
27 | * Creates an optimize command XML string.
28 | *
29 | * @param boolean $waitFlush Is ignored.
30 | * @param boolean $waitSearcher
31 | * @param float $timeout Maximum expected duration of the commit operation on the server (otherwise, will throw a communication exception)
32 | * @return string An XML string
33 | */
34 | public function createOptimizeXml($waitFlush = true, $waitSearcher = true)
35 | {
36 | $searcherValue = $waitSearcher ? 'true' : 'false';
37 |
38 | $rawPost = '';
39 |
40 | return $rawPost;
41 | }
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/sql/solr_setup/mysql4-install-0.11.0.php:
--------------------------------------------------------------------------------
1 | startSetup();
8 |
9 |
10 | // create file index queue
11 | $table = $installer->getConnection()
12 | ->newTable($installer->getTable('solr/indexqueue_file'))
13 | ->addColumn('file_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
14 | 'identity' => true,
15 | 'unsigned' => true,
16 | 'nullable' => false,
17 | 'primary' => true,
18 | ), 'File ID')
19 | ->addColumn('cms_page_id', Varien_Db_Ddl_Table::TYPE_INTEGER, 11, array(
20 | 'unsigned' => true,
21 | 'nullable' => false,
22 | 'default' => '0',
23 | ), 'CMS page ID')
24 | ->addColumn('store_id', Varien_Db_Ddl_Table::TYPE_INTEGER, 11, array(
25 | 'unsigned' => true,
26 | 'nullable' => false,
27 | 'default' => '0',
28 | ), 'Store ID')
29 | ->addColumn('file_path', Varien_Db_Ddl_Table::TYPE_TEXT, null, array(
30 | 'nullable' => false,
31 | ), 'File path')
32 | ->addColumn('changed', Varien_Db_Ddl_Table::TYPE_INTEGER, 11, array(
33 | 'unsigned' => true,
34 | 'nullable' => false,
35 | 'default' => '0',
36 | ), 'File changed or added to tracking at')
37 | ->addColumn('indexed', Varien_Db_Ddl_Table::TYPE_INTEGER, 11, array(
38 | 'unsigned' => true,
39 | 'nullable' => false,
40 | 'default' => '0',
41 | ), 'File indexed at')
42 | ->setComment('Keeps track of which files have been indexed for which page');
43 | $installer->getConnection()->createTable($table);
44 |
45 |
46 | // add search weight field to eav attributes
47 | $installer->getConnection()->addColumn(
48 | $installer->getTable('catalog/eav_attribute'),
49 | 'search_weight',
50 | array(
51 | 'type' => Varien_Db_Ddl_Table::TYPE_SMALLINT,
52 | 'unsigned' => true,
53 | 'nullable' => false,
54 | 'default' => '1',
55 | 'comment' => 'Search Weight',
56 | )
57 | );
58 |
59 |
60 | $installer->endSetup();
61 |
62 |
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Resources/solr/magentocores/conf/english/stopwords.txt:
--------------------------------------------------------------------------------
1 | i
2 | me
3 | my
4 | myself
5 | we
6 | us
7 | our
8 | ours
9 | ourselves
10 | you
11 | your
12 | yours
13 | yourself
14 | yourselves
15 | he
16 | him
17 | his
18 | himself
19 | she
20 | her
21 | hers
22 | herself
23 | it
24 | its
25 | itself
26 | they
27 | them
28 | their
29 | theirs
30 | themselves
31 | what
32 | which
33 | who
34 | whom
35 | this
36 | that
37 | these
38 | those
39 | am
40 | is
41 | are
42 | was
43 | were
44 | be
45 | been
46 | being
47 | have
48 | has
49 | had
50 | having
51 | do
52 | does
53 | did
54 | doing
55 | would
56 | should
57 | could
58 | ought
59 | i'm
60 | you're
61 | he's
62 | she's
63 | it's
64 | we're
65 | they're
66 | i've
67 | you've
68 | we've
69 | they've
70 | i'd
71 | you'd
72 | he'd
73 | she'd
74 | we'd
75 | they'd
76 | i'll
77 | you'll
78 | he'll
79 | she'll
80 | we'll
81 | they'll
82 | isn't
83 | aren't
84 | wasn't
85 | weren't
86 | hasn't
87 | haven't
88 | hadn't
89 | doesn't
90 | don't
91 | didn't
92 | won't
93 | wouldn't
94 | shan't
95 | shouldn't
96 | can't
97 | cannot
98 | couldn't
99 | mustn't
100 | let's
101 | that's
102 | who's
103 | what's
104 | here's
105 | there's
106 | when's
107 | where's
108 | why's
109 | how's
110 | an
111 | the
112 | and
113 | but
114 | if
115 | or
116 | because
117 | as
118 | until
119 | while
120 | of
121 | at
122 | by
123 | for
124 | with
125 | about
126 | against
127 | between
128 | into
129 | through
130 | during
131 | before
132 | after
133 | above
134 | below
135 | to
136 | from
137 | up
138 | down
139 | in
140 | out
141 | on
142 | off
143 | over
144 | under
145 | again
146 | further
147 | then
148 | once
149 | here
150 | there
151 | when
152 | where
153 | why
154 | how
155 | all
156 | any
157 | both
158 | each
159 | few
160 | more
161 | most
162 | other
163 | some
164 | such
165 | no
166 | nor
167 | not
168 | only
169 | own
170 | same
171 | so
172 | than
173 | too
174 | very
175 |
--------------------------------------------------------------------------------
/lib/Apache/Solr/Compatibility/Solr3CompatibilityLayer.php:
--------------------------------------------------------------------------------
1 | ';
22 |
23 | return $rawPost;
24 | }
25 |
26 | /**
27 | * Creates an optimize command XML string.
28 | *
29 | * @param boolean $waitFlush
30 | * @param boolean $waitSearcher
31 | * @param float $timeout Maximum expected duration of the commit operation on the server (otherwise, will throw a communication exception)
32 | * @return string An XML string
33 | */
34 | public function createOptimizeXml($waitFlush = true, $waitSearcher = true)
35 | {
36 | $flushValue = $waitFlush ? 'true' : 'false';
37 | $searcherValue = $waitSearcher ? 'true' : 'false';
38 |
39 | $rawPost = '';
40 |
41 | return $rawPost;
42 | }
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Resource/Indexer/Fieldprocessor/Abstract.php:
--------------------------------------------------------------------------------
1 | attribute = Mage::getSingleton('eav/config')->getAttribute(
48 | Mage_Catalog_Model_Product::ENTITY,
49 | $parameters['attributeCode']
50 | );
51 |
52 | $this->attributeValue = $parameters['attributeValue'];
53 |
54 | $this->fieldType = (string) Mage::getConfig()->getNode('global/index/fieldMap/' . $parameters['attributeCode'] . '/type');
55 | }
56 |
57 | /**
58 | * Generates the Solr field name for a given Magento product field
59 | *
60 | * @return string Solr field name
61 | */
62 | abstract public function getFieldName();
63 |
64 | /**
65 | * Process the Solr field value from the Magento field's value
66 | *
67 | * @return string|array
68 | */
69 | abstract public function getFieldValue();
70 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Resource/Indexer/Fieldprocessor/Factory.php:
--------------------------------------------------------------------------------
1 |
25 | */
26 | class Asm_Solr_Model_Resource_Indexer_Fieldprocessor_Factory {
27 |
28 | /**
29 | * Factory method for field processors
30 | *
31 | * @param string $attributeCode
32 | * @param mixed $value Attribute value
33 | * @return Asm_Solr_Model_Resource_Indexer_Fieldprocessor_Abstract
34 | */
35 | public function getFieldProcessor($attributeCode, $value = '')
36 | {
37 | $fieldProcessor = null;
38 |
39 | $fieldProcessorParameters = array(
40 | 'attributeCode' => $attributeCode,
41 | 'attributeValue' => $value
42 | );
43 |
44 | $fieldMap = Mage::getConfig()->getNode('global/index/fieldMap')->asArray();
45 | if (array_key_exists($attributeCode, $fieldMap)) {
46 | $processors = array_keys($fieldMap[$attributeCode]['processor']);
47 | $processorName = $processors[0];
48 |
49 | $fieldProcessor = Mage::getResourceModel(
50 | 'solr/indexer_fieldprocessor_' . $processorName,
51 | $fieldProcessorParameters
52 | );
53 | } else {
54 | $fieldProcessor = Mage::getResourceModel(
55 | 'solr/indexer_fieldprocessor_default',
56 | $fieldProcessorParameters
57 | );
58 | }
59 |
60 | return $fieldProcessor;
61 | }
62 |
63 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Block/Abstract.php:
--------------------------------------------------------------------------------
1 | setData('store_id', $storeId);
20 | }
21 |
22 | /**
23 | * Retrieve store Id
24 | *
25 | * @return int
26 | */
27 | public function getStoreId()
28 | {
29 | if (!$storeId = $this->getData('store_id')) {
30 | $storeId = Mage::app()->getStore()->getId();
31 | }
32 | return $storeId;
33 | }
34 |
35 | public function getOffset()
36 | {
37 | if (!$this->getData('offset'))
38 | {
39 | $limit = $this->getRequest()->getParam('offset', 0);
40 |
41 | $this->setData('offset', $limit);
42 | }
43 |
44 | return $this->getData('offset');
45 | }
46 |
47 | public function getLimit()
48 | {
49 | if (!$this->getData('limit'))
50 | {
51 | $limit = $this->getRequest()->getParam('limit', 25);
52 |
53 | $this->setData('limit', $limit);
54 | }
55 |
56 | return $this->getData('limit');
57 | }
58 |
59 | public function getKeywords()
60 | {
61 | if (!$this->getData('keywords'))
62 | {
63 | $keywords = $this->getRequest()->getParam('q', '');
64 |
65 | $this->setData('keywords', $keywords);
66 | }
67 |
68 | return $this->getData('keywords');
69 | }
70 |
71 | public function getFilteredQuery()
72 | {
73 | if (!$this->getData('filtered_query'))
74 | {
75 | $filteredQuery = $this->getRequest()->getParam('fq', '');
76 |
77 | $this->setData('filtered_query', $filteredQuery);
78 | }
79 |
80 | return $this->getData('filtered_query');
81 | }
82 |
83 | public function getKeywordsCleaned()
84 | {
85 | return Asm_Solr_Model_Solr_Query::cleanKeywords($this->getKeywords());
86 | }
87 |
88 | }
--------------------------------------------------------------------------------
/lib/Apache/Solr/Exception.php:
--------------------------------------------------------------------------------
1 |
37 | */
38 |
39 | class Apache_Solr_Exception extends Exception
40 | {
41 | /**
42 | * SVN Revision meta data for this class
43 | */
44 | const SVN_REVISION = '$Revision$';
45 |
46 | /**
47 | * SVN ID meta data for this class
48 | */
49 | const SVN_ID = '$Id$';
50 | }
--------------------------------------------------------------------------------
/lib/Apache/Solr/ParserException.php:
--------------------------------------------------------------------------------
1 |
37 | */
38 |
39 | class Apache_Solr_ParserException extends Apache_Solr_Exception
40 | {
41 | /**
42 | * SVN Revision meta data for this class
43 | */
44 | const SVN_REVISION = '$Revision$';
45 |
46 | /**
47 | * SVN ID meta data for this class
48 | */
49 | const SVN_ID = '$Id$';
50 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Resource/Indexer/Fieldprocessor/Tokenizer.php:
--------------------------------------------------------------------------------
1 |
28 | *
29 | * string
30 | *
31 | *
32 | * ,
33 | *
34 | *
35 | *
36 | *
37 | *
38 | * @author Ingo Renner
39 | */
40 | class Asm_Solr_Model_Resource_Indexer_Fieldprocessor_Tokenizer extends Asm_Solr_Model_Resource_Indexer_Fieldprocessor_Abstract {
41 |
42 | /**
43 | * @var string
44 | */
45 | protected $delimiter = ',';
46 |
47 |
48 | /**
49 | * @inheritdoc
50 | */
51 | public function __construct($parameters) {
52 | $delimiter = (string) Mage::getConfig()->getNode('global/index/fieldMap/' . $parameters['attributeCode'] . '/processor/tokenizer/delimiter');
53 | if (!empty($delimiter)) {
54 | $this->delimiter = $delimiter;
55 | }
56 |
57 | parent::__construct($parameters);
58 | }
59 |
60 | /**
61 | * @inheritdoc
62 | */
63 | public function getFieldName() {
64 | return $this->attribute->getAttributeCode() . '_' . $this->fieldType . 'M';
65 | }
66 |
67 | /**
68 | * @inheritdoc
69 | */
70 | public function getFieldValue() {
71 | return explode($this->delimiter, $this->attributeValue);
72 | }
73 |
74 | }
--------------------------------------------------------------------------------
/lib/Apache/Solr/InvalidArgumentException.php:
--------------------------------------------------------------------------------
1 |
37 | */
38 |
39 | class Apache_Solr_InvalidArgumentException extends Apache_Solr_Exception
40 | {
41 | /**
42 | * SVN Revision meta data for this class
43 | */
44 | const SVN_REVISION = '$Revision$';
45 |
46 | /**
47 | * SVN ID meta data for this class
48 | */
49 | const SVN_ID = '$Id$';
50 | }
--------------------------------------------------------------------------------
/lib/Apache/Solr/NoServiceAvailableException.php:
--------------------------------------------------------------------------------
1 |
37 | */
38 |
39 | class Apache_Solr_NoServiceAvailableException extends Apache_Solr_Exception
40 | {
41 | /**
42 | * SVN Revision meta data for this class
43 | */
44 | const SVN_REVISION = '$Revision$';
45 |
46 | /**
47 | * SVN ID meta data for this class
48 | */
49 | const SVN_ID = '$Id$';
50 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Solr/Facet/FacetOption.php:
--------------------------------------------------------------------------------
1 |
9 | *
10 | * @method Asm_Solr_Model_Solr_Facet_Facet getFacet()
11 | * @method Asm_Solr_Model_Solr_Facet_FacetOption setFacet(Asm_Solr_Model_Solr_Facet_Facet $facet)
12 | * @method string getValue()
13 | * @method Asm_Solr_Model_Solr_Facet_FacetOption setLabel(string $label)
14 | * @method Asm_Solr_Model_Solr_Facet_FacetOption setValue(string $value)
15 | * @method Asm_Solr_Model_Solr_Facet_FacetOption setNumberOfResults(string $numberOfResults)
16 | */
17 | class Asm_Solr_Model_Solr_Facet_FacetOption extends Varien_Object
18 | {
19 |
20 | /**
21 | * URL parameters to remove when adding/removing facet options
22 | *
23 | * @var array
24 | */
25 | protected $unwantedUrlParameters;
26 |
27 |
28 | /**
29 | * Constructor, initializes URL parameters to remove when changing
30 | * facet combinations.
31 | *
32 | */
33 | public function __construct()
34 | {
35 | // Go back to page 1 when adding/removing a facet option
36 | $this->unwantedUrlParameters = array(
37 | Mage::getBlockSingleton('page/html_pager')->getPageVarName() => null // reset page browser
38 | );
39 |
40 | parent::__construct();
41 | }
42 |
43 | /**
44 | * Gets the URL to add the facet option as a filter to the current query
45 | *
46 | * @return string URL with parameters to add a new filter to the query
47 | */
48 | public function getAddUrl()
49 | {
50 | $query = array_merge(
51 | array($this->getFacet()->getName() => $this->getValue()),
52 | $this->unwantedUrlParameters
53 | );
54 |
55 | return Mage::getUrl('*/*', array(
56 | '_current' => true,
57 | '_use_rewrite' => true,
58 | '_query' => $query
59 | ));
60 | }
61 |
62 | /**
63 | * Gets the current URL with the facet option's filter removed
64 | *
65 | * @return string URL with the facet option's filter parameter removed
66 | */
67 | public function getRemoveUrl()
68 | {
69 | $query = array_merge(
70 | array($this->getFacet()->getName() => null),
71 | $this->unwantedUrlParameters
72 | );
73 |
74 | return Mage::getUrl('*/*', array(
75 | '_current' => true,
76 | '_use_rewrite' => true,
77 | '_query' => $query
78 | ));
79 | }
80 |
81 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Resource/Search.php:
--------------------------------------------------------------------------------
1 |
10 | */
11 |
12 | class Asm_Solr_Model_Resource_Search
13 | {
14 |
15 | /**
16 | * An instance of the Solr service
17 | *
18 | * @var Asm_Solr_Model_Solr_Connection
19 | */
20 | protected $connection = NULL;
21 |
22 | /**
23 | * The search query
24 | *
25 | * @var Asm_Solr_Model_Solr_Query
26 | */
27 | protected $query = NULL;
28 |
29 | /**
30 | * The search response
31 | *
32 | * @var Apache_Solr_Response
33 | */
34 | protected $rawResponse = NULL;
35 |
36 | /**
37 | * Flag for marking a search
38 | *
39 | * @var boolean
40 | */
41 | protected $hasSearched = FALSE;
42 |
43 |
44 | public function __construct(array $searchParameters = array())
45 | {
46 | if (isset($searchParameters['connection'])) {
47 | $this->connection = $searchParameters['connection'];
48 | } else {
49 | $this->connection = Mage::helper('solr/connectionManager')->getConnection();
50 | }
51 | }
52 |
53 | /**
54 | * Executes a query against a Solr server.
55 | *
56 | * 1) Gets the query string
57 | * 2) Conducts the actual search
58 | * 3) Checks debug settings
59 | *
60 | * @param Asm_Solr_Model_Solr_Query $query The query with keywords, filters, and so on.
61 | * @param integer $offset Result offset for pagination.
62 | * @param integer $limit Maximum number of results to return. If set to NULL, this value is taken from the query object.
63 | * @return Asm_Solr_Model_Solr_Response Solr response
64 | */
65 | public function search(Asm_Solr_Model_Solr_Query $query, $offset = 0, $limit = 10)
66 | {
67 | Mage::dispatchEvent('asm_search_query_before', array('query' => $query));
68 | $this->query = $query;
69 |
70 | if (empty($limit)) {
71 | $limit = $query->getResultsPerPage();
72 | }
73 |
74 | try {
75 | $response = $this->connection->search(
76 | $query->getKeywords(),
77 | $offset,
78 | $limit,
79 | $query->getQueryParameters()
80 | );
81 | } catch (RuntimeException $e) {
82 | $response = $this->connection->getResponse();
83 | }
84 |
85 | $this->rawResponse = $response;
86 | $this->hasSearched = TRUE;
87 |
88 | return Mage::getModel('solr/solr_response', array('rawResponse' => $response));
89 | }
90 |
91 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Indexer/File.php:
--------------------------------------------------------------------------------
1 | array(
29 | Mage_Index_Model_Event::TYPE_SAVE,
30 | Mage_Index_Model_Event::TYPE_MASS_ACTION,
31 | Mage_Index_Model_Event::TYPE_REINDEX,
32 | Mage_Index_Model_Event::TYPE_DELETE
33 | ),
34 | );
35 |
36 | protected function _construct()
37 | {
38 | $this->_init('solr/indexer_file');
39 | }
40 |
41 | /**
42 | * Get Indexer name
43 | *
44 | * @return string
45 | */
46 | public function getName() {
47 | return Mage::helper('solr')->__('Solr File Search Index');
48 | }
49 |
50 | /**
51 | * Get Indexer description
52 | *
53 | * @return string
54 | */
55 | public function getDescription()
56 | {
57 | return Mage::helper('solr')->__('Rebuild Solr CMS File search index');
58 | }
59 |
60 | /**
61 | * Register indexer required data inside event object
62 | *
63 | * @param Mage_Index_Model_Event $event
64 | */
65 | protected function _registerEvent(Mage_Index_Model_Event $event) {
66 | if ($event->getEntity() == Asm_Solr_Model_Indexqueue_File::ENTITY
67 | && $event->getType() == Mage_Index_Model_Event::TYPE_SAVE
68 | ) {
69 | $event->setData('solr_update_file_id', $event->getDataObject()->getId());
70 | }
71 | }
72 |
73 | /**
74 | * Process event based on event state data
75 | *
76 | * @param Mage_Index_Model_Event $event
77 | */
78 | protected function _processEvent(Mage_Index_Model_Event $event) {
79 | if ($event->getData('solr_update_file_id')) {
80 | $this->callEventHandler($event);
81 | }
82 | }
83 |
84 | public function reindexAll()
85 | {
86 | $resource = $this->_getResource();
87 | $resource->rebuildIndex();
88 | }
89 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Resources/solr/magentocores/conf/german/stopwords.txt:
--------------------------------------------------------------------------------
1 | aber
2 | alle
3 | allem
4 | allen
5 | aller
6 | alles
7 | als
8 | also
9 | am
10 | an
11 | ander
12 | andere
13 | anderem
14 | anderen
15 | anderer
16 | anderes
17 | anderm
18 | andern
19 | anderr
20 | anders
21 | auch
22 | auf
23 | aus
24 | bei
25 | bin
26 | bis
27 | bist
28 | da
29 | damit
30 | dann
31 | der
32 | den
33 | des
34 | dem
35 | die
36 | das
37 | daß
38 | derselbe
39 | derselben
40 | denselben
41 | desselben
42 | demselben
43 | dieselbe
44 | dieselben
45 | dasselbe
46 | dazu
47 | dein
48 | deine
49 | deinem
50 | deinen
51 | deiner
52 | deines
53 | denn
54 | derer
55 | dessen
56 | dich
57 | dir
58 | du
59 | dies
60 | diese
61 | diesem
62 | diesen
63 | dieser
64 | dieses
65 | doch
66 | dort
67 | durch
68 | ein
69 | eine
70 | einem
71 | einen
72 | einer
73 | eines
74 | einig
75 | einige
76 | einigem
77 | einigen
78 | einiger
79 | einiges
80 | einmal
81 | er
82 | ihn
83 | ihm
84 | es
85 | etwas
86 | euer
87 | eure
88 | eurem
89 | euren
90 | eurer
91 | eures
92 | für
93 | gegen
94 | gewesen
95 | hab
96 | habe
97 | haben
98 | hat
99 | hatte
100 | hatten
101 | hier
102 | hin
103 | hinter
104 | ich
105 | mich
106 | mir
107 | ihr
108 | ihre
109 | ihrem
110 | ihren
111 | ihrer
112 | ihres
113 | euch
114 | im
115 | in
116 | indem
117 | ins
118 | ist
119 | jede
120 | jedem
121 | jeden
122 | jeder
123 | jedes
124 | jene
125 | jenem
126 | jenen
127 | jener
128 | jenes
129 | jetzt
130 | kann
131 | kein
132 | keine
133 | keinem
134 | keinen
135 | keiner
136 | keines
137 | können
138 | könnte
139 | machen
140 | man
141 | manche
142 | manchem
143 | manchen
144 | mancher
145 | manches
146 | mein
147 | meine
148 | meinem
149 | meinen
150 | meiner
151 | meines
152 | mit
153 | muss
154 | musste
155 | nach
156 | nicht
157 | nichts
158 | noch
159 | nun
160 | nur
161 | ob
162 | oder
163 | ohne
164 | sehr
165 | sein
166 | seine
167 | seinem
168 | seinen
169 | seiner
170 | seines
171 | selbst
172 | sich
173 | sie
174 | ihnen
175 | sind
176 | so
177 | solche
178 | solchem
179 | solchen
180 | solcher
181 | solches
182 | soll
183 | sollte
184 | sondern
185 | sonst
186 | über
187 | um
188 | und
189 | uns
190 | unse
191 | unsem
192 | unsen
193 | unser
194 | unses
195 | unter
196 | viel
197 | vom
198 | von
199 | vor
200 | während
201 | war
202 | waren
203 | warst
204 | was
205 | weg
206 | weil
207 | weiter
208 | welche
209 | welchem
210 | welchen
211 | welcher
212 | welches
213 | wenn
214 | werde
215 | werden
216 | wie
217 | wieder
218 | will
219 | wir
220 | wird
221 | wirst
222 | wo
223 | wollen
224 | wollte
225 | würde
226 | würden
227 | zu
228 | zum
229 | zur
230 | zwar
231 | zwischen
232 |
233 |
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Solr/Query/Modifier/Faceting.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | class Asm_Solr_Model_Solr_Query_Modifier_Faceting
11 | {
12 |
13 | /**
14 | * @var Mage_Catalog_Model_Resource_Eav_Attribute[]
15 | */
16 | protected $filterableAttributes;
17 |
18 | /**
19 | * Called before a query is executed. Modifies the query to add faceting
20 | * parameters.
21 | *
22 | * @param Varien_Event_Observer $observer Observer/event data
23 | */
24 | public function modifyQuery(Varien_Event_Observer $observer)
25 | {
26 | /** @var Asm_Solr_Model_Solr_Query $query */
27 | $query = $observer->getQuery();
28 | $query->setFaceting();
29 |
30 | $this->filterableAttributes = $this->getFilterableAttributes();
31 |
32 | // set facet.* query parameters / which facets to generate
33 | foreach ($this->filterableAttributes as $attribute) {
34 | $query->addFacetField(Mage::helper('solr/schema')->getFieldNameByAttribute($attribute));
35 | }
36 |
37 | // set filter query (fq) parameters / actually filtering results
38 | $filters = $this->getQueryFilters();
39 | foreach ($filters as $fieldName => $value) {
40 | $query->addFilter($fieldName, $value);
41 | }
42 | }
43 |
44 | /**
45 | * Get collection of all filterable attributes for layer products set
46 | *
47 | * @return Mage_Catalog_Model_Resource_Product_Attribute_Collection
48 | */
49 | protected function getFilterableAttributes()
50 | {
51 | $collection = Mage::getResourceModel('catalog/product_attribute_collection');
52 | $collection
53 | ->setItemObjectClass('catalog/resource_eav_attribute')
54 | ->addStoreLabel(Mage::app()->getStore()->getId())
55 | ->setOrder('position', 'ASC')
56 | ->addIsFilterableFilter();
57 | $collection->load();
58 |
59 | return $collection;
60 | }
61 |
62 | /**
63 | * Generate filters from current URL query
64 | *
65 | * @return array Filters as field name => value pairs
66 | */
67 | protected function getQueryFilters()
68 | {
69 | $filters = array();
70 | $helper = Mage::helper('solr');
71 |
72 | // get query part from current URL
73 | $urlQuery = Mage::getModel('core/url')->getRequest()->getQuery();
74 |
75 | foreach ($this->filterableAttributes as $attribute) {
76 | $attributeCode = $attribute->getAttributeCode();
77 |
78 | // match attribute codes
79 | if (array_key_exists($attributeCode, $urlQuery)) {
80 | // generate filters from matches
81 | $fieldName = Mage::helper('solr/schema')->getFieldNameByAttribute($attribute);
82 | $filters[$fieldName] = '"' . $urlQuery[$attributeCode] . '"';
83 | }
84 | }
85 |
86 | return $filters;
87 | }
88 |
89 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Indexer/Catalog.php:
--------------------------------------------------------------------------------
1 | array(
14 | Mage_Index_Model_Event::TYPE_SAVE,
15 | Mage_Index_Model_Event::TYPE_MASS_ACTION,
16 | Mage_Index_Model_Event::TYPE_REINDEX
17 | ),
18 | );
19 |
20 |
21 | protected function _construct()
22 | {
23 | $this->_init('solr/indexer_catalog');
24 | }
25 |
26 | /**
27 | * Get Indexer name
28 | *
29 | * @return string
30 | */
31 | public function getName()
32 | {
33 | return Mage::helper('solr')->__('Solr Catalog Search Index');
34 | }
35 |
36 | /**
37 | * Get Indexer description
38 | *
39 | * @return string
40 | */
41 | public function getDescription()
42 | {
43 | return Mage::helper('solr')->__('Rebuild Solr catalog search index');
44 | }
45 |
46 | /**
47 | * Register indexer required data inside event object
48 | *
49 | * @param Mage_Index_Model_Event $event
50 | */
51 | protected function _registerEvent(Mage_Index_Model_Event $event)
52 | {
53 | // TODO: Implement _registerEvent() method.
54 |
55 | $event->addNewData(self::EVENT_MATCH_RESULT_KEY, true);
56 | switch ($event->getEntity()) {
57 | case Mage_Catalog_Model_Product::ENTITY:
58 | $this->registerCatalogProductEvent($event);
59 | break;
60 | // TODO handle other models
61 | }
62 | }
63 |
64 | protected function registerCatalogProductEvent(Mage_Index_Model_Event $event)
65 | {
66 | switch ($event->getType()) {
67 | case Mage_Index_Model_Event::TYPE_SAVE:
68 | $product = $event->getDataObject();
69 | /** @var Mage_Catalog_Model_Product $product */
70 | $event->addNewData('solr_update_product_id', $product->getId());
71 | break;
72 | case Mage_Index_Model_Event::TYPE_MASS_ACTION:
73 |
74 |
75 | break;
76 |
77 | }
78 | }
79 |
80 | /**
81 | * Process event based on event state data
82 | *
83 | * @param Mage_Index_Model_Event $event
84 | */
85 | protected function _processEvent(Mage_Index_Model_Event $event)
86 | {
87 | // TODO: Implement _processEvent() method.
88 |
89 | // if ($event->getData('solr_update_product_id'))
90 | // {
91 | // $this->callEventHandler($event);
92 | // }
93 |
94 |
95 | }
96 |
97 | public function reindexAll()
98 | {
99 | $resource = $this->getResource();
100 | /** @var Asm_Solr_Model_Resource_Indexer_Catalog $resource */
101 | $resource->rebuildIndex();
102 |
103 |
104 |
105 | $connection = Mage::helper('solr/connectionManager')->getConnection();
106 | /** @var $connection Asm_Solr_Model_Solr_Connection */
107 |
108 | $connection->commit();
109 | }
110 | }
--------------------------------------------------------------------------------
/lib/Apache/Solr/HttpTransportException.php:
--------------------------------------------------------------------------------
1 |
37 | */
38 |
39 | class Apache_Solr_HttpTransportException extends Apache_Solr_Exception
40 | {
41 | /**
42 | * SVN Revision meta data for this class
43 | */
44 | const SVN_REVISION = '$Revision$';
45 |
46 | /**
47 | * SVN ID meta data for this class
48 | */
49 | const SVN_ID = '$Id$';
50 |
51 | /**
52 | * Response for which exception was generated
53 | *
54 | * @var Apache_Solr_Response
55 | */
56 | private $_response;
57 |
58 | /**
59 | * HttpTransportException Constructor
60 | *
61 | * @param Apache_Solr_Response $response
62 | */
63 | public function __construct(Apache_Solr_Response $response)
64 | {
65 | parent::__construct("'{$response->getHttpStatus()}' Status: {$response->getHttpStatusMessage()}", $response->getHttpStatus());
66 |
67 | $this->_response = $response;
68 | }
69 |
70 | /**
71 | * Get the response for which this exception was generated
72 | *
73 | * @return Apache_Solr_Response
74 | */
75 | public function getResponse()
76 | {
77 | return $this->_response;
78 | }
79 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Solr/Query/Modifier/Sorting.php:
--------------------------------------------------------------------------------
1 |
10 | */
11 | class Asm_Solr_Model_Solr_Query_Modifier_Sorting
12 | {
13 |
14 | /**
15 | *
16 | *
17 | * @var array
18 | */
19 | protected $sortAttributes = array();
20 |
21 | /**
22 | * Sort directions whitelist
23 | *
24 | * @var array
25 | */
26 | protected $directions = array('asc', 'desc');
27 |
28 |
29 | /**
30 | * Init sorting query modifier
31 | *
32 | */
33 | public function __construct()
34 | {
35 | $availableSortAttributes = $this->getCatalogConfig()->getAttributeUsedForSortByArray();
36 | unset($availableSortAttributes['position']);
37 |
38 | $this->sortAttributes = array_merge(array(
39 | 'relevance' => 'Relevance' // the actual label does not matter here, we're only using the keys
40 | ), $availableSortAttributes);
41 |
42 | // unset the sort order session data to have the sort select box always
43 | // reflect the correct sort field and reset it when starting a new search
44 | Mage::getSingleton('catalog/session')->unsetData('sort_order');
45 | }
46 |
47 | /**
48 | * Called before a query is executed. Modifies the query to add sorting
49 | * parameters.
50 | *
51 | * @param Varien_Event_Observer $observer Observer/event data
52 | * @throws InvalidArgumentException for invalid dir and order parameters
53 | */
54 | public function modifyQuery(Varien_Event_Observer $observer)
55 | {
56 | // get query part from current URL
57 | $urlQuery = Mage::getModel('core/url')->getRequest()->getQuery();
58 |
59 | if (!array_key_exists('order', $urlQuery)) {
60 | return;
61 | }
62 |
63 | $direction = $urlQuery['dir'];
64 | $field = $urlQuery['order'];
65 |
66 | if (!in_array($direction, $this->directions)) {
67 | throw new InvalidArgumentException(
68 | 'Invalid sort direction parameter "' . $direction . '", must be asc or desc.',
69 | 1397868721
70 | );
71 | }
72 |
73 | if (array_key_exists($field, $this->sortAttributes)) {
74 | if ($field == 'relevance') {
75 | $sortField = 'relevance';
76 | } else if ($field == 'name') {
77 | $sortField = 'sortTitle';
78 | } else {
79 | $sortField = Mage::helper('solr/schema')->getFieldNameByAttribute($field);
80 | }
81 |
82 | /** @var Asm_Solr_Model_Solr_Query $query */
83 | $query = $observer->getQuery();
84 | $query->setSorting($sortField . ' ' . $direction);
85 | } else {
86 | throw new InvalidArgumentException(
87 | 'No sortable attribute found for sort parameter ' . $field,
88 | 1397868606
89 | );
90 | }
91 | }
92 |
93 | /**
94 | * Retrieve Catalog Config object
95 | *
96 | * @return Mage_Catalog_Model_Config
97 | */
98 | protected function getCatalogConfig() {
99 | return Mage::getSingleton('catalog/config');
100 | }
101 |
102 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Solr/Response.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | class Asm_Solr_Model_Solr_Response
11 | {
12 | /**
13 | * @var Apache_Solr_Response
14 | */
15 | protected $rawResponse;
16 |
17 | /**
18 | * Constructor
19 | *
20 | */
21 | public function __construct(array $responseParameters = array())
22 | {
23 | $this->rawResponse = $responseParameters['rawResponse'];
24 | }
25 |
26 | /**
27 | * Gets the number of results found
28 | *
29 | * @return integer Number of results found
30 | */
31 | public function getNumberOfResults()
32 | {
33 | return $this->rawResponse->response->numFound;
34 | }
35 |
36 | /**
37 | * Gets the result documents
38 | *
39 | * @return Apache_Solr_Document[] Array of Apache_Solr_Document
40 | */
41 | public function getDocuments()
42 | {
43 | return $this->rawResponse->response->docs;
44 | }
45 |
46 | /**
47 | * Gets the result highlighting
48 | *
49 | * @return Apache_Solr_Document[] Array of Apache_Solr_Document
50 | */
51 | public function getHighlighting()
52 | {
53 | return $this->rawResponse->highlighting;
54 | }
55 |
56 | public function getFacetRanges()
57 | {
58 | return $this->rawResponse->facet_counts->facet_ranges;
59 | }
60 |
61 | public function getFacetField()
62 | {
63 | return $this->rawResponse->facet_counts->facet_fields;
64 | }
65 |
66 | /**
67 | * Gets the field facets
68 | *
69 | * @return Asm_Solr_Model_Solr_Facet_Facet[] Array of Asm_Solr_Model_Solr_Facet_Facet
70 | */
71 | public function getFacetFields()
72 | {
73 | $facets = array();
74 | $facetFields = $this->rawResponse->facet_counts->facet_fields;
75 | $fieldToAttributeMap = Mage::helper('solr/schema')->getFieldToAttributeMap();
76 |
77 | foreach ($facetFields as $facetField => $facetOptions) {
78 | $attributeCode = $facetField;
79 | if (!array_key_exists($facetField, $fieldToAttributeMap)) {
80 | // remove field type suffix
81 | $attributeCode = implode('_', explode('_', $facetField, -1));
82 | }
83 |
84 | $facet = Mage::getModel('solr/solr_facet_facet')
85 | ->setName($attributeCode)
86 | ->setAttributeCode($attributeCode)
87 | ->setField($facetField);
88 |
89 | if (!empty($facetOptions)) {
90 | foreach ($facetOptions as $optionValue => $numberOfResults) {
91 | $facetOption = Mage::getModel('solr/solr_facet_facetOption')
92 | ->setFacet($facet)
93 | ->setLabel($optionValue)
94 | ->setValue($optionValue)
95 | ->setNumberOfResults($numberOfResults);
96 | $facet->addOption($facetOption);
97 | }
98 | }
99 |
100 | $facets[] = $facet;
101 | }
102 |
103 | return $facets;
104 | }
105 |
106 | /* TODO add range and query facet support
107 | public function getFacetRanges()
108 | {
109 |
110 | }
111 |
112 | public function getFacetQueries()
113 | {
114 |
115 | }
116 | */
117 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Solr/Facet/Facet.php:
--------------------------------------------------------------------------------
1 |
10 | *
11 | * @method string getName()
12 | * @method Asm_Solr_Model_Solr_Facet_Facet setName(string $name)
13 | * @method Asm_Solr_Model_Solr_Facet_Facet setAttributeCode(string $attributeCode)
14 | * @method Asm_Solr_Model_Solr_Facet_Facet setField(string $field)
15 | */
16 | class Asm_Solr_Model_Solr_Facet_Facet extends Varien_Object
17 | {
18 | const TYPE_FIELD = 'field';
19 |
20 | const TYPE_QUERY = 'query';
21 |
22 | const TYPE_RANGE = 'range';
23 |
24 | /**
25 | * Facet type, defaults to field facet.
26 | *
27 | * @var string
28 | */
29 | protected $type = self::TYPE_FIELD;
30 |
31 | /**
32 | * Facet options
33 | *
34 | * @var array
35 | */
36 | protected $options = array();
37 |
38 |
39 |
40 | /**
41 | * Checks whether an option of the facet has been selected by the user by
42 | * checking the URL GET parameters.
43 | *
44 | * @return boolean TRUE if any option of the facet is applied, FALSE otherwise
45 | */
46 | public function isActive()
47 | {
48 | $isActive = FALSE;
49 |
50 | $selectedOptions = $this->getSelectedOptions();
51 | if (!empty($selectedOptions)) {
52 | $isActive = TRUE;
53 | }
54 |
55 | return $isActive;
56 | }
57 |
58 | /**
59 | * Gets the facet's currently user-selected options
60 | *
61 | * @return array An array with user-selected facet options.
62 | */
63 | public function getSelectedOptions()
64 | {
65 | $selectedOptions = array();
66 |
67 | #FIXME
68 | $resultParameters = t3lib_div::_GET('tx_solr');
69 | $filterParameters = array();
70 | if (isset($resultParameters['filter'])) {
71 | $filterParameters = (array)array_map('urldecode', $resultParameters['filter']);
72 | }
73 |
74 | foreach ($filterParameters as $filter) {
75 | list($facetName, $filterValue) = explode(':', $filter);
76 |
77 | if ($facetName == $this->name) {
78 | $selectedOptions[] = $filterValue;
79 | }
80 | }
81 |
82 | return $selectedOptions;
83 | }
84 |
85 | /**
86 | * Adds a facet option
87 | *
88 | * @param Asm_Solr_Model_Solr_Facet_FacetOption $option
89 | */
90 | public function addOption(Asm_Solr_Model_Solr_Facet_FacetOption $option) {
91 | $this->options[$option->getValue()] = $option;
92 | }
93 |
94 | public function getOptions() {
95 | return $this->options;
96 | }
97 |
98 | /**
99 | * Gets an option by its value
100 | *
101 | * @param string $optionValue Option value
102 | * @return Asm_Solr_Model_Solr_Facet_FacetOption
103 | */
104 | public function getOption($optionValue)
105 | {
106 | return $this->options[$optionValue];
107 | }
108 |
109 | /**
110 | * Gets the facet's internal type. One of field, range, or query.
111 | *
112 | * @return string Facet type.
113 | */
114 | public function getType()
115 | {
116 | return $this->type;
117 | }
118 |
119 | /**
120 | * Gets the facet's label
121 | *
122 | * @return string
123 | */
124 | public function getLabel()
125 | {
126 | return $this->getName();
127 | }
128 |
129 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Helper/ConnectionManager.php:
--------------------------------------------------------------------------------
1 |
11 | */
12 | class Asm_Solr_Helper_ConnectionManager
13 | {
14 |
15 | /**
16 | * Gets the default connection / connection for the current store
17 | *
18 | * @return Asm_Solr_Model_Solr_Connection
19 | */
20 | public function getConnection()
21 | {
22 | // get current store Solr configuration
23 | $solrConnectionParameters = Mage::getStoreConfig('solr/connection');
24 | $connection = Mage::getModel('solr/solr_connection', $solrConnectionParameters);
25 |
26 | return $connection;
27 | }
28 |
29 | /**
30 | * Gets the Solr connection for a specific store
31 | *
32 | * @param string|int $store Store code or store ID
33 | * @return Asm_Solr_Model_Solr_Connection
34 | */
35 | public function getConnectionByStore($store)
36 | {
37 | $storeCode = $store;
38 |
39 | if (is_numeric($store)) {
40 | $storeCode = Mage::getModel('core/store')
41 | ->getCollection()
42 | ->addIdFilter($store)
43 | ->getFirstItem()
44 | ->getCode();
45 | }
46 |
47 | $solrConnectionParameters = Mage::getConfig()->getNode('solr/connection', 'stores', $storeCode);
48 | $connection = Mage::getModel('solr/solr_connection', $solrConnectionParameters);
49 |
50 | return $connection;
51 | }
52 |
53 | /**
54 | * Gets the Solr connections for all stores of a website.
55 | *
56 | * @param int|string $site Website code or ID
57 | * @return Asm_Solr_Model_Solr_Connection[] Array of Asm_Solr_Model_Solr_Connection objects
58 | */
59 | public function getConnectionsBySite($site)
60 | {
61 | $connections = array();
62 |
63 | if (is_string($site) && !is_numeric($site)) {
64 | // website code
65 | $collection = Mage::getModel('core/website')->getCollection()->addFieldToFilter('code', $site);
66 | $website = $collection->getFirstItem();
67 | } else {
68 | // website id
69 | $website = Mage::getModel('core/website')->getCollection()->addIdFilter($site)->getFirstItem();
70 | }
71 |
72 | $stores = $website->getStoreCollection();
73 | foreach ($stores as $store) {
74 | /** @var Mage_Core_Model_Store $store */
75 | $storeConnection = $this->getConnectionByStore($store->getId());
76 | $connections[] = $storeConnection;
77 | }
78 |
79 | return $connections;
80 | }
81 |
82 | /**
83 | * Gets all connections for all websites and their stores
84 | *
85 | * @return Asm_Solr_Model_Solr_Connection[]
86 | */
87 | public function getAllConnections()
88 | {
89 | $connections = array();
90 | $websites = Mage::getModel('core/website')->getCollection()->addFieldToFilter('website_id', array("neq" => '0'));
91 |
92 | foreach ($websites as $website) {
93 | /** @var Mage_Core_Model_Website $website */
94 | $id = $website->getId();
95 | $websiteConnections = $this->getConnectionsBySite($website->getId());
96 | $connections = array_merge($connections, $websiteConnections);
97 | }
98 |
99 | return $connections;
100 | }
101 |
102 | }
103 |
104 | ?>
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Block/Facets.php:
--------------------------------------------------------------------------------
1 | getChildHtml('solr.filters_applied');
20 | }
21 |
22 | // /**
23 | // * Whether to show the number of products that will be returned when
24 | // * applying a filter.
25 | // *
26 | // * @return bool
27 | // */
28 | // public function shouldDisplayProductCount()
29 | // {
30 | // if ($this->displayProductCount === null) {
31 | // $this->displayProductCount = Mage::helper('catalog')->shouldDisplayProductCountOnLayer();
32 | // }
33 | //
34 | // return $this->displayProductCount;
35 | // }
36 |
37 | /**
38 | * Gets the facets returned for the current/last query
39 | *
40 | * @return Asm_Solr_Model_Solr_Facet_Facet[]
41 | */
42 | public function getFacets() {
43 | $result = Mage::registry('solr_result');
44 | $facets = $this->getResult()->getResponse()->getFacetFields();
45 |
46 | return $facets;
47 | }
48 |
49 | public function getKeywords()
50 | {
51 | if (!$this->getData('keywords'))
52 | {
53 | $keywords = $this->getRequest()->getParam('q', '');
54 |
55 | $this->setData('keywords', $keywords);
56 | }
57 |
58 | return $this->getData('keywords');
59 | }
60 |
61 | public function getFilterQuery()
62 | {
63 | if (!$this->getData('filter_query'))
64 | {
65 | $keywords = $this->getRequest()->getParam('fq', '');
66 |
67 | $this->setData('filter_query', $keywords);
68 | }
69 |
70 | return $this->getData('filter_query');
71 | }
72 |
73 | public function getResult()
74 | {
75 | // if we don't have a result set for us, let's make one
76 | if (!$this->getData('result'))
77 | {
78 | /** @var Asm_Solr_Model_Result $result */
79 | $result = Mage::getModel('solr/result');
80 |
81 | $keywords = $this->getKeywords();
82 | $filterQuery = $this->getFilterQuery();
83 | $solrType = 'catalog/product';
84 | $limit = 0;
85 | $offset = 0;
86 |
87 | $query = $result->getQuery();
88 | $query->setFaceting(true);
89 | $query->setKeywords($keywords);
90 | $query->addFilter('type', $solrType);
91 |
92 | $query->addQueryParameter("facet.range","price");
93 | $query->addQueryParameter("facet.range.start","0");
94 | $query->addQueryParameter("facet.range.end","100");
95 | $query->addQueryParameter("facet.range.gap","10");
96 |
97 | $result->load($limit, $offset);
98 |
99 | $this->setData('result', $result);
100 | }
101 |
102 | return $this->getData('result');
103 | }
104 |
105 | public function getFacetRanges()
106 | {
107 | return $this->getResult()->getResponse()->getFacetRanges();
108 | }
109 | }
--------------------------------------------------------------------------------
/lib/Apache/Solr/HttpTransport/Abstract.php:
--------------------------------------------------------------------------------
1 | , Donovan Jimenez
37 | */
38 |
39 | /**
40 | * Convenience class that implements the transport implementation. Can be extended by
41 | * real implementations to do some of the common book keeping
42 | */
43 | abstract class Apache_Solr_HttpTransport_Abstract implements Apache_Solr_HttpTransport_Interface
44 | {
45 | /**
46 | * Our default timeout value for requests that don't specify a timeout
47 | *
48 | * @var float
49 | */
50 | private $_defaultTimeout = false;
51 |
52 | /**
53 | * Get the current default timeout setting (initially the default_socket_timeout ini setting)
54 | * in seconds
55 | *
56 | * @return float
57 | */
58 | public function getDefaultTimeout()
59 | {
60 | // lazy load the default timeout from the ini settings
61 | if ($this->_defaultTimeout === false)
62 | {
63 | $this->_defaultTimeout = (int) ini_get('default_socket_timeout');
64 |
65 | // double check we didn't get 0 for a timeout
66 | if ($this->_defaultTimeout <= 0)
67 | {
68 | $this->_defaultTimeout = 60;
69 | }
70 | }
71 |
72 | return $this->_defaultTimeout;
73 | }
74 |
75 | /**
76 | * Set the current default timeout for all HTTP requests
77 | *
78 | * @param float $timeout
79 | */
80 | public function setDefaultTimeout($timeout)
81 | {
82 | $timeout = (float) $timeout;
83 |
84 | if ($timeout >= 0)
85 | {
86 | $this->_defaultTimeout = $timeout;
87 | }
88 | }
89 | }
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/solr/result/page/list.phtml:
--------------------------------------------------------------------------------
1 |
27 |
34 | getCollection();
36 | $_helper = $this->helper('catalog/output');
37 | ?>
38 | count()): ?>
39 | __('There are no pages matching your search terms.') ?>
40 |
41 |
42 | getToolbarHtml() ?>
43 |
44 |
45 |
46 |
47 | -
48 |
49 |
50 | stripTags($_page->getTitle(), null, true); ?>
51 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | getToolbarHtml() ?>
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Observer/Index/Page.php:
--------------------------------------------------------------------------------
1 | getPage();
28 | $storeId = $event->getStoreId();
29 | $pageId = $page->getId();
30 | $pageContent = $page->getContent();
31 | $links = array();
32 | $allowedFileTypes = $this->getAllowedFileTypesRegex();
33 |
34 | preg_match_all('/.*<\/a>/iU', $pageContent, $links);
35 |
36 | if (empty($links[0])) {
37 | // bail out if we didn't find any file links, save a couple CPU cycles
38 | return;
39 | }
40 |
41 | $foundFiles = array();
42 | $trackedFiles = $this->getTrackedFilesForPage($pageId);
43 |
44 | $numberOfFiles = count($links[0]);
45 | for ($i = 0; $i < $numberOfFiles; $i++) {
46 | $foundFiles[] = '/' . htmlspecialchars_decode($links[1][$i]) . '.' . $links[2][$i];
47 | }
48 |
49 | $addedFiles = array_diff($foundFiles, $trackedFiles);
50 | $removedFiles = array_diff($trackedFiles, $foundFiles);
51 |
52 | $this->addFilesToTracking($storeId, $pageId, $addedFiles);
53 | $this->removeFilesFromTracking($storeId, $pageId, $removedFiles);
54 | }
55 |
56 | protected function addFilesToTracking($storeId, $pageId, $addedFiles)
57 | {
58 | foreach ($addedFiles as $addedFile) {
59 | $indexQueueFile = Mage::getModel('solr/indexqueue_file')->setData(array(
60 | 'cms_page_id' => $pageId,
61 | 'store_id' => $storeId,
62 | 'file_path' => $addedFile,
63 | 'changed' => time(),
64 | 'indexed' => 0
65 | ));
66 | $indexQueueFile->save();
67 | }
68 | }
69 |
70 | protected function removeFilesFromTracking($storeId, $pageId, $removedFiles)
71 | {
72 |
73 | // FIXME must filter by pageId, possibly also storeId
74 | // file might still be linked from another page
75 |
76 | foreach ($removedFiles as $removedFile) {
77 | $indexQueueFile = Mage::getModel('solr/indexqueue_file')->load(
78 | $removedFile,
79 | 'file_path'
80 | );
81 | $indexQueueFile->delete();
82 | }
83 | }
84 |
85 | protected function getAllowedFileTypesRegex() {
86 | $fileTypes = Mage::getStoreConfig('index/files/file_types');
87 |
88 | $fileTypes = trim($fileTypes);
89 | $fileTypes = str_replace(' ', '', $fileTypes);
90 | $fileTypes = str_replace(',', '|', $fileTypes);
91 |
92 | return "($fileTypes)";
93 | }
94 |
95 | protected function getTrackedFilesForPage($pageId)
96 | {
97 | $trackedFiles = Mage::getModel('solr/indexqueue_file')
98 | ->getCollection()
99 | ->addFieldToFilter('cms_page_id', $pageId);
100 |
101 | $trackedFiles = $trackedFiles->getColumnValues('file_path');
102 |
103 | return $trackedFiles;
104 | }
105 |
106 | }
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/solr/result/file/list.phtml:
--------------------------------------------------------------------------------
1 |
27 |
34 | getCollection();
36 | $_helper = $this->helper('catalog/output');
37 | ?>
38 | count()): ?>
39 | __('There are no pages matching your search terms.') ?>
40 |
41 |
42 | getToolbarHtml() ?>
43 |
44 |
45 |
46 |
47 | -
48 |
49 |
50 | stripTags($_file->getTitle(), null, true); ?>
51 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | getToolbarHtml() ?>
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Model/Resource/Indexer/File.php:
--------------------------------------------------------------------------------
1 |
26 | */
27 | class Asm_Solr_Model_Resource_Indexer_File extends Mage_Core_Model_Resource_Db_Abstract
28 | {
29 |
30 | /**
31 | * Resource initialization
32 | */
33 | protected function _construct() {
34 | $this->_setResource('core');
35 | }
36 |
37 | /**
38 | * Rebuild the index for all stores at once or just one specific store.
39 | *
40 | * @param int|null $storeId Store to re-index single int store ID to re-index single store, null to re-index all stores
41 | */
42 | public function rebuildIndex($storeId = null)
43 | {
44 | if (is_null($storeId)) {
45 | // re-index all stores
46 | $storeIds = array_keys(Mage::app()->getStores());
47 | foreach ($storeIds as $storeId) {
48 | $this->rebuildStoreIndex($storeId);
49 | }
50 | } else {
51 | // re-index specific store
52 | $this->rebuildStoreIndex($storeId);
53 | }
54 | }
55 |
56 | public function rebuildStoreIndex($storeId)
57 | {
58 | $files = $this->getFilesByStore($storeId);
59 | $solr = Mage::helper('solr/connectionManager')->getConnectionByStore($storeId);
60 |
61 | foreach ($files as $file) {
62 | $document = $this->buildFileDocument($storeId, $file);
63 | $solr->addDocument($document);
64 | }
65 | }
66 |
67 |
68 | protected function getFilesByStore($storeId)
69 | {
70 | $collection = Mage::getModel('solr/indexqueue_file')->getCollection()
71 | ->addFilter('store_id', $storeId)
72 | ->load();
73 |
74 | return $collection;
75 | }
76 |
77 | /**
78 | * Build a Solr document for a specific file
79 | *
80 | * @param integer $storeId Store ID the file belongs to/where it is linked on a page
81 | * @param Asm_Solr_Model_Indexqueue_File $file The file to index
82 | * @return Apache_Solr_Document
83 | */
84 | protected function buildFileDocument($storeId, Asm_Solr_Model_Indexqueue_File $file)
85 | {
86 | $helper = Mage::helper('solr');
87 | $baseUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
88 | $host = parse_url($baseUrl, PHP_URL_HOST);
89 |
90 | $document = new Apache_Solr_Document();
91 |
92 | $document->setField('appKey', 'Asm_Solr');
93 | $document->setField('type', 'solr/indexqueue_file');
94 |
95 | $document->setField('id', $helper->getFileDocumentId($file->getId()));
96 | $document->setField('site', $host);
97 | $document->setField('siteHash', $helper->getSiteHashForDomain($host));
98 | $document->setField('storeId', $storeId);
99 | $document->setField('changed', $helper->dateToIso($file->getFileLastChangedTime()));
100 |
101 | $document->setField('productId', 0);
102 | $document->setField('sku', 'solr/indexqueue_file');
103 |
104 | $document->setField('title', $file->getName());
105 | $document->setField('content', $file->getContent());
106 | $document->setField('url', $file->getUrl());
107 |
108 | return $document;
109 | }
110 |
111 |
112 | }
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Resources/solr/magentocores/conf/currency.xml:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/controllers/Adminhtml/Solr/System/Config/UtilityController.php:
--------------------------------------------------------------------------------
1 | getRequest()->getParam('section');
17 | $website = $this->getRequest()->getParam('website');
18 | $store = $this->getRequest()->getParam('store');
19 |
20 | $logger = Mage::helper('solr')->getLogger();
21 | $logger->debug("section: $section, website: $website, store: $store");
22 |
23 | if (!empty($section) && empty($website) && empty($store)) {
24 | // empty ALL indexes
25 |
26 | $connections = Mage::helper('solr/connectionManager')->getAllConnections();
27 | foreach ($connections as $connection) {
28 | /** @var $connection Asm_Solr_Model_Solr_Connection */
29 | $connection->deleteByQuery('*:*');
30 | $result = ($connection->commit()->getHttpStatus() == 200);
31 |
32 | if ($result) {
33 | $logger->info('Empty index', array('core' => $connection->getPath()));
34 | } else {
35 | $logger->error('Empty index', array('core' => $connection->getPath()));
36 | break;
37 | }
38 | }
39 | } elseif (!empty($section) && !empty($website) && empty($store)) {
40 | // empty a website's stores' indexes
41 |
42 | $connections = Mage::helper('solr/connectionManager')->getConnectionsBySite($website);
43 | foreach ($connections as $connection) {
44 | /** @var $connection Asm_Solr_Model_Solr_Connection */
45 | $connection->deleteByQuery('*:*');
46 | $result = ($connection->commit()->getHttpStatus() == 200);
47 |
48 | if ($result) {
49 | $logger->info('Empty index', array('core' => $connection->getPath()));
50 | } else {
51 | $logger->error('Empty index', array('core' => $connection->getPath()));
52 | break;
53 | }
54 | }
55 | } else {
56 | // empty a specific store's index
57 |
58 | $connection = Mage::helper('solr/connectionManager')->getConnectionByStore($store);
59 | $connection->deleteByQuery('*:*');
60 | $result = ($connection->commit()->getHttpStatus() == 200);
61 |
62 | if ($result) {
63 | $logger->info('Empty index', array('core' => $connection->getPath()));
64 | } else {
65 | $logger->error('Empty index', array('core' => $connection->getPath()));
66 | }
67 | }
68 |
69 | echo $result ? 1 : 0;
70 | }
71 |
72 | public function syncsynonymsAction() {
73 | $result = true;
74 |
75 | // FIXME does not support per store synonyms yet, syncing for all
76 | $connections = Mage::helper('solr/connectionManager')->getAllConnections();
77 | $connection = $connections[0];
78 |
79 | $synonymHandler = Mage::getModel('solr/synonymHandler');
80 |
81 | // remove existing synonyms
82 | $oldSynonyms = $connection->getSynonyms();
83 | $oldSynonyms = (array) $oldSynonyms;
84 | $oldSynonyms = array_keys($oldSynonyms);
85 | foreach ($oldSynonyms as $synonym) {
86 | $connection->deleteSynonym($synonym);
87 | }
88 |
89 | // write new synonyms
90 | $queries = Mage::getModel('catalogsearch/query')
91 | ->getCollection()
92 | ->addFieldToFilter('synonym_for', array("notnull"=>true));
93 |
94 | foreach ($queries as $query) {
95 | $baseWord = $query->getData('query_text');
96 | $synonyms = $query->getData('synonym_for');
97 |
98 | if (!empty($synonyms)) {
99 | $synonyms = trim($synonyms, " \"\n\r\t");
100 | $newSynonyms = Mage::helper('solr')->trimExplode(',', $synonyms);
101 | $connection->addSynonym($baseWord, $newSynonyms);
102 | }
103 | }
104 |
105 | echo $result ? 1 : 0;
106 | }
107 |
108 | /**
109 | * Action to test the configured connection (ping) depending on the current scope
110 | *
111 | */
112 | public function testconnectionAction()
113 | {
114 | $store = $this->getRequest()->getParam('store');
115 | $connection = Mage::helper('solr/connectionManager')->getConnectionByStore($store);
116 |
117 | echo $connection->ping() ? 1 : 0;
118 | }
119 |
120 | public function playgroundAction()
121 | {
122 | # var_dump(Mage::getConfig()->getNode('solr/connection', 'stores', 'german'));
123 |
124 |
125 | var_dump(Mage::helper('solr/connectionManager')->getConnectionByStore('german'));
126 | }
127 |
128 | }
129 |
130 |
131 | ?>
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Helper/Schema.php:
--------------------------------------------------------------------------------
1 |
9 | */
10 | class Asm_Solr_Helper_Schema
11 | {
12 | /**
13 | * A map of Solr document fields to Magento product attributes.
14 | *
15 | * Contains all fixed indexed fields/attributes, other product attributes
16 | * are added to Solr documents using dynamic fields.
17 | *
18 | * @var array
19 | */
20 | protected static $fieldToAttributeMap = array(
21 | 'appKey' => '',
22 | 'type' => '',
23 | 'id' => '',
24 | 'site' => '',
25 | 'siteHash' => '',
26 | 'created' => 'created_at',
27 | 'changed' => 'changed_at',
28 | 'sku' => 'sku',
29 | 'productId' => 'entity_id',
30 | 'storeId' => '',
31 | 'categoryId' => 'category_ids',
32 | 'inStock' => '',
33 | 'isSalable' => 'is_salable',
34 | 'isVisible' => 'status',
35 | 'isVisibleInCatalog' => '',
36 | 'title' => 'name',
37 | 'content' => 'description',
38 | 'keywords' => 'meta_keywords',
39 | 'url' => '',
40 | 'price' => 'price',
41 | 'manufacturer' => 'manufacturer',
42 | 'priceCurrency' => '',
43 | 'indexed' => '',
44 | '_version_' => '',
45 | 'score' => ''
46 | );
47 |
48 | /**
49 | * A list of dynamic field suffixes. There are more dynamic field types,
50 | * but these are the ones that are currently used.
51 | *
52 | * Used to automatically map dynamic fields back to product attributes.
53 | *
54 | * @var array
55 | */
56 | protected static $dynamicFieldSuffixes = array(
57 | 'dateS',
58 | 'doubleS',
59 | 'intS',
60 | 'stringS',
61 | 'textS'
62 | );
63 |
64 | /**
65 | * Gets a map of Solr document fields to Magento product attributes.
66 | *
67 | * @return array
68 | */
69 | public function getFieldToAttributeMap() {
70 | return self::$fieldToAttributeMap;
71 | }
72 |
73 | /**
74 | * Gets a list of Solr dynamic field suffixes
75 | *
76 | * @return array
77 | */
78 | public function getDynamicFieldSuffixes() {
79 | return self::$dynamicFieldSuffixes;
80 | }
81 |
82 | /**
83 | * Generates a (dynamic) field name for a given attribute
84 | *
85 | * @param string|Mage_Eav_Model_Entity_Attribute_Abstract $attribute Maybe an attribute object or an attribute code
86 | * @param bool $multiValue If true, generates a multi value field name, single value if false/by default
87 | * @return bool|string Field name or false if the attribute's backend type cannot be matched to a Solr field type
88 | * @throws UnexpectedValueException if $attribute is not an attribute code or an attribute instance
89 | */
90 | public function getFieldNameByAttribute($attribute, $multiValue = false) {
91 | $fieldName = false;
92 |
93 | if (is_string($attribute)) {
94 | $fieldName = array_search($attribute, self::$fieldToAttributeMap, true);
95 | if ($fieldName !== false) {
96 | // early return if we can find the field in the field/attribute map
97 | return $fieldName;
98 | }
99 |
100 | // turn attribute code into attribute instance
101 | $attribute = Mage::getSingleton('eav/config')
102 | ->getAttribute(Mage_Catalog_Model_Product::ENTITY, $attribute);
103 | }
104 |
105 | if (!($attribute instanceof Mage_Eav_Model_Entity_Attribute_Abstract)) {
106 | throw new UnexpectedValueException(
107 | '$attribute must either be an attribute code or an instance of Mage_Eav_Model_Entity_Attribute_Abstract',
108 | 1395360135
109 | );
110 | }
111 |
112 | $attributeCode = $attribute->getAttributeCode();
113 |
114 | $countFieldType = 'S'; // single value
115 | if ($multiValue || $attribute->getIsConfigurable()) {
116 | $countFieldType = 'M';
117 | }
118 |
119 | if (array_key_exists($attributeCode, self::$fieldToAttributeMap)) {
120 | return self::$fieldToAttributeMap[$attributeCode];
121 | }
122 |
123 | switch ($attribute->getBackendType()) {
124 | case 'datetime':
125 | $fieldName = $attributeCode . '_date' . $countFieldType;
126 | break;
127 | case 'decimal':
128 | $fieldName = $attributeCode . '_double' . $countFieldType;
129 | break;
130 | case 'int':
131 | // FIXME must use correct field type if it's actually int
132 | // $fieldName = $attributeCode . '_int' . $countFieldType;
133 | $fieldName = $attributeCode . '_string' . $countFieldType;
134 | break;
135 | case 'text':
136 | case 'varchar':
137 | // TODO there might be cases when you want a string instead,
138 | // might need a configuration option
139 | $fieldName = $attributeCode . '_text' . $countFieldType;
140 | break;
141 | }
142 |
143 | return $fieldName;
144 | }
145 |
146 | }
--------------------------------------------------------------------------------
/app/design/frontend/base/default/layout/solr.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | page/3columns.phtml
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | empty6
36 | one_column5
37 | two_columns_left4
38 | two_columns_right4
39 | three_columns3
40 |
41 | product_list_toolbar
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | page/3columns.phtml
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | page/3columns.phtml
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/app/code/community/Asm/Solr/Helper/ContentExtractor.php:
--------------------------------------------------------------------------------
1 |
25 | */
26 | class Asm_Solr_Helper_ContentExtractor
27 | {
28 | /**
29 | * Unicode ranges which should get stripped before sending a document to solr.
30 | * This is necessary if a document (PDF, etc.) contains unicode characters which
31 | * are valid in the font being used in the document but are not available in the
32 | * font being used for displaying results.
33 | *
34 | * This is often the case if PDFs are being indexed where special fonts are used
35 | * for displaying bullets, etc. Usually those bullets reside in one of the unicode
36 | * "Private Use Zones" or the "Private Use Area" (plane 15 + 16)
37 | *
38 | * @see http://en.wikipedia.org/wiki/Unicode_block
39 | * @var array
40 | */
41 | protected $stripUnicodeRanges = array(
42 | array('FFFD', 'FFFD'), // Replacement Character (�) @see http://en.wikipedia.org/wiki/Specials_%28Unicode_block%29
43 | array('E000', 'F8FF'), // Private Use Area (part of Plane 0)
44 | array('F0000', 'FFFFF'), // Supplementary Private Use Area (Plane 15)
45 | array('100000', '10FFFF'), // Supplementary Private Use Area (Plane 16)
46 | );
47 |
48 |
49 | /**
50 | * Returns the cleaned indexable content from HTML markup.
51 | *
52 | * The content is cleaned from HTML tags and control chars Solr could
53 | * stumble on.
54 | *
55 | * @param string $content Content to clean for indexing
56 | * @return string Indexable, cleaned content ready for indexing.
57 | */
58 | public function getIndexableContent($content) {
59 | $content = $this->cleanContent($content);
60 | $content = html_entity_decode($content, ENT_QUOTES, 'UTF-8');
61 | // after entity decoding we might have tags again
62 | $content = strip_tags($content);
63 | $content = trim($content);
64 |
65 | return $content;
66 | }
67 |
68 | /**
69 | * Strips control characters that cause Jetty/Solr to fail.
70 | *
71 | * @param string $content The content to sanitize
72 | * @return string The sanitized content
73 | * @see http://w3.org/International/questions/qa-forms-utf-8.html
74 | */
75 | public function stripControlCharacters($content) {
76 | // Printable utf-8 does not include any of these chars below x7F
77 | return preg_replace('@[\x00-\x08\x0B\x0C\x0E-\x1F]@', ' ', $content);
78 | }
79 |
80 | /**
81 | * Strips a UTF-8 character range
82 | *
83 | * @param string $content Content to sanitize
84 | * @param string $start Unicode range start character as uppercase hexadecimal string
85 | * @param string $end Unicode range end character as uppercase hexadecimal string
86 | * @return string Sanitized content
87 | */
88 | public function stripUnicodeRange($content, $start, $end) {
89 | return preg_replace('/[\x{' . $start . '}-\x{' . $end . '}]/u', '', $content);
90 | }
91 |
92 | /**
93 | * Strips unusable unicode ranges
94 | *
95 | * @param string $content Content to sanitize
96 | * @return string Sanitized content
97 | */
98 | public function stripUnicodeRanges($content) {
99 | foreach ($this->stripUnicodeRanges as $range) {
100 | $content = $this->stripUnicodeRange($content, $range[0], $range[1]);
101 | }
102 |
103 | return $content;
104 | }
105 |
106 | /**
107 | * Strips html tags, and tab, new-line, carriage-return, whitespace
108 | * characters.
109 | *
110 | * @param string $content String to clean
111 | * @return string String cleaned from tags and special whitespace characters
112 | */
113 | public function cleanContent($content) {
114 | $content = $this->stripControlCharacters($content);
115 |
116 | // remove Javascript
117 | $content = preg_replace('@