Changeset 2643

Show
Ignore:
Timestamp:
10/04/06 01:49:29 (7 years ago)
Author:
gregmac
Message:

Beginning of modules revamp: moving module_* api functions to functions.inc.php (see ApiModules);
Redesigning modules page to be more category-centric (currently upgrades/installs/etc are broken)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • freepbx/trunk/amp_conf/htdocs/admin/common/mainstyle.css

    r2106 r2643  
    289289  display: none  
    290290} 
     291 
     292 
     293/* For modules page */ 
     294#modulelist li { 
     295    list-style-type: none; 
     296} 
     297#modulelist ul { 
     298  padding-left:0; 
     299  position:relative; 
     300} 
     301#modulelist #modulelist-header { 
     302  position:relative; 
     303} 
     304#modulelist .modulename { 
     305  position:absolute; 
     306  left:0em; 
     307} 
     308#modulelist .moduletype { 
     309  position:absolute; 
     310  left: 20em; 
     311} 
     312#modulelist .moduleversion { 
     313  position:absolute; 
     314  left: 25em; 
     315} 
     316#modulelist .modulestatus { 
     317  position:absolute; 
     318  left: 30em; 
     319 
     320} 
     321#modulelist .clear { 
     322  clear:both; 
     323} 
  • freepbx/trunk/amp_conf/htdocs/admin/functions.inc.php

    r2642 r2643  
    1414require_once('featurecodes.class.php'); 
    1515require_once('components.class.php'); 
     16 
     17define('MODULE_STATUS_NOTINSTALLED', 0); 
     18define('MODULE_STATUS_DISABLED', 1); 
     19define('MODULE_STATUS_ENABLED', 2); 
     20define('MODULE_STATUS_NEEDUPGRADE', 3); 
     21define('MODULE_STATUS_BROKEN', -1); 
    1622 
    1723function parse_amportal_conf($filename) { 
     
    804810    if(trim($tagData)) { 
    805811      if(isset($this->arrOutput[count($this->arrOutput)-1]['tagData'])) { 
    806         $this->arrOutput[count($this->arrOutput)-1]['tagData'] .= $tagData; 
     812        $this->arrOutput[count($this->arrOutput)-1]['tagData'] .= "\n".$tagData; 
    807813      }  
    808814      else { 
     
    815821    $this->arrOutput[count($this->arrOutput)-2]['children'][] = $this->arrOutput[count($this->arrOutput)-1]; 
    816822    array_pop($this->arrOutput); 
     823  } 
     824   
     825  function recursive_parseLevel($items) { 
     826    $array = array(); 
     827    foreach (array_keys($items) as $idx) { 
     828      $items[$idx]['name'] = strtolower($items[$idx]['name']); 
     829       
     830      $multi = false; 
     831      if (isset($array[ $items[$idx]['name'] ])) { 
     832        // this child is already set, so we're adding multiple items to an array  
     833         
     834        if (!is_array($array[ $items[$idx]['name'] ]) || !isset($array[ $items[$idx]['name'] ][0])) { 
     835          // hasn't already been made into a numerically-indexed array, so do that now 
     836          // we're basically moving the current contents of this item into a 1-item array (at the  
     837          // original location) so that we can add a second item in the code below 
     838          $array[ $items[$idx]['name'] ] = array( $array[ $items[$idx]['name'] ] ); 
     839        } 
     840        $multi = true; 
     841      } 
     842       
     843      if (isset($items[$idx]['children']) && is_array($items[$idx]['children'])) { 
     844        if ($multi) { 
     845          $array[ $items[$idx]['name'] ][] = $this->recursive_parseLevel($items[$idx]['children']); 
     846        } else { 
     847          $array[ $items[$idx]['name'] ] = $this->recursive_parseLevel($items[$idx]['children']); 
     848        } 
     849      } else if (isset($items[$idx]['tagData'])) { 
     850        if ($multi) { 
     851          $array[ $items[$idx]['name'] ][] = $items[$idx]['tagData']; 
     852        } else { 
     853          $array[ $items[$idx]['name'] ] = $items[$idx]['tagData']; 
     854        } 
     855      } 
     856    } 
     857    return $array; 
     858  } 
     859   
     860  function parseAdvanced($strInputXML) { 
     861    $array = $this->parse($strInputXML); 
     862    return $this->recursive_parseLevel($array); 
    817863  } 
    818864} 
     
    823869class xml2ModuleArray extends xml2Array { 
    824870  function parseModulesXML($strInputXML) { 
    825     $arrOutput = $this->parse($strInputXML); 
     871    $array = $this->parseAdvanced($strInputXML); 
     872    if (isset($array['xml'])) { 
     873      foreach ($array['xml'] as $key=>$module) { 
     874        if ($key == 'module') { 
     875          // copy the structure verbatim 
     876          $modules[ $module['name'] ] = $module; 
     877          // add in a couple that aren't normally there.. 
     878          $modules[ $module['name'] ] = $module; 
     879        } 
     880      } 
     881    } 
     882     
    826883    // if you are confused about what's happening below, uncomment this why we do it 
    827884    // echo "<pre>"; print_r($arrOutput); echo "</pre>"; 
     
    10051062*/ 
    10061063 
     1064/** Module functions  
     1065 */ 
     1066  
     1067/** Get the latest module.xml file for this freePBX version.  
     1068 * Caches in the database for 5 mintues. 
     1069 * If $module is specified, only returns the data for that module 
     1070 */ 
     1071function module_getonlinexml($module = false) { // was getModuleXml() 
     1072  global $amp_conf; 
     1073  //this should be in an upgrade file ... putting here for now. 
     1074  sql('CREATE TABLE IF NOT EXISTS module_xml (time INT NOT NULL , data BLOB NOT NULL) TYPE = MYISAM ;'); 
     1075   
     1076  $result = sql('SELECT * FROM module_xml','getRow',DB_FETCHMODE_ASSOC); 
     1077  // if the epoch in the db is more than 2 hours old, or the xml is less than 100 bytes, then regrab xml 
     1078  // Changed to 5 minutes while not in release. Change back for released version. 
     1079  // 
     1080  // used for debug, time set to 0 to always fall through 
     1081  // if((time() - $result['time']) > 0 || strlen($result['data']) < 100 ) { 
     1082  if((time() - $result['time']) > 300 || strlen($result['data']) < 100 ) { 
     1083    $version = getversion(); 
     1084    $version = $version[0][0]; 
     1085    // we need to know the freepbx major version we have running (ie: 2.1.2 is 2.1) 
     1086    preg_match('/(\d+\.\d+)/',$version,$matches); 
     1087    //echo "the result is ".$matches[1]; 
     1088    if (isset($amp_conf["AMPMODULEXML"])) { 
     1089      $fn = $amp_conf["AMPMODULEXML"]."modules-".$matches[1].".xml"; 
     1090      // echo "(From amportal.conf)"; //debug 
     1091    } else { 
     1092    $fn = "http://mirror.freepbx.org/modules-".$matches[1].".xml"; 
     1093      // echo "(From default)"; //debug 
     1094    } 
     1095    //$fn = "/usr/src/freepbx-modules/modules.xml"; 
     1096    $data = file_get_contents($fn); 
     1097    // remove the old xml 
     1098    sql('DELETE FROM module_xml'); 
     1099    // update the db with the new xml 
     1100    $data4sql = (get_magic_quotes_gpc() ? $data : addslashes($data)); 
     1101    sql('INSERT INTO module_xml (time,data) VALUES ('.time().',"'.$data4sql.'")'); 
     1102  } else { 
     1103//    echo "using cache"; 
     1104    $data = $result['data']; 
     1105  } 
     1106  //echo time() - $result['time']; 
     1107  $parser = new xml2ModuleArray($data); 
     1108  $xmlarray = $parser->parseAdvanced($data); 
     1109  //$modules = $xmlarray['XML']['MODULE']; 
     1110   
     1111  //echo "<hr>Raw XML Data<pre>"; print_r(htmlentities($data)); echo "</pre>"; 
     1112  //echo "<hr>XML2ARRAY<pre>"; print_r($xmlarray); echo "</pre>"; 
     1113   
     1114   
     1115  if (isset($xmlarray['xml']['module'])) { 
     1116   
     1117    if ($module != false) { 
     1118      foreach ($xmlarray['xml']['module'] as $mod) { 
     1119        if ($module == $mod['rawname']) { 
     1120          return $module; 
     1121        } 
     1122      } 
     1123      return null; 
     1124    } else { 
     1125     
     1126     
     1127      $modules = array(); 
     1128      foreach ($xmlarray['xml']['module'] as $mod) { 
     1129        $modules[ $mod['rawname'] ] = $mod; 
     1130      } 
     1131      return $modules; 
     1132    } 
     1133  } 
     1134  return null; 
     1135} 
     1136 
     1137/** Looks through the modules directory and modules database and returns all available 
     1138 * information about one or all modules 
     1139 * @param string  (optional) The module name to query, or false for all module 
     1140 * @param mixed   (optional) The status(es) to show, using MODULE_STATUS_* constants. Can 
     1141 *                either be one value, or an array of values. 
     1142 */ 
     1143function module_getinfo($module = false, $status = false) { 
     1144  global $amp_conf, $db; 
     1145  $modules = array(); 
     1146   
     1147  if ($module) { 
     1148    // get info on only one module 
     1149    $modules[$module] = _module_readxml($module); 
     1150    $sql = 'SELECT * FROM modules WHERE modulename = "'.$module.'"'; 
     1151  } else { 
     1152    // get info on all modules 
     1153    $dir = opendir($amp_conf['AMPWEBROOT'].'/admin/modules'); 
     1154    while ($file = readdir($dir)) { 
     1155      if (($file != ".") && ($file != "..") && ($file != "CVS") &&  
     1156          ($file != ".svn") && ($file != "_cache") &&  
     1157        is_dir($amp_conf['AMPWEBROOT'].'/admin/modules/'.$file)) { 
     1158         
     1159        $modules[$file] = _module_readxml($file); 
     1160        // if status is anything else, it will be updated below when we read the db 
     1161        $modules[$file]['status'] = MODULE_STATUS_NOTINSTALLED; 
     1162      } 
     1163    } 
     1164    $sql = 'SELECT * FROM modules'; 
     1165  } 
     1166   
     1167  // determine details about this module from database 
     1168  // modulename should match the directory name 
     1169   
     1170  $results = $db->getAll($sql,DB_FETCHMODE_ASSOC); 
     1171  if(DB::IsError($results)) { 
     1172    die($results->getMessage()); 
     1173  } 
     1174   
     1175  if (is_array($results)) { 
     1176    foreach($results as $row) { 
     1177      if (isset($modules[ $row['modulename'] ])) { 
     1178        if ($row['enabled'] != 0) { 
     1179           
     1180          // check if file and registered versions are the same 
     1181          // version_compare returns 0 if no difference 
     1182          if (version_compare($row['version'], $modules[ $row['modulename'] ]['version']) == 0) { 
     1183            $modules[ $row['modulename'] ]['status'] = MODULE_STATUS_ENABLED; 
     1184          } else { 
     1185            $modules[ $row['modulename'] ]['status'] = MODULE_STATUS_NEEDUPGRADE; 
     1186          } 
     1187           
     1188        } else { 
     1189          $modules[ $row['modulename'] ]['status'] = MODULE_STATUS_DISABLED; 
     1190        } 
     1191      } else { 
     1192        // no directory for this db entry 
     1193        $modules[ $row['modulename'] ]['status'] = MODULE_STATUS_BROKEN; 
     1194      } 
     1195      $modules[ $row['modulename'] ]['dbversion'] = $row['version']; 
     1196    } 
     1197  } 
     1198   
     1199  if ($status !== false) { 
     1200    if (!is_array($status)) { 
     1201      // make a one element array so we can use in_array below 
     1202      $status = array($status); 
     1203    } 
     1204     
     1205    foreach (array_keys($modules) as $name) { 
     1206      if (!in_array($modules[$name]['status'], $status)) { 
     1207        // not found in the $status array, remove it 
     1208        unset($modules[$name]); 
     1209      } 
     1210    } 
     1211  } 
     1212   
     1213  return $modules; 
     1214} 
     1215 
     1216/** Check if a module meets dependencies.  
     1217 * @param string  The array from a parsed module.xml for this module. 
     1218 * @return mixed  Returns true if dependencies are met, or an array  
     1219 *                containing a list of human-readable errors if not. 
     1220 *                NOTE: you must use strict type checking (===) to test 
     1221 *                for true, because  array() == true ! 
     1222 */ 
     1223function module_checkdepends($modulexml) { 
     1224  $errors = array(); 
     1225   
     1226  if (isset($modulexml['depends'])) { 
     1227    foreach ($modulexml['depends'] as $type => $requirements) { 
     1228      // if only a single item, make it an array so we can use the same code as for multiple items 
     1229      if (!is_array($requirements)) { 
     1230        $requirements = array($requirements); 
     1231      } 
     1232       
     1233      foreach ($requirements as $value) { 
     1234        switch ($type) { 
     1235          case 'version': 
     1236            if (preg_match('/^([a-zA-Z_]+)(\s+(>=|>|=|<|<=|!=)?(\d(\.\d)*))?$/i', $value, $matches)) { 
     1237              // matches[1] = operator, [2] = version 
     1238            } 
     1239          break; 
     1240          case 'module': 
     1241            if (preg_match('/^([a-z_]+)(\s+(>=|>|=|<|<=|!=)?(\d(\.\d)*))?$/i', $value, $matches)) { 
     1242              // matches[1] = modulename, [3]=comparison operator, [4] = version 
     1243            } 
     1244          break; 
     1245          case 'file': // file exists 
     1246            if (!file_exists($value)) { 
     1247              $errors[] = 'File '.$value.' must exist.'; 
     1248            } 
     1249          break; 
     1250          case 'engine': 
     1251            if (preg_match('/^([a-z_]+)(\s+(>=|>|=|<|<=|!=)?(\d(\.\d)*))?$/i', $value, $matches)) { 
     1252              // matches[1] = engine, [3]=comparison operator, [4] = version 
     1253            } 
     1254          break; 
     1255        } 
     1256      } 
     1257    } 
     1258     
     1259  } 
     1260} 
     1261 
     1262/** Downloads the latest version of a module 
     1263 * and extracts it to the directory 
     1264 */ 
     1265function module_download($modulename) { // was fetchModule  
     1266  function untar_module($filename, $target) { 
     1267    global $amp_conf; 
     1268    system("tar zxf ".escapeshellarg($filename)." --directory=".escapeshellarg($target)); 
     1269    return true; 
     1270  } 
     1271   
     1272  global $amp_conf; 
     1273  $res = module_getonlinexml($modulename); 
     1274  if ($res == null) { 
     1275    echo "<div class=\"error\">"._("Unaware of module")." {$name}</div>"; 
     1276    return false; 
     1277  } 
     1278   
     1279  $file = basename($res['location']); 
     1280  $filename = $amp_conf['AMPWEBROOT']."/admin/modules/_cache/".$file; 
     1281  if (file_exists($filename)) { 
     1282    // We might already have it! Let's check the MD5. 
     1283    $filedata = ""; 
     1284    if ( $fh = @ fopen($filename, "r") ) { 
     1285      while (!feof($fh)) { 
     1286        $filedata .= fread($fh, 8192); 
     1287      } 
     1288      fclose($fh); 
     1289    } 
     1290     
     1291    if (isset($res['md5sum']) && $res['md5sum'] == md5 ($filedata)) { 
     1292      // Note, if there's no MD5 information, it will redownload 
     1293      // every time. Otherwise theres no way to avoid a corrupt 
     1294      // download 
     1295       
     1296      return untar_module($filename, $amp_conf['AMPWEBROOT'].'/admin/modules/'); 
     1297    } else { 
     1298      unlink($filename); 
     1299    } 
     1300  } 
     1301   
     1302  if (isset($amp_conf['AMPMODULESVN'])) { 
     1303    $url = $amp_conf['AMPMODULESVN'].$res['location']; 
     1304    // echo "(From amportal.conf)"; // debug 
     1305  } else { 
     1306    $url = "http://mirror.freepbx.org/modules/".$res['location']; 
     1307    // echo "(From default)"; // debug 
     1308  } 
     1309   
     1310  if ($fp = @fopen($filename,"w")) { 
     1311    $filedata = file_get_contents($url); 
     1312    fwrite($fp,$filedata); 
     1313    fclose($fp); 
     1314  } 
     1315   
     1316  if (is_readable($filename) !== TRUE ) { 
     1317    echo "<div class=\"error\">"._("Unable to save")." {$filename} - Check file/directory permissions</div>"; 
     1318    return false; 
     1319  } 
     1320   
     1321  // Check the MD5 info against what's in the module's XML 
     1322  if (!isset($res['md5sum']) || empty($res['md5sum'])) { 
     1323    echo "<div class=\"error\">"._("Unable to Locate Integrity information for")." {$filename} - "._("Continuing Anyway")."</div>"; 
     1324  } elseif ($res['md5sum'] != md5 ($filedata)) { 
     1325    echo "<div class=\"error\">"._("File Integrity FAILED for")." {$filename} - "._("Aborting")."</div>"; 
     1326    unlink($filename); 
     1327    return false; 
     1328  } 
     1329   
     1330  return untar_module($filename, $amp_conf['AMPWEBROOT'].'/admin/modules/'); 
     1331   
     1332} 
     1333 
     1334function _module_readxml($modulename) { 
     1335  global $amp_conf; 
     1336  $dir = $amp_conf['AMPWEBROOT'].'/admin/modules/'.$modulename; 
     1337  if (is_dir($dir) && file_exists($dir.'/module.xml')) { 
     1338    $data = file_get_contents($dir.'/module.xml'); 
     1339    //$parser = new xml2ModuleArray($data); 
     1340    //$xmlarray = $parser->parseModulesXML($data); 
     1341    $parser = new xml2Array($data); 
     1342    $xmlarray = $parser->parseAdvanced($data); 
     1343    if (isset($xmlarray['module'])) { 
     1344      // add a couple fields first 
     1345      $xmlarray['module']['displayname'] = $xmlarray['module']['name']; 
     1346      if (isset($xmlarray['module']['menuitems'])) { 
     1347        $xmlarray['module']['items'] = $xmlarray['module']['menuitems']; 
     1348      } 
     1349      return $xmlarray['module']; 
     1350    } 
     1351  } 
     1352  return null; 
     1353} 
     1354 
     1355/** Installs or upgrades a module from it's directory 
     1356 * Checks dependencies, and enables 
     1357 */ 
     1358function module_install($modulename) { 
     1359  $dir = $amp_conf['AMPWEBROOT'].'/admin/modules/'.$modulename; 
     1360  if (is_dir($dir) && file_exists($dir.'/module.xml')) { 
     1361  } 
     1362   
     1363   
     1364} 
     1365 
     1366function module_enable($modulename) { // was enableModule 
     1367} 
     1368 
     1369function module_disable($modulename) { // was disableModule 
     1370  global $db; 
     1371  $sql = 'UPDATE modules SET enabled = 0 WHERE modulename = "'.$modulename.'"'; 
     1372  $results = $db->query($sql); 
     1373  if(DB::IsError($results)) { 
     1374    die($results->getMessage()); 
     1375  } 
     1376} 
     1377 
     1378/** Totally deletes a module 
     1379 */ 
     1380function module_delete($modulename) { 
     1381} 
     1382 
     1383// runModuleSQL moved to functions.inc.php 
     1384/* 
     1385function installModule($modname,$modversion)  
     1386{ 
     1387  global $db; 
     1388  global $amp_conf; 
     1389   
     1390  switch ($amp_conf["AMPDBENGINE"]) 
     1391  { 
     1392    case "sqlite": 
     1393      // to support sqlite2, we are not using autoincrement. we need to find the  
     1394      // max ID available, and then insert it 
     1395      $sql = "SELECT max(id) FROM modules;"; 
     1396      $results = $db->getRow($sql); 
     1397      $new_id = $results[0]; 
     1398      $new_id ++; 
     1399      $sql = "INSERT INTO modules (id,modulename, version,enabled) values ('{$new_id}','{$modname}','{$modversion}','0' );"; 
     1400      break; 
     1401     
     1402    default: 
     1403      $sql = "INSERT INTO modules (modulename, version) values ('{$modname}','{$modversion}');"; 
     1404    break; 
     1405  } 
     1406 
     1407  $results = $db->query($sql); 
     1408  if(DB::IsError($results)) { 
     1409    die($results->getMessage()); 
     1410  } 
     1411} 
     1412 
     1413function uninstallModule($modname) { 
     1414  global $db; 
     1415  $sql = "DELETE FROM modules WHERE modulename = '{$modname}'"; 
     1416  $results = $db->query($sql); 
     1417  if(DB::IsError($results)) { 
     1418    die($results->getMessage()); 
     1419  } 
     1420} 
     1421 
     1422/** downloads a module, and extracts it into the module dir 
     1423 * / 
     1424function module_fetch($name) { // was fetchModule 
     1425  global $amp_conf; 
     1426  $res = module_getonlinexml($modulename); 
     1427  if (!isset($res)) { 
     1428    echo "<div class=\"error\">"._("Unaware of module")." {$name}</div>"; 
     1429    return false; 
     1430  } 
     1431  $file = basename($res['location']); 
     1432  $filename = $amp_conf['AMPWEBROOT']."/admin/modules/_cache/".$file; 
     1433  if(file_exists($filename)) { 
     1434    // We might already have it! Let's check the MD5. 
     1435    $filedata = ""; 
     1436    $fh = @fopen($filename, "r"); 
     1437    while (!feof($fh)) { 
     1438      $filedata .= fread($fh, 8192); 
     1439    } 
     1440    if (isset($res['md5sum']) && $res['md5sum'] == md5 ($filedata)) { 
     1441      // Note, if there's no MD5 information, it will redownload 
     1442      // every time. Otherwise theres no way to avoid a corrupt 
     1443      // download 
     1444       
     1445      return verifyAndInstall($filename); 
     1446    } else { 
     1447      unlink($filename); 
     1448    } 
     1449  } 
     1450  if (isset($amp_conf['AMPMODULESVN'])) { 
     1451    $url = $amp_conf['AMPMODULESVN'].$res['location']; 
     1452    // echo "(From amportal.conf)"; // debug 
     1453  } else { 
     1454  $url = "http://mirror.freepbx.org/modules/".$res['location']; 
     1455    // echo "(From default)"; // debug 
     1456  } 
     1457  $fp = @fopen($filename,"w"); 
     1458  $filedata = file_get_contents($url); 
     1459  fwrite($fp,$filedata); 
     1460  fclose($fp); 
     1461  if (is_readable($filename) !== TRUE ) { 
     1462    echo "<div class=\"error\">"._("Unable to save")." {$filename} - Check file/directory permissions</div>"; 
     1463    return false; 
     1464  } 
     1465  // Check the MD5 info against what's in the module's XML 
     1466  if (!isset($res['md5sum']) || empty($res['md5sum'])) { 
     1467    echo "<div class=\"error\">"._("Unable to Locate Integrity information for")." {$filename} - "._("Continuing Anyway")."</div>"; 
     1468  } elseif ($res['md5sum'] != md5 ($filedata)) { 
     1469    echo "<div class=\"error\">"._("File Integrity FAILED for")." {$filename} - "._("Aborting")."</div>"; 
     1470    unlink($filename); 
     1471    return false; 
     1472  } 
     1473  // verifyAndInstall does the untar, and will do the signed-package check. 
     1474  return verifyAndInstall($filename); 
     1475 
     1476} 
     1477 
     1478function upgradeModule($module, $allmods = NULL) { 
     1479  if($allmods === NULL) 
     1480    $allmods = find_allmodules(); 
     1481  // the install.php can set this to false if the upgrade fails. 
     1482  $success = true; 
     1483  if(is_file("modules/$module/install.php")) 
     1484    include "modules/$module/install.php"; 
     1485  if ($success) { 
     1486    sql('UPDATE modules SET version = "'.$allmods[$module]['version'].'" WHERE modulename = "'.$module.'"'); 
     1487    needreload(); 
     1488  } 
     1489} 
     1490 
     1491function rmModule($module) { 
     1492  global $amp_conf; 
     1493  if($module != 'core') { 
     1494    if (is_dir($amp_conf['AMPWEBROOT'].'/admin/modules/'.$module) && strstr($module, '.') === FALSE ) { 
     1495      exec('/bin/rm -rf '.$amp_conf['AMPWEBROOT'].'/admin/modules/'.$module); 
     1496    } 
     1497  } else { 
     1498    echo "<script language=\"Javascript\">alert('"._("You cannot delete the Core module")."');</script>"; 
     1499  } 
     1500} 
     1501 
     1502*/ 
     1503 
     1504 
    10071505function freepbx_log($section, $level, $message) { 
    1008  global $db; 
    1009  global $debug; // This is used by retrieve_conf 
    1010  
    1011  $sth = $db->prepare("INSERT INTO freepbx_log (time, section, level, message) VALUES (NOW(),?,?,?)"); 
    1012  $db->execute($sth, array($section, $level, $message)); 
    1013  if (isset($debug) && ($debug != false)) 
    1014    print "[DEBUG-$section] ($level) $message\n"; 
     1506        global $db; 
     1507        global $debug; // This is used by retrieve_conf 
     1508 
     1509        $sth = $db->prepare("INSERT INTO freepbx_log (time, section, level, message) VALUES (NOW(),?,?,?)"); 
     1510        $db->execute($sth, array($section, $level, $message)); 
     1511        if (isset($debug) && ($debug != false)) 
     1512                print "[DEBUG-$section] ($level) $message\n"; 
    10151513} 
    10161514?> 
  • freepbx/trunk/amp_conf/htdocs/admin/page.modules.php

    r2623 r2643  
    105105<div class="content"> 
    106106 
    107  
    108107<?php 
     108$modules_local = module_getinfo(); 
     109 
     110$modules_online = module_getonlinexml(); 
     111 
     112$modules = $modules_local + $modules_online; 
     113 
     114function category_sort_callback($a, $b) { 
     115  // sort by category.. 
     116  $catcomp = strcmp($a['category'], $b['category']); 
     117  if ($catcomp == 0) { 
     118    // .. then by name 
     119    return strcmp($a['name'], $b['name']); 
     120  } else 
     121    return $catcomp; 
     122} 
     123uasort($modules, 'category_sort_callback'); 
     124 
     125echo "<div id=\"modulelist\">\n"; 
     126 
     127echo "\t<div id=\"modulelist-header\">"; 
     128echo "\t\t<span class=\"modulename\">Module</span>\n"; 
     129echo "\t\t<span class=\"moduletype\">Type</span>\n"; 
     130echo "\t\t<span class=\"moduleversion\">Version</span>\n"; 
     131echo "\t\t<span class=\"clear\">&nbsp;</span>\n"; 
     132echo "\t</div>"; 
     133 
     134$category = false; 
     135foreach (array_keys($modules) as $name) { 
     136 
     137  if ($category != $modules[$name]['category']) { 
     138    // show category header 
     139     
     140    if ($category !== false) { 
     141      // not the first one, so end the previous blocks 
     142      echo "\t</ul></div>\n"; 
     143    } 
     144     
     145    // start a new category header, and associated html blocks 
     146    $category = $modules[$name]['category']; 
     147    echo "\t<div class=\"category\" id=\"category_".$category."\"><h3>".$category."</h3>\n"; 
     148    echo "\t<ul>"; 
     149  } 
     150   
     151  echo "\t\t<li>\n"; 
     152  echo "\t\t<span class=\"modulename\">".$modules[$name]['name']."</span>\n"; 
     153  echo "\t\t<span class=\"moduletype\">".$modules[$name]['type']."</span>\n"; 
     154  echo "\t\t<span class=\"moduleversion\">".$modules[$name]['dbversion']."</span>\n"; 
     155   
     156  echo "\t\t<span class=\"modulestatus\">"; 
     157  switch ($modules[$name]['status']) { 
     158    case MODULE_STATUS_NOTINSTALLED: 
     159      if (isset($modules_local[$name])) { 
     160        echo '<span class="alert">Not Installed (Locally available)</span>'; 
     161      } else { 
     162        echo '<span class="alert">Not Installed (Available online: '.$modules_online[$name]['version'].')</span>'; 
     163      } 
     164    break; 
     165    case MODULE_STATUS_DISABLED: 
     166      echo '<span class="alert">Disabled</span>'; 
     167    break; 
     168    case MODULE_STATUS_NEEDUPGRADE: 
     169      echo '<span class="alert">Awaiting upgrade ('.$modules[$name]['version'].' ready)</span>'; 
     170    break; 
     171    case MODULE_STATUS_BROKEN: 
     172      echo '<span class="alert">Broken</span>'; 
     173    break; 
     174    default: 
     175      if (isset($modules_online[$name]['version'])) { 
     176        $vercomp = version_compare($modules[$name]['version'], $modules_online[$name]['version']); 
     177        if ($vercomp < 0) { 
     178          echo '<span class="alert">Online upgrade available ('.$modules_online[$name]['version'].')</span>'; 
     179        } else if ($vercomp > 0) { 
     180          echo 'Newer than online version ('.$modules_online[$name]['version'].')'; 
     181        } 
     182      } 
     183    break; 
     184  } 
     185  echo "</span>\n"; 
     186   
     187  echo "\t\t<span class=\"clear\">&nbsp;</span>\n"; 
     188   
     189   
     190  echo "\t\t</li>\n"; 
     191} 
     192echo "\t</ul></div>\n"; 
     193echo "</div>"; 
     194 
     195 
     196 
     197echo '<pre>'; 
     198 
     199 
     200 
     201 
     202 
     203 
     204 
     205exit; 
     206 
    109207switch($extdisplay) { 
    110208  case "online":  
     
    133231    $installed = find_allmodules(); 
    134232    // determine what modules are available 
    135     $online = getModuleXml(); 
     233    $online = module_getonlinexml(); 
    136234    $dispMods = new displayModules($installed,$online); 
    137235    echo $dispMods->drawModules(); 
     
    220318       */ 
    221319      if(isset($modsOnlineUpdate) && is_array($modsOnlineUpdate)) { 
    222         $rows = ""; 
    223         foreach($modsOnlineUpdate as $mod) { 
    224           $color = "orange"; 
    225           $rows .= $this->tableHtml($mod,$color); 
    226         } 
     320        $color = "orange"; 
    227321        $this->options = " 
    228322          <select name=\"modaction\"> 
     
    233327          "; 
    234328        // build the table 
    235         $this->html .= $this->formStart(_("Available Module Updates (online)")); 
    236         $this->html .= $rows; 
    237         $this->html .= $this->formEnd($mod['status']); 
     329        $this->html .= $this->buildTable(_("Available Module Updates (online)"), $modsOnlineUpdate, $color, $options); 
    238330      } 
    239331       
     
    242334       */      
    243335      if(isset($modsOnlineOnly) && is_array($modsOnlineOnly)) { 
    244         $rows = ""; 
    245         foreach($modsOnlineOnly as $mod) { 
    246           $color = "white"; 
    247           $rows .= $this->tableHtml($mod,$color); 
    248         } 
     336        $color = "white"; 
    249337        $this->options = " 
    250338          <select name=\"modaction\"> 
     
    255343          "; 
    256344        // build the table 
    257         $this->html .= $this->formStart(_("Modules Available (online)")); 
    258         $this->html .= $rows; 
    259         $this->html .= $this->formEnd($mod['status']); 
     345        $this->html .= $this->buildTable(_("Modules Available (online)"), $modsOnlineOnly, $color, $options); 
    260346      }      
    261347       
     
    286372       */ 
    287373      if(isset($modsUpdate) && is_array($modsUpdate)) { 
    288         $rows = ""; 
    289         foreach($modsUpdate as $mod) {     
    290           $color = "#CCFF00"; 
    291           $rows .= $this->tableHtml($mod,$color); 
    292         } 
    293         $this->options = " 
     374        $color = "#CCFF00"; 
     375        $options = " 
    294376          <select name=\"modaction\"> 
    295377            <option value=\"upgrade\">"._("Upgrade Selected")." 
     
    298380          "; 
    299381        // build the table 
    300         $this->html .= $this->formStart(_("Enabled Modules Requiring Upgrade")); 
    301         $this->html .= $rows; 
    302         $this->html .= $this->formEnd($mod['status']); 
     382        $this->html .= $this->buildTable(_("Enabled Modules Requiring Upgrade"), $modsUpdate, $color, $options); 
    303383      } 
    304384       
     
    307387       */      
    308388      if(isset($modsEnabled) && is_array($modsEnabled)) { 
    309         $rows = ""; 
    310         foreach($modsEnabled as $mod) { 
    311           $color = "white"; 
    312           $rows .= $this->tableHtml($mod,$color); 
    313         } 
     389        $color = "white"; 
    314390        $this->options = " 
    315391          <select name=\"modaction\"> 
     
    321397          "; 
    322398        // build the table 
    323         $this->html .= $this->formStart(_("Enabled Modules")); 
    324         $this->html .= $rows; 
    325         $this->html .= $this->formEnd($mod['status']); 
     399        $this->html .= $this->buildTable(_("Enabled Modules"), $modsEnabled, $color, $options); 
    326400      } 
    327401       
     
    330404       */      
    331405      if(isset($modsDisabled) && is_array($modsDisabled)) { 
    332         $rows = ""; 
    333         foreach($modsDisabled as $mod) { 
    334           $color = "white"; 
    335           $rows .= $this->tableHtml($mod,$color); 
    336         } 
     406        $color = "white"; 
    337407        $this->options = " 
    338408          <select name=\"modaction\"> 
     
    344414          "; 
    345415        // build the table 
    346         $this->html .= $this->formStart(_("Disabled Modules")); 
    347         $this->html .= $rows; 
    348         $this->html .= $this->formEnd($mod['status']); 
     416        $this->html .= $this->buildTable(_("Disabled Modules"), $modsDisabled, $color, $options); 
    349417      } 
    350418 
     
    353421       */      
    354422      if(isset($modsNotinstalled) && is_array($modsNotinstalled)) { 
    355         $rows = ""; 
    356         foreach($modsNotinstalled as $mod) { 
    357           $color = "white"; 
    358           $rows .= $this->tableHtml($mod,$color); 
    359         } 
     423        $color = "white"; 
    360424        $this->options = " 
    361425          <select name=\"modaction\"> 
     
    366430          "; 
    367431        // build the table 
    368         $this->html .= $this->formStart(_("Not Installed Local Modules")); 
    369         $this->html .= $rows; 
    370         $this->html .= $this->formEnd($mod['status']); 
     432        $this->html .= $this->buildTable(_("Not Installed Local Modules"), $modsNotinstalled, $color, $options); 
    371433      } 
    372434       
    373435      if(isset($modsBroken) && is_array($modsBroken)) { 
    374         $rows = ""; 
    375         foreach($modsBroken as $mod) { 
    376           $color = "#FFFFFF"; 
    377           $rows .= $this->tableHtmlBroken($mod,$color); 
    378         } 
     436        $color = "#FFFFFF"; 
     437          //$rows .= $this->tableHtmlBroken($mod,$color); 
    379438        $this->options = " 
    380439          <select name=\"modaction\"> 
     
    384443          "; 
    385444        // build the table 
    386         $this->html .= $this->formStart(_('Broken')); 
    387         $this->html .= $rows; 
    388         $this->html .= $this->formEnd($mod['status']); 
     445        // BROKEN modname instead of rawname ??  
     446        $this->html .= $this->buildTable(_("Not Installed Local Modules"), $modsBroken, $color, $options); 
    389447      } 
    390448       
     
    423481  } 
    424482   
    425   function tableHtml($arrRow,$color) { 
     483  // tableRow($color, $mod['rawname'], $mod['version'], $mod['type'], $mod['categrory'], $mod['displayName'], $mod['info'] 
     484  function tableRow($color, $rawname, $version, $type, $category, $displayname, $infourl) { 
     485    $out = '<tr bgcolor="'.$color.'">'; 
     486    $out .= '<td><input type="checkbox" name="modules[]" value="'.$rawname.'">'. 
     487            '<input type="hidden" name="'.$rawname.'_version" value="'.$version.'"></td>'; 
     488    $out .= '<td><a target="_BLANK" href="'.$infourl.'">'.$displayname.' ('.$rawname.')</a></td>'; 
     489    $out .= '<td>'.$version.'</td>'; 
     490    $out .= '<td>'.$type.'</td>'; 
     491    $out .= '</tr>'; 
     492    return $out; 
    426493    return <<< End_of_Html 
    427494       
     
    473540    return $this->html; 
    474541  } 
     542   
     543   
     544  function buildTable($title, $rows, $color, $options) { 
     545    $out = $this->formStart($title); 
     546    foreach($rows as $mod) { 
     547      $out .= $this->tableRow($mod); 
     548    } 
     549    $out .= $this->formEnd(); 
     550    return $out; 
     551  } 
    475552} 
    476553 
    477 function getModuleXml() { 
    478   global $amp_conf; 
    479   //this should be in an upgrade file ... putting here for now. 
    480   sql('CREATE TABLE IF NOT EXISTS module_xml (time INT NOT NULL , data BLOB NOT NULL) TYPE = MYISAM ;'); 
    481    
    482   $result = sql('SELECT * FROM module_xml','getRow',DB_FETCHMODE_ASSOC); 
    483   // if the epoch in the db is more than 2 hours old, or the xml is less than 100 bytes, then regrab xml 
    484   // Changed to 5 minutes while not in release. Change back for released version. 
    485   // 
    486   // used for debug, time set to 0 to always fall through 
    487   // if((time() - $result['time']) > 0 || strlen($result['data']) < 100 ) { 
    488   if((time() - $result['time']) > 300 || strlen($result['data']) < 100 ) { 
    489     $version = getversion(); 
    490     $version = $version[0][0]; 
    491     // we need to know the freepbx major version we have running (ie: 2.1.2 is 2.1) 
    492     preg_match('/(\d+\.\d+)/',$version,$matches); 
    493     //echo "the result is ".$matches[1]; 
    494     if (isset($amp_conf["AMPMODULEXML"])) { 
    495       $fn = $amp_conf["AMPMODULEXML"]."modules-".$matches[1].".xml"; 
    496       // echo "(From amportal.conf)"; //debug 
    497     } else { 
    498     $fn = "http://mirror.freepbx.org/modules-".$matches[1].".xml"; 
    499       // echo "(From default)"; //debug 
    500     } 
    501     //$fn = "/usr/src/freepbx-modules/modules.xml"; 
    502     $data = file_get_contents($fn); 
    503     // remove the old xml 
    504     sql('DELETE FROM module_xml'); 
    505     // update the db with the new xml 
    506     $data4sql = (get_magic_quotes_gpc() ? $data : addslashes($data)); 
    507     sql('INSERT INTO module_xml (time,data) VALUES ('.time().',"'.$data4sql.'")'); 
    508   } else { 
    509 //    echo "using cache"; 
    510     $data = $result['data']; 
    511   } 
    512   //echo time() - $result['time']; 
    513   $parser = new xml2ModuleArray($data); 
    514   $xmlarray = $parser->parseModulesXML($data); 
    515   //$modules = $xmlarray['XML']['MODULE']; 
    516    
    517   //echo "<hr>Raw XML Data<pre>"; print_r(htmlentities($data)); echo "</pre>"; 
    518   //echo "<hr>XML2ARRAY<pre>"; print_r($xmlarray); echo "</pre>"; 
    519    
    520   return $xmlarray; 
    521 } 
    522  
    523 // runModuleSQL moved to functions.inc.php 
    524  
    525 function installModule($modname,$modversion)  
    526 { 
    527   global $db; 
    528   global $amp_conf; 
    529    
    530   switch ($amp_conf["AMPDBENGINE"]) 
    531   { 
    532     case "sqlite": 
    533       // to support sqlite2, we are not using autoincrement. we need to find the  
    534       // max ID available, and then insert it 
    535       $sql = "SELECT max(id) FROM modules;"; 
    536       $results = $db->getRow($sql); 
    537       $new_id = $results[0]; 
    538       $new_id ++; 
    539       $sql = "INSERT INTO modules (id,modulename, version,enabled) values ('{$new_id}','{$modname}','{$modversion}','0' );"; 
    540       break; 
    541      
    542     default: 
    543       $sql = "INSERT INTO modules (modulename, version) values ('{$modname}','{$modversion}');"; 
    544     break; 
    545   } 
    546  
    547   $results = $db->query($sql); 
    548   if(DB::IsError($results)) { 
    549     die($results->getMessage()); 
    550   } 
    551 } 
    552  
    553 function uninstallModule($modname) { 
    554   global $db; 
    555   $sql = "DELETE FROM modules WHERE modulename = '{$modname}'"; 
    556   $results = $db->query($sql); 
    557   if(DB::IsError($results)) { 
    558     die($results->getMessage()); 
    559   } 
    560 } 
    561  
    562 function enableModule($modname) { 
    563   global $db; 
    564   $sql = "UPDATE modules SET enabled = 1 WHERE modulename = '{$modname}'"; 
    565   $results = $db->query($sql); 
    566   if(DB::IsError($results)) { 
    567     die($results->getMessage()); 
    568   } 
    569 } 
    570  
    571 function disableModule($modname) { 
    572   global $db; 
    573   $sql = "UPDATE modules SET enabled = 0 WHERE modulename = '{$modname}'"; 
    574   $results = $db->query($sql); 
    575   if(DB::IsError($results)) { 
    576     die($results->getMessage()); 
    577   } 
    578 } 
    579  
    580 function deleteModule($modname) { 
    581   global $db; 
    582   $sql = "DELETE FROM modules WHERE modulename = '{$modname}' LIMIT 1"; 
    583   $results = $db->query($sql); 
    584   if(DB::IsError($results)) { 
    585     die($results->getMessage()); 
    586   } 
    587 } 
    588  
    589 //downloads a module, and extracts it into the module dir 
    590 function fetchModule($name) { 
    591   global $amp_conf; 
    592   $res = getThisModule($name); 
    593   if (!isset($res)) { 
    594     echo "<div class=\"error\">"._("Unaware of module")." {$name}</div>"; 
    595     return false; 
    596   } 
    597   $file = basename($res['location']); 
    598   $filename = $amp_conf['AMPWEBROOT']."/admin/modules/_cache/".$file; 
    599   if(file_exists($filename)) { 
    600     // We might already have it! Let's check the MD5. 
    601     $filedata = ""; 
    602     $fh = @fopen($filename, "r"); 
    603     while (!feof($fh)) { 
    604       $filedata .= fread($fh, 8192); 
    605     } 
    606     if (isset($res['md5sum']) && $res['md5sum'] == md5 ($filedata)) { 
    607       // Note, if there's no MD5 information, it will redownload 
    608       // every time. Otherwise theres no way to avoid a corrupt 
    609       // download 
    610       return verifyAndInstall($filename); 
    611     } else { 
    612       unlink($filename); 
    613     } 
    614   } 
    615   if (isset($amp_conf['AMPMODULESVN'])) { 
    616     $url = $amp_conf['AMPMODULESVN'].$res['location']; 
    617     // echo "(From amportal.conf)"; // debug 
    618   } else { 
    619   $url = "http://mirror.freepbx.org/modules/".$res['location']; 
    620     // echo "(From default)"; // debug 
    621   } 
    622   $fp = @fopen($filename,"w"); 
    623   $filedata = file_get_contents($url); 
    624   fwrite($fp,$filedata); 
    625   fclose($fp); 
    626   if (is_readable($filename) !== TRUE ) { 
    627     echo "<div class=\"error\">"._("Unable to save")." {$filename} - Check file/directory permissions</div>"; 
    628     return false; 
    629   } 
    630   // Check the MD5 info against what's in the module's XML 
    631   if (!isset($res['md5sum']) || empty($res['md5sum'])) { 
    632     echo "<div class=\"error\">"._("Unable to Locate Integrity information for")." {$filename} - "._("Continuing Anyway")."</div>"; 
    633   } elseif ($res['md5sum'] != md5 ($filedata)) { 
    634     echo "<div class=\"error\">"._("File Integrity FAILED for")." {$filename} - "._("Aborting")."</div>"; 
    635     unlink($filename); 
    636     return false; 
    637   } 
    638   // verifyAndInstall does the untar, and will do the signed-package check. 
    639   return verifyAndInstall($filename); 
    640  
    641 } 
    642  
    643 function upgradeModule($module, $allmods = NULL) { 
    644   if($allmods === NULL) 
    645     $allmods = find_allmodules(); 
    646   // the install.php can set this to false if the upgrade fails. 
    647   $success = true; 
    648   if(is_file("modules/$module/install.php")) 
    649     include "modules/$module/install.php"; 
    650   if ($success) { 
    651     sql('UPDATE modules SET version = "'.$allmods[$module]['version'].'" WHERE modulename = "'.$module.'"'); 
    652     needreload(); 
    653   } 
    654 } 
    655  
    656 function rmModule($module) { 
    657   global $amp_conf; 
    658   if($module != 'core') { 
    659     if (is_dir($amp_conf['AMPWEBROOT'].'/admin/modules/'.$module) && strstr($module, '.') === FALSE ) { 
    660       exec('/bin/rm -rf '.$amp_conf['AMPWEBROOT'].'/admin/modules/'.$module); 
    661     } 
    662   } else { 
    663     echo "<script language=\"Javascript\">alert('"._("You cannot delete the Core module")."');</script>"; 
    664   } 
    665 } 
    666  
    667 function getThisModule($modname) { 
    668   $xmlinfo = getModuleXml(); 
    669   foreach($xmlinfo as $key => $mod) { 
    670     if (isset($mod['rawname']) && $mod['rawname'] == $modname)  
    671       return $mod; 
    672   } 
    673 } 
    674  
    675 function verifyAndInstall($filename) { 
    676   global $amp_conf; 
    677   system("tar zxf {$filename} --directory={$amp_conf['AMPWEBROOT']}/admin/modules/"); 
    678   return true; 
    679 } 
    680554?> 
    681555