PageRenderTime 55ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/magento/app/code/core/Mage/Index/Model/Indexer.php

https://bitbucket.org/jit_bec/shopifine
PHP | 429 lines | 227 code | 34 blank | 168 comment | 43 complexity | 66f3d10cb64c6f4cb746db3a7d13dd18 MD5 | raw file
Possible License(s): LGPL-3.0
  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@magentocommerce.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.magentocommerce.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Index
  23. * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * Indexer strategy
  28. */
  29. class Mage_Index_Model_Indexer
  30. {
  31. /**
  32. * Collection of available processes
  33. *
  34. * @var Mage_Index_Model_Resource_Process_Collection
  35. */
  36. protected $_processesCollection;
  37. /**
  38. * Indexer processes lock flag
  39. *
  40. * @deprecated after 1.6.1.0
  41. * @var bool
  42. */
  43. protected $_lockFlag = false;
  44. /**
  45. * Whether table changes are allowed
  46. *
  47. * @var bool
  48. */
  49. protected $_allowTableChanges = true;
  50. /**
  51. * Current processing event(s)
  52. * In array case it should be array(Entity type, Event type)
  53. *
  54. * @var null|Mage_Index_Model_Event|array
  55. */
  56. protected $_currentEvent = null;
  57. /**
  58. * Class constructor. Initialize index processes based on configuration
  59. */
  60. public function __construct()
  61. {
  62. $this->_processesCollection = Mage::getResourceModel('index/process_collection');
  63. }
  64. /**
  65. * Get collection of all available processes
  66. *
  67. * @return Mage_Index_Model_Resource_Process_Collection
  68. */
  69. public function getProcessesCollection()
  70. {
  71. return $this->_processesCollection;
  72. }
  73. /**
  74. * Get index process by specific id
  75. *
  76. * @param int $processId
  77. * @return Mage_Index_Model_Process | false
  78. */
  79. public function getProcessById($processId)
  80. {
  81. foreach ($this->_processesCollection as $process) {
  82. if ($process->getId() == $processId) {
  83. return $process;
  84. }
  85. }
  86. return false;
  87. }
  88. /**
  89. * Get index process by specific code
  90. *
  91. * @param string $code
  92. * @return Mage_Index_Model_Process | false
  93. */
  94. public function getProcessByCode($code)
  95. {
  96. foreach ($this->_processesCollection as $process) {
  97. if ($process->getIndexerCode() == $code) {
  98. return $process;
  99. }
  100. }
  101. return false;
  102. }
  103. /**
  104. * Lock indexer actions
  105. * @deprecated after 1.6.1.0
  106. *
  107. * @return Mage_Index_Model_Indexer
  108. */
  109. public function lockIndexer()
  110. {
  111. $this->_lockFlag = true;
  112. return $this;
  113. }
  114. /**
  115. * Unlock indexer actions
  116. * @deprecated after 1.6.1.0
  117. *
  118. * @return Mage_Index_Model_Indexer
  119. */
  120. public function unlockIndexer()
  121. {
  122. $this->_lockFlag = false;
  123. return $this;
  124. }
  125. /**
  126. * Check if onject actions are locked
  127. *
  128. * @deprecated after 1.6.1.0
  129. * @return bool
  130. */
  131. public function isLocked()
  132. {
  133. return $this->_lockFlag;
  134. }
  135. /**
  136. * Indexing all pending events.
  137. * Events set can be limited by event entity and type
  138. *
  139. * @param null | string $entity
  140. * @param null | string $type
  141. * @return Mage_Index_Model_Indexer
  142. */
  143. public function indexEvents($entity=null, $type=null)
  144. {
  145. Mage::dispatchEvent('start_index_events' . $this->_getEventTypeName($entity, $type));
  146. /** @var $resourceModel Mage_Index_Model_Resource_Process */
  147. $resourceModel = Mage::getResourceSingleton('index/process');
  148. $allowTableChanges = $this->_allowTableChanges && !$resourceModel->isInTransaction();
  149. if ($allowTableChanges) {
  150. $this->_currentEvent = array($entity, $type);
  151. $this->_changeKeyStatus(false);
  152. }
  153. $resourceModel->beginTransaction();
  154. $this->_allowTableChanges = false;
  155. try {
  156. $this->_runAll('indexEvents', array($entity, $type));
  157. $resourceModel->commit();
  158. } catch (Exception $e) {
  159. $resourceModel->rollBack();
  160. throw $e;
  161. }
  162. if ($allowTableChanges) {
  163. $this->_allowTableChanges = true;
  164. $this->_changeKeyStatus(true);
  165. $this->_currentEvent = null;
  166. }
  167. Mage::dispatchEvent('end_index_events' . $this->_getEventTypeName($entity, $type));
  168. return $this;
  169. }
  170. /**
  171. * Index one event by all processes
  172. *
  173. * @param Mage_Index_Model_Event $event
  174. * @return Mage_Index_Model_Indexer
  175. */
  176. public function indexEvent(Mage_Index_Model_Event $event)
  177. {
  178. $this->_runAll('safeProcessEvent', array($event));
  179. return $this;
  180. }
  181. /**
  182. * Register event in each indexing process process
  183. *
  184. * @param Mage_Index_Model_Event $event
  185. */
  186. public function registerEvent(Mage_Index_Model_Event $event)
  187. {
  188. $this->_runAll('register', array($event));
  189. return $this;
  190. }
  191. /**
  192. * Create new event log and register event in all processes
  193. *
  194. * @param Varien_Object $entity
  195. * @param string $entityType
  196. * @param string $eventType
  197. * @param bool $doSave
  198. * @return Mage_Index_Model_Event
  199. */
  200. public function logEvent(Varien_Object $entity, $entityType, $eventType, $doSave=true)
  201. {
  202. $event = Mage::getModel('index/event')
  203. ->setEntity($entityType)
  204. ->setType($eventType)
  205. ->setDataObject($entity)
  206. ->setEntityPk($entity->getId());
  207. $this->registerEvent($event);
  208. if ($doSave) {
  209. $event->save();
  210. }
  211. return $event;
  212. }
  213. /**
  214. * Create new event log and register event in all processes.
  215. * Initiate events indexing procedure.
  216. *
  217. * @param Varien_Object $entity
  218. * @param string $entityType
  219. * @param string $eventType
  220. * @return Mage_Index_Model_Indexer
  221. */
  222. public function processEntityAction(Varien_Object $entity, $entityType, $eventType)
  223. {
  224. $event = $this->logEvent($entity, $entityType, $eventType, false);
  225. /**
  226. * Index and save event just in case if some process matched it
  227. */
  228. if ($event->getProcessIds()) {
  229. Mage::dispatchEvent('start_process_event' . $this->_getEventTypeName($entityType, $eventType));
  230. /** @var $resourceModel Mage_Index_Model_Resource_Process */
  231. $resourceModel = Mage::getResourceSingleton('index/process');
  232. $allowTableChanges = $this->_allowTableChanges && !$resourceModel->isInTransaction();
  233. if ($allowTableChanges) {
  234. $this->_currentEvent = $event;
  235. $this->_changeKeyStatus(false);
  236. }
  237. $resourceModel->beginTransaction();
  238. $this->_allowTableChanges = false;
  239. try {
  240. $this->indexEvent($event);
  241. $resourceModel->commit();
  242. } catch (Exception $e) {
  243. $resourceModel->rollBack();
  244. if ($allowTableChanges) {
  245. $this->_allowTableChanges = true;
  246. $this->_changeKeyStatus(true);
  247. $this->_currentEvent = null;
  248. }
  249. throw $e;
  250. }
  251. if ($allowTableChanges) {
  252. $this->_allowTableChanges = true;
  253. $this->_changeKeyStatus(true);
  254. $this->_currentEvent = null;
  255. }
  256. $event->save();
  257. Mage::dispatchEvent('end_process_event' . $this->_getEventTypeName($entityType, $eventType));
  258. }
  259. return $this;
  260. }
  261. /**
  262. * Run all processes method with parameters
  263. * Run by depends priority
  264. * Not recursive call is not implement
  265. *
  266. * @param string $method
  267. * @param array $args
  268. * @return Mage_Index_Model_Indexer
  269. */
  270. protected function _runAll($method, $args)
  271. {
  272. $checkLocks = $method != 'register';
  273. $processed = array();
  274. foreach ($this->_processesCollection as $process) {
  275. $code = $process->getIndexerCode();
  276. if (in_array($code, $processed)) {
  277. continue;
  278. }
  279. $hasLocks = false;
  280. if ($process->getDepends()) {
  281. foreach ($process->getDepends() as $processCode) {
  282. $dependProcess = $this->getProcessByCode($processCode);
  283. if ($dependProcess && !in_array($processCode, $processed)) {
  284. if ($checkLocks && $dependProcess->isLocked()) {
  285. $hasLocks = true;
  286. } else {
  287. call_user_func_array(array($dependProcess, $method), $args);
  288. if ($checkLocks && $dependProcess->getMode() == Mage_Index_Model_Process::MODE_MANUAL) {
  289. $hasLocks = true;
  290. } else {
  291. $processed[] = $processCode;
  292. }
  293. }
  294. }
  295. }
  296. }
  297. if (!$hasLocks) {
  298. call_user_func_array(array($process, $method), $args);
  299. $processed[] = $code;
  300. }
  301. }
  302. }
  303. /**
  304. * Enable/Disable keys in index tables
  305. *
  306. * @param bool $enable
  307. * @return Mage_Index_Model_Indexer
  308. */
  309. protected function _changeKeyStatus($enable = true)
  310. {
  311. $processed = array();
  312. foreach ($this->_processesCollection as $process) {
  313. $code = $process->getIndexerCode();
  314. if (in_array($code, $processed)) {
  315. continue;
  316. }
  317. if ($process->getDepends()) {
  318. foreach ($process->getDepends() as $processCode) {
  319. $dependProcess = $this->getProcessByCode($processCode);
  320. if ($dependProcess && !in_array($processCode, $processed)) {
  321. if ($this->_changeProcessKeyStatus($dependProcess, $enable)) {
  322. $processed[] = $processCode;
  323. }
  324. }
  325. }
  326. }
  327. if ($this->_changeProcessKeyStatus($process, $enable)) {
  328. $processed[] = $code;
  329. }
  330. }
  331. return $this;
  332. }
  333. /**
  334. * Check if the event will be processed and disable/enable keys in index tables
  335. *
  336. * @param mixed|Mage_Index_Model_Process $process
  337. * @param bool $enable
  338. * @return bool
  339. */
  340. protected function _changeProcessKeyStatus($process, $enable = true)
  341. {
  342. $event = $this->_currentEvent;
  343. if ($process instanceof Mage_Index_Model_Process
  344. && $process->getMode() !== Mage_Index_Model_Process::MODE_MANUAL
  345. && !$process->isLocked()
  346. && (is_null($event)
  347. || ($event instanceof Mage_Index_Model_Event && $process->matchEvent($event))
  348. || (is_array($event) && $process->matchEntityAndType($event[0], $event[1]))
  349. )) {
  350. if ($enable) {
  351. $process->enableIndexerKeys();
  352. } else {
  353. $process->disableIndexerKeys();
  354. }
  355. return true;
  356. }
  357. return false;
  358. }
  359. /**
  360. * Allow DDL operations while indexing
  361. *
  362. * @return Mage_Index_Model_Indexer
  363. */
  364. public function allowTableChanges()
  365. {
  366. $this->_allowTableChanges = true;
  367. return $this;
  368. }
  369. /**
  370. * Disallow DDL operations while indexing
  371. *
  372. * @return Mage_Index_Model_Indexer
  373. */
  374. public function disallowTableChanges()
  375. {
  376. $this->_allowTableChanges = false;
  377. return $this;
  378. }
  379. /**
  380. * Get event type name
  381. *
  382. * @param null|string $entityType
  383. * @param null|string $eventType
  384. * @return string
  385. */
  386. protected function _getEventTypeName($entityType = null, $eventType = null)
  387. {
  388. $eventName = $entityType . '_' . $eventType;
  389. $eventName = trim($eventName, '_');
  390. if (!empty($eventName)) {
  391. $eventName = '_' . $eventName;
  392. }
  393. return $eventName;
  394. }
  395. }