PageRenderTime 47ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/application/helper/massAction/MassActionProcessor.php

http://github.com/integry/livecart
PHP | 181 lines | 142 code | 33 blank | 6 comment | 15 complexity | 04856a2ac0b49af9d64dce80151d9ec4 MD5 | raw file
Possible License(s): LGPL-3.0
  1. <?php
  2. /**
  3. * @package application.helper.massAction
  4. * @author Integry Systems
  5. */
  6. class MassActionProcessor
  7. {
  8. protected $grid;
  9. protected $params;
  10. protected $completionMessage;
  11. protected $pid;
  12. const MASS_ACTION_CHUNK_SIZE = 50;
  13. public function __construct(ActiveGrid $grid, $params = array())
  14. {
  15. $this->grid = $grid;
  16. $this->params = $params;
  17. $this->request = $grid->getApplication()->getRequest();
  18. $this->pid = uniqid();
  19. }
  20. public function setCompletionMessage($message)
  21. {
  22. $this->completionMessage = $message;
  23. }
  24. public function process($loadReferencedRecords = array())
  25. {
  26. set_time_limit(0);
  27. ignore_user_abort(true);
  28. $this->deleteCancelFile();
  29. $filter = $this->grid->getFilter();
  30. $filter->setLimit(0);
  31. $ids = array();
  32. foreach (ActiveRecordModel::getFieldValues($this->grid->getModelClass(), $filter, array('ID'), ActiveRecordModel::LOAD_REFERENCES) as $row)
  33. {
  34. $ids[] = $row['ID'];
  35. }
  36. $totalCount = count($ids);
  37. $progress = 0;
  38. $response = new JSONResponse(array('act' => $this->request->get('act')), 'success', $this->completionMessage);
  39. ActiveRecord::beginTransaction();
  40. $chunkSize = (count($ids) / self::MASS_ACTION_CHUNK_SIZE) > 5 ? self::MASS_ACTION_CHUNK_SIZE : ceil(count($ids) / 5);
  41. foreach (array_chunk($ids, $chunkSize) as $chunk)
  42. {
  43. $response->flush('|' . base64_encode(json_encode(array('total' => $totalCount, 'progress' => $progress, 'pid' => $this->pid))));
  44. $this->processSet(ActiveRecordModel::getRecordSet($this->grid->getModelClass(), new ARSelectFilter(new INCond(new ARFieldHandle($this->grid->getModelClass(), 'ID'), $chunk)), $loadReferencedRecords));
  45. $progress += count($chunk);
  46. }
  47. ActiveRecord::commit();
  48. $response->flush('|');
  49. return $response;
  50. }
  51. public static function isCancelled($pid)
  52. {
  53. $cancelFile = self::getCancelFile($pid);
  54. $k = 0;
  55. $ret = false;
  56. // wait the cancel file for 5 seconds
  57. while (++$k < 6 && !$ret)
  58. {
  59. $ret = file_exists($cancelFile);
  60. if ($ret)
  61. {
  62. unlink($cancelFile);
  63. break;
  64. }
  65. else
  66. {
  67. sleep(1);
  68. }
  69. }
  70. return $ret;
  71. }
  72. protected function processSet(ARSet $set)
  73. {
  74. foreach ($set as $record)
  75. {
  76. $this->processRecord($record);
  77. //echo round(memory_get_usage() / (1024*1024), 1) . "MB \n";
  78. if ('delete' == $this->getAction())
  79. {
  80. $this->deleteRecord($record);
  81. }
  82. else
  83. {
  84. $this->saveRecord($record);
  85. }
  86. $record->__destruct();
  87. unset($record);
  88. if (connection_aborted())
  89. {
  90. $this->cancel();
  91. }
  92. }
  93. $set->__destruct();
  94. unset($set);
  95. ActiveRecord::clearPool();
  96. }
  97. protected function saveRecord(ActiveRecordModel $record)
  98. {
  99. $record->save();
  100. }
  101. protected function deleteRecord(ActiveRecordModel $record)
  102. {
  103. $record->delete();
  104. }
  105. protected function getAction()
  106. {
  107. return $this->request->get('act');
  108. }
  109. protected function getField()
  110. {
  111. return array_pop(explode('_', $this->getAction(), 2));
  112. }
  113. protected function processRecord(ActiveRecordModel $record)
  114. {
  115. $act = $this->getAction();
  116. $field = $this->getField();
  117. if (substr($act, 0, 7) == 'enable_')
  118. {
  119. $record->setFieldValue($field, 1);
  120. }
  121. else if (substr($act, 0, 8) == 'disable_')
  122. {
  123. $record->setFieldValue($field, 0);
  124. }
  125. else if (substr($act, 0, 4) == 'set_')
  126. {
  127. $record->setFieldValue($field, $this->request->get('set_' . $field));
  128. }
  129. }
  130. private function cancel()
  131. {
  132. file_put_contents($this->getCancelFile(), '');
  133. ActiveRecord::rollback();
  134. exit;
  135. }
  136. private function getCancelFile($pid = null)
  137. {
  138. return ClassLoader::getRealPath('cache') . '/.massCancel-' . ($pid ? $pid : $this->pid);
  139. }
  140. private function deleteCancelFile()
  141. {
  142. if (file_exists($this->getCancelFile()))
  143. {
  144. unlink($this->getCancelFile());
  145. }
  146. }
  147. }
  148. ?>