mirror of
https://github.com/processwire/processwire.git
synced 2025-08-09 08:17:12 +02:00
Some cleanup in ProcessPageList.module, plus attempt compromise fix identified for ProcessPageEdit breadcrumb starting from issue #22.
This commit is contained in:
@@ -2230,11 +2230,12 @@ class ProcessPageEdit extends Process implements WirePageEditor, ConfigurableMod
|
||||
if($this->page && $this->page->id != 1) $this->wire('breadcrumbs')->shift(); // shift off the 'Pages' breadcrumb
|
||||
$page = $this->page ? $this->page : $this->parent;
|
||||
if($this->masterPage) $page = $this->masterPage;
|
||||
$lastID = (int) $this->wire('session')->get('ProcessPageList', 'lastID');
|
||||
|
||||
$numParents = $page->parents->count();
|
||||
foreach($page->parents() as $cnt => $p) {
|
||||
$url = "../?open=$p->id";
|
||||
if($cnt == $numParents-1) $url = "../";
|
||||
if($cnt == $numParents-1 && $p->id == $lastID) $url = "../";
|
||||
$this->breadcrumb($url, $p->get("title|name"));
|
||||
}
|
||||
|
||||
|
@@ -8,7 +8,7 @@
|
||||
* For more details about how Process modules work, please see:
|
||||
* /wire/core/Process.php
|
||||
*
|
||||
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
|
||||
* ProcessWire 3.x, Copyright 2017 by Ryan Cramer
|
||||
* https://processwire.com
|
||||
*
|
||||
* @property bool $showRootPage Whether root page (like home) should be shown.
|
||||
@@ -19,18 +19,76 @@
|
||||
* @property int $hoverActionDelay Milliseconds delay between hover and showing of actions.
|
||||
* @property int $hoverActionFade Milliseconds to spend fading in or out actions.
|
||||
* @property bool|int $useBookmarks Allow use of PageList bookmarks?
|
||||
*
|
||||
* @method string ajaxAction($action)
|
||||
* @method PageArray find($selectorString, Page $page)
|
||||
*
|
||||
*/
|
||||
|
||||
class ProcessPageList extends Process implements ConfigurableModule {
|
||||
|
||||
/**
|
||||
* Module information
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
public static function getModuleInfo() {
|
||||
return array(
|
||||
'title' => 'Page List',
|
||||
'summary' => 'List pages in a hierarchal tree structure',
|
||||
'version' => 119,
|
||||
'permanent' => true,
|
||||
'permission' => 'page-edit',
|
||||
'icon' => 'sitemap',
|
||||
'useNavJSON' => true,
|
||||
);
|
||||
}
|
||||
|
||||
protected $page;
|
||||
protected $id;
|
||||
protected $openPage;
|
||||
|
||||
/**
|
||||
* @var Page|null
|
||||
*
|
||||
*/
|
||||
protected $page;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @var Page|null
|
||||
*
|
||||
*/
|
||||
protected $openPage;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*
|
||||
*/
|
||||
protected $start;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
*/
|
||||
protected $trashLabel;
|
||||
protected $render;
|
||||
protected $allowRenderTypes = array('JSON' => 'ProcessPageListRenderJSON');
|
||||
|
||||
/**
|
||||
* @var string|null i.e. "JSON"
|
||||
*
|
||||
*/
|
||||
protected $render;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*
|
||||
*/
|
||||
protected $allowRenderTypes = array(
|
||||
'JSON' => 'ProcessPageListRenderJSON'
|
||||
);
|
||||
|
||||
/**
|
||||
* Default max pages to show before pagination (configurable in the module editor)
|
||||
@@ -42,25 +100,17 @@ class ProcessPageList extends Process implements ConfigurableModule {
|
||||
* Default animation speed (in ms) for the PageList
|
||||
*
|
||||
*/
|
||||
const defaultSpeed = 200;
|
||||
|
||||
public static function getModuleInfo() {
|
||||
return array(
|
||||
'title' => 'Page List',
|
||||
'summary' => 'List pages in a hierarchal tree structure',
|
||||
'version' => 118,
|
||||
'permanent' => true,
|
||||
'permission' => 'page-edit',
|
||||
'icon' => 'sitemap',
|
||||
'useNavJSON' => true,
|
||||
);
|
||||
}
|
||||
const defaultSpeed = 200;
|
||||
|
||||
/**
|
||||
* Construct and establish default config values
|
||||
*
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
$this->showRootPage = true;
|
||||
$this->pageLabelField = 'title';
|
||||
$this->limit = self::defaultLimit;
|
||||
$this->set('showRootPage', true);
|
||||
$this->set('pageLabelField', 'title');
|
||||
$this->set('limit', self::defaultLimit);
|
||||
$this->set('useHoverActions', false);
|
||||
$this->set('useBookmarks', false);
|
||||
$this->set('bookmarks', array());
|
||||
@@ -73,15 +123,20 @@ class ProcessPageList extends Process implements ConfigurableModule {
|
||||
*
|
||||
*/
|
||||
public function init() {
|
||||
|
||||
parent::init();
|
||||
$isAjax = $this->wire('config')->ajax;
|
||||
$this->start = isset($_GET['start']) ? (int) $_GET['start'] : 0;
|
||||
$this->limit = (isset($_GET['limit']) && $_GET['limit'] < $this->limit) ? (int) $_GET['limit'] : $this->limit;
|
||||
$this->render = isset($_GET['render']) ? strtoupper($this->sanitizer->name($_GET['render'])) : '';
|
||||
if($isAjax && !$this->render && !$this->wire('input')->get('renderInputfieldAjax')) $this->render = 'JSON';
|
||||
$config = $this->wire('config');
|
||||
$input = $this->wire('input');
|
||||
$isAjax = $config->ajax;
|
||||
$limit = (int) $input->get->int('limit');
|
||||
$render = $input->get('render');
|
||||
$this->start = (int) $input->get->int('start'); //isset($_GET['start']) ? (int) $_GET['start'] : 0;
|
||||
$this->limit = $limit && $limit < $this->limit ? $limit : $this->limit;
|
||||
$this->render = $render ? strtoupper($this->wire('sanitizer')->name($render)) : '';
|
||||
if($isAjax && !$this->render && !$input->get('renderInputfieldAjax')) $this->render = 'JSON';
|
||||
if($this->render && !isset($this->allowRenderTypes[$this->render])) $this->render = null;
|
||||
|
||||
$settings = $this->wire('config')->pageList;
|
||||
$settings = $config->pageList;
|
||||
if(is_array($settings)) {
|
||||
if(!empty($settings['useHoverActions'])) $this->set('useHoverActions', true);
|
||||
$this->set('hoverActionDelay', isset($settings['hoverActionDelay']) ? (int) $settings['hoverActionDelay'] : 100);
|
||||
@@ -91,67 +146,67 @@ class ProcessPageList extends Process implements ConfigurableModule {
|
||||
}
|
||||
|
||||
if(!$isAjax) {
|
||||
$this->wire('modules')->get('JqueryCore')->use('cookie');
|
||||
$this->wire('modules')->get('JqueryCore')->use('longclick');
|
||||
$this->wire('modules')->get('JqueryUI')->use('modal');
|
||||
$modules = $this->wire('modules');
|
||||
$jQuery = $modules->get('JqueryCore');
|
||||
$jQuery->use('cookie');
|
||||
$jQuery->use('longclick');
|
||||
$modules->get('JqueryUI')->use('modal');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the Page List
|
||||
*
|
||||
* @return string
|
||||
* @throws WireException|Wire404Exception|WirePermissionException
|
||||
*
|
||||
*/
|
||||
public function ___execute() {
|
||||
|
||||
$langID = (int) $this->wire('input')->get->lang;
|
||||
$pages = $this->wire('pages');
|
||||
$input = $this->wire('input');
|
||||
$ajax = $this->wire('config')->ajax;
|
||||
$langID = (int) $input->get('lang');
|
||||
if($langID) $this->wire('user')->language = $this->languages->get($langID);
|
||||
|
||||
$this->trashLabel = $this->_('Trash'); // Label for 'Trash' page in PageList // Overrides page title if used
|
||||
|
||||
if(isset($_GET['id']) && $_GET['id'] == 'bookmark') $this->wire('session')->redirect('./bookmarks/');
|
||||
if(!$this->id) $this->id = isset($_GET['id']) ? (int) $_GET['id'] : 0;
|
||||
$this->openPage = $this->input->get->open ? $this->pages->get((int) $this->input->get->open) : $this->wire('pages')->newNullPage();
|
||||
|
||||
$id = $input->get('id');
|
||||
if($id === 'bookmark') $this->wire('session')->redirect('./bookmarks/');
|
||||
$id = (int) $id;
|
||||
if(!$this->id && $id > 0) $this->id = $id;
|
||||
|
||||
$openID = (int) $input->get('open');
|
||||
$this->openPage = $openID ? $pages->get($openID) : $pages->newNullPage();
|
||||
if($this->openPage->id && $this->speed > 50) $this->speed = floor($this->speed / 2);
|
||||
$this->page = $this->pages->get("id=" . ($this->id ? $this->id : 1) . ", status<" . Page::statusMax);
|
||||
$this->page = $pages->get("id=" . ($this->id > 0 ? $this->id : 1) . ", status<" . Page::statusMax);
|
||||
|
||||
if(!$this->page) throw new Wire404Exception("Unable to load page {$this->id}");
|
||||
if(!$this->page->listable()) throw new WirePermissionException("You don't have access to list page {$this->page->url}");
|
||||
$this->page->setOutputFormatting(false);
|
||||
|
||||
if($this->wire('config')->ajax && !empty($_POST['action'])) {
|
||||
$action = $this->wire('input')->post('action');
|
||||
if($action) return $this->ajaxAction($this->wire('sanitizer')->name($action));
|
||||
$this->page->setOutputFormatting(false);
|
||||
|
||||
$action = $input->post('action');
|
||||
if($ajax && $action) {
|
||||
return $this->ajaxAction($this->wire('sanitizer')->name($action));
|
||||
}
|
||||
|
||||
$p = $this->wire('page');
|
||||
|
||||
if($p->name == 'list' && $p->process == $this) {
|
||||
// ensure that we use the page's title is always consistent in the admin (i.e. 'Pages' not 'Page List')
|
||||
$p->title = $p->parent->title;
|
||||
}
|
||||
|
||||
/*
|
||||
if($p->process == $this && $this->wire('input')->get('mode') != 'select') {
|
||||
// store information about the last page list so that it can later be linked to again by ProcessPageEdit
|
||||
$n = 1;
|
||||
if($this->start >= $this->limit) $n = ($this->start / $this->limit)+1;
|
||||
$lastPageList = $this->session->get('lastPageList');
|
||||
if(!is_array($lastPageList)) $lastPageList = array();
|
||||
else $lastPageList = array_slice($lastPageList, 0, 10, true);
|
||||
$lastPageList[$this->page->id] = array(
|
||||
'title' => (string) $this->page->get('title|name'),
|
||||
'url' => (string) $this->wire('page')->url,
|
||||
'n' => $n
|
||||
);
|
||||
$this->session->set('lastPageList', $lastPageList);
|
||||
}
|
||||
*/
|
||||
|
||||
if($ajax && $this->id > 1 && $p->process == $this && $this->wire('input')->get('mode') != 'select') {
|
||||
// remember last requested id
|
||||
$this->wire('session')->setFor($this, 'lastID', $this->id);
|
||||
}
|
||||
|
||||
return $this->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the Page List
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
protected function render() {
|
||||
@@ -159,7 +214,11 @@ class ProcessPageList extends Process implements ConfigurableModule {
|
||||
$this->setupBreadcrumbs();
|
||||
if($this->render) return $this->getPageListRender($this->page)->render();
|
||||
|
||||
$isAjax = $this->wire('config')->ajax;
|
||||
$input = $this->wire('input');
|
||||
$config = $this->wire('config');
|
||||
$session = $this->wire('session');
|
||||
$urls = $config->urls;
|
||||
$isAjax = $config->ajax;
|
||||
$openPageIDs = array();
|
||||
$openPageData = array();
|
||||
$script = '';
|
||||
@@ -173,12 +232,12 @@ class ProcessPageList extends Process implements ConfigurableModule {
|
||||
if($this->id) {
|
||||
// leave openPageIDs as empty array
|
||||
} else {
|
||||
$openPageIDs = $this->wire('input')->cookie->array('pagelist_open');
|
||||
$openPageIDs = $input->cookie->array('pagelist_open');
|
||||
}
|
||||
}
|
||||
|
||||
if($isAjax) {
|
||||
if($this->wire('input')->get('renderInputfieldAjax')) {
|
||||
if($input->get('renderInputfieldAjax')) {
|
||||
$script = "<script>ProcessPageListInit();</script>";
|
||||
}
|
||||
} else if(count($openPageIDs)) {
|
||||
@@ -203,12 +262,12 @@ class ProcessPageList extends Process implements ConfigurableModule {
|
||||
|
||||
$defaults = array(
|
||||
'containerID' => 'PageListContainer',
|
||||
'ajaxURL' => $this->config->urls->admin . "page/list/",
|
||||
'ajaxMoveURL' => $this->config->urls->admin . "page/sort/",
|
||||
'ajaxURL' => $urls->admin . "page/list/",
|
||||
'ajaxMoveURL' => $urls->admin . "page/sort/",
|
||||
'rootPageID' => $this->id,
|
||||
'openPageIDs' => $openPageIDs,
|
||||
'openPageData' => $openPageData,
|
||||
'openPagination' => (int) $this->input->get->n, // @todo: make it openPaginations and correspond to openPageIDs
|
||||
'openPagination' => (int) $input->get('n'),
|
||||
'paginationClass' => 'PageListPagination',
|
||||
'showRootPage' => $this->showRootPage ? true : false,
|
||||
'limit' => $this->limit,
|
||||
@@ -227,12 +286,12 @@ class ProcessPageList extends Process implements ConfigurableModule {
|
||||
'ajaxNetworkError' => $this->_('Network error, please try again later'), // Network error during AJAX request
|
||||
'ajaxUnknownError' => $this->_('Unknown error, please try again later'), // Unknown error during AJAX request
|
||||
);
|
||||
$settings = $this->wire('config')->ProcessPageList;
|
||||
$settings = $config->ProcessPageList;
|
||||
$settings = is_array($settings) ? array_merge($defaults, $settings) : $defaults;
|
||||
$this->wire('config')->js('ProcessPageList', $settings);
|
||||
$config->js('ProcessPageList', $settings);
|
||||
|
||||
$tokenName = $this->session->CSRF->getTokenName();
|
||||
$tokenValue = $this->session->CSRF->getTokenValue();
|
||||
$tokenName = $session->CSRF->getTokenName();
|
||||
$tokenValue = $session->CSRF->getTokenValue();
|
||||
$class = $this->id ? "PageListContainerPage" : "PageListContainerRoot";
|
||||
|
||||
return "\n" .
|
||||
@@ -277,51 +336,98 @@ class ProcessPageList extends Process implements ConfigurableModule {
|
||||
|
||||
return $renderer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the page label field
|
||||
*
|
||||
* @param $name
|
||||
* @param $pageLabelField
|
||||
*
|
||||
*/
|
||||
public function setPageLabelField($name, $pageLabelField) {
|
||||
$this->wire('session')->setFor($this, $name, $pageLabelField);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the page label field
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
protected function getPageLabelField() {
|
||||
|
||||
$pageLabelField = '';
|
||||
if(isset($_GET['labelName'])) {
|
||||
$name = $this->wire('sanitizer')->fieldName($_GET['labelName']);
|
||||
$name = $this->wire('input')->get('labelName');
|
||||
|
||||
if($name) {
|
||||
$name = $this->wire('sanitizer')->fieldName($name);
|
||||
if($name) $pageLabelField = $this->wire('session')->getFor($this, $name);
|
||||
if($pageLabelField) $pageLabelField = '!' . $pageLabelField; // "!" means it may not be overridden by template
|
||||
}
|
||||
if(empty($pageLabelField)) $pageLabelField = $this->pageLabelField;
|
||||
|
||||
if(empty($pageLabelField)) {
|
||||
$pageLabelField = $this->pageLabelField;
|
||||
}
|
||||
|
||||
return $pageLabelField;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process an AJAX action and return JSON string
|
||||
*
|
||||
* @param string $action
|
||||
* @return string
|
||||
* @throws WireException
|
||||
*
|
||||
*/
|
||||
public function ___ajaxAction($action) {
|
||||
if(!$this->page->editable()) throw new WireException("Page not editable");
|
||||
if($this->page->id != $this->wire('input')->post('id')) throw new WireException("GET id does not match POST id");
|
||||
|
||||
$tokenName = $this->session->CSRF->getTokenName();
|
||||
$tokenValue = $this->session->CSRF->getTokenValue();
|
||||
$postTokenValue = $this->wire('input')->post($tokenName);
|
||||
$input = $this->wire('input');
|
||||
$session = $this->wire('session');
|
||||
|
||||
if(!$this->page->editable()) throw new WireException("Page not editable");
|
||||
if($this->page->id != $input->post('id')) throw new WireException("GET id does not match POST id");
|
||||
|
||||
$tokenName = $session->CSRF->getTokenName();
|
||||
$tokenValue = $session->CSRF->getTokenValue();
|
||||
$postTokenValue = $input->post($tokenName);
|
||||
if($postTokenValue === null || $postTokenValue !== $tokenValue) throw new WireException("CSRF token does not match");
|
||||
|
||||
$renderer = $this->getPageListRender($this->page, 0);
|
||||
$result = $renderer->actions()->processAction($this->page, $action);
|
||||
|
||||
if(!empty($result['updateItem'])) {
|
||||
$result['child'] = $renderer->renderChild($this->page);
|
||||
unset($result['updateItem']);
|
||||
}
|
||||
|
||||
if(!empty($result['appendItem'])) {
|
||||
$newChild = $this->wire('pages')->get((int) $result['appendItem']);
|
||||
$result['newChild'] = $renderer->renderChild($newChild);
|
||||
unset($result['appendItem']);
|
||||
}
|
||||
|
||||
header("Content-type: application/json");
|
||||
|
||||
return json_encode($result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $selectorString
|
||||
* @param Page $page
|
||||
* @return PageArray
|
||||
*
|
||||
*/
|
||||
public function ___find($selectorString, Page $page) {
|
||||
return $page->children($selectorString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a value to this Page List (see WireData)
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return Process|ProcessPageList
|
||||
*
|
||||
*/
|
||||
public function set($key, $value) {
|
||||
@@ -490,13 +596,19 @@ class ProcessPageList extends Process implements ConfigurableModule {
|
||||
|
||||
/**
|
||||
* Build a form allowing configuration of this Module
|
||||
*
|
||||
* @param array $data
|
||||
* @return InputfieldWrapper
|
||||
*
|
||||
*/
|
||||
public function getModuleConfigInputfields(array $data) {
|
||||
|
||||
/** @var InputfieldWrapper $fields */
|
||||
$fields = $this->wire(new InputfieldWrapper());
|
||||
/** @var Modules $modules */
|
||||
$modules = $this->wire('modules');
|
||||
|
||||
/** @var InputfieldText $field */
|
||||
$field = $modules->get("InputfieldText");
|
||||
$field->attr('name', 'pageLabelField');
|
||||
$field->attr('value', !empty($data['pageLabelField']) ? $data['pageLabelField'] : 'title');
|
||||
@@ -509,10 +621,10 @@ class ProcessPageList extends Process implements ConfigurableModule {
|
||||
$bookmarks->addConfigInputfields($fields);
|
||||
$admin = $this->wire('pages')->get($this->wire('config')->adminRootPageID);
|
||||
$page = $this->wire('pages')->get($admin->path . 'page/list/');
|
||||
$bookmarks->checkprocessPage($page);
|
||||
$bookmarks->checkProcessPage($page);
|
||||
|
||||
$settings = $this->wire('config')->pageList;
|
||||
/*
|
||||
$settings = $this->wire('config')->pageList;
|
||||
if(empty($settings['useHoverActions'])) {
|
||||
$field = $modules->get('InputfieldCheckbox');
|
||||
$field->attr('name', 'useHoverActions');
|
||||
@@ -526,7 +638,8 @@ class ProcessPageList extends Process implements ConfigurableModule {
|
||||
|
||||
$defaultNote1 = $this->_('Default value is %d.');
|
||||
$defaultNote2 = $this->_('If left at the default value, this setting can also be specified in the $config->pageList array.');
|
||||
|
||||
|
||||
/** @var InputfieldInteger $field */
|
||||
$field = $modules->get("InputfieldInteger");
|
||||
$field->attr('name', 'limit');
|
||||
$field->attr('value', !empty($data['limit']) ? (int) $data['limit'] : self::defaultLimit);
|
||||
@@ -534,6 +647,7 @@ class ProcessPageList extends Process implements ConfigurableModule {
|
||||
$field->notes = sprintf($defaultNote1, self::defaultLimit) . ' ' . $defaultNote2;
|
||||
$fields->append($field);
|
||||
|
||||
/** @var InputfieldInteger $field */
|
||||
$field = $modules->get("InputfieldInteger");
|
||||
$field->attr('name', 'speed');
|
||||
$field->attr('value', array_key_exists('speed', $data) ? (int) $data['speed'] : self::defaultSpeed);
|
||||
|
Reference in New Issue
Block a user