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

Revision 12517, 44.7 kB (checked in by mbrevda, 2 years ago)

re #5342 - flush the buffer without ending it, seems to work better with safari

  • Property svn:mime-type set to text/html
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 <?php /* $Id$ */
2
3 /** Controls if online module and install/uninstall options are available.
4  * This is meant for when using external packaging systems (eg, deb or rpm) to manage
5  * modules. Package maintainers should set AMPEXTERNPACKAGES to true in /etc/amportal.conf.
6  * Optionally, the other way is to remove the below lines, and instead just define
7  * EXTERNAL_PACKAGE_MANAGEMENT as 1. This prevents changing the setting from amportal.conf.
8  */
9 if (!isset($amp_conf['AMPEXTERNPACKAGES']) || ($amp_conf['AMPEXTERNPACKAGES'] != 'true')) {
10   define('EXTERNAL_PACKAGE_MANAGEMENT', 0);
11 } else {
12   define('EXTERNAL_PACKAGE_MANAGEMENT', 1);
13 }
14
15 $extdisplay = isset($_REQUEST['extdisplay'])?$_REQUEST['extdisplay']:'';
16 $repo = $amp_conf['MODULE_REPO'];
17
18 global $active_repos;
19 if (isset($_REQUEST['check_online'])) {
20   $online = 1;
21   $active_repos = $_REQUEST['active_repos'];
22   module_set_active_repos($active_repos);
23 } else {
24   $online = (isset($_REQUEST['online']) && $_REQUEST['online'] && !EXTERNAL_PACKAGE_MANAGEMENT) ? 1 : 0;
25   $active_repos = module_get_active_repos();
26 }
27
28 // fix php errors from undefined variable. Not sure if we can just change the reference below to use
29 // online since it changes values so just setting to what we decided it is here.
30
31 $moduleaction = isset($_REQUEST['moduleaction'])?$_REQUEST['moduleaction']:false;
32 /*
33   moduleaction is an array with the key as the module name, and possible values:
34  
35   downloadinstall - download and install (used when a module is not locally installed)
36   upgrade - download and install (used when a module is locally installed)
37   install - install/upgrade locally available module
38   enable - enable local module
39   disable - disable local module
40   uninstall - uninstall local module
41 */
42
43 $freepbx_version = get_framework_version();
44 $freepbx_version = $freepbx_version ? $freepbx_version : getversion();
45 $freepbx_help_url = "http://www.freepbx.org/freepbx-help-system?freepbx_version=".urlencode($freepbx_version);
46
47 if (!$quietmode) {
48   ?>
49   <script type="text/javascript">
50   $(document).ready(function(){
51     $('.repo_boxes').find('input[type=checkbox]').button()
52   })
53   function toggleInfoPane(pane) {
54     var style = document.getElementById(pane).style;
55     if (style.display == 'none' || style.display == '') {
56       style.display = 'block';
57     } else {
58       style.display = 'none';
59     }
60   }
61   function check_upgrade_all() {
62     var re = /^moduleaction\[([a-z0-9_\-]+)\]$/;
63     for(i=0; i<document.modulesGUI.elements.length; i++) {
64       if (document.modulesGUI.elements[i].value == 'upgrade') {
65         if (match = document.modulesGUI.elements[i].name.match(re)) {
66           // check the box
67           document.modulesGUI.elements[i].checked = true;
68           // expand info pane
69           document.getElementById('infopane_'+match[1]).style.display = 'block';
70         }
71       }
72     }
73   }
74   function check_download_all() {
75     var re = /^moduleaction\[([a-z0-9_\-]+)\]$/;
76     for(i=0; i<document.modulesGUI.elements.length; i++) {
77       if (document.modulesGUI.elements[i].value == 'downloadinstall') {
78         if (match = document.modulesGUI.elements[i].name.match(re)) {
79           // check the box
80           document.modulesGUI.elements[i].checked = true;
81           // expand info pane
82           document.getElementById('infopane_'+match[1]).style.display = 'block';
83         }
84       }
85     }
86   }
87   function showhide_upgrades() {
88     var upgradesonly = document.getElementById('show_upgradable_only').checked;
89     var module_re = /^module_([a-z0-9_]+)$/;   // regex to match a module element id
90     var cat_re = /^category_([a-zA-Z0-9_]+)$/; // regex to match a category element id
91     var elements = document.getElementById('modulelist').getElementsByTagName('li');
92     // loop through all modules, check if there is an upgrade_<module> radio box
93     for(i=0; i<elements.length; i++) {
94       if (match = elements[i].id.match(module_re)) {
95         if (!document.getElementById('upgrade_'+match[1])) {
96           // not upgradable
97           document.getElementById('module_'+match[1]).style.display = upgradesonly ? 'none' : 'block';
98         }
99       }
100     }
101     // hide category headings that don't have any visible modules
102     var elements = document.getElementById('modulelist').getElementsByTagName('div');
103     // loop through category items
104     for(i=0; i<elements.length; i++) {
105       if (elements[i].id.match(cat_re)) {
106         var subelements = elements[i].getElementsByTagName('li');
107         var display = false;
108         for(j=0; j<subelements.length; j++) {
109           // loop through children <li>'s, find names that are module element id's
110           if (subelements[j].id.match(module_re) && subelements[j].style.display != 'none') {
111             // if at least one is visible, we're displaying this element
112             display = true;
113             break; // no need to go further
114           }
115         }
116         document.getElementById(elements[i].id).style.display = display ? 'block' : 'none';
117       }
118     }
119   }
120   var box;
121   function process_module_actions(actions) {
122     urlStr = "config.php?type=<?php echo $type ?>&amp;display=modules&amp;extdisplay=process&amp;quietmode=1";
123     for (var i in actions) {
124       urlStr += "&amp;moduleaction["+i+"]="+actions[i];
125     }
126      box = $('<div></div>')
127       .html('<iframe frameBorder="0" src="'+urlStr+'"></iframe>')
128       .dialog({
129         title: 'Status',
130         resizable: false,
131         modal: true,
132         position: ['center', 50],
133         close: function (e) {
134           $(e.target).dialog("destroy").remove();
135         }
136       });
137   }
138   function close_module_actions(goback) {
139     box.dialog("destroy").remove();
140     if (goback) {
141           location.href = 'config.php?display=modules&amp;type=<?php echo $type ?>&amp;online=<?php echo $online; ?>';
142     }
143   }
144   </script>
145   <?php
146
147   echo "<h2>" . _("Module Administration") . "</h2>";
148   //TODO: decide if warnings of any sort need to be given, or just list of repos active?
149 } else {
150   // $quietmode==true
151   ?>
152   <html><head>
153     <link href="common/mainstyle.css" rel="stylesheet" type="text/css" />
154   </head><body>
155   <?php
156 }
157
158 $modules_local = module_getinfo(false,false,true);
159
160 if ($online) {
161   $modules_online = module_getonlinexml(false, $repo);
162  
163   // $module_getonlinexml_error is a global set by module_getonlinexml()
164   if ($module_getonlinexml_error) {
165     echo "<div class=\"warning\"><p>".sprintf(_("Warning: Cannot connect to online repository (%s). Online modules are not available."), $amp_conf['MODULE_REPO'])."</p></div><br />";
166     $online = 0;
167     unset($modules_online);
168   } else if (!is_array($modules_online)) {
169     echo "<div class=\"warning\"><p>".sprintf(_("Warning: Error retrieving updates from online repository (%s). Online modules are not available."), $amp_conf['MODULE_REPO'])."</p></div><br />";
170     $online = 0;
171     unset($modules_online);
172   } else {
173     // combine online and local modules
174     $modules = $modules_online;
175     foreach (array_keys($modules) as $name) {
176       if (isset($modules_local[$name])) {
177         // combine in any other values in _local that aren't in _online
178         $modules[$name] += $modules_local[$name];
179         
180         // explicitly override these values with the _local ones
181         // - should never come from _online anyways, but this is just to be sure
182         $modules[$name]['status'] = $modules_local[$name]['status'];
183         $modules[$name]['dbversion'] = isset($modules_local[$name]['dbversion'])?$modules_local[$name]['dbversion']:'';
184       } else {
185         // not local, so it's not installed
186         $modules[$name]['status'] = MODULE_STATUS_NOTINSTALLED;
187       }
188     }
189     // add any remaining local-only modules
190     $modules += $modules_local;
191     
192     // use online categories
193     foreach (array_keys($modules) as $modname) {
194       if (isset($modules_online[$modname]['category'])) {
195         $modules[$modname]['category'] = $modules_online[$modname]['category'];
196       }
197     }
198   }
199 }
200
201 if (!isset($modules)) {
202   $modules = & $modules_local;
203 }
204
205 //--------------------------------------------------------------------------------------------------------
206 switch ($extdisplay) {  // process, confirm, or nothing
207   case 'process':
208     echo "<div id=\"moduleBoxContents\">";
209     echo "<h4>"._("Please wait while module actions are performed")."</h4>\n";
210     echo "<div id=\"moduleprogress\">";
211
212     // stop output buffering, and send output
213     @ ob_flush();
214     flush();
215     foreach ($moduleaction as $modulename => $action) {
216       $didsomething = true; // set to false in default clause of switch() below..
217       
218       switch ($action) {
219         case 'force_upgrade':
220         case 'upgrade':
221         case 'downloadinstall':
222           if (!EXTERNAL_PACKAGE_MANAGEMENT) {
223             echo sprintf(_('Downloading %s'), $modulename).' <span id="downloadprogress_'.$modulename.'"></span>';
224             if (is_array($errors = module_download($modulename, false, 'download_progress', false, $repo))) {
225               echo '<span class="error">'.sprintf(_("Error(s) downloading %s"),$modulename).': ';
226               echo '<ul><li>'.implode('</li><li>',$errors).'</li></ul>';
227               echo '</span>';
228             } else {
229               if (is_array($errors = module_install($modulename))) {
230                 echo '<span class="error">'.sprintf(_("Error(s) installing %s"),$modulename).': ';
231                 echo '<ul><li>'.implode('</li><li>',$errors).'</li></ul>';
232                 echo '</span>';
233               } else {
234                 echo '<span class="success">'.sprintf(_("%s installed successfully"),$modulename).'</span>';
235               }
236             }
237           }
238         break;
239         case 'install':
240           if (!EXTERNAL_PACKAGE_MANAGEMENT) {
241             if (is_array($errors = module_install($modulename))) {
242               echo '<span class="error">'.sprintf(_("Error(s) installing %s"),$modulename).': ';
243               echo '<ul><li>'.implode('</li><li>',$errors).'</li></ul>';
244               echo '</span>';
245             } else {
246               echo '<span class="success">'.sprintf(_("%s installed successfully"),$modulename).'</span>';
247             }
248           }
249         break;
250         case 'enable':
251           if (is_array($errors = module_enable($modulename))) {
252             echo '<span class="error">'.sprintf(_("Error(s) enabling %s"),$modulename).': ';
253             echo '<ul><li>'.implode('</li><li>',$errors).'</li></ul>';
254             echo '</span>';
255           } else {
256             echo '<span class="success">'.sprintf(_("%s enabled successfully"),$modulename).'</span>';
257           }
258         break;
259         case 'disable':
260           if (is_array($errors = module_disable($modulename))) {
261             echo '<span class="error">'.sprintf(_("Error(s) disabling %s"),$modulename).': ';
262             echo '<ul><li>'.implode('</li><li>',$errors).'</li></ul>';
263             echo '</span>';
264           } else {
265             echo '<span class="success">'.sprintf(_("%s disabled successfully"),$modulename).'</span>';
266           }
267         break;
268         case 'uninstall':
269           if (!EXTERNAL_PACKAGE_MANAGEMENT) {
270             if (is_array($errors = module_uninstall($modulename))) {
271               echo '<span class="error">'.sprintf(_("Error(s) uninstalling %s"),$modulename).': ';
272               echo '<ul><li>'.implode('</li><li>',$errors).'</li></ul>';
273               echo '</span>';
274             } else {
275               echo '<span class="success">'.sprintf(_("%s uninstalled successfully"),$modulename).'</span>';
276             }
277           }
278         break;
279         default:
280           // just so we don't send an <hr> and flush()
281           $didsomething = false;
282       }
283       
284       if ($didsomething) {
285         echo "<hr /><br />";
286         flush();
287       }
288     }
289     echo "</div>";
290     if ($quietmode) {
291       echo "\t<a href=\"#\" onclick=\"parent.close_module_actions(true);\" />"._("Return")."</a>";
292     } else {
293       echo "\t<input type=\"button\" value=\""._("Return")."\" onclick=\"location.href = 'config.php?display=modules&amp;type=$type&amp;online=".$online."';\" />";
294     echo "</div>";
295     }
296   break;
297   case 'confirm':
298     ksort($moduleaction);
299     /* if updating language packs, make sure they are the last thing to be done so that
300       any modules currently being updated at the same time will be done so first and
301       language pack updates for those modules will be included.
302     */
303     if (isset($moduleaction['fw_langpacks'])) {
304       $tmp = $moduleaction['fw_langpacks'];
305       unset($moduleaction['fw_langpacks']);
306       $moduleaction['fw_langpacks'] = $tmp;
307       unset($tmp);
308     }
309     
310     echo "<form name=\"modulesGUI\" action=\"config.php\" method=\"post\">";
311     echo "<input type=\"hidden\" name=\"display\" value=\"".$display."\" />";
312     echo "<input type=\"hidden\" name=\"type\" value=\"".$type."\" />";
313     echo "<input type=\"hidden\" name=\"online\" value=\"".$online."\" />";
314     echo "<input type=\"hidden\" name=\"extdisplay\" value=\"process\" />";
315     
316     echo "\t<script type=\"text/javascript\"> var moduleActions = new Array(); </script>\n";
317     
318     $actionstext = array();
319     $force_actionstext = array();
320     $errorstext = array();
321     foreach ($moduleaction as $module => $action) {
322       $text = false;
323       $skipaction = false;
324
325       // make sure name is set. This is a problem for broken modules
326       if (!isset($modules[$module]['name'])) {
327         $modules[$module]['name'] = $module;
328       }
329       
330       switch ($action) {
331         case 'upgrade':
332         case 'force_upgrade':
333           if (!EXTERNAL_PACKAGE_MANAGEMENT) {
334             if (is_array($errors = module_checkdepends($modules_online[$module]))) {
335               $skipaction = true;
336               $errorstext[] = sprintf(_("%s cannot be upgraded: %s Please try again after the dependencies have been installed."), 
337                                       $modules[$module]['name'],
338                                       '<ul><li>'.implode('</li><li>',$errors).'</li></ul>');
339             } else {
340               switch ( version_compare_freepbx($modules[$module]['dbversion'], $modules_online[$module]['version'])) {
341               case '-1':
342                 $actionstext[] = sprintf(_("%s %s will be upgraded to online version %s"), $modules[$module]['name'], $modules[$module]['dbversion'], $modules_online[$module]['version']);
343                 break;
344               case '0':
345                 $force_actionstext[] = sprintf(_("%s %s will be re-installed to online version %s"), $modules[$module]['name'], $modules[$module]['dbversion'], $modules_online[$module]['version']);
346                 break;
347               default:
348                 $force_actionstext[] = sprintf(_("%s %s will be downgraded to online version %s"), $modules[$module]['name'], $modules[$module]['dbversion'], $modules_online[$module]['version']);
349               }
350             }
351           }
352         break;
353         case 'downloadinstall':
354           if (!EXTERNAL_PACKAGE_MANAGEMENT) {
355             if (is_array($errors = module_checkdepends($modules_online[$module]))) {
356               $skipaction = true;
357               $errorstext[] = sprintf(_("%s cannot be installed: %s Please try again after the dependencies have been installed."), 
358                                       $modules[$module]['name'],
359                                       '<ul><li>'.implode('</li><li>',$errors).'</li></ul>');
360             } else {
361               $actionstext[] =  sprintf(_("%s %s will be downloaded and installed"), $modules[$module]['name'], $modules_online[$module]['version']);
362             }
363           }
364         break;
365         case 'install':
366           if (!EXTERNAL_PACKAGE_MANAGEMENT) {
367             if (is_array($errors = module_checkdepends($modules[$module]))) {
368               $skipaction = true;
369               $errorstext[] = sprintf((($modules[$module]['status'] == MODULE_STATUS_NEEDUPGRADE) ?  _("%s cannot be upgraded: %s Please try again after the dependencies have been installed.") : _("%s cannot be installed: %s Please try again after the dependencies have been installed.") ), 
370                                       $modules[$module]['name'],
371                                       '<ul><li>'.implode('</li><li>',$errors).'</li></ul>');
372             } else {
373               if ($modules[$module]['status'] == MODULE_STATUS_NEEDUPGRADE) {
374                 $actionstext[] =  sprintf(_("%s %s will be upgraded to %s"), $modules[$module]['name'], $modules[$module]['dbversion'], $modules[$module]['version']);
375               } else {
376                 $actionstext[] =  sprintf(_("%s %s will be installed and enabled"), $modules[$module]['name'], $modules[$module]['version']);
377               }
378             }
379           }
380         break;
381         case 'enable':
382           if (is_array($errors = module_checkdepends($modules[$module]))) {
383             $skipaction = true;
384             $errorstext[] = sprintf(_("%s cannot be enabled: %s Please try again after the dependencies have been installed."), 
385                                     $modules[$module]['name'],
386                                     '<ul><li>'.implode('</li><li>',$errors).'</li></ul>');
387           } else {
388             $actionstext[] =  sprintf(_("%s %s will be enabled"), $modules[$module]['name'], $modules[$module]['dbversion']);
389           }
390         break;
391         case 'disable':
392           if (is_array($errors = module_reversedepends($modules[$module]))) {
393             $skipaction = true;
394             $errorstext[] = sprintf(_("%s cannot be disabled because the following modules depend on it: %s Please disable those modules first then try again."), 
395                                     $modules[$module]['name'],
396                                     '<ul><li>'.implode('</li><li>',$errors).'</li></ul>');
397           } else {
398             $actionstext[] =  sprintf(_("%s %s will be disabled"), $modules[$module]['name'], $modules[$module]['dbversion']);
399           }
400         break;
401         case 'uninstall':
402           if (!EXTERNAL_PACKAGE_MANAGEMENT) {
403             if (is_array($errors = module_reversedepends($modules[$module]))) {
404               $skipaction = true;
405               $errorstext[] = sprintf(_("%s cannot be uninstalled because the following modules depend on it: %s Please disable those modules first then try again."), 
406                                       $modules[$module]['name'],
407                                       '<ul><li>'.implode('</li><li>',$errors).'</li></ul>');
408             } else {
409               $actionstext[] =  sprintf(_("%s %s will be uninstalled"), $modules[$module]['name'], $modules[$module]['dbversion']);
410             }
411           }
412         break;
413       }
414
415       // If error above we skip this action so we can proceed with the others
416       //
417       if (!$skipaction) { //TODO
418         echo "\t<script type=\"text/javascript\"> moduleActions['".$module."'] = '".$action."'; </script>\n";
419       }
420     }
421     
422     // Write out the errors, if there are additional actions that can be accomplished list those next with the choice to
423     // process which will ignore the ones with errors but process the rest.
424     //
425     if (count($errorstext) > 0) {
426       echo "<h4>"._("Errors with selection:")."</h4>\n";
427       echo "<ul>\n";
428       foreach ($errorstext as $text) {
429         echo "\t<li>".$text."</li>\n";
430       }
431       echo "</ul>";
432     }
433     if (count($actionstext) > 0 || count($force_actionstext) > 0) {
434       if (count($errorstext) > 0) {
435         echo "<h4>"._("You may confirm the remaining selection and then try the again for the listed issues once the required dependencies have been met:")."</h4>\n";
436       } else {
437         echo "<h4>"._("Please confirm the following actions:")."</h4>\n";
438       }
439       if (count($actionstext)) {
440         echo "<h5>"._("Upgrades, installs, enables and disables:")."</h5>\n";
441         echo "<ul>\n";
442         foreach ($actionstext as $text) {
443           echo "\t<li>".$text."</li>\n";
444         }
445         echo "</ul>";
446       }
447       if (count($force_actionstext)) {
448         echo "<h5>"._("Forced downgrades and re-installs:")."</h5>\n";
449         echo "<ul>\n";
450         foreach ($force_actionstext as $text) {
451           echo "\t<li>".$text."</li>\n";
452         }
453         echo "</ul>";
454       }
455       echo "\t<input type=\"button\" value=\""._("Confirm")."\" name=\"process\" onclick=\"process_module_actions(moduleActions);\" />";
456     } else {
457       echo "<h4>"._("No actions to perform")."</h4>\n";
458       echo "<p>"._("Please select at least one action to perform by clicking on the module, and selecting an action on the \"Action\" tab.")."</p>";
459     }
460     echo "\t<input type=\"button\" value=\""._("Cancel")."\" onclick=\"location.href = 'config.php?display=modules&amp;type=$type&amp;online=$online';\" />";
461     echo "</form>";
462     
463   break;
464   case 'upload':
465     // display links
466     if (!EXTERNAL_PACKAGE_MANAGEMENT) {
467       $disp_buttons[] = 'local';
468       if (isset($_FILES['uploadmod']) && !empty($_FILES['uploadmod']['name'])) {
469         // display upload button, only if they did upload something
470         $disp_buttons[] = 'upload';
471       }
472       displayRepoSelect($disp_buttons);
473     } else {
474       echo "<a href='config.php?display=modules&amp;type=$type'>"._("Manage local modules")."</a>\n";
475     }
476         
477     if (isset($_FILES['uploadmod']) && !empty($_FILES['uploadmod']['name'])) {
478       $res = module_handleupload($_FILES['uploadmod']);
479       if (is_array($res)) {
480         
481         echo '<div class="error"><p>';
482         echo sprintf(_('The following error(s) occurred processing the uploaded file: %s'),
483              '<ul><li>'.implode('</li><li>',$res).'</li></ul>');
484         echo sprintf(_('You should fix the problem or select another file and %s.'),
485              "<a href='config.php?display=modules&amp;type=$type'>"._("try again")."</a>");
486         echo "</p></div>\n";
487       } else {
488         
489         echo "<p>".sprintf(_("Module uploaded successfully. You need to enable the module using %s to make it available."),
490              "<a href='config.php?display=modules&amp;type=$type'>"._("local module administration")."</a>")
491            ."</p>\n";
492       }
493       
494     } else {
495       echo "<p>"._('You can upload a tar gzip file containing a FreePBX module from your local system. If a module with the same name already exists, it will be overwritten.')."</p>\n";
496     
497       echo "<form name=\"modulesGUI-upload\" action=\"config.php\" method=\"post\" enctype=\"multipart/form-data\">";
498       echo "<input type=\"hidden\" name=\"display\" value=\"".$display."\" />";
499       echo "<input type=\"hidden\" name=\"type\" value=\"".$type."\" />";
500       echo "<input type=\"hidden\" name=\"extdisplay\" value=\"upload\" />";
501       echo "<input type=\"file\" name=\"uploadmod\" /> ";
502       echo "&nbsp;&nbsp; <input type=\"submit\" value=\"Upload\" />";
503       echo "</form>";
504     }
505     
506   break;
507   case 'online':
508   default:
509     
510     uasort($modules, 'category_sort_callback');
511     
512     if ($online) {
513       // Check for announcements such as security advisories, required updates, etc.
514       //
515       $announcements = module_get_annoucements();
516       if (isset($announcements) && !empty($announcements)) {
517         echo "<div class='announcements'>$announcements</div>";
518       }
519       
520       if (!EXTERNAL_PACKAGE_MANAGEMENT) {
521         echo "<a href='config.php?display=modules&amp;type=$type&amp;online=0'>"._("Manage local modules")."</a>\n";
522         echo "<input type=\"checkbox\" id=\"show_upgradable_only\" onclick=\"showhide_upgrades();\" /><label for=\"show_upgradable_only\">"._("Show only upgradeable")."</label>";
523       }
524     } else {
525       if (!EXTERNAL_PACKAGE_MANAGEMENT) {
526         displayRepoSelect(array('upload'));
527       } else {
528         echo " | <a href='config.php?display=modules&type=$type&extdisplay=upload'>"._("Upload module")."</a><br />\n";
529       }
530     }
531
532     echo "<form name=\"modulesGUI\" action=\"config.php\" method=\"post\">";
533     echo "<input type=\"hidden\" name=\"display\" value=\"".$display."\" />";
534     echo "<input type=\"hidden\" name=\"type\" value=\"".$type."\" />";
535     echo "<input type=\"hidden\" name=\"online\" value=\"".$online."\" />";
536     echo "<input type=\"hidden\" name=\"extdisplay\" value=\"confirm\" />";
537     
538     echo "<div class=\"modulebuttons\">";
539     if ($online) {
540       echo "\t<a href=\"javascript:void(null);\" onclick=\"check_download_all();\">"._("Download all")."</a>";
541       echo "\t<a href=\"javascript:void(null);\" onclick=\"check_upgrade_all();\">"._("Upgrade all")."</a>";
542     }
543     echo "\t<input type=\"reset\" value=\""._("Reset")."\" />";
544     echo "\t<input type=\"submit\" value=\""._("Process")."\" name=\"process\" />";
545     echo "</div>";
546
547     echo "<div id=\"modulelist\">\n";
548
549     echo "\t<div id=\"modulelist-header\">";
550     echo "\t\t<span class=\"modulename\">"._("Module")."</span>\n";
551     echo "\t\t<span class=\"moduleversion\">"._("Version")."</span>\n";
552     echo "\t\t<span class=\"modulepublisher\">"._("Publisher")."</span>\n";
553     echo "\t\t<span class=\"clear\">&nbsp;</span>\n";
554     echo "\t</div>";
555
556     $category = false;
557     $numdisplayed = 0;
558     $fd = $amp_conf['ASTETCDIR'].'/freepbx_module_admin.conf';
559     if (file_exists($fd)) {
560       $module_filter = parse_ini_file($fd);
561     } else {
562       $module_filter = array();
563     }
564     foreach (array_keys($modules) as $name) {
565       if (!isset($modules[$name]['category'])) {
566         $modules[$name]['category'] = _("Broken");
567         $modules[$name]['name'] = $name;
568       }
569       if (isset($module_filter[$name]) && strtolower(trim($module_filter[$name])) == 'hidden') {
570         continue;
571       }
572
573       // Theory: module is not in the defined repos, and since it is not local (meaning we loaded it at some point) then we
574       //         don't show it. Exception, if the status is BROKEN then we should show it because it was here once.
575       //
576       if ((!isset($active_repos[$modules[$name]['repo']]) || !$active_repos[$modules[$name]['repo']])
577         && $modules[$name]['status'] != MODULE_STATUS_BROKEN && !isset($modules_local[$name])) {
578         continue;
579       }
580
581       // If versionupgrade module is present then allow it to skip modules that should not be presented
582       // because an upgrade is in process. This can help assure only safe modules are present and
583       // force the user to upgrade in the proper order.
584       //
585       if (function_exists('versionupgrade_allowed_modules') && !versionupgrade_allowed_modules($modules[$name])) {
586         continue;
587       }
588       $numdisplayed++;
589       
590       if ($category !== $modules[$name]['category']) {
591         // show category header
592         
593         if ($category !== false) {
594           // not the first one, so end the previous blocks
595           echo "\t</ul></div>\n";
596         }
597         
598         // start a new category header, and associated html blocks
599         $category = $modules[$name]['category'];
600         echo "\t<div class=\"category\" id=\"category_".prep_id($category)."\"><h3>"._($category)."</h3>\n";
601         echo "\t<ul>";
602       }
603
604       // This will load any module's i18n translations that are available and try to use them when printing the
605       // module names with a fall back to using the amp.po master translations for a check if not available in
606       // the local module. For new modules of course, there will be no translations usually.
607       //
608       if (extension_loaded('gettext') && is_dir("modules/".$name."/i18n")) {
609         bindtextdomain($name,"modules/".$name."/i18n");
610         bind_textdomain_codeset($name, 'utf8');
611         $loc_domain = $name;
612
613         $name_text = dgettext($loc_domain,$modules[$name]['name']);
614         if ($name_text == $modules[$name]['name']) {
615           $name_text = _($name_text);
616         }
617       } else {
618         $name_text = _($modules[$name]['name']);
619         $loc_domain = false;
620       }
621
622       echo "\t\t<li id=\"module_".prep_id($name)."\">\n";
623       
624       // ---- module header
625       echo "\t\t<div class=\"moduleheader\" onclick=\"toggleInfoPane('infopane_".prep_id($name)."');\" >\n";
626       echo "\t\t\t<span class=\"modulename\"><a href=\"javascript:void(null);\">".(!empty($name_text) ? $name_text : $name)."</a></span>\n";
627       echo "\t\t\t<span class=\"moduleversion\">".(isset($modules[$name]['dbversion'])?$modules[$name]['dbversion']:'&nbsp;')."</span>\n";
628       echo "\t\t\t<span class=\"modulepublisher\">".(isset($modules[$name]['publisher'])?$modules[$name]['publisher']:'&nbsp;')."</span>\n";
629       
630       echo "\t\t\t<span class=\"modulestatus\">";
631
632       switch ($modules[$name]['status']) {
633         case MODULE_STATUS_NOTINSTALLED:
634           if (isset($modules_local[$name])) {
635             echo '<span class="notinstalled">'._('Not Installed (Locally available)').'</span>';
636           } else {
637             echo '<span class="notinstalled">'.sprintf(_('Not Installed (Available online: %s)'), $modules_online[$name]['version']).'</span>';
638           }
639         break;
640         case MODULE_STATUS_DISABLED:
641           if (isset($modules_online[$name]['version'])) {
642             $vercomp = version_compare_freepbx($modules_local[$name]['version'], $modules_online[$name]['version']);
643             if ($vercomp < 0) {
644               echo '<span class="alert">'.sprintf(_('Disabled; Online upgrade available (%s)'),$modules_online[$name]['version']).'</span>';
645             } else if ($vercomp > 0) {
646               echo sprintf(_('Disabled; Newer than online version (%s)'), $modules_online[$name]['version']);
647             } else {
648               echo _('Disabled; up to date');
649             }
650           } else {
651             echo _('Disabled');
652           }
653         break;
654         case MODULE_STATUS_NEEDUPGRADE:
655           echo '<span class="alert">'.sprintf(_('Disabled; Pending upgrade to %s'),$modules_local[$name]['version']).'</span>';
656         break;
657         case MODULE_STATUS_BROKEN:
658           echo '<span class="alert">'._('Broken').'</span>';
659         break;
660         default:
661           // check for online upgrade
662           if (isset($modules_online[$name]['version'])) {
663             $vercomp = version_compare_freepbx($modules_local[$name]['version'], $modules_online[$name]['version']);
664             if ($vercomp < 0) {
665               echo '<span class="alert">'.sprintf(_('Online upgrade available (%s)'), $modules_online[$name]['version']).'</span>';
666             } else if ($vercomp > 0) {
667               echo sprintf(_('Newer than online version (%s)'),$modules_online[$name]['version']);
668             } else {
669               echo _('Enabled and up to date');
670             }
671           } else if (isset($modules_online)) {
672             // we're connected to online, but didn't find this module
673             echo _('Enabled; Not available online');
674           } else {
675             echo _('Enabled');
676           }
677         break;
678       }
679       echo "</span>\n";
680       
681       
682       echo "\t\t\t<span class=\"clear\">&nbsp;</span>\n";
683       echo "\t\t</div>\n";
684       
685       // ---- end of module header
686       
687       // ---- drop-down tab box thingy:
688       
689       echo "\t\t<div class=\"moduleinfopane\" id=\"infopane_".prep_id($name)."\" >\n";
690       echo "\t\t\t<div class=\"tabber\">\n";
691       
692       if (isset($modules_online[$name]['attention']) && !empty($modules_online[$name]['attention'])) {
693         echo "\t\t\t\t<div class=\"tabbertab\" title=\""._("Attention")."\">\n";
694         echo nl2br( $loc_domain ? dgettext($loc_domain,$modules[$name]['attention']) : _($modules[$name]['attention']) );
695         echo "\t\t\t\t</div>\n";
696       }
697       
698       echo "\t\t\t\t<div class=\"tabbertab actiontab\" title=\""._("Action")."\">\n";
699       
700       echo '<input type="radio" checked="CHECKED" id="noaction_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="0" /> '.
701          '<label for="noaction_'.prep_id($name).'">'._('No Action').'</label> <br />'; 
702       switch ($modules[$name]['status']) {
703       
704         case MODULE_STATUS_NOTINSTALLED:
705           if (!EXTERNAL_PACKAGE_MANAGEMENT) {
706             if (isset($modules_local[$name])) {
707               echo '<input type="radio" id="install_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="install" /> '.
708                  '<label for="install_'.prep_id($name).'">'._('Install').'</label> <br />';
709             } else {
710               echo '<input type="radio" id="upgrade_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="downloadinstall" /> '.
711                  '<label for="upgrade_'.prep_id($name).'">'._('Download and Install').'</label> <br />';
712             }
713           }
714         break;
715         case MODULE_STATUS_DISABLED:
716           echo '<input type="radio" id="enable_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="enable" /> '.
717              '<label for="enable_'.prep_id($name).'">'._('Enable').'</label> <br />';
718           if (!EXTERNAL_PACKAGE_MANAGEMENT) {
719             echo '<input type="radio" id="uninstall_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="uninstall" /> '.
720                '<label for="uninstall_'.prep_id($name).'">'._('Uninstall').'</label> <br />';
721             if (isset($modules_online[$name]['version'])) {
722               $vercomp = version_compare_freepbx($modules_local[$name]['version'], $modules_online[$name]['version']);
723               if ($vercomp < 0) {
724                 echo '<input type="radio" id="upgrade_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="upgrade" /> '.
725                    '<label for="upgrade_'.prep_id($name).'">'.sprintf(_('Download %s, keep Disabled'),$modules_online[$name]['version']).'</label> <br />';
726               }
727             }
728           }
729         break;
730         case MODULE_STATUS_NEEDUPGRADE:
731           if (!EXTERNAL_PACKAGE_MANAGEMENT) {
732             echo '<input type="radio" id="install_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="install" /> '.
733                '<label for="install_'.prep_id($name).'">'.sprintf(_('Upgrade to %s and Enable'),$modules_local[$name]['version']).'</label> <br />';
734
735             if (isset($modules_online[$name]['version'])) {
736               $vercomp = version_compare_freepbx($modules_local[$name]['version'], $modules_online[$name]['version']);
737               if ($vercomp < 0) {
738                 echo '<input type="radio" id="upgrade_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="upgrade" /> '.
739                    '<label for="upgrade_'.prep_id($name).'">'.sprintf(_('Download and Upgrade to %s'), $modules_online[$name]['version']).'</label> <br />';
740               }
741             }
742             echo '<input type="radio" id="uninstall_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="uninstall" /> '.
743                '<label for="uninstall_'.prep_id($name).'">'._('Uninstall').'</label> <br />';
744           }
745         break;
746         case MODULE_STATUS_BROKEN:
747           if (!EXTERNAL_PACKAGE_MANAGEMENT) {
748             echo '<input type="radio" id="install_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="install" /> '.
749                '<label for="install_'.prep_id($name).'">'._('Install').'</label> <br />';
750             echo '<input type="radio" id="uninstall_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="uninstall" /> '.
751                '<label for="uninstall_'.prep_id($name).'">'._('Uninstall').'</label> <br />';
752           }
753         break;
754         default:
755           // check for online upgrade
756           if (isset($modules_online[$name]['version'])) {
757             $vercomp = version_compare_freepbx($modules_local[$name]['version'], $modules_online[$name]['version']);
758             if (!EXTERNAL_PACKAGE_MANAGEMENT) {
759               if ($vercomp < 0) {
760                 echo '<input type="radio" id="upgrade_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="upgrade" /> '.
761                    '<label for="upgrade_'.prep_id($name).'">'.sprintf(_('Download and Upgrade to %s'), $modules_online[$name]['version']).'</label> <br />';
762               } else {
763                 $force_msg = ($vercomp == 0 ? sprintf(_('Force Download and Install %s'), $modules_online[$name]['version']) : sprintf(_('Force Download and Downgrade to %s'), $modules_online[$name]['version']));
764                 echo '<input type="radio" id="force_upgrade_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="force_upgrade" /> '.
765                    '<label for="force_upgrade_'.prep_id($name).'">'.$force_msg.'</label> <br />';
766               }
767             }
768           }
769           if (enable_option($name,'candisable')) {
770             echo '<input type="radio" id="disable_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="disable" /> '.
771                '<label for="disable_'.prep_id($name).'">'._('Disable').'</label> <br />';
772           }
773           if (!EXTERNAL_PACKAGE_MANAGEMENT && enable_option($name,'canuninstall')) {
774             echo '<input type="radio" id="uninstall_'.prep_id($name).'" name="moduleaction['.prep_id($name).']" value="uninstall" /> '.
775                '<label for="uninstall_'.prep_id($name).'">'._('Uninstall').'</label> <br />';
776           }
777         break;
778       }
779       echo "\t\t\t\t</div>\n";
780       
781       echo "\t\t\t\t<div class=\"tabbertab\" title=\""._("Description")."\">\n";
782       if (isset($modules[$name]['publisher'])) {
783         echo "<h5>".sprintf(_("Publisher: %s"),$modules[$name]['publisher'])."</h5>";
784       }
785       echo "<h5>".sprintf(_("License: %s"), (isset($modules[$name]['license'])?$modules[$name]['license']:"GPLv2") )."</h5>";
786       if (isset($modules[$name]['description']) && !empty($modules[$name]['description'])) {
787         echo "<h5>".sprintf(_("Description for version %s"),$modules[$name]['version'])."</h5>";
788         echo nl2br( $loc_domain ? dgettext($loc_domain,$modules[$name]['description']) : _($modules[$name]['description']) );
789       } else {
790         echo _("No description is available.");
791       }
792       if (isset($modules[$name]['info']) && !empty($modules[$name]['info'])) {
793         echo '<p>'._('More info').': <a href="'.$modules[$name]['info'].'" target="_new">'.$modules[$name]['info'].'</a></p>';
794       } else {
795         echo '<p>'._('More info').': <a href="'."$freepbx_help_url&freepbx_module=".urlencode($name).'" target="help">'.sprintf(_("Get help for %s"),$name_text).'</a></p>';
796       }
797       echo "\t\t\t\t</div>\n";
798       
799       if (isset($modules[$name]['changelog']) && !empty($modules[$name]['changelog'])) {
800         echo "\t\t\t\t<div class=\"tabbertab\" title=\""._("Changelog")."\">\n";
801         echo "<h5>".sprintf(_("Change Log for version %s"), $modules[$name]['version'])."</h5>";
802
803         // convert "1.x.x:" and "*1.x.x*" into bold, and do nl2br
804         // TODO: need to fix this to convert 1.x.xbetax.x, 1.x.xalphax.x, 1.x.xrcx.x, 1.x.xRCx.x formats as well
805         //
806         $changelog = nl2br($modules[$name]['changelog']);
807         $changelog = preg_replace('/(\d+(\.\d+|\.\d+beta\d+|\.\d+alpha\d+|\.\d+rc\d+|\.\d+RC\d+)+):/', '<strong>$0</strong>', $changelog);
808         $changelog = preg_replace('/\*(\d+(\.\d+|\.\d+beta\d+|\.\d+alpha\d+|\.\d+rc\d+|\.\d+RC\d+)+)\*/', '<strong>$1:</strong>', $changelog);
809
810         // convert '#xxx', 'ticket xxx', 'bug xxx' to ticket links and rxxx to changeset links in trac
811         //
812         $changelog = preg_replace_callback('/(?<!\w)(?:#|bug |ticket )([^&]\d{3,4})(?!\w)/i', 'trac_replace_ticket', $changelog);
813         $changelog = preg_replace_callback('/(?<!\w)r(\d+)(?!\w)/', 'trac_replace_changeset', $changelog);
814         $changelog = preg_replace_callback('/(?<!\w)\[(\d+)\](?!\w)/', 'trac_replace_changeset', $changelog);
815
816         echo $changelog;
817         echo "\t\t\t\t</div>\n";
818       }
819       
820       if ($amp_conf['DEVEL']) {
821         echo "\t\t\t\t<div class=\"tabbertab\" title=\""._("Debug")."\">\n";
822         echo "\t\t\t\t<h5>".$name."</h5><pre>\n";
823         print_r($modules_local[$name]);
824         echo "</pre>";
825         if (isset($modules_online)) {
826           echo "\t\t\t\t<h5>Online info</h5><pre>\n";
827           print_r($modules_online[$name]);
828           echo "</pre>\n";
829         }
830           echo "\t\t\t\t<h5>combined</h5><pre>\n";
831           print_r($modules[$name]);
832           echo "</pre>\n";
833         echo "\t\t\t\t</div>\n";
834       }
835       
836       echo "\t\t\t</div>\n";
837       echo "\t\t</div>\n";
838       
839       // ---- end of drop-down tab box
840       
841       echo "\t\t</li>\n";
842     }
843     
844     if ($numdisplayed == 0) {
845       if (isset($modules_online) && count($modules_online) > 0) {
846         echo _("All available modules are up-to-date and installed.");
847       } else {
848         echo _("No modules to display.");
849       }
850     }
851     
852     echo "\t</ul></div>\n";
853     echo "</div>";
854
855     echo "<div class=\"modulebuttons\">";
856     if ($online) {
857       echo "\t<a href=\"javascript:void(null);\" onclick=\"check_download_all();\">"._("Download all")."</a>";
858       echo "\t<a href=\"javascript:void(null);\" onclick=\"check_upgrade_all();\">"._("Upgrade all")."</a>";
859     }
860     echo "\t<input type=\"reset\" value=\""._("Reset")."\" />";
861     echo "\t<input type=\"submit\" value=\""._("Process")."\" name=\"process\" />";
862     echo "</div>";
863
864     echo "</form>";
865   break;
866 }
867
868 if ($quietmode) {
869   echo '</body></html>';
870 }
871
872 //-------------------------------------------------------------------------------------------
873 // Help functions
874 //
875
876 function category_sort_callback($a, $b) {
877   // sort by category..
878   $catcomp = strcmp($a['category'], $b['category']);
879   if ($catcomp == 0) {
880     // .. then by name
881     return strcmp($a['name'], $b['name']);
882   } elseif ($a['category'] == 'Basic') {
883       return -1;
884   } elseif ($b['category'] == 'Basic') {
885     return 1;
886   } else {
887     return $catcomp;
888   }
889 }
890
891 /** preps a string to use as an HTML id element
892  */
893 function prep_id($name) {
894   return preg_replace("/[^a-z0-9-]/i", "_", $name);
895 }
896
897 /** Progress callback used by module_download()
898  */
899 function download_progress($action, $params) {
900   switch ($action) {
901     case 'untar':
902       echo '<script type="text/javascript">
903               var txt = document.createTextNode("'._('Untarring..').'");
904               var br = document.createElement(\'br\');
905               document.getElementById(\'moduleprogress\').appendChild(br);
906           document.getElementById(\'moduleprogress\').appendChild(txt);
907            </script>';
908       flush();
909     break;
910     case 'downloading':
911       if ($params['total']==0) {
912         $progress = $params['read'].' of '.$params['total'].' (0%)';
913       } else {
914         $progress = $params['read'].' of '.$params['total'].' ('.round($params['read']/$params['total']*100).'%)';
915       }
916       echo '<script type="text/javascript">
917               document.getElementById(\'downloadprogress_'.$params['module'].'\').innerHTML = \''.$progress.'\';
918             </script>';
919       flush();
920     break;
921     case 'done';
922       echo '<script type="text/javascript">
923               var txt = document.createTextNode("'._('Done.').'");
924           var br = document.createElement(\'br\');
925               document.getElementById(\'moduleprogress\').appendChild(txt);
926           document.getElementById(\'moduleprogress\').appendChild(br);
927            </script>';
928       flush();
929     break;
930   }
931 }
932
933 /* enable_option($module_name, $option)
934    This function will return false if the particular option, which is a module xml tag,
935    is set to 'no'. It also provides for some hardcoded overrides on critical modules to
936    keep people from editing the xml themselves and then breaking their the system.
937 */
938 function enable_option($module_name, $option) {
939   global $modules;
940
941   $enable=true;
942   $override = array('core'      => array('candisable' => 'no',
943                                          'canuninstall' => 'no',
944                                         ),
945                     'framework' => array('candisable' => 'no',
946                                          'canuninstall' => 'no',
947                                         ),
948                    );
949   if (isset($modules[$module_name][$option]) && strtolower(trim($modules[$module_name][$option])) == 'no') {
950     $enable=false;
951   }
952   if (isset($override[$module_name][$option]) && strtolower(trim($override[$module_name][$option])) == 'no') {
953     $enable=false;
954   }
955   return $enable;
956 }
957
958 /* Replace '#nnn', 'bug nnn', 'ticket nnn' type ticket numbers in changelog with a link, taken from Greg's drupal filter
959 */
960 function trac_replace_ticket($match) {
961   $baseurl = 'http://freepbx.org/trac/ticket/';
962   return '<a target="tractickets" href="'.$baseurl.$match[1].'" title="ticket '.$match[1].'">'.$match[0].'</a>';
963 }
964
965 /* Replace 'rnnn' changeset references to a link, taken from Greg's drupal filter
966 */
967 function trac_replace_changeset($match) {
968   $baseurl = 'http://freepbx.org/trac/changeset/';
969   return '<a target="tractickets" href="'.$baseurl.$match[1].'" title="changeset '.$match[1].'">'.$match[0].'</a>';
970 }                                                                                                                                             
971
972 function pageReload(){
973   return "";
974   //return "<script language=\"Javascript\">document.location='".$_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING']."&foo=".rand()."'</script>";
975 }
976
977 function displayRepoSelect($buttons) {
978   global $display, $type, $online, $tabindex;
979   global $active_repos;
980
981   $standard_repo = true;
982   $extended_repo = true;
983   $unsupported_repo = false;
984   $commercial_repo = true;
985
986   $button_display = '';
987   $href = "config.php?display=$display&type=$type";
988   $button_template = '<input type="button" value="%s" onclick="location.href=\'%s\';" />'."\n";
989
990   foreach ($buttons as $button) {
991     switch($button) {
992     case 'local':
993       $button_display .= sprintf($button_template, _("Manage local modules"), $href);
994     break;
995     case 'upload':
996       $button_display .= sprintf($button_template, _("Upload modules"), $href.'&extdisplay=upload');
997     break;
998     }
999   }
1000
1001   $tooltip  = _("Choose the repositories that you want to check for new modules. Any updates available for modules you have on your system will be detected even if the repository is not checked. If you are installing a new system, you may want to start with the Basic repository and upload all modules, then go back and review the others.").' ';
1002   $tooltip .= _(" The modules in the Extended repository are less common and may receive lower levels of support. The Unsupported repository has modules that are not supported by the FreePBX team but may receive some level of support by the authors.").' ';
1003   $tooltip .= _("The Commercial repository is reserved for modules that are available for purchase and commercially supported.").' ';
1004   $tooltip .= '<br /><br /><small><i>('._("Checking for updates will transmit your FreePBX, Distro, Asterisk and PHP version numbers along with a unique but random identifier. This is used to provide proper update information and track version usage to focus development and maintenance efforts. No private information is transmitted.").')</i></small>';
1005 ?>
1006   <form name="onlineRepo" action="config.php" method="post">
1007     <input type="hidden" name="display" value="<?php echo $display ?>"/>
1008     <input type="hidden" name="type" value="<?php echo $type ?>"/>
1009     <input type="hidden" name="online" value="<?php echo $online ?>"/>
1010     <table width="600px">
1011       <tr>
1012         <td>
1013           <?php echo fpbx_label(_("Repositories"), $tooltip); ?>
1014         </td><td>
1015           <table>
1016             <tr class="repo_boxes">
1017               <td>
1018                 <input id="standard_repo" type="checkbox" name="active_repos[standard]" value="1" tabindex="<?php echo ++$tabindex;?>"<?php echo isset($active_repos['standard'])?"checked":""?>/>
1019                 <label for="standard_repo"><?php echo _("Basic") ?></label>
1020               </td>
1021               <td>
1022                 <input id="extended_repo" type="checkbox" name="active_repos[extended]" value="1" tabindex="<?php echo ++$tabindex;?>"<?php echo isset($active_repos['extended'])?"checked":""?>/>
1023                 <label for="extended_repo"><?php echo _("Extended") ?></label>
1024               </td>
1025               <td>
1026                 <input id="unsupported_repo" type="checkbox" name="active_repos[unsupported]" value="1" tabindex="<?php echo ++$tabindex;?>"<?php echo isset($active_repos['unsupported'])?"checked":""?>/>
1027                 <label for="unsupported_repo"><?php echo _("Unsupported") ?></label>
1028               </td>
1029               <td>
1030                 <input id="commercial_repo" type="checkbox" name="active_repos[commercial]" value="1" tabindex="<?php echo ++$tabindex;?>"<?php echo isset($active_repos['commercial'])?"checked":""?>/>
1031                 <label for="commercial_repo"><?php echo _("Commercial") ?></label>
1032               </td>
1033             </tr>
1034           </table>
1035         </td>
1036       </tr>
1037     </table>
1038     <input type="submit" value="<?php echo _("Check Online") ?>" name="check_online" />
1039     <?php echo $button_display ?>
1040   </form>
1041 <?php
1042 }
1043 ?>
Note: See TracBrowser for help on using the browser.