Code

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