1 <?php
3 class faiPartitionTable extends plugin
4 {
5 /* attribute list for save action */
6 var $ignore_account = TRUE;
7 var $attributes = array("cn","description");
8 var $objectclasses = array("top","FAIclass","FAIpartitionTable");
10 var $subAttributes = array("cn","description");
11 var $subPartAttributes = array("cn","FAIpartitionNr","FAIpartitionSize","FAImountPoint","FAIfsType","FAIpartitionType","FAImountOptions","FAIfsOptions","FAIpartitionFlags","description");
13 var $sub64coded = array();
14 var $subBinary = array();
16 /* Specific attributes */
17 var $cn = ""; // The class name for this object
18 var $description = ""; // The description for this set of partitions
19 var $disks = array(); // All defined Disks
20 var $is_dialog = false; // specifies which buttons will be shown to save or abort
22 var $FAIstate = "";
23 var $ui;
25 var $view_logged = FALSE;
27 function faiPartitionTable (&$config, $dn= NULL)
28 {
29 /* Load Attributes */
30 plugin::plugin ($config, $dn);
32 /* If "dn==new" we try to create a new entry
33 * Else we must read all objects from ldap which belong to this entry.
34 */
35 $this->ui = get_userinfo();
36 if($dn != "new"){
37 $this->dn =$dn;
39 /* Read all leaf objects of this object (For FAIscript this would be FAIscriptEntry)
40 */
41 $res = FAI::get_all_objects_for_given_base($this->dn,"(&(objectClass=FAIclass)(objectClass=FAIpartitionDisk))");
42 foreach($res as $obj){
44 /* Skip not relevant objects */
45 if(!preg_match("/".normalizePreg($this->dn)."$/i",$obj['dn'])) continue;
47 $objects = array();
48 $objects['description'] = "";
49 $objects['status'] = "edited";
50 $objects['dn'] = $obj['dn'];
51 $objects = $this->get_object_attributes($objects,$this->subAttributes);
52 $this->disks[$objects['cn']] = $objects;
53 $this->disks[$objects['cn']]['partitions'] = array();
54 }
56 /* read all partitions for each disk
57 */
58 foreach($this->disks as $name => $disk){
59 $res = FAI::get_all_objects_for_given_base($disk['dn'],"(&(objectClass=FAIclass)(objectClass=FAIpartitionEntry))");
60 foreach($res as $obj){
62 /* Skip not relevant objects */
63 if(!preg_match("/".normalizePreg($disk['dn'])."$/i",$obj['dn'])) continue;
65 $objects = array();
66 $objects['status'] = "edited";
67 $objects['dn'] = $obj['dn'];
68 $objects = $this->get_object_attributes($objects,$this->subPartAttributes);
69 unset($objects['dn']);;
70 $this->disks[$name]['partitions'][$objects['FAIpartitionNr']] = $objects;
71 }
72 }
73 }
75 $this->is_new = FALSE;
76 if($this->dn == "new"){
77 $this->is_new =TRUE;
78 }
79 ksort($this->disks);
80 }
83 function acl_base_for_current_object($dn)
84 {
85 if($dn == "new"){
86 if($this->dn == "new"){
87 $dn = session::get('CurrentMainBase');
88 }else{
89 $dn = $this->dn;
90 }
91 }
92 return($dn);
93 }
96 function execute()
97 {
98 /* Call parent execute */
99 plugin::execute();
101 if($this->is_account && !$this->view_logged){
102 $this->view_logged = TRUE;
103 new log("view","fai/".get_class($this),$this->dn);
104 }
106 /* Fill templating stuff */
107 $smarty= get_smarty();
108 $display= "";
110 /* Add Disk to this Partitionset
111 * This code adds a new HDD to the disks
112 * A new Dialog will be opened
113 */
114 if(isset($_POST['AddDisk']) && !preg_match("/freeze/i",$this->FAIstate)){
115 $usedDiskNames =array();
116 foreach($this->disks as $key=>$disk){
117 $usedDiskNames[]= $key;
118 }
119 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames);
120 $this->dialog->set_acl_base($this->acl_base_for_current_object($this->dn));
121 $this->dialog->set_acl_category("fai");
122 $this->dialog->FAIstate = $this->FAIstate;
123 $this->is_dialog = true;
124 }
126 /* Edit disk.
127 * Open dialog which allows us to edit the selected entry
128 */
130 if($this->dn != "new"){
131 session::set('objectinfo',$this->dn);
132 }
134 if((isset($_POST['EditDisk']))&&(isset($_POST['disks']))){
135 $usedDiskNames =array();
136 $Udisk = $_POST['disks'][0];
137 if(isset($this->disks[$Udisk])){
139 foreach($this->disks as $key=>$disk){
140 if($key != $Udisk){
141 $usedDiskNames[]= $key;
142 }
143 }
145 /* Set object info string, which will be displayed in plugin info line */
146 if(isset($this->disks[$Udisk]['dn'])){
147 session::set('objectinfo',$this->disks[$Udisk]['dn']);
148 $dn = $this->disks[$Udisk]['dn'];
149 }else{
150 session::set('objectinfo',"");
151 $dn = "new";
152 }
154 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames,$this->disks[$Udisk]);
155 $this->dialog->set_acl_base($this->acl_base_for_current_object($dn));
156 $this->dialog->set_acl_category("fai");
157 $this->dialog->FAIstate = $this->FAIstate;
159 $this->is_dialog = true;
160 }
161 }
163 /* Edit aborted, close dialog, without saving anything
164 */
165 if(isset($_POST['CancelDisk'])){
166 unset($this->dialog);
167 $this->dialog = FALSE;
168 $this->is_dialog=false;
169 }
171 /* Dialog saved
172 * Save given data from Dialog, if no error is occurred
173 */
174 if(isset($_POST['SaveDisk'])){
176 if (!preg_match("/freeze/i", $this->FAIstate)){
177 $this->dialog->save_object();
178 if(count($this->dialog->check())){
179 foreach($this->dialog->check() as $msg){
180 msg_dialog::display(_("Error"), $msg, ERROR_DIALOG);
181 }
182 }else{
183 $disk = $this->dialog->save();
184 if(isset($disk['rename'])){
185 if($this->disks[$disk['rename']['from']]['status']=="edited"){
186 $this->disks[$disk['rename']['from']]['status']="delete";
187 }else{
188 unset($this->disks[$disk['rename']['from']]);
189 }
191 foreach($disk['partitions'] as $key => $val){
192 if($disk['partitions'][$key]['status']!="delete"){
193 $disk['partitions'][$key]['status']= "new";
194 }
195 }
197 $disk['status']="new";
198 $disk['cn']= $disk['rename']['to'];
199 }
201 $this->disks[$disk['cn']]=$disk;
202 unset($this->dialog);
203 $this->dialog = FALSE;
204 $this->is_dialog=false;
205 ksort($this->disks);
206 }
207 }else{
208 $this->dialog = FALSE;
209 $this->is_dialog=false;
210 }
211 }
213 /* Delete selected disk drive from list
214 * Assign delete status for all its partitions
215 */
216 if((isset($_POST['DelDisk']))&&(!empty($_POST['disks']))){
217 if (!preg_match("/freeze/i", $this->FAIstate)){
218 foreach($_POST['disks'] as $disk) {
220 if(isset($this->disks[$disk])){
221 if($this->disks[$disk]['status']=="edited"){
222 $this->disks[$disk."-delete"]=$this->disks[$disk];
223 unset($this->disks[$disk]);
224 $disk = $disk."-delete";
225 $this->disks[$disk]['status']="delete";
226 foreach($this->disks[$disk]['partitions'] as $name => $value ){
227 if($value['status']=="edited"){
228 $this->disks[$disk]['partitions'][$name]['status']="delete";
229 }else{
230 unset($this->disks[$disk]['partitions'][$name]);
231 }
232 }
233 }else{
234 unset($this->disks[$disk]);
235 }
236 }
237 }
238 }
239 }
241 /* Display dialog if one is defined
242 */
243 if(is_object($this->dialog)){
244 $this->dialog->save_object();
245 return($this->dialog->execute());
246 }
248 /* Assign all attributes to smarty engine
249 */
250 foreach($this->attributes as $attrs){
251 $smarty->assign($attrs,$this->$attrs);
252 if($this->$attrs){
253 $smarty->assign($attrs."CHK"," ");
254 }else{
255 $smarty->assign($attrs."CHK"," disabled ");
256 }
257 }
259 $dn = $this->acl_base_for_current_object($this->dn);
260 $smarty->assign("sub_object_is_addable",
261 preg_match("/c/",$this->ui->get_permissions($dn,"fai/faiPartitionTableEntry")) &&
262 !preg_match("/freeze/",$this->FAIstate));
263 $smarty->assign("sub_object_is_removeable",
264 preg_match("/d/",$this->ui->get_permissions($dn,"fai/faiPartitionTableEntry")) &&
265 !preg_match("/freeze/",$this->FAIstate));
267 $tmp = $this->plInfo();
268 foreach($tmp['plProvidedAcls'] as $name => $translated){
269 $smarty->assign($name."ACL",$this->getacl($name,preg_match("/freeze/i",$this->FAIstate)));
270 }
271 $disks = $this->getDisks();
272 $smarty->assign("disks" ,$disks);
273 $display.= $smarty->fetch(get_template_path('faiPartitionTable.tpl', TRUE));
274 return($display);
275 }
277 function getDisks(){
278 /* Return all available disks for this partition table
279 * Return in listBox friendly array
280 */
281 $a_return = array();
282 foreach($this->disks as $key => $disk){
284 $dn = "new";
285 if(isset($obj['dn'])){
286 $dn = $obj['dn'];
287 }
288 $dn = $this->acl_base_for_current_object($dn);
289 $acl = $this->ui->get_permissions($dn,"fai/faiPartitionTableEntry");
290 if(preg_match("/(r|w)/",$acl)) {
292 if($disk['status'] != "delete"){
293 $cnt=0;
294 foreach($disk['partitions'] as $val){
295 if($val['status']!="delete"){
296 $cnt ++;
297 }
298 }
299 if(!empty($disk['description'])){
300 if($cnt == 1){
301 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition"), $cnt);
302 }else{
303 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition(s)"), $cnt);
304 }
305 }else{
306 if($cnt == 1){
307 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition"), $cnt);
308 }else{
309 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition(s)"), $cnt);
310 }
311 }
312 }
313 }
314 }
315 return($a_return);
316 }
319 /* Delete me, and all my subtrees
320 */
321 function remove_from_parent()
322 {
323 $ldap = $this->config->get_ldap_link();
324 $ldap->cd ($this->dn);
326 $release = $this->parent->parent->fai_release;
327 $use_dn = preg_replace("/".normalizePreg(FAI::get_release_dn($this->dn))."/i", $release, $this->dn);
329 FAI::prepare_to_save_FAI_object($use_dn,array(),true);
330 new log("remove","fai/".get_class($this),$use_dn,$this->attributes);
331 foreach($this->disks as $disk){
332 $disk_dn = "cn=".$disk['cn'].",".$this->dn;
333 $use_dn = preg_replace("/".normalizePreg(FAI::get_release_dn($this->dn))."/i",$release, $disk_dn);
334 FAI::prepare_to_save_FAI_object($use_dn,array(),true);
335 foreach($disk['partitions'] as $key => $partition){
336 $partition_dn= "FAIpartitionNr=".$partition['FAIpartitionNr'].",".$disk_dn;
337 $use_dn = preg_replace("/".normalizePreg(FAI::get_release_dn($this->dn))."/i", $release, $partition_dn);
338 FAI::prepare_to_save_FAI_object($use_dn,array(),true);
339 }
340 }
341 }
344 /* Save data to object
345 */
346 function save_object()
347 {
348 if (preg_match("/freeze/", $this->FAIstate)) return;
349 plugin::save_object();
350 foreach($this->attributes as $attrs){
351 if(isset($_POST[$attrs])){
352 $this->$attrs = $_POST[$attrs];
353 }
354 }
355 }
358 /* Check supplied data */
359 function check()
360 {
361 /* Call common method to give check the hook */
362 $message= plugin::check();
364 /* Ensure that we do not overwrite an allready existing entry
365 */
366 if($this->is_new){
367 $release = $this->parent->parent->fai_release;
368 $new_dn= 'cn='.$this->cn.",".get_ou('faipartitionou').get_ou('faiou').$release;
369 $res = faiManagement::check_class_name("FAIpartitionTable",$this->cn,$new_dn);
370 if(isset($res[$this->cn])){
371 $message[] = msgPool::duplicated(_("Name"));
372 }
373 }
374 return ($message);
375 }
378 /* Save to LDAP */
379 function save()
380 {
382 plugin::save();
383 /* Save current settings.
384 * 1 : We must save the partition table, with its description and cn
385 * 2 : Append Disk with cn and description.
386 * 3 : Save partitions for each disk
387 */
389 $ldap = $this->config->get_ldap_link();
391 FAI::prepare_to_save_FAI_object($this->dn,$this->attrs);
393 if($this->initially_was_account){
394 new log("modify","fai/".get_class($this),$this->dn,$this->attributes);
395 }else{
396 new log("create","fai/".get_class($this),$this->dn,$this->attributes);
397 }
399 /* Sort entries, because we must delete entries with status="delete" first */
400 $order = array();
401 foreach($this->disks as $key => $disk){
402 if($disk['status'] == "delete"){
403 $order[$key] = $disk;
404 }
405 }
406 foreach($this->disks as $key => $disk){
407 if($disk['status'] != "delete"){
408 $order[$key] = $disk;
409 }
410 }
412 /* Append all disks to ldap */
413 foreach($order as $cn=>$disk){
414 $disk_dn = "cn=".$disk['cn'].",".$this->dn;
415 $disk_attrs['cn'] = $disk['cn'];
416 $disk_attrs['description'] = $disk['description'];
418 if(empty($disk_attrs['description']) && $disk['status'] == "edited"){
419 $disk_attrs['description'] = array();
420 }
422 $disk_attrs['objectClass'] = array("top","FAIclass","FAIpartitionDisk");
424 if($disk['status']=="new"){
425 $ldap->cat($disk_dn,array("objectClass"));
426 if($ldap->count()){
427 $disk['status']="edited";
428 }
429 }
431 /* Tag object */
432 $this->tag_attrs($disk_attrs, $disk_dn, $this->gosaUnitTag);
434 if($disk['status'] == "delete"){
435 FAI::prepare_to_save_FAI_object($disk_dn,array(),true);
436 $this->handle_post_events("remove");
437 }elseif($disk['status'] == "edited"){
438 FAI::prepare_to_save_FAI_object($disk_dn,$disk_attrs);
439 $this->handle_post_events("modify");
440 }elseif($disk['status']=="new"){
441 FAI::prepare_to_save_FAI_object($disk_dn,$disk_attrs);
442 $this->handle_post_events("add");
443 }
445 if($disk['status']!="delete")
446 /* Add all partitions */
447 foreach($disk['partitions'] as $key => $partition){
448 $partition_attrs = array();
450 foreach($partition as $key => $value){
451 if(!empty($value)){
452 $partition_attrs[$key]=$value;
453 }else{
454 unset($partition_attrs[$key]);
455 }
456 }
458 $partition_dn= "FAIpartitionNr=".$partition_attrs['FAIpartitionNr'].",".$disk_dn;
459 $partition_attrs['objectClass']= array("top","FAIclass","FAIpartitionEntry");
460 $partition_attrs['cn']= $partition_attrs['FAIpartitionNr'];
462 unset($partition_attrs['status']);
463 unset($partition_attrs['old_cn']);
465 if($partition['status']=="new"){
466 $ldap->cat($partition_dn,array("objectClass"));
467 if($ldap->count()){
468 $partition['status']="edited";
469 }
470 }
472 if((!isset($partition['FAImountPoint']))||(empty($partition['FAImountPoint']))){
473 $partition_attrs['FAImountPoint']="swap";
474 }
476 /* Tag object */
477 $this->tag_attrs($partition_attrs, $partition_dn, $this->gosaUnitTag);
479 if($partition['status'] == "delete"){
480 FAI::prepare_to_save_FAI_object($partition_dn,array(),true);
481 $this->handle_post_events("remove");
482 }elseif($partition['status'] == "edited"){
483 FAI::prepare_to_save_FAI_object($partition_dn,$partition_attrs);
484 $this->handle_post_events("modify");
485 }elseif($partition['status']=="new"){
486 FAI::prepare_to_save_FAI_object($partition_dn,$partition_attrs);
487 $this->handle_post_events("add");
488 }
489 }
490 }
491 $this->handle_post_events("add");
492 }
495 function PrepareForCopyPaste($source)
496 {
497 plugin::PrepareForCopyPaste($source);
499 /* Read all leaf objects of this object (For FAIscript this would be FAIscriptEntry)
500 */
501 $res = FAI::get_all_objects_for_given_base($source['dn'],"(&(objectClass=FAIclass)(objectClass=FAIpartitionDisk))");
502 foreach($res as $obj){
504 /* Skip not relevant objects */
505 if(!preg_match("/".normalizePreg($source['dn'])."$/i",$obj['dn'])) continue;
507 $objects = array();
508 $objects['description'] = "";
509 $objects['status'] = "edited";
510 $objects['dn'] = $obj['dn'];
511 $objects = $this->get_object_attributes($objects,$this->subAttributes);
512 $this->disks[$objects['cn']] = $objects;
513 $this->disks[$objects['cn']]['partitions'] = array();
514 }
516 /* read all partitions for each disk
517 */
518 foreach($this->disks as $name => $disk){
519 $res = FAI::get_all_objects_for_given_base($disk['dn'],"(&(objectClass=FAIclass)(objectClass=FAIpartitionEntry))");
520 foreach($res as $obj){
522 /* Skip not relevant objects */
523 if(!preg_match("/".normalizePreg($disk['dn'])."$/i",$obj['dn'])) continue;
525 $objects = array();
526 $objects['status'] = "edited";
527 $objects['dn'] = $obj['dn'];
528 $objects = $this->get_object_attributes($objects,$this->subPartAttributes);
529 unset($objects['dn']);;
530 $this->disks[$name]['partitions'][$objects['FAIpartitionNr']] = $objects;
531 }
532 }
533 ksort($this->disks);
534 }
537 /* Return plugin informations for acl handling */
538 static function plInfo()
539 {
540 return (array(
541 "plShortName" => _("Partition table"),
542 "plDescription" => _("FAI partition table"),
543 "plSelfModify" => FALSE,
544 "plDepends" => array(),
545 "plPriority" => 26,
546 "plSection" => array("administration"),
547 "plCategory" => array("fai"),
548 "plProvidedAcls" => array(
549 "cn" => _("Name")." ("._("Read only").")",
550 "description" => _("Description"))
551 ));
552 }
555 /*! \brief Used for copy & paste.
556 Returns a HTML input mask, which allows to change the cn of this entry.
557 @param Array Array containing current status && a HTML template.
558 */
559 function getCopyDialog()
560 {
561 $vars = array("cn");
562 $smarty = get_smarty();
563 $smarty->assign("cn", htmlentities($this->cn));
564 $str = $smarty->fetch(get_template_path("paste_generic.tpl",TRUE));
565 $ret = array();
566 $ret['string'] = $str;
567 $ret['status'] = "";
568 return($ret);
569 }
572 /*! \brief Used for copy & paste.
573 Some entries must be renamed to avaoid duplicate entries.
574 */
575 function saveCopyDialog()
576 {
577 if(isset($_POST['cn'])){
578 $this->cn = get_post('cn');
579 }
580 }
582 /* Reload some attributes */
583 function get_object_attributes($object,$attributes)
584 {
585 $ldap = $this->config->get_ldap_link();
586 $ldap->cd($this->config->current['BASE']);
587 $ldap->cat($object['dn'],$attributes);
588 $tmp = $ldap->fetch();
590 foreach($attributes as $attrs){
591 if(isset($tmp[$attrs][0])){
592 $var = $tmp[$attrs][0];
594 /* Check if we must decode some attributes */
595 if(in_array_ics($attrs,$this->sub64coded)){
596 $var = base64_decode($var);
597 }
599 /* check if this is a binary entry */
600 if(in_array_ics($attrs,$this->subBinary)){
601 $var = $ldap->get_attribute($object['dn'], $attrs,$r_array=0);
602 }
604 /* Fix slashes */
605 $var = addslashes($var);
606 $object[$attrs] = $var;
607 }
608 }
609 return($object);
610 }
612 }
614 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
615 ?>