root/modules/branches/2.10/paging/functions.inc.php

Revision 14279, 36.0 kB (checked in by p_lindheimer, 10 months ago)

fixes #5913 I think though no feedback from reporter

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 <?php
2 /* $Id $ */
3 if (!defined('FREEPBX_IS_AUTH')) { die('No direct script access allowed'); }
4
5 /* paging_init - Is run every time the page is loaded, checks
6    to make sure that the database is current and loaded, if not,
7    it propogates it. I expect that extra code will go here to
8    check for version upgrades, etc, of the paging database, to
9    allow for easy upgrades. */
10
11 //    Generates dialplan for paging  - is called from retrieve_conf
12
13 function paging_get_config($engine) {
14     global $db, $ext, $chan_dahdi, $version, $amp_conf, $conferences_conf;
15     switch($engine) {
16         case "asterisk":
17             $ast_ge_14 = version_compare($version, "1.4", "ge");
18             $ast_ge_10 = version_compare($version, '10', 'ge');
19
20             // setup for intercom
21             $fcc = new featurecode('paging', 'intercom-prefix');
22             $intercom_code = $fcc->getCodeActive();
23             unset($fcc);
24
25             // Since these are going down channel local, set ALERT_INFO and SIPADDHEADER which will be set in dialparties.agi
26             // no point in even setting the headers here they will get lost in channel local
27             //
28
29             /* Set these up once here and in intercom so that autoanswer macro does not have
30              * to go through this for every single extension which causes a lot of extra overhead
31              * with big page groups
32              */
33
34             $has_answermacro = false;
35
36             $alertinfo = 'Alert-Info: Ring Answer';
37             $callinfo  = 'Call-Info: <uri>\;answer-after=0';
38             $sipuri    = 'intercom=true';
39             $doptions = 'A(beep)';
40             $vxml_url = '';
41             $dtime = '5';
42             $custom_vars = array();
43             $autoanswer_arr = paging_get_autoanswer_defaults();
44             foreach ($autoanswer_arr as $autosetting) {
45                 switch (trim($autosetting['var'])) {
46                     case 'ALERTINFO':
47                         $alertinfo = trim($autosetting['setting']);
48                         break;
49                     case 'CALLINFO':
50                         $callinfo = trim($autosetting['setting']);
51                         break;
52                     case 'SIPURI':
53                         $sipuri = trim($autosetting['setting']);
54                         break;
55                     case 'VXML_URL':
56                         $vxml_url = trim($autosetting['setting']);
57                         break;
58                     case 'DOPTIONS':
59                         $doptions = trim($autosetting['setting']);
60                         break;
61                     case 'DTIME':
62                         $dtime = trim($autosetting['setting']);
63                         break;
64                     default:
65                         $key = trim($autosetting['var']);
66                         $custom_vars[$key] = trim($autosetting['setting']);
67                         if (ltrim($custom_vars[$key],'_') == "ANSWERMACRO") {
68                             $has_answermacro = true;
69                         }
70                         break;
71                 }
72             }
73
74             $apppaging = 'app-paging';
75             if (!empty($intercom_code)) {
76                 $code = '_'.$intercom_code.'.';
77                 $context = 'ext-intercom';
78                 $ext->add($context, $code, '', new ext_macro('user-callerid'));
79                 $ext->add($context, $code, '', new ext_setvar('dialnumber', '${EXTEN:'.strlen($intercom_code).'}'));
80                 $ext->add($context, $code, '', new ext_setvar('INTERCOM_CALL', 'TRUE'));
81                 $ext->add($context, $code, '', new ext_gotoif('$["${DB(AMPUSER/${AMPUSER}/intercom/block)}" = "blocked"]', 'end'));
82                 $ext->add($context, $code, '', new ext_gotoif('$["${DB(DND/${dialnumber})}" = "YES"]', 'end'));
83                 $ext->add($context, $code, '', new ext_gotoif('$["${DB(AMPUSER/${dialnumber}/intercom/${AMPUSER})}" = "allow" ]', 'allow'));
84                 $ext->add($context, $code, '', new ext_gotoif('$["${DB(AMPUSER/${dialnumber}/intercom/${AMPUSER})}" = "deny" ]', 'nointercom'));
85                 $ext->add($context, $code, '', new ext_gotoif('$["${DB(AMPUSER/${dialnumber}/intercom)}" = "disabled" ]', 'nointercom'));
86                 $ext->add($context, $code, 'allow', new ext_dbget('DEVICES','AMPUSER/${dialnumber}/device'));
87                 $ext->add($context, $code, '', new ext_gotoif('$["${DEVICES}" = "" ]', 'end'));
88                 $ext->add($context, $code, '', new ext_setvar('LOOPCNT', '${FIELDQTY(DEVICES,&)}'));
89
90                 /* Set these up so that macro-autoanswer doesn't have to
91                  */
92                 $ext->add($context, $code, '', new ext_setvar('_SIPURI', ''));
93                 if (trim($alertinfo) != "") {
94                     $ext->add($context, $code, '', new ext_setvar('_ALERTINFO', $alertinfo));
95                 }
96                 if (trim($callinfo) != "") {
97                     $ext->add($context, $code, '', new ext_setvar('_CALLINFO', $callinfo));
98                 }
99                 if (trim($sipuri) != "") {
100                     $ext->add($context, $code, '', new ext_setvar('_SIPURI', $sipuri));
101                 }
102                 if (trim($vxml_url) != "") {
103                     $ext->add($context, $code, '', new ext_setvar('_VXML_URL', $vxml_url));
104                 }
105                 if (trim($doptions) != "") {
106                     $ext->add($context, $code, '', new ext_setvar('_DOPTIONS', $doptions));
107                 }
108                 foreach ($custom_vars as $key => $value) {
109                     $ext->add($context, $code, '', new ext_setvar('_'.ltrim($key,'_'), $value));
110                 }
111                 $ext->add($context, $code, '', new ext_setvar('_DTIME', $dtime));
112                 $ext->add($context, $code, '', new ext_setvar('_ANSWERMACRO', ''));
113
114                 $ext->add($context, $code, '', new ext_gotoif('$[${LOOPCNT} > 1 ]', 'pagemode'));
115                 $ext->add($context, $code, '', new ext_macro('autoanswer','${DEVICES}'));
116
117         if ($ast_ge_14) {
118                   $ext->add($context, $code, 'check', new ext_chanisavail('${DIAL}', 's'));
119                 $ext->add($context, $code, '', new ext_gotoif('$["${AVAILORIGCHAN}" = ""]', 'end'));           
120         } else {
121                   $ext->add($context, $code, 'check', new ext_chanisavail('${DIAL}', 'sj'));
122         }
123                 $ext->add($context, $code, '', new ext_noop_trace('AVAILCHAN: ${AVAILCHAN}, AVAILORIGCHAN: ${AVAILORIGCHAN}, AVAILSTATUS: ${AVAILSTATUS}',5));
124                 $dopt = '';
125                 if ($amp_conf['AST_FUNC_CONNECTEDLINE']) {
126                     $len = strlen($code)-2;
127                     $dopt = 'I';
128                     $ext->add($context, $code, '', new ext_gotoif('$["${DB(AMPUSER/${EXTEN:' . $len . '}/cidname)}" = ""]','godial'));
129                     $ext->add($context, $code, '', new ext_set('CONNECTEDLINE(name,i)', '${DB(AMPUSER/${EXTEN:' . $len . '}/cidname)}'));
130                     $ext->add($context, $code, '', new ext_set('CONNECTEDLINE(num)', '${EXTEN:' . $len . '}'));
131                 }
132                 $ext->add($context, $code, 'godial', new ext_dial('${DIAL}','${DTIME},' . $dopt . '${DOPTIONS}${INTERCOM_EXT_DOPTIONS}'));
133
134
135         $ext->add($context, $code, 'end', new ext_execif('$[${INTERCOM_RETURN}]', 'Return'));
136                 $ext->add($context, $code, '', new ext_busy());
137                 $ext->add($context, $code, '', new ext_macro('hangupcall'));
138         if (!$ast_ge_14) {
139                   $ext->add($context, $code, '', new ext_execif('$[${INTERCOM_RETURN}]', 'Return'),'check',101);
140                 $ext->add($context, $code, '', new ext_busy());
141                 $ext->add($context, $code, '', new ext_macro('hangupcall'));
142         }
143
144                 $ext->add($context, $code, 'pagemode', new ext_setvar('ITER', '1'));
145                 $ext->add($context, $code, '', new ext_setvar('DIALSTR', ''));
146                 $ds = $amp_conf['ASTCONFAPP'] == 'app_confbridge' ? '${DIALSTR}-${CUT(DEVICES,&,${ITER})}'
147                     : '${DIALSTR}&LOCAL/PAGE${CUT(DEVICES,&,${ITER})}@'.$apppaging;
148                 $ext->add($context, $code, 'begin', new ext_chanisavail('${DB(DEVICE/${CUT(DEVICES,&,${ITER})}/dial)}','s'));
149                 $ext->add($context, $code, '', new ext_gotoif('$["${AVAILORIGCHAN}" = ""]', 'skip'));
150                 $ext->add($context, $code, '', new ext_setvar('DIALSTR', $ds));
151                 $ext->add($context, $code, 'skip', new ext_setvar('ITER', '$[${ITER} + 1]'));
152                 $ext->add($context, $code, '', new ext_gotoif('$[${ITER} <= ${LOOPCNT}]', 'begin'));
153                 $ext->add($context, $code, '', new ext_setvar('DIALSTR', '${DIALSTR:1}'));
154                 $ext->add($context, $code, '', new ext_gotoif('$["${DIALSTR}" = ""]', 'end2'));
155                 $ext->add($context, $code, '', new ext_setvar('_AMPUSER', '${AMPUSER}'));
156                 if ($amp_conf['ASTCONFAPP'] == 'app_confbridge') {
157                     $ext->add($context, $code, '', new ext_gosub('1', 'page', false, '${DIALSTR}'));
158                 } else {
159                     $ext->add($context, $code, '', new ext_page('${DIALSTR},d'));
160                 }
161            $ext->add($context, $code, 'end2', new ext_execif('$[${INTERCOM_RETURN}]', 'Return'));
162                 $ext->add($context, $code, '', new ext_busy());
163                 $ext->add($context, $code, '', new ext_macro('hangupcall'));
164
165                 $ext->add($context, $code, 'nointercom', new ext_noop('Intercom disallowed by ${dialnumber}'));
166                 $ext->add($context, $code, '', new ext_execif('$[${INTERCOM_RETURN}]', 'Return'));
167                 $ext->add($context, $code, '', new ext_playback('intercom&for&extension'));
168                 $ext->add($context, $code, '', new ext_saydigits('${dialnumber}'));
169                 $ext->add($context, $code, '', new ext_playback('is&disabled'));
170                 $ext->add($context, $code, '', new ext_congestion());
171
172                 if ($amp_conf['ASTCONFAPP'] == 'app_confbridge') {
173                     $sub = 'page';
174                     $ext->add($context, $sub, '', new ext_set('PAGE_CONF', '${EPOCH}${RAND(100,999)}'));
175                     $ext->add($context, $sub, '', new ext_set('PAGEMODE', 'PAGE'));
176                     $ext->add($context, $sub, '', new ext_set('PAGE_MEMBERS', '${ARG1}'));
177                     $ext->add($context, $sub, '', new ext_set('PAGE_CONF_OPTS', 'duplex'));
178                     $ext->add($context, $sub, '', new ext_agi('page.agi'));           
179                     if ($ast_ge_10) {
180                         $ext->add($context, $sub, '', new ext_set('CONFBRIDGE(user,template)', 'page_user_duplex'));
181                         $ext->add($context, $sub, '', new ext_set('CONFBRIDGE(user,admin)', 'yes'));
182                         $ext->add($context, $sub, '', new ext_set('CONFBRIDGE(user,marked)', 'yes'));
183                         $ext->add($context, $sub, '', new ext_meetme('${PAGE_CONF}',',','admin_menu'));
184                     } else {
185                         $ext->add($context, $sub, '', new ext_meetme('${PAGE_CONF}', 'doqwxAG'));
186                     }
187                     $ext->add($context, $sub, '', new ext_hangup());
188                 }
189
190                 $extintercomusers = 'ext-intercom-users';
191                 $userlist = core_users_list();
192                 if (is_array($userlist)) {
193                     foreach($userlist as $item) {
194                         $ext_intercom_code = $intercom_code.$item[0];
195                         $ext->add($extintercomusers, $ext_intercom_code, '', new ext_goto($context.',${EXTEN},1'));
196                     }
197                 }
198
199                 $context = $extintercomusers;
200                 $ext->addInclude('from-internal-additional', $context);
201             }
202             
203             $fcc = new featurecode('paging', 'intercom-on');
204             $oncode = $fcc->getCodeActive();
205             unset($fcc);
206
207             if ($oncode) {
208                 $ext->add($context, $oncode, '', new ext_answer(''));
209                 $ext->add($context, $oncode, '', new ext_wait('1'));
210                 $ext->add($context, $oncode, '', new ext_macro('user-callerid'));
211                 $ext->add($context, $oncode, '', new ext_setvar('DB(AMPUSER/${AMPUSER}/intercom)', 'enabled'));
212                 $ext->add($context, $oncode, '', new ext_playback('intercom&enabled'));
213                 $ext->add($context, $oncode, '', new ext_macro('hangupcall'));
214
215                 $target = '${EXTEN:'.strlen($oncode).'}';
216                 $oncode = "_".$oncode.".";
217                 $ext->add($context, $oncode, '', new ext_answer(''));
218                 $ext->add($context, $oncode, '', new ext_wait('1'));
219                 $ext->add($context, $oncode, '', new ext_macro('user-callerid'));
220                 $ext->add($context, $oncode, '', new ext_gotoif('$["${DB(AMPUSER/${AMPUSER}/intercom/'.$target.')}" = "allow" ]}','unset'));
221                 $ext->add($context, $oncode, '', new ext_gotoif('$[${DB_EXISTS(AMPUSER/${EXTEN:3}/device)} != 1]','invaliduser'));
222                 $ext->add($context, $oncode, '', new ext_dbput('AMPUSER/${AMPUSER}/intercom/'.$target, 'allow'));
223                 $ext->add($context, $oncode, '', new ext_playback('intercom&enabled&for&extension&number'));
224                 $ext->add($context, $oncode, '', new ext_saydigits($target));
225                 $ext->add($context, $oncode, '', new ext_macro('hangupcall'));
226                 $ext->add($context, $oncode, 'unset', new ext_dbdeltree('AMPUSER/${AMPUSER}/intercom/'.$target));
227                 $ext->add($context, $oncode, '', new ext_playback('intercom&enabled&cancelled&for&extension&number'));
228                 $ext->add($context, $oncode, '', new ext_saydigits($target));
229                 $ext->add($context, $oncode, '', new ext_macro('hangupcall'));
230                 $ext->add($context, $oncode, 'invaliduser', new ext_playback('extension&number'));
231                 $ext->add($context, $oncode, '', new ext_saydigits($target));
232                 $ext->add($context, $oncode, '', new ext_playback('is&invalid'));
233                 $ext->add($context, $oncode, '', new ext_macro('hangupcall'));
234             }
235             
236             $fcc = new featurecode('paging', 'intercom-off');
237             $offcode = $fcc->getCodeActive();
238             unset($fcc);
239     
240             if ($offcode) {
241                 $ext->add($context, $offcode, '', new ext_answer(''));
242                 $ext->add($context, $offcode, '', new ext_wait('1'));
243                 $ext->add($context, $offcode, '', new ext_macro('user-callerid'));
244                 $ext->add($context, $offcode, '', new ext_setvar('DB(AMPUSER/${AMPUSER}/intercom)', 'disabled'));
245                 $ext->add($context, $offcode, '', new ext_playback('intercom&disabled'));
246                 $ext->add($context, $offcode, '', new ext_macro('hangupcall'));
247
248                 $target = '${EXTEN:'.strlen($offcode).'}';
249                 $offcode = "_".$offcode.".";
250                 $ext->add($context, $offcode, '', new ext_answer(''));
251                 $ext->add($context, $offcode, '', new ext_wait('1'));
252                 $ext->add($context, $offcode, '', new ext_macro('user-callerid'));
253                 $ext->add($context, $offcode, '', new ext_gotoif('$["${DB(AMPUSER/${AMPUSER}/intercom/'.$target.')}" = "deny" ]}','unset2'));
254                 $ext->add($context, $offcode, '', new ext_gotoif('$[${DB_EXISTS(AMPUSER/${EXTEN:3}/device)} != 1]','invaliduser2'));
255                 $ext->add($context, $offcode, '', new ext_dbput('AMPUSER/${AMPUSER}/intercom/'.$target, 'deny'));
256                 $ext->add($context, $offcode, '', new ext_playback('intercom&disabled&for&extension&number'));
257                 $ext->add($context, $offcode, '', new ext_saydigits($target));
258                 $ext->add($context, $offcode, '', new ext_macro('hangupcall'));
259                 $ext->add($context, $offcode, 'unset2', new ext_dbdeltree('AMPUSER/${AMPUSER}/intercom/'.$target));
260                 $ext->add($context, $offcode, '', new ext_playback('intercom&disabled&cancelled&for&extension&number'));
261                 $ext->add($context, $offcode, '', new ext_saydigits($target));
262                 $ext->add($context, $offcode, '', new ext_macro('hangupcall'));
263                 $ext->add($context, $offcode, 'invaliduser2', new ext_playback('extension&number'));
264                 $ext->add($context, $offcode, '', new ext_saydigits($target));
265                 $ext->add($context, $offcode, '', new ext_playback('is&invalid'));
266                 $ext->add($context, $offcode, '', new ext_macro('hangupcall'));
267             }
268
269             /* Create macro-autoanswer that will try to intelligently set the
270                required parameters to handle paging. Eventually it will use
271                  known device information.
272
273                 This macro does the following:
274
275                 Input:  FreePBX Device number to be called requiring autoanswer
276                 Output: ${DIAL} Channel Variable with the dial string to be called
277                         Appropriate SIP headers added
278                                 Other special requirements that may be custom for this device
279
280                 1. Set ${DIAL} to the device's dial string
281                 2. If there is a device specific macro defined in the DEVICE's object
282                    (DEVICE/<devicenum>/autoanswer/macro) then execute that macro and end
283                 3. Try to identify endpoints by their useragents that may need known
284                    changes and make those changes. These are generated from the
285                      paging_autoanswer table so users can extend them, if any are present
286                 5. Set the variables and end unless a useragent specific ANSWERMACRO is
287                    defined in which case call it and end.
288
289                 This macro is called for intercoming and paging to try and enable the
290                 target device to auto-answer. Devices with special needs can be handled
291                 with the device specific macro. For example, if you have a device that
292                 can not auto-answer except by specifically configuring a line key on
293                 the device that always answers, you could use a device specific macro
294                 to change the dialstring. If you had a set of such devices, you could
295                 standardize on the device numbers (e.g. nnnn for normal calls and 2nnnn
296                 for auto-answer calls). You could then create a general purpose macro
297                 to modify the dial string accordingly. Provisioning tools will be able
298                 to take advantage of setting and creating such an ability.
299                 If you have a set of devices that can be identified with a SIP useragent
300                 then you can use a general macro without setting info in each device.
301              */
302
303             $autoanswer_arr = paging_get_autoanswer_useragents();
304
305             $macro = 'macro-autoanswer';
306             $ext->add($macro, "s", '', new ext_setvar('DIAL', '${DB(DEVICE/${ARG1}/dial)}'));
307
308             // If we are in DAHDI compat mode, then we need to substitute DAHDI for ZAP
309             if ($chan_dahdi) {
310                 $ext->add($macro, "s", '', new ext_execif('$["${DIAL:0:3}" = "ZAP"]', 'Set','DIAL=DAHDI${DIAL:3}'));
311             }
312             $ext->add($macro, "s", '', new ext_gotoif('$["${DB(DEVICE/${ARG1}/autoanswer/macro)}" != "" ]', 'macro'));
313
314             // If there are no phone specific auto-answer vars, then we don't care what the phone is below
315             //
316             if (!empty($autoanswer_arr)) {
317                 $ext->add($macro, "s", '', new ext_setvar('phone', '${SIPPEER(${CUT(DIAL,/,2)}:useragent)}'));
318             }
319             // We used to set all the variables here (ALERTINFO, CALLINFO, etc. That has been moved to each
320             // paging group and the intercom main macro, since it was redundant for every phone causing a lot
321             // of overhead with large page groups.
322             //
323
324             // Defaults are setup, now make specific adjustments for detected phones
325             // These come from the SQL table as well where installations can make customizations
326             //
327             foreach ($autoanswer_arr as $autosetting) {
328                 $useragent   = trim($autosetting['useragent']);
329                 $autovar     = trim($autosetting['var']);
330                 $data        = trim($autosetting['setting']);
331                 switch (ltrim($autovar,'_')) {
332                     case 'ANSWERMACRO':
333                         $has_answermacro = true;
334                         // fall through - no break on purpose
335                     case 'ALERTINFO':
336                     case 'CALLINFO':
337                     case 'SIPURI':
338                     case 'VXML_URL':
339                     case 'DOPTIONS':
340                     case 'DTIME':
341                     default:
342                         if (trim($data) != "") {
343                             $ext->add($macro, "s", '', new ext_execif('$["${phone:0:'.strlen($useragent).'}" = "'.$useragent.'"]', 'Set',$autovar.'='.$data));
344                         }
345                         break;
346                 }
347             }
348
349             // Now any adjustments have been made, set the headers and done
350             //
351             if ($has_answermacro) {
352                 $ext->add($macro, "s", '', new ext_gotoif('$["${ANSWERMACRO}" != ""]','macro2'));
353             }
354             $ext->add($macro, "s", '', new ext_execif('$["${ALERTINFO}" != ""]', 'SipAddHeader','${ALERTINFO}'));
355             $ext->add($macro, "s", '', new ext_execif('$["${CALLINFO}" != ""]', 'SipAddHeader','${CALLINFO}'));
356             $ext->add($macro, "s", '', new ext_execif('$["${SIPURI}" != ""]', 'Set','__SIP_URI_OPTIONS=${SIPURI}'));
357             $ext->add($macro, "s", 'macro', new ext_macro('${DB(DEVICE/${ARG1}/autoanswer/macro)}','${ARG1}'), 'n',2);
358             if ($has_answermacro) {
359                 $ext->add($macro, "s", 'macro2', new ext_macro('${ANSWERMACRO}','${ARG1}'), 'n',2);
360             }
361             
362             //auto answer stuff
363             //set autoanswer variables
364             if (!empty($custom_vars)) {
365                 foreach ($custom_vars as $key => $value) {
366                     $ext->add($apppaging, '_AUTOASWER.', '', new ext_setvar('_'.ltrim($key,'_'), $value));
367                 }
368                 $ext->add($apppaging, '_AUTOASWER.', '', new ext_macro('autoanswer','${EXTEN:9}'));
369                 $ext->add($apppaging, '_AUTOASWER.', '', new ext_return());
370             }
371
372             // Setup Variables before AGI script
373             //
374             $ext->add($apppaging, 'ssetup', '', new ext_set('_SIPURI', ''));
375             if (isset($alertinfo) && trim($alertinfo) != "") {
376                 $ext->add($apppaging, 'ssetup', '', new ext_set('_ALERTINFO', $alertinfo));
377             }
378             
379             if (isset($callinfo) && trim($callinfo) != "") {
380                 $ext->add($apppaging, 'ssetup', '', new ext_set('_CALLINFO', $callinfo));
381             }
382             if (isset($sipuri) && trim($sipuri) != "") {
383                 $ext->add($apppaging, 'ssetup', '', new ext_set('_SIPURI', $sipuri));
384             }
385             if (isset($vxml_url) && trim($vxml_url) != "") {
386                 $ext->add($apppaging, 'ssetup', '', new ext_set('_VXML_URL', $vxml_url));
387             }
388             if (isset($doptions) && trim($doptions) != "") {
389                 $ext->add($apppaging, 'ssetup', '', new ext_set('_DOPTIONS', $doptions));
390             }
391             $ext->add($apppaging, 'ssetup', '', new ext_set('_DTIME', $dtime));
392             $ext->add($apppaging, 'ssetup', '', new ext_set('_ANSWERMACRO', ''));
393
394             $page_opts = $amp_conf['ASTCONFAPP'] == 'app_confbridge' ? '1qs' : '1doqsx';
395             $ext->add($apppaging, 'ssetup', '', new ext_set('PAGE_CONF', '${EPOCH}${RAND(100,999)}'));
396             $ext->add($apppaging, 'ssetup', '', new ext_return());
397                 
398             // Normal page version (now used for Force also)
399             // If we had any custom_vars then call the AUTOASWER subroutine first, otherwise go
400             // straight to macro-autoanswer
401             if (!empty($custom_vars)) {
402                 $ext->add($apppaging, "_PAGE.", 'SKIPCHECK', new ext_gosub('AUTOASWER${EXTEN:4},1'));
403             } else {
404                 $ext->add($apppaging, "_PAGE.", 'SKIPCHECK', new ext_macro('autoanswer', '${EXTEN:4}'));
405             }
406             $ext->add($apppaging, "_PAGE.", '', new ext_dial('${DIAL}','${DTIME},${DOPTIONS}'));
407             $ext->add($apppaging, "_PAGE.", 'skipself', new ext_hangup());
408
409             // Try ChanSpy Version
410             $ext->add($apppaging, "_SPAGE.", 'chanspy', new ext_chanspy('${SP_DEVICE}-','qW'));
411             $ext->add($apppaging, "_SPAGE.", '', new ext_hangup());
412
413             $apppagegroups = 'app-pagegroups';
414             // Now get a list of all the paging groups...
415             $sql = "SELECT page_group, force_page, duplex FROM paging_config";
416             $paging_groups = $db->getAll($sql, DB_FETCHMODE_ASSOC);
417             
418             if (!$paging_groups) {
419                 break;//no need to continue if we dont have any pagegroups
420             }
421
422             // If Asterisk 10 and app_confbridge:
423             //
424             // Common to admin:
425             //  d: dynamically addd conf
426             //  o: talker optimization (don't mix non-talkers)
427             //  q: quiet mode no enter/leave sounds
428             //  x: close conf when last marked user exits
429             //
430             // Not in Admin:
431             //  1: ???
432             //  s: present menu
433
434             if ($amp_conf['ASTCONFAPP'] == 'app_confbridge' && $ast_ge_10
435                 && isset($conferences_conf) && is_a($conferences_conf, "conferences_conf")) {
436                 $pu = 'page_user';
437                 $pud = 'page_user_duplex';
438                 foreach (array($pu, $pud) as $u) {
439                     $conferences_conf->addConfUser($u, 'quiet', 'yes');
440                     $conferences_conf->addConfUser($u, 'announce_user_count', 'no');
441                     $conferences_conf->addConfUser($u, 'wait_marked', 'yes');
442                     $conferences_conf->addConfUser($u, 'end_marked', 'yes');
443                     $conferences_conf->addConfUser($u, 'dsp_drop_silence', 'yes');
444                     $conferences_conf->addConfUser($u, 'announce_join_leave', 'no');
445                     $conferences_conf->addConfUser($u, 'admin', 'no');
446                     $conferences_conf->addConfUser($u, 'marked', 'no');
447                 }
448                 $conferences_conf->addConfUser($pu, 'startmuted', 'yes');
449             }
450
451             foreach ($paging_groups as $thisgroup) {
452                 $grp=trim($thisgroup['page_group']);
453                 switch ($thisgroup['force_page']) {
454                 case 1:
455                     $pagemode = 'FPAGE';
456                 break;
457                 case 2:
458                     $pagemode = 'SPAGE';
459                 break;
460                 case 0:
461                 default:
462                     $pagemode = 'PAGE';
463                 break;
464                 }
465
466                 $sql = "SELECT ext FROM paging_groups WHERE page_number='$grp'";
467                 $all_exts = $db->getCol($sql);
468                     
469                 // Create the paging context that is used in the paging application for each phone to auto-answer
470                 //add ext-paging with goto's to our app-paging context and a hint for the page
471                 $extpaging = 'ext-paging';
472                 $ext->add($extpaging, $grp, '', new ext_goto($apppagegroups . ',' . $grp . ',1'));
473                 $ext->addInclude('from-internal-noxfer-additional',$extpaging);
474                 $ext->addHint($extpaging, $grp, 'Custom:PAGE' . $grp);
475                     
476                 //app-page dialplan
477                     
478                 $ext->add($apppagegroups, $grp, '', new ext_macro('user-callerid'));
479                 $ext->add($apppagegroups, $grp, '', new ext_set('_PAGEGROUP', $grp));
480                     
481                 //if page group it in use, goto to busy
482                 $ext->add($apppagegroups, $grp, 'busy-check', new ext_gotoif('$[${TRYLOCK(apppagegroups'. $grp .')}]', '', 'busy'));
483                     
484                 //set blf to in use
485                 $ext->add($apppagegroups, $grp, 'devstate', new ext_setvar('DEVICE_STATE(Custom:PAGE' . $grp .')', 'INUSE'));
486                     
487                 $ext->add($apppagegroups, $grp, '', new ext_answer(''));
488                 $ext->add($apppagegroups, $grp, '', new ext_gosub('1','ssetup', $apppaging));
489                 $ext->add($apppagegroups, $grp, '', new ext_set('PAGEMODE', $pagemode));
490                 $ext->add($apppagegroups, $grp, '', new ext_set('PAGE_MEMBERS', implode('-', $all_exts)));
491                 if ($amp_conf['ASTCONFAPP'] == 'app_confbridge' && $ast_ge_10) {
492                     $ext->add($apppagegroups, $grp, '', new ext_set('PAGE_CONF_OPTS', ($thisgroup['duplex'] ? 'duplex' : '')));
493                 } else {
494                     $ext->add($apppagegroups, $grp, '', new ext_set('PAGE_CONF_OPTS', $page_opts . (!$thisgroup['duplex'] ? 'm' : '')));
495                 }
496                 $ext->add($apppagegroups, $grp, 'agi', new ext_agi('page.agi'));           
497
498                 //we cant use originate from the dialplan as the dialplan command is not asynchronous
499                 //we would like to though...
500                 //this code here as a sign of hope -MB
501                 /*foreach ($page_members as $member) {
502                         $ext->add($apppagegroups, $grp, 'page', new ext_originate($member,'app','meetme', '${PAGE_CONF}\,${PAGE_CONF_OPTS}'));
503                 }*/                   
504                 // TODO this is the master so set appropriate
505                 //      This is what everyone else has: 1doqsx
506                 //      Common:
507                 //        d: dynamically addd conf
508                 //        o: talker optimization (don't mix non-talkers)
509                 //        q: quiet mode no enter/leave sounds
510                 //        x: close conf when last marked user exits
511                 //      Added:
512                 //          w: W() wait until marked user enters conf
513                 //          A: Set marked mode
514                 //          G: G() Play an intro announcemend in conference
515                 //      Removed:
516                 //        1: ???
517                 //        s: present menu
518                 //
519                 //
520                 if ($amp_conf['ASTCONFAPP'] == 'app_confbridge' && $ast_ge_10) {
521                     $ext->add($apppagegroups, $grp, '', new ext_set('CONFBRIDGE(user,template)', $pud));
522                     $ext->add($apppagegroups, $grp, '', new ext_set('CONFBRIDGE(user,admin)', 'yes'));
523                     $ext->add($apppagegroups, $grp, '', new ext_set('CONFBRIDGE(user,marked)', 'yes'));
524                     // TODO: should I have no menu?
525                     $ext->add($apppagegroups, $grp, 'page', new ext_meetme('${PAGE_CONF}',',','admin_menu'));
526                 } else {
527                     $ext->add($apppagegroups, $grp, 'page', new ext_meetme('${PAGE_CONF}', 'doqwxAG'));
528                 }
529                 $ext->add($apppagegroups, $grp, '', new ext_hangup());
530                 $ext->add($apppagegroups, $grp, 'busy', new ext_set('PAGE${PAGEGROUP}BUSY', 'TRUE'));
531                 $ext->add($apppagegroups, $grp, 'play-busy', new ext_busy(3));
532                 $ext->add($apppagegroups, $grp, 'busy-hang', new ext_goto('app-pagegroups,h,1'));
533             }
534             
535             //h
536             $ext->add($apppagegroups, 'h', '',
537                 new ext_execif('$[${ISNULL(${PAGE${PAGEGROUP}BUSY})}]', 'Set', 'DEVICE_STATE(Custom:PAGE${PAGEGROUP})=NOT_INUSE'));
538             
539             //page playback
540             $c = 'app-page-stream';
541             $ext->add($c, 's', '', new ext_wait(1));
542             $ext->add($c, 's', '', new ext_answer());
543
544             // TODO: PAGE_CONF_OPTS reset in agi script so just use proper context if 10+confbridge no mute
545             // x: close conf when last marked user exits
546             // q: quiet mode no enter/leave sounds
547             //
548             // TODO: Ideally what we want is to mark the stream and wait for that, if no stream then no wait for makred user. However
549             //       it seems like to end a conference you have to have the kick after last marked user since there doesn't have to be
550             //       an admin as far as I can tell.
551             //
552             //
553             if ($amp_conf['ASTCONFAPP'] == 'app_confbridge' && $ast_ge_10) {
554                 $ext->add($c, 's', '', new ext_set('CONFBRIDGE(user,template)', $pud));
555                 $ext->add($c, 's', '', new ext_set('CONFBRIDGE(user,marked)', 'yes'));
556                 $ext->add($c, 's', '', new ext_meetme('${PAGE_CONF}','',''));
557             } else {
558                 $ext->add($c, 's', '', new ext_meetme('${PAGE_CONF}', '${PAGE_CONF_OPTS}'));
559             }
560             $ext->add($c, 's', '', new ext_hangup());
561             
562         break;
563     }
564 }
565
566 // This is the hook for 'destinations'
567 function paging_destinations() {
568     $results = paging_list();
569     // return an associative array with destination and description
570     if (isset($results)) {
571         foreach($results as $result){
572             $desc = $result['description'] ? $result['description'] : _('Page Group') . ' ' . $result['page_group'];
573             $extens[] = array('destination' => 'app-pagegroups,' . $result['page_group'] . ',1', 'description' => $desc);
574         }
575         return $extens;
576     } else {
577         return null;
578     }
579 }
580
581 function paging_getdest($exten) {
582     return array('pagegroups,'.$exten.',1');
583 }
584
585 function paging_get_autoanswer_defaults() {
586     global $db;
587
588     $sql = "SELECT * FROM paging_autoanswer WHERE useragent = 'default'";
589     $results = $db->getAll($sql,DB_FETCHMODE_ASSOC);
590     if(DB::IsError($results)) {
591         $results = array();
592     }
593     return $results;
594 }
595
596 function paging_get_autoanswer_useragents($useragent = '') {
597     global $db;
598
599     $sql = "SELECT * FROM paging_autoanswer WHERE useragent != 'default' ";
600     if ($useragent != "") {
601         $sql .= "AND useragent = $useragent ";
602     }
603     $results = $db->getAll($sql,DB_FETCHMODE_ASSOC);
604     if(DB::IsError($results)) {
605         $results = array();
606     }
607     return $results;
608 }
609
610 function paging_list() {
611     global $db;
612
613     $sql = "SELECT page_group, description FROM paging_config ORDER BY page_group";
614     $results = $db->getAll($sql,DB_FETCHMODE_ASSOC);
615     if(DB::IsError($results)) {
616         $results = null;
617     } else {
618         foreach ($results as $key => $list) {
619             $results[$key][0] = $list['page_group'];
620         }
621     }
622     // There should be a checkRange here I think, but I haven't looked into it yet.
623     //    return array('999', '998', '997');
624     return $results;
625 }
626
627 function paging_check_extensions($exten=true) {
628     global $active_modules;
629
630     $extenlist = array();
631     if (is_array($exten) && empty($exten)) {
632         return $extenlist;
633     }
634
635     $sql = "SELECT page_group, description FROM paging_config ";
636     if (is_array($exten)) {
637         $sql .= "WHERE page_group in ('".implode("','",$exten)."')";
638     }
639     $sql .= " ORDER BY page_group";
640     $results = sql($sql,"getAll",DB_FETCHMODE_ASSOC);
641
642     $type = isset($active_modules['paging']['type'])?$active_modules['paging']['type']:'setup';
643     foreach ($results as $result) {
644         $thisexten = $result['page_group'];
645         $extenlist[$thisexten]['description'] = _("Page Group: ").$result['description'];
646         $extenlist[$thisexten]['status'] = 'INUSE';
647         $extenlist[$thisexten]['edit_url'] = 'config.php?type='.urlencode($type).'setup&display=paging&selection='.urlencode($thisexten).'&action=modify';
648     }
649     return $extenlist;
650 }
651
652 function paging_get_devs($grp) {
653     global $db;
654
655     // Just in case someone's trying to be smart with a SQL injection.
656     $grp = $db->escapeSimple($grp);
657
658     $sql = "SELECT ext FROM paging_groups where page_number='$grp'";
659     $results = $db->getAll($sql);
660     if(DB::IsError($results))
661         $results = array();
662     foreach ($results as $val)
663         $tmparray[] = $val[0];
664     return $tmparray;
665 }
666
667 function paging_get_pagingconfig($grp) {
668     global $db;
669
670     // Just in case someone's trying to be smart with a SQL injection.
671     $grp = $db->escapeSimple($grp);
672
673     $sql = "SELECT * FROM paging_config WHERE page_group='$grp'";
674     $results = $db->getRow($sql, DB_FETCHMODE_ASSOC);
675     if(DB::IsError($results)) {
676         $results = null;
677     }
678     $sql = "SELECT * FROM admin WHERE variable='default_page_grp' AND value='$grp'";
679     $default_group = $db->getRow($sql, DB_FETCHMODE_ASSOC);
680     if(DB::IsError($default_group)) {
681         $results['default_group'] = 0;
682     } else {
683         $results['default_group'] = empty($default_group) ? 0 : $default_group['value'];
684     }
685     return $results;
686 }
687
688 function paging_modify($oldxtn, $xtn, $plist, $force_page, $duplex, $description='', $default_group=0) {
689     global $db;
690
691     // Just in case someone's trying to be smart with a SQL injection.
692     $xtn = $db->escapeSimple($xtn);
693
694     // Delete it if it's there.
695     paging_del($oldxtn);
696
697     // Now add it all back in.
698     paging_add($xtn, $plist, $force_page, $duplex, $description, $default_group);
699
700     // Aaad we need a reload.
701     needreload();
702
703 }
704
705 function paging_del($xtn) {
706     global $db;
707     $sql = "DELETE FROM paging_groups WHERE page_number='$xtn'";
708     $res = $db->query($sql);
709     if (DB::isError($res)) {
710         var_dump($res);
711         die_freepbx("Error in paging_del(): ");
712     }
713     
714     $sql = "DELETE FROM paging_config WHERE page_group='$xtn'";
715     $res = $db->query($sql);
716     if (DB::isError($res)) {
717         var_dump($res);
718         die_freepbx("Error in paging_del(): ");
719     }
720     sql("DELETE FROM `admin` WHERE variable = 'default_page_grp' AND value = '$xtn'");
721     
722     needreload();
723 }
724
725 function paging_add($xtn, $plist, $force_page, $duplex, $description='', $default_group) {
726     global $db;
727
728     // $plist contains a string of extensions, with \n as a seperator.
729     // Split that up first.
730     if (is_array($plist)) {
731         $xtns = $plist;
732     } else {
733         $xtns = explode("\n",$plist);
734     }
735     foreach (array_keys($xtns) as $val) {
736         $val = $db->escapeSimple(trim($xtns[$val]));
737         // Sanity check input.
738         
739         $sql = "INSERT INTO paging_groups(page_number, ext) VALUES ('$xtn', '$val')";
740         $db->query($sql);
741     }
742     
743     $description = $db->escapeSimple(trim($description));
744     $sql = "INSERT INTO paging_config(page_group, force_page, duplex, description) VALUES ('$xtn', '$force_page', '$duplex', '$description')";
745     $db->query($sql);
746     
747     if ($default_group) {
748         sql("DELETE FROM `admin` WHERE variable = 'default_page_grp'");
749         sql("INSERT INTO `admin` (variable, value) VALUES ('default_page_grp', '$xtn')");
750     } else {
751         sql("DELETE FROM `admin` WHERE variable = 'default_page_grp' AND value = '$xtn'");
752     }
753     
754     needreload();
755 }
756
757 function paging_check_default($extension) {
758     $sql = "SELECT ext FROM paging_groups WHERE ext = '$extension' AND page_number = (SELECT value FROM admin WHERE variable = 'default_page_grp' limit 1)";
759     $results = sql($sql,"getAll");
760     return (count($results) ? 1 : 0);
761 }
762
763 function paging_get_default() {
764     $default_group = sql("SELECT value FROM `admin` WHERE variable = 'default_page_grp' limit 1", "getOne");
765   return $default_group;
766 }
767
768 function paging_set_default($extension, $value) {
769     $default_group = sql("SELECT value FROM `admin` WHERE variable = 'default_page_grp' limit 1", "getOne");
770     if ($default_group == '') {
771         return false;
772     }
773     sql("DELETE FROM paging_groups WHERE ext = '$extension' AND page_number = '$default_group'");
774     if ($value == 1) {
775         sql("INSERT INTO paging_groups (page_number, ext) VALUES ('$default_group', '$extension')");
776     }
777 }
778     
779 function paging_configpageinit($pagename) {
780     global $currentcomponent;
781
782     $action = isset($_REQUEST['action'])?$_REQUEST['action']:null;
783     $extdisplay = isset($_REQUEST['extdisplay'])?$_REQUEST['extdisplay']:null;
784     $extension = isset($_REQUEST['extension'])?$_REQUEST['extension']:null;
785     $tech_hardware = isset($_REQUEST['tech_hardware'])?$_REQUEST['tech_hardware']:null;
786
787     // We only want to hook 'devices' or 'extensions' pages.
788     if ($pagename != 'devices' && $pagename != 'extensions') {
789         return true;
790     }
791
792     if ($tech_hardware != null && ($pagename == 'extensions' || $pagename == 'devices')) {
793         paging_applyhooks();
794         $currentcomponent->addprocessfunc('paging_configprocess', 8);
795     } elseif ($action=="add") {
796         // We don't need to display anything on an 'add', but we do need to handle returned data.
797         $currentcomponent->addprocessfunc('paging_configprocess', 8);
798     } elseif ($extdisplay != '') {
799         // We're now viewing an extension, so we need to display _and_ process.
800         paging_applyhooks();
801         $currentcomponent->addprocessfunc('paging_configprocess', 8);
802     }
803 }
804
805 function paging_applyhooks() {
806     global $currentcomponent;
807
808     // Add the 'process' function - this gets called when the page is loaded, to hook into
809     // displaying stuff on the page.
810     $currentcomponent->addoptlistitem('page_group', '0', _("Exclude"));
811     $currentcomponent->addoptlistitem('page_group', '1', _("Include"));
812     $currentcomponent->setoptlistopts('page_group', 'sort', false);
813
814     $currentcomponent->addguifunc('paging_configpageload');
815 }
816
817 /*
818 */
819 // This is called before the page is actually displayed, so we can use addguielem().
820 function paging_configpageload() {
821     global $currentcomponent;
822
823     // Init vars from $_REQUEST[]
824     $action = isset($_REQUEST['action']) ? $_REQUEST['action']:null;
825     $extdisplay = isset($_REQUEST['extdisplay']) ? $_REQUEST['extdisplay']:null;
826     $tech_hardware = isset($_REQUEST['tech_hardware']) ? $_REQUEST['tech_hardware']:'';
827     
828     // Don't display this stuff it it's on a 'This xtn has been deleted' page.
829     if ($action != 'del' && $tech_hardware != 'virtual') {
830
831         $default_group = sql("SELECT value FROM `admin` WHERE variable = 'default_page_grp'", "getOne");
832         $section = _("Default Group Inclusion");
833         if ($default_group != "") {
834             $in_default_page_grp = paging_check_default($extdisplay);
835             $currentcomponent->addguielem($section, new gui_selectbox('in_default_page_grp', $currentcomponent->getoptlist('page_group'), $in_default_page_grp, _('Default Page Group'), _('You can include or exclude this extension/device from being part of the default page group when creating or editing.'), false));
836         }
837     }
838 }
839
840 function paging_configprocess() {
841     global $db;
842
843     //create vars from the request
844     //
845     $action = isset($_REQUEST['action'])?$_REQUEST['action']:null;
846     $ext = isset($_REQUEST['extdisplay'])?$_REQUEST['extdisplay']:null;
847     $extn = isset($_REQUEST['extension'])?$_REQUEST['extension']:null;
848     $in_default_page_grp = isset($_REQUEST['in_default_page_grp'])?$_REQUEST['in_default_page_grp']:false;
849
850     if (($_REQUEST['display'] == 'devices') && $action == 'add') {
851         $extdisplay = $_REQUEST['deviceid'];
852     } else {
853         $extdisplay = ($ext=='') ? $extn : $ext;
854     }
855
856     if ($action == "add" || $action == "edit") {
857         if (!isset($GLOBALS['abort']) || $GLOBALS['abort'] !== true) {
858             if ($in_default_page_grp !== false) {
859                 paging_set_default($extdisplay, $in_default_page_grp);
860             }
861         }
862     } elseif ($action == "del") {
863         $sql = "DELETE FROM paging_groups WHERE ext = '$extdisplay'";
864         sql($sql);
865     }
866 }
867
868 ?>
869
Note: See TracBrowser for help on using the browser.