2703ae7219a1bc6b6f793396f920c84f7922642e
1 <?php
3 class faiScript extends plugin
4 {
5 /* attribute list for save action */
6 var $ignore_account = TRUE;
8 /* Attributes for this Object */
9 var $attributes = array("cn","description");
11 /* ObjectClasses for this Object*/
12 var $objectclasses = array("top","FAIclass","FAIscript");
14 /* Class name of the Ldap ObjectClass for the Sub Object */
15 var $subClass = "FAIscriptEntry";
16 var $subClasses = array("top","FAIclass","FAIscriptEntry");
18 /* Class name of the php class which allows us to edit a Sub Object */
19 var $subClassName = "faiScriptEntry";
21 /* Attributes to initialise for each subObject */
22 var $subAttributes = array("cn","description","FAIpriority");
23 var $sub_Load_Later = array("FAIscript");
24 var $sub64coded = array();
25 var $subBinary = array("FAIscript");
27 /* Specific attributes */
28 var $cn = ""; // The class name for this object
29 var $description = ""; // The description for this set of partitions
30 var $is_dialog = false; // specifies which buttons will be shown to save or abort
31 var $SubObjects = array(); // All leafobjects of this object
33 var $FAIstate = "branch";
34 var $sort_by = "name";
35 var $sort_order = "up";
37 var $view_logged = FALSE;
38 var $ui;
40 function faiScript (&$config, $dn= NULL)
41 {
42 /* Load Attributes */
43 plugin::plugin ($config, $dn);
45 /* If "dn==new" we try to create a new entry
46 * Else we must read all objects from ldap which belong to this entry.
47 * First read SubObjects from ldap ... and then the partition definitions for the SubObjects.
48 */
49 if($dn != "new"){
50 $this->dn =$dn;
52 /* Read all leaf objects of this object (For FAIscript this would be FAIscriptEntry)
53 */
54 $res = FAI::get_all_objects_for_given_base($this->dn,"(&(objectClass=FAIclass)(objectClass=".$this->subClass."))");
55 foreach($res as $obj){
57 /* Skip not relevant objects */
58 if(!preg_match("/".preg_quote($this->dn, '/')."$/i",$obj['dn'])) continue;
60 $objects = array();
61 $objects['status'] = "FreshLoaded";
62 $objects['dn'] = $obj['dn'];
63 $objects = $this->get_object_attributes($objects,$this->subAttributes);
64 $this->SubObjects[$objects['cn']] = $objects;
65 }
66 }
68 $this->is_new = FALSE;
69 if($this->dn == "new"){
70 $this->is_new =TRUE;
71 }
73 $this->ui = get_userinfo();
75 $this->scriptListWidget= new sortableListing($this->convertList(TRUE), $this->convertList());
76 $this->scriptListWidget->setDeleteable(true);
77 $this->scriptListWidget->setInstantDelete(false);
78 $this->scriptListWidget->setEditable(true);
79 $this->scriptListWidget->setWidth("100%");
80 $this->scriptListWidget->setHeight("140px");
81 $this->scriptListWidget->setHeader(array(_("Name"),_("Description")));
82 }
85 function convertList($type = FALSE)
86 {
87 $data = array();
88 $s_acl = $this->ui->get_permissions($this->dn,"fai/faiScriptEntry","FAIscript");
89 foreach($this->SubObjects as $cn => $entry){
90 if($entry['status'] == "delete") continue;
91 if($type){
92 $data[$cn] = $entry;
93 }else{
94 if(!isset($entry['description'])) $entry['description']="";
95 $data[$cn] = array('data' => array($entry['cn'], $entry['description']));
96 }
97 }
98 return($data);
99 }
102 /* Reload some attributes */
103 function get_object_attributes($object,$attributes)
104 {
105 $ldap = $this->config->get_ldap_link();
106 $ldap->cd($this->config->current['BASE']);
107 $ldap->cat($object['dn'],$attributes);
108 $tmp = $ldap->fetch();
110 foreach($attributes as $attrs){
111 if(isset($tmp[$attrs][0])){
112 $var = $tmp[$attrs][0];
114 /* Check if we must decode some attributes */
115 if(in_array_ics($attrs,$this->sub64coded)){
116 $var = base64_decode($var);
117 }
119 /* check if this is a binary entry */
120 if(in_array_ics($attrs,$this->subBinary)){
121 $var = $ldap->get_attribute($object['dn'], $attrs,$r_array=0);
122 }
124 /* Fix slashes */
125 $var = addslashes($var);
126 $object[$attrs] = $var;
127 }
128 }
129 return($object);
130 }
133 /* Return a valid dn to fetch acls. Because 'new' will not work. */
134 function acl_base_for_current_object($dn)
135 {
136 if($dn == "new" || $dn == ""){
137 if($this->dn == "new"){
138 $dn= $this->parent->parent->acl_base;
139 }else{
140 $dn = $this->dn;
141 }
142 }
143 return($dn);
144 }
147 function execute()
148 {
149 /* Call parent execute */
150 plugin::execute();
152 if($this->is_account && !$this->view_logged){
153 $this->view_logged = TRUE;
154 new log("view","fai/".get_class($this),$this->dn);
155 }
157 /* Fill templating stuff */
158 $smarty= get_smarty();
159 $display= "";
161 /* Add new sub object */
162 if(isset($_POST['AddSubObject']) && !preg_match("/freeze/i",$this->FAIstate)){
163 $this->dialog= new $this->subClassName($this->config,"new");
164 $this->dialog->FAIstate = $this->FAIstate;
165 $this->dialog->set_acl_base($this->acl_base);
166 $this->dialog->set_acl_category("fai");
167 $this->dialog->parent = &$this;
168 $this->is_dialog=true;
169 }
171 if($this->dn != "new"){
172 set_object_info($this->dn);
173 }
175 $this->scriptListWidget->setAcl($this->getacl(""));
176 $this->scriptListWidget->save_object();
177 $action = $this->scriptListWidget->getAction();
178 if($action['action'] =="edit"){
179 $s_entry = $this->scriptListWidget->getKey($action['targets'][0]);
180 if(isset($this->SubObjects[$s_entry])){
182 $obj = $this->SubObjects[$s_entry];
183 if($obj['status'] == "FreshLoaded"){
184 $obj = $this->get_object_attributes($obj,$this->sub_Load_Later);
185 }
187 /* Create new dialog and set acl attributes */
188 $this->dialog= new $this->subClassName($this->config,$this->dn,$obj);
189 $this->dialog->FAIstate = $this->FAIstate;
190 $this->dialog->set_acl_base($this->acl_base_for_current_object($obj['dn']));
191 $this->dialog->set_acl_category("fai");
193 /* Assign some additional dialog informations like headline and parent */
194 set_object_info($obj['dn']);
195 $this->dialog->parent = &$this;
196 $this->is_dialog=true;
197 }
198 }
200 /* Check acls, are we allowed to delete an entry */
201 if($action['action'] =="delete"){
202 $s_entry = $this->scriptListWidget->getKey($action['targets'][0]);
203 if(isset($this->SubObjects[$s_entry])){
204 $entry = $this->SubObjects[$s_entry];
205 $acl = $this->ui->get_permissions($this->acl_base_for_current_object($entry['dn']),"fai/faiScriptEntry") ;
206 if(preg_match("/d/",$acl)){
207 $status = $entry['status'];
208 if($status == "edited" || $status == "FreshLoaded"){
209 $this->SubObjects[$s_entry]['status']= "delete";
210 }else{
211 unset($this->SubObjects[$s_entry]);
212 }
213 }
214 }
215 }
218 /* Save the edited entry */
219 if(isset($_POST['SaveSubObject'])){
221 /* Check if there are still errors remaining that must be fixed before saving */
222 $this->dialog->save_object();
223 $msgs = $this->dialog->check();
224 if(count($msgs)>0){
225 foreach($msgs as $msg){
226 msg_dialog::display(_("Error"), $msg, ERROR_DIALOG);
227 }
228 }else{
230 /* Get return object */
231 $obj = $this->dialog->save();
233 /* If we have renamed the script entry, we must remove the old entry */
234 if(isset($obj['remove'])){
236 /* Get old entry values */
237 $old_stat = $this->SubObjects[$obj['remove']['from']]['status'];
239 /* Depending on status, set new status */
240 if($old_stat == "edited" || $old_stat == "FreshLoaded"){
241 $this->SubObjects[$obj['remove']['from']]['status'] = "delete";
242 }elseif($this->SubObjects[$obj['remove']['from']]['status']=="new"){
243 unset($this->SubObjects[$obj['remove']['from']]);
244 }
246 /* Append the new entry */
247 $obj['status'] = "new";
248 $this->SubObjects[$obj['remove']['to']] = $obj;
249 unset($this->SubObjects[$obj['remove']['to']]['remove']);
250 }else{
252 /* Set new status and append the entry */
253 if($obj['status'] == "FreshLoaded"){
254 $obj['status'] = "edited";
255 }
256 $this->SubObjects[$obj['cn']]=$obj;
257 }
258 $this->is_dialog=false;
259 unset($this->dialog);
260 $this->dialog=FALSE;
262 }
263 }
265 /* Cancel Dialog */
266 if(isset($_POST['CancelSubObject'])){
267 $this->is_dialog=false;
268 unset($this->dialog);
269 $this->dialog=FALSE;
270 }
272 /* Print dialog if $this->dialog is set */
273 if(is_object($this->dialog)){
274 $this->dialog->save_object();
275 $display = $this->dialog->execute();
276 return($display);
277 }
279 $this->scriptListWidget->setListData($this->convertList(TRUE), $this->convertList());
280 $this->scriptListWidget->update();
281 $smarty->assign("Entry_listing",$this->scriptListWidget->render());
283 /* Magic quotes GPC, escapes every ' " \, to solve some security risks
284 * If we post the escaped strings they will be escaped again
285 */
286 foreach($this->attributes as $attrs){
287 if(get_magic_quotes_gpc()){
288 $smarty->assign($attrs,stripslashes($this->$attrs));
289 }else{
290 $smarty->assign($attrs,($this->$attrs));
291 }
292 }
294 $dn = $this->acl_base_for_current_object($this->dn);
295 $smarty->assign("sub_object_is_addable",
296 preg_match("/c/",$this->ui->get_permissions($dn,"fai/faiScriptEntry")) &&
297 !preg_match("/freeze/",$this->FAIstate));
299 $tmp = $this->plInfo();
300 foreach($tmp['plProvidedAcls'] as $name => $translated){
301 $smarty->assign($name."ACL",$this->getacl($name));
302 }
304 $display.= $smarty->fetch(get_template_path('faiScript.tpl', TRUE));
305 return($display);
306 }
309 /* Generate listbox friendly SubObject list
310 */
311 function getList($use_dns=false){
312 $a_return=array();
313 foreach($this->SubObjects as $obj){
314 if($obj['status'] != "delete"){
316 $cn = stripslashes($obj['cn']);
317 $desc = "";
319 if((isset($obj['description']))&&(!empty($obj['description']))){
320 $desc = " [".stripslashes($obj['description'])."]";
321 }
323 if($use_dns){
324 $a_return[$obj['cn']]['name']= $cn.$desc;
325 $a_return[$obj['cn']]['dn']= $obj['dn'];
326 $a_return[$obj['cn']]['FAIpriority']= $obj['FAIpriority'];
327 }else{
328 $a_return[$obj['cn']] = $cn.$desc;
329 }
330 }
331 }
332 return($a_return);
333 }
336 /* Delete me, and all my subtrees
337 */
338 function remove_from_parent()
339 {
340 if($this->acl_is_removeable()){
341 $ldap = $this->config->get_ldap_link();
342 $ldap->cd ($this->dn);
343 $release = $this->parent->parent->fai_release;
344 $use_dn = preg_replace("/".preg_quote(FAI::get_release_dn($this->dn), '/')."/i", $release, $this->dn);
345 new log("remove","fai/".get_class($this),$use_dn,$this->attributes);
346 FAI::prepare_to_save_FAI_object($use_dn,array(),true);
348 foreach($this->SubObjects as $name => $obj){
349 $use_dn = preg_replace("/".preg_quote(FAI::get_release_dn($this->dn), '/')."/i", $release, $obj['dn']);
350 FAI::prepare_to_save_FAI_object($use_dn,array(),true);
351 }
352 $this->handle_post_events("remove");
353 }
354 }
357 /* Save data to object
358 */
359 function save_object()
360 {
361 if((isset($_POST['FAIscript_posted'])) && !preg_match("/freeze/", $this->FAIstate)){
362 plugin::save_object();
363 }
365 /* Get sort order */
366 if(isset($_GET['sort']) && in_array($_GET['sort'],array("name","priority"))){
367 if($this->sort_by == $_GET['sort']){
368 if($this->sort_order == "up"){
369 $this->sort_order = "down";
370 }elseif($this->sort_order == "down"){
371 $this->sort_order = "up";
372 }
373 }
374 $this->sort_by = $_GET['sort'];
375 }
376 }
379 /* Check supplied data */
380 function check()
381 {
382 /* Call common method to give check the hook */
383 $message= plugin::check();
385 /* Ensure that we do not overwrite an allready existing entry
386 */
387 if($this->is_new){
388 $release = $this->parent->parent->fai_release;
389 $new_dn= 'cn='.$this->cn.",".get_ou('faiScriptRDN').get_ou('faiBaseRDN').$release;
390 $res = faiManagement::check_class_name("FAIscript",$this->cn,$new_dn);
391 if(isset($res[$this->cn])){
392 $message[] = msgPool::duplicated(_("Name"));
393 }
394 }
396 return ($message);
397 }
400 /* Save to LDAP */
401 function save()
402 {
403 plugin::save();
405 $ldap = $this->config->get_ldap_link();
407 FAI::prepare_to_save_FAI_object($this->dn,$this->attrs);
409 if($this->initially_was_account){
410 new log("modify","fai/".get_class($this),$this->dn,$this->attributes);
411 }else{
412 new log("create","fai/".get_class($this),$this->dn,$this->attributes);
413 }
415 /* Prepare FAIscriptEntry to write it to ldap
416 * First sort array.
417 * Because we must delete old entries first.
418 * After deletion, we perform add and modify
419 */
420 $Objects = array();
422 /* We do not need to save untouched objects */
423 foreach($this->SubObjects as $name => $obj){
424 if($obj['status'] == "FreshLoaded"){
425 unset($this->SubObjects[$name]);
426 }
427 }
429 foreach($this->SubObjects as $name => $obj){
430 if($obj['status'] == "delete"){
431 $Objects[$name] = $obj;
432 }
433 }
434 foreach($this->SubObjects as $name => $obj){
435 if($obj['status'] != "delete"){
436 $Objects[$name] = $obj;
437 }
438 }
440 foreach($Objects as $name => $obj){
442 foreach($this->sub64coded as $codeIt){
443 $obj[$codeIt]=base64_encode(stripslashes($obj[$codeIt]));
444 }
446 $tmp = array();
447 $attributes = array_merge($this->sub_Load_Later,$this->subAttributes);
448 foreach($attributes as $attrs){
449 if(!isset($obj[$attrs])) continue;
450 if($obj[$attrs] == ""){
451 $obj[$attrs] = array();
452 }
453 if(!is_array($obj[$attrs])){
454 $tmp[$attrs] = stripslashes($obj[$attrs]);
455 }else{
456 $tmp[$attrs] = $obj[$attrs];
457 }
458 }
460 $tmp['objectClass'] = $this->subClasses;
462 $sub_dn = "cn=".$obj['cn'].",".$this->dn;
464 if($obj['status']=="new"){
465 $ldap->cat($sub_dn,array("objectClass"));
466 if($ldap->count()){
467 $obj['status']="edited";
468 }
469 }
471 if(empty($tmp['FAIpriority'])){
472 $tmp['FAIpriority'] ="0";
473 }
475 /* Tag object */
476 $this->tag_attrs($tmp, $sub_dn, $this->gosaUnitTag);
478 if($obj['status'] == "delete"){
479 FAI::prepare_to_save_FAI_object($sub_dn,array(),true);
480 $this->handle_post_events("remove");
481 }elseif($obj['status'] == "edited"){
482 FAI::prepare_to_save_FAI_object($sub_dn,$tmp);
483 $this->handle_post_events("modify");
484 }elseif($obj['status']=="new"){
485 FAI::prepare_to_save_FAI_object($sub_dn,$tmp);
486 $this->handle_post_events("add");
487 }
488 }
489 }
492 function PrepareForCopyPaste($source)
493 {
494 plugin::PrepareForCopyPaste($source);
496 /* Read all leaf objects of this object (For FAIscript this would be FAIscriptEntry)
497 */
498 $res = FAI::get_all_objects_for_given_base($source['dn'],"(&(objectClass=FAIclass)(objectClass=".$this->subClass."))");
499 foreach($res as $obj){
501 /* Skip not relevant objects */
502 if(!preg_match("/".preg_quote($source['dn'], '/')."$/i",$obj['dn'])) continue;
504 $objects = array();
505 $objects['status'] = "edited";
506 $objects['dn'] = $obj['dn'];
507 $objects = $this->get_object_attributes($objects,$this->subAttributes);
508 $objects = $this->get_object_attributes($objects,$this->sub_Load_Later);
509 $this->SubObjects[$objects['cn']] = $objects;
510 }
511 }
514 /*! \brief Used for copy & paste.
515 Returns a HTML input mask, which allows to change the cn of this entry.
516 @param Array Array containing current status && a HTML template.
517 */
518 function getCopyDialog()
519 {
520 $vars = array("cn");
521 $smarty = get_smarty();
522 $smarty->assign("cn", htmlentities($this->cn));
523 $str = $smarty->fetch(get_template_path("paste_generic.tpl",TRUE));
524 $ret = array();
525 $ret['string'] = $str;
526 $ret['status'] = "";
527 return($ret);
528 }
531 /*! \brief Used for copy & paste.
532 Some entries must be renamed to avaoid duplicate entries.
533 */
534 function saveCopyDialog()
535 {
536 if(isset($_POST['cn'])){
537 $this->cn = get_post('cn');
538 }
539 }
542 /* Return plugin informations for acl handling */
543 static function plInfo()
544 {
545 return (array(
546 "plShortName" => _("Script"),
547 "plDescription" => _("FAI script"),
548 "plSelfModify" => FALSE,
549 "plDepends" => array(),
550 "plPriority" => 18,
551 "plSection" => array("administration"),
552 "plCategory" => array("fai"),
553 "plProvidedAcls" => array(
554 "cn" => _("Name")." ("._("Readonly").")",
555 "description" => _("Description"))
556 ));
557 }
558 }
560 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
561 ?>