Code

872faefff6ddd4b96eefdd1eed5a32861be8e616
[gosa.git] / gosa-plugins / gofon / gofon / phoneaccount / class_phoneAccount.inc
1 <?php
3 class phoneAccount extends plugin
4 {
5     /* Definitions */
6     var $plHeadline   = "Phone";
7     var $plDescription= "Manage personal phone settings";
8     var $plIcon       = "plugins/gofon/images/phoneAccount.png";
10     /* Attributes */
11     var $telephoneNumber        = array();
12     var $goFonHardware          = "automatic";
13     var $goFonFormat            = "wav";
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          = "";
30     var $goFonHomeServer        = "0";            // Contains the dn of the server that manage this account 
31     var $init_HomeServer        = "0";            // Contains the dn of the server that manage this account 
32     var $goFonHomeServers       = array();        // Contains all available server configurations 
34     var $context                = "default";
35     var $sip_contexts           = array();
36     var $voice_context          = "default";
37     var $voicemail_contexts     = array();
39     /* attribute list for save action */
40     var $CopyPasteVars          = array("phoneNumbers","macroarray","macrostillavailable"/*"phoneNumbers" -Reset- */,
41             "hardware_list","used_hardware");
43     var $attributes             = array("goFonDeliveryMode", "goFonFormat","goFonHomeServer",
44             "goFonHardware","goFonPIN","goFonVoicemailPIN","telephoneNumber", "goFonMacro","macro");
45     var $objectclasses= array("goFonAccount");
47     var $uid;
48     var $cn;
50     var $view_logged = FALSE;
51     var $multiple_support = TRUE;
52     var $mailAddress      = "";
53     var $has_mailAccount  = FALSE;
54     var $pager      = "";
56     function phoneAccount (&$config, $dn= NULL, $parent= NULL)
57     {
58         plugin::plugin ($config, $dn, $parent);
60         /* Assemble phone numbers */
61         if (isset($this->attrs['telephoneNumber'])){
62             for ($i= 0; $i<$this->attrs['telephoneNumber']['count']; $i++){
63                 $number= $this->attrs['telephoneNumber'][$i];
64                 $this->phoneNumbers[$number]= $number;
65             }
66         }
68         $this->sip_contexts = $this->get_asterisk_sip_contexts();
69         $this->voicemail_contexts = $this->get_asterisk_voicemail_contexts();
71         /* Set parent object to tab object */
72         if(is_object($parent)){
73             $this->parent = $parent->parent;
74         }
76         /* Get current uid and cn 
77          */
78         if(isset($this->attrs['uid'][0])){
79             $this->uid = $this->attrs['uid'][0];
80         }
81         if(isset($this->attrs['cn'][0])){
82             $this->cn = $this->attrs['cn'][0];
83         }
84         if(isset($this->attrs['mail'][0])){
85             $this->mailAddress = $this->attrs['mail'][0];
86             $this->has_mailAccount = true;
87         }
88         if(isset($this->attrs['pager'][0])){
89             $this->pager = $this->attrs['pager'][0];
90         }
92         /* If there is a parent object present, use references 
93          */
94         if(isset($this->parent->by_object['user']->uid)){
95             $this->uid = &$this->parent->by_object['user']->uid;
96         }
97         if(isset($this->parent->by_object['user']->cn)){
98             $this->cn   =&$this->parent->by_object['user']->cn;
99         }
100         if(isset($this->parent->by_object['user']->pager)){
101             $this->pager   =&$this->parent->by_object['user']->pager;
102         }
103         if(isset($this->parent->by_object['mailAccount']->mail)){
104             $this->mailAddress      = &$this->parent->by_object['mailAccount']->mail;
105             $this->has_mailAccount  = &$this->parent->by_object['mailAccount']->is_account;
106         }
108         /* Check server configurations 
109          * Load all server configuration in $this->goFonHomeServers if available
110          *  and first server as default if necessary.
111          * Check if connection is successfull for the selected server $this->goFonHomeServer
112          */
115         /* Set available server */
116         $config = session::get('config');
117         if(isset($config->data['SERVERS']['FON'])){
118             $this->goFonHomeServers = $config->data['SERVERS']['FON'];
119         }
121         $a_SETUP= array();
122         if($this->is_account && isset($config->data['SERVERS']['FON']) &&
123                 array_key_exists('FON',$config->data['SERVERS']) &&
124                 is_callable("mysql_connect")
125           ) {
127             /* Servers defined? Watch here... */
128             if (count($this->goFonHomeServers)){
130                 /* Set default server */
131                 if(empty($this->goFonHomeServer) || $this->goFonHomeServer == "0"){
132                     $this->goFonHomeServer= $this->goFonHomeServers[0]['DN'];
133                 }
135                 /* Remember inital home server, to be able to remove old entries */
136                 $this->init_HomeServer = $this->goFonHomeServer;
138                 /* Get config */
139                 if(!isset($this->goFonHomeServers[$this->goFonHomeServer])){
140                     msg_dialog::display(_("Obsolete entry"), sprintf(_("The current home server is not available anymore. It will be moved to '%s' if you save this entry!"), preg_replace("/,/",", ",$this->goFonHomeServers[0]['DN'])), ERROR_DIALOG);
142                     $this->goFonHomeServer = $this->goFonHomeServers[0]['DN'];
143                     $this->init_HomeServer = $this->goFonHomeServers[0]['DN'];
144                 }    
145                 $cur_cfg = $this->goFonHomeServers[$this->goFonHomeServer];
147                 $r_con =  @mysql_pconnect($cur_cfg['SERVER'],$cur_cfg['LOGIN'],$cur_cfg['PASSWORD']);
148                 if(!$r_con){
149                     new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error());
150                 }
151                 $db  =  @mysql_select_db($cur_cfg['DB'],$r_con);
152                 if(!$db){
153                     new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error());
154                 }
156                 $first = false; 
157                 foreach($this->phoneNumbers as $key => $val){
158                     if(!$first){
159                         $first = $key;
160                     }
161                 }
162             }
163         }
165         /* Get available phone hardware  
166          * Search for all available phone hardware  
167          */
168         $tmp = get_sub_list("(objectClass=goFonHardware)","phone",array(get_ou("phoneGeneric", "phoneRDN")),
169                 $this->config->current['BASE'],array("cn","description"), GL_SUBSEARCH);
170         foreach($tmp as $attrs){
171             $cn= $attrs['cn'][0];
172             $description= "";
173             if (isset($attrs['description'])){
174                 $description= " - ".$attrs['description'][0];
175             }
176             $this->hardware_list[$cn]= "$cn$description";
177         }
178         $this->hardware_list["automatic"]= _("automatic");
179         ksort($this->hardware_list);
182         /* Collect all usd phones 
183            goFonHardware set.
184          */
185         $deps_a = array(
186                 get_people_ou(),
187                 get_ou("group", "ogroupRDN"),
188                 get_ou("servgeneric", "serverRDN"),
189                 get_ou("termgeneric", "terminalRDN"),
190                 get_ou("workgeneric", "workstationRDN"),
191                 get_ou("printgeneric", "printerRDN"),
192                 get_ou("componentGeneric", "componentRDN"),
193                 get_ou("phoneGeneric", "phoneRDN"));
195         $tmp = get_sub_list("(goFonHardware=*)","phone",$deps_a,$this->config->current['BASE'],
196                 array('cn','dn','goFonHardware'),GL_SUBSEARCH);
197         foreach($tmp as $attrs){
198             $cn = $attrs['goFonHardware'][0];
199             if(isset($this->hardware_list[$cn])){
200                 $this->used_hardware[$cn]= $cn;
201             }
202         }
205         /* Get available Macros  
206          * Search for all Macros that are visible and create 
207          *  an array with name and parameters 
208          */
209         $tmp = get_sub_list("(&(objectClass=goFonMacro)(goFonMacroVisible=1))","gofonmacro",array(get_ou("macro", "phoneMacroRDN")),
210                 $this->config->current['BASE'],array("displayName","goFonMacroParameter","dn","cn"), GL_NO_ACL_CHECK | GL_SUBSEARCH );
213         /* Add none for no macro*/
214         $this->macros['none']=_("no macro");    
215         $this->macro ="none";
217         /* Fetch all Macros*/
218         foreach($tmp as $attrs){
220             $ui = get_userinfo(); 
221             $acl = $ui->get_permissions($attrs['dn'],"gofonmacro/macro","");
223             /* Skip all macros we are not able to read 
224                execpt, the currently selected macro.
225              */
226             if(!preg_match("/r/",$acl) && !preg_match("/^".preg_quote($attrs['dn'], '/')."/",$this->goFonMacro)){
227                 continue;
228             }
230             /* unset Count, we don't need that here */
231             unset($attrs['displayName']['count']);
233             /* Parse macro data, unset count for parameterarrays  */
234             if (isset($attrs['goFonMacroParameter']['count'])){
235                 unset($attrs['goFonMacroParameter']['count']);
236             }
238             /* fill Selectfield variable with Macros */
239             if(isset($attrs['displayName'][0])){
240                 $this->macros[$attrs['dn']] = $attrs['displayName'][0]." (".$attrs['cn'][0].")";
241             }else{
242                 $this->macros[$attrs['dn']] = _("undefined");
243             }
245             /* Go through available parameters and parse all attributes, like parametername, type, default ...*/
246             if((isset($attrs['goFonMacroParameter']))&&(is_array($attrs['goFonMacroParameter']))){
247                 foreach($attrs['goFonMacroParameter'] as $pkey=>$pval){
248                     /* Split Data in readable values, by delimiter !  */
249                     $data = explode("!",$attrs['goFonMacroParameter'][$pkey]);
251                     $string = $data[3];
252                     $string=preg_replace("/%uid/i",$this->uid,$string);
253                     $string=preg_replace("/%pager/i",$this->pager,$string);
254                     $string=preg_replace("/%context/i",$this->context,$string);
255                     $string=preg_replace("/%voicemailcontext/i",$this->voice_context,$string);
257                     if(isset($this->cn)){
258                         $string=preg_replace("/%cn/i",$this->cn,$string);
259                     }
262                     $tmp = array();
263                     foreach($this->phoneNumbers as $phonenum){
264                         $tmp[] = $phonenum;
265                     }
267                     for($i = 0 ; $i < 10; $i++){
268                         if(isset($tmp[$i])){
269                             $string = preg_replace("/%telephoneNumber_".($i+1)."/i",$tmp[$i],$string);
270                         }
271                     }
272                     if(isset($tmp[0])){
273                         $string = preg_replace("/%telephoneNumber/i",$tmp[0],$string);
274                     }
275                     $data[3] = $string;
278                     /* Set all attrs */
279                     $id = $data[0];
280                     $this->macroarray[$attrs['dn']][$id]['var']    ="var".$id;
281                     $this->macroarray[$attrs['dn']][$id]['choosen']=$data[3];
282                     $this->macroarray[$attrs['dn']][$id]['id']     =$id;
283                     $this->macroarray[$attrs['dn']][$id]['name']   =$data[1];
284                     $this->macroarray[$attrs['dn']][$id]['type']   =$data[2];
285                     $this->macroarray[$attrs['dn']][$id]['default']=$data[3];
286                     if($data[2] == "bool"){
287                         $this->macroarray[$attrs['dn']][$id]['choosen']=$data[3];
288                     }
289                 }//foreach
290             }//is_array
291         }//while
294         /* Parse used Macro  
295          * If we have a macro selected, parse it and set values 
296          *  in $this->macroarray[$this->macro]. 
297          */
298         $tmp = explode("!",$this->goFonMacro);
299         if(is_array($tmp)){
301             /* First value is the macroname */
302             $this->macro = $tmp[0];
304             /* Macroname saved, delete that index */
305             unset($tmp[0]);
307             /* Check if makro has been removed */
308             if(!isset($this->macros[$this->macro])){
309                 $this->macrostillavailable = false;
310             }else{
311                 $this->macrostillavailable = true;
312             }
314             /* for each parametervalues ( parameterID#value like 25#twentyfive) */
315             foreach($tmp as $var){
317                 /* Split this, so we have $varar[0] = parameterID $varar[1] = SelectedValue */
318                 $varar = explode("#",$var);
320                 /* Only insert if the parameter still exists */
321                 if(isset($this->macroarray[$this->macro][$varar[0]])){
322                     /* Assign value */
323                     $this->macroarray[$this->macro][$varar[0]]['choosen']=$varar[1];
324                 }
325             }
326         }
329         $this->a_old_telenums = $this->phoneNumbers;
332         /* Get voicemail PIN from MySQL DB 
333          * Because every user can change his PIN directly from the phone
334          *  without any update to the ldap
335          * This means, the PIN in the DB is up to date
336          */
337         // Connect to DB server
340         $num = key($this->phoneNumbers);
342         if( (is_callable("mysql_pconnect"))&&
343                 (isset($cur_cfg))&&
344                 (isset($cur_cfg['SERVER']))&&
345                 (isset($cur_cfg['LOGIN']))&&
346                 (isset($cur_cfg['PASSWORD']))){
348             $r_con =  @mysql_pconnect($cur_cfg['SERVER'],$cur_cfg['LOGIN'],$cur_cfg['PASSWORD']);
349             if($r_con){
351                 // Try to select the gophone database
352                 $r_db  =  @mysql_select_db($cur_cfg['DB'],$r_con);
353                 if(!$r_db){
354                     msg_dialog::display(_("Warning"), msgPool::dbselect($cur_cfg['DB'],mysql_error()), WARNING_DIALOG);
355                 }
357                 $query_tmp = "SELECT ".$cur_cfg['VOICE_TABLE'].".context as 'v_context', 
358                     ".$cur_cfg['SIP_TABLE'].".context, 
359                     ".$cur_cfg['VOICE_TABLE'].".password 
360                         FROM  ".$cur_cfg['VOICE_TABLE'].", 
361                     ".$cur_cfg['SIP_TABLE']." 
362                         WHERE ".$cur_cfg['VOICE_TABLE'].".mailbox = ".mysql_real_escape_string($num)." 
363                         AND ".$cur_cfg['SIP_TABLE'].".name='".mysql_real_escape_string($this->uid)."'";
364                 $res = mysql_query($query_tmp);
365                 $vp  = mysql_fetch_assoc($res);
366                 if(!isset($vp['context'])){
367                     $this->is_modified= TRUE;
368                     msg_dialog::display(_("Warning"), sprintf(_("Cannot identify telephone extension in database, please try to save again.")), WARNING_DIALOG);
369                 } 
371                 @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query_tmp, "Database query");
372                 if((isset($vp['password']))&&(!empty($vp['password']))){
373                     $this->goFonPINVoice = $vp['password'];
374                 }
375                 if((isset($vp['context']))&&(!empty($vp['context']))){
376                     $this->context = $vp['context'];
377                 }
378                 if((isset($vp['v_context']))&&(!empty($vp['v_context']))){
379                     $this->voice_context = $vp['v_context'];
380                 }
381             }
382         }
383         $this->lastmacro=$this->macro;
385         if(is_callable("mysql_close")&&(isset($r_con))&&($r_con)){
386             @mysql_close($r_con) ;
387         }
388     }
391     /* Transaction will only work with InnoDB tables 
392      */
393     public static function checkRealtimeTables($config)
394     {
395         $ret =TRUE;
397         // Connect to DB server
398         if( (is_callable("mysql_pconnect"))&&
399                 (isset($config))&&
400                 (isset($config['SERVER']))&&
401                 (isset($config['LOGIN']))&&
402                 (isset($config['PASSWORD']))){
404             $r_con =  @mysql_pconnect($config['SERVER'],$config['LOGIN'],$config['PASSWORD']);
405             if($r_con){
406                 $r_db  =  @mysql_select_db($config['DB'],$r_con);
408                 /* Validate Table Type - it must be InnoDB to be able to use transactions 
409                  */
410                 $inno_tables = array("SIP_TABLE","EXT_TABLE","VOICE_TABLE","QUEUE_TABLE","QUEUE_MEMBER_TABLE"); 
411                 foreach($inno_tables as $inno_table){
412                     $sql = "show table status like '".mysql_real_escape_string($config[$inno_table])."';";
413                     $res = mysql_query($sql);
414                     $vp  = mysql_fetch_assoc($res);
415                     if(!preg_match("/^InnoDB$/i",$vp['Engine'])){
417                         /* Not an InnoDB Table type, try to modify type. 
418                          */
419                         $sql = "ALTER TABLE `".$config[$inno_table]."` ENGINE = INNODB; ";
420                         $res = mysql_query($sql);
421                         if(!$res){
422                             @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>".$sql."</b>", 
423                                     "<b>FAILED!</b>. Transactions will not work!");
424                             $ret = FALSE;
425                         }else{
426                             @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>".$sql."</b>", 
427                                     "<i>Table '".$config[$inno_table]."' is now of type InnoDB, this enables transactions.</i>");
428                         }
429                     }else{
430                         @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"",
431                                 "<i>Table type of '".$config[$inno_table]."' OK, using transactions!</i>");
432                     }
433                 }
434             }
435         }
436         return($ret);
437     }
439     function stripInvalidChars($tele){
440         /* Strip invalid chars, but maintain a leading + for international numbers */
441         $t_tele= preg_replace("/[^0-9]/","",$tele);
442         if (preg_match('/^\+/', $tele)) {
443             $t_tele= "+".$t_tele;
444         }
445         return($t_tele);
446     }
451     /* This function generates the Database entries. 
452      * The Parameter 'save' could be true or false.
453      *  false - means only testing no database transactions.
454      *  true  - write database entries.
455      *
456      * 'sip_users','voice_mail' and 'extensions' table entries will be created.
457      * 
458      * If the phone hardware is 'automatic' the table entries will only be removed
459      *  and not added. 
460      */
461     function generate_mysql_entension_entries($save = false)
462     {
463         /* Check if there is at least one server available 
464          * If not, return and tell the user that saving failed 
465          */
466         if(!count($this->goFonHomeServers)){
467             if($save){
468                 msg_dialog::display(_("Configuration error"), msgPool::noserver(_("GOfon")), WARNING_DIALOG);
469             }
470             return(true);
471         }
473         /* Check if Mysql extension is available */
474         if(!is_callable("mysql_pconnect")){
475             if($save){
476                 msg_dialog::display(_("Configuration error"), msgPool::missingext("php-mysql"), WARNING_DIALOG);
477             }
478             return(true);
479         }
481         /********************** 
482          * Attribute Initialisation
483          **********************/
485         $old_connection = false;
487         // Get Configuration for Mysql database Server
488         $s_parameter    = "";                                           // Contains paramter for selected Macro 
489         $r_con          = false;                                        // DB connection
490         $r_db           = false;                                        // Selected DB
491         $r_res          = false;                                        // Result resource
492         $a_ldap_attrs   = array();                                      //  
494         $s_ip           = NULL;                   // Contains ip for Sip entry
495         $s_host         = NULL;                   // Contains host for Sip entry
496         $s_qualify      = "yes";                  // Qualify entry
497         $s_pin          = NULL;                   // Entry for secret
498         $s_type         = "friend";               // Entry for phone type (friend , peer ..)
499         // Set the default to the default of the db
501         $sip_data_array = array();                // Contains complete sip entry, to generate SQL syntax
502         $i_old_key      = false;                  // Contains index for first old phonenumber, to delete old entries corectly
503         $i_new_key      = false;                  // Contains index for first new phonenumber, to generate new  entries corectly
505         $s_sip_values   = "";     // Contains string with all values for given attributes in SQL syntax
506         $s_sip_keys     = "";     // Contains all needed attributes to generate sip entry in DB
508         $s_sip_key      = "";     // Key for SIP entry index      
509         $s_sip_val      = "";     // Value for SIP entry index      
511         $b_first_deleted= false;  // Only delete first entry, 
512         $s_telenums     = "";     // for each value variable
514         $i_is_accounted = false;  // Ensure that extension entry, for name to number is only once in table
516         /* Prepare some basic attributes */
517         $oldnums = array();
519         foreach($this->a_old_telenums as $tele){
520             $oldnums[]= $this->stripInvalidChars($tele);
521         }
522         foreach($this->phoneNumbers as $tele){
523             $newnums[]= $this->stripInvalidChars($tele);
524         }
526         if(empty($this->uid)) trigger_error("Uid is empty.");
529         /* Create voicemail entry 
530          */
531         if((!isset($this->cn))||(empty($this->cn))){
532             $CNname= $this->uid;
533         }else{
534             $CNname= $this->cn;
535         }
537         $s_mail = "";
538         if($this->has_mailAccount){
539             $s_mail = $this->mailAddress;;
540         }
542         /* Get phonehardware to setup sip entry  */
543         $ldap         = $this->config->get_ldap_link();
544         $ldap->cd ($this->config->current['BASE']);
545         $r_res        = $ldap->search("(&(objectClass=goFonHardware)(cn=".$this->goFonHardware."))", array('*'));
546         $a_ldap_attrs = $ldap->fetch();
548         /* Check selected phone hardware, is a default IP set? */
549         if(((isset($a_ldap_attrs['goFonDefaultIP'][0]))&&($a_ldap_attrs['goFonDefaultIP'][0] != "dynamic"))){
550             $s_ip       = $a_ldap_attrs['goFonDefaultIP'][0];
551             $s_host     = $s_ip;
552         }else{
553             $s_ip       = NULL;
554             $s_host     = "dynamic";
555         }
557         // Attribute GoFonQualify set ?
558         if(isset($a_ldap_attrs['goFonQualify'])){
559             $s_qualify = $a_ldap_attrs['goFonQualify'][0];
560         }
562         // Attribute GoFonPIN set ?
563         if(isset($this->goFonPIN)){
564             $s_pin      = $this->goFonPIN;
565         }
567         // Attribute GoFonType set ?
568         if(isset($a_ldap_attrs['goFonType'])){
569             $s_type = $a_ldap_attrs['goFonType'][0];
570         }
572         if(isset($a_ldap_attrs['goFonDmtfMode'][0])){
573             $sip_data_array['dtmfmode']     = $a_ldap_attrs['goFonDmtfMode'][0];
574         }else{
575             $sip_data_array['dtmfmode']     ="rfc2833";
576         }
578         /* Check if phone number is used */
579         if($this->is_number_used()){
580             $this->generate_error = $this->is_number_used(); 
581             return false;
582         }
586         /********************** 
587          * Check Server Connection Information
588          **********************/
590         /* Create Mysql handle for the current goFonHomeServer, if possible  
591          * Get configuration to old asterisk home server 
592          */ 
593         $a_New = $this->goFonHomeServers[$this->goFonHomeServer];  // DB Configuration
594         $new_connection =  @mysql_pconnect($a_New['SERVER'],$a_New['LOGIN'],$a_New['PASSWORD']);
595         if(!$new_connection){
596             $this->generate_error =  msgPool::dbconnect($a_New['SERVER'],@mysql_error($new_connection),
597                     _("Abort saving entries to keep the database consistent."));
598             new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error($new_connection));
599             return false;
600         }
601         $new_database  =  @mysql_select_db($a_New['DB'],$new_connection);
602         if(!$new_database){
603             $this->generate_error =  msgPool::dbselect($a_New['DB'],@mysql_error($new_connection),
604                     _("Abort saving entries to keep the database consistent."));
605             new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error($new_connection));
606             return false;
607         }
609         /* If the home server has changed, we must remove entries from old 
610          *  server and add new entries in new server.  
611          */
612         if($this->init_HomeServer != $this->goFonHomeServer){
614             /* Get configuration to old asterisk home server */ 
615             $a_Remove = $this->goFonHomeServers[$this->init_HomeServer];  // DB Configuration
617             /* Create connection to the database that contains the old entry. 
618              */
619             $old_connection =  @mysql_pconnect($a_Remove['SERVER'],$a_Remove['LOGIN'],$a_Remove['PASSWORD']);
620             if(!$old_connection){
621                 $this->generate_error =  msgPool::dbconnect($a_Remove['SERVER'],@mysql_error($old_connection),
622                         _("Abort saving entries to keep the database consistent."));
623                 new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error($old_connection));
624                 return false;
625             }
626             $old_database  =  @mysql_select_db($a_Remove['DB'],$old_connection);
627             if(!$old_database){
628                 $this->generate_error =  msgPool::dbselect($a_Remove['DB'],@mysql_error($old_connection),
629                         _("Abort saving entries to keep the database consistent."));
630                 new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error($old_connection));
631                 return false;
632             }
633         }
636         /* Save means that we must save changes, not only test  */
637         if($save == true){
639             /********************** 
640              * Remove entries from old home server 
641              **********************/
643             /* Check if there is an old entry 
644              * If there is an old entry, get callerid and remove voicemail and extensions 
645              */
646             if($old_connection){
648                 /* Check table definitions
649                  */
650                 if(!phoneAccount::checkRealtimeTables($a_Remove)){
651                     msg_dialog::display(_("Warning"),
652                             sprintf(_("GOsa identified problems with your MySQL table definition!")),
653                             WARNING_DIALOG);
654                 }
656                 $query  = "SELECT id,name,callerid FROM ".$a_Remove['SIP_TABLE']." WHERE name='".mysql_real_escape_string($this->uid)."';";
657                 $rid    = mysql_query($query,$old_connection);
658                 @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query, 
659                         "<i>Reguest callerid to be able to identify the user.</i>");
661                 /* Old entry found, remove it */
662                 $query_a = array();
663                 if(mysql_affected_rows($old_connection)){
664                     $result = mysql_fetch_assoc($rid);
666                     /* Set mode to strict
667                        Strict disallows the addition of entries that do not match the targets field length.
668                      */
669                     $query_a[]= "SET @@sql_mode = STRICT_ALL_TABLES;";
670                     $query_a[]= "DELETE FROM ".$a_Remove['SIP_TABLE']." WHERE name='".mysql_real_escape_string($this->uid)."';";
671                     $query_a[]= "DELETE FROM ".$a_Remove['VOICE_TABLE']." WHERE customer_id='".mysql_real_escape_string($result['callerid'])."';";
672                     $query_a[]= "DELETE FROM ".$a_Remove['EXT_TABLE']." WHERE exten='".mysql_real_escape_string($this->uid)."';";
673                     foreach($oldnums as $s_telenums) {
674                         $query_a[]= "DELETE FROM ".$a_Remove['EXT_TABLE']." WHERE exten='".mysql_real_escape_string($s_telenums)."';";
675                     }
677                     /* Start transaction, to be able to rollback 
678                      */
679                     @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>---Removing entry from old server---</b>","");
681                     mysql_query("begin;",$old_connection);
682                     @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>begin;</b>","<i>Starting transaction!</i>");
684                     foreach($query_a as $query){
685                         @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>".$query."</b>", "");
686                         if(!mysql_query($query,$old_connection)){
687                             $err = mysql_error($old_connection);
688                             @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"\n".$err, "<b>FAILED</b>");
689                             msg_dialog::display(_("Error"), 
690                                     msgPool::mysqlerror($err,__CLASS__)."&nbsp;".
691                                     "\n<p>"._("Please activate debugging for details!")."</p>",
692                                     ERROR_DIALOG);
694                             mysql_query("rollback;",$old_connection);
695                             @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>rollback;</b>", "<b>ERROR</b> Rollback transaction!");
696                             @mysql_close($old_connection);
697                             return(false);
698                         } 
699                     }
701                     /* Let changes get active, everything was fine;
702                      */ 
703                     mysql_query("commit;",$old_connection);
704                     @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>commit;</b>", "");
705                     @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>---Transaction sucessful!---</b>", "");
706                 }
707             }
710             /********************** 
711              * Update / Insert sip_users entry  
712              **********************/
714             /* Check table definitions
715              */
716             if(!phoneAccount::checkRealtimeTables($a_New)){
717                 msg_dialog::display(_("Warning"),
718                         sprintf(_("GOsa identified problems with your MySQL table definition!")),
719                         WARNING_DIALOG);
720             }
723             /* Set the first given phone number as callerid */
724             reset($newnums);        
725             $i_new_key = key($newnums);
726             $sip_data_array['callerid']  =$newnums[$i_new_key];
727             $sip_data_array['mailbox']   =$newnums[$i_new_key]."@".$this->voice_context;
729             /* Check if there is already an entry in sip_users for this uid */
730             $SQL_query_array = array();
732             /* Enforce strict mode, ensures inout validation, e.g. target field length 
733              */
734             $SQL_query_array[] = "SET @@sql_mode = STRICT_ALL_TABLES;";
736             $query = "SELECT * FROM ".$a_New['SIP_TABLE']." WHERE name='".mysql_real_escape_string($this->uid)."';\n"; 
737             $rid = mysql_query($query,$new_connection);
738             @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query, "Receive current mysql entries.");
739             if(mysql_affected_rows($new_connection)){
741                 /********************** 
742                  * Update sip_users entry 
743                  **********************/
744                 $result                     = mysql_fetch_assoc($rid);
745                 $sip_data_array['host']         = $s_host;
746                 $sip_data_array['qualify']      = $s_qualify;
747                 $sip_data_array['secret']       = $this->goFonPIN;
748                 $sip_data_array['type']         = $s_type ;
749                 $sip_data_array['username']     = $this->uid;
750                 $sip_data_array['ipaddr']       = $s_ip;
751                 $sip_data_array['context']      = $this->context;
753                 /* Remove not changed attributes, to avoid updating table with same values */
754                 foreach($sip_data_array as $name => $value){
755                     if($result[$name] == $value){
756                         unset($sip_data_array[$name]);
757                     }
758                 }
759                 /* Only update entry if there is something to uopdate */
760                 if(count($sip_data_array)){
761                     $query = "UPDATE ".$a_New['SIP_TABLE']." SET ";
762                     foreach($sip_data_array as $key => $val){
763                         $query.= "".$key."='".mysql_real_escape_string($val)."',"; 
764                     } 
765                     $query = preg_replace("/,$/","",$query);
766                     $query.= " WHERE name='".mysql_real_escape_string($this->uid)."';";
767                     $SQL_query_array[] = $query;
768                 }
769             } else {
771                 /********************** 
772                  * Insert sip_users entry 
773                  **********************/
774                 //generate SIP entry
775                 $sip_data_array['name']         = $this->uid;
776                 $sip_data_array['accountcode']  = NULL;          
777                 $sip_data_array['amaflags']     = NULL;
778                 $sip_data_array['callgroup']    = NULL;
779                 $sip_data_array['canreinvite']  = "no";
780                 $sip_data_array['context']      = $this->context;
781                 $sip_data_array['defaultip']    = NULL;
782                 $sip_data_array['fromuser']     = NULL;
783                 $sip_data_array['fromdomain']   = NULL;
784                 $sip_data_array['host']         = $s_host;
785                 $sip_data_array['insecure']     = NULL;
786                 $sip_data_array['language']     = NULL;
787                 $sip_data_array['mailbox']      = $newnums[$i_new_key]."@".$this->voice_context;
788                 $sip_data_array['md5secret']    = NULL;
789                 $sip_data_array['nat']          = "no";
790                 $sip_data_array['permit']       = NULL;
791                 $sip_data_array['deny']         = NULL;
792                 $sip_data_array['mask']         = NULL;
793                 $sip_data_array['pickupgroup']  = NULL;
794                 $sip_data_array['port']         = NULL;
795                 $sip_data_array['qualify']      = $s_qualify;
796                 $sip_data_array['restrictcid']  = "n";
797                 $sip_data_array['rtptimeout']   = NULL;
798                 $sip_data_array['rtpholdtimeout']=NULL;
799                 $sip_data_array['secret']       = $this->goFonPIN;
800                 $sip_data_array['type']         = $s_type ;
801                 $sip_data_array['username']     = $this->uid;
802                 $sip_data_array['disallow']     = NULL;
803                 $sip_data_array['allow']        = NULL;
804                 $sip_data_array['musiconhold']  = NULL;
805                 $sip_data_array['regseconds']   = NULL;
806                 $sip_data_array['ipaddr']       = $s_ip;
807                 $sip_data_array['regexten']     = NULL;
808                 $sip_data_array['cancallforward']=NULL;
810                 /* There is currently no entry for this user in the sip_users table. 
811                  * We should create one i
812                  */
813                 foreach($sip_data_array as $s_sip_key=>$s_sip_val){
814                     if($s_sip_val === NULL) continue;
815                     $s_sip_values.="'".mysql_real_escape_string($s_sip_val)."',";
816                     $s_sip_keys  .="`".$s_sip_key."`,";
817                 }
818                 $s_sip_values =  preg_replace("/,$/","",$s_sip_values);
819                 $s_sip_keys   =  preg_replace("/,$/","",$s_sip_keys);
821                 /* Add sip entries to mysql queries */
822                 $SQL_query_array[] ="INSERT INTO ".$a_New['SIP_TABLE']." (".$s_sip_keys.") VALUES (".$s_sip_values.");";
823             }
826             /********************** 
827              * Update / Insert Voice mail entry  
828              **********************/
830             $customer_id = $newnums[$i_new_key];
831             $query  = "SELECT id,name,callerid FROM ".$a_New['SIP_TABLE']." WHERE name='".mysql_real_escape_string($this->uid)."';";
832             $rid    = mysql_query($query,$new_connection);
834             @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query, "Receive callerid");
835             $result = mysql_fetch_assoc($rid);
837             $old_customer_id = ""; 
838             if($result){
839                 $old_customer_id = $result['callerid'];
840             }
842             $voice_data_array = array(
843                     "customer_id" => $customer_id,
844                     "mailbox"     => $customer_id,
845                     "password"    => $this->goFonVoicemailPIN,
846                     "fullname"    => $CNname,
847                     "context"     => $this->voice_context,
848                     "email"       => $s_mail);
850             $voice_data_array['pager']   = $this->pager;
852             /* Check if there is already an entry in sip_users for this uid */
853             $query_tmp = "SELECT * FROM ".$a_New['VOICE_TABLE']." WHERE customer_id='".mysql_real_escape_string($old_customer_id)."';\n";
854             $rid = mysql_query($query_tmp,$new_connection);
856             @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query_tmp, "Check if voicemail entry exists");
857             if(mysql_affected_rows($new_connection)){
859                 /********************** 
860                  * Update Voice mail entry  
861                  **********************/
863                 @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"", "<i>Voicemail entry exists, adding updating to queue.</i>");
864                 $result = mysql_fetch_assoc($rid)  ;
866                 foreach($voice_data_array as $name => $value){
867                     if($result[$name] == $value){
868                         unset($voice_data_array[$name]);
869                     }
870                 }
872                 /* Only update entry if there is something to update */
873                 if(count($voice_data_array)){
874                     $query = "UPDATE ".$a_New['VOICE_TABLE']." SET ";
875                     foreach($voice_data_array as $key => $val){
876                         $query.= "".$key."='".$val."',"; 
877                     } 
878                     $query = preg_replace("/,$/","",$query);
879                     $query.= " WHERE customer_id='".mysql_real_escape_string($old_customer_id)."';";
880                     $SQL_query_array[] = $query;
881                 }
882             }else{
884                 /********************** 
885                  * Insert Voice mail entry  
886                  **********************/
887                 @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"", "<i>No voicemail entry found, add 'create' to queue.</i>");
888                 $voice_data_array['context'] = $this->voice_context;
890                 /* There is currently no voice mail entry for this user. 
891                  * We should create one 
892                  */
893                 $s_voi_values = $s_voi_keys = "";
894                 foreach($voice_data_array as $s_voi_key=>$s_voi_val){
895                     if($s_voi_val === NULL) continue;
896                     $s_voi_values.="'".mysql_real_escape_string($s_voi_val)."',";
897                     $s_voi_keys  .="`".$s_voi_key."`,";
898                 }
899                 $s_voi_values =  preg_replace("/,$/","",$s_voi_values);
900                 $s_voi_keys   =  preg_replace("/,$/","",$s_voi_keys);
902                 /* Add sip entries to mysql queries */
903                 $SQL_query_array[] ="INSERT INTO ".$a_New['VOICE_TABLE']." (".$s_voi_keys.") VALUES (".$s_voi_values.");";
904             }
907             /********************** 
908              * Remove/Insert extension entries
909              **********************/
911             /* Initiate transaction 
912              */
913             $SQL_query_array[]= "DELETE FROM ".$a_New['EXT_TABLE']." WHERE exten=\"".mysql_real_escape_string($this->uid)."\";";
914             $oldnums= array();
915             foreach($oldnums as $s_telenums){
916                 $SQL_query_array[]= "DELETE FROM ".$a_New['EXT_TABLE']." WHERE exten=\"".mysql_real_escape_string($s_telenums)."\";";
917             }
918             foreach($newnums as $s_telenums){
919                 $SQL_query_array[]= "DELETE FROM ".$a_New['EXT_TABLE']." WHERE exten=\"".mysql_real_escape_string($s_telenums)."\";";
920             }
922             /********************** 
923              * Insert extension entries
924              **********************/
926             // Get selected Macro Parameter and create parameter entry 
927             if(isset($this->macroarray[$this->macro])){
928                 foreach($this->macroarray[$this->macro] as $key => $val ){
929                     $s_parameter .= $val['choosen']."|";
930                 }
931                 $s_parameter = preg_replace("/\|$/","",$s_parameter);
932             }
934             $i = 0; 
935             $EXT = array();
936             if(!is_numeric($this->uid)){
937                 $EXT[$i]['context'] = 'GOsa';
938                 $EXT[$i]['exten']   = $this->uid;
939                 $EXT[$i]['priority']= 1;
940                 $EXT[$i]['app']     = "Goto";
941                 $EXT[$i]['appdata'] = $newnums[$i_new_key]."|1";
942                 $i ++;
943             }
945             // Entension entries  Hint / Dial / Goto
946             foreach($newnums as $s_telenums){
948                 /* Hint Entry */
949                 $EXT[$i]['context'] = 'GOsa';
950                 $EXT[$i]['exten']   = $s_telenums;
951                 $EXT[$i]['priority']= 0;
952                 $EXT[$i]['app']     = 'SIP/'.$this->uid;
953                 $i ++;  
954                 /* SetCID */
955                 //$EXT[$i]['context'] = 'GOsa';
956                 //$EXT[$i]['exten']   = $s_telenums;
957                 //$EXT[$i]['priority']= 1;
958                 //$EXT[$i]['app']     = "SetCIDName";
959                 //$EXT[$i]['appdata'] = $CNname;
960                 //$i ++;  
962                 // If no macro is selected use Dial
963                 if($this->macro!="none"){ 
964                     $macroname = preg_replace("/,.*$/","",$this->macro);        
965                     $macroname = preg_replace("/^.*=/","",$macroname);        
966                     $s_app = "Macro";$macroname;
967                     $s_par = $macroname."|".$s_parameter; 
968                 }else{
969                     $s_app = "Dial";
970                     $s_par = 'SIP/'.$this->uid."|20|r";
971                 }
973                 $EXT[$i]['context'] = 'GOsa';
974                 $EXT[$i]['exten']   = $s_telenums;
975                 $EXT[$i]['priority']= 1;
976                 $EXT[$i]['app']     = $s_app;
977                 $EXT[$i]['appdata'] = $s_par;
978                 $i ++;
979             }
981             // Append all these Entries 
982             foreach($EXT as $entr){
983                 $SQL_syn = "INSERT INTO ".$a_New['EXT_TABLE']." (";
984                 foreach($entr as $key2 => $val2){
985                     $SQL_syn.= "`".$key2."`,";
986                 }
987                 $SQL_syn = preg_replace("/,$/","",$SQL_syn);
988                 $SQL_syn .= ") VALUES ("; 
989                 foreach($entr as $key2 => $val2){
990                     $SQL_syn .= "'".mysql_real_escape_string($val2)."',";
991                 }
992                 $SQL_syn = preg_replace("/,$/","",$SQL_syn);
993                 $SQL_syn .=");\n";
995                 $SQL_query_array[] =$SQL_syn;
996                 $SQL_syn ="";
997             }
999             /* Start transaction, to be able to rollback 
1000              */
1001             @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>---Insert/Update new entry---</b>","");
1003             mysql_query("begin;",$new_connection);
1004             @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>begin;</b>","<i>Starting transaction!</i>");
1006             foreach($SQL_query_array as $query){
1007                 @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>".$query."</b>", "");
1008                 if(!mysql_query($query,$new_connection)){
1009                     $err = mysql_error($new_connection);
1010                     @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"\n".$err, "<b>FAILED</b>");
1011                     msg_dialog::display(_("Error"), 
1012                             msgPool::mysqlerror($err,__CLASS__)."&nbsp;".
1013                             "\n<p>"._("Please activate debugging for details!")."</p>",
1014                             ERROR_DIALOG);
1016                     mysql_query("rollback;",$new_connection);
1017                     @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>rollback;</b>", "<b>ERROR</b> Rollback transaction!");
1018                     @mysql_close($new_connection);
1019                     return(false);
1020                 } 
1021             }
1023             /* Let changes get active, everything was fine;
1024              */ 
1025             mysql_query("commit;",$new_connection);
1026             @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>commit;</b>", "Perform transaction!");
1027             @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>---Transaction sucessful!---</b>", "");
1028         }
1029         @mysql_close($new_connection);
1030         return true;
1031     }
1034     function execute()
1035     {
1036         /* Call parent execute */
1037         plugin::execute();
1039         /* Log view */
1040         if($this->is_account && !$this->view_logged){
1041             $this->view_logged = TRUE;
1042             new log("view","users/".get_class($this),$this->dn);
1043         }
1045         $display = "";
1046         $SkipWrite = (!isset($this->parent) || !$this->parent) && !session::is_set('edit');
1048         if(empty($this->macro)&&(!empty($this->goFonMacro))){
1050             /* Go through already saved values, for a parameter */
1051             $tmp = explode("!",$this->goFonMacro);
1053             /* it is possible that nothing has been saved yet */
1054             if(is_array($tmp)){
1056                 /* First value is the macroname */
1057                 $this->macro = $tmp[0];
1059                 /* Macroname saved, delete that index */
1060                 unset($tmp[0]);
1062                 /* Check if macro has been removed */
1063                 if(!isset($this->macroarray[$this->macro])){
1064                     $this->macrostillavailable = false;
1065                 }else{
1066                     $this->macrostillavailable = true;
1067                 }
1069                 /* for each parametervalues ( parameterID#value like 25#twentyfive) */
1070                 foreach($tmp as $var){
1072                     /* Split this, so we have $varar[0] = parameterID $varar[1] = SelectedValue */
1073                     $varar = explode("#",$var);
1075                     /* Only insert if the parameter still exists */
1076                     if(isset($this->macroarray[$this->macro][$varar[0]])){
1077                         /* Assign value */
1078                         $this->macroarray[$this->macro][$varar[0]]['choosen']=$varar[1];
1079                     }
1080                 }
1081             }
1082         }
1084         /* Do we represent a valid account? */
1085         if (!$this->is_account && $this->parent === NULL){
1086             $display= "<img alt=\"\" src=\"images/small-error.png\" align=\"middle\">&nbsp;<b>".
1087                 msgPool::noValidExtension(_("Phone"))."</b>";
1088             $display.= back_to_main();
1089             return ($display);
1090         }
1092         /* Do we need to flip is_account state? */
1093         if (isset($_POST['modify_state'])){
1094             $this->is_account= !$this->is_account;
1095         }
1097         /* Do we represent a valid account? */
1098         if (!$this->is_account && $this->parent === NULL){
1099             $display= "<img alt=\"\" src=\"images/small-error.png\" align=\"middle\">&nbsp;<b>".
1100                 msgPool::noValidExtension(_("Phone"))."</b>";
1101             $display.= back_to_main();
1102             return($display);
1103         }
1105         $display= "";
1107         /* Show tab dialog headers */
1109         if (!$this->multiple_support_active && $this->parent !== NULL){
1110             if ($this->is_account){
1111                 $display= $this->show_disable_header(_("Remove phone account"),
1112                         msgPool::featuresEnabled(_("Phone")));
1113             } else {
1114                 if(empty($this->uid)){
1115                     $display= $this->show_enable_header(_("Create phone account"),
1116                             msgPool::featuresDisabled(_("Phone"),_("User UID")));
1117                 }else{
1118                     $display= $this->show_enable_header(_("Create phone account"),
1119                             msgPool::featuresDisabled(_("Phone")));
1120                 }
1121                 return ($display);
1122             }
1123         }
1124         /* Select no macro if, state is empty, this is the case, if the selected macro is no longer available */
1125         if(empty($this->macro)){
1126             $this->macro ="none";
1127         }
1129         /* Prepare templating */
1130         $smarty= get_smarty();
1132         /* tell user that the selected plugin is no longer available */
1133         if((!$this->macrostillavailable)&&($this->macro!="none")){
1134             msg_dialog::display(_("Error"), _("Selected macro is not available anymore!"), ERROR_DIALOG);
1135         }
1137         /* Assing macroselectbox values  */
1138         $smarty->assign("macros",set_post($this->macros));   
1139         $smarty->assign("macro", set_post($this->macro));   
1141         /* Assign contexts */
1142         $smarty->assign("voicemail_contexts",  set_post($this->voicemail_contexts));
1143         $smarty->assign("sip_contexts",        set_post($this->sip_contexts));
1144         $smarty->assign("context" ,            set_post($this->context));
1145         $smarty->assign("voice_context" ,      set_post($this->voice_context));
1147         /* check if there is a FON server created */
1148         if(!count($this->goFonHomeServer)){
1149             msg_dialog::display(_("Configuration error"), msgPool::noserver(_("GOfon")), WARNING_DIALOG);
1150         }
1152         /* Create html parameter table for selected macro parameters 
1153          *  skip if no parameters given 
1154          */
1155         if(!isset($this->macroarray[$this->macro])){
1156             $macrotab="";
1157         }else{
1159             $macrotab ="<table summary=\""._("Parameter")."\">";
1160             /* for every single parameter-> display textfile,combo, or true false switch*/
1162             foreach($this->phoneNumbers as $phonenum){
1163                 $tmp[] = $phonenum;
1164             }
1166             if($this->macro != $this->lastmacro){
1167                 /* Go through all params */
1168                 foreach($this->macroarray[$this->macro] as $key => $paras){
1170                     $string = $paras['default'];
1172                     $string=preg_replace("/%uid/i",$this->uid,$string);
1173                     $string=preg_replace("/%pager/i",$this->pager,$string);
1174                     $string=preg_replace("/%context/i",$this->context,$string);
1175                     $string=preg_replace("/%voicemailcontext/i",$this->voice_context,$string);
1177                     if(isset($this->cn)){
1178                         $string=preg_replace("/%cn/i",$this->cn,$string);
1179                     }
1181                     for($i = 0 ; $i < 10; $i++){
1182                         if(isset($tmp[$i])){
1183                             $string = preg_replace("/%telephoneNumber_".($i+1)."/i",$tmp[$i],$string);
1184                         }
1185                     }
1186                     if(isset($tmp[0])){
1187                         $string = preg_replace("/%telephoneNumber/i",$tmp[0],$string);
1188                     }
1189                     $this->macroarray[$this->macro][$key]['choosen']=$string;
1190                 }
1191             }
1193             foreach($this->macroarray[$this->macro] as $paras){
1195                 /* get al vars */
1196                 $var        = $paras['var'];           
1197                 $name       = $paras['name'];           
1198                 $default    = $paras['default'];
1199                 $type       = $paras['type'];
1200                 $choosen    = $paras['choosen'] ; 
1201                 $str        = $default;
1203                 $dis = "";
1204                 if(!$this->acl_is_writeable("goFonMacro",$SkipWrite)){
1205                     $dis = " disabled ";
1206                 }
1208                 /* in case of a combo box display a combobox with selected attr */
1209                 $macrotab.= "<tr>";
1210                 switch ($type){
1212                     case "combo":{
1213                         $str= "<select name='".$var."' ".$dis." >";
1214                         foreach(explode(":",$default) as $choice){
1215                             if($choosen==$choice){
1216                                 $str.= "\n<option value='".$choice."' selected>".$choice."&nbsp;</option>";
1217                             }else{
1218                                 $str.= "\n<option value='".$choice."'>".$choice."&nbsp;</option>";
1219                             }
1220                         }
1221                         $str.="</select>";
1222                         $macrotab.= "<td style='vertical-align: middle;'>".base64_decode($name)."&nbsp;</td><td>$str";
1223                         break;
1224                     }
1226                     case "bool":{
1227                         if(!$choosen){
1228                             $str="\n<input type='checkbox' name='".$var."' value='1' ".$dis." >";
1229                         }else{
1230                             $str="\n<input type='checkbox' name='".$var."' value='1' checked  ".$dis.">";
1231                         }
1232                         $macrotab.= "<td style='vertical-align: middle;'colspan='2'>$str&nbsp;".base64_decode($name)."";
1233                         break;
1234                     }
1236                     case "string": {
1237                         $str="<input type='text' name='".$var."' value='".set_post($choosen)."' ".$dis." style='width:340px;'>";
1238                         $macrotab.= "<td style='vertical-align: middle;'>".base64_decode($name)."&nbsp;</td><td>$str";
1239                         break;  
1240                     }
1242                 }
1243                 $macrotab.= "</td></tr>";
1245             }
1246             $macrotab.="</table><input name='post_success' type='hidden' value='1'>";
1247         }//is_array()
1249         /* Give smarty the table */
1250         $smarty->assign("macrotab",$macrotab);
1253         /* Add phone number */
1254         if (isset($_POST["add_phonenumber"]) && $_POST['phonenumber']){
1256             if(strlen(trim($_POST["phonenumber"])) > 20 ){
1257                 msg_dialog::display(_("Error"), msgPool::toobig("Phone number"), ERROR_DIALOG);
1258             }elseif (tests::is_phone_nr($_POST['phonenumber'])){
1259                 $number= trim(get_post("phonenumber"));
1260                 $this->phoneNumbers[$number]= $number;
1261                 $this->is_modified= TRUE;
1262             } else {
1263                 msg_dialog::display(_("Error"), msgPool::invalid("Phone number"), ERROR_DIALOG);
1264             }
1265         }
1267         /* Remove phone number */
1268         if (isset($_POST["delete_phonenumber"]) && isset($_POST["phonenumber_list"])){
1269             foreach ($_POST['phonenumber_list'] as $number){
1270                 unset($this->phoneNumbers[$number]);
1271                 $this->is_modified= TRUE;
1272             }
1273         }
1275         /* Assign acls */
1276         $tmp = $this->plInfo();
1277         foreach($tmp['plProvidedAcls'] as $name => $translation){
1278             $smarty->assign($name."ACL",$this->getacl($name,$SkipWrite));
1279         }
1281         /* Transfer ACL's */
1282         foreach($this->attributes as $val){
1283             if(isset($this->$val)){
1284                 $smarty->assign($val,set_post($this->$val));
1285             }else{
1286                 $smarty->assign($val,"");
1287             }
1288         }
1290         /* Create home server array */
1291         $tmp = array();
1292         foreach($this->goFonHomeServers as $dn => $attrs){
1293             if(!is_numeric($dn)){
1294                 $tmp[$dn] = $attrs['SERVER'];
1295             }
1296         }
1297         $smarty->assign("goFonHomeServers", set_post($tmp));
1299         /* Fill arrays */
1300         $smarty->assign ("goFonHardware", set_post($this->goFonHardware));
1301         if (!count($this->phoneNumbers)){
1302             $smarty->assign ("phoneNumbers", array());
1303         } else {
1304             $smarty->assign ("phoneNumbers", set_post($this->phoneNumbers));
1305         }
1307         $dis = "";
1308         if(!$this->acl_is_writeable("goFonHardware",$SkipWrite)){
1309             $dis= " disabled ";
1310         }
1311         $hl= "<select size=\"1\" name=\"goFonHardware\" ".$dis." title=\"".
1312             _("Choose your private phone")."\">\n";
1314         foreach ($this->hardware_list as $cn => $description){
1315             if ($cn == $this->goFonHardware){
1316                 $selected= "selected";
1317             } else {
1318                 $selected= "";
1319             }
1320             if (isset($this->used_hardware[$cn])){
1321                 $color= "style=\"color:#A0A0A0\"";
1322             } else {
1323                 $color= "";
1324             }
1325             $hl.= "  <option $color label=\"$cn\" value=\"".set_post($cn)."\" $selected>".$description."&nbsp;</option>\n";
1326         }
1327         $hl.= "</select>\n";
1328         $smarty->assign ("hardware_list", $hl);
1331         foreach($this->attributes as $attr){
1332             if(in_array($attr,$this->multi_boxes)){
1333                 $smarty->assign("use_".$attr,TRUE);
1334             }else{
1335                 $smarty->assign("use_".$attr,FALSE);
1336             }
1337         }
1339         foreach(array("goFonVoiceMailContext","goFonContext") as $attr){
1340             if(in_array($attr,$this->multi_boxes)){
1341                 $smarty->assign("use_".$attr,TRUE);
1342             }else{
1343                 $smarty->assign("use_".$attr,FALSE);
1344             }
1345         }
1347         /* Show main page */
1348         $this->lastmacro = $this->macro;
1349         $smarty->assign("multiple_support",$this->multiple_support_active);
1350         $display.= $smarty->fetch(get_template_path('generic.tpl', TRUE, dirname(__FILE__)));
1351         return($display);
1352     }
1355     function save_object()
1356     {
1357         $SkipWrite = (!isset($this->parent) || !$this->parent) && !session::is_set('edit');
1358         if (isset($_POST["phoneTab"])){
1360             plugin::save_object();
1362             /* Save checkbox */
1363             $tmp = preg_replace("/[^a-z]/i","",$this->goFonDeliveryMode);
1364             //     if($this->acl_is_writeable("goFonDeliveryMode",$SkipWrite)){
1365             //       if(isset($_POST['fon_to_mail']) && !preg_match("/M/",$this->goFonDeliveryMode)){
1366             //         $tmp .= "M";
1367             //       }elseif(!isset($_POST['fon_to_mail']) && preg_match("/M/",$this->goFonDeliveryMode)){
1368             //         $tmp  = preg_replace ("/M/","",$tmp);
1369             //       }
1370             //     }
1371             $this->goFonDeliveryMode= "[".$tmp."]";
1374             /* Every macro in the select box are available */
1375             if((isset($_POST['selectedMacro']))){
1376                 $this->macro = get_post('selectedMacro');
1377                 $this->macrostillavailable=true;
1378             }
1380             if(isset($_POST['macro']) && $_POST['macro'] != $this->macro){
1381                 $this->is_modified =true;
1382             }
1384             /* Save context */
1385             if(isset($_POST['context'])){
1386                 if($this->context != get_post('context')){
1387                     $this->is_modified= TRUE;
1388                 }
1389                 $this->context= get_post('context');
1390             }
1392             /* Save voice context */
1393             if(isset($_POST['voice_context'])){
1394                 if($this->voice_context != get_post('voice_context')){
1395                     $this->is_modified= TRUE;
1396                 }
1397                 $this->voice_context= get_post('voice_context');
1398             }
1400             if(is_array($this->phoneNumbers)){
1401                 foreach($this->phoneNumbers as $telenumms) {
1402                     $nummsinorder[]=$telenumms; 
1403                 }
1404             }else{
1405                 $nummsinorder=array("");
1406             }
1409             /* get all Postvars */
1410             if(isset($this->macroarray[$this->macro])){
1413                 if($this->acl_is_writeable("goFonMacro",$SkipWrite)){
1414                     foreach($this->macroarray[$this->macro] as $key => $paras){
1416                         $old_macro_settings = $this->macroarray[$this->macro][$key]; 
1417                         $backup = $this->macroarray[$this->macro][$key];
1419                         if(isset($_POST[$paras['var']])){
1420                             $this->macroarray[$this->macro][$key]['choosen'] = get_post($paras['var']);
1421                         }
1423                         /* Checkboxes are special, they are not Posted if they are not selected, so the won't be changed with the above code
1424                            We need this code below to read and save checkboxes correct
1425                          */
1427                         if(isset($_POST['post_success'])){
1428                             if($this->macroarray[$this->macro][$key]['type']=="bool"){
1429                                 if(isset($_POST[$this->macroarray[$this->macro][$key]['var']])) {
1430                                     $this->macroarray[$this->macro][$key]['choosen']=1;
1431                                 }else{
1432                                     $this->macroarray[$this->macro][$key]['choosen']=0;
1433                                 }
1434                             }
1435                         }
1436                         if(array_differs($old_macro_settings,$this->macroarray[$this->macro][$key])){
1437                             $this->is_modified = TRUE;
1438                         }
1439                     }
1441                     if(count(array_diff($this->macroarray[$this->macro][$key],$backup))){
1442                         $this->is_modified = TRUE;
1443                     }
1444                 }
1445             }
1446         }
1447     }
1449     function check()
1450     {
1451         /* Call common method to give check the hook */
1452         $message= plugin::check();
1454         if(!count($this->goFonHomeServers)){
1455             $message[] = _("There must be at least one server with an asterisk database to create a phone account.");
1456         }
1458         if(empty($this->goFonHomeServer)){
1459             $message[] = msgPool::invalid(_("Home server"));
1460         }
1462         if((strlen($this->goFonVoicemailPIN)==0)||(strlen($this->goFonVoicemailPIN)>4)){
1463             $message[]= msgPool::invalid(_("Voice mail PIN"),"","",_("Between 1-4 characters"));
1464         }else{
1465             if(preg_match("/[^0-9]/",$this->goFonVoicemailPIN)){
1466                 $message[]= msgPool::invalid(_("Voice mail PIN"),preg_replace("/[0-9]/","X",$this->goFonVoicemailPIN),"/X/");
1467             }
1468         }
1470         if(preg_match("/[^0-9a-z]/i",$this->goFonPIN)){
1471             $message[]= msgPool::invalid(_("Phone PIN"),preg_replace("/[0-9a-z]/i","X",$this->goFonPIN),"/X/");
1472         }
1474         if ($this->initially_was_account != $this->is_account || $this->is_modified){
1475             $str = $this->generate_mysql_entension_entries(false);
1476             if(empty($str)){
1477                 msg_dialog::display(_("Error"), $str, ERROR_DIALOG);
1478             }
1479         }
1481         /* We need at least one phone number */
1482         if (count($this->phoneNumbers) == 0){
1483             $message[]= msgPool::required("Phone number");
1484         }
1486         /* Do not allow to save duplicate phone numbers 
1487          *  this may destroy the extensions table.
1488          */ 
1489         $ldap = $this->config->get_ldap_link();
1490         $ldap->cd($this->config->current['BASE']);  
1491         $numberFilter = "";
1492         foreach($this->phoneNumbers as $number){
1493             $numberFilter .= "(telephoneNumber={$number})";
1494         }
1495         $ldap->search("(&(!(uid=".$this->uid."))(objectClass=goFonAccount)(|{$numberFilter}))",array("dn","telephoneNumber"));
1496         $res = array();
1497         while($attrs = $ldap->fetch()){
1498             unset($attrs['telephoneNumber']['count']);
1499             $res = array_merge($res,array_intersect($attrs['telephoneNumber'], $this->phoneNumbers));
1500         }
1501         $res = array_unique($res);
1502         if(count($res)){
1503             $message[] = msgPool::duplicated(_("Phone number"))."&nbsp;<br>".
1504                 implode(array_intersect($res, $this->phoneNumbers), ", ");
1505         }
1507         /* check for ! in any parameter setting*/
1508         if(isset($this->macroarray[$this->macro])){
1509             foreach($this->macroarray[$this->macro] as $val){
1510                 if((strstr($val['choosen'],"!"))||(strstr($val['choosen'],"#"))){
1511                     $message[] = msgPool::invalid(sprintf(_("macro parameter %s"),$val['name']),$val['choosen'],"/[^\#]/");
1512                 }
1513             }
1514         }
1515         return ($message);
1516     }
1520     function save()
1521     {
1522         plugin::save();
1524         /* Force saving macro again 
1525          * This ensures that 
1526          *  - the macro is available on the destiantion server.
1527          *  - the macro saved is up to date on the destination server.
1528          */
1529         if(!empty($this->macro) && $this->macro != "none")  {
1530             $macro_tab= new macrotabs($this->config,$this->config->data['TABS']['MACROTABS'], $this->macro,"gofonmacro");
1531             $macro_tab -> save();
1532         }
1534         /* Save arrays */
1535         $tmp_numbers = array();
1536         foreach ($this->phoneNumbers as $number){
1537             $tmp_numbers[] = $number;
1538         }
1540         /* Save settings, or remove goFonMacro attribute*/
1541         if($this->macro!="none"){    
1542             $this->attrs['goFonMacro']=$this->macro;
1543             if(isset($this->macroarray[$this->macro])){
1544                 foreach($this->macroarray[$this->macro] as $paras)  {
1545                     $this->attrs['goFonMacro'].="!".$paras['id']."#".$paras['choosen'];
1546                 }
1547             }
1548         }else{
1549             $this->attrs['goFonMacro']=array();
1550         }
1551         unset($this->attrs['macro'])  ;
1553         $this->attrs['goFonForwarding']=array();
1555         /*
1556          */
1557         $str = $this->generate_mysql_entension_entries(true);
1558         if(!$str){
1559             msg_dialog::display(_("Error"),_("An error occurred while updating the database entries!") , ERROR_DIALOG);
1560         }
1562         if($this->attrs['goFonMacro']==""){
1563             $this->attrs['goFonMacro']=array();
1564         }
1566         unset($this->attrs['cn']);
1568         /* Write back to ldap */
1569         $ldap= $this->config->get_ldap_link();
1570         $ldap->cd($this->dn);
1571         $this->cleanup();
1573         /* Force saving numbers, else it will be overwriten by user account. */
1574         $this->attrs['telephoneNumber'] =$tmp_numbers;
1575         $ldap->modify ($this->attrs); 
1577         /* Log last action */
1578         if($this->initially_was_account){
1579             new log("modify","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
1580         }else{
1581             new log("create","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
1582         }
1584         if (!$ldap->success()){
1585             msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, 0, get_class()));
1586         }
1588         /* Optionally execute a command after we're done */
1590         if ($this->initially_was_account == $this->is_account){
1591             if ($this->is_modified){
1592                 $this->handle_post_events("modify",array("uid" => $this->uid));
1593             }
1594         } else {
1595             $this->handle_post_events("add",array("uid" => $this->uid));
1596         }
1598     }
1601     function adapt_from_template($dn, $skip= array())
1602     {
1603         plugin::adapt_from_template($dn, $skip);
1605         /* Assemble phone numbers */
1606         if (isset($this->attrs['telephoneNumber']) && !in_array("telephoneNumber", $skip)){
1607             for ($i= 0; $i<$this->attrs['telephoneNumber']['count']; $i++){
1608                 $number= $this->attrs['telephoneNumber'][$i];
1609                 $this->phoneNumbers[$number]= $number;
1610             }
1611         }
1612     }
1615     function remove_from_parent()
1616     {
1617         if(!$this->initially_was_account) return;
1619         // Check for MySQL extension
1620         if(!is_callable("mysql_pconnect")){
1621             msg_dialog::display(_("Configuration error"), msgPool::missingext("php-mysql"), WARNING_DIALOG);
1622             return(FALSE);
1623         }
1625         // Check if we've at least one Home-Server
1626         if(!count($this->goFonHomeServers)){
1627             msg_dialog::display(_("Configuration error"), msgPool::noserver(_("GOfon")), WARNING_DIALOG);
1628             return false;
1629         }
1631         if(empty($this->init_HomeServer)) return;
1634         // -------- REMOVE from MySQL
1636         // Get Configuration for initial Mysql database Server
1637         $a_SETUP = $this->goFonHomeServers[$this->init_HomeServer];
1638         $s_parameter  ="";
1640         /* Check table definitions
1641          */
1642         if(!phoneAccount::checkRealtimeTables($a_SETUP)){
1643             msg_dialog::display(_("Warning"),
1644                     sprintf(_("GOsa identified problems with your MySQL table definition!")),
1645                     WARNING_DIALOG);
1646         }
1648         // Connect to DB server
1649         $r_con =  @mysql_pconnect($a_SETUP['SERVER'],$a_SETUP['LOGIN'],$a_SETUP['PASSWORD']);
1651         // Check if we are  connected correctly
1652         if(!$r_con){
1653             msg_dialog::display(_("Error"), msgPool::dbconnect("GOfon",@mysql_error()), ERROR_DIALOG);
1654             new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error());
1655             return false;
1656         }
1658         // Select database for Extensions
1659         $db  =  @mysql_select_db($a_SETUP['DB'],$r_con);
1661         // Test if we have the database selected correctly
1662         if(!$db){
1663             msg_dialog::display(_("Error"), msgPool::dbselect("GOfon", @mysql_error()), ERROR_DIALOG);
1664             new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error());
1665             return false;
1666         }
1668         $SQL="";
1669         $SQL[]= "SET @@sql_mode = STRICT_ALL_TABLES;";
1671         $first_num = false;
1672         // Delete old entries
1673         foreach($this->a_old_telenums as $s_telenums){
1674             if(!$first_num){
1675                 $first_num = $s_telenums;
1676             }
1677             $SQL[] = "DELETE FROM ".$a_SETUP['EXT_TABLE']." WHERE exten='".mysql_real_escape_string($s_telenums)."';\n";
1678         }
1681         $query  = "SELECT id,name,callerid FROM ".$a_SETUP['SIP_TABLE']." WHERE name='".mysql_real_escape_string($this->uid)."';";
1682         $rid    = mysql_query($query,$r_con);
1683         @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query, "Database query");
1684         $result = mysql_fetch_assoc($rid);
1685         $callerid = $first_num;
1686         if($result){
1687             $callerid = $result['callerid'];
1688         }
1690         /* Set mode to strict
1691            Strict disallows the addition of entries that do not match the targets field length.
1692          */
1693         $SQL[] = "DELETE FROM ".$a_SETUP['VOICE_TABLE']." WHERE customer_id='".mysql_real_escape_string($callerid)."';";
1694         $SQL[] = "DELETE FROM ".$a_SETUP['EXT_TABLE']." WHERE exten='".mysql_real_escape_string($this->uid)."';\n";
1695         $SQL[] = "DELETE FROM ".$a_SETUP['SIP_TABLE']." WHERE name='".mysql_real_escape_string($this->uid)."';\n";
1697         /* Start transaction, to be able to rollback
1698          */
1699         @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>---Removing entry from server---</b>","");
1701         mysql_query("begin;",$r_con);
1702         @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>begin;</b>","<i>Starting transaction!</i>");
1704         foreach($SQL as $query){
1705             @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>".$query."</b>", "");
1707             if(!mysql_query($query,$r_con)){
1708                 $err = mysql_error($r_con);
1709                 @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"\n".$err, "<b>FAILED</b>");
1710                 msg_dialog::display(_("Error"),
1711                         msgPool::mysqlerror($err,__CLASS__)."&nbsp;".
1712                         "\n<p>"._("Please activate debugging for details!")."</p>",
1713                         ERROR_DIALOG);
1715                 mysql_query("rollback;",$r_con);
1716                 @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>rollback;</b>", "<b>ERROR</b> Rollback transaction!");
1717                 @mysql_close($r_con);
1718                 return(false);
1719             }
1720         }
1722         /* Let changes get active, everything was fine;
1723          */
1724         mysql_query("commit;",$r_con);
1725         @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>commit;</b>", "");
1726         @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>---Transaction sucessful!---</b>", "");
1729         // -------- REMOVE from LDAP
1731         /* unset macro attr, it will cause an error */
1732         $tmp = array_flip($this->attributes);
1733         unset($tmp['macro']);
1734         $this->attributes=array_flip($tmp);
1736         plugin::remove_from_parent();
1738         /* Just keep one phone number */
1739         if (count($this->telephoneNumber) && $this->telephoneNumber != ""){
1740             $this->attrs['telephoneNumber']= $this->telephoneNumber;
1741         } else {
1742             $this->attrs['telephoneNumber']= array();
1743         }
1746         $ldap= $this->config->get_ldap_link();
1747         $ldap->cd($this->config->current['BASE']);
1748         $ldap->search("(&(objectClass=goFonQueue)(member=*))", array("member"));
1749         while($attr = $ldap->fetch()){
1750             if(in_array($this->dn,$attr['member'])){
1751                 $new =new ogrouptabs($this->config, $this->config->data['TABS']['OGROUPTABS'],$attr['dn']);
1752                 unset($new->by_object['ogroup']->memberList[$this->dn]);
1753                 unset($new->by_object['ogroup']->member[$this->dn]);
1754                 $new->save();
1755                 msg_dialog::display(_("Information"), sprintf(_("User '%s' has been removed from phone queue '%s'."), $this->cn, $new->by_object['ogroup']->cn), INFO_DIALOG);
1756             }
1757         }
1758         $ldap->cd($this->dn);
1759         $this->cleanup();
1760         $ldap->modify ($this->attrs); 
1762         new log("remove","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
1763         if (!$ldap->success()){
1764             msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
1765         }
1767         /* Optionally execute a command after we're done */
1768         @mysql_close($r_con);
1769         $this->handle_post_events('remove',array("uid"=> $this->uid));
1770     }
1774     /* This function checks if the given phonenumbers are available or already in use*/
1775     function is_number_used()
1776     {
1777         $ldap= $this->config->get_ldap_link();
1778         $ldap->cd($this->config->current['BASE']);
1779         $ldap->search("(|(objectClass=goFonAccount)(objectClass=goFonQueue)(objectClass=goFonConference))", array("telephoneNumber","cn","uid"));
1780         while($attrs = $ldap->fetch()) {
1781             unset($attrs['telephoneNumber']['count']);
1782             foreach($attrs['telephoneNumber'] as $tele){
1783                 if(!isset($attrs['cn'][0])) $attrs['cn'][0]=$attrs['dn'];
1784                 if(!isset($attrs['uid'][0])) $attrs['uid'][0]=$attrs['dn'];
1785                 $numbers[$tele]=$attrs;
1786             }
1787         }
1789         foreach($this->phoneNumbers as $num){
1790             if((isset($numbers[$num]))&&(($numbers[$num]['uid'][0]!=$this->uid))){
1791                 if(isset($numbers[$num]['uid'][0])){
1792                     return sprintf(_("The specified telephone number '%s' is already assigned to '%s'."),$num,$numbers[$num]['uid'][0]);
1793                 }else{
1794                     return sprintf(_("The specified telephone number '%s' is already assigned to '%s'."),$num,$numbers[$num]['cn'][0]);
1795                 }
1796             }
1797         }
1798     }
1801     /* Create phoneAccount part of copy & paste dialog */
1802     function getCopyDialog()
1803     { 
1804         if(!$this->is_account) return("");
1805         $smarty = get_smarty();
1806         if (!count($this->phoneNumbers)){
1807             $smarty->assign ("phoneNumbers", array(""));
1808         } else {
1809             $smarty->assign ("phoneNumbers", set_post($this->phoneNumbers));
1810         }
1812         $smarty->assign("goFonVoicemailPIN",set_post($this->goFonVoicemailPIN));
1813         $smarty->assign("goFonPIN",set_post($this->goFonPIN));
1815         $display= $smarty->fetch(get_template_path('paste_generic.tpl', TRUE, dirname(__FILE__)));
1816         $ret =array();
1817         $ret['string'] = $display;
1818         $ret['status'] = "";
1819         return($ret);
1820     }
1822     /* Save posts from copy & paste dialog dialog  */
1823     function saveCopyDialog()
1824     {
1825         if(!$this->is_account) return;
1826         $this->execute();
1827         if(isset($_POST['goFonVoicemailPIN'])) {
1828             $this->goFonVoicemailPIN = get_post('goFonVoicemailPIN');
1829         }
1830         if(isset($_POST['goFonPIN'])){
1831             $this->goFonPIN = get_post('goFonPIN');
1832         }
1833     }
1836     function allow_remove()
1837     {
1838         /* Check if previously selected server is still available */
1839         if($this->initially_was_account && !isset($this->goFonHomeServers[$this->goFonHomeServer])){
1840             return sprintf(_("The previously selected asterisk home server (%s) is no longer available. Remove aborted."),preg_replace("/,/",", ",$this->goFonHomeServer));
1841         }
1842     }
1844     /* Return plugin informations for acl handling */
1845     static function plInfo()
1846     {
1847         return (array(
1848                     "plShortName"     => _("Phone"),
1849                     "plDescription"   => _("Phone account settings"),
1850                     "plSelfModify"    => TRUE,
1851                     "plDepends"       => array("user"),
1852                     "plPriority"      => 7,                                 // Position in tabs
1853                     "plSection"         => array("personal" => _("My account")),
1854                     "plCategory"        => array("users"),
1857                     "plOptions"       => array(),
1858                     "plRequirements"=> array(
1859                         'ldapSchema' => array('goFonAccount' => '>=2.7'),
1860                         'onFailureDisablePlugin' => array(get_class(),'phoneAccount','phoneConferenceManagment','goFonMacro')
1861                         ),
1863                     "plProvidedAcls"  => array(
1864                         "telephoneNumber"     => _("Telephone number"),
1865                         "goFonMacro"          => _("Macro settings"),
1866                         "goFonHardware"       => _("Phone hardware"),
1867                         "goFonHomeServer"     => _("Home server"),
1868                         "goFonContext"          => _("Phone context"),
1869                         "goFonVoiceMailContext" => _("Voice mail context"),
1870                         "goFonPIN"            => _("Telephone PIN"),
1871                         "goFonVoicemailPIN"   => _("Voice mail PIN"))
1872                         ));
1873     }
1877     function multiple_execute()
1878     {
1879         plugin::multiple_execute();
1880         return($this->execute());
1881     }
1883     function get_multi_init_values()
1884     {
1885         $ret = plugin::get_multi_init_values();
1886         $ret['phoneNumbers'] = array();
1887         foreach($this->phoneNumbers as $number){
1888             $ret['phoneNumbers'][] = $number."  [".$this->attrs['cn'][0]."]"; 
1889         }
1890         $ret['phoneNumbers']['count'] = count($ret['phoneNumbers']);
1891         return($ret);
1892     }
1894     function init_multiple_support($attrs,$all)
1895     {
1896         plugin::init_multiple_support($attrs,$all);
1898         $this->phoneNumbers = array();
1899         if(isset($all['phoneNumbers'])){
1900             for($i = 0 ; $i < $all['phoneNumbers']['count'] ; $i++){
1901                 $this->phoneNumbers[$all['phoneNumbers'][$i]] = $all['phoneNumbers'][$i];
1902             }
1903         }
1904     }
1906     function multiple_save_object()
1907     {
1908         /* Simply call parents save_object */
1909         if (isset($_POST["phoneTab"])){
1911             plugin::save_object();
1912             plugin::multiple_save_object();
1914             /* Every macro in the select box are available */
1915             if((isset($_POST['macro']))){
1916                 $this->macrostillavailable=true;
1917             }
1919             if(isset($_POST['macro']) && $_POST['macro'] != $this->macro){
1920                 $this->macro = get_post('macro');
1921                 $this->is_modified =true;
1922             }
1924             /* get all Postvars */
1925             if(isset($this->macroarray[$this->macro])){
1926                 foreach($this->macroarray[$this->macro] as $key => $paras){
1927                     $backup = $this->macroarray[$this->macro][$key];
1928                     if(isset($_POST[$paras['var']])){
1929                         $this->macroarray[$this->macro][$key]['choosen'] = get_post($paras['var']);
1930                     }
1931                     if(isset($_POST['post_success'])){
1932                         if($this->macroarray[$this->macro][$key]['type']=="bool"){
1933                             if(isset($_POST[$this->macroarray[$this->macro][$key]['var']])) {
1934                                 $this->macroarray[$this->macro][$key]['choosen']=get_post($paras['var']);
1935                             }else{
1936                                 $this->macroarray[$this->macro][$key]['choosen']=false;
1937                             }
1938                         }
1939                     }
1940                 }
1941                 if(count(array_diff($this->macroarray[$this->macro][$key],$backup))){
1942                     $this->is_modified = TRUE;
1943                 }
1944             }
1945         }
1946     }
1948     function multiple_check()
1949     {
1950         $message = plugin::multiple_check();
1952         if(!count($this->goFonHomeServers) && in_array("goFonHomeServers",$this->multi_boxes)){
1953             $message[] = _("There is currently no asterisk server defined!");
1954         }
1956         if(empty($this->goFonHomeServer) && in_array("goFonHomeServers",$this->multi_boxes)){
1957             $message[] = _("Asterisk server is invalid!");
1958         }
1960         if(in_array("goFonVoicemailPIN",$this->multi_boxes) && 
1961                 ( (strlen($this->goFonVoicemailPIN)==0)||
1962                   (strlen($this->goFonVoicemailPIN)>4))){
1963             $message[]=(_("Voice mail PIN must be 4 characters long!"));
1964         }else{
1965             if(preg_match("/[^0-9]/",$this->goFonVoicemailPIN) && in_array("goFonVoicemailPIN",$this->multi_boxes) ){
1966                 $message[]=(_("Voice mail PIN contains invalid characters!"));
1967             }
1968         }
1970         if(preg_match("/[^0-9a-z]/i",$this->goFonPIN) && in_array("goFonPIN",$this->multi_boxes)){
1971             $message[]=(_("Phone PIN contains invalid characters!"));
1972         }
1974         /* check for ! in any parameter setting*/
1975         if(isset($this->macroarray[$this->macro]) && in_array("macro",$this->multi_boxes)){
1976             foreach($this->macroarray[$this->macro] as $val){
1977                 if((strstr($val['choosen'],"!"))||(strstr($val['choosen'],"#"))){
1978                     $message[] = sprintf(_("The parameter %s contains invalid char. '!,#' is used as delimiter"),$val['name']);
1979                 }
1980             }
1981         }
1983         return($message);
1984     }
1986     function get_multi_edit_values()
1987     {
1988         $ret = plugin::get_multi_edit_values();
1989         if(in_array("macro",$this->multi_boxes)){
1990             $ret['macro'] = $this->macro;
1991             $ret['macroarray'] = $this->macroarray;
1992             $ret['macros'] = $this->macros;
1993         }
1994         return($ret);
1995     }
1998     /* Return asterisk contexts
1999      * Additionaly read contexts from file.
2000      */
2001     function get_asterisk_voicemail_contexts()
2002     {
2003         return($this->get_asterisk_contexts(CONFIG_DIR."/asterisk/voicemail_context.conf"));
2004     }
2005     function get_asterisk_sip_contexts()
2006     {
2007         return($this->get_asterisk_contexts(CONFIG_DIR."/asterisk/sip_context.conf"));
2008     }
2009     function get_asterisk_contexts($file)
2010     {
2011         $contexts = array();
2012         if(file_exists($file) && is_readable($file)){
2013             foreach(file($file) as $context){
2014                 $contexts[] = trim($context);
2015             }
2016         }else{
2017             msg_dialog::display(_("Warning"), msgPool::cannotReadFile($file),WARNING_DIALOG);
2018             $contexts[] = "default";
2019         }
2020         array_unique($contexts);
2021         return($contexts);
2022     }
2025 ?>