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 = "";
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",
40 "telephoneNumber", "goFonMacro","macro");
41 var $objectclasses= array("goFonAccount");
43 function phoneAccount ($config, $dn= NULL)
44 {
45 plugin::plugin ($config, $dn);
47 /* Set phone hardware */
48 if (!isset($this->attrs['goFonHardware'])){
49 $this->goFonHardware= "automatic";
50 }
52 /* Preset voice format */
53 if (!isset($this->attrs['goFonFormat'])){
54 $this->goFonFormat= "wav";
55 }
57 /* Assemble phone numbers */
58 if (isset($this->attrs['telephoneNumber'])){
59 for ($i= 0; $i<$this->attrs['telephoneNumber']['count']; $i++){
60 $number= $this->attrs['telephoneNumber'][$i];
61 $this->phoneNumbers[$number]= $number;
62 }
63 }
65 /* Set up has_mailAccount */
66 if (isset($this->attrs['objectClass'])){
67 if (in_array("gosaMailAccount", $this->attrs['objectClass'])){
68 $this->has_mailAccount= TRUE;
69 }
70 }
72 $a_SETUP= array();
73 if(array_key_exists('config',$_SESSION) &&
74 array_key_exists('SERVERS',$_SESSION['config']->data) &&
75 array_key_exists('FON',$_SESSION['config']->data['SERVERS']) &&
76 is_callable("mysql_connect")
77 ) {
78 $a_SETUP = $_SESSION['config']->data['SERVERS']['FON'];
79 $r_con = @mysql_pconnect($a_SETUP['SERVER'],$a_SETUP['LOGIN'],$a_SETUP['PASSWORD']);
80 if(!$r_con){
81 $this->generate_error = sprintf(_("The MySQL Server '%s' isn't reachable as user '%s', check GOsa log for mysql error."),
82 $a_SETUP['SERVER'],$a_SETUP['LOGIN']);
83 gosa_log(mysql_error());
84 return false;
85 }
86 $db = @mysql_select_db($a_SETUP['DB'],$r_con);
87 if(!$db){
88 $this->generate_error = sprintf(_("Can't select database %s on %s."),$a_SETUP['DB'],$a_SETUP['SERVER']);
89 gosa_log(mysql_error());
90 return false;
91 }
93 $first = false;
94 foreach($this->phoneNumbers as $key => $val){
95 if(!$first){
96 $first = $key;
97 }
98 }
99 }
101 /* Load hardware list */
102 $ldap= $this->config->get_ldap_link();
103 $ldap->cd($this->config->current['BASE']);
104 $ldap->search("(objectClass=goFonHardware)", array('cn', 'description'));
105 while ($attrs= $ldap->fetch()){
106 $cn= $attrs['cn'][0];
107 if (isset($attrs['description'])){
108 $description= " - ".$attrs['description'][0];
109 } else {
110 $description= "";
111 }
112 $this->hardware_list[$cn]= "$cn$description";
114 }
116 /* Perform search, to get Macro Parameters,Name,Dn,Displayname etc*/
117 $ldap->search("(objectClass=goFonMacro)", array("*"));
119 /* Add none for no macro*/
120 $this->macros['none']=_("no macro");
121 $this->macro ="none";
124 /* Fetch all Macros*/
125 while ($attrs= $ldap->fetch()){
127 /* Only visisble */
128 if((isset($attrs['goFonMacroVisible'][0]))&&($attrs['goFonMacroVisible'][0] ==1)){
130 /* unset Count, we don't need that here */
131 unset($attrs['displayName']['count']);
133 /* fill Selectfield variable with Macros */
134 if(isset($attrs['displayName'][0])){
135 $this->macros[$attrs['dn']] = $attrs['displayName'][0]." (".$attrs['cn'][0].")";
136 }else{
137 $this->macros[$attrs['dn']] = _("undefined");
138 }
140 /* Parse macro data, unset count for parameterarrays */
141 if (isset($attrs['goFonMacroParameter']['count'])){
142 unset($attrs['goFonMacroParameter']['count']);
143 }
145 /* Go through available parameters and parse all attributes, like parametername, type, default ...*/
146 if((isset($attrs['goFonMacroParameter']))&&(is_array($attrs['goFonMacroParameter']))){
148 foreach($attrs['goFonMacroParameter'] as $pkey=>$pval){
149 /* Split Data in readable values, by delimiter ! */
150 $data = split("!",$attrs['goFonMacroParameter'][$pkey]);
152 /* Set all attrs */
153 $id = $data[0];
154 $this->macroarray[$attrs['dn']][$id]['var'] ="var".$id;
155 $this->macroarray[$attrs['dn']][$id]['choosen']=$data[3];
156 $this->macroarray[$attrs['dn']][$id]['id'] =$id;
157 $this->macroarray[$attrs['dn']][$id]['name'] =$data[1];
158 $this->macroarray[$attrs['dn']][$id]['type'] =$data[2];
159 $this->macroarray[$attrs['dn']][$id]['default']=$data[3];
160 if($data[2] == "bool"){
161 $this->macroarray[$attrs['dn']][$id]['choosen']=$data[3];
162 }
163 }//foreach
164 }//is_array
165 }//visible = 1
166 }//while
168 /* Go through already saved values, for a parameter */
169 $tmp = split("!",$this->goFonMacro);
171 /* it is possible that nothing has been saved yet */
172 if(is_array($tmp)){
174 /* First value is the macroname */
175 $this->macro = $tmp[0];
177 /* Macroname saved, delete that index */
178 unset($tmp[0]);
180 /* Check if makro has been removed */
181 if(!isset($this->macroarray[$this->macro])){
182 $this->macrostillavailable = false;
183 }else{
184 $this->macrostillavailable = true;
185 }
187 /* for each parametervalues ( parameterID#value like 25#twentyfive) */
188 foreach($tmp as $var){
190 /* Split this, so we have $varar[0] = parameterID $varar[1] = SelectedValue */
191 $varar = split("#",$var);
193 /* Only insert if the parameter still exists */
194 if(isset($this->macroarray[$this->macro][$varar[0]])){
195 /* Assign value */
196 $this->macroarray[$this->macro][$varar[0]]['choosen']=$varar[1];
197 }
198 }
199 }
202 /* Eventually colorize phones */
203 $ldap->cd($this->config->current['BASE']);
204 foreach ($this->hardware_list as $cn => $desc){
205 $ldap->search("(goFonHardware=$cn)", array('cn'));
206 if ($ldap->count() > 0){
207 $ldap->fetch();
208 if ($ldap->getDN() != $this->dn){
209 $this->used_hardware[$cn]= $ldap->getDN();
210 }
211 }
212 }
213 $this->hardware_list["automatic"]= _("automatic");
214 ksort($this->hardware_list);
215 $this->a_old_telenums = $this->phoneNumbers;
217 if($this->is_account){
218 $this->is_modified = true;
219 }
222 /* Get voicemail PIN from MySQL DB
223 * Because every user can change his PIN directly from the phone
224 * without any update to the ldap
225 * This means, the PIN in the DB is up to date
226 */
227 // Connect to DB server
228 if((is_callable("mysql_pconnect"))&&(isset($a_SETUP))&&(isset($a_SETUP['SERVER']))&&(isset($a_SETUP['LOGIN']))&&(isset($a_SETUP['PASSWORD']))){
229 $r_con = @mysql_pconnect($a_SETUP['SERVER'],$a_SETUP['LOGIN'],$a_SETUP['PASSWORD']);
230 if($r_con){
231 $r_db = @mysql_select_db($a_SETUP['DB'],$r_con);
232 $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."'"));
234 if((isset($vp[0]))&&(!empty($vp[0]))){
235 $this->goFonPINVoice = $vp[0];
236 }
237 }
238 }
239 $this->lastmacro=$this->macro;
241 if(is_callable("mysql_close")&&(isset($r_con))&&($r_con)){
242 @mysql_close($r_con) ;
243 }
244 }
247 // Generate MySQL Syntax
248 function generate_mysql_entension_entries($save = false){
250 if(!isset($_SESSION['config']->data['SERVERS']['FON'])){
251 if($save)
252 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."));
253 return(true);
254 }
256 if(!is_callable("mysql_pconnect")){
257 if($save)
258 print_red(_("Can't save any changes to asterisk database, there is no mysql extension available."));
259 return(true);
260 }
262 // Get Configuration for Mysql database Server
263 $a_SETUP = $_SESSION['config']->data['SERVERS']['FON']; // DB Configuration
264 $s_parameter = ""; // Contains paramter for selected Macro
265 $r_con = false; // DB connection
266 $r_db = false; // Selected DB
267 $r_res = false; // Result resource
268 $a_ldap_attrs = array(); //
270 $s_ip = NULL; // Contains ip for Sip entry
271 $s_host = NULL; // Contains host for Sip entry
272 $s_qualify = "yes"; // Qualify entry
273 $s_pin = NULL; // Entry for secret
274 $s_type = NULL; // Entry for phone type (friend , peer ..)
276 $sip_data_array = array(); // Contains complete sip entry, to generate SQL syntax
277 $i_old_key = false; // Contains index for first old phonenumber, to delete old entries corectly
278 $i_new_key = false; // Contains index for first new phonenumber, to generate new entries corectly
280 $s_sip_values = ""; // Contains string with all values for given attributes in SQL syntax
281 $s_sip_keys = ""; // Contains all needed attributes to generate sip entry in DB
283 $s_sip_key = ""; // Key for SIP entry index
284 $s_sip_val = ""; // Value for SIP entry index
286 $b_first_deleted= false; // Only delete first entry,
287 $s_telenums = ""; // for each value variable
289 $i_is_accounted = false; // Ensure that extension entry, for name to number is only once in table
292 // Connect to DB server
293 $r_con = @mysql_pconnect($a_SETUP['SERVER'],$a_SETUP['LOGIN'],$a_SETUP['PASSWORD']);
295 // Check if we are connected correctly
296 if(!$r_con){
297 $this->generate_error = sprintf(_("The MySQL Server '%s' isn't reachable as user '%s', check GOsa log for mysql error."),
298 $a_SETUP['SERVER'],$a_SETUP['LOGIN']);
299 gosa_log(mysql_error());
300 return false;
301 }
303 // Select database for Extensions
304 $r_db = @mysql_select_db($a_SETUP['DB'],$r_con);
306 // Test if we have the database selected correctly
307 if(!$r_db){
308 $this->generate_error = sprintf(_("Can't select database %s on %s."),$a_SETUP['DB'],$a_SETUP['SERVER']);
309 gosa_log(mysql_error());
310 return false;
311 }
313 // Get phonehardware to setup sip entry
314 $ldap = $this->config->get_ldap_link();
315 $r_res = $ldap->search("(&(objectClass=goFonHardware)(cn=".$this->goFonHardware."))", array('*'));
316 $a_ldap_attrs = $ldap->fetch();
318 if($this->is_number_used()){
319 $this->generate_error = $this->is_number_used();
320 return false;
321 }
323 /* If Save == true, we should save something.
324 * Generate SQL, for drop of old entries
325 * Generate SQL, for insert new entries
326 */
327 if($save == true){
329 foreach($this->a_old_telenums as $tele){
330 $oldnums[]= preg_replace("/[^0-9]/","",$tele);
331 }
333 foreach($this->phoneNumbers as $tele){
334 $newnums[]= preg_replace("/[^0-9]/","",$tele);
335 }
337 // Attribute GoFonDefaultIP set ?
338 if(((isset($a_ldap_attrs['goFonDefaultIP'][0]))&&($a_ldap_attrs['goFonDefaultIP'][0] != "dynamic"))){
339 $s_ip = $a_ldap_attrs['goFonDefaultIP'][0];
340 $s_host = $s_ip;
341 }else{
342 $s_ip = NULL;
343 $s_host = "dynamic";
344 }
346 // Attribute GoFonQualify set ?
347 if(isset($a_ldap_attrs['goFonQualify'])){
348 $s_qualify = $a_ldap_attrs['goFonQualify'][0];
349 }
351 // Attribute GoFonPIN set ?
352 if(isset($this->goFonPIN)){
353 $s_pin = $this->goFonPIN;
354 }
356 // Attribute GoFonType set ?
357 if(isset($a_ldap_attrs['goFonType'])){
358 $s_type = $a_ldap_attrs['goFonType'][0];
359 }
361 if(isset($a_ldap_attrs['goFonDmtfMode'][0])){
362 $sip_data_array['dtmfmode'] = $a_ldap_attrs['goFonDmtfMode'][0];
363 }else{
364 $sip_data_array['dtmfmode'] ="rfc2833";
365 }
367 // generate SIP entry
368 $sip_data_array['id'] = "";
369 $sip_data_array['name'] = $this->uid;
370 $sip_data_array['accountcode'] = NULL;
371 $sip_data_array['amaflags'] = NULL;
372 $sip_data_array['callgroup'] = NULL;
373 $sip_data_array['callerid'] = "";
374 $sip_data_array['canreinvite'] = "no";
375 $sip_data_array['context'] = "default";
376 $sip_data_array['defaultip'] = NULL;
377 $sip_data_array['fromuser'] = NULL;
378 $sip_data_array['fromdomain'] = NULL;
379 $sip_data_array['host'] = $s_host;
380 $sip_data_array['insecure'] = NULL;
381 $sip_data_array['language'] = NULL;
382 $sip_data_array['mailbox'] = "asterisk";
383 $sip_data_array['md5secret'] = NULL;
384 $sip_data_array['nat'] = "no";
385 $sip_data_array['permit'] = NULL;
386 $sip_data_array['deny'] = NULL;
387 $sip_data_array['mask'] = NULL;
388 $sip_data_array['pickupgroup'] = NULL;
389 $sip_data_array['port'] = NULL;
390 $sip_data_array['qualify'] = $s_qualify;
391 $sip_data_array['restrictcid'] = "n";
392 $sip_data_array['rtptimeout'] = NULL;
393 $sip_data_array['rtpholdtimeout']=NULL;
394 $sip_data_array['secret'] = $this->goFonPIN;
395 $sip_data_array['type'] = $s_type ;
396 $sip_data_array['username'] = $this->uid;
397 $sip_data_array['disallow'] = NULL;
398 $sip_data_array['allow'] = NULL;
399 $sip_data_array['musiconhold'] = NULL;
400 $sip_data_array['regseconds'] = NULL;
401 $sip_data_array['ipaddr'] = $s_ip;
402 $sip_data_array['regexten'] = NULL;
403 $sip_data_array['cancallforward']=NULL;
405 // Get selected Macro Parameter and create parameter entry
406 if(isset($this->macroarray[$this->macro])){
407 foreach($this->macroarray[$this->macro] as $key => $val ){
408 $s_parameter .= $val['choosen']."|";
409 }
410 $s_parameter = preg_replace("/\|$/","",$s_parameter);
411 }
413 if($this->is_number_used()){
414 $this->generate_error = $this->is_number_used();
415 return false;
416 }
418 // Create new SIP entry ...
419 $sip_entry = $sip_data_array;
420 reset($newnums);
421 $i_new_key = key($newnums);
422 $sip_entry['callerid'] =$newnums[$i_new_key];
423 $sip_entry['mailbox'] =$newnums[$i_new_key];
425 if((isset($this->parent))&&(isset($this->parent->by_object['mailAccount']))&&($this->parent->by_object['mailAccount']->is_account==true)){
426 $s_mail = $this->parent->by_object['mailAccount']->mail;
427 }else{
428 $s_mail = "";
429 }
431 // $SQL contains all queries
432 $SQL = array();
433 $SQL[] = "DELETE FROM ".$a_SETUP['EXT_TABLE']." WHERE exten='".$this->uid."';\n";
434 $SQL[] = "DELETE FROM ".$a_SETUP['SIP_TABLE']." WHERE name='".$this->uid."';\n";
435 $SQL[] = "DELETE FROM ".$a_SETUP['VOICE_TABLE']." WHERE customer_id=".$newnums[$i_new_key].";";
436 // Delete old entries
437 $b_first_deleted =false;
438 if(isset($oldnums) && is_array($oldnums)){
439 foreach($oldnums as $s_telenums){
440 $SQL[] = "DELETE FROM ".$a_SETUP['EXT_TABLE']." WHERE exten='".$s_telenums."';\n";
441 if(!$b_first_deleted){
442 $b_first_deleted=true;
443 $SQL[] = "DELETE FROM ".$a_SETUP['VOICE_TABLE']." WHERE customer_id=".$s_telenums.";";
444 }
445 }
446 }
447 if($this->goFonHardware=="automatic"){
448 foreach($SQL as $query ){
449 mysql_query($query) ;
450 }
451 return;
452 }
454 // Generate Strings with keys and values
455 foreach($sip_entry as $s_sip_key=>$s_sip_val){
456 if($s_sip_val == NULL) continue;
457 $s_sip_values.="'".$s_sip_val."',";
458 $s_sip_keys .="`".$s_sip_key."`,";
459 }
460 // Remove last ,
461 $s_sip_values = preg_replace("/,$/","",$s_sip_values);
462 $s_sip_keys = preg_replace("/,$/","",$s_sip_keys);
464 // Append SIP Entry
465 $SQL[] ="INSERT INTO ".$a_SETUP['SIP_TABLE']." (".$s_sip_keys.") VALUES (".$s_sip_values.");";
467 /* If deletion starts from userslist, cn uid are not set */
468 if((isset($this->parent->by_object['user']->uid))&&(!empty($this->parent->by_object['user']->uid))){
469 $this->uid = $this->parent->by_object['user']->uid;
470 }
472 if((isset($this->parent->by_object['user']->cn))&&(!empty($this->parent->by_object['user']->cn))){
473 $this->cn = $this->parent->by_object['user']->cn;
474 }
476 if((!isset($this->cn))||(empty($this->cn))){
477 $CNname= $this->uid;
478 }else{
479 $CNname= $this->cn;
480 }
482 $SQL[]= "INSERT INTO ".$a_SETUP['VOICE_TABLE']." (`customer_id`,`context`,`mailbox`,`password`,`fullname`,`email`,`pager`)
483 VALUES ('".$newnums[$i_new_key]."',
484 'default',
485 '".$newnums[$i_new_key]."',
486 '".$this->goFonVoicemailPIN."',
487 '".$CNname."',
488 '".$s_mail."',
489 '');";
490 $i_is_accounted=false;
492 $i = 0;
494 $is_inserted_once = false;
496 // Entension entries Hint / Dial / Goto
497 foreach($newnums as $s_telenums){
499 if(!$is_inserted_once){
500 $is_inserted_once = true;
501 $EXT[$i]['context'] = 'GOsa';
502 $EXT[$i]['exten'] = $this->uid;
503 $EXT[$i]['priority']= 1;
504 $EXT[$i]['app'] = "Goto";
505 $EXT[$i]['appdata'] = $s_telenums."|1";
506 $i ++;
507 }
508 /* Hint Entry */
509 $EXT[$i]['context'] = 'GOsa';
510 $EXT[$i]['exten'] = $s_telenums;
511 $EXT[$i]['priority']= "Hint";
512 $EXT[$i]['app'] = 'SIP/'.$this->uid;
513 $i ++;
514 /* SetCID */
515 //$EXT[$i]['context'] = 'GOsa';
516 //$EXT[$i]['exten'] = $s_telenums;
517 //$EXT[$i]['priority']= 1;
518 //$EXT[$i]['app'] = "SetCIDName";
519 //$EXT[$i]['appdata'] = $CNname;
520 //$i ++;
522 // If no macro is selected use Dial
523 if($this->macro!="none"){
524 $macroname = preg_replace("/,.*$/","",$this->macro);
525 $macroname = preg_replace("/^.*=/","",$macroname);
526 $s_app = "Macro";$macroname;
527 $s_par = $macroname."|".$s_parameter;
528 }else{
529 $s_app = "Dial";
530 $s_par = 'SIP/'.$this->uid."|20|r";
531 }
533 $EXT[$i]['context'] = 'GOsa';
534 $EXT[$i]['exten'] = $s_telenums;
535 $EXT[$i]['priority']= 1;
536 $EXT[$i]['app'] = $s_app;
537 $EXT[$i]['appdata'] = $s_par;
538 $i ++;
540 }
542 // Append all these Entries
543 foreach($EXT as $entr){
544 $SQL_syn = "INSERT INTO ".$a_SETUP['EXT_TABLE']." (";
545 foreach($entr as $key2 => $val2){
546 $SQL_syn.= "`".$key2."`,";
547 }
548 $SQL_syn = preg_replace("/,$/","",$SQL_syn);
549 $SQL_syn .= ") VALUES (";
550 foreach($entr as $key2 => $val2){
551 $SQL_syn .= "'".$val2."',";
552 }
553 $SQL_syn = preg_replace("/,$/","",$SQL_syn);
554 $SQL_syn .=");\n";
555 $SQL[] =$SQL_syn;
556 $SQL_syn ="";
557 }
559 // Perform queries ...
560 foreach($SQL as $query){
561 if(!@mysql_query($query,$r_con)){
562 print_red(_("Error while performing query:")." ".mysql_error());
563 return false;
564 }
565 }
566 }
567 @mysql_close($r_con);
568 return true;
569 }
572 function execute()
573 {
574 /* Call parent execute */
575 plugin::execute();
577 $display = "";
579 if(empty($this->macro)&&(!empty($this->goFonMacro))){
581 /* Go through already saved values, for a parameter */
582 $tmp = split("!",$this->goFonMacro);
584 /* it is possible that nothing has been saved yet */
585 if(is_array($tmp)){
587 /* First value is the macroname */
588 $this->macro = $tmp[0];
590 /* Macroname saved, delete that index */
591 unset($tmp[0]);
593 /* Check if makro has been removed */
594 if(!isset($this->macroarray[$this->macro])){
595 $this->macrostillavailable = false;
596 }else{
597 $this->macrostillavailable = true;
598 }
600 /* for each parametervalues ( parameterID#value like 25#twentyfive) */
601 foreach($tmp as $var){
603 /* Split this, so we have $varar[0] = parameterID $varar[1] = SelectedValue */
604 $varar = split("#",$var);
606 /* Only insert if the parameter still exists */
607 if(isset($this->macroarray[$this->macro][$varar[0]])){
608 /* Assign value */
609 $this->macroarray[$this->macro][$varar[0]]['choosen']=$varar[1];
610 }
611 }
612 }
613 }
615 /* Do we represent a valid account? */
616 if (!$this->is_account && $this->parent == NULL){
617 $display= "<img alt=\"\" src=\"images/stop.png\" align=\"middle\"> <b>".
618 _("This account has no phone extensions.")."</b>";
619 $display.= back_to_main();
620 return ($display);
621 }
623 /* Do we need to flip is_account state? */
624 if (isset($_POST['modify_state'])){
625 $this->is_account= !$this->is_account;
626 }
628 /* Select no macro if, state is empty, this is the case, if the selected macro is no longer available */
629 if(empty($this->macro)){
630 $this->macro ="none";
631 }
633 /* Prepare templating */
634 $smarty= get_smarty();
636 /* tell user that the pluging selected is no longer available*/
637 if((!$this->macrostillavailable)&&($this->macro!="none")){
638 print_red(_("The macro you selected, is no longer available for you, please choose another one."));
639 }
641 /* Assing macroselectbox values */
642 $smarty->assign("macros",$this->macros);
643 $smarty->assign("macro", $this->macro);
645 /* check if there is a FON server created */
646 if(!isset($_SESSION['config']->data['SERVERS']['FON'])){
647 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."));
648 }
650 /* Create parameter table, skip if no parameters given */
651 if(!isset($this->macroarray[$this->macro])){
652 $macrotab="";
653 }else{
655 $macrotab ="<table summary=\""._("Parameter")."\">";
656 /* for every single parameter-> display textfile,combo, or true false switch*/
658 foreach($this->phoneNumbers as $phonenum){
659 $tmp[] = $phonenum;
660 }
664 if($this->macro != $this->lastmacro){
665 /* Go through all params */
666 foreach($this->macroarray[$this->macro] as $key => $paras){
668 $string = $paras['default'];
670 $string=preg_replace("/%uid/i",$this->uid,$string);
672 if(isset($this->cn)){
673 $string=preg_replace("/%cn/i",$this->cn,$string);
674 }
676 for($i = 0 ; $i < 10; $i++){
677 if(isset($tmp[$i])){
678 $string = preg_replace("/%telephoneNumber_".($i+1)."/i",$tmp[$i],$string);
679 }
680 }
681 if(isset($tmp[0])){
682 $string = preg_replace("/%telephoneNumber/i",$tmp[0],$string);
683 }
684 $this->macroarray[$this->macro][$key]['choosen']=$string;
685 }
686 }
688 foreach($this->macroarray[$this->macro] as $paras){
690 /* get al vars */
691 $var = $paras['var'];
692 $name = $paras['name'];
693 $default = $paras['default'];
694 $type = $paras['type'];
695 $choosen = $paras['choosen'] ;
696 $str = $default;
698 $dis = "";
699 if(!$this->acl_is_writeable("goFonMacro")){
700 $dis = " disabled ";
701 }
703 /* in case of a combo box display a combobox with selected attr */
704 $macrotab.= "<tr>";
705 switch ($type){
707 case "combo":
708 $str= "<select name='".$var."' ".chkacl($this->acl, "goFonMacro")." ".$dis.">";
709 foreach(split(":",$default) as $choice){
710 if($choosen==$choice){
711 $str.= "\n<option value='".$choice."' selected>".$choice." </option>";
712 }else{
713 $str.= "\n<option value='".$choice."'>".$choice." </option>";
714 }
715 }
716 $str.="</select>";
717 $macrotab.= "<td>".base64_decode($name)."</td><td>$str";
718 break;
720 case "bool":
721 if(!$choosen){
722 $str="\n<input type='checkbox' name='".$var."' value='1' ".chkacl($this->acl, "goFonMacro")." ".$dis.">";
723 }else{
724 $str="\n<input type='checkbox' name='".$var."' value='1' checked ".chkacl($this->acl, "goFonMacro")." ".$dis.">";
725 }
726 $macrotab.= "<td colspan='2'>$str ".base64_decode($name)."";
727 break;
729 case "string":
730 $str="<input name='".$var."' value='".$choosen."' ".chkacl($this->acl, "goFonMacro")." style='width:340px;' ".$dis.">";
731 $macrotab.= "<td>".base64_decode($name)."</td><td>$str";
732 break;
734 }
735 $macrotab.= "</td></tr>";
737 }
738 $macrotab.="</table><input name='post_success' type='hidden' value='1'>";
739 }//is_array()
741 /* Give smarty the table */
742 $smarty->assign("macrotab",$macrotab);
744 /* Do we represent a valid account? */
745 if (!$this->is_account && $this->parent == NULL){
746 $display= "<img alt=\"\" src=\"images/stop.png\" align=\"middle\"> <b>".
747 _("This account has no phone extensions.")."</b>";
748 $display.= back_to_main();
749 return($display);
750 }
752 $display= "";
754 /* Show tab dialog headers */
755 if ($this->parent != NULL){
756 if ($this->is_account){
757 $display= $this->show_disable_header(_("Remove phone account"),
758 _("This account has phone features enabled. You can disable them by clicking below."));
759 } else {
760 if(empty($this->uid)){
761 $display= $this->show_enable_header(_("Create phone account"),
762 _("This account has phone features disabled. You can't enable them while no uid is set."),TRUE,TRUE);
763 }else{
764 $display= $this->show_enable_header(_("Create phone account"),
765 _("This account has phone features disabled. You can enable them by clicking below."));
766 }
767 return ($display);
768 }
769 }
771 /* Add phone number */
772 if (isset($_POST["add_phonenumber"]) && $_POST['phonenumber']){
773 if (is_phone_nr($_POST['phonenumber'])){
774 $number= $_POST["phonenumber"];
775 $this->phoneNumbers[$number]= $number;
776 $this->is_modified= TRUE;
777 } else {
778 print_red(_("Please enter a valid phone number!"));
779 }
780 }
782 /* Remove phone number */
783 if (isset($_POST["delete_phonenumber"]) && isset($_POST["phonenumber_list"])){
784 foreach ($_POST['phonenumber_list'] as $number){
785 unset($this->phoneNumbers[$number]);
786 $this->is_modified= TRUE;
787 }
788 }
790 /* Transfer ACL's */
791 foreach($this->attributes as $val){
792 $smarty->assign($val."ACL",$this->getacl($val));
793 if(isset($this->$val)){
794 $smarty->assign($val,$this->$val);
795 }else{
796 $smarty->assign($val,"");
797 }
798 }
800 /* Fill arrays */
801 $smarty->assign ("goFonHardware", $this->goFonHardware);
802 if (!count($this->phoneNumbers)){
803 $smarty->assign ("phoneNumbers", array(""));
804 } else {
805 $smarty->assign ("phoneNumbers", $this->phoneNumbers);
806 }
809 $dis = "";
810 if(!$this->acl_is_writeable("goFonHardware")){
811 $dis= " disabled ";
812 }
813 $hl= "<select size=\"1\" name=\"goFonHardware\" ".$dis." title=\"".
814 _("Choose your private phone")." >\n";
815 foreach ($this->hardware_list as $cn => $description){
817 if ($cn == $this->goFonHardware){
818 $selected= "selected";
819 } else {
820 $selected= "";
821 }
823 if (isset($this->used_hardware[$cn])){
824 $color= "style=\"color:#A0A0A0\"";
825 } else {
826 $color= "";
827 }
828 $hl.= " <option $color label=\"$cn\" value=\"$cn\" $selected>$description </option>\n";
829 }
830 $hl.= "</select>\n";
831 $smarty->assign ("hardware_list", $hl);
833 /* Show main page */
834 $this->lastmacro = $this->macro;
835 $display.= $smarty->fetch(get_template_path('generic.tpl', TRUE, dirname(__FILE__)));
836 return($display);
837 }
840 function save_object()
841 {
842 if (isset($_POST["phoneTab"])){
843 plugin::save_object();
845 /* Every macro in the select box are available */
846 if((isset($_POST['macro']))){
847 $this->macrostillavailable=true;
848 }
850 if(is_array($this->phoneNumbers)){
851 foreach($this->phoneNumbers as $telenumms) {
852 $nummsinorder[]=$telenumms;
853 }
854 }else{
855 $nummsinorder=array("");
856 }
858 /* get all Postvars */
859 if(isset($this->macroarray[$this->macro])){
860 if($this->acl_is_writeable("goFonMarco")){
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 }
883 }
885 function check()
886 {
887 /* Call common method to give check the hook */
888 $message= plugin::check();
890 if((strlen($this->goFonVoicemailPIN)==0)||(strlen($this->goFonVoicemailPIN)>4)){
891 $message[]=(_("Voicemail PIN must be between 1-4 characters."));
892 }else{
893 if(preg_match("/[^0-9]/",$this->goFonVoicemailPIN)){
894 $message[]=(_("The specified Voicemail PIN contains invalid characters, only numeric values are allowed here."));
895 }
896 }
898 if((strlen($this->goFonPIN)<=0)){
899 $message[]=(_("Phone PIN must be at least one character long."));
900 }else{
901 if(preg_match("/[^0-9a-z]/i",$this->goFonPIN)){
902 $message[]=(_("The specified phone PIN contains invalid characters, only aphanumeric values are allowed here."));
903 }
904 }
906 if(!$this->generate_mysql_entension_entries()){
907 $message[] = $this->generate_error;
908 }
910 /* We need at least one phone number */
911 if (count($this->phoneNumbers) == 0){
912 $message[]= sprintf(_("You need to specify at least one phone number!"));
913 }
915 /* check for ! in any parameter setting*/
916 if(isset($this->macroarray[$this->macro])){
917 foreach($this->macroarray[$this->macro] as $val){
918 if((strstr($val['choosen'],"!"))||(strstr($val['choosen'],"#"))){
919 $message[] = sprintf(_("The parameter %s contains invalid char. '!,#' is used as delimiter"),$val['name']);
920 }
921 }
922 }
923 return ($message);
924 }
928 function save()
929 {
930 plugin::save();
932 /* Save arrays */
933 $this->attrs['telephoneNumber']= array();
934 foreach ($this->phoneNumbers as $number){
935 $this->attrs['telephoneNumber'][]= $number;
936 }
938 /* Save settings, or remove goFonMacro attribute*/
939 if($this->macro!="none"){
940 $this->attrs['goFonMacro']=$this->macro;
941 if(isset($this->macroarray[$this->macro])){
942 foreach($this->macroarray[$this->macro] as $paras) {
943 $this->attrs['goFonMacro'].="!".$paras['id']."#".$paras['choosen'];
944 }
945 }
946 }else{
947 $this->attrs['goFonMacro']=array();
948 }
949 unset($this->attrs['macro']) ;
951 $this->attrs['goFonForwarding']=array();
953 $this->generate_mysql_entension_entries(true);
955 if($this->attrs['goFonMacro']==""){
956 $this->attrs['goFonMacro']=array();
957 }
959 unset($this->attrs['cn']);
961 /* Write back to ldap */
962 $ldap= $this->config->get_ldap_link();
963 $ldap->cd($this->dn);
964 $this->cleanup();
965 $ldap->modify ($this->attrs);
967 show_ldap_error($ldap->get_error(), sprintf(_("Saving of user/phone account with dn '%s' failed."),$this->dn));
969 /* Optionally execute a command after we're done */
971 if ($this->initially_was_account == $this->is_account){
972 if ($this->is_modified){
973 $this->handle_post_events("modify");
974 }
975 } else {
976 $this->handle_post_events("add");
977 }
979 }
982 function insert_after($entry, $nr, $list)
983 {
984 /* Is the entry free? No? Make it free... */
985 if (isset($list[$nr])) {
986 $dest= array();
987 $newidx= 0;
989 foreach ($list as $idx => $contents){
990 $dest[$newidx++]= $contents;
991 if ($idx == $nr){
992 $dest[$newidx++]= $entry;
993 }
994 }
995 } else {
996 $dest= $list;
997 $dest[$nr]= $entry;
998 }
1000 return ($dest);
1001 }
1004 function adapt_from_template($dn)
1005 {
1006 plugin::adapt_from_template($dn);
1008 /* Assemble phone numbers */
1009 if (isset($this->attrs['telephoneNumber'])){
1010 for ($i= 0; $i<$this->attrs['telephoneNumber']['count']; $i++){
1011 $number= $this->attrs['telephoneNumber'][$i];
1012 $this->phoneNumbers[$number]= $number;
1013 }
1014 }
1015 }
1018 function remove_from_parent()
1019 {
1020 if(!$this->initially_was_account) return;
1022 foreach($this->attributes as $key=>$val){
1023 if(in_array($val,array("uid","cn"))){
1024 unset($this->attributes[$key]);
1025 unset($this->$val);
1026 }
1027 }
1028 if(array_key_exists('config', $_SESSION) &&
1029 array_key_exists('SERVERS', $_SESSION['config']->data) &&
1030 array_key_exists('FON', $_SESSION['config']->data['SERVERS']) &&
1031 is_callable("mysql_pconnect")) {
1032 // Get Configuration for Mysql database Server
1033 $a_SETUP = $_SESSION['config']->data['SERVERS']['FON'];
1034 $s_parameter ="";
1036 // Connect to DB server
1037 $r_con = @mysql_pconnect($a_SETUP['SERVER'],$a_SETUP['LOGIN'],$a_SETUP['PASSWORD']);
1039 // Check if we are connected correctly
1040 if(!$r_con){
1041 print_red(sprintf(_("The MySQL Server '%s' isn't reachable as user '%s', check GOsa log for mysql error."),
1042 $a_SETUP['SERVER'],$a_SETUP['LOGIN']));
1043 gosa_log(@mysql_error());
1044 return false;
1045 }
1047 // Select database for Extensions
1048 $db = @mysql_select_db($a_SETUP['DB'],$r_con);
1050 // Test if we have the database selected correctly
1051 if(!$db){
1052 print_red(sprintf(_("Can't select database %s on %s."),$a_SETUP['DB'],$a_SETUP['SERVER']));
1053 gosa_log(@mysql_error());
1054 return false;
1055 }
1057 $SQL="";
1059 /* If deletion starts from userslist, cn uid are not set */
1060 if((isset($this->parent->by_object['user']->uid))&&(!empty($this->parent->by_object['user']->uid))){
1061 $this->uid = $this->parent->by_object['user']->uid;
1062 }
1064 if((isset($this->parent->by_object['user']->cn))&&(!empty($this->parent->by_object['user']->cn))){
1065 $this->cn = $this->parent->by_object['user']->cn;
1066 }
1068 $first_num = false;
1069 // Delete old entries
1070 foreach($this->a_old_telenums as $s_telenums){
1071 if(!$first_num){
1072 $first_num = $s_telenums;
1073 }
1074 $SQL[] = "DELETE FROM ".$a_SETUP['EXT_TABLE']." WHERE exten='".$s_telenums."';\n";
1075 }
1077 $SQL[] = "DELETE FROM ".$a_SETUP['VOICE_TABLE']." WHERE customer_id='".$first_num."';";
1078 $SQL[] = "DELETE FROM ".$a_SETUP['EXT_TABLE']." WHERE exten='".$this->uid."';\n";
1079 $SQL[] = "DELETE FROM ".$a_SETUP['SIP_TABLE']." WHERE name='".$this->uid."';\n";
1081 foreach($SQL as $query){
1082 if(!@mysql_query($query,$r_con)){
1083 print_red(_("Stop".mysql_error()));
1084 return false;
1085 }
1086 }
1087 }else{
1088 print_red(_("Can't remove phone account, the mysql extension is not present in php configuration."));
1089 return false;
1090 }
1092 /* unset macro attr, it will cause an error */
1093 $tmp = array_flip($this->attributes);
1094 unset($tmp['macro']);
1095 $this->attributes=array_flip($tmp);
1097 /* Cancel if there's nothing to do here */
1098 if (!$this->initially_was_account){
1099 return;
1100 }
1102 plugin::remove_from_parent();
1104 /* Just keep one phone number */
1105 if (count($this->telephoneNumber) && $this->telephoneNumber != ""){
1106 $this->attrs['telephoneNumber']= $this->telephoneNumber;
1107 } else {
1108 $this->attrs['telephoneNumber']= array();
1109 }
1112 $ldap= $this->config->get_ldap_link();
1113 $ldap->cd($this->config->current['BASE']);
1114 $ldap->search("(objectClass=goFonQueue)", array("member"));
1115 while($attr = $ldap->fetch()){
1116 if(in_array($this->dn,$attr['member'])){
1117 $new =new ogrouptabs($this->config, $this->config->data['TABS']['OGROUPTABS'],$attr['dn']);
1118 unset($new->by_object['ogroup']->memberList[$this->dn]);
1119 unset($new->by_object['ogroup']->member[$this->dn]);
1120 $new->save();
1121 print_red(sprintf(_("Removed user '%s' from phone queue '%s'."),$this->uid,$new->by_object['ogroup']->attrs['cn']));
1122 }
1123 }
1124 $ldap->cd($this->dn);
1125 $this->cleanup();
1126 $ldap->modify ($this->attrs);
1128 show_ldap_error($ldap->get_error(), sprintf(_("Removing of user/phone account with dn '%s' failed."),$this->dn));
1130 /* Optionally execute a command after we're done */
1131 @mysql_close($r_con);
1132 $this->handle_post_events('remove');
1133 }
1137 /* This function checks if the given phonenumbers are available or already in use*/
1138 function is_number_used()
1139 {
1140 $ldap= $this->config->get_ldap_link();
1141 $ldap->cd($this->config->current['BASE']);
1142 $ldap->search("(|(objectClass=goFonAccount)(objectClass=goFonQueue)(objectClass=goFonConference))", array("telephoneNumber","cn","uid"));
1143 while($attrs = $ldap->fetch()) {
1144 unset($attrs['telephoneNumber']['count']);
1145 foreach($attrs['telephoneNumber'] as $tele){
1146 if(!isset($attrs['cn'][0])) $attrs['cn'][0]=$attrs['dn'];
1147 if(!isset($attrs['uid'][0])) $attrs['uid'][0]=$attrs['dn'];
1148 $numbers[$tele]=$attrs;
1149 }
1150 }
1152 foreach($this->phoneNumbers as $num){
1153 if(!isset($this->cn)) $this->cn = "";
1155 if((isset($numbers[$num]))&&(($numbers[$num]['uid'][0]!=$this->uid))){
1156 if(isset($numbers[$num]['uid'][0])){
1157 return sprintf(_("The specified telephonenumber '%s' is already assigned to '%s'."),$num,$numbers[$num]['uid'][0]);
1158 }else{
1159 return sprintf(_("The specified telephonenumber '%s' is already assigned to '%s'."),$num,$numbers[$num]['cn'][0]);
1160 }
1161 }
1162 }
1163 }
1166 /* Create phoneAccount part of copy & paste dialog */
1167 function getCopyDialog()
1168 {
1169 if(!$this->is_account) return("");
1170 $smarty = get_smarty();
1171 if (!count($this->phoneNumbers)){
1172 $smarty->assign ("phoneNumbers", array(""));
1173 } else {
1174 $smarty->assign ("phoneNumbers", $this->phoneNumbers);
1175 }
1177 $smarty->assign("goFonVoicemailPIN",$this->goFonVoicemailPIN);
1178 $smarty->assign("goFonPIN",$this->goFonPIN);
1180 $display= $smarty->fetch(get_template_path('paste_generic.tpl', TRUE, dirname(__FILE__)));
1181 $ret =array();
1182 $ret['string'] = $display;
1183 $ret['status'] = "";
1184 return($ret);
1185 }
1187 /* Save posts from copy & paste dialog dialog */
1188 function saveCopyDialog()
1189 {
1190 if(!$this->is_account) return;
1191 $this->execute();
1192 if(isset($_POST['goFonVoicemailPIN'])) {
1193 $this->goFonVoicemailPIN = $_POST['goFonVoicemailPIN'];
1194 }
1195 if(isset($_POST['goFonPIN'])){
1196 $this->goFonPIN = $_POST['goFonPIN'];
1197 }
1198 }
1201 /* Return plugin informations for acl handling */
1202 function plInfo()
1203 {
1204 return (array(
1205 "plShortName" => _("Phone"),
1206 "plDescription" => _("Phone account settings"),
1207 "plSelfModify" => TRUE,
1208 "plDepends" => array("user"),
1209 "plPriority" => 7, // Position in tabs
1210 "plSection" => "personal", // This belongs to personal
1211 "plCategory" => array("users"),
1212 "plOptions" => array(),
1214 "plProvidedAcls" => array(
1215 "telephoneNumber" => _("Telephone number"),
1216 "goFonMacro" => _("Macro settings"),
1217 "goFonHardware" => _("Phone hardware"),
1218 "goFonPIN" => _("Telephone pin"),
1219 "goFonVoicemailPIN" => _("Voicemail pin"))
1220 ));
1221 }
1222 }
1224 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1225 ?>