class_simpleManagement.inc 41.19 KiB
<?php
/*
  This code is part of FusionDirectory (http://www.fusiondirectory.org/)
  Copyright (C) 2013-2016  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.
class templateDialog
  protected $simpleManagement;
  protected $type;
  protected $template = NULL;
  protected $templates;
  protected $target = NULL;
  protected $tabObject;
  protected $post_finish = 'template_continue';
  protected $post_cancel = 'template_cancel';
  function __construct($simpleManagement, $type, $dn = NULL, $target = NULL)
    $this->simpleManagement = $simpleManagement;
    $this->type             = $type;
    $this->templates        = objects::getTemplates($this->type);
    if ($dn !== NULL) {
      if (isset($this->templates[$dn])) {
        $this->template = new template($this->type, $dn);
      } else {
        trigger_error('Unknown template "'.$dn.'"');
    $this->target = $target;
  function save_object ()
    if (isset($_POST[$this->post_cancel])) {
      return $this->handle_cancel();
    if (($this->target === NULL) &&
        (isset($_POST[$this->post_finish]) || isset($_GET[$this->post_finish])) &&
        is_object($this->template)) {
      $this->template->save_object();
      return $this->handle_finish();
    if (
      isset($_POST['template']) &&
      isset($this->templates[$_POST['template']])
      ) {
      if (is_object($this->template)) {
        trigger_error('redefining template object');
      $this->template = new template($this->type, $_POST['template']);
      /* This method can loop if there are several targets */
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
unset($_POST['template']); } if (is_object($this->template)) { if ($this->target !== NULL) { $this->simpleManagement->openTabObject($this->template->apply($this->target), $this->template->getBase()); $this->simpleManagement->handleTemplateApply(); return FALSE; } else { $this->template->save_object(); } } return TRUE; } function setNextTarget ($target) { $this->target = $target; $this->template->reset(); } function execute () { $smarty = get_smarty(); if (is_object($this->template)) { $smarty->assign('template_dialog', $this->template->execute()); } else { $smarty->assign('templates', $this->templates); } $display = $smarty->fetch(get_template_path('template.tpl')); return $display; } function handle_finish () { $this->simpleManagement->closeDialogs(); $this->simpleManagement->openTabObject($this->template->apply(), $this->template->getBase()); return FALSE; } function handle_cancel () { $this->simpleManagement->closeDialogs(); return FALSE; } } class simpleManagement { // The currently used object(s) (e.g. in edit, removal) // $dn is public due to some compatibility problems with class plugin.. public $dn = ''; protected $dns = array(); // The last used object(s). protected $last_dn = ''; protected $last_dns = array(); // The common places the displayed objects are stored in. (e.g. array("ou=groups,","..")) protected $storagePoints = array(); // The opened object. protected $tabObject = NULL; protected $dialogObject = NULL; // The last opened object. protected $last_tabObject = NULL; protected $last_dialogObject = NULL; // Whether to display the apply button or not
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
protected $displayApplyBtn = FALSE; // Whether to display a header or not. protected $skipHeader = FALSE; // Whether to display a footer or not. protected $skipFooter = FALSE; // Copy&Paste handler protected $cpHandler = NULL; // Indicates that we want to paste objects right now. protected $cpPastingStarted = FALSE; // The Snapshot handler class. protected $snapHandler = NULL; // The listing handlers protected $headpage = NULL; protected $filter = NULL; // A list of configured actions/events protected $actions = array(); // Some management classes are used in tab groups and needs this public $is_template = FALSE; public $attributes = array(); /* Attributes that child classes should override */ protected $objectTypes = array(); /* Attributes that child classes can override */ protected $departmentBrowser = TRUE; protected $departmentRootVisible = TRUE; protected $baseMode = TRUE; protected $multiSelect = TRUE; protected $filterXMLPath = NULL; protected $listXMLPath = NULL; protected $autoFilter = TRUE; protected $autoActions = TRUE; protected $skipCpHandler = FALSE; protected $skipSnapHandler = FALSE; protected $autoFilterAttributes = array('dn', 'cn', 'description'); protected $headpageClass = "listing"; public static $skipTemplates = TRUE; function __construct() { global $config; if ($this->filterXMLPath === NULL) { $this->filterXMLPath = get_template_path('simple-filter.xml', TRUE, dirname(__FILE__)); } if ($this->listXMLPath === NULL) { $this->listXMLPath = get_template_path('simple-list.xml', TRUE, dirname(__FILE__)); } foreach ($this->objectTypes as &$object) { $object = strtoupper($object); } unset($object); $this->storagePoints = array(); foreach ($this->objectTypes as $key => $object) { try { $i = objects::infos($object);
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
} catch (NonExistingObjectTypeException $e) { /* Remove objectTypes which are not existing */ unset($this->objectTypes[$key]); continue; } if ($i['ou'] !== NULL) { $this->storagePoints[] = $i['ou']; } } $this->storagePoints = array_unique($this->storagePoints); if (count($this->storagePoints) == 0) { $this->storagePoints[] = ''; } // Build filter if (session::global_is_set(get_class($this).'_filter')) { $filter = session::global_get(get_class($this).'_filter'); } else { $filter = new filter($this->filterXMLPath); $filter->setObjectStorage($this->storagePoints); } $this->setFilter($filter); // Build headpage $this->headpage = new $this->headpageClass($this->parseXML($this->listXMLPath)); $this->headpage->setFilter($filter); // Add copy&paste and snapshot handler. if (!$this->skipCpHandler) { $this->cpHandler = new CopyPasteHandler(); $this->headpage->setCopyPasteHandler($this->cpHandler); $this->registerAction('copy', 'copyPasteHandler'); $this->registerAction('cut', 'copyPasteHandler'); $this->registerAction('paste', 'copyPasteHandler'); } if (!$this->skipSnapHandler && ($config->get_cfg_value('enableSnapshots') == 'TRUE')) { $this->snapHandler = new SnapshotHandler(); $this->headpage->setSnapshotHandler($this->snapHandler); $this->registerAction('snapshot', 'createSnapshotDialog'); $this->registerAction('restore', 'restoreSnapshotDialog'); } // Register default actions $this->registerAction('new', 'newEntry'); $this->registerAction('edit', 'editEntry'); $this->registerAction('apply', 'applyChanges'); $this->registerAction('save', 'saveChanges'); $this->registerAction('cancel', 'cancelEdit'); $this->registerAction('cancelDelete', 'cancelEdit'); $this->registerAction('remove', 'removeEntryRequested'); $this->registerAction('removeConfirmed', 'removeEntryConfirmed'); $this->configureHeadpage(); $this->configureFilter(); if ($this->baseMode === FALSE) { $this->headpage->setBase($config->current['BASE']); } } /* Build the action menu, fill the object definition, etc, based on objectTypes info */ function configureHeadpage () { if ($this->autoActions) { if (static::$skipTemplates) { $this->headpage->xmlData['actionmenu']['action'][0]['action'] = array(); } else { $this->headpage->xmlData['actionmenu']['action'][0]['action'] = array( array(
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
'type' => 'sub', 'image' => 'geticon.php?context=devices&icon=template&size=16', 'label' => _('Template'), 'action' => array(), ), array( 'type' => 'sub', 'image' => 'geticon.php?context=actions&icon=document-new&size=16', 'label' => _('From template'), 'action' => array(), ), ); } } $this->configureHeadline(); foreach ($this->objectTypes as $object) { $i = objects::infos($object); if (!isset($i['icon'])) { trigger_error('Missing icon for type '.$object); $i['icon'] = ''; } $filterObject = objects::getFilterObject($object); $this->headpage->objectTypes[$object] = array( 'label' => $i['name'], 'category' => $i['aclCategory'], 'class' => $i['mainTab'], 'image' => $i['icon'], 'filter' => $filterObject, 'nameAttr' => $i['nameAttr'], ); if (!static::$skipTemplates) { $this->headpage->objectTypes['template_'.$object] = array( 'label' => sprintf(_('%s template'), $i['name']), 'category' => $i['aclCategory'], 'class' => 'template', 'image' => 'geticon.php?context=devices&icon=template&size=16', 'filter' => new ldapFilter( '&', array( new ldapFilterLeaf('objectClass', '=', 'fdTemplate'), fdTemplateFilter($filterObject), ) ), 'nameAttr' => $i['nameAttr'], ); } $this->headpage->categories[] = $i['aclCategory']; if ($this->autoActions) { $this->registerAction('new_'.$object, 'newEntry'); $icon = 'geticon.php?context=actions&amp;icon=document-new&amp;size=16'; if (isset($i['icon'])) { $icon = $i['icon']; } else { $infos = pluglist::pluginInfos($i['mainTab']); if (isset($infos['plIcon'])) { $icon = $infos['plIcon']; } } $this->headpage->xmlData['actionmenu']['action'][0]['action'][] = array( 'name' => 'new_'.$object, 'type' => 'entry', 'image' => $icon, 'label' => $i['name'], 'acl' => $i['aclCategory'].'/'.$i['mainTab'].'[c]', );
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
if (!static::$skipTemplates) { $this->registerAction('new_template_'.$object, 'newEntryTemplate'); $this->registerAction('template_apply_'.$object, 'newEntryFromTemplate'); $this->headpage->xmlData['actionmenu']['action'][0]['action'][0]['action'][] = array( 'name' => 'new_template_'.$object, 'type' => 'entry', 'image' => $icon, 'label' => $i['name'], 'acl' => $i['aclCategory'].'/template[c]', ); $this->headpage->xmlData['actionmenu']['action'][0]['action'][1]['action'][] = array( 'name' => 'template_apply_'.$object, 'type' => 'entry', 'image' => $icon, 'label' => $i['name'], 'acl' => $i['aclCategory'].'/'.$i['mainTab'].'[c]', ); } } } if ($this->autoActions && !static::$skipTemplates) { $this->registerAction('template_apply', 'newEntryFromTemplate'); } $this->headpage->refreshBasesList(); } function configureHeadline () { $pInfos = pluglist::pluginInfos(get_class($this)); $this->headpage->headline = $pInfos['plShortName']; } function configureFilterCategory () { $pInfos = pluglist::pluginInfos(get_class($this)); $cat = NULL; if (isset($pInfos['plCategory'])) { $cat = key($pInfos['plCategory']); if (is_numeric($cat)) { $cat = $pInfos['plCategory'][$cat]; } } elseif (isset($pInfos['plObjectType'])) { $ot = key($pInfos['plObjectType']); if (is_numeric($ot)) { $ot = $pInfos['plObjectType'][$ot]; } $infos = objects::infos($ot); $cat = $infos['aclCategory']; } if ($cat === NULL) { trigger_error('Could not find a category for '.get_class($this)); } $this->filter->category = $cat; } /* Build the filter(s) based on objectTypes info */ function configureFilter () { if ($this->autoFilter) { $this->configureFilterCategory(); $attributes = $this->autoFilterAttributes; $filter = '(|'; foreach ($this->objectTypes as $object) { $tag = 'FILTER'.$object; $filter .= '$'.$tag; $i = objects::infos($object); $this->filter->elements[$tag] = array( 'type' => 'checkbox', 'tag' => $tag, 'default' => TRUE,
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
'unset' => array(), 'set' => preg_replace('/\$/', '\\\$', $i['filter']) ); $this->filter->elementValues[$tag] = TRUE; if ($i['mainAttr']) { $attributes[] = $i['mainAttr']; } if ($i['nameAttr']) { $attributes[] = $i['nameAttr']; } } if (!static::$skipTemplates) { $tag = 'FILTERTEMPLATE'; $filter .= '$'.$tag; $this->filter->elements[$tag] = array( 'type' => 'checkbox', 'tag' => $tag, 'default' => TRUE, 'unset' => array(), 'set' => '(objectClass=fdTemplate)' ); $this->filter->elementValues[$tag] = TRUE; $attributes[] = 'fdTemplateField'; } $filter .= ')'; $attributes = array_values(array_unique($attributes)); $this->filter->query[0]['filter'] = '(&'.$filter.'$NAME)'; $this->filter->query[0]['attribute'] = $attributes; $this->filter->elements['NAME']['set'] = '(|('.join('=*$*)(', $attributes).'=*$*))'; $this->filter->elements['NAME']['autocomplete']['filter'] = '(&'.$filter.'(|('.join('=*$NAME*)(', $attributes).'=*$NAME*))'.')'; $this->filter->elements['NAME']['autocomplete']['attribute'] = $attributes; uasort($this->filter->elements, 'strlenSort'); $this->filter->elements = array_reverse($this->filter->elements); } } function parseXML ($file) { $contents = file_get_contents($file); $data = xml::xml2array($contents, 1); foreach (array('departmentBrowser','departmentRootVisible','baseMode','multiSelect') as $var) { $data['list']['definition']["$var"] = ($this->$var ? 'true' : 'false'); } return $data; } function getHeadpage() { return $this->headpage; } function getFilter() { return $this->filter; } /*! * \brief Set a new filter * * \param object $filter The new filter */ function setFilter($filter) { $this->filter = $filter; } /*! * \brief Every click in the list user interface sends an event * here can we connect those events to a method.
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
* eg. see simpleManagement::registerEvent('new','createUser') * When the action/event new is send, the method 'createUser' * will be called. */ function registerAction($action, $target) { $this->actions[$action] = $target; } function getType($dn) { return $this->getHeadpage()->getType($dn); } function renderList() { global $config; $smarty = get_smarty(); $filters = array(); foreach ($this->objectTypes as $object) { $filters[] = array( 'id' => 'FILTER'.$object, 'label' => sprintf(_('Show %s'), $config->data['OBJECTS'][$object]['name']) ); } if (!static::$skipTemplates) { $filters[] = array( 'id' => 'FILTERTEMPLATE', 'label' => sprintf(_('Show %s'), _('Template')) ); } $smarty->assign('objectFilters', $filters); $this->headpage->update(); $display = $this->headpage->render(); return $this->getHeader().$display; } /*! * \brief Execute this plugin * Handle actions/events, locking, snapshots, dialogs, tabs,... */ function execute() { // Ensure that html posts and gets are kept even if we see a 'Entry islocked' dialog. $vars = array('/^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; } // Update filter if ($this->filter) { $this->filter->update(); session::global_set(get_class($this).'_filter', $this->filter); session::set('autocomplete', $this->filter); if (!$this->filter->isValid()) { msg_dialog::display(_('Filter error'), _('The filter is incomplete!'), ERROR_DIALOG); } } // Handle actions (POSTs and GETs) $str = $this->handleActions($this->detectPostActions()); if ($str) { return $this->getHeader().$str; } // Open single dialog objects
561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
if (is_object($this->dialogObject)) { if (method_exists($this->dialogObject, 'save_object')) { $this->dialogObject->save_object(); } if (method_exists($this->dialogObject, 'execute')) { $display = $this->dialogObject->execute(); $display .= $this->_getTabFooter(); return $this->getHeader().$display; } } // Display tab object. if ($this->tabObject instanceOf simpleTabs) { $this->tabObject->save_object(); $display = $this->tabObject->execute(); $display .= $this->_getTabFooter(); return $this->getHeader().$display; } // Set current restore base for snapshot handling. if (is_object($this->snapHandler)) { $bases = array(); foreach ($this->storagePoints as $sp) { $bases[] = $sp.$this->headpage->getBase(); } // No bases specified? Try base if (!count($bases)) { $bases[] = $this->headpage->getBase(); } $this->snapHandler->setSnapshotBases($bases); } // Display list return $this->renderList(); } /*! * \brief Generates the plugin header which is displayed whenever a tab object is opened. */ protected function getHeader() { if ($this->skipHeader) { return ''; } $plInfos = pluglist::pluginInfos(get_class($this)); $plTitle = $plInfos['plTitle']; $plIcon = $plInfos['plIcon']; if (!preg_match('/^geticon/', $plIcon)) { $plIcon = get_template_path($plIcon); } return print_header($plIcon, $plTitle, get_object_info()); } /*! * \brief Generates the footer which is used whenever a tab object is displayed. */ protected function _getTabFooter() { // Do not display tab footer for non tab objects if (!($this->tabObject instanceOf simpleTabs)) { return ''; } // Check if there is a dialog opened - We don't need any buttons in this case. if ($this->tabObject->dialogOpened()) { return '';
631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
} // Skip footer if requested; if ($this->skipFooter) { return ''; } // In case an of locked entry, we may have opened a read-only tab. $str = ''; if ($this->tabObject->readOnly()) { $str .= '<p class="plugbottom">'."\n". '<input type="submit" name="edit_cancel" value="'.msgPool::cancelButton().'">'."\n". '</p>'; return $str; } else { // Display ok, (apply) and cancel buttons $str .= '<p class="plugbottom">'."\n"; $str .= '<input type="submit" name="edit_finish" style="width:80px" value="'.msgPool::okButton().'"/>'."\n"; $str .= "&nbsp;\n"; if ($this->displayApplyBtn) { $str .= '<input type="submit" name="edit_apply" value="'.msgPool::applyButton().'"/>'."\n"; $str .= "&nbsp;\n"; } $str .= '<input type="submit" name="edit_cancel" value="'.msgPool::cancelButton().'"/>'."\n"; $str .= '</p>'; } return $str; } /*! * \brief This method intiates the object creation. * * \param String $action The name of the action which was the used as trigger. * * \param Array $target A list of object dns, which should be affected by this method. * * \param Array $all A combination of both 'action' and 'target'. */ function newEntry($action, array $target, array $all) { $type = strtoupper(preg_replace('/^new_/', '', $action)); $this->displayApplyBtn = FALSE; $this->dn = 'new'; $this->is_single_edit = FALSE; set_object_info($this->dn); // Open object $this->openTabObject(objects::open($this->dn, $type), $this->headpage->getBase()); @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $this->dn, "Create new entry initiated!"); } function newEntryTemplate($action, array $target, array $all) { if (static::$skipTemplates) { return; } $action = preg_replace('/^new_template_/', 'new_', $action); $this->newEntry($action, $target, $all); $this->tabObject->setTemplateMode('template_cn'); } function newEntryFromTemplate($action, array $target, array $all) { if (static::$skipTemplates) { return; } if (isset ($target[0])) { $dn = $target[0];
701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
} else { $dn = NULL; } if ($action == 'template_apply') { if ($dn === NULL) { return; } $type = $this->getType($dn); $type = preg_replace('/^template_/', '', $type); } else { $type = preg_replace('/^template_apply_/', '', $action); } $this->dialogObject = new templateDialog($this, $type, $dn); } function applyTemplateToEntry($action, array $target, array $all) { global $ui; if (static::$skipTemplates) { return; } if (empty($target)) { return; } $type = preg_replace('/^template_apply_to_/', '', $action); $this->dns = $target; // check locks if ($locks = get_locks($this->dns)) { return gen_locked_message($locks, $this->dns); } // Add locks add_lock ($this->dns, $ui->dn); $this->dn = array_shift($this->dns); $this->dialogObject = new templateDialog($this, $type, NULL, $this->dn); } function handleTemplateApply ($cancel = FALSE) { if (static::$skipTemplates) { return; } if ($cancel) { $msgs = array(); } else { $msgs = $this->tabObject->save(); } if (count($msgs)) { msg_dialog::displayChecks($msgs); return; } else { if (!$cancel) { @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $this->dn, 'Template applied!'); } del_lock($this->dn); if (empty($this->dns)) { $this->closeDialogs(); } else { $this->last_tabObject = $this->tabObject; $this->tabObject = NULL; $this->dn = array_shift($this->dns); $this->dialogObject->setNextTarget($this->dn); $this->dialogObject->save_object(); } } } /*!
771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
* \brief Save object modifications and closes dialogs (returns to object listing). * - Calls 'simpleTabs::save' to save back object modifications (e.g. to ldap). * - Calls 'simpleManagement::closeDialogs' to return to the object listing. */ protected function saveChanges() { if (($this->tabObject instanceOf simpleTabs) && ($this->dialogObject instanceOf templateDialog)) { $this->tabObject->save_object(); $this->handleTemplateApply(); return; } if ($this->tabObject instanceOf simpleTabs) { $this->tabObject->save_object(); $msgs = $this->tabObject->save(); if (count($msgs)) { msg_dialog::displayChecks($msgs); return; } else { @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $this->dns, 'Entry saved!'); $this->remove_lock(); $this->closeDialogs(); } } elseif ($this->dialogObject instanceOf simplePlugin) { $this->dialogObject->save_object(); $msgs = $this->dialogObject->check(); if (count($msgs)) { msg_dialog::displayChecks($msgs); return; } else { $this->dialogObject->save(); @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $this->dns, 'Entry saved!'); $this->remove_lock(); $this->closeDialogs(); } } } /*! * \brief Save object modifications and keep dialogs opened */ protected function applyChanges() { if ($this->tabObject instanceOf simpleTabs) { $this->tabObject->save_object(); $msgs = $this->tabObject->save(); if (count($msgs)) { msg_dialog::displayChecks($msgs); } else { @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $this->dns, 'Modifications applied!'); $this->tabObject->re_init(); } } } /*! * \brief Editing an object was caneled. * Close dialogs/tabs and remove locks. */ protected function cancelEdit() { if (($this->tabObject instanceOf simpleTabs) && ($this->dialogObject instanceOf templateDialog)) { $this->handleTemplateApply(TRUE); return; } $this->remove_lock(); $this->closeDialogs(); } /*! * \brief This method opens an existing object or a list of existing objects to be edited.