Code

Maintain international numbers. Closes #860
[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= "This does something";
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           = "default";
36   var $voice_context          = "default";
37   var $voicemail_contexts     = "default";
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      */
114   
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("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("ogroupRDN"),
188         get_ou("serverRDN"),
189         get_ou("terminalRDN"),
190         get_ou("workstationRDN"),
191         get_ou("printerRDN"),
192         get_ou("componentRDN"),
193         get_ou("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("phoneMacroRDN")),
210                   $this->config->current['BASE'],array("displayName","goFonMacroParameter","dn","cn"), GL_NO_ACL_CHECK | GL_SUBSEARCH );
211     
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']))){
248         foreach($attrs['goFonMacroParameter'] as $pkey=>$pval){
249           /* Split Data in readable values, by delimiter !  */
250           $data = explode("!",$attrs['goFonMacroParameter'][$pkey]);
252           /* Set all attrs */
253           $id = $data[0];
254           $this->macroarray[$attrs['dn']][$id]['var']    ="var".$id;
255           $this->macroarray[$attrs['dn']][$id]['choosen']=$data[3]; 
256           $this->macroarray[$attrs['dn']][$id]['id']     =$id;
257           $this->macroarray[$attrs['dn']][$id]['name']   =$data[1];
258           $this->macroarray[$attrs['dn']][$id]['type']   =$data[2];
259           $this->macroarray[$attrs['dn']][$id]['default']=$data[3];
260           if($data[2] == "bool"){
261             $this->macroarray[$attrs['dn']][$id]['choosen']=$data[3];
262           }
263         }//foreach
264       }//is_array
265     }//while
268     /* Parse used Macro  
269      * If we have a macro selected, parse it and set values 
270      *  in $this->macroarray[$this->macro]. 
271      */
272     $tmp = explode("!",$this->goFonMacro);
273     if(is_array($tmp)){
275       /* First value is the macroname */
276       $this->macro = $tmp[0];
278       /* Macroname saved, delete that index */
279       unset($tmp[0]);
281       /* Check if makro has been removed */
282       if(!isset($this->macros[$this->macro])){
283         $this->macrostillavailable = false;
284       }else{
285         $this->macrostillavailable = true;
286       }
288       /* for each parametervalues ( parameterID#value like 25#twentyfive) */
289       foreach($tmp as $var){
291         /* Split this, so we have $varar[0] = parameterID $varar[1] = SelectedValue */
292         $varar = explode("#",$var);
294         /* Only insert if the parameter still exists */
295         if(isset($this->macroarray[$this->macro][$varar[0]])){
296           /* Assign value */
297           $this->macroarray[$this->macro][$varar[0]]['choosen']=$varar[1];
298         }
299       }
300     }
303     $this->a_old_telenums = $this->phoneNumbers;
306     /* Get voicemail PIN from MySQL DB 
307      * Because every user can change his PIN directly from the phone
308      *  without any update to the ldap
309      * This means, the PIN in the DB is up to date
310      */
311     // Connect to DB server
314     $num = key($this->phoneNumbers);
316     if( (is_callable("mysql_pconnect"))&&
317         (isset($cur_cfg))&&
318         (isset($cur_cfg['SERVER']))&&
319         (isset($cur_cfg['LOGIN']))&&
320         (isset($cur_cfg['PASSWORD']))){
322       $r_con =  @mysql_pconnect($cur_cfg['SERVER'],$cur_cfg['LOGIN'],$cur_cfg['PASSWORD']);
323       if($r_con){
325         // Try to select the gophone database
326         $r_db  =  @mysql_select_db($cur_cfg['DB'],$r_con);
327         if(!$r_db){
328           msg_dialog::display(_("Warning"), msgPool::dbselect($cur_cfg['DB'],mysql_error()), WARNING_DIALOG);
329         }
331         $query_tmp = "SELECT ".$cur_cfg['VOICE_TABLE'].".context as 'v_context', 
332                              ".$cur_cfg['SIP_TABLE'].".context, 
333                              ".$cur_cfg['VOICE_TABLE'].".password 
334                        FROM  ".$cur_cfg['VOICE_TABLE'].", 
335                              ".$cur_cfg['SIP_TABLE']." 
336                        WHERE ".$cur_cfg['VOICE_TABLE'].".mailbox = ".$num." 
337                           AND ".$cur_cfg['SIP_TABLE'].".name='".$this->uid."'";
338         $res = mysql_query($query_tmp);
339         $vp  = mysql_fetch_assoc($res);
340         if(!isset($vp['context'])){
341           $this->is_modified= TRUE;
342           msg_dialog::display(_("Warning"), sprintf(_("Cannot identify telephone extension in database, please try to save again.")), WARNING_DIALOG);
343         } 
344  
345         @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query_tmp, "Database query");
346         if((isset($vp['password']))&&(!empty($vp['password']))){
347           $this->goFonPINVoice = $vp['password'];
348         }
349         if((isset($vp['context']))&&(!empty($vp['context']))){
350           $this->context = $vp['context'];
351         }
352         if((isset($vp['v_context']))&&(!empty($vp['v_context']))){
353           $this->voice_context = $vp['v_context'];
354         }
355       }
356     }
357     $this->lastmacro=$this->macro;
359     if(is_callable("mysql_close")&&(isset($r_con))&&($r_con)){
360       @mysql_close($r_con) ;
361     }
362   }
365   /* Transaction will only work with InnoDB tables 
366    */
367   public static function checkRealtimeTables($config)
368   {
369     $ret =TRUE;
371     // Connect to DB server
372     if( (is_callable("mysql_pconnect"))&&
373         (isset($config))&&
374         (isset($config['SERVER']))&&
375         (isset($config['LOGIN']))&&
376         (isset($config['PASSWORD']))){
378       $r_con =  @mysql_pconnect($config['SERVER'],$config['LOGIN'],$config['PASSWORD']);
379       if($r_con){
380         $r_db  =  @mysql_select_db($config['DB'],$r_con);
382         /* Validate Table Type - it must be InnoDB to be able to use transactions 
383          */
384         $inno_tables = array("SIP_TABLE","EXT_TABLE","VOICE_TABLE","QUEUE_TABLE","QUEUE_MEMBER_TABLE"); 
385         foreach($inno_tables as $inno_table){
386           $sql = "show table status like '".$config[$inno_table]."';";
387           $res = mysql_query($sql);
388           $vp  = mysql_fetch_assoc($res);
389           if(!preg_match("/^InnoDB$/i",$vp['Engine'])){
391             /* Not an InnoDB Table type, try to modify type. 
392              */
393             $sql = "ALTER TABLE `".$config[$inno_table]."` ENGINE = INNODB; ";
394             $res = mysql_query($sql);
395             if(!$res){
396               @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>".$sql."</b>", 
397                   "<b>FAILED!</b>. Transactions will not work!");
398               $ret = FALSE;
399             }else{
400               @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>".$sql."</b>", 
401                   "<i>Table '".$config[$inno_table]."' is now of type InnoDB, this enables transactions.</i>");
402             }
403           }else{
404             @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"",
405                 "<i>Table type of '".$config[$inno_table]."' OK, using transactions!</i>");
406           }
407         }
408       }
409     }
410     return($ret);
411   }
414   /* This function generates the Database entries. 
415    * The Parameter 'save' could be true or false.
416    *  false - means only testing no database transactions.
417    *  true  - write database entries.
418    *
419    * 'sip_users','voice_mail' and 'extensions' table entries will be created.
420    * 
421    * If the phone hardware is 'automatic' the table entries will only be removed
422    *  and not added. 
423    */
424   function generate_mysql_entension_entries($save = false)
425   {
426     /* Check if there is at least one server available 
427      * If not, return and tell the user that saving failed 
428      */
429     if(!count($this->goFonHomeServers)){
430       if($save){
431         msg_dialog::display(_("Configuration error"), msgPool::noserver(_("GOfon")), WARNING_DIALOG);
432       }
433       return(true);
434     }
436     /* Check if Mysql extension is available */
437     if(!is_callable("mysql_pconnect")){
438       if($save){
439         msg_dialog::display(_("Configuration error"), msgPool::missingext("php-mysql"), WARNING_DIALOG);
440       }
441       return(true);
442     }
443  
444     /********************** 
445      * Attribute Initialisation
446      **********************/
448     $old_connection = false;
450     // Get Configuration for Mysql database Server
451     $s_parameter    = "";                                           // Contains paramter for selected Macro 
452     $r_con          = false;                                        // DB connection
453     $r_db           = false;                                        // Selected DB
454     $r_res          = false;                                        // Result resource
455     $a_ldap_attrs   = array();                                      //  
457     $s_ip           = NULL;                   // Contains ip for Sip entry
458     $s_host         = NULL;                   // Contains host for Sip entry
459     $s_qualify      = "yes";                  // Qualify entry
460     $s_pin          = NULL;                   // Entry for secret
461     $s_type         = NULL;                   // Entry for phone type (friend , peer ..)
463     $sip_data_array = array();                // Contains complete sip entry, to generate SQL syntax
464     $i_old_key      = false;                  // Contains index for first old phonenumber, to delete old entries corectly
465     $i_new_key      = false;                  // Contains index for first new phonenumber, to generate new  entries corectly
467     $s_sip_values   = "";     // Contains string with all values for given attributes in SQL syntax
468     $s_sip_keys     = "";     // Contains all needed attributes to generate sip entry in DB
470     $s_sip_key      = "";     // Key for SIP entry index      
471     $s_sip_val      = "";     // Value for SIP entry index      
473     $b_first_deleted= false;  // Only delete first entry, 
474     $s_telenums     = "";     // for each value variable
476     $i_is_accounted = false;  // Ensure that extension entry, for name to number is only once in table
478     /* Prepare some basic attributes */
479     $oldnums = array();
481     /* Strip invalid chars, but maintain a leading + for international numbers */
482     $t_tele= preg_replace("/[^0-9]/","",$tele);
483     if (preg_match('/^\+/', $tele)) {
484       $t_tele= "+".$t_tele;
485     }
486     
487     foreach($this->a_old_telenums as $tele){
488       $oldnums[]= $t_tele;
489     }
490     foreach($this->phoneNumbers as $tele){
491       $newnums[]= $t_tele;
492     }
494     if(empty($this->uid)) trigger_error("Uid is empty.");
497     /* Create voicemail entry 
498      */
499     if((!isset($this->cn))||(empty($this->cn))){
500       $CNname= $this->uid;
501     }else{
502       $CNname= $this->cn;
503     }
505     $s_mail = "";
506     if($this->has_mailAccount){
507       $s_mail = $this->mailAddress;;
508     }
510     /* Get phonehardware to setup sip entry  */
511     $ldap         = $this->config->get_ldap_link();
512     $r_res        = $ldap->search("(&(objectClass=goFonHardware)(cn=".$this->goFonHardware."))", array('*'));
513     $a_ldap_attrs = $ldap->fetch();
515     /* Check selected phone hardware, is a default IP set? */
516     if(((isset($a_ldap_attrs['goFonDefaultIP'][0]))&&($a_ldap_attrs['goFonDefaultIP'][0] != "dynamic"))){
517       $s_ip       = $a_ldap_attrs['goFonDefaultIP'][0];
518       $s_host     = $s_ip;
519     }else{
520       $s_ip       = NULL;
521       $s_host     = "dynamic";
522     }
524     // Attribute GoFonQualify set ?
525     if(isset($a_ldap_attrs['goFonQualify'])){
526       $s_qualify = $a_ldap_attrs['goFonQualify'][0];
527     }
529     // Attribute GoFonPIN set ?
530     if(isset($this->goFonPIN)){
531       $s_pin      = $this->goFonPIN;
532     }
534     // Attribute GoFonType set ?
535     if(isset($a_ldap_attrs['goFonType'])){
536       $s_type = $a_ldap_attrs['goFonType'][0];
537     }
539     if(isset($a_ldap_attrs['goFonDmtfMode'][0])){
540       $sip_data_array['dtmfmode']     = $a_ldap_attrs['goFonDmtfMode'][0];
541     }else{
542       $sip_data_array['dtmfmode']     ="rfc2833";
543     }
545     /* Check if phone number is used */
546     if($this->is_number_used()){
547       $this->generate_error = $this->is_number_used(); 
548       return false;
549     }
553     /********************** 
554      * Check Server Connection Information
555      **********************/
556  
557     /* Create Mysql handle for the current goFonHomeServer, if possible  
558      * Get configuration to old asterisk home server 
559      */ 
560     $a_New = $this->goFonHomeServers[$this->goFonHomeServer];  // DB Configuration
561     $new_connection =  @mysql_pconnect($a_New['SERVER'],$a_New['LOGIN'],$a_New['PASSWORD']);
562     if(!$new_connection){
563       $this->generate_error =  msgPool::dbconnect($a_New['SERVER'],@mysql_error($new_connection),
564           _("Abort saving entries to keep the database consistent."));
565       new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error($new_connection));
566       return false;
567     }
568     $new_database  =  @mysql_select_db($a_New['DB'],$new_connection);
569     if(!$new_database){
570       $this->generate_error =  msgPool::dbselect($a_New['DB'],@mysql_error($new_connection),
571           _("Abort saving entries to keep the database consistent."));
572       new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error($new_connection));
573       return false;
574     }
576     /* If the home server has changed, we must remove entries from old 
577      *  server and add new entries in new server.  
578      */
579     if($this->init_HomeServer != $this->goFonHomeServer){
580     
581       /* Get configuration to old asterisk home server */ 
582       $a_Remove = $this->goFonHomeServers[$this->init_HomeServer];  // DB Configuration
583  
584       /* Create connection to the database that contains the old entry. 
585        */
586       $old_connection =  @mysql_pconnect($a_Remove['SERVER'],$a_Remove['LOGIN'],$a_Remove['PASSWORD']);
587       if(!$old_connection){
588         $this->generate_error =  msgPool::dbconnect($a_Remove['SERVER'],@mysql_error($old_connection),
589             _("Abort saving entries to keep the database consistent."));
590         new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error($old_connection));
591         return false;
592       }
593       $old_database  =  @mysql_select_db($a_Remove['DB'],$old_connection);
594       if(!$old_database){
595         $this->generate_error =  msgPool::dbselect($a_Remove['DB'],@mysql_error($old_connection),
596             _("Abort saving entries to keep the database consistent."));
597         new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error($old_connection));
598         return false;
599       }
600     }
603     /* Save means that we must save changes, not only test  */
604     if($save == true){
605     
606       /********************** 
607        * Remove entries from old home server 
608        **********************/
610       /* Check if there is an old entry 
611        * If there is an old entry, get callerid and remove voicemail and extensions 
612        */
613       if($old_connection){
615         /* Check table definitions
616          */
617         if(!phoneAccount::checkRealtimeTables($a_Remove)){
618           msg_dialog::display(_("Warning"),
619               sprintf(_("GOsa identified problems with your MySQL table definition!")),
620               WARNING_DIALOG);
621         }
623         $query  = "SELECT id,name,callerid FROM ".$a_Remove['SIP_TABLE']." WHERE name='".$this->uid."';";
624         $rid    = mysql_query($query,$old_connection);
625         @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query, 
626             "<i>Reguest callerid to be able to identify the user.</i>");
628         /* Old entry found, remove it */
629         $query_a = array();
630         if(mysql_affected_rows($old_connection)){
631           $result = mysql_fetch_assoc($rid);
633           /* Set mode to strict
634              Strict disallows the addition of entries that do not match the targets field length.
635            */
636           $query_a[]= "SET @@sql_mode = STRICT_ALL_TABLES;";
637           $query_a[]= "DELETE FROM ".$a_Remove['SIP_TABLE']." WHERE name='".$this->uid."';";
638           $query_a[]= "DELETE FROM ".$a_Remove['VOICE_TABLE']." WHERE customer_id='".$result['callerid']."';";
639           $query_a[]= "DELETE FROM ".$a_Remove['EXT_TABLE']." WHERE exten='".$this->uid."';";
640           foreach($oldnums as $s_telenums) {
641             $query_a[]= "DELETE FROM ".$a_Remove['EXT_TABLE']." WHERE exten='".$s_telenums."';";
642           }
644           /* Start transaction, to be able to rollback 
645            */
646           @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>---Removing entry from old server---</b>","");
648           mysql_query("begin;",$old_connection);
649           @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>begin;</b>","<i>Starting transaction!</i>");
651           foreach($query_a as $query){
652             @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>".$query."</b>", "");
653             if(!mysql_query($query,$old_connection)){
654               $err = mysql_error($old_connection);
655               @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"\n".$err, "<b>FAILED</b>");
656               msg_dialog::display(_("Error"), 
657                   msgPool::mysqlerror($err,__CLASS__)."&nbsp;".
658                   "\n<p>"._("Please activate debugging for details!")."</p>",
659                   ERROR_DIALOG);
661               mysql_query("rollback;",$old_connection);
662               @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>rollback;</b>", "<b>ERROR</b> Rollback transaction!");
663               @mysql_close($old_connection);
664               return(false);
665             } 
666           }
668           /* Let changes get active, everything was fine;
669            */ 
670           mysql_query("commit;",$old_connection);
671           @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>commit;</b>", "");
672           @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>---Transaction sucessful!---</b>", "");
673         }
674       }
677       /********************** 
678        * Update / Insert sip_users entry  
679        **********************/
681       /* Check table definitions
682        */
683       if(!phoneAccount::checkRealtimeTables($a_New)){
684         msg_dialog::display(_("Warning"),
685             sprintf(_("GOsa identified problems with your MySQL table definition!")),
686             WARNING_DIALOG);
687       }
690       /* Set the first given phone number as callerid */
691       reset($newnums);        
692       $i_new_key = key($newnums);
693       $sip_data_array['callerid']  =$newnums[$i_new_key];
694       $sip_data_array['mailbox']   =$newnums[$i_new_key]."@".$this->voice_context;
696       /* Check if there is already an entry in sip_users for this uid */
697       $SQL_query_array = array();
699       /* Enforce strict mode, ensures inout validation, e.g. target field length 
700        */
701       $SQL_query_array[] = "SET @@sql_mode = STRICT_ALL_TABLES;";
703       $query = "SELECT * FROM ".$a_New['SIP_TABLE']." WHERE name='".$this->uid."';\n"; 
704       $rid = mysql_query($query,$new_connection);
705       @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query, "Receive current mysql entries.");
706       if(mysql_affected_rows($new_connection)){
708         /********************** 
709          * Update sip_users entry 
710          **********************/
711         $result                     = mysql_fetch_assoc($rid);
712         $sip_data_array['host']         = $s_host;
713         $sip_data_array['qualify']      = $s_qualify;
714         $sip_data_array['secret']       = $this->goFonPIN;
715         $sip_data_array['type']         = $s_type ;
716         $sip_data_array['username']     = $this->uid;
717         $sip_data_array['ipaddr']       = $s_ip;
718         $sip_data_array['context']      = $this->context;
720         /* Remove not changed attributes, to avoid updating table with same values */
721         foreach($sip_data_array as $name => $value){
722           if($result[$name] == $value){
723             unset($sip_data_array[$name]);
724           }
725         }
726         /* Only update entry if there is something to uopdate */
727         if(count($sip_data_array)){
728           $query = "UPDATE ".$a_New['SIP_TABLE']." SET ";
729           foreach($sip_data_array as $key => $val){
730             $query.= "".$key."='".$val."',"; 
731           } 
732           $query = preg_replace("/,$/","",$query);
733           $query.= " WHERE name='".$this->uid."';";
734           $SQL_query_array[] = $query;
735         }
736       } else {
738         /********************** 
739          * Insert sip_users entry 
740          **********************/
741         //generate SIP entry
742         $sip_data_array['name']         = $this->uid;
743         $sip_data_array['accountcode']  = NULL;          
744         $sip_data_array['amaflags']     = NULL;
745         $sip_data_array['callgroup']    = NULL;
746         $sip_data_array['canreinvite']  = "no";
747         $sip_data_array['context']      = $this->context;
748         $sip_data_array['defaultip']    = NULL;
749         $sip_data_array['fromuser']     = NULL;
750         $sip_data_array['fromdomain']   = NULL;
751         $sip_data_array['host']         = $s_host;
752         $sip_data_array['insecure']     = NULL;
753         $sip_data_array['language']     = NULL;
754         $sip_data_array['mailbox']      = $newnums[$i_new_key]."@".$this->voice_context;
755         $sip_data_array['md5secret']    = NULL;
756         $sip_data_array['nat']          = "no";
757         $sip_data_array['permit']       = NULL;
758         $sip_data_array['deny']         = NULL;
759         $sip_data_array['mask']         = NULL;
760         $sip_data_array['pickupgroup']  = NULL;
761         $sip_data_array['port']         = NULL;
762         $sip_data_array['qualify']      = $s_qualify;
763         $sip_data_array['restrictcid']  = "n";
764         $sip_data_array['rtptimeout']   = NULL;
765         $sip_data_array['rtpholdtimeout']=NULL;
766         $sip_data_array['secret']       = $this->goFonPIN;
767         $sip_data_array['type']         = $s_type ;
768         $sip_data_array['username']     = $this->uid;
769         $sip_data_array['disallow']     = NULL;
770         $sip_data_array['allow']        = NULL;
771         $sip_data_array['musiconhold']  = NULL;
772         $sip_data_array['regseconds']   = NULL;
773         $sip_data_array['ipaddr']       = $s_ip;
774         $sip_data_array['regexten']     = NULL;
775         $sip_data_array['cancallforward']=NULL;
777         /* There is currently no entry for this user in the sip_users table. 
778          * We should create one i
779          */
780         foreach($sip_data_array as $s_sip_key=>$s_sip_val){
781           if($s_sip_val === NULL) continue;
782           $s_sip_values.="'".$s_sip_val."',";
783           $s_sip_keys  .="`".$s_sip_key."`,";
784         }
785         $s_sip_values =  preg_replace("/,$/","",$s_sip_values);
786         $s_sip_keys   =  preg_replace("/,$/","",$s_sip_keys);
788         /* Add sip entries to mysql queries */
789         $SQL_query_array[] ="INSERT INTO ".$a_New['SIP_TABLE']." (".$s_sip_keys.") VALUES (".$s_sip_values.");";
790       }
793       /********************** 
794        * Update / Insert Voice mail entry  
795        **********************/
797       $customer_id = $newnums[$i_new_key];
798       $query  = "SELECT id,name,callerid FROM ".$a_New['SIP_TABLE']." WHERE name='".$this->uid."';";
799       $rid    = mysql_query($query,$new_connection);
801       @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query, "Receive callerid");
802       $result = mysql_fetch_assoc($rid);
804       $old_customer_id = ""; 
805       if($result){
806         $old_customer_id = $result['callerid'];
807       }
809       $voice_data_array = array(
810           "customer_id" => $customer_id,
811           "mailbox"     => $customer_id,
812           "password"    => $this->goFonVoicemailPIN,
813           "fullname"    => $CNname,
814           "context"     => $this->voice_context,
815           "email"       => $s_mail);
817       $voice_data_array['pager']   = $this->pager;
819       /* Check if there is already an entry in sip_users for this uid */
820       $query_tmp = "SELECT * FROM ".$a_New['VOICE_TABLE']." WHERE customer_id='".$old_customer_id."';\n";
821       $rid = mysql_query($query_tmp,$new_connection);
823       @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query_tmp, "Check if voicemail entry exists");
824       if(mysql_affected_rows($new_connection)){
826         /********************** 
827          * Update Voice mail entry  
828          **********************/
830         @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"", "<i>Voicemail entry exists, adding updating to queue.</i>");
831         $result = mysql_fetch_assoc($rid)  ;
833         foreach($voice_data_array as $name => $value){
834           if($result[$name] == $value){
835             unset($voice_data_array[$name]);
836           }
837         }
839         /* Only update entry if there is something to update */
840         if(count($voice_data_array)){
841           $query = "UPDATE ".$a_New['VOICE_TABLE']." SET ";
842           foreach($voice_data_array as $key => $val){
843             $query.= "".$key."='".$val."',"; 
844           } 
845           $query = preg_replace("/,$/","",$query);
846           $query.= " WHERE customer_id='".$old_customer_id."';";
847           $SQL_query_array[] = $query;
848         }
849       }else{
851         /********************** 
852          * Insert Voice mail entry  
853          **********************/
854         @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"", "<i>No voicemail entry found, add 'create' to queue.</i>");
855         $voice_data_array['context'] = $this->voice_context;
857         /* There is currently no voice mail entry for this user. 
858          * We should create one 
859          */
860         $s_voi_values = $s_voi_keys = "";
861         foreach($voice_data_array as $s_voi_key=>$s_voi_val){
862           if($s_voi_val === NULL) continue;
863           $s_voi_values.="'".$s_voi_val."',";
864           $s_voi_keys  .="`".$s_voi_key."`,";
865         }
866         $s_voi_values =  preg_replace("/,$/","",$s_voi_values);
867         $s_voi_keys   =  preg_replace("/,$/","",$s_voi_keys);
869         /* Add sip entries to mysql queries */
870         $SQL_query_array[] ="INSERT INTO ".$a_New['VOICE_TABLE']." (".$s_voi_keys.") VALUES (".$s_voi_values.");";
871       }
874       /********************** 
875        * Remove/Insert extension entries
876        **********************/
878       /* Initiate transaction 
879        */
880       $SQL_query_array[]= "DELETE FROM ".$a_New['EXT_TABLE']." WHERE exten=\"".$this->uid."\";";
881       $oldnums= array();
882       foreach($oldnums as $s_telenums){
883         $SQL_query_array[]= "DELETE FROM ".$a_New['EXT_TABLE']." WHERE exten=\"".$s_telenums."\";";
884       }
885       foreach($newnums as $s_telenums){
886         $SQL_query_array[]= "DELETE FROM ".$a_New['EXT_TABLE']." WHERE exten=\"".$s_telenums."\";";
887       }
889       /********************** 
890        * Insert extension entries
891        **********************/
893       // Get selected Macro Parameter and create parameter entry 
894       if(isset($this->macroarray[$this->macro])){
895         foreach($this->macroarray[$this->macro] as $key => $val ){
896           $s_parameter .= $val['choosen']."|";
897         }
898         $s_parameter = preg_replace("/\|$/","",$s_parameter);
899       }
901       $i = 0; 
902       $EXT = array();
903       if(!is_numeric($this->uid)){
904         $EXT[$i]['context'] = 'GOsa';
905         $EXT[$i]['exten']   = $this->uid;
906         $EXT[$i]['priority']= 1;
907         $EXT[$i]['app']     = "Goto";
908         $EXT[$i]['appdata'] = $newnums[$i_new_key]."|1";
909         $i ++;
910       }
912       // Entension entries  Hint / Dial / Goto
913       foreach($newnums as $s_telenums){
915         /* Hint Entry */
916         $EXT[$i]['context'] = 'GOsa';
917         $EXT[$i]['exten']   = $s_telenums;
918         $EXT[$i]['priority']= 0;
919         $EXT[$i]['app']     = 'SIP/'.$this->uid;
920         $i ++;  
921         /* SetCID */
922         //$EXT[$i]['context'] = 'GOsa';
923         //$EXT[$i]['exten']   = $s_telenums;
924         //$EXT[$i]['priority']= 1;
925         //$EXT[$i]['app']     = "SetCIDName";
926         //$EXT[$i]['appdata'] = $CNname;
927         //$i ++;  
929         // If no macro is selected use Dial
930         if($this->macro!="none"){ 
931           $macroname = preg_replace("/,.*$/","",$this->macro);        
932           $macroname = preg_replace("/^.*=/","",$macroname);        
933           $s_app = "Macro";$macroname;
934           $s_par = $macroname."|".$s_parameter; 
935         }else{
936           $s_app = "Dial";
937           $s_par = 'SIP/'.$this->uid."|20|r";
938         }
940         $EXT[$i]['context'] = 'GOsa';
941         $EXT[$i]['exten']   = $s_telenums;
942         $EXT[$i]['priority']= 1;
943         $EXT[$i]['app']     = $s_app;
944         $EXT[$i]['appdata'] = $s_par;
945         $i ++;
946       }
948       // Append all these Entries 
949       foreach($EXT as $entr){
950         $SQL_syn = "INSERT INTO ".$a_New['EXT_TABLE']." (";
951         foreach($entr as $key2 => $val2){
952           $SQL_syn.= "`".$key2."`,";
953         }
954         $SQL_syn = preg_replace("/,$/","",$SQL_syn);
955         $SQL_syn .= ") VALUES ("; 
956         foreach($entr as $key2 => $val2){
957           $SQL_syn .= "'".$val2."',";
958         }
959         $SQL_syn = preg_replace("/,$/","",$SQL_syn);
960         $SQL_syn .=");\n";
962         $SQL_query_array[] =$SQL_syn;
963         $SQL_syn ="";
964       }
966       /* Start transaction, to be able to rollback 
967        */
968       @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>---Insert/Update new entry---</b>","");
970       mysql_query("begin;",$new_connection);
971       @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>begin;</b>","<i>Starting transaction!</i>");
973       foreach($SQL_query_array as $query){
974         @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>".$query."</b>", "");
975         if(!mysql_query($query,$new_connection)){
976           $err = mysql_error($new_connection);
977           @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"\n".$err, "<b>FAILED</b>");
978           msg_dialog::display(_("Error"), 
979               msgPool::mysqlerror($err,__CLASS__)."&nbsp;".
980               "\n<p>"._("Please activate debugging for details!")."</p>",
981               ERROR_DIALOG);
983           mysql_query("rollback;",$new_connection);
984           @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>rollback;</b>", "<b>ERROR</b> Rollback transaction!");
985           @mysql_close($new_connection);
986           return(false);
987         } 
988       }
989      
990       /* Let changes get active, everything was fine;
991        */ 
992       mysql_query("commit;",$new_connection);
993       @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>commit;</b>", "Perform transaction!");
994       @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>---Transaction sucessful!---</b>", "");
995     }
996     @mysql_close($new_connection);
997     return true;
998   }
1001   function execute()
1002   {
1003     /* Call parent execute */
1004     plugin::execute();
1006     /* Log view */
1007     if($this->is_account && !$this->view_logged){
1008       $this->view_logged = TRUE;
1009       new log("view","users/".get_class($this),$this->dn);
1010     }
1012     $display = "";
1013     $SkipWrite = (!isset($this->parent) || !$this->parent) && !session::is_set('edit');
1015     if(empty($this->macro)&&(!empty($this->goFonMacro))){
1017       /* Go through already saved values, for a parameter */
1018       $tmp = explode("!",$this->goFonMacro);
1020       /* it is possible that nothing has been saved yet */
1021       if(is_array($tmp)){
1023         /* First value is the macroname */
1024         $this->macro = $tmp[0];
1026         /* Macroname saved, delete that index */
1027         unset($tmp[0]);
1029         /* Check if macro has been removed */
1030         if(!isset($this->macroarray[$this->macro])){
1031           $this->macrostillavailable = false;
1032         }else{
1033           $this->macrostillavailable = true;
1034         }
1036         /* for each parametervalues ( parameterID#value like 25#twentyfive) */
1037         foreach($tmp as $var){
1039           /* Split this, so we have $varar[0] = parameterID $varar[1] = SelectedValue */
1040           $varar = explode("#",$var);
1042           /* Only insert if the parameter still exists */
1043           if(isset($this->macroarray[$this->macro][$varar[0]])){
1044             /* Assign value */
1045             $this->macroarray[$this->macro][$varar[0]]['choosen']=$varar[1];
1046           }
1047         }
1048       }
1049     }
1050     
1051     /* Do we represent a valid account? */
1052     if (!$this->is_account && $this->parent === NULL){
1053       $display= "<img alt=\"\" src=\"images/small-error.png\" align=\"middle\">&nbsp;<b>".
1054         msgPool::noValidExtension(_("Phone"))."</b>";
1055       $display.= back_to_main();
1056       return ($display);
1057     }
1059     /* Do we need to flip is_account state? */
1060     if (isset($_POST['modify_state'])){
1061       $this->is_account= !$this->is_account;
1062     }
1064     /* Do we represent a valid account? */
1065     if (!$this->is_account && $this->parent === NULL){
1066       $display= "<img alt=\"\" src=\"images/small-error.png\" align=\"middle\">&nbsp;<b>".
1067         msgPool::noValidExtension(_("Phone"))."</b>";
1068       $display.= back_to_main();
1069       return($display);
1070     }
1072     $display= "";
1074     /* Show tab dialog headers */
1075     
1076     if (!$this->multiple_support_active && $this->parent !== NULL){
1077       if ($this->is_account){
1078         $display= $this->show_disable_header(_("Remove phone account"),
1079             msgPool::featuresEnabled(_("Phone")));
1080       } else {
1081         if(empty($this->uid)){
1082           $display= $this->show_enable_header(_("Create phone account"),
1083             msgPool::featuresDisabled(_("Phone"),_("User uid")));
1084         }else{
1085           $display= $this->show_enable_header(_("Create phone account"),
1086             msgPool::featuresDisabled(_("Phone")));
1087         }
1088         return ($display);
1089       }
1090     }
1091     /* Select no macro if, state is empty, this is the case, if the selected macro is no longer available */
1092     if(empty($this->macro)){
1093       $this->macro ="none";
1094     }
1096     /* Prepare templating */
1097     $smarty= get_smarty();
1099     /* tell user that the selected plugin is no longer available */
1100     if((!$this->macrostillavailable)&&($this->macro!="none")){
1101       msg_dialog::display(_("Error"), _("Selected macro is not available anymore!"), ERROR_DIALOG);
1102     }
1104     /* Assing macroselectbox values  */
1105     $smarty->assign("macros",$this->macros);   
1106     $smarty->assign("macro", $this->macro);   
1108     /* Assign contexts */
1109     $smarty->assign("voicemail_contexts",$this->voicemail_contexts);
1110     $smarty->assign("sip_contexts",$this->sip_contexts);
1111     $smarty->assign("context" ,$this->context);
1112     $smarty->assign("voice_context" ,$this->voice_context);
1114     /* check if there is a FON server created */
1115     if(!count($this->goFonHomeServer)){
1116       msg_dialog::display(_("Configuration error"), msgPool::noserver(_("GOfon")), WARNING_DIALOG);
1117     }
1119     /* Create html parameter table for selected macro parameters 
1120      *  skip if no parameters given 
1121      */
1122     if(!isset($this->macroarray[$this->macro])){
1123       $macrotab="";
1124     }else{
1126       $macrotab ="<table summary=\""._("Parameter")."\">";
1127       /* for every single parameter-> display textfile,combo, or true false switch*/
1129       foreach($this->phoneNumbers as $phonenum){
1130         $tmp[] = $phonenum;
1131       }
1132     
1133       if($this->macro != $this->lastmacro){
1134         /* Go through all params */
1135         foreach($this->macroarray[$this->macro] as $key => $paras){
1137           $string = $paras['default'];
1139           $string=preg_replace("/%uid/i",$this->uid,$string);
1141           if(isset($this->cn)){
1142             $string=preg_replace("/%cn/i",$this->cn,$string);
1143           }
1145           for($i = 0 ; $i < 10; $i++){
1146             if(isset($tmp[$i])){
1147               $string = preg_replace("/%telephoneNumber_".($i+1)."/i",$tmp[$i],$string);
1148             }
1149           }
1150           if(isset($tmp[0])){
1151             $string = preg_replace("/%telephoneNumber/i",$tmp[0],$string);
1152           }
1153           $this->macroarray[$this->macro][$key]['choosen']=$string;
1154         }
1155       }
1157       foreach($this->macroarray[$this->macro] as $paras){
1159         /* get al vars */
1160         $var        = $paras['var'];           
1161         $name       = $paras['name'];           
1162         $default    = $paras['default'];
1163         $type       = $paras['type'];
1164         $choosen    = $paras['choosen'] ; 
1165         $str        = $default;
1167         $dis = "";
1168         if(!$this->acl_is_writeable("goFonMacro",$SkipWrite)){
1169           $dis = " disabled ";
1170         }
1172         /* in case of a combo box display a combobox with selected attr */
1173         $macrotab.= "<tr>";
1174         switch ($type){
1176           case "combo":
1177             $str= "<select name='".$var."' ".$dis." >";
1178           foreach(explode(":",$default) as $choice){
1179             if($choosen==$choice){
1180               $str.= "\n<option value='".$choice."' selected>".$choice."&nbsp;</option>";
1181             }else{
1182               $str.= "\n<option value='".$choice."'>".$choice."&nbsp;</option>";
1183             }
1184           }
1185           $str.="</select>";
1186           $macrotab.= "<td>".base64_decode($name)."</td><td>$str";
1187           break;
1189           case "bool":
1190             if(!$choosen){
1191               $str="\n<input type='checkbox' name='".$var."' value='1' ".$dis." >";
1192             }else{
1193               $str="\n<input type='checkbox' name='".$var."' value='1' checked  ".$dis.">";
1194             }
1195           $macrotab.= "<td colspan='2'>$str&nbsp;".base64_decode($name)."";
1196           break;
1198           case "string":
1199             $str="<input name='".$var."' value='".$choosen."' ".$dis." style='width:340px;'>";
1200           $macrotab.= "<td>".base64_decode($name)."</td><td>$str";
1201           break;
1203         }
1204         $macrotab.= "</td></tr>";
1206       }
1207       $macrotab.="</table><input name='post_success' type='hidden' value='1'>";
1208     }//is_array()
1210     /* Give smarty the table */
1211     $smarty->assign("macrotab",$macrotab);
1214     /* Add phone number */
1215     if (isset($_POST["add_phonenumber"]) && $_POST['phonenumber']){
1217       if(strlen(trim($_POST["phonenumber"])) > 20 ){
1218         msg_dialog::display(_("Error"), msgPool::toobig("Phone number"), ERROR_DIALOG);
1219       }elseif (tests::is_phone_nr($_POST['phonenumber'])){
1220         $number= trim($_POST["phonenumber"]);
1221         $this->phoneNumbers[$number]= $number;
1222         $this->is_modified= TRUE;
1223       } else {
1224         msg_dialog::display(_("Error"), msgPool::invalid("Phone number"), ERROR_DIALOG);
1225       }
1226     }
1228     /* Remove phone number */
1229     if (isset($_POST["delete_phonenumber"]) && isset($_POST["phonenumber_list"])){
1230       foreach ($_POST['phonenumber_list'] as $number){
1231         unset($this->phoneNumbers[$number]);
1232         $this->is_modified= TRUE;
1233       }
1234     }
1236     /* Assign acls */
1237     $tmp = $this->plInfo();
1238     foreach($tmp['plProvidedAcls'] as $name => $translation){
1239       $smarty->assign($name."ACL",$this->getacl($name,$SkipWrite));
1240     }
1242     /* Transfer ACL's */
1243     foreach($this->attributes as $val){
1244       if(isset($this->$val)){
1245         $smarty->assign($val,$this->$val);
1246       }else{
1247         $smarty->assign($val,"");
1248       }
1249     }
1251     /* Create home server array */
1252     $tmp = array();
1253     foreach($this->goFonHomeServers as $dn => $attrs){
1254       if(!is_numeric($dn)){
1255         $tmp[$dn] = $attrs['SERVER'];
1256       }
1257     }
1258     $smarty->assign("goFonHomeServers",$tmp);
1260     /* Fill arrays */
1261     $smarty->assign ("goFonHardware", $this->goFonHardware);
1262     if (!count($this->phoneNumbers)){
1263       $smarty->assign ("phoneNumbers", array());
1264     } else {
1265       $smarty->assign ("phoneNumbers", $this->phoneNumbers);
1266     }
1268     $dis = "";
1269     if(!$this->acl_is_writeable("goFonHardware",$SkipWrite)){
1270       $dis= " disabled ";
1271     }
1272     $hl= "<select size=\"1\" name=\"goFonHardware\" ".$dis." title=\"".
1273        _("Choose your private phone")."\">\n";
1275     foreach ($this->hardware_list as $cn => $description){
1276       if ($cn == $this->goFonHardware){
1277         $selected= "selected";
1278       } else {
1279         $selected= "";
1280       }
1281       if (isset($this->used_hardware[$cn])){
1282         $color= "style=\"color:#A0A0A0\"";
1283       } else {
1284         $color= "";
1285       }
1286       $hl.= "  <option $color label=\"$cn\" value=\"$cn\" $selected>$description&nbsp;</option>\n";
1287     }
1288     $hl.= "</select>\n";
1289     $smarty->assign ("hardware_list", $hl);
1292     foreach($this->attributes as $attr){
1293       if(in_array($attr,$this->multi_boxes)){
1294         $smarty->assign("use_".$attr,TRUE);
1295       }else{
1296         $smarty->assign("use_".$attr,FALSE);
1297       }
1298     }
1300     foreach(array("goFonVoiceMailContext","goFonContext") as $attr){
1301       if(in_array($attr,$this->multi_boxes)){
1302         $smarty->assign("use_".$attr,TRUE);
1303       }else{
1304         $smarty->assign("use_".$attr,FALSE);
1305       }
1306     }
1308     /* Show main page */
1309     $this->lastmacro = $this->macro;
1310     $smarty->assign("multiple_support",$this->multiple_support_active);
1311     $display.= $smarty->fetch(get_template_path('generic.tpl', TRUE, dirname(__FILE__)));
1312     return($display);
1313   }
1316   function save_object()
1317   {
1318     $SkipWrite = (!isset($this->parent) || !$this->parent) && !session::is_set('edit');
1319     if (isset($_POST["phoneTab"])){
1320     
1321       plugin::save_object();
1323       /* Save checkbox */
1324       $tmp = preg_replace("/[^a-z]/i","",$this->goFonDeliveryMode);
1325       if($this->acl_is_writeable("goFonDeliveryMode",$SkipWrite)){
1326         if(isset($_POST['fon_to_mail']) && !preg_match("/M/",$this->goFonDeliveryMode)){
1327           $tmp .= "M";
1328         }elseif(!isset($_POST['fon_to_mail']) && preg_match("/M/",$this->goFonDeliveryMode)){
1329           $tmp  = preg_replace ("/M/","",$tmp);
1330         }
1331       }
1332       $this->goFonDeliveryMode= "[".$tmp."]";
1335       /* Every macro in the select box are available */
1336       if((isset($_POST['macro']))){
1337         $this->macro = $_POST['macro'];
1338         $this->macrostillavailable=true;
1339       }
1341       if(isset($_POST['macro']) && $_POST['macro'] != $this->macro){
1342         $this->is_modified =true;
1343       }
1345       /* Save context */
1346       if(isset($_POST['context'])){
1347         if($this->context != $_POST['context']){
1348           $this->is_modified= TRUE;
1349         }
1350         $this->context= $_POST['context'];
1351       }
1353       /* Save voice context */
1354       if(isset($_POST['voice_context'])){
1355         if($this->voice_context != $_POST['voice_context']){
1356           $this->is_modified= TRUE;
1357         }
1358         $this->voice_context= $_POST['voice_context'];
1359       }
1361       if(is_array($this->phoneNumbers)){
1362         foreach($this->phoneNumbers as $telenumms) {
1363           $nummsinorder[]=$telenumms; 
1364         }
1365       }else{
1366         $nummsinorder=array("");
1367       }
1370       /* get all Postvars */
1371       if(isset($this->macroarray[$this->macro])){
1374         if($this->acl_is_writeable("goFonMacro",$SkipWrite)){
1375           foreach($this->macroarray[$this->macro] as $key => $paras){
1377             $old_macro_settings = $this->macroarray[$this->macro][$key]; 
1378             $backup = $this->macroarray[$this->macro][$key];
1380             if(isset($_POST[$paras['var']])){
1381               $this->macroarray[$this->macro][$key]['choosen'] = $_POST[$paras['var']];
1382             }
1384             /* Checkboxes are special, they are not Posted if they are not selected, so the won't be changed with the above code
1385                We need this code below to read and save checkboxes correct
1386              */
1388             if(isset($_POST['post_success'])){
1389               if($this->macroarray[$this->macro][$key]['type']=="bool"){
1390                 if(isset($_POST[$this->macroarray[$this->macro][$key]['var']])) {
1391                   $this->macroarray[$this->macro][$key]['choosen']=1;
1392                 }else{
1393                   $this->macroarray[$this->macro][$key]['choosen']=0;
1394                 }
1395               }
1396             }
1397             if(array_differs($old_macro_settings,$this->macroarray[$this->macro][$key])){
1398               $this->is_modified = TRUE;
1399             }
1400           }
1402           if(count(array_diff($this->macroarray[$this->macro][$key],$backup))){
1403             $this->is_modified = TRUE;
1404           }
1405         }
1406       }
1407     }
1408   }
1410   function check()
1411   {
1412     /* Call common method to give check the hook */
1413     $message= plugin::check();
1415     if(!count($this->goFonHomeServers)){
1416       $message[] = _("There must be at least one server with an asterisk database to create a phone account.");
1417     }
1419     if(empty($this->goFonHomeServer)){
1420       $message[] = msgPool::invalid(_("Home server"));
1421     }
1423     if((strlen($this->goFonVoicemailPIN)==0)||(strlen($this->goFonVoicemailPIN)>4)){
1424       $message[]= msgPool::invalid(_("Voicemail PIN"),"","",_("Between 1-4 charactes"));
1425     }else{
1426       if(preg_match("/[^0-9]/",$this->goFonVoicemailPIN)){
1427         $message[]= msgPool::invalid(_("Voicemail PIN"),preg_replace("/[0-9]/","X",$this->goFonVoicemailPIN),"/X/");
1428       }
1429     }
1431     if(preg_match("/[^0-9a-z]/i",$this->goFonPIN)){
1432       $message[]= msgPool::invalid(_("Phone PIN"),preg_replace("/[0-9a-z]/i","X",$this->goFonPIN),"/X/");
1433     }
1435     if ($this->initially_was_account != $this->is_account || $this->is_modified){
1436       $str = $this->generate_mysql_entension_entries(true);
1437       if(empty($str)){
1438         msg_dialog::display(_("Error"), $str, ERROR_DIALOG);
1439       }
1440     }
1442     /* We need at least one phone number */
1443     if (count($this->phoneNumbers) == 0){
1444       $message[]= msgPool::required("Phone number");
1445     }
1447     /* Do not allow to save duplicate phone numbers 
1448      *  this may destroy the extensions table.
1449      */ 
1450     $ldap = $this->config->get_ldap_link();
1451     $ldap->cd($this->config->current['BASE']);  
1452     $numberFilter = "";
1453     foreach($this->phoneNumbers as $number){
1454       $numberFilter .= "(telephoneNumber={$number})";
1455     }
1456     $ldap->search("(&(!(uid=".$this->uid."))(objectClass=goFonAccount)(|{$numberFilter}))",array("dn","telephoneNumber"));
1457     $res = array();
1458     while($attrs = $ldap->fetch()){
1459       unset($attrs['telephoneNumber']['count']);
1460       $res = array_merge($res,array_intersect($attrs['telephoneNumber'], $this->phoneNumbers));
1461     }
1462     $res = array_unique($res);
1463     if(count($res)){
1464       $message[] = msgPool::duplicated(_("Phone number"))."&nbsp;<br>".
1465         implode(array_intersect($res, $this->phoneNumbers), ", ");
1466     }
1468     /* check for ! in any parameter setting*/
1469     if(isset($this->macroarray[$this->macro])){
1470       foreach($this->macroarray[$this->macro] as $val){
1471         if((strstr($val['choosen'],"!"))||(strstr($val['choosen'],"#"))){
1472           $message[] = msgPool::invalid(sprintf(_("macro parameter %s"),$val['name']),$val['choosen'],"/[^\#]/");
1473         }
1474       }
1475     }
1476     return ($message);
1477   }
1481   function save()
1482   {
1483     plugin::save();
1485     /* Force saving macro again 
1486      * This ensures that 
1487      *  - the macro is available on the destiantion server.
1488      *  - the macro saved is up to date on the destination server.
1489      */
1490     if(!empty($this->macro) && $this->macro != "none")  {
1491       $macro_tab= new macrotabs($this->config,$this->config->data['TABS']['MACROTABS'], $this->macro,"gofonmacro");
1492       $macro_tab -> save();
1493     }
1495     /* Save arrays */
1496     $tmp_numbers = array();
1497     foreach ($this->phoneNumbers as $number){
1498       $tmp_numbers[] = $number;
1499     }
1501     /* Save settings, or remove goFonMacro attribute*/
1502     if($this->macro!="none"){    
1503       $this->attrs['goFonMacro']=$this->macro;
1504       if(isset($this->macroarray[$this->macro])){
1505         foreach($this->macroarray[$this->macro] as $paras)  {
1506           $this->attrs['goFonMacro'].="!".$paras['id']."#".$paras['choosen'];
1507         }
1508       }
1509     }else{
1510       $this->attrs['goFonMacro']=array();
1511     }
1512     unset($this->attrs['macro'])  ;
1514     $this->attrs['goFonForwarding']=array();
1516     /*
1517      */
1518     $str = $this->generate_mysql_entension_entries(true);
1519     if(!$str){
1520       msg_dialog::display(_("Error"),_("An error occured while updating the database entries!") , ERROR_DIALOG);
1521     }
1523     if($this->attrs['goFonMacro']==""){
1524       $this->attrs['goFonMacro']=array();
1525     }
1527     unset($this->attrs['cn']);
1529     /* Write back to ldap */
1530     $ldap= $this->config->get_ldap_link();
1531     $ldap->cd($this->dn);
1532     $this->cleanup();
1533     
1534     /* Force saving numbers, else it will be overwriten by user account. */
1535     $this->attrs['telephoneNumber'] =$tmp_numbers;
1536     $ldap->modify ($this->attrs); 
1538     /* Log last action */
1539     if($this->initially_was_account){
1540       new log("modify","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
1541     }else{
1542       new log("create","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
1543     }
1545     if (!$ldap->success()){
1546       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, 0, get_class()));
1547     }
1549     /* Optionally execute a command after we're done */
1551     if ($this->initially_was_account == $this->is_account){
1552       if ($this->is_modified){
1553         $this->handle_post_events("modify",array("uid" => $this->uid));
1554       }
1555     } else {
1556       $this->handle_post_events("add",array("uid" => $this->uid));
1557     }
1559   }
1562   function adapt_from_template($dn, $skip= array())
1563   {
1564     plugin::adapt_from_template($dn, $skip);
1566     /* Assemble phone numbers */
1567     if (isset($this->attrs['telephoneNumber']) && !in_array("telephoneNumber", $skip)){
1568       for ($i= 0; $i<$this->attrs['telephoneNumber']['count']; $i++){
1569         $number= $this->attrs['telephoneNumber'][$i];
1570         $this->phoneNumbers[$number]= $number;
1571       }
1572     }
1573   }
1576   function remove_from_parent()
1577   {
1578     if(!$this->initially_was_account) return;
1580     if(count($this->goFonHomeServers) && !empty($this->init_HomeServer) && is_callable("mysql_pconnect")){
1582       // Get Configuration for initial Mysql database Server
1583       $a_SETUP = $this->goFonHomeServers[$this->init_HomeServer];
1584       $s_parameter  ="";
1586       /* Check table definitions
1587        */
1588       if(!phoneAccount::checkRealtimeTables($a_SETUP)){
1589         msg_dialog::display(_("Warning"),
1590             sprintf(_("GOsa identified problems with your MySQL table definition!")),
1591             WARNING_DIALOG);
1592       }
1594       // Connect to DB server
1595       $r_con =  @mysql_pconnect($a_SETUP['SERVER'],$a_SETUP['LOGIN'],$a_SETUP['PASSWORD']);
1597       // Check if we are  connected correctly
1598       if(!$r_con){
1599         msg_dialog::display(_("Error"), msgPool::dbconnect("GOfon",@mysql_error()), ERROR_DIALOG);
1600         new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error());
1601         return false;
1602       }
1604       // Select database for Extensions
1605       $db  =  @mysql_select_db($a_SETUP['DB'],$r_con);
1607       // Test if we have the database selected correctly
1608       if(!$db){
1609         msg_dialog::display(_("Error"), msgPool::dbselect("GOfon", @mysql_error()), ERROR_DIALOG);
1610         new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error());
1611         return false;
1612       }
1614       $SQL="";
1615       $SQL[]= "SET @@sql_mode = STRICT_ALL_TABLES;";
1617       $first_num = false;
1618       // Delete old entries
1619       foreach($this->a_old_telenums as $s_telenums){
1620         if(!$first_num){
1621           $first_num = $s_telenums;
1622         }
1623         $SQL[] = "DELETE FROM ".$a_SETUP['EXT_TABLE']." WHERE exten='".$s_telenums."';\n";
1624       }
1627       $query  = "SELECT id,name,callerid FROM ".$a_SETUP['SIP_TABLE']." WHERE name='".$this->uid."';";
1628       $rid    = mysql_query($query,$r_con);
1629       @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query, "Database query");
1630       $result = mysql_fetch_assoc($rid);
1631       $callerid = $first_num;
1632       if($result){
1633         $callerid = $result['callerid'];
1634       }
1636       /* Set mode to strict
1637          Strict disallows the addition of entries that do not match the targets field length.
1638        */
1639       $SQL[] = "DELETE FROM ".$a_SETUP['VOICE_TABLE']." WHERE customer_id='".$callerid."';";
1640       $SQL[] = "DELETE FROM ".$a_SETUP['EXT_TABLE']." WHERE exten='".$this->uid."';\n";
1641       $SQL[] = "DELETE FROM ".$a_SETUP['SIP_TABLE']." WHERE name='".$this->uid."';\n";
1643       /* Start transaction, to be able to rollback
1644        */
1645       @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>---Removing entry from server---</b>","");
1647       mysql_query("begin;",$r_con);
1648       @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>begin;</b>","<i>Starting transaction!</i>");
1650       foreach($SQL as $query){
1651         @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>".$query."</b>", "");
1653         if(!mysql_query($query,$r_con)){
1654           $err = mysql_error($r_con);
1655           @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"\n".$err, "<b>FAILED</b>");
1656           msg_dialog::display(_("Error"),
1657               msgPool::mysqlerror($err,__CLASS__)."&nbsp;".
1658               "\n<p>"._("Please activate debugging for details!")."</p>",
1659               ERROR_DIALOG);
1661           mysql_query("rollback;",$r_con);
1662           @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>rollback;</b>", "<b>ERROR</b> Rollback transaction!");
1663           @mysql_close($r_con);
1664           return(false);
1665         }
1666       }
1668       /* Let changes get active, everything was fine;
1669        */
1670       mysql_query("commit;",$r_con);
1671       @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>commit;</b>", "");
1672       @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>---Transaction sucessful!---</b>", "");
1674     }else{
1675       msg_dialog::display(_("Configuration error"), msgPool::missingext("php-mysql"), WARNING_DIALOG);
1676       return false;
1677     }
1679     /* unset macro attr, it will cause an error */
1680     $tmp = array_flip($this->attributes);
1681     unset($tmp['macro']);
1682     $this->attributes=array_flip($tmp);
1684     /* Cancel if there's nothing to do here */
1685     if (!$this->initially_was_account){
1686       return;
1687     }
1689     plugin::remove_from_parent();
1691     /* Just keep one phone number */
1692     if (count($this->telephoneNumber) && $this->telephoneNumber != ""){
1693       $this->attrs['telephoneNumber']= $this->telephoneNumber;
1694     } else {
1695       $this->attrs['telephoneNumber']= array();
1696     }
1699     $ldap= $this->config->get_ldap_link();
1700     $ldap->cd($this->config->current['BASE']);
1701     $ldap->search("(&(objectClass=goFonQueue)(member=*))", array("member"));
1702     while($attr = $ldap->fetch()){
1703       if(in_array($this->dn,$attr['member'])){
1704         $new =new ogrouptabs($this->config, $this->config->data['TABS']['OGROUPTABS'],$attr['dn']);
1705         unset($new->by_object['ogroup']->memberList[$this->dn]);
1706         unset($new->by_object['ogroup']->member[$this->dn]);
1707         $new->save();
1708         msg_dialog::display(_("Information"), sprintf(_("User '%s' has been removed from phone queue '%s'."), $this->cn, $new->by_object['ogroup']->cn), INFO_DIALOG);
1709       }
1710     }
1711     $ldap->cd($this->dn);
1712     $this->cleanup();
1713     $ldap->modify ($this->attrs); 
1715     new log("remove","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
1716     if (!$ldap->success()){
1717       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
1718     }
1720     /* Optionally execute a command after we're done */
1721     @mysql_close($r_con);
1722     $this->handle_post_events('remove',array("uid"=> $this->uid));
1723   }
1727   /* This function checks if the given phonenumbers are available or already in use*/
1728   function is_number_used()
1729   {
1730     $ldap= $this->config->get_ldap_link();
1731     $ldap->cd($this->config->current['BASE']);
1732     $ldap->search("(|(objectClass=goFonAccount)(objectClass=goFonQueue)(objectClass=goFonConference))", array("telephoneNumber","cn","uid"));
1733     while($attrs = $ldap->fetch()) {
1734       unset($attrs['telephoneNumber']['count']);
1735       foreach($attrs['telephoneNumber'] as $tele){
1736         if(!isset($attrs['cn'][0])) $attrs['cn'][0]=$attrs['dn'];
1737         if(!isset($attrs['uid'][0])) $attrs['uid'][0]=$attrs['dn'];
1738         $numbers[$tele]=$attrs;
1739       }
1740     }
1742     foreach($this->phoneNumbers as $num){
1743       if((isset($numbers[$num]))&&(($numbers[$num]['uid'][0]!=$this->uid))){
1744         if(isset($numbers[$num]['uid'][0])){
1745           return sprintf(_("The specified telephonenumber '%s' is already assigned to '%s'."),$num,$numbers[$num]['uid'][0]);
1746         }else{
1747           return sprintf(_("The specified telephonenumber '%s' is already assigned to '%s'."),$num,$numbers[$num]['cn'][0]);
1748         }
1749       }
1750     }
1751   }
1754   /* Create phoneAccount part of copy & paste dialog */
1755   function getCopyDialog()
1756   { 
1757     if(!$this->is_account) return("");
1758     $smarty = get_smarty();
1759     if (!count($this->phoneNumbers)){
1760       $smarty->assign ("phoneNumbers", array(""));
1761     } else {
1762       $smarty->assign ("phoneNumbers", $this->phoneNumbers);
1763     }
1765     $smarty->assign("goFonVoicemailPIN",$this->goFonVoicemailPIN);
1766     $smarty->assign("goFonPIN",$this->goFonPIN);
1768     $display= $smarty->fetch(get_template_path('paste_generic.tpl', TRUE, dirname(__FILE__)));
1769     $ret =array();
1770     $ret['string'] = $display;
1771     $ret['status'] = "";
1772     return($ret);
1773   }
1775   /* Save posts from copy & paste dialog dialog  */
1776   function saveCopyDialog()
1777   {
1778     if(!$this->is_account) return;
1779     $this->execute();
1780     if(isset($_POST['goFonVoicemailPIN'])) {
1781       $this->goFonVoicemailPIN = $_POST['goFonVoicemailPIN'];
1782     }
1783     if(isset($_POST['goFonPIN'])){
1784       $this->goFonPIN = $_POST['goFonPIN'];
1785     }
1786   }
1789   function allow_remove()
1790   {
1791     /* Check if previously selected server is still available */
1792     if($this->initially_was_account && !isset($this->goFonHomeServers[$this->goFonHomeServer])){
1793       return sprintf(_("The previously selected asterisk home server (%s) is no longer available. Remove aborted."),preg_replace("/,/",", ",$this->goFonHomeServer));
1794     }
1795   }
1797   /* Return plugin informations for acl handling */
1798   static function plInfo()
1799   {
1800     return (array(
1801           "plShortName"     => _("Phone"),
1802           "plDescription"   => _("Phone account settings"),
1803           "plSelfModify"    => TRUE,
1804           "plDepends"       => array("user"),
1805           "plPriority"      => 7,                                 // Position in tabs
1806           "plSection"         => array("personal" => _("My account")),
1807           "plCategory"        => array("users"),
1810           "plOptions"       => array(),
1812           "plProvidedAcls"  => array(
1813             "telephoneNumber"     => _("Telephone number"),
1814             "goFonMacro"          => _("Macro settings"),
1815             "goFonHardware"       => _("Phone hardware"),
1816             "goFonHomeServer"     => _("Home server"),
1817             "goFonContext"          => _("Phone context"),
1818             "goFonVoiceMailContext" => _("Voice mail context"),
1819             "goFonPIN"            => _("Telephone pin"),
1820             "goFonVoicemailPIN"   => _("Voicemail pin"))
1821           ));
1822   }
1826   function multiple_execute()
1827   {
1828     plugin::multiple_execute();
1829     return($this->execute());
1830   }
1832   function get_multi_init_values()
1833   {
1834     $ret = plugin::get_multi_init_values();
1835     $ret['phoneNumbers'] = array();
1836     foreach($this->phoneNumbers as $number){
1837       $ret['phoneNumbers'][] = $number."  [".$this->attrs['cn'][0]."]"; 
1838     }
1839     $ret['phoneNumbers']['count'] = count($ret['phoneNumbers']);
1840     return($ret);
1841   }
1843   function init_multiple_support($attrs,$all)
1844   {
1845     plugin::init_multiple_support($attrs,$all);
1847     $this->phoneNumbers = array();
1848     if(isset($all['phoneNumbers'])){
1849       for($i = 0 ; $i < $all['phoneNumbers']['count'] ; $i++){
1850         $this->phoneNumbers[$all['phoneNumbers'][$i]] = $all['phoneNumbers'][$i];
1851       }
1852     }
1853   }
1855   function multiple_save_object()
1856   {
1857     /* Simply call parents save_object */
1858     if (isset($_POST["phoneTab"])){
1860       plugin::save_object();
1861       plugin::multiple_save_object();
1863       /* Every macro in the select box are available */
1864       if((isset($_POST['macro']))){
1865         $this->macrostillavailable=true;
1866       }
1868       if(isset($_POST['macro']) && $_POST['macro'] != $this->macro){
1869         $this->macro = $_POST['macro'];
1870         $this->is_modified =true;
1871       }
1873       /* get all Postvars */
1874       if(isset($this->macroarray[$this->macro])){
1875         foreach($this->macroarray[$this->macro] as $key => $paras){
1876           $backup = $this->macroarray[$this->macro][$key];
1877           if(isset($_POST[$paras['var']])){
1878             $this->macroarray[$this->macro][$key]['choosen'] = $_POST[$paras['var']];
1879           }
1880           if(isset($_POST['post_success'])){
1881             if($this->macroarray[$this->macro][$key]['type']=="bool"){
1882               if(isset($_POST[$this->macroarray[$this->macro][$key]['var']])) {
1883                 $this->macroarray[$this->macro][$key]['choosen']=$_POST[$paras['var']];
1884               }else{
1885                 $this->macroarray[$this->macro][$key]['choosen']=false;
1886               }
1887             }
1888           }
1889         }
1890         if(count(array_diff($this->macroarray[$this->macro][$key],$backup))){
1891           $this->is_modified = TRUE;
1892         }
1893       }
1894     }
1895   }
1897   function multiple_check()
1898   {
1899     $message = plugin::multiple_check();
1901     if(!count($this->goFonHomeServers) && in_array("goFonHomeServers",$this->multi_boxes)){
1902       $message[] = _("There is currently no asterisk server defined!");
1903     }
1905     if(empty($this->goFonHomeServer) && in_array("goFonHomeServers",$this->multi_boxes)){
1906       $message[] = _("Asterisk server is invalid!");
1907     }
1909     if(in_array("goFonVoicemailPIN",$this->multi_boxes) && 
1910         ( (strlen($this->goFonVoicemailPIN)==0)||
1911           (strlen($this->goFonVoicemailPIN)>4))){
1912       $message[]=(_("Voicemail PIN must be 4 characters long!"));
1913     }else{
1914       if(preg_match("/[^0-9]/",$this->goFonVoicemailPIN) && in_array("goFonVoicemailPIN",$this->multi_boxes) ){
1915         $message[]=(_("Voicemail PIN contains invalid characters!"));
1916       }
1917     }
1919     if(preg_match("/[^0-9a-z]/i",$this->goFonPIN) && in_array("goFonPIN",$this->multi_boxes)){
1920       $message[]=(_("Phone pin contains invalid characters!"));
1921     }
1923     /* check for ! in any parameter setting*/
1924     if(isset($this->macroarray[$this->macro]) && in_array("macro",$this->multi_boxes)){
1925       foreach($this->macroarray[$this->macro] as $val){
1926         if((strstr($val['choosen'],"!"))||(strstr($val['choosen'],"#"))){
1927           $message[] = sprintf(_("The parameter %s contains invalid char. '!,#' is used as delimiter"),$val['name']);
1928         }
1929       }
1930     }
1932     return($message);
1933   }
1935   function get_multi_edit_values()
1936   {
1937     $ret = plugin::get_multi_edit_values();
1938     if(in_array("macro",$this->multi_boxes)){
1939       $ret['macro'] = $this->macro;
1940       $ret['macroarray'] = $this->macroarray;
1941       $ret['macros'] = $this->macros;
1942     }
1943     return($ret);
1944   }
1947   /* Return asterisk contexts
1948    * Additionaly read contexts from file.
1949    */
1950   function get_asterisk_voicemail_contexts()
1951   {
1952     return($this->get_asterisk_contexts(CONFIG_DIR."/asterisk/voicemail_context.conf"));
1953   }
1954   function get_asterisk_sip_contexts()
1955   {
1956     return($this->get_asterisk_contexts(CONFIG_DIR."/asterisk/sip_context.conf"));
1957   }
1958   function get_asterisk_contexts($file)
1959   {
1960     $contexts = array();
1961     if(file_exists($file) && is_readable($file)){
1962       foreach(file($file) as $context){
1963         $contexts[] = trim($context);
1964       }
1965     }else{
1966       msg_dialog::display(_("Warning"), msgPool::cannotReadFile($file),WARNING_DIALOG);
1967       $contexts[] = "default";
1968     }
1969     array_unique($contexts);
1970     return($contexts);
1971   }
1974 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1975 ?>