7d985ec7ea4c43c8561b667be35e3b4968d1e00e
1 <?php
2 /*
3 * This code is part of GOsa (http://www.gosa-project.org)
4 * Copyright (C) 2003-2008 GONICUS GmbH
5 *
6 * ID: $$Id$$
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
23 class tabs
24 {
25 var $dn;
26 var $config;
27 var $acl;
28 var $is_template;
29 var $is_new= FALSE;
31 var $last= "";
32 var $current= "";
33 var $disabled= "";
34 var $by_name= array();
35 var $by_object= array();
36 var $SubDialog = false;
37 var $acl_category;
38 var $multiple_support_active = FALSE;
40 var $parent = null; // A parent object if available, e.g. a management class.
42 var $read_only = FALSE; // Used when the entry is opened as "readonly" due to locks.
43 var $hide_refs = FALSE;
44 var $hide_acls = FALSE;
46 function tabs(&$config, $data, $dn, $acl_category= "", $hide_refs = FALSE, $hide_acls = FALSE)
47 {
48 /* Save dn */
49 $this->dn= $dn;
50 $this->config= &$config;
51 $this->hide_refs = $hide_refs;
52 $this->hide_acls = $hide_acls;
54 if(!count($data)) {
55 $data[] = array("CLASS" => 'plugin',"NAME" => 'Error');
56 msg_dialog::display(_("Error"),
57 sprintf(_("No plugin definition for %s found: please check the configuration file!"), bold(get_class($this))),
58 "ERROR_DIALOG");
59 }
61 $baseobject= NULL;
62 $this->acl_category = $acl_category;
63 foreach ($data as &$tab){
65 if (!plugin_available($tab['CLASS'])){
66 if($this->config->boolValueIsTrue("core","developmentMode")){
67 trigger_error(sprintf("Unknown class %s!", bold($tab['CLASS'])));
68 }
69 continue;
70 }
71 if ($this->current == "") $this->current= $tab['CLASS'];
73 $this->by_name[$tab['CLASS']]= $tab['NAME'];
75 if ($baseobject === NULL){
76 $baseobject= new $tab['CLASS']($this->config, $this->dn);
77 $baseobject->enable_CSN_check();
78 $this->by_object[$tab['CLASS']]= $baseobject;
79 } else {
80 $this->by_object[$tab['CLASS']]= new $tab['CLASS']($this->config, $this->dn, $baseobject);
81 }
83 $this->read_only |= $this->by_object[$tab['CLASS']]->read_only;
84 $this->by_object[$tab['CLASS']]->parent= &$this;
85 $this->by_object[$tab['CLASS']]->set_acl_category($this->acl_category);
86 }
88 // Try to set the current tab to the posted value
89 if(isset($_GET['pluginTab'])){
90 $tab = $_GET['pluginTab'];
91 if(isset($this->by_name[$tab])) $this->current = $tab;
92 }
93 }
96 /*! \brief Reinitializes the tab classes with fresh ldap values.
97 This maybe usefull if for example the apply button was pressed.
98 */
99 function re_init()
100 {
101 $baseobject= NULL;
102 foreach($this->by_object as $name => $object){
103 $class = get_class($object);
104 if(in_array_strict($class,array("reference","acl"))) continue;
105 if ($baseobject === NULL){
106 $baseobject= new $class($this->config, $this->dn);
107 $baseobject->enable_CSN_check();
108 $this->by_object[$name]= $baseobject;
109 } else {
110 $this->by_object[$name]= new $class($this->config, $this->dn, $baseobject);
111 }
112 $this->by_object[$name]->parent= &$this;
113 $this->by_object[$name]->set_acl_category($this->acl_category);
114 }
115 }
118 function execute()
119 {
120 // Ensure that the currently selected tab is valid.
121 if(!isset($this->by_name[$this->current])) {
122 $this->current = key($this->by_name);
123 }
125 pathNavigator::registerPlugin($this);
127 // Rotate current to last
128 $this->last= $this->current;
130 // Look for pressed tab button
131 foreach ($this->by_object as $class => &$obj){
132 if (isset($_POST[$class]) || (isset($_POST['arg']) && $_POST['arg'] == "$class")){
133 $this->current= $class;
134 break;
135 }
136 }
138 // Save last tab object
139 if ($this->last == $this->current){
140 $this->save_object(TRUE);
141 } else {
142 $this->save_object(FALSE);
143 }
145 /* If multiple edit is enabled for this tab,
146 we have tho display different templates */
147 if(!$this->multiple_support_active){
148 $display= $this->by_object[$this->current]->execute();
149 }else{
150 $display= $this->by_object[$this->current]->multiple_execute();
151 }
152 $tabs= $this->gen_tabs();
154 if($this->is_modal_dialog()){
155 $display =
156 "\n <div class='plugin'>".
157 "\n {$display}".
158 "\n </div>";
159 }else{
161 $display =
162 "\n {$tabs}".
163 "\n <input type='hidden' name='arg' value=''>".
164 "\n <div class='tab-content'>".
165 "\n {$display}".
166 "\n </div>";
167 }
169 // Detect if we've modifications right now.
170 // - A plugin state has to be changed, this is not a goo solution, but
171 // currently it does what we want.
172 // (It would be better to ask the plugins if something has changed)
173 $this->isPluginModified |= isset($_POST['modify_state']);
175 // - Capture the plugins modification status.
176 foreach ($this->by_name as $class => $name){
177 $this->isPluginModified |= (isset($this->by_object[$class]->is_modified)) && $this->by_object[$class]->is_modified;
178 }
179 $display="<input type='hidden' id='pluginModified' name='pluginModified' value='{$this->isPluginModified}'>".$display;
181 return ($display);
182 }
184 function save_object($save_current= FALSE)
185 {
186 /* Save last tab */
187 if ($this->last != ""){
188 @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
189 $this->last, "Saving");
191 if(!$this->multiple_support_active){
192 $this->by_object[$this->last]->save_object ();
193 }else{
194 $this->by_object[$this->last]->multiple_save_object();
195 }
196 }
198 /* Skip if curent and last are the same object */
199 if ($this->last == $this->current){
200 return;
201 }
203 $obj= @$this->by_object[$this->current];
204 $this->disabled= $obj->parent->disabled;
206 if ($save_current){
207 @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
208 $this->current, "Saving (current)");
210 if(!$this->multiple_support_active){
211 $obj->save_object();
212 }else{
213 $obj->multiple_save_object();
214 }
215 }
216 }
219 function is_modal_dialog()
220 {
221 return($this->by_object[$this->current]->is_modal_dialog());
222 }
224 function gen_tabs()
225 {
226 if($this->is_modal_dialog()) return("");
228 $display = "\n <div class='tabs'>";
229 $display.= "\n <ul>";
231 foreach ($this->by_name as $class => $name){
233 // Shorten string if its too long for the tab headers
234 $title= _($name);
235 if (mb_strlen($title, 'UTF-8') > 28){
236 $title= mb_substr($title,0, 25, 'UTF-8')."...";
237 }
239 // nobr causes w3c warnings so we use to keep the tab name in one line
240 $title= str_replace(" "," ",$title);
242 // Take care about notifications
243 $obj = $this->by_object[$class];
244 $tabClass = ($this->current == $class) ? "current" :"";
245 if ( $this->by_object[$class]->pl_notify && ($obj->is_account || $obj->ignore_account)){
246 $tabClass .= " info";
247 }
248 if(!empty($tabClass)) $tabClass="class='{$tabClass}'";
249 $onClick = "document.mainform.arg.value='{$class}'; document.mainform.submit();";
250 $display.= "\n <li {$tabClass} onClick=\"{$onClick}\">{$title}</li>";
251 }
252 $display.="\n </ul>";
253 $display.="\n </div>";
254 return($display);
255 }
258 function set_acl($acl)
259 {
260 /* Look for attribute in ACL */
261 trigger_error("Don't use tabs::set_acl() its obsolete.");
262 }
264 function delete()
265 {
266 /* Check if all plugins will ACK for deletion */
267 foreach (array_reverse($this->by_object) as $key => $obj){
268 $reason= $obj->allow_remove();
269 if ($reason != ""){
270 msg_dialog::display(_("Warning"), sprintf(_("Delete process has been canceled by plugin %s: %s"), bold($key), $reason), WARNING_DIALOG);
271 return;
272 }
273 }
275 /* Delete for all plugins */
276 foreach (array_reverse($this->by_object) as $obj){
277 $obj->remove_from_parent();
278 }
279 }
281 function password_change_needed()
282 {
283 /* Ask all plugins for needed password changes */
284 foreach ($this->by_object as &$obj){
285 if ($obj->password_change_needed()){
286 return TRUE;
287 }
288 }
290 return FALSE;
291 }
293 function check($ignore_account= FALSE)
294 {
295 $this->save_object(TRUE);
296 $messages= array();
298 $current_set = FALSE;
300 /* Check all plugins */
301 foreach ($this->by_object as $key => &$obj){
302 if ($obj->is_account || $ignore_account || $obj->ignore_account){
303 @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,$key, "Checking");
305 if(!$this->multiple_support_active){
306 $msg = $obj->check();
307 }else{
308 $msg = $obj->multiple_check();
309 }
311 if (count($msg)){
312 $obj->pl_notify= TRUE;
313 if(!$current_set){
314 $current_set = TRUE;
315 $this->current= $key;
316 $messages = $msg;
317 }
318 }else{
319 $obj->pl_notify= FALSE;
320 }
321 }else{
322 $obj->pl_notify= FALSE;
323 }
324 }
325 return ($messages);
326 }
328 function save($ignore_account= FALSE)
329 {
330 /* Save all plugins */
331 foreach ($this->by_object as $key => &$obj){
332 @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
333 $key, "Saving");
335 $obj->dn= $this->dn;
337 if(!$obj instanceof plugin && !$obj instanceOf management){
338 trigger_error("Something went wrong while saving ".$obj->dn.". Object class '".get_class($obj)."'.");
339 }else{
341 if ($obj->is_account || $ignore_account || $obj->ignore_account){
342 if ($obj->save() == 1){
343 return (1);
344 }
345 } else {
346 $obj->remove_from_parent();
347 }
348 }
349 }
350 return (0);
351 }
353 function adapt_from_template($dn, $skip= array())
354 {
355 foreach ($this->by_object as $key => &$obj){
356 @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
357 $key, "Adapting");
358 $obj->parent= &$this;
359 $obj->adapt_from_template($dn, $skip);
360 }
361 }
364 /* Save attributes posted by copy & paste dialog
365 */
366 function saveCopyDialog()
367 {
368 foreach ($this->by_object as &$obj){
369 if($obj->is_account || $obj->ignore_account){
370 $obj->saveCopyDialog();
371 }
372 }
373 }
376 /* return copy & paste dialog
377 */
378 function getCopyDialog()
379 {
380 $ret = "";
381 $this->SubDialog = false;
382 foreach ($this->by_object as &$obj){
383 if($obj->is_account || $obj->ignore_account){
384 $tmp = $obj->getCopyDialog();
385 if($tmp['status'] == "SubDialog"){
386 $this->SubDialog = true;
387 return($tmp['string']);
388 }else{
389 if(!empty($tmp['string'])){
390 $ret .= $tmp['string'];
391 $ret .= "<hr>";
392 }
393 }
394 }
395 }
396 return($ret);
397 }
400 function addSpecialTabs()
401 {
402 if(!$this->hide_acls){
403 $this->by_name['acl']= _("ACL");
404 $this->by_object['acl']= new acl($this->config, $this, $this->dn);
405 $this->by_object['acl']->parent= &$this;
406 }
407 if(!$this->hide_refs){
408 $this->by_name['reference']= _("References");
409 $this->by_object['reference']= new reference($this->config, $this->dn);
410 $this->by_object['reference']->parent= &$this;
411 $this->by_object['reference']->set_acl_category($this->acl_category);
412 }
413 }
416 function set_acl_base($base= "")
417 {
418 /* Update reference, transfer variables */
419 $first= ($base == "");
420 foreach ($this->by_object as &$obj){
421 if ($first){
422 $first= FALSE;
423 $base= $obj->acl_base;
424 } else {
425 $obj->set_acl_base($base);
426 }
427 }
428 }
431 /*! \brief Checks if one of the used tab plugins supports multiple edit.
432 @param boolean Returns TRUE if at least one plugins supports multiple edit.
433 */
434 function multiple_support_available()
435 {
436 foreach($this->by_object as $name => $obj){
437 if($obj->multiple_support){
438 return(TRUE);
439 }
440 }
441 return(FALSE);
442 }
445 /*! \brief Enables multiple edit support for the given tab.
446 All unsupported plugins will be disabled.
447 @param boolean Returns TRUE if at least one plugin supports multiple edit
448 */
449 function enable_multiple_support()
450 {
451 if(!$this->multiple_support_available()){
452 return(FALSE);
453 }else{
454 $this->multiple_support_active = TRUE;
455 foreach($this->by_object as $name => $obj){
456 if($obj->multiple_support){
457 $this->by_object[$name]->enable_multiple_support();
458 }else{
459 unset($this->by_object[$name]);
460 unset($this->by_name[$name]);
461 }
462 }
463 }
464 return(TRUE);
465 }
467 function setReadOnly($s = TRUE)
468 {
469 foreach($this->by_object as $name => $obj){
470 $this->by_object[$name]->read_only = $s;
471 }
472 $this->read_only = $s;
473 }
474 }
475 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
476 ?>