artabro/wire/modules/Process/ProcessPageEdit/PageBookmarks.php

321 lines
10 KiB
PHP
Raw Normal View History

2024-08-27 11:35:37 +02:00
<?php namespace ProcessWire;
/**
* Class PageBookmarks
*
* Class for managing Page bookmarks, currently used by ProcessPageEdit and ProcessPageList
*
*/
class PageBookmarks extends Wire {
/**
* @var Process
*
*/
protected $process;
/**
* @var array
*
*/
protected $labels = array();
/**
* @param Process|ProcessPageEdit $process
*
*/
public function __construct(Process $process) {
parent::__construct();
$this->process = $process;
$this->labels = array(
'bookmarks' => $this->_('Bookmarks'),
'edit-bookmarks' => $this->_('Edit Bookmarks'),
'all' => $this->_('all'),
);
}
/**
* Initialize/create the $options array for executeNavJSON() in Process modules
*
* @param array $options
* @return array
*
*/
public function initNavJSON(array $options = array()) {
$pages = $this->wire()->pages;
$user = $this->wire()->user;
$modules = $this->wire()->modules;
$bookmarkFields = array();
$bookmarksArray = array();
$rolesArray = array();
$data = $modules->getModuleConfigData($this->process);
$iconKey = isset($options['iconKey']) ? $options['iconKey'] : '_icon';
$classKey = isset($options['classKey']) ? $options['classKey'] : '_class';
$options['classKey'] = $classKey;
$options['iconKey'] = $iconKey;
if(!isset($options['defaultIcon'])) $options['defaultIcon'] = 'arrow-circle-right';
foreach($this->wire()->user->roles as $role) {
if($role->name === 'guest') continue;
$value = isset($data["bookmarks"]["_$role->id"]) ? $data["bookmarks"]["_$role->id"] : array();
if(empty($value)) continue;
$bookmarkFields[$role->name] = $value;
$rolesArray[$role->name] = $role;
}
$bookmarkFields['bookmarks'] = isset($data['bookmarks']["_0"]) ? $data['bookmarks']["_0"] : array();
$n = 0;
foreach($bookmarkFields as $name => $bookmarkIDs) {
$bookmarks = count($bookmarkIDs) ? $pages->getById($bookmarkIDs) : array();
$role = isset($rolesArray[$name]) ? $rolesArray[$name] : null;
foreach($bookmarks as $page) {
if($this->process == 'ProcessPageEdit' && !$page->editable()) continue;
else if($this->process == 'ProcessPageAdd' && !$page->addable()) continue;
else if(!$page->listable()) continue;
if(isset($bookmarksArray[$page->id])) continue;
$icon = $page->template->getIcon();
if(!$icon) $icon = $options['defaultIcon'];
$page->setQuietly($iconKey, $icon);
$page->setQuietly('_roleName', $role ? $role->name : $this->labels['all']);
$bookmarksArray[$page->id] = $page;
}
$n++;
}
if(empty($options['add'])) {
if($user->isSuperuser()) {
$options['add'] = 'bookmarks/?role=0';
$options['addLabel'] = $this->labels['bookmarks'];
$options['addIcon'] = 'bookmark-o';
} else {
$options['add'] = null;
}
} else if($user->isSuperuser()) {
$add = $this->wire(new WireData());
$add->set('_icon', 'bookmark-o');
$add->set('title', $this->labels['bookmarks']);
$add->set('id', 'bookmark');
$add->set($classKey, 'separator');
array_unshift($bookmarksArray, $add);
}
if(isset($options['items'])) {
$options['items'] = $options['items'] + $bookmarksArray;
} else {
$options['items'] = $bookmarksArray;
}
if(!isset($options['itemLabel'])) $options['itemLabel'] = 'title|name';
if(!isset($options['sort'])) $options['sort'] = false;
if(!isset($options['iconKey'])) $options['iconKey'] = '_icon';
if(empty($options['edit'])) {
$options['edit'] = $this->wire()->config->urls->admin . 'page/edit/?id={id}';
}
return $options;
}
/**
* Render list of current bookmarks
*
* @return string
*
*/
public function listBookmarks() {
$sanitizer = $this->wire()->sanitizer;
$config = $this->wire()->config;
$config->styles->add($config->urls('ProcessPageEdit') . 'PageBookmarks.css');
$superuser = $this->wire()->user->isSuperuser();
$out = '';
$options = $this->initNavJSON();
$noneHeadline = $this->_('There are currently no bookmarks defined');
foreach($options['items'] as $item) {
/** @var WireData $item */
if($item->id == 'bookmark') continue;
$url = str_replace('{id}', $item->id, $options['edit']);
$icon = $item->_icon ? "<i class='fa fa-fw fa-$item->_icon'></i> " : "";
$out .=
"<li class='$item->_class'>" .
"<a href='$url'>$icon" . $sanitizer->entities1($item->get('title|name')) . "</a>" .
"</li>";
}
$icon = "<i class='fa fa-fw fa-lg fa-bookmark-o'></i> ";
if($out) {
$out = "<h2>$icon" . $this->labels['bookmarks'] . "</h2><ul class='bookmarks'>$out</ul>";
} else {
$out = "<h2>$icon$noneHeadline</h2>";
}
if($superuser) {
/** @var InputfieldButton $button */
$button = $this->wire()->modules->get('InputfieldButton');
$button->href = "./?role=0";
$button->value = $this->labels['edit-bookmarks'];
$button->icon = 'edit';
$button->showInHeader();
$out .= $button->render();
}
return $out;
}
/**
* Provides the editor for bookmarks and returns InputfieldForm
*
* @return InputfieldForm
* @throws WirePermissionException|WireException
*
*/
public function editBookmarksForm() {
$modules = $this->wire()->modules;
$input = $this->wire()->input;
$roles = $this->wire()->roles;
$roleID = $input->get('role');
if(is_null($roleID) && $input->get('id') === 'bookmarks') $roleID = 0;
$roleID = (int) $roleID;
if(!$this->wire()->user->isSuperuser()) throw new WirePermissionException("Superuser required to define bookmarks");
$moduleInfo = $modules->getModuleInfo($this->process);
$this->process->breadcrumb('../', $this->_($moduleInfo['title']));
$this->process->breadcrumb('./', $this->labels['bookmarks']);
$role = $roleID ? $roles->get($roleID) : $this->wire()->pages->newNullPage();
if($roleID && !$role->id) throw new WireException("Unknown role");
$allLabel = $this->_('everyone'); // All roles
$data = $modules->getModuleConfigData($this->process);
$headline = $this->labels['edit-bookmarks'];
$title = sprintf($this->_('Bookmarks for: %s'), ($role->id ? $role->name : $allLabel));
$this->process->headline($headline);
$this->process->browserTitle($title);
/** @var InputfieldForm $form */
$form = $modules->get('InputfieldForm');
$form->action = "./?role=$role->id";
$form->addClass('InputfieldFormConfirm');
$form->description = sprintf($this->_('%s Bookmark Editor'), __($moduleInfo['title'], '/wire/templates-admin/default.php'));
$form->appendMarkup = "<p style='clear:both' class='detail'><br /><i class='fa fa-info-circle ui-priority-secondary'></i> " .
$this->_('Note that only superusers are able to see this editor.') . "</p>";
/** @var InputfieldPageListSelectMultiple $field */
$field = $modules->get('InputfieldPageListSelectMultiple');
$field->attr('name', 'bookmarks');
$field->label = $title;
$field->icon = 'bookmark-o';
$field->startLabel = $this->_('Add Bookmark');
$field->description = $this->_('Click the "add bookmark" action below to select page(s) to add as bookmarks. If you want the bookmarks to only appear for a specific user role, first select the role above.');
$class = $role->id ? '' : 'ui-state-disabled';
$out = "<ul class='PageListActions actions'><li><a class='$class' href='./?role=0'>$allLabel</a></li>";
foreach($roles as $r) {
if($r->name === 'guest') continue;
$class = $r->id == $role->id ? 'ui-state-disabled' : '';
$o = "<a class='$class' href='./?role=$r->id'>$r->name</a>";
$out .= "<li>$o</li>";
}
$out .= "</ul>";
$field->prependMarkup = $out;
if(!isset($data["bookmarks"])) $data["bookmarks"] = array();
$value = isset($data["bookmarks"]["_$role->id"]) ? $data["bookmarks"]["_$role->id"] : array();
if(!is_array($value)) $value = array();
$field->attr('value', $value);
$form->add($field);
/** @var InputfieldSubmit $submit */
$submit = $modules->get('InputfieldSubmit');
$submit->attr('name', 'submit_save_bookmarks');
$submit->showInHeader();
$form->add($submit);
if($form->isSubmitted('submit_save_bookmarks')) {
// save bookmarks
$form->process();
$bookmarks = $field->attr('value');
// clear out bookmarks for roles that no longer exist
foreach($data['bookmarks'] as $_roleID => $_bookmarks) {
if($_roleID == "_0") continue;
$r = $roles->get((int) ltrim($_roleID, '_'));
if(!$r->id) unset($data['bookmarks'][$_roleID]);
}
// update bookmarks for role
$data["bookmarks"]["_$role->id"] = $bookmarks;
// save to module config data
$modules->saveModuleConfigData($this->process, $data);
$this->message($this->_('Saved bookmarks'));
$this->wire()->session->location("./?role=$role->id");
}
return $form;
}
/**
* Provides the editor or list for bookmarks and returns rendered markup
*
* @return string
* @throws WirePermissionException
*
*/
public function editBookmarks() {
$input = $this->wire()->input;
$roleID = $input->get('role');
if(is_null($roleID)) {
if($input->get('id') === 'bookmarks') {
// ok
} else {
return $this->listBookmarks();
}
}
return $this->editBookmarksForm()->render();
}
/**
* Check and update the given process page for hidden/visible status depending on useBookmarks setting
*
* @param Page $page
*
*/
public function checkProcessPage(Page $page) {
$hidden = $page->isHidden();
if($this->process->useBookmarks) {
if($hidden) {
$page->removeStatus(Page::statusHidden);
$page->save();
}
} else if(!$hidden) {
$page->addStatus(Page::statusHidden);
$page->save();
}
}
/**
* Populate any configuration inputfields to the given $inputfields wrapper for $process
*
* @param InputfieldWrapper $inputfields
*
*/
public function addConfigInputfields(InputfieldWrapper $inputfields) {
/** @var InputfieldCheckbox $field */
$field = $this->wire()->modules->get('InputfieldCheckbox');
$field->attr('name', 'useBookmarks');
$field->label = $this->_('Allow use of bookmarks?');
$field->description = $this->_('Bookmarks enable you to create shortcuts to pages from this module, configurable by user role. Useful for large applications.');
$field->icon = 'bookmark-o';
if($this->process->useBookmarks) $field->attr('checked', 'checked');
$inputfields->add($field);
}
}