Code

4be721303bd9718349be1a883cdb83f6b4df2f78
[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";
9   /* Attributes */
10   var $telephoneNumber        = array();
11   var $goFonHardware          = "automatic";
12   var $goFonFormat            = "wav";
13   var $goFonPIN               = "";
14   var $goFonVoicemailPIN      = "";
15   var $goFonDeliveryMode      = "";
16   var $phoneNumbers           = array();
17   var $mail                   = "";
18   var $hardware_list          = array();
19   var $used_hardware          = array();
20   var $goFonMacro             = "";
21   var $macro                  = 0;              // Selected Macroi
22   var $lastmacro              = "";
23   var $macros                 = array();        // List of macros for smarty select box
24   var $macroarray             = array();        // All needed macro informations
25   var $macrostillavailable    = false;
26   var $generate_error         = "";
27   var $a_old_telenums         = array();
28   var $goFonPINVoice          = "";
29   var $goFonHomeServer        = "0";            // Contains the dn of the server that manage this account 
30   var $init_HomeServer        = "0";            // Contains the dn of the server that manage this account 
31   var $goFonHomeServers       = array();        // Contains all available server configurations 
33   var $context                = "default";
34   var $voice_context          = "default";
36   /* attribute list for save action */
37   var $CopyPasteVars          = array("phoneNumbers","macroarray","macrostillavailable"/*"phoneNumbers" -Reset- */,
38                                       "hardware_list","used_hardware");
40   var $attributes             = array("goFonDeliveryMode", "goFonFormat","goFonHomeServer",
41       "goFonHardware","goFonPIN","goFonVoicemailPIN","telephoneNumber", "goFonMacro","macro");
42   var $objectclasses= array("goFonAccount");
44   var $uid;
45   var $cn;
47   var $view_logged = FALSE;
48   var $multiple_support = TRUE;
49   var $mailAddress      = "";
50   var $has_mailAccount  = FALSE;
51   var $pager      = "";
53   function phoneAccount (&$config, $dn= NULL, $parent= NULL)
54   {
55     plugin::plugin ($config, $dn, $parent);
57     /* Assemble phone numbers */
58     if (isset($this->attrs['telephoneNumber'])){
59       for ($i= 0; $i<$this->attrs['telephoneNumber']['count']; $i++){
60         $number= $this->attrs['telephoneNumber'][$i];
61         $this->phoneNumbers[$number]= $number;
62       }
63     }
65     /* Set parent object to tab object */
66     if(is_object($parent)){
67       $this->parent = $parent->parent;
68     }
70     /* Get current uid and cn 
71      */
72     if(isset($this->attrs['uid'][0])){
73       $this->uid = $this->attrs['uid'][0];
74     }
75     if(isset($this->attrs['cn'][0])){
76       $this->cn = $this->attrs['cn'][0];
77     }
78     if(isset($this->attrs['mail'][0])){
79       $this->mailAddress = $this->attrs['mail'][0];
80     }
81     if(isset($this->attrs['pager'][0])){
82       $this->pager = $this->attrs['pager'][0];
83     }
85     /* If there is a parent object present, use references 
86      */
87     if(isset($this->parent->by_object['user']->uid)){
88       $this->uid = &$this->parent->by_object['user']->uid;
89     }
90     if(isset($this->parent->by_object['user']->cn)){
91       $this->cn   =&$this->parent->by_object['user']->cn;
92     }
93     if(isset($this->parent->by_object['user']->pager)){
94       $this->pager   =&$this->parent->by_object['user']->pager;
95     }
96     if(isset($this->parent->by_object['mailAccount']->mail)){
97       $this->mailAddress      = &$this->parent->by_object['mailAccount']->mail;
98       $this->has_mailAccount  = &$this->parent->by_object['mailAccount']->is_account();
99     }
101     /* Check server configurations 
102      * Load all server configuration in $this->goFonHomeServers if available
103      *  and first server as default if necessary.
104      * Check if connection is successfull for the selected server $this->goFonHomeServer
105      */
107   
108     /* Set available server */
109     $config = session::get('config');
110     if(isset($config->data['SERVERS']['FON'])){
111       $this->goFonHomeServers = $config->data['SERVERS']['FON'];
112     }
114     $a_SETUP= array();
115     if($this->is_account && isset($config->data['SERVERS']['FON']) &&
116        array_key_exists('FON',$config->data['SERVERS']) &&
117        is_callable("mysql_connect")
118        ) {
120       /* Servers defined? Watch here... */
121       if (count($this->goFonHomeServers)){
123         /* Set default server */
124         if(empty($this->goFonHomeServer) || $this->goFonHomeServer == "0"){
125           $this->goFonHomeServer= $this->goFonHomeServers[0]['DN'];
126         }
128         /* Remember inital home server, to be able to remove old entries */
129         $this->init_HomeServer = $this->goFonHomeServer;
131         /* Get config */
132         if(!isset($this->goFonHomeServers[$this->goFonHomeServer])){
133           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);
135           $this->goFonHomeServer = $this->goFonHomeServers[0]['DN'];
136           $this->init_HomeServer = $this->goFonHomeServers[0]['DN'];
137         }    
138         $cur_cfg = $this->goFonHomeServers[$this->goFonHomeServer];
140         $r_con =  @mysql_pconnect($cur_cfg['SERVER'],$cur_cfg['LOGIN'],$cur_cfg['PASSWORD']);
141         if(!$r_con){
142           new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error());
143         }
144         $db  =  @mysql_select_db($cur_cfg['DB'],$r_con);
145         if(!$db){
146           new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error());
147         }
149         $first = false; 
150         foreach($this->phoneNumbers as $key => $val){
151           if(!$first){
152             $first = $key;
153           }
154         }
155       }
156     }
158     /* Get available phone hardware  
159      * Search for all available phone hardware  
160      */
161     $tmp = get_sub_list("(objectClass=goFonHardware)","phone",array(get_ou("phoneou")),
162                   $this->config->current['BASE'],array("cn","description"), GL_NO_ACL_CHECK);
163     foreach($tmp as $attrs){
164       $cn= $attrs['cn'][0];
165       $description= "";
166       if (isset($attrs['description'])){
167         $description= " - ".$attrs['description'][0];
168       }
169       $this->hardware_list[$cn]= "$cn$description";
170     }
171     $this->hardware_list["automatic"]= _("automatic");
172     ksort($this->hardware_list);
175      /* Collect all usd phones 
176         goFonHardware set.
177      */
178     $deps_a = array(
179         get_people_ou(),
180         get_ou("ogroupou"),
181         get_ou("serverou"),
182         get_ou("terminalou"),
183         get_ou("workstationou"),
184         get_ou("printerou"),
185         get_ou("componentou"),
186         get_ou("phoneou"));
188     $tmp = get_sub_list("(goFonHardware=*)","phone",$deps_a,$this->config->current['BASE'],
189         array('cn','dn','goFonHardware'),GL_NO_ACL_CHECK);
190     foreach($tmp as $attrs){
191       $cn = $attrs['goFonHardware'][0];
192       if(isset($this->hardware_list[$cn])){
193         $this->used_hardware[$cn]= $cn;
194       }
195     }
198     /* Get available Macros  
199      * Search for all Macros that are visible and create 
200      *  an array with name and parameters 
201      */
202     $tmp = get_sub_list("(&(objectClass=goFonMacro)(goFonMacroVisible=1))","gofonmacro",array(get_ou("macroou")),
203                   $this->config->current['BASE'],array("displayName","goFonMacroParameter","dn","cn"), GL_NONE);
204     
206     /* Add none for no macro*/
207     $this->macros['none']=_("no macro");    
208     $this->macro ="none";
210     /* Fetch all Macros*/
211     foreach($tmp as $attrs){
213       /* unset Count, we don't need that here */
214       unset($attrs['displayName']['count']);
216       /* Parse macro data, unset count for parameterarrays  */
217       if (isset($attrs['goFonMacroParameter']['count'])){
218         unset($attrs['goFonMacroParameter']['count']);
219       }
221       /* fill Selectfield variable with Macros */
222       if(isset($attrs['displayName'][0])){
223         $this->macros[$attrs['dn']] = $attrs['displayName'][0]." (".$attrs['cn'][0].")";
224       }else{
225         $this->macros[$attrs['dn']] = _("undefined");
226       }
228       /* Go through available parameters and parse all attributes, like parametername, type, default ...*/
229       if((isset($attrs['goFonMacroParameter']))&&(is_array($attrs['goFonMacroParameter']))){
231         foreach($attrs['goFonMacroParameter'] as $pkey=>$pval){
232           /* Split Data in readable values, by delimiter !  */
233           $data = split("!",$attrs['goFonMacroParameter'][$pkey]);
235           /* Set all attrs */
236           $id = $data[0];
237           $this->macroarray[$attrs['dn']][$id]['var']    ="var".$id;
238           $this->macroarray[$attrs['dn']][$id]['choosen']=$data[3]; 
239           $this->macroarray[$attrs['dn']][$id]['id']     =$id;
240           $this->macroarray[$attrs['dn']][$id]['name']   =$data[1];
241           $this->macroarray[$attrs['dn']][$id]['type']   =$data[2];
242           $this->macroarray[$attrs['dn']][$id]['default']=$data[3];
243           if($data[2] == "bool"){
244             $this->macroarray[$attrs['dn']][$id]['choosen']=$data[3];
245           }
246         }//foreach
247       }//is_array
248     }//while
251     /* Parse used Macro  
252      * If we have a macro selected, parse it and set values 
253      *  in $this->macroarray[$this->macro]. 
254      */
255     $tmp = split("!",$this->goFonMacro);
256     if(is_array($tmp)){
258       /* First value is the macroname */
259       $this->macro = $tmp[0];
261       /* Macroname saved, delete that index */
262       unset($tmp[0]);
264       /* Check if makro has been removed */
265       if(!isset($this->macros[$this->macro])){
266         $this->macrostillavailable = false;
267       }else{
268         $this->macrostillavailable = true;
269       }
271       /* for each parametervalues ( parameterID#value like 25#twentyfive) */
272       foreach($tmp as $var){
274         /* Split this, so we have $varar[0] = parameterID $varar[1] = SelectedValue */
275         $varar = split("#",$var);
277         /* Only insert if the parameter still exists */
278         if(isset($this->macroarray[$this->macro][$varar[0]])){
279           /* Assign value */
280           $this->macroarray[$this->macro][$varar[0]]['choosen']=$varar[1];
281         }
282       }
283     }
286     $this->a_old_telenums = $this->phoneNumbers;
288     /* Get voicemail PIN from MySQL DB 
289      * Because every user can change his PIN directly from the phone
290      *  without any update to the ldap
291      * This means, the PIN in the DB is up to date
292      */
293     // Connect to DB server
294     if( (is_callable("mysql_pconnect"))&&
295         (isset($cur_cfg))&&
296         (isset($cur_cfg['SERVER']))&&
297         (isset($cur_cfg['LOGIN']))&&
298         (isset($cur_cfg['PASSWORD']))){
300       $r_con =  @mysql_pconnect($cur_cfg['SERVER'],$cur_cfg['LOGIN'],$cur_cfg['PASSWORD']);
301       if($r_con){
302         $r_db  =  @mysql_select_db($cur_cfg['DB'],$r_con);
303   
304         $query_tmp = "SELECT ".$cur_cfg['VOICE_TABLE'].".context as 'v_context', 
305                              ".$cur_cfg['SIP_TABLE'].".context, 
306                              ".$cur_cfg['VOICE_TABLE'].".password 
307                        FROM  ".$cur_cfg['VOICE_TABLE'].", 
308                              ".$cur_cfg['SIP_TABLE']." 
309                        WHERE customer_id = sip_users.mailbox AND name='".$this->uid."'";
312         $res = mysql_query($query_tmp);
313         $vp  = mysql_fetch_assoc($res);
314   
315         @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query_tmp, "Database query");
316         if((isset($vp['password']))&&(!empty($vp['password']))){
317           $this->goFonPINVoice = $vp['password'];
318         }
319         if((isset($vp['context']))&&(!empty($vp['context']))){
320           $this->context = $vp['context'];
321         }
322         if((isset($vp['v_context']))&&(!empty($vp['v_context']))){
323           $this->voice_context = $vp['v_context'];
324         }
325       }
326     }
327     $this->lastmacro=$this->macro;
329     if(is_callable("mysql_close")&&(isset($r_con))&&($r_con)){
330       @mysql_close($r_con) ;
331     }
332   }
335   /* This function generates the Database entries. 
336    * The Parameter 'save' could be true or false.
337    *  false - means only testing no database transactions.
338    *  true  - write database entries.
339    *
340    * 'sip_users','voice_mail' and 'extensions' table entries will be created.
341    * 
342    * If the phone hardware is 'automatic' the table entries will only be removed
343    *  and not added. 
344    */
345   function generate_mysql_entension_entries($save = false)
346   {
347     /* Check if there is at least one server available 
348      * If not, return and tell the user that saving failed 
349      */
350     if(!count($this->goFonHomeServers)){
351       if($save){
352         msg_dialog::display(_("Configuration error"), msgPool::noserver(_("GOfon")), WARNING_DIALOG);
353       }
354       return(true);
355     }
357     /* Check if Mysql extension is available */
358     if(!is_callable("mysql_pconnect")){
359       if($save){
360         msg_dialog::display(_("Configuration error"), msgPool::missingext("php-mysql"), WARNING_DIALOG);
361       }
362       return(true);
363     }
364  
365     /********************** 
366      * Attribute Initialisation
367      **********************/
369     $old_connection = false;
371     // Get Configuration for Mysql database Server
372     $s_parameter    = "";                                           // Contains paramter for selected Macro 
373     $r_con          = false;                                        // DB connection
374     $r_db           = false;                                        // Selected DB
375     $r_res          = false;                                        // Result resource
376     $a_ldap_attrs   = array();                                      //  
378     $s_ip           = NULL;                   // Contains ip for Sip entry
379     $s_host         = NULL;                   // Contains host for Sip entry
380     $s_qualify      = "yes";                  // Qualify entry
381     $s_pin          = NULL;                   // Entry for secret
382     $s_type         = NULL;                   // Entry for phone type (friend , peer ..)
384     $sip_data_array = array();                // Contains complete sip entry, to generate SQL syntax
385     $i_old_key      = false;                  // Contains index for first old phonenumber, to delete old entries corectly
386     $i_new_key      = false;                  // Contains index for first new phonenumber, to generate new  entries corectly
388     $s_sip_values   = "";     // Contains string with all values for given attributes in SQL syntax
389     $s_sip_keys     = "";     // Contains all needed attributes to generate sip entry in DB
391     $s_sip_key      = "";     // Key for SIP entry index      
392     $s_sip_val      = "";     // Value for SIP entry index      
394     $b_first_deleted= false;  // Only delete first entry, 
395     $s_telenums     = "";     // for each value variable
397     $i_is_accounted = false;  // Ensure that extension entry, for name to number is only once in table
399     restore_error_handler();
401     /* Prepare some basic attributes */
402     $oldnums = array();
403     foreach($this->a_old_telenums as $tele){
404       $oldnums[]= preg_replace("/[^0-9]/","",$tele);
405     }
406     foreach($this->phoneNumbers as $tele){
407       $newnums[]= preg_replace("/[^0-9]/","",$tele);
408     }
410     if(empty($this->uid)) trigger_error("Uid is empty.");
413     /* Create voicemail entry 
414      */
415     if((!isset($this->cn))||(empty($this->cn))){
416       $CNname= $this->uid;
417     }else{
418       $CNname= $this->cn;
419     }
421     $s_mail = "";
422     if($this->has_mailAccount){
423       $s_mail = $this->mailAddress;;
424     }
426     /* Get phonehardware to setup sip entry  */
427     $ldap         = $this->config->get_ldap_link();
428     $r_res        = $ldap->search("(&(objectClass=goFonHardware)(cn=".$this->goFonHardware."))", array('*'));
429     $a_ldap_attrs = $ldap->fetch();
431     /* Check selected phone hardware, is a default IP set? */
432     if(((isset($a_ldap_attrs['goFonDefaultIP'][0]))&&($a_ldap_attrs['goFonDefaultIP'][0] != "dynamic"))){
433       $s_ip       = $a_ldap_attrs['goFonDefaultIP'][0];
434       $s_host     = $s_ip;
435     }else{
436       $s_ip       = NULL;
437       $s_host     = "dynamic";
438     }
440     // Attribute GoFonQualify set ?
441     if(isset($a_ldap_attrs['goFonQualify'])){
442       $s_qualify = $a_ldap_attrs['goFonQualify'][0];
443     }
445     // Attribute GoFonPIN set ?
446     if(isset($this->goFonPIN)){
447       $s_pin      = $this->goFonPIN;
448     }
450     // Attribute GoFonType set ?
451     if(isset($a_ldap_attrs['goFonType'])){
452       $s_type = $a_ldap_attrs['goFonType'][0];
453     }
455     if(isset($a_ldap_attrs['goFonDmtfMode'][0])){
456       $sip_data_array['dtmfmode']     = $a_ldap_attrs['goFonDmtfMode'][0];
457     }else{
458       $sip_data_array['dtmfmode']     ="rfc2833";
459     }
461     /* Check if phone number is used */
462     if($this->is_number_used()){
463       $this->generate_error = $this->is_number_used(); 
464       return false;
465     }
469     /********************** 
470      * Check Server Connection Information
471      **********************/
472  
473     /* Create Mysql handle for the current goFonHomeServer, if possible  
474      * Get configuration to old asterisk home server 
475      */ 
476     $a_New = $this->goFonHomeServers[$this->goFonHomeServer];  // DB Configuration
477     $new_connection =  @mysql_pconnect($a_New['SERVER'],$a_New['LOGIN'],$a_New['PASSWORD']);
478     if(!$new_connection){
479       $this->generate_error =  msgPool::dbconnect($a_New['SERVER'],@mysql_error($new_connection),
480           _("Abort saving entries to keep the database consistent."));
481       new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error($new_connection));
482       return false;
483     }
484     $new_database  =  @mysql_select_db($a_New['DB'],$new_connection);
485     if(!$new_database){
486       $this->generate_error =  msgPool::dbselect($a_New['DB'],@mysql_error($new_connection),
487           _("Abort saving entries to keep the database consistent."));
488       new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error($new_connection));
489       return false;
490     }
492     /* If the home server has changed, we must remove entries from old 
493      *  server and add new entries in new server.  
494      */
495     if($this->init_HomeServer != $this->goFonHomeServer){
496     
497       /* Get configuration to old asterisk home server */ 
498       $a_Remove = $this->goFonHomeServers[$this->init_HomeServer];  // DB Configuration
499  
500       /* Create connection to the database that contains the old entry. 
501        */
502       $old_connection =  @mysql_pconnect($a_Remove['SERVER'],$a_Remove['LOGIN'],$a_Remove['PASSWORD']);
503       if(!$old_connection){
504         $this->generate_error =  msgPool::dbconnect($a_Remove['SERVER'],@mysql_error($old_connection),
505             _("Abort saving entries to keep the database consistent."));
506         new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error($old_connection));
507         return false;
508       }
509       $old_database  =  @mysql_select_db($a_Remove['DB'],$old_connection);
510       if(!$old_database){
511         $this->generate_error =  msgPool::dbselect($a_Remove['DB'],@mysql_error($old_connection),
512             _("Abort saving entries to keep the database consistent."));
513         new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error($old_connection));
514         return false;
515       }
516     }
518     /* Save means that we must save changes, not only test  */
519     if($save == true){
520     
521       /********************** 
522        * Remove entries from old home server 
523        **********************/
525       /* Check if there is an old entry 
526        * If there is an old entry, get callerid and remove voicemail and extensions 
527        */
528       if($old_connection){
529         $query  = "SELECT id,name,callerid FROM ".$a_Remove['SIP_TABLE']." WHERE name='".$this->uid."';";
530         $rid    = mysql_query($query,$old_connection);
531         @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query, "Database query");
533         /* Old entry found, remove it */
534         $query_a = array();
535         if(mysql_affected_rows($old_connection)){
536           $result = mysql_fetch_assoc($rid);
537           $query_a[]= "DELETE FROM ".$a_Remove['SIP_TABLE']." WHERE name='".$this->uid."';";
538           $query_a[]= "DELETE FROM ".$a_Remove['VOICE_TABLE']." WHERE customer_id='".$result['callerid']."';";
539           $query_a[]= "DELETE FROM ".$a_Remove['EXT_TABLE']." WHERE exten='".$this->uid."';";
540           foreach($oldnums as $s_telenums) {
541             $query_a[]= "DELETE FROM ".$a_Remove['EXT_TABLE']." WHERE exten='".$s_telenums."';";
542           }
544           foreach($query_a as $qry){
545                   @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$qry, "Database query");
546             if(!mysql_query($qry,$old_connection)){
547               trigger_error(mysql_error($old_connection));
548             } 
549           }
550         }
551       }
553       /********************** 
554        * Update / Insert sip_users entry  
555        **********************/
557       /* Set the first given phone number as callerid */
558       reset($newnums);        
559       $i_new_key = key($newnums);
560       $sip_data_array['callerid']  =$newnums[$i_new_key];
561       $sip_data_array['mailbox']   =$newnums[$i_new_key];
563       /* Check if there is already an entry in sip_users for this uid */
564       $SQL_query_array = array();
565       $query = "SELECT * FROM ".$a_New['SIP_TABLE']." WHERE name='".$this->uid."';\n"; 
566       $rid = mysql_query($query,$new_connection);
567       @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query, "Database query");
568       if(mysql_affected_rows($new_connection)){
570         /********************** 
571          * Update sip_users entry 
572          **********************/
573         $result                     = mysql_fetch_assoc($rid);
574         $sip_data_array['host']         = $s_host;
575         $sip_data_array['qualify']      = $s_qualify;
576         $sip_data_array['secret']       = $this->goFonPIN;
577         $sip_data_array['type']         = $s_type ;
578         $sip_data_array['username']     = $this->uid;
579         $sip_data_array['ipaddr']       = $s_ip;
580         $sip_data_array['context']      = $this->context;
582         /* Remove not changed attributes, to avoid updating table with same values */
583         foreach($sip_data_array as $name => $value){
584           if($result[$name] == $value){
585             unset($sip_data_array[$name]);
586           }
587         }
588         /* Only update entry if there is something to uopdate */
589         if(count($sip_data_array)){
590           $query = "UPDATE ".$a_New['SIP_TABLE']." SET ";
591           foreach($sip_data_array as $key => $val){
592             $query.= "".$key."='".$val."',"; 
593           } 
594           $query = preg_replace("/,$/","",$query);
595           $query.= " WHERE name='".$this->uid."';";
596           $SQL_query_array[] = $query;
597         }
598       } else {
599  
600         /********************** 
601          * Insert sip_users entry 
602          **********************/
603         //generate SIP entry
604         $sip_data_array['id']           = "";
605         $sip_data_array['name']         = $this->uid;
606         $sip_data_array['accountcode']  = NULL;          
607         $sip_data_array['amaflags']     = NULL;
608         $sip_data_array['callgroup']    = NULL;
609         $sip_data_array['canreinvite']  = "no";
610         $sip_data_array['context']      = $this->context;
611         $sip_data_array['defaultip']    = NULL;
612         $sip_data_array['fromuser']     = NULL;
613         $sip_data_array['fromdomain']   = NULL;
614         $sip_data_array['host']         = $s_host;
615         $sip_data_array['insecure']     = NULL;
616         $sip_data_array['language']     = NULL;
617         $sip_data_array['mailbox']      = $newnums[$i_new_key];
618         $sip_data_array['md5secret']    = NULL;
619         $sip_data_array['nat']          = "no";
620         $sip_data_array['permit']       = NULL;
621         $sip_data_array['deny']         = NULL;
622         $sip_data_array['mask']         = NULL;
623         $sip_data_array['pickupgroup']  = NULL;
624         $sip_data_array['port']         = NULL;
625         $sip_data_array['qualify']      = $s_qualify;
626         $sip_data_array['restrictcid']  = "n";
627         $sip_data_array['rtptimeout']   = NULL;
628         $sip_data_array['rtpholdtimeout']=NULL;
629         $sip_data_array['secret']       = $this->goFonPIN;
630         $sip_data_array['type']         = $s_type ;
631         $sip_data_array['username']     = $this->uid;
632         $sip_data_array['disallow']     = NULL;
633         $sip_data_array['allow']        = NULL;
634         $sip_data_array['musiconhold']  = NULL;
635         $sip_data_array['regseconds']   = NULL;
636         $sip_data_array['ipaddr']       = $s_ip;
637         $sip_data_array['regexten']     = NULL;
638         $sip_data_array['cancallforward']=NULL;
640         /* There is currently no entry for this user in the sip_users table. 
641          * We should create one i
642          */
643         foreach($sip_data_array as $s_sip_key=>$s_sip_val){
644           if($s_sip_val === NULL) continue;
645           $s_sip_values.="'".$s_sip_val."',";
646           $s_sip_keys  .="`".$s_sip_key."`,";
647         }
648         $s_sip_values =  preg_replace("/,$/","",$s_sip_values);
649         $s_sip_keys   =  preg_replace("/,$/","",$s_sip_keys);
651         /* Add sip entries to mysql queries */
652         $SQL_query_array[] ="INSERT INTO ".$a_New['SIP_TABLE']." (".$s_sip_keys.") VALUES (".$s_sip_values.");";
653       }
656       /********************** 
657        * Update / Insert Voice mail entry  
658        **********************/
660       $customer_id = $newnums[$i_new_key];
662       $voice_data_array = array(
663           "customer_id" => $customer_id,
664           "mailbox"     => $customer_id,
665           "password"    => $this->goFonVoicemailPIN,
666           "fullname"    => $CNname,
667           "context"     => $this->voice_context,
668           "email"       => $s_mail);
670       $voice_data_array['pager']   = $this->pager;
672       /* Check if there is already an entry in sip_users for this uid */
673       $query_tmp = "SELECT * FROM ".$a_New['VOICE_TABLE']." WHERE customer_id='".$customer_id."';\n";
674       $rid = mysql_query($query_tmp,$new_connection);
675       @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query_tmp, "Database query");
676       if(mysql_affected_rows($new_connection)){
678         /********************** 
679          * Update Voice mail entry  
680          **********************/
681         $result = mysql_fetch_assoc($rid)  ;
683         foreach($voice_data_array as $name => $value){
684           if($result[$name] == $value){
685             unset($voice_data_array[$name]);
686           }
687         }
689         /* Only update entry if there is something to uopdate */
690         if(count($voice_data_array)){
691           $query = "UPDATE ".$a_New['VOICE_TABLE']." SET ";
692           foreach($voice_data_array as $key => $val){
693             $query.= "".$key."='".$val."',"; 
694           } 
695           $query = preg_replace("/,$/","",$query);
696           $query.= " WHERE customer_id='".$customer_id."';";
697           $SQL_query_array[] = $query;
698         }
699       }else{
701         /********************** 
702          * Insert Voice mail entry  
703          **********************/
704         $voice_data_array['context'] = $this->voice_context;
705   
706         /* There is currently no voice mail entry for this user. 
707          * We should create one 
708          */
709         $s_voi_values = $s_voi_keys = "";
710         foreach($voice_data_array as $s_voi_key=>$s_voi_val){
711           if($s_voi_val === NULL) continue;
712           $s_voi_values.="'".$s_voi_val."',";
713           $s_voi_keys  .="`".$s_voi_key."`,";
714         }
715         $s_voi_values =  preg_replace("/,$/","",$s_voi_values);
716         $s_voi_keys   =  preg_replace("/,$/","",$s_voi_keys);
718         /* Add sip entries to mysql queries */
719         $SQL_query_array[] ="INSERT INTO ".$a_New['VOICE_TABLE']." (".$s_voi_keys.") VALUES (".$s_voi_values.");";
720       }
722      
723       /********************** 
724        * Remove/Insert extension entries
725        **********************/
726       
727       /* Remove old entries */
728       $query = array();
729       $query[]= "DELETE FROM ".$a_New['EXT_TABLE']." WHERE exten=\"".$this->uid."\";";
730       $oldnums= array();
731       foreach($oldnums as $s_telenums){
732         $query[]= "DELETE FROM ".$a_New['EXT_TABLE']." WHERE exten=\"".$s_telenums."\";";
733       }
734       foreach($newnums as $s_telenums){
735         $query[]= "DELETE FROM ".$a_New['EXT_TABLE']." WHERE exten=\"".$s_telenums."\";";
736       }
737       foreach($query as $qry){
738         @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$qry, "Database query");
739         if(!mysql_query($qry,$new_connection)){
740           trigger_error(mysql_error($new_connection));
741         } 
742       }
743  
744       /********************** 
745        * Insert extension entries
746        **********************/
747  
748       // Get selected Macro Parameter and create parameter entry 
749       if(isset($this->macroarray[$this->macro])){
750         foreach($this->macroarray[$this->macro] as $key => $val ){
751           $s_parameter .= $val['choosen']."|";
752         }
753         $s_parameter = preg_replace("/\|$/","",$s_parameter);
754       }
755      
756       $i = 0; 
757       $EXT = array();
758       if(!is_numeric($this->uid)){
759         $EXT[$i]['context'] = 'GOsa';
760         $EXT[$i]['exten']   = $this->uid;
761         $EXT[$i]['priority']= 1;
762         $EXT[$i]['app']     = "Goto";
763         $EXT[$i]['appdata'] = $newnums[$i_new_key]."|1";
764         $i ++;
765       }
767       // Entension entries  Hint / Dial / Goto
768       foreach($newnums as $s_telenums){
770         /* Hint Entry */
771         $EXT[$i]['context'] = 'GOsa';
772         $EXT[$i]['exten']   = $s_telenums;
773         $EXT[$i]['priority']= "Hint";
774         $EXT[$i]['app']     = 'SIP/'.$this->uid;
775         $i ++;  
776         /* SetCID */
777         //$EXT[$i]['context'] = 'GOsa';
778         //$EXT[$i]['exten']   = $s_telenums;
779         //$EXT[$i]['priority']= 1;
780         //$EXT[$i]['app']     = "SetCIDName";
781         //$EXT[$i]['appdata'] = $CNname;
782         //$i ++;  
784         // If no macro is selected use Dial
785         if($this->macro!="none"){ 
786           $macroname = preg_replace("/,.*$/","",$this->macro);        
787           $macroname = preg_replace("/^.*=/","",$macroname);        
788           $s_app = "Macro";$macroname;
789           $s_par = $macroname."|".$s_parameter; 
790         }else{
791           $s_app = "Dial";
792           $s_par = 'SIP/'.$this->uid."|20|r";
793         }
795         $EXT[$i]['context'] = 'GOsa';
796         $EXT[$i]['exten']   = $s_telenums;
797         $EXT[$i]['priority']= 1;
798         $EXT[$i]['app']     = $s_app;
799         $EXT[$i]['appdata'] = $s_par;
800         $i ++;
801       }
803       // Append all these Entries 
804       foreach($EXT as $entr){
805         $SQL_syn = "INSERT INTO ".$a_New['EXT_TABLE']." (";
806         foreach($entr as $key2 => $val2){
807           $SQL_syn.= "`".$key2."`,";
808         }
809         $SQL_syn = preg_replace("/,$/","",$SQL_syn);
810         $SQL_syn .= ") VALUES ("; 
811         foreach($entr as $key2 => $val2){
812           $SQL_syn .= "'".$val2."',";
813         }
814         $SQL_syn = preg_replace("/,$/","",$SQL_syn);
815         $SQL_syn .=");\n";
817         $SQL_query_array[] =$SQL_syn;
818         $SQL_syn ="";
819       }
821       // Perform queries ...
822       if($this->goFonHardware != "automatic"){
823         foreach($SQL_query_array as $query){
824           @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query, "Database query");
825           if(!@mysql_query($query,$new_connection)){
826             $this->generate_error =  msgPool::dbquery("GOfon",@mysql_error($old_connection));
827             return false;
828           }
829         }
830       }
831     }
832     @mysql_close($new_connection);
833     return true;
834   }
837   function execute()
838   {
839     /* Call parent execute */
840     plugin::execute();
842     /* Log view */
843     if($this->is_account && !$this->view_logged){
844       $this->view_logged = TRUE;
845       new log("view","users/".get_class($this),$this->dn);
846     }
848     $display = "";
849     $SkipWrite = (!isset($this->parent) || !$this->parent) && !session::is_set('edit');
851     if(empty($this->macro)&&(!empty($this->goFonMacro))){
853       /* Go through already saved values, for a parameter */
854       $tmp = split("!",$this->goFonMacro);
856       /* it is possible that nothing has been saved yet */
857       if(is_array($tmp)){
859         /* First value is the macroname */
860         $this->macro = $tmp[0];
862         /* Macroname saved, delete that index */
863         unset($tmp[0]);
865         /* Check if macro has been removed */
866         if(!isset($this->macroarray[$this->macro])){
867           $this->macrostillavailable = false;
868         }else{
869           $this->macrostillavailable = true;
870         }
872         /* for each parametervalues ( parameterID#value like 25#twentyfive) */
873         foreach($tmp as $var){
875           /* Split this, so we have $varar[0] = parameterID $varar[1] = SelectedValue */
876           $varar = split("#",$var);
878           /* Only insert if the parameter still exists */
879           if(isset($this->macroarray[$this->macro][$varar[0]])){
880             /* Assign value */
881             $this->macroarray[$this->macro][$varar[0]]['choosen']=$varar[1];
882           }
883         }
884       }
885     }
886     
887     /* Do we represent a valid account? */
888     if (!$this->is_account && $this->parent === NULL){
889       $display= "<img alt=\"\" src=\"images/small-error.png\" align=\"middle\">&nbsp;<b>".
890         msgPool::noValidExtension(_("Phone"))."</b>";
891       $display.= back_to_main();
892       return ($display);
893     }
895     /* Do we need to flip is_account state? */
896     if (isset($_POST['modify_state'])){
897       $this->is_account= !$this->is_account;
898     }
900     /* Do we represent a valid account? */
901     if (!$this->is_account && $this->parent === NULL){
902       $display= "<img alt=\"\" src=\"images/small-error.png\" align=\"middle\">&nbsp;<b>".
903         msgPool::noValidExtension(_("Phone"))."</b>";
904       $display.= back_to_main();
905       return($display);
906     }
908     $display= "";
910     /* Show tab dialog headers */
911     
912     if (!$this->multiple_support_active && $this->parent !== NULL){
913       if ($this->is_account){
914         $display= $this->show_disable_header(_("Remove phone account"),
915             msgPool::featuresEnabled(_("Phone")));
916       } else {
917         if(empty($this->uid)){
918           $display= $this->show_enable_header(_("Create phone account"),
919             msgPool::featuresDisabled(_("Phone"),_("User uid")));
920         }else{
921           $display= $this->show_enable_header(_("Create phone account"),
922             msgPool::featuresDisabled(_("Phone")));
923         }
924         return ($display);
925       }
926     }
927     /* Select no macro if, state is empty, this is the case, if the selected macro is no longer available */
928     if(empty($this->macro)){
929       $this->macro ="none";
930     }
932     /* Prepare templating */
933     $smarty= get_smarty();
935     /* tell user that the selected plugin is no longer available */
936     if((!$this->macrostillavailable)&&($this->macro!="none")){
937       msg_dialog::display(_("Error"), _("Selected macro is not available anymore!"), ERROR_DIALOG);
938     }
940     /* Assing macroselectbox values  */
941     $smarty->assign("macros",$this->macros);   
942     $smarty->assign("macro", $this->macro);   
944     /* Assign contexts */
945     $smarty->assign("contexts",$this->get_asterisk_contexts());
946     $smarty->assign("context" ,$this->context);
947     $smarty->assign("voice_context" ,$this->voice_context);
949     /* check if there is a FON server created */
950     if(!count($this->goFonHomeServer)){
951       msg_dialog::display(_("Configuration error"), msgPool::noserver(_("GOfon")), WARNING_DIALOG);
952     }
954     /* Create html parameter table for selected macro parameters 
955      *  skip if no parameters given 
956      */
957     if(!isset($this->macroarray[$this->macro])){
958       $macrotab="";
959     }else{
961       $macrotab ="<table summary=\""._("Parameter")."\">";
962       /* for every single parameter-> display textfile,combo, or true false switch*/
964       foreach($this->phoneNumbers as $phonenum){
965         $tmp[] = $phonenum;
966       }
967     
968       if($this->macro != $this->lastmacro){
969         /* Go through all params */
970         foreach($this->macroarray[$this->macro] as $key => $paras){
972           $string = $paras['default'];
974           $string=preg_replace("/%uid/i",$this->uid,$string);
976           if(isset($this->cn)){
977             $string=preg_replace("/%cn/i",$this->cn,$string);
978           }
980           for($i = 0 ; $i < 10; $i++){
981             if(isset($tmp[$i])){
982               $string = preg_replace("/%telephoneNumber_".($i+1)."/i",$tmp[$i],$string);
983             }
984           }
985           if(isset($tmp[0])){
986             $string = preg_replace("/%telephoneNumber/i",$tmp[0],$string);
987           }
988           $this->macroarray[$this->macro][$key]['choosen']=$string;
989         }
990       }
992       foreach($this->macroarray[$this->macro] as $paras){
994         /* get al vars */
995         $var        = $paras['var'];           
996         $name       = $paras['name'];           
997         $default    = $paras['default'];
998         $type       = $paras['type'];
999         $choosen    = $paras['choosen'] ; 
1000         $str        = $default;
1002         $dis = "";
1003         if(!$this->acl_is_writeable("goFonMacro",$SkipWrite)){
1004           $dis = " disabled ";
1005         }
1007         /* in case of a combo box display a combobox with selected attr */
1008         $macrotab.= "<tr>";
1009         switch ($type){
1011           case "combo":
1012             $str= "<select name='".$var."' ".$dis." >";
1013           foreach(split(":",$default) as $choice){
1014             if($choosen==$choice){
1015               $str.= "\n<option value='".$choice."' selected>".$choice."&nbsp;</option>";
1016             }else{
1017               $str.= "\n<option value='".$choice."'>".$choice."&nbsp;</option>";
1018             }
1019           }
1020           $str.="</select>";
1021           $macrotab.= "<td>".base64_decode($name)."</td><td>$str";
1022           break;
1024           case "bool":
1025             if(!$choosen){
1026               $str="\n<input type='checkbox' name='".$var."' value='1' ".$dis." >";
1027             }else{
1028               $str="\n<input type='checkbox' name='".$var."' value='1' checked  ".$dis.">";
1029             }
1030           $macrotab.= "<td colspan='2'>$str&nbsp;".base64_decode($name)."";
1031           break;
1033           case "string":
1034             $str="<input name='".$var."' value='".$choosen."' ".$dis." style='width:340px;'>";
1035           $macrotab.= "<td>".base64_decode($name)."</td><td>$str";
1036           break;
1038         }
1039         $macrotab.= "</td></tr>";
1041       }
1042       $macrotab.="</table><input name='post_success' type='hidden' value='1'>";
1043     }//is_array()
1045     /* Give smarty the table */
1046     $smarty->assign("macrotab",$macrotab);
1049     /* Add phone number */
1050     if (isset($_POST["add_phonenumber"]) && $_POST['phonenumber']){
1051       if (tests::is_phone_nr($_POST['phonenumber'])){
1052         $number= $_POST["phonenumber"];
1053         $this->phoneNumbers[$number]= $number;
1054         $this->is_modified= TRUE;
1055       } else {
1056         msg_dialog::display(_("Error"), msgPool::invalid("Phone number"), ERROR_DIALOG);
1057       }
1058     }
1060     /* Remove phone number */
1061     if (isset($_POST["delete_phonenumber"]) && isset($_POST["phonenumber_list"])){
1062       foreach ($_POST['phonenumber_list'] as $number){
1063         unset($this->phoneNumbers[$number]);
1064         $this->is_modified= TRUE;
1065       }
1066     }
1068     /* Assign acls */
1069     $tmp = $this->plInfo();
1070     foreach($tmp['plProvidedAcls'] as $name => $translation){
1071       $smarty->assign($name."ACL",$this->getacl($name,$SkipWrite));
1072     }
1074     /* Transfer ACL's */
1075     foreach($this->attributes as $val){
1076       if(isset($this->$val)){
1077         $smarty->assign($val,$this->$val);
1078       }else{
1079         $smarty->assign($val,"");
1080       }
1081     }
1083     /* Create home server array */
1084     $tmp = array();
1085     foreach($this->goFonHomeServers as $dn => $attrs){
1086       if(!is_numeric($dn)){
1087         $tmp[$dn] = $attrs['SERVER'];
1088       }
1089     }
1090     $smarty->assign("goFonHomeServers",$tmp);
1092     /* Fill arrays */
1093     $smarty->assign ("goFonHardware", $this->goFonHardware);
1094     if (!count($this->phoneNumbers)){
1095       $smarty->assign ("phoneNumbers", array());
1096     } else {
1097       $smarty->assign ("phoneNumbers", $this->phoneNumbers);
1098     }
1100     $dis = "";
1101     if(!$this->acl_is_writeable("goFonHardware",$SkipWrite)){
1102       $dis= " disabled ";
1103     }
1104     $hl= "<select size=\"1\" name=\"goFonHardware\" ".$dis." title=\"".
1105        _("Choose your private phone")."\">\n";
1107     foreach ($this->hardware_list as $cn => $description){
1108       if ($cn == $this->goFonHardware){
1109         $selected= "selected";
1110       } else {
1111         $selected= "";
1112       }
1113       if (isset($this->used_hardware[$cn])){
1114         $color= "style=\"color:#A0A0A0\"";
1115       } else {
1116         $color= "";
1117       }
1118       $hl.= "  <option $color label=\"$cn\" value=\"$cn\" $selected>$description&nbsp;</option>\n";
1119     }
1120     $hl.= "</select>\n";
1121     $smarty->assign ("hardware_list", $hl);
1124     foreach($this->attributes as $attr){
1125       if(in_array($attr,$this->multi_boxes)){
1126         $smarty->assign("use_".$attr,TRUE);
1127       }else{
1128         $smarty->assign("use_".$attr,FALSE);
1129       }
1130     }
1132     foreach(array("goFonVoiceMailContext","goFonContext") as $attr){
1133       if(in_array($attr,$this->multi_boxes)){
1134         $smarty->assign("use_".$attr,TRUE);
1135       }else{
1136         $smarty->assign("use_".$attr,FALSE);
1137       }
1138     }
1140     /* Show main page */
1141     $this->lastmacro = $this->macro;
1142     $smarty->assign("multiple_support",$this->multiple_support_active);
1143     $display.= $smarty->fetch(get_template_path('generic.tpl', TRUE, dirname(__FILE__)));
1144     return($display);
1145   }
1148   function save_object()
1149   {
1150     $SkipWrite = (!isset($this->parent) || !$this->parent) && !session::is_set('edit');
1151     if (isset($_POST["phoneTab"])){
1152     
1153       plugin::save_object();
1155       /* Save checkbox */
1156       $tmp = preg_replace("/[^a-z]/i","",$this->goFonDeliveryMode);
1157       if($this->acl_is_writeable("goFonDeliveryMode",$SkipWrite)){
1158         if(isset($_POST['fon_to_mail']) && !preg_match("/M/",$this->goFonDeliveryMode)){
1159           $tmp .= "M";
1160         }elseif(!isset($_POST['fon_to_mail']) && preg_match("/M/",$this->goFonDeliveryMode)){
1161           $tmp  = preg_replace ("/M/","",$tmp);
1162         }
1163       }
1164       $this->goFonDeliveryMode= "[".$tmp."]";
1167       /* Every macro in the select box are available */
1168       if((isset($_POST['macro']))){
1169         $this->macro = $_POST['macro'];
1170         $this->macrostillavailable=true;
1171       }
1173       if(isset($_POST['macro']) && $_POST['macro'] != $this->macro){
1174         $this->is_modified =true;
1175       }
1177       /* Save context */
1178       if(isset($_POST['context'])){
1179         if($this->context != $_POST['context']){
1180           $this->is_modified= TRUE;
1181         }
1182         $this->context= $_POST['context'];
1183       }
1185       /* Save voice context */
1186       if(isset($_POST['voice_context'])){
1187         if($this->voice_context != $_POST['voice_context']){
1188           $this->is_modified= TRUE;
1189         }
1190         $this->voice_context= $_POST['voice_context'];
1191       }
1193       if(is_array($this->phoneNumbers)){
1194         foreach($this->phoneNumbers as $telenumms) {
1195           $nummsinorder[]=$telenumms; 
1196         }
1197       }else{
1198         $nummsinorder=array("");
1199       }
1202       /* get all Postvars */
1203       if(isset($this->macroarray[$this->macro])){
1206         if($this->acl_is_writeable("goFonMacro",$SkipWrite)){
1207           foreach($this->macroarray[$this->macro] as $key => $paras){
1209             $old_macro_settings = $this->macroarray[$this->macro][$key]; 
1210             $backup = $this->macroarray[$this->macro][$key];
1212             if(isset($_POST[$paras['var']])){
1213               $this->macroarray[$this->macro][$key]['choosen'] = $_POST[$paras['var']];
1214             }
1216             /* Checkboxes are special, they are not Posted if they are not selected, so the won't be changed with the above code
1217                We need this code below to read and save checkboxes correct
1218              */
1220             if(isset($_POST['post_success'])){
1221               if($this->macroarray[$this->macro][$key]['type']=="bool"){
1222                 if(isset($_POST[$this->macroarray[$this->macro][$key]['var']])) {
1223                   $this->macroarray[$this->macro][$key]['choosen']=$_POST[$paras['var']];
1224                 }else{
1225                   $this->macroarray[$this->macro][$key]['choosen']=false;
1226                 }
1227               }
1228             }
1229             if(array_differs($old_macro_settings,$this->macroarray[$this->macro][$key])){
1230               $this->is_modified = TRUE;
1231             }
1232           }
1234           if(count(array_diff($this->macroarray[$this->macro][$key],$backup))){
1235             $this->is_modified = TRUE;
1236           }
1237         }
1238       }
1239     }
1240   }
1242   function check()
1243   {
1244     /* Call common method to give check the hook */
1245     $message= plugin::check();
1247     if(!count($this->goFonHomeServers)){
1248       $message[] = _("There must be at least one server with an asterisk database to create a phone account.");
1249     }
1251     if(empty($this->goFonHomeServer)){
1252       $message[] = msgPool::invalid(_("Home server"));
1253     }
1255     if((strlen($this->goFonVoicemailPIN)==0)||(strlen($this->goFonVoicemailPIN)>4)){
1256       $message[]= msgPool::invalid(_("Voicemail PIN"),"","",_("Between 1-4 charactes"));
1257     }else{
1258       if(preg_match("/[^0-9]/",$this->goFonVoicemailPIN)){
1259         $message[]= msgPool::invalid(_("Voicemail PIN"),preg_replace("/[0-9]/","X",$this->goFonVoicemailPIN),"/X/");
1260       }
1261     }
1263     if(preg_match("/[^0-9a-z]/i",$this->goFonPIN)){
1264       $message[]= msgPool::invalid(_("Phone PIN"),preg_replace("/[0-9a-z]/i","X",$this->goFonPIN),"/X/");
1265     }
1267     if ($this->initially_was_account != $this->is_account || $this->is_modified){
1268       if(!$this->generate_mysql_entension_entries()){
1269         $message[] = $this->generate_error;
1270       }
1271     }
1273     /* We need at least one phone number */
1274     if (count($this->phoneNumbers) == 0){
1275       $message[]= msgPool::required("Phone number");
1276     }
1278     /* check for ! in any parameter setting*/
1279     if(isset($this->macroarray[$this->macro])){
1280       foreach($this->macroarray[$this->macro] as $val){
1281         if((strstr($val['choosen'],"!"))||(strstr($val['choosen'],"#"))){
1282           $message[] = msgPool::invalid(sprintf(_("macro parameter %s"),$val['name']),$val['choosen'],"/[^\#]/");
1283         }
1284       }
1285     }
1286     return ($message);
1287   }
1291   function save()
1292   {
1293     plugin::save();
1295     /* Force saving macro again 
1296      * This ensures that 
1297      *  - the macro is available on the destiantion server.
1298      *  - the macro saved is up to date on the destination server.
1299      */
1300     if(!empty($this->macro) && $this->macro != "none")  {
1301       $macro_tab= new macrotabs($this->config,$this->config->data['TABS']['MACROTABS'], $this->macro,"gofonmacro");
1302       $macro_tab -> save();
1303     }
1305     /* Save arrays */
1306     $tmp_numbers = array();
1307     foreach ($this->phoneNumbers as $number){
1308       $tmp_numbers[] = $number;
1309     }
1311     /* Save settings, or remove goFonMacro attribute*/
1312     if($this->macro!="none"){    
1313       $this->attrs['goFonMacro']=$this->macro;
1314       if(isset($this->macroarray[$this->macro])){
1315         foreach($this->macroarray[$this->macro] as $paras)  {
1316           $this->attrs['goFonMacro'].="!".$paras['id']."#".$paras['choosen'];
1317         }
1318       }
1319     }else{
1320       $this->attrs['goFonMacro']=array();
1321     }
1322     unset($this->attrs['macro'])  ;
1324     $this->attrs['goFonForwarding']=array();
1326     if ($this->initially_was_account != $this->is_account || $this->is_modified){
1327       $str = $this->generate_mysql_entension_entries(true);
1328       if(empty($str)){
1329         msg_dialog::display(_("Error"), $str, ERROR_DIALOG);
1330       }
1331     }
1333     if($this->attrs['goFonMacro']==""){
1334       $this->attrs['goFonMacro']=array();
1335     }
1337     unset($this->attrs['cn']);
1339     /* Write back to ldap */
1340     $ldap= $this->config->get_ldap_link();
1341     $ldap->cd($this->dn);
1342     $this->cleanup();
1343     
1344     /* Force saving numbers, else it will be overwriten by user account. */
1345     $this->attrs['telephoneNumber'] =$tmp_numbers;
1346     $ldap->modify ($this->attrs); 
1348     /* Log last action */
1349     if($this->initially_was_account){
1350       new log("modify","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
1351     }else{
1352       new log("create","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
1353     }
1355     if (!$ldap->success()){
1356       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, 0, get_class()));
1357     }
1359     /* Optionally execute a command after we're done */
1361     if ($this->initially_was_account == $this->is_account){
1362       if ($this->is_modified){
1363         $this->handle_post_events("modify",array("uid" => $this->uid));
1364       }
1365     } else {
1366       $this->handle_post_events("add",array("uid" => $this->uid));
1367     }
1369   }
1372   function adapt_from_template($dn, $skip= array())
1373   {
1374     plugin::adapt_from_template($dn, $skip);
1376     /* Assemble phone numbers */
1377     if (isset($this->attrs['telephoneNumber']) && !in_array("telephoneNumber", $skip)){
1378       for ($i= 0; $i<$this->attrs['telephoneNumber']['count']; $i++){
1379         $number= $this->attrs['telephoneNumber'][$i];
1380         $this->phoneNumbers[$number]= $number;
1381       }
1382     }
1383   }
1386   function remove_from_parent()
1387   {
1388     if(!$this->initially_was_account) return;
1390     if(count($this->goFonHomeServers) && !empty($this->init_HomeServer) && is_callable("mysql_pconnect")){
1392       // Get Configuration for initial Mysql database Server
1393       $a_SETUP = $this->goFonHomeServers[$this->init_HomeServer];
1394       $s_parameter  ="";
1396       // Connect to DB server
1397       $r_con =  @mysql_pconnect($a_SETUP['SERVER'],$a_SETUP['LOGIN'],$a_SETUP['PASSWORD']);
1399       // Check if we are  connected correctly
1400       if(!$r_con){
1401         msg_dialog::display(_("Error"), msgPool::dbconnect("GOfon",@mysql_error()), ERROR_DIALOG);
1402         new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error());
1403         return false;
1404       }
1406       // Select database for Extensions
1407       $db  =  @mysql_select_db($a_SETUP['DB'],$r_con);
1409       // Test if we have the database selected correctly
1410       if(!$db){
1411         msg_dialog::display(_("Error"), msgPool::dbselect("GOfon", @mysql_error()), ERROR_DIALOG);
1412         new log("debug","gofonreport/".get_class($this),"",array(),@mysql_error());
1413         return false;
1414       }
1416       $SQL="";
1419       $first_num = false;
1420       // Delete old entries
1421       foreach($this->a_old_telenums as $s_telenums){
1422         if(!$first_num){
1423           $first_num = $s_telenums;
1424         }
1425         $SQL[] = "DELETE FROM ".$a_SETUP['EXT_TABLE']." WHERE exten='".$s_telenums."';\n";
1426       }
1428       $SQL[] = "DELETE FROM ".$a_SETUP['VOICE_TABLE']." WHERE customer_id='".$first_num."';";
1429       $SQL[] = "DELETE FROM ".$a_SETUP['EXT_TABLE']." WHERE exten='".$this->uid."';\n";
1430       $SQL[] = "DELETE FROM ".$a_SETUP['SIP_TABLE']." WHERE name='".$this->uid."';\n";
1432       foreach($SQL as $query){
1433         @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__,$query, "Database query");
1434         if(!@mysql_query($query,$r_con)){
1435           msg_dialog::display(_("Error"), msgPool::dbquery("GOfon",@mysql_error()), ERROR_DIALOG);
1436           return false;
1437         }
1438       }
1439     }else{
1440       msg_dialog::display(_("Configuration error"), msgPool::missingext("php-mysql"), WARNING_DIALOG);
1441       return false;
1442     }
1444     /* unset macro attr, it will cause an error */
1445     $tmp = array_flip($this->attributes);
1446     unset($tmp['macro']);
1447     $this->attributes=array_flip($tmp);
1449     /* Cancel if there's nothing to do here */
1450     if (!$this->initially_was_account){
1451       return;
1452     }
1454     plugin::remove_from_parent();
1456     /* Just keep one phone number */
1457     if (count($this->telephoneNumber) && $this->telephoneNumber != ""){
1458       $this->attrs['telephoneNumber']= $this->telephoneNumber;
1459     } else {
1460       $this->attrs['telephoneNumber']= array();
1461     }
1464     $ldap= $this->config->get_ldap_link();
1465     $ldap->cd($this->config->current['BASE']);
1466     $ldap->search("(&(objectClass=goFonQueue)(member=*))", array("member"));
1467     while($attr = $ldap->fetch()){
1468       if(in_array($this->dn,$attr['member'])){
1469         $new =new ogrouptabs($this->config, $this->config->data['TABS']['OGROUPTABS'],$attr['dn']);
1470         unset($new->by_object['ogroup']->memberList[$this->dn]);
1471         unset($new->by_object['ogroup']->member[$this->dn]);
1472         $new->save();
1473         msg_dialog::display(_("Information"), sprintf(_("User '%s' has been removed from phone queue '%s'."), $this->cn, $new->by_object['ogroup']->cn), INFO_DIALOG);
1474       }
1475     }
1476     $ldap->cd($this->dn);
1477     $this->cleanup();
1478     $ldap->modify ($this->attrs); 
1480     new log("remove","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
1481     if (!$ldap->success()){
1482       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
1483     }
1485     /* Optionally execute a command after we're done */
1486     @mysql_close($r_con);
1487     $this->handle_post_events('remove',array("uid"=> $this->uid));
1488   }
1492   /* This function checks if the given phonenumbers are available or already in use*/
1493   function is_number_used()
1494   {
1495     $ldap= $this->config->get_ldap_link();
1496     $ldap->cd($this->config->current['BASE']);
1497     $ldap->search("(|(objectClass=goFonAccount)(objectClass=goFonQueue)(objectClass=goFonConference))", array("telephoneNumber","cn","uid"));
1498     while($attrs = $ldap->fetch()) {
1499       unset($attrs['telephoneNumber']['count']);
1500       foreach($attrs['telephoneNumber'] as $tele){
1501         if(!isset($attrs['cn'][0])) $attrs['cn'][0]=$attrs['dn'];
1502         if(!isset($attrs['uid'][0])) $attrs['uid'][0]=$attrs['dn'];
1503         $numbers[$tele]=$attrs;
1504       }
1505     }
1507     foreach($this->phoneNumbers as $num){
1508       if((isset($numbers[$num]))&&(($numbers[$num]['uid'][0]!=$this->uid))){
1509         if(isset($numbers[$num]['uid'][0])){
1510           return sprintf(_("The specified telephonenumber '%s' is already assigned to '%s'."),$num,$numbers[$num]['uid'][0]);
1511         }else{
1512           return sprintf(_("The specified telephonenumber '%s' is already assigned to '%s'."),$num,$numbers[$num]['cn'][0]);
1513         }
1514       }
1515     }
1516   }
1519   /* Create phoneAccount part of copy & paste dialog */
1520   function getCopyDialog()
1521   { 
1522     if(!$this->is_account) return("");
1523     $smarty = get_smarty();
1524     if (!count($this->phoneNumbers)){
1525       $smarty->assign ("phoneNumbers", array(""));
1526     } else {
1527       $smarty->assign ("phoneNumbers", $this->phoneNumbers);
1528     }
1530     $smarty->assign("goFonVoicemailPIN",$this->goFonVoicemailPIN);
1531     $smarty->assign("goFonPIN",$this->goFonPIN);
1533     $display= $smarty->fetch(get_template_path('paste_generic.tpl', TRUE, dirname(__FILE__)));
1534     $ret =array();
1535     $ret['string'] = $display;
1536     $ret['status'] = "";
1537     return($ret);
1538   }
1540   /* Save posts from copy & paste dialog dialog  */
1541   function saveCopyDialog()
1542   {
1543     if(!$this->is_account) return;
1544     $this->execute();
1545     if(isset($_POST['goFonVoicemailPIN'])) {
1546       $this->goFonVoicemailPIN = $_POST['goFonVoicemailPIN'];
1547     }
1548     if(isset($_POST['goFonPIN'])){
1549       $this->goFonPIN = $_POST['goFonPIN'];
1550     }
1551   }
1554   function allow_remove()
1555   {
1556     /* Check if previously selected server is still available */
1557     if($this->initially_was_account && !isset($this->goFonHomeServers[$this->goFonHomeServer])){
1558       return sprintf(_("The previously selected asterisk home server (%s) is no longer available. Remove aborted."),preg_replace("/,/",", ",$this->goFonHomeServer));
1559     }
1560   }
1562   /* Return plugin informations for acl handling */
1563   static function plInfo()
1564   {
1565     return (array(
1566           "plShortName"     => _("Phone"),
1567           "plDescription"   => _("Phone account settings"),
1568           "plSelfModify"    => TRUE,
1569           "plDepends"       => array("user"),
1570           "plPriority"      => 7,                                 // Position in tabs
1571           "plSection"         => array("personal" => _("My account")),
1572           "plCategory"        => array("users"),
1575           "plOptions"       => array(),
1577           "plProvidedAcls"  => array(
1578             "telephoneNumber"     => _("Telephone number"),
1579             "goFonHomeServer"     => _("Home server"),
1580             "goFonMacro"          => _("Macro settings"),
1581             "goFonHardware"       => _("Phone hardware"),
1582             "goFonContext"          => _("Phone context"),
1583             "goFonVoiceMailContext" => _("Voice mail context"),
1584             "goFonPIN"            => _("Telephone pin"),
1585             "goFonVoicemailPIN"   => _("Voicemail pin"))
1586           ));
1587   }
1591   function multiple_execute()
1592   {
1593     plugin::multiple_execute();
1594     return($this->execute());
1595   }
1597   function get_multi_init_values()
1598   {
1599     $ret = plugin::get_multi_init_values();
1600     $ret['phoneNumbers'] = array();
1601     foreach($this->phoneNumbers as $number){
1602       $ret['phoneNumbers'][] = $number."  [".$this->attrs['cn'][0]."]"; 
1603     }
1604     $ret['phoneNumbers']['count'] = count($ret['phoneNumbers']);
1605     return($ret);
1606   }
1608   function init_multiple_support($attrs,$all)
1609   {
1610     plugin::init_multiple_support($attrs,$all);
1612     $this->phoneNumbers = array();
1613     if(isset($all['phoneNumbers'])){
1614       for($i = 0 ; $i < $all['phoneNumbers']['count'] ; $i++){
1615         $this->phoneNumbers[$all['phoneNumbers'][$i]] = $all['phoneNumbers'][$i];
1616       }
1617     }
1618   }
1620   function multiple_save_object()
1621   {
1622     /* Simply call parents save_object */
1623     if (isset($_POST["phoneTab"])){
1625       plugin::save_object();
1626       plugin::multiple_save_object();
1628       /* Every macro in the select box are available */
1629       if((isset($_POST['macro']))){
1630         $this->macrostillavailable=true;
1631       }
1633       if(isset($_POST['macro']) && $_POST['macro'] != $this->macro){
1634         $this->macro = $_POST['macro'];
1635         $this->is_modified =true;
1636       }
1638       /* get all Postvars */
1639       if(isset($this->macroarray[$this->macro])){
1640         foreach($this->macroarray[$this->macro] as $key => $paras){
1641           $backup = $this->macroarray[$this->macro][$key];
1642           if(isset($_POST[$paras['var']])){
1643             $this->macroarray[$this->macro][$key]['choosen'] = $_POST[$paras['var']];
1644           }
1645           if(isset($_POST['post_success'])){
1646             if($this->macroarray[$this->macro][$key]['type']=="bool"){
1647               if(isset($_POST[$this->macroarray[$this->macro][$key]['var']])) {
1648                 $this->macroarray[$this->macro][$key]['choosen']=$_POST[$paras['var']];
1649               }else{
1650                 $this->macroarray[$this->macro][$key]['choosen']=false;
1651               }
1652             }
1653           }
1654         }
1655         if(count(array_diff($this->macroarray[$this->macro][$key],$backup))){
1656           $this->is_modified = TRUE;
1657         }
1658       }
1659     }
1660   }
1662   function multiple_check()
1663   {
1664     $message = plugin::multiple_check();
1666     if(!count($this->goFonHomeServers) && in_array("goFonHomeServers",$this->multi_boxes)){
1667       $message[] = _("There is currently no asterisk server defined!");
1668     }
1670     if(empty($this->goFonHomeServer) && in_array("goFonHomeServers",$this->multi_boxes)){
1671       $message[] = _("Asterisk server is invalid!");
1672     }
1674     if(in_array("goFonVoicemailPIN",$this->multi_boxes) && 
1675         ( (strlen($this->goFonVoicemailPIN)==0)||
1676           (strlen($this->goFonVoicemailPIN)>4))){
1677       $message[]=(_("Voicemail PIN must be 4 characters long!"));
1678     }else{
1679       if(preg_match("/[^0-9]/",$this->goFonVoicemailPIN) && in_array("goFonVoicemailPIN",$this->multi_boxes) ){
1680         $message[]=(_("Voicemail PIN contains invalid characters!"));
1681       }
1682     }
1684     if(preg_match("/[^0-9a-z]/i",$this->goFonPIN) && in_array("goFonPIN",$this->multi_boxes)){
1685       $message[]=(_("Phone pin contains invalid characters!"));
1686     }
1688     /* check for ! in any parameter setting*/
1689     if(isset($this->macroarray[$this->macro]) && in_array("macro",$this->multi_boxes)){
1690       foreach($this->macroarray[$this->macro] as $val){
1691         if((strstr($val['choosen'],"!"))||(strstr($val['choosen'],"#"))){
1692           $message[] = sprintf(_("The parameter %s contains invalid char. '!,#' is used as delimiter"),$val['name']);
1693         }
1694       }
1695     }
1697     return($message);
1698   }
1700   function get_multi_edit_values()
1701   {
1702     $ret = plugin::get_multi_edit_values();
1703     if(in_array("macro",$this->multi_boxes)){
1704       $ret['macro'] = $this->macro;
1705       $ret['macroarray'] = $this->macroarray;
1706       $ret['macros'] = $this->macros;
1707     }
1708     return($ret);
1709   }
1712   /* Return asterisk contexts
1713    * Additionaly read contexts from file.
1714    */
1715   function get_asterisk_contexts()
1716   {
1717     $contexts = array();
1718     $contexts[] = "default";
1719     $contexts[] = "parkedcalls";
1720     $contexts[] = "from-sip";
1721     $contexts[] = "from-capi";
1722     $file = "/etc/gosa/asterisk_contexts.conf";
1723     if(file_exists($file) && is_readable($file)){
1724       foreach(file($file) as $context){
1725         $contexts[] = trim($context);
1726       }
1727     }
1728     array_unique($contexts);
1729     return($contexts);
1730   }
1733 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1734 ?>