PageRenderTime 26ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/core/model/modx/processors/element/sort.class.php

https://github.com/enigmatic-user/revolution
PHP | 203 lines | 141 code | 26 blank | 36 comment | 37 complexity | 93492146221261615874ce821607120e MD5 | raw file
  1. <?php
  2. /**
  3. * Sorts elements in the element tree
  4. *
  5. * @param json $data The JSON encoded data from the tree
  6. *
  7. * @package modx
  8. * @subpackage processors.layout.tree.element
  9. */
  10. class modElementSortProcessor extends modProcessor {
  11. public function checkPermissions() {
  12. return $this->modx->hasPermission('element_tree');
  13. }
  14. public function getLanguageTopics() {
  15. return array('category');
  16. }
  17. public function process() {
  18. $data = $this->getData();
  19. if (empty($data)) return $this->failure();
  20. $error = false;
  21. if (!empty($data['n_category']) && is_array($data['n_category'])) {
  22. $error = $this->handleCategoryDrop($data['n_category']);
  23. } else if (!empty($data)) {
  24. $error = $this->handleSubCategoryDrop($data);
  25. }
  26. if (is_string($error)) return $this->failure($error);
  27. return $this->success();
  28. }
  29. /**
  30. * Get the data formatted and ready for sorting
  31. * @return array
  32. */
  33. public function getData() {
  34. $data = $this->getProperty('data');
  35. $data = urldecode($data);
  36. $data = $this->modx->fromJSON($data);
  37. $this->sortNodes('modTemplate','template',$data);
  38. $this->sortNodes('modTemplateVar','tv',$data);
  39. $this->sortNodes('modChunk','chunk',$data);
  40. $this->sortNodes('modSnippet','snippet',$data);
  41. $this->sortNodes('modPlugin','plugin',$data);
  42. return $data;
  43. }
  44. /**
  45. * Handle dropping of Elements or Categories onto Categories
  46. *
  47. * @param array $data
  48. * @return boolean|string
  49. */
  50. public function handleCategoryDrop(array $data) {
  51. /* if dropping an element onto a category, do that here */
  52. foreach ($data as $key => $elements) {
  53. if (!is_array($elements) || empty($elements)) continue;
  54. $key = explode('_',$key);
  55. if (empty($key[1]) || empty($key[2]) || $key[1] != 'category') continue;
  56. foreach ($elements as $elKey => $elArray) {
  57. $elKey = explode('_',$elKey);
  58. if (empty($elKey[1]) || empty($elKey[3])) continue;
  59. $className = 'mod'.ucfirst($elKey[1]);
  60. if ($className == 'modTv') $className = 'modTemplateVar';
  61. /** @var modElement $element */
  62. $element = $this->modx->getObject($className,$elKey[3]);
  63. if ($element) {
  64. $element->set('category',$key[2]);
  65. $element->save();
  66. }
  67. }
  68. }
  69. /* if sorting categories, do that here */
  70. $cdata = array();
  71. $this->getNodesFormatted($cdata,$data);
  72. foreach ($cdata as $categoryArray) {
  73. if ($categoryArray['type'] != 'category') continue;
  74. /** @var modCategory $category */
  75. $category = $this->modx->getObject('modCategory',$categoryArray['id']);
  76. if ($category && $categoryArray['parent'] != $category->get('parent')) {
  77. $exists = $this->modx->getCount('modCategory',array('category' => $category->get('category'), 'parent' => $categoryArray['parent'])) > 0;
  78. if ($exists) return $this->modx->lexicon('category_err_ae');
  79. $category->set('parent',$categoryArray['parent']);
  80. $category->save();
  81. }
  82. }
  83. return true;
  84. }
  85. /**
  86. * Handle dropping of Categories onto other Categories
  87. * @param array $data
  88. * @return boolean
  89. */
  90. public function handleSubCategoryDrop(array $data) {
  91. $cdata = array();
  92. foreach ($data as $typeKey => $type) {
  93. if (!empty($type)) {
  94. $this->getCategoryNodeDrop($cdata,$type);
  95. }
  96. }
  97. foreach ($cdata as $item) {
  98. if (empty($item['class']) || empty($item['pk'])) continue;
  99. if ($item['class'] == 'modCategory') {
  100. /** @var modCategory $category */
  101. $category = $this->modx->getObject('modCategory',$item['pk']);
  102. if ($category) {
  103. $category->set('parent',$item['category']);
  104. $category->save();
  105. }
  106. }
  107. }
  108. return true;
  109. }
  110. /**
  111. * Properly sort the data
  112. * @param string $xname
  113. * @param string $type
  114. * @param array $data
  115. * @return void
  116. */
  117. public function sortNodes($xname,$type,$data) {
  118. $s = $data['n_type_'.$type];
  119. if (is_array($s)) {
  120. $this->sortNodesHelper($s,$xname);
  121. }
  122. }
  123. public function sortNodesHelper($objs,$xname,$currentCategoryId = 0) {
  124. foreach ($objs as $objar => $kids) {
  125. $oar = explode('_',$objar);
  126. $nodeArray = $this->processID($oar);
  127. if ($nodeArray['type'] == 'category') {
  128. $this->sortNodesHelper($kids,$xname,$nodeArray['pk']);
  129. } elseif ($nodeArray['type'] == 'element') {
  130. /** @var modElement $element */
  131. $element = $this->modx->getObject($xname,$nodeArray['pk']);
  132. if (empty($element)) continue;
  133. $element->set('category',$currentCategoryId);
  134. $element->save();
  135. }
  136. }
  137. }
  138. public function processID($ar) {
  139. return array(
  140. 'elementType' => $ar[1],
  141. 'type' => $ar[2],
  142. 'pk' => $ar[3],
  143. 'elementCatId' => isset($ar[4]) ? $ar[4] : 0,
  144. );
  145. }
  146. public function getNodesFormatted(&$ar_nodes,$cur_level,$parent = 0) {
  147. $order = 0;
  148. foreach ($cur_level as $nodeId => $children) {
  149. $ar = explode('_',$nodeId);
  150. if (empty($ar[1]) || empty($ar[2])) continue;
  151. $ar_nodes[] = array(
  152. 'id' => $ar[2],
  153. 'type' => $ar[1],
  154. 'parent' => $parent,
  155. 'order' => $order,
  156. );
  157. $order++;
  158. $this->getNodesFormatted($ar_nodes,$children,$ar[2]);
  159. }
  160. }
  161. public function getCategoryNodeDrop(&$cdata,$type = array(),$currentParent = 0) {
  162. foreach ($type as $itemKey => $item) {
  163. $nar = explode('_',$itemKey);
  164. $pk = !empty($nar[3]) ? $nar[3] : 0;
  165. $cdata[] = array(
  166. 'type' => $nar[1],
  167. 'class' => 'mod'.ucfirst($nar[2]),
  168. 'pk' => $pk,
  169. 'category' => $currentParent,
  170. );
  171. if (!empty($item)) {
  172. $this->getCategoryNodeDrop($cdata,$item,$pk);
  173. }
  174. }
  175. }
  176. }
  177. return 'modElementSortProcessor';