PageRenderTime 51ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/app/code/core/Mage/Catalog/Model/Product/Indexer/Flat.php

https://gitlab.com/LisovyiEvhenii/ismextensions
PHP | 362 lines | 226 code | 32 blank | 104 comment | 78 complexity | 1e6d861ae255d6b381f93e7eaf9e937b MD5 | raw file
  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magento.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magento.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Catalog
  23. * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. class Mage_Catalog_Model_Product_Indexer_Flat extends Mage_Index_Model_Indexer_Abstract
  27. {
  28. /**
  29. * Data key for matching result to be saved in
  30. */
  31. const EVENT_MATCH_RESULT_KEY = 'catalog_product_flat_match_result';
  32. /**
  33. * Index math Entities array
  34. *
  35. * @var array
  36. */
  37. protected $_matchedEntities = array(
  38. Mage_Catalog_Model_Product::ENTITY => array(
  39. Mage_Index_Model_Event::TYPE_SAVE,
  40. Mage_Index_Model_Event::TYPE_MASS_ACTION,
  41. ),
  42. Mage_Catalog_Model_Resource_Eav_Attribute::ENTITY => array(
  43. Mage_Index_Model_Event::TYPE_SAVE,
  44. Mage_Index_Model_Event::TYPE_DELETE,
  45. ),
  46. Mage_Core_Model_Store::ENTITY => array(
  47. Mage_Index_Model_Event::TYPE_SAVE,
  48. Mage_Index_Model_Event::TYPE_DELETE
  49. ),
  50. Mage_Core_Model_Store_Group::ENTITY => array(
  51. Mage_Index_Model_Event::TYPE_SAVE
  52. ),
  53. Mage_Catalog_Model_Convert_Adapter_Product::ENTITY => array(
  54. Mage_Index_Model_Event::TYPE_SAVE
  55. ),
  56. Mage_Catalog_Model_Product_Flat_Indexer::ENTITY => array(
  57. Mage_Catalog_Model_Product_Flat_Indexer::EVENT_TYPE_REBUILD,
  58. ),
  59. );
  60. /**
  61. * Whether the indexer should be displayed on process/list page
  62. *
  63. * @return bool
  64. */
  65. public function isVisible()
  66. {
  67. /** @var $productFlatHelper Mage_Catalog_Helper_Product_Flat */
  68. $productFlatHelper = Mage::helper('catalog/product_flat');
  69. return $productFlatHelper->isEnabled() || !$productFlatHelper->isBuilt();
  70. }
  71. /**
  72. * Retrieve Indexer name
  73. *
  74. * @return string
  75. */
  76. public function getName()
  77. {
  78. return Mage::helper('catalog')->__('Product Flat Data');
  79. }
  80. /**
  81. * Retrieve Indexer description
  82. *
  83. * @return string
  84. */
  85. public function getDescription()
  86. {
  87. return Mage::helper('catalog')->__('Reorganize EAV product structure to flat structure');
  88. }
  89. /**
  90. * Retrieve Catalog Product Flat Indexer model
  91. *
  92. * @return Mage_Catalog_Model_Product_Flat_Indexer
  93. */
  94. protected function _getIndexer()
  95. {
  96. return Mage::getSingleton('catalog/product_flat_indexer');
  97. }
  98. /**
  99. * Check if event can be matched by process
  100. * Overwrote for check is flat catalog product is enabled and specific save
  101. * attribute, store, store_group
  102. *
  103. * @param Mage_Index_Model_Event $event
  104. * @return bool
  105. */
  106. public function matchEvent(Mage_Index_Model_Event $event)
  107. {
  108. /** @var $productFlatHelper Mage_Catalog_Helper_Product_Flat */
  109. $productFlatHelper = Mage::helper('catalog/product_flat');
  110. if (!$productFlatHelper->isEnabled() || !$productFlatHelper->isBuilt()) {
  111. return false;
  112. }
  113. $data = $event->getNewData();
  114. if (isset($data[self::EVENT_MATCH_RESULT_KEY])) {
  115. return $data[self::EVENT_MATCH_RESULT_KEY];
  116. }
  117. $entity = $event->getEntity();
  118. if ($entity == Mage_Catalog_Model_Resource_Eav_Attribute::ENTITY) {
  119. /* @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
  120. $attribute = $event->getDataObject();
  121. $addFilterable = $productFlatHelper->isAddFilterableAttributes();
  122. $enableBefore = $attribute && (($attribute->getOrigData('backend_type') == 'static')
  123. || ($addFilterable && $attribute->getOrigData('is_filterable') > 0)
  124. || ($attribute->getOrigData('used_in_product_listing') == 1)
  125. || ($attribute->getOrigData('is_used_for_promo_rules') == 1)
  126. || ($attribute->getOrigData('used_for_sort_by') == 1));
  127. $enableAfter = $attribute && (($attribute->getData('backend_type') == 'static')
  128. || ($addFilterable && $attribute->getData('is_filterable') > 0)
  129. || ($attribute->getData('used_in_product_listing') == 1)
  130. || ($attribute->getData('is_used_for_promo_rules') == 1)
  131. || ($attribute->getData('used_for_sort_by') == 1));
  132. if ($attribute && $event->getType() == Mage_Index_Model_Event::TYPE_DELETE) {
  133. $result = $enableBefore;
  134. } elseif ($attribute && $event->getType() == Mage_Index_Model_Event::TYPE_SAVE) {
  135. if ($enableAfter || $enableBefore) {
  136. $result = true;
  137. } else {
  138. $result = false;
  139. }
  140. } else {
  141. $result = false;
  142. }
  143. } else if ($entity == Mage_Core_Model_Store::ENTITY) {
  144. if ($event->getType() == Mage_Index_Model_Event::TYPE_DELETE) {
  145. $result = true;
  146. } else {
  147. /* @var $store Mage_Core_Model_Store */
  148. $store = $event->getDataObject();
  149. if ($store && $store->isObjectNew()) {
  150. $result = true;
  151. } else {
  152. $result = false;
  153. }
  154. }
  155. } else if ($entity == Mage_Core_Model_Store_Group::ENTITY) {
  156. /* @var $storeGroup Mage_Core_Model_Store_Group */
  157. $storeGroup = $event->getDataObject();
  158. if ($storeGroup && $storeGroup->dataHasChangedFor('website_id')) {
  159. $result = true;
  160. } else {
  161. $result = false;
  162. }
  163. } else {
  164. $result = parent::matchEvent($event);
  165. }
  166. $event->addNewData(self::EVENT_MATCH_RESULT_KEY, $result);
  167. return $result;
  168. }
  169. /**
  170. * Register data required by process in event object
  171. *
  172. * @param Mage_Index_Model_Event $event
  173. */
  174. protected function _registerEvent(Mage_Index_Model_Event $event)
  175. {
  176. $event->addNewData(self::EVENT_MATCH_RESULT_KEY, true);
  177. switch ($event->getEntity()) {
  178. case Mage_Catalog_Model_Product::ENTITY:
  179. $this->_registerCatalogProductEvent($event);
  180. break;
  181. case Mage_Catalog_Model_Convert_Adapter_Product::ENTITY:
  182. $event->addNewData('catalog_product_flat_reindex_all', true);
  183. break;
  184. case Mage_Core_Model_Store::ENTITY:
  185. if ($event->getType() == Mage_Index_Model_Event::TYPE_DELETE) {
  186. $this->_registerCoreStoreEvent($event);
  187. break;
  188. }
  189. case Mage_Catalog_Model_Resource_Eav_Attribute::ENTITY:
  190. case Mage_Core_Model_Store_Group::ENTITY:
  191. $event->addNewData('catalog_product_flat_skip_call_event_handler', true);
  192. $process = $event->getProcess();
  193. $process->changeStatus(Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX);
  194. break;
  195. case Mage_Catalog_Model_Product_Flat_Indexer::ENTITY:
  196. switch ($event->getType()) {
  197. case Mage_Catalog_Model_Product_Flat_Indexer::EVENT_TYPE_REBUILD:
  198. $event->addNewData('id', $event->getDataObject()->getId());
  199. }
  200. break;
  201. }
  202. }
  203. /**
  204. * Register data required by catalog product process in event object
  205. *
  206. * @param Mage_Index_Model_Event $event
  207. * @return Mage_Catalog_Model_Product_Indexer_Flat
  208. */
  209. protected function _registerCatalogProductEvent(Mage_Index_Model_Event $event)
  210. {
  211. switch ($event->getType()) {
  212. case Mage_Index_Model_Event::TYPE_SAVE:
  213. /* @var $product Mage_Catalog_Model_Product */
  214. $product = $event->getDataObject();
  215. $event->addNewData('catalog_product_flat_product_id', $product->getId());
  216. break;
  217. case Mage_Index_Model_Event::TYPE_MASS_ACTION:
  218. /* @var $actionObject Varien_Object */
  219. $actionObject = $event->getDataObject();
  220. $reindexData = array();
  221. $reindexFlat = false;
  222. // check if status changed
  223. $attrData = $actionObject->getAttributesData();
  224. if (isset($attrData['status'])) {
  225. $reindexFlat = true;
  226. $reindexData['catalog_product_flat_status'] = $attrData['status'];
  227. }
  228. // check changed websites
  229. if ($actionObject->getWebsiteIds()) {
  230. $reindexFlat = true;
  231. $reindexData['catalog_product_flat_website_ids'] = $actionObject->getWebsiteIds();
  232. $reindexData['catalog_product_flat_action_type'] = $actionObject->getActionType();
  233. }
  234. $flatAttributes = array();
  235. if (is_array($attrData)) {
  236. $flatAttributes = array_intersect($this->_getFlatAttributes(), array_keys($attrData));
  237. }
  238. if (count($flatAttributes) > 0) {
  239. $reindexFlat = true;
  240. $reindexData['catalog_product_flat_force_update'] = true;
  241. }
  242. // register affected products
  243. if ($reindexFlat) {
  244. $reindexData['catalog_product_flat_product_ids'] = $actionObject->getProductIds();
  245. foreach ($reindexData as $k => $v) {
  246. $event->addNewData($k, $v);
  247. }
  248. }
  249. break;
  250. }
  251. return $this;
  252. }
  253. /**
  254. * Register core store delete process
  255. *
  256. * @param Mage_Index_Model_Event $event
  257. * @return Mage_Catalog_Model_Product_Indexer_Flat
  258. */
  259. protected function _registerCoreStoreEvent(Mage_Index_Model_Event $event)
  260. {
  261. if ($event->getType() == Mage_Index_Model_Event::TYPE_DELETE) {
  262. /* @var $store Mage_Core_Model_Store */
  263. $store = $event->getDataObject();
  264. $event->addNewData('catalog_product_flat_delete_store_id', $store->getId());
  265. }
  266. return $this;
  267. }
  268. /**
  269. * Process event
  270. *
  271. * @param Mage_Index_Model_Event $event
  272. */
  273. protected function _processEvent(Mage_Index_Model_Event $event)
  274. {
  275. $data = $event->getNewData();
  276. if ($event->getType() == Mage_Catalog_Model_Product_Flat_Indexer::EVENT_TYPE_REBUILD) {
  277. $this->_getIndexer()->getResource()->rebuild($data['id']);
  278. return;
  279. }
  280. if (!empty($data['catalog_product_flat_reindex_all'])) {
  281. $this->reindexAll();
  282. } else if (!empty($data['catalog_product_flat_product_id'])) {
  283. // catalog_product save
  284. $productId = $data['catalog_product_flat_product_id'];
  285. $this->_getIndexer()->saveProduct($productId);
  286. } else if (!empty($data['catalog_product_flat_product_ids'])) {
  287. // catalog_product mass_action
  288. $productIds = $data['catalog_product_flat_product_ids'];
  289. if (!empty($data['catalog_product_flat_website_ids'])) {
  290. $websiteIds = $data['catalog_product_flat_website_ids'];
  291. foreach ($websiteIds as $websiteId) {
  292. $website = Mage::app()->getWebsite($websiteId);
  293. foreach ($website->getStores() as $store) {
  294. if ($data['catalog_product_flat_action_type'] == 'remove') {
  295. $this->_getIndexer()->removeProduct($productIds, $store->getId());
  296. } else {
  297. $this->_getIndexer()->updateProduct($productIds, $store->getId());
  298. }
  299. }
  300. }
  301. }
  302. if (isset($data['catalog_product_flat_status'])) {
  303. $status = $data['catalog_product_flat_status'];
  304. $this->_getIndexer()->updateProductStatus($productIds, $status);
  305. }
  306. if (isset($data['catalog_product_flat_force_update'])) {
  307. $this->_getIndexer()->updateProduct($productIds);
  308. }
  309. } else if (!empty($data['catalog_product_flat_delete_store_id'])) {
  310. $this->_getIndexer()->deleteStore($data['catalog_product_flat_delete_store_id']);
  311. }
  312. }
  313. /**
  314. * Rebuild all index data
  315. *
  316. */
  317. public function reindexAll()
  318. {
  319. $this->_getIndexer()->reindexAll();
  320. }
  321. /**
  322. * Retrieve list of attribute codes, that are used in flat
  323. *
  324. * @return array
  325. */
  326. protected function _getFlatAttributes()
  327. {
  328. return Mage::getModel('catalog/product_flat_indexer')->getAttributeCodes();
  329. }
  330. }