Code

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