mirror of
https://github.com/processwire/processwire.git
synced 2025-08-07 07:16:51 +02:00
Add a new $page->cloneable() method that returns true if the user is allowed to clone the page. Or use $page->cloneable(true) if the user is allowed to clone the page and its children together. This moves the logic was was previously in the ProcessPageClone module into a method that can be more widely used where needed. Also updated the ProcessPageClone module to use it.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
* 1. Providing get/set access to the Page's properties
|
||||
* 2. Accessing the related hierarchy of pages (i.e. parents, children, sibling pages)
|
||||
*
|
||||
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
|
||||
* ProcessWire 3.x, Copyright 2024 by Ryan Cramer
|
||||
* https://processwire.com
|
||||
*
|
||||
* #pw-summary Class used by all Page objects in ProcessWire.
|
||||
@@ -120,6 +120,7 @@
|
||||
* @method bool addable($pageToAdd = null) Returns true if the current user can add children to the page, false if not. Optionally specify the page to be added for additional access checking. #pw-group-access
|
||||
* @method bool moveable($newParent = null) Returns true if the current user can move this page. Optionally specify the new parent to check if the page is moveable to that parent. #pw-group-access
|
||||
* @method bool sortable() Returns true if the current user can change the sort order of the current page (within the same parent). #pw-group-access
|
||||
* @method bool cloneable($recursive = null) Can current user clone this page? Specify false for $recursive argument to ignore whether children are cloneable. @since 3.0.239 #pw-group-access
|
||||
* @property bool $viewable #pw-group-access
|
||||
* @property bool $editable #pw-group-access
|
||||
* @property bool $publishable #pw-group-access
|
||||
@@ -130,6 +131,7 @@
|
||||
* @property bool $moveable #pw-group-access
|
||||
* @property bool $sortable #pw-group-access
|
||||
* @property bool $listable #pw-group-access
|
||||
* @property bool $cloneable @since 3.0.239 #pw-group-access
|
||||
*
|
||||
* Methods added by PagePathHistory.module (installed by default)
|
||||
* --------------------------------------------------------------
|
||||
|
@@ -9,7 +9,7 @@
|
||||
* Except where indicated, please treat these properties as private to the
|
||||
* Page class.
|
||||
*
|
||||
* ProcessWire 3.x, Copyright 2021 by Ryan Cramer
|
||||
* ProcessWire 3.x, Copyright 2024 by Ryan Cramer
|
||||
* https://processwire.com
|
||||
*
|
||||
*/
|
||||
@@ -75,6 +75,7 @@ abstract class PageProperties {
|
||||
'addable' => 'm',
|
||||
'child' => 'm',
|
||||
'children' => 'm',
|
||||
'cloneable' => 'm',
|
||||
'created' => 's',
|
||||
'createdStr' => '',
|
||||
'createdUser' => '',
|
||||
|
@@ -116,7 +116,8 @@ class PagePermissions extends WireData implements Module {
|
||||
$this->addHook('Page::restorable', $this, 'restorable');
|
||||
$this->addHook('Page::addable', $this, 'addable');
|
||||
$this->addHook('Page::moveable', $this, 'moveable');
|
||||
$this->addHook('Page::sortable', $this, 'sortable');
|
||||
$this->addHook('Page::sortable', $this, 'sortable');
|
||||
$this->addHook('Page::cloneable', $this, 'cloneable');
|
||||
// $this->addHook('Page::fieldViewable', $this, 'hookFieldViewable');
|
||||
// $this->addHook('Page::fieldEditable', $this, 'hookFieldEditable');
|
||||
// $this->addHook('Template::createable', $this, 'createable');
|
||||
@@ -1107,6 +1108,69 @@ class PagePermissions extends WireData implements Module {
|
||||
// if we made it here, then page is not publishable
|
||||
$event->return = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is page cloneable by current user?
|
||||
*
|
||||
* Note: If a page has children and current user is not superuser, this method will return
|
||||
* true only if the user has the `page-clone-tree` permission (from ProcessPageClone module).
|
||||
*
|
||||
* ~~~~~
|
||||
* if($page->cloneable()) {
|
||||
* // page is cloneable
|
||||
* }
|
||||
* if($page->cloneable(false)) {
|
||||
* // page is cloneable, ignoring if recursive clone of children is allowed
|
||||
* }
|
||||
* ~~~~~
|
||||
*
|
||||
* @param HookEvent $event
|
||||
*
|
||||
*/
|
||||
public function cloneable($event) {
|
||||
|
||||
$page = $event->object; /** @var Page $page */
|
||||
$recursive = $event->arguments(0); /** @var bool|null $recursive */
|
||||
$user = $this->wire()->user;
|
||||
$permissions = $this->wire()->permissions;
|
||||
$parent = $page->parent();
|
||||
$parentTemplate = $parent->template;
|
||||
$pageTemplate = $page->template;
|
||||
$event->return = false;
|
||||
|
||||
if(!$parentTemplate) return;
|
||||
|
||||
if($page->hasStatus(Page::statusSystem) || $page->hasStatus(Page::statusSystemID)) return;
|
||||
if($parentTemplate->noChildren) return;
|
||||
if($pageTemplate->noParents) return;
|
||||
|
||||
if(count($parentTemplate->childTemplates) && !in_array($pageTemplate->id, $parentTemplate->childTemplates)) return;
|
||||
if(count($pageTemplate->parentTemplates) && !in_array($parentTemplate->id, $pageTemplate->parentTemplates)) return;
|
||||
|
||||
if($user->isSuperuser()) {
|
||||
$event->return = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!$user->hasPermission('page-create', $page)) return;
|
||||
|
||||
if(!$parent->addable()) return;
|
||||
|
||||
if($permissions->has('page-clone')) {
|
||||
if(!$user->hasPermission('page-clone', $page)) return;
|
||||
}
|
||||
|
||||
if($recursive === false || !$page->numChildren) {
|
||||
// call indicates they do not intend to clone children
|
||||
// or there are no children, so no additional checks necessary
|
||||
} else {
|
||||
// check that they have page-clone-tree permission IF the page has children
|
||||
// recursive cloning is only allowed via ProcessPageClone module
|
||||
if(!$user->hasPermission('page-clone-tree', $page)) return;
|
||||
}
|
||||
|
||||
$event->return = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given user has the optional language permission, or false if not
|
||||
|
@@ -150,24 +150,7 @@ class ProcessPageClone extends Process implements ConfigurableModule {
|
||||
*
|
||||
*/
|
||||
public function hasPermission(Page $page) {
|
||||
$user = $this->wire()->user;
|
||||
$parent = $page->parent();
|
||||
$parentTemplate = $parent->template;
|
||||
$pageTemplate = $page->template;
|
||||
|
||||
if(!$parentTemplate) return false;
|
||||
|
||||
if($page->hasStatus(Page::statusSystem) || $page->hasStatus(Page::statusSystemID)) return false;
|
||||
if($parentTemplate->noChildren) return false;
|
||||
if($pageTemplate->noParents) return false;
|
||||
|
||||
if(count($parentTemplate->childTemplates) && !in_array($pageTemplate->id, $parentTemplate->childTemplates)) return false;
|
||||
if(count($pageTemplate->parentTemplates) && !in_array($parentTemplate->id, $pageTemplate->parentTemplates)) return false;
|
||||
|
||||
if($user->isSuperuser()) return true;
|
||||
if($user->hasPermission('page-create', $page) && $user->hasPermission('page-clone', $page) && $parent->addable()) return true;
|
||||
|
||||
return false;
|
||||
return $page->cloneable(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -378,7 +361,7 @@ class ProcessPageClone extends Process implements ConfigurableModule {
|
||||
|
||||
$titleField = $form->get('clone_page_title');
|
||||
$nameField = $form->get('clone_page_name');
|
||||
$cloneTree = $input->post('clone_page_tree') && $this->wire()->user->hasPermission('page-clone-tree', $this->page);
|
||||
$cloneTree = $input->post('clone_page_tree') && $this->page->cloneable(true);
|
||||
|
||||
if($input->post('clone_page_unpublished')) {
|
||||
$page->addStatus(Page::statusUnpublished);
|
||||
|
Reference in New Issue
Block a user