Code

Replaced in_array calls for gosa-plugins
[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           = 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      */
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']))){
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 = ".$num." 
363                           AND ".$cur_cfg['SIP_TABLE'].".name='".$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         } 
370  
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 '".$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   }
447     
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     }
480  
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      **********************/
589  
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){
613     
614       /* Get configuration to old asterisk home server */ 
615       $a_Remove = $this->goFonHomeServers[$this->init_HomeServer];  // DB Configuration
616  
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){
638     
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='".$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='".$this->uid."';";
671           $query_a[]= "DELETE FROM ".$a_Remove['VOICE_TABLE']." WHERE customer_id='".$result['callerid']."';";
672           $query_a[]= "DELETE FROM ".$a_Remove['EXT_TABLE']." WHERE exten='".$this->uid."';";
673           foreach($oldnums as $s_telenums) {
674             $query_a[]= "DELETE FROM ".$a_Remove['EXT_TABLE']." WHERE exten='".$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='".$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."='".$val."',"; 
764           } 
765           $query = preg_replace("/,$/","",$query);
766           $query.= " WHERE name='".$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.="'".$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='".$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='".$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='".$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.="'".$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=\"".$this->uid."\";";
914       $oldnums= array();
915       foreach($oldnums as $s_telenums){
916         $SQL_query_array[]= "DELETE FROM ".$a_New['EXT_TABLE']." WHERE exten=\"".$s_telenums."\";";
917       }
918       foreach($newnums as $s_telenums){
919         $SQL_query_array[]= "DELETE FROM ".$a_New['EXT_TABLE']." WHERE exten=\"".$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 .= "'".$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       }
1022      
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     }
1083     
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 */
1108     
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",$this->macros);   
1139     $smarty->assign("macro", $this->macro);   
1141     /* Assign contexts */
1142     $smarty->assign("voicemail_contexts",$this->voicemail_contexts);
1143     $smarty->assign("sip_contexts",$this->sip_contexts);
1144     $smarty->assign("context" ,$this->context);
1145     $smarty->assign("voice_context" ,$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       }
1165     
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>".base64_decode($name)."</td><td>$str";
1223           break;
1225           case "bool":
1226             if(!$choosen){
1227               $str="\n<input type='checkbox' name='".$var."' value='1' ".$dis." >";
1228             }else{
1229               $str="\n<input type='checkbox' name='".$var."' value='1' checked  ".$dis.">";
1230             }
1231           $macrotab.= "<td colspan='2'>$str&nbsp;".base64_decode($name)."";
1232           break;
1234           case "string":
1235             $str="<input name='".$var."' value='".$choosen."' ".$dis." style='width:340px;'>";
1236           $macrotab.= "<td>".base64_decode($name)."</td><td>$str";
1237           break;
1239         }
1240         $macrotab.= "</td></tr>";
1242       }
1243       $macrotab.="</table><input name='post_success' type='hidden' value='1'>";
1244     }//is_array()
1246     /* Give smarty the table */
1247     $smarty->assign("macrotab",$macrotab);
1250     /* Add phone number */
1251     if (isset($_POST["add_phonenumber"]) && $_POST['phonenumber']){
1253       if(strlen(trim($_POST["phonenumber"])) > 20 ){
1254         msg_dialog::display(_("Error"), msgPool::toobig("Phone number"), ERROR_DIALOG);
1255       }elseif (tests::is_phone_nr($_POST['phonenumber'])){
1256         $number= trim($_POST["phonenumber"]);
1257         $this->phoneNumbers[$number]= $number;
1258         $this->is_modified= TRUE;
1259       } else {
1260         msg_dialog::display(_("Error"), msgPool::invalid("Phone number"), ERROR_DIALOG);
1261       }
1262     }
1264     /* Remove phone number */
1265     if (isset($_POST["delete_phonenumber"]) && isset($_POST["phonenumber_list"])){
1266       foreach ($_POST['phonenumber_list'] as $number){
1267         unset($this->phoneNumbers[$number]);
1268         $this->is_modified= TRUE;
1269       }
1270     }
1272     /* Assign acls */
1273     $tmp = $this->plInfo();
1274     foreach($tmp['plProvidedAcls'] as $name => $translation){
1275       $smarty->assign($name."ACL",$this->getacl($name,$SkipWrite));
1276     }
1278     /* Transfer ACL's */
1279     foreach($this->attributes as $val){
1280       if(isset($this->$val)){
1281         $smarty->assign($val,$this->$val);
1282       }else{
1283         $smarty->assign($val,"");
1284       }
1285     }
1287     /* Create home server array */
1288     $tmp = array();
1289     foreach($this->goFonHomeServers as $dn => $attrs){
1290       if(!is_numeric($dn)){
1291         $tmp[$dn] = $attrs['SERVER'];
1292       }
1293     }
1294     $smarty->assign("goFonHomeServers",$tmp);
1296     /* Fill arrays */
1297     $smarty->assign ("goFonHardware", $this->goFonHardware);
1298     if (!count($this->phoneNumbers)){
1299       $smarty->assign ("phoneNumbers", array());
1300     } else {
1301       $smarty->assign ("phoneNumbers", $this->phoneNumbers);
1302     }
1304     $dis = "";
1305     if(!$this->acl_is_writeable("goFonHardware",$SkipWrite)){
1306       $dis= " disabled ";
1307     }
1308     $hl= "<select size=\"1\" name=\"goFonHardware\" ".$dis." title=\"".
1309        _("Choose your private phone")."\">\n";
1311     foreach ($this->hardware_list as $cn => $description){
1312       if ($cn == $this->goFonHardware){
1313         $selected= "selected";
1314       } else {
1315         $selected= "";
1316       }
1317       if (isset($this->used_hardware[$cn])){
1318         $color= "style=\"color:#A0A0A0\"";
1319       } else {
1320         $color= "";
1321       }
1322       $hl.= "  <option $color label=\"$cn\" value=\"$cn\" $selected>$description&nbsp;</option>\n";
1323     }
1324     $hl.= "</select>\n";
1325     $smarty->assign ("hardware_list", $hl);
1328     foreach($this->attributes as $attr){
1329       if(in_array_strict($attr,$this->multi_boxes)){
1330         $smarty->assign("use_".$attr,TRUE);
1331       }else{
1332         $smarty->assign("use_".$attr,FALSE);
1333       }
1334     }
1336     foreach(array("goFonVoiceMailContext","goFonContext") as $attr){
1337       if(in_array_strict($attr,$this->multi_boxes)){
1338         $smarty->assign("use_".$attr,TRUE);
1339       }else{
1340         $smarty->assign("use_".$attr,FALSE);
1341       }
1342     }
1344     /* Show main page */
1345     $this->lastmacro = $this->macro;
1346     $smarty->assign("multiple_support",$this->multiple_support_active);
1347     $display.= $smarty->fetch(get_template_path('generic.tpl', TRUE, dirname(__FILE__)));
1348     return($display);
1349   }
1352   function save_object()
1353   {
1354     $SkipWrite = (!isset($this->parent) || !$this->parent) && !session::is_set('edit');
1355     if (isset($_POST["phoneTab"])){
1356     
1357       plugin::save_object();
1359       /* Save checkbox */
1360       $tmp = preg_replace("/[^a-z]/i","",$this->goFonDeliveryMode);
1361       if($this->acl_is_writeable("goFonDeliveryMode",$SkipWrite)){
1362         if(isset($_POST['fon_to_mail']) && !preg_match("/M/",$this->goFonDeliveryMode)){
1363           $tmp .= "M";
1364         }elseif(!isset($_POST['fon_to_mail']) && preg_match("/M/",$this->goFonDeliveryMode)){
1365           $tmp  = preg_replace ("/M/","",$tmp);
1366         }
1367       }
1368       $this->goFonDeliveryMode= "[".$tmp."]";
1371       /* Every macro in the select box are available */
1372       if((isset($_POST['macro']))){
1373         $this->macro = $_POST['macro'];
1374         $this->macrostillavailable=true;
1375       }
1377       if(isset($_POST['macro']) && $_POST['macro'] != $this->macro){
1378         $this->is_modified =true;
1379       }
1381       /* Save context */
1382       if(isset($_POST['context'])){
1383         if($this->context != $_POST['context']){
1384           $this->is_modified= TRUE;
1385         }
1386         $this->context= $_POST['context'];
1387       }
1389       /* Save voice context */
1390       if(isset($_POST['voice_context'])){
1391         if($this->voice_context != $_POST['voice_context']){
1392           $this->is_modified= TRUE;
1393         }
1394         $this->voice_context= $_POST['voice_context'];
1395       }
1397       if(is_array($this->phoneNumbers)){
1398         foreach($this->phoneNumbers as $telenumms) {
1399           $nummsinorder[]=$telenumms; 
1400         }
1401       }else{
1402         $nummsinorder=array("");
1403       }
1406       /* get all Postvars */
1407       if(isset($this->macroarray[$this->macro])){
1410         if($this->acl_is_writeable("goFonMacro",$SkipWrite)){
1411           foreach($this->macroarray[$this->macro] as $key => $paras){
1413             $old_macro_settings = $this->macroarray[$this->macro][$key]; 
1414             $backup = $this->macroarray[$this->macro][$key];
1416             if(isset($_POST[$paras['var']])){
1417               $this->macroarray[$this->macro][$key]['choosen'] = $_POST[$paras['var']];
1418             }
1420             /* Checkboxes are special, they are not Posted if they are not selected, so the won't be changed with the above code
1421                We need this code below to read and save checkboxes correct
1422              */
1424             if(isset($_POST['post_success'])){
1425               if($this->macroarray[$this->macro][$key]['type']=="bool"){
1426                 if(isset($_POST[$this->macroarray[$this->macro][$key]['var']])) {
1427                   $this->macroarray[$this->macro][$key]['choosen']=1;
1428                 }else{
1429                   $this->macroarray[$this->macro][$key]['choosen']=0;
1430                 }
1431               }
1432             }
1433             if(array_differs($old_macro_settings,$this->macroarray[$this->macro][$key])){
1434               $this->is_modified = TRUE;
1435             }
1436           }
1438           if(count(array_diff($this->macroarray[$this->macro][$key],$backup))){
1439             $this->is_modified = TRUE;
1440           }
1441         }
1442       }
1443     }
1444   }
1446   function check()
1447   {
1448     /* Call common method to give check the hook */
1449     $message= plugin::check();
1451     if(!count($this->goFonHomeServers)){
1452       $message[] = _("There must be at least one server with an asterisk database to create a phone account.");
1453     }
1455     if(empty($this->goFonHomeServer)){
1456       $message[] = msgPool::invalid(_("Home server"));
1457     }
1459     if((strlen($this->goFonVoicemailPIN)==0)||(strlen($this->goFonVoicemailPIN)>4)){
1460       $message[]= msgPool::invalid(_("Voicemail PIN"),"","",_("Between 1-4 charactes"));
1461     }else{
1462       if(preg_match("/[^0-9]/",$this->goFonVoicemailPIN)){
1463         $message[]= msgPool::invalid(_("Voicemail PIN"),preg_replace("/[0-9]/","X",$this->goFonVoicemailPIN),"/X/");
1464       }
1465     }
1467     if(preg_match("/[^0-9a-z]/i",$this->goFonPIN)){
1468       $message[]= msgPool::invalid(_("Phone PIN"),preg_replace("/[0-9a-z]/i","X",$this->goFonPIN),"/X/");
1469     }
1471     if ($this->initially_was_account != $this->is_account || $this->is_modified){
1472       $str = $this->generate_mysql_entension_entries(false);
1473       if(empty($str)){
1474         msg_dialog::display(_("Error"), $str, ERROR_DIALOG);
1475       }
1476     }
1478     /* We need at least one phone number */
1479     if (count($this->phoneNumbers) == 0){
1480       $message[]= msgPool::required("Phone number");
1481     }
1483     /* Do not allow to save duplicate phone numbers 
1484      *  this may destroy the extensions table.
1485      */ 
1486     $ldap = $this->config->get_ldap_link();
1487     $ldap->cd($this->config->current['BASE']);  
1488     $numberFilter = "";
1489     foreach($this->phoneNumbers as $number){
1490       $numberFilter .= "(telephoneNumber={$number})";
1491     }
1492     $ldap->search("(&(!(uid=".$this->uid."))(objectClass=goFonAccount)(|{$numberFilter}))",array("dn","telephoneNumber"));
1493     $res = array();
1494     while($attrs = $ldap->fetch()){
1495       unset($attrs['telephoneNumber']['count']);
1496       $res = array_merge($res,array_intersect($attrs['telephoneNumber'], $this->phoneNumbers));
1497     }
1498     $res = array_unique($res);
1499     if(count($res)){
1500       $message[] = msgPool::duplicated(_("Phone number"))."&nbsp;<br>".
1501         implode(array_intersect($res, $this->phoneNumbers), ", ");
1502     }
1504     /* check for ! in any parameter setting*/
1505     if(isset($this->macroarray[$this->macro])){
1506       foreach($this->macroarray[$this->macro] as $val){
1507         if((strstr($val['choosen'],"!"))||(strstr($val['choosen'],"#"))){
1508           $message[] = msgPool::invalid(sprintf(_("macro parameter %s"),$val['name']),$val['choosen'],"/[^\#]/");
1509         }
1510       }
1511     }
1512     return ($message);
1513   }
1517   function save()
1518   {
1519     plugin::save();
1521     /* Force saving macro again 
1522      * This ensures that 
1523      *  - the macro is available on the destiantion server.
1524      *  - the macro saved is up to date on the destination server.
1525      */
1526     if(!empty($this->macro) && $this->macro != "none")  {
1527       $macro_tab= new macrotabs($this->config,$this->config->data['TABS']['MACROTABS'], $this->macro,"gofonmacro");
1528       $macro_tab -> save();
1529     }
1531     /* Save arrays */
1532     $tmp_numbers = array();
1533     foreach ($this->phoneNumbers as $number){
1534       $tmp_numbers[] = $number;
1535     }
1537     /* Save settings, or remove goFonMacro attribute*/
1538     if($this->macro!="none"){    
1539       $this->attrs['goFonMacro']=$this->macro;
1540       if(isset($this->macroarray[$this->macro])){
1541         foreach($this->macroarray[$this->macro] as $paras)  {
1542           $this->attrs['goFonMacro'].="!".$paras['id']."#".$paras['choosen'];
1543         }
1544       }
1545     }else{
1546       $this->attrs['goFonMacro']=array();
1547     }
1548     unset($this->attrs['macro'])  ;
1550     $this->attrs['goFonForwarding']=array();
1552     /*
1553      */
1554     $str = $this->generate_mysql_entension_entries(true);
1555     if(!$str){
1556       msg_dialog::display(_("Error"),_("An error occured while updating the database entries!") , ERROR_DIALOG);
1557     }
1559     if($this->attrs['goFonMacro']==""){
1560       $this->attrs['goFonMacro']=array();
1561     }
1563     unset($this->attrs['cn']);
1565     /* Write back to ldap */
1566     $ldap= $this->config->get_ldap_link();
1567     $ldap->cd($this->dn);
1568     $this->cleanup();
1569     
1570     /* Force saving numbers, else it will be overwriten by user account. */
1571     $this->attrs['telephoneNumber'] =$tmp_numbers;
1572     $ldap->modify ($this->attrs); 
1574     /* Log last action */
1575     if($this->initially_was_account){
1576       new log("modify","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
1577     }else{
1578       new log("create","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
1579     }
1581     if (!$ldap->success()){
1582       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, 0, get_class()));
1583     }
1585     /* Optionally execute a command after we're done */
1587     if ($this->initially_was_account == $this->is_account){
1588       if ($this->is_modified){
1589         $this->handle_post_events("modify",array("uid" => $this->uid));
1590       }
1591     } else {
1592       $this->handle_post_events("add",array("uid" => $this->uid));
1593     }
1595   }
1598   function adapt_from_template($dn, $skip= array())
1599   {
1600     plugin::adapt_from_template($dn, $skip);
1602     /* Assemble phone numbers */
1603     if (isset($this->attrs['telephoneNumber']) && !in_array_strict("telephoneNumber", $skip)){
1604       for ($i= 0; $i<$this->attrs['telephoneNumber']['count']; $i++){
1605         $number= $this->attrs['telephoneNumber'][$i];
1606         $this->phoneNumbers[$number]= $number;
1607       }
1608     }
1609   }
1612   function remove_from_parent()
1613   {
1614     if(!$this->initially_was_account) return;
1616     if(count($this->goFonHomeServers) && !empty($this->init_HomeServer) && is_callable("mysql_pconnect")){
1618       // Get Configuration for initial Mysql database Server
1619       $a_SETUP = $this->goFonHomeServers[$this->init_HomeServer];
1620       $s_parameter  ="";
1622       /* Check table definitions
1623        */
1624       if(!phoneAccount::checkRealtimeTables($a_SETUP)){
1625         msg_dialog::display(_("Warning"),
1626             sprintf(_("GOsa identified problems with your MySQL table definition!")),
1627             WARNING_DIALOG);
1628       }
1630       // Connect to DB server
1631       $r_con =  @mysql_pconnect($a_SETUP['SERVER'],$a_SETUP['LOGIN'],$a_SETUP['PASSWORD']);
1633       // Check if we are  connected correctly
1634       if(!$r_con){
1635         msg_dialog::display(_("Error"), msgPool::dbconnect("GOfon",@mysql_error()), ERROR_DIALOG);
1636         new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error());
1637         return false;
1638       }
1640       // Select database for Extensions
1641       $db  =  @mysql_select_db($a_SETUP['DB'],$r_con);
1643       // Test if we have the database selected correctly
1644       if(!$db){
1645         msg_dialog::display(_("Error"), msgPool::dbselect("GOfon", @mysql_error()), ERROR_DIALOG);
1646         new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error());
1647         return false;
1648       }
1650       $SQL="";
1651       $SQL[]= "SET @@sql_mode = STRICT_ALL_TABLES;";
1653       $first_num = false;
1654       // Delete old entries
1655       foreach($this->a_old_telenums as $s_telenums){
1656         if(!$first_num){
1657           $first_num = $s_telenums;
1658         }
1659         $SQL[] = "DELETE FROM ".$a_SETUP['EXT_TABLE']." WHERE exten='".$s_telenums."';\n";
1660       }
1663       $query  = "SELECT id,name,callerid FROM ".$a_SETUP['SIP_TABLE']." WHERE name='".$this->uid."';";
1664       $rid    = mysql_query($query,$r_con);
1665       @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query, "Database query");
1666       $result = mysql_fetch_assoc($rid);
1667       $callerid = $first_num;
1668       if($result){
1669         $callerid = $result['callerid'];
1670       }
1672       /* Set mode to strict
1673          Strict disallows the addition of entries that do not match the targets field length.
1674        */
1675       $SQL[] = "DELETE FROM ".$a_SETUP['VOICE_TABLE']." WHERE customer_id='".$callerid."';";
1676       $SQL[] = "DELETE FROM ".$a_SETUP['EXT_TABLE']." WHERE exten='".$this->uid."';\n";
1677       $SQL[] = "DELETE FROM ".$a_SETUP['SIP_TABLE']." WHERE name='".$this->uid."';\n";
1679       /* Start transaction, to be able to rollback
1680        */
1681       @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>---Removing entry from server---</b>","");
1683       mysql_query("begin;",$r_con);
1684       @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>begin;</b>","<i>Starting transaction!</i>");
1686       foreach($SQL as $query){
1687         @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>".$query."</b>", "");
1689         if(!mysql_query($query,$r_con)){
1690           $err = mysql_error($r_con);
1691           @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"\n".$err, "<b>FAILED</b>");
1692           msg_dialog::display(_("Error"),
1693               msgPool::mysqlerror($err,__CLASS__)."&nbsp;".
1694               "\n<p>"._("Please activate debugging for details!")."</p>",
1695               ERROR_DIALOG);
1697           mysql_query("rollback;",$r_con);
1698           @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>rollback;</b>", "<b>ERROR</b> Rollback transaction!");
1699           @mysql_close($r_con);
1700           return(false);
1701         }
1702       }
1704       /* Let changes get active, everything was fine;
1705        */
1706       mysql_query("commit;",$r_con);
1707       @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>commit;</b>", "");
1708       @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,"<b>---Transaction sucessful!---</b>", "");
1710     }else{
1711       msg_dialog::display(_("Configuration error"), msgPool::missingext("php-mysql"), WARNING_DIALOG);
1712       return false;
1713     }
1715     /* unset macro attr, it will cause an error */
1716     $tmp = array_flip($this->attributes);
1717     unset($tmp['macro']);
1718     $this->attributes=array_flip($tmp);
1720     /* Cancel if there's nothing to do here */
1721     if (!$this->initially_was_account){
1722       return;
1723     }
1725     plugin::remove_from_parent();
1727     /* Just keep one phone number */
1728     if (count($this->telephoneNumber) && $this->telephoneNumber != ""){
1729       $this->attrs['telephoneNumber']= $this->telephoneNumber;
1730     } else {
1731       $this->attrs['telephoneNumber']= array();
1732     }
1735     $ldap= $this->config->get_ldap_link();
1736     $ldap->cd($this->config->current['BASE']);
1737     $ldap->search("(&(objectClass=goFonQueue)(member=*))", array("member"));
1738     while($attr = $ldap->fetch()){
1739       if(in_array_strict($this->dn,$attr['member'])){
1740         $new =new ogrouptabs($this->config, $this->config->data['TABS']['OGROUPTABS'],$attr['dn']);
1741         unset($new->by_object['ogroup']->memberList[$this->dn]);
1742         unset($new->by_object['ogroup']->member[$this->dn]);
1743         $new->save();
1744         msg_dialog::display(_("Information"), sprintf(_("User '%s' has been removed from phone queue '%s'."), $this->cn, $new->by_object['ogroup']->cn), INFO_DIALOG);
1745       }
1746     }
1747     $ldap->cd($this->dn);
1748     $this->cleanup();
1749     $ldap->modify ($this->attrs); 
1751     new log("remove","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
1752     if (!$ldap->success()){
1753       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
1754     }
1756     /* Optionally execute a command after we're done */
1757     @mysql_close($r_con);
1758     $this->handle_post_events('remove',array("uid"=> $this->uid));
1759   }
1763   /* This function checks if the given phonenumbers are available or already in use*/
1764   function is_number_used()
1765   {
1766     $ldap= $this->config->get_ldap_link();
1767     $ldap->cd($this->config->current['BASE']);
1768     $ldap->search("(|(objectClass=goFonAccount)(objectClass=goFonQueue)(objectClass=goFonConference))", array("telephoneNumber","cn","uid"));
1769     while($attrs = $ldap->fetch()) {
1770       unset($attrs['telephoneNumber']['count']);
1771       foreach($attrs['telephoneNumber'] as $tele){
1772         if(!isset($attrs['cn'][0])) $attrs['cn'][0]=$attrs['dn'];
1773         if(!isset($attrs['uid'][0])) $attrs['uid'][0]=$attrs['dn'];
1774         $numbers[$tele]=$attrs;
1775       }
1776     }
1778     foreach($this->phoneNumbers as $num){
1779       if((isset($numbers[$num]))&&(($numbers[$num]['uid'][0]!=$this->uid))){
1780         if(isset($numbers[$num]['uid'][0])){
1781           return sprintf(_("The specified telephonenumber '%s' is already assigned to '%s'."),$num,$numbers[$num]['uid'][0]);
1782         }else{
1783           return sprintf(_("The specified telephonenumber '%s' is already assigned to '%s'."),$num,$numbers[$num]['cn'][0]);
1784         }
1785       }
1786     }
1787   }
1790   /* Create phoneAccount part of copy & paste dialog */
1791   function getCopyDialog()
1792   { 
1793     if(!$this->is_account) return("");
1794     $smarty = get_smarty();
1795     if (!count($this->phoneNumbers)){
1796       $smarty->assign ("phoneNumbers", array(""));
1797     } else {
1798       $smarty->assign ("phoneNumbers", $this->phoneNumbers);
1799     }
1801     $smarty->assign("goFonVoicemailPIN",$this->goFonVoicemailPIN);
1802     $smarty->assign("goFonPIN",$this->goFonPIN);
1804     $display= $smarty->fetch(get_template_path('paste_generic.tpl', TRUE, dirname(__FILE__)));
1805     $ret =array();
1806     $ret['string'] = $display;
1807     $ret['status'] = "";
1808     return($ret);
1809   }
1811   /* Save posts from copy & paste dialog dialog  */
1812   function saveCopyDialog()
1813   {
1814     if(!$this->is_account) return;
1815     $this->execute();
1816     if(isset($_POST['goFonVoicemailPIN'])) {
1817       $this->goFonVoicemailPIN = $_POST['goFonVoicemailPIN'];
1818     }
1819     if(isset($_POST['goFonPIN'])){
1820       $this->goFonPIN = $_POST['goFonPIN'];
1821     }
1822   }
1825   function allow_remove()
1826   {
1827     /* Check if previously selected server is still available */
1828     if($this->initially_was_account && !isset($this->goFonHomeServers[$this->goFonHomeServer])){
1829       return sprintf(_("The previously selected asterisk home server (%s) is no longer available. Remove aborted."),preg_replace("/,/",", ",$this->goFonHomeServer));
1830     }
1831   }
1833   /* Return plugin informations for acl handling */
1834   static function plInfo()
1835   {
1836     return (array(
1837           "plShortName"     => _("Phone"),
1838           "plDescription"   => _("Phone account settings"),
1839           "plSelfModify"    => TRUE,
1840           "plDepends"       => array("user"),
1841           "plPriority"      => 7,                                 // Position in tabs
1842           "plSection"         => array("personal" => _("My account")),
1843           "plCategory"        => array("users"),
1846           "plOptions"       => array(),
1848           "plProvidedAcls"  => array(
1849             "telephoneNumber"     => _("Telephone number"),
1850             "goFonMacro"          => _("Macro settings"),
1851             "goFonHardware"       => _("Phone hardware"),
1852             "goFonHomeServer"     => _("Home server"),
1853             "goFonContext"          => _("Phone context"),
1854             "goFonVoiceMailContext" => _("Voice mail context"),
1855             "goFonPIN"            => _("Telephone pin"),
1856             "goFonVoicemailPIN"   => _("Voicemail pin"))
1857           ));
1858   }
1862   function multiple_execute()
1863   {
1864     plugin::multiple_execute();
1865     return($this->execute());
1866   }
1868   function get_multi_init_values()
1869   {
1870     $ret = plugin::get_multi_init_values();
1871     $ret['phoneNumbers'] = array();
1872     foreach($this->phoneNumbers as $number){
1873       $ret['phoneNumbers'][] = $number."  [".$this->attrs['cn'][0]."]"; 
1874     }
1875     $ret['phoneNumbers']['count'] = count($ret['phoneNumbers']);
1876     return($ret);
1877   }
1879   function init_multiple_support($attrs,$all)
1880   {
1881     plugin::init_multiple_support($attrs,$all);
1883     $this->phoneNumbers = array();
1884     if(isset($all['phoneNumbers'])){
1885       for($i = 0 ; $i < $all['phoneNumbers']['count'] ; $i++){
1886         $this->phoneNumbers[$all['phoneNumbers'][$i]] = $all['phoneNumbers'][$i];
1887       }
1888     }
1889   }
1891   function multiple_save_object()
1892   {
1893     /* Simply call parents save_object */
1894     if (isset($_POST["phoneTab"])){
1896       plugin::save_object();
1897       plugin::multiple_save_object();
1899       /* Every macro in the select box are available */
1900       if((isset($_POST['macro']))){
1901         $this->macrostillavailable=true;
1902       }
1904       if(isset($_POST['macro']) && $_POST['macro'] != $this->macro){
1905         $this->macro = $_POST['macro'];
1906         $this->is_modified =true;
1907       }
1909       /* get all Postvars */
1910       if(isset($this->macroarray[$this->macro])){
1911         foreach($this->macroarray[$this->macro] as $key => $paras){
1912           $backup = $this->macroarray[$this->macro][$key];
1913           if(isset($_POST[$paras['var']])){
1914             $this->macroarray[$this->macro][$key]['choosen'] = $_POST[$paras['var']];
1915           }
1916           if(isset($_POST['post_success'])){
1917             if($this->macroarray[$this->macro][$key]['type']=="bool"){
1918               if(isset($_POST[$this->macroarray[$this->macro][$key]['var']])) {
1919                 $this->macroarray[$this->macro][$key]['choosen']=$_POST[$paras['var']];
1920               }else{
1921                 $this->macroarray[$this->macro][$key]['choosen']=false;
1922               }
1923             }
1924           }
1925         }
1926         if(count(array_diff($this->macroarray[$this->macro][$key],$backup))){
1927           $this->is_modified = TRUE;
1928         }
1929       }
1930     }
1931   }
1933   function multiple_check()
1934   {
1935     $message = plugin::multiple_check();
1937     if(!count($this->goFonHomeServers) && in_array_strict("goFonHomeServers",$this->multi_boxes)){
1938       $message[] = _("There is currently no asterisk server defined!");
1939     }
1941     if(empty($this->goFonHomeServer) && in_array_strict("goFonHomeServers",$this->multi_boxes)){
1942       $message[] = _("Asterisk server is invalid!");
1943     }
1945     if(in_array_strict("goFonVoicemailPIN",$this->multi_boxes) && 
1946         ( (strlen($this->goFonVoicemailPIN)==0)||
1947           (strlen($this->goFonVoicemailPIN)>4))){
1948       $message[]=(_("Voicemail PIN must be 4 characters long!"));
1949     }else{
1950       if(preg_match("/[^0-9]/",$this->goFonVoicemailPIN) && in_array_strict("goFonVoicemailPIN",$this->multi_boxes) ){
1951         $message[]=(_("Voicemail PIN contains invalid characters!"));
1952       }
1953     }
1955     if(preg_match("/[^0-9a-z]/i",$this->goFonPIN) && in_array_strict("goFonPIN",$this->multi_boxes)){
1956       $message[]=(_("Phone pin contains invalid characters!"));
1957     }
1959     /* check for ! in any parameter setting*/
1960     if(isset($this->macroarray[$this->macro]) && in_array_strict("macro",$this->multi_boxes)){
1961       foreach($this->macroarray[$this->macro] as $val){
1962         if((strstr($val['choosen'],"!"))||(strstr($val['choosen'],"#"))){
1963           $message[] = sprintf(_("The parameter %s contains invalid char. '!,#' is used as delimiter"),$val['name']);
1964         }
1965       }
1966     }
1968     return($message);
1969   }
1971   function get_multi_edit_values()
1972   {
1973     $ret = plugin::get_multi_edit_values();
1974     if(in_array_strict("macro",$this->multi_boxes)){
1975       $ret['macro'] = $this->macro;
1976       $ret['macroarray'] = $this->macroarray;
1977       $ret['macros'] = $this->macros;
1978     }
1979     return($ret);
1980   }
1983   /* Return asterisk contexts
1984    * Additionaly read contexts from file.
1985    */
1986   function get_asterisk_voicemail_contexts()
1987   {
1988     return($this->get_asterisk_contexts(CONFIG_DIR."/asterisk/voicemail_context.conf"));
1989   }
1990   function get_asterisk_sip_contexts()
1991   {
1992     return($this->get_asterisk_contexts(CONFIG_DIR."/asterisk/sip_context.conf"));
1993   }
1994   function get_asterisk_contexts($file)
1995   {
1996     $contexts = array();
1997     if(file_exists($file) && is_readable($file)){
1998       foreach(file($file) as $context){
1999         $contexts[] = trim($context);
2000       }
2001     }else{
2002       msg_dialog::display(_("Warning"), msgPool::cannotReadFile($file),WARNING_DIALOG);
2003       $contexts[] = "default";
2004     }
2005     array_unique($contexts);
2006     return($contexts);
2007   }
2010 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
2011 ?>