1 <?php
2 /*
3 This code is part of GOsa (https://oss.gonicus.de/labs/gosa/)
4 Copyright (C) 2007 Fabian Hickert
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
21 /*
23 Data structure :
24 ================
25 |->o_tab <-- dummy object, collects HTML posts, displays ui
26 |->a_handles <-- tab object for each given dn
27 |->tab object for dn 1
28 |->tab object for dn 2
29 ...
30 |->tab object for dn n
33 Other functions implemented:
34 ============================
36 CLASS tab
37 - multiple_support_available() Check if there is at least one plugin with
38 enabled multiple edit support
39 - enable_multiple_support() Enable multiple edit, for this tab.
41 CLASS plugin
42 - enable_multiple_support() Enable multiple support for this plugin.
43 - init_multiple_support() Init summy object, to preset some values.
44 - multiple_execute() Display dummy object ui.
45 - multiple_save_object() Get posted values in multiple edit mode.
46 - multiple_check() Check values specified in dummy object.
47 - get_multi_edit_values() Get values changed from dummy object.
48 - set_multi_edit_values() Set values collected with get_multi_edit_values.
49 to all objects currently edited.
52 Process:
53 ========
55 multi_plug::multi_plug()
56 |->o_tab = new tab() #Initialize ui handle
57 |
58 |->handles
59 | |->handles[] = new tab() #Initialize objects we want to edit at once
60 |
61 |->o_tab->enable_multiple_support() #Enable multiple support for ui handle
62 |->detect_multiple_used_attributes() #Update ui handle with some default values
63 |->handles->attrs
64 |->ui->attrs
65 |
66 |->execute() #Display ui
67 | |->o_tab->execute()
68 |->by_object->multiple_execute()
69 |
70 |->check() #Check given values
71 |->o_tab->check()
72 |->by_object->multiple_check()
73 |
74 |->save_object() #Save posts
75 |->o_tab->save_object()
76 |->by_object->multiple_save_object()
77 |
78 |->save() #Save collected values
79 |->populate_values() #Populate values to all handles
80 |->o_tab->get_multi_edit_values() #Get values to populate
81 |->handles->set_multi_edit_values() #Set values
82 |->handles->save() #Save handles
87 Using this class:
88 =================
89 Simple Example:
91 $dn = array(dn1,dn2,dn3);
92 $tmp = new multi_plug($config,"usertabs",$config->data['TABS']['USERTABS'],$dn);
93 echo $tmp->execute();
95 $tmp can now be used like the normal tab class, execute, save_object ...
97 To enable multipe edit for a specific plugin,
98 just set the plugin variable 'multiple_support' to true:
100 var $multiple_support = TRUE;
102 If plugin::multiple_support is true, the member function
103 multiple_execute() will be called and displayed, NOT execute().
105 (I will put this in the wiki, later. This are just notes for me.)
107 */
110 /*! \brief Handles multiple edits for a given set of dns.
111 \author Fabian Hickert
112 \version 1.01
113 \date 2007/12/07
115 This class edits multiple tab objects at once.
116 1. There is a dummy tab object initialized that collects the user input.
117 2. All given objects specified by '$dn' will be initialized and the collected
118 data from the dummy object will be populated to them.
119 */
120 class multi_plug
121 {
122 /* Tab handler for each given dn entry */
123 public $a_handles = array();
125 /* Dummy handler which collects the data */
126 private $o_tab = NULL;
128 public $dn = array();
129 public $config = NULL;
130 private $s_class= "";
131 public $current = "";
133 /*! \brief Creates a multi_plug object
134 @param object $config GOsa Configuration object
135 @param string $class The class name of the tab we want to edit. e.g. usertabs
136 @param string $tab The config tab name e.g. USERTABS
137 @param array $dns The object dns we want to edit.
138 @return object multi_plug
139 */
140 public function __construct($config,$class,$tab,$dns,$acl_base,$acl_category)
141 {
142 if(!count($dns)){
143 return;
144 }
146 $this->dn = $dns;
147 $this->config = $config;
148 $this->s_class = $class;
150 /* Initialize collector object
151 * Used to display the ui and to collect the user input.
152 */
153 $this->o_tab = new $class($config,$tab,"new",$acl_category);
154 $this->o_tab->set_acl_base($acl_base);
156 /* Check if the specified tab object supports multiple edits
157 */
158 if($this->o_tab->multiple_support_available()){
160 /* Enable multiple actions for the collector object
161 */
162 $this->o_tab->enable_multiple_support();
164 /* Initialize the objects we want to edit at once
165 */
166 foreach($dns as $dn){
167 $obj = new $class($config,$tab,$dn,$acl_category);
168 $obj->set_acl_base($acl_base);
169 $this->a_handles[] = $obj;
170 }
171 }
173 /* Detect attributes used by all plugins and set
174 * those values as default in edit handle
175 */
176 $this->detect_multiple_used_attributes();
177 }
180 /*! \brief Combine two ldap result arrays.
181 * @param array $base Base array
182 * @param array $add Array to add
183 * @returns array Combination of $base and $add
184 */
185 private function array_combine($base,$add)
186 {
187 foreach($add as $key => $attr) {
188 if(!is_numeric($key)){
189 if(!isset($base[$key])){
190 $base[$key] = $add[$key];
191 }elseif(is_array($add[$key])){
192 for($i=0;$i<$add[$key]['count'];$i++){
193 if(!in_array($add[$key][$i],$base[$key])){
194 $base[$key][] = $add[$key][$i];
195 $base[$key]['count']++;
196 }
197 }
198 }
199 }
200 }
201 return($base);
202 }
205 /*! \brief Intersect two ldap result arrays/Inner join of two ldap result arrays
206 * @param array $base Base array
207 * @param array $minus Array number two
208 * @returns array Result intersection
209 */
210 private function array_intersect($base,$minus)
211 {
212 foreach($base as $key => $entry){
213 if(is_numeric($key) || !isset($minus[$key])){
214 unset($base[$key]);
215 }elseif(gettype($base[$key]) != gettype($minus[$key])){
216 unset($base[$key]);
217 }elseif(is_string($base[$key]) && $base[$key]!=$minus[$key]){
218 unset($base[$key]);
219 }elseif(is_array($base[$key])){
220 $tmp = array();
221 for($i = 0 ; $i < $base[$key]['count'] ; $i ++){
222 if(isset($base[$key][$i]) && in_array($base[$key][$i],$minus[$key])){
223 $tmp[] = $base[$key][$i];
224 }
225 }
226 if(count($tmp)){
227 $tmp['count'] = count($tmp);
228 $base[$key] = $tmp;
229 }else{
230 unset($base[$key]);
231 }
232 }
233 }
234 return($base);
235 }
238 /*! \brief Detect values that are used in all edited objects.
239 */
240 private function detect_multiple_used_attributes()
241 {
242 $attrs = array();
243 $first = $this->o_tab->current;
244 $all = array();
245 foreach($this->a_handles as $handle){
246 if(count($attrs) == 0){
247 $attrs = $handle->by_object[$first]->attrs;
248 }else{
249 $attrs = $this->array_intersect($attrs,$handle->by_object[$first]->attrs);
250 }
251 $all = $this->array_combine($all,$handle->by_object[$first]->attrs);
252 }
253 foreach($this->o_tab->by_object as $name => $obj){
254 $this->o_tab->by_object[$name]->init_multiple_support($attrs,$all);
255 }
256 }
259 /*! \brief Returns the edit ui for multiple edit.
260 @return string HTML User interface for given tab object.
261 */
262 public function execute()
263 {
264 return($this->o_tab->execute());
265 }
268 /*! \brief Checks if one of the objects we want to edit is locked.
269 @return boolean Returns TRUE if at least one entry is locked, else false.
270 */
271 public function entries_locked()
272 {
273 $ui = get_userinfo();
274 foreach($this->dn as $dn){
275 if(get_lock($dn) != ""){
276 return(TRUE);
277 }
278 }
279 return(FALSE);
280 }
283 /*! \brief Generates a lock message that can be displayed if an entry is locked.
284 @return string Returns a list of locked entries
285 */
286 public function display_lock_message()
287 {
288 $ui = get_userinfo();
289 $lock_msg = "";
290 $lock_msg.= gen_locked_message ($ui->dn, $this->dn);
291 return($lock_msg);
292 }
295 /*! \brief Locks all currently managed objects (array $this->dn)
296 @return boolean Returns TRUE
297 */
298 public function lock_entries($uid)
299 {
300 foreach($this->dn as $dn)
301 add_lock($dn,$uid);
302 return(TRUE);
303 }
306 /*! \brief Checks if the given tab object supports multiple edit.
307 @return boolean Returns TRUE if the given tab objects supports multiple edit else FALSE.
308 */
309 public function multiple_available()
310 {
311 if(isset($this->o_tab) && is_object($this->o_tab)){
312 return($this->o_tab->multiple_support_available());
313 }else{
314 return(FALSE);
315 }
316 }
319 /*! \brief Sets the currently active tab. The tab that will be displayed by $this->execute().
320 */
321 public function set_active_tab($str)
322 {
323 $this->current = $str;
324 }
327 /*! \brief Returns the object info string, that can be displayed in the tab header.
328 @return string Returns an information string, containing the list of currently edited dns.
329 */
330 public function get_object_info()
331 {
332 return(_("You are currently editing mutliple entries."));
333 }
336 /*! \brief Handles all HTML posts from the dummy tab object.
337 */
338 public function save_object()
339 {
340 $this->o_tab->save_object();
341 }
344 /*! \brief Checks if the values fetched by $this->save_object() are valid.
345 @param array Returns an array containig all error messages.
346 */
347 public function check()
348 {
349 $messages = $this->o_tab->check();
350 return($messages);
351 }
354 /*! \brief Currently not implemented, later be used to trigger password changes.
355 @param boolean Returns TRUE if a password change is needed.
356 */
357 public function password_change_needed()
358 {
359 foreach($this->a_handles as $i_id => $o_handle){
360 if($o_handle->password_change_needed() && isset($o_handle->by_object['user'])){
361 new msg_dialog(_("Password reset"),_("The user password was resetted, please set a new password value!"),WARNING_DIALOG);
362 change_password ($o_handle->dn, "",0, $o_handle->by_object['user']->pw_storage);
363 }
364 }
365 return(FALSE);
366 }
369 /*! \brief Populate all collected values to the target tab objects ($this->o_handles)
370 */
371 public function populate_values()
372 {
373 if($this->multiple_available() && is_array($this->a_handles)){
374 foreach($this->o_tab->by_object as $name => $obj){
376 $values = $this->o_tab->by_object[$name]->get_multi_edit_values();
377 foreach($this->a_handles as $i_id => $o_handle){
378 $this->a_handles[$i_id]->by_object[$name]->set_multi_edit_values($values);
379 }
380 }
381 }
382 }
385 /*! \brief Save all edited tab objects ($this->o_handles).
386 */
387 public function save()
388 {
389 if($this->multiple_available() && is_array($this->a_handles)){
390 $this->populate_values();
391 foreach($this->a_handles as $i_id => $o_handle){
392 $o_handle->save();
393 }
394 }
395 }
396 }
398 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
399 ?>