Changeset 6600

Show
Ignore:
Timestamp:
09/07/08 18:33:09 (5 years ago)
Author:
p_lindheimer
Message:

Merged revisions 6539-6598 via svnmerge from
http://svn.freepbx.org/freepbx/branches/2.5

........

r6549 | p_lindheimer | 2008-09-03 14:54:37 -0700 (Wed, 03 Sep 2008) | 1 line


fixes #3145 LookupCIDName deprecated in 1.6

........

r6551 | p_lindheimer | 2008-09-03 16:16:11 -0700 (Wed, 03 Sep 2008) | 1 line


fixes #3151 typo in variable name that should not be there at all

........

r6552 | p_lindheimer | 2008-09-03 16:19:08 -0700 (Wed, 03 Sep 2008) | 1 line


fixes #3154 undefined variable needs global directive

........

r6554 | p_lindheimer | 2008-09-03 23:31:18 -0700 (Wed, 03 Sep 2008) | 1 line


fixes #3155 chown should be int not string for permissions

........

r6563 | p_lindheimer | 2008-09-04 14:43:50 -0700 (Thu, 04 Sep 2008) | 1 line


fix SECURITY SQL Injection vulnerability that could allow an authenticated user to access CDR and recorded calls from any other user on the system

........

r6572 | p_lindheimer | 2008-09-04 15:44:55 -0700 (Thu, 04 Sep 2008) | 1 line


re #3156 updated CHANGES MoH Streaming Categories

........

r6573 | p_lindheimer | 2008-09-04 18:05:44 -0700 (Thu, 04 Sep 2008) | 1 line


rearraged to move all classes at begining and fixed bug in mirror annoucements when using wget mode

........

r6574 | p_lindheimer | 2008-09-04 18:26:41 -0700 (Thu, 04 Sep 2008) | 1 line


no changes, just re-organized to move all functions to the bottom

........

r6577 | p_lindheimer | 2008-09-05 23:10:23 -0700 (Fri, 05 Sep 2008) | 1 line


typo in warning banner override mode

........

r6578 | p_lindheimer | 2008-09-05 23:11:39 -0700 (Fri, 05 Sep 2008) | 1 line


closes #3164 sql_formattext issue with sqlite3

........

r6579 | p_lindheimer | 2008-09-06 08:28:11 -0700 (Sat, 06 Sep 2008) | 1 line


additional sanity checks on callmonitor sql paramters

........

r6583 | p_lindheimer | 2008-09-06 17:34:17 -0700 (Sat, 06 Sep 2008) | 1 line


closes #3166 includes compatibility mode. translation using module's i18n is done first. If the translated text is the same as the original text, then translation is done against the the default _() which is amp.po at that point. So for previous translation work, it will continue to pull the old translations. All modules should move towards providing their own translations for menu items as this point despite this.

........

r6584 | p_lindheimer | 2008-09-06 19:37:04 -0700 (Sat, 06 Sep 2008) | 1 line


re #3166 and re #2461 the remove the linefeed that the xml parser inserts before and after an ampersand in menuitems and catagories so that translations can have a better chance of matching

........

r6585 | p_lindheimer | 2008-09-06 19:55:55 -0700 (Sat, 06 Sep 2008) | 1 line


re #3166 and re #2461 also cleanup the name field

........

r6586 | p_lindheimer | 2008-09-06 20:09:38 -0700 (Sat, 06 Sep 2008) | 1 line


re #3166 and re #2461 fixed typo in variable

........

r6587 | p_lindheimer | 2008-09-06 20:21:10 -0700 (Sat, 06 Sep 2008) | 1 line


re #3166 and re #2461 added translations to Module Admin so it can get them out of module's i18n also

........

r6590 | p_lindheimer | 2008-09-07 08:27:08 -0700 (Sun, 07 Sep 2008) | 1 line


re #3166 and re #2461 added ability to translated description and attention module admin xml fields

........

r6591 | p_lindheimer | 2008-09-07 09:51:56 -0700 (Sun, 07 Sep 2008) | 1 line


strip leading/trailingwhitespace and linefeed characters out of module.xml description field so that translations can more consistenly be done and so that when displayed, the text floats properly.

........

r6593 | ethans | 2008-09-07 11:24:20 -0700 (Sun, 07 Sep 2008) | 2 lines


Fixes #3165

........

r6595 | pnlarsson | 2008-09-07 13:42:10 -0700 (Sun, 07 Sep 2008) | 1 line


Fix for #3077 - DAHDI support, commit no 2 for core

........

r6597 | p_lindheimer | 2008-09-07 14:47:58 -0700 (Sun, 07 Sep 2008) | 1 line


re #3077 some tweaks based on version actually tested and update of CHANGES, amportal.conf

........

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • freepbx/trunk

    • Property svnmerge-integrated changed from /freepbx/branches/2.4:1-5944 /freepbx/branches/2.5:1-6538 to /freepbx/branches/2.4:1-5944 /freepbx/branches/2.5:1-6599
  • freepbx/trunk/CHANGES

    r6539 r6600  
    1616  ARI updates could be split from other framework updates in order to allow people 
    1717  with highly customized FOP and ARI changes to pull framework updates easier. 
     18 
     19- Added Streaming categories to MoH in addition to downloaded files 
    1820 
    19212.5.0 Added before rc1 
     
    101103 the stats are updated based on the STATS interval but a few items are checked 
    102104 less frequently (such as Astersisk Uptime) based on the INFO value 
     105 
     106 ZAP2DAHDICOMPAT=true|false 
     107 DEFAULT VALUE: false 
     108 If set to true, FreePBX will check if you have chan_dadhi installed. If so, it will 
     109 automatically use all your ZAP configuration settings (devices and trunks) and 
     110 silently convert them, under the covers, to DAHDI so no changes are needed. The 
     111 GUI will continue to refer to these as ZAP but it will use the proper DAHDI channels. 
     112 This will also keep Zap Channel DIDs working. 
    103113 
    104114 
  • freepbx/trunk/amp_conf/bin/freepbx_engine

    r6244 r6600  
    9696  # Ensure that various hardware devices are owned correctly. 
    9797  [ -e /dev/zap ] && chown -R $AMPDEVUSER:$AMPDEVGROUP /dev/zap  
     98  [ -e /dev/dahdi ] && chown -R $AMPDEVUSER:$AMPDEVGROUP /dev/dahdi  
    9899  [ -e /dev/capi20 ] && chown -R $AMPDEVUSER:$AMPDEVGROUP /dev/capi20 
    99100  [ -e /dev/misdn ] && chown -R $AMPDEVUSER:$AMPDEVGROUP /dev/misdn 
  • freepbx/trunk/amp_conf/bin/libfreepbx.confgen.php

    r5974 r6600  
    170170 
    171171function generate_configurations_zap($ast_version) { 
    172  
     172  global $chan_dahdi; 
    173173  global $amp_conf; 
    174174  global $db; 
     
    177177 
    178178  $zap_conf = $amp_conf['ASTETCDIR']."/zapata_additional.conf"; 
     179  $channel_name = 'ZAP'; 
     180  if ($chan_dahdi) { 
     181    $zap_conf = $amp_conf['ASTETCDIR']."/chan_dahdi_additional.conf"; 
     182    $channel_name = 'DAHDI'; 
     183  } 
    179184 
    180185  $table_name = "zap"; 
     
    184189  $zap_conf_fh = fopen($zap_conf,"w"); 
    185190  if ($zap_conf_fh === false) { 
    186     fatal(_("Cannot write ZAP configurations"),sprintf(_("Failed creating/overwriting Zapata extensions file: %s"),$zap_conf)); 
     191    fatal(_("Cannot write $channel_name configurations"),sprintf(_("Failed creating/overwriting $channel_name extensions file: %s"),$zap_conf)); 
    187192  } 
    188193 
  • freepbx/trunk/amp_conf/bin/retrieve_conf

    r6539 r6600  
    370370$engine = $engineinfo['engine']; 
    371371$version = $engineinfo['version']; 
     372$chan_dahdi = ast_with_dahdi(); 
    372373 
    373374// Check for and report any extension conflicts 
     
    482483        freepbx_log('retrieve_conf', 'devel-debug', 'generateConf from '.$classname); 
    483484        if (isset(${$classname}->use_warning_banner)) { 
    484           write_file(${$classname}->get_filename(),${$classname}->generateConf(),${$classname}->use_nowarning_banner); 
     485          write_file(${$classname}->get_filename(),${$classname}->generateConf(),${$classname}->use_warning_banner); 
    485486        } else { 
    486487          write_file(${$classname}->get_filename(),${$classname}->generateConf()); 
     
    588589  set_error_handler("report_errors"); 
    589590  if (copy($source, $dest)) { 
    590     $ret = chmod($dest,'0754'); 
     591    $ret = chmod($dest,0754); 
    591592  } 
    592593  restore_error_handler(); 
  • freepbx/trunk/amp_conf/htdocs/admin/config.php

    r6539 r6600  
    129129    //create an array of module sections to display 
    130130    // stored as [items][$type][$category][$name] = $displayvalue 
    131     if (!$quitemode && isset($module['items']) && is_array($module['items'])) { 
     131    if (isset($module['items']) && is_array($module['items'])) { 
    132132      // loop through the types 
    133133      foreach($module['items'] as $itemKey => $item) { 
  • freepbx/trunk/amp_conf/htdocs/admin/extensions.class.php

    r6539 r6600  
    929929class ext_zapbarge extends extension { 
    930930  function output() { 
    931     return "ZapBarge(".$this->data.")"; 
     931    global $chan_dahdi; 
     932     
     933    if ($chan_dahdi) { 
     934      $command = 'DAHDIBarge'; 
     935    } else { 
     936      $command = 'ZapBarge'; 
     937    } 
     938     
     939    return "$command(".$this->data.")"; 
    932940  } 
    933941} 
     
    974982class ext_lookupcidname extends extension { 
    975983  function output() { 
    976     return "LookupCIDName"; 
    977   } 
     984    global $version; 
     985 
     986    if (version_compare($version, "1.6", "ge")) { 
     987      $outstr=addslashes('Set(CALLERID(name)=${DB(cidname/${CALLERID(num)})})'); 
     988      return $outstr; 
     989    } else {  
     990      return "LookupCIDName"; 
     991    } 
     992  }    
    978993} 
    979994 
  • freepbx/trunk/amp_conf/htdocs/admin/functions.inc.php

    r6539 r6600  
    2020define('MODULE_STATUS_NEEDUPGRADE', 3); 
    2121define('MODULE_STATUS_BROKEN', -1); 
     22 
     23class modulelist { 
     24  var $_loaded = false; 
     25  var $module_array = array(); 
     26  var $_db; 
     27 
     28  function &create(&$db) { 
     29    static $obj; 
     30    if (!isset($obj)) { 
     31      $obj = new modulelist($db); 
     32    } 
     33    return $obj; 
     34  } 
     35  function modulelist(&$db) { 
     36    $this->_db =& $db; 
     37    $module_serialized = sql("SELECT `data` FROM `module_xml` WHERE `id` = 'mod_serialized'","getOne"); 
     38    if (isset($module_serialized) && $module_serialized) { 
     39      $this->module_array = (unserialize($module_serialized)); 
     40      $this->_loaded = true; 
     41    } 
     42  } 
     43  function is_loaded() { 
     44    return $this->_loaded; 
     45  } 
     46  function initialize(&$module_list) { 
     47    $this->module_array = $module_list; 
     48    $module_serialized = $this->_db->escapeSimple(serialize($this->module_array)); 
     49    sql("DELETE FROM `module_xml` WHERE `id` = 'mod_serialized'"); 
     50    sql("INSERT INTO `module_xml` (`id`, `time`, `data`) VALUES ('mod_serialized', '".time()."','".$module_serialized."')"); 
     51    $this->_loaded = true; 
     52  } 
     53  function invalidate() { 
     54    unset($this->module_array); 
     55    sql("DELETE FROM `module_xml` WHERE `id` = 'mod_serialized'"); 
     56    $this->_loaded = false; 
     57  } 
     58} 
     59 
     60define("NOTIFICATION_TYPE_CRITICAL", 100); 
     61define("NOTIFICATION_TYPE_SECURITY", 200); 
     62define("NOTIFICATION_TYPE_UPDATE",  300); 
     63define("NOTIFICATION_TYPE_ERROR",    400); 
     64define("NOTIFICATION_TYPE_WARNING" , 500); 
     65define("NOTIFICATION_TYPE_NOTICE",   600); 
     66 
     67class notifications { 
     68 
     69  var $not_loaded = true; 
     70  var $notification_table = array(); 
     71  var $_db; 
     72     
     73  function &create(&$db) { 
     74    static $obj; 
     75    if (!isset($obj)) { 
     76      $obj = new notifications($db); 
     77    } 
     78    return $obj; 
     79  } 
     80 
     81  function notifications(&$db) { 
     82    $this->_db =& $db; 
     83  } 
     84 
     85 
     86  function add_critical($module, $id, $display_text, $extended_text="", $link="", $reset=true, $candelete=false) { 
     87    $this->_add_type(NOTIFICATION_TYPE_CRITICAL, $module, $id, $display_text, $extended_text, $link, $reset, $candelete); 
     88  } 
     89  function add_security($module, $id, $display_text, $extended_text="", $link="", $reset=true, $candelete=false) { 
     90    $this->_add_type(NOTIFICATION_TYPE_SECURITY, $module, $id, $display_text, $extended_text, $link, $reset, $candelete); 
     91  } 
     92  function add_update($module, $id, $display_text, $extended_text="", $link="", $reset=false, $candelete=false) { 
     93    $this->_add_type(NOTIFICATION_TYPE_UPDATE, $module, $id, $display_text, $extended_text, $link, $reset, $candelete); 
     94  } 
     95  function add_error($module, $id, $display_text, $extended_text="", $link="", $reset=false, $candelete=false) { 
     96    $this->_add_type(NOTIFICATION_TYPE_ERROR, $module, $id, $display_text, $extended_text, $link, $reset, $candelete); 
     97  } 
     98  function add_warning($module, $id, $display_text, $extended_text="", $link="", $reset=false, $candelete=false) { 
     99    $this->_add_type(NOTIFICATION_TYPE_WARNING, $module, $id, $display_text, $extended_text, $link, $reset, $candelete); 
     100  } 
     101  function add_notice($module, $id, $display_text, $extended_text="", $link="", $reset=false, $candelete=true) { 
     102    $this->_add_type(NOTIFICATION_TYPE_NOTICE, $module, $id, $display_text, $extended_text, $link, $reset, $candelete); 
     103  } 
     104 
     105 
     106  function list_critical($show_reset=false) { 
     107    return $this->_list(NOTIFICATION_TYPE_CRITICAL, $show_reset); 
     108  } 
     109  function list_security($show_reset=false) { 
     110    return $this->_list(NOTIFICATION_TYPE_SECURITY, $show_reset); 
     111  } 
     112  function list_update($show_reset=false) { 
     113    return $this->_list(NOTIFICATION_TYPE_UPDATE, $show_reset); 
     114  } 
     115  function list_error($show_reset=false) { 
     116    return $this->_list(NOTIFICATION_TYPE_ERROR, $show_reset); 
     117  } 
     118  function list_warning($show_reset=false) { 
     119    return $this->_list(NOTIFICATION_TYPE_WARNING, $show_reset); 
     120  } 
     121  function list_notice($show_reset=false) { 
     122    return $this->_list(NOTIFICATION_TYPE_NOTICE, $show_reset); 
     123  } 
     124  function list_all($show_reset=false) { 
     125    return $this->_list("", $show_reset); 
     126  } 
     127 
     128 
     129  function reset($module, $id) { 
     130    $module        = q($module); 
     131    $id            = q($id); 
     132 
     133    $sql = "UPDATE notifications SET reset = 1 WHERE module = $module AND id = $id"; 
     134    sql($sql); 
     135  } 
     136 
     137  function delete($module, $id) { 
     138    $module        = q($module); 
     139    $id            = q($id); 
     140 
     141    $sql = "DELETE FROM notifications WHERE module = $module AND id = $id"; 
     142    sql($sql); 
     143  } 
     144 
     145  function safe_delete($module, $id) { 
     146    $module        = q($module); 
     147    $id            = q($id); 
     148 
     149    $sql = "DELETE FROM notifications WHERE module = $module AND id = $id AND candelete = 1"; 
     150    sql($sql); 
     151  } 
     152 
     153  /* Internal functions 
     154   */ 
     155 
     156  function _add_type($level, $module, $id, $display_text, $extended_text="", $link="", $reset=false, $candelete=false) { 
     157    if ($this->not_loaded) { 
     158      $this->notification_table = $this->_list("",true); 
     159      $this->not_loaded = false; 
     160    } 
     161 
     162    $existing_row = false; 
     163    foreach ($this->notification_table as $row) { 
     164      if ($row['module'] == $module && $row['id'] == $id ) { 
     165        $existing_row = $row; 
     166        break; 
     167      } 
     168    } 
     169    // Found an existing row - check if anything changed or if we are suppose to reset it 
     170    // 
     171    $candelete = $candelete ? 1 : 0; 
     172    if ($existing_row) { 
     173 
     174      if (($reset && $existing_row['reset'] == 1) || $existing_row['level'] != $level || $existing_row['display_text'] != $display_text || $existing_row['extended_text'] != $extended_text || $existing_row['link'] != $link || $existing_row['candelete'] == $candelete) { 
     175 
     176        // If $reset is set to the special case of PASSIVE then the updates will not change it's value in an update 
     177        // 
     178        $reset_value = ($reset == 'PASSIVE') ? $existing_row['reset'] : 0; 
     179 
     180        $module        = q($module); 
     181        $id            = q($id); 
     182        $level         = q($level); 
     183        $display_text  = q($display_text); 
     184        $extended_text = q($extended_text); 
     185        $link          = q($link); 
     186        $now = time(); 
     187        $sql = "UPDATE notifications SET 
     188          level = $level, 
     189          display_text = $display_text, 
     190          extended_text = $extended_text, 
     191          link = $link, 
     192          reset = $reset_value, 
     193          candelete = $candelete, 
     194          timestamp = $now 
     195          WHERE module = $module AND id = $id 
     196        "; 
     197        sql($sql); 
     198 
     199        // TODO: I should really just add this to the internal cache, but really 
     200        //       how often does this get called that if is a big deal. 
     201        $this->not_loaded = true; 
     202      } 
     203    } else { 
     204      // No existing row so insert this new one 
     205      // 
     206      $now           = time(); 
     207      $module        = q($module); 
     208      $id            = q($id); 
     209      $level         = q($level); 
     210      $display_text  = q($display_text); 
     211      $extended_text = q($extended_text); 
     212      $link          = q($link); 
     213      $sql = "INSERT INTO notifications  
     214        (module, id, level, display_text, extended_text, link, reset, candelete, timestamp) 
     215        VALUES  
     216        ($module, $id, $level, $display_text, $extended_text, $link, 0, $candelete, $now) 
     217      "; 
     218      sql($sql); 
     219 
     220      // TODO: I should really just add this to the internal cache, but really 
     221      //       how often does this get called that if is a big deal. 
     222      $this->not_loaded = true; 
     223    } 
     224  } 
     225 
     226  function _list($level, $show_reset=false) { 
     227 
     228    $level = q($level); 
     229    $where = array(); 
     230 
     231    if (!$show_reset) { 
     232      $where[] = "reset = 0"; 
     233    } 
     234 
     235    switch ($level) { 
     236      case NOTIFICATION_TYPE_CRITICAL: 
     237      case NOTIFICATION_TYPE_SECURITY: 
     238      case NOTIFICATION_TYPE_UPDATE: 
     239      case NOTIFICATION_TYPE_ERROR: 
     240      case NOTIFICATION_TYPE_WARNING: 
     241      case NOTIFICATION_TYPE_NOTICE: 
     242        $where[] = "level = $level "; 
     243        break; 
     244      default: 
     245    } 
     246    $sql = "SELECT * FROM notifications "; 
     247    if (count($where)) { 
     248      $sql .= " WHERE ".implode(" AND ", $where); 
     249    } 
     250    $sql .= " ORDER BY level, module"; 
     251 
     252    $list = sql($sql,"getAll",DB_FETCHMODE_ASSOC); 
     253    return $list; 
     254  } 
     255  /* Returns the number of active notifications 
     256   */ 
     257  function get_num_active() { 
     258    $sql = "SELECT COUNT(id) FROM notifications WHERE reset = 0"; 
     259    return sql($sql,'getOne'); 
     260  } 
     261} 
     262 
     263class cronmanager { 
     264  /** 
     265   * note: time is the hour time of day a job should run, -1 indicates don't care 
     266   */ 
     267 
     268  function &create(&$db) { 
     269    static $obj; 
     270    if (!isset($obj)) { 
     271      $obj = new cronmanager($db); 
     272    } 
     273    return $obj; 
     274  } 
     275 
     276  function cronmanager(&$db) { 
     277    $this->_db =& $db; 
     278  } 
     279 
     280  function save_email($address) { 
     281    $address = q($address); 
     282    sql("DELETE FROM admin WHERE variable = 'email'"); 
     283    sql("INSERT INTO admin (variable, value) VALUES ('email', $address)"); 
     284  } 
     285 
     286  function get_email() { 
     287    $sql = "SELECT value FROM admin WHERE variable = 'email'"; 
     288    return sql($sql, 'getOne'); 
     289  } 
     290 
     291  function save_hash($id, &$string) { 
     292    $hash = md5($string); 
     293    $id = q($id); 
     294    sql("DELETE FROM admin WHERE variable = $id"); 
     295    sql("INSERT INTO admin (variable, value) VALUE ($id, '$hash')"); 
     296  } 
     297 
     298  function check_hash($id, &$string) { 
     299    $id = q($id); 
     300    $sql = "SELECT value FROM admin WHERE variable = $id LIMIT 1"; 
     301    $hash = sql($sql, "getOne"); 
     302    return ($hash == md5($string)); 
     303  } 
     304 
     305  function enable_updates($freq=24) { 
     306    global $amp_conf; 
     307 
     308    $night_time = array(19,20,21,22,23,0,1,2,3,4,5); 
     309    $run_time = $night_time[rand(0,10)]; 
     310    $command = $amp_conf['AMPBIN']."/module_admin listonline"; 
     311    $lasttime = 0; 
     312 
     313    $sql = "SELECT * FROM cronmanager WHERE module = 'module_admin' AND id = 'UPDATES'"; 
     314    $result = sql($sql, "getAll",DB_FETCHMODE_ASSOC); 
     315    if (count($result)) { 
     316      $sql = "UPDATE cronmanager SET 
     317                freq = '$freq', 
     318                command = '$command' 
     319              WHERE 
     320                module = 'module_admin' AND id = 'UPDATES'   
     321             "; 
     322    } else { 
     323      $sql = "INSERT INTO cronmanager  
     324              (module, id, time, freq, lasttime, command) 
     325              VALUES 
     326              ('module_admin', 'UPDATES', '$run_time', $freq, 0, '$command') 
     327            "; 
     328    } 
     329    sql($sql); 
     330  } 
     331 
     332  function disable_updates() { 
     333    sql("DELETE FROM cronmanager WHERE module = 'module_admin' AND id = 'UPDATES'"); 
     334  } 
     335 
     336  function updates_enabled() { 
     337    $results = sql("SELECT module, id FROM cronmanager WHERE module = 'module_admin' AND id = 'UPDATES'",'getAll'); 
     338    return count($results); 
     339  } 
     340 
     341  /** run_jobs() 
     342   *  select all entries that need to be run now and run them, then update the times. 
     343   *   
     344   *  1. select all entries 
     345   *  2. foreach entry, if its paramters indicate it should be run, then run it and 
     346   *     update it was run in the time stamp. 
     347   */ 
     348  function run_jobs() { 
     349 
     350    $errors = 0; 
     351    $error_arr = array(); 
     352 
     353    $now = time(); 
     354    $jobs = sql("SELECT * FROM cronmanager","getAll", DB_FETCHMODE_ASSOC); 
     355    foreach ($jobs as $job) { 
     356      $nexttime = $job['lasttime'] + $job['freq']*3600;  
     357      if ($nexttime <= $now) { 
     358        if ($job['time'] >= 0 && $job['time'] < 24) { 
     359          $date_arr = getdate($now); 
     360          // Now if lasttime is 0, then we want this kicked off at the proper hour 
     361          // after wich the frequencey will set the pace for same time each night 
     362          // 
     363          if (($date_arr['hours'] != $job['time']) && !$job['lasttime']) { 
     364            continue; 
     365          } 
     366        }  
     367      } else { 
     368        // no need to run job, time is not up yet 
     369        continue; 
     370      } 
     371      // run the job 
     372      exec($job['command'],$job_out,$ret); 
     373      if ($ret) { 
     374        $errors++; 
     375        $error_arr[] = array($job['command'],$ret); 
     376 
     377        // If there where errors, let's print them out in case the script is being debugged or running 
     378        // from cron which will then put the errors out through the cron system. 
     379        // 
     380        foreach ($job_out as $line) { 
     381          echo $line."\n"; 
     382        } 
     383      } else { 
     384        $module = $job['module']; 
     385        $id =     $job['id']; 
     386        $sql = "UPDATE cronmanager SET lasttime = $now WHERE module = '$module' AND id = '$id'"; 
     387        sql($sql); 
     388      } 
     389    } 
     390    if ($errors) { 
     391      $nt =& notifications::create($db); 
     392      $text = sprintf(_("Cronmanager encountered %s Errors"),$errors); 
     393      $extext = _("The following commands failed with the listed error"); 
     394      foreach ($error_arr as $item) { 
     395        $extext .= "<br>".$item[0]." (".$item[1].")"; 
     396      } 
     397      $nt->add_error('cron_manager', 'EXECFAIL', $text, $extext, '', true, true); 
     398    } 
     399  } 
     400} 
     401 
     402class ampuser { 
     403  var $username; 
     404  var $_password; 
     405  var $_extension_high; 
     406  var $_extension_low; 
     407  var $_deptname; 
     408  var $_sections; 
     409   
     410  function ampuser($username) { 
     411    $this->username = $username; 
     412    if ($user = getAmpUser($username)) { 
     413      $this->_password = $user["password"]; 
     414      $this->_extension_high = $user["extension_high"]; 
     415      $this->_extension_low = $user["extension_low"]; 
     416      $this->_deptname = $user["deptname"]; 
     417      $this->_sections = $user["sections"]; 
     418    } else { 
     419      // user doesn't exist 
     420      $this->_password = false; 
     421      $this->_extension_high = ""; 
     422      $this->_extension_low = ""; 
     423      $this->_deptname = ""; 
     424      $this->_sections = array(); 
     425    } 
     426  } 
     427   
     428  /** Give this user full admin access 
     429  */ 
     430  function setAdmin() { 
     431    $this->_extension_high = ""; 
     432    $this->_extension_low = ""; 
     433    $this->_deptname = ""; 
     434    $this->_sections = array("*"); 
     435  } 
     436   
     437  function checkPassword($password) { 
     438    // strict checking so false will never match 
     439    return ($this->_password === $password); 
     440  } 
     441   
     442  function checkSection($section) { 
     443    // if they have * then it means all sections 
     444    return in_array("*", $this->_sections) || in_array($section, $this->_sections); 
     445  } 
     446} 
     447 
     448/* Usage 
     449Grab some XML data, either from a file, URL, etc. however you want. Assume storage in $strYourXML; 
     450 
     451$xml = new xml2Array($strYourXML); 
     452xml array is in $xml->data; 
     453  This is basically an array version of the XML data (no attributes), striaght-up. If there are 
     454  multiple items with the same name, they are split into a numeric sub-array,  
     455  eg, <items><item test="123">foo</item><item>bar</item></items> 
     456  becomes: array('item' => array(0=>array('item'=>'foo'), 1=>array('item'=>'foo')) 
     457attributes are in $xml->attributes; 
     458  These are stored with xpath type paths, as $xml->attributes['/items/item/0']["test"] == "123" 
     459   
     460 
     461Other way (still works, but not as nice): 
     462 
     463$objXML = new xml2Array(); 
     464$arrOutput = $objXML->parse($strYourXML); 
     465print_r($arrOutput); //print it out, or do whatever! 
     466 
     467*/ 
     468 
     469class xml2Array { 
     470  var $arrOutput = array(); 
     471  var $resParser; 
     472  var $strXmlData; 
     473   
     474  var $attributes; 
     475  var $data; 
     476   
     477  function xml2Array($strInputXML = false) { 
     478    if (!empty($strInputXML)) { 
     479      $this->data = $this->parseAdvanced($strInputXML); 
     480    } 
     481  } 
     482   
     483  function parse($strInputXML) { 
     484   
     485      $this->resParser = xml_parser_create (); 
     486      xml_set_object($this->resParser,$this); 
     487      xml_set_element_handler($this->resParser, "tagOpen", "tagClosed"); 
     488       
     489      xml_set_character_data_handler($this->resParser, "tagData"); 
     490     
     491      $this->strXmlData = xml_parse($this->resParser,$strInputXML ); 
     492      if(!$this->strXmlData) { 
     493        die_freepbx(sprintf("XML error: %s at line %d", 
     494      xml_error_string(xml_get_error_code($this->resParser)), 
     495      xml_get_current_line_number($this->resParser))); 
     496      } 
     497               
     498      xml_parser_free($this->resParser); 
     499       
     500      return $this->arrOutput; 
     501  } 
     502  function tagOpen($parser, $name, $attrs) { 
     503    $tag=array("name"=>$name,"attrs"=>$attrs);  
     504    @array_push($this->arrOutput,$tag); 
     505  } 
     506   
     507  function tagData($parser, $tagData) { 
     508    if(trim($tagData)) { 
     509      if(isset($this->arrOutput[count($this->arrOutput)-1]['tagData'])) { 
     510        $this->arrOutput[count($this->arrOutput)-1]['tagData'] .= "\n".$tagData; 
     511      }  
     512      else { 
     513        $this->arrOutput[count($this->arrOutput)-1]['tagData'] = $tagData; 
     514      } 
     515    } 
     516  } 
     517   
     518  function tagClosed($parser, $name) { 
     519    @$this->arrOutput[count($this->arrOutput)-2]['children'][] = $this->arrOutput[count($this->arrOutput)-1]; 
     520    array_pop($this->arrOutput); 
     521  } 
     522   
     523  function recursive_parseLevel($items, &$attrs, $path = "") { 
     524    $array = array(); 
     525    foreach (array_keys($items) as $idx) { 
     526      @$items[$idx]['name'] = strtolower($items[$idx]['name']); 
     527       
     528      $multi = false; 
     529      if (isset($array[ $items[$idx]['name'] ])) { 
     530        // this child is already set, so we're adding multiple items to an array  
     531         
     532        if (!is_array($array[ $items[$idx]['name'] ]) || !isset($array[ $items[$idx]['name'] ][0])) { 
     533          // hasn't already been made into a numerically-indexed array, so do that now 
     534          // we're basically moving the current contents of this item into a 1-item array (at the  
     535          // original location) so that we can add a second item in the code below 
     536          $array[ $items[$idx]['name'] ] = array( $array[ $items[$idx]['name'] ] ); 
     537 
     538          if (isset($attrs[ $path.'/'.$items[$idx]['name'] ])) { 
     539            // move the attributes to /0 
     540            $attrs[ $path.'/'.$items[$idx]['name'].'/0' ] = $attrs[ $path.'/'.$items[$idx]['name'] ]; 
     541            unset($attrs[ $path.'/'.$items[$idx]['name'] ]); 
     542          } 
     543        } 
     544        $multi = true; 
     545      } 
     546       
     547      if ($multi) {  
     548        $newitem = &$array[ $items[$idx]['name'] ][]; 
     549      } else { 
     550        $newitem = &$array[ $items[$idx]['name'] ]; 
     551      } 
     552       
     553       
     554      if (isset($items[$idx]['children']) && is_array($items[$idx]['children'])) { 
     555        $newitem = $this->recursive_parseLevel($items[$idx]['children'], $attrs, $path.'/'.$items[$idx]['name']); 
     556      } else if (isset($items[$idx]['tagData'])) { 
     557        $newitem = $items[$idx]['tagData']; 
     558      } else { 
     559        $newitem = false; 
     560      } 
     561       
     562      if (isset($items[$idx]['attrs']) && is_array($items[$idx]['attrs']) && count($items[$idx]['attrs'])) { 
     563        $attrpath = $path.'/'.$items[$idx]['name']; 
     564        if ($multi) { 
     565          $attrpath .= '/'.(count($array[ $items[$idx]['name'] ])-1); 
     566        } 
     567        foreach ($items[$idx]['attrs'] as $name=>$value) { 
     568          $attrs[ $attrpath ][ strtolower($name) ] = $value; 
     569        } 
     570      } 
     571    } 
     572    return $array; 
     573  } 
     574   
     575  function parseAdvanced($strInputXML) { 
     576    $array = $this->parse($strInputXML); 
     577    $this->attributes = array(); 
     578    return $this->data = $this->recursive_parseLevel($array, $this->attributes); 
     579  } 
     580} 
     581 
     582/* 
     583  Return a much more manageable assoc array with module data. 
     584*/ 
     585class xml2ModuleArray extends xml2Array { 
     586  function parseModulesXML($strInputXML) { 
     587    $array = $this->parseAdvanced($strInputXML); 
     588    if (isset($array['xml'])) { 
     589      foreach ($array['xml'] as $key=>$module) { 
     590        if ($key == 'module') { 
     591          // copy the structure verbatim 
     592          $modules[ $module['name'] ] = $module; 
     593        } 
     594      } 
     595    } 
     596     
     597    // if you are confused about what's happening below, uncomment this why we do it 
     598    // echo "<pre>"; print_r($arrOutput); echo "</pre>"; 
     599     
     600    // ignore the regular xml garbage ([0]['children']) & loop through each module 
     601    if(!is_array($arrOutput[0]['children'])) return false; 
     602    foreach($arrOutput[0]['children'] as $module) { 
     603      if(!is_array($module['children'])) return false; 
     604      // loop through each modules's tags 
     605      foreach($module['children'] as $modTags) { 
     606          if(isset($modTags['children']) && is_array($modTags['children'])) { 
     607            $$modTags['name'] = $modTags['children']; 
     608            // loop if there are children (menuitems and requirements) 
     609            foreach($modTags['children'] as $subTag) { 
     610              $subTags[strtolower($subTag['name'])] = $subTag['tagData']; 
     611            } 
     612            $$modTags['name'] = $subTags; 
     613            unset($subTags); 
     614          } else { 
     615            // create a variable for each tag we find 
     616            $$modTags['name'] = $modTags['tagData']; 
     617          } 
     618 
     619      } 
     620      // now build our return array 
     621      $arrModules[$RAWNAME]['rawname'] = $RAWNAME;    // This has to be set 
     622      $arrModules[$RAWNAME]['displayName'] = $NAME;    // This has to be set 
     623      $arrModules[$RAWNAME]['version'] = $VERSION;     // This has to be set 
     624      $arrModules[$RAWNAME]['type'] = isset($TYPE)?$TYPE:'setup'; 
     625      $arrModules[$RAWNAME]['category'] = isset($CATEGORY)?$CATEGORY:'Unknown'; 
     626      $arrModules[$RAWNAME]['info'] = isset($INFO)?$INFO:'http://www.freepbx.org/wiki/'.$RAWNAME; 
     627      $arrModules[$RAWNAME]['location'] = isset($LOCATION)?$LOCATION:'local'; 
     628      $arrModules[$RAWNAME]['items'] = isset($MENUITEMS)?$MENUITEMS:null; 
     629      $arrModules[$RAWNAME]['requirements'] = isset($REQUIREMENTS)?$REQUIREMENTS:null; 
     630      $arrModules[$RAWNAME]['md5sum'] = isset($MD5SUM)?$MD5SUM:null; 
     631      //print_r($arrModules); 
     632      //unset our variables 
     633      unset($NAME); 
     634      unset($VERSION); 
     635      unset($TYPE); 
     636      unset($CATEGORY); 
     637      unset($AUTHOR); 
     638      unset($EMAIL); 
     639      unset($LOCATION); 
     640      unset($MENUITEMS); 
     641      unset($REQUIREMENTS); 
     642      unset($MD5SUM); 
     643    } 
     644    //echo "<pre>"; print_r($arrModules); echo "</pre>"; 
     645 
     646    return $arrModules; 
     647  } 
     648} 
     649 
     650class moduleHook { 
     651  var $hookHtml = ''; 
     652  var $arrHooks = array(); 
     653   
     654  function install_hooks($viewing_itemid,$target_module,$target_menuid = '') { 
     655    global $active_modules; 
     656    // loop through all active modules 
     657    foreach($active_modules as $this_module) { 
     658        // look for requested hooks for $module 
     659        // ie: findme_hook_extensions() 
     660        $funct = $this_module['rawname'] . '_hook_' . $target_module; 
     661        if( function_exists( $funct ) ) { 
     662          // execute the function, appending the  
     663          // html output to that of other hooking modules 
     664          if ($hookReturn = $funct($target_menuid, $viewing_itemid)) { 
     665            $this->hookHtml .= $hookReturn; 
     666          } 
     667          // remember who installed hooks 
     668          // we need to know this for processing form vars 
     669          $this->arrHooks[] = $this_module['rawname']; 
     670        } 
     671    } 
     672  } 
     673   
     674  // process the request from the module we hooked 
     675  function process_hooks($viewing_itemid, $target_module, $target_menuid, $request) { 
     676    if(is_array($this->arrHooks)) { 
     677      foreach($this->arrHooks as $hookingMod) { 
     678        // check if there is a processing function 
     679        $funct = $hookingMod . '_hookProcess_' . $target_module; 
     680        if( function_exists( $funct ) ) { 
     681          $funct($viewing_itemid, $request); 
     682        } 
     683      } 
     684    } 
     685  } 
     686} 
    22687 
    23688$amp_conf_defaults = array( 
     
    64729  'AMPENABLEDEVELDEBUG'=> array('bool' , false), 
    65730  'AMPMPG123'      => array('bool' , true), 
     731  'ZAP2DAHDICOMPAT' => array('bool' , false), 
    66732); 
    67733 
     
    73739   * components don't have to keep being 'gun shy' about these variables. 
    74740   *  
    75  
    76741   */ 
    77742  $file = file($filename); 
     
    118783    } 
    119784  } 
    120  
    121 /*       
    122   TODO: what was this, should the comment be removed? 
    123  
    124   if (($amp_conf["AMPDBENGINE"] == "sqlite") && (!isset($amp_conf["AMPDBENGINE"]))) 
    125     $amp_conf["AMPDBFILE"] = "/var/lib/freepbx/freepbx.sqlite"; 
    126 */ 
    127  
    128785  return $conf; 
    129786} 
     
    160817  } 
    161818  return $conf; 
    162 } 
    163  
    164  
    165 define("NOTIFICATION_TYPE_CRITICAL", 100); 
    166 define("NOTIFICATION_TYPE_SECURITY", 200); 
    167 define("NOTIFICATION_TYPE_UPDATE",  300); 
    168 define("NOTIFICATION_TYPE_ERROR",    400); 
    169 define("NOTIFICATION_TYPE_WARNING" , 500); 
    170 define("NOTIFICATION_TYPE_NOTICE",   600); 
    171  
    172 class modulelist { 
    173   var $_loaded = false; 
    174   var $module_array = array(); 
    175   var $_db; 
    176  
    177   function &create(&$db) { 
    178     static $obj; 
    179     if (!isset($obj)) { 
    180       $obj = new modulelist($db); 
    181     } 
    182     return $obj; 
    183   } 
    184   function modulelist(&$db) { 
    185     $this->_db =& $db; 
    186     $module_serialized = sql("SELECT `data` FROM `module_xml` WHERE `id` = 'mod_serialized'","getOne"); 
    187     if (isset($module_serialized) && $module_serialized) { 
    188       $this->module_array = (unserialize($module_serialized)); 
    189       $this->_loaded = true; 
    190     } 
    191   } 
    192   function is_loaded() { 
    193     return $this->_loaded; 
    194   } 
    195   function initialize(&$module_list) { 
    196     $this->module_array = $module_list; 
    197     $module_serialized = $this->_db->escapeSimple(serialize($this->module_array)); 
    198     sql("DELETE FROM `module_xml` WHERE `id` = 'mod_serialized'"); 
    199     sql("INSERT INTO `module_xml` (`id`, `time`, `data`) VALUES ('mod_serialized', '".time()."','".$module_serialized."')"); 
    200     $this->_loaded = true; 
    201   } 
    202   function invalidate() { 
    203     unset($this->module_array); 
    204     sql("DELETE FROM `module_xml` WHERE `id` = 'mod_serialized'"); 
    205     $this->_loaded = false; 
    206   } 
    207 } 
    208  
    209  
    210  
    211 class notifications { 
    212  
    213   var $not_loaded = true; 
    214   var $notification_table = array(); 
    215   var $_db; 
    216      
    217   function &create(&$db) { 
    218     static $obj; 
    219     if (!isset($obj)) { 
    220       $obj = new notifications($db); 
    221     } 
    222     return $obj; 
    223   } 
    224  
    225   function notifications(&$db) { 
    226     $this->_db =& $db; 
    227   } 
    228  
    229  
    230   function add_critical($module, $id, $display_text, $extended_text="", $link="", $reset=true, $candelete=false) { 
    231     $this->_add_type(NOTIFICATION_TYPE_CRITICAL, $module, $id, $display_text, $extended_text, $link, $reset, $candelete); 
    232   } 
    233   function add_security($module, $id, $display_text, $extended_text="", $link="", $reset=true, $candelete=false) { 
    234     $this->_add_type(NOTIFICATION_TYPE_SECURITY, $module, $id, $display_text, $extended_text, $link, $reset, $candelete); 
    235   } 
    236   function add_update($module, $id, $display_text, $extended_text="", $link="", $reset=false, $candelete=false) { 
    237     $this->_add_type(NOTIFICATION_TYPE_UPDATE, $module, $id, $display_text, $extended_text, $link, $reset, $candelete); 
    238   } 
    239   function add_error($module, $id, $display_text, $extended_text="", $link="", $reset=false, $candelete=false) { 
    240     $this->_add_type(NOTIFICATION_TYPE_ERROR, $module, $id, $display_text, $extended_text, $link, $reset, $candelete); 
    241   } 
    242   function add_warning($module, $id, $display_text, $extended_text="", $link="", $reset=false, $candelete=false) { 
    243     $this->_add_type(NOTIFICATION_TYPE_WARNING, $module, $id, $display_text, $extended_text, $link, $reset, $candelete); 
    244   } 
    245   function add_notice($module, $id, $display_text, $extended_text="", $link="", $reset=false, $candelete=true) { 
    246     $this->_add_type(NOTIFICATION_TYPE_NOTICE, $module, $id, $display_text, $extended_text, $link, $reset, $candelete); 
    247   } 
    248  
    249  
    250   function list_critical($show_reset=false) { 
    251     return $this->_list(NOTIFICATION_TYPE_CRITICAL, $show_reset); 
    252   } 
    253   function list_security($show_reset=false) { 
    254     return $this->_list(NOTIFICATION_TYPE_SECURITY, $show_reset); 
    255   } 
    256   function list_update($show_reset=false) { 
    257     return $this->_list(NOTIFICATION_TYPE_UPDATE, $show_reset); 
    258   } 
    259   function list_error($show_reset=false) { 
    260     return $this->_list(NOTIFICATION_TYPE_ERROR, $show_reset); 
    261   } 
    262   function list_warning($show_reset=false) { 
    263     return $this->_list(NOTIFICATION_TYPE_WARNING, $show_reset); 
    264   } 
    265   function list_notice($show_reset=false) { 
    266     return $this->_list(NOTIFICATION_TYPE_NOTICE, $show_reset); 
    267   } 
    268   function list_all($show_reset=false) { 
    269     return $this->_list("", $show_reset); 
    270   } 
    271  
    272  
    273   function reset($module, $id) { 
    274     $module        = q($module); 
    275     $id            = q($id); 
    276  
    277     $sql = "UPDATE notifications SET reset = 1 WHERE module = $module AND id = $id"; 
    278     sql($sql); 
    279   } 
    280  
    281   function delete($module, $id) { 
    282     $module        = q($module); 
    283     $id            = q($id); 
    284  
    285     $sql = "DELETE FROM notifications WHERE module = $module AND id = $id"; 
    286     sql($sql); 
    287   } 
    288  
    289   function safe_delete($module, $id) { 
    290     $module        = q($module); 
    291     $id            = q($id); 
    292  
    293     $sql = "DELETE FROM notifications WHERE module = $module AND id = $id AND candelete = 1"; 
    294     sql($sql); 
    295   } 
    296  
    297   /* Internal functions 
    298    */ 
    299  
    300   function _add_type($level, $module, $id, $display_text, $extended_text="", $link="", $reset=false, $candelete=false) { 
    301     if ($this->not_loaded) { 
    302       $this->notification_table = $this->_list("",true); 
    303       $this->not_loaded = false; 
    304     } 
    305  
    306     $existing_row = false; 
    307     foreach ($this->notification_table as $row) { 
    308       if ($row['module'] == $module && $row['id'] == $id ) { 
    309         $existing_row = $row; 
    310         break; 
    311       } 
    312     } 
    313     // Found an existing row - check if anything changed or if we are suppose to reset it 
    314     // 
    315     $candelete = $candelete ? 1 : 0; 
    316     if ($existing_row) { 
    317  
    318       if (($reset && $existing_row['reset'] == 1) || $existing_row['level'] != $level || $existing_row['display_text'] != $display_text || $existing_row['extended_text'] != $extended_text || $existing_row['link'] != $link || $existing_row['candelete'] == $candelete) { 
    319  
    320         // If $reset is set to the special case of PASSIVE then the updates will not change it's value in an update 
    321         // 
    322         $reset_value = ($reset == 'PASSIVE') ? $existing_row['reset'] : 0; 
    323  
    324         $module        = q($module); 
    325         $id            = q($id); 
    326         $level         = q($level); 
    327         $display_text  = q($display_text); 
    328         $extended_text = q($extended_text); 
    329         $link          = q($link); 
    330         $now = time(); 
    331         $sql = "UPDATE notifications SET 
    332           level = $level, 
    333           display_text = $display_text, 
    334           extended_text = $extended_text, 
    335           link = $link, 
    336           reset = $reset_value, 
    337           candelete = $candelete, 
    338           timestamp = $now 
    339           WHERE module = $module AND id = $id 
    340         "; 
    341         sql($sql); 
    342  
    343         // TODO: I should really just add this to the internal cache, but really 
    344         //       how often does this get called that if is a big deal. 
    345         $this->not_loaded = true; 
    346       } 
    347     } else { 
    348       // No existing row so insert this new one 
    349       // 
    350       $now           = time(); 
    351       $module        = q($module); 
    352       $id            = q($id); 
    353       $level         = q($level); 
    354       $display_text  = q($display_text); 
    355       $extended_text = q($extended_text); 
    356       $link          = q($link); 
    357       $sql = "INSERT INTO notifications  
    358         (module, id, level, display_text, extended_text, link, reset, candelete, timestamp) 
    359         VALUES  
    360         ($module, $id, $level, $display_text, $extended_text, $link, 0, $candelete, $now) 
    361       "; 
    362       sql($sql); 
    363  
    364       // TODO: I should really just add this to the internal cache, but really 
    365       //       how often does this get called that if is a big deal. 
    366       $this->not_loaded = true; 
    367     } 
    368   } 
    369  
    370   function _list($level, $show_reset=false) { 
    371  
    372     $level = q($level); 
    373     $where = array(); 
    374  
    375     if (!$show_reset) { 
    376       $where[] = "reset = 0"; 
    377     } 
    378  
    379     switch ($level) { 
    380       case NOTIFICATION_TYPE_CRITICAL: 
    381       case NOTIFICATION_TYPE_SECURITY: 
    382       case NOTIFICATION_TYPE_UPDATE: 
    383       case NOTIFICATION_TYPE_ERROR: 
    384       case NOTIFICATION_TYPE_WARNING: 
    385       case NOTIFICATION_TYPE_NOTICE: 
    386         $where[] = "level = $level "; 
    387         break; 
    388       default: 
    389     } 
    390     $sql = "SELECT * FROM notifications "; 
    391     if (count($where)) { 
    392       $sql .= " WHERE ".implode(" AND ", $where); 
    393     } 
    394     $sql .= " ORDER BY level, module"; 
    395  
    396     $list = sql($sql,"getAll",DB_FETCHMODE_ASSOC); 
    397     return $list; 
    398   } 
    399   /* Returns the number of active notifications 
    400    */ 
    401   function get_num_active() { 
    402     $sql = "SELECT COUNT(id) FROM notifications WHERE reset = 0"; 
    403     return sql($sql,'getOne'); 
    404   } 
    405 } 
    406  
    407 class cronmanager { 
    408   /** 
    409    * note: time is the hour time of day a job should run, -1 indicates don't care 
    410    */ 
    411  
    412   function &create(&$db) { 
    413     static $obj; 
    414     if (!isset($obj)) { 
    415       $obj = new cronmanager($db); 
    416     } 
    417     return $obj; 
    418   } 
    419  
    420   function cronmanager(&$db) { 
    421     $this->_db =& $db; 
    422   } 
    423  
    424   function save_email($address) { 
    425     $address = q($address); 
    426     sql("DELETE FROM admin WHERE variable = 'email'"); 
    427     sql("INSERT INTO admin (variable, value) VALUES ('email', $address)"); 
    428   } 
    429  
    430   function get_email() { 
    431     $sql = "SELECT value FROM admin WHERE variable = 'email'"; 
    432     return sql($sql, 'getOne'); 
    433   } 
    434  
    435   function save_hash($id, &$string) { 
    436     $hash = md5($string); 
    437     $id = q($id); 
    438     sql("DELETE FROM admin WHERE variable = $id"); 
    439     sql("INSERT INTO admin (variable, value) VALUE ($id, '$hash')"); 
    440   } 
    441  
    442   function check_hash($id, &$string) { 
    443     $id = q($id); 
    444     $sql = "SELECT value FROM admin WHERE variable = $id LIMIT 1"; 
    445     $hash = sql($sql, "getOne"); 
    446     return ($hash == md5($string)); 
    447   } 
    448  
    449   function enable_updates($freq=24) { 
    450     global $amp_conf; 
    451  
    452     $night_time = array(19,20,21,22,23,0,1,2,3,4,5); 
    453     $run_time = $night_time[rand(0,10)]; 
    454     $command = $amp_conf['AMPBIN']."/module_admin listonline"; 
    455     $lasttime = 0; 
    456  
    457     $sql = "SELECT * FROM cronmanager WHERE module = 'module_admin' AND id = 'UPDATES'"; 
    458     $result = sql($sql, "getAll",DB_FETCHMODE_ASSOC); 
    459     if (count($result)) { 
    460       $sql = "UPDATE cronmanager SET 
    461                 freq = '$freq', 
    462                 command = '$command' 
    463               WHERE 
    464                 module = 'module_admin' AND id = 'UPDATES'   
    465              "; 
    466     } else { 
    467       $sql = "INSERT INTO cronmanager  
    468               (module, id, time, freq, lasttime, command) 
    469               VALUES 
    470               ('module_admin', 'UPDATES', '$run_time', $freq, 0, '$command') 
    471             "; 
    472     } 
    473     sql($sql); 
    474   } 
    475  
    476   function disable_updates() { 
    477     sql("DELETE FROM cronmanager WHERE module = 'module_admin' AND id = 'UPDATES'"); 
    478   } 
    479  
    480   function updates_enabled() { 
    481     $results = sql("SELECT module, id FROM cronmanager WHERE module = 'module_admin' AND id = 'UPDATES'",'getAll'); 
    482     return count($results); 
    483   } 
    484  
    485   /** run_jobs() 
    486    *  select all entries that need to be run now and run them, then update the times. 
    487    *   
    488    *  1. select all entries 
    489    *  2. foreach entry, if its paramters indicate it should be run, then run it and 
    490    *     update it was run in the time stamp. 
    491    */ 
    492   function run_jobs() { 
    493  
    494     $errors = 0; 
    495     $error_arr = array(); 
    496  
    497     $now = time(); 
    498     $jobs = sql("SELECT * FROM cronmanager","getAll", DB_FETCHMODE_ASSOC); 
    499     foreach ($jobs as $job) { 
    500       $nexttime = $job['lasttime'] + $job['freq']*3600;  
    501       if ($nexttime <= $now) { 
    502         if ($job['time'] >= 0 && $job['time'] < 24) { 
    503           $date_arr = getdate($now); 
    504           // Now if lasttime is 0, then we want this kicked off at the proper hour 
    505           // after wich the frequencey will set the pace for same time each night 
    506           // 
    507           if (($date_arr['hours'] != $job['time']) && !$job['lasttime']) { 
    508             continue; 
    509           } 
    510         }  
    511       } else { 
    512         // no need to run job, time is not up yet 
    513         continue; 
    514       } 
    515       // run the job 
    516       exec($job['command'],$job_out,$ret); 
    517       if ($ret) { 
    518         $errors++; 
    519         $error_arr[] = array($job['command'],$ret); 
    520  
    521         // If there where errors, let's print them out in case the script is being debugged or running 
    522         // from cron which will then put the errors out through the cron system. 
    523         // 
    524         foreach ($job_out as $line) { 
    525           echo $line."\n"; 
    526         } 
    527       } else { 
    528         $module = $job['module']; 
    529         $id =     $job['id']; 
    530         $sql = "UPDATE cronmanager SET lasttime = $now WHERE module = '$module' AND id = '$id'"; 
    531         sql($sql); 
    532       } 
    533     } 
    534     if ($errors) { 
    535       $nt =& notifications::create($db); 
    536       $text = sprintf(_("Cronmanager encountered %s Errors"),$errors); 
    537       $extext = _("The following commands failed with the listed error"); 
    538       foreach ($error_arr as $item) { 
    539         $extext .= "<br>".$item[0]." (".$item[1].")"; 
    540       } 
    541       $nt->add_error('cron_manager', 'EXECFAIL', $text, $extext, '', true, true); 
    542     } 
    543   } 
    544819} 
    545820 
     
    9461221} 
    9471222 
     1223// returns true if extension is within allowed range 
     1224function checkRange($extension){ 
     1225  $low = isset($_SESSION["AMP_user"]->_extension_low)?$_SESSION["AMP_user"]->_extension_low:''; 
     1226  $high = isset($_SESSION["AMP_user"]->_extension_high)?$_SESSION["AMP_user"]->_extension_high:''; 
     1227   
     1228  if ((($extension >= $low) && ($extension <= $high)) || ($low == '' && $high == '')) 
     1229    return true; 
     1230  else 
     1231    return false; 
     1232} 
     1233 
    9481234function getAmpAdminUsers() { 
    9491235  global $db; 
     
    9801266} 
    9811267 
    982 class ampuser { 
    983   var $username; 
    984   var $_password; 
    985   var $_extension_high; 
    986   var $_extension_low; 
    987   var $_deptname; 
    988   var $_sections; 
    989    
    990   function ampuser($username) { 
    991     $this->username = $username; 
    992     if ($user = getAmpUser($username)) { 
    993       $this->_password = $user["password"]; 
    994       $this->_extension_high = $user["extension_high"]; 
    995       $this->_extension_low = $user["extension_low"]; 
    996       $this->_deptname = $user["deptname"]; 
    997       $this->_sections = $user["sections"]; 
    998     } else { 
    999       // user doesn't exist 
    1000       $this->_password = false; 
    1001       $this->_extension_high = ""; 
    1002       $this->_extension_low = ""; 
    1003       $this->_deptname = ""; 
    1004       $this->_sections = array(); 
    1005     } 
    1006   } 
    1007    
    1008   /** Give this user full admin access 
    1009   */ 
    1010   function setAdmin() { 
    1011     $this->_extension_high = ""; 
    1012     $this->_extension_low = ""; 
    1013     $this->_deptname = ""; 
    1014     $this->_sections = array("*"); 
    1015   } 
    1016    
    1017   function checkPassword($password) { 
    1018     // strict checking so false will never match 
    1019     return ($this->_password === $password); 
    1020   } 
    1021    
    1022   function checkSection($section) { 
    1023     // if they have * then it means all sections 
    1024     return in_array("*", $this->_sections) || in_array($section, $this->_sections); 
    1025   } 
    1026 } 
    1027  
    1028 // returns true if extension is within allowed range 
    1029 function checkRange($extension){ 
    1030   $low = isset($_SESSION["AMP_user"]->_extension_low)?$_SESSION["AMP_user"]->_extension_low:''; 
    1031   $high = isset($_SESSION["AMP_user"]->_extension_high)?$_SESSION["AMP_user"]->_extension_high:''; 
    1032    
    1033   if ((($extension >= $low) && ($extension <= $high)) || ($low == '' && $high == '')) 
    1034     return true; 
    1035   else 
    1036     return false; 
    1037 } 
    1038  
    10391268// returns true if department string matches dept for this user 
    10401269function checkDept($dept){ 
     
    10451274  else 
    10461275    return false; 
     1276} 
     1277 
     1278/** 
     1279 * returns true if asterisk is running with chan_dahdi 
     1280 * 
     1281 * @return bool 
     1282 */ 
     1283function ast_with_dahdi() { 
     1284  global $version; 
     1285  global $astman; 
     1286  global $amp_conf; 
     1287   
     1288  if (!$amp_conf['ZAP2DAHDICOMPAT']) { 
     1289    return false; 
     1290  } 
     1291   
     1292  if (empty($version)) { 
     1293    $engine_info = engine_getinfo(); 
     1294    $version = $engine_info['version']; 
     1295  } 
     1296     
     1297  if (version_compare($version, '1.4', 'ge') && $amp_conf['AMPENGINE'] == 'asterisk') {    
     1298    if (isset($astman) && $astman->connected()) { 
     1299      $response = $astman->send_request('Command', array('Command' => 'module show like chan_dahdi')); 
     1300      if (preg_match('/1 modules loaded/', $response['data'])) { 
     1301        return true; 
     1302      } 
     1303    } 
     1304  } 
     1305  return false; 
    10471306} 
    10481307 
     
    10841343} 
    10851344 
    1086  
    10871345if (!function_exists('version_compare_freepbx')) { 
    10881346  /* verison_compare that works with freePBX version numbers 
     
    10991357} 
    11001358 
    1101  
    11021359/* queries database using PEAR. 
    11031360*  $type can be query, getAll, getRow, getCol, getOne, etc 
     
    11221379 * @return string  A value that can be safely inserted into an SQL query 
    11231380 */ 
    1124 function q(&$value) {   
     1381function q(&$value) { 
    11251382  global $db; 
    11261383  return $db->quoteSmart($value); 
     
    11291386// sql text formatting -- couldn't see that one was available already 
    11301387function sql_formattext($txt) { 
     1388  global $db; 
    11311389  if (isset($txt)) { 
    1132     $fmt = str_replace("'", "''", $txt); 
     1390    $fmt = $db->escapeSimple($txt); 
    11331391    $fmt = "'" . $fmt . "'"; 
    11341392  } else { 
     
    11381396  return $fmt; 
    11391397} 
    1140  
    11411398 
    11421399function die_freepbx($text, $extended_text="", $type="FATAL") { 
     
    13951652  } 
    13961653} 
    1397  
    13981654 
    13991655/** Recursively read voicemail.conf (and any included files) 
     
    16721928      fclose($fd); 
    16731929    } 
    1674      
    1675 
    1676  
     1930
    16771931 
    16781932// $goto is the current goto destination setting 
     
    16801934// esnure that any form that includes this calls the setDestinations() javascript function on submit. 
    16811935// ie: if the form name is "edit", and drawselects has been called with $i=2 then use onsubmit="setDestinations(edit,2)" 
    1682 function drawselects($goto,$i,$show_custom=false) {   
     1936function drawselects($goto,$i,$show_custom=false) { 
    16831937  global $tabindex; 
    16841938   
     
    17792033} 
    17802034 
    1781  
    17822035/* below are legacy functions required to allow pre 2.0 modules to function (ie: interact with 'extensions' table) */ 
    17832036 
     
    18042057  } 
    18052058   
    1806    
    18072059  //get args for specified exten and priority - primarily used to grab goto destination 
    18082060  function legacy_args_get($exten,$priority,$context) { 
     
    18152067/* end legacy functions */ 
    18162068 
    1817 /* Usage 
    1818 Grab some XML data, either from a file, URL, etc. however you want. Assume storage in $strYourXML; 
    1819  
    1820 $xml = new xml2Array($strYourXML); 
    1821 xml array is in $xml->data; 
    1822   This is basically an array version of the XML data (no attributes), striaght-up. If there are 
    1823   multiple items with the same name, they are split into a numeric sub-array,  
    1824   eg, <items><item test="123">foo</item><item>bar</item></items> 
    1825   becomes: array('item' => array(0=>array('item'=>'foo'), 1=>array('item'=>'foo')) 
    1826 attributes are in $xml->attributes; 
    1827   These are stored with xpath type paths, as $xml->attributes['/items/item/0']["test"] == "123" 
    1828    
    1829  
    1830 Other way (still works, but not as nice): 
    1831  
    1832 $objXML = new xml2Array(); 
    1833 $arrOutput = $objXML->parse($strYourXML); 
    1834 print_r($arrOutput); //print it out, or do whatever! 
    1835  
    1836 */ 
    1837  
    1838 class xml2Array { 
    1839   var $arrOutput = array(); 
    1840   var $resParser; 
    1841   var $strXmlData; 
    1842    
    1843   var $attributes; 
    1844   var $data; 
    1845    
    1846   function xml2Array($strInputXML = false) { 
    1847     if (!empty($strInputXML)) { 
    1848       $this->data = $this->parseAdvanced($strInputXML); 
    1849     } 
    1850   } 
    1851    
    1852   function parse($strInputXML) { 
    1853    
    1854       $this->resParser = xml_parser_create (); 
    1855       xml_set_object($this->resParser,$this); 
    1856       xml_set_element_handler($this->resParser, "tagOpen", "tagClosed"); 
    1857        
    1858       xml_set_character_data_handler($this->resParser, "tagData"); 
    1859      
    1860       $this->strXmlData = xml_parse($this->resParser,$strInputXML ); 
    1861       if(!$this->strXmlData) { 
    1862         die_freepbx(sprintf("XML error: %s at line %d", 
    1863       xml_error_string(xml_get_error_code($this->resParser)), 
    1864       xml_get_current_line_number($this->resParser))); 
    1865       } 
    1866                
    1867       xml_parser_free($this->resParser); 
    1868        
    1869       return $this->arrOutput; 
    1870   } 
    1871   function tagOpen($parser, $name, $attrs) { 
    1872     $tag=array("name"=>$name,"attrs"=>$attrs);  
    1873     @array_push($this->arrOutput,$tag); 
    1874   } 
    1875    
    1876   function tagData($parser, $tagData) { 
    1877     if(trim($tagData)) { 
    1878       if(isset($this->arrOutput[count($this->arrOutput)-1]['tagData'])) { 
    1879         $this->arrOutput[count($this->arrOutput)-1]['tagData'] .= "\n".$tagData; 
    1880       }  
    1881       else { 
    1882         $this->arrOutput[count($this->arrOutput)-1]['tagData'] = $tagData; 
    1883       } 
    1884     } 
    1885   } 
    1886    
    1887   function tagClosed($parser, $name) { 
    1888     @$this->arrOutput[count($this->arrOutput)-2]['children'][] = $this->arrOutput[count($this->arrOutput)-1]; 
    1889     array_pop($this->arrOutput); 
    1890   } 
    1891    
    1892   function recursive_parseLevel($items, &$attrs, $path = "") { 
    1893     $array = array(); 
    1894     foreach (array_keys($items) as $idx) { 
    1895       @$items[$idx]['name'] = strtolower($items[$idx]['name']); 
    1896        
    1897       $multi = false; 
    1898       if (isset($array[ $items[$idx]['name'] ])) { 
    1899         // this child is already set, so we're adding multiple items to an array  
    1900          
    1901         if (!is_array($array[ $items[$idx]['name'] ]) || !isset($array[ $items[$idx]['name'] ][0])) { 
    1902           // hasn't already been made into a numerically-indexed array, so do that now 
    1903           // we're basically moving the current contents of this item into a 1-item array (at the  
    1904           // original location) so that we can add a second item in the code below 
    1905           $array[ $items[$idx]['name'] ] = array( $array[ $items[$idx]['name'] ] ); 
    1906  
    1907           if (isset($attrs[ $path.'/'.$items[$idx]['name'] ])) { 
    1908             // move the attributes to /0 
    1909             $attrs[ $path.'/'.$items[$idx]['name'].'/0' ] = $attrs[ $path.'/'.$items[$idx]['name'] ]; 
    1910             unset($attrs[ $path.'/'.$items[$idx]['name'] ]); 
    1911           } 
    1912         } 
    1913         $multi = true; 
    1914       } 
    1915        
    1916       if ($multi) {  
    1917         $newitem = &$array[ $items[$idx]['name'] ][]; 
    1918       } else { 
    1919         $newitem = &$array[ $items[$idx]['name'] ]; 
    1920       } 
    1921        
    1922        
    1923       if (isset($items[$idx]['children']) && is_array($items[$idx]['children'])) { 
    1924         $newitem = $this->recursive_parseLevel($items[$idx]['children'], $attrs, $path.'/'.$items[$idx]['name']); 
    1925       } else if (isset($items[$idx]['tagData'])) { 
    1926         $newitem = $items[$idx]['tagData']; 
    1927       } else { 
    1928         $newitem = false; 
    1929       } 
    1930        
    1931       if (isset($items[$idx]['attrs']) && is_array($items[$idx]['attrs']) && count($items[$idx]['attrs'])) { 
    1932         $attrpath = $path.'/'.$items[$idx]['name']; 
    1933         if ($multi) { 
    1934           $attrpath .= '/'.(count($array[ $items[$idx]['name'] ])-1); 
    1935         } 
    1936         foreach ($items[$idx]['attrs'] as $name=>$value) { 
    1937           $attrs[ $attrpath ][ strtolower($name) ] = $value; 
    1938         } 
    1939       } 
    1940     } 
    1941     return $array; 
    1942   } 
    1943    
    1944   function parseAdvanced($strInputXML) { 
    1945     $array = $this->parse($strInputXML); 
    1946     $this->attributes = array(); 
    1947     return $this->data = $this->recursive_parseLevel($array, $this->attributes); 
    1948   } 
    1949 } 
    1950  
    1951  
    1952 /* 
    1953   Return a much more manageable assoc array with module data. 
    1954 */ 
    1955 class xml2ModuleArray extends xml2Array { 
    1956   function parseModulesXML($strInputXML) { 
    1957     $array = $this->parseAdvanced($strInputXML); 
    1958     if (isset($array['xml'])) { 
    1959       foreach ($array['xml'] as $key=>$module) { 
    1960         if ($key == 'module') { 
    1961           // copy the structure verbatim 
    1962           $modules[ $module['name'] ] = $module; 
    1963         } 
    1964       } 
    1965     } 
    1966      
    1967     // if you are confused about what's happening below, uncomment this why we do it 
    1968     // echo "<pre>"; print_r($arrOutput); echo "</pre>"; 
    1969      
    1970     // ignore the regular xml garbage ([0]['children']) & loop through each module 
    1971     if(!is_array($arrOutput[0]['children'])) return false; 
    1972     foreach($arrOutput[0]['children'] as $module) { 
    1973       if(!is_array($module['children'])) return false; 
    1974       // loop through each modules's tags 
    1975       foreach($module['children'] as $modTags) { 
    1976           if(isset($modTags['children']) && is_array($modTags['children'])) { 
    1977             $$modTags['name'] = $modTags['children']; 
    1978             // loop if there are children (menuitems and requirements) 
    1979             foreach($modTags['children'] as $subTag) { 
    1980               $subTags[strtolower($subTag['name'])] = $subTag['tagData']; 
    1981             } 
    1982             $$modTags['name'] = $subTags; 
    1983             unset($subTags); 
    1984           } else { 
    1985             // create a variable for each tag we find 
    1986             $$modTags['name'] = $modTags['tagData']; 
    1987           } 
    1988  
    1989       } 
    1990       // now build our return array 
    1991       $arrModules[$RAWNAME]['rawname'] = $RAWNAME;    // This has to be set 
    1992       $arrModules[$RAWNAME]['displayName'] = $NAME;    // This has to be set 
    1993       $arrModules[$RAWNAME]['version'] = $VERSION;     // This has to be set 
    1994       $arrModules[$RAWNAME]['type'] = isset($TYPE)?$TYPE:'setup'; 
    1995       $arrModules[$RAWNAME]['category'] = isset($CATEGORY)?$CATEGORY:'Unknown'; 
    1996       $arrModules[$RAWNAME]['info'] = isset($INFO)?$INFO:'http://www.freepbx.org/wiki/'.$RAWNAME; 
    1997       $arrModules[$RAWNAME]['location'] = isset($LOCATION)?$LOCATION:'local'; 
    1998       $arrModules[$RAWNAME]['items'] = isset($MENUITEMS)?$MENUITEMS:null; 
    1999       $arrModules[$RAWNAME]['requirements'] = isset($REQUIREMENTS)?$REQUIREMENTS:null; 
    2000       $arrModules[$RAWNAME]['md5sum'] = isset($MD5SUM)?$MD5SUM:null; 
    2001       //print_r($arrModules); 
    2002       //unset our variables 
    2003       unset($NAME); 
    2004       unset($VERSION); 
    2005       unset($TYPE); 
    2006       unset($CATEGORY); 
    2007       unset($AUTHOR); 
    2008       unset($EMAIL); 
    2009       unset($LOCATION); 
    2010       unset($MENUITEMS); 
    2011       unset($REQUIREMENTS); 
    2012       unset($MD5SUM); 
    2013     } 
    2014     //echo "<pre>"; print_r($arrModules); echo "</pre>"; 
    2015  
    2016     return $arrModules; 
    2017   } 
    2018 } 
    20192069 
    20202070function get_headers_assoc($url ) { 
     
    20502100} 
    20512101 
    2052     
    2053  
    2054 class moduleHook { 
    2055   var $hookHtml = ''; 
    2056   var $arrHooks = array(); 
    2057    
    2058   function install_hooks($viewing_itemid,$target_module,$target_menuid = '') { 
    2059     global $active_modules; 
    2060     // loop through all active modules 
    2061     foreach($active_modules as $this_module) { 
    2062         // look for requested hooks for $module 
    2063         // ie: findme_hook_extensions() 
    2064         $funct = $this_module['rawname'] . '_hook_' . $target_module; 
    2065         if( function_exists( $funct ) ) { 
    2066           // execute the function, appending the  
    2067           // html output to that of other hooking modules 
    2068           if ($hookReturn = $funct($target_menuid, $viewing_itemid)) { 
    2069             $this->hookHtml .= $hookReturn; 
    2070           } 
    2071           // remember who installed hooks 
    2072           // we need to know this for processing form vars 
    2073           $this->arrHooks[] = $this_module['rawname']; 
    2074         } 
    2075     } 
    2076   } 
    2077    
    2078   // process the request from the module we hooked 
    2079   function process_hooks($viewing_itemid, $target_module, $target_menuid, $request) { 
    2080     if(is_array($this->arrHooks)) { 
    2081       foreach($this->arrHooks as $hookingMod) { 
    2082         // check if there is a processing function 
    2083         $funct = $hookingMod . '_hookProcess_' . $target_module; 
    2084         if( function_exists( $funct ) ) { 
    2085           $funct($viewing_itemid, $request); 
    2086         } 
    2087       } 
    2088     } 
    2089   } 
    2090 
    2091  
    2092 function execSQL( $file ) 
    2093 
     2102function execSQL( $file ) { 
    20942103  global $db; 
    20952104  $data = null; 
     
    21152124  _module_runscripts($moddir, $type); 
    21162125} 
    2117  
    21182126 
    21192127/** Replaces variables in a string with the values from ampconf 
     
    21582166  $got_new = false; 
    21592167   
    2160   //this should be in an upgrade file ... putting here for now. 
    2161   /* 
    2162   sql('CREATE TABLE IF NOT EXISTS module_xml (time INT NOT NULL , data BLOB NOT NULL) TYPE = MYISAM ;'); 
    2163   */ 
    2164    
    21652168  $result = sql("SELECT * FROM module_xml WHERE id = 'xml'",'getRow',DB_FETCHMODE_ASSOC); 
    21662169  $data = $result['data']; 
     
    22162219  } 
    22172220   
    2218   //echo time() - $result['time']; 
    22192221  $parser = new xml2ModuleArray($data); 
    22202222  $xmlarray = $parser->parseAdvanced($data); 
    2221   //$modules = $xmlarray['XML']['MODULE']; 
    22222223   
    22232224  if ($got_new) { 
     
    22252226  } 
    22262227 
    2227  
    2228   //echo "<hr>Raw XML Data<pre>"; print_r(htmlentities($data)); echo "</pre>"; 
    2229   //echo "<hr>XML2ARRAY<pre>"; print_r($xmlarray); echo "</pre>"; 
    2230    
    2231    
    22322228  if (isset($xmlarray['xml']['module'])) { 
    22332229   
     
    22402236      return null; 
    22412237    } else { 
    2242      
    2243      
    22442238      $modules = array(); 
    22452239      foreach ($xmlarray['xml']['module'] as $mod) { 
     
    26882682} 
    26892683 
    2690  
    26912684/** Enables a module 
    26922685 * @param string    The name of the module to enable 
     
    29842977  return true; 
    29852978} 
    2986  
    29872979 
    29882980/** Installs or upgrades a module from it's directory 
     
    31883180} 
    31893181 
    3190  
    31913182/** Internal use only */ 
    31923183function _module_setenabled($modulename, $enabled) { 
     
    32223213    if (isset($xmlarray['module'])) { 
    32233214      // add a couple fields first 
     3215      $xmlarray['module']['name'] = str_replace("\n&\n","&",$xmlarray['module']['name']); 
    32243216      $xmlarray['module']['displayname'] = $xmlarray['module']['name']; 
     3217      if (isset($xmlarray['module']['description'])) { 
     3218        $xmlarray['module']['description'] = trim(str_replace("\n","",$xmlarray['module']['description'])); 
     3219      } 
    32253220      if (isset($xmlarray['module']['menuitems'])) { 
    32263221         
    32273222        foreach ($xmlarray['module']['menuitems'] as $item=>$displayname) { 
     3223          $displayname = str_replace("\n&\n","&",$displayname); 
     3224          $xmlarray['module']['menuitems'][$item] = $displayname; 
    32283225          $path = '/module/menuitems/'.$item; 
    32293226           
    32303227          // find category 
    32313228          if (isset($parser->attributes[$path]['category'])) { 
    3232             $category = $parser->attributes[$path]['category']
     3229            $category = str_replace("\n&\n","&",$parser->attributes[$path]['category'])
    32333230          } else if (isset($xmlarray['module']['category'])) { 
    3234             $category = $xmlarray['module']['category']
     3231            $category = str_replace("\n&\n","&",$xmlarray['module']['category'])
    32353232          } else { 
    32363233            $category = 'Basic'; 
     
    32853282        } 
    32863283      } 
    3287        
    32883284      return $xmlarray['module']; 
    32893285    } 
     
    33723368  return true; 
    33733369} 
     3370 
    33743371function _modules_doinclude($filename, $modulename) { 
    33753372  // we provide the following variables to the included file (as well as $filename and $modulename) 
     
    33803377  } 
    33813378} 
    3382    
    33833379 
    33843380/* module_get_annoucements() 
     
    33903386function module_get_annoucements() { 
    33913387  global $db; 
     3388  global $amp_conf; 
    33923389  $firstinstall=false; 
    33933390  $type=null; 
     
    34403437  } 
    34413438 
     3439  $fn = "http://mirror.freepbx.org/version-".getversion().".html".$options; 
    34423440  if (!$amp_conf['MODULEADMINWGET']) { 
    3443     $announcement = @ file_get_contents("http://mirror.freepbx.org/version-".getversion().".html".$options); 
     3441    $announcement = @ file_get_contents($fn); 
    34443442  } else { 
    34453443    $announcement = ''; 
     
    34513449  return $announcement; 
    34523450} 
    3453  
    34543451 
    34553452/* Assumes properly formated input, which is ok since 
     
    35773574    $notifications->delete('freepbx', 'modules_broken'); 
    35783575  } 
     3576} 
     3577 
     3578/** Log a debug message to a debug file 
     3579 * @param  string   debug message to be printed 
     3580 * @param  string   optional mode, default 'a' 
     3581 * @param  string   optinal filename, default /tmp/freepbx_debug.log 
     3582 */ 
     3583function freepbx_debug($string, $option='a', $filename='/tmp/freepbx_debug.log') { 
     3584  $fh = fopen($filename,$option); 
     3585  fwrite($fh,$string."\n"); 
     3586  fclose($fh); 
    35793587} 
    35803588 
  • freepbx/trunk/amp_conf/htdocs/admin/page.modules.php

    r6575 r6600  
    1313} 
    1414 
    15  
    1615$extdisplay = isset($_REQUEST['extdisplay'])?$_REQUEST['extdisplay']:''; 
     16 
    1717// can't go online if external management is on 
    1818$online = (isset($_REQUEST['online']) && !EXTERNAL_PACKAGE_MANAGEMENT) ? $_REQUEST['online'] : false; 
     19 
    1920// fix php errors from undefined variable. Not sure if we can just change the reference below to use 
    2021// online since it changes values so just setting to what we decided it is here. 
    2122$_REQUEST['online'] = $online ? 1 : 0; 
     23 
    2224$moduleaction = isset($_REQUEST['moduleaction'])?$_REQUEST['moduleaction']:false; 
    2325/* 
     
    3638$freepbx_help_url = "http://www.freepbx.org/freepbx-help-system?freepbx_version=".urlencode($freepbx_version); 
    3739 
    38 function pageReload(){ 
    39 return ""; 
    40   //return "<script language=\"Javascript\">document.location='".$_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING']."&foo=".rand()."'</script>"; 
    41 } 
    42  
    43  
    4440if (!$quietmode) { 
    4541  ?> 
     
    5450    } 
    5551  } 
    56  
    5752  function check_upgrade_all() { 
    5853    var re = /^moduleaction\[([a-z0-9_\-]+)\]$/; 
     
    6863    } 
    6964  } 
    70  
    7165  function check_download_all() { 
    7266    var re = /^moduleaction\[([a-z0-9_\-]+)\]$/; 
     
    8276    } 
    8377  } 
    84  
    85  
    8678  function showhide_upgrades() { 
    8779    var upgradesonly = document.getElementById('show_upgradable_only').checked; 
    88      
    8980    var module_re = /^module_([a-z0-9_]+)$/;   // regex to match a module element id 
    9081    var cat_re = /^category_([a-zA-Z0-9_]+)$/; // regex to match a category element id 
    91  
    9282    var elements = document.getElementById('modulelist').getElementsByTagName('li'); 
    93  
    9483    // loop through all modules, check if there is an upgrade_<module> radio box  
    9584    for(i=0; i<elements.length; i++) { 
     
    10190      } 
    10291    } 
    103      
    104      
    105      
    10692    // hide category headings that don't have any visible modules 
    107      
    10893    var elements = document.getElementById('modulelist').getElementsByTagName('div'); 
    10994    // loop through category items 
     
    120105          } 
    121106        } 
    122          
    123107        document.getElementById(elements[i].id).style.display = display ? 'block' : 'none'; 
    124108      } 
    125109    } 
    126      
    127   } 
    128  
     110  } 
    129111  function process_module_actions(actions) { 
    130112    freepbx_modal_show('moduleBox'); 
     
    142124    } 
    143125  } 
    144  
    145126  </script> 
    146127  <?php 
     
    155136  <?php 
    156137} 
    157  
    158138 
    159139$modules_local = module_getinfo(false,false,true); 
     
    204184} 
    205185 
     186//-------------------------------------------------------------------------------------------------------- 
     187switch ($extdisplay) {  // process, confirm, or nothing 
     188  case 'process': 
     189    echo "<div id=\"moduleBoxContents\">"; 
     190    echo "<h4>"._("Please wait while module actions are performed")."</h4>\n"; 
     191    echo "<div id=\"moduleprogress\">"; 
     192 
     193    // stop output buffering, and send output 
     194    @ ob_end_flush(); 
     195    flush(); 
     196    foreach ($moduleaction as $modulename => $action) {  
     197      $didsomething = true; // set to false in default clause of switch() below.. 
     198       
     199      switch ($action) { 
     200        case 'upgrade': 
     201        case 'downloadinstall': 
     202          if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
     203            echo sprintf(_('Downloading %s'), $modulename).' <span id="downloadprogress_'.$modulename.'"></span>'; 
     204            if (is_array($errors = module_download($modulename, false, 'download_progress'))) { 
     205              echo '<span class="error">'.sprintf(_("Error(s) downloading %s"),$modulename).': '; 
     206              echo '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'; 
     207              echo '</span>'; 
     208            } else { 
     209              if (is_array($errors = module_install($modulename))) { 
     210                echo '<span class="error">'.sprintf(_("Error(s) installing %s"),$modulename).': '; 
     211                echo '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'; 
     212                echo '</span>'; 
     213              } else { 
     214                echo '<span class="success">'.sprintf(_("%s installed successfully"),$modulename).'</span>'; 
     215              } 
     216            } 
     217          } 
     218        break; 
     219        case 'install': 
     220          if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
     221            if (is_array($errors = module_install($modulename))) { 
     222              echo '<span class="error">'.sprintf(_("Error(s) installing %s"),$modulename).': '; 
     223              echo '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'; 
     224              echo '</span>'; 
     225            } else { 
     226              echo '<span class="success">'.sprintf(_("%s installed successfully"),$modulename).'</span>'; 
     227            } 
     228          } 
     229        break; 
     230        case 'enable': 
     231          if (is_array($errors = module_enable($modulename))) { 
     232            echo '<span class="error">'.sprintf(_("Error(s) enabling %s"),$modulename).': '; 
     233            echo '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'; 
     234            echo '</span>'; 
     235          } else { 
     236            echo '<span class="success">'.sprintf(_("%s enabled successfully"),$modulename).'</span>'; 
     237          } 
     238        break; 
     239        case 'disable': 
     240          if (is_array($errors = module_disable($modulename))) { 
     241            echo '<span class="error">'.sprintf(_("Error(s) disabling %s"),$modulename).': '; 
     242            echo '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'; 
     243            echo '</span>'; 
     244          } else { 
     245            echo '<span class="success">'.sprintf(_("%s disabled successfully"),$modulename).'</span>'; 
     246          } 
     247        break; 
     248        case 'uninstall': 
     249          if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
     250            if (is_array($errors = module_uninstall($modulename))) { 
     251              echo '<span class="error">'.sprintf(_("Error(s) uninstalling %s"),$modulename).': '; 
     252              echo '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'; 
     253              echo '</span>'; 
     254            } else { 
     255              echo '<span class="success">'.sprintf(_("%s uninstalled successfully"),$modulename).'</span>'; 
     256            } 
     257          } 
     258        break; 
     259        default: 
     260          // just so we don't send an <hr> and flush() 
     261          $didsomething = false; 
     262      } 
     263       
     264      if ($didsomething) { 
     265        echo "<hr /><br />"; 
     266        flush(); 
     267      } 
     268    } 
     269    echo "</div>"; 
     270    if ($quietmode) { 
     271      echo "\t<a href=\"#\" onclick=\"parent.close_module_actions(true);\" />"._("Return")."</a>"; 
     272    } else { 
     273      echo "\t<input type=\"button\" value=\""._("Return")."\" onclick=\"location.href = 'config.php?display=modules&amp;type=tool&amp;online=".($_REQUEST['online']?1:0)."';\" />"; 
     274    echo "</div>"; 
     275    } 
     276  break; 
     277  case 'confirm': 
     278    ksort($moduleaction); 
     279     
     280    echo "<form name=\"modulesGUI\" action=\"config.php\" method=\"post\">"; 
     281    echo "<input type=\"hidden\" name=\"display\" value=\"".$display."\" />"; 
     282    echo "<input type=\"hidden\" name=\"type\" value=\"".$type."\" />"; 
     283    echo "<input type=\"hidden\" name=\"online\" value=\"".$online."\" />"; 
     284    echo "<input type=\"hidden\" name=\"extdisplay\" value=\"process\" />"; 
     285     
     286    echo "\t<script type=\"text/javascript\"> var moduleActions = new Array(); </script>\n"; 
     287     
     288    $actionstext = array(); 
     289    $errorstext = array(); 
     290    foreach ($moduleaction as $module => $action) {  
     291      $text = false; 
     292      $skipaction = false; 
     293 
     294      // make sure name is set. This is a problem for broken modules 
     295      if (!isset($modules[$module]['name'])) { 
     296        $modules[$module]['name'] = $module; 
     297      } 
     298       
     299      switch ($action) { 
     300        case 'upgrade': 
     301          if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
     302            if (is_array($errors = module_checkdepends($modules_online[$module]))) { 
     303              $skipaction = true; 
     304              $errorstext[] = sprintf(_("%s cannot be upgraded: %s Please try again after the dependencies have been installed."),   
     305                                      $modules[$module]['name'], 
     306                                      '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'); 
     307            } else { 
     308              $actionstext[] = sprintf(_("%s %s will be upgraded to online version %s"), $modules[$module]['name'], $modules[$module]['dbversion'], $modules_online[$module]['version']); 
     309            } 
     310          } 
     311        break; 
     312        case 'downloadinstall': 
     313          if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
     314            if (is_array($errors = module_checkdepends($modules_online[$module]))) { 
     315              $skipaction = true; 
     316              $errorstext[] = sprintf(_("%s cannot be installed: %s Please try again after the dependencies have been installed."),   
     317                                      $modules[$module]['name'], 
     318                                      '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'); 
     319            } else { 
     320              $actionstext[] =  sprintf(_("%s %s will be downloaded and installed"), $modules[$module]['name'], $modules_online[$module]['version']); 
     321            } 
     322          } 
     323        break; 
     324        case 'install': 
     325          if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
     326            if (is_array($errors = module_checkdepends($modules[$module]))) { 
     327              $skipaction = true; 
     328              $errorstext[] = sprintf((($modules[$module]['status'] == MODULE_STATUS_NEEDUPGRADE) ?  _("%s cannot be upgraded: %s Please try again after the dependencies have been installed.") : _("%s cannot be installed: %s Please try again after the dependencies have been installed.") ),   
     329                                      $modules[$module]['name'], 
     330                                      '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'); 
     331            } else { 
     332              if ($modules[$module]['status'] == MODULE_STATUS_NEEDUPGRADE) { 
     333                $actionstext[] =  sprintf(_("%s %s will be upgraded to %s"), $modules[$module]['name'], $modules[$module]['dbversion'], $modules[$module]['version']); 
     334              } else { 
     335                $actionstext[] =  sprintf(_("%s %s will be installed and enabled"), $modules[$module]['name'], $modules[$module]['version']); 
     336              } 
     337            } 
     338          } 
     339        break; 
     340        case 'enable': 
     341          if (is_array($errors = module_checkdepends($modules[$module]))) { 
     342            $skipaction = true; 
     343            $errorstext[] = sprintf(_("%s cannot be enabled: %s Please try again after the dependencies have been installed."),   
     344                                    $modules[$module]['name'], 
     345                                    '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'); 
     346          } else { 
     347            $actionstext[] =  sprintf(_("%s %s will be enabled"), $modules[$module]['name'], $modules[$module]['dbversion']); 
     348          } 
     349        break; 
     350        case 'disable': 
     351          if (is_array($errors = module_reversedepends($modules[$module]))) { 
     352            $skipaction = true; 
     353            $errorstext[] = sprintf(_("%s cannot be disabled because the following modules depend on it: %s Please disable those modules first then try again."),   
     354                                    $modules[$module]['name'], 
     355                                    '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'); 
     356          } else { 
     357            $actionstext[] =  sprintf(_("%s %s will be disabled"), $modules[$module]['name'], $modules[$module]['dbversion']); 
     358          } 
     359        break; 
     360        case 'uninstall': 
     361          if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
     362            if (is_array($errors = module_reversedepends($modules[$module]))) { 
     363              $skipaction = true; 
     364              $errorstext[] = sprintf(_("%s cannot be uninstalled because the following modules depend on it: %s Please disable those modules first then try again."),   
     365                                      $modules[$module]['name'], 
     366                                      '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'); 
     367            } else { 
     368              $actionstext[] =  sprintf(_("%s %s will be uninstalled"), $modules[$module]['name'], $modules[$module]['dbversion']); 
     369            } 
     370          } 
     371        break; 
     372      } 
     373 
     374      // If error above we skip this action so we can proceed with the others 
     375      // 
     376      if (!$skipaction) { //TODO 
     377        echo "\t<script type=\"text/javascript\"> moduleActions['".$module."'] = '".$action."'; </script>\n"; 
     378      } 
     379    } 
     380     
     381    // Write out the erros, if there are additional actions that can be accomplished list those next with the choice to 
     382    // process which will ignore the ones with errors but process the rest. 
     383    // 
     384    if (count($errorstext) > 0) { 
     385      echo "<h4>"._("Errors with selection:")."</h4>\n"; 
     386      echo "<ul>\n"; 
     387      foreach ($errorstext as $text) { 
     388        echo "\t<li>".$text."</li>\n"; 
     389      } 
     390      echo "</ul>"; 
     391    }  
     392    if (count($actionstext) > 0) { 
     393      if (count($errorstext) > 0) { 
     394        echo "<h4>"._("You may confirm the remaining selection and then try the again for the listed issues once the required dependencies have been met:")."</h4>\n"; 
     395      } else { 
     396        echo "<h4>"._("Please confirm the following actions:")."</h4>\n"; 
     397      } 
     398      echo "<ul>\n"; 
     399      foreach ($actionstext as $text) { 
     400        echo "\t<li>".$text."</li>\n"; 
     401      } 
     402      echo "</ul>"; 
     403      echo "\t<input type=\"button\" value=\"Confirm\" name=\"process\" onclick=\"process_module_actions(moduleActions);\" />"; 
     404    } else { 
     405      echo "<h4>"._("No actions to perform")."</h4>\n"; 
     406      echo "<p>"._("Please select at least one action to perform by clicking on the module, and selecting an action on the \"Action\" tab.")."</p>"; 
     407    } 
     408    echo "\t<input type=\"button\" value=\""._("Cancel")."\" onclick=\"location.href = 'config.php?display=modules&amp;type=tool&amp;online=".($_REQUEST['online']?1:0)."';\" />"; 
     409    echo "</form>"; 
     410     
     411  break; 
     412  case 'upload': 
     413    // display links 
     414    echo "<a href='config.php?display=modules&amp;type=tool'>"._("Manage local modules")."</a>\n"; 
     415    if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
     416      echo " | <a class='info' href='config.php?display=modules&amp;type=tool&amp;online=1'>"._("Check for updates online")."<span>"._("Checking for updates will transmit your FreePBX and Asterisk version numbers along with a unique but random identifier. This is used to provide proper update information and track version usage to focus development and maintenance efforts. No private information is transmitted.")."</span></a>\n"; 
     417    } 
     418         
     419    if (isset($_FILES['uploadmod']) && !empty($_FILES['uploadmod']['name'])) { 
     420      // display upload link, only if they did upload something 
     421      echo " | <a href='config.php?display=modules&amp;type=tool&amp;extdisplay=upload'>"._("Upload module")."</a><br />\n"; 
     422       
     423      $res = module_handleupload($_FILES['uploadmod']); 
     424      if (is_array($res)) { 
     425         
     426        echo '<div class="error"><p>'; 
     427        echo sprintf(_('The following error(s) occurred processing the uploaded file: %s'),  
     428             '<ul><li>'.implode('</li><li>',$res).'</li></ul>'); 
     429        echo sprintf(_('You should fix the problem or select another file and %s.'),  
     430             "<a href='config.php?display=modules&amp;type=tool'>"._("try again")."</a>"); 
     431        echo "</p></div>\n"; 
     432      } else { 
     433         
     434        echo "<p>".sprintf(_("Module uploaded successfully. You need to enable the module using %s to make it available."), 
     435             "<a href='config.php?display=modules&amp;type=tool'>"._("local module administration")."</a>") 
     436           ."</p>\n"; 
     437      } 
     438       
     439    } else { 
     440      echo "<p>"._('You can upload a tar gzip file containing a FreePBX module from your local system. If a module with the same name already exists, it will be overwritten.')."</p>\n"; 
     441     
     442      echo "<form name=\"modulesGUI-upload\" action=\"config.php\" method=\"post\" enctype=\"multipart/form-data\">"; 
     443      echo "<input type=\"hidden\" name=\"display\" value=\"".$display."\" />"; 
     444      echo "<input type=\"hidden\" name=\"type\" value=\"".$type."\" />"; 
     445      echo "<input type=\"hidden\" name=\"extdisplay\" value=\"upload\" />"; 
     446      echo "<input type=\"file\" name=\"uploadmod\" /> "; 
     447      echo "&nbsp;&nbsp; <input type=\"submit\" value=\"Upload\" />"; 
     448      echo "</form>"; 
     449    } 
     450     
     451  break; 
     452  case 'online': 
     453  default: 
     454     
     455    uasort($modules, 'category_sort_callback'); 
     456     
     457    if ($online) { 
     458      // Check for annoucements such as security advisories, required updates, etc. 
     459      // 
     460      $announcements = module_get_annoucements(); 
     461      if (isset($announcements) && !empty($announcements)) { 
     462        echo "<div class='announcements'>$announcements</div>"; 
     463      } 
     464       
     465      if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
     466        echo "<a href='config.php?display=modules&amp;type=tool&amp;online=0'>"._("Manage local modules")."</a>\n"; 
     467        echo "<input type=\"checkbox\" id=\"show_upgradable_only\" onclick=\"showhide_upgrades();\" /><label for=\"show_upgradable_only\">"._("Show only upgradable")."</label>"; 
     468      } 
     469    } else { 
     470      if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
     471        echo "<a class='info' href='config.php?display=modules&amp;type=tool&amp;online=1'>"._("Check for updates online")."<span>"._("Checking for updates will transmit your FreePBX and Asterisk version numbers along with a unique but random identifier. This is used to provide proper update information and track version usage to focus development and maintenance efforts. No private information is transmitted.")."</span></a>\n"; 
     472      } 
     473      echo " | <a href='config.php?display=modules&amp;type=tool&amp;extdisplay=upload'>"._("Upload module")."</a><br />\n"; 
     474    } 
     475 
     476    echo "<form name=\"modulesGUI\" action=\"config.php\" method=\"post\">"; 
     477    echo "<input type=\"hidden\" name=\"display\" value=\"".$display."\" />"; 
     478    echo "<input type=\"hidden\" name=\"type\" value=\"".$type."\" />"; 
     479    echo "<input type=\"hidden\" name=\"online\" value=\"".$online."\" />"; 
     480    echo "<input type=\"hidden\" name=\"extdisplay\" value=\"confirm\" />"; 
     481     
     482    echo "<div class=\"modulebuttons\">"; 
     483    if ($online) { 
     484      echo "\t<a href=\"javascript:void(null);\" onclick=\"check_download_all();\">"._("Download all")."</a>"; 
     485      echo "\t<a href=\"javascript:void(null);\" onclick=\"check_upgrade_all();\">"._("Upgrade all")."</a>"; 
     486    } 
     487    echo "\t<input type=\"reset\" value=\""._("Reset")."\" />"; 
     488    echo "\t<input type=\"submit\" value=\""._("Process")."\" name=\"process\" />"; 
     489    echo "</div>"; 
     490 
     491    echo "<div id=\"modulelist\">\n"; 
     492 
     493    echo "\t<div id=\"modulelist-header\">"; 
     494    echo "\t\t<span class=\"modulename\">"._("Module")."</span>\n"; 
     495    echo "\t\t<span class=\"moduletype\">"._("Type")."</span>\n"; 
     496    echo "\t\t<span class=\"moduleversion\">"._("Version")."</span>\n"; 
     497    echo "\t\t<span class=\"clear\">&nbsp;</span>\n"; 
     498    echo "\t</div>"; 
     499 
     500    $category = false; 
     501    $numdisplayed = 0; 
     502    $fd = $amp_conf['ASTETCDIR'].'/freepbx_module_admin.conf'; 
     503    if (file_exists($fd)) { 
     504      $module_filter = parse_ini_file($fd); 
     505    } else { 
     506      $module_filter = array(); 
     507    } 
     508    foreach (array_keys($modules) as $name) { 
     509      if (isset($module_filter[$name]) && strtolower(trim($module_filter[$name])) == 'hidden') { 
     510        continue; 
     511      } 
     512      $numdisplayed++; 
     513       
     514      if ($category !== $modules[$name]['category']) { 
     515        // show category header 
     516         
     517        if ($category !== false) { 
     518          // not the first one, so end the previous blocks 
     519          echo "\t</ul></div>\n"; 
     520        } 
     521         
     522        // start a new category header, and associated html blocks 
     523        $category = $modules[$name]['category']; 
     524        echo "\t<div class=\"category\" id=\"category_".prep_id($category)."\"><h3>"._($category)."</h3>\n"; 
     525        echo "\t<ul>"; 
     526      } 
     527 
     528      // This will load any module's i18n translations that are available and try to use them when printing the 
     529      // module names with a fall back to using the amp.po master translations for a check if not available in 
     530      // the local module. For new modules of course, there will be no translations usually. 
     531      // 
     532      if (extension_loaded('gettext') && is_dir("modules/".$name."/i18n")) { 
     533        bindtextdomain($name,"modules/".$name."/i18n"); 
     534        bind_textdomain_codeset($name, 'utf8'); 
     535        $loc_domain = $name; 
     536 
     537        $name_text = dgettext($loc_domain,$modules[$name]['name']); 
     538        if ($name_text == $modules[$name]['name']) { 
     539          $name_text = _($name_text); 
     540        } 
     541      } else { 
     542        $name_text = _($modules[$name]['name']); 
     543        $loc_domain = false; 
     544      } 
     545 
     546      echo "\t\t<li id=\"module_".prep_id($name)."\">\n"; 
     547       
     548      // ---- module header  
     549      echo "\t\t<div class=\"moduleheader\" onclick=\"toggleInfoPane('infopane_".prep_id($name)."');\" >\n"; 
     550      echo "\t\t\t<span class=\"modulename\"><a href=\"javascript:void(null);\">".(!empty($name_text) ? $name_text : $name)."</a></span>\n"; 
     551      echo "\t\t\t<span class=\"moduletype\">".$modules[$name]['type']."</span>\n"; 
     552      echo "\t\t\t<span class=\"moduleversion\">".(isset($modules[$name]['dbversion'])?$modules[$name]['dbversion']:'&nbsp;')."</span>\n"; 
     553       
     554      echo "\t\t\t<span class=\"modulestatus\">"; 
     555      switch ($modules[$name]['status']) { 
     556        case MODULE_STATUS_NOTINSTALLED: 
     557          if (isset($modules_local[$name])) { 
     558            echo '<span class="notinstalled">'._('Not Installed (Locally available)').'</span>'; 
     559          } else { 
     560            echo '<span class="notinstalled">'.sprintf(_('Not Installed (Available online: %s)'), $modules_online[$name]['version']).'</span>'; 
     561          } 
     562        break; 
     563        case MODULE_STATUS_DISABLED: 
     564          if (isset($modules_online[$name]['version'])) { 
     565            $vercomp = version_compare_freepbx($modules_local[$name]['version'], $modules_online[$name]['version']); 
     566            if ($vercomp < 0) { 
     567              echo '<span class="alert">'.sprintf(_('Disabled; Online upgrade available (%s)'),$modules_online[$name]['version']).'</span>'; 
     568            } else if ($vercomp > 0) { 
     569              echo sprintf(_('Disabled; Newer than online version (%s)'), $modules_online[$name]['version']); 
     570            } else { 
     571              echo _('Disabled; up to date'); 
     572            } 
     573          } else { 
     574            echo 'Disabled'; 
     575          } 
     576        break; 
     577        case MODULE_STATUS_NEEDUPGRADE: 
     578          echo '<span class="alert">'.sprintf(_('Disabled; Pending upgrade to %s'),$modules_local[$name]['version']).'</span>'; 
     579        break; 
     580        case MODULE_STATUS_BROKEN: 
     581          echo '<span class="alert">'._('Broken').'</span>'; 
     582        break; 
     583        default: 
     584          // check for online upgrade 
     585          if (isset($modules_online[$name]['version'])) { 
     586            $vercomp = version_compare_freepbx($modules_local[$name]['version'], $modules_online[$name]['version']); 
     587            if ($vercomp < 0) { 
     588              echo '<span class="alert">'.sprintf(_('Online upgrade available (%s)'), $modules_online[$name]['version']).'</span>'; 
     589            } else if ($vercomp > 0) { 
     590              echo sprintf(_('Newer than online version (%s)'),$modules_online[$name]['version']); 
     591            } else { 
     592              echo _('Enabled and up to date'); 
     593            } 
     594          } else if (isset($modules_online)) { 
     595            // we're connected to online, but didn't find this module 
     596            echo _('Enabled; Not available online'); 
     597          } else { 
     598            echo _('Enabled'); 
     599          } 
     600        break; 
     601      } 
     602      echo "</span>\n"; 
     603       
     604       
     605      echo "\t\t\t<span class=\"clear\">&nbsp;</span>\n"; 
     606      echo "\t\t</div>\n"; 
     607       
     608      // ---- end of module header 
     609       
     610      // ---- drop-down tab box thingy: 
     611       
     612      echo "\t\t<div class=\"moduleinfopane\" id=\"infopane_".prep_id($name)."\" >\n"; 
     613      echo "\t\t\t<div class=\"tabber\">\n"; 
     614       
     615      if (isset($modules_online[$name]['attention']) && !empty($modules_online[$name]['attention'])) { 
     616        echo "\t\t\t\t<div class=\"tabbertab\" title=\""._("Attention")."\">\n"; 
     617        echo nl2br( $loc_domain ? dgettext($loc_domain,$modules[$name]['attention']) : _($modules[$name]['attention']) ); 
     618        echo "\t\t\t\t</div>\n"; 
     619      } 
     620       
     621      echo "\t\t\t\t<div class=\"tabbertab actiontab\" title=\""._("Action")."\">\n"; 
     622       
     623      echo '<input type="radio" checked="CHECKED" id="noaction_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="0" /> '. 
     624         '<label for="noaction_'.prep_id($name).'">'._('No Action').'</label> <br />';   
     625      switch ($modules[$name]['status']) { 
     626       
     627        case MODULE_STATUS_NOTINSTALLED: 
     628          if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
     629            if (isset($modules_local[$name])) { 
     630              echo '<input type="radio" id="install_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="install" /> '. 
     631                 '<label for="install_'.prep_id($name).'">'._('Install').'</label> <br />'; 
     632            } else { 
     633              echo '<input type="radio" id="upgrade_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="downloadinstall" /> '. 
     634                 '<label for="upgrade_'.prep_id($name).'">'._('Download and Install').'</label> <br />'; 
     635            } 
     636          } 
     637        break; 
     638        case MODULE_STATUS_DISABLED: 
     639          echo '<input type="radio" id="enable_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="enable" /> '. 
     640             '<label for="enable_'.prep_id($name).'">'._('Enable').'</label> <br />'; 
     641          if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
     642            echo '<input type="radio" id="uninstall_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="uninstall" /> '. 
     643               '<label for="uninstall_'.prep_id($name).'">'._('Uninstall').'</label> <br />'; 
     644            if (isset($modules_online[$name]['version'])) { 
     645              $vercomp = version_compare_freepbx($modules_local[$name]['version'], $modules_online[$name]['version']); 
     646              if ($vercomp < 0) { 
     647                echo '<input type="radio" id="upgrade_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="upgrade" /> '. 
     648                   '<label for="upgrade_'.prep_id($name).'">'.sprintf(_('Download and Upgrade to %s, and Enable'),$modules_online[$name]['version']).'</label> <br />'; 
     649              } 
     650            } 
     651          } 
     652        break; 
     653        case MODULE_STATUS_NEEDUPGRADE: 
     654          if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
     655            echo '<input type="radio" id="install_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="install" /> '. 
     656               '<label for="install_'.prep_id($name).'">'.sprintf(_('Upgrade to %s and Enable'),$modules_local[$name]['version']).'</label> <br />'; 
     657            echo '<input type="radio" id="uninstall_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="uninstall" /> '. 
     658               '<label for="uninstall_'.prep_id($name).'">'._('Uninstall').'</label> <br />'; 
     659          } 
     660        break; 
     661        case MODULE_STATUS_BROKEN: 
     662          if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
     663            echo '<input type="radio" id="install_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="install" /> '. 
     664               '<label for="install_'.prep_id($name).'">'._('Install').'</label> <br />'; 
     665            echo '<input type="radio" id="uninstall_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="uninstall" /> '. 
     666               '<label for="uninstall_'.prep_id($name).'">'._('Uninstall').'</label> <br />'; 
     667          } 
     668        break; 
     669        default: 
     670          // check for online upgrade 
     671          if (isset($modules_online[$name]['version'])) { 
     672            $vercomp = version_compare_freepbx($modules_local[$name]['version'], $modules_online[$name]['version']); 
     673            if ($vercomp < 0) { 
     674              if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
     675                echo '<input type="radio" id="upgrade_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="upgrade" /> '. 
     676                   '<label for="upgrade_'.prep_id($name).'">'.sprintf(_('Download and Upgrade to %s'), $modules_online[$name]['version']).'</label> <br />'; 
     677              } 
     678            } 
     679          } 
     680          if (enable_option($name,'candisable')) { 
     681            echo '<input type="radio" id="disable_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="disable" /> '. 
     682               '<label for="disable_'.prep_id($name).'">'._('Disable').'</label> <br />'; 
     683          } 
     684          if (!EXTERNAL_PACKAGE_MANAGEMENT && enable_option($name,'canuninstall')) { 
     685            echo '<input type="radio" id="uninstall_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="uninstall" /> '. 
     686               '<label for="uninstall_'.prep_id($name).'">'._('Uninstall').'</label> <br />'; 
     687          } 
     688        break; 
     689      } 
     690      echo "\t\t\t\t</div>\n"; 
     691       
     692      echo "\t\t\t\t<div class=\"tabbertab\" title=\""._("Description")."\">\n"; 
     693      if (isset($modules[$name]['description']) && !empty($modules[$name]['description'])) { 
     694        echo "<h5>".sprintf(_("Description for version %s"),$modules[$name]['version'])."</h5>"; 
     695        echo nl2br( $loc_domain ? dgettext($loc_domain,$modules[$name]['description']) : _($modules[$name]['description']) ); 
     696      } else { 
     697        echo _("No description is available."); 
     698      } 
     699      if (isset($modules[$name]['info']) && !empty($modules[$name]['info'])) { 
     700        echo '<p>'._('More info').': <a href="'.$modules[$name]['info'].'" target="_new">'.$modules[$name]['info'].'</a></p>'; 
     701      } else { 
     702        echo '<p>'._('More info').': <a href="'."$freepbx_help_url&freepbx_module=".urlencode($name).'" target="help">'.sprintf(_("Get help for %s"),$name_text).'</a></p>'; 
     703      } 
     704      echo "\t\t\t\t</div>\n"; 
     705       
     706      if (isset($modules[$name]['changelog']) && !empty($modules[$name]['changelog'])) { 
     707        echo "\t\t\t\t<div class=\"tabbertab\" title=\""._("Changelog")."\">\n"; 
     708        echo "<h5>".sprintf(_("Change Log for version %s"), $modules[$name]['version'])."</h5>"; 
     709 
     710        // convert "1.x.x:" and "*1.x.x*" into bold, and do nl2br 
     711        // TODO: need to fix this to convert 1.x.xbetax.x, 1.x.xalphax.x, 1.x.xrcx.x, 1.x.xRCx.x formats as well 
     712        // 
     713        $changelog = nl2br($modules[$name]['changelog']); 
     714        $changelog = preg_replace('/(\d+(\.\d+|\.\d+beta\d+|\.\d+alpha\d+|\.\d+rc\d+|\.\d+RC\d+)+):/', '<strong>$0</strong>', $changelog); 
     715        $changelog = preg_replace('/\*(\d+(\.\d+|\.\d+beta\d+|\.\d+alpha\d+|\.\d+rc\d+|\.\d+RC\d+)+)\*/', '<strong>$1:</strong>', $changelog); 
     716 
     717        // convert '#xxx', 'ticket xxx', 'bug xxx' to ticket links and rxxx to changeset links in trac 
     718        // 
     719        $changelog = preg_replace_callback('/(?<!\w)(?:#|bug |ticket )([^&]\d{3,4})(?!\w)/i', 'trac_replace_ticket', $changelog); 
     720        $changelog = preg_replace_callback('/(?<!\w)r(\d+)(?!\w)/', 'trac_replace_changeset', $changelog); 
     721        $changelog = preg_replace_callback('/(?<!\w)\[(\d+)\](?!\w)/', 'trac_replace_changeset', $changelog); 
     722 
     723        echo $changelog; 
     724        echo "\t\t\t\t</div>\n"; 
     725      } 
     726       
     727      if ($amp_conf['DEVEL']) { 
     728        echo "\t\t\t\t<div class=\"tabbertab\" title=\""._("Debug")."\">\n"; 
     729        echo "\t\t\t\t<h5>".$name."</h5><pre>\n"; 
     730        print_r($modules_local[$name]); 
     731        echo "</pre>"; 
     732        if (isset($modules_online)) { 
     733          echo "\t\t\t\t<h5>Online info</h5><pre>\n"; 
     734          print_r($modules_online[$name]); 
     735          echo "</pre>\n"; 
     736        } 
     737          echo "\t\t\t\t<h5>combined</h5><pre>\n"; 
     738          print_r($modules[$name]); 
     739          echo "</pre>\n"; 
     740        echo "\t\t\t\t</div>\n"; 
     741      } 
     742       
     743      echo "\t\t\t</div>\n"; 
     744      echo "\t\t</div>\n"; 
     745       
     746      // ---- end of drop-down tab box  
     747       
     748      echo "\t\t</li>\n"; 
     749    } 
     750     
     751    if ($numdisplayed == 0) { 
     752      if (isset($modules_online) && count($modules_online) > 0) { 
     753        echo _("All available modules are up-to-date and installed."); 
     754      } else { 
     755        echo _("No modules to display."); 
     756      } 
     757    } 
     758     
     759    echo "\t</ul></div>\n"; 
     760    echo "</div>"; 
     761 
     762    echo "<div class=\"modulebuttons\">"; 
     763    if ($online) { 
     764      echo "\t<a href=\"javascript:void(null);\" onclick=\"check_download_all();\">"._("Download all")."</a>"; 
     765      echo "\t<a href=\"javascript:void(null);\" onclick=\"check_upgrade_all();\">"._("Upgrade all")."</a>"; 
     766    } 
     767    echo "\t<input type=\"reset\" value=\""._("Reset")."\" />"; 
     768    echo "\t<input type=\"submit\" value=\""._("Process")."\" name=\"process\" />"; 
     769    echo "</div>"; 
     770 
     771    echo "</form>"; 
     772  break; 
     773} 
     774 
     775if ($quietmode) { 
     776  echo '</body></html>'; 
     777} 
     778 
     779//------------------------------------------------------------------------------------------- 
     780// Help functions 
     781// 
    206782 
    207783function category_sort_callback($a, $b) { 
     
    273849                                        ), 
    274850                   ); 
    275  
    276851  if (isset($modules[$module_name][$option]) && strtolower(trim($modules[$module_name][$option])) == 'no') { 
    277852    $enable=false; 
     
    280855    $enable=false; 
    281856  } 
    282  
    283857  return $enable; 
    284858} 
     
    298872}                                                                                                                                               
    299873 
    300 //-------------------------------------------------------------------------------------------------------- 
    301 switch ($extdisplay) {  // process, confirm, or nothing 
    302   case 'process': 
    303     echo "<div id=\"moduleBoxContents\">"; 
    304     echo "<h4>"._("Please wait while module actions are performed")."</h4>\n"; 
    305      
    306     echo "<div id=\"moduleprogress\">"; 
    307  
    308     // stop output buffering, and send output 
    309     @ ob_end_flush(); 
    310  
    311     flush(); 
    312     foreach ($moduleaction as $modulename => $action) {  
    313       $didsomething = true; // set to false in default clause of switch() below.. 
    314        
    315       switch ($action) { 
    316         case 'upgrade': 
    317         case 'downloadinstall': 
    318           if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
    319             echo sprintf(_('Downloading %s'), $modulename).' <span id="downloadprogress_'.$modulename.'"></span>'; 
    320             if (is_array($errors = module_download($modulename, false, 'download_progress'))) { 
    321               echo '<span class="error">'.sprintf(_("Error(s) downloading %s"),$modulename).': '; 
    322               echo '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'; 
    323               echo '</span>'; 
    324             } else { 
    325              
    326               if (is_array($errors = module_install($modulename))) { 
    327                 echo '<span class="error">'.sprintf(_("Error(s) installing %s"),$modulename).': '; 
    328                 echo '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'; 
    329                 echo '</span>'; 
    330               } else { 
    331                 echo '<span class="success">'.sprintf(_("%s installed successfully"),$modulename).'</span>'; 
    332               } 
    333             } 
    334           } 
    335         break; 
    336         case 'install': 
    337           if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
    338             if (is_array($errors = module_install($modulename))) { 
    339               echo '<span class="error">'.sprintf(_("Error(s) installing %s"),$modulename).': '; 
    340               echo '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'; 
    341               echo '</span>'; 
    342             } else { 
    343               echo '<span class="success">'.sprintf(_("%s installed successfully"),$modulename).'</span>'; 
    344             } 
    345           } 
    346         break; 
    347         case 'enable': 
    348           if (is_array($errors = module_enable($modulename))) { 
    349             echo '<span class="error">'.sprintf(_("Error(s) enabling %s"),$modulename).': '; 
    350             echo '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'; 
    351             echo '</span>'; 
    352           } else { 
    353             echo '<span class="success">'.sprintf(_("%s enabled successfully"),$modulename).'</span>'; 
    354           } 
    355         break; 
    356         case 'disable': 
    357           if (is_array($errors = module_disable($modulename))) { 
    358             echo '<span class="error">'.sprintf(_("Error(s) disabling %s"),$modulename).': '; 
    359             echo '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'; 
    360             echo '</span>'; 
    361           } else { 
    362             echo '<span class="success">'.sprintf(_("%s disabled successfully"),$modulename).'</span>'; 
    363           } 
    364         break; 
    365         case 'uninstall': 
    366           if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
    367             if (is_array($errors = module_uninstall($modulename))) { 
    368               echo '<span class="error">'.sprintf(_("Error(s) uninstalling %s"),$modulename).': '; 
    369               echo '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'; 
    370               echo '</span>'; 
    371             } else { 
    372               echo '<span class="success">'.sprintf(_("%s uninstalled successfully"),$modulename).'</span>'; 
    373             } 
    374           } 
    375         break; 
    376         default: 
    377           // just so we don't send an <hr> and flush() 
    378           $didsomething = false; 
    379       } 
    380        
    381       if ($didsomething) { 
    382         echo "<hr /><br />"; 
    383         flush(); 
    384       } 
    385     } 
    386     echo "</div>"; 
    387     if ($quietmode) { 
    388       echo "\t<a href=\"#\" onclick=\"parent.close_module_actions(true);\" />"._("Return")."</a>"; 
    389     } else { 
    390       echo "\t<input type=\"button\" value=\""._("Return")."\" onclick=\"location.href = 'config.php?display=modules&amp;type=tool&amp;online=".($_REQUEST['online']?1:0)."';\" />"; 
    391     echo "</div>"; 
    392     } 
    393   break; 
    394   case 'confirm': 
    395     ksort($moduleaction); 
    396      
    397     echo "<form name=\"modulesGUI\" action=\"config.php\" method=\"post\">"; 
    398     echo "<input type=\"hidden\" name=\"display\" value=\"".$display."\" />"; 
    399     echo "<input type=\"hidden\" name=\"type\" value=\"".$type."\" />"; 
    400     echo "<input type=\"hidden\" name=\"online\" value=\"".$online."\" />"; 
    401     echo "<input type=\"hidden\" name=\"extdisplay\" value=\"process\" />"; 
    402      
    403     echo "\t<script type=\"text/javascript\"> var moduleActions = new Array(); </script>\n"; 
    404      
    405     $actionstext = array(); 
    406     $errorstext = array(); 
    407     foreach ($moduleaction as $module => $action) {  
    408       $text = false; 
    409       $skipaction = false; 
    410  
    411       // make sure name is set. This is a problem for broken modules 
    412       if (!isset($modules[$module]['name'])) { 
    413         $modules[$module]['name'] = $module; 
    414       } 
    415        
    416       switch ($action) { 
    417         case 'upgrade': 
    418           if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
    419             if (is_array($errors = module_checkdepends($modules_online[$module]))) { 
    420               $skipaction = true; 
    421               $errorstext[] = sprintf(_("%s cannot be upgraded: %s Please try again after the dependencies have been installed."),   
    422                                       $modules[$module]['name'], 
    423                                       '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'); 
    424             } else { 
    425               $actionstext[] = sprintf(_("%s %s will be upgraded to online version %s"), $modules[$module]['name'], $modules[$module]['dbversion'], $modules_online[$module]['version']); 
    426             } 
    427           } 
    428         break; 
    429         case 'downloadinstall': 
    430           if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
    431             if (is_array($errors = module_checkdepends($modules_online[$module]))) { 
    432               $skipaction = true; 
    433               $errorstext[] = sprintf(_("%s cannot be installed: %s Please try again after the dependencies have been installed."),   
    434                                       $modules[$module]['name'], 
    435                                       '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'); 
    436             } else { 
    437               $actionstext[] =  sprintf(_("%s %s will be downloaded and installed"), $modules[$module]['name'], $modules_online[$module]['version']); 
    438             } 
    439           } 
    440         break; 
    441         case 'install': 
    442           if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
    443             if (is_array($errors = module_checkdepends($modules[$module]))) { 
    444               $skipaction = true; 
    445               $errorstext[] = sprintf((($modules[$module]['status'] == MODULE_STATUS_NEEDUPGRADE) ?  _("%s cannot be upgraded: %s Please try again after the dependencies have been installed.") : _("%s cannot be installed: %s Please try again after the dependencies have been installed.") ),   
    446                                       $modules[$module]['name'], 
    447                                       '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'); 
    448             } else { 
    449               if ($modules[$module]['status'] == MODULE_STATUS_NEEDUPGRADE) { 
    450                 $actionstext[] =  sprintf(_("%s %s will be upgraded to %s"), $modules[$module]['name'], $modules[$module]['dbversion'], $modules[$module]['version']); 
    451               } else { 
    452                 $actionstext[] =  sprintf(_("%s %s will be installed and enabled"), $modules[$module]['name'], $modules[$module]['version']); 
    453               } 
    454             } 
    455           } 
    456         break; 
    457         case 'enable': 
    458           if (is_array($errors = module_checkdepends($modules[$module]))) { 
    459             $skipaction = true; 
    460             $errorstext[] = sprintf(_("%s cannot be enabled: %s Please try again after the dependencies have been installed."),   
    461                                     $modules[$module]['name'], 
    462                                     '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'); 
    463           } else { 
    464             $actionstext[] =  sprintf(_("%s %s will be enabled"), $modules[$module]['name'], $modules[$module]['dbversion']); 
    465           } 
    466         break; 
    467         case 'disable': 
    468           if (is_array($errors = module_reversedepends($modules[$module]))) { 
    469             $skipaction = true; 
    470             $errorstext[] = sprintf(_("%s cannot be disabled because the following modules depend on it: %s Please disable those modules first then try again."),   
    471                                     $modules[$module]['name'], 
    472                                     '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'); 
    473           } else { 
    474             $actionstext[] =  sprintf(_("%s %s will be disabled"), $modules[$module]['name'], $modules[$module]['dbversion']); 
    475           } 
    476         break; 
    477         case 'uninstall': 
    478           if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
    479             if (is_array($errors = module_reversedepends($modules[$module]))) { 
    480               $skipaction = true; 
    481               $errorstext[] = sprintf(_("%s cannot be uninstalled because the following modules depend on it: %s Please disable those modules first then try again."),   
    482                                       $modules[$module]['name'], 
    483                                       '<ul><li>'.implode('</li><li>',$errors).'</li></ul>'); 
    484             } else { 
    485               $actionstext[] =  sprintf(_("%s %s will be uninstalled"), $modules[$module]['name'], $modules[$module]['dbversion']); 
    486             } 
    487           } 
    488         break; 
    489       } 
    490  
    491       // If error above we skip this action so we can proceed with the others 
    492       // 
    493       if (!$skipaction) { //TODO 
    494         echo "\t<script type=\"text/javascript\"> moduleActions['".$module."'] = '".$action."'; </script>\n"; 
    495       } 
    496     } 
    497      
    498     // Write out the erros, if there are additional actions that can be accomplished list those next with the choice to 
    499     // process which will ignore the ones with errors but process the rest. 
    500     // 
    501     if (count($errorstext) > 0) { 
    502       echo "<h4>"._("Errors with selection:")."</h4>\n"; 
    503       echo "<ul>\n"; 
    504       foreach ($errorstext as $text) { 
    505         echo "\t<li>".$text."</li>\n"; 
    506       } 
    507       echo "</ul>"; 
    508     }  
    509     if (count($actionstext) > 0) { 
    510       if (count($errorstext) > 0) { 
    511         echo "<h4>"._("You may confirm the remaining selection and then try the again for the listed issues once the required dependencies have been met:")."</h4>\n"; 
    512       } else { 
    513         echo "<h4>"._("Please confirm the following actions:")."</h4>\n"; 
    514       } 
    515       echo "<ul>\n"; 
    516       foreach ($actionstext as $text) { 
    517         echo "\t<li>".$text."</li>\n"; 
    518       } 
    519       echo "</ul>"; 
    520       echo "\t<input type=\"button\" value=\"Confirm\" name=\"process\" onclick=\"process_module_actions(moduleActions);\" />"; 
    521     } else { 
    522       echo "<h4>"._("No actions to perform")."</h4>\n"; 
    523       echo "<p>"._("Please select at least one action to perform by clicking on the module, and selecting an action on the \"Action\" tab.")."</p>"; 
    524     } 
    525     echo "\t<input type=\"button\" value=\""._("Cancel")."\" onclick=\"location.href = 'config.php?display=modules&amp;type=tool&amp;online=".($_REQUEST['online']?1:0)."';\" />"; 
    526     echo "</form>"; 
    527      
    528   break; 
    529   case 'upload': 
    530     // display links 
    531     echo "<a href='config.php?display=modules&amp;type=tool'>"._("Manage local modules")."</a>\n"; 
    532     if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
    533       echo " | <a class='info' href='config.php?display=modules&amp;type=tool&amp;online=1'>"._("Check for updates online")."<span>"._("Checking for updates will transmit your FreePBX and Asterisk version numbers along with a unique but random identifier. This is used to provide proper update information and track version usage to focus development and maintenance efforts. No private information is transmitted.")."</span></a>\n"; 
    534     } 
    535          
    536     if (isset($_FILES['uploadmod']) && !empty($_FILES['uploadmod']['name'])) { 
    537       // display upload link, only if they did upload something 
    538       echo " | <a href='config.php?display=modules&amp;type=tool&amp;extdisplay=upload'>"._("Upload module")."</a><br />\n"; 
    539        
    540       $res = module_handleupload($_FILES['uploadmod']); 
    541       if (is_array($res)) { 
    542          
    543         echo '<div class="error"><p>'; 
    544         echo sprintf(_('The following error(s) occurred processing the uploaded file: %s'),  
    545              '<ul><li>'.implode('</li><li>',$res).'</li></ul>'); 
    546         echo sprintf(_('You should fix the problem or select another file and %s.'),  
    547              "<a href='config.php?display=modules&amp;type=tool'>"._("try again")."</a>"); 
    548         echo "</p></div>\n"; 
    549       } else { 
    550          
    551         echo "<p>".sprintf(_("Module uploaded successfully. You need to enable the module using %s to make it available."), 
    552              "<a href='config.php?display=modules&amp;type=tool'>"._("local module administration")."</a>") 
    553            ."</p>\n"; 
    554       } 
    555        
    556     } else { 
    557       echo "<p>"._('You can upload a tar gzip file containing a FreePBX module from your local system. If a module with the same name already exists, it will be overwritten.')."</p>\n"; 
    558      
    559       echo "<form name=\"modulesGUI-upload\" action=\"config.php\" method=\"post\" enctype=\"multipart/form-data\">"; 
    560       echo "<input type=\"hidden\" name=\"display\" value=\"".$display."\" />"; 
    561       echo "<input type=\"hidden\" name=\"type\" value=\"".$type."\" />"; 
    562       echo "<input type=\"hidden\" name=\"extdisplay\" value=\"upload\" />"; 
    563        
    564       echo "<input type=\"file\" name=\"uploadmod\" /> "; 
    565       echo "&nbsp;&nbsp; <input type=\"submit\" value=\"Upload\" />"; 
    566       echo "</form>"; 
    567     } 
    568      
    569   break; 
    570   case 'online': 
    571   default: 
    572      
    573     uasort($modules, 'category_sort_callback'); 
    574      
    575     if ($online) { 
    576       //echo "<a href='config.php?display=modules&amp;type=tool&amp;extdisplay=local'>"._("Terminate Connection to Online Module Repository")."</a><br />\n"; 
    577       //echo "<a href='config.php?display=modules&amp;type=tool&amp;extdisplay=online&amp;refresh=true'>"._("Force Refresh of Local Module Cache")."</a>\n"; 
    578        
    579       // Check for annoucements such as security advisories, required updates, etc. 
    580       // 
    581       $announcements = module_get_annoucements(); 
    582       if (isset($announcements) && !empty($announcements)) { 
    583         echo "<div class='announcements'>$announcements</div>"; 
    584       } 
    585        
    586       if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
    587         echo "<a href='config.php?display=modules&amp;type=tool&amp;online=0'>"._("Manage local modules")."</a>\n"; 
    588         echo "<input type=\"checkbox\" id=\"show_upgradable_only\" onclick=\"showhide_upgrades();\" /><label for=\"show_upgradable_only\">"._("Show only upgradable")."</label>"; 
    589       } 
    590     } else { 
    591       if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
    592         echo "<a class='info' href='config.php?display=modules&amp;type=tool&amp;online=1'>"._("Check for updates online")."<span>"._("Checking for updates will transmit your FreePBX and Asterisk version numbers along with a unique but random identifier. This is used to provide proper update information and track version usage to focus development and maintenance efforts. No private information is transmitted.")."</span></a>\n"; 
    593       } 
    594       echo " | <a href='config.php?display=modules&amp;type=tool&amp;extdisplay=upload'>"._("Upload module")."</a><br />\n"; 
    595     } 
    596  
    597     echo "<form name=\"modulesGUI\" action=\"config.php\" method=\"post\">"; 
    598     echo "<input type=\"hidden\" name=\"display\" value=\"".$display."\" />"; 
    599     echo "<input type=\"hidden\" name=\"type\" value=\"".$type."\" />"; 
    600     echo "<input type=\"hidden\" name=\"online\" value=\"".$online."\" />"; 
    601     echo "<input type=\"hidden\" name=\"extdisplay\" value=\"confirm\" />"; 
    602      
    603     echo "<div class=\"modulebuttons\">"; 
    604     if ($online) { 
    605       echo "\t<a href=\"javascript:void(null);\" onclick=\"check_download_all();\">"._("Download all")."</a>"; 
    606       echo "\t<a href=\"javascript:void(null);\" onclick=\"check_upgrade_all();\">"._("Upgrade all")."</a>"; 
    607     } 
    608     echo "\t<input type=\"reset\" value=\""._("Reset")."\" />"; 
    609     echo "\t<input type=\"submit\" value=\""._("Process")."\" name=\"process\" />"; 
    610     echo "</div>"; 
    611  
    612     echo "<div id=\"modulelist\">\n"; 
    613  
    614     echo "\t<div id=\"modulelist-header\">"; 
    615     echo "\t\t<span class=\"modulename\">"._("Module")."</span>\n"; 
    616     echo "\t\t<span class=\"moduletype\">"._("Type")."</span>\n"; 
    617     echo "\t\t<span class=\"moduleversion\">"._("Version")."</span>\n"; 
    618     echo "\t\t<span class=\"clear\">&nbsp;</span>\n"; 
    619     echo "\t</div>"; 
    620  
    621     $category = false; 
    622     $numdisplayed = 0; 
    623     $fd = $amp_conf['ASTETCDIR'].'/freepbx_module_admin.conf'; 
    624     if (file_exists($fd)) { 
    625       $module_filter = parse_ini_file($fd); 
    626     } else { 
    627       $module_filter = array(); 
    628     } 
    629     foreach (array_keys($modules) as $name) { 
    630       if (isset($module_filter[$name]) && strtolower(trim($module_filter[$name])) == 'hidden') { 
    631         continue; 
    632       } 
    633       $numdisplayed++; 
    634        
    635       if ($category !== $modules[$name]['category']) { 
    636         // show category header 
    637          
    638         if ($category !== false) { 
    639           // not the first one, so end the previous blocks 
    640           echo "\t</ul></div>\n"; 
    641         } 
    642          
    643         // start a new category header, and associated html blocks 
    644         $category = $modules[$name]['category']; 
    645         echo "\t<div class=\"category\" id=\"category_".prep_id($category)."\"><h3>"._($category)."</h3>\n"; 
    646         echo "\t<ul>"; 
    647       } 
    648        
    649       echo "\t\t<li id=\"module_".prep_id($name)."\">\n"; 
    650        
    651       // ---- module header  
    652       echo "\t\t<div class=\"moduleheader\" onclick=\"toggleInfoPane('infopane_".prep_id($name)."');\" >\n"; 
    653       echo "\t\t\t<span class=\"modulename\"><a href=\"javascript:void(null);\">".(!empty($modules[$name]['name']) ? $modules[$name]['name'] : $name)."</a></span>\n"; 
    654       echo "\t\t\t<span class=\"moduletype\">".$modules[$name]['type']."</span>\n"; 
    655       echo "\t\t\t<span class=\"moduleversion\">".(isset($modules[$name]['dbversion'])?$modules[$name]['dbversion']:'&nbsp;')."</span>\n"; 
    656        
    657       echo "\t\t\t<span class=\"modulestatus\">"; 
    658       switch ($modules[$name]['status']) { 
    659         case MODULE_STATUS_NOTINSTALLED: 
    660           if (isset($modules_local[$name])) { 
    661             echo '<span class="notinstalled">'._('Not Installed (Locally available)').'</span>'; 
    662           } else { 
    663             echo '<span class="notinstalled">'.sprintf(_('Not Installed (Available online: %s)'), $modules_online[$name]['version']).'</span>'; 
    664           } 
    665         break; 
    666         case MODULE_STATUS_DISABLED: 
    667           if (isset($modules_online[$name]['version'])) { 
    668             $vercomp = version_compare_freepbx($modules_local[$name]['version'], $modules_online[$name]['version']); 
    669             if ($vercomp < 0) { 
    670               echo '<span class="alert">'.sprintf(_('Disabled; Online upgrade available (%s)'),$modules_online[$name]['version']).'</span>'; 
    671             } else if ($vercomp > 0) { 
    672               echo sprintf(_('Disabled; Newer than online version (%s)'), $modules_online[$name]['version']); 
    673             } else { 
    674               echo _('Disabled; up to date'); 
    675             } 
    676           } else { 
    677             echo 'Disabled'; 
    678           } 
    679         break; 
    680         case MODULE_STATUS_NEEDUPGRADE: 
    681           echo '<span class="alert">'.sprintf(_('Disabled; Pending upgrade to %s'),$modules_local[$name]['version']).'</span>'; 
    682         break; 
    683         case MODULE_STATUS_BROKEN: 
    684           echo '<span class="alert">'._('Broken').'</span>'; 
    685         break; 
    686         default: 
    687           // check for online upgrade 
    688           if (isset($modules_online[$name]['version'])) { 
    689             $vercomp = version_compare_freepbx($modules_local[$name]['version'], $modules_online[$name]['version']); 
    690             if ($vercomp < 0) { 
    691               echo '<span class="alert">'.sprintf(_('Online upgrade available (%s)'), $modules_online[$name]['version']).'</span>'; 
    692             } else if ($vercomp > 0) { 
    693               echo sprintf(_('Newer than online version (%s)'),$modules_online[$name]['version']); 
    694             } else { 
    695               echo _('Enabled and up to date'); 
    696             } 
    697           } else if (isset($modules_online)) { 
    698             // we're connected to online, but didn't find this module 
    699             echo _('Enabled; Not available online'); 
    700           } else { 
    701             echo _('Enabled'); 
    702           } 
    703         break; 
    704       } 
    705       echo "</span>\n"; 
    706        
    707        
    708       echo "\t\t\t<span class=\"clear\">&nbsp;</span>\n"; 
    709       echo "\t\t</div>\n"; 
    710        
    711       // ---- end of module header 
    712        
    713        
    714       // ---- drop-down tab box thingy: 
    715        
    716       echo "\t\t<div class=\"moduleinfopane\" id=\"infopane_".prep_id($name)."\" >\n"; 
    717       echo "\t\t\t<div class=\"tabber\">\n"; 
    718        
    719       if (isset($modules_online[$name]['attention']) && !empty($modules_online[$name]['attention'])) { 
    720         echo "\t\t\t\t<div class=\"tabbertab\" title=\""._("Attention")."\">\n"; 
    721         echo nl2br($modules_online[$name]['attention']); 
    722         echo "\t\t\t\t</div>\n"; 
    723       } 
    724        
    725       echo "\t\t\t\t<div class=\"tabbertab actiontab\" title=\""._("Action")."\">\n"; 
    726        
    727       echo '<input type="radio" checked="CHECKED" id="noaction_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="0" /> '. 
    728          '<label for="noaction_'.prep_id($name).'">'._('No Action').'</label> <br />';   
    729       switch ($modules[$name]['status']) { 
    730        
    731         case MODULE_STATUS_NOTINSTALLED: 
    732           if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
    733             if (isset($modules_local[$name])) { 
    734               echo '<input type="radio" id="install_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="install" /> '. 
    735                  '<label for="install_'.prep_id($name).'">'._('Install').'</label> <br />'; 
    736             } else { 
    737               echo '<input type="radio" id="upgrade_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="downloadinstall" /> '. 
    738                  '<label for="upgrade_'.prep_id($name).'">'._('Download and Install').'</label> <br />'; 
    739             } 
    740           } 
    741         break; 
    742         case MODULE_STATUS_DISABLED: 
    743           echo '<input type="radio" id="enable_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="enable" /> '. 
    744              '<label for="enable_'.prep_id($name).'">'._('Enable').'</label> <br />'; 
    745           if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
    746             echo '<input type="radio" id="uninstall_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="uninstall" /> '. 
    747                '<label for="uninstall_'.prep_id($name).'">'._('Uninstall').'</label> <br />'; 
    748             if (isset($modules_online[$name]['version'])) { 
    749               $vercomp = version_compare_freepbx($modules_local[$name]['version'], $modules_online[$name]['version']); 
    750               if ($vercomp < 0) { 
    751                 echo '<input type="radio" id="upgrade_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="upgrade" /> '. 
    752                    '<label for="upgrade_'.prep_id($name).'">'.sprintf(_('Download and Upgrade to %s, and Enable'),$modules_online[$name]['version']).'</label> <br />'; 
    753               } 
    754             } 
    755           } 
    756         break; 
    757         case MODULE_STATUS_NEEDUPGRADE: 
    758           if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
    759             echo '<input type="radio" id="install_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="install" /> '. 
    760                '<label for="install_'.prep_id($name).'">'.sprintf(_('Upgrade to %s and Enable'),$modules_local[$name]['version']).'</label> <br />'; 
    761             echo '<input type="radio" id="uninstall_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="uninstall" /> '. 
    762                '<label for="uninstall_'.prep_id($name).'">'._('Uninstall').'</label> <br />'; 
    763           } 
    764         break; 
    765         case MODULE_STATUS_BROKEN: 
    766           if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
    767             echo '<input type="radio" id="install_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="install" /> '. 
    768                '<label for="install_'.prep_id($name).'">'._('Install').'</label> <br />'; 
    769             echo '<input type="radio" id="uninstall_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="uninstall" /> '. 
    770                '<label for="uninstall_'.prep_id($name).'">'._('Uninstall').'</label> <br />'; 
    771           } 
    772         break; 
    773         default: 
    774           // check for online upgrade 
    775           if (isset($modules_online[$name]['version'])) { 
    776             $vercomp = version_compare_freepbx($modules_local[$name]['version'], $modules_online[$name]['version']); 
    777             if ($vercomp < 0) { 
    778               if (!EXTERNAL_PACKAGE_MANAGEMENT) { 
    779                 echo '<input type="radio" id="upgrade_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="upgrade" /> '. 
    780                    '<label for="upgrade_'.prep_id($name).'">'.sprintf(_('Download and Upgrade to %s'), $modules_online[$name]['version']).'</label> <br />'; 
    781               } 
    782             } 
    783           } 
    784           if (enable_option($name,'candisable')) { 
    785             echo '<input type="radio" id="disable_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="disable" /> '. 
    786                '<label for="disable_'.prep_id($name).'">'._('Disable').'</label> <br />'; 
    787           } 
    788           if (!EXTERNAL_PACKAGE_MANAGEMENT && enable_option($name,'canuninstall')) { 
    789             echo '<input type="radio" id="uninstall_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="uninstall" /> '. 
    790                '<label for="uninstall_'.prep_id($name).'">'._('Uninstall').'</label> <br />'; 
    791           } 
    792         break; 
    793       } 
    794       echo "\t\t\t\t</div>\n"; 
    795        
    796       echo "\t\t\t\t<div class=\"tabbertab\" title=\""._("Description")."\">\n"; 
    797       if (isset($modules[$name]['description']) && !empty($modules[$name]['description'])) { 
    798         echo "<h5>".sprintf(_("Description for version %s"),$modules[$name]['version'])."</h5>"; 
    799         echo nl2br($modules[$name]['description']); 
    800       } else { 
    801         echo _("No description is available."); 
    802       } 
    803       if (isset($modules[$name]['info']) && !empty($modules[$name]['info'])) { 
    804         echo '<p>'._('More info').': <a href="'.$modules[$name]['info'].'" target="_new">'.$modules[$name]['info'].'</a></p>'; 
    805       } else { 
    806         echo '<p>'._('More info').': <a href="'."$freepbx_help_url&freepbx_module=".urlencode($name).'" target="help">'._("Get help for ").$modules[$name]['name'].'</a></p>'; 
    807       } 
    808       echo "\t\t\t\t</div>\n"; 
    809        
    810       if (isset($modules[$name]['changelog']) && !empty($modules[$name]['changelog'])) { 
    811         echo "\t\t\t\t<div class=\"tabbertab\" title=\""._("Changelog")."\">\n"; 
    812         echo "<h5>".sprintf(_("Change Log for version %s"), $modules[$name]['version'])."</h5>"; 
    813  
    814         // convert "1.x.x:" and "*1.x.x*" into bold, and do nl2br 
    815         // TODO: need to fix this to convert 1.x.xbetax.x, 1.x.xalphax.x, 1.x.xrcx.x, 1.x.xRCx.x formats as well 
    816         // 
    817         $changelog = nl2br($modules[$name]['changelog']); 
    818         $changelog = preg_replace('/(\d+(\.\d+|\.\d+beta\d+|\.\d+alpha\d+|\.\d+rc\d+|\.\d+RC\d+)+):/', '<strong>$0</strong>', $changelog); 
    819         $changelog = preg_replace('/\*(\d+(\.\d+|\.\d+beta\d+|\.\d+alpha\d+|\.\d+rc\d+|\.\d+RC\d+)+)\*/', '<strong>$1:</strong>', $changelog); 
    820  
    821         // convert '#xxx', 'ticket xxx', 'bug xxx' to ticket links and rxxx to changeset links in trac 
    822         // 
    823         $changelog = preg_replace_callback('/(?<!\w)(?:#|bug |ticket )([^&]\d{3,4})(?!\w)/i', 'trac_replace_ticket', $changelog); 
    824         $changelog = preg_replace_callback('/(?<!\w)r(\d+)(?!\w)/', 'trac_replace_changeset', $changelog); 
    825         $changelog = preg_replace_callback('/(?<!\w)\[(\d+)\](?!\w)/', 'trac_replace_changeset', $changelog); 
    826  
    827         echo $changelog; 
    828         echo "\t\t\t\t</div>\n"; 
    829       } 
    830        
    831       if (isset($amp_conf['DEVEL']) && $amp_conf['DEVEL'] == 'true') { 
    832         echo "\t\t\t\t<div class=\"tabbertab\" title=\""._("Debug")."\">\n"; 
    833         echo "\t\t\t\t<h5>".$name."</h5><pre>\n"; 
    834         print_r($modules_local[$name]); 
    835         echo "</pre>"; 
    836         if (isset($modules_online)) { 
    837           echo "\t\t\t\t<h5>Online info</h5><pre>\n"; 
    838           print_r($modules_online[$name]); 
    839           echo "</pre>\n"; 
    840         } 
    841           echo "\t\t\t\t<h5>combined</h5><pre>\n"; 
    842           print_r($modules[$name]); 
    843           echo "</pre>\n"; 
    844         echo "\t\t\t\t</div>\n"; 
    845       } 
    846        
    847       echo "\t\t\t</div>\n"; 
    848       echo "\t\t</div>\n"; 
    849        
    850       // ---- end of drop-down tab box  
    851        
    852       echo "\t\t</li>\n"; 
    853     } 
    854      
    855     if ($numdisplayed == 0) { 
    856       if (isset($modules_online) && count($modules_online) > 0) { 
    857         echo _("All available modules are up-to-date and installed."); 
    858       } else { 
    859         echo _("No modules to display."); 
    860       } 
    861     } 
    862      
    863     echo "\t</ul></div>\n"; 
    864     echo "</div>"; 
    865  
    866     echo "<div class=\"modulebuttons\">"; 
    867     if ($online) { 
    868       echo "\t<a href=\"javascript:void(null);\" onclick=\"check_download_all();\">"._("Download all")."</a>"; 
    869       echo "\t<a href=\"javascript:void(null);\" onclick=\"check_upgrade_all();\">"._("Upgrade all")."</a>"; 
    870     } 
    871     echo "\t<input type=\"reset\" value=\""._("Reset")."\" />"; 
    872     echo "\t<input type=\"submit\" value=\""._("Process")."\" name=\"process\" />"; 
    873     echo "</div>"; 
    874  
    875     echo "</form>"; 
    876   break; 
    877 
    878  
    879 if ($quietmode) { 
    880   echo '</body></html>'; 
    881 
    882  
     874function pageReload(){ 
     875  return ""; 
     876  //return "<script language=\"Javascript\">document.location='".$_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING']."&foo=".rand()."'</script>"; 
     877
    883878?> 
  • freepbx/trunk/amp_conf/htdocs/admin/views/freepbx_admin.php

    r5760 r6600  
    1313  $sort_name = Array(); 
    1414  $sort_type = Array(); 
     15  $framework_text_domain = Array(); 
    1516  // Sorting menu by category and name 
    1617  foreach ($fpbx_menu as $key => $row) { 
     
    1920    $sort_name[$key] = $row['name']; 
    2021    $sort_type[$key] = $row['type']; 
     22 
     23    if (extension_loaded('gettext') && is_dir("modules/".$key."/i18n")) { 
     24      bindtextdomain($key,"modules/".$key."/i18n"); 
     25      bind_textdomain_codeset($key, 'utf8'); 
     26      $framework_text_domain[$key] = true; 
     27    } else { 
     28      $framework_text_domain[$key] = false; 
     29    } 
    2130  } 
    2231   
     
    95104 
    96105    echo "\t<li class=\"".implode(' ',$li_classes)."\">"; 
     106    if ($framework_text_domain[$key]) { 
     107      $label_text = dgettext($key,$row['name']); 
     108      if ($label_text == $row['name']) { 
     109        $label_text = _($label_text); 
     110      } 
     111    } else { 
     112      $label_text = _($row['name']); 
     113    } 
    97114    if (isset($row['disabled']) && $row['disabled']) { 
    98       echo _($row['name'])
     115      echo $label_text
    99116    } else { 
    100       echo '<a href="'.$href.'" '.$extra_attributes.' >'._($row['name'])."</a>"; 
     117      echo '<a href="'.$href.'" '.$extra_attributes.' >'. $label_text . "</a>"; 
    101118    } 
    102119    echo "</li>\n"; 
  • freepbx/trunk/amp_conf/htdocs/recordings/includes/display.php

    r1395 r6600  
    171171  function displayNavigationBlock($m,$q,$url_opts,$start,$span,$total) { 
    172172 
    173     $start = $start=='' ? 0 : $start
    174     $span = $span=='' ? 15 : $span
     173    $start = ($start=='' || !ctype_digit($start)) ? 0 : $start
     174    $span = ($span=='' || !ctype_digit($span)) ? 15 : $span
    175175 
    176176    $total_pages = ceil($total/$span); 
  • freepbx/trunk/amp_conf/htdocs/recordings/includes/main.conf.php

    r6539 r6600  
    263263$ASTERISK_PROTOCOLS['sip']['config_files'] = "/etc/asterisk/sip.conf;/etc/asterisk/sip_additional.conf"; 
    264264$ASTERISK_PROTOCOLS['zap']['table'] = "zap"; 
    265 $ASTERISK_PROTOCOLS['zap']['config_files'] = "/etc/asterisk/zapata.conf;/etc/asterisk/zapata_additional.conf"; 
     265$ASTERISK_PROTOCOLS['zap']['config_files'] = "/etc/asterisk/zapata.conf;/etc/asterisk/zapata_additional.conf;/etc/asterisk/chan_dahdi.conf;/etc/asterisk/chan_dahdi_additional.conf"; 
    266266 
    267267# Settings for Follow-Me Select Boxes in seconds 
  • freepbx/trunk/amp_conf/htdocs/recordings/modules/callmonitor.module

    r6511 r6600  
    115115    $duration_filter = getArgument($args,'duration_filter'); 
    116116 
    117     $start = $start=='' ? 0 : $start; 
    118     $span = $span=='' ? 15 : $span; 
     117    $start = ($start=='' || !ctype_digit($start)) ? 0 : $start; 
     118    $span = ($span=='' || !ctype_digit($span)) ? 15 : $span; 
    119119    $order = $order=='' ? 'calldate' : $order; 
    120     $sort = $sort=='' ? 'desc' : $sort
     120    $sort = ($sort=='' || strtolower($sort) == 'desc') ? 'desc' : 'asc'
    121121 
    122122    $displayname = $_SESSION['ari_user']['displayname']; 
     
    205205    // table body 
    206206    $playbackRow = 2; // Index to keep track of where playback control rows should be inserted. 
    207     foreach($data as $key=>$value) { 
     207    if (is_array($data)) foreach($data as $key=>$value) { 
    208208 
    209209      // recording file 
     
    407407    } 
    408408 
    409     foreach($data as $data_key => $data_value) { 
     409    if (is_array($data)) foreach($data as $data_key => $data_value) { 
    410410 
    411411      $recording=''; 
     
    573573  function getSearchText($q,$duration_filter) { 
    574574 
     575    $duration_filter = ctype_digit($duration_filter) ? $duration_filter : 0; 
     576 
    575577    // search text 
    576578    if ($q!='*' && $q!=NULL) { 
     579 
     580      $dbh = $_SESSION['dbh_cdr']; 
    577581      $searchText .= "WHERE "; 
    578582      $tok = strtok($q," \n\t"); 
     583      $tok = $dbh->escapeSimple($tok); 
    579584      while ($tok) { 
    580585        $searchText .= " (calldate regexp '" . $tok . "' 
     
    590595                       )"; 
    591596        $tok = strtok(" \n\t"); 
     597        $tok = $dbh->escapeSimple($tok); 
    592598        if ($tok) { 
    593599          $searchText .= " AND"; 
     
    684690 
    685691    $dbh = $_SESSION['dbh_cdr']; 
     692    $order = $dbh->escapeSimple($order); 
    686693    $sql = "SELECT * 
    687694            FROM " . $ASTERISKCDR_DBTABLE . "  
  • freepbx/trunk/amp_conf/htdocs/recordings/modules/followme.module

    r6029 r6600  
    655655 
    656656  if (isset($_SESSION['dbh_asterisk'])) { 
     657    $db = $_SESSION['dbh_asterisk']; 
    657658 
    658659    //format for SQL database 
     
    660661 
    661662    $sql = "UPDATE findmefollow SET grptime = '" . $follow_me_listring_time . "', grplist = '". 
    662        str_replace("'", "''", trim($follow_me_list)) . "', pre_ring = '" . $follow_me_prering_time . 
     663       $db->escapeSimple(trim($follow_me_list)) . "', pre_ring = '" . $follow_me_prering_time . 
    663664       "', needsconf = '" . $follow_me_confirm . "' WHERE grpnum = $exten LIMIT 1"; 
    664665    $results = $_SESSION['dbh_asterisk']->query($sql); 
  • freepbx/trunk/amportal.conf

    r6539 r6600  
    199199# the stats are updated based on the STATS interval but a few items are checked 
    200200# less frequently (such as Astersisk Uptime) based on the INFO value 
     201 
     202# ZAP2DAHDICOMPAT=true|false 
     203# DEFAULT VALUE: false 
     204# If set to true, FreePBX will check if you have chan_dadhi installed. If so, it will 
     205# automatically use all your ZAP configuration settings (devices and trunks) and 
     206# silently convert them, under the covers, to DAHDI so no changes are needed. The 
     207# GUI will continue to refer to these as ZAP but it will use the proper DAHDI channels. 
     208# This will also keep Zap Channel DIDs working.