root/freepbx/trunk/amp_conf/htdocs/admin/page.modules.php

Revision 1798, 16.9 kB (checked in by diego_iastrubni, 7 years ago)

use full path when installing modules

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 <?php /* $Id$ */
2
3 $extdisplay = isset($_REQUEST['extdisplay'])?$_REQUEST['extdisplay']:'';
4
5 if (isset($_POST['submit'])) { // if form has been submitted
6     switch ($_POST['modaction']) {
7         case "install":
8             if (runModuleSQL($_POST['modname'],$_POST['modaction']))
9                 installModule($_POST['modname'],$_POST['modversion']);
10             else
11                 echo "<div class=\"error\">"._("Module install script failed to run")."</div>";
12         break;
13         case "uninstall":
14             if (runModuleSQL($_POST['modname'],$_POST['modaction']))
15                 uninstallModule($_POST['modname']);
16             else
17                 echo "<div class=\"error\">"._("Module uninstall script failed to run")."</div>";
18             
19         break;
20         case "enable":
21             enableModule($_POST['modname']);
22             echo "<script language=\"Javascript\">document.location='".$_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING']."&foo=1'</script>";
23         break;
24         case "disable":
25             disableModule($_POST['modname']);
26             echo "<script language=\"Javascript\">document.location='".$_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING']."&foo=2'</script>";
27         break;
28         case "delete":
29             deleteModule($_POST['modname']);
30         break;
31         case "download":
32             fetchModule($_POST['rawname']);
33         break;
34         case "upgrade":
35             upgradeModule($_POST['modname']);
36         break;
37         case "rmmod":
38             rmModule($_POST['modname']);
39         break;
40     }
41 }
42 ?>
43
44 </div>
45 <!-- <div class="rnav">
46     <li><a id="<?php echo ($extdisplay=='' ? 'current':'') ?>" href="config.php?display=modules&type=tool&extdisplay="><?php echo _("Local Modules") ?></a></li>
47     <li><a id="<?php echo ($extdisplay=='online' ? 'current':'') ?>" href="config.php?display=modules&type=tool&extdisplay=online"><?php echo _("Online Modules") ?></a></li>
48 </div>
49 -->
50 <div class="content">
51
52
53 <?php
54 switch($extdisplay) {
55     case "online":
56         echo "<h2>";
57         echo _("Online Modules");
58         echo "</h2>";
59         echo "<h3><a href='config.php?display=modules&type=tool&extdisplay=local'>"._("Local Modules")."</a></h3>\n";
60         // determine which modules we have installed already
61         $installed = find_allmodules();
62         // determine what modules are available
63         $online = getModuleXml();
64         $dispMods = new displayModules($installed,$online);
65         echo $dispMods->drawModules();
66     break;
67     default:
68         echo "<h2>";
69         echo _("Local Module Administration");
70         echo "</h2>";
71         echo "<h3><a href='config.php?display=modules&type=tool&extdisplay=online'>"._("Online Modules")."</a></h3>\n";
72         $installed = find_allmodules();
73         $dispMods = new displayModules($installed);
74         echo $dispMods->drawModules();
75
76     break;
77 }
78 ?>
79
80 <?php
81
82 /* BEGIN FUNCTIONS */
83
84 /* displays table of modules provided in the passed array
85  * If displaying online modules, pass that array as the second arg
86 */
87
88 class displayModules {
89     var $html;
90     //constructor
91     function displayModules($installed,$online=false) {
92         // So, we have an array with several:
93     /*
94         [phpinfo] => Array
95             (
96                 [displayName] => PHP Info
97                 [version] => 1.0
98                 [type] => tool
99                 [category] => Basic
100                 [info] => http://www.freepbx.org/wikiPage
101                 [items] => Array
102                     (
103                         [PHPINFO] => PHP Info
104                         [PHPINFO2] => PHP Info2
105                     )
106     
107                 [requirements] => Array
108                     (
109                         [FILE] => /usr/sbin/asterisk
110                         [MODULE] => core
111                     )
112     
113             )
114     */
115     
116         // if we are displaying online modules, determine which are installed
117         if($online) {
118             
119             $online = $this->sortModules($online);
120             foreach(array_keys($online) as $arrkey) {
121             
122                 if (!is_array($installed))
123                 {
124                     continue;
125                 }
126                     
127                 // Determine if module is already local
128                 if(array_key_exists($arrkey,$installed)) {
129                     //check if online version is newer
130                     $newversion = $online[$arrkey]['version'];
131                     $oldversion = $installed[$arrkey]['version'];
132                     // version_compare returns 1 if new > old
133                     if (version_compare($newversion,$oldversion) == 1) {
134                         $status = "Local (update available)";
135                         $action = "
136                         <form action={$_SERVER['PHP_SELF']}?{$_SERVER['QUERY_STRING']} method=post>
137                             <input type=hidden name=modaction value=download>
138                             <input type=hidden name=rawname value={$online[$arrkey]['rawname']}>
139                             <input type=submit name=submit value=Download>
140                         </form>
141                         ";
142                     } else {
143                         $status = "Local (up to date)";
144                         $action = "";
145                     }
146                 } else {
147                     $status = "Online";
148                     $action = "
149                     <form action={$_SERVER['PHP_SELF']}?{$_SERVER['QUERY_STRING']} method=post>
150                         <input type=hidden name=modaction value=download>
151                         <input type=hidden name=rawname value={$online[$arrkey]['rawname']}>
152                         <input type=submit name=submit value=Download>
153                     </form>
154                     ";
155                 }
156                 
157                 $this->html .= $this->tableHtml($online[$arrkey],$status,$action);
158             }
159             
160         } else {    //local modules
161             
162             $installed = $this->sortModules($installed);
163             if (isset($installed) && is_array($installed)) {
164                 foreach($installed as $key => $mod) {
165                     //dynamicatlly create a form based on status
166                     if ($mod['status'] == 0) {
167                         $status = _("Not Installed");
168                         //install form
169                         $action = "<form method=\"POST\" action=\"{$_SERVER['REQUEST_URI']}\" style=display:inline>";
170                         $action .= "<input type=\"hidden\" name=\"modname\" value=\"{$key}\">";
171                         $action .= "<input type=\"hidden\" name=\"modversion\" value=\"{$mod['version']}\">";
172                         $action .= "<input type=\"hidden\" name=\"modaction\" value=\"install\">";
173                         $action .= "<input type=\"submit\" name=\"submit\" value=\""._("Install")."\">";
174                         $action .= "</form>";
175                         $action .= "<form method=\"POST\" action=\"{$_SERVER['REQUEST_URI']}\" style=display:inline>";
176                         $action .= "<input type=\"hidden\" name=\"modname\" value=\"{$key}\">";
177                         $action .= "<input type=\"hidden\" name=\"modversion\" value=\"{$mod['version']}\">";
178                         $action .= "<input type=\"hidden\" name=\"modaction\" value=\"rmmod\">";
179                         $action .= "<input type=\"submit\" name=\"submit\" value=\""._("Remove")."\">";
180                         $action .= "</form>";
181                     } else if($mod['status'] == 1){
182                         $status = _("Disabled");
183                         //enable form
184                         $action = "<form method=\"POST\" action=\"{$_SERVER['REQUEST_URI']}\" style=display:inline>";
185                         $action .= "<input type=\"hidden\" name=\"modname\" value=\"{$key}\">";
186                         $action .= "<input type=\"hidden\" name=\"modaction\" value=\"enable\">";
187                         $action .= "<input type=\"submit\" name=\"submit\" value=\""._("Enable")."\">";
188                         $action .= "</form>";
189                         //uninstall form
190                         $action .= "<form method=\"POST\" action=\"{$_SERVER['REQUEST_URI']}\" style=display:inline>";
191                         $action .= "<input type=\"hidden\" name=\"modname\" value=\"{$key}\">";
192                         $action .= "<input type=\"hidden\" name=\"modaction\" value=\"uninstall\">";
193                         $action .= "<input type=\"submit\" name=\"submit\" value=\""._("Uninstall")."\">";
194                         $action .= "</form>";
195                         
196                     } else if($mod['status'] == 2){
197                         $status = _("Enabled");
198                         //disable form
199                         $action = "<form method=\"POST\" action=\"{$_SERVER['REQUEST_URI']}\" style=display:inline>";
200                         $action .= "<input type=\"hidden\" name=\"modname\" value=\"{$key}\">";
201                         $action .= "<input type=\"hidden\" name=\"modaction\" value=\"disable\">";
202                         $action .= "<input type=\"submit\" name=\"submit\" value=\""._("Disable")."\">";
203                         $action .= "</form>";
204                     } else if($mod['status'] == 3){
205                         $status = _("Enabled (needs update)");
206                         //disable form
207                         $action = "<form method=\"POST\" action=\"{$_SERVER['REQUEST_URI']}\" style=display:inline>";
208                         $action .= "<input type=\"hidden\" name=\"modname\" value=\"{$key}\">";
209                         $action .= "<input type=\"hidden\" name=\"modaction\" value=\"disable\">";
210                         $action .= "<input type=\"submit\" name=\"submit\" value=\""._("Disable")."\">";
211                         $action .= "</form>";
212                         //upgrade form
213                         $action .= "<form method=\"POST\" action=\"{$_SERVER['REQUEST_URI']}\" style=display:inline>";
214                         $action .= "<input type=\"hidden\" name=\"modname\" value=\"{$key}\">";
215                         $action .= "<input type=\"hidden\" name=\"modversion\" value=\"{$mod['version']}\">";
216                         $action .= "<input type=\"hidden\" name=\"modaction\" value=\"upgrade\">";
217                         $action .= "<input type=\"submit\" name=\"submit\" value=\""._("Update")."\">";
218                         $action .= "</form>";
219                     } else if($mod['status'] == -1){
220                         $status = _("Broken");
221                         //disable form
222                         $action = "<form method=\"POST\" action=\"{$_SERVER['REQUEST_URI']}\" style=display:inline>";
223                         $action .= "<input type=\"hidden\" name=\"modname\" value=\"{$key}\">";
224                         $action .= "<input type=\"hidden\" name=\"modaction\" value=\"delete\">";
225                         $action .= "<input type=\"submit\" name=\"submit\" value=\""._("Delete")."\">";
226                         $action .= "</form>";
227                     }
228                     $this->html .= $this->tableHtml($mod,$status,$action);
229                 }
230             }
231         }
232     }
233     
234     //sorts the modules by category
235     function sortModules($array) {
236         if (isset($array) && is_array($array)) {
237             foreach($array as $key => $mod) {
238                 // sort the list in category / displayName order
239                 // this is the only way i know how to do this...surely there is another way?
240                 
241                 // fields for sort
242                 $displayName = isset($mod['displayName']) ? $mod['displayName'] : 'unknown';
243                 $category = isset($mod['category']) ? $mod['category'] : 'unknown';   
244                 // we want to sort on this so make it first in the new array
245                 $newallmods[$key]['asort'] = $category.$displayName;
246             
247                 // copy the rest of the array
248                 $newallmods[$key]['displayName'] = $displayName;
249                 $newallmods[$key]['category'] = $category;
250                 $newallmods[$key]['rawname'] = $mod['rawname'];
251                 $newallmods[$key]['info'] = $mod['info'];
252                 $newallmods[$key]['location'] = $mod['location'];
253                 $newallmods[$key]['version'] = isset($mod['version']) ? $mod['version'] : 'unknown';
254                 $newallmods[$key]['type'] = isset($mod['type']) ? $mod['type'] : 'unknown';
255                 $newallmods[$key]['status'] = isset($mod['status']) ? $mod['status'] : 0;
256                 
257                 asort($newallmods);   
258             }
259             return $newallmods;
260         }
261     }
262     
263     function tableHtml($arrRow,$status,$action) {
264         return <<< End_of_Html
265             
266             <tr>
267                 <td><a target=_BLANK href={$arrRow['info']}>{$arrRow['displayName']} ({$arrRow['rawname']})</a></td>
268                 <td>{$arrRow['version']}</td>
269                 <td>{$arrRow['type']}</td>
270                 <td>{$arrRow['category']}</td>
271                 <td>{$status}</td>
272                 <td>{$action}</td>
273             </tr>
274             
275 End_of_Html;
276     }
277     
278     function drawModules() {
279         $table = "<table border=1><tr><th>". _("Module")."</th><th>". _("Version")."</th><th>". _("Type") ."</th><th>". _("Category") ."</th><th>". _("Status") ."</th><th>". _("Action") ."</th></tr>";
280         $table .= $this->html;
281           $table .= "</table>";
282         return $table;
283     }
284 }
285
286 function getModuleXml() {
287     //this should be in an upgrade file ... putting here for now.
288     sql('CREATE TABLE IF NOT EXISTS module_xml (time INT NOT NULL , data BLOB NOT NULL) TYPE = MYISAM ;');
289     
290     $result = sql('SELECT * FROM module_xml','getRow',DB_FETCHMODE_ASSOC);
291     // if the epoch in the db is more than 2 hours old, or the xml is less than 100 bytes, then regrab xml
292     // Changed to 5 minutes while not in release. Change back for released version.
293     if((time() - $result['time']) > 300 || strlen($result['data']) < 100 ) {
294         $version = getversion();
295         $version = $version[0][0];
296         // we need to know the freepbx major version we have running (ie: 2.1.2 is 2.1)
297         preg_match('/(\d+\.\d+)/',$version,$matches);
298         //echo "the result is ".$matches[1];
299         $fn = "http://amportal.sourceforge.net/modules-".$matches[1].".xml";
300         //$fn = "/usr/src/freepbx-modules/modules.xml";
301         $data = file_get_contents($fn);
302         // remove the old xml
303         sql('DELETE FROM module_xml');
304         // update the db with the new xml
305         $data4sql = (get_magic_quotes_gpc() ? $data : addslashes($data));
306         sql('INSERT INTO module_xml (time,data) VALUES ('.time().',"'.$data4sql.'")');
307     } else {
308 //        echo "using cache";
309         $data = $result['data'];
310     }
311     //echo time() - $result['time'];
312     $parser = new xml2ModuleArray($data);
313     $xmlarray = $parser->parseModulesXML($data);
314     //$modules = $xmlarray['XML']['MODULE'];
315     
316     //echo "<hr>Raw XML Data<pre>"; print_r(htmlentities($data)); echo "</pre>";
317     //echo "<hr>XML2ARRAY<pre>"; print_r($xmlarray); echo "</pre>";
318     
319     return $xmlarray;
320 }
321
322 // executes the SQL found in a module install.sql or uninstall.sql
323 function runModuleSQL($moddir,$type){
324     global $db;
325     global $amp_conf;
326     $data='';
327     $retval = false;
328     // if there is an sql file, run it
329     if (is_file("{$amp_conf['AMPWEBROOT']}/modules/{$moddir}/{$type}.sql")) {
330         // run sql script
331         $fd = fopen("{$amp_conf['AMPWEBROOT']}/modules/{$moddir}/{$type}.sql","r");
332         while (!feof($fd)) {
333             $data .= fread($fd, 1024);
334         }
335         fclose($fd);
336
337         preg_match_all("/((SELECT|INSERT|UPDATE|DELETE|CREATE|DROP).*);\s*\n/Us", $data, $matches);
338         
339         foreach ($matches[1] as $sql) {
340                 $result = $db->query($sql);
341                 if(DB::IsError($result)) {     
342                     return false;
343                 }
344         }
345         $retval = true;
346     }
347     
348     // if there is a php file, run it
349     if (is_file("{$amp_conf['AMPWEBROOT']}/modules/{$moddir}/{$type}.php")) {
350         include("{$amp_conf['AMPWEBROOT']}/modules/{$moddir}/{$type}.php");
351         $retval = true;
352     }
353     
354     return true;
355 }
356
357 function installModule($modname,$modversion)
358 {
359     global $db;
360     global $amp_conf;
361     
362     switch ($amp_conf["AMPDBENGINE"])
363     {
364         case "sqlite":
365             // to support sqlite2, we are not using autoincrement. we need to find the
366             // max ID available, and then insert it
367             $sql = "SELECT max(id) FROM modules;";
368             $results = $db->getRow($sql);
369             $new_id = $results[0];
370             $new_id ++;
371             $sql = "INSERT INTO modules (id,modulename, version,enabled) values ('{$new_id}','{$modname}','{$modversion}','0' );";
372             break;
373         
374         default:
375             $sql = "INSERT INTO modules (modulename, version) values ('{$modname}','{$modversion}');";
376         break;
377     }
378
379     $results = $db->query($sql);
380     if(DB::IsError($results)) {
381         die($results->getMessage());
382     }
383 }
384
385 function uninstallModule($modname) {
386     global $db;
387     $sql = "DELETE FROM modules WHERE modulename = '{$modname}'";
388     $results = $db->query($sql);
389     if(DB::IsError($results)) {
390         die($results->getMessage());
391     }
392 }
393
394 function enableModule($modname) {
395     global $db;
396     $sql = "UPDATE modules SET enabled = 1 WHERE modulename = '{$modname}'";
397     $results = $db->query($sql);
398     if(DB::IsError($results)) {
399         die($results->getMessage());
400     }
401 }
402
403 function disableModule($modname) {
404     global $db;
405     $sql = "UPDATE modules SET enabled = 0 WHERE modulename = '{$modname}'";
406     $results = $db->query($sql);
407     if(DB::IsError($results)) {
408         die($results->getMessage());
409     }
410 }
411
412 function deleteModule($modname) {
413     global $db;
414     $sql = "DELETE FROM modules WHERE modulename = '{$modname}' LIMIT 1";
415     $results = $db->query($sql);
416     if(DB::IsError($results)) {
417         die($results->getMessage());
418     }
419 }
420
421 //downloads a module, and extracts it into the module dir
422 function fetchModule($name) {
423     global $amp_conf;
424     $res = getThisModule($name);
425     if (!isset($res)) {
426         echo "<div class=\"error\">"._("Unaware of module")." {$name}</div>";
427         return false;
428     }
429     $file = basename($res['location']);
430     $filename = $amp_conf['AMPWEBROOT']."/admin/modules/_cache/".$file;
431     if(file_exists($filename)) {
432         // We might already have it! Let's check the MD5.
433         $filedata = "";
434         $fh = @fopen($filename, "r");
435         while (!feof($fh)) {
436             $filedata .= fread($fh, 8192);
437         }
438         if (isset($res['md5sum']) && $res['md5sum'] == md5 ($filedata)) {
439             // Note, if there's no MD5 information, it will redownload
440             // every time. Otherwise theres no way to avoid a corrupt
441             // download
442             return verifyAndInstall($filename);
443         } else {
444             unlink($filename);
445         }
446     }
447     $url = "https://svn.sourceforge.net/svnroot/amportal/modules/".$res['location'];
448     $fp = @fopen($filename,"w");
449     $filedata = file_get_contents($url);
450     fwrite($fp,$filedata);
451     fclose($fp);
452     if (is_readable($filename) !== TRUE ) {
453         echo "<div class=\"error\">"._("Unable to save")." {$filename} - Check file/directory permissions</div>";
454         return false;
455     }
456     // Check the MD5 info against what's in the module's XML
457     if (!isset($res['md5sum']) || empty($res['md5sum'])) {
458         echo "<div class=\"error\">"._("Unable to Locate Integrity information for")." {$filename} - "._("Continuing Anyway")."</div>";
459     } elseif ($res['md5sum'] != md5 ($filedata)) {
460         echo "<div class=\"error\">"._("File Integrity FAILED for")." {$filename} - "._("Aborting")."</div>";
461         unlink($filename);
462         return false;
463     }
464     // verifyAndInstall does the untar, and will do the signed-package check.
465     return verifyAndInstall($filename);
466
467 }
468
469 function upgradeModule($module, $allmods = NULL) {
470     if($allmods === NULL)
471         $allmods = find_allmodules();
472     // the install.php can set this to false if the upgrade fails.
473     $success = true;
474     if(is_file("modules/$module/install.php"))
475         include "modules/$module/install.php";
476     if ($success) {
477         sql('UPDATE modules SET version = "'.$allmods[$module]['version'].'" WHERE modulename = "'.$module.'"');
478         needreload();
479     }
480 }
481
482 function rmModule($module) {
483     global $amp_conf;
484     if (is_dir($amp_conf['AMPWEBROOT'].'/admin/modules/'.$module) && strstr($module, '.') === FALSE ) {
485         exec('/bin/rm -rf '.$amp_conf['AMPWEBROOT'].'/admin/modules/'.$module);
486     }
487 }
488
489 function getThisModule($modname) {
490     $xmlinfo = getModuleXml();
491     foreach($xmlinfo as $key => $mod) {
492         if (isset($mod['rawname']) && $mod['rawname'] == $modname)
493             return $mod;
494     }
495 }
496
497 function verifyAndInstall($filename) {
498     global $amp_conf;
499     system("tar zxf {$filename} --directory={$amp_conf['AMPWEBROOT']}/admin/modules/");
500     return true;
501 }
502 ?>
503
504
Note: See TracBrowser for help on using the browser.