-
Côme Chilliet authored
tabObject is opened by the dialogObject save_object method, so the workflow is more complexed that I first thought. issue #5974
Unverified7cebf402
<?php
/*
This code is part of FusionDirectory (http://www.fusiondirectory.org/)
Copyright (C) 2017-2018 FusionDirectory
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*!
* \brief Management base class
*/
class management
{
/* Object types we are currently managing */
public $objectTypes;
/* managementListing instance which manages the entries */
public $listing;
/* managementFilter instance which manages the filters */
public $filter;
/* Copy&Paste */
protected $cpHandler = NULL;
protected $cpPastingStarted = FALSE;
protected $skipCpHandler = FALSE;
/* Snapshots */
protected $snapHandler = NULL;
public static $skipSnapshots = FALSE;
// The currently used object(s) (e.g. in edit, removal)
protected $currentDn = '';
protected $currentDns = [];
// The last used object(s).
protected $previousDn = '';
protected $previousDns = [];
// The opened object.
protected $tabObject = NULL;
protected $dialogObject = NULL;
// The last opened object.
protected $last_tabObject = NULL;
protected $last_dialogObject = NULL;
public $headline;
public $title;
public $icon;
protected $actions = [];
protected $actionHandlers = [];
protected $exporters = [];
public $neededAttrs = [];
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
public static $skipTemplates = TRUE;
/* Disable and hide configuration system */
protected $skipConfiguration = FALSE;
/* Default columns */
public static $columns = [
['ObjectTypeColumn', []],
['LinkColumn', ['attributes' => 'nameAttr', 'label' => 'Name']],
['LinkColumn', ['attributes' => 'description', 'label' => 'Description']],
['ActionsColumn', ['label' => 'Actions']],
];
// Whether to display a header or not.
protected $skipHeader = FALSE;
function __construct (
$objectTypes = FALSE,
array $filterElementDefinitions = [
['TabFilterElement', []],
]
)
{
global $config, $class_mapping;
if ($objectTypes === FALSE) {
$plInfos = pluglist::pluginInfos(get_class($this));
$objectTypes = $plInfos['plManages'];
}
if (!preg_match('/^geticon/', $this->icon)) {
$this->icon = get_template_path($this->icon);
}
/* Ignore non existing objectTypes. This happens when an optional plugin is missing. */
foreach ($objectTypes as $key => $type) {
try {
objects::infos($type);
$objectTypes[$key] = strtoupper($type);
} catch (NonExistingObjectTypeException $e) {
unset($objectTypes[$key]);
}
}
$this->objectTypes = array_values($objectTypes);
$this->setUpHeadline();
$this->setUpListing();
$this->setUpFilter($filterElementDefinitions);
// Add copy&paste and snapshot handler.
if (!$this->skipCpHandler) {
$this->cpHandler = new CopyPasteHandler();
}
if (!static::$skipSnapshots && ($config->get_cfg_value('enableSnapshots') == 'TRUE')) {
$this->snapHandler = new SnapshotHandler();
}
// Load exporters
foreach (array_keys($class_mapping) as $class) {
if (preg_match('/Exporter$/', $class)) {
$info = call_user_func([$class, 'getInfo']);
if ($info != NULL) {
$this->exporters = array_merge($this->exporters, $info);
}
}
}
$this->configureActions();
}
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
protected function setUpListing ()
{
$this->listing = new managementListing($this);
}
protected function setUpFilter (array $filterElementDefinitions)
{
$this->filter = new managementFilter($this, NULL, $filterElementDefinitions);
}
protected function setUpHeadline ()
{
$plInfos = pluglist::pluginInfos(get_class($this));
$this->headline = $plInfos['plShortName'];
$this->title = $plInfos['plTitle'];
$this->icon = $plInfos['plIcon'];
}
protected function configureActions ()
{
global $config;
// Register default actions
$createMenu = [];
if (!static::$skipTemplates) {
$templateMenu = [];
$fromTemplateMenu = [];
}
foreach ($this->objectTypes as $type) {
$infos = objects::infos($type);
$img = 'geticon.php?context=actions&icon=document-new&size=16';
if (isset($infos['icon'])) {
$img = $infos['icon'];
}
$createMenu[] = new Action(
'new_'.$type, $infos['name'], $img,
'0', 'newEntry',
[$infos['aclCategory'].'/'.$infos['mainTab'].'/c']
);
if (!static::$skipTemplates) {
$templateMenu[] = new Action(
'new_template_'.$type, $infos['name'], $img,
'0', 'newEntryTemplate',
[$infos['aclCategory'].'/template/c']
);
$fromTemplateMenu[] = new Action(
'template_apply_'.$type, $infos['name'], $img,
'0', 'newEntryFromTemplate',
[$infos['aclCategory'].'/template/r', $infos['aclCategory'].'/'.$infos['mainTab'].'/c']
);
}
}
if (!static::$skipTemplates) {
$createMenu =
array_merge(
[
new SubMenuAction(
'template', _('Template'), 'geticon.php?context=devices&icon=template&size=16',
$templateMenu
),
new SubMenuAction(
'fromtemplate', _('From template'), 'geticon.php?context=actions&icon=document-new&size=16',
$fromTemplateMenu
),
],
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
$createMenu
);
}
$this->registerAction(
new SubMenuAction(
'new', _('Create'), 'geticon.php?context=actions&icon=document-new&size=16',
$createMenu
)
);
// Add export actions
$exportMenu = [];
foreach ($this->exporters as $action => $exporter) {
$exportMenu[] = new Action(
$action, $exporter['label'], $exporter['image'],
'0', 'export'
);
}
$this->registerAction(
new SubMenuAction(
'export', _('Export list'), 'geticon.php?context=actions&icon=document-export&size=16',
$exportMenu
)
);
$this->registerAction(
new Action(
'edit', _('Edit'), 'geticon.php?context=actions&icon=document-edit&size=16',
'+', 'editEntry'
)
);
$this->actions['edit']->setSeparator(TRUE);
if (!$this->skipCpHandler) {
$this->registerAction(
new Action(
'cut', _('Cut'), 'geticon.php?context=actions&icon=edit-cut&size=16',
'+', 'copyPasteHandler',
['dr']
)
);
$this->registerAction(
new Action(
'copy', _('Copy'), 'geticon.php?context=actions&icon=edit-copy&size=16',
'+', 'copyPasteHandler',
['r']
)
);
$this->registerAction(
new Action(
'paste', _('Paste'), 'geticon.php?context=actions&icon=edit-paste&size=16',
'0', 'copyPasteHandler',
['w']
)
);
$this->actions['paste']->setEnableFunction([$this, 'enablePaste']);
}
if (!static::$skipTemplates) {
$this->registerAction(
new Action(
'template_apply_to', _('Apply template'), 'geticon.php?context=actions&icon=tools-wizard&size=16',
'+', 'applyTemplateToEntry',
['/template/r', 'c'],
TRUE,
FALSE
)
);
}
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
$this->registerAction(
new Action(
'remove', _('Remove'), 'geticon.php?context=actions&icon=edit-delete&size=16',
'+', 'removeRequested',
['d']
)
);
if (!static::$skipSnapshots && ($config->get_cfg_value('enableSnapshots') == 'TRUE')) {
$this->registerAction(
new Action(
'snapshot', _('Create snapshot'), 'geticon.php?context=actions&icon=snapshot&size=16',
'1', 'createSnapshotDialog',
['/snapshot/c']
)
);
$this->registerAction(
new Action(
'restore', _('Restore snapshot'), 'geticon.php?context=actions&icon=document-restore&size=16',
'*', 'restoreSnapshotDialog',
['w', '/snapshot/r']
)
);
$this->actions['snapshot']->setSeparator(TRUE);
$this->actions['restore']->setEnableFunction([$this, 'enableSnapshotRestore']);
}
if (!static::$skipTemplates) {
$this->registerAction(
new Action(
'template_apply', _('Create an object from this template'), 'geticon.php?context=actions&icon=document-new&size=16',
'1', 'newEntryFromTemplate',
['/template/r', 'c'],
FALSE,
TRUE,
['template']
)
);
}
/* Actions from footer are not in any menus and do not need a label */
$this->registerAction(new HiddenAction('apply', 'applyChanges'));
$this->registerAction(new HiddenAction('save', 'saveChanges'));
$this->registerAction(new HiddenAction('cancel', 'cancelEdit'));
$this->registerAction(new HiddenAction('cancelDelete', 'cancelEdit'));
$this->registerAction(new HiddenAction('removeConfirmed', 'removeConfirmed'));
if (!$this->skipConfiguration) {
$this->registerAction(new HiddenAction('configure', 'configureDialog'));
}
}
/*!
* \brief Register an action to show in the action menu and/or the action column
*/
function registerAction (Action $action)
{
$action->setParent($this);
$this->actions[$action->getName()] = $action;
foreach ($action->listActions() as $actionName) {
$this->actionHandlers[$actionName] = $action;
}
}
public function getColumnConfiguration (): array
{
global $config;
if (!isset($this->columnConfiguration)) {
// LDAP configuration
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
$this->columnConfiguration = $config->getManagementConfig(get_class($this));
}
if (!isset($this->columnConfiguration)) {
// Default configuration
$this->columnConfiguration = static::$columns;
}
// Session configuration
return $this->columnConfiguration;
}
public function setColumnConfiguration ($columns)
{
$this->columnConfiguration = $columns;
$this->listing->reloadColumns();
}
/*!
* \brief Detects actions/events send by the ui
* and the corresponding targets.
*/
function detectPostActions (): array
{
if (!is_object($this->listing)) {
throw new FusionDirectoryException('No valid listing object');
}
$action = ['targets' => [], 'action' => '', 'subaction' => NULL];
if ($this->showTabFooter()) {
if (isset($_POST['edit_cancel'])) {
$action['action'] = 'cancel';
} elseif (isset($_POST['edit_finish'])) {
$action['action'] = 'save';
} elseif (isset($_POST['edit_apply'])) {
$action['action'] = 'apply';
}
} elseif (!$this->dialogOpened()) {
if (isset($_POST['delete_confirmed'])) {
$action['action'] = 'removeConfirmed';
} elseif (isset($_POST['delete_cancel'])) {
$action['action'] = 'cancelDelete';
} else {
$action = $this->listing->getAction();
}
}
return $action;
}
/*!
* \brief Calls the registered method for a given action/event.
*/
function handleAction (array $action)
{
// Start action
if (isset($action['subaction']) && isset($this->actionHandlers[$action['action'].'_'.$action['subaction']])) {
return $this->actionHandlers[$action['action'].'_'.$action['subaction']]->execute($this, $action);
} elseif (isset($this->actionHandlers[$action['action']])) {
return $this->actionHandlers[$action['action']]->execute($this, $action);
}
}
protected function handleSubAction (array $action): bool
{
if (preg_match('/^tab_/', $action['subaction'])) {
$tab = preg_replace('/^tab_/', '', $action['subaction']);
if (isset($this->tabObject->by_object[$tab])) {
$this->tabObject->current = $tab;
} else {
trigger_error('Unknown tab: '.$tab);
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
}
return TRUE;
}
return FALSE;
}
/*!
* \brief Execute this plugin
* Handle actions/events, locking, snapshots, dialogs, tabs,...
*/
function execute (): string
{
// Ensure that html posts and gets are kept even if we see a 'Entry islocked' dialog.
$vars = ['/^act$/','/^listing/','/^PID$/'];
session::set('LOCK_VARS_TO_USE', $vars);
/* Display the copy & paste dialog, if it is currently open */
$ret = $this->copyPasteHandler();
if ($ret) {
return $this->getHeader().$ret;
}
// Handle actions (POSTs and GETs)
$action = $this->detectPostActions();
if (!empty($action['action'])) {
@DEBUG(DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $action, 'Action');
try {
$str = $this->handleAction($action);
if (!empty($str)) {
return $this->getHeader().$str;
}
} catch (FusionDirectoryException $e) {
msg_dialog::display(_('Error'), $e->getMessage(), ERROR_DIALOG);
}
}
/* Save tab or dialog object */
if ($this->tabObject instanceOf simpleTabs) {
$this->tabObject->save_object();
} elseif (is_object($this->dialogObject) && method_exists($this->dialogObject, 'save_object')) {
$this->dialogObject->save_object();
}
/* Display tab object */
if ($this->tabObject instanceOf simpleTabs) {
$display = $this->tabObject->execute();
$display .= $this->getTabFooter();
return $this->getHeader().$display;
}
/* Display dialog object */
if (is_object($this->dialogObject) && method_exists($this->dialogObject, 'execute')) {
$display = $this->dialogObject->execute();
$display .= $this->getTabFooter();
return $this->getHeader().$display;
}
// Update list
$this->listing->update();
// Init snapshot list for renderSnapshotActions
if (is_object($this->snapHandler)) {
$this->snapHandler->initSnapshotCache($this->listing->getBase());
}
// Display list
return $this->renderList();
}
function renderList (): string