mirror of
https://github.com/processwire/processwire.git
synced 2025-08-12 09:44:38 +02:00
Update ProcessPageEdit to enable removal of system status when superuser in advanced mode (though I don't recommend using it unless you are trying to fix something that's broken), plus make a couple more status options available to superuser in advanced mode. Also some other unrelated and minor optimizations in this module.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
* For more details about how Process modules work, please see:
|
||||
* /wire/core/Process.php
|
||||
*
|
||||
* ProcessWire 3.x, Copyright 2018 by Ryan Cramer
|
||||
* ProcessWire 3.x, Copyright 2021 by Ryan Cramer
|
||||
* https://processwire.com
|
||||
*
|
||||
* @property string $noticeUnknown
|
||||
@@ -54,7 +54,7 @@ class ProcessPageEdit extends Process implements WirePageEditor, ConfigurableMod
|
||||
return array(
|
||||
'title' => 'Page Edit',
|
||||
'summary' => 'Edit a Page',
|
||||
'version' => 109,
|
||||
'version' => 110,
|
||||
'permanent' => true,
|
||||
'permission' => 'page-edit',
|
||||
'icon' => 'edit',
|
||||
@@ -345,8 +345,13 @@ class ProcessPageEdit extends Process implements WirePageEditor, ConfigurableMod
|
||||
$this->set('viewAction', 'this');
|
||||
return parent::__construct();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wired to API
|
||||
*
|
||||
*/
|
||||
public function wired() {
|
||||
parent::wired();
|
||||
if($this->wire('process') instanceof WirePageEditor) {
|
||||
// keep existing process, which may be building on top of this one
|
||||
} else {
|
||||
@@ -437,7 +442,7 @@ class ProcessPageEdit extends Process implements WirePageEditor, ConfigurableMod
|
||||
if($context) $this->requestContext = $this->sanitizer->name($context);
|
||||
|
||||
// optional language GET var
|
||||
$languages = $this->wire('languages');
|
||||
$languages = $this->wire()->languages;
|
||||
if($languages) {
|
||||
$this->hasLanguagePageNames = $this->modules->isInstalled('LanguageSupportPageNames');
|
||||
if($this->hasLanguagePageNames) {
|
||||
@@ -476,40 +481,35 @@ class ProcessPageEdit extends Process implements WirePageEditor, ConfigurableMod
|
||||
protected function ___loadPage($id) {
|
||||
|
||||
/** @var Page|NullPage $page */
|
||||
$page = $this->wire('pages')->get((int) $id);
|
||||
$page = $this->wire()->pages->get((int) $id);
|
||||
|
||||
if($page instanceof NullPage) {
|
||||
throw new WireException($this->noticeUnknown); // page doesn't exist
|
||||
}
|
||||
|
||||
$editable = $page->editable();
|
||||
|
||||
/** @var User $user */
|
||||
$user = $this->user;
|
||||
|
||||
/** @var Config $config */
|
||||
$config = $this->config;
|
||||
|
||||
/** @var Config $config */
|
||||
$input = $this->input;
|
||||
|
||||
if($page instanceof User) {
|
||||
// special case when page is a User
|
||||
$userAdmin = $this->user->hasPermission('user-admin');
|
||||
|
||||
$userAdmin = $user->hasPermission('user-admin');
|
||||
$field = $input->get('field') ? $this->wire('fields')->get($input->get->fieldName('field')) : null;
|
||||
|
||||
if($userAdmin && $this->wire('process') != 'ProcessUser') {
|
||||
if($userAdmin && $this->wire()->process != 'ProcessUser') {
|
||||
// only allow user pages to be edited from the access section (at least for non-superusers)
|
||||
$this->session->redirect($config->urls->admin . 'access/users/edit/?id=' . $page->id);
|
||||
$this->session->redirect($this->config->urls->admin . 'access/users/edit/?id=' . $page->id);
|
||||
}
|
||||
|
||||
} else if(!$userAdmin && $page->id === $user->id && $field && $config->ajax) {
|
||||
// user is editing themself and we're responding to an ajax request for a field
|
||||
/** @var PagePermissions $pagePermissions */
|
||||
$pagePermissions = $this->modules->get('PagePermissions');
|
||||
$editable = $pagePermissions->userFieldEditable($field);
|
||||
// prevent a later potential redirect to user editor
|
||||
if($editable) $this->setEditor = false;
|
||||
if(!$userAdmin && $page->id === $this->user->id && $this->config->ajax) {
|
||||
// user that lacks user-admin permission editing themself during ajax request
|
||||
$fieldName = $this->input->get->fieldName('field');
|
||||
$field = $fieldName ? $this->wire()->fields->get($fieldName) : null;
|
||||
if($field instanceof Field) {
|
||||
// respond to ajax request for field that is editable
|
||||
/** @var PagePermissions $pagePermissions */
|
||||
$pagePermissions = $this->modules->get('PagePermissions');
|
||||
$editable = $pagePermissions->userFieldEditable($field);
|
||||
// prevent a later potential redirect to user editor
|
||||
if($editable) $this->setEditor = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -633,7 +633,8 @@ class ProcessPageEdit extends Process implements WirePageEditor, ConfigurableMod
|
||||
$out .= "</ul>";
|
||||
}
|
||||
|
||||
$out .= "<scr" . "ipt>initPageEditForm();</script>"; // ends up being slightly faster than ready() (or at least appears that way)
|
||||
$func = 'initPageEditForm();'; // to prevent IDE from flagging as unknown function
|
||||
$out .= "<scr" . "ipt>$func</script>"; // ends up being slightly faster than ready() (or at least appears that way)
|
||||
|
||||
return $out;
|
||||
}
|
||||
@@ -665,6 +666,7 @@ class ProcessPageEdit extends Process implements WirePageEditor, ConfigurableMod
|
||||
if($this->requestModal) return array();
|
||||
|
||||
$viewable = $this->page->viewable();
|
||||
$process = $this->wire()->process;
|
||||
$actions = array();
|
||||
|
||||
$actions['exit'] = array(
|
||||
@@ -680,9 +682,8 @@ class ProcessPageEdit extends Process implements WirePageEditor, ConfigurableMod
|
||||
'label' => $this->_('%s + View'),
|
||||
'class' => '',
|
||||
);
|
||||
|
||||
if($this->wire('process') == $this && $this->page->id > 1) {
|
||||
|
||||
|
||||
if("$process" === "$this" && $this->page->id > 1) {
|
||||
$parent = $this->page->parent();
|
||||
if($parent->addable()) $actions['add'] = array(
|
||||
'value' => 'add',
|
||||
@@ -1459,14 +1460,10 @@ class ProcessPageEdit extends Process implements WirePageEditor, ConfigurableMod
|
||||
*/
|
||||
protected function buildFormPrevPaths() {
|
||||
|
||||
/** @var WireInput $input */
|
||||
$input = $this->wire('input');
|
||||
/** @var Modules $modules */
|
||||
$modules = $this->wire('modules');
|
||||
/** @var Sanitizer $sanitizer */
|
||||
$sanitizer = $this->wire('sanitizer');
|
||||
/** @var Languages|null $languages */
|
||||
$languages = $this->wire('languages');
|
||||
$input = $this->input;
|
||||
$modules = $this->modules;
|
||||
$sanitizer = $this->sanitizer;
|
||||
$languages = $this->wire()->languages;
|
||||
|
||||
if($this->isPost && $input->post('_prevpath_add') === null) return null;
|
||||
if(!$modules->isInstalled('PagePathHistory')) return null;
|
||||
@@ -1697,34 +1694,14 @@ class ProcessPageEdit extends Process implements WirePageEditor, ConfigurableMod
|
||||
protected function buildFormStatus() {
|
||||
|
||||
$status = (int) $this->page->status;
|
||||
$statuses = array();
|
||||
$debug = $this->config->debug;
|
||||
$advanced = $this->config->advanced;
|
||||
$statuses = $this->getAllowedStatuses();
|
||||
|
||||
/** @var InputfieldCheckboxes $field */
|
||||
$field = $this->modules->get('InputfieldCheckboxes');
|
||||
$field->attr('name', 'status');
|
||||
$field->icon = 'sliders';
|
||||
|
||||
if(!$this->page->template->noUnpublish && $this->page->publishable()) {
|
||||
$statuses[Page::statusUnpublished] = $this->_('Unpublished: Not visible on site'); // Settings: Unpublished status checkbox label
|
||||
}
|
||||
if($this->user->hasPermission('page-hide', $this->page)) {
|
||||
$statuses[Page::statusHidden] = $this->_('Hidden: Excluded from lists and searches'); // Settings: Hidden status checkbox label
|
||||
}
|
||||
if($this->user->hasPermission('page-lock', $this->page)) {
|
||||
$statuses[Page::statusLocked] = $this->_('Locked: Not editable'); // Settings: Locked status checkbox label
|
||||
}
|
||||
|
||||
if($this->user->isSuperuser()) {
|
||||
$statuses[Page::statusUnique] = sprintf($this->_('Unique: Require page name “%s” to be globally unique'), $this->page->name) .
|
||||
($this->wire('languages') ? ' ' . $this->_('(in default language only)') : '');
|
||||
if($advanced) {
|
||||
$statuses[Page::statusSystemID] = "System: Non-deleteable and locked ID (status not removeable via API)";
|
||||
$statuses[Page::statusSystem] = "System: Non-deleteable and locked ID, name, template, parent (status not removeable via API)";
|
||||
}
|
||||
}
|
||||
|
||||
$value = array();
|
||||
|
||||
foreach($statuses as $s => $label) {
|
||||
@@ -1803,7 +1780,7 @@ class ProcessPageEdit extends Process implements WirePageEditor, ConfigurableMod
|
||||
|
||||
if(!$this->page->isTrash()) return false;
|
||||
if(!$this->page->restorable()) return false;
|
||||
$info = $this->wire('pages')->trasher()->getRestoreInfo($this->page);
|
||||
$info = $this->wire()->pages->trasher()->getRestoreInfo($this->page);
|
||||
if(!$info['restorable']) return false;
|
||||
|
||||
/** @var InputfieldWrapper $wrapper */
|
||||
@@ -2195,7 +2172,7 @@ class ProcessPageEdit extends Process implements WirePageEditor, ConfigurableMod
|
||||
$this->page->setQuietly('_forceAddStatus', 0);
|
||||
}
|
||||
|
||||
$languages = $this->wire('languages');
|
||||
$languages = $this->wire()->languages;
|
||||
$errorAction = (int) $this->page->template->errorAction;
|
||||
|
||||
foreach($form as $inputfield) {
|
||||
@@ -2383,34 +2360,30 @@ class ProcessPageEdit extends Process implements WirePageEditor, ConfigurableMod
|
||||
*/
|
||||
protected function processInputStatus(Inputfield $inputfield) {
|
||||
|
||||
$status = $inputfield->value;
|
||||
$inputStatusFlags = $inputfield->val();
|
||||
if(!is_array($inputStatusFlags)) $inputStatusFlags = array();
|
||||
foreach($inputStatusFlags as $k => $v) $inputStatusFlags[$k] = (int) $v;
|
||||
|
||||
$allowedStatusFlags = array_keys($this->getAllowedStatuses());
|
||||
$statusLabels = array_flip(Page::getStatuses());
|
||||
$value = $this->page->status;
|
||||
|
||||
if(!is_array($status)) $status = array();
|
||||
|
||||
$statusFlags = array();
|
||||
if($this->user->hasPermission('page-hide', $this->page)) $statusFlags[] = Page::statusHidden;
|
||||
if($this->page->publishable()) $statusFlags[] = Page::statusUnpublished;
|
||||
if($this->user->hasPermission('page-lock', $this->page)) $statusFlags[] = Page::statusLocked;
|
||||
|
||||
if($this->user->isSuperuser()) {
|
||||
$statusFlags[] = Page::statusUnique;
|
||||
if($this->config->advanced) {
|
||||
$statusFlags[] = Page::statusSystemID;
|
||||
$statusFlags[] = Page::statusSystem;
|
||||
}
|
||||
}
|
||||
|
||||
foreach($statusFlags as $flag) {
|
||||
if(in_array($flag, $status)) {
|
||||
if(!($value & $flag)) $value = $value | $flag;
|
||||
|
||||
foreach($allowedStatusFlags as $flag) {
|
||||
if(in_array($flag, $inputStatusFlags, true)) {
|
||||
if($value & $flag) {
|
||||
// already has flag
|
||||
} else {
|
||||
$value = $value | $flag; // add status
|
||||
$this->message(sprintf($this->_('Added status: %s'), $statusLabels[$flag]), Notice::debug);
|
||||
}
|
||||
} else if($value & $flag) {
|
||||
$value = $value & ~$flag;
|
||||
$value = $value & ~$flag; // remove flag
|
||||
$this->message(sprintf($this->_('Removed status: %s'), $statusLabels[$flag]), Notice::debug);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->page->status = $value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2500,6 +2473,7 @@ class ProcessPageEdit extends Process implements WirePageEditor, ConfigurableMod
|
||||
if(!$this->ajaxEditable($page)) throw new WirePermissionException($this->noticeNoAccess);
|
||||
$this->session->CSRF->validate(); // throws exception when invalid
|
||||
|
||||
/** @var InputfieldWrapper $form */
|
||||
$form = $this->wire(new InputfieldWrapper());
|
||||
$form->useDependencies = false;
|
||||
$keys = array();
|
||||
@@ -2963,6 +2937,61 @@ class ProcessPageEdit extends Process implements WirePageEditor, ConfigurableMod
|
||||
return $this->tabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get allowed page statuses
|
||||
*
|
||||
* @return array Array of [ statusFlagInteger => 'Status flag label' ]
|
||||
* @since 3.0.181
|
||||
*
|
||||
*/
|
||||
public function getAllowedStatuses() {
|
||||
|
||||
$page = $this->page;
|
||||
$config = $this->wire()->config;
|
||||
$statuses = array();
|
||||
$superuser = $this->user->isSuperuser();
|
||||
|
||||
if(!$this->page->template->noUnpublish && $this->page->publishable()) {
|
||||
$statuses[Page::statusUnpublished] = $this->_('Unpublished: Not visible on site'); // Settings: Unpublished status checkbox label
|
||||
}
|
||||
|
||||
if($this->user->hasPermission('page-hide', $this->page)) {
|
||||
$statuses[Page::statusHidden] = $this->_('Hidden: Excluded from lists and searches'); // Settings: Hidden status checkbox label
|
||||
}
|
||||
|
||||
if($this->user->hasPermission('page-lock', $this->page)) {
|
||||
$statuses[Page::statusLocked] = $this->_('Locked: Not editable'); // Settings: Locked status checkbox label
|
||||
}
|
||||
|
||||
if($superuser) {
|
||||
$uniqueNote = ($this->wire('languages') ? ' ' . $this->_('(in default language only)') : '');
|
||||
$statuses[Page::statusUnique] = sprintf($this->_('Unique: Require page name “%s” to be globally unique'), $this->page->name) . $uniqueNote;
|
||||
}
|
||||
|
||||
if($superuser && $config->advanced) {
|
||||
// additional statuses available to superuser in advanced mode
|
||||
$hasSystem = $page->hasStatus(Page::statusSystem) || $page->hasStatus(Page::statusSystemID) || $page->hasStatus(Page::statusSystemOverride);
|
||||
$statuses[Page::statusSystem] = "System: Non-deleteable and locked ID, name, template, parent (status not removeable without override)";
|
||||
$statuses[Page::statusSystemID] = "System ID: Non-deleteable and locked ID (status not removeable without override)";
|
||||
if($hasSystem) $statuses[Page::statusSystemOverride] = "System Override: Override (must be added temporarily in its own save before system status can be removed)";
|
||||
$statuses[Page::statusDraft] = "Draft: Page has a separate draft version";
|
||||
$statuses[Page::statusOn] = "On: Internal toggle when combined with other statuses (only for specific cases, otherwise ignored)";
|
||||
/*
|
||||
* Additional statuses that are possible but shouldn't be editable (uncomment temporarily if needed)
|
||||
*
|
||||
* $statuses[Page::statusTemp] = "Temp: Unpublished page more than 1 day old may be automatically deleted";
|
||||
* $statuses[Page::statusFlagged] = "Flagged: Page is flagged as incomplete, needing review, or having some issue";
|
||||
* $statuses[Page::statusTrash] = "Internal trash: Indicates that page is in the trash";
|
||||
* $statuses[Page::statusReserved] = "Internal-reserved: Status reserved for future use";
|
||||
* $statuses[Page::statusInternal] = "Internal-internal: Status for internal or future use";
|
||||
*
|
||||
*/
|
||||
}
|
||||
|
||||
return $statuses;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get PageBookmarks array
|
||||
*
|
||||
@@ -3147,11 +3176,16 @@ class ProcessPageEdit extends Process implements WirePageEditor, ConfigurableMod
|
||||
*
|
||||
*/
|
||||
public function getModuleConfigInputfields(array $data) {
|
||||
|
||||
|
||||
$config = $this->wire()->config;
|
||||
$pages = $this->wire()->pages;
|
||||
$modules = $this->wire()->modules;
|
||||
$inputfields = new InputfieldWrapper();
|
||||
$this->wire($inputfields);
|
||||
|
||||
$f = $this->wire('modules')->get('InputfieldRadios');
|
||||
$this->wire($inputfields);
|
||||
|
||||
/** @var InputfieldRadios $f */
|
||||
$f = $modules->get('InputfieldRadios');
|
||||
$f->name = 'viewAction';
|
||||
$f->label = $this->_('Default "view" location/action');
|
||||
$f->description = $this->_('The default type of action used when the "view" tab is clicked on in the page editor.');
|
||||
@@ -3161,7 +3195,8 @@ class ProcessPageEdit extends Process implements WirePageEditor, ConfigurableMod
|
||||
$f->addOption($name, $label);
|
||||
}
|
||||
|
||||
$configData = $this->wire('config')->pageEdit;
|
||||
/** @var array $configData */
|
||||
$configData = $config->pageEdit;
|
||||
if(isset($data['viewAction'])) {
|
||||
$f->attr('value', $data['viewAction']);
|
||||
} else if(is_array($configData) && !empty($configData['viewNew'])) {
|
||||
@@ -3174,8 +3209,8 @@ class ProcessPageEdit extends Process implements WirePageEditor, ConfigurableMod
|
||||
|
||||
$bookmarks = $this->getPageBookmarks();
|
||||
$bookmarks->addConfigInputfields($inputfields);
|
||||
$admin = $this->wire('pages')->get($this->wire('config')->adminRootPageID);
|
||||
$page = $this->wire('pages')->get($admin->path . 'page/edit/');
|
||||
$admin = $pages->get($config->adminRootPageID);
|
||||
$page = $pages->get($admin->path . 'page/edit/');
|
||||
$bookmarks->checkProcessPage($page);
|
||||
|
||||
return $inputfields;
|
||||
|
Reference in New Issue
Block a user