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 /*
25 Data structure :
26 ================
27 |->o_tab <-- dummy object, collects HTML posts, displays ui
28 |->a_handles <-- tab object for each given dn
29 |->tab object for dn 1
30 |->tab object for dn 2
31 ...
32 |->tab object for dn n
35 Other functions implemented:
36 ============================
38 CLASS tab
39 - multiple_support_available() Check if there is at least one plugin with
40 enabled multiple edit support
41 - enable_multiple_support() Enable multiple edit, for this tab.
43 CLASS plugin
44 - enable_multiple_support() Enable multiple support for this plugin.
45 - init_multiple_support() Init summy object, to preset some values.
46 - multiple_execute() Display dummy object ui.
47 - multiple_save_object() Get posted values in multiple edit mode.
48 - multiple_check() Check values specified in dummy object.
49 - get_multi_edit_values() Get values changed from dummy object.
50 - set_multi_edit_values() Set values collected with get_multi_edit_values.
51 to all objects currently edited.
54 Process:
55 ========
57 multi_plug::multi_plug()
58 |->o_tab = new tab() #Initialize ui handle
59 |
60 |->handles
61 | |->handles[] = new tab() #Initialize objects we want to edit at once
62 |
63 |->o_tab->enable_multiple_support() #Enable multiple support for ui handle
64 |->detect_multiple_used_attributes() #Update ui handle with some default values
65 |->handles[]
66 |->by_object->get_multi_init_values() #Get attributes from all handles
67 |->o_tab
68 |->by_object->init_multiple_support() #Assign values to ui handle
69 |
70 |->execute() #Display ui
71 | |->o_tab->execute()
72 |->by_object->multiple_execute()
73 |
74 |->check() #Check given values
75 |->o_tab->check()
76 |->by_object->multiple_check()
77 |
78 |->save_object() #Save posts
79 |->o_tab->save_object()
80 |->by_object->multiple_save_object()
81 |
82 |->save() #Save collected values
83 |->populate_values() #Populate values to all handles
84 |->o_tab->get_multi_edit_values() #Get values to populate
85 |->handles->set_multi_edit_values() #Set values
86 |->handles->save() #Save handles
91 Using this class:
92 =================
93 Simple Example:
95 $dn = array(dn1,dn2,dn3);
96 $tmp = new multi_plug($config,"usertabs",$config->data['TABS']['USERTABS'],$dn);
97 echo $tmp->execute();
99 $tmp can now be used like the normal tab class, execute, save_object ...
101 To enable multipe edit for a specific plugin,
102 just set the plugin variable 'multiple_support' to true:
104 var $multiple_support = TRUE;
106 If plugin::multiple_support is true, the member function
107 multiple_execute() will be called and displayed, NOT execute().
109 (I will put this in the wiki, later. This are just notes for me.)
111 */
114 /*! \brief Handles multiple edits for a given set of dns.
115 \author Fabian Hickert
116 \version 1.01
117 \date 2007/12/07
119 This class edits multiple tab objects at once.
120 1. There is a dummy tab object initialized that collects the user input.
121 2. All given objects specified by '$dn' will be initialized and the collected
122 data from the dummy object will be populated to them.
123 */
124 class multi_plug
125 {
126 /* Tab handler for each given dn entry */
127 public $a_handles = array();
129 /* Dummy handler which collects the data */
130 private $o_tab = NULL;
132 public $dn = array();
133 public $config = NULL;
134 private $s_class= "";
135 public $current = "";
136 public $by_object = array();
137 public $by_name = array();
139 /*! \brief Creates a multi_plug object
140 @param object $config GOsa Configuration object
141 @param string $class The class name of the tab we want to edit. e.g. usertabs
142 @param string $tab The config tab name e.g. USERTABS
143 @param array $dns The object dns we want to edit.
144 @return object multi_plug
145 */
146 public function __construct($config,$class,$tab,$dns,$acl_base,$acl_category)
147 {
148 if(!count($dns)){
149 return;
150 }
152 $this->dn = $dns;
153 $this->config = $config;
154 $this->s_class = $class;
156 /* Initialize collector object
157 * Used to display the ui and to collect the user input.
158 */
159 $this->o_tab = new $class($config,$tab,"new",$acl_category, TRUE, TRUE);
160 $this->o_tab->set_acl_base($acl_base);
161 $this->by_object = &$this->o_tab->by_object;
162 $this->by_name = &$this->o_tab->by_name;
163 $this->current = &$this->o_tab->current;
165 /* Check if the specified tab object supports multiple edits
166 */
167 if($this->o_tab->multiple_support_available()){
169 /* Enable multiple actions for the collector object
170 */
171 $this->o_tab->enable_multiple_support();
173 /* Initialize the objects we want to edit at once
174 */
175 foreach($dns as $dn){
176 $obj = new $class($config,$tab,$dn,$acl_category, TRUE, TRUE);
177 $obj->set_acl_base($acl_base);
178 $this->a_handles[] = $obj;
179 }
180 }
182 /* Detect attributes used by all plugins and set
183 * those values as default in edit handle
184 */
185 $this->detect_multiple_used_attributes();
186 }
189 /*! \brief Combine two ldap result arrays.
190 * @param array $base Base array
191 * @param array $add Array to add
192 * @returns array Combination of $base and $add
193 */
194 private function array_combine($base,$add)
195 {
197 foreach($add as $key => $attr) {
198 if(!is_numeric($key)){
200 if(!is_array($add[$key])){
201 $add[$key] = array('count' => 1,$add[$key]);
202 }
204 if(!isset($base[$key])){
205 $base[$key] = $add[$key];
206 }else{
208 if(!isset($base[$key]['count'])){
209 $base[$key]['count'] = count($base[$key]);
210 }
212 if(!isset($add[$key]['count'])){
213 $add[$key]['count'] = count($add[$key]);
214 }
215 for($i=0;$i<$add[$key]['count'];$i++){
216 if(!in_array($add[$key][$i],$base[$key])){
217 $base[$key][] = $add[$key][$i];
218 $base[$key]['count']++;
219 }
220 }
221 }
222 }
223 }
224 return($base);
225 }
228 /*! \brief Intersect two ldap result arrays/Inner join of two ldap result arrays
229 * @param array $base Base array
230 * @param array $minus Array number two
231 * @returns array Result intersection
232 */
233 private function array_intersect($base,$minus)
234 {
235 foreach($base as $key => $entry){
236 if(is_numeric($key) || !isset($minus[$key])){
237 unset($base[$key]);
238 }elseif(gettype($base[$key]) != gettype($minus[$key])){
239 unset($base[$key]);
240 }elseif(is_string($base[$key]) && $base[$key]!=$minus[$key]){
241 unset($base[$key]);
242 }elseif(is_array($base[$key])){
243 $tmp = array();
244 if(!isset($base[$key]['count'])){
245 $base[$key]['count'] = count($base[$key]);
246 }
247 for($i = 0 ; $i < $base[$key]['count'] ; $i ++){
248 if(isset($base[$key][$i]) && in_array($base[$key][$i],$minus[$key])){
249 $tmp[] = $base[$key][$i];
250 }
251 }
252 if(count($tmp)){
253 $tmp['count'] = count($tmp);
254 $base[$key] = $tmp;
255 }else{
256 unset($base[$key]);
257 }
258 }
259 }
260 return($base);
261 }
264 /*! \brief Detect values that are used in all edited objects.
265 */
266 private function detect_multiple_used_attributes()
267 {
268 foreach($this->o_tab->by_object as $name => $plug){
270 if(empty($name)) continue;
272 $attrs = array();
273 $all = array();
274 foreach($this->a_handles as $hid => $handle){
275 $h_attrs = $this->a_handles[$hid]->by_object[$name]->get_multi_init_values();
276 if(count($attrs) == 0){
277 $attrs = $h_attrs;
278 }else{
279 $attrs = $this->array_intersect($attrs,$h_attrs);
280 }
281 $all = $this->array_combine($all,$h_attrs);
282 }
283 $this->o_tab->by_object[$name]->init_multiple_support($attrs,$all);
284 }
285 }
288 /*! \brief Returns the edit ui for multiple edit.
289 @return string HTML User interface for given tab object.
290 */
291 public function execute()
292 {
293 $str = $this->o_tab->execute();
294 return($str);
295 }
298 /*! \brief Checks if one of the objects we want to edit is locked.
299 @return boolean Returns TRUE if at least one entry is locked, else false.
300 */
301 public function entries_locked()
302 {
303 $ui = get_userinfo();
304 foreach($this->dn as $dn){
305 if(get_lock($dn) != ""){
306 return(TRUE);
307 }
308 }
309 return(FALSE);
310 }
313 /*! \brief Generates a lock message that can be displayed if an entry is locked.
314 @return string Returns a list of locked entries
315 */
316 public function display_lock_message()
317 {
318 $ui = get_userinfo();
319 $lock_msg = "";
320 $lock_msg.= gen_locked_message ($ui->dn, $this->dn);
321 return($lock_msg);
322 }
325 /*! \brief Locks all currently managed objects (array $this->dn)
326 @return boolean Returns TRUE
327 */
328 public function lock_entries($uid)
329 {
330 foreach($this->dn as $dn)
331 add_lock($dn,$uid);
332 return(TRUE);
333 }
336 /*! \brief Checks if the given tab object supports multiple edit.
337 @return boolean Returns TRUE if the given tab objects supports multiple edit else FALSE.
338 */
339 public function multiple_available()
340 {
341 if(isset($this->o_tab) && is_object($this->o_tab)){
342 return($this->o_tab->multiple_support_available());
343 }else{
344 return(FALSE);
345 }
346 }
349 /*! \brief Sets the currently active tab. The tab that will be displayed by $this->execute().
350 */
351 public function set_active_tab($str)
352 {
353 $this->current = $str;
354 }
357 /*! \brief Returns the object info string, that can be displayed in the tab header.
358 @return string Returns an information string, containing the list of currently edited dns.
359 */
360 public function get_object_info()
361 {
362 return(_("You are currently editing mutliple entries."));
363 }
366 /*! \brief Handles all HTML posts from the dummy tab object.
367 */
368 public function save_object()
369 {
370 $this->o_tab->save_object();
371 }
374 /*! \brief Checks if the values fetched by $this->save_object() are valid.
375 @param array Returns an array containig all error messages.
376 */
377 public function check()
378 {
379 $messages = $this->o_tab->check();
380 return($messages);
381 }
384 /*! \brief Currently not implemented, later be used to trigger password changes.
385 @param boolean Returns TRUE if a password change is needed.
386 */
387 public function password_change_needed()
388 {
389 foreach($this->a_handles as $i_id => $o_handle){
390 if($o_handle->password_change_needed() && isset($o_handle->by_object['user'])){
391 new msg_dialog(_("Reset password"),_("The user password has been reset. Please set a new password!"),WARNING_DIALOG);
392 change_password ($o_handle->dn, "",0, $o_handle->by_object['user']->pw_storage);
393 }
394 }
395 return(FALSE);
396 }
399 /*! \brief Populate all collected values to the target tab objects ($this->o_handles)
400 */
401 public function populate_values()
402 {
403 if($this->multiple_available() && is_array($this->a_handles)){
404 foreach($this->o_tab->by_object as $name => $obj){
406 $values = $this->o_tab->by_object[$name]->get_multi_edit_values();
407 foreach($this->a_handles as $i_id => $o_handle){
408 $this->a_handles[$i_id]->by_object[$name]->set_multi_edit_values($values);
409 }
410 }
411 }
412 }
415 /*! \brief Save all edited tab objects ($this->o_handles).
416 */
417 public function save()
418 {
419 if($this->multiple_available() && is_array($this->a_handles)){
420 $this->populate_values();
421 foreach($this->a_handles as $i_id => $o_handle){
422 $o_handle->save();
423 }
424 }
425 }
426 }
428 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
429 ?>