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

Revision 1371, 12.0 kB (checked in by rcourtna, 7 years ago)

Online modules will now be properly downloaded from SVN, and unarchived into FreePBX's module directory. It actually works folks! Give it a try, there is a "phpinfo" module to test with.

  • 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         break;
19         case "enable":
20             enableModule($_POST['modname']);
21             echo "<script language=\"Javascript\">document.location='".$_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING']."'</script>";
22         break;
23         case "disable":
24             disableModule($_POST['modname']);
25             echo "<script language=\"Javascript\">document.location='".$_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING']."'</script>";
26         break;
27         case "download":
28             fetchModule($_POST['location']);
29             //echo "<script language=\"Javascript\">document.location='".$_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING']."'</script>";
30         break;
31     }
32 }
33 ?>
34
35 </div>
36 <div class="rnav">
37     <li><a id="<?php echo ($extdisplay=='' ? 'current':'') ?>" href="config.php?display=modules&type=tool&extdisplay="><?php echo _("Local Modules") ?></a></li>
38     <li><a id="<?php echo ($extdisplay=='online' ? 'current':'') ?>" href="config.php?display=modules&type=tool&extdisplay=online"><?php echo _("Online Modules") ?></a></li>
39 </div>
40 <div class="content">
41
42 <?php
43 switch($extdisplay) {
44     case "online": ?>
45         <h2><?php echo _("Online Modules")?></h2>
46         <table border="1" >
47 <tr>
48     <th><?php echo _("Module")?></th><th><?php echo _("Category")?></th><th><?php echo _("Version")?></th><th><?php echo _("Author")?></th><th><?php echo _("Status")?></th><th><?php echo _("Action")?></th>
49 </tr>
50 <?php
51         // determine which modules we have installed already
52         $installed = find_allmodules();
53         $modules = getModuleXml();
54         if (is_array($modules)) {
55             foreach ($modules as $module)
56                 displayModule($module,$installed);
57         } else {
58             displayModule($modules,$installed);
59         }
60     break;
61     default: ?>
62         <h2><?php echo _("Local Module Administration")?></h2>
63         <table border="1" >
64 <tr>
65     <th><?php echo _("Module")?></th><th><?php echo _("Category")?></th><th><?php echo _("Version")?></th><th><?php echo _("Type")?></th><th><?php echo _("Status")?></th><th><?php echo _("Action")?></th>
66 </tr>
67 <?php
68         $allmods = find_allmodules();
69         foreach($allmods as $key => $mod) {
70             // sort the list in category / displayName order
71             // this is the only way i know how to do this...surely there is another way?
72             
73             // fields for sort
74             $displayName = isset($mod['displayName']) ? $mod['displayName'] : 'unknown';
75             $category = isset($mod['category']) ? $mod['category'] : 'unknown';   
76             // we want to sort on this so make it first in the new array
77             $newallmods[$key]['asort'] = $category.$displayName;
78         
79             // copy the rest of the array
80             $newallmods[$key]['displayName'] = $displayName;
81             $newallmods[$key]['category'] = $category;
82             $newallmods[$key]['version'] = isset($mod['version']) ? $mod['version'] : 'unknown';
83             $newallmods[$key]['type'] = isset($mod['type']) ? $mod['type'] : 'unknown';
84             $newallmods[$key]['status'] = isset($mod['status']) ? $mod['status'] : 0;
85             
86             asort($newallmods);   
87         }
88         foreach($newallmods as $key => $mod) {
89             
90             //dynamicatlly create a form based on status
91             if ($mod['status'] == 0) {
92                 $status = _("Not Installed");
93                 //install form
94                 $action = "<form method=\"POST\" action=\"{$_SERVER['REQUEST_URI']}\" style=display:inline>";
95                 $action .= "<input type=\"hidden\" name=\"modname\" value=\"{$key}\">";
96                 $action .= "<input type=\"hidden\" name=\"modversion\" value=\"{$mod['version']}\">";
97                 $action .= "<input type=\"hidden\" name=\"modaction\" value=\"install\">";
98                 $action .= "<input type=\"submit\" name=\"submit\" value=\""._("Install")."\">";
99                 $action .= "</form>";
100             } else if($mod['status'] == 1){
101                 $status = _("Disabled");
102                 //enable form
103                 $action = "<form method=\"POST\" action=\"{$_SERVER['REQUEST_URI']}\" style=display:inline>";
104                 $action .= "<input type=\"hidden\" name=\"modname\" value=\"{$key}\">";
105                 $action .= "<input type=\"hidden\" name=\"modaction\" value=\"enable\">";
106                 $action .= "<input type=\"submit\" name=\"submit\" value=\""._("Enable")."\">";
107                 $action .= "</form>";
108                 //uninstall form
109                 $action .= "<form method=\"POST\" action=\"{$_SERVER['REQUEST_URI']}\" style=display:inline>";
110                 $action .= "<input type=\"hidden\" name=\"modname\" value=\"{$key}\">";
111                 $action .= "<input type=\"hidden\" name=\"modaction\" value=\"uninstall\">";
112                 $action .= "<input type=\"submit\" name=\"submit\" value=\""._("Uninstall")."\">";
113                 $action .= "</form>";
114                 
115             } else if($mod['status'] == 2){
116                 $status = _("Enabled");
117                 //disable form
118                 $action = "<form method=\"POST\" action=\"{$_SERVER['REQUEST_URI']}\" style=display:inline>";
119                 $action .= "<input type=\"hidden\" name=\"modname\" value=\"{$key}\">";
120                 $action .= "<input type=\"hidden\" name=\"modaction\" value=\"disable\">";
121                 $action .= "<input type=\"submit\" name=\"submit\" value=\""._("Disable")."\">";
122                 $action .= "</form>";
123             }
124             
125             echo "<tr>";
126             echo "<td>";
127             echo _($mod['displayName']);
128             echo "</td>";
129             echo "<td>";
130             echo $mod['category'];
131             echo "</td>";
132             echo "<td>";
133             echo $mod['version'];
134             echo "</td>";
135             echo "<td>";
136             echo _($mod['type']);
137             echo "</td>";
138             echo "<td>";
139             echo $status;
140             echo "</td>";
141             echo "<td>";
142             echo $action;
143             echo "</td>";
144             echo "</tr>";
145         }
146     break;
147 }
148 ?>
149
150 </table>
151
152 <?php
153
154 /* BEGIN FUNCTIONS */
155
156 function displayModule($arr,$installed) {
157     // So, we have an array with:
158     // [RAWNAME] => testmodule
159      // [TYPE] => testing
160     // [NAME] => Test Module
161     // [AUTHOR] => Rob Thomas
162     // [EMAIL] => xrobau@gmail.com
163     // [VERSION] => 1.0
164     // [REQUIREMENTS] => Array
165     //     (
166     //    [MODULE] => recordings
167     //     [PRODUCT] => asterisk-sounds
168     //     [FILE] => /bin/sh
169     //     /)
170     // [LOCATION] => trunk/testing/test-1.0.tgz
171     
172     // Determine module status
173     if(array_key_exists($arr['RAWNAME'],$installed)) {
174         $status = "Local";
175         $action = "";
176     } else {
177         $status = "Online";
178         $action = "
179         <form action={$_SERVER['PHP_SELF']}?{$_SERVER['QUERY_STRING']} method=post>
180             <input type=hidden name=modaction value=download>
181             <input type=hidden name=location value={$arr['LOCATION']}>
182             <input type=submit name=submit value=Download>
183         </form>
184         ";
185     }
186
187     // build author string/link
188     if (isset($arr['EMAIL']))
189         $email = "<a href=\"mailto:".$arr['EMAIL']."\">".$arr['AUTHOR']."</a>";
190     else
191         $email = $arr['AUTHOR'];
192         
193     print <<< End_of_Html
194     
195     <tr>
196         <td>{$arr['NAME']} ({$arr['RAWNAME']})</td>
197         <td>{$arr['TYPE']}</td>
198         <td>{$arr['VERSION']}</td>
199         <td>{$email}</td>
200         <td>{$status}</td>
201         <td>{$action}</td>
202     </tr>
203     
204 End_of_Html;
205 }
206
207 function getModuleXml() {
208     //this should be in an upgrade file ... putting here for now.
209     sql('CREATE TABLE IF NOT EXISTS module_xml (time INT NOT NULL , data BLOB NOT NULL) TYPE = MYISAM ;');
210     
211     $result = sql('SELECT * FROM module_xml','getRow',DB_FETCHMODE_ASSOC);
212     // if the epoch in the db is more than 10 minutes old, then regrab xml
213     if((time() - $result['time']) > 600) {
214         $fn = "http://svn.sourceforge.net/svnroot/amportal/modules/trunk/modules.xml";
215         $data = file_get_contents($fn);
216         // remove the old xml
217         sql('DELETE FROM module_xml');
218         // update the db with the new xml
219         sql('INSERT INTO module_xml (time,data) VALUES ('.time().',"'.$data.'")');
220     } else {
221         echo "using cache";
222         $data = $result['data'];
223     }
224     //echo time() - $result['time'];
225     $parser = new xml2array($data);
226     $xmlarray = $parser->parseXMLintoarray($data);
227     $modules = $xmlarray['XML']['MODULE'];
228     $debug=false;
229     if($debug) {
230         echo "<pre>";
231         print_r($modules);
232         echo "</pre>";
233     }
234     return $modules;
235 }
236
237 // executes the SQL found in a module install.sql or uninstall.sql
238 function runModuleSQL($moddir,$type){
239     global $db;
240     $data='';
241     if (is_file("modules/{$moddir}/{$type}.sql")) {
242         // run sql script
243         $fd = fopen("modules/{$moddir}/{$type}.sql","r");
244         while (!feof($fd)) {
245             $data .= fread($fd, 1024);
246         }
247         fclose($fd);
248
249         preg_match_all("/((SELECT|INSERT|UPDATE|DELETE|CREATE|DROP).*);\s*\n/Us", $data, $matches);
250         
251         foreach ($matches[1] as $sql) {
252                 $result = $db->query($sql);
253                 if(DB::IsError($result)) {     
254                     return false;
255                 }
256         }
257         return true;
258     }
259         return true;
260 }
261
262 function installModule($modname,$modversion)
263 {
264     global $db;
265     global $amp_conf;
266     
267     switch ($amp_conf["AMPDBENGINE"])
268     {
269         case "sqlite":
270             // to support sqlite2, we are not using autoincrement. we need to find the
271             // max ID available, and then insert it
272             $sql = "SELECT max(id) FROM modules;";
273             $results = $db->getRow($sql);
274             $new_id = $results[0];
275             $new_id ++;
276             $sql = "INSERT INTO modules (id,modulename, version,enabled) values ('{$new_id}','{$modname}','{$modversion}','0' );";
277             break;
278         
279         default:
280             $sql = "INSERT INTO modules (modulename, version) values ('{$modname}','{$modversion}');";
281             break;
282     }
283
284     $results = $db->query($sql);
285     if(DB::IsError($results)) {
286         die($results->getMessage());
287     }
288 }
289
290 function uninstallModule($modname) {
291     global $db;
292     $sql = "DELETE FROM modules WHERE modulename = '{$modname}'";
293     $results = $db->query($sql);
294     if(DB::IsError($results)) {
295         die($results->getMessage());
296     }
297 }
298
299 function enableModule($modname) {
300     global $db;
301     $sql = "UPDATE modules SET enabled = 1 WHERE modulename = '{$modname}'";
302     $results = $db->query($sql);
303     if(DB::IsError($results)) {
304         die($results->getMessage());
305     }
306 }
307
308 function disableModule($modname) {
309     global $db;
310     $sql = "UPDATE modules SET enabled = 0 WHERE modulename = '{$modname}'";
311     $results = $db->query($sql);
312     if(DB::IsError($results)) {
313         die($results->getMessage());
314     }
315 }
316
317 # Test parser to import the XML file from sourceforge.
318 # Rob Thomas <xrobau@gmail.com>
319 # Released under GPL V2.
320 class xml2array{
321
322    function parseXMLintoarray ($xmldata){ // starts the process and returns the final array
323      $xmlparser = xml_parser_create();
324      xml_parse_into_struct($xmlparser, $xmldata, $arraydat);
325      xml_parser_free($xmlparser);
326      $semicomplete = $this->subdivide($arraydat);
327      $complete = $this->correctentries($semicomplete);
328      return $complete;
329    }
330  
331    function subdivide ($dataarray, $level = 1){
332      foreach ($dataarray as $key => $dat){
333        if ($dat['level'] === $level && $dat['type'] === "open"){
334          $toplvltag = $dat['tag'];
335        } elseif ($dat['level'] === $level && $dat['type'] === "close" && $dat['tag']=== $toplvltag){
336          $newarray[$toplvltag][] = $this->subdivide($temparray,($level +1));
337          unset($temparray,$nextlvl);
338        } elseif ($dat['level'] === $level && $dat['type'] === "complete"){
339          $newarray[$dat['tag']]=$dat['value'];
340        } elseif ($dat['type'] === "complete"||$dat['type'] === "close"||$dat['type'] === "open"){
341          $temparray[]=$dat;
342        }
343      }
344      return $newarray;
345    }
346       
347     function correctentries($dataarray){
348         if (is_array($dataarray)){
349           $keys array_keys($dataarray);
350           if (count($keys)== 1 && is_int($keys[0])){
351            $tmp = $dataarray[0];
352            unset($dataarray[0]);
353                $dataarray = $tmp;
354           }
355           $keys2 = array_keys($dataarray);
356           foreach($keys2 as $key){
357            $tmp2 = $dataarray[$key];
358            unset($dataarray[$key]);
359            $dataarray[$key] = $this->correctentries($tmp2);
360            unset($tmp2);
361           }
362         }
363         return $dataarray;
364     }
365 }
366
367 //downloads a module, and extracts it into the module dir
368 function fetchModule($location) {
369     global $amp_conf;
370     $file = basename($location);
371     $url = "https://svn.sourceforge.net/svnroot/amportal/modules/trunk/".$location;
372     //save the file to /tmp
373     $filename = "/tmp/".$file;
374     $fp = @fopen($filename,"w");
375     fwrite($fp,file_get_contents($url));
376     fclose($fp);
377     if(!file_exists($filename)) {
378         echo "<div class=\"error\">"._("Unable to save")." {$filename}</div>";
379         return false;
380     }
381     // unarchive the module to the modules dir
382     system("tar zxf {$filename} --directory={$amp_conf['AMPWEBROOT']}/admin/modules/");
383     unlink($filename);
384     return true;
385 }
386
387 ?>
Note: See TracBrowser for help on using the browser.