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 /* Specific attributes */
11 var $cn = ""; // The class name for this object
12 var $description = ""; // The description for this set of partitions
13 var $disks = array(); // All defined Disks
14 var $is_dialog = false; // specifies which buttons will be shown to save or abort
16 var $FAIstate = "";
17 var $ui;
19 var $view_logged = FALSE;
21 function faiPartitionTable (&$config, $dn= NULL)
22 {
23 /* Load Attributes */
24 plugin::plugin ($config, $dn);
26 $this->acl ="#all#";
28 $this->ui = get_userinfo();
30 /* If "dn==new" we try to create a new entry
31 * Else we must read all objects from ldap which belong to this entry.
32 * First read disks from ldap ... and then the partition definitions for the disks.
33 */
34 if($dn != "new"){
35 $this->dn =$dn;
37 /* Get FAIstate
38 */
39 if(isset($this->attrs['FAIstate'][0])){
40 $this->FAIstate = $this->attrs['FAIstate'][0];
41 }
43 /* Read all disks from ldap taht are defined fot this partition table
44 */
45 $ldap = $this->config->get_ldap_link();
46 $ldap->cd ($this->dn);
47 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionDisk))",array("*"));
48 while($object = $ldap->fetch()){
50 /* Skip objects, that are tagged as removed */
51 if(isset($object['FAIstate'][0])){
52 if(preg_match("/removed$/",$object['FAIstate'][0])){
53 continue;
54 }
55 }
57 $this->disks[$object['cn'][0]]['status'] = "edited";
58 $this->disks[$object['cn'][0]]['dn'] = $object['dn'];
59 $this->disks[$object['cn'][0]]['cn'] = $object['cn'][0];
60 if(isset($object['description'][0])){
61 $this->disks[$object['cn'][0]]['description'] = $object['description'][0];
62 }else{
63 $this->disks[$object['cn'][0]]['description'] = "";
64 }
65 $this->disks[$object['cn'][0]]['partitions'] = array();
66 }
68 /* read all partitions for each disk
69 */
70 foreach($this->disks as $name => $disk){
71 $ldap->cd ($disk['dn']);
72 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionEntry))",array("*"));
73 while($partition = $ldap->fetch()){
75 /* Skip objects, that are tagged as removed */
76 if(isset($partition['FAIstate'][0])){
77 if(preg_match("/removed$/",$partition['FAIstate'][0])){
78 continue;
79 }
80 }
82 /* remove count ... from ldap result
83 */
84 foreach($partition as $key=>$val){
85 if((is_numeric($key))||($key=="count")||($key=="dn")){
86 unset($partition[$key]);
87 }else{
88 $partition[$key] = $val[0];
89 }
90 }
92 /* Append fetched partitions
93 */
94 $partition['status']="edited";
95 $this->disks[$name]['partitions'][$partition['FAIpartitionNr']] = $partition;
96 }
97 }
98 }
99 $this->is_new = FALSE;
100 if($this->dn == "new"){
101 $this->is_new =TRUE;
102 }
103 ksort($this->disks);
104 }
107 function acl_base_for_current_object($dn)
108 {
109 if($dn == "new"){
110 if($this->dn == "new"){
111 $dn = session::get('CurrentMainBase');
112 }else{
113 $dn = $this->dn;
114 }
115 }
116 return($dn);
117 }
120 function execute()
121 {
122 /* Call parent execute */
123 plugin::execute();
125 if($this->is_account && !$this->view_logged){
126 $this->view_logged = TRUE;
127 new log("view","fai/".get_class($this),$this->dn);
128 }
130 /* Fill templating stuff */
131 $smarty= get_smarty();
132 $display= "";
134 /* Add Disk to this Partitionset
135 * This code adds a new HDD to the disks
136 * A new Dialog will be opened
137 */
138 if(isset($_POST['AddDisk'])){
139 $usedDiskNames =array();
140 foreach($this->disks as $key=>$disk){
141 $usedDiskNames[]= $key;
142 }
143 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames);
144 $this->dialog->set_acl_base($this->acl_base_for_current_object($this->dn));
145 $this->dialog->set_acl_category("fai");
146 $this->dialog->FAIstate = $this->FAIstate;
147 $this->is_dialog = true;
148 }
150 /* Edit disk.
151 * Open dialog which allows us to edit the selected entry
152 */
154 if($this->dn != "new"){
155 session::set('objectinfo',$this->dn);
156 }
158 if((isset($_POST['EditDisk']))&&(isset($_POST['disks']))){
159 $usedDiskNames =array();
160 $Udisk = $_POST['disks'][0];
161 if(isset($this->disks[$Udisk])){
163 foreach($this->disks as $key=>$disk){
164 if($key != $Udisk){
165 $usedDiskNames[]= $key;
166 }
167 }
169 /* Set object info string, which will be displayed in plugin info line */
170 if(isset($this->disks[$Udisk]['dn'])){
171 session::set('objectinfo',$this->disks[$Udisk]['dn']);
172 $dn = $this->disks[$Udisk]['dn'];
173 }else{
174 session::set('objectinfo',"");
175 $dn = "new";
176 }
178 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames,$this->disks[$Udisk]);
179 $this->dialog->set_acl_base($this->acl_base_for_current_object($dn));
180 $this->dialog->set_acl_category("fai");
181 $this->dialog->FAIstate = $this->FAIstate;
183 $this->is_dialog = true;
184 }
185 }
187 /* Edit aborted, close dialog, without saving anything
188 */
189 if(isset($_POST['CancelDisk'])){
190 unset($this->dialog);
191 $this->dialog = FALSE;
192 $this->is_dialog=false;
193 }
195 /* Dialog saved
196 * Save given data from Dialog, if no error is occurred
197 */
198 if(isset($_POST['SaveDisk'])){
200 if (!preg_match("/freeze/", $this->FAIstate)){
201 $this->dialog->save_object();
202 if(count($this->dialog->check())){
203 foreach($this->dialog->check() as $msg){
204 msg_dialog::display(_("Error"), $msg, ERROR_DIALOG);
205 }
206 }else{
207 $disk = $this->dialog->save();
208 if(isset($disk['rename'])){
209 if($this->disks[$disk['rename']['from']]['status']=="edited"){
210 $this->disks[$disk['rename']['from']]['status']="delete";
211 }else{
212 unset($this->disks[$disk['rename']['from']]);
213 }
215 foreach($disk['partitions'] as $key => $val){
216 if($disk['partitions'][$key]['status']!="delete"){
217 $disk['partitions'][$key]['status']= "new";
218 }
219 }
221 $disk['status']="new";
222 $disk['cn']= $disk['rename']['to'];
223 }
225 $this->disks[$disk['cn']]=$disk;
226 unset($this->dialog);
227 $this->dialog = FALSE;
228 $this->is_dialog=false;
229 ksort($this->disks);
230 }
231 }else{
232 $this->dialog = FALSE;
233 $this->is_dialog=false;
234 }
235 }
237 /* Delete selected disk drive from list
238 * Assign delete status for all its partitions
239 */
240 if((isset($_POST['DelDisk']))&&(!empty($_POST['disks']))){
241 if (!preg_match("/freeze/", $this->FAIstate)){
242 foreach($_POST['disks'] as $disk) {
244 if(isset($this->disks[$disk])){
245 if($this->disks[$disk]['status']=="edited"){
246 $this->disks[$disk."-delete"]=$this->disks[$disk];
247 unset($this->disks[$disk]);
248 $disk = $disk."-delete";
249 $this->disks[$disk]['status']="delete";
250 foreach($this->disks[$disk]['partitions'] as $name => $value ){
251 if($value['status']=="edited"){
252 $this->disks[$disk]['partitions'][$name]['status']="delete";
253 }else{
254 unset($this->disks[$disk]['partitions'][$name]);
255 }
256 }
257 }else{
258 unset($this->disks[$disk]);
259 }
260 }
261 }
262 }
263 }
265 /* Display dialog if one is defined
266 */
267 if(is_object($this->dialog)){
268 $this->dialog->save_object();
269 return($this->dialog->execute());
270 }
272 /* Assign all attributes to smarty engine
273 */
274 foreach($this->attributes as $attrs){
275 $smarty->assign($attrs,$this->$attrs);
276 if($this->$attrs){
277 $smarty->assign($attrs."CHK"," ");
278 }else{
279 $smarty->assign($attrs."CHK"," disabled ");
280 }
281 }
283 $dn = $this->acl_base_for_current_object($this->dn);
284 $smarty->assign("sub_object_is_addable",
285 preg_match("/c/",$this->ui->get_permissions($dn,"fai/faiPartitionTableEntry")) &&
286 !preg_match("/freeze/",$this->FAIstate));
288 $tmp = $this->plInfo();
289 foreach($tmp['plProvidedAcls'] as $name => $translated){
290 $smarty->assign($name."ACL",$this->getacl($name));
291 }
292 $disks = $this->getDisks();
293 $smarty->assign("disks" ,$disks);
294 $display.= $smarty->fetch(get_template_path('faiPartitionTable.tpl', TRUE));
295 return($display);
296 }
298 function getDisks(){
299 /* Return all available disks for this partition table
300 * Return in listBox friendly array
301 */
302 $a_return = array();
303 foreach($this->disks as $key => $disk){
305 $dn = "new";
306 if(isset($obj['dn'])){
307 $dn = $obj['dn'];
308 }
309 $dn = $this->acl_base_for_current_object($dn);
310 $acl = $this->ui->get_permissions($dn,"fai/faiPartitionTableEntry");
311 if(preg_match("/(r|w)/",$acl)) {
313 if($disk['status'] != "delete"){
314 $cnt=0;
315 foreach($disk['partitions'] as $val){
316 if($val['status']!="delete"){
317 $cnt ++;
318 }
319 }
320 if(!empty($disk['description'])){
321 if($cnt == 1){
322 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition"), $cnt);
323 }else{
324 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition(s)"), $cnt);
325 }
326 }else{
327 if($cnt == 1){
328 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition"), $cnt);
329 }else{
330 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition(s)"), $cnt);
331 }
332 }
333 }
334 }
335 }
336 return($a_return);
337 }
340 /* Delete me, and all my subtrees
341 */
342 function remove_from_parent()
343 {
344 $ldap = $this->config->get_ldap_link();
345 $ldap->cd ($this->dn);
347 $faifilter = session::get('faifilter');
348 $use_dn = preg_replace("/".normalizePreg(FAI::get_release_dn($this->dn))."/i", $faifilter['branch'], $this->dn);
349 if($faifilter['branch'] == "main"){
350 $use_dn = $this->dn;
351 }
353 FAI::prepare_to_save_FAI_object($use_dn,array(),true);
355 new log("remove","fai/".get_class($this),$use_dn,$this->attributes);
357 foreach($this->disks as $disk){
359 $disk_dn = "cn=".$disk['cn'].",".$this->dn;
360 $use_dn = preg_replace("/".normalizePreg(FAI::get_release_dn($this->dn))."/i", $faifilter['branch'], $disk_dn);
361 if($faifilter['branch'] == "main"){
362 $use_dn = $disk_dn;
363 }
364 FAI::prepare_to_save_FAI_object($use_dn,array(),true);
366 foreach($disk['partitions'] as $key => $partition){
368 $partition_dn= "FAIpartitionNr=".$partition['FAIpartitionNr'].",".$disk_dn;
369 $use_dn = preg_replace("/".normalizePreg(FAI::get_release_dn($this->dn))."/i", $faifilter['branch'], $partition_dn);
370 if($faifilter['branch'] == "main"){
371 $use_dn = $disk_dn;
372 }
373 FAI::prepare_to_save_FAI_object($use_dn,array(),true);
374 }
375 }
376 }
379 /* Save data to object
380 */
381 function save_object()
382 {
383 if (preg_match("/freeze/", $this->FAIstate)) return;
384 plugin::save_object();
385 foreach($this->attributes as $attrs){
386 if(isset($_POST[$attrs])){
387 $this->$attrs = $_POST[$attrs];
388 }
389 }
390 }
393 /* Check supplied data */
394 function check()
395 {
396 /* Call common method to give check the hook */
397 $message= plugin::check();
399 /* Ensure that we do not overwrite an allready existing entry
400 */
401 if($this->is_new){
402 $new_dn= 'cn='.$this->cn.",".get_ou('faipartitionou').get_ou('faiou').session::get('CurrentMainBase');
403 $faifilter = session::get('faifilter');
404 if($faifilter['branch']!="main"){
405 $new_dn ='cn='.$this->cn.",".get_ou('faipartitionou').$faifilter['branch'];
406 }
408 $res = faiManagement::check_class_name("FAIpartitionTable",$this->cn,$new_dn);
409 if(isset($res[$this->cn])){
410 $message[] = msgPool::duplicated(_("Name"));
411 }
412 }
413 return ($message);
414 }
417 /* Save to LDAP */
418 function save()
419 {
421 plugin::save();
422 /* Save current settings.
423 * 1 : We must save the partition table, with its description and cn
424 * 2 : Append Disk with cn and description.
425 * 3 : Save partitions for each disk
426 */
428 $ldap = $this->config->get_ldap_link();
430 FAI::prepare_to_save_FAI_object($this->dn,$this->attrs);
432 if($this->initially_was_account){
433 new log("modify","fai/".get_class($this),$this->dn,$this->attributes);
434 }else{
435 new log("create","fai/".get_class($this),$this->dn,$this->attributes);
436 }
438 /* Sort entries, because we must delete entries with status="delete" first */
439 $order = array();
440 foreach($this->disks as $key => $disk){
441 if($disk['status'] == "delete"){
442 $order[$key] = $disk;
443 }
444 }
445 foreach($this->disks as $key => $disk){
446 if($disk['status'] != "delete"){
447 $order[$key] = $disk;
448 }
449 }
451 /* Append all disks to ldap */
452 foreach($order as $cn=>$disk){
453 $disk_dn = "cn=".$disk['cn'].",".$this->dn;
454 $disk_attrs['cn'] = $disk['cn'];
455 $disk_attrs['description'] = $disk['description'];
456 $disk_attrs['objectClass'] = array("top","FAIclass","FAIpartitionDisk");
458 if($disk['status']=="new"){
459 $ldap->cat($disk_dn,array("objectClass"));
460 if($ldap->count()){
461 $disk['status']="edited";
462 }
463 }
465 /* Tag object */
466 $this->tag_attrs($disk_attrs, $disk_dn, $this->gosaUnitTag);
468 if($disk['status'] == "delete"){
469 FAI::prepare_to_save_FAI_object($disk_dn,array(),true);
470 $this->handle_post_events("remove");
471 }elseif($disk['status'] == "edited"){
472 FAI::prepare_to_save_FAI_object($disk_dn,$disk_attrs);
473 $this->handle_post_events("modify");
474 }elseif($disk['status']=="new"){
475 FAI::prepare_to_save_FAI_object($disk_dn,$disk_attrs);
476 $this->handle_post_events("add");
477 }
479 if($disk['status']!="delete")
480 /* Add all partitions */
481 foreach($disk['partitions'] as $key => $partition){
482 $partition_attrs = array();
484 foreach($partition as $key => $value){
485 if(!empty($value)){
486 $partition_attrs[$key]=$value;
487 }else{
488 unset($partition_attrs[$key]);
489 }
490 }
492 $partition_dn= "FAIpartitionNr=".$partition_attrs['FAIpartitionNr'].",".$disk_dn;
493 $partition_attrs['objectClass']= array("top","FAIclass","FAIpartitionEntry");
494 $partition_attrs['cn']= $partition_attrs['FAIpartitionNr'];
496 unset($partition_attrs['status']);
497 unset($partition_attrs['old_cn']);
499 if($partition['status']=="new"){
500 $ldap->cat($partition_dn,array("objectClass"));
501 if($ldap->count()){
502 $partition['status']="edited";
503 }
504 }
506 if((!isset($partition['FAImountPoint']))||(empty($partition['FAImountPoint']))){
507 $partition_attrs['FAImountPoint']="swap";
508 }
510 /* Tag object */
511 $this->tag_attrs($partition_attrs, $partition_dn, $this->gosaUnitTag);
513 if($partition['status'] == "delete"){
514 FAI::prepare_to_save_FAI_object($partition_dn,array(),true);
515 $this->handle_post_events("remove");
516 }elseif($partition['status'] == "edited"){
517 FAI::prepare_to_save_FAI_object($partition_dn,$partition_attrs);
518 $this->handle_post_events("modify");
519 }elseif($partition['status']=="new"){
520 FAI::prepare_to_save_FAI_object($partition_dn,$partition_attrs);
521 $this->handle_post_events("add");
522 }
523 }
524 }
525 $this->handle_post_events("add");
526 }
529 function PrepareForCopyPaste($source)
530 {
531 plugin::PrepareForCopyPaste($source);
532 /* Get FAIstate
533 */
534 if(isset($source['FAIstate'][0])){
535 $this->FAIstate = $source['FAIstate'][0];
536 }
538 /* Read all disks from ldap taht are defined fot this partition table
539 */
540 $ldap = $this->config->get_ldap_link();
541 $ldap->cd ($source['dn']);
542 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionDisk))",array("*"));
543 while($object = $ldap->fetch()){
545 /* Skip objects, that are tagged as removed */
546 if(isset($object['FAIstate'][0])){
547 if(preg_match("/removed$/",$object['FAIstate'][0])){
548 continue;
549 }
550 }
552 $this->disks[$object['cn'][0]]['status'] = "edited";
553 $this->disks[$object['cn'][0]]['dn'] = $object['dn'];
554 $this->disks[$object['cn'][0]]['cn'] = $object['cn'][0];
555 if(isset($object['description'][0])){
556 $this->disks[$object['cn'][0]]['description'] = $object['description'][0];
557 }else{
558 $this->disks[$object['cn'][0]]['description'] = "";
559 }
560 $this->disks[$object['cn'][0]]['partitions'] = array();
561 }
563 /* read all partitions for each disk
564 */
565 foreach($this->disks as $name => $disk){
566 $ldap->cd ($disk['dn']);
567 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionEntry))",array("*"));
568 while($partition = $ldap->fetch()){
570 /* Skip objects, that are tagged as removed */
571 if(isset($partition['FAIstate'][0])){
572 if(preg_match("/removed$/",$partition['FAIstate'][0])){
573 continue;
574 }
575 }
577 /* remove count ... from ldap result
578 */
579 foreach($partition as $key=>$val){
580 if((is_numeric($key))||($key=="count")||($key=="dn")){
581 unset($partition[$key]);
582 }else{
583 $partition[$key] = $val[0];
584 }
585 }
587 /* Append fetched partitions
588 */
589 $partition['status']="edited";
590 $this->disks[$name]['partitions'][$partition['FAIpartitionNr']] = $partition;
591 }
592 }
593 ksort($this->disks);
594 }
597 /* Return plugin informations for acl handling */
598 static function plInfo()
599 {
600 return (array(
601 "plShortName" => _("Partition table"),
602 "plDescription" => _("FAI partition table"),
603 "plSelfModify" => FALSE,
604 "plDepends" => array(),
605 "plPriority" => 26,
606 "plSection" => array("administration"),
607 "plCategory" => array("fai"),
608 "plProvidedAcls" => array(
609 "cn" => _("Name")." ("._("Read only").")",
610 "description" => _("Description"))
611 ));
612 }
615 /*! \brief Used for copy & paste.
616 Returns a HTML input mask, which allows to change the cn of this entry.
617 @param Array Array containing current status && a HTML template.
618 */
619 function getCopyDialog()
620 {
621 $vars = array("cn");
622 $smarty = get_smarty();
623 $smarty->assign("cn", htmlentities($this->cn));
624 $str = $smarty->fetch(get_template_path("paste_generic.tpl",TRUE));
625 $ret = array();
626 $ret['string'] = $str;
627 $ret['status'] = "";
628 return($ret);
629 }
632 /*! \brief Used for copy & paste.
633 Some entries must be renamed to avaoid duplicate entries.
634 */
635 function saveCopyDialog()
636 {
637 if(isset($_POST['cn'])){
638 $this->cn = get_post('cn');
639 }
640 }
641 }
643 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
644 ?>