Changeset 10286 for freepbx

Show
Ignore:
Timestamp:
09/16/10 02:44:08 (3 years ago)
Author:
mbrevda
Message:

re #4527

  • Move config reading/manipulation functions to own file
  • Move registry (extension/destination) to own file
  • Move sql shortcuts to own file
  • Add php upgrade to provide some level of compatibility to php < 5
  • removed file_put_contents as thats included in php-upgrade
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • freepbx/trunk/amp_conf/htdocs/admin/functions.inc.php

    r10244 r10286  
    1212//GNU General Public License for more details. 
    1313 
     14//include all nesesary classes TODO: inlcude them dynamicaly as needed 
     15require_once( (defined('AMP_BASE_INCLUDE_PATH') ? AMP_BASE_INCLUDE_PATH.'/' : '').'libraries/config.functions.php'); 
    1416require_once( (defined('AMP_BASE_INCLUDE_PATH') ? AMP_BASE_INCLUDE_PATH.'/' : '').'libraries/featurecodes.class.php'); 
    1517require_once( (defined('AMP_BASE_INCLUDE_PATH') ? AMP_BASE_INCLUDE_PATH.'/' : '').'libraries/components.class.php'); 
     
    2123require_once( (defined('AMP_BASE_INCLUDE_PATH') ? AMP_BASE_INCLUDE_PATH.'/' : '').'libraries/xml2Array.class.php'); 
    2224 
     25//include other files 
    2326require_once( (defined('AMP_BASE_INCLUDE_PATH') ? AMP_BASE_INCLUDE_PATH.'/' : '').'libraries/module.functions.php'); 
    24  
    25 $amp_conf_defaults = array( 
    26   'AMPDBENGINE'    => array('std' , 'mysql'), 
    27   'AMPDBNAME'      => array('std' , 'asterisk'), 
    28   'AMPENGINE'      => array('std' , 'asterisk'), 
    29   'ASTMANAGERPORT' => array('std' , '5038'), 
    30   'ASTMANAGERHOST' => array('std' , 'localhost'), 
    31   'AMPDBHOST'      => array('std' , 'localhost'), 
    32   'AMPDBUSER'      => array('std' , 'asteriskuser'), 
    33   'AMPDBPASS'      => array('std' , 'amp109'), 
    34   'AMPMGRUSER'     => array('std' , 'admin'), 
    35   'AMPMGRPASS'     => array('std' , 'amp111'), 
    36   'FOPPASSWORD'    => array('std' , 'passw0rd'), 
    37   'FOPSORT'        => array('std' , 'extension'), 
    38   'AMPSYSLOGLEVEL '=> array('std' , 'LOG_ERR'), 
    39   'ARI_ADMIN_PASSWORD' => array('std' , 'ari_password'), 
    40  
    41   'ASTETCDIR'      => array('dir' , '/etc/asterisk'), 
    42   'ASTMODDIR'      => array('dir' , '/usr/lib/asterisk/modules'), 
    43   'ASTVARLIBDIR'   => array('dir' , '/var/lib/asterisk'), 
    44   'ASTAGIDIR'      => array('dir' , '/var/lib/asterisk/agi-bin'), 
    45   'ASTSPOOLDIR'    => array('dir' , '/var/spool/asterisk/'), 
    46   'ASTRUNDIR'      => array('dir' , '/var/run/asterisk'), 
    47   'ASTLOGDIR'      => array('dir' , '/var/log/asterisk'), 
    48   'AMPBIN'         => array('dir' , '/var/lib/asterisk/bin'), 
    49   'AMPSBIN'        => array('dir' , '/usr/sbin'), 
    50   'AMPWEBROOT'     => array('dir' , '/var/www/html'), 
    51   'FOPWEBROOT'     => array('dir' , '/var/www/html/panel'), 
    52   'MOHDIR'         => array('dir' , '/mohmp3'), 
    53   'FPBXDBUGFILE'   => array('dir' , '/tmp/freepbx_debug.log'), 
    54  
    55   'USECATEGORIES'  => array('bool' , true), 
    56   'ENABLECW'       => array('bool' , true), 
    57   'CWINUSEBUSY'    => array('bool' , true), 
    58   'FOPRUN'         => array('bool' , true), 
    59   'AMPBADNUMBER'   => array('bool' , true), 
    60   'DEVEL'          => array('bool' , false), 
    61   'DEVELRELOAD'    => array('bool' , false), 
    62   'CUSTOMASERROR'  => array('bool' , true), 
    63   'DYNAMICHINTS'   => array('bool' , false), 
    64   'BADDESTABORT'   => array('bool' , false), 
    65   'SERVERINTITLE'  => array('bool' , false), 
    66   'XTNCONFLICTABORT' => array('bool' , false), 
    67   'USEDEVSTATE'    => array('bool' , false), 
    68   'MODULEADMINWGET'=> array('bool' , false), 
    69   'AMPDISABLELOG'  => array('bool' , true), 
    70   'AMPENABLEDEVELDEBUG'=> array('bool' , false), 
    71   'AMPMPG123'       => array('bool' , true), 
    72   'FOPDISABLE'      => array('bool' , false), 
    73   'ZAP2DAHDICOMPAT' => array('bool' , false), 
    74   'USEQUEUESTATE'   => array('bool' , false), 
    75   'CHECKREFERER'    => array('bool' , true), 
    76   'USEDIALONE'      => array('bool' , false), 
    77   'RELOADCONFIRM'   => array('bool' , true), 
    78   'DISABLECUSTOMCONTEXTS'   => array('bool' , false), 
    79  
    80 ); 
    81  
    82 function parse_amportal_conf($filename) { 
    83   global $amp_conf_defaults; 
    84  
    85   /* defaults 
    86    * This defines defaults and formating to assure consistency across the system so that 
    87    * components don't have to keep being 'gun shy' about these variables. 
    88    *  
    89    */ 
    90   $file = file($filename); 
    91   if (is_array($file)) { 
    92     foreach ($file as $line) { 
    93       if (preg_match("/^\s*([a-zA-Z0-9_]+)=([a-zA-Z0-9 .&-@=_!<>\"\']+)\s*$/",$line,$matches)) { 
    94         $conf[ $matches[1] ] = $matches[2]; 
    95       } 
    96     } 
    97   } else { 
    98     die_freepbx("<h1>".sprintf(_("Missing or unreadable config file (%s)...cannot continue"), $filename)."</h1>"); 
    99   } 
    100    
    101   // set defaults 
    102   foreach ($amp_conf_defaults as $key=>$arr) { 
    103  
    104     switch ($arr[0]) { 
    105       // for type dir, make sure there is no trailing '/' to keep consistent everwhere 
    106       // 
    107       case 'dir': 
    108         if (!isset($conf[$key]) || trim($conf[$key]) == '') { 
    109           $conf[$key] = $arr[1]; 
    110         } else { 
    111           $conf[$key] = rtrim($conf[$key],'/'); 
    112         } 
    113         break; 
    114       // booleans: 
    115       // "yes", "true", "on", true, 1 (case-insensitive) will be treated as true, everything else is false 
    116       // 
    117       case 'bool': 
    118         if (!isset($conf[$key])) { 
    119           $conf[$key] = $arr[1]; 
    120         } else { 
    121           $conf[$key] = ($conf[$key] === true || strtolower($conf[$key]) == 'true' || $conf[$key] === 1 || $conf[$key] == '1'  
    122                                               || strtolower($conf[$key]) == 'yes' ||  strtolower($conf[$key]) == 'on'); 
    123         } 
    124         break; 
    125       default: 
    126         if (!isset($conf[$key])) { 
    127           $conf[$key] = $arr[1]; 
    128         } else { 
    129           $conf[$key] = trim($conf[$key]); 
    130         } 
    131     } 
    132   } 
    133   return $conf; 
    134 
    135  
    136 function parse_asterisk_conf($filename) { 
    137   //TODO: Should the correction of $amp_conf be passed by refernce and optional? 
    138   // 
    139   global $amp_conf; 
    140   $conf = array(); 
    141      
    142   $convert = array( 
    143     'astetcdir'    => 'ASTETCDIR', 
    144     'astmoddir'    => 'ASTMODDIR', 
    145     'astvarlibdir' => 'ASTVARLIBDIR', 
    146     'astagidir'    => 'ASTAGIDIR', 
    147     'astspooldir'  => 'ASTSPOOLDIR', 
    148     'astrundir'    => 'ASTRUNDIR', 
    149     'astlogdir'    => 'ASTLOGDIR' 
    150   ); 
    151  
    152   $file = file($filename); 
    153   foreach ($file as $line) { 
    154     if (preg_match("/^\s*([a-zA-Z0-9]+)\s* => \s*(.*)\s*([;#].*)?/",$line,$matches)) {  
    155       $conf[ $matches[1] ] = rtrim($matches[2],"/ \t"); 
    156     } 
    157   } 
    158  
    159   // Now that we parsed asterisk.conf, we need to make sure $amp_conf is consistent 
    160   // so just set it to what we found, since this is what asterisk will use anyhow. 
    161   // 
    162   foreach ($convert as $ast_conf_key => $amp_conf_key) { 
    163     if (isset($conf[$ast_conf_key])) { 
    164       $amp_conf[$amp_conf_key] = $conf[$ast_conf_key]; 
    165     } 
    166   } 
    167   return $conf; 
    168 
    169  
    170 /** check if a specific extension is being used, or get a list of all extensions that are being used 
    171  * @param mixed     an array of extension numbers to check against, or if boolean true then return list of all extensions 
    172  * @param array     a hash of module names to search for callbacks, otherwise global $active_modules is used 
    173  * @return array    returns an empty array if exten not in use, or any array with usage info, or of all usage  
    174  *                  if exten is boolean true 
    175  * @description     Upon passing in an array of extension numbers, this api will query all modules to determine if any 
    176  *                  are using those extension numbers. If so, it will return an array with the usage information 
    177  *                  as described below, otherwise an empty array. If passed boolean true, it will return an array 
    178  *                  of the same format with all extensions on the system that are being used. 
    179  * 
    180  *                  $exten_usage[$module][$exten]['description'] // description of the extension 
    181  *                                               ['edit_url']    // a url that could be invoked to edit extension 
    182  *                                               ['status']      // Status: INUSE, RESERVED, RESTRICTED 
    183  */ 
    184 function framework_check_extension_usage($exten=true, $module_hash=false) { 
    185   global $active_modules; 
    186   $exten_usage = array(); 
    187  
    188   if (!is_array($module_hash)) { 
    189     $module_hash = $active_modules; 
    190   } 
    191  
    192   if (!is_array($exten) && $exten !== true) { 
    193     $exten = array($exten); 
    194   } 
    195  
    196   foreach(array_keys($module_hash) as $mod) { 
    197     $function = $mod."_check_extensions"; 
    198     if (function_exists($function)) { 
    199       $prev_domain = textdomain(NULL); 
    200       if (isset($_COOKIE['lang']) && is_dir("./modules/$mod/i18n/".$_COOKIE['lang'])) { 
    201         bindtextdomain($mod,"./modules/$mod/i18n"); 
    202         bind_textdomain_codeset($mod, 'utf8'); 
    203         textdomain($mod); 
    204         $module_usage = $function($exten); 
    205       } else { 
    206         textdomain('amp'); 
    207         $module_usage = $function($exten); 
    208       } 
    209       if (!empty($module_usage)) { 
    210         $exten_usage[$mod] = $module_usage; 
    211       } 
    212       textdomain($prev_domain); 
    213     } 
    214   } 
    215   if ($exten === true) { 
    216     return $exten_usage; 
    217   } else { 
    218     $exten_matches = array(); 
    219     foreach (array_keys($exten_usage) as $mod) { 
    220       foreach ($exten as $test_exten) { 
    221         if (isset($exten_usage[$mod][$test_exten])) { 
    222           $exten_matches[$mod][$test_exten] = $exten_usage[$mod][$test_exten]; 
    223         } 
    224       } 
    225     } 
    226   } 
    227   return $exten_matches; 
    228 
    229  
    230 /** check if a specific destination is being used, or get a list of all destinations that are being used 
    231  * @param mixed     an array of destinations to check against, or if boolean true then return list of all destinations in use 
    232  * @param array     a hash of module names to search for callbacks, otherwise global $active_modules is used 
    233  * @return array    returns an empty array if destination not in use, or any array with usage info, or of all usage  
    234  *                  if dest is boolean true 
    235  * @description     Upon passing in an array of destinations, this api will query all modules to determine if any 
    236  *                  are using that destination. If so, it will return an array with the usage information 
    237  *                  as described below, otherwise an empty array. If passed boolean true, it will return an array 
    238  *                  of the same format with all destinations on the system that are being used. 
    239  * 
    240  *                  $dest_usage[$module][]['dest']        // The destination being used 
    241  *                                        ['description'] // Description of who is using it 
    242  *                                        ['edit_url']    // a url that could be invoked to edit the using entity 
    243  *                                                
    244  */ 
    245 function framework_check_destination_usage($dest=true, $module_hash=false) { 
    246   global $active_modules; 
    247  
    248   $dest_usage = array(); 
    249   $dest_matches = array(); 
    250  
    251   if (!is_array($module_hash)) { 
    252     $module_hash = $active_modules; 
    253   } 
    254  
    255   if (!is_array($dest) && $dest !== true) { 
    256     $dest = array($dest); 
    257   } 
    258  
    259   foreach(array_keys($module_hash) as $mod) { 
    260     $function = $mod."_check_destinations"; 
    261     if (function_exists($function)) { 
    262       $prev_domain = textdomain(NULL); 
    263       if (isset($_COOKIE['lang']) && is_dir("./modules/$mod/i18n/".$_COOKIE['lang'])) { 
    264         bindtextdomain($mod,"./modules/$mod/i18n"); 
    265         bind_textdomain_codeset($mod, 'utf8'); 
    266         textdomain($mod); 
    267         $module_usage = $function($dest); 
    268       } else { 
    269         textdomain('amp'); 
    270         $module_usage = $function($dest); 
    271       } 
    272       if (!empty($module_usage)) { 
    273         $dest_usage[$mod] = $module_usage; 
    274       } 
    275       textdomain($prev_domain); 
    276     } 
    277   } 
    278   if ($dest === true) { 
    279     return $dest_usage; 
    280   } else { 
    281     /* 
    282     $destlist[] = array( 
    283       'dest' => $thisdest, 
    284       'description' => 'Annoucement: '.$result['description'], 
    285       'edit_url' => 'config.php?display=announcement&type='.$type.'&extdisplay='.urlencode($thisid), 
    286     ); 
    287     */ 
    288     foreach (array_keys($dest_usage) as $mod) { 
    289       foreach ($dest as $test_dest) { 
    290         foreach ($dest_usage[$mod] as $dest_item) { 
    291           if ($dest_item['dest'] == $test_dest) { 
    292             $dest_matches[$mod][] = $dest_item; 
    293           } 
    294         } 
    295       } 
    296     } 
    297   } 
    298   return $dest_matches; 
    299 
    300  
    301 /** provide optional alert() box and formatted url info for extension conflicts 
    302  * @param array     an array of extensions that are in conflict obtained from framework_check_extension_usage 
    303  * @param boolean   default false. True if url and descriptions should be split, false to combine (see return) 
    304  * @param boolean   default true. True to echo an alert() box, false to bypass the alert box 
    305  * @return array    returns an array of formatted URLs with descriptions. If $split is true, retuns an array 
    306  *                  of the URLs with each element an array in the format of array('label' => 'description, 'url' => 'a url') 
    307  * @description     This is used upon detecting conflicting extension numbers to provide an optional alert box of the issue 
    308  *                  by a module which should abort the attempt to create the extension. It also returns an array of 
    309  *                  URLs that can be displayed by the module to show the conflicting extension(s) and links to edit 
    310  *                  them or further interogate. The resulting URLs are returned in an array either formatted for immediate 
    311  *                  display or split into a description and the raw URL to provide more fine grained control (or use with guielements). 
    312  */ 
    313 function framework_display_extension_usage_alert($usage_arr=array(),$split=false,$alert=true) { 
    314   $url = array(); 
    315   if (!empty($usage_arr)) { 
    316     $conflicts=0; 
    317     foreach($usage_arr as $rawmodule => $properties) { 
    318       foreach($properties as $exten => $details) { 
    319         $conflicts++; 
    320         if ($conflicts == 1) { 
    321           switch ($details['status']) { 
    322             case 'INUSE': 
    323               $str = "Extension $exten not available, it is currently used by ".htmlspecialchars($details['description'])."."; 
    324               if ($split) { 
    325                 $url[] =  array('label' => "Edit: ".htmlspecialchars($details['description']), 
    326                                  'url'  =>  $details['edit_url'], 
    327                                ); 
    328               } else { 
    329                 $url[] =  "<a href='".$details['edit_url']."'>Edit: ".htmlspecialchars($details['description'])."</a>"; 
    330               } 
    331               break; 
    332             default: 
    333             $str = "This extension is not available: ".htmlspecialchars($details['description'])."."; 
    334           } 
    335         } else { 
    336           if ($split) { 
    337             $url[] =  array('label' => "Edit: ".htmlspecialchars($details['description']), 
    338                              'url'  =>  $details['edit_url'], 
    339                            ); 
    340           } else { 
    341             $url[] =  "<a href='".$details['edit_url']."'>Edit: ".htmlspecialchars($details['description'])."</a>"; 
    342           } 
    343         } 
    344       } 
    345     } 
    346     if ($conflicts > 1) { 
    347       $str .= sprintf(" There are %s additonal conflicts not listed",$conflicts-1); 
    348     } 
    349   } 
    350   if ($alert) { 
    351     echo "<script>javascript:alert('$str')</script>"; 
    352   } 
    353   return($url); 
    354 
    355  
    356 /** check if a specific destination is being used, or get a list of all destinations that are being used 
    357  * @param mixed     an array of destinations to check against 
    358  * @param array     a hash of module names to search for callbacks, otherwise global $active_modules is used 
    359  * @return array    array with a message and tooltip to display usage of this destination 
    360  * @description     This is called to generate a label and tooltip which summarized the usage of this 
    361  *                  destination and a tooltip listing all the places that use it 
    362  * 
    363  */ 
    364 function framework_display_destination_usage($dest, $module_hash=false) { 
    365  
    366   if (!is_array($dest)) { 
    367     $dest = array($dest); 
    368   } 
    369   $usage_list = framework_check_destination_usage($dest, $module_hash); 
    370   if (!empty($usage_list)) { 
    371     $usage_count = 0; 
    372     $str = null; 
    373     foreach ($usage_list as $mod_list) { 
    374       foreach ($mod_list as $details) { 
    375         $usage_count++; 
    376         $str .= $details['description']."<br />"; 
    377       } 
    378     } 
    379     $object = $usage_count > 1 ? _("Objects"):_("Object"); 
    380     return array('text' => '&nbsp;'.sprintf(dgettext('amp',"Used as Destination by %s %s"),$usage_count, dgettext('amp',$object)), 
    381                  'tooltip' => $str, 
    382                 ); 
    383   } else { 
    384     return array(); 
    385   } 
    386 
    387  
    388 /** determines which module a list of destinations belongs to, and if the destination object exists 
    389  * @param mixed     an array of destinations to check against 
    390  * @param array     a hash of module names to search for callbacks, otherwise global $active_modules is used 
    391  * @return array    an array structure with informaiton about the destinations (see code) 
    392  * @description     Mainly used by framework_list_problem_destinations. This function will find the module 
    393  *                  that a destination belongs to and determine if the object still exits. This allow it to 
    394  *                  either obtain the identify, identify it as an object that has been deleted, or identify 
    395  *                  it as an unknown destination, usually a custom destination. 
    396  * 
    397  */ 
    398 function framework_identify_destinations($dest, $module_hash=false) { 
    399   global $active_modules; 
    400   static $dest_cache = array(); 
    401  
    402   $dest_results = array(); 
    403  
    404   $dest_usage = array(); 
    405   $dest_matches = array(); 
    406  
    407   if (!is_array($module_hash)) { 
    408     $module_hash = $active_modules; 
    409   } 
    410  
    411   if (!is_array($dest)) { 
    412     $dest = array($dest); 
    413   } 
    414  
    415   foreach ($dest as $target) { 
    416     if (isset($dest_cache[$target])) { 
    417       $dest_results[$target] = $dest_cache[$target]; 
    418     } else { 
    419       $found_owner = false; 
    420       foreach(array_keys($module_hash) as $mod) { 
    421         $function = $mod."_getdestinfo"; 
    422         if (function_exists($function)) { 
    423           $prev_domain = textdomain(NULL); 
    424           if (isset($_COOKIE['lang']) && is_dir("./modules/$mod/i18n/".$_COOKIE['lang'])) { 
    425             bindtextdomain($mod,"./modules/$mod/i18n"); 
    426             bind_textdomain_codeset($mod, 'utf8'); 
    427             textdomain($mod); 
    428             $check_module = $function($target); 
    429           } else { 
    430             textdomain('amp'); 
    431             $check_module = $function($target); 
    432           } 
    433           textdomain($prev_domain); 
    434           if ($check_module !== false) { 
    435             $found_owner = true; 
    436             $dest_cache[$target] = array($mod => $check_module); 
    437             $dest_results[$target] = $dest_cache[$target]; 
    438             break; 
    439           } 
    440         } 
    441       } 
    442       if (! $found_owner) { 
    443         //echo "Not Found: $target\n"; 
    444         $dest_cache[$target] = false; 
    445         $dest_results[$target] = $dest_cache[$target]; 
    446       } 
    447     } 
    448   } 
    449   return $dest_results; 
    450 
    451  
    452 /** create a comprehensive list of all destinations that are problematic 
    453  * @param array     an array of destinations to check against 
    454  * @param bool      set to true if custome (unknown) destinations should be reported 
    455  * @return array    an array of the destinations that are empty, orphaned or custom 
    456  * @description     This function will scan the entire system and identify destinations 
    457  *                  that are problematic. Either empty, orphaned or an unknow custom 
    458  *                  destinations. An orphaned destination is one that should belong 
    459  *                  to a module but the object it would have pointed to does not exist 
    460  *                  because it was probably deleted. 
    461  */ 
    462 function framework_list_problem_destinations($module_hash=false, $ignore_custom=false) { 
    463   global $active_modules; 
    464  
    465   if (!is_array($module_hash)) { 
    466     $module_hash = $active_modules; 
    467   } 
    468  
    469   $my_dest_arr = array(); 
    470   $problem_dests = array(); 
    471  
    472   $all_dests = framework_check_destination_usage(true, $module_hash); 
    473  
    474   foreach ($all_dests as $dests) { 
    475     foreach ($dests as $adest) { 
    476       if (!empty($adest['dest'])) { 
    477         $my_dest_arr[] = $adest['dest']; 
    478       } 
    479     } 
    480   } 
    481   $my_dest_arr = array_unique($my_dest_arr); 
    482  
    483   $identities = framework_identify_destinations($my_dest_arr, $module_hash); 
    484  
    485   foreach ($all_dests as $dests) { 
    486     foreach ($dests as $adest) { 
    487       if (empty($adest['dest'])) { 
    488         $problem_dests[] = array('status' => 'EMPTY',  
    489                                  'dest' => $adest['dest'], 
    490                                  'description' => $adest['description'], 
    491                                  'edit_url' => $adest['edit_url'], 
    492                                 ); 
    493       } else if ($identities[$adest['dest']] === false){ 
    494         if ($ignore_custom) { 
    495           continue; 
    496         } 
    497         $problem_dests[] = array('status' => 'CUSTOM',  
    498                                  'dest' => $adest['dest'], 
    499                                  'description' => $adest['description'], 
    500                                  'edit_url' => $adest['edit_url'], 
    501                                 ); 
    502       } else if (is_array($identities[$adest['dest']])){ 
    503         foreach ($identities[$adest['dest']] as $details) { 
    504           if (empty($details)) { 
    505             $problem_dests[] = array('status' => 'ORPHAN',  
    506                                      'dest' => $adest['dest'], 
    507                                      'description' => $adest['description'], 
    508                                      'edit_url' => $adest['edit_url'], 
    509                                     ); 
    510  
    511           } 
    512           break; // there is only one set per array 
    513         } 
    514       } else { 
    515         echo "ERROR?\n"; 
    516         var_dump($adest); 
    517       } 
    518     } 
    519   } 
    520   return $problem_dests; 
    521 
    522  
    523 /** sort the hash based on the inner key 
    524  */ 
    525 function _framework_sort_exten($a, $b) { 
    526   $a_key = array_keys($a); 
    527   $a_key = $a_key[0]; 
    528   $b_key = array_keys($b); 
    529   $b_key = $b_key[0]; 
    530   if ($a_key == $b_key) { 
    531     return 0; 
    532   } else { 
    533     return ($a_key < $b_key) ? -1 : 1; 
    534   } 
    535 
    536  
    537 /** create a comprehensive list of all extensions conflicts 
    538  * @return array    an array of the destinations that are empty, orphaned or custom 
    539  * @description     This returns an array structure with information about all 
    540  *                  extension numbers that are in conflict. This means the same number 
    541  *                  is being used by 2 or more modules and the results will be ambiguous 
    542  *                  which one will be ignored when dialed. See the code for the 
    543  *                  structure of the retured array. 
    544  */ 
    545 function framework_list_extension_conflicts($module_hash=false) { 
    546   global $active_modules; 
    547  
    548   if (!is_array($module_hash)) { 
    549     $module_hash = $active_modules; 
    550   } 
    551  
    552   $exten_list = framework_check_extension_usage(true,$module_hash); 
    553  
    554   /** Bookkeeping hashes 
    555   *  full_hash[]     will contain the first extension encountered 
    556   *  conflict_hash[] will contain any subsequent extensions if conflicts 
    557   * 
    558   *  If there are conflicts, the full set is what is in conflict_hash + the 
    559   *  first extension encoutnered in full_hash[] 
    560   */ 
    561   $full_hash = array(); 
    562   $conflict_hash = array(); 
    563  
    564   foreach ($exten_list as $mod => $mod_extens) { 
    565     foreach ($mod_extens as $exten => $details) { 
    566       if (!isset($full_hash[$exten])) { 
    567         $full_hash[$exten] = $details; 
    568       } else { 
    569         $conflict_hash[] = array($exten => $details); 
    570       } 
    571     } 
    572   } 
    573  
    574   // extract conflicting remaining extension from full_hash but needs to be unique 
    575   // 
    576   if (!empty($conflict_hash)) { 
    577     $other_conflicts = array(); 
    578     foreach ($conflict_hash as $item)  { 
    579       foreach (array_keys($item) as $exten) { 
    580         $other_conflicts[$exten] = $full_hash[$exten]; 
    581       } 
    582     } 
    583     foreach ($other_conflicts as $exten => $details) { 
    584       $conflict_hash[] = array($exten => $details); 
    585     } 
    586     usort($conflict_hash, "_framework_sort_exten"); 
    587     return $conflict_hash; 
    588   } 
    589 
    590  
    591 /** Expands variables from amportal.conf  
    592  * Replaces any variables enclosed in percent (%) signs with their value 
    593  * eg, "%AMPWEBROOT%/admin/functions.inc.php" 
    594  */ 
    595 function expand_variables($string) { 
    596   global $amp_conf; 
    597   $search = $replace = array(); 
    598   foreach ($amp_conf as $key=>$value) { 
    599     $search[] = '%'.$key.'%'; 
    600     $replace[] = $value; 
    601   } 
    602   return str_replace($search, $replace, $string); 
    603 
     27require_once( (defined('AMP_BASE_INCLUDE_PATH') ? AMP_BASE_INCLUDE_PATH.'/' : '').'libraries/usage_registry.functions.php'); 
     28require_once( (defined('AMP_BASE_INCLUDE_PATH') ? AMP_BASE_INCLUDE_PATH.'/' : '').'libraries/php-upgrade.functions.php'); 
     29require_once( (defined('AMP_BASE_INCLUDE_PATH') ? AMP_BASE_INCLUDE_PATH.'/' : '').'libraries/sql.functions.php'); 
    60430 
    60531// returns true if extension is within allowed range 
     
    756182      } 
    757183  } 
    758 } 
    759  
    760 /* queries database using PEAR. 
    761 *  $type can be query, getAll, getRow, getCol, getOne, etc 
    762 *  $fetchmode can be DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC, DB_FETCHMODE_OBJECT 
    763 *  returns array, unless using getOne 
    764 */ 
    765 function sql($sql,$type="query",$fetchmode=null) { 
    766   global $db; 
    767   $results = $db->$type($sql,$fetchmode); 
    768   if(DB::IsError($results)) { 
    769     die_freepbx($results->getDebugInfo() . "SQL - <br /> $sql" ); 
    770   } 
    771   return $results; 
    772 } 
    773  
    774 /**  Format input so it can be safely used as a literal in a query.  
    775  * Literals are values such as strings or numbers which get utilized in places 
    776  * like WHERE, SET and VALUES clauses of SQL statements. 
    777  * The format returned depends on the PHP data type of input and the database  
    778  * type being used. This simply calls PEAR's DB::smartQuote() function 
    779  * @param  mixed  The value to go into the database 
    780  * @return string  A value that can be safely inserted into an SQL query 
    781  */ 
    782 function q(&$value) { 
    783   global $db; 
    784   return $db->quoteSmart($value); 
    785 } 
    786  
    787 // sql text formatting -- couldn't see that one was available already 
    788 function sql_formattext($txt) { 
    789   global $db; 
    790   if (isset($txt)) { 
    791     $fmt = $db->escapeSimple($txt); 
    792     $fmt = "'" . $fmt . "'"; 
    793   } else { 
    794     $fmt = 'null'; 
    795   } 
    796  
    797   return $fmt; 
    798184} 
    799185 
     
    1471857} 
    1472858 
    1473 function execSQL( $file ) { 
    1474   global $db; 
    1475   $data = null; 
    1476    
    1477   // run sql script 
    1478   $fd = fopen( $file ,"r" ); 
    1479    
    1480   while (!feof($fd)) {  
    1481     $data .= fread($fd, 1024);  
    1482   } 
    1483   fclose($fd); 
    1484    
    1485   preg_match_all("/((SELECT|INSERT|UPDATE|DELETE|CREATE|DROP).*);\s*\n/Us", $data, $matches); 
    1486   foreach ($matches[1] as $sql) { 
    1487     $result = $db->query($sql); 
    1488     if(DB::IsError($result)) { return false; } 
    1489   } 
    1490   return true; 
    1491 } 
    1492859 
    1493860// Dragged this in from page.modules.php, so it can be used by install_amp.  
     
    1495862  trigger_error("runModuleSQL() is depreciated - please use _module_runscripts(), or preferably module_install() or module_enable() instead", E_USER_WARNING); 
    1496863  _module_runscripts($moddir, $type); 
    1497 } 
    1498  
    1499 /** Replaces variables in a string with the values from ampconf 
    1500  * eg, "%AMPWEBROOT%/admin" => "/var/www/html/admin" 
    1501  */ 
    1502 function ampconf_string_replace($string) { 
    1503   global $amp_conf; 
    1504    
    1505   $target = array(); 
    1506   $replace = array(); 
    1507    
    1508   foreach ($amp_conf as $key=>$value) { 
    1509     $target[] = '%'.$key.'%'; 
    1510     $replace[] = $value; 
    1511   } 
    1512    
    1513   return str_replace($target, $replace, $string); 
    1514864} 
    1515865 
     
    1578928    dbug_write($msg."\n"); 
    1579929  } 
    1580 } 
    1581  
    1582 // PHP 4 does not have file_put_contents so create an aproximation of what the real function does 
    1583 // 
    1584 if (!function_exists('file_put_contents')) { 
    1585   function file_put_contents($filename, $data, $flags='', $context=null) { 
    1586     $option = $flags == FILE_APPEND ? 'a' : 'w'; 
    1587     if ($context !== null) { 
    1588       $fd = @fopen($filename, $option); 
    1589     } else { 
    1590       $fd = @fopen($filename, $option, false, $context); 
    1591     } 
    1592     if (!$fd) { 
    1593       return false; 
    1594     } 
    1595     if (is_array($data)) { 
    1596       $data = implode('',$data); 
    1597     } else if (is_object($data)) { 
    1598       $data = print_r($data,true); 
    1599     } 
    1600     $bytes = fwrite($fd,$data); 
    1601     fclose($fd); 
    1602  
    1603     return $bytes; 
    1604   } 
    1605930} 
    1606931