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","macroarray","macrostillavailable"/*"phoneNumbers" -Reset- */,
38 "hardware_list","used_hardware");
40 var $attributes = array("goFonDeliveryMode", "goFonFormat","uid","cn",
41 "goFonHardware","goFonPIN","goFonVoicemailPIN",
42 "telephoneNumber", "goFonMacro","macro");
43 var $objectclasses= array("goFonAccount");
45 var $uid ="";
47 function phoneAccount ($config, $dn= NULL, $parent= NULL)
48 {
49 plugin::plugin ($config, $dn, $parent);
51 /* Set uid, it is used in handle_post_events */
52 if(isset($this->attrs['uid'])){
53 $this->uid = $this->attrs['uid'][0];
54 }
56 /* Set phone hardware */
57 if (!isset($this->attrs['goFonHardware'])){
58 $this->goFonHardware= "automatic";
59 }
61 /* Preset voice format */
62 if (!isset($this->attrs['goFonFormat'])){
63 $this->goFonFormat= "wav";
64 }
66 /* Assemble phone numbers */
67 if (isset($this->attrs['telephoneNumber'])){
68 for ($i= 0; $i<$this->attrs['telephoneNumber']['count']; $i++){
69 $number= $this->attrs['telephoneNumber'][$i];
70 $this->phoneNumbers[$number]= $number;
71 }
72 }
74 /* Set up has_mailAccount */
75 if (isset($this->attrs['objectClass'])){
76 if (in_array("gosaMailAccount", $this->attrs['objectClass'])){
77 $this->has_mailAccount= TRUE;
78 }
79 }
81 $a_SETUP= array();
82 if(array_key_exists('config',$_SESSION) &&
83 array_key_exists('SERVERS',$_SESSION['config']->data) &&
84 array_key_exists('FON',$_SESSION['config']->data['SERVERS']) &&
85 is_callable("mysql_connect")
86 ) {
87 $a_SETUP = $_SESSION['config']->data['SERVERS']['FON'];
88 $r_con = @mysql_pconnect($a_SETUP['SERVER'],$a_SETUP['LOGIN'],$a_SETUP['PASSWORD']);
89 if(!$r_con){
90 $this->generate_error = sprintf(_("The MySQL Server '%s' isn't reachable as user '%s', check GOsa log for mysql error."),
91 $a_SETUP['SERVER'],$a_SETUP['LOGIN']);
92 gosa_log(mysql_error());
93 return false;
94 }
95 $db = @mysql_select_db($a_SETUP['DB'],$r_con);
96 if(!$db){
97 $this->generate_error = sprintf(_("Can't select database %s on %s."),$a_SETUP['DB'],$a_SETUP['SERVER']);
98 gosa_log(mysql_error());
99 return false;
100 }
102 $first = false;
103 foreach($this->phoneNumbers as $key => $val){
104 if(!$first){
105 $first = $key;
106 }
107 }
108 }
110 /* Load hardware list */
111 $ldap= $this->config->get_ldap_link();
112 $ldap->cd($this->config->current['BASE']);
113 $ldap->search("(objectClass=goFonHardware)", array('cn', 'description'));
114 while ($attrs= $ldap->fetch()){
115 $cn= $attrs['cn'][0];
116 if (isset($attrs['description'])){
117 $description= " - ".$attrs['description'][0];
118 } else {
119 $description= "";
120 }
121 $this->hardware_list[$cn]= "$cn$description";
123 }
125 /* Perform search, to get Macro Parameters,Name,Dn,Displayname etc*/
126 $ldap->search("(objectClass=goFonMacro)", array("*"));
128 /* Add none for no macro*/
129 $this->macros['none']=_("no macro");
130 $this->macro ="none";
133 /* Fetch all Macros*/
134 while ($attrs= $ldap->fetch()){
136 /* Only visisble */
137 if((isset($attrs['goFonMacroVisible'][0]))&&($attrs['goFonMacroVisible'][0] ==1)){
139 /* unset Count, we don't need that here */
140 unset($attrs['displayName']['count']);
142 /* fill Selectfield variable with Macros */
143 if(isset($attrs['displayName'][0])){
144 $this->macros[$attrs['dn']] = $attrs['displayName'][0]." (".$attrs['cn'][0].")";
145 }else{
146 $this->macros[$attrs['dn']] = _("undefined");
147 }
149 /* Parse macro data, unset count for parameterarrays */
150 if (isset($attrs['goFonMacroParameter']['count'])){
151 unset($attrs['goFonMacroParameter']['count']);
152 }
154 /* Go through available parameters and parse all attributes, like parametername, type, default ...*/
155 if((isset($attrs['goFonMacroParameter']))&&(is_array($attrs['goFonMacroParameter']))){
157 foreach($attrs['goFonMacroParameter'] as $pkey=>$pval){
158 /* Split Data in readable values, by delimiter ! */
159 $data = split("!",$attrs['goFonMacroParameter'][$pkey]);
161 /* Set all attrs */
162 $id = $data[0];
163 $this->macroarray[$attrs['dn']][$id]['var'] ="var".$id;
164 $this->macroarray[$attrs['dn']][$id]['choosen']=$data[3];
165 $this->macroarray[$attrs['dn']][$id]['id'] =$id;
166 $this->macroarray[$attrs['dn']][$id]['name'] =$data[1];
167 $this->macroarray[$attrs['dn']][$id]['type'] =$data[2];
168 $this->macroarray[$attrs['dn']][$id]['default']=$data[3];
169 if($data[2] == "bool"){
170 $this->macroarray[$attrs['dn']][$id]['choosen']=$data[3];
171 }
172 }//foreach
173 }//is_array
174 }//visible = 1
175 }//while
177 /* Go through already saved values, for a parameter */
178 $tmp = split("!",$this->goFonMacro);
180 /* it is possible that nothing has been saved yet */
181 if(is_array($tmp)){
183 /* First value is the macroname */
184 $this->macro = $tmp[0];
186 /* Macroname saved, delete that index */
187 unset($tmp[0]);
189 /* Check if makro has been removed */
190 if(!isset($this->macroarray[$this->macro])){
191 $this->macrostillavailable = false;
192 }else{
193 $this->macrostillavailable = true;
194 }
196 /* for each parametervalues ( parameterID#value like 25#twentyfive) */
197 foreach($tmp as $var){
199 /* Split this, so we have $varar[0] = parameterID $varar[1] = SelectedValue */
200 $varar = split("#",$var);
202 /* Only insert if the parameter still exists */
203 if(isset($this->macroarray[$this->macro][$varar[0]])){
204 /* Assign value */
205 $this->macroarray[$this->macro][$varar[0]]['choosen']=$varar[1];
206 }
207 }
208 }
211 /* Eventually colorize phones */
212 $ldap->cd($this->config->current['BASE']);
213 foreach ($this->hardware_list as $cn => $desc){
214 $ldap->search("(goFonHardware=$cn)", array('cn'));
215 if ($ldap->count() > 0){
216 $ldap->fetch();
217 if ($ldap->getDN() != $this->dn){
218 $this->used_hardware[$cn]= $ldap->getDN();
219 }
220 }
221 }
222 $this->hardware_list["automatic"]= _("automatic");
223 ksort($this->hardware_list);
224 $this->a_old_telenums = $this->phoneNumbers;
226 if($this->is_account){
227 $this->is_modified = true;
228 }
231 /* Get voicemail PIN from MySQL DB
232 * Because every user can change his PIN directly from the phone
233 * without any update to the ldap
234 * This means, the PIN in the DB is up to date
235 */
236 // Connect to DB server
237 if((is_callable("mysql_pconnect"))&&(isset($a_SETUP))&&(isset($a_SETUP['SERVER']))&&(isset($a_SETUP['LOGIN']))&&(isset($a_SETUP['PASSWORD']))){
238 $r_con = @mysql_pconnect($a_SETUP['SERVER'],$a_SETUP['LOGIN'],$a_SETUP['PASSWORD']);
239 if($r_con){
240 $r_db = @mysql_select_db($a_SETUP['DB'],$r_con);
241 $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."'"));
243 if((isset($vp[0]))&&(!empty($vp[0]))){
244 $this->goFonPINVoice = $vp[0];
245 }
246 }
247 }
248 $this->lastmacro=$this->macro;
250 if(is_callable("mysql_close")&&(isset($r_con))&&($r_con)){
251 @mysql_close($r_con) ;
252 }
253 }
256 // Generate MySQL Syntax
257 function generate_mysql_entension_entries($save = false){
259 if(!isset($_SESSION['config']->data['SERVERS']['FON'])){
260 if($save)
261 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."));
262 return(true);
263 }
265 if(!is_callable("mysql_pconnect")){
266 if($save)
267 print_red(_("Can't save any changes to asterisk database, there is no mysql extension available."));
268 return(true);
269 }
271 // Get Configuration for Mysql database Server
272 $a_SETUP = $_SESSION['config']->data['SERVERS']['FON']; // DB Configuration
273 $s_parameter = ""; // Contains paramter for selected Macro
274 $r_con = false; // DB connection
275 $r_db = false; // Selected DB
276 $r_res = false; // Result resource
277 $a_ldap_attrs = array(); //
279 $s_ip = NULL; // Contains ip for Sip entry
280 $s_host = NULL; // Contains host for Sip entry
281 $s_qualify = "yes"; // Qualify entry
282 $s_pin = NULL; // Entry for secret
283 $s_type = NULL; // Entry for phone type (friend , peer ..)
285 $sip_data_array = array(); // Contains complete sip entry, to generate SQL syntax
286 $i_old_key = false; // Contains index for first old phonenumber, to delete old entries corectly
287 $i_new_key = false; // Contains index for first new phonenumber, to generate new entries corectly
289 $s_sip_values = ""; // Contains string with all values for given attributes in SQL syntax
290 $s_sip_keys = ""; // Contains all needed attributes to generate sip entry in DB
292 $s_sip_key = ""; // Key for SIP entry index
293 $s_sip_val = ""; // Value for SIP entry index
295 $b_first_deleted= false; // Only delete first entry,
296 $s_telenums = ""; // for each value variable
298 $i_is_accounted = false; // Ensure that extension entry, for name to number is only once in table
301 // Connect to DB server
302 $r_con = @mysql_pconnect($a_SETUP['SERVER'],$a_SETUP['LOGIN'],$a_SETUP['PASSWORD']);
304 // Check if we are connected correctly
305 if(!$r_con){
306 $this->generate_error = sprintf(_("The MySQL Server '%s' isn't reachable as user '%s', check GOsa log for mysql error."),
307 $a_SETUP['SERVER'],$a_SETUP['LOGIN']);
308 gosa_log(mysql_error());
309 return false;
310 }
312 // Select database for Extensions
313 $r_db = @mysql_select_db($a_SETUP['DB'],$r_con);
315 // Test if we have the database selected correctly
316 if(!$r_db){
317 $this->generate_error = sprintf(_("Can't select database %s on %s."),$a_SETUP['DB'],$a_SETUP['SERVER']);
318 gosa_log(mysql_error());
319 return false;
320 }
322 // Get phonehardware to setup sip entry
323 $ldap = $this->config->get_ldap_link();
324 $r_res = $ldap->search("(&(objectClass=goFonHardware)(cn=".$this->goFonHardware."))", array('*'));
325 $a_ldap_attrs = $ldap->fetch();
327 if($this->is_number_used()){
328 $this->generate_error = $this->is_number_used();
329 return false;
330 }
332 /* If Save == true, we should save something.
333 * Generate SQL, for drop of old entries
334 * Generate SQL, for insert new entries
335 */
336 if($save == true){
338 foreach($this->a_old_telenums as $tele){
339 $oldnums[]= preg_replace("/[^0-9]/","",$tele);
340 }
342 foreach($this->phoneNumbers as $tele){
343 $newnums[]= preg_replace("/[^0-9]/","",$tele);
344 }
346 // Attribute GoFonDefaultIP set ?
347 if(((isset($a_ldap_attrs['goFonDefaultIP'][0]))&&($a_ldap_attrs['goFonDefaultIP'][0] != "dynamic"))){
348 $s_ip = $a_ldap_attrs['goFonDefaultIP'][0];
349 $s_host = $s_ip;
350 }else{
351 $s_ip = NULL;
352 $s_host = "dynamic";
353 }
355 // Attribute GoFonQualify set ?
356 if(isset($a_ldap_attrs['goFonQualify'])){
357 $s_qualify = $a_ldap_attrs['goFonQualify'][0];
358 }
360 // Attribute GoFonPIN set ?
361 if(isset($this->goFonPIN)){
362 $s_pin = $this->goFonPIN;
363 }
365 // Attribute GoFonType set ?
366 if(isset($a_ldap_attrs['goFonType'])){
367 $s_type = $a_ldap_attrs['goFonType'][0];
368 }
370 if(isset($a_ldap_attrs['goFonDmtfMode'][0])){
371 $sip_data_array['dtmfmode'] = $a_ldap_attrs['goFonDmtfMode'][0];
372 }else{
373 $sip_data_array['dtmfmode'] ="rfc2833";
374 }
376 // generate SIP entry
377 $sip_data_array['id'] = "";
378 $sip_data_array['name'] = $this->uid;
379 $sip_data_array['accountcode'] = NULL;
380 $sip_data_array['amaflags'] = NULL;
381 $sip_data_array['callgroup'] = NULL;
382 $sip_data_array['callerid'] = "";
383 $sip_data_array['canreinvite'] = "no";
384 $sip_data_array['context'] = "default";
385 $sip_data_array['defaultip'] = NULL;
386 $sip_data_array['fromuser'] = NULL;
387 $sip_data_array['fromdomain'] = NULL;
388 $sip_data_array['host'] = $s_host;
389 $sip_data_array['insecure'] = NULL;
390 $sip_data_array['language'] = NULL;
391 $sip_data_array['mailbox'] = "asterisk";
392 $sip_data_array['md5secret'] = NULL;
393 $sip_data_array['nat'] = "no";
394 $sip_data_array['permit'] = NULL;
395 $sip_data_array['deny'] = NULL;
396 $sip_data_array['mask'] = NULL;
397 $sip_data_array['pickupgroup'] = NULL;
398 $sip_data_array['port'] = NULL;
399 $sip_data_array['qualify'] = $s_qualify;
400 $sip_data_array['restrictcid'] = "n";
401 $sip_data_array['rtptimeout'] = NULL;
402 $sip_data_array['rtpholdtimeout']=NULL;
403 $sip_data_array['secret'] = $this->goFonPIN;
404 $sip_data_array['type'] = $s_type ;
405 $sip_data_array['username'] = $this->uid;
406 $sip_data_array['disallow'] = NULL;
407 $sip_data_array['allow'] = NULL;
408 $sip_data_array['musiconhold'] = NULL;
409 $sip_data_array['regseconds'] = NULL;
410 $sip_data_array['ipaddr'] = $s_ip;
411 $sip_data_array['regexten'] = NULL;
412 $sip_data_array['cancallforward']=NULL;
414 // Get selected Macro Parameter and create parameter entry
415 if(isset($this->macroarray[$this->macro])){
416 foreach($this->macroarray[$this->macro] as $key => $val ){
417 $s_parameter .= $val['choosen']."|";
418 }
419 $s_parameter = preg_replace("/\|$/","",$s_parameter);
420 }
422 if($this->is_number_used()){
423 $this->generate_error = $this->is_number_used();
424 return false;
425 }
427 // Create new SIP entry ...
428 $sip_entry = $sip_data_array;
429 reset($newnums);
430 $i_new_key = key($newnums);
431 $sip_entry['callerid'] =$newnums[$i_new_key];
432 $sip_entry['mailbox'] =$newnums[$i_new_key];
434 if((isset($this->parent))&&(isset($this->parent->by_object['mailAccount']))&&($this->parent->by_object['mailAccount']->is_account==true)){
435 $s_mail = $this->parent->by_object['mailAccount']->mail;
436 }else{
437 $s_mail = "";
438 }
440 // $SQL contains all queries
441 $SQL = array();
442 $SQL[] = "DELETE FROM ".$a_SETUP['EXT_TABLE']." WHERE exten='".$this->uid."';\n";
443 $SQL[] = "DELETE FROM ".$a_SETUP['SIP_TABLE']." WHERE name='".$this->uid."';\n";
444 $SQL[] = "DELETE FROM ".$a_SETUP['VOICE_TABLE']." WHERE customer_id=".$newnums[$i_new_key].";";
445 // Delete old entries
446 $b_first_deleted =false;
447 if(isset($oldnums) && is_array($oldnums)){
448 foreach($oldnums as $s_telenums){
449 $SQL[] = "DELETE FROM ".$a_SETUP['EXT_TABLE']." WHERE exten='".$s_telenums."';\n";
450 if(!$b_first_deleted){
451 $b_first_deleted=true;
452 $SQL[] = "DELETE FROM ".$a_SETUP['VOICE_TABLE']." WHERE customer_id=".$s_telenums.";";
453 }
454 }
455 }
456 if($this->goFonHardware=="automatic"){
457 foreach($SQL as $query ){
458 mysql_query($query) ;
459 }
460 return;
461 }
463 // Generate Strings with keys and values
464 foreach($sip_entry as $s_sip_key=>$s_sip_val){
465 if($s_sip_val == NULL) continue;
466 $s_sip_values.="'".$s_sip_val."',";
467 $s_sip_keys .="`".$s_sip_key."`,";
468 }
469 // Remove last ,
470 $s_sip_values = preg_replace("/,$/","",$s_sip_values);
471 $s_sip_keys = preg_replace("/,$/","",$s_sip_keys);
473 // Append SIP Entry
474 $SQL[] ="INSERT INTO ".$a_SETUP['SIP_TABLE']." (".$s_sip_keys.") VALUES (".$s_sip_values.");";
476 /* If deletion starts from userslist, cn uid are not set */
477 if((isset($this->parent->by_object['user']->uid))&&(!empty($this->parent->by_object['user']->uid))){
478 $this->uid = $this->parent->by_object['user']->uid;
479 }
481 if((isset($this->parent->by_object['user']->cn))&&(!empty($this->parent->by_object['user']->cn))){
482 $this->cn = $this->parent->by_object['user']->cn;
483 }
485 if((!isset($this->cn))||(empty($this->cn))){
486 $CNname= $this->uid;
487 }else{
488 $CNname= $this->cn;
489 }
491 $SQL[]= "INSERT INTO ".$a_SETUP['VOICE_TABLE']." (`customer_id`,`context`,`mailbox`,`password`,`fullname`,`email`,`pager`)
492 VALUES ('".$newnums[$i_new_key]."',
493 'default',
494 '".$newnums[$i_new_key]."',
495 '".$this->goFonVoicemailPIN."',
496 '".$CNname."',
497 '".$s_mail."',
498 '');";
499 $i_is_accounted=false;
501 $i = 0;
503 $is_inserted_once = false;
505 // Entension entries Hint / Dial / Goto
506 foreach($newnums as $s_telenums){
508 if(!$is_inserted_once){
509 $is_inserted_once = true;
510 $EXT[$i]['context'] = 'GOsa';
511 $EXT[$i]['exten'] = $this->uid;
512 $EXT[$i]['priority']= 1;
513 $EXT[$i]['app'] = "Goto";
514 $EXT[$i]['appdata'] = $s_telenums."|1";
515 $i ++;
516 }
517 /* Hint Entry */
518 $EXT[$i]['context'] = 'GOsa';
519 $EXT[$i]['exten'] = $s_telenums;
520 $EXT[$i]['priority']= "Hint";
521 $EXT[$i]['app'] = 'SIP/'.$this->uid;
522 $i ++;
523 /* SetCID */
524 //$EXT[$i]['context'] = 'GOsa';
525 //$EXT[$i]['exten'] = $s_telenums;
526 //$EXT[$i]['priority']= 1;
527 //$EXT[$i]['app'] = "SetCIDName";
528 //$EXT[$i]['appdata'] = $CNname;
529 //$i ++;
531 // If no macro is selected use Dial
532 if($this->macro!="none"){
533 $macroname = preg_replace("/,.*$/","",$this->macro);
534 $macroname = preg_replace("/^.*=/","",$macroname);
535 $s_app = "Macro";$macroname;
536 $s_par = $macroname."|".$s_parameter;
537 }else{
538 $s_app = "Dial";
539 $s_par = 'SIP/'.$this->uid."|20|r";
540 }
542 $EXT[$i]['context'] = 'GOsa';
543 $EXT[$i]['exten'] = $s_telenums;
544 $EXT[$i]['priority']= 1;
545 $EXT[$i]['app'] = $s_app;
546 $EXT[$i]['appdata'] = $s_par;
547 $i ++;
549 }
551 // Append all these Entries
552 foreach($EXT as $entr){
553 $SQL_syn = "INSERT INTO ".$a_SETUP['EXT_TABLE']." (";
554 foreach($entr as $key2 => $val2){
555 $SQL_syn.= "`".$key2."`,";
556 }
557 $SQL_syn = preg_replace("/,$/","",$SQL_syn);
558 $SQL_syn .= ") VALUES (";
559 foreach($entr as $key2 => $val2){
560 $SQL_syn .= "'".$val2."',";
561 }
562 $SQL_syn = preg_replace("/,$/","",$SQL_syn);
563 $SQL_syn .=");\n";
564 $SQL[] =$SQL_syn;
565 $SQL_syn ="";
566 }
568 // Perform queries ...
569 foreach($SQL as $query){
570 if(!@mysql_query($query,$r_con)){
571 print_red(_("Error while performing query:")." ".mysql_error());
572 return false;
573 }
574 }
575 }
576 @mysql_close($r_con);
577 return true;
578 }
581 function execute()
582 {
583 /* Call parent execute */
584 plugin::execute();
586 $display = "";
588 $SkipWrite = (!isset($this->parent) || !$this->parent) && !isset($_SESSION['edit']);
590 if(empty($this->macro)&&(!empty($this->goFonMacro))){
592 /* Go through already saved values, for a parameter */
593 $tmp = split("!",$this->goFonMacro);
595 /* it is possible that nothing has been saved yet */
596 if(is_array($tmp)){
598 /* First value is the macroname */
599 $this->macro = $tmp[0];
601 /* Macroname saved, delete that index */
602 unset($tmp[0]);
604 /* Check if makro has been removed */
605 if(!isset($this->macroarray[$this->macro])){
606 $this->macrostillavailable = false;
607 }else{
608 $this->macrostillavailable = true;
609 }
611 /* for each parametervalues ( parameterID#value like 25#twentyfive) */
612 foreach($tmp as $var){
614 /* Split this, so we have $varar[0] = parameterID $varar[1] = SelectedValue */
615 $varar = split("#",$var);
617 /* Only insert if the parameter still exists */
618 if(isset($this->macroarray[$this->macro][$varar[0]])){
619 /* Assign value */
620 $this->macroarray[$this->macro][$varar[0]]['choosen']=$varar[1];
621 }
622 }
623 }
624 }
626 /* Do we represent a valid account? */
627 if (!$this->is_account && $this->parent == NULL){
628 $display= "<img alt=\"\" src=\"images/stop.png\" align=\"middle\"> <b>".
629 _("This account has no phone extensions.")."</b>";
630 $display.= back_to_main();
631 return ($display);
632 }
634 /* Do we need to flip is_account state? */
635 if (isset($_POST['modify_state'])){
636 $this->is_account= !$this->is_account;
637 }
639 /* Select no macro if, state is empty, this is the case, if the selected macro is no longer available */
640 if(empty($this->macro)){
641 $this->macro ="none";
642 }
644 /* Prepare templating */
645 $smarty= get_smarty();
647 /* tell user that the pluging selected is no longer available*/
648 if((!$this->macrostillavailable)&&($this->macro!="none")){
649 print_red(_("The macro you selected, is no longer available for you, please choose another one."));
650 }
652 /* Assing macroselectbox values */
653 $smarty->assign("macros",$this->macros);
654 $smarty->assign("macro", $this->macro);
656 /* check if there is a FON server created */
657 if(!isset($_SESSION['config']->data['SERVERS']['FON'])){
658 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."));
659 }
661 /* Create parameter table, skip if no parameters given */
662 if(!isset($this->macroarray[$this->macro])){
663 $macrotab="";
664 }else{
666 $macrotab ="<table summary=\""._("Parameter")."\">";
667 /* for every single parameter-> display textfile,combo, or true false switch*/
669 foreach($this->phoneNumbers as $phonenum){
670 $tmp[] = $phonenum;
671 }
675 if($this->macro != $this->lastmacro){
676 /* Go through all params */
677 foreach($this->macroarray[$this->macro] as $key => $paras){
679 $string = $paras['default'];
681 $string=preg_replace("/%uid/i",$this->uid,$string);
683 if(isset($this->cn)){
684 $string=preg_replace("/%cn/i",$this->cn,$string);
685 }
687 for($i = 0 ; $i < 10; $i++){
688 if(isset($tmp[$i])){
689 $string = preg_replace("/%telephoneNumber_".($i+1)."/i",$tmp[$i],$string);
690 }
691 }
692 if(isset($tmp[0])){
693 $string = preg_replace("/%telephoneNumber/i",$tmp[0],$string);
694 }
695 $this->macroarray[$this->macro][$key]['choosen']=$string;
696 }
697 }
699 foreach($this->macroarray[$this->macro] as $paras){
701 /* get al vars */
702 $var = $paras['var'];
703 $name = $paras['name'];
704 $default = $paras['default'];
705 $type = $paras['type'];
706 $choosen = $paras['choosen'] ;
707 $str = $default;
709 $dis = "";
710 if(!$this->acl_is_writeable("goFonMacro",$SkipWrite)){
711 $dis = " disabled ";
712 }
714 /* in case of a combo box display a combobox with selected attr */
715 $macrotab.= "<tr>";
716 switch ($type){
718 case "combo":
719 $str= "<select name='".$var."' ".$dis.">";
720 foreach(split(":",$default) as $choice){
721 if($choosen==$choice){
722 $str.= "\n<option value='".$choice."' selected>".$choice." </option>";
723 }else{
724 $str.= "\n<option value='".$choice."'>".$choice." </option>";
725 }
726 }
727 $str.="</select>";
728 $macrotab.= "<td>".base64_decode($name)."</td><td>$str";
729 break;
731 case "bool":
732 if(!$choosen){
733 $str="\n<input type='checkbox' name='".$var."' value='1' ".$dis.">";
734 }else{
735 $str="\n<input type='checkbox' name='".$var."' value='1' checked ".$dis.">";
736 }
737 $macrotab.= "<td colspan='2'>$str ".base64_decode($name)."";
738 break;
740 case "string":
741 $str="<input name='".$var."' value='".$choosen."' style='width:340px;' ".$dis.">";
742 $macrotab.= "<td>".base64_decode($name)."</td><td>$str";
743 break;
745 }
746 $macrotab.= "</td></tr>";
748 }
749 $macrotab.="</table><input name='post_success' type='hidden' value='1'>";
750 }//is_array()
752 /* Give smarty the table */
753 $smarty->assign("macrotab",$macrotab);
755 /* Do we represent a valid account? */
756 if (!$this->is_account && $this->parent == NULL){
757 $display= "<img alt=\"\" src=\"images/stop.png\" align=\"middle\"> <b>".
758 _("This account has no phone extensions.")."</b>";
759 $display.= back_to_main();
760 return($display);
761 }
763 $display= "";
765 /* Show tab dialog headers */
766 if ($this->parent != NULL){
767 if ($this->is_account){
768 $display= $this->show_disable_header(_("Remove phone account"),
769 _("This account has phone features enabled. You can disable them by clicking below."));
770 } else {
771 if(empty($this->uid)){
772 $display= $this->show_enable_header(_("Create phone account"),
773 _("This account has phone features disabled. You can't enable them while no uid is set."),TRUE,TRUE);
774 }else{
775 $display= $this->show_enable_header(_("Create phone account"),
776 _("This account has phone features disabled. You can enable them by clicking below."));
777 }
778 return ($display);
779 }
780 }
782 /* Add phone number */
783 if (isset($_POST["add_phonenumber"]) && $_POST['phonenumber']){
784 if (is_phone_nr($_POST['phonenumber'])){
785 $number= $_POST["phonenumber"];
786 $this->phoneNumbers[$number]= $number;
787 $this->is_modified= TRUE;
788 } else {
789 print_red(_("Please enter a valid phone number!"));
790 }
791 }
793 /* Remove phone number */
794 if (isset($_POST["delete_phonenumber"]) && isset($_POST["phonenumber_list"])){
795 foreach ($_POST['phonenumber_list'] as $number){
796 unset($this->phoneNumbers[$number]);
797 $this->is_modified= TRUE;
798 }
799 }
801 /* Transfer ACL's */
802 foreach($this->attributes as $val){
803 $smarty->assign($val."ACL",$this->getacl($val,$SkipWrite));
804 if(isset($this->$val)){
805 $smarty->assign($val,$this->$val);
806 }else{
807 $smarty->assign($val,"");
808 }
809 }
811 /* Fill arrays */
812 $smarty->assign ("goFonHardware", $this->goFonHardware);
813 if (!count($this->phoneNumbers)){
814 $smarty->assign ("phoneNumbers", array(""));
815 } else {
816 $smarty->assign ("phoneNumbers", $this->phoneNumbers);
817 }
820 $dis = "";
821 if(!$this->acl_is_writeable("goFonHardware",$SkipWrite)){
822 $dis= " disabled ";
823 }
824 $hl= "<select size=\"1\" name=\"goFonHardware\" ".$dis." title=\"".
825 _("Choose your private phone")."\">\n";
826 foreach ($this->hardware_list as $cn => $description){
828 if ($cn == $this->goFonHardware){
829 $selected= "selected";
830 } else {
831 $selected= "";
832 }
834 if (isset($this->used_hardware[$cn])){
835 $color= "style=\"color:#A0A0A0\"";
836 } else {
837 $color= "";
838 }
839 $hl.= " <option $color label=\"$cn\" value=\"$cn\" $selected>$description </option>\n";
840 }
841 $hl.= "</select>\n";
842 $smarty->assign ("hardware_list", $hl);
844 /* Show main page */
845 $this->lastmacro = $this->macro;
846 $display.= $smarty->fetch(get_template_path('generic.tpl', TRUE, dirname(__FILE__)));
847 return($display);
848 }
851 function save_object()
852 {
853 $SkipWrite = (!isset($this->parent) || !$this->parent) && !isset($_SESSION['edit']);
854 if (isset($_POST["phoneTab"])){
855 plugin::save_object();
857 /* Every macro in the select box are available */
858 if((isset($_POST['macro']))){
859 $this->macrostillavailable=true;
860 }
862 if(is_array($this->phoneNumbers)){
863 foreach($this->phoneNumbers as $telenumms) {
864 $nummsinorder[]=$telenumms;
865 }
866 }else{
867 $nummsinorder=array("");
868 }
871 /* Save checkbox */
872 $tmp = preg_replace("/[^a-z]/i","",$this->goFonDeliveryMode);
873 if($this->acl_is_writeable("goFonDeliveryMode",$SkipWrite)){
874 if(isset($_POST['fon_to_mail']) && !preg_match("/M/",$this->goFonDeliveryMode)){
875 $tmp .= "M";
876 }elseif(!isset($_POST['fon_to_mail']) && preg_match("/M/",$this->goFonDeliveryMode)){
877 $tmp = preg_replace ("/M/","",$tmp);
878 }
879 }
880 $this->goFonDeliveryMode= "[".$tmp."]";
884 /* get all Postvars */
885 if(isset($this->macroarray[$this->macro])){
886 if($this->acl_is_writeable("goFonMarco",$SkipWrite)){
887 foreach($this->macroarray[$this->macro] as $key => $paras){
888 if(isset($_POST[$paras['var']])){
889 $this->macroarray[$this->macro][$key]['choosen'] = $_POST[$paras['var']];
890 }
892 /* Checkboxes are special, they are not Posted if they are not selected, so the won't be changed with the above code
893 We need this code below to read and save checkboxes correct
894 */
896 if(isset($_POST['post_success'])){
897 if($this->macroarray[$this->macro][$key]['type']=="bool"){
898 if(isset($_POST[$this->macroarray[$this->macro][$key]['var']])) {
899 $this->macroarray[$this->macro][$key]['choosen']=$_POST[$paras['var']];
900 }else{
901 $this->macroarray[$this->macro][$key]['choosen']=false;
902 }
903 }
904 }
905 }
906 }
907 }
908 }
909 }
911 function check()
912 {
913 /* Call common method to give check the hook */
914 $message= plugin::check();
916 if((strlen($this->goFonVoicemailPIN)==0)||(strlen($this->goFonVoicemailPIN)>4)){
917 $message[]=(_("Voicemail PIN must be between 1-4 characters."));
918 }else{
919 if(preg_match("/[^0-9]/",$this->goFonVoicemailPIN)){
920 $message[]=(_("The specified Voicemail PIN contains invalid characters, only numeric values are allowed here."));
921 }
922 }
924 if((strlen($this->goFonPIN)<=0)){
925 $message[]=(_("Phone PIN must be at least one character long."));
926 }else{
927 if(preg_match("/[^0-9a-z]/i",$this->goFonPIN)){
928 $message[]=(_("The specified phone PIN contains invalid characters, only aphanumeric values are allowed here."));
929 }
930 }
932 if(!$this->generate_mysql_entension_entries()){
933 $message[] = $this->generate_error;
934 }
936 /* We need at least one phone number */
937 if (count($this->phoneNumbers) == 0){
938 $message[]= sprintf(_("You need to specify at least one phone number!"));
939 }
941 /* check for ! in any parameter setting*/
942 if(isset($this->macroarray[$this->macro])){
943 foreach($this->macroarray[$this->macro] as $val){
944 if((strstr($val['choosen'],"!"))||(strstr($val['choosen'],"#"))){
945 $message[] = sprintf(_("The parameter %s contains invalid char. '!,#' is used as delimiter"),$val['name']);
946 }
947 }
948 }
949 return ($message);
950 }
954 function save()
955 {
956 plugin::save();
958 /* Save arrays */
959 $this->attrs['telephoneNumber']= array();
960 foreach ($this->phoneNumbers as $number){
961 $this->attrs['telephoneNumber'][]= $number;
962 }
964 /* Save settings, or remove goFonMacro attribute*/
965 if($this->macro!="none"){
966 $this->attrs['goFonMacro']=$this->macro;
967 if(isset($this->macroarray[$this->macro])){
968 foreach($this->macroarray[$this->macro] as $paras) {
969 $this->attrs['goFonMacro'].="!".$paras['id']."#".$paras['choosen'];
970 }
971 }
972 }else{
973 $this->attrs['goFonMacro']=array();
974 }
975 unset($this->attrs['macro']) ;
977 $this->attrs['goFonForwarding']=array();
979 $this->generate_mysql_entension_entries(true);
981 if($this->attrs['goFonMacro']==""){
982 $this->attrs['goFonMacro']=array();
983 }
985 unset($this->attrs['cn']);
987 /* Write back to ldap */
988 $ldap= $this->config->get_ldap_link();
989 $ldap->cd($this->dn);
990 $this->cleanup();
991 $ldap->modify ($this->attrs);
993 show_ldap_error($ldap->get_error(), sprintf(_("Saving of user/phone account with dn '%s' failed."),$this->dn));
995 /* Optionally execute a command after we're done */
997 if ($this->initially_was_account == $this->is_account){
998 if ($this->is_modified){
999 $this->handle_post_events("modify",array("uid"=> $this->uid));
1000 }
1001 } else {
1002 $this->handle_post_events("add",array("uid" => $this->uid));
1003 }
1005 }
1008 function insert_after($entry, $nr, $list)
1009 {
1010 /* Is the entry free? No? Make it free... */
1011 if (isset($list[$nr])) {
1012 $dest= array();
1013 $newidx= 0;
1015 foreach ($list as $idx => $contents){
1016 $dest[$newidx++]= $contents;
1017 if ($idx == $nr){
1018 $dest[$newidx++]= $entry;
1019 }
1020 }
1021 } else {
1022 $dest= $list;
1023 $dest[$nr]= $entry;
1024 }
1026 return ($dest);
1027 }
1030 function adapt_from_template($dn)
1031 {
1032 plugin::adapt_from_template($dn);
1034 /* Assemble phone numbers */
1035 if (isset($this->attrs['telephoneNumber'])){
1036 for ($i= 0; $i<$this->attrs['telephoneNumber']['count']; $i++){
1037 $number= $this->attrs['telephoneNumber'][$i];
1038 $this->phoneNumbers[$number]= $number;
1039 }
1040 }
1041 }
1044 function remove_from_parent()
1045 {
1046 if(!$this->initially_was_account) return;
1048 foreach($this->attributes as $key=>$val){
1049 if(in_array($val,array("uid","cn"))){
1050 unset($this->attributes[$key]);
1051 unset($this->$val);
1052 }
1053 }
1054 if(array_key_exists('config', $_SESSION) &&
1055 array_key_exists('SERVERS', $_SESSION['config']->data) &&
1056 array_key_exists('FON', $_SESSION['config']->data['SERVERS']) &&
1057 is_callable("mysql_pconnect")) {
1058 // Get Configuration for Mysql database Server
1059 $a_SETUP = $_SESSION['config']->data['SERVERS']['FON'];
1060 $s_parameter ="";
1062 // Connect to DB server
1063 $r_con = @mysql_pconnect($a_SETUP['SERVER'],$a_SETUP['LOGIN'],$a_SETUP['PASSWORD']);
1065 // Check if we are connected correctly
1066 if(!$r_con){
1067 print_red(sprintf(_("The MySQL Server '%s' isn't reachable as user '%s', check GOsa log for mysql error."),
1068 $a_SETUP['SERVER'],$a_SETUP['LOGIN']));
1069 gosa_log(@mysql_error());
1070 return false;
1071 }
1073 // Select database for Extensions
1074 $db = @mysql_select_db($a_SETUP['DB'],$r_con);
1076 // Test if we have the database selected correctly
1077 if(!$db){
1078 print_red(sprintf(_("Can't select database %s on %s."),$a_SETUP['DB'],$a_SETUP['SERVER']));
1079 gosa_log(@mysql_error());
1080 return false;
1081 }
1083 $SQL="";
1085 /* If deletion starts from userslist, cn uid are not set */
1086 if((isset($this->parent->by_object['user']->uid))&&(!empty($this->parent->by_object['user']->uid))){
1087 $this->uid = $this->parent->by_object['user']->uid;
1088 }
1090 if((isset($this->parent->by_object['user']->cn))&&(!empty($this->parent->by_object['user']->cn))){
1091 $this->cn = $this->parent->by_object['user']->cn;
1092 }
1094 $first_num = false;
1095 // Delete old entries
1096 foreach($this->a_old_telenums as $s_telenums){
1097 if(!$first_num){
1098 $first_num = $s_telenums;
1099 }
1100 $SQL[] = "DELETE FROM ".$a_SETUP['EXT_TABLE']." WHERE exten='".$s_telenums."';\n";
1101 }
1103 $SQL[] = "DELETE FROM ".$a_SETUP['VOICE_TABLE']." WHERE customer_id='".$first_num."';";
1104 $SQL[] = "DELETE FROM ".$a_SETUP['EXT_TABLE']." WHERE exten='".$this->uid."';\n";
1105 $SQL[] = "DELETE FROM ".$a_SETUP['SIP_TABLE']." WHERE name='".$this->uid."';\n";
1107 foreach($SQL as $query){
1108 if(!@mysql_query($query,$r_con)){
1109 print_red(_("Stop".mysql_error()));
1110 return false;
1111 }
1112 }
1113 }else{
1114 print_red(_("Can't remove phone account, the mysql extension is not present in php configuration."));
1115 return false;
1116 }
1118 /* unset macro attr, it will cause an error */
1119 $tmp = array_flip($this->attributes);
1120 unset($tmp['macro']);
1121 $this->attributes=array_flip($tmp);
1123 /* Cancel if there's nothing to do here */
1124 if (!$this->initially_was_account){
1125 return;
1126 }
1128 plugin::remove_from_parent();
1130 /* Just keep one phone number */
1131 if (count($this->telephoneNumber) && $this->telephoneNumber != ""){
1132 $this->attrs['telephoneNumber']= $this->telephoneNumber;
1133 } else {
1134 $this->attrs['telephoneNumber']= array();
1135 }
1138 $ldap= $this->config->get_ldap_link();
1139 $ldap->cd($this->config->current['BASE']);
1140 $ldap->search("(objectClass=goFonQueue)", array("member"));
1141 while($attr = $ldap->fetch()){
1142 if(in_array($this->dn,$attr['member'])){
1143 $new =new ogrouptabs($this->config, $this->config->data['TABS']['OGROUPTABS'],$attr['dn']);
1144 unset($new->by_object['ogroup']->memberList[$this->dn]);
1145 unset($new->by_object['ogroup']->member[$this->dn]);
1146 $new->save();
1147 print_red(sprintf(_("Removed user '%s' from phone queue '%s'."),$this->uid,$new->by_object['ogroup']->attrs['cn']));
1148 }
1149 }
1150 $ldap->cd($this->dn);
1151 $this->cleanup();
1152 $ldap->modify ($this->attrs);
1154 show_ldap_error($ldap->get_error(), sprintf(_("Removing of user/phone account with dn '%s' failed."),$this->dn));
1156 /* Optionally execute a command after we're done */
1157 @mysql_close($r_con);
1158 $this->handle_post_events('remove',array("uid" => $this->uid));
1159 }
1163 /* This function checks if the given phonenumbers are available or already in use*/
1164 function is_number_used()
1165 {
1166 $ldap= $this->config->get_ldap_link();
1167 $ldap->cd($this->config->current['BASE']);
1168 $ldap->search("(|(objectClass=goFonAccount)(objectClass=goFonQueue)(objectClass=goFonConference))", array("telephoneNumber","cn","uid"));
1169 while($attrs = $ldap->fetch()) {
1170 unset($attrs['telephoneNumber']['count']);
1171 foreach($attrs['telephoneNumber'] as $tele){
1172 if(!isset($attrs['cn'][0])) $attrs['cn'][0]=$attrs['dn'];
1173 if(!isset($attrs['uid'][0])) $attrs['uid'][0]=$attrs['dn'];
1174 $numbers[$tele]=$attrs;
1175 }
1176 }
1178 foreach($this->phoneNumbers as $num){
1179 if(!isset($this->cn)) $this->cn = "";
1181 if((isset($numbers[$num]))&&(($numbers[$num]['uid'][0]!=$this->uid))){
1182 if(isset($numbers[$num]['uid'][0])){
1183 return sprintf(_("The specified telephonenumber '%s' is already assigned to '%s'."),$num,$numbers[$num]['uid'][0]);
1184 }else{
1185 return sprintf(_("The specified telephonenumber '%s' is already assigned to '%s'."),$num,$numbers[$num]['cn'][0]);
1186 }
1187 }
1188 }
1189 }
1192 /* Create phoneAccount part of copy & paste dialog */
1193 function getCopyDialog()
1194 {
1195 if(!$this->is_account) return("");
1196 $smarty = get_smarty();
1197 if (!count($this->phoneNumbers)){
1198 $smarty->assign ("phoneNumbers", array(""));
1199 } else {
1200 $smarty->assign ("phoneNumbers", $this->phoneNumbers);
1201 }
1203 $smarty->assign("goFonVoicemailPIN",$this->goFonVoicemailPIN);
1204 $smarty->assign("goFonPIN",$this->goFonPIN);
1206 $display= $smarty->fetch(get_template_path('paste_generic.tpl', TRUE, dirname(__FILE__)));
1207 $ret =array();
1208 $ret['string'] = $display;
1209 $ret['status'] = "";
1210 return($ret);
1211 }
1213 /* Save posts from copy & paste dialog dialog */
1214 function saveCopyDialog()
1215 {
1216 if(!$this->is_account) return;
1217 $this->execute();
1218 if(isset($_POST['goFonVoicemailPIN'])) {
1219 $this->goFonVoicemailPIN = $_POST['goFonVoicemailPIN'];
1220 }
1221 if(isset($_POST['goFonPIN'])){
1222 $this->goFonPIN = $_POST['goFonPIN'];
1223 }
1224 }
1227 /* Return plugin informations for acl handling */
1228 function plInfo()
1229 {
1230 return (array(
1231 "plShortName" => _("Phone"),
1232 "plDescription" => _("Phone account settings"),
1233 "plSelfModify" => TRUE,
1234 "plDepends" => array("user"),
1235 "plPriority" => 7, // Position in tabs
1236 "plSection" => "personal", // This belongs to personal
1237 "plCategory" => array("gofonreport" => array("description" => _("GOfon reports"),
1238 "objectClass" => "")),
1240 "plOptions" => array(),
1242 "plProvidedAcls" => array(
1243 "telephoneNumber" => _("Telephone number"),
1244 "goFonMacro" => _("Macro settings"),
1245 "goFonHardware" => _("Phone hardware"),
1246 "goFonPIN" => _("Telephone pin"),
1247 "goFonVoicemailPIN" => _("Voicemail pin"))
1248 ));
1249 }
1250 }
1252 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1253 ?>