/wire/modules/Process/ProcessPageSort.module

http://github.com/ryancramerdesign/ProcessWire · Unknown · 140 lines · 114 code · 26 blank · 0 comment · 0 complexity · a331309656085004c3554e211a670f7a MD5 · raw file

  1. <?php
  2. /**
  3. * ProcessWire Page Sort Process
  4. *
  5. * Saves moved or sorted pages for the PageList process.
  6. * Intended to be executed via an ajax call.
  7. *
  8. * For more details about how Process modules work, please see:
  9. * /wire/core/Process.php
  10. *
  11. * ProcessWire 2.x
  12. * Copyright (C) 2012 by Ryan Cramer
  13. * Licensed under GNU/GPL v2, see LICENSE.TXT
  14. *
  15. * http://www.processwire.com
  16. * http://www.ryancramer.com
  17. *
  18. */
  19. class ProcessPageSort extends Process {
  20. protected $ids = array();
  21. protected $parent_id = 0;
  22. protected $move_id = 0;
  23. protected $user;
  24. protected $isMoved = false;
  25. public static function getModuleInfo() {
  26. return array(
  27. 'title' => __('Page Sort and Move', __FILE__), // getModuleInfo title
  28. 'summary' => __('Handles page sorting and moving for PageList', __FILE__), // getModuleInfo summary
  29. 'version' => 100,
  30. 'permanent' => true,
  31. 'permission' => 'page-edit',
  32. );
  33. }
  34. /**
  35. * Install a new permission in addition to the regular ProcessPageSort permission
  36. *
  37. * The "ProcessPageSortMove" permission refers to changing the page's parent,
  38. * whereas the "ProcessPageSort" permission refers to changing the sort within the same parent.
  39. *
  40. */
  41. public function ___install() {
  42. parent::___install();
  43. }
  44. /**
  45. * Save a move/sort request
  46. *
  47. */
  48. public function ___execute() {
  49. if($this->config->demo) throw new WireException($this->_("Your change was not saved because this site is in demo mode"));
  50. if(!isset($_POST['sort'])) throw new WireException($this->_("This Process is only accessible via POST"));
  51. $this->session->CSRF->validate(); // throws exception if invalid
  52. $this->user = $this->fuel('user');
  53. $this->ids = array();
  54. $ids = explode(',', $_POST['sort']);
  55. foreach($ids as $sort => $id) $this->ids[(int) $sort] = (int) $id;
  56. if(!count($this->ids)) return;
  57. unset($ids);
  58. $this->parent_id = (int) $_POST['parent_id'];
  59. $this->move_id = (int) $_POST['id'];
  60. $parentPage = $this->fuel('pages')->get($this->parent_id);
  61. $movePage = $this->fuel('pages')->get($this->move_id);
  62. if($movePage->id < 2 || !$parentPage->id) return;
  63. $this->movePage($movePage, $parentPage);
  64. $this->sortPages($movePage, $parentPage);
  65. }
  66. /**
  67. * Saves a page that has had it's parent_id changed
  68. *
  69. */
  70. protected function movePage(Page $page, Page $parent) {
  71. if($page->parent_id == $parent->id) return;
  72. if(!$page->moveable($parent))
  73. throw new WirePermissionException($this->_("You do not have permission to move pages using this parent") . " - {$parent->path}");
  74. $page->setOutputFormatting(false);
  75. $page->resetTrackChanges(true);
  76. $page->parent = $parent;
  77. $page->save();
  78. $this->message("Moved page $page to parent $parent");
  79. $this->isMoved = true;
  80. }
  81. /**
  82. * Updates the sortfield for all pages having the same parent
  83. *
  84. */
  85. protected function sortPages(Page $page, Page $parent) {
  86. if(!$page->sortable()) {
  87. if(!$this->isMoved) throw new WirePermissionException($this->_("You do not have permission to sort pages using this parent") . " - {$parent->path}");
  88. return;
  89. }
  90. if($parent->sortfield && $parent->sortfield != 'sort') {
  91. $msg = sprintf($this->_("Your sort was not saved because these pages are automatically sorted by %s."), $parent->sortfield);
  92. if(!$this->isMoved) throw new WireException($msg);
  93. else $this->message($msg);
  94. return;
  95. }
  96. $changes = 0;
  97. $sortStart = 0;
  98. // locate the 'sort' value of the current first sorted item, to use as our starting point (in case sorting in a pagination other than 1)
  99. $sql = "SELECT sort FROM pages " .
  100. "WHERE parent_id={$parent->id} " .
  101. "AND id IN(" . implode(',', $this->ids) . ") " .
  102. ($this->isMoved ? "AND id!={$this->move_id} " : '') .
  103. "ORDER BY sort " .
  104. "LIMIT 1";
  105. $result = $this->db->query($sql);
  106. if($result->num_rows) list($sortStart) = $result->fetch_row();
  107. foreach($this->ids as $sort => $id) {
  108. $sort += $sortStart;
  109. $this->db->query("UPDATE pages SET sort=$sort WHERE id=$id AND parent_id=$parent->id AND sort!=$sort");
  110. if($this->db->affected_rows) $changes++;
  111. }
  112. if($changes) $this->message("Updated sort for $changes pages");
  113. }
  114. }