├── .github
├── ISSUE_TEMPLATE.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .php_cs
├── .styleci.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE.txt
├── MAINTAINERS.md
├── README.md
├── app
├── code
│ └── community
│ │ └── Algolia
│ │ └── Algoliasearch
│ │ ├── Block
│ │ ├── Adminhtml
│ │ │ ├── Indexingqueue.php
│ │ │ ├── Indexingqueue
│ │ │ │ ├── Edit.php
│ │ │ │ ├── Edit
│ │ │ │ │ └── Form.php
│ │ │ │ ├── Grid.php
│ │ │ │ ├── Grid
│ │ │ │ │ └── Renderer
│ │ │ │ │ │ └── Json.php
│ │ │ │ └── Status.php
│ │ │ ├── Notifications.php
│ │ │ └── Reindexsku
│ │ │ │ ├── Edit.php
│ │ │ │ └── Edit
│ │ │ │ └── Form.php
│ │ ├── Checkout
│ │ │ └── Success
│ │ │ │ └── Conversion.php
│ │ └── System
│ │ │ └── Config
│ │ │ └── Form
│ │ │ └── Field
│ │ │ ├── AbstractField.php
│ │ │ ├── AdditionalSections.php
│ │ │ ├── CategoryAdditionalAttributes.php
│ │ │ ├── ClickAnalytics.php
│ │ │ ├── CustomRankingCategoryAttributes.php
│ │ │ ├── CustomRankingProductAttributes.php
│ │ │ ├── ExcludedPages.php
│ │ │ ├── Facets.php
│ │ │ ├── Logo.php
│ │ │ ├── OnewaySynonyms.php
│ │ │ ├── ProductAdditionalAttributes.php
│ │ │ ├── ProductAttributes.php
│ │ │ ├── Select.php
│ │ │ ├── Sorts.php
│ │ │ └── Synonyms.php
│ │ ├── Helper
│ │ ├── Algoliahelper.php
│ │ ├── Config.php
│ │ ├── Data.php
│ │ ├── Entity
│ │ │ ├── Additionalsectionshelper.php
│ │ │ ├── Categoryhelper.php
│ │ │ ├── Helper.php
│ │ │ ├── Pagehelper.php
│ │ │ ├── Producthelper.php
│ │ │ └── Suggestionhelper.php
│ │ ├── Image.php
│ │ ├── IndexChecker.php
│ │ ├── Logger.php
│ │ └── ProxyHelper.php
│ │ ├── Model
│ │ ├── Exception
│ │ │ ├── IndexPendingException.php
│ │ │ ├── ProductDeletedException.php
│ │ │ ├── ProductDisabledException.php
│ │ │ ├── ProductNotVisibleException.php
│ │ │ ├── ProductOutOfStockException.php
│ │ │ ├── ProductReindexException.php
│ │ │ └── ProductUnknownSkuException.php
│ │ ├── Indexer
│ │ │ ├── Abstract.php
│ │ │ ├── Algolia.php
│ │ │ ├── Algoliaadditionalsections.php
│ │ │ ├── Algoliacategories.php
│ │ │ ├── Algoliadeleteproducts.php
│ │ │ ├── Algoliapages.php
│ │ │ ├── Algoliaqueuerunner.php
│ │ │ └── Algoliasuggestions.php
│ │ ├── Job.php
│ │ ├── Observer.php
│ │ ├── Observer
│ │ │ └── Conversion.php
│ │ ├── Queue.php
│ │ ├── Resource
│ │ │ ├── Engine.php
│ │ │ ├── Fulltext.php
│ │ │ ├── Fulltext
│ │ │ │ └── Collection.php
│ │ │ ├── Job.php
│ │ │ └── Job
│ │ │ │ └── Collection.php
│ │ ├── Source
│ │ │ ├── JobMethods.php
│ │ │ └── JobStatuses.php
│ │ └── System
│ │ │ ├── BackendRenderingDisplayMode.php
│ │ │ ├── Config
│ │ │ ├── Backend
│ │ │ │ ├── EnableClickAnalytics.php
│ │ │ │ ├── ExtraSettings.php
│ │ │ │ ├── Serialized
│ │ │ │ │ └── Array.php
│ │ │ │ └── SynonymsFile.php
│ │ │ └── Source
│ │ │ │ └── Dropdown
│ │ │ │ └── RetryValues.php
│ │ │ ├── ConversionAnalyticsMode.php
│ │ │ ├── Imagetype.php
│ │ │ ├── IndexVisibility.php
│ │ │ └── Removewords.php
│ │ ├── bin
│ │ └── dump.php
│ │ ├── controllers
│ │ └── Adminhtml
│ │ │ └── Algoliasearch
│ │ │ ├── IndexingqueueController.php
│ │ │ ├── QueueController.php
│ │ │ └── ReindexskuController.php
│ │ ├── etc
│ │ ├── adminhtml.xml
│ │ ├── config.xml
│ │ └── system.xml
│ │ └── sql
│ │ └── algoliasearch_setup
│ │ ├── mysql4-install-0.1.0.php
│ │ ├── mysql4-upgrade-0.1.0-1.4.8.php
│ │ ├── mysql4-upgrade-1.11.1-1.12.0.php
│ │ ├── mysql4-upgrade-1.14.1-1.15.0.php
│ │ ├── mysql4-upgrade-1.15.0-1.16.0.php
│ │ ├── mysql4-upgrade-1.16.0-1.17.0.php
│ │ ├── mysql4-upgrade-1.4.8-1.5.0.php
│ │ ├── mysql4-upgrade-1.5.5-1.6.0.php
│ │ ├── mysql4-upgrade-1.6.0-1.7.1.php
│ │ └── mysql4-upgrade-1.7.1-1.11.1.php
├── design
│ ├── adminhtml
│ │ └── default
│ │ │ └── default
│ │ │ ├── layout
│ │ │ └── algoliasearch.xml
│ │ │ └── template
│ │ │ └── algoliasearch
│ │ │ ├── adminjs.phtml
│ │ │ ├── notifications.phtml
│ │ │ └── queue
│ │ │ └── status.phtml
│ └── frontend
│ │ └── base
│ │ └── default
│ │ ├── layout
│ │ └── algoliasearch.xml
│ │ └── template
│ │ └── algoliasearch
│ │ ├── autocomplete.phtml
│ │ ├── autocomplete
│ │ ├── attribute.phtml
│ │ ├── category.phtml
│ │ ├── menu.phtml
│ │ ├── page.phtml
│ │ ├── product.phtml
│ │ └── suggestion.phtml
│ │ ├── checkout
│ │ └── success
│ │ │ └── conversion.phtml
│ │ ├── instantsearch
│ │ ├── currentRefinements.phtml
│ │ ├── hit-item.phtml
│ │ ├── hit.phtml
│ │ ├── refinementsItem.phtml
│ │ ├── stats.phtml
│ │ └── wrapper.phtml
│ │ └── internals
│ │ ├── beforecontent.phtml
│ │ └── configuration.phtml
├── etc
│ └── modules
│ │ └── Algolia_Algoliasearch.xml
└── locale
│ ├── en_US
│ └── Algolia_Algoliasearch.csv
│ ├── nl_NL
│ └── Algolia_Algoliasearch.csv
│ └── sv_SE
│ └── Algolia_Algoliasearch.csv
├── composer.json
├── dev
├── Dockerfile.base
├── Dockerfile.dev
├── Dockerfile.test
├── bin
│ ├── .zshrc
│ ├── algoliasearch.xml
│ ├── config.inc.php
│ ├── install-magento
│ ├── makeRelease.php
│ ├── php.ini
│ ├── start.sh
│ └── test.sh
├── restart.sh
└── runTests.sh
├── doc
├── auto-complete.gif
└── instant-search.gif
├── js
└── algoliasearch
│ ├── autocomplete.js
│ ├── click_conversion_analytics.js
│ ├── instantsearch.js
│ └── internals
│ ├── adminhtml
│ ├── admin_scripts.js
│ ├── algoliaAdminBundle.min.js
│ └── algoliaAdminBundle.min.js.map
│ └── frontend
│ ├── Function.prototype.bind.js
│ ├── algoliaBundle.min.js
│ ├── algoliaBundle.min.js.map
│ ├── common.js
│ └── search-insights.js
├── lib
└── AlgoliaSearch
│ ├── AlgoliaConnectionException.php
│ ├── AlgoliaException.php
│ ├── Analytics.php
│ ├── Client.php
│ ├── ClientContext.php
│ ├── FailingHostsCache.php
│ ├── FileFailingHostsCache.php
│ ├── InMemoryFailingHostsCache.php
│ ├── Index.php
│ ├── IndexBrowser.php
│ ├── Iterators
│ ├── AlgoliaIterator.php
│ ├── RuleIterator.php
│ └── SynonymIterator.php
│ ├── Json.php
│ ├── PlacesIndex.php
│ ├── SynonymType.php
│ ├── Version.php
│ ├── loader.php
│ └── resources
│ └── ca-bundle.crt
├── modman
├── phpunit.xml.dist
├── skin
├── adminhtml
│ └── base
│ │ └── default
│ │ └── algoliasearch
│ │ └── algoliasearch.css
└── frontend
│ └── base
│ └── default
│ └── algoliasearch
│ ├── algolia-admin-menu.svg
│ ├── algoliasearch.css
│ ├── clear-cross.svg
│ ├── cross-circle.svg
│ ├── is-icon.svg
│ ├── magnifying-glass.svg
│ ├── search-by-algolia.svg
│ └── stars-icon.svg
└── tests
├── AbstractIndexingTestCase.php
├── AbstractTestCase.php
├── CategoriesIndexingTest.php
├── ConfigTest.php
├── PagesIndexingTest.php
├── ProductsIndexingTest.php
├── QueueTest.php
└── bootstrap.php
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
15 |
16 | **Do you want to request a *feature* or report a *bug*?**
17 |
18 |
26 |
27 | **Bug: What is the current behavior?**
28 |
29 | **Bug: What is the expected behavior?**
30 |
31 | **Bug: What is the proposed solution?**
32 |
33 | **Feature: What is your use case for such a feature?**
34 |
35 | **Feature: What is your proposed configuration entry? The new option to add? What is the behavior?**
36 |
37 | **What is the version of Magento and of Algolia extension you are using? Always use the latest version of the extension one before opening a bug issue.**
38 |
39 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
5 |
6 | **Summary**
7 |
8 |
13 |
14 | **Result**
15 |
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | vendor
3 | composer.lock
4 |
--------------------------------------------------------------------------------
/.php_cs:
--------------------------------------------------------------------------------
1 | in(__DIR__.DIRECTORY_SEPARATOR.'app/code/');
5 |
6 | return Symfony\CS\Config\Config::create()
7 | ->setUsingCache(true)
8 | ->level(Symfony\CS\FixerInterface::SYMFONY_LEVEL)
9 | ->fixers([
10 | 'align_double_arrow',
11 | 'long_array_syntax',
12 | '-multiline_array_trailing_comma',
13 | '-pre_increment'
14 | ])->finder($finder);
--------------------------------------------------------------------------------
/.styleci.yml:
--------------------------------------------------------------------------------
1 | preset: PSR2
2 |
3 | enabled:
4 | - long_array_syntax
5 |
6 | finder:
7 | path:
8 | - "app/code"
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | How to contribute?
2 |
3 | Basic flow:
4 |
5 | - Fork this repository
6 | - Make the fix/change/feature
7 | - Commit
8 | - Open a pull request to the **develop** branch
9 | - We will then review your pull request and make sure your fix helps the community.
10 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Algolia
4 | http://www.algolia.com/
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/MAINTAINERS.md:
--------------------------------------------------------------------------------
1 | ## Maintainers
2 | The Algolia Magento 1 extension has reached a support and maintenance EOL and, therefore, will not commit to maintain the extension past FEB 2021. We encourage you to upgrade to Magento 2 as Magento 1 has already reached its end of life.
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/Adminhtml/Indexingqueue.php:
--------------------------------------------------------------------------------
1 | _blockGroup = 'algoliasearch';
11 | $this->_controller = 'adminhtml_indexingqueue';
12 |
13 | parent::__construct();
14 |
15 | $this->_removeButton('add');
16 | $this->_addButton('clear_queue', array(
17 | 'label' => Mage::helper('algoliasearch')->__('Clear Queue'),
18 | 'onclick' => "if (confirm('Are you sure you want to clear the queue? This operation cannot be reverted.')) {
19 | location.href='" . $this->getUrl('*/*/clear') . "' };",
20 | 'class' => 'cancel',
21 | ));
22 | }
23 |
24 | /**
25 | * Get header text.
26 | *
27 | * @return string
28 | */
29 | public function getHeaderText()
30 | {
31 | return Mage::helper('algoliasearch')->__('Algolia Search - Indexing Queue');
32 | }
33 |
34 | /**
35 | * Set custom Algolia icon class.
36 | *
37 | * @return string
38 | */
39 | public function getHeaderCssClass()
40 | {
41 | return 'icon-head algoliasearch-head-icon';
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/Adminhtml/Indexingqueue/Edit.php:
--------------------------------------------------------------------------------
1 | _objectId = 'job_id';
13 | $this->_blockGroup = 'algoliasearch';
14 | $this->_controller = 'adminhtml_indexingqueue';
15 |
16 | $this->_removeButton('save');
17 | $this->_removeButton('reset');
18 | $this->_removeButton('delete');
19 | }
20 |
21 | /**
22 | * Get header text.
23 | *
24 | * @return string
25 | */
26 | public function getHeaderText()
27 | {
28 | return Mage::helper('algoliasearch')->__('Algolia Search - Indexing Queue Job #%s',
29 | Mage::registry('algoliasearch_current_job')->getJobId());
30 | }
31 |
32 | /**
33 | * Set custom Algolia icon class.
34 | *
35 | * @return string
36 | */
37 | public function getHeaderCssClass()
38 | {
39 | return 'icon-head algoliasearch-head-icon';
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/Adminhtml/Indexingqueue/Grid.php:
--------------------------------------------------------------------------------
1 | setId('job_id');
13 | $this->setDefaultSort('job_id');
14 | $this->setDefaultDir('acs');
15 | }
16 |
17 | /**
18 | * Prepare Search Report collection for grid
19 | *
20 | * @return Mage_Adminhtml_Block_Report_Search_Grid
21 | */
22 | protected function _prepareCollection()
23 | {
24 | $collection = Mage::getResourceModel('algoliasearch/job_collection');
25 | $this->setCollection($collection);
26 |
27 | return parent::_prepareCollection();
28 | }
29 |
30 | /**
31 | * Prepare Grid columns
32 | *
33 | * @return Mage_Adminhtml_Block_Report_Search_Grid
34 | */
35 | protected function _prepareColumns()
36 | {
37 | $this->addColumn('job_id', array(
38 | 'header' => Mage::helper('algoliasearch')->__('Job ID'),
39 | 'width' => '50px',
40 | 'filter' => false,
41 | 'index' => 'job_id',
42 | 'type' => 'number'
43 | ));
44 |
45 | $this->addColumn('created', array(
46 | 'header' => Mage::helper('algoliasearch')->__('Created'),
47 | 'index' => 'created',
48 | 'type' => 'datetime',
49 | ));
50 |
51 | $this->addColumn('status', array(
52 | 'header' => Mage::helper('algoliasearch')->__('Status'),
53 | 'index' => 'status',
54 | 'getter' => 'getStatusLabel',
55 | 'filter' => false,
56 | ));
57 |
58 | $this->addColumn('method', array(
59 | 'header' => Mage::helper('algoliasearch')->__('Method'),
60 | 'index' => 'method',
61 | 'type' => 'options',
62 | 'options' => Mage::getModel('algoliasearch/source_jobMethods')->getMethods(),
63 | ));
64 |
65 | $this->addColumn('data', array(
66 | 'header' => Mage::helper('algoliasearch')->__('Data'),
67 | 'index' => 'data',
68 | 'renderer' => 'Algolia_Algoliasearch_Block_Adminhtml_Indexingqueue_Grid_Renderer_Json'
69 | ));
70 |
71 | $this->addColumn('max_retries', array(
72 | 'header' => Mage::helper('algoliasearch')->__('Max Retries'),
73 | 'width' => '40px',
74 | 'filter' => false,
75 | 'index' => 'max_retries',
76 | 'type' => 'number'
77 | ));
78 |
79 | $this->addColumn('retries', array(
80 | 'header' => Mage::helper('algoliasearch')->__('Retries'),
81 | 'width' => '40px',
82 | 'filter' => false,
83 | 'index' => 'retries',
84 | 'type' => 'number'
85 | ));
86 |
87 | $this->addColumn('action',
88 | array(
89 | 'header' => Mage::helper('algoliasearch')->__('Action'),
90 | 'width' => '50px',
91 | 'type' => 'action',
92 | 'getter' => 'getJobId',
93 | 'actions' => array(
94 | array(
95 | 'caption' => Mage::helper('algoliasearch')->__('View'),
96 | 'url' => array('base'=>'*/*/view'),
97 | 'field' => 'id'
98 | )
99 | ),
100 | 'filter' => false,
101 | 'sortable' => false,
102 | ));
103 |
104 | return parent::_prepareColumns();
105 | }
106 |
107 | /**
108 | * Retrieve Row Click callback URL
109 | *
110 | * @return string
111 | */
112 | public function getRowUrl($row)
113 | {
114 | return $this->getUrl('*/*/view', array('id' => $row->getJobId()));
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/Adminhtml/Indexingqueue/Grid/Renderer/Json.php:
--------------------------------------------------------------------------------
1 | getData('data')) {
13 | $json = json_decode($json, true);
14 |
15 | foreach ($json as $var => $value) {
16 | $html .= $var . ': ' . (is_array($value) ? implode(',', $value) : $value) . ' ';
17 | }
18 | }
19 | return $html;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/Adminhtml/Notifications.php:
--------------------------------------------------------------------------------
1 | getUrl('adminhtml/system_config/edit/section/algoliasearch');
10 | }
11 |
12 | public function showNotification()
13 | {
14 | /** @var Algolia_Algoliasearch_Helper_Config $config */
15 | $config = Mage::helper('algoliasearch/config');
16 |
17 | return $config->showQueueNotificiation();
18 | }
19 |
20 | public function getQueueInfo()
21 | {
22 | if (isset($this->_queueInfo)) {
23 | return $this->_queueInfo;
24 | }
25 |
26 | /** @var Algolia_Algoliasearch_Helper_Config $config */
27 | $config = Mage::helper('algoliasearch/config');
28 |
29 | /** @var Mage_Core_Model_Resource $resource */
30 | $resource = Mage::getSingleton('core/resource');
31 | $tableName = $resource->getTableName('algoliasearch/queue');
32 |
33 | $readConnection = $resource->getConnection('core_read');
34 |
35 | $size = (int)$readConnection->query('SELECT COUNT(*) as total_count FROM ' . $tableName)->fetchColumn(0);
36 | $maxJobsPerSingleRun = $config->getNumberOfJobToRun();
37 |
38 | $etaMinutes = ceil($size / $maxJobsPerSingleRun) * 5; // 5 - assuming the queue runner runs every 5 minutes
39 |
40 | $eta = $etaMinutes . ' minutes';
41 | if ($etaMinutes > 60) {
42 | $hours = floor($etaMinutes / 60);
43 | $restMinutes = $etaMinutes % 60;
44 |
45 | $eta = $hours . ' hours ' . $restMinutes . ' minutes';
46 | }
47 |
48 | $queueInfo = array(
49 | 'isEnabled' => $config->isQueueActive(),
50 | 'currentSize' => $size,
51 | 'eta' => $eta,
52 | );
53 |
54 | $this->_queueInfo = $queueInfo;
55 |
56 | return $this->_queueInfo;
57 | }
58 |
59 | /**
60 | * Show notification based on condition
61 | *
62 | * @return bool
63 | */
64 | protected function _toHtml()
65 | {
66 | $queueInfo = $this->getQueueInfo();
67 | if ($this->showNotification()
68 | && $queueInfo['isEnabled'] === true
69 | && $queueInfo['currentSize'] > 0) {
70 | return parent::_toHtml();
71 | }
72 |
73 | return '';
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/Adminhtml/Reindexsku/Edit.php:
--------------------------------------------------------------------------------
1 | _objectId = 'sku';
13 | $this->_blockGroup = 'algoliasearch';
14 | $this->_controller = 'adminhtml_reindexsku';
15 | }
16 |
17 | /**
18 | * Get header text.
19 | *
20 | * @return string
21 | */
22 | public function getHeaderText()
23 | {
24 | return Mage::helper('algoliasearch')->__('Algolia Search - Reindex SKU(s)');
25 | }
26 |
27 | /**
28 | * Set custom Algolia icon class.
29 | *
30 | * @return string
31 | */
32 | public function getHeaderCssClass()
33 | {
34 | return 'icon-head algoliasearch-head-icon';
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/Adminhtml/Reindexsku/Edit/Form.php:
--------------------------------------------------------------------------------
1 | 'edit_form',
12 | 'action' => $this->getUrl('*/*/reindexPost'),
13 | 'method' => 'post',
14 | ));
15 |
16 | $fieldset = $form->addFieldset('base_fieldset', array());
17 |
18 | $html = '';
19 | $html .= '
'.__('Enter here the SKU(s) you want to reindex separated by commas or carriage returns.').'
';
20 | $html .= ''.__('You will be notified if there is any reason why your product can\'t be reindexed.').'
';
21 | $html .= ''.__('It can be :').'
';
22 | $html .= '';
23 | $html .= ''.__('Product is disabled.').' ';
24 | $html .= ''.__('Product is deleted.').' ';
25 | $html .= ''.__('Product is out of stock.').' ';
26 | $html .= ''.__('Product is not visible.').' ';
27 | $html .= ''.__('Product is not related to the store.').' ';
28 | $html .= ' ';
29 | $html .= ''.__('You can reindex up to 10 SKUs at once.').'
';
30 |
31 | $fieldset->addField('skus', 'textarea', array(
32 | 'name' => 'skus',
33 | 'label' => Mage::helper('algoliasearch')->__('Product SKU(s)'),
34 | 'title' => Mage::helper('algoliasearch')->__('Product SKU(s)'),
35 | 'required' => true,
36 | 'style' => 'width:100%',
37 | 'after_element_html' => $html,
38 | ));
39 |
40 | $form->setUseContainer(true);
41 | $this->setForm($form);
42 |
43 | return parent::_prepareForm();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/Checkout/Success/Conversion.php:
--------------------------------------------------------------------------------
1 | getLastOrderId()) {
13 | $this->_order = Mage::getModel('sales/order')->load($orderId);
14 | }
15 | }
16 |
17 | /**
18 | * @return string
19 | */
20 | public function getOrderItemsConversionJson()
21 | {
22 | $orderItemsData = array();
23 | $orderItems = $this->_order->getAllVisibleItems();
24 |
25 | /** @var Item $item */
26 | foreach ($orderItems as $item) {
27 | if ($item->getData('algoliasearch_query_param') !== '') {
28 | $orderItemsData[$item->getProductId()] = json_decode($item->getData('algoliasearch_query_param'));
29 | }
30 | }
31 |
32 | return Mage::helper('core')->jsonEncode($orderItemsData);
33 | }
34 |
35 | public function _toHtml()
36 | {
37 | if ($this->_order
38 | && Mage::helper('algoliasearch/config')->isClickConversionAnalyticsEnabled($this->_order->getStoreId())
39 | && Mage::helper('algoliasearch/config')->getConversionAnalyticsMode($this->_order->getStoreId()) === 'place_order'
40 | ) {
41 | return parent::_toHtml();
42 | }
43 |
44 | return '';
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/System/Config/Form/Field/AbstractField.php:
--------------------------------------------------------------------------------
1 | settings)) {
11 | throw new Exception('Please, specify columns settings.');
12 | }
13 |
14 | foreach ($this->settings['columns'] as $columnName => $columnSettings) {
15 | $fieldSettings = array();
16 |
17 | if (isset($columnSettings['label'])) {
18 | $fieldSettings['label'] = Mage::helper('adminhtml')->__($columnSettings['label']);
19 | }
20 |
21 | if (isset($columnSettings['options'])) {
22 | $fieldSettings['renderer'] = $this->getRenderer($columnName, $columnSettings);
23 | }
24 |
25 | if (isset($columnSettings['class'])) {
26 | $fieldSettings['class'] = $columnSettings['class'];
27 | }
28 |
29 | if (isset($columnSettings['style'])) {
30 | $fieldSettings['style'] = $columnSettings['style'];
31 | }
32 |
33 | $this->addColumn($columnName, $fieldSettings);
34 | }
35 |
36 | $this->_addAfter = $this->settings['addAfter'];
37 | $this->_addButtonLabel = Mage::helper('adminhtml')->__($this->settings['buttonLabel']);
38 |
39 | parent::__construct();
40 | }
41 |
42 | protected function _prepareArrayRow(Varien_Object $row)
43 | {
44 | foreach ($this->settings['columns'] as $columnName => $columnSettings) {
45 | if (!isset($columnSettings['options']) || !isset($columnSettings['rowMethod'])) {
46 | continue;
47 | }
48 |
49 | $row->setData('option_extra_attr_'.$this->getRenderer($columnName, $columnSettings)->calcOptionHash($row->{$columnSettings['rowMethod']}()), 'selected="selected"');
50 | }
51 | }
52 |
53 | /**
54 | * Creates and populates a select block to represent each column in the configuration property.
55 | *
56 | * @param $columnId string The name of the column defined in addColumn
57 | * @param $columnSettings array Settings for select box
58 | *
59 | * @return Algolia_Algoliasearch_Block_System_Config_Form_Field_Select
60 | *
61 | * @throws Exception
62 | */
63 | protected function getRenderer($columnId, array $columnSettings)
64 | {
65 | if (array_key_exists($columnId, $this->selectFields) && $this->selectFields[$columnId]) {
66 | return $this->selectFields[$columnId];
67 | }
68 |
69 | $options = $columnSettings['options'];
70 | if (!is_array($options) && is_callable($options)) {
71 | $options = $options();
72 | }
73 |
74 | $width = 100;
75 | if (isset($columnSettings['width'])) {
76 | $width = $columnSettings['width'];
77 | }
78 |
79 | /** @var Algolia_Algoliasearch_Block_System_Config_Form_Field_Select $selectField */
80 | $selectField = Mage::app()->getLayout()->createBlock('algoliasearch/system_config_form_field_select');
81 |
82 | $selectField->setIsRenderToJsTemplate(true);
83 | $selectField->setOptions($options);
84 | $selectField->setExtraParams('style="width:'.$width.'px;"');
85 |
86 | if (isset($columnSettings['disabled']) && $columnSettings['disabled'] != 0) {
87 | $extra = $selectField->getExtraParams();
88 | $extra .= ' disabled';
89 | $selectField->setExtraParams($extra);
90 | }
91 |
92 | $this->selectFields[$columnId] = $selectField;
93 |
94 | return $this->selectFields[$columnId];
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/System/Config/Form/Field/AdditionalSections.php:
--------------------------------------------------------------------------------
1 | settings = array(
11 | 'columns' => array(
12 | 'name' => array(
13 | 'label' => 'Section',
14 | 'options' => function () {
15 | $options = array();
16 |
17 | $sections = array(
18 | array('name' => 'pages', 'label' => 'Pages'),
19 | );
20 |
21 | /** @var Algolia_Algoliasearch_Helper_Config $config */
22 | $config = Mage::helper('algoliasearch/config');
23 |
24 | $attributes = $config->getFacets();
25 | foreach ($attributes as $attribute) {
26 | if ($attribute['attribute'] == 'price' || $attribute['attribute'] == 'category' || $attribute['attribute'] == 'categories') {
27 | continue;
28 | }
29 |
30 | $sections[] = array(
31 | 'name' => $attribute['attribute'],
32 | 'label' => $attribute['label'] ? $attribute['label'] : $attribute['attribute']
33 | );
34 | }
35 |
36 | foreach ($sections as $section) {
37 | $options[$section['name']] = $section['label'];
38 | }
39 |
40 | return $options;
41 | },
42 | 'rowMethod' => 'getName',
43 | 'width' => 130,
44 | ),
45 | 'label' => array(
46 | 'label' => 'Label',
47 | 'style' => 'width: 100px;',
48 | ),
49 | 'hitsPerPage' => array(
50 | 'label' => 'Hits per page',
51 | 'style' => 'width: 100px;',
52 | 'class' => 'required-entry input-text validate-number',
53 | ),
54 | ),
55 | 'buttonLabel' => 'Add Section',
56 | 'addAfter' => false,
57 | );
58 |
59 | parent::__construct();
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/System/Config/Form/Field/CategoryAdditionalAttributes.php:
--------------------------------------------------------------------------------
1 | settings = array(
11 | 'columns' => array(
12 | 'attribute' => array(
13 | 'label' => 'Attribute',
14 | 'options' => function () {
15 | $options = array();
16 |
17 | /** @var Algolia_Algoliasearch_Helper_Entity_Categoryhelper $category_helper */
18 | $category_helper = Mage::helper('algoliasearch/entity_categoryhelper');
19 |
20 | $searchableAttributes = $category_helper->getAllAttributes();
21 | foreach ($searchableAttributes as $key => $label) {
22 | $options[$key] = $key ? $key : $label;
23 | }
24 |
25 | return $options;
26 | },
27 | 'rowMethod' => 'getAttribute',
28 | 'width' => 160,
29 | ),
30 | 'searchable' => array(
31 | 'label' => 'Searchable',
32 | 'options' => array(
33 | '1' => 'Yes',
34 | '0' => 'No',
35 | ),
36 | 'rowMethod' => 'getSearchable',
37 | ),
38 | 'retrievable' => array(
39 | 'label' => 'Retrievable',
40 | 'options' => array(
41 | '1' => 'Yes',
42 | '0' => 'No',
43 | ),
44 | 'rowMethod' => 'getRetrievable',
45 | ),
46 | 'order' => array(
47 | 'label' => 'Ordered',
48 | 'options' => array(
49 | 'unordered' => 'Unordered',
50 | 'ordered' => 'Ordered',
51 | ),
52 | 'rowMethod' => 'getOrder',
53 | ),
54 | ),
55 | 'buttonLabel' => 'Add Attribute',
56 | 'addAfter' => false,
57 | );
58 |
59 | parent::__construct();
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/System/Config/Form/Field/ClickAnalytics.php:
--------------------------------------------------------------------------------
1 | isClickAnalyticsEnabled($element)) {
10 | $element->setDisabled(true);
11 | $this->_showUpsell = true;
12 | }
13 |
14 | return parent::_getElementHtml($element);
15 | }
16 |
17 | /**
18 | * @return bool
19 | */
20 | public function isClickAnalyticsEnabled()
21 | {
22 | $proxyHelper = Mage::helper('algoliasearch/proxyHelper');
23 | $info = $proxyHelper->getClientConfigurationData();
24 |
25 | return isset($info['click_analytics']) && $info['click_analytics'] == 1;
26 | }
27 |
28 | protected function _decorateRowHtml($element, $html)
29 | {
30 | if (!$this->_showUpsell) {
31 | return parent::_decorateRowHtml($element, $html);
32 | }
33 |
34 | $additionalRow = '';
35 | $additionalRow .= $this->__('To get access to this Algolia feature, please consider
upgrading to a higher plan. ',
36 | 'https://www.algolia.com/pricing/');
37 | $additionalRow .= '
';
38 |
39 | return '' . $html . ' ' . $additionalRow;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/System/Config/Form/Field/CustomRankingCategoryAttributes.php:
--------------------------------------------------------------------------------
1 | settings = array(
11 | 'columns' => array(
12 | 'attribute' => array(
13 | 'label' => 'Attribute',
14 | 'options' => function () {
15 | $options = array();
16 |
17 | /** @var Algolia_Algoliasearch_Helper_Config $config */
18 | $config = Mage::helper('algoliasearch/config');
19 |
20 | $attributes = $config->getCategoryAdditionalAttributes();
21 | foreach ($attributes as $attribute) {
22 | $options[$attribute['attribute']] = $attribute['attribute'];
23 | }
24 |
25 | $options['custom_attribute'] = '[use custom attribute]';
26 |
27 | return $options;
28 | },
29 | 'rowMethod' => 'getAttribute',
30 | 'width' => 150,
31 | ),
32 | 'custom_attribute' => array(
33 | 'label' => 'Custom attribute',
34 | 'style' => 'width: 120px;',
35 | ),
36 | 'order' => array(
37 | 'label' => 'Asc / Desc',
38 | 'options' => array(
39 | 'desc' => 'Descending',
40 | 'asc' => 'Ascending',
41 | ),
42 | 'rowMethod' => 'getOrder',
43 | ),
44 | ),
45 | 'buttonLabel' => 'Add Ranking Criterion',
46 | 'addAfter' => false,
47 | );
48 |
49 | parent::__construct();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/System/Config/Form/Field/CustomRankingProductAttributes.php:
--------------------------------------------------------------------------------
1 | settings = array(
11 | 'columns' => array(
12 | 'attribute' => array(
13 | 'label' => 'Attribute',
14 | 'options' => function () {
15 | $options = array();
16 |
17 | /** @var Algolia_Algoliasearch_Helper_Entity_Producthelper $product_helper */
18 | $product_helper = Mage::helper('algoliasearch/entity_producthelper');
19 | $attributes = $product_helper->getAllAttributes();
20 | foreach ($attributes as $key => $label) {
21 | $options[$key] = $key ?: $label;
22 | }
23 |
24 | $options['custom_attribute'] = '[use custom attribute]';
25 |
26 | return $options;
27 | },
28 | 'rowMethod' => 'getAttribute',
29 | 'width' => 150,
30 | ),
31 | 'custom_attribute' => array(
32 | 'label' => 'Custom attribute',
33 | 'style' => 'width: 120px;',
34 | ),
35 | 'order' => array(
36 | 'label' => 'Asc / Desc',
37 | 'options' => array(
38 | 'desc' => 'Descending',
39 | 'asc' => 'Ascending',
40 | ),
41 | 'rowMethod' => 'getOrder',
42 | ),
43 | ),
44 | 'buttonLabel' => 'Add Ranking Criterion',
45 | 'addAfter' => false,
46 | );
47 |
48 | parent::__construct();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/System/Config/Form/Field/ExcludedPages.php:
--------------------------------------------------------------------------------
1 | settings = array(
11 | 'columns' => array(
12 | 'pages' => array(
13 | 'label' => 'Pages',
14 | 'options' => function () {
15 | $options = array();
16 |
17 | /** @var Mage_Cms_Model_Resource_Page_Collection $magento_pages */
18 | $magento_pages = Mage::getModel('cms/page')->getCollection()->addFieldToFilter('is_active', 1);
19 |
20 | $ids = $magento_pages->toOptionArray();
21 | foreach ($ids as $id) {
22 | $options[$id['value']] = $id['value'];
23 | }
24 |
25 | return $options;
26 | },
27 | 'rowMethod' => 'getPages',
28 | 'width' => 230,
29 | ),
30 | ),
31 | 'buttonLabel' => 'Add Excluded Page',
32 | 'addAfter' => false,
33 | );
34 |
35 | parent::__construct();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/System/Config/Form/Field/Facets.php:
--------------------------------------------------------------------------------
1 | settings = array(
13 | 'columns' => array(
14 | 'attribute' => array(
15 | 'label' => 'Attribute',
16 | 'options' => function () {
17 | $options = array();
18 |
19 | /** @var Algolia_Algoliasearch_Helper_Entity_Producthelper $product_helper */
20 | $product_helper = Mage::helper('algoliasearch/entity_producthelper');
21 |
22 | $attributes = $product_helper->getAllAttributes();
23 | foreach ($attributes as $key => $label) {
24 | $options[$key] = $key ?: $label;
25 | }
26 |
27 | return $options;
28 | },
29 | 'rowMethod' => 'getAttribute',
30 | 'width' => 160,
31 | ),
32 | 'type' => array(
33 | 'label' => 'Facet type',
34 | 'options' => array(
35 | 'conjunctive' => 'Conjunctive',
36 | 'disjunctive' => 'Disjunctive',
37 | 'slider' => 'Slider',
38 | 'priceRanges' => 'Price Ranges',
39 | ),
40 | 'rowMethod' => 'getType',
41 | ),
42 | 'label' => array(
43 | 'label' => 'Label',
44 | 'style' => 'width: 100px;',
45 | ),
46 | 'searchable' => array(
47 | 'label' => 'Searchable?',
48 | 'options' => array(
49 | '1' => 'Yes',
50 | '2' => 'No'
51 | ),
52 | 'rowMethod' => 'getSearchable',
53 | ),
54 | 'create_rule' => array(
55 | 'label' => 'Create Query rule?',
56 | 'options' => array(
57 | '2' => 'No',
58 | '1' => 'Yes'
59 | ),
60 | 'rowMethod' => 'getCreateRule',
61 | 'disabled' => $this->isQueryRulesDisabled()
62 | ),
63 | ),
64 | 'buttonLabel' => 'Add Facet',
65 | 'addAfter' => false,
66 | );
67 |
68 | parent::__construct();
69 | }
70 |
71 | /**
72 | * @return bool
73 | */
74 | public function isQueryRulesDisabled()
75 | {
76 | if (is_null($this->_isQueryRulesDisabled)) {
77 | $this->_isQueryRulesDisabled = $this->_disableQueryRules();
78 | }
79 |
80 | return $this->_isQueryRulesDisabled;
81 | }
82 |
83 | /**
84 | * @return bool
85 | */
86 | protected function _disableQueryRules()
87 | {
88 | $proxyHelper = Mage::helper('algoliasearch/proxyHelper');
89 | $info = $proxyHelper->getClientConfigurationData();
90 |
91 | return !isset($info['query_rules']) || $info['query_rules'] == 0;
92 | }
93 |
94 | protected function _decorateRowHtml($element, $html)
95 | {
96 | if (!$this->isQueryRulesDisabled()) {
97 | return parent::_decorateRowHtml($element, $html);
98 | }
99 |
100 | $additionalRow = '';
101 | $additionalRow .= $this->__('To get access to this Algolia feature, please consider
upgrading to a higher plan. ',
102 | 'https://www.algolia.com/pricing/');
103 | $additionalRow .= '
';
104 |
105 | return '' . $html . ' ' . $additionalRow;
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/System/Config/Form/Field/Logo.php:
--------------------------------------------------------------------------------
1 | showLogo($element)) {
10 | $element->setDisabled(true);
11 | $element->setValue(0);
12 | $this->_showUpsell = true;
13 | }
14 |
15 | return parent::_getElementHtml($element);
16 | }
17 |
18 | /**
19 | * @return bool
20 | */
21 | public function showLogo()
22 | {
23 | $proxyHelper = Mage::helper('algoliasearch/proxyHelper');
24 | $info = $proxyHelper->getClientConfigurationData();
25 |
26 | return isset($info['require_logo']) && $info['require_logo'] == 1;
27 | }
28 |
29 | protected function _decorateRowHtml($element, $html)
30 | {
31 | if (!$this->_showUpsell) {
32 | return parent::_decorateRowHtml($element, $html);
33 | }
34 |
35 | $additionalRow = '';
36 | $additionalRow .= $this->__('To be able to remove the Algolia logo, please consider
upgrading to a higher plan. ',
37 | 'https://www.algolia.com/pricing/');
38 | $additionalRow .= '
';
39 |
40 | return '' . $html . ' ' . $additionalRow;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/System/Config/Form/Field/OnewaySynonyms.php:
--------------------------------------------------------------------------------
1 | settings = array(
8 | 'columns' => array(
9 | 'input' => array(
10 | 'label' => 'Input',
11 | 'style' => 'width: 100px;',
12 | ),
13 | 'synonyms' => array(
14 | 'label' => 'Synonyms (comma-separated)',
15 | 'style' => 'width: 435px;',
16 | ),
17 | ),
18 | 'buttonLabel' => 'Add One-way Synonyms',
19 | 'addAfter' => false,
20 | );
21 |
22 | parent::__construct();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/System/Config/Form/Field/ProductAdditionalAttributes.php:
--------------------------------------------------------------------------------
1 | settings = array(
11 | 'columns' => array(
12 | 'attribute' => array(
13 | 'label' => 'Attribute',
14 | 'options' => function () {
15 | $options = array();
16 |
17 | /** @var Algolia_Algoliasearch_Helper_Entity_Producthelper $product_helper */
18 | $product_helper = Mage::helper('algoliasearch/entity_producthelper');
19 |
20 | $searchableAttributes = $product_helper->getAllAttributes();
21 | foreach ($searchableAttributes as $key => $label) {
22 | $options[$key] = $key ?: $label;
23 | }
24 |
25 | return $options;
26 | },
27 | 'rowMethod' => 'getAttribute',
28 | 'width' => 160,
29 | ),
30 | 'searchable' => array(
31 | 'label' => 'Searchable',
32 | 'options' => array(
33 | '1' => 'Yes',
34 | '0' => 'No',
35 | ),
36 | 'rowMethod' => 'getSearchable',
37 | ),
38 | 'retrievable' => array(
39 | 'label' => 'Retrievable',
40 | 'options' => array(
41 | '1' => 'Yes',
42 | '0' => 'No',
43 | ),
44 | 'rowMethod' => 'getRetrievable',
45 | ),
46 | 'order' => array(
47 | 'label' => 'Ordered',
48 | 'options' => array(
49 | 'unordered' => 'Unordered',
50 | 'ordered' => 'Ordered',
51 | ),
52 | 'rowMethod' => 'getOrder',
53 | ),
54 | 'index_no_value' => array(
55 | 'label' => 'Index empty value',
56 | 'options' => array(
57 | '1' => 'Yes',
58 | '0' => 'No',
59 | ),
60 | 'rowMethod' => 'getIndexNoValue',
61 | ),
62 | ),
63 | 'buttonLabel' => 'Add Attribute',
64 | 'addAfter' => false,
65 | );
66 |
67 | parent::__construct();
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/System/Config/Form/Field/ProductAttributes.php:
--------------------------------------------------------------------------------
1 | settings = array(
11 | 'columns' => array(
12 | 'attribute' => array(
13 | 'label' => 'Attribute',
14 | 'options' => function () {
15 | $options = array();
16 |
17 | /** @var Algolia_Algoliasearch_Helper_Entity_Producthelper $product_helper */
18 | $product_helper = Mage::helper('algoliasearch/entity_producthelper');
19 | $attributes = $product_helper->getAllAttributes();
20 | foreach ($attributes as $key => $label) {
21 | $options[$key] = $key ?: $label;
22 | }
23 |
24 | $options['custom_attribute'] = '[use custom attribute]';
25 |
26 | return $options;
27 | },
28 | 'rowMethod' => 'getAttribute',
29 | 'width' => 150,
30 | ),
31 | ),
32 | 'buttonLabel' => 'Add Attribute',
33 | 'addAfter' => false,
34 | );
35 |
36 | parent::__construct();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/System/Config/Form/Field/Select.php:
--------------------------------------------------------------------------------
1 | setName($this->getInputName());
8 | $this->setClass('select');
9 |
10 | return trim(preg_replace('/\s+/', ' ', parent::_toHtml()));
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/System/Config/Form/Field/Sorts.php:
--------------------------------------------------------------------------------
1 | settings = array(
11 | 'columns' => array(
12 | 'attribute' => array(
13 | 'label' => 'Attribute',
14 | 'options' => function () {
15 | $options = array();
16 |
17 | /** @var Algolia_Algoliasearch_Helper_Entity_Producthelper $product_helper */
18 | $product_helper = Mage::helper('algoliasearch/entity_producthelper');
19 | $attributes = $product_helper->getAllAttributes();
20 | foreach ($attributes as $key => $label) {
21 | $options[$key] = $key ?: $label;
22 | }
23 |
24 | return $options;
25 | },
26 | 'rowMethod' => 'getAttribute',
27 | 'width' => 160,
28 | ),
29 | 'sort' => array(
30 | 'label' => 'Sort',
31 | 'options' => array(
32 | 'asc' => 'Ascending',
33 | 'desc' => 'Descending',
34 | ),
35 | 'rowMethod' => 'getSort',
36 | ),
37 | 'label' => array(
38 | 'label' => 'Label',
39 | 'style' => 'width: 200px;',
40 | ),
41 | ),
42 | 'buttonLabel' => 'Add Sorting Attribute',
43 | 'addAfter' => false,
44 | );
45 |
46 | parent::__construct();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Block/System/Config/Form/Field/Synonyms.php:
--------------------------------------------------------------------------------
1 | settings = array(
8 | 'columns' => array(
9 | 'synonyms' => array(
10 | 'label' => 'Synonyms (comma-separated)',
11 | 'style' => 'width: 550px;',
12 | ),
13 | ),
14 | 'buttonLabel' => 'Add Synonyms',
15 | 'addAfter' => false,
16 | );
17 |
18 | parent::__construct();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Helper/Entity/Additionalsectionshelper.php:
--------------------------------------------------------------------------------
1 | array('unordered(value)'),
14 | );
15 |
16 | $transport = new Varien_Object($indexSettings);
17 | Mage::dispatchEvent('algolia_additional_sections_index_before_set_settings', array('store_id' => $storeId, 'index_settings' => $transport));
18 | $indexSettings = $transport->getData();
19 |
20 | return $indexSettings;
21 | }
22 |
23 | public function getAttributeValues($storeId, $section)
24 | {
25 | /** @var Mage_Catalog_Model_Product_Visibility $catalogProductVisibility */
26 | $catalogProductVisibility = Mage::getSingleton('catalog/product_visibility');
27 |
28 | $attributeCode = $section['name'];
29 |
30 | /** @var Mage_Catalog_Model_Resource_Product_Collection $products */
31 | $products = Mage::getResourceModel('catalog/product_collection')->addStoreFilter($storeId)
32 | ->addAttributeToFilter('visibility',
33 | array('in' => $catalogProductVisibility->getVisibleInSearchIds()))
34 | ->addAttributeToFilter('status',
35 | array('eq' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED))
36 | ->addAttributeToFilter($attributeCode, array('notnull' => true))
37 | ->addAttributeToFilter($attributeCode, array('neq' => ''))
38 | ->addAttributeToSelect($attributeCode);
39 |
40 | $usedAttributeValues = array_keys(array_flip(// array unique
41 | explode(',', implode(',', $products->getColumnValues($attributeCode)))));
42 |
43 | /** @var Mage_Eav_Model_Config $eavConfig */
44 | $eavConfig = Mage::getSingleton('eav/config');
45 |
46 | /** @var Mage_Eav_Model_Attribute $attributeModel */
47 | $attributeModel = $eavConfig->getAttribute('catalog_product', $attributeCode);
48 | $attributeModel->setStoreId($storeId);
49 |
50 | $values = $attributeModel->getSource()->getOptionText(implode(',', $usedAttributeValues));
51 |
52 | if (!$values || count($values) == 0) {
53 | $values = array_unique($products->getColumnValues($attributeCode));
54 | }
55 |
56 | if ($values && is_array($values) == false) {
57 | $values = array($values);
58 | }
59 |
60 | $values = array_map(function ($value) use ($section, $storeId) {
61 | $record = array(
62 | 'objectID' => $value,
63 | 'value' => $value,
64 | );
65 |
66 | $transport = new Varien_Object($record);
67 | Mage::dispatchEvent('algolia_additional_section_item_index_before', array('section' => $section, 'record' => $transport, 'store_id' => $storeId)); // Only for backward compatibility
68 | Mage::dispatchEvent('algolia_additional_section_items_before_index', array('section' => $section, 'record' => $transport, 'store_id' => $storeId));
69 | $record = $transport->getData();
70 |
71 | return $record;
72 | }, $values);
73 |
74 | return $values;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Helper/Entity/Pagehelper.php:
--------------------------------------------------------------------------------
1 | array('unordered(slug)', 'unordered(name)', 'unordered(content)'),
14 | 'attributesToSnippet' => array('content:7'),
15 | );
16 |
17 | $transport = new Varien_Object($indexSettings);
18 | Mage::dispatchEvent('algolia_pages_index_before_set_settings', array('store_id' => $storeId, 'index_settings' => $transport));
19 | $indexSettings = $transport->getData();
20 |
21 | return $indexSettings;
22 | }
23 |
24 | public function getPages($storeId, $pageIds = null)
25 | {
26 | /** @var Mage_Cms_Model_Resource_Page_Collection $pages */
27 | $pageCollection = Mage::getModel('cms/page')->getCollection()
28 | ->addStoreFilter($storeId)
29 | ->addFieldToFilter('is_active', 1);
30 |
31 | if ($pageIds && count($pageIds) > 0) {
32 | $pageCollection->addFieldToFilter('page_id', array('in' => $pageIds));
33 | }
34 |
35 | Mage::dispatchEvent('algolia_after_pages_collection_build', array('store' => $storeId, 'collection' => $pageCollection));
36 |
37 | $excludedPages = array_values($this->config->getExcludedPages());
38 | foreach ($excludedPages as &$excludedPage) {
39 | $excludedPage = $excludedPage['pages'];
40 | }
41 |
42 | $pages = array();
43 | /** @var Mage_Cms_Model_Page $page */
44 | foreach ($pageCollection as $page) {
45 | if (in_array($page->getIdentifier(), $excludedPages)) {
46 | continue;
47 | }
48 |
49 | $pageObject = array();
50 |
51 | $pageObject['slug'] = $page->getIdentifier();
52 | $pageObject['name'] = $page->getTitle();
53 |
54 | $content = $page->getContent();
55 | if ($this->config->getRenderTemplateDirectives()) {
56 | /** @var Mage_Cms_Helper_Data $cms_helper */
57 | $cms_helper = Mage::helper('cms');
58 | $tmplProc = $cms_helper->getPageTemplateProcessor();
59 | $content = $tmplProc->filter($content);
60 | }
61 |
62 | /** @var Mage_Cms_Helper_Page $cmsPageHelper */
63 | $cmsPageHelper = Mage::helper('cms/page');
64 |
65 | $pageObject['objectID'] = $page->getId();
66 | $pageObject['url'] = $cmsPageHelper->getPageUrl($page->getId());
67 | $pageObject['content'] = $this->strip($content, array('script', 'style'));
68 |
69 | $transport = new Varien_Object($pageObject);
70 | Mage::dispatchEvent('algolia_after_create_page_object', array('page' => $transport, 'pageObject' => $page));
71 | $pageObject = $transport->getData();
72 |
73 | $pages[] = $pageObject;
74 | }
75 |
76 | return $pages;
77 | }
78 |
79 | public function shouldIndexPages($storeId)
80 | {
81 | $autocompleteSections = $this->config->getAutocompleteSections($storeId);
82 |
83 | foreach ($autocompleteSections as $section) {
84 | if ($section['name'] === 'pages') {
85 | return true;
86 | }
87 | }
88 |
89 | return false;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Helper/Image.php:
--------------------------------------------------------------------------------
1 | _getModel();
11 |
12 | if ($this->getImageFile()) {
13 | $model->setBaseFile($this->getImageFile());
14 | } else {
15 | $model->setBaseFile($this->getProduct()->getData($model->getDestinationSubdir()));
16 | }
17 |
18 | if ($model->isCached()) {
19 | return $this->removeProtocol($model->getUrl());
20 | }
21 |
22 | if ($this->_scheduleRotate) {
23 | $model->rotate($this->getAngle());
24 | }
25 |
26 | if ($this->_scheduleResize) {
27 | $model->resize();
28 | }
29 |
30 | if ($this->getWatermark()) {
31 | $model->setWatermark($this->getWatermark());
32 | }
33 |
34 | return $this->removeProtocol($model->saveFile()->getUrl());
35 | }
36 |
37 | public function removeProtocol($url)
38 | {
39 | return str_replace(array('https://', 'http://'), '//', $url);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Helper/Logger.php:
--------------------------------------------------------------------------------
1 | config = Mage::helper('algoliasearch/config');
15 | $this->enabled = $this->config->isLoggingEnabled();
16 |
17 | /** @var Mage_Core_Model_Store $store */
18 | foreach (Mage::app()->getStores() as $store) {
19 | $this->stores[$store->getId()] = $store->getName();
20 | }
21 | }
22 |
23 | public function isEnable()
24 | {
25 | return $this->enabled;
26 | }
27 |
28 | public function getStoreName($storeId)
29 | {
30 | if ($storeId === null) {
31 | return 'undefined store';
32 | }
33 |
34 | if (array_key_exists($storeId, $this->stores)) {
35 | return $storeId . ' (' . $this->stores[$storeId] . ')';
36 | }
37 |
38 | return $storeId;
39 | }
40 |
41 | public function start($action)
42 | {
43 | if ($this->enabled == false) {
44 | return;
45 | }
46 |
47 | $this->log('');
48 | $this->log('');
49 | $this->log('>>>>> BEGIN '.$action);
50 | $this->timers[$action] = microtime(true);
51 | }
52 |
53 | public function stop($action)
54 | {
55 | if ($this->enabled == false) {
56 | return;
57 | }
58 |
59 | if (false === isset($this->timers[$action])) {
60 | throw new Exception('Algolia Logger => non existing action');
61 | }
62 |
63 | $this->log('<<<<< END '.$action.' ('.$this->formatTime($this->timers[$action], microtime(true)).')');
64 | }
65 |
66 | public function log($message, $forceLog = false)
67 | {
68 | if ($this->config->isLoggingEnabled() || $forceLog) {
69 | Mage::log($message, null, 'algolia.log');
70 | }
71 | }
72 |
73 | protected function formatTime($begin, $end)
74 | {
75 | return ($end - $begin).'sec';
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Helper/ProxyHelper.php:
--------------------------------------------------------------------------------
1 | configHelper = Mage::helper('algoliasearch/config');
22 | }
23 |
24 | /**
25 | * @param string $type
26 | *
27 | * @return string|array
28 | */
29 | public function getInfo($type)
30 | {
31 | $appId = $this->configHelper->getApplicationID();
32 | $apiKey = $this->configHelper->getAPIKey();
33 |
34 | $token = $appId . ':' . $apiKey;
35 | $token = base64_encode($token);
36 | $token = str_replace(array("\n", '='), '', $token);
37 |
38 | $params = array(
39 | 'appId' => $appId,
40 | 'token' => $token,
41 | );
42 |
43 | if ($type !== self::INFO_TYPE_EXTENSION_SUPPORT) {
44 | $params['type'] = $type;
45 | }
46 |
47 | $info = $this->postRequest($params, self::PROXY_URL_PARAM_GET_INFO);
48 |
49 | if ($info) {
50 | $info = json_decode($info, true);
51 | }
52 |
53 | return $info;
54 | }
55 |
56 | public function getClientConfigurationData()
57 | {
58 | if (!$this->allClientData) {
59 | $this->allClientData = $this->getInfo(self::INFO_TYPE_ALL);
60 | }
61 |
62 | return $this->allClientData;
63 | }
64 |
65 | /**
66 | * @param $data
67 | * @param $proxyMethod
68 | *
69 | * @return bool|string
70 | */
71 | private function postRequest($data, $proxyMethod)
72 | {
73 | $ch = curl_init();
74 |
75 | curl_setopt($ch, CURLOPT_URL, self::PROXY_URL . $proxyMethod);
76 | curl_setopt($ch, CURLOPT_POST, 1);
77 | curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
78 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
79 |
80 | $result = curl_exec($ch);
81 |
82 | curl_close($ch);
83 |
84 | return $result;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/Exception/IndexPendingException.php:
--------------------------------------------------------------------------------
1 | product = $product;
21 |
22 | return $this;
23 | }
24 |
25 | /**
26 | * Add related store ID.
27 | *
28 | * @param int $storeId
29 | *
30 | * @return $this
31 | */
32 | public function withStoreId($storeId)
33 | {
34 | $this->storeId = $storeId;
35 |
36 | return $this;
37 | }
38 |
39 | /**
40 | * Get related product.
41 | *
42 | * @return Mage_Catalog_Model_Product
43 | */
44 | public function getProduct()
45 | {
46 | return $this->product;
47 | }
48 |
49 | /**
50 | * Get related store ID.
51 | *
52 | * @return int
53 | */
54 | public function getStoreId()
55 | {
56 | return $this->storeId;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/Exception/ProductUnknownSkuException.php:
--------------------------------------------------------------------------------
1 | Configuration > Algolia Search > Queue configuration';
9 |
10 | public function __construct()
11 | {
12 | parent::__construct();
13 |
14 | $this->engine = Mage::getResourceModel('algoliasearch/engine');
15 | }
16 |
17 | /**
18 | * This function will update all the requested categories and their child
19 | * categories in Algolia. You can provide either a single category ID or an
20 | * array of category IDs. A category ID should be either a string or an
21 | * integer.
22 | *
23 | * @param array|string|int $updateCategoryIds
24 | */
25 | public function reindexSpecificCategories($updateCategoryIds)
26 | {
27 | $updateCategoryIds = (array) $updateCategoryIds;
28 |
29 | foreach ($updateCategoryIds as $id) {
30 | /** @var Mage_Catalog_Model_Category $categoryModel */
31 | $categoryModel = Mage::getModel('catalog/category');
32 | $categories = $categoryModel->getCategories($id);
33 |
34 | foreach ($categories as $category) {
35 | $updateCategoryIds[] = $category->getId();
36 | }
37 | }
38 |
39 | $this->engine->rebuildCategoryIndex(null, $updateCategoryIds);
40 | }
41 |
42 | /**
43 | * This function will update all the requested products and their parent
44 | * products in Algolia. You can provide either a single product ID or an
45 | * array of product IDs. A product ID should be either a string or an
46 | * integer.
47 | *
48 | * @param array|string|int $updateProductIds
49 | */
50 | public function reindexSpecificProducts($updateProductIds)
51 | {
52 | $updateProductIds = (array) $updateProductIds;
53 | $productIds = $updateProductIds;
54 |
55 | foreach ($updateProductIds as $updateProductId) {
56 | if (!$this->_isProductComposite($updateProductId)) {
57 | $parentIds = $this->_getResource()->getRelationsByChild($updateProductId);
58 |
59 | if (!empty($parentIds)) {
60 | $productIds = array_merge($productIds, $parentIds);
61 | }
62 | }
63 | }
64 |
65 | if (!empty($productIds)) {
66 | $this->engine->rebuildProductIndex(null, $productIds);
67 | }
68 | }
69 |
70 | /**
71 | * @return Mage_CatalogSearch_Model_Resource_Indexer_Fulltext
72 | */
73 | protected function _getResource()
74 | {
75 | return Mage::getResourceSingleton('catalogsearch/indexer_fulltext');
76 | }
77 |
78 | /**
79 | * Check whether a product is composite.
80 | *
81 | * @param int $productId
82 | *
83 | * @return bool
84 | */
85 | protected function _isProductComposite($productId)
86 | {
87 | /** @var Mage_Catalog_Model_Product $product */
88 | $product = Mage::getModel('catalog/product')->loadByAttribute('entity_id', $productId);
89 |
90 | if ($product === false) {
91 | return false;
92 | }
93 |
94 | return $product->isComposite();
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/Indexer/Algoliaadditionalsections.php:
--------------------------------------------------------------------------------
1 | engine = new Algolia_Algoliasearch_Model_Resource_Engine();
18 | $this->config = Mage::helper('algoliasearch/config');
19 | }
20 |
21 | protected $_matchedEntities = array();
22 |
23 | protected function _getResource()
24 | {
25 | return Mage::getResourceSingleton('catalogsearch/indexer_fulltext');
26 | }
27 |
28 | public function getName()
29 | {
30 | return Mage::helper('algoliasearch')->__('Algolia Search Additional autocomplete sections');
31 | }
32 |
33 | public function getDescription()
34 | {
35 | /** @var Algolia_Algoliasearch_Helper_Data $helper */
36 | $helper = Mage::helper('algoliasearch');
37 | $decription = $helper->__('Rebuild additional sections.').' '.$helper->__($this->enableQueueMsg);
38 |
39 | return $decription;
40 | }
41 |
42 | public function matchEvent(Mage_Index_Model_Event $event)
43 | {
44 | return false;
45 | }
46 |
47 | protected function _registerEvent(Mage_Index_Model_Event $event)
48 | {
49 | return $this;
50 | }
51 |
52 | protected function _registerCatalogProductEvent(Mage_Index_Model_Event $event)
53 | {
54 | return $this;
55 | }
56 |
57 | protected function _registerCatalogCategoryEvent(Mage_Index_Model_Event $event)
58 | {
59 | return $this;
60 | }
61 |
62 | protected function _processEvent(Mage_Index_Model_Event $event)
63 | {
64 | }
65 |
66 | /**
67 | * Rebuild all index data.
68 | */
69 | public function reindexAll()
70 | {
71 | if ($this->config->isModuleOutputEnabled() === false) {
72 | return $this;
73 | }
74 |
75 | if (!$this->config->getApplicationID() || !$this->config->getAPIKey() || !$this->config->getSearchOnlyAPIKey()) {
76 | /** @var Mage_Adminhtml_Model_Session $session */
77 | $session = Mage::getSingleton('adminhtml/session');
78 | $session->addError('Algolia reindexing failed: You need to configure your Algolia credentials in System > Configuration > Algolia Search.');
79 |
80 | return $this;
81 | }
82 |
83 | $this->engine->rebuildAdditionalSections();
84 |
85 | return $this;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/Indexer/Algoliadeleteproducts.php:
--------------------------------------------------------------------------------
1 | engine = new Algolia_Algoliasearch_Model_Resource_Engine();
16 | $this->config = Mage::helper('algoliasearch/config');
17 | }
18 |
19 | public function getName()
20 | {
21 | return Mage::helper('algoliasearch')->__('Algolia Search - Remove inactive products from Algolia');
22 | }
23 |
24 | public function getDescription()
25 | {
26 | /** @var Algolia_Algoliasearch_Helper_Data $helper */
27 | $helper = Mage::helper('algoliasearch');
28 | $decription = $helper->__('Run this indexer only when you want to remove inactive / deleted products from Algolia.');
29 |
30 | return $decription;
31 | }
32 |
33 | public function matchEvent(Mage_Index_Model_Event $event)
34 | {
35 | return false;
36 | }
37 |
38 | protected function _registerEvent(Mage_Index_Model_Event $event)
39 | {
40 | return $this;
41 | }
42 |
43 | protected function _registerCatalogProductEvent(Mage_Index_Model_Event $event)
44 | {
45 | return $this;
46 | }
47 |
48 | protected function _registerCatalogCategoryEvent(Mage_Index_Model_Event $event)
49 | {
50 | return $this;
51 | }
52 |
53 | protected function _processEvent(Mage_Index_Model_Event $event)
54 | {
55 | }
56 |
57 | /**
58 | * Rebuild all index data.
59 | */
60 | public function reindexAll()
61 | {
62 | if ($this->config->isModuleOutputEnabled() === false) {
63 | return $this;
64 | }
65 |
66 | if (!$this->config->getApplicationID() || !$this->config->getAPIKey() || !$this->config->getSearchOnlyAPIKey()) {
67 | /** @var Mage_Adminhtml_Model_Session $session */
68 | $session = Mage::getSingleton('adminhtml/session');
69 | $session->addError('Algolia reindexing failed: You need to configure your Algolia credentials in System > Configuration > Algolia Search.');
70 |
71 | return $this;
72 | }
73 |
74 | $this->engine->deleteInactiveProducts();
75 |
76 | return $this;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/Indexer/Algoliapages.php:
--------------------------------------------------------------------------------
1 | engine = new Algolia_Algoliasearch_Model_Resource_Engine();
18 | $this->config = Mage::helper('algoliasearch/config');
19 | }
20 |
21 | protected $_matchedEntities = array();
22 |
23 | protected function _getResource()
24 | {
25 | return Mage::getResourceSingleton('catalogsearch/indexer_fulltext');
26 | }
27 |
28 | public function getName()
29 | {
30 | return Mage::helper('algoliasearch')->__('Algolia Search Pages');
31 | }
32 |
33 | public function getDescription()
34 | {
35 | /** @var Algolia_Algoliasearch_Helper_Data $helper */
36 | $helper = Mage::helper('algoliasearch');
37 | $decription = $helper->__('Rebuild pages.').' '.$helper->__($this->enableQueueMsg);
38 |
39 | return $decription;
40 | }
41 |
42 | public function matchEvent(Mage_Index_Model_Event $event)
43 | {
44 | return false;
45 | }
46 |
47 | protected function _registerEvent(Mage_Index_Model_Event $event)
48 | {
49 | return $this;
50 | }
51 |
52 | protected function _registerCatalogProductEvent(Mage_Index_Model_Event $event)
53 | {
54 | return $this;
55 | }
56 |
57 | protected function _registerCatalogCategoryEvent(Mage_Index_Model_Event $event)
58 | {
59 | return $this;
60 | }
61 |
62 | protected function _processEvent(Mage_Index_Model_Event $event)
63 | {
64 | }
65 |
66 | /**
67 | * Rebuild all index data.
68 | */
69 | public function reindexAll()
70 | {
71 | if ($this->config->isModuleOutputEnabled() === false) {
72 | return $this;
73 | }
74 |
75 | if (!$this->config->getApplicationID() || !$this->config->getAPIKey() || !$this->config->getSearchOnlyAPIKey()) {
76 | /** @var Mage_Adminhtml_Model_Session $session */
77 | $session = Mage::getSingleton('adminhtml/session');
78 | $session->addError('Algolia reindexing failed: You need to configure your Algolia credentials in System > Configuration > Algolia Search.');
79 |
80 | return $this;
81 | }
82 |
83 | $this->engine->rebuildPages();
84 |
85 | return $this;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/Indexer/Algoliaqueuerunner.php:
--------------------------------------------------------------------------------
1 | config = Mage::helper('algoliasearch/config');
18 | $this->queue = Mage::getSingleton('algoliasearch/queue');
19 | }
20 |
21 | protected $_matchedEntities = array();
22 |
23 | protected function _getResource()
24 | {
25 | return Mage::getResourceSingleton('catalogsearch/indexer_fulltext');
26 | }
27 |
28 | public function getName()
29 | {
30 | return Mage::helper('algoliasearch')->__('Algolia Search Queue Runner');
31 | }
32 |
33 | public function getDescription()
34 | {
35 | return Mage::helper('algoliasearch')->__('Process the queue if enabled. This allow to run jobs in the queue');
36 | }
37 |
38 | public function matchEvent(Mage_Index_Model_Event $event)
39 | {
40 | return false;
41 | }
42 |
43 | protected function _registerEvent(Mage_Index_Model_Event $event)
44 | {
45 | return $this;
46 | }
47 |
48 | protected function _registerCatalogProductEvent(Mage_Index_Model_Event $event)
49 | {
50 | return $this;
51 | }
52 |
53 | protected function _registerCatalogCategoryEvent(Mage_Index_Model_Event $event)
54 | {
55 | return $this;
56 | }
57 |
58 | protected function _processEvent(Mage_Index_Model_Event $event)
59 | {
60 | }
61 |
62 | /**
63 | * Rebuild all index data.
64 | */
65 | public function reindexAll()
66 | {
67 | if (!$this->config->getApplicationID() || !$this->config->getAPIKey() || !$this->config->getSearchOnlyAPIKey()) {
68 | /** @var Mage_Adminhtml_Model_Session $session */
69 | $session = Mage::getSingleton('adminhtml/session');
70 | $session->addError('Algolia reindexing failed: You need to configure your Algolia credentials in System > Configuration > Algolia Search.');
71 |
72 | return $this;
73 | }
74 |
75 | $this->queue->runCron();
76 |
77 | return $this;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/Indexer/Algoliasuggestions.php:
--------------------------------------------------------------------------------
1 | engine = new Algolia_Algoliasearch_Model_Resource_Engine();
18 | $this->config = Mage::helper('algoliasearch/config');
19 | }
20 |
21 | protected $_matchedEntities = array();
22 |
23 | protected function _getResource()
24 | {
25 | return Mage::getResourceSingleton('catalogsearch/indexer_fulltext');
26 | }
27 |
28 | public function getName()
29 | {
30 | return Mage::helper('algoliasearch')->__('Algolia Search Suggestions');
31 | }
32 |
33 | public function getDescription()
34 | {
35 | /** @var Algolia_Algoliasearch_Helper_Data $helper */
36 | $helper = Mage::helper('algoliasearch');
37 | $decription = $helper->__('Rebuild suggestions.').' '.$helper->__($this->enableQueueMsg);
38 |
39 | return $decription;
40 | }
41 |
42 | public function matchEvent(Mage_Index_Model_Event $event)
43 | {
44 | $result = false;
45 |
46 | $event->addNewData(self::EVENT_MATCH_RESULT_KEY, $result);
47 |
48 | return $result;
49 | }
50 |
51 | protected function _registerEvent(Mage_Index_Model_Event $event)
52 | {
53 | return $this;
54 | }
55 |
56 | protected function _registerCatalogProductEvent(Mage_Index_Model_Event $event)
57 | {
58 | return $this;
59 | }
60 |
61 | protected function _registerCatalogCategoryEvent(Mage_Index_Model_Event $event)
62 | {
63 | return $this;
64 | }
65 |
66 | protected function _processEvent(Mage_Index_Model_Event $event)
67 | {
68 | }
69 |
70 | /**
71 | * Rebuild all index data.
72 | */
73 | public function reindexAll()
74 | {
75 | if ($this->config->isModuleOutputEnabled() === false) {
76 | return $this;
77 | }
78 |
79 | if (!$this->config->getApplicationID() || !$this->config->getAPIKey() || !$this->config->getSearchOnlyAPIKey()) {
80 | /** @var Mage_Adminhtml_Model_Session $session */
81 | $session = Mage::getSingleton('adminhtml/session');
82 | $session->addError('Algolia reindexing failed: You need to configure your Algolia credentials in System > Configuration > Algolia Search.');
83 |
84 | return $this;
85 | }
86 |
87 | $this->engine->rebuildSuggestions();
88 |
89 | return $this;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/Job.php:
--------------------------------------------------------------------------------
1 | _init('algoliasearch/job');
17 | }
18 |
19 | /**
20 | * @return string
21 | */
22 | public function getStatus()
23 | {
24 | $status = Algolia_Algoliasearch_Model_Source_JobStatuses::STATUS_PROCESSING;
25 |
26 | if (is_null($this->getPid())) {
27 | $status = Algolia_Algoliasearch_Model_Source_JobStatuses::STATUS_NEW;
28 | }
29 |
30 | if ((int) $this->getRetries() >= $this->getMaxRetries()) {
31 | $status = Algolia_Algoliasearch_Model_Source_JobStatuses::STATUS_ERROR;
32 | }
33 |
34 | return $status;
35 | }
36 |
37 | /**
38 | * @return string
39 | */
40 | public function getStatusLabel()
41 | {
42 | $status = $this->getStatus();
43 | $labels = Mage::getModel('algoliasearch/source_jobStatuses')->getStatuses();
44 |
45 | return isset($labels[$status]) ? $labels[$status] : $status;
46 | }
47 |
48 | /**
49 | * @param Exception $e
50 | *
51 | * @return Algolia_Algoliasearch_Model_Job
52 | */
53 | public function saveError(Exception $e)
54 | {
55 | $this->setErrorLog($e->getMessage());
56 | $this->save($this);
57 |
58 | return $this;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/Observer/Conversion.php:
--------------------------------------------------------------------------------
1 | isClickConversionAnalyticsEnabled($storeId)
18 | && Mage::helper('algoliasearch/config')->getConversionAnalyticsMode($storeId) === 'place_order';
19 | }
20 |
21 | /**
22 | * @param array $params
23 | * @return bool
24 | */
25 | protected function _hasRequiredParameters($params = array())
26 | {
27 | foreach ($this->_analyticsParams as $requiredParam) {
28 | if (!isset($params[$requiredParam])) {
29 | return false;
30 | }
31 | }
32 |
33 | return true;
34 | }
35 |
36 | /**
37 | * @event catalog_controller_product_init_before
38 | */
39 | public function setAlgoliaParamsToSession(Varien_Event_Observer $observer)
40 | {
41 | $checkoutSession = Mage::getSingleton('checkout/session');
42 | if (!$this->_isOrderConversionTrackingEnabled($checkoutSession->getQuote()->getStoreId())) {
43 | return;
44 | }
45 |
46 | /** @var Mage_Core_Controller_Front_Action $controllerAction */
47 | $controllerAction = $observer->getEvent()->getControllerAction();
48 | $params = $controllerAction->getRequest()->getParams();
49 |
50 | if (!$this->_hasRequiredParameters($params)) {
51 | return;
52 | }
53 |
54 | $conversionData = array(
55 | 'queryID' => $params['queryID'],
56 | 'indexName' => $params['indexName'],
57 | 'objectID' => $params['objectID'],
58 | );
59 |
60 | $session = Mage::getSingleton('core/session', array('name' => 'frontend'));
61 | $session->setData('algolia_conversion_parameters', Mage::helper('core')->jsonEncode($conversionData));
62 | }
63 |
64 | /**
65 | * @event checkout_cart_product_add_after
66 | */
67 | public function saveAlgoliaParamToQuoteItem(Varien_Event_Observer $observer)
68 | {
69 | /** @var Mage_Sales_Model_Quote_Item $quoteItem */
70 | $quoteItem = $observer->getEvent()->getQuoteItem();
71 | /** @var Mage_Catalog_Model_Product $product */
72 | $product = $observer->getEvent()->getProduct();
73 |
74 | if ($this->_isOrderConversionTrackingEnabled($product->getStoreId())) {
75 | $session = Mage::getSingleton('core/session');
76 | $quoteItem->setData('algoliasearch_query_param', $session->getData('algolia_conversion_parameters'));
77 | $session->unsetData('algolia_conversion_parameters');
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/Resource/Fulltext.php:
--------------------------------------------------------------------------------
1 | engine = new Algolia_Algoliasearch_Model_Resource_Engine();
19 | $this->config = Mage::helper('algoliasearch/config');
20 | $this->logger = Mage::helper('algoliasearch/logger');
21 | }
22 |
23 | public function prepareResult($object, $queryText, $query)
24 | {
25 | if (!$this->config->getApplicationID() || !$this->config->getAPIKey() || $this->config->isEnabledFrontEnd() === false) {
26 | return parent::prepareResult($object, $queryText, $query);
27 | }
28 |
29 | return $this;
30 | }
31 |
32 | protected function _saveProductIndexes($storeId, $productIndexes)
33 | {
34 | if ($this->config->isEnabledBackend($storeId) === false) {
35 | return parent::_saveProductIndexes($storeId, $productIndexes);
36 | }
37 |
38 | return $this;
39 | }
40 |
41 | /**
42 | * Only used when reindexing everything. Otherwise Model/Indexer/Algolia will take care of the rest.
43 | *
44 | * @param int|null $storeId
45 | * @param array|null $productIds
46 | *
47 | * @return $this|Mage_CatalogSearch_Model_Resource_Fulltext
48 | */
49 | public function rebuildIndex($storeId = null, $productIds = null)
50 | {
51 | if ($this->config->isModuleOutputEnabled() === false) {
52 | return parent::rebuildIndex($storeId, $productIds);
53 | }
54 |
55 | if ($storeId !== null) {
56 | $this->reindex($storeId, $productIds);
57 |
58 | return $this;
59 | }
60 |
61 | /** @var Mage_Core_Model_Store $store */
62 | foreach (Mage::app()->getStores() as $store) {
63 | $this->reindex($store->getId(), $productIds);
64 | }
65 |
66 | return $this;
67 | }
68 |
69 | private function reindex($storeId, $productIds)
70 | {
71 | if ($this->config->isEnabledBackend($storeId) === false) {
72 | return parent::rebuildIndex($storeId, $productIds);
73 | }
74 |
75 | return $this->reindexAlgolia($storeId, $productIds);
76 | }
77 |
78 | private function reindexAlgolia($storeId, $productIds)
79 | {
80 | if (!$this->config->getApplicationID($storeId) || !$this->config->getAPIKey($storeId) || !$this->config->getSearchOnlyAPIKey($storeId)) {
81 | /** @var Mage_Adminhtml_Model_Session $session */
82 | $session = Mage::getSingleton('adminhtml/session');
83 | $session->addError('Algolia reindexing failed: You need to configure your Algolia credentials in System > Configuration > Algolia Search.');
84 |
85 | return;
86 | }
87 |
88 | /* Avoid Indexing twice */
89 | if (is_array($productIds) && $productIds > 0) {
90 | return;
91 | }
92 |
93 | $this->engine->rebuildProducts($storeId);
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/Resource/Fulltext/Collection.php:
--------------------------------------------------------------------------------
1 | _helper()->isX3Version()) {
13 | return $this;
14 | }
15 |
16 | $query = $this->_getQuery();
17 | if (is_null($this->_foundData) && !empty($query) && $query instanceof Mage_CatalogSearch_Model_Query) {
18 | $data = $this->getAlgoliaData($query->getQueryText());
19 | if (false === $data) {
20 | return parent::getFoundIds();
21 | }
22 |
23 | $this->_foundData = $data;
24 | }
25 |
26 | return parent::getFoundIds();
27 | }
28 |
29 | /**
30 | * @return Algolia_Algoliasearch_Helper_Data
31 | */
32 | protected function _helper()
33 | {
34 | return Mage::helper('algoliasearch');
35 | }
36 |
37 | /**
38 | * @param string $query
39 | *
40 | * @return array|bool
41 | */
42 | protected function getAlgoliaData($query)
43 | {
44 | /** @var Algolia_Algoliasearch_Helper_Config $config */
45 | $config = Mage::helper('algoliasearch/config');
46 | $storeId = Mage::app()->getStore()->getId();
47 |
48 | if (!$config->getApplicationID() || !$config->getAPIKey() || $config->isEnabledFrontEnd($storeId) === false) {
49 | return false;
50 | }
51 |
52 | $data = array();
53 |
54 | if ($config->isInstantEnabled($storeId) === false || $config->makeSeoRequest($storeId)) {
55 | $algolia_query = $query !== '__empty__' ? $query : '';
56 |
57 | try {
58 | $data = $this->_helper()->getSearchResult($algolia_query, $storeId);
59 | } catch (\Exception $e) {
60 | /** @var Algolia_Algoliasearch_Helper_Logger $logger */
61 | $logger = Mage::helper('algoliasearch/logger');
62 |
63 | $logger->log($e->getMessage(), true);
64 | $logger->log($e->getTraceAsString(), true);
65 |
66 | return false;
67 | }
68 | }
69 |
70 | return $data;
71 | }
72 |
73 | /**
74 | * @param string $query
75 | *
76 | * @return Algolia_Algoliasearch_Model_Resource_Fulltext_Collection
77 | */
78 | public function addSearchFilter($query)
79 | {
80 | if ($this->_helper()->isX3Version()) {
81 | return $this;
82 | }
83 |
84 | $data = $this->getAlgoliaData($query);
85 | if (false === $data) {
86 | return parent::addSearchFilter($query);
87 | }
88 | $sortedIds = array_reverse(array_keys($data));
89 |
90 | $this->getSelect()->columns(array(
91 | 'relevance' => new Zend_Db_Expr("FIND_IN_SET(e.entity_id, '" . implode(',', $sortedIds) . "')"),
92 | ));
93 | $this->getSelect()->where('e.entity_id IN (?)', $sortedIds);
94 |
95 | return $this;
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/Resource/Job.php:
--------------------------------------------------------------------------------
1 | _init('algoliasearch/job', 'job_id');
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/Resource/Job/Collection.php:
--------------------------------------------------------------------------------
1 | _init('algoliasearch/job');
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/Source/JobMethods.php:
--------------------------------------------------------------------------------
1 | 'Save Settings',
7 | 'saveConfigurationToAlgolia' => 'Save Configuration',
8 | 'moveIndex' => 'Move Index',
9 | 'moveProductsTmpIndex' => 'Move Products Temp Index',
10 | 'deleteObjects' => 'Object Deletion',
11 | 'rebuildStoreCategoryIndex' => 'Store Category Reindex',
12 | 'rebuildCategoryIndex' => 'Category Reindex',
13 | 'rebuildStoreProductIndex' => 'Store Product Reindex',
14 | 'rebuildProductIndex' => 'Product Reindex',
15 | 'rebuildStoreAdditionalSectionsIndex' => 'Store Additional Section Reindex',
16 | 'rebuildAdditionalSectionsIndex' => 'Additional Section Reindex',
17 | 'rebuildStoreSuggestionIndex' => 'Store Suggestion Reindex',
18 | 'rebuildSuggestionIndex' => 'Sugesstion Reindex',
19 | 'rebuildStorePageIndex' => 'Store Page Reindex',
20 | 'rebuildPageIndex' => 'Page Reindex',
21 | );
22 |
23 | /**
24 | * @return array
25 | */
26 | public function getMethods()
27 | {
28 | return $this->_methods;
29 | }
30 |
31 | /**
32 | * @return array
33 | */
34 | public function toOptionArray()
35 | {
36 | $options = array();
37 | foreach ($this->_methods as $method => $label) {
38 | $option[] = array(
39 | 'value' => $method,
40 | 'label' => $label,
41 | );
42 | }
43 | return $options;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/Source/JobStatuses.php:
--------------------------------------------------------------------------------
1 | 'New',
12 | self::STATUS_ERROR => 'Error',
13 | self::STATUS_PROCESSING => 'Processing',
14 | self::STATUS_COMPLETE => 'Complete'
15 | );
16 |
17 | /**
18 | * @return array
19 | */
20 | public function getStatuses()
21 | {
22 | return $this->_statuses;
23 | }
24 |
25 | /**
26 | * @return array
27 | */
28 | public function toOptionArray()
29 | {
30 | $options = array();
31 | foreach ($this->_methods as $method => $label) {
32 | $option[] = array(
33 | 'value' => $method,
34 | 'label' => $label,
35 | );
36 | }
37 | return $options;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/System/BackendRenderingDisplayMode.php:
--------------------------------------------------------------------------------
1 | 'all', 'label' => Mage::helper('algoliasearch')->__('All categories')),
9 | array('value' => 'only_products', 'label' => Mage::helper('algoliasearch')->__('Categories without static blocks')),
10 | );
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/System/Config/Backend/EnableClickAnalytics.php:
--------------------------------------------------------------------------------
1 | getValue());
8 |
9 | if ($value !== '1') {
10 | return parent::_beforeSave();
11 | }
12 |
13 | $context = Mage::helper('algoliasearch/algoliahelper')->getClient()->getContext();
14 |
15 | $ch = curl_init();
16 |
17 | $headers = array();
18 | $headers[] = 'X-Algolia-Api-Key: '.$context->apiKey;
19 | $headers[] = 'X-Algolia-Application-Id: '.$context->applicationID;
20 | $headers[] = 'Content-Type: application/x-www-form-urlencoded';
21 | curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
22 |
23 | $postFields = json_encode(array(
24 | 'timestamp' => time(),
25 | 'queryID' => 'a',
26 | 'objectID' => 'non_existent_object_id',
27 | 'position' => 1,
28 | ));
29 |
30 | curl_setopt($ch, CURLOPT_URL, "https://insights.algolia.io/1/searches/click");
31 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
32 | curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
33 | curl_setopt($ch, CURLOPT_POST, 1);
34 |
35 | $result = curl_exec($ch);
36 | curl_close($ch);
37 |
38 | if ($result) {
39 | $result = json_decode($result);
40 | if ($result->status === 401 && $result->message === 'Feature not available') {
41 | Mage::throwException(
42 | Mage::helper('algoliasearch')->__('Click & Conversion analytics are not supported on your current plan. Please refer to Algolia\'s pricing page for more details.')
43 | );
44 | }
45 | }
46 |
47 | return parent::_beforeSave();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/System/Config/Backend/ExtraSettings.php:
--------------------------------------------------------------------------------
1 | getValue());
8 |
9 | if (empty($value)) {
10 | return parent::_beforeSave();
11 | }
12 |
13 | $fieldConfig = $this->getFieldConfig();
14 | $label = (string) $fieldConfig->label;
15 |
16 | json_decode($value);
17 | $error = json_last_error();
18 |
19 | if ($error) {
20 | Mage::throwException('JSON provided for "'.$label.'" field is not valid JSON.');
21 | }
22 |
23 | return parent::_beforeSave();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/System/Config/Backend/Serialized/Array.php:
--------------------------------------------------------------------------------
1 | isX3Version()) {
10 | if (!is_array($this->getValue())) {
11 | $value = $this->getValue();
12 | $this->setValue(empty($value) ? false : \Zend_Serializer::unserialize((string) $value));
13 | }
14 |
15 | return;
16 | }
17 |
18 | parent::_afterLoad();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/System/Config/Backend/SynonymsFile.php:
--------------------------------------------------------------------------------
1 | '1','label' => '1'),
9 | array('value' => '2','label' => '2'),
10 | array('value' => '3','label' => '3'),
11 | array('value' => '5','label' => '5'),
12 | array('value' => '10','label' => '10'),
13 | array('value' => '20','label' => '20'),
14 | array('value' => '50','label' => '50'),
15 | array('value' => '100','label' => '100'),
16 | array('value' => '9999999','label' => 'unlimited')
17 | );
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/System/ConversionAnalyticsMode.php:
--------------------------------------------------------------------------------
1 | 'disabled', 'label' => Mage::helper('algoliasearch')->__('[Disabled]')),
11 | array('value' => 'add_to_cart', 'label' => Mage::helper('algoliasearch')->__('Track "Add to cart" action as conversion')),
12 | array('value' => 'place_order', 'label' => Mage::helper('algoliasearch')->__('Track "Place Order" action as conversion')),
13 | );
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/System/Imagetype.php:
--------------------------------------------------------------------------------
1 | 'image', 'label' => Mage::helper('core')->__('Base Image')),
11 | array('value' => 'small_image', 'label' => Mage::helper('core')->__('Small Image')),
12 | array('value' => 'thumbnail', 'label' => Mage::helper('core')->__('Thumbnail')),
13 | );
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/System/IndexVisibility.php:
--------------------------------------------------------------------------------
1 | 'all', 'label' => Mage::helper('algoliasearch')->__('All visible products')),
13 | array('value' => 'only_search', 'label' => Mage::helper('algoliasearch')->__('Only products visible in Search')),
14 | array('value' => 'only_catalog', 'label' => Mage::helper('algoliasearch')->__('Only products visible in Catalog')),
15 | );
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/Model/System/Removewords.php:
--------------------------------------------------------------------------------
1 | 'none', 'label' => Mage::helper('algoliasearch')->__('None')),
11 | array('value' => 'allOptional', 'label' => Mage::helper('algoliasearch')->__('AllOptional')),
12 | array('value' => 'lastWords', 'label' => Mage::helper('algoliasearch')->__('LastWords')),
13 | array('value' => 'firstWords', 'label' => Mage::helper('algoliasearch')->__('FirstWords')),
14 | );
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/bin/dump.php:
--------------------------------------------------------------------------------
1 | setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
6 |
7 | @unlink(Mage::getBaseDir('var') . DIRECTORY_SEPARATOR . 'log' . DIRECTORY_SEPARATOR . 'algolia_dump.log');
8 |
9 | /** @var Algolia_Algoliasearch_Helper_Config $config */
10 | $config = Mage::helper('algoliasearch/config');
11 | $configReflection = new ReflectionClass(get_class($config));
12 |
13 | $allMethods = $configReflection->getMethods(ReflectionMethod::IS_PUBLIC);
14 |
15 | $configMethods = array();
16 | foreach ($allMethods as $method) {
17 | if ($method->getDeclaringClass()->getName() == get_class($config)) {
18 | $parameters = $method->getParameters();
19 | $firstParamter = reset($parameters);
20 | if ($method->getNumberOfParameters() === 1 && $firstParamter->getName() === 'storeId') {
21 | $configMethods[] = $method->getName();
22 | }
23 | }
24 | }
25 |
26 | /** @var Mage_Core_Model_Resource $coreResource */
27 | $coreResource = Mage::getSingleton('core/resource');
28 | $db = $coreResource->getConnection('core_read');
29 |
30 | $configTableName = $coreResource->getTableName('core/config_data');
31 |
32 | $configRows = $db->query('SELECT path FROM '.$configTableName.' WHERE path LIKE "algolia%"')->fetchAll();
33 |
34 | /** @var Mage_Core_Model_Store $store */
35 | foreach (Mage::app()->getStores() as $store) {
36 | $storeId = $store->getId();
37 |
38 | algolia_dump_log('-- Dump config for store ID '.$storeId.' --');
39 |
40 | algolia_dump_log('-- Computed values --');
41 | foreach ($configMethods as $configMethod) {
42 | $result = $config->{$configMethod}($storeId);
43 | algolia_dump_log('$config->'.$configMethod.'('.$storeId.') === '.var_export($result, true));
44 | }
45 |
46 | algolia_dump_log('-- Raw values --');
47 | foreach ($configRows as $row) {
48 | algolia_dump_log($row['path'].' === '.var_export(Mage::getStoreConfig($row['path'], $storeId), true));
49 | }
50 | }
51 |
52 | echo "Dump file was successfully created.\n";
53 |
54 | function algolia_dump_log($message)
55 | {
56 | Mage::log($message, null, 'algolia_dump.log', true);
57 | }
58 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/controllers/Adminhtml/Algoliasearch/IndexingqueueController.php:
--------------------------------------------------------------------------------
1 | _checkQueueIsActivated();
13 | return parent::preDispatch();
14 | }
15 |
16 | public function indexAction()
17 | {
18 | $this->_title($this->__('System'))
19 | ->_title($this->__('Algolia Search'))
20 | ->_title($this->__('Indexing Queue'));
21 |
22 | $this->loadLayout();
23 | $this->_setActiveMenu('system/algolia/indexing_queue');
24 | $this->renderLayout();
25 | }
26 |
27 | public function viewAction()
28 | {
29 | $this->_title($this->__('System'))
30 | ->_title($this->__('Algolia Search'))
31 | ->_title($this->__('Indexing Queue'));
32 |
33 | $id = $this->getRequest()->getParam('id');
34 | if (!$id) {
35 | Mage::getSingleton('adminhtml/session')->addError(
36 | Mage::helper('algoliasearch')->__('Indexing Queue Job ID is not set.'));
37 | $this->_redirect('*/*/');
38 | return;
39 | }
40 |
41 | $job = Mage::getModel('algoliasearch/job')->load($id);
42 | if (!$job->getId()) {
43 | Mage::getSingleton('adminhtml/session')->addError(
44 | Mage::helper('algoliasearch')->__('This indexing queue job no longer exists.'));
45 | $this->_redirect('*/*/');
46 | return;
47 | }
48 |
49 | Mage::register('algoliasearch_current_job', $job);
50 |
51 | $this->loadLayout();
52 | $this->_setActiveMenu('system/algolia/indexing_queue');
53 | $this->renderLayout();
54 | }
55 |
56 | public function clearAction()
57 | {
58 | try {
59 | /** @var Algolia_Algoliasearch_Model_Queue $queue */
60 | $queue = Mage::getModel('algoliasearch/queue');
61 | $queue->clearQueue(true);
62 |
63 | Mage::getSingleton('adminhtml/session')->addSuccess('Indexing Queue has been cleared.');
64 | } catch (Exception $e) {
65 | Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
66 | }
67 |
68 | $this->_redirect('*/*/');
69 | }
70 |
71 | public function resetAction()
72 | {
73 | try {
74 | $queueRunnerIndexer = Mage::getModel('index/indexer')
75 | ->getProcessByCode(Algolia_Algoliasearch_Model_Indexer_Algoliaqueuerunner::INDEXER_ID);
76 | $queueRunnerIndexer->setStatus(Mage_Index_Model_Process::STATUS_PENDING);
77 | $queueRunnerIndexer->save();
78 |
79 | Mage::getSingleton('adminhtml/session')->addSuccess('Indexing Queue has been reset.');
80 | } catch (Exception $e) {
81 | Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
82 | }
83 |
84 | $this->_redirect('*/*/');
85 | }
86 |
87 | protected function _checkQueueIsActivated()
88 | {
89 | if (!Mage::helper('algoliasearch/config')->isQueueActive()) {
90 | Mage::getSingleton('adminhtml/session')->addWarning(
91 | $this->__('The indexing queue is not enabled. Please activate it in your Algolia configuration .',
92 | $this->getUrl('adminhtml/system_config/edit/section/algoliasearch')));
93 | }
94 | }
95 |
96 | /**
97 | * Check ACL permissions.
98 | *
99 | * @return bool
100 | */
101 | protected function _isAllowed()
102 | {
103 | return Mage::getSingleton('admin/session')->isAllowed('system/algoliasearch/indexing_queue');
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/controllers/Adminhtml/Algoliasearch/QueueController.php:
--------------------------------------------------------------------------------
1 | getTableName('algoliasearch/queue');
18 |
19 | $readConnection = $resource->getConnection('core_read');
20 |
21 | $size = (int) $readConnection->query('SELECT COUNT(*) as total_count FROM '.$tableName)->fetchColumn(0);
22 | $maxJobsPerSingleRun = $config->getNumberOfJobToRun();
23 |
24 | $etaMinutes = ceil($size / $maxJobsPerSingleRun) * 5; // 5 - assuming the queue runner runs every 5 minutes
25 |
26 | $eta = $etaMinutes . ' minutes';
27 | if ($etaMinutes > 60) {
28 | $hours = floor($etaMinutes / 60);
29 | $restMinutes = $etaMinutes % 60;
30 |
31 | $eta = $hours . ' hours ' . $restMinutes . ' minutes';
32 | }
33 |
34 | $queueInfo = array(
35 | 'isEnabled' => $config->isQueueActive(),
36 | 'currentSize' => $size,
37 | 'eta' => $eta,
38 | );
39 |
40 | $this->sendResponse($queueInfo);
41 | }
42 |
43 | public function truncateAction()
44 | {
45 | try {
46 | /** @var Algolia_Algoliasearch_Model_Queue $queue */
47 | $queue = Mage::getModel('algoliasearch/queue');
48 | $queue->clearQueue(true);
49 |
50 | $status = array('status' => 'ok');
51 | } catch (\Exception $e) {
52 | $status = array('status' => 'ko', 'message' => $e->getMessage());
53 | }
54 |
55 | $this->sendResponse($status);
56 | }
57 |
58 | private function sendResponse($data)
59 | {
60 | $this->getResponse()->setHeader('Content-Type', 'application/json');
61 | $this->getResponse()->setBody(json_encode($data));
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/etc/adminhtml.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Algolia Search
8 | 93
9 |
10 |
11 | Configurations
12 | adminhtml/system_config/edit/section/algoliasearch
13 | 0
14 |
15 |
16 | Indexing Queue
17 | adminhtml/algoliasearch_indexingqueue
18 | 10
19 |
20 |
21 | Reindex SKU(s)
22 | adminhtml/algoliasearch_reindexsku
23 | 20
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | Algolia Search Configuration
40 | 100
41 |
42 |
43 |
44 |
45 | Algolia Search
46 |
47 |
48 | Indexing Queue
49 | 100
50 |
51 |
52 | Reindex SKU(s)
53 | 110
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/sql/algoliasearch_setup/mysql4-install-0.1.0.php:
--------------------------------------------------------------------------------
1 | startSetup();
7 |
8 | $installer->run("
9 | CREATE TABLE IF NOT EXISTS `{$installer->getTable('algoliasearch/queue')}` (
10 | `job_id` int(20) NOT NULL auto_increment,
11 | `pid` int(20) NULL,
12 | `class` varchar(50) NOT NULL,
13 | `method` varchar(50) NOT NULL,
14 | `data` varchar(5000) NOT NULL,
15 | `max_retries` int(11) NOT NULL DEFAULT 3,
16 | `retries` int(11) NOT NULL DEFAULT 0,
17 | `error_log` text NOT NULL DEFAULT '',
18 | PRIMARY KEY `job_id` (`job_id`)
19 | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8 AUTO_INCREMENT=1;
20 | ");
21 |
22 | $installer->endSetup();
23 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/sql/algoliasearch_setup/mysql4-upgrade-0.1.0-1.4.8.php:
--------------------------------------------------------------------------------
1 | startSetup();
7 |
8 | $table = Mage::getConfig()->getTablePrefix().'sales_flat_order_item';
9 | $installer->run("ALTER TABLE `{$table}` ADD INDEX `IDX_ALGOLIA_SALES_FLAT_ORDER_ITEM_PRODUCT_ID` (`product_id`);");
10 |
11 | $table = Mage::getConfig()->getTablePrefix().'review_entity_summary';
12 | $installer->run("ALTER TABLE `{$table}` ADD INDEX `IDX_ALGOLIA_REVIEW_ENTITY_SUMMARY_ENTITY_PK_VALUE_STORE_ID` (`store_id`, `entity_pk_value`);");
13 |
14 | $installer->endSetup();
15 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/sql/algoliasearch_setup/mysql4-upgrade-1.11.1-1.12.0.php:
--------------------------------------------------------------------------------
1 | startSetup();
9 |
10 | $tableName = $installer->getTable('algoliasearch/queue');
11 |
12 | $installer->getConnection()->addColumn($tableName, 'created', array(
13 | 'type' => Varien_Db_Ddl_Table::TYPE_DATETIME,
14 | 'after' => 'job_id',
15 | 'nullable' => true,
16 | 'comment' => 'Time of job creation',
17 | ));
18 |
19 | $installer->run("
20 | CREATE TABLE IF NOT EXISTS `{$tableName}_log` (
21 | `id` INT(20) NOT NULL auto_increment,
22 | `started` DATETIME NOT NULL,
23 | `duration` INT(20) NOT NULL,
24 | `processed_jobs` INT NOT NULL,
25 | `with_empty_queue` INT(1) NOT NULL,
26 | PRIMARY KEY `id` (`id`)
27 | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8 AUTO_INCREMENT=1;
28 | ");
29 |
30 | $installer->endSetup();
31 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/sql/algoliasearch_setup/mysql4-upgrade-1.14.1-1.15.0.php:
--------------------------------------------------------------------------------
1 | startSetup();
5 |
6 | $tableName = $installer->getTable('algoliasearch/queue_archive');
7 |
8 | $installer->run("
9 | CREATE TABLE IF NOT EXISTS `{$tableName}` (
10 | `pid` int(11) DEFAULT NULL COMMENT 'Pid',
11 | `class` varchar(50) NOT NULL COMMENT 'Class',
12 | `method` varchar(50) NOT NULL COMMENT 'Method',
13 | `data` text NOT NULL COMMENT 'Data',
14 | `error_log` text NOT NULL COMMENT 'Error Log',
15 | `data_size` int(11) DEFAULT NULL COMMENT 'Data Size',
16 | `created_at` datetime NOT NULL COMMENT 'Created At'
17 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
18 | ");
19 |
20 | $installer->endSetup();
21 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/sql/algoliasearch_setup/mysql4-upgrade-1.15.0-1.16.0.php:
--------------------------------------------------------------------------------
1 | startSetup();
5 |
6 | $tableName = $installer->getTable('algoliasearch/queue');
7 |
8 | $installer->getConnection()->addColumn($tableName, 'locked_at', array(
9 | 'type' => Varien_Db_Ddl_Table::TYPE_DATETIME,
10 | 'after' => 'job_id',
11 | 'nullable' => true,
12 | 'comment' => 'Time of job creation',
13 | ));
14 |
15 | $installer->endSetup();
16 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/sql/algoliasearch_setup/mysql4-upgrade-1.16.0-1.17.0.php:
--------------------------------------------------------------------------------
1 | startSetup();
5 |
6 | $setup = new Mage_Sales_Model_Resource_Setup('core_setup');
7 |
8 | $setup->addAttribute(
9 | 'quote_item',
10 | 'algoliasearch_query_param',
11 | array(
12 | 'type' => Varien_Db_Ddl_Table::TYPE_TEXT,
13 | 'grid' => false,
14 | 'comment' => 'AlgoliaSearch Conversion Query Parameters'
15 | )
16 | );
17 |
18 | $setup->addAttribute(
19 | 'order_item',
20 | 'algoliasearch_query_param',
21 | array(
22 | 'type' => Varien_Db_Ddl_Table::TYPE_TEXT,
23 | 'grid' => false,
24 | 'comment' => 'AlgoliaSearch Conversion Query Parameters'
25 | )
26 | );
27 |
28 | $installer->endSetup();
29 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/sql/algoliasearch_setup/mysql4-upgrade-1.4.8-1.5.0.php:
--------------------------------------------------------------------------------
1 | startSetup();
7 |
8 | /* Need a truncate since now everything is json_encoded and not serialized */
9 | $installer->run("TRUNCATE TABLE `{$installer->getTable('algoliasearch/queue')}`");
10 | $installer->run("ALTER TABLE `{$installer->getTable('algoliasearch/queue')}` ADD data_size INT(11);");
11 |
12 | $index_prefix = Mage::getConfig()->getTablePrefix();
13 | $installer->run('DELETE FROM `'.$index_prefix."core_config_data` WHERE `path` LIKE '%algolia%'");
14 |
15 | $installer->endSetup();
16 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/sql/algoliasearch_setup/mysql4-upgrade-1.5.5-1.6.0.php:
--------------------------------------------------------------------------------
1 | startSetup();
7 |
8 | // Need to transform "removeProducts" to "rebuildProductIndex" as re-indexing was refactored and "removeProducts" do not exists anymore
9 | $installer->run("DELETE FROM `{$installer->getTable('algoliasearch/queue')}`");
10 |
11 | $installer->endSetup();
12 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/sql/algoliasearch_setup/mysql4-upgrade-1.6.0-1.7.1.php:
--------------------------------------------------------------------------------
1 | startSetup();
6 |
7 | $tableName = Mage::getSingleton('core/resource')->getTableName('algoliasearch/queue');
8 |
9 | $installer->run('ALTER TABLE ' . $tableName . ' MODIFY data LONGTEXT NOT NULL');
10 |
11 | $installer->endSetup();
12 |
--------------------------------------------------------------------------------
/app/code/community/Algolia/Algoliasearch/sql/algoliasearch_setup/mysql4-upgrade-1.7.1-1.11.1.php:
--------------------------------------------------------------------------------
1 | startSetup();
6 |
7 | $tableName = $installer->getTable('algoliasearch/queue');
8 | $installer->run("ALTER TABLE `{$tableName}` ADD `created` DATETIME AFTER `job_id`;");
9 |
10 | $installer->run("
11 | CREATE TABLE IF NOT EXISTS `{$tableName}_log` (
12 | `id` INT(20) NOT NULL auto_increment,
13 | `started` DATETIME NOT NULL,
14 | `duration` INT(20) NOT NULL,
15 | `processed_jobs` INT NOT NULL,
16 | `with_empty_queue` INT(1) NOT NULL,
17 | PRIMARY KEY `id` (`id`)
18 | ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8 AUTO_INCREMENT=1;
19 | ");
20 |
21 | $installer->endSetup();
22 |
--------------------------------------------------------------------------------
/app/design/adminhtml/default/default/layout/algoliasearch.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | algoliasearch/algoliasearch.css
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
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 |
--------------------------------------------------------------------------------
/app/design/adminhtml/default/default/template/algoliasearch/adminjs.phtml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/design/adminhtml/default/default/template/algoliasearch/notifications.phtml:
--------------------------------------------------------------------------------
1 | getQueueInfo();
4 | ?>
5 |
6 |
7 |
Algolia Search -
8 |
9 |
10 | Indexing queue information:
11 |
12 |
13 | Number of queued jobs:
,
14 | all queued jobs will be processed in appr.
,
15 | more information about how the indexing queue works you can find in the documentation:
Indexing queue
16 |
17 |
18 | Indexing queue is not enabled.
19 |
20 |
21 | It's highly recommended to enable it, especially if you are on production environment. You can learn how to enable the index queue in the documentation:
Indexing queue
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/design/adminhtml/default/default/template/algoliasearch/queue/status.phtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | __('Status of the queue: %s ', $this->getQueueRunnerStatus()); ?>
6 | getLastQueueUpdate()): ?>
7 | __('Last update: %s ', $this->getLastQueueUpdate()); ?>
8 |
9 |
10 | getNotices() ?>
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/algoliasearch/autocomplete.phtml:
--------------------------------------------------------------------------------
1 | helper('catalogsearch');
8 |
9 | $placeholder = $this->__('Search for products, categories, ...');
10 |
11 | /** Render form with autocomplete input **/
12 | ?>
13 |
14 |
22 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/algoliasearch/autocomplete/attribute.phtml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/algoliasearch/autocomplete/category.phtml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/algoliasearch/autocomplete/menu.phtml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/algoliasearch/autocomplete/page.phtml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/algoliasearch/autocomplete/product.phtml:
--------------------------------------------------------------------------------
1 | getCustomerGroupId();
9 |
10 | $storeId = Mage::app()->getStore()->getStoreId();
11 | $currencyCode = Mage::app()->getStore()->getCurrentCurrencyCode();
12 |
13 | $priceKey = '.'.$currencyCode.'.default';
14 | if ($config->isCustomerGroupsEnabled($storeId)) {
15 | $priceKey = '.'.$currencyCode.'.group_'.$customerGroupId;
16 | }
17 |
18 | ?>
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/algoliasearch/autocomplete/suggestion.phtml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/algoliasearch/checkout/success/conversion.phtml:
--------------------------------------------------------------------------------
1 | getOrderItemsConversionJson();
4 | ?>
5 |
6 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/algoliasearch/instantsearch/currentRefinements.phtml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/algoliasearch/instantsearch/hit.phtml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/algoliasearch/instantsearch/refinementsItem.phtml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/algoliasearch/instantsearch/stats.phtml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/algoliasearch/internals/beforecontent.phtml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/etc/modules/Algolia_Algoliasearch.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | true
6 | community
7 | 1.19.0
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/locale/en_US/Algolia_Algoliasearch.csv:
--------------------------------------------------------------------------------
1 | "Algolia Search Products", "Algolia Search Products"
2 | "Rebuild products.", "Rebuild products."
3 | "Algolia Search Categories", "Algolia Search Categories"
4 | "Rebuild categories.", "Rebuild categories."
5 | "Algolia Search Pages", "Algolia Search Pages"
6 | "Rebuild pages.", "Rebuild pages."
7 | "Algolia Search Suggestions", "Algolia Search Suggestions"
8 | "Rebuild suggestions.", "Rebuild suggestions."
9 | "Rebuild additional sections.", "Rebuild additional sections."
10 | "Please enable the queueing system to do it asynchronously (CRON) if you have a lot of products in System > Configuration > Algolia Search > Queue configuration", "Please enable the queueing system to do it asynchronously (CRON) if you have a lot of products in System > Configuration > Algolia Search > Queue configuration"
11 | "Algolia Search Queue Runner", "Algolia Search Queue Runner"
12 | "Process the queue if enabled. This allow to run jobs in the queue", "Process the queue if enabled. This allow to run jobs in the queue"
13 | "Section", "Section"
14 | "Label", "Label"
15 | "Hits per page", "Hits per page"
16 | "Add Section", "Add Section"
17 | "Attribute", "Attribute"
18 | "Searchable", "Searchable"
19 | "Retrievable", "Retrievable"
20 | "Ordered", "Ordered"
21 | "Add Attribute", "Add Attribute"
22 | "Asc / Desc", "Asc / Desc"
23 | "Add Ranking Criterion", "Add Ranking Criterion"
24 | "Facet type", "Facet type"
25 | "Add Facet", "Add Facet"
26 | "Sort", "Sort"
27 | "Add Sorting Attribute", "Add Sorting Attribute"
28 | "Pages", "Pages"
29 | "Add Excluded Page", "Add Excluded Page"
30 | "Search by", "Search by"
31 | "Search for products, categories, ...", "Search for products, categories, ..."
32 | "Search:", "Search:"
33 | "in", "in"
34 | "Categories", "Categories"
35 | "Products", "Products"
36 | "Refine", "Refine"
37 | "Current search", "Current search"
38 | "Search for products", "Search for products"
39 | "SORT BY", "SORT BY"
40 | "Add to Cart", "Add to Cart"
41 | "result found", "result found"
42 | "results found", "results found"
43 | "out of", "out of"
44 | "seconds", "seconds"
45 | "Relevance", "Relevance"
46 | "No products for query", "No products for query"
47 | "You can try one of the popular search queries", "You can try one of the popular search queries"
48 | "or", "or"
49 | "See all products", "See all products"
50 | "Selected Filters", "Selected Filters"
51 | "Clear all", "Clear all"
52 | "Previous page", "Previous page"
53 | "Next page", "Next page"
54 | "to", "to"
55 | "Go", "Go"
56 | "No results", "No results"
57 | "All departments", "All departments"
58 | "See products in", "See products in"
59 | "or in", "or in"
60 | "Base Image", "Base Image"
61 | "Small Image", "Small Image"
62 | "Thumbnail", "Thumbnail"
63 | "None", "None"
64 | "AllOptional", "AllOptional"
65 | "LastWords", "LastWords"
66 | "FirstWords", "FirstWords"
67 | "Synonyms (comma-separated)", "Synonyms (comma-separated)"
68 | "Add Synonyms", "Add Synonyms"
69 | "Add One-way Synonyms", "Add One-way Synonyms"
70 | "Input", "Input"
71 | "Synonyms", "Synonyms"
72 | "One-way Synonyms", "One-way Synonyms"
73 | "Synonyms File", "Synonyms File"
74 | "Search for other ...","Search for other ..."
--------------------------------------------------------------------------------
/app/locale/nl_NL/Algolia_Algoliasearch.csv:
--------------------------------------------------------------------------------
1 | "Algolia Search Products", "Algolia Zoek Producten"
2 | "Rebuild products.", "Rebuild producten."
3 | "Algolia Search Categories", "Algolia Zoek Categorieën"
4 | "Rebuild categories.", "Rebuild categorieën."
5 | "Algolia Search Pages", "Algolia Zoek Pagina's"
6 | "Rebuild pages.", "Rebuild pagina's."
7 | "Algolia Search Suggestions", "Algolia Zoek Suggesties"
8 | "Rebuild suggestions.", "Rebuild suggesties."
9 | "Rebuild additional sections.", "Rebuild additionele secties."
10 | "Please enable the queueing system to do it asynchronously (CRON) if you have a lot of products in System > Configuration > Algolia Search > Queue configuration", "Schakel het queue systeem in om het asynchroon (CRON) te doen wanneer je veel producten hebt in Systeem > Configuratie > Algolia Zoeken > Queue configuratie"
11 | "Algolia Search Queue Runner", "Algolia Zoek Queue Runner"
12 | "Process the queue if enabled. This allow to run jobs in the queue", "Gaat alle queue processen af wanneer ingeschakeld."
13 | "Section", "Sectie"
14 | "Label", "Label"
15 | "Hits per page", "Resultaten per pagina"
16 | "Add Section", "Add Sectie"
17 | "Attribute", "Attribuut"
18 | "Searchable", "Doorzoekbaar"
19 | "Retrievable", "Op te halen"
20 | "Ordered", "Gerangschikt"
21 | "Add Attribute", "Attribuut toevoegen"
22 | "Asc / Desc", "Op- / aflopend"
23 | "Add Ranking Criterion", "Ranking criterium toevoegen"
24 | "Facet type", "Facet type"
25 | "Add Facet", "Facet toevoegen"
26 | "Sort", "Sorteren"
27 | "Add Sorting Attribute", "Sortering attribuut toevoegen"
28 | "Pages", "Pagina's"
29 | "Add Excluded Page", "Uitgeslote pagina's toevoegen"
30 | "Search by", "Zoeken op"
31 | "Search for products, categories, ...", "Zoek naar producten, categorieën, ..."
32 | "Search:", "Zoeken:"
33 | "in", "in"
34 | "Categories", "Categorieën"
35 | "Products", "Producten"
36 | "Refine", "Verfijnen"
37 | "Current search", "Huidige zoekopdracht"
38 | "Search for products", "Zoek naar producten"
39 | "SORT BY", "Sorteren op"
40 | "Add to Cart", "Toevoegen aan winkelwagen"
41 | "result found", "resultaat gevonden"
42 | "results found", "resultaten gevonden"
43 | "out of", "van de"
44 | "seconds", "seconden"
45 | "Relevance", "Relevantie"
46 | "No products for query", "Geen producten voor zoekopdracht"
47 | "You can try one of the popular search queries", "Probeer een van de populaire zoektermen"
48 | "or", "of"
49 | "See all products", "Bekijk alle producten"
50 | "Selected Filters", "Geselecteerde filters"
51 | "Clear all", "Wis alles"
52 | "Previous page", "Vorige pagina"
53 | "Next page", "Volgende pagina"
54 | "to", "naar"
55 | "Go", "Gaan"
56 | "No results", "Geen resultaten"
57 | "All departments", "Alle afdelingen"
58 | "See products in", "Toon producten in"
59 | "or in", "of in"
60 | "Base Image", "Standaard afbeelding"
61 | "Small Image", "Kleine afbeelding"
62 | "Thumbnail", "Miniatuur"
63 | "None", "Geen"
64 | "AllOptional", "Alle optioneel"
65 | "LastWords", "Laatste woorden"
66 | "FirstWords", "Eerste woorden"
67 | "Synonyms (comma-separated)", "Synoniemen (komma gescheiden)"
68 | "Add Synonyms", "Synoniem toevoegen"
69 | "Add One-way Synonyms", "One-way synoniem toevoegen"
70 | "Input", "Invoer"
71 | "Synonyms", "Synoniemen"
72 | "One-way Synonyms", "One-way synoniemen"
73 | "Synonyms File", "Synoniemen bestand"
--------------------------------------------------------------------------------
/app/locale/sv_SE/Algolia_Algoliasearch.csv:
--------------------------------------------------------------------------------
1 | "Algolia Search Products", "Algolia Sök Produkter"
2 | "Rebuild products.", "Bygg om produkter."
3 | "Algolia Search Categories", "Algolia Sök Kategorier"
4 | "Rebuild categories.", "Bygg om kategorier."
5 | "Algolia Search Pages", "Algolia Sök Sidor"
6 | "Rebuild pages.", "Bygg om sidor."
7 | "Algolia Search Suggestions", "Algolia Sök Förslag"
8 | "Rebuild suggestions.", "Bygg om förslag."
9 | "Rebuild additional sections.", "Bygg om extra sektioner."
10 | "Please enable the queueing system to do it asynchronously (CRON) if you have a lot of products in System > Configuration > Algolia Search > Queue configuration", "Vänligen aktivera kösystemet för att göra det asynkront (CRON) om du har en många produkter i System > Konfiguration > Algolia Sök > Queue configuration"
11 | "Algolia Search Queue Runner", "Algolia Search Queue Runner"
12 | "Process the queue if enabled. This allow to run jobs in the queue", "Bearbeta kön om den är aktiverad. Detta gör det möjligt att köra jobb i kön"
13 | "Section", "Sektion"
14 | "Label", "Etikett"
15 | "Hits per page", "Träffar per sida"
16 | "Add Section", "Lägg till Sektion"
17 | "Attribute", "Attribut"
18 | "Searchable", "Sökbar"
19 | "Retrievable", "Hämtbar"
20 | "Ordered", "Sorterad"
21 | "Add Attribute", "Lägg till Attribut"
22 | "Asc / Desc", "Stigande / Minskande"
23 | "Add Ranking Criterion", "Lägg till Ranking Kriterium"
24 | "Facet type", "Facet typ"
25 | "Add Facet", "Lägg till Facet"
26 | "Sort", "Sortera"
27 | "Add Sorting Attribute", "Lägg till Sorteringsattribut"
28 | "Pages", "Sidor"
29 | "Add Excluded Page", "Lägg till Utesluten Sida"
30 | "Search by", "Sök efter"
31 | "Search for products, categories, ...", "Sök efter produkter, kategorier, ..."
32 | "Search:", "Sök:"
33 | "in", "i"
34 | "Categories", "Kategorier"
35 | "Products", "Produkter"
36 | "Refine", "Finslipa"
37 | "Current search", "Nuvarande sökning"
38 | "Search for products", "Sök efter produkter"
39 | "SORT BY", "SORTERA EFTER"
40 | "Add to Cart", "Lägg i kundvagn"
41 | "result", "resultat"
42 | "results found", "resultat hittade"
43 | "seconds", "sekunder"
44 | "Relevance", "Relevans"
45 | "No products for query", "Inga produkter för frågan"
46 | "You can try one of the popular search queries", "Du kan prova en av de populära sökfrågorna"
47 | "or", "eller"
48 | "See all products", "Visa alla produkter"
49 | "Selected Filters", "Valda filter"
50 | "Clear all", "Rensa alla"
51 | "Previous page", "Föregående sida"
52 | "Next page", "Nästa sida"
53 | "to", "till"
54 | "Go", "Kör"
55 | "No results", "Inga resultat"
56 | "All departments", "Alla avdelningar"
57 | "See products in", "Visa produkter i"
58 | "or in", "eller i"
59 | "Base Image","Bild på produktsida"
60 | "Small Image","Bild i kategorivy"
61 | "Thumbnail","Bild i varukorg"
62 | "None", "Ingen"
63 | "AllOptional", "AllOptional"
64 | "LastWords", "LastWords"
65 | "FirstWords", "FirstWords"
66 | "Synonyms (comma-separated)", "Synonymer (comma-separerade)"
67 | "Add Synonyms", "Lägg till Synonymer"
68 | "Add One-way Synonyms", "Lägg till One-way Synonymer"
69 | "Input", "Input"
70 | "Synonyms", "Synonymer"
71 | "One-way Synonyms", "One-way Synonymer"
72 | "Synonyms File", "Fil för Synonymer"
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "algolia/algoliasearch-magento",
3 | "type": "magento-module",
4 | "license": "MIT",
5 | "homepage": "https://github.com/algolia/algoliasearch-magento",
6 | "description": "Algolia Search for Magento",
7 | "require": {
8 | "magento-hackathon/magento-composer-installer": "*"
9 | },
10 | "require-dev": {
11 | "phpunit/phpunit": "^6.0"
12 | },
13 | "extra": {
14 | "magento-root-dir": "/var/www/htdocs"
15 | },
16 | "autoload": {
17 | "psr-4": {
18 | "": "tests/"
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/dev/Dockerfile.base:
--------------------------------------------------------------------------------
1 | FROM occitech/magento:php7.0-apache
2 |
3 | # packages/dependencies installation
4 | RUN apt-get update && apt-get install -y \
5 | mysql-server \
6 | libxml2-dev \
7 | git-core \
8 | wget
9 |
10 | RUN docker-php-ext-install soap
11 | RUN docker-php-ext-install mysqli
12 |
13 | COPY bin/php.ini /usr/local/etc/php/php.ini
14 |
15 | RUN sed -i -e 's/\/var\/www\/html/\/var\/www\/htdocs/' /etc/apache2/sites-enabled/000-default.conf
16 |
17 | ## download & install Magento
18 | ARG MAGENTO_VERSION
19 |
20 | RUN cd /tmp && curl -O https://demos-cdn.algolia.com/magento/archive/magento-$MAGENTO_VERSION.tar.gz && tar xf magento-$MAGENTO_VERSION.tar.gz && mv magento/* magento/.htaccess /var/www/htdocs
21 | COPY ./bin/install-magento /usr/local/bin/install-magento
22 | RUN chmod +x /usr/local/bin/install-magento
23 |
24 | ## sample dataset import
25 | RUN cd /tmp && curl -O https://demos-cdn.algolia.com/magento/archive/magento-sample-data-1.9.0.0.tar.gz && tar xf magento-sample-data-1.9.0.0.tar.gz
26 | RUN cd /var/www/htdocs/media && cp -R /tmp/magento-sample-data-1.9.0.0/media/* . && chmod -R 777 /var/www/htdocs/media
27 | RUN cd /var/www/htdocs/skin && cp -R /tmp/magento-sample-data-1.9.0.0/skin/* .
28 | RUN chown -R www-data:www-data /var/www/htdocs
29 |
30 | ## database setup
31 | RUN service mysql start && \
32 | mysql -u root -e "CREATE DATABASE magento;"
33 |
34 | RUN service mysql start && \
35 | mysql -u root -e "CREATE USER 'magento'@'localhost' IDENTIFIED BY 'P4ssw0rd'; GRANT ALL PRIVILEGES ON *.* TO 'magento'@'localhost'; FLUSH PRIVILEGES;"
36 |
37 | RUN service mysql start && \
38 | mysql -u root magento < /tmp/magento-sample-data-1.9.0.0/magento_sample_data_for_1.9.0.0.sql
39 |
40 | RUN service mysql start && \
41 | MYSQL_HOST=127.0.0.1 MYSQL_USER=magento MYSQL_PASSWORD=P4ssw0rd MYSQL_DATABASE=magento MAGENTO_LOCALE=en_US MAGENTO_TIMEZONE=Europe/Paris MAGENTO_DEFAULT_CURRENCY=USD MAGENTO_URL=http://mymagentostore.com MAGENTO_ADMIN_FIRSTNAME=Admin MAGENTO_ADMIN_LASTNAME=MyStore MAGENTO_ADMIN_EMAIL=amdin@mymagentostore.com MAGENTO_ADMIN_USERNAME=admin MAGENTO_ADMIN_PASSWORD=magentorocks1 /usr/local/bin/install-magento
42 |
43 | ## configure Magento
44 | RUN service mysql start && \
45 | n98-magerun --skip-root-check --root-dir=/var/www/htdocs cache:flush && \
46 | n98-magerun --skip-root-check --root-dir=/var/www/htdocs cache:disable && \
47 | n98-magerun --skip-root-check --root-dir=/var/www/htdocs config:set dev/template/allow_symlink "1" >/dev/null 2>&1 && \
48 | n98-magerun --skip-root-check --root-dir=/var/www/htdocs admin:notifications >/dev/null 2>&1 && \
49 | n98-magerun --skip-root-check --root-dir=/var/www/htdocs config:set admin/security/use_form_key "0" >/dev/null 2>&1
50 |
51 | # algoliasearch-magento setup
52 | RUN cd /tmp && curl -s -L -O https://raw.github.com/colinmollenhour/modman/master/modman-installer && chmod +x modman-installer && ./modman-installer
53 | RUN cd /var/www/htdocs && /root/bin/modman init && /root/bin/modman clone https://github.com/algolia/algoliasearch-magento && rm -rf .modman/algoliasearch-magento
54 | RUN cd /var/www/htdocs && /root/bin/modman clone https://github.com/algolia/algoliasearch-magento-extend-module-skeleton && rm -rf .modman/algoliasearch-magento-extend-module-skeleton
55 |
56 | # release config file
57 | COPY ./bin/algoliasearch.xml /var/www/htdocs/var/connect/algoliasearch.xml
58 | COPY ./bin/makeRelease.php /var/www/htdocs/makeRelease.php
59 |
60 | #path admin template to have credentials filled && auto login
61 | RUN sed -i 's/name="login\[username\]" value=""/name="login[username]" value="admin"/g' /var/www/htdocs/app/design/adminhtml/default/default/template/login.phtml && \
62 | sed -i 's/name="login\[password\]" class="required-entry input-text" value=""/name="login[password]" class="required-entry input-text" value="magentorocks1"/g' /var/www/htdocs/app/design/adminhtml/default/default/template/login.phtml && \
63 | sed -i 's/<\/script>/Event.observe(window, "load", function() {$("loginForm").submit();});<\/script>/g' /var/www/htdocs/app/design/adminhtml/default/default/template/login.phtml && \
64 | sed -i "s/#ini_set('display_errors', 1);/ini_set('display_errors', 1);error_reporting(E_ALL);Mage::setIsDeveloperMode(true);/g" /var/www/htdocs/index.php && \
65 | sed -i "s/\$out .= \$this->getBlock(\$callback\[0\])->\$callback\[1\]()/\$out .= \$this->getBlock(\$callback\[0\])->{\$callback\[1\]}()/g" /var/www/htdocs/app/code/core/Mage/Core/Model/Layout.php
66 |
--------------------------------------------------------------------------------
/dev/Dockerfile.dev:
--------------------------------------------------------------------------------
1 | FROM algolia/base-algoliasearch-magento
2 |
3 | # packages/dependencies installation
4 | RUN apt-get update && apt-get install -y \
5 | vim emacs-nox \
6 | zsh
7 |
8 | RUN chsh -s /bin/zsh
9 | RUN sh -x -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh | grep -v 'set -e')"
10 | COPY bin/.zshrc /root/.zshrc
11 |
12 | ARG INSTALL_XDEBUG
13 | RUN if [ $INSTALL_XDEBUG = Yes ]; then pecl install xdebug && docker-php-ext-enable xdebug; fi
14 |
15 | RUN cd /tmp && curl -O https://phpmyadmin-downloads-532693.c.cdn77.org/phpMyAdmin/4.4.9/phpMyAdmin-4.4.9-english.tar.gz && tar xf phpMyAdmin-4.4.9-english.tar.gz && mv phpMyAdmin-4.4.9-english /var/www/htdocs/phpmyadmin
16 | COPY bin/config.inc.php /var/www/htdocs/phpmyadmin/
17 |
18 | # start script
19 | COPY ./bin/start.sh /usr/local/bin/start.sh
20 | RUN chmod +x /usr/local/bin/start.sh
21 |
22 | # GO
23 | EXPOSE 80
24 | CMD start.sh
25 |
--------------------------------------------------------------------------------
/dev/Dockerfile.test:
--------------------------------------------------------------------------------
1 | FROM algolia/base-algoliasearch-magento
2 |
3 | ARG INSTALL_XDEBUG
4 | RUN if [ $INSTALL_XDEBUG = Yes ]; then pecl install xdebug && docker-php-ext-enable xdebug; fi
5 |
6 | # test script
7 | COPY ./bin/test.sh /usr/local/bin/test.sh
8 | RUN chmod +x /usr/local/bin/test.sh
9 |
10 | # GO
11 | ENTRYPOINT test.sh
12 |
--------------------------------------------------------------------------------
/dev/bin/.zshrc:
--------------------------------------------------------------------------------
1 | # Path to your oh-my-zsh installation.
2 | export ZSH=$HOME/.oh-my-zsh
3 |
4 | # Set name of the theme to load.
5 | # Look in ~/.oh-my-zsh/themes/
6 | # Optionally, if you set this to "random", it'll load a random theme each
7 | # time that oh-my-zsh is loaded.
8 | ZSH_THEME="robbyrussell"
9 |
10 | # Example aliases
11 | # alias zshconfig="mate ~/.zshrc"
12 | # alias ohmyzsh="mate ~/.oh-my-zsh"
13 |
14 | # Uncomment the following line to use case-sensitive completion.
15 | # CASE_SENSITIVE="true"
16 |
17 | # Uncomment the following line to disable bi-weekly auto-update checks.
18 | # DISABLE_AUTO_UPDATE="true"
19 |
20 | # Uncomment the following line to change how often to auto-update (in days).
21 | # export UPDATE_ZSH_DAYS=13
22 |
23 | # Uncomment the following line to disable colors in ls.
24 | # DISABLE_LS_COLORS="true"
25 |
26 | # Uncomment the following line to disable auto-setting terminal title.
27 | # DISABLE_AUTO_TITLE="true"
28 |
29 | # Uncomment the following line to disable command auto-correction.
30 | # DISABLE_CORRECTION="true"
31 |
32 | # Uncomment the following line to display red dots whilst waiting for completion.
33 | # COMPLETION_WAITING_DOTS="true"
34 |
35 | # Uncomment the following line if you want to disable marking untracked files
36 | # under VCS as dirty. This makes repository status check for large repositories
37 | # much, much faster.
38 | # DISABLE_UNTRACKED_FILES_DIRTY="true"
39 |
40 | # Uncomment the following line if you want to change the command execution time
41 | # stamp shown in the history command output.
42 | # The optional three formats: "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
43 | # HIST_STAMPS="mm/dd/yyyy"
44 |
45 | # Would you like to use another custom folder than $ZSH/custom?
46 | # ZSH_CUSTOM=/path/to/new-custom-folder
47 |
48 | # Which plugins would you like to load? (plugins can be found in ~/.oh-my-zsh/plugins/*)
49 | # Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/
50 | # Example format: plugins=(rails git textmate ruby lighthouse)
51 | plugins=(git, laravel4)
52 |
53 | source /root/.oh-my-zsh/oh-my-zsh.sh
54 |
55 | # User configuration
56 |
57 | export PATH="/opt/local/bin:/opt/local/sbin:/opt/local/bin:/opt/local/sbin:/opt/local/bin:/opt/lampp/bin:/home/maxiloc/usr/bin:/bin:/usr/local/bin:/usr/bin:/usr/sbin:/sbin"
58 | # export MANPATH="/usr/local/man:$MANPATH"
59 |
60 | # You may need to manually set your language environment
61 | # export LANG=en_US.UTF-8
62 |
63 | # Preferred editor for local and remote sessions
64 | # if [[ -n $SSH_CONNECTION ]]; then
65 | # export EDITOR='vim'
66 | # else
67 | # export EDITOR='mvim'
68 | # fi
69 |
70 | # Compilation flags
71 | # export ARCHFLAGS="-arch x86_64"
72 |
73 | # ssh
74 | # export SSH_KEY_PATH="~/.ssh/dsa_id"
75 |
76 | PS1='`echo "\e[0;33m┌─\e[0;36m[DOCKER MAGENTO]\e[0;35m[%*]\e[0;37m[%?]\e[0;37m[%~]\e[0;33m
77 | └─>docker:~$ ";`'
78 |
79 | alias ll='ls -alF'
80 | alias la='ls -A'
81 | alias l='ls -CF'
82 | alias wp='wp --allow-root'
--------------------------------------------------------------------------------
/dev/bin/config.inc.php:
--------------------------------------------------------------------------------
1 | loadLocalPackage('algoliasearch');
17 | $data['version'] = $config->getExtensionVersion();
18 |
19 | $model->setData($data);
20 |
21 | if ($model->createPackage()) {
22 | echo 'Release package was successfully created.';
23 | exit(0);
24 | }
25 |
26 | echo 'Release package could not be created.';
27 | exit(1);
28 |
--------------------------------------------------------------------------------
/dev/bin/start.sh:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 |
3 | # start services
4 | find /var/lib/mysql -type f -exec touch {} \; && service mysql start
5 | service apache2 start
6 |
7 | # GET / to initialize the algolia_search_indexer (Open to another cleaner way to do it :) )
8 | if [ $EXPOSED_PORT == 80 ]; then
9 | wget --max-redirect 0 $BASE_URL
10 | else
11 | wget --max-redirect 0 0.0.0.0
12 | fi
13 |
14 | # set configuration variables & volumes
15 | cd /var/www/htdocs
16 |
17 | n98-magerun --skip-root-check --root-dir=/var/www/htdocs config:set algoliasearch/credentials/application_id $APPLICATION_ID
18 | n98-magerun --skip-root-check --root-dir=/var/www/htdocs config:set algoliasearch/credentials/search_only_api_key $SEARCH_ONLY_API_KEY
19 | n98-magerun --skip-root-check --root-dir=/var/www/htdocs config:set --encrypt algoliasearch/credentials/api_key $API_KEY
20 | n98-magerun --skip-root-check --root-dir=/var/www/htdocs config:set algoliasearch/credentials/index_prefix $INDEX_PREFIX
21 | n98-magerun --skip-root-check --root-dir=/var/www/htdocs config:set algoliasearch/credentials/is_instant_enabled "1"
22 | n98-magerun --skip-root-check --root-dir=/var/www/htdocs config:set web/unsecure/base_url $BASE_URL
23 | n98-magerun --skip-root-check --root-dir=/var/www/htdocs config:set web/secure/base_url $BASE_URL
24 |
25 | if [ $INSTALL_ALGOLIA == Yes ]; then
26 | /root/bin/modman deploy-all
27 |
28 | # reindex whole index
29 | n98-magerun --skip-root-check --root-dir=/var/www/htdocs index:reindex algolia_search_indexer
30 | n98-magerun --skip-root-check --root-dir=/var/www/htdocs index:reindex algolia_search_indexer_cat
31 | n98-magerun --skip-root-check --root-dir=/var/www/htdocs index:reindex algolia_search_indexer_pages
32 | n98-magerun --skip-root-check --root-dir=/var/www/htdocs index:reindex search_indexer_suggest
33 | else
34 | /root/bin/modman undeploy algoliasearch-magento
35 | /root/bin/modman undeploy algoliasearch-magento-extend-module-skeleton
36 | fi
37 |
38 | chmod -R 777 /var/www/htdocs/media
39 | chown -R www-data:www-data /var/www/htdocs/media
40 |
41 | # do it after indexing so that var/log doesn't get created as root
42 | n98-magerun --skip-root-check --root-dir=/var/www/htdocs config:set dev/log/active 1
43 |
44 | if [ $MAKE_RELEASE == Yes ]; then
45 | php makeRelease.php
46 | fi
47 |
48 | service apache2 stop
49 | exec /usr/sbin/apache2ctl -D FOREGROUND
--------------------------------------------------------------------------------
/dev/bin/test.sh:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 |
3 | # Start services
4 | echo -e "\e[93m-- Starting Apache and MySQL services --\e[0m"
5 | find /var/lib/mysql -type f -exec touch {} \; && service mysql start
6 | service apache2 start
7 |
8 | if [ "$TRAVIS" == true ]; then
9 | echo -e "\n\e[93m-- Setting the correct rights to Magento files --\e[0m"
10 | chmod -R 777 /var/www/htdocs
11 | chown -R www-data:www-data /var/www/htdocs
12 | fi
13 |
14 | # GET / to initialize Magento - required before test runs
15 | echo -e "\n\e[93m-- Fetching the Magento homepage to initialize Magento --\e[0m"
16 | wget --max-redirect 0 0.0.0.0
17 |
18 | # Apache is not needed for tests
19 | echo -e "\e[93m-- Stopping the Apache server (not needed for the tests) --\e[0m"
20 | service apache2 stop
21 |
22 | chmod -R 777 /var/www/htdocs/media
23 | chown -R www-data:www-data /var/www/htdocs/media
24 |
25 | # Repair Modman simlinks
26 | # echo -e "\n\e[93m-- Force repairing the Modman symlinks --\e[0m"
27 | # cd /var/www/htdocs
28 | # /root/bin/modman repair --force algoliasearch-magento
29 |
30 | # Again in case root created some folder with root:root
31 | chmod -R 777 /var/www/htdocs/media
32 | chown -R www-data:www-data /var/www/htdocs/media
33 |
34 | # Run tests
35 | echo -e "\n\e[93m-- Running the tests --\e[0m"
36 | cd /var/www/htdocs/.modman/algoliasearch-magento
37 |
38 | if [ $FILTER ]; then
39 | vendor/bin/phpunit tests --filter "$FILTER"
40 | else
41 | vendor/bin/phpunit tests
42 | fi
--------------------------------------------------------------------------------
/doc/auto-complete.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/algolia/algoliasearch-magento/b4781de31b5e41bc574b59d1b161fd2a067660a6/doc/auto-complete.gif
--------------------------------------------------------------------------------
/doc/instant-search.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/algolia/algoliasearch-magento/b4781de31b5e41bc574b59d1b161fd2a067660a6/doc/instant-search.gif
--------------------------------------------------------------------------------
/js/algoliasearch/click_conversion_analytics.js:
--------------------------------------------------------------------------------
1 | algoliaBundle.$(function ($) {
2 | AlgoliaAnalytics.init({
3 | appId: algoliaConfig.applicationId,
4 | apiKey: algoliaConfig.instant.apiKey
5 | });
6 |
7 | // "Click" in autocomplete
8 | $(algoliaConfig.autocomplete.selector).each(function () {
9 | $(this).on('autocomplete:selected', function (e, suggestion, dataset) {
10 |
11 | var sources = analyticsHelper.sources;
12 | var source = sources.filter(function(src) {
13 | return src.name == dataset;
14 | });
15 |
16 | if (source.length > 0) {
17 | var source = source[0];
18 | trackClick(source.indexName, suggestion.objectID, suggestion.__position, suggestion.__queryID);
19 | }
20 | });
21 | });
22 |
23 | // "Click" on instant search page
24 | $(document).on('click', algoliaConfig.ccAnalytics.ISSelector, function() {
25 | var $this = $(this);
26 | var lastResults = analyticsHelper.getLastResults();
27 |
28 | // want to track results returned
29 | if (lastResults) {
30 | trackClick(lastResults.index, $this.data('objectid'), $this.data('position'), $this.data('queryid'));
31 | }
32 | });
33 |
34 | // "Add to cart" conversion
35 | if (algoliaConfig.ccAnalytics.conversionAnalyticsMode === 'add_to_cart') {
36 | function getQueryParamFromCurrentUrl(queryParamName) {
37 | var url = window.location.href;
38 | var regex = new RegExp('[?&]' + queryParamName + '(=([^]*)|&|#|$)');
39 | var results = regex.exec(url);
40 | if (!results || !results[2]) return '';
41 | return results[2];
42 | }
43 |
44 | $(document).on('click', algoliaConfig.ccAnalytics.addToCartSelector, function () {
45 | var objectId = $(this).data('objectid') || getQueryParamFromCurrentUrl('objectID');
46 | var queryId = $(this).data('queryid') || getQueryParamFromCurrentUrl('queryID');
47 | var index = algoliaConfig.indexName + "_products" || getQueryParamFromCurrentUrl('index');
48 |
49 | trackConversion(index, objectId, queryId);
50 | });
51 | }
52 |
53 | if (algoliaConfig.ccAnalytics.conversionAnalyticsMode === 'place_order') {
54 |
55 | if (typeof algoliaOrderConversionJson !== 'undefined') {
56 | $.each(algoliaOrderConversionJson, function(idx, itemData) {
57 | if (itemData && itemData.objectID) {
58 | trackConversion(itemData.indexName, itemData.objectID, itemData.queryID);
59 | }
60 | });
61 | }
62 | }
63 |
64 | });
65 |
66 | var analyticsHelper = {};
67 |
68 | algolia.registerHook('beforeAutocompleteSources', function(sources) {
69 | analyticsHelper.sources = sources;
70 | return sources;
71 | });
72 |
73 | algolia.registerHook('beforeInstantsearchStart', function (search) {
74 | search.once('render', function() {
75 | analyticsHelper.getLastResults = function () {
76 | return search.helper.lastResults;
77 | }
78 | });
79 | return search;
80 | });
81 |
82 | algolia.registerHook('beforeInstantsearchInit', function (instantsearchOptions) {
83 | instantsearchOptions.searchParameters['clickAnalytics'] = true;
84 | return instantsearchOptions;
85 | });
86 |
87 | function trackClick(index, objectID, position, queryId) {
88 | var clickData = {
89 | index: index,
90 | eventName: "Clicked item",
91 | objectIDs: [objectID.toString()],
92 | positions: [parseInt(position)],
93 | queryID: queryId
94 | };
95 |
96 | AlgoliaAnalytics.clickedObjectIDsAfterSearch(clickData);
97 | }
98 |
99 | function trackConversion(index, objectID, queryId) {
100 | AlgoliaAnalytics.convertedObjectIDsAfterSearch({
101 | index: index,
102 | eventName: "Conversion",
103 | objectIDs: [objectID.toString()],
104 | queryID: queryId,
105 | });
106 | }
107 |
--------------------------------------------------------------------------------
/js/algoliasearch/internals/frontend/Function.prototype.bind.js:
--------------------------------------------------------------------------------
1 | // Magento is using a very old prototype.js version with a poor Function.prototype.bind
2 | // forced overloading, we redefine it here so that our code works
3 | // ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
4 | Function.prototype.bind = function(oThis) {
5 | if (typeof this !== 'function') {
6 | // closest thing possible to the ECMAScript 5
7 | // internal IsCallable function
8 | throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
9 | }
10 |
11 | var aArgs = Array.prototype.slice.call(arguments, 1),
12 | fToBind = this,
13 | fNOP = function() {},
14 | fBound = function() {
15 | return fToBind.apply(this instanceof fNOP
16 | ? this
17 | : oThis,
18 | aArgs.concat(Array.prototype.slice.call(arguments)));
19 | };
20 |
21 | if (this.prototype) {
22 | // native functions don't have a prototype
23 | fNOP.prototype = this.prototype;
24 | }
25 | fBound.prototype = new fNOP();
26 |
27 | return fBound;
28 | };
29 |
--------------------------------------------------------------------------------
/lib/AlgoliaSearch/AlgoliaConnectionException.php:
--------------------------------------------------------------------------------
1 | client = $client;
15 | }
16 |
17 | public function getABTests($params = array())
18 | {
19 | $params += array('offset' => 0, 'limit' => 10);
20 |
21 | return $this->request('GET', '/2/abtests', $params);
22 | }
23 |
24 | public function getABTest($abTestID)
25 | {
26 | if (!$abTestID) {
27 | throw new AlgoliaException('Cannot retrieve ABTest because the abtestID is invalid.');
28 | }
29 |
30 | return $this->request('GET', sprintf('/2/abtests/%s', urlencode($abTestID)));
31 | }
32 |
33 | public function addABTest($abTest)
34 | {
35 | return $this->request(
36 | 'POST',
37 | '/2/abtests',
38 | array(),
39 | $abTest
40 | );
41 | }
42 |
43 | public function stopABTest($abTestID)
44 | {
45 | if (!$abTestID) {
46 | throw new AlgoliaException('Cannot retrieve ABTest because the abtestID is invalid.');
47 | }
48 |
49 | return $this->request('POST', sprintf('/2/abtests/%s/stop', urlencode($abTestID)));
50 | }
51 |
52 | public function deleteABTest($abTestID)
53 | {
54 | if (!$abTestID) {
55 | throw new AlgoliaException('Cannot retrieve ABTest because the abtestID is invalid.');
56 | }
57 |
58 | return $this->request('DELETE', sprintf('/2/abtests/%s', urlencode($abTestID)));
59 | }
60 |
61 | public function waitTask($indexName, $taskID, $timeBeforeRetry = 100, $requestHeaders = array())
62 | {
63 | $this->client->waitTask($indexName, $taskID, $timeBeforeRetry, $requestHeaders);
64 | }
65 |
66 | protected function request(
67 | $method,
68 | $path,
69 | $params = array(),
70 | $data = array()
71 | ) {
72 | return $this->client->request(
73 | $this->client->getContext(),
74 | $method,
75 | $path,
76 | $params,
77 | $data,
78 | array('analytics.algolia.com'),
79 | $this->client->getContext()->connectTimeout,
80 | $this->client->getContext()->readTimeout
81 | );
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/lib/AlgoliaSearch/FailingHostsCache.php:
--------------------------------------------------------------------------------
1 | ttl = (int) $ttl;
33 | }
34 |
35 |
36 | /**
37 | * @param string $host
38 | */
39 | public function addFailingHost($host)
40 | {
41 | if (! in_array($host, self::$failingHosts)) {
42 | // Keep a local cache of failed hosts in case the file based strategy doesn't work out.
43 | self::$failingHosts[] = $host;
44 |
45 | if (self::$timestamp === null) {
46 | self::$timestamp = time();
47 | }
48 | }
49 | }
50 |
51 | /**
52 | * Get failing hosts from cache. This method should also handle cache invalidation if required.
53 | * The TTL of the failed hosts cache should be 5mins.
54 | *
55 | * @return array
56 | */
57 | public function getFailingHosts()
58 | {
59 | if (self::$timestamp === null) {
60 | return self::$failingHosts;
61 | }
62 |
63 | $elapsed = time() - self::$timestamp;
64 | if ($elapsed > $this->ttl) {
65 | $this->flushFailingHostsCache();
66 | }
67 |
68 | return self::$failingHosts;
69 | }
70 |
71 | public function flushFailingHostsCache()
72 | {
73 | self::$failingHosts = array();
74 | self::$timestamp = null;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/lib/AlgoliaSearch/Iterators/RuleIterator.php:
--------------------------------------------------------------------------------
1 | response = $this->index->searchRules(array(
35 | 'hitsPerPage' => $this->hitsPerPage,
36 | 'page' => $this->getCurrentPage(),
37 | ));
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/lib/AlgoliaSearch/Iterators/SynonymIterator.php:
--------------------------------------------------------------------------------
1 | response = $this->index->searchSynonyms('', array(), $this->getCurrentPage(), $this->hitsPerPage);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib/AlgoliaSearch/Json.php:
--------------------------------------------------------------------------------
1 | context = $context;
49 | $this->client = $client;
50 | }
51 |
52 | /**
53 | * @param string $query
54 | * @param array|null $args
55 | *
56 | * @return mixed
57 | *
58 | * @throws AlgoliaException
59 | */
60 | public function search($query, $args = null)
61 | {
62 | if ($args === null) {
63 | $args = array();
64 | }
65 | $args['query'] = $query;
66 |
67 | return $this->client->request(
68 | $this->context,
69 | 'POST',
70 | '/1/places/query',
71 | array(),
72 | array('params' => $this->client->buildQuery($args)),
73 | $this->context->readHostsArray,
74 | $this->context->connectTimeout,
75 | $this->context->searchTimeout
76 | );
77 | }
78 |
79 | /**
80 | * @param mixed $objectID
81 | *
82 | * @return mixed
83 | *
84 | * @throws AlgoliaException
85 | */
86 | public function getObject($objectID)
87 | {
88 | return $this->client->request(
89 | $this->context,
90 | 'GET',
91 | '/1/places/' . urlencode($objectID),
92 | null,
93 | null,
94 | $this->context->readHostsArray,
95 | $this->context->connectTimeout,
96 | $this->context->searchTimeout
97 | );
98 | }
99 |
100 | /**
101 | * @param string $key
102 | * @param string $value
103 | */
104 | public function setExtraHeader($key, $value)
105 | {
106 | $this->context->setExtraHeader($key, $value);
107 | }
108 |
109 | /**
110 | * @return ClientContext
111 | */
112 | public function getContext()
113 | {
114 | return $this->context;
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/lib/AlgoliaSearch/SynonymType.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | tests/
6 |
7 |
8 |
9 |
10 | app/
11 |
12 | app/code/community/Algolia/Algoliasearch/Block/
13 | app/code/community/Algolia/Algoliasearch/Model/System/
14 | app/code/community/Algolia/Algoliasearch/sql/
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/skin/adminhtml/base/default/algoliasearch/algoliasearch.css:
--------------------------------------------------------------------------------
1 | .algoliasearch-queue-notification {
2 | background: #e9f3ff url(/skin/frontend/base/default/algoliasearch/algolia-admin-menu.svg) no-repeat 27px 5px;
3 | background-size: 16px 16px;
4 | border-color: #bee1ee;
5 | }
6 |
7 | .algoliasearch-head-icon {
8 | background: url(/skin/frontend/base/default/algoliasearch/algolia-admin-menu.svg) no-repeat;
9 | background-size: 16px 16px;
10 | }
11 |
12 | .algolia-notice {
13 | border: 1px solid #dfdfdf;
14 | background-position: 10px 10px;
15 | padding-left: 35px;
16 | padding-top: 10px;
17 | margin-bottom: 1rem;
18 | color: #333;
19 | font-size: 13px;
20 | }
21 |
22 | .algoliasearch-config-info {
23 | border: 1px solid #D6D6D6;
24 | padding: 16px 20px 15px 56px;
25 | margin: 7px 0;
26 | }
27 |
28 |
29 | .algoliasearch-config-info.icon-stars {
30 | background: 19px 13px url(/skin/frontend/base/default/algoliasearch/stars-icon.svg) no-repeat;
31 | }
--------------------------------------------------------------------------------
/skin/frontend/base/default/algoliasearch/algolia-admin-menu.svg:
--------------------------------------------------------------------------------
1 | algolia-mark-square Created with Sketch.
--------------------------------------------------------------------------------
/skin/frontend/base/default/algoliasearch/clear-cross.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/skin/frontend/base/default/algoliasearch/cross-circle.svg:
--------------------------------------------------------------------------------
1 | testvg
--------------------------------------------------------------------------------
/skin/frontend/base/default/algoliasearch/is-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/skin/frontend/base/default/algoliasearch/magnifying-glass.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/skin/frontend/base/default/algoliasearch/stars-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/tests/AbstractIndexingTestCase.php:
--------------------------------------------------------------------------------
1 | algoliaHelper = Mage::helper('algoliasearch/algoliahelper');
18 | }
19 |
20 | protected function processTest(Algolia_Algoliasearch_Model_Indexer_Abstract $indexer, $indexSuffix, $expectedNbHits, $expectedNbHitsFrench = null, $expectedNbHitsGerman = null)
21 | {
22 | $this->algoliaHelper->clearIndex($this->indexPrefix.'default_'.$indexSuffix);
23 | $this->algoliaHelper->clearIndex($this->indexPrefix.'french_'.$indexSuffix);
24 | $this->algoliaHelper->clearIndex($this->indexPrefix.'german_'.$indexSuffix);
25 |
26 | $indexer->reindexAll();
27 |
28 | $this->algoliaHelper->waitLastTask();
29 |
30 | $resultsDefault = $this->algoliaHelper->query($this->indexPrefix.'default_'.$indexSuffix, '', array());
31 | $resultsFrench = $this->algoliaHelper->query($this->indexPrefix.'french_'.$indexSuffix, '', array());
32 | $resultsGerman = $this->algoliaHelper->query($this->indexPrefix.'german_'.$indexSuffix, '', array());
33 |
34 | $expectedNbHitsFrench = $expectedNbHitsFrench ?: $expectedNbHits;
35 | $expectedNbHitsGerman = $expectedNbHitsGerman ?: $expectedNbHits;
36 |
37 | $this->assertEquals($expectedNbHits, $resultsDefault['nbHits']);
38 | $this->assertEquals($expectedNbHitsFrench, $resultsFrench['nbHits']);
39 | $this->assertEquals($expectedNbHitsGerman, $resultsGerman['nbHits']);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/tests/AbstractTestCase.php:
--------------------------------------------------------------------------------
1 | '0',
14 | );
15 |
16 | public function setUp()
17 | {
18 | /** @var Algolia_Algoliasearch_Helper_Config $config */
19 | $config = Mage::helper('algoliasearch/config');
20 | $this->indexPrefix = $config->getIndexPrefix();
21 |
22 | foreach ($this->defaultConfig as $name => $value) {
23 | setConfig($name, $value);
24 | }
25 |
26 | resetConfigs();
27 | }
28 | }
--------------------------------------------------------------------------------
/tests/CategoriesIndexingTest.php:
--------------------------------------------------------------------------------
1 | processTest($categoriesIndexer, 'categories', 25);
9 | }
10 |
11 | public function testDefaultIndexableAttributes()
12 | {
13 | setConfig('algoliasearch/categories/category_additional_attributes2', serialize(array()));
14 |
15 | $indexer = new Algolia_Algoliasearch_Model_Indexer_Algoliacategories();
16 | $indexer->reindexSpecificCategories(24);
17 |
18 | $this->algoliaHelper->waitLastTask();
19 |
20 | $results = $this->algoliaHelper->getObjects($this->indexPrefix.'default_categories', array('24'));
21 | $hit = reset($results['results']);
22 |
23 | $defaultAttributes = array(
24 | 'objectID',
25 | 'name',
26 | 'url',
27 | 'path',
28 | 'level',
29 | 'include_in_menu',
30 | '_tags',
31 | 'popularity',
32 | 'product_count',
33 | 'algoliaLastUpdateAtCET',
34 | );
35 |
36 | foreach ($defaultAttributes as $key => $attribute) {
37 | $this->assertTrue(isset($hit[$attribute]), 'Category attribute "'.$attribute.'" should be indexed but it is not"');
38 | unset($hit[$attribute]);
39 | }
40 |
41 | $extraAttributes = implode(', ', array_keys($hit));
42 | $this->assertTrue(empty($hit), 'Extra category attributes ('.$extraAttributes.') are indexed and should not be.');
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/tests/ProductsIndexingTest.php:
--------------------------------------------------------------------------------
1 | processTest($productIndexer, 'products', self::DEFAULT_PRODUCT_COUNT);
11 | }
12 |
13 | public function testProductsOnlySearchVisible()
14 | {
15 | setConfig('algoliasearch/products/index_visibility', 'only_search');
16 |
17 | $productIndexer = new Algolia_Algoliasearch_Model_Indexer_Algolia();
18 | $this->processTest($productIndexer, 'products', 85);
19 | }
20 |
21 | public function testProductsOnlyCatalogVisible()
22 | {
23 | setConfig('algoliasearch/products/index_visibility', 'only_catalog');
24 |
25 | $productIndexer = new Algolia_Algoliasearch_Model_Indexer_Algolia();
26 | $this->processTest($productIndexer, 'products', self::DEFAULT_PRODUCT_COUNT);
27 | }
28 |
29 | public function testProductsOnInStock()
30 | {
31 | $productIndexer = new Algolia_Algoliasearch_Model_Indexer_Algolia();
32 | $this->processTest($productIndexer, 'products', self::DEFAULT_PRODUCT_COUNT);
33 | }
34 |
35 | public function testProductsIncludingOutOfStock()
36 | {
37 | setConfig('cataloginventory/options/show_out_of_stock', '1');
38 |
39 | $productIndexer = new Algolia_Algoliasearch_Model_Indexer_Algolia();
40 | $this->processTest($productIndexer, 'products', 93);
41 | }
42 |
43 | public function testDefaultIndexableAttributes()
44 | {
45 | setConfig('algoliasearch/products/product_additional_attributes', serialize(array()));
46 | setConfig('algoliasearch/instant/facets', serialize(array()));
47 | setConfig('algoliasearch/instant/sorts', serialize(array()));
48 | setConfig('algoliasearch/products/custom_ranking_product_attributes', serialize(array()));
49 |
50 | $indexer = new Algolia_Algoliasearch_Model_Indexer_Algolia();
51 | $indexer->reindexSpecificProducts(405);
52 |
53 | $this->algoliaHelper->waitLastTask();
54 |
55 | $results = $this->algoliaHelper->getObjects($this->indexPrefix.'default_products', array('405'));
56 | $hit = reset($results['results']);
57 |
58 | $defaultAttributes = array(
59 | 'objectID',
60 | 'name',
61 | 'url',
62 | 'visibility_search',
63 | 'visibility_catalog',
64 | 'categories',
65 | 'categories_without_path',
66 | 'thumbnail_url',
67 | 'image_url',
68 | 'in_stock',
69 | 'price',
70 | 'type_id',
71 | 'algoliaLastUpdateAtCET',
72 | );
73 |
74 | foreach ($defaultAttributes as $key => $attribute) {
75 | $this->assertTrue(isset($hit[$attribute]), 'Products attribute "'.$attribute.'" should be indexed but it is not"');
76 | unset($hit[$attribute]);
77 | }
78 |
79 | $extraAttributes = implode(', ', array_keys($hit));
80 | $this->assertTrue(empty($hit), 'Extra products attributes ('.$extraAttributes.') are indexed and should not be.');
81 | }
82 |
83 | public function testIfIndexingCanBeEnabledAndDisabled()
84 | {
85 | setConfig('algoliasearch/credentials/enable_backend', '0');
86 |
87 | $productIndexer = new Algolia_Algoliasearch_Model_Indexer_Algolia();
88 | $this->processTest($productIndexer, 'products', 0);
89 |
90 | setConfig('algoliasearch/credentials/enable_backend', '1');
91 |
92 | $productIndexer = new Algolia_Algoliasearch_Model_Indexer_Algolia();
93 | $this->processTest($productIndexer, 'products', self::DEFAULT_PRODUCT_COUNT);
94 | }
95 |
96 | public function testProductAreSearchableIfIndexingIsDisabled()
97 | {
98 | setConfig('algoliasearch/credentials/enable_backend', '0');
99 |
100 | $resultsDefault = $this->algoliaHelper->query($this->indexPrefix.'default_products', 'lemon flower', array());
101 |
102 | $this->assertEquals(1, $resultsDefault['nbHits']);
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/tests/bootstrap.php:
--------------------------------------------------------------------------------
1 | setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
9 |
10 | // Set Magento's base URLs
11 | setConfig('web/secure/base_url', getenv('BASE_URL'));
12 | setConfig('web/unsecure/base_url', getenv('BASE_URL'));
13 |
14 | // Set Algolia API credentials
15 | setConfig('algoliasearch/credentials/application_id', getenv('APPLICATION_ID'));
16 | setConfig('algoliasearch/credentials/search_only_api_key', getenv('SEARCH_ONLY_API_KEY'));
17 | setConfig('algoliasearch/credentials/api_key', Mage::helper('core')->encrypt(getenv('API_KEY')));
18 |
19 | setConfig('algoliasearch/credentials/index_prefix', getenv('INDEX_PREFIX'));
20 |
21 | /**
22 | * @param array $configs
23 | */
24 | function resetConfigs($configs = array())
25 | {
26 | $configXmlFile = __DIR__.'/../app/code/community/Algolia/Algoliasearch/etc/config.xml';
27 |
28 | $xml = simplexml_load_file($configXmlFile);
29 |
30 | $credentialsShortcuts = array(
31 | 'credentials/application_id', 'credentials/api_key', 'credentials/search_only_api_key', 'credentials/index_prefix'
32 | );
33 |
34 | foreach ($xml->default->algoliasearch->children() as $section => $subsections) {
35 | foreach ($subsections as $subsectionName => $subsection) {
36 | $shortcut = $section.'/'.$subsectionName;
37 |
38 | if (in_array($shortcut, $credentialsShortcuts)) {
39 | continue;
40 | }
41 |
42 | if (!empty($configs) && !in_array($shortcut, $configs, true)) {
43 | continue;
44 | }
45 |
46 | $sectionName = 'algoliasearch/'.$shortcut;
47 | $sectionValue = (string) $subsection;
48 |
49 | setConfig($sectionName, $sectionValue);
50 | }
51 | }
52 | }
53 |
54 | function setConfig($path, $value, $storeId = null)
55 | {
56 | if ($storeId === null) {
57 | Mage::app()->getStore()->setConfig($path, $value);
58 | }
59 |
60 | for ($i = 1; $i <= 3; $i++) {
61 | if ($storeId !== null && $i !== $storeId) {
62 | continue;
63 | }
64 |
65 | Mage::app()->getStore($i)->setConfig($path, $value);
66 | }
67 | }
68 |
69 | /**
70 | * Call protected/private method of a class.
71 | *
72 | * @param object &$object Instantiated object that we will run method on.
73 | * @param string $methodName Method name to call
74 | * @param array $parameters Array of parameters to pass into method.
75 | *
76 | * @return mixed Method return.
77 | */
78 | function invokeMethod(&$object, $methodName, array $parameters = array())
79 | {
80 | $reflection = new \ReflectionClass(get_class($object));
81 | $method = $reflection->getMethod($methodName);
82 | $method->setAccessible(true);
83 |
84 | return $method->invokeArgs($object, $parameters);
85 | }
86 |
--------------------------------------------------------------------------------