Changeset 2643
- Timestamp:
- 10/04/06 01:49:29 (7 years ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
freepbx/trunk/amp_conf/htdocs/admin/common/mainstyle.css
r2106 r2643 289 289 display: none 290 290 } 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 14 14 require_once('featurecodes.class.php'); 15 15 require_once('components.class.php'); 16 17 define('MODULE_STATUS_NOTINSTALLED', 0); 18 define('MODULE_STATUS_DISABLED', 1); 19 define('MODULE_STATUS_ENABLED', 2); 20 define('MODULE_STATUS_NEEDUPGRADE', 3); 21 define('MODULE_STATUS_BROKEN', -1); 16 22 17 23 function parse_amportal_conf($filename) { … … 804 810 if(trim($tagData)) { 805 811 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; 807 813 } 808 814 else { … … 815 821 $this->arrOutput[count($this->arrOutput)-2]['children'][] = $this->arrOutput[count($this->arrOutput)-1]; 816 822 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); 817 863 } 818 864 } … … 823 869 class xml2ModuleArray extends xml2Array { 824 870 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 826 883 // if you are confused about what's happening below, uncomment this why we do it 827 884 // echo "<pre>"; print_r($arrOutput); echo "</pre>"; … … 1005 1062 */ 1006 1063 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 */ 1071 function 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 */ 1143 function 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 */ 1223 function 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 */ 1265 function 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 1334 function _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 */ 1358 function 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 1366 function module_enable($modulename) { // was enableModule 1367 } 1368 1369 function 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 */ 1380 function module_delete($modulename) { 1381 } 1382 1383 // runModuleSQL moved to functions.inc.php 1384 /* 1385 function 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 1413 function 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 * / 1424 function 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 1478 function 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 1491 function 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 1007 1505 function freepbx_log($section, $level, $message) { 1008 global $db;1009 global $debug; // This is used by retrieve_conf1010 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"; 1015 1513 } 1016 1514 ?> freepbx/trunk/amp_conf/htdocs/admin/page.modules.php
r2623 r2643 105 105 <div class="content"> 106 106 107 108 107 <?php 108 $modules_local = module_getinfo(); 109 110 $modules_online = module_getonlinexml(); 111 112 $modules = $modules_local + $modules_online; 113 114 function 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 } 123 uasort($modules, 'category_sort_callback'); 124 125 echo "<div id=\"modulelist\">\n"; 126 127 echo "\t<div id=\"modulelist-header\">"; 128 echo "\t\t<span class=\"modulename\">Module</span>\n"; 129 echo "\t\t<span class=\"moduletype\">Type</span>\n"; 130 echo "\t\t<span class=\"moduleversion\">Version</span>\n"; 131 echo "\t\t<span class=\"clear\"> </span>\n"; 132 echo "\t</div>"; 133 134 $category = false; 135 foreach (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\"> </span>\n"; 188 189 190 echo "\t\t</li>\n"; 191 } 192 echo "\t</ul></div>\n"; 193 echo "</div>"; 194 195 196 197 echo '<pre>'; 198 199 200 201 202 203 204 205 exit; 206 109 207 switch($extdisplay) { 110 208 case "online": … … 133 231 $installed = find_allmodules(); 134 232 // determine what modules are available 135 $online = getModuleXml();233 $online = module_getonlinexml(); 136 234 $dispMods = new displayModules($installed,$online); 137 235 echo $dispMods->drawModules(); … … 220 318 */ 221 319 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"; 227 321 $this->options = " 228 322 <select name=\"modaction\"> … … 233 327 "; 234 328 // 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); 238 330 } 239 331 … … 242 334 */ 243 335 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"; 249 337 $this->options = " 250 338 <select name=\"modaction\"> … … 255 343 "; 256 344 // 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); 260 346 } 261 347 … … 286 372 */ 287 373 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 = " 294 376 <select name=\"modaction\"> 295 377 <option value=\"upgrade\">"._("Upgrade Selected")." … … 298 380 "; 299 381 // 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); 303 383 } 304 384 … … 307 387 */ 308 388 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"; 314 390 $this->options = " 315 391 <select name=\"modaction\"> … … 321 397 "; 322 398 // 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); 326 400 } 327 401 … … 330 404 */ 331 405 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"; 337 407 $this->options = " 338 408 <select name=\"modaction\"> … … 344 414 "; 345 415 // 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); 349 417 } 350 418 … … 353 421 */ 354 422 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"; 360 424 $this->options = " 361 425 <select name=\"modaction\"> … … 366 430 "; 367 431 // 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); 371 433 } 372 434 373 435 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); 379 438 $this->options = " 380 439 <select name=\"modaction\"> … … 384 443 "; 385 444 // 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); 389 447 } 390 448 … … 423 481 } 424 482 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; 426 493 return <<< End_of_Html 427 494 … … 473 540 return $this->html; 474 541 } 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 } 475 552 } 476 553 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 xml484 // 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 through487 // 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)"; //debug497 } else {498 $fn = "http://mirror.freepbx.org/modules-".$matches[1].".xml";499 // echo "(From default)"; //debug500 }501 //$fn = "/usr/src/freepbx-modules/modules.xml";502 $data = file_get_contents($fn);503 // remove the old xml504 sql('DELETE FROM module_xml');505 // update the db with the new xml506 $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.php524 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 the534 // max ID available, and then insert it535 $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 dir590 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 redownload608 // every time. Otherwise theres no way to avoid a corrupt609 // download610 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)"; // debug618 } else {619 $url = "http://mirror.freepbx.org/modules/".$res['location'];620 // echo "(From default)"; // debug621 }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 XML631 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 }680 554 ?> 681 555
