FusionDirectory
 All Data Structures Files Functions Variables
class_simpleTabs.inc
Go to the documentation of this file.
1 <?php
2 /*
3  This code is part of FusionDirectory (http://www.fusiondirectory.org/)
4  Copyright (C) 2003-2010 Cajus Pollmeier
5  Copyright (C) 2011-2016 FusionDirectory
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21 
31 {
32  var $dn;
33  var $acl;
34  var $is_template;
35 
36  public $objectType = FALSE;
37  protected $specialTabs = TRUE;
38  protected $plNotify = array();
39 
40  var $last = "";
41  var $current = "";
42  var $disabled = "";
43  var $by_name = array();
44  var $by_object = array();
45  var $acl_category;
46 
47  /* A parent object if available, e.g. a management class. */
48  var $parent = NULL;
49 
50  var $baseclass = "";
51 
52  public $ignoreAcls = FALSE;
53 
57  function __construct($type, $dn, $attrs_object = NULL)
58  {
59  global $config;
60 
61  if (!is_string($type)) {
62  die('deprecated call to old tabclass constructor');
63  }
64 
65  $infos = objects::infos($type);
66  $data = $config->data['TABS'][$infos['tabGroup']];
67  $this->acl_category = $infos['aclCategory'];
68  $this->objectType = $type;
69  $this->dn = $dn;
70 
71  if (!count($data)) {
72  $data[] = array('CLASS' => 'plugin','NAME' => 'Error');
73  msg_dialog::display(_('Error'),
74  sprintf(_('No plugin definitions found to initialize "%s", please check your configuration file.'), get_class($this)),
75  ERROR_DIALOG);
76  }
77 
78  $baseobject = NULL;
79  foreach ($data as $tab) {
80  if (!plugin_available($tab['CLASS'])) {
81  continue;
82  }
83 
84  $this->by_name[$tab['CLASS']] = $tab['NAME'];
85  $this->plNotify[$tab['CLASS']] = FALSE;
86 
87  if ($baseobject === NULL) {
88  $baseobject = new $tab['CLASS']($this->dn, $attrs_object, $this, TRUE);
89  $this->by_object[$tab['CLASS']] = $baseobject;
90  $this->baseclass = $tab['CLASS'];
91  } else {
92  $this->by_object[$tab['CLASS']] = new $tab['CLASS']($this->dn, $baseobject, $this, FALSE);
93  }
94 
95  $this->by_object[$tab['CLASS']]->set_acl_category($this->acl_category);
96  }
97 
98  /* Initialize current */
99  $this->current = $this->baseclass;
100 
101  if ($infos['mainAttr']) {
102  $baseobject = $this->getBaseObject();
103  if (
104  ($baseobject instanceof simplePlugin) &&
105  ($baseobject->attributesAccess[$infos['mainAttr']]->getUnique() === FALSE)
106  ) {
107  $baseobject->attributesAccess[$infos['mainAttr']]->setUnique(TRUE);
108  }
109  }
110 
111  if ($this->specialTabs) {
112  /* Add references/acls/snapshots */
113  $this->addSpecialTabs();
114  }
115  }
116 
117 
123  function re_init()
124  {
125  $baseobject = NULL;
126  foreach ($this->by_object as $name => $object) {
127  $class = get_class($object);
128  if (in_array($class, array("reference","acl"))) {
129  continue;
130  }
131  if ($baseobject === NULL) {
132  $baseobject = new $class($this->dn, NULL, $this, TRUE);
133  $this->by_object[$name] = $baseobject;
134  } else {
135  $this->by_object[$name] = new $class($this->dn, $baseobject, $this, FALSE);
136  }
137  $this->by_object[$name]->set_acl_category($this->acl_category);
138  }
139  }
140 
141  function resetCopyInfos()
142  {
143  $this->dn = 'new';
144  foreach ($this->by_object as &$obj) {
145  $obj->resetCopyInfos();
146  }
147  unset($obj);
148  }
149 
150  function resetBase()
151  {
152  $baseobject = $this->getBaseObject();
153  if (isset($baseobject->base)) {
154  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $baseobject->base, 'Fixing base');
155  if (session::global_is_set('CurrentMainBase')) {
156  $baseobject->base = dn2base('cn=dummy,'.session::global_get('CurrentMainBase'));
157  } else {
158  $baseobject->base = dn2base(get_userinfo()->dn);
159  }
160  if (!($baseobject instanceOf simplePlugin) && is_object($baseobject->baseSelector)) {
161  /* For some plugins not yet migrated to simple plugin. */
162  $baseobject->baseSelector->setBase($baseobject->base);
163  }
164  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $baseobject->base, 'Fixed base');
165  } else {
166  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, '', 'no base');
167  }
168  }
169 
170  function getBaseObject()
171  {
172  return $this->by_object[$this->baseclass];
173  }
174 
176  function readOnly()
177  {
178  return $this->getBaseObject()->readOnly();
179  }
180 
184  function execute()
185  {
186  /* Look for pressed tab button first */
187  foreach ($this->by_object as $class => &$obj) {
188  if (isset($_POST[$class]) || (isset($_POST['arg']) && $_POST['arg'] == "$class")) {
189  $this->current = $class;
190  break;
191  }
192  }
193  unset($obj);
194 
195  /* Show object */
196  $display = '<div class="tab-content">'."\n";
197 
198  $display .= $this->by_object[$this->current]->execute();
199 
200  /* Build tab line */
201  $tabs = $this->gen_tabs($this->dialogOpened());
202 
203  /* Footer for tabbed dialog */
204  $display = $tabs.$display.'</div>';
205 
206  return $display;
207  }
208 
214  function save_object()
215  {
216  /* Ensure that the currently selected tab is valid. */
217  if (!isset($this->by_name[$this->current])) {
218  $this->current = key($this->by_name);
219  }
220 
221  /* Rotate current to last */
222  $this->last = $this->current;
223 
224  /* Save last tab */
225  if ($this->last != "") {
226  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $this->last, "Saving");
227 
228  $this->by_object[$this->last]->save_object();
229  }
230  }
231 
237  function gen_tabs($disabled = FALSE)
238  {
239  $display = "";
240  if (!$disabled) {
241  $display .= '<input type="hidden" name="arg" value=""/>';
242  }
243  $display .= '<table class="tabs-header"><tbody><tr>';
244  $index = 0;
245  $style = array('tab-left', 'tab-active', 'tab-right');
246  foreach ($this->by_name as $class => $name) {
247 
248  /* Activate right tabs with style "tab-right" */
249  if ($index == 1) {
250  $index++;
251  } elseif ($class == $this->current) {
252  /* Activate current tab with style "tab-active " */
253  $index++;
254  }
255 
256  /* Paint tab */
257  $display .= '<td>';
258 
259  /* Shorten string if its too long for the tab headers*/
260  $title = _($name);
261  if (mb_strlen($title, 'UTF-8') > 28) {
262  $title = mb_substr($title, 0, 25, 'UTF-8')."...";
263  }
264 
265  /* nobr causes w3c warnings so we use &nbsp; to keep the tab name in one line */
266  $title = str_replace(' ', '&nbsp;', $title);
267 
268  $cssClasses = $style[$index];
269 
270  /* Take care about notifications */
271  $obj = $this->by_object[$class];
272  if ($this->plNotify[$class] && ($obj->is_account || $obj->ignore_account)) {
273  $cssClasses .= ' tab-notify';
274  }
275  if ($disabled) {
276  $cssClasses .= ' tab-disabled';
277  }
278  if (!$obj->is_account && !$obj->ignore_account) {
279  $cssClasses .= ' tab-inactive';
280  }
281 
282 
283  $display .= '<div class="'.$cssClasses.'">';
284  if ($disabled) {
285  $display .= '<a>';
286  } else {
287  $display .= '<a '.
288  'id="tab_'.$class.'" '.
289  'onclick="return true;" '.
290  'href="'."javascript:document.mainform.arg.value='$class';document.mainform.submit();".'">';
291  }
292  $display .= $title.'</a></div></td>';
293  }
294 
295  $display .= "<td>\n";
296  $display .= '<div class="tab-border">&nbsp;</div></td></tr></tbody></table>';
297 
298  return $display;
299  }
300 
304  function delete()
305  {
306  /* Delete for all plugins */
307  foreach (array_reverse($this->by_object) as $obj) {
308  $errors = $obj->remove_from_parent();
309  if (!empty($errors)) {
310  msg_dialog::displayChecks($errors);
311  }
312  }
313  }
314 
320  protected function check()
321  {
322  global $config;
323  $messages = array();
324 
325  if ($this->getBaseObject()->is_template) {
326  $ldap = $config->get_ldap_link();
327  $ldap->cd($config->current['BASE']);
328  $filter = '(&(objectClass=fdTemplate)(cn='.ldap_escape_f($this->getBaseObject()->_template_cn).'))';
329  $ldap->search($filter, array('dn'));
330  while ($attrs = $ldap->fetch()) {
331  if ($attrs['dn'] != $this->getBaseObject()->dn) {
332  $messages[] = msgPool::duplicated($this->getBaseObject()->attributesAccess['_template_cn']->getLabel(), $attrs['dn']);
333  }
334  }
335  return $messages;
336  }
337 
338  $current_set = FALSE;
339 
340  /* Check all plugins */
341  foreach ($this->by_object as $key => $obj) {
342  $this->plNotify[$key] = FALSE;
343  if (($obj->is_account || $obj->ignore_account) && (!$obj->is_template)) {
344  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $key, "Checking");
345 
346  $msg = $obj->check();
347 
348  if (count($msg)) {
349  $this->plNotify[$key] = TRUE;
350  if (!$current_set) {
351  $current_set = TRUE;
352  $this->current = $key;
353  $messages = $msg;
354  }
355  }
356  }
357  }
358 
359  return $messages;
360  }
361 
362  /*
363  * \brief Save object in the tab
364  *
365  * \param boolean $ignore_account false
366  */
367  function save()
368  {
369  global $ui;
370  $messages = $this->check();
371  if (!empty($messages)) {
372  return $messages;
373  }
374 
375  $baseobject = $this->getBaseObject();
376  $old_dn = $this->dn;
377  try {
378  $new_dn = $baseobject->compute_dn();
379  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $new_dn, 'Saving');
380  } catch (FusionDirectoryException $e) {
381  return array(
382  sprintf(_('Failed to compute DN for object: %s'), $e->getMessage())
383  );
384  }
385 
386  $errors = array();
387  $creation = ($this->dn == 'new');
388 
389  /* Move ? */
390  if ($this->dn != $new_dn) {
391  /* Write entry on new 'dn' */
392  if ($creation) {
393  /* use the new one */
394  $this->dn = $new_dn;
395  } else {
396  if (($error = $baseobject->move($this->dn, $new_dn)) === TRUE) {
397  $this->dn = $new_dn;
398  } else {
399  $errors[] = sprintf(_('Move from "%s" to "%s" failed: %s'), $this->dn, $new_dn, $error);
400  return $errors;
401  }
402  }
403  }
404 
405  /* Save all plugins */
406  $first = TRUE;
407  foreach ($this->by_object as $key => $obj) {
408  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $key, 'Saving');
409 
410  $obj->dn = $this->dn;
411 
412  if (!($obj instanceof simplePlugin) && !($obj instanceOf simpleManagement)) {
413  trigger_error('Something went wrong while saving '.$obj->dn.'. Class "'.get_class($obj).'".');
414  } else {
415  if ($obj->is_account || $obj->ignore_account) {
416  $result = $obj->save();
417  } else {
418  $result = $obj->remove_from_parent();
419  }
420  if (!empty($result)) {
421  if ($creation && $first) {
422  /* If the fail of main tab fails for a creation, cancel the save of other tabs */
423  $this->dn = $old_dn;
424  $obj->dn = $this->dn;
425  return $result;
426  }
427  $errors = array_merge($errors, $result);
428  }
429  }
430  if ($first) {
431  $first = FALSE;
432  }
433  }
434 
435  if (empty($errors) && ($this->dn == $ui->dn)) {
436  /* If the logged in user was edited, update his information */
437  $ui->loadLDAPInfo();
438  }
439 
440  if (!empty($errors)) {
441  $this->dn = $old_dn;
442  foreach ($this->by_object as $obj) {
443  $obj->dn = $this->dn;
444  }
445  }
446 
447  return $errors;
448  }
449 
457  function adapt_from_template($attrs, $skip = array())
458  {
459  foreach ($this->by_object as $key => &$obj) {
460  @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $key, "Adapting");
461  $obj->parent = &$this;
462  $obj->adapt_from_template($attrs, $skip);
463  }
464  unset($obj);
465  }
466 
470  function addSpecialTabs()
471  {
472  global $config;
473  $baseobject = $this->getBaseObject();
474  foreach ($config->data['TABS']['SPECIALTABS'] as $tab) {
475  if (!plugin_available($tab['CLASS'])) {
476  continue;
477  }
478 
479  $this->by_name[$tab['CLASS']] = $tab['NAME'];
480  $this->plNotify[$tab['CLASS']] = FALSE;
481  $this->by_object[$tab['CLASS']] = new $tab['CLASS']($this->dn, $baseobject, $this, FALSE);
482  $this->by_object[$tab['CLASS']]->set_acl_category($this->acl_category);
483  }
484  }
485 
491  function set_acl_base($base = "")
492  {
493  /* Update reference, transfer variables */
494  $first = ($base == "");
495  foreach ($this->by_object as &$obj) {
496  if ($first) {
497  $first = FALSE;
498  $base = $obj->acl_base;
499  } else {
500  $obj->set_acl_base($base);
501  }
502  }
503  unset($obj);
504  }
505 
506  function setTemplateMode($cn)
507  {
508  $this->getBaseObject()->_template_cn = $cn;
509 
510  foreach ($this->by_object as &$obj) {
511  $obj->setTemplate(TRUE);
512  }
513  unset($obj);
514  }
515 
516  public function setNeedEditMode ($bool)
517  {
518  foreach ($this->by_object as &$obj) {
519  $obj->setNeedEditMode($bool);
520  }
521  unset($obj);
522  }
523 
524  public function setIgnoreAcls($bool)
525  {
526  $this->ignoreAcls = $bool;
527  }
528 
529  public function dialogOpened ()
530  {
531  return $this->by_object[$this->current]->is_modal_dialog();
532  }
533 
534  function objectInfos()
535  {
536  if ($this->objectType === FALSE) {
537  return FALSE;
538  }
539  return objects::infos($this->objectType);
540  }
541 
542  /* Return tab or service if activated, FALSE¬†otherwise */
543  function getTabOrServiceObject($tab)
544  {
545  if (isset($this->by_object[$tab]) && ($this->by_object[$tab]->is_account || $this->by_object[$tab]->ignore_account)) {
546  return $this->by_object[$tab];
547  } elseif (is_subclass_of($tab, 'simpleService') && isset($this->by_object['ServerService']->plugins[$tab]) && $this->by_object['ServerService']->plugins[$tab]->is_account) {
548  return $this->by_object['ServerService']->plugins[$tab];
549  } else {
550  return FALSE;
551  }
552  }
553 }
554 
556 {
557  protected $specialTabs = FALSE;
558 }
559 ?>
This class is made for easy plugin creation for editing LDAP attributes.
readOnly()
Indicates if this tab class is read-only (because of locks)
adapt_from_template($attrs, $skip=array())
Adapt from template.
This class contains all function to manage tabs classes.
& get_userinfo()
Return the current userinfo object.
Definition: functions.inc:922
set_acl_base($base="")
Set acl base.
re_init()
Reinitializes the tab classes with fresh ldap values.
gen_tabs($disabled=FALSE)
Generate the tab classes.
save_object()
Save a tabs object.
Parent class for all exceptions thrown in FusionDirectory.
dn2base($dn, $ou=NULL)
Return the base of a given DN.
Definition: functions.inc:1295
__construct($type, $dn, $attrs_object=NULL)
Tabs classes constructor.
static duplicated($name, $dn=NULL)
Display error about existing entry in the system.
DEBUG($level, $line, $function, $file, $data, $info= '')
Debug level action.
Definition: functions.inc:200
execute()
Save the tab(s) contents.
static global_get($name)
Accessor of a session var.
static display($s_title, $s_message, $i_type=INFO_DIALOG)
Display a message dialog.
addSpecialTabs()
Add special Tabs.
plugin_available($plugin)
Check if plugin is available.
Definition: functions.inc:146
static global_is_set($name)
Check if a session is defined.