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 /* Read all disks from ldap taht are defined fot this partition table
38 */
39 $ldap = $this->config->get_ldap_link();
40 $ldap->cd ($this->dn);
41 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionDisk))",array("*"));
42 while($object = $ldap->fetch()){
44 /* Skip objects, that are tagged as removed */
45 if(isset($object['FAIstate'][0])){
46 if(preg_match("/removed$/",$object['FAIstate'][0])){
47 continue;
48 }
49 }
51 $this->disks[$object['cn'][0]]['status'] = "edited";
52 $this->disks[$object['cn'][0]]['dn'] = $object['dn'];
53 $this->disks[$object['cn'][0]]['cn'] = $object['cn'][0];
54 if(isset($object['description'][0])){
55 $this->disks[$object['cn'][0]]['description'] = $object['description'][0];
56 }else{
57 $this->disks[$object['cn'][0]]['description'] = "";
58 }
59 $this->disks[$object['cn'][0]]['partitions'] = array();
60 }
62 /* read all partitions for each disk
63 */
64 foreach($this->disks as $name => $disk){
65 $ldap->cd ($disk['dn']);
66 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionEntry))",array("*"));
67 while($partition = $ldap->fetch()){
69 /* Skip objects, that are tagged as removed */
70 if(isset($partition['FAIstate'][0])){
71 if(preg_match("/removed$/",$partition['FAIstate'][0])){
72 continue;
73 }
74 }
76 /* remove count ... from ldap result
77 */
78 foreach($partition as $key=>$val){
79 if((is_numeric($key))||($key=="count")||($key=="dn")){
80 unset($partition[$key]);
81 }else{
82 $partition[$key] = $val[0];
83 }
84 }
86 /* Append fetched partitions
87 */
88 $partition['status']="edited";
89 $this->disks[$name]['partitions'][$partition['FAIpartitionNr']] = $partition;
90 }
91 }
92 }
93 $this->is_new = FALSE;
94 if($this->dn == "new"){
95 $this->is_new =TRUE;
96 }
97 ksort($this->disks);
98 }
101 function acl_base_for_current_object($dn)
102 {
103 if($dn == "new"){
104 if($this->dn == "new"){
105 $dn = session::get('CurrentMainBase');
106 }else{
107 $dn = $this->dn;
108 }
109 }
110 return($dn);
111 }
114 function execute()
115 {
116 /* Call parent execute */
117 plugin::execute();
119 if($this->is_account && !$this->view_logged){
120 $this->view_logged = TRUE;
121 new log("view","fai/".get_class($this),$this->dn);
122 }
124 /* Fill templating stuff */
125 $smarty= get_smarty();
126 $display= "";
128 /* Add Disk to this Partitionset
129 * This code adds a new HDD to the disks
130 * A new Dialog will be opened
131 */
132 if(isset($_POST['AddDisk']) && !preg_match("/freeze/i",$this->FAIstate)){
133 $usedDiskNames =array();
134 foreach($this->disks as $key=>$disk){
135 $usedDiskNames[]= $key;
136 }
137 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames);
138 $this->dialog->set_acl_base($this->acl_base_for_current_object($this->dn));
139 $this->dialog->set_acl_category("fai");
140 $this->dialog->FAIstate = $this->FAIstate;
141 $this->is_dialog = true;
142 }
144 /* Edit disk.
145 * Open dialog which allows us to edit the selected entry
146 */
148 if($this->dn != "new"){
149 session::set('objectinfo',$this->dn);
150 }
152 if((isset($_POST['EditDisk']))&&(isset($_POST['disks']))){
153 $usedDiskNames =array();
154 $Udisk = $_POST['disks'][0];
155 if(isset($this->disks[$Udisk])){
157 foreach($this->disks as $key=>$disk){
158 if($key != $Udisk){
159 $usedDiskNames[]= $key;
160 }
161 }
163 /* Set object info string, which will be displayed in plugin info line */
164 if(isset($this->disks[$Udisk]['dn'])){
165 session::set('objectinfo',$this->disks[$Udisk]['dn']);
166 $dn = $this->disks[$Udisk]['dn'];
167 }else{
168 session::set('objectinfo',"");
169 $dn = "new";
170 }
172 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames,$this->disks[$Udisk]);
173 $this->dialog->set_acl_base($this->acl_base_for_current_object($dn));
174 $this->dialog->set_acl_category("fai");
175 $this->dialog->FAIstate = $this->FAIstate;
177 $this->is_dialog = true;
178 }
179 }
181 /* Edit aborted, close dialog, without saving anything
182 */
183 if(isset($_POST['CancelDisk'])){
184 unset($this->dialog);
185 $this->dialog = FALSE;
186 $this->is_dialog=false;
187 }
189 /* Dialog saved
190 * Save given data from Dialog, if no error is occurred
191 */
192 if(isset($_POST['SaveDisk'])){
194 if (!preg_match("/freeze/i", $this->FAIstate)){
195 $this->dialog->save_object();
196 if(count($this->dialog->check())){
197 foreach($this->dialog->check() as $msg){
198 msg_dialog::display(_("Error"), $msg, ERROR_DIALOG);
199 }
200 }else{
201 $disk = $this->dialog->save();
202 if(isset($disk['rename'])){
203 if($this->disks[$disk['rename']['from']]['status']=="edited"){
204 $this->disks[$disk['rename']['from']]['status']="delete";
205 }else{
206 unset($this->disks[$disk['rename']['from']]);
207 }
209 foreach($disk['partitions'] as $key => $val){
210 if($disk['partitions'][$key]['status']!="delete"){
211 $disk['partitions'][$key]['status']= "new";
212 }
213 }
215 $disk['status']="new";
216 $disk['cn']= $disk['rename']['to'];
217 }
219 $this->disks[$disk['cn']]=$disk;
220 unset($this->dialog);
221 $this->dialog = FALSE;
222 $this->is_dialog=false;
223 ksort($this->disks);
224 }
225 }else{
226 $this->dialog = FALSE;
227 $this->is_dialog=false;
228 }
229 }
231 /* Delete selected disk drive from list
232 * Assign delete status for all its partitions
233 */
234 if((isset($_POST['DelDisk']))&&(!empty($_POST['disks']))){
235 if (!preg_match("/freeze/i", $this->FAIstate)){
236 foreach($_POST['disks'] as $disk) {
238 if(isset($this->disks[$disk])){
239 if($this->disks[$disk]['status']=="edited"){
240 $this->disks[$disk."-delete"]=$this->disks[$disk];
241 unset($this->disks[$disk]);
242 $disk = $disk."-delete";
243 $this->disks[$disk]['status']="delete";
244 foreach($this->disks[$disk]['partitions'] as $name => $value ){
245 if($value['status']=="edited"){
246 $this->disks[$disk]['partitions'][$name]['status']="delete";
247 }else{
248 unset($this->disks[$disk]['partitions'][$name]);
249 }
250 }
251 }else{
252 unset($this->disks[$disk]);
253 }
254 }
255 }
256 }
257 }
259 /* Display dialog if one is defined
260 */
261 if(is_object($this->dialog)){
262 $this->dialog->save_object();
263 return($this->dialog->execute());
264 }
266 /* Assign all attributes to smarty engine
267 */
268 foreach($this->attributes as $attrs){
269 $smarty->assign($attrs,$this->$attrs);
270 if($this->$attrs){
271 $smarty->assign($attrs."CHK"," ");
272 }else{
273 $smarty->assign($attrs."CHK"," disabled ");
274 }
275 }
277 $dn = $this->acl_base_for_current_object($this->dn);
278 $smarty->assign("sub_object_is_addable",
279 preg_match("/c/",$this->ui->get_permissions($dn,"fai/faiPartitionTableEntry")) &&
280 !preg_match("/freeze/",$this->FAIstate));
281 $smarty->assign("sub_object_is_removeable",
282 preg_match("/d/",$this->ui->get_permissions($dn,"fai/faiPartitionTableEntry")) &&
283 !preg_match("/freeze/",$this->FAIstate));
285 $tmp = $this->plInfo();
286 foreach($tmp['plProvidedAcls'] as $name => $translated){
287 $smarty->assign($name."ACL",$this->getacl($name,preg_match("/freeze/i",$this->FAIstate)));
288 }
289 $disks = $this->getDisks();
290 $smarty->assign("disks" ,$disks);
291 $display.= $smarty->fetch(get_template_path('faiPartitionTable.tpl', TRUE));
292 return($display);
293 }
295 function getDisks(){
296 /* Return all available disks for this partition table
297 * Return in listBox friendly array
298 */
299 $a_return = array();
300 foreach($this->disks as $key => $disk){
302 $dn = "new";
303 if(isset($obj['dn'])){
304 $dn = $obj['dn'];
305 }
306 $dn = $this->acl_base_for_current_object($dn);
307 $acl = $this->ui->get_permissions($dn,"fai/faiPartitionTableEntry");
308 if(preg_match("/(r|w)/",$acl)) {
310 if($disk['status'] != "delete"){
311 $cnt=0;
312 foreach($disk['partitions'] as $val){
313 if($val['status']!="delete"){
314 $cnt ++;
315 }
316 }
317 if(!empty($disk['description'])){
318 if($cnt == 1){
319 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition"), $cnt);
320 }else{
321 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition(s)"), $cnt);
322 }
323 }else{
324 if($cnt == 1){
325 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition"), $cnt);
326 }else{
327 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition(s)"), $cnt);
328 }
329 }
330 }
331 }
332 }
333 return($a_return);
334 }
337 /* Delete me, and all my subtrees
338 */
339 function remove_from_parent()
340 {
341 $ldap = $this->config->get_ldap_link();
342 $ldap->cd ($this->dn);
344 $release = $this->parent->parent->fai_release;
345 $use_dn = preg_replace("/".normalizePreg(FAI::get_release_dn($this->dn))."/i", $release, $this->dn);
347 FAI::prepare_to_save_FAI_object($use_dn,array(),true);
348 new log("remove","fai/".get_class($this),$use_dn,$this->attributes);
349 foreach($this->disks as $disk){
350 $disk_dn = "cn=".$disk['cn'].",".$this->dn;
351 $use_dn = preg_replace("/".normalizePreg(FAI::get_release_dn($this->dn))."/i",$release, $disk_dn);
352 FAI::prepare_to_save_FAI_object($use_dn,array(),true);
353 foreach($disk['partitions'] as $key => $partition){
354 $partition_dn= "FAIpartitionNr=".$partition['FAIpartitionNr'].",".$disk_dn;
355 $use_dn = preg_replace("/".normalizePreg(FAI::get_release_dn($this->dn))."/i", $release, $partition_dn);
356 FAI::prepare_to_save_FAI_object($use_dn,array(),true);
357 }
358 }
359 }
362 /* Save data to object
363 */
364 function save_object()
365 {
366 if (preg_match("/freeze/", $this->FAIstate)) return;
367 plugin::save_object();
368 foreach($this->attributes as $attrs){
369 if(isset($_POST[$attrs])){
370 $this->$attrs = $_POST[$attrs];
371 }
372 }
373 }
376 /* Check supplied data */
377 function check()
378 {
379 /* Call common method to give check the hook */
380 $message= plugin::check();
382 /* Ensure that we do not overwrite an allready existing entry
383 */
384 if($this->is_new){
385 $release = $this->parent->parent->fai_release;
386 $new_dn= 'cn='.$this->cn.",".get_ou('faipartitionou').get_ou('faiou').$release;
387 $res = faiManagement::check_class_name("FAIpartitionTable",$this->cn,$new_dn);
388 if(isset($res[$this->cn])){
389 $message[] = msgPool::duplicated(_("Name"));
390 }
391 }
392 return ($message);
393 }
396 /* Save to LDAP */
397 function save()
398 {
400 plugin::save();
401 /* Save current settings.
402 * 1 : We must save the partition table, with its description and cn
403 * 2 : Append Disk with cn and description.
404 * 3 : Save partitions for each disk
405 */
407 $ldap = $this->config->get_ldap_link();
409 FAI::prepare_to_save_FAI_object($this->dn,$this->attrs);
411 if($this->initially_was_account){
412 new log("modify","fai/".get_class($this),$this->dn,$this->attributes);
413 }else{
414 new log("create","fai/".get_class($this),$this->dn,$this->attributes);
415 }
417 /* Sort entries, because we must delete entries with status="delete" first */
418 $order = array();
419 foreach($this->disks as $key => $disk){
420 if($disk['status'] == "delete"){
421 $order[$key] = $disk;
422 }
423 }
424 foreach($this->disks as $key => $disk){
425 if($disk['status'] != "delete"){
426 $order[$key] = $disk;
427 }
428 }
430 /* Append all disks to ldap */
431 foreach($order as $cn=>$disk){
432 $disk_dn = "cn=".$disk['cn'].",".$this->dn;
433 $disk_attrs['cn'] = $disk['cn'];
434 $disk_attrs['description'] = $disk['description'];
435 $disk_attrs['objectClass'] = array("top","FAIclass","FAIpartitionDisk");
437 if($disk['status']=="new"){
438 $ldap->cat($disk_dn,array("objectClass"));
439 if($ldap->count()){
440 $disk['status']="edited";
441 }
442 }
444 /* Tag object */
445 $this->tag_attrs($disk_attrs, $disk_dn, $this->gosaUnitTag);
447 if($disk['status'] == "delete"){
448 FAI::prepare_to_save_FAI_object($disk_dn,array(),true);
449 $this->handle_post_events("remove");
450 }elseif($disk['status'] == "edited"){
451 FAI::prepare_to_save_FAI_object($disk_dn,$disk_attrs);
452 $this->handle_post_events("modify");
453 }elseif($disk['status']=="new"){
454 FAI::prepare_to_save_FAI_object($disk_dn,$disk_attrs);
455 $this->handle_post_events("add");
456 }
458 if($disk['status']!="delete")
459 /* Add all partitions */
460 foreach($disk['partitions'] as $key => $partition){
461 $partition_attrs = array();
463 foreach($partition as $key => $value){
464 if(!empty($value)){
465 $partition_attrs[$key]=$value;
466 }else{
467 unset($partition_attrs[$key]);
468 }
469 }
471 $partition_dn= "FAIpartitionNr=".$partition_attrs['FAIpartitionNr'].",".$disk_dn;
472 $partition_attrs['objectClass']= array("top","FAIclass","FAIpartitionEntry");
473 $partition_attrs['cn']= $partition_attrs['FAIpartitionNr'];
475 unset($partition_attrs['status']);
476 unset($partition_attrs['old_cn']);
478 if($partition['status']=="new"){
479 $ldap->cat($partition_dn,array("objectClass"));
480 if($ldap->count()){
481 $partition['status']="edited";
482 }
483 }
485 if((!isset($partition['FAImountPoint']))||(empty($partition['FAImountPoint']))){
486 $partition_attrs['FAImountPoint']="swap";
487 }
489 /* Tag object */
490 $this->tag_attrs($partition_attrs, $partition_dn, $this->gosaUnitTag);
492 if($partition['status'] == "delete"){
493 FAI::prepare_to_save_FAI_object($partition_dn,array(),true);
494 $this->handle_post_events("remove");
495 }elseif($partition['status'] == "edited"){
496 FAI::prepare_to_save_FAI_object($partition_dn,$partition_attrs);
497 $this->handle_post_events("modify");
498 }elseif($partition['status']=="new"){
499 FAI::prepare_to_save_FAI_object($partition_dn,$partition_attrs);
500 $this->handle_post_events("add");
501 }
502 }
503 }
504 $this->handle_post_events("add");
505 }
508 function PrepareForCopyPaste($source)
509 {
510 plugin::PrepareForCopyPaste($source);
511 /* Get FAIstate
512 */
513 if(isset($source['FAIstate'][0])){
514 $this->FAIstate = $source['FAIstate'][0];
515 }
517 /* Read all disks from ldap taht are defined fot this partition table
518 */
519 $ldap = $this->config->get_ldap_link();
520 $ldap->cd ($source['dn']);
521 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionDisk))",array("*"));
522 while($object = $ldap->fetch()){
524 /* Skip objects, that are tagged as removed */
525 if(isset($object['FAIstate'][0])){
526 if(preg_match("/removed$/",$object['FAIstate'][0])){
527 continue;
528 }
529 }
531 $this->disks[$object['cn'][0]]['status'] = "edited";
532 $this->disks[$object['cn'][0]]['dn'] = $object['dn'];
533 $this->disks[$object['cn'][0]]['cn'] = $object['cn'][0];
534 if(isset($object['description'][0])){
535 $this->disks[$object['cn'][0]]['description'] = $object['description'][0];
536 }else{
537 $this->disks[$object['cn'][0]]['description'] = "";
538 }
539 $this->disks[$object['cn'][0]]['partitions'] = array();
540 }
542 /* read all partitions for each disk
543 */
544 foreach($this->disks as $name => $disk){
545 $ldap->cd ($disk['dn']);
546 $ldap->search("(&(objectClass=FAIclass)(objectClass=FAIpartitionEntry))",array("*"));
547 while($partition = $ldap->fetch()){
549 /* Skip objects, that are tagged as removed */
550 if(isset($partition['FAIstate'][0])){
551 if(preg_match("/removed$/",$partition['FAIstate'][0])){
552 continue;
553 }
554 }
556 /* remove count ... from ldap result
557 */
558 foreach($partition as $key=>$val){
559 if((is_numeric($key))||($key=="count")||($key=="dn")){
560 unset($partition[$key]);
561 }else{
562 $partition[$key] = $val[0];
563 }
564 }
566 /* Append fetched partitions
567 */
568 $partition['status']="edited";
569 $this->disks[$name]['partitions'][$partition['FAIpartitionNr']] = $partition;
570 }
571 }
572 ksort($this->disks);
573 }
576 /* Return plugin informations for acl handling */
577 static function plInfo()
578 {
579 return (array(
580 "plShortName" => _("Partition table"),
581 "plDescription" => _("FAI partition table"),
582 "plSelfModify" => FALSE,
583 "plDepends" => array(),
584 "plPriority" => 26,
585 "plSection" => array("administration"),
586 "plCategory" => array("fai"),
587 "plProvidedAcls" => array(
588 "cn" => _("Name")." ("._("Read only").")",
589 "description" => _("Description"))
590 ));
591 }
594 /*! \brief Used for copy & paste.
595 Returns a HTML input mask, which allows to change the cn of this entry.
596 @param Array Array containing current status && a HTML template.
597 */
598 function getCopyDialog()
599 {
600 $vars = array("cn");
601 $smarty = get_smarty();
602 $smarty->assign("cn", htmlentities($this->cn));
603 $str = $smarty->fetch(get_template_path("paste_generic.tpl",TRUE));
604 $ret = array();
605 $ret['string'] = $str;
606 $ret['status'] = "";
607 return($ret);
608 }
611 /*! \brief Used for copy & paste.
612 Some entries must be renamed to avaoid duplicate entries.
613 */
614 function saveCopyDialog()
615 {
616 if(isset($_POST['cn'])){
617 $this->cn = get_post('cn');
618 }
619 }
620 }
622 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
623 ?>