Code

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