1 <?php
3 class phoneAccount extends plugin
4 {
5 /* Definitions */
6 var $plHeadline= "Phone";
7 var $plDescription= "This does something";
8 var $has_mailAccount= FALSE;
10 /* Attributes */
11 var $telephoneNumber = array();
12 var $goFonHardware = "";
13 var $goFonFormat = "";
14 var $goFonPIN = "";
15 var $goFonVoicemailPIN = "";
16 var $goFonDeliveryMode = "";
17 var $phoneNumbers = array();
18 var $mail = "";
19 var $hardware_list = array();
20 var $used_hardware = array();
21 var $goFonMacro = "";
22 var $macro = 0; // Selected Macroi
23 var $lastmacro = "";
24 var $macros = array(); // List of macros for smarty select box
25 var $macroarray = array(); // All needed macro informations
26 var $macrostillavailable = false;
27 var $generate_error = "";
28 var $a_old_telenums = array();
29 var $goFonPINVoice = "";
31 /* CLI vars */
32 var $cli_summary = "Manage users phone account";
33 var $cli_description = "Some longer text\nfor help";
34 var $cli_parameters = array("eins" => "Eins ist toll", "zwei" => "Zwei ist noch besser");
36 /* attribute list for save action */
37 var $CopyPasteVars = array("phoneNumbers");
38 var $attributes = array("goFonDeliveryMode", "goFonFormat","uid","cn",
39 "goFonHardware","goFonPIN","goFonVoicemailPIN","telephoneNumber", "goFonMacro","macro");
40 var $objectclasses= array("goFonAccount");
42 var $uid;
44 function phoneAccount ($config, $dn= NULL)
45 {
46 plugin::plugin ($config, $dn);
48 /* Set phone hardware */
49 if (!isset($this->attrs['goFonHardware'])){
50 $this->goFonHardware= "automatic";
51 }
53 /* Preset voice format */
54 if (!isset($this->attrs['goFonFormat'])){
55 $this->goFonFormat= "wav";
56 }
58 /* Assemble phone numbers */
59 if (isset($this->attrs['telephoneNumber'])){
60 for ($i= 0; $i<$this->attrs['telephoneNumber']['count']; $i++){
61 $number= $this->attrs['telephoneNumber'][$i];
62 $this->phoneNumbers[$number]= $number;
63 }
64 }
66 /* Set up has_mailAccount */
67 if (isset($this->attrs['objectClass'])){
68 if (in_array("gosaMailAccount", $this->attrs['objectClass'])){
69 $this->has_mailAccount= TRUE;
70 }
71 }
73 $a_SETUP= array();
74 if(array_key_exists('config',$_SESSION) &&
75 array_key_exists('SERVERS',$_SESSION['config']->data) &&
76 array_key_exists('FON',$_SESSION['config']->data['SERVERS']) &&
77 is_callable("mysql_connect")
78 ) {
79 $a_SETUP = $_SESSION['config']->data['SERVERS']['FON'];
80 $r_con = @mysql_pconnect($a_SETUP['SERVER'],$a_SETUP['LOGIN'],$a_SETUP['PASSWORD']);
81 if(!$r_con){
82 $this->generate_error = sprintf(_("The MySQL Server '%s' isn't reachable as user '%s', check GOsa log for mysql error."),
83 $a_SETUP['SERVER'],$a_SETUP['LOGIN']);
84 gosa_log(mysql_error());
85 return false;
86 }
87 $db = @mysql_select_db($a_SETUP['DB'],$r_con);
88 if(!$db){
89 $this->generate_error = sprintf(_("Can't select database %s on %s."),$a_SETUP['DB'],$a_SETUP['SERVER']);
90 gosa_log(mysql_error());
91 return false;
92 }
94 $first = false;
95 foreach($this->phoneNumbers as $key => $val){
96 if(!$first){
97 $first = $key;
98 }
99 }
100 }
102 /* Load hardware list */
103 $ldap= $this->config->get_ldap_link();
104 $ldap->cd($this->config->current['BASE']);
105 $ldap->search("(objectClass=goFonHardware)", array('cn', 'description'));
106 while ($attrs= $ldap->fetch()){
107 $cn= $attrs['cn'][0];
108 if (isset($attrs['description'])){
109 $description= " - ".$attrs['description'][0];
110 } else {
111 $description= "";
112 }
113 $this->hardware_list[$cn]= "$cn$description";
115 }
117 /* Perform search, to get Macro Parameters,Name,Dn,Displayname etc*/
118 $ldap->search("(objectClass=goFonMacro)", array("*"));
120 /* Add none for no macro*/
121 $this->macros['none']=_("no macro");
122 $this->macro ="none";
125 /* Fetch all Macros*/
126 while ($attrs= $ldap->fetch()){
128 /* Only visisble */
129 if((isset($attrs['goFonMacroVisible'][0]))&&($attrs['goFonMacroVisible'][0] ==1)){
131 /* unset Count, we don't need that here */
132 unset($attrs['displayName']['count']);
134 /* fill Selectfield variable with Macros */
135 if(isset($attrs['displayName'][0])){
136 $this->macros[$attrs['dn']] = $attrs['displayName'][0]." (".$attrs['cn'][0].")";
137 }else{
138 $this->macros[$attrs['dn']] = _("undefined");
139 }
141 /* Parse macro data, unset count for parameterarrays */
142 if (isset($attrs['goFonMacroParameter']['count'])){
143 unset($attrs['goFonMacroParameter']['count']);
144 }
146 /* Go through available parameters and parse all attributes, like parametername, type, default ...*/
147 if((isset($attrs['goFonMacroParameter']))&&(is_array($attrs['goFonMacroParameter']))){
149 foreach($attrs['goFonMacroParameter'] as $pkey=>$pval){
150 /* Split Data in readable values, by delimiter ! */
151 $data = split("!",$attrs['goFonMacroParameter'][$pkey]);
153 /* Set all attrs */
154 $id = $data[0];
155 $this->macroarray[$attrs['dn']][$id]['var'] ="var".$id;
156 $this->macroarray[$attrs['dn']][$id]['choosen']=$data[3];
157 $this->macroarray[$attrs['dn']][$id]['id'] =$id;
158 $this->macroarray[$attrs['dn']][$id]['name'] =$data[1];
159 $this->macroarray[$attrs['dn']][$id]['type'] =$data[2];
160 $this->macroarray[$attrs['dn']][$id]['default']=$data[3];
161 if($data[2] == "bool"){
162 $this->macroarray[$attrs['dn']][$id]['choosen']=$data[3];
163 }
164 }//foreach
165 }//is_array
166 }//visible = 1
167 }//while
169 /* Go through already saved values, for a parameter */
170 $tmp = split("!",$this->goFonMacro);
172 /* it is possible that nothing has been saved yet */
173 if(is_array($tmp)){
175 /* First value is the macroname */
176 $this->macro = $tmp[0];
178 /* Macroname saved, delete that index */
179 unset($tmp[0]);
181 /* Check if makro has been removed */
182 if(!isset($this->macroarray[$this->macro])){
183 $this->macrostillavailable = false;
184 }else{
185 $this->macrostillavailable = true;
186 }
188 /* for each parametervalues ( parameterID#value like 25#twentyfive) */
189 foreach($tmp as $var){
191 /* Split this, so we have $varar[0] = parameterID $varar[1] = SelectedValue */
192 $varar = split("#",$var);
194 /* Only insert if the parameter still exists */
195 if(isset($this->macroarray[$this->macro][$varar[0]])){
196 /* Assign value */
197 $this->macroarray[$this->macro][$varar[0]]['choosen']=$varar[1];
198 }
199 }
200 }
203 /* Eventually colorize phones */
204 $ldap->cd($this->config->current['BASE']);
205 foreach ($this->hardware_list as $cn => $desc){
206 $ldap->search("(goFonHardware=$cn)", array('cn'));
207 if ($ldap->count() > 0){
208 $ldap->fetch();
209 if ($ldap->getDN() != $this->dn){
210 $this->used_hardware[$cn]= $ldap->getDN();
211 }
212 }
213 }
214 $this->hardware_list["automatic"]= _("automatic");
215 ksort($this->hardware_list);
216 $this->a_old_telenums = $this->phoneNumbers;
218 if($this->is_account){
219 $this->is_modified = true;
220 }
223 /* Get voicemail PIN from MySQL DB
224 * Because every user can change his PIN directly from the phone
225 * without any update to the ldap
226 * This means, the PIN in the DB is up to date
227 */
228 // Connect to DB server
229 if((is_callable("mysql_pconnect"))&&(isset($a_SETUP))&&(isset($a_SETUP['SERVER']))&&(isset($a_SETUP['LOGIN']))&&(isset($a_SETUP['PASSWORD']))){
230 $r_con = @mysql_pconnect($a_SETUP['SERVER'],$a_SETUP['LOGIN'],$a_SETUP['PASSWORD']);
231 if($r_con){
232 $r_db = @mysql_select_db($a_SETUP['DB'],$r_con);
233 $vp = mysql_fetch_row(mysql_query("SELECT ".$a_SETUP['VOICE_TABLE'].".password FROM ".$a_SETUP['VOICE_TABLE'].", ".$a_SETUP['SIP_TABLE']." WHERE customer_id = sip_users.mailbox AND name='".$this->uid."'"));
235 if((isset($vp[0]))&&(!empty($vp[0]))){
236 $this->goFonPINVoice = $vp[0];
237 }
238 }
239 }
240 $this->lastmacro=$this->macro;
242 if(is_callable("mysql_close")&&(isset($r_con))&&($r_con)){
243 @mysql_close($r_con) ;
244 }
245 }
248 // Generate MySQL Syntax
249 function generate_mysql_entension_entries($save = false){
251 if(!isset($_SESSION['config']->data['SERVERS']['FON'])){
252 if($save)
253 print_red(_("There is currently no asterisk server defined. Possibly you are missing a server that handles the asterisk management (goFonServer). Your settings can't be saved to asterisk database."));
254 return(true);
255 }
257 if(!is_callable("mysql_pconnect")){
258 if($save)
259 print_red(_("Can't save any changes to asterisk database, there is no mysql extension available."));
260 return(true);
261 }
263 // Get Configuration for Mysql database Server
264 $a_SETUP = $_SESSION['config']->data['SERVERS']['FON']; // DB Configuration
265 $s_parameter = ""; // Contains paramter for selected Macro
266 $r_con = false; // DB connection
267 $r_db = false; // Selected DB
268 $r_res = false; // Result resource
269 $a_ldap_attrs = array(); //
271 $s_ip = NULL; // Contains ip for Sip entry
272 $s_host = NULL; // Contains host for Sip entry
273 $s_qualify = "yes"; // Qualify entry
274 $s_pin = NULL; // Entry for secret
275 $s_type = NULL; // Entry for phone type (friend , peer ..)
277 $sip_data_array = array(); // Contains complete sip entry, to generate SQL syntax
278 $i_old_key = false; // Contains index for first old phonenumber, to delete old entries corectly
279 $i_new_key = false; // Contains index for first new phonenumber, to generate new entries corectly
281 $s_sip_values = ""; // Contains string with all values for given attributes in SQL syntax
282 $s_sip_keys = ""; // Contains all needed attributes to generate sip entry in DB
284 $s_sip_key = ""; // Key for SIP entry index
285 $s_sip_val = ""; // Value for SIP entry index
287 $b_first_deleted= false; // Only delete first entry,
288 $s_telenums = ""; // for each value variable
290 $i_is_accounted = false; // Ensure that extension entry, for name to number is only once in table
293 // Connect to DB server
294 $r_con = @mysql_pconnect($a_SETUP['SERVER'],$a_SETUP['LOGIN'],$a_SETUP['PASSWORD']);
296 // Check if we are connected correctly
297 if(!$r_con){
298 $this->generate_error = sprintf(_("The MySQL Server '%s' isn't reachable as user '%s', check GOsa log for mysql error."),
299 $a_SETUP['SERVER'],$a_SETUP['LOGIN']);
300 gosa_log(mysql_error());
301 return false;
302 }
304 // Select database for Extensions
305 $r_db = @mysql_select_db($a_SETUP['DB'],$r_con);
307 // Test if we have the database selected correctly
308 if(!$r_db){
309 $this->generate_error = sprintf(_("Can't select database %s on %s."),$a_SETUP['DB'],$a_SETUP['SERVER']);
310 gosa_log(mysql_error());
311 return false;
312 }
314 // Get phonehardware to setup sip entry
315 $ldap = $this->config->get_ldap_link();
316 $r_res = $ldap->search("(&(objectClass=goFonHardware)(cn=".$this->goFonHardware."))", array('*'));
317 $a_ldap_attrs = $ldap->fetch();
319 if($this->is_number_used()){
320 $this->generate_error = $this->is_number_used();
321 return false;
322 }
324 /* If Save == true, we should save something.
325 * Generate SQL, for drop of old entries
326 * Generate SQL, for insert new entries
327 */
328 if($save == true){
330 foreach($this->a_old_telenums as $tele){
331 $oldnums[]= preg_replace("/[^0-9]/","",$tele);
332 }
334 foreach($this->phoneNumbers as $tele){
335 $newnums[]= preg_replace("/[^0-9]/","",$tele);
336 }
338 // Attribute GoFonDefaultIP set ?
339 if(((isset($a_ldap_attrs['goFonDefaultIP'][0]))&&($a_ldap_attrs['goFonDefaultIP'][0] != "dynamic"))){
340 $s_ip = $a_ldap_attrs['goFonDefaultIP'][0];
341 $s_host = $s_ip;
342 }else{
343 $s_ip = NULL;
344 $s_host = "dynamic";
345 }
347 // Attribute GoFonQualify set ?
348 if(isset($a_ldap_attrs['goFonQualify'])){
349 $s_qualify = $a_ldap_attrs['goFonQualify'][0];
350 }
352 // Attribute GoFonPIN set ?
353 if(isset($this->goFonPIN)){
354 $s_pin = $this->goFonPIN;
355 }
357 // Attribute GoFonType set ?
358 if(isset($a_ldap_attrs['goFonType'])){
359 $s_type = $a_ldap_attrs['goFonType'][0];
360 }
362 if(isset($a_ldap_attrs['goFonDmtfMode'][0])){
363 $sip_data_array['dtmfmode'] = $a_ldap_attrs['goFonDmtfMode'][0];
364 }else{
365 $sip_data_array['dtmfmode'] ="rfc2833";
366 }
368 // generate SIP entry
369 $sip_data_array['id'] = "";
370 $sip_data_array['name'] = $this->uid;
371 $sip_data_array['accountcode'] = NULL;
372 $sip_data_array['amaflags'] = NULL;
373 $sip_data_array['callgroup'] = NULL;
374 $sip_data_array['callerid'] = "";
375 $sip_data_array['canreinvite'] = "no";
376 $sip_data_array['context'] = "default";
377 $sip_data_array['defaultip'] = NULL;
378 $sip_data_array['fromuser'] = NULL;
379 $sip_data_array['fromdomain'] = NULL;
380 $sip_data_array['host'] = $s_host;
381 $sip_data_array['insecure'] = NULL;
382 $sip_data_array['language'] = NULL;
383 $sip_data_array['mailbox'] = "asterisk";
384 $sip_data_array['md5secret'] = NULL;
385 $sip_data_array['nat'] = "no";
386 $sip_data_array['permit'] = NULL;
387 $sip_data_array['deny'] = NULL;
388 $sip_data_array['mask'] = NULL;
389 $sip_data_array['pickupgroup'] = NULL;
390 $sip_data_array['port'] = NULL;
391 $sip_data_array['qualify'] = $s_qualify;
392 $sip_data_array['restrictcid'] = "n";
393 $sip_data_array['rtptimeout'] = NULL;
394 $sip_data_array['rtpholdtimeout']=NULL;
395 $sip_data_array['secret'] = $this->goFonPIN;
396 $sip_data_array['type'] = $s_type ;
397 $sip_data_array['username'] = $this->uid;
398 $sip_data_array['disallow'] = NULL;
399 $sip_data_array['allow'] = NULL;
400 $sip_data_array['musiconhold'] = NULL;
401 $sip_data_array['regseconds'] = NULL;
402 $sip_data_array['ipaddr'] = $s_ip;
403 $sip_data_array['regexten'] = NULL;
404 $sip_data_array['cancallforward']=NULL;
406 // Get selected Macro Parameter and create parameter entry
407 if(isset($this->macroarray[$this->macro])){
408 foreach($this->macroarray[$this->macro] as $key => $val ){
409 $s_parameter .= $val['choosen']."|";
410 }
411 $s_parameter = preg_replace("/\|$/","",$s_parameter);
412 }
414 if($this->is_number_used()){
415 $this->generate_error = $this->is_number_used();
416 return false;
417 }
419 // Create new SIP entry ...
420 $sip_entry = $sip_data_array;
421 reset($newnums);
422 $i_new_key = key($newnums);
423 $sip_entry['callerid'] =$newnums[$i_new_key];
424 $sip_entry['mailbox'] =$newnums[$i_new_key];
426 if((isset($this->parent))&&(isset($this->parent->by_object['mailAccount']))&&($this->parent->by_object['mailAccount']->is_account==true)){
427 $s_mail = $this->parent->by_object['mailAccount']->mail;
428 }else{
429 $s_mail = "";
430 }
432 // $SQL contains all queries
433 $SQL = array();
434 $SQL[] = "DELETE FROM ".$a_SETUP['EXT_TABLE']." WHERE exten='".$this->uid."';\n";
435 $SQL[] = "DELETE FROM ".$a_SETUP['SIP_TABLE']." WHERE name='".$this->uid."';\n";
436 $SQL[] = "DELETE FROM ".$a_SETUP['VOICE_TABLE']." WHERE customer_id=".$newnums[$i_new_key].";";
437 // Delete old entries
438 $b_first_deleted =false;
439 if(isset($oldnums) && is_array($oldnums)){
440 foreach($oldnums as $s_telenums){
441 $SQL[] = "DELETE FROM ".$a_SETUP['EXT_TABLE']." WHERE exten='".$s_telenums."';\n";
442 if(!$b_first_deleted){
443 $b_first_deleted=true;
444 $SQL[] = "DELETE FROM ".$a_SETUP['VOICE_TABLE']." WHERE customer_id=".$s_telenums.";";
445 }
446 }
447 }
448 if($this->goFonHardware=="automatic"){
449 foreach($SQL as $query ){
450 mysql_query($query) ;
451 }
452 return;
453 }
455 // Generate Strings with keys and values
456 foreach($sip_entry as $s_sip_key=>$s_sip_val){
457 if($s_sip_val == NULL) continue;
458 $s_sip_values.="'".$s_sip_val."',";
459 $s_sip_keys .="`".$s_sip_key."`,";
460 }
461 // Remove last ,
462 $s_sip_values = preg_replace("/,$/","",$s_sip_values);
463 $s_sip_keys = preg_replace("/,$/","",$s_sip_keys);
465 // Append SIP Entry
466 $SQL[] ="INSERT INTO ".$a_SETUP['SIP_TABLE']." (".$s_sip_keys.") VALUES (".$s_sip_values.");";
468 /* If deletion starts from userslist, cn uid are not set */
469 if((isset($this->parent->by_object['user']->uid))&&(!empty($this->parent->by_object['user']->uid))){
470 $this->uid = $this->parent->by_object['user']->uid;
471 }
473 if((isset($this->parent->by_object['user']->cn))&&(!empty($this->parent->by_object['user']->cn))){
474 $this->cn = $this->parent->by_object['user']->cn;
475 }
477 if((!isset($this->cn))||(empty($this->cn))){
478 $CNname= $this->uid;
479 }else{
480 $CNname= $this->cn;
481 }
483 $SQL[]= "INSERT INTO ".$a_SETUP['VOICE_TABLE']." (`customer_id`,`context`,`mailbox`,`password`,`fullname`,`email`,`pager`)
484 VALUES ('".$newnums[$i_new_key]."',
485 'default',
486 '".$newnums[$i_new_key]."',
487 '".$this->goFonVoicemailPIN."',
488 '".$CNname."',
489 '".$s_mail."',
490 '');";
491 $i_is_accounted=false;
493 $i = 0;
495 $is_inserted_once = false;
497 // Entension entries Hint / Dial / Goto
498 foreach($newnums as $s_telenums){
500 if(!$is_inserted_once){
501 $is_inserted_once = true;
502 $EXT[$i]['context'] = 'GOsa';
503 $EXT[$i]['exten'] = $this->uid;
504 $EXT[$i]['priority']= 1;
505 $EXT[$i]['app'] = "Goto";
506 $EXT[$i]['appdata'] = $s_telenums."|1";
507 $i ++;
508 }
509 /* Hint Entry */
510 $EXT[$i]['context'] = 'GOsa';
511 $EXT[$i]['exten'] = $s_telenums;
512 $EXT[$i]['priority']= "Hint";
513 $EXT[$i]['app'] = 'SIP/'.$this->uid;
514 $i ++;
515 /* SetCID */
516 //$EXT[$i]['context'] = 'GOsa';
517 //$EXT[$i]['exten'] = $s_telenums;
518 //$EXT[$i]['priority']= 1;
519 //$EXT[$i]['app'] = "SetCIDName";
520 //$EXT[$i]['appdata'] = $CNname;
521 //$i ++;
523 // If no macro is selected use Dial
524 if($this->macro!="none"){
525 $macroname = preg_replace("/,.*$/","",$this->macro);
526 $macroname = preg_replace("/^.*=/","",$macroname);
527 $s_app = "Macro";$macroname;
528 $s_par = $macroname."|".$s_parameter;
529 }else{
530 $s_app = "Dial";
531 $s_par = 'SIP/'.$this->uid."|20|r";
532 }
534 $EXT[$i]['context'] = 'GOsa';
535 $EXT[$i]['exten'] = $s_telenums;
536 $EXT[$i]['priority']= 1;
537 $EXT[$i]['app'] = $s_app;
538 $EXT[$i]['appdata'] = $s_par;
539 $i ++;
541 }
543 // Append all these Entries
544 foreach($EXT as $entr){
545 $SQL_syn = "INSERT INTO ".$a_SETUP['EXT_TABLE']." (";
546 foreach($entr as $key2 => $val2){
547 $SQL_syn.= "`".$key2."`,";
548 }
549 $SQL_syn = preg_replace("/,$/","",$SQL_syn);
550 $SQL_syn .= ") VALUES (";
551 foreach($entr as $key2 => $val2){
552 $SQL_syn .= "'".$val2."',";
553 }
554 $SQL_syn = preg_replace("/,$/","",$SQL_syn);
555 $SQL_syn .=");\n";
556 $SQL[] =$SQL_syn;
557 $SQL_syn ="";
558 }
560 // Perform queries ...
561 foreach($SQL as $query){
562 if(!@mysql_query($query,$r_con)){
563 print_red(_("Error while performing query:")." ".mysql_error());
564 return false;
565 }
566 }
567 }
568 @mysql_close($r_con);
569 return true;
570 }
573 function execute()
574 {
575 /* Call parent execute */
576 plugin::execute();
578 $display = "";
580 if(empty($this->macro)&&(!empty($this->goFonMacro))){
582 /* Go through already saved values, for a parameter */
583 $tmp = split("!",$this->goFonMacro);
585 /* it is possible that nothing has been saved yet */
586 if(is_array($tmp)){
588 /* First value is the macroname */
589 $this->macro = $tmp[0];
591 /* Macroname saved, delete that index */
592 unset($tmp[0]);
594 /* Check if makro has been removed */
595 if(!isset($this->macroarray[$this->macro])){
596 $this->macrostillavailable = false;
597 }else{
598 $this->macrostillavailable = true;
599 }
601 /* for each parametervalues ( parameterID#value like 25#twentyfive) */
602 foreach($tmp as $var){
604 /* Split this, so we have $varar[0] = parameterID $varar[1] = SelectedValue */
605 $varar = split("#",$var);
607 /* Only insert if the parameter still exists */
608 if(isset($this->macroarray[$this->macro][$varar[0]])){
609 /* Assign value */
610 $this->macroarray[$this->macro][$varar[0]]['choosen']=$varar[1];
611 }
612 }
613 }
614 }
616 /* Do we represent a valid account? */
617 if (!$this->is_account && $this->parent == NULL){
618 $display= "<img alt=\"\" src=\"images/stop.png\" align=\"middle\"> <b>".
619 _("This account has no phone extensions.")."</b>";
620 $display.= back_to_main();
621 return ($display);
622 }
624 /* Do we need to flip is_account state? */
625 if (isset($_POST['modify_state'])){
626 $this->is_account= !$this->is_account;
627 }
629 /* Select no macro if, state is empty, this is the case, if the selected macro is no longer available */
630 if(empty($this->macro)){
631 $this->macro ="none";
632 }
634 /* Prepare templating */
635 $smarty= get_smarty();
637 /* tell user that the pluging selected is no longer available*/
638 if((!$this->macrostillavailable)&&($this->macro!="none")){
639 print_red(_("The macro you selected, is no longer available for you, please choose another one."));
640 }
642 /* Assing macroselectbox values */
643 $smarty->assign("macros",$this->macros);
644 $smarty->assign("macro", $this->macro);
646 /* check if there is a FON server created */
647 if(!isset($_SESSION['config']->data['SERVERS']['FON'])){
648 print_red(_("There is currently no asterisk server defined. Possibly you are missing a server that handles the asterisk management (goFonServer). Your settings can't be saved to asterisk database."));
649 }
651 /* Create parameter table, skip if no parameters given */
652 if(!isset($this->macroarray[$this->macro])){
653 $macrotab="";
654 }else{
656 $macrotab ="<table summary=\""._("Parameter")."\">";
657 /* for every single parameter-> display textfile,combo, or true false switch*/
659 foreach($this->phoneNumbers as $phonenum){
660 $tmp[] = $phonenum;
661 }
665 if($this->macro != $this->lastmacro){
666 /* Go through all params */
667 foreach($this->macroarray[$this->macro] as $key => $paras){
669 $string = $paras['default'];
671 $string=preg_replace("/%uid/i",$this->uid,$string);
673 if(isset($this->cn)){
674 $string=preg_replace("/%cn/i",$this->cn,$string);
675 }
677 for($i = 0 ; $i < 10; $i++){
678 if(isset($tmp[$i])){
679 $string = preg_replace("/%telephoneNumber_".($i+1)."/i",$tmp[$i],$string);
680 }
681 }
682 if(isset($tmp[0])){
683 $string = preg_replace("/%telephoneNumber/i",$tmp[0],$string);
684 }
685 $this->macroarray[$this->macro][$key]['choosen']=$string;
686 }
687 }
689 foreach($this->macroarray[$this->macro] as $paras){
691 /* get al vars */
692 $var = $paras['var'];
693 $name = $paras['name'];
694 $default = $paras['default'];
695 $type = $paras['type'];
696 $choosen = $paras['choosen'] ;
697 $str = $default;
699 /* in case of a combo box display a combobox with selected attr */
700 $macrotab.= "<tr>";
701 switch ($type){
703 case "combo":
704 $str= "<select name='".$var."' ".chkacl($this->acl, "goFonMacro")." >";
705 foreach(split(":",$default) as $choice){
706 if($choosen==$choice){
707 $str.= "\n<option value='".$choice."' selected>".$choice." </option>";
708 }else{
709 $str.= "\n<option value='".$choice."'>".$choice." </option>";
710 }
711 }
712 $str.="</select>";
713 $macrotab.= "<td>".base64_decode($name)."</td><td>$str";
714 break;
716 case "bool":
717 if(!$choosen){
718 $str="\n<input type='checkbox' name='".$var."' value='1' ".chkacl($this->acl, "goFonMacro")." >";
719 }else{
720 $str="\n<input type='checkbox' name='".$var."' value='1' checked ".chkacl($this->acl, "goFonMacro").">";
721 }
722 $macrotab.= "<td colspan='2'>$str ".base64_decode($name)."";
723 break;
725 case "string":
726 $str="<input name='".$var."' value='".$choosen."' ".chkacl($this->acl, "goFonMacro")." style='width:340px;'>";
727 $macrotab.= "<td>".base64_decode($name)."</td><td>$str";
728 break;
730 }
731 $macrotab.= "</td></tr>";
733 }
734 $macrotab.="</table><input name='post_success' type='hidden' value='1'>";
735 }//is_array()
737 /* Give smarty the table */
738 $smarty->assign("macrotab",$macrotab);
740 /* Do we represent a valid account? */
741 if (!$this->is_account && $this->parent == NULL){
742 $display= "<img alt=\"\" src=\"images/stop.png\" align=\"middle\"> <b>".
743 _("This account has no phone extensions.")."</b>";
744 $display.= back_to_main();
745 return($display);
746 }
748 $display= "";
750 /* Show tab dialog headers */
751 if ($this->parent != NULL){
752 if ($this->is_account){
753 $display= $this->show_header(_("Remove phone account"),
754 _("This account has phone features enabled. You can disable them by clicking below."));
755 } else {
756 if(empty($this->uid)){
757 $display= $this->show_header(_("Create phone account"),
758 _("This account has phone features disabled. You can't enable them while no uid is set."),TRUE,TRUE);
759 }else{
760 $display= $this->show_header(_("Create phone account"),
761 _("This account has phone features disabled. You can enable them by clicking below."));
762 }
763 return ($display);
764 }
765 }
767 /* Add phone number */
768 if (isset($_POST["add_phonenumber"]) && $_POST['phonenumber']){
769 if (is_phone_nr($_POST['phonenumber'])){
770 $number= $_POST["phonenumber"];
771 $this->phoneNumbers[$number]= $number;
772 $this->is_modified= TRUE;
773 } else {
774 print_red(_("Please enter a valid phone number!"));
775 }
776 }
778 /* Remove phone number */
779 if (isset($_POST["delete_phonenumber"]) && isset($_POST["phonenumber_list"])){
780 foreach ($_POST['phonenumber_list'] as $number){
781 unset($this->phoneNumbers[$number]);
782 $this->is_modified= TRUE;
783 }
784 }
786 /* Transfer ACL's */
787 foreach($this->attributes as $val){
788 $smarty->assign($val."ACL", chkacl($this->acl,$val));
789 if(isset($this->$val)){
790 $smarty->assign($val,$this->$val);
791 }else{
792 $smarty->assign($val,"");
793 }
794 }
796 /* Fill arrays */
797 $smarty->assign ("goFonHardware", $this->goFonHardware);
798 if (!count($this->phoneNumbers)){
799 $smarty->assign ("phoneNumbers", array());
800 } else {
801 $smarty->assign ("phoneNumbers", $this->phoneNumbers);
802 }
803 $hl= "<select size=\"1\" name=\"goFonHardware\" title=\"".
804 _("Choose your private phone")."\" ".chkacl($this->acl, "goFonHardware").">\n";
805 foreach ($this->hardware_list as $cn => $description){
806 if ($cn == $this->goFonHardware){
807 $selected= "selected";
808 } else {
809 $selected= "";
810 }
811 if (isset($this->used_hardware[$cn])){
812 $color= "style=\"color:#A0A0A0\"";
813 } else {
814 $color= "";
815 }
816 $hl.= " <option $color label=\"$cn\" value=\"$cn\" $selected>$description </option>\n";
817 }
818 $hl.= "</select>\n";
819 $smarty->assign ("hardware_list", $hl);
821 /* Show main page */
822 $this->lastmacro = $this->macro;
823 $display.= $smarty->fetch(get_template_path('generic.tpl', TRUE, dirname(__FILE__)));
824 return($display);
825 }
828 function save_object()
829 {
830 if (isset($_POST["phoneTab"])){
831 plugin::save_object();
833 /* Save checkbox */
834 if (isset($_POST['fon_to_mail'])){
835 $tmp= "[M]";
836 } else {
837 $tmp= "[]";
838 }
839 if (chkacl ($this->acl, "goFonDeliveryMode") == ""){
840 if ($this->goFonDeliveryMode != $tmp){
841 $this->is_modified= TRUE;
842 }
843 $this->goFonDeliveryMode= $tmp;
844 }
846 /* Every macro in the select box are available */
847 if((isset($_POST['macro']))){
848 $this->macrostillavailable=true;
849 }
851 if(is_array($this->phoneNumbers)){
852 foreach($this->phoneNumbers as $telenumms) {
853 $nummsinorder[]=$telenumms;
854 }
855 }else{
856 $nummsinorder=array("");
857 }
859 /* get all Postvars */
860 if(isset($this->macroarray[$this->macro])){
861 foreach($this->macroarray[$this->macro] as $key => $paras){
862 if(isset($_POST[$paras['var']])){
863 $this->macroarray[$this->macro][$key]['choosen'] = $_POST[$paras['var']];
864 }
866 /* Checkboxes are special, they are not Posted if they are not selected, so the won't be changed with the above code
867 We need this code below to read and save checkboxes correct
868 */
870 if(isset($_POST['post_success'])){
871 if($this->macroarray[$this->macro][$key]['type']=="bool"){
872 if(isset($_POST[$this->macroarray[$this->macro][$key]['var']])) {
873 $this->macroarray[$this->macro][$key]['choosen']=$_POST[$paras['var']];
874 }else{
875 $this->macroarray[$this->macro][$key]['choosen']=false;
876 }
877 }
878 }
879 }
880 }
881 }
882 }
884 function check()
885 {
886 /* Call common method to give check the hook */
887 $message= plugin::check();
889 if((strlen($this->goFonVoicemailPIN)==0)||(strlen($this->goFonVoicemailPIN)>4)){
890 $message[]=(_("Voicemail PIN must be between 1-4 characters."));
891 }else{
892 if(preg_match("/[^0-9]/",$this->goFonVoicemailPIN)){
893 $message[]=(_("The specified Voicemail PIN contains invalid characters, only numeric values are allowed here."));
894 }
895 }
897 if((strlen($this->goFonPIN)<=0)){
898 $message[]=(_("Phone PIN must be at least one character long."));
899 }else{
900 if(preg_match("/[^0-9a-z]/i",$this->goFonPIN)){
901 $message[]=(_("The specified phone PIN contains invalid characters, only aphanumeric values are allowed here."));
902 }
903 }
905 if(!$this->generate_mysql_entension_entries()){
906 $message[] = $this->generate_error;
907 }
909 /* We need at least one phone number */
910 if (count($this->phoneNumbers) == 0){
911 $message[]= sprintf(_("You need to specify at least one phone number!"));
912 }
914 /* check for ! in any parameter setting*/
915 if(isset($this->macroarray[$this->macro])){
916 foreach($this->macroarray[$this->macro] as $val){
917 if((strstr($val['choosen'],"!"))||(strstr($val['choosen'],"#"))){
918 $message[] = sprintf(_("The parameter %s contains invalid char. '!,#' is used as delimiter"),$val['name']);
919 }
920 }
921 }
922 return ($message);
923 }
927 function save()
928 {
929 plugin::save();
931 /* Save arrays */
932 $this->attrs['telephoneNumber']= array();
933 foreach ($this->phoneNumbers as $number){
934 $this->attrs['telephoneNumber'][]= $number;
935 }
937 /* Save settings, or remove goFonMacro attribute*/
938 if($this->macro!="none"){
939 $this->attrs['goFonMacro']=$this->macro;
940 if(isset($this->macroarray[$this->macro])){
941 foreach($this->macroarray[$this->macro] as $paras) {
942 $this->attrs['goFonMacro'].="!".$paras['id']."#".$paras['choosen'];
943 }
944 }
945 }else{
946 $this->attrs['goFonMacro']=array();
947 }
948 unset($this->attrs['macro']) ;
950 $this->attrs['goFonForwarding']=array();
952 $this->generate_mysql_entension_entries(true);
954 if($this->attrs['goFonMacro']==""){
955 $this->attrs['goFonMacro']=array();
956 }
958 unset($this->attrs['cn']);
960 /* Write back to ldap */
961 $ldap= $this->config->get_ldap_link();
962 $ldap->cd($this->dn);
963 $this->cleanup();
964 $ldap->modify ($this->attrs);
966 show_ldap_error($ldap->get_error(), _("Saving phone account failed"));
968 /* Optionally execute a command after we're done */
970 if ($this->initially_was_account == $this->is_account){
971 if ($this->is_modified){
972 $this->handle_post_events("modify",array("uid" => $this->uid));
973 }
974 } else {
975 $this->handle_post_events("add",array("uid" => $this->uid));
976 }
978 }
981 function insert_after($entry, $nr, $list)
982 {
983 /* Is the entry free? No? Make it free... */
984 if (isset($list[$nr])) {
985 $dest= array();
986 $newidx= 0;
988 foreach ($list as $idx => $contents){
989 $dest[$newidx++]= $contents;
990 if ($idx == $nr){
991 $dest[$newidx++]= $entry;
992 }
993 }
994 } else {
995 $dest= $list;
996 $dest[$nr]= $entry;
997 }
999 return ($dest);
1000 }
1003 function adapt_from_template($dn)
1004 {
1005 plugin::adapt_from_template($dn);
1007 /* Assemble phone numbers */
1008 if (isset($this->attrs['telephoneNumber'])){
1009 for ($i= 0; $i<$this->attrs['telephoneNumber']['count']; $i++){
1010 $number= $this->attrs['telephoneNumber'][$i];
1011 $this->phoneNumbers[$number]= $number;
1012 }
1013 }
1014 }
1017 function remove_from_parent()
1018 {
1019 if(!$this->initially_was_account) return;
1021 foreach($this->attributes as $key=>$val){
1022 if(in_array($val,array("uid","cn"))){
1023 unset($this->attributes[$key]);
1024 unset($this->$val);
1025 }
1026 }
1027 if(array_key_exists('config', $_SESSION) &&
1028 array_key_exists('SERVERS', $_SESSION['config']->data) &&
1029 array_key_exists('FON', $_SESSION['config']->data['SERVERS']) &&
1030 is_callable("mysql_pconnect")) {
1031 // Get Configuration for Mysql database Server
1032 $a_SETUP = $_SESSION['config']->data['SERVERS']['FON'];
1033 $s_parameter ="";
1035 // Connect to DB server
1036 $r_con = @mysql_pconnect($a_SETUP['SERVER'],$a_SETUP['LOGIN'],$a_SETUP['PASSWORD']);
1038 // Check if we are connected correctly
1039 if(!$r_con){
1040 print_red(sprintf(_("The MySQL Server '%s' isn't reachable as user '%s', check GOsa log for mysql error."),
1041 $a_SETUP['SERVER'],$a_SETUP['LOGIN']));
1042 gosa_log(@mysql_error());
1043 return false;
1044 }
1046 // Select database for Extensions
1047 $db = @mysql_select_db($a_SETUP['DB'],$r_con);
1049 // Test if we have the database selected correctly
1050 if(!$db){
1051 print_red(sprintf(_("Can't select database %s on %s."),$a_SETUP['DB'],$a_SETUP['SERVER']));
1052 gosa_log(@mysql_error());
1053 return false;
1054 }
1056 $SQL="";
1058 /* If deletion starts from userslist, cn uid are not set */
1059 if((isset($this->parent->by_object['user']->uid))&&(!empty($this->parent->by_object['user']->uid))){
1060 $this->uid = $this->parent->by_object['user']->uid;
1061 }
1063 if((isset($this->parent->by_object['user']->cn))&&(!empty($this->parent->by_object['user']->cn))){
1064 $this->cn = $this->parent->by_object['user']->cn;
1065 }
1067 $first_num = false;
1068 // Delete old entries
1069 foreach($this->a_old_telenums as $s_telenums){
1070 if(!$first_num){
1071 $first_num = $s_telenums;
1072 }
1073 $SQL[] = "DELETE FROM ".$a_SETUP['EXT_TABLE']." WHERE exten='".$s_telenums."';\n";
1074 }
1076 $SQL[] = "DELETE FROM ".$a_SETUP['VOICE_TABLE']." WHERE customer_id='".$first_num."';";
1077 $SQL[] = "DELETE FROM ".$a_SETUP['EXT_TABLE']." WHERE exten='".$this->uid."';\n";
1078 $SQL[] = "DELETE FROM ".$a_SETUP['SIP_TABLE']." WHERE name='".$this->uid."';\n";
1080 foreach($SQL as $query){
1081 if(!@mysql_query($query,$r_con)){
1082 print_red(_("Stop".mysql_error()));
1083 return false;
1084 }
1085 }
1086 }else{
1087 print_red(_("Can't remove phone account, the mysql extension is not present in php configuration."));
1088 return false;
1089 }
1091 /* unset macro attr, it will cause an error */
1092 $tmp = array_flip($this->attributes);
1093 unset($tmp['macro']);
1094 $this->attributes=array_flip($tmp);
1096 /* Cancel if there's nothing to do here */
1097 if (!$this->initially_was_account){
1098 return;
1099 }
1101 plugin::remove_from_parent();
1103 /* Just keep one phone number */
1104 if (count($this->telephoneNumber) && $this->telephoneNumber != ""){
1105 $this->attrs['telephoneNumber']= $this->telephoneNumber;
1106 } else {
1107 $this->attrs['telephoneNumber']= array();
1108 }
1111 $ldap= $this->config->get_ldap_link();
1112 $ldap->cd($this->config->current['BASE']);
1113 $ldap->search("(objectClass=goFonQueue)", array("member"));
1114 while($attr = $ldap->fetch()){
1115 if(in_array($this->dn,$attr['member'])){
1116 $new =new ogrouptabs($this->config, $this->config->data['TABS']['OGROUPTABS'],$attr['dn']);
1117 unset($new->by_object['ogroup']->memberList[$this->dn]);
1118 unset($new->by_object['ogroup']->member[$this->dn]);
1119 $new->save();
1120 print_red(sprintf(_("Removed user '%s' from phone queue '%s'."),$this->uid,$new->by_object['ogroup']->attrs['cn']));
1121 }
1122 }
1123 $ldap->cd($this->dn);
1124 $this->cleanup();
1125 $ldap->modify ($this->attrs);
1127 show_ldap_error($ldap->get_error(), _("Removing phone account failed"));
1129 /* Optionally execute a command after we're done */
1130 @mysql_close($r_con);
1131 $this->handle_post_events('remove',array("uid"=> $this->uid));
1132 }
1136 /* This function checks if the given phonenumbers are available or already in use*/
1137 function is_number_used()
1138 {
1139 $ldap= $this->config->get_ldap_link();
1140 $ldap->cd($this->config->current['BASE']);
1141 $ldap->search("(|(objectClass=goFonAccount)(objectClass=goFonQueue)(objectClass=goFonConference))", array("telephoneNumber","cn","uid"));
1142 while($attrs = $ldap->fetch()) {
1143 unset($attrs['telephoneNumber']['count']);
1144 foreach($attrs['telephoneNumber'] as $tele){
1145 if(!isset($attrs['cn'][0])) $attrs['cn'][0]=$attrs['dn'];
1146 if(!isset($attrs['uid'][0])) $attrs['uid'][0]=$attrs['dn'];
1147 $numbers[$tele]=$attrs;
1148 }
1149 }
1151 foreach($this->phoneNumbers as $num){
1152 if(!isset($this->cn)) $this->cn = "";
1154 if((isset($numbers[$num]))&&(($numbers[$num]['uid'][0]!=$this->uid))){
1155 if(isset($numbers[$num]['uid'][0])){
1156 return sprintf(_("The specified telephonenumber '%s' is already assigned to '%s'."),$num,$numbers[$num]['uid'][0]);
1157 }else{
1158 return sprintf(_("The specified telephonenumber '%s' is already assigned to '%s'."),$num,$numbers[$num]['cn'][0]);
1159 }
1160 }
1161 }
1162 }
1165 /* Create phoneAccount part of copy & paste dialog */
1166 function getCopyDialog()
1167 {
1168 if(!$this->is_account) return("");
1169 $smarty = get_smarty();
1170 if (!count($this->phoneNumbers)){
1171 $smarty->assign ("phoneNumbers", array(""));
1172 } else {
1173 $smarty->assign ("phoneNumbers", $this->phoneNumbers);
1174 }
1176 $smarty->assign("goFonVoicemailPIN",$this->goFonVoicemailPIN);
1177 $smarty->assign("goFonPIN",$this->goFonPIN);
1179 $display= $smarty->fetch(get_template_path('paste_generic.tpl', TRUE, dirname(__FILE__)));
1180 $ret =array();
1181 $ret['string'] = $display;
1182 $ret['status'] = "";
1183 return($ret);
1184 }
1186 /* Save posts from copy & paste dialog dialog */
1187 function saveCopyDialog()
1188 {
1189 if(!$this->is_account) return;
1190 $this->execute();
1191 if(isset($_POST['goFonVoicemailPIN'])) {
1192 $this->goFonVoicemailPIN = $_POST['goFonVoicemailPIN'];
1193 }
1194 if(isset($_POST['goFonPIN'])){
1195 $this->goFonPIN = $_POST['goFonPIN'];
1196 }
1197 }
1198 }
1200 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1201 ?>