78b9be741e3819c429ec63295341b81302612168
[gosa.git] / branches / old / 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.
16 var $acl = "";
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"));
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("acl",$this->acl);
76 $smarty->assign("disableDialog",$this->disableDialog);
77 $smarty->assign("table",$table);;
78 $display.= $smarty->fetch(get_template_path('servDNSeditZoneEntries.tpl', TRUE, dirname(__FILE__)));
79 return($display);
80 }
83 function save_object()
84 {
85 /* Check posts for operations ...
86 */
87 $once = true;
88 $ptr_updates = array();
89 if(!preg_match("/w/",$this->acl)) return;
91 foreach($_POST as $name => $value){
93 /* Add a new Record in given object
94 */
96 $tmp = preg_replace("/^.*_(.*)_.*$/","\\1",$name);
97 $tmp2 = split("\|",$tmp);
99 /* Add new host entry
100 */
101 if((preg_match("/^UserRecord_?/",$name)) && ($once)){
102 $once = false;
103 $entry = DNS::getDNSHostEntries($this->config,"",true);
104 $entry['exists'] = true;
105 $entry['zoneName'] = strtoupper($this->attrs['cn'][0])."/".$this->zoneName;
106 $entry['RECORDS'][] = array("type" => "aRecord" , "value"=>"");
107 $this->Devices[_("New entry")] = $entry;
108 }
110 if(count($tmp2) != 2) continue;
112 $Name = base64_decode($tmp2[0]);
113 $RecordID = $tmp2[1];
115 /* Add new REcord
116 */
117 if((preg_match("/^AddRecord_/",$name)) && ($once)){
118 $once = false;
119 $this->Devices[$Name]['RECORDS'][] = $this->Devices[$Name]['RECORDS'][$RecordID];
120 }
122 /* Remove record from given dn
123 */
124 if((preg_match("/^RemoveRecord_/",$name)) && ($once)){
125 $once = false;
126 if(isset($this->Devices[$Name]['RECORDS'][$RecordID])){
127 unset($this->Devices[$Name]['RECORDS'][$RecordID]);
128 }
130 /* Check if there is at least one visible record. Else remove complete entry */
131 $visible = false;
132 foreach($this->Devices[$Name]['RECORDS'] as $rec){
133 if(in_array($rec['type'],$this->RecordTypes)){
134 $visible = true;
135 break;
136 }
137 }
138 if(!$visible && isset($this->Devices[$Name]['RECORDS'])){
139 $this->Devices[$Name]['RECORDS'] = array();
140 }
141 }
142 }
144 /* Possible attributes posted
145 */
146 foreach($_POST as $name => $value){
148 /* Extract informations out of post name
149 */
150 $tmp = preg_replace("/^.*_/","\\1",$name);
151 $tmp2 = split("\|",$tmp);
153 if(count($tmp2) != 2) continue;
155 $Name = base64_decode($tmp2[0]);
156 $RecordID = $tmp2[1];
158 /* Check for value change
159 */
160 if(preg_match("/ValueSelection_/",$name)){
161 if(isset($this->Devices[$Name]['RECORDS'][$RecordID])){
163 /* Update value */
164 $old = $this->Devices[$Name]['RECORDS'][$RecordID]['value'];
165 $this->Devices[$Name]['RECORDS'][$RecordID]['value'] = $value;
167 /* Handle pTRRecord */
168 if(!isset($ptr_updates[$Name]) && $this->Devices[$Name]['RECORDS'][$RecordID]['type'] == "aRecord"){
170 $found = false;
171 $ip = $value;
172 $match = preg_replace("/^[^\/]*+\//","",$this->reverseName);
173 $ip = preg_replace("/^".normalizePreg($match)."/","",$ip);
174 $ip = preg_replace("/^\./","",$ip);
176 foreach($this->Devices[$Name]['RECORDS'] as $key => $dev){
177 if($dev['type'] == "pTRRecord"){
178 $ptr_updates[$Name] = $Name;
179 $this->Devices[$Name]['RECORDS'][$key]['value'] = $ip;
180 $found = true;
181 break;
182 }
183 }
184 if(!$found){
185 $dev = array('type'=> 'pTRRecord', 'value' => $ip);
186 $this->Devices[$Name]['RECORDS'][] = $dev;
187 }
188 }
189 }
190 }
192 /* record type changed
193 */
194 if(preg_match("/^RecordTypeSelection_/",$name)){
195 if(isset($this->Devices[$Name]['RECORDS'][$RecordID])){
196 $this->Devices[$Name]['RECORDS'][$RecordID]['type'] = $value;
197 }
198 }
199 }
201 /* check for renamed entries
202 */
203 foreach($_POST as $name => $value){
205 /* Extract informations out of post name
206 */
207 $tmp = preg_replace("/^.*_/","\\1",$name);
208 $tmp2 = split("\|",$tmp);
210 if(count($tmp2) != 2) continue;
212 $Name = base64_decode($tmp2[0]);
213 $RecordID = $tmp2[1];
215 /* Host renamed
216 */
217 if(preg_match("/RenameHost_/",$name)){
218 if((isset($this->Devices[$Name])) && ($Name != $value)){
220 if(isset($this->Devices[$value])){
221 msg_dialog::display(_("Error"), sprintf(_("Cannot rename '%s' to '%s'. Name is already in use!"), $Name, $value), ERROR_DIALOG);
222 }else{
223 $this->Devices[$value] = $this->Devices[$Name];
224 unset($this->Devices[$Name]);
225 }
226 }
227 }
228 }
229 }
232 /* check something
233 */
234 function check()
235 {
236 /* Call common method to give check the hook */
237 $message= plugin::check();
239 if(!preg_match("/w/",$this->acl)) return($message);
241 $ldap = $this->config->get_ldap_link();
242 $ldap->cd($this->config->current['BASE']);
244 $names = array();
245 foreach($this->Devices as $DevName => $device){
247 /* Don't need to check empty values ... */
248 if(!count($device['RECORDS'])) continue;
250 /* Checking entry name
251 */
252 if(!preg_match("/^[a-z0-9_\.-]+$/i", $DevName) || (empty($DevName))){
253 $message[] = msgPool::invalid(_("Name"),$DevName,"/[a-z0-9_\.-]/i");
254 }
256 /* Renaming check for existing devices
257 */
258 if(isset($device['OrigCn']) && ($DevName != $device['OrigCn'] )){
259 $ldap->cd($this->config->current['BASE']);
260 $ldap->search("(relativeDomainName=".$DevName.")",array("relativeDomainName"));
261 if($ldap->count()){
262 $message[] = sprintf(_("Cannot rename '%s' to '%s'. Entry is already in use."),$device['OrigCn'],$DevName);
263 }
264 }elseif(!isset($device['OrigCn'])){
265 $ldap->cd($this->config->current['BASE']);
266 $ldap->search("(relativeDomainName=".$DevName.")",array("relativeDomainName"));
267 if($ldap->count()){
268 $message[] = sprintf(_("Cannot create '%s'. Entry is already in use."),$DevName);
269 }
270 }
272 /* Check names
273 */
274 if(!isset($names[$DevName])){
275 $names[$DevName] = "";
276 }else{
277 $message[] = sprintf(_("Entry '%s' is used more than once."),$DevName);
278 }
280 /* Names should be written in lowercase
281 */
282 # if(strtolower($DevName) != $DevName){
283 # $message[] = sprintf(_("The host name '%s' should be written in lowercase."), $DevName);
284 # }
286 /* Check records
287 */
288 $singleEntries = array("pTRRecord");
290 $tmp = array();
291 $tmp2 = array();
292 foreach($device['RECORDS'] as $Num => $Rec){
294 /* Check for multiple use of unique record types
295 */
296 if(in_array($Rec['type'],$singleEntries)){
297 if(!isset($tmp[$Rec['type']])){
298 $tmp[$Rec['type']] = "";
299 }else{
300 $message[] = sprintf(_("%s records cannot be used more than once."),$Rec['type']);
301 }
302 }
304 /* Check for empty / duplicate entries in record array
305 */
306 if(empty($Rec['value'])){
307 $message[] = sprintf(_("Please fix the empty %s record for entry '%s'."),$Rec['type'],$DevName);
308 }
310 /* Check for duplicate record entries
311 */
312 if(!isset($tmp[$Rec['type']][$Rec['value']])){
313 $tmp[$Rec['type']][$Rec['value']] = "";
314 }else{
315 $message[] = sprintf(_("Please fix the duplicate %s record for entry '%s'."),$Rec['type'],$DevName);
316 }
317 }
318 }
319 return ($message);
320 }
323 function save()
324 {
325 if($this->disableDialog || !preg_match("/w/",$this->acl)) return;
327 $todo = array();
331 /* Create todolist
332 */
333 foreach($this->Devices as $name => $dev){
334 if(isset($dev['OrigCn'])){
335 if(count($dev['RECORDS'])){
336 $todo[] = DNS::getDNSHostEntriesDiff($this->config,$dev['OrigCn'],$dev,$name);
337 }else{
338 $dev['exists'] = false;
339 $todo[] = DNS::getDNSHostEntriesDiff($this->config,$dev['OrigCn'],$dev,$name);
340 }
341 }else{
342 if(count($dev['RECORDS'])){
343 $todo[] = DNS::getDNSHostEntriesDiff($this->config,"",$dev,$name);
344 }else{
345 $dev['exists'] = false;
346 $todo[] = DNS::getDNSHostEntriesDiff($this->config,"",$dev,$name);
347 }
348 }
349 }
351 $tmp = array();
352 $tmp['del'] = array();
353 $tmp['add'] = array();
354 $tmp['move'] = array();
355 foreach($todo as $to){
356 foreach($to as $type => $entries){
357 $tmp[$type] = array_merge($tmp[$type],$entries);
358 }
359 }
361 /* Get ldap link
362 */
363 $ldap = $this->config->get_ldap_link();
364 $ldap->cd ($this->config->current['BASE']);
366 /* move follwoing entries
367 */
368 foreach($tmp['move'] as $src => $dst){
369 $this->recursive_move($src,$dst);
370 }
372 /* Delete dns */
373 foreach($tmp['del'] as $dn => $del){
374 $ldap->cd($dn);
375 $ldap->rmdir_recursive($dn);
376 if(is_object($this->parent->parent)){
377 $this->parent->parent->handle_post_events("remove",array("dn" => $dn));
378 }
379 }
381 /* Add || Update new DNS entries
382 */
383 foreach($tmp['add'] as $dn => $attrs){
384 $ldap->cd($dn);
385 $ldap->cat($dn, array('dn'));
386 if(count($ldap->fetch())){
387 $ldap->cd($dn);
388 $ldap->modify ($attrs);
389 if(is_object($this->parent->parent)){
390 $this->parent->parent->handle_post_events("modify",array("dn" => $dn));
391 }
392 }else{
393 $ldap->cd($dn);
394 $ldap->add($attrs);
395 if(is_object($this->parent->parent)){
396 $this->parent->parent->handle_post_events("create",array("dn" => $dn));
397 }
398 }
399 }
400 }
403 /* Create html table out of given entry
404 */
405 function generateRecordConfigurationRow($objKey){
407 /* Get some basic informations
408 */
409 $obj = $this->Devices[$objKey];
410 $objectName = $objKey;
412 $dis = "";
413 if(!preg_match("/w/",$this->acl)){
414 $dis = " disabled ";
415 }
417 /* Abort if emtpy
418 */
419 if(count($obj['RECORDS']) == 0) return "";
421 /* Set title
422 */
423 $str= "<br>";
425 $hostNameOnce = true;
427 /* Walk through all defined records
428 */
429 $str.= "<table cellspacing='0' cellpadding='0'>";
430 foreach($obj['RECORDS'] as $id => $record){
432 /* Skip not selectable entries */
433 if(!isset($this->RecordTypes [$record['type']])) {
434 continue;
435 }
437 /* Create unique post name
438 */
439 $name = base64_encode($objKey)."|".$id;
441 $str .= "<tr><td style='width:170px;'>\n";
443 /* Only first host entry name should be editable
444 */
445 if($hostNameOnce){
446 $hostNameOnce = false;
447 $str .="<input $dis type='text' name='RenameHost_".$name."' value='".$objectName."'>\n";
448 }
450 /* Create rest. Selectbox, icons ...
451 */
452 $str .="
453 </td>
454 <td style='width:90px;'>
455 ".$this->createRecordTypeSelection($record['type'],$name)."
456 </td>
457 <td>
458 <input type='text' $dis value='".$record['value']."' name='ValueSelection_".$name."' style='width:250px;'>
459 </td>";
461 if(preg_match("/w/",$this->acl)){
462 $str .= "<td style='width:75px;text-align:right;'>
463 <input type='image' name='AddRecord_".$name."'
464 src='images/lists/new.png' alt='"._("Add")."' title='"._("Add")."'>
465 <input type='image' name='RemoveRecord_".$name."'
466 src='images/lists/trash.png' alt='"._("Remove")."' title='"._("Remove")."'>
467 ";
468 }
470 $str.=
471 "</td>
472 </tr>";
473 }
474 $str .="</table>";
475 return($str);
476 }
479 /* Create selectbox with all available option types
480 */
481 function createRecordTypeSelection($id,$refID){
483 if(preg_match("/w/",$this->acl)){
484 $str = "\n<select name='RecordTypeSelection_".$refID."'>";
485 foreach($this->RecordTypes as $type => $atr) {
486 if($id == $type){
487 $str .="\n<option value='".$type."' selected >".strtoupper(preg_replace("/record/i","",$type))."</option>";
488 }else{
489 $str .="\n<option value='".$type."'>".strtoupper(preg_replace("/record/i","",$type))."</option>";
490 }
491 }
492 $str.= "\n</select>";
493 }else{
494 $str = " ".strtoupper(preg_replace("/record/i","",$id));
495 }
496 return($str);
497 }
500 function remove_from_parent()
501 {
502 }
504 }
506 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
507 ?>