Code

list base image migration for gosa-plugins
[gosa.git] / gosa-plugins / dns / admin / systems / services / dns / class_servDNSeditZoneEntries.inc
1 <?php
3 class servDNSeditZoneEntries extends plugin
4 {
5   /* attribute list for save action */
6   var $ignore_account     = TRUE;
7   var $attributes         = array();
8   var $objectclasses      = array("whatever");
10   var $Devices            = array();
12   var $zoneName           = "";   // ZoneName of currently edited Zone
13   var $reverseName        = "";   // ReverseZone of the currently edited Zone
15   var $RecordTypes        = array();  // Possible record type.
17   var $disableDialog      = false; // Dialog will be disabled, if this zone is new 
20   function servDNSeditZoneEntries (&$config,$dn, &$zoneObject)
21   {
22     plugin::plugin ($config, $dn);
24     /* Initialise class
25      */
26     $this->RecordTypes  = DNS::getDnsRecordTypes();
27     $this->dn           = "zoneName=".$zoneObject['InitialzoneName'].",".$dn; 
28     $this->zoneName     = $zoneObject['InitialzoneName'];
29     $this->reverseName  = $zoneObject['InitialReverseZone'];
31     /* Remove nSRecord from listed types */
32     if(isset($this->RecordTypes['nSRecord'])){
33       unset($this->RecordTypes['nSRecord']);
34     }
35     /* Remove nSRecord from listed types */
36     if(isset($this->RecordTypes['pTRRecord'])){
37       unset($this->RecordTypes['pTRRecord']);
38     }
40     /* Get ldap connection 
41      */
42     $ldap = $this->config->get_ldap_link();
43     $ldap->cd($this->config->current['BASE']);
45     /* Get zone content
46      */
47     $ldap->ls("(&(objectClass=dNSZone)(!(relativeDomainName=@)))",$this->dn,array("relativeDomainName"));
48     
49     while($attrs = $ldap->fetch()){
50       $this->Devices[$attrs['relativeDomainName'][0]] = DNS::getDNSHostEntries($config,$attrs['relativeDomainName'][0],true);
51       $this->Devices[$attrs['relativeDomainName'][0]]['OrigCn'] = $attrs['relativeDomainName'][0];
52     }
54     $ldap->cat($this->dn,array("objectClass"));
56     $this->disableDialog = true;
57     if(count($this->Devices)|| $ldap->count()){
58       $this->disableDialog = false;
59     }
60   }
62   function execute()
63   {
64     plugin::execute();
66     /* Fill templating stuff */
67     $smarty= get_smarty();
68     $display= "";
70     $table = "";
71     foreach($this->Devices as $key => $dev){
72       $table .= $this->generateRecordConfigurationRow($key);
73     }
75     $smarty->assign("disableDialog",$this->disableDialog);
76     $smarty->assign("table",$table);;
77     $display.= $smarty->fetch(get_template_path('servDNSeditZoneEntries.tpl', TRUE, dirname(__FILE__)));
78     return($display);
79   }
82   function save_object()
83   {
84     /* Check posts for operations ...  
85      */
86     $once = true;
87     $ptr_updates = array();
88     foreach($_POST as $name => $value){
90       /* Add a new Record in given object  
91        */
92       
93       $tmp    = preg_replace("/^.*_(.*)_.*$/","\\1",$name);
94       $tmp2   = split("\|",$tmp);
96       /* Add new host entry
97        */
98       if((preg_match("/^UserRecord_?/",$name)) && ($once)){
99         $once = false;
100         $entry = DNS::getDNSHostEntries($this->config,"",true);     
101         $entry['exists']    = true;
102         $entry['zoneName']  = strtoupper($this->attrs['cn'][0])."/".$this->zoneName; 
103         $entry['RECORDS'][] = array("type" => "aRecord" , "value"=>"");
104         $this->Devices[_("New entry")] = $entry;
105       }
107       if(count($tmp2) != 2) continue;
109       $Name     = base64_decode($tmp2[0]);
110       $RecordID = $tmp2[1];
112       /* Add new REcord
113        */
114       if((preg_match("/^AddRecord_/",$name)) && ($once)){
115         $once = false;
116         $this->Devices[$Name]['RECORDS'][] = $this->Devices[$Name]['RECORDS'][$RecordID];
117       }
119       /* Remove record from given dn
120        */
121       if((preg_match("/^RemoveRecord_/",$name)) && ($once)){
122         $once   = false;
123         if(isset($this->Devices[$Name]['RECORDS'][$RecordID])){
124           unset($this->Devices[$Name]['RECORDS'][$RecordID]);
125         }
127         /* Check if there is at least one visible record. Else remove complete entry */
128         $visible = false;
129         foreach($this->Devices[$Name]['RECORDS'] as $rec){
130           if(in_array($rec['type'],$this->RecordTypes)){
131             $visible = true;  
132             break;
133           }
134         }
135         if(!$visible && isset($this->Devices[$Name]['RECORDS'])){
136           $this->Devices[$Name]['RECORDS'] = array();
137         }
138       }
139     }
141     /* Possible attributes posted 
142      */
143     foreach($_POST as $name => $value){
145       /* Extract informations out of post name 
146        */
147       $tmp    = preg_replace("/^.*_/","\\1",$name);
148       $tmp2   = split("\|",$tmp);      
149  
150       if(count($tmp2) != 2) continue;
152       $Name     = base64_decode($tmp2[0]);
153       $RecordID = $tmp2[1];
155       /* Check for value change 
156        */          
157       if(preg_match("/ValueSelection_/",$name)){
158         if(isset($this->Devices[$Name]['RECORDS'][$RecordID])){
159          
160           /* Update value */ 
161           $old = $this->Devices[$Name]['RECORDS'][$RecordID]['value'];
162           $this->Devices[$Name]['RECORDS'][$RecordID]['value'] = $value;
164           /* Handle pTRRecord */
165           if(!isset($ptr_updates[$Name]) && $this->Devices[$Name]['RECORDS'][$RecordID]['type'] == "aRecord"){
166     
167             $found = false;
168             $ip = $value;
169             $match = preg_replace("/^[^\/]*+\//","",$this->reverseName);
170             $ip = preg_replace("/^".normalizePreg($match)."/","",$ip);
171             $ip = preg_replace("/^\./","",$ip);
173             foreach($this->Devices[$Name]['RECORDS'] as $key => $dev){
174               if($dev['type'] == "pTRRecord"){
175                 $ptr_updates[$Name] = $Name;
176                 $this->Devices[$Name]['RECORDS'][$key]['value'] = $ip;
177                 $found = true;
178                 break;
179               }
180             }
181             if(!$found){
182               $dev = array('type'=> 'pTRRecord', 'value' => $ip);
183               $this->Devices[$Name]['RECORDS'][] = $dev;
184             }
185           }
186         }
187       }
189       /* record type changed
190        */        
191       if(preg_match("/^RecordTypeSelection_/",$name)){
192         if(isset($this->Devices[$Name]['RECORDS'][$RecordID])){
193           $this->Devices[$Name]['RECORDS'][$RecordID]['type'] = $value;
194         }  
195       }   
196     }
197     
198     /* check for renamed entries 
199      */ 
200     foreach($_POST as $name => $value){
202       /* Extract informations out of post name 
203        */
204       $tmp    = preg_replace("/^.*_/","\\1",$name);
205       $tmp2   = split("\|",$tmp);      
206  
207       if(count($tmp2) != 2) continue;
209       $Name     = base64_decode($tmp2[0]);
210       $RecordID = $tmp2[1];
212       /* Host renamed
213        */
214       if(preg_match("/RenameHost_/",$name)){
215         if((isset($this->Devices[$Name])) && ($Name != $value)){
216     
217           if(isset($this->Devices[$value])){
218             msg_dialog::display(_("Error"), sprintf(_("Cannot rename '%s' to '%s'. Name is already in use!"), $Name, $value), ERROR_DIALOG);
219           }else{
220             $this->Devices[$value] = $this->Devices[$Name];
221             unset($this->Devices[$Name]);
222           }
223         }
224       }
225     }
226   }
229   /*  check something 
230    */
231   function check()
232   {
233     /* Call common method to give check the hook */
234     $message= plugin::check();
235     
236     $ldap = $this->config->get_ldap_link();
237     $ldap->cd($this->config->current['BASE']);
239     $names = array();
240     foreach($this->Devices as $DevName => $device){
242       /* Don't need to check empty values ... */
243       if(!count($device['RECORDS'])) continue;
245       /* Checking entry name
246        */
247       if(!preg_match("/^[a-z0-9_\.-]+$/i", $DevName) || (empty($DevName))){
248         $message[] = msgPool::invalid(_("Name"),$DevName,"/[a-z0-9_\.-]/i");
249       }      
251       /* Renaming check for existing devices 
252        */
253       if(isset($device['OrigCn'])  && ($DevName != $device['OrigCn'] )){
254         $ldap->cd($this->config->current['BASE']);
255         $ldap->search("(relativeDomainName=".$DevName.")",array("relativeDomainName"));
256         if($ldap->count()){
257           $message[] = sprintf(_("Cannot rename '%s' to '%s'. Entry is already in use."),$device['OrigCn'],$DevName);
258         }
259       }elseif(!isset($device['OrigCn'])){
260         $ldap->cd($this->config->current['BASE']);
261         $ldap->search("(relativeDomainName=".$DevName.")",array("relativeDomainName"));
262         if($ldap->count()){
263           $message[] = sprintf(_("Cannot create '%s'. Entry is already in use."),$DevName);
264         }
265       }
267       /* Check names 
268        */
269       if(!isset($names[$DevName])){
270         $names[$DevName] = "";
271       }else{
272         $message[] = sprintf(_("Entry '%s' is used more than once."),$DevName);
273       }
275       /* Names should be written in lowercase
276        */
277 #      if(strtolower($DevName) != $DevName){
278 #        $message[] = sprintf(_("The host name '%s' should be written in lowercase."), $DevName);
279 #      }
281       /* Check records
282        */                 
283       $singleEntries = array("cNAMERecord","pTRRecord");
285       $tmp  = array();
286       $tmp2 = array();
287       foreach($device['RECORDS'] as $Num => $Rec){
289         /* Check for multiple use of unique record types
290          */
291         if(in_array($Rec['type'],$singleEntries)){
292           if(!isset($tmp[$Rec['type']])){
293             $tmp[$Rec['type']] = "";
294           }else{
295             $message[] = sprintf(_("%s records cannot be used more than once."),$Rec['type']);
296           }
297         }
299         /* Check for empty / duplicate entries in record array 
300          */
301         if(empty($Rec['value'])){
302           $message[] = sprintf(_("Please fix the empty %s record for entry '%s'."),$Rec['type'],$DevName);
303         }
305         /* Check for duplicate record entries 
306          */
307         if(!isset($tmp[$Rec['type']][$Rec['value']])){
308           $tmp[$Rec['type']][$Rec['value']] = "";
309         }else{
310           $message[] = sprintf(_("Please fix the duplicate %s record for entry '%s'."),$Rec['type'],$DevName); 
311         }
312       }
313     }
314     return ($message);
315   }
318   function save()
319   {
320     if($this->disableDialog) return;
322     $todo = array(); 
326     /* Create todolist
327      */
328     foreach($this->Devices as $name => $dev){
329       if(isset($dev['OrigCn'])){
330         if(count($dev['RECORDS'])){
331           $todo[] = DNS::getDNSHostEntriesDiff($this->config,$dev['OrigCn'],$dev,$name);
332         }else{
333           $dev['exists'] = false;
334           $todo[] = DNS::getDNSHostEntriesDiff($this->config,$dev['OrigCn'],$dev,$name);
335         }
336       }else{
337         if(count($dev['RECORDS'])){
338           $todo[] = DNS::getDNSHostEntriesDiff($this->config,"",$dev,$name);
339         }else{
340           $dev['exists'] = false;
341           $todo[] = DNS::getDNSHostEntriesDiff($this->config,"",$dev,$name);
342         }
343       }
344     }
346     $tmp = array();
347     $tmp['del']   = array();
348     $tmp['add']   = array();
349     $tmp['move']  = array();
350     foreach($todo as $to){
351       foreach($to as $type => $entries){
352         $tmp[$type] = array_merge($tmp[$type],$entries);
353       }
354     }
356     /* Get ldap link
357      */
358     $ldap = $this->config->get_ldap_link();
359     $ldap->cd ($this->config->current['BASE']);
361     /* move follwoing entries
362      */
363     foreach($tmp['move'] as $src => $dst){
364       $this->recursive_move($src,$dst);
365     }
367     /* Delete dns */
368     foreach($tmp['del'] as $dn => $del){
369       $ldap->cd($dn);
370       $ldap->rmdir_recursive($dn);
371       if(is_object($this->parent->parent)){
372         $this->parent->parent->handle_post_events("remove",array("dn" => $dn));
373       }
374     }
376     /* Add || Update new DNS entries
377      */
378     foreach($tmp['add'] as $dn => $attrs){
379       $ldap->cd($dn);
380       $ldap->cat($dn, array('dn'));
381       if(count($ldap->fetch())){
382         $ldap->cd($dn);
383         $ldap->modify ($attrs);
384         if(is_object($this->parent->parent)){
385           $this->parent->parent->handle_post_events("modify",array("dn" => $dn));
386         }
387       }else{
388         $ldap->cd($dn);
389         $ldap->add($attrs);
390         if(is_object($this->parent->parent)){
391           $this->parent->parent->handle_post_events("create",array("dn" => $dn));
392         }
393       }
394     }
395   }
398   /* Create html table out of given entry 
399    */
400   function generateRecordConfigurationRow($objKey){
402     /* Get some basic informations 
403      */
404     $obj        = $this->Devices[$objKey];
405     $objectName = $objKey;
407     /* Abort if emtpy
408      */
409     if(count($obj['RECORDS']) == 0) return "";
411     /* Set title 
412      */
413     $str= "<br>";
415     $hostNameOnce = true;
417     /* Walk through all defined records 
418      */
419     $str.= "<table cellspacing='0' cellpadding='0'>";
420     foreach($obj['RECORDS'] as $id => $record){
422       /* Skip not selectable entries */
423       if(!isset($this->RecordTypes [$record['type']])) {
424         continue;
425       }
427       /* Create unique post name
428        */
429       $name = base64_encode($objKey)."|".$id;
431       $str .= "<tr><td style='width:170px;'>\n";
433       /* Only first host entry name should be editable
434        */
435       if($hostNameOnce){
436         $hostNameOnce = false;  
437         $str .="<input type='text' name='RenameHost_".$name."' value='".$objectName."'>\n";
438       }
440       /* Create rest. Selectbox, icons ...
441        */
442       $str .="
443         </td>
444         <td style='width:90px;'>
445           ".$this->createRecordTypeSelection($record['type'],$name)."
446         </td>
447         <td>
448           <input type='text'  value='".$record['value']."' name='ValueSelection_".$name."' style='width:250px;'>
449         </td>
450         <td style='width:75px;text-align:right;'>
451           <input type='image' name='AddRecord_".$name."'   src='images/list_new.png' alt='"._("Add")."' title='"._("Add")."'>
452           <input type='image' name='RemoveRecord_".$name."' src='images/lists/trash.png'      alt='"._("Remove")."' title='"._("Remove")."'>
453         ";
455       $str.=
456         "</td>
457       </tr>";
458     }
459     $str .="</table>";
460     return($str); 
461   }
464   /* Create selectbox with all available option types 
465    */
466   function createRecordTypeSelection($id,$refID){
468     $str = "\n<select name='RecordTypeSelection_".$refID."'>";
469     foreach($this->RecordTypes as $type => $atr) {
470       if($id == $type){
471         $str .="\n<option value='".$type."' selected >".strtoupper(preg_replace("/record/i","",$type))."</option>";
472       }else{
473         $str .="\n<option value='".$type."'>".strtoupper(preg_replace("/record/i","",$type))."</option>";
474       }
475     }
476     $str.= "\n</select>";
477     return($str);
478   }
481   function remove_from_parent()
482   {
483   }
487 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
488 ?>