source: moodle/trunk/fuentes/admin/renderer.php

Last change on this file was 1331, checked in by jrpelegrina, 4 years ago

Updated to moodle 3.0.3

File size: 81.4 KB
Line 
1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * Renderer for core_admin subsystem
19 *
20 * @package    core
21 * @subpackage admin
22 * @copyright  2011 David Mudrak <david@moodle.com>
23 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26defined('MOODLE_INTERNAL') || die();
27
28
29/**
30 * Standard HTML output renderer for core_admin subsystem
31 */
32class core_admin_renderer extends plugin_renderer_base {
33
34    /**
35     * Display the 'Do you acknowledge the terms of the GPL' page. The first page
36     * during install.
37     * @return string HTML to output.
38     */
39    public function install_licence_page() {
40        global $CFG;
41        $output = '';
42
43        $copyrightnotice = text_to_html(get_string('gpl3'));
44        $copyrightnotice = str_replace('target="_blank"', 'onclick="this.target=\'_blank\'"', $copyrightnotice); // extremely ugly validation hack
45
46        $continue = new single_button(new moodle_url($this->page->url, array(
47            'lang' => $CFG->lang, 'agreelicense' => 1)), get_string('continue'), 'get');
48
49        $output .= $this->header();
50        $output .= $this->heading('<a href="http://moodle.org">Moodle</a> - Modular Object-Oriented Dynamic Learning Environment');
51        $output .= $this->heading(get_string('copyrightnotice'));
52        $output .= $this->box($copyrightnotice, 'copyrightnotice');
53        $output .= html_writer::empty_tag('br');
54        $output .= $this->confirm(get_string('doyouagree'), $continue, "http://docs.moodle.org/dev/License");
55        $output .= $this->footer();
56
57        return $output;
58    }
59
60    /**
61     * Display page explaining proper upgrade process,
62     * there can not be any PHP file leftovers...
63     *
64     * @return string HTML to output.
65     */
66    public function upgrade_stale_php_files_page() {
67        $output = '';
68        $output .= $this->header();
69        $output .= $this->heading(get_string('upgradestalefiles', 'admin'));
70        $output .= $this->box_start('generalbox', 'notice');
71        $output .= format_text(get_string('upgradestalefilesinfo', 'admin', get_docs_url('Upgrading')), FORMAT_MARKDOWN);
72        $output .= html_writer::empty_tag('br');
73        $output .= html_writer::tag('div', $this->single_button($this->page->url, get_string('reload'), 'get'), array('class' => 'buttons'));
74        $output .= $this->box_end();
75        $output .= $this->footer();
76
77        return $output;
78    }
79
80    /**
81     * Display the 'environment check' page that is displayed during install.
82     * @param int $maturity
83     * @param boolean $envstatus final result of the check (true/false)
84     * @param array $environment_results array of results gathered
85     * @param string $release moodle release
86     * @return string HTML to output.
87     */
88    public function install_environment_page($maturity, $envstatus, $environment_results, $release) {
89        global $CFG;
90        $output = '';
91
92        $output .= $this->header();
93        $output .= $this->maturity_warning($maturity);
94        $output .= $this->heading("Moodle $release");
95        $output .= $this->release_notes_link();
96
97        $output .= $this->environment_check_table($envstatus, $environment_results);
98
99        if (!$envstatus) {
100            $output .= $this->upgrade_reload(new moodle_url($this->page->url, array('agreelicense' => 1, 'lang' => $CFG->lang)));
101        } else {
102            $output .= $this->notification(get_string('environmentok', 'admin'), 'notifysuccess');
103            $output .= $this->continue_button(new moodle_url($this->page->url, array(
104                'agreelicense' => 1, 'confirmrelease' => 1, 'lang' => $CFG->lang)));
105        }
106
107        $output .= $this->footer();
108        return $output;
109    }
110
111    /**
112     * Displays the list of plugins with unsatisfied dependencies
113     *
114     * @param double|string|int $version Moodle on-disk version
115     * @param array $failed list of plugins with unsatisfied dependecies
116     * @param moodle_url $reloadurl URL of the page to recheck the dependencies
117     * @return string HTML
118     */
119    public function unsatisfied_dependencies_page($version, array $failed, moodle_url $reloadurl) {
120        $output = '';
121
122        $output .= $this->header();
123        $output .= $this->heading(get_string('pluginscheck', 'admin'));
124        $output .= $this->warning(get_string('pluginscheckfailed', 'admin', array('pluginslist' => implode(', ', array_unique($failed)))));
125        $output .= $this->plugins_check_table(core_plugin_manager::instance(), $version, array('xdep' => true));
126        $output .= $this->warning(get_string('pluginschecktodo', 'admin'));
127        $output .= $this->continue_button($reloadurl);
128
129        $output .= $this->footer();
130
131        return $output;
132    }
133
134    /**
135     * Display the 'You are about to upgrade Moodle' page. The first page
136     * during upgrade.
137     * @param string $strnewversion
138     * @param int $maturity
139     * @param string $testsite
140     * @return string HTML to output.
141     */
142    public function upgrade_confirm_page($strnewversion, $maturity, $testsite) {
143        $output = '';
144
145        $continueurl = new moodle_url($this->page->url, array('confirmupgrade' => 1, 'cache' => 0));
146        $continue = new single_button($continueurl, get_string('continue'), 'get');
147        $cancelurl = new moodle_url('/admin/index.php');
148
149        $output .= $this->header();
150        $output .= $this->maturity_warning($maturity);
151        $output .= $this->test_site_warning($testsite);
152        $output .= $this->confirm(get_string('upgradesure', 'admin', $strnewversion), $continue, $cancelurl);
153        $output .= $this->footer();
154
155        return $output;
156    }
157
158    /**
159     * Display the environment page during the upgrade process.
160     * @param string $release
161     * @param boolean $envstatus final result of env check (true/false)
162     * @param array $environment_results array of results gathered
163     * @return string HTML to output.
164     */
165    public function upgrade_environment_page($release, $envstatus, $environment_results) {
166        global $CFG;
167        $output = '';
168
169        $output .= $this->header();
170        $output .= $this->heading("Moodle $release");
171        $output .= $this->release_notes_link();
172        $output .= $this->environment_check_table($envstatus, $environment_results);
173
174        if (!$envstatus) {
175            $output .= $this->upgrade_reload(new moodle_url($this->page->url, array('confirmupgrade' => 1, 'cache' => 0)));
176
177        } else {
178            $output .= $this->notification(get_string('environmentok', 'admin'), 'notifysuccess');
179
180            if (empty($CFG->skiplangupgrade) and current_language() !== 'en') {
181                $output .= $this->box(get_string('langpackwillbeupdated', 'admin'), 'generalbox', 'notice');
182            }
183
184            $output .= $this->continue_button(new moodle_url($this->page->url, array(
185                'confirmupgrade' => 1, 'confirmrelease' => 1, 'cache' => 0)));
186        }
187
188        $output .= $this->footer();
189
190        return $output;
191    }
192
193    /**
194     * Display the upgrade page that lists all the plugins that require attention.
195     * @param core_plugin_manager $pluginman provides information about the plugins.
196     * @param \core\update\checker $checker provides information about available updates.
197     * @param int $version the version of the Moodle code from version.php.
198     * @param bool $showallplugins
199     * @param moodle_url $reloadurl
200     * @param moodle_url $continueurl
201     * @return string HTML to output.
202     */
203    public function upgrade_plugin_check_page(core_plugin_manager $pluginman, \core\update\checker $checker,
204            $version, $showallplugins, $reloadurl, $continueurl) {
205
206        $output = '';
207
208        $output .= $this->header();
209        $output .= $this->box_start('generalbox', 'plugins-check-page');
210        $output .= html_writer::tag('p', get_string('pluginchecknotice', 'core_plugin'), array('class' => 'page-description'));
211        $output .= $this->check_for_updates_button($checker, $reloadurl);
212        $output .= $this->missing_dependencies($pluginman);
213        $output .= $this->plugins_check_table($pluginman, $version, array('full' => $showallplugins));
214        $output .= $this->box_end();
215        $output .= $this->upgrade_reload($reloadurl);
216
217        if ($pluginman->some_plugins_updatable()) {
218            $output .= $this->container_start('upgradepluginsinfo');
219            $output .= $this->help_icon('upgradepluginsinfo', 'core_admin', get_string('upgradepluginsfirst', 'core_admin'));
220            $output .= $this->container_end();
221        }
222
223        $button = new single_button($continueurl, get_string('upgradestart', 'admin'), 'get');
224        $button->class = 'continuebutton';
225        $output .= $this->render($button);
226        $output .= $this->footer();
227
228        return $output;
229    }
230
231    /**
232     * Display a page to confirm plugin installation cancelation.
233     *
234     * @param array $abortable list of \core\update\plugininfo
235     * @param moodle_url $continue
236     * @return string
237     */
238    public function upgrade_confirm_abort_install_page(array $abortable, moodle_url $continue) {
239
240        $pluginman = core_plugin_manager::instance();
241
242        if (empty($abortable)) {
243            // The UI should not allow this.
244            throw new moodle_exception('err_no_plugin_install_abortable', 'core_plugin');
245        }
246
247        $out = $this->output->header();
248        $out .= $this->output->heading(get_string('cancelinstallhead', 'core_plugin'), 3);
249        $out .= $this->output->container(get_string('cancelinstallinfo', 'core_plugin'), 'cancelinstallinfo');
250
251        foreach ($abortable as $pluginfo) {
252            $out .= $this->output->heading($pluginfo->displayname.' ('.$pluginfo->component.')', 4);
253            $out .= $this->output->container(get_string('cancelinstallinfodir', 'core_plugin', $pluginfo->rootdir));
254            if ($repotype = $pluginman->plugin_external_source($pluginfo->component)) {
255                $out .= $this->output->container(get_string('uninstalldeleteconfirmexternal', 'core_plugin', $repotype),
256                    'uninstalldeleteconfirmexternal');
257            }
258        }
259
260        $out .= $this->plugins_management_confirm_buttons($continue, $this->page->url);
261        $out .= $this->output->footer();
262
263        return $out;
264    }
265
266    /**
267     * Display the admin notifications page.
268     * @param int $maturity
269     * @param bool $insecuredataroot warn dataroot is invalid
270     * @param bool $errorsdisplayed warn invalid dispaly error setting
271     * @param bool $cronoverdue warn cron not running
272     * @param bool $dbproblems warn db has problems
273     * @param bool $maintenancemode warn in maintenance mode
274     * @param bool $buggyiconvnomb warn iconv problems
275     * @param array|null $availableupdates array of \core\update\info objects or null
276     * @param int|null $availableupdatesfetch timestamp of the most recent updates fetch or null (unknown)
277     * @param string[] $cachewarnings An array containing warnings from the Cache API.
278     *
279     * @return string HTML to output.
280     */
281    public function admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed,
282            $cronoverdue, $dbproblems, $maintenancemode, $availableupdates, $availableupdatesfetch,
283            $buggyiconvnomb, $registered, array $cachewarnings = array()) {
284        global $CFG;
285        $output = '';
286
287        $output .= $this->header();
288        $output .= $this->maturity_info($maturity);
289        $output .= empty($CFG->disableupdatenotifications) ? $this->available_updates($availableupdates, $availableupdatesfetch) : '';
290        $output .= $this->insecure_dataroot_warning($insecuredataroot);
291        $output .= $this->display_errors_warning($errorsdisplayed);
292        $output .= $this->buggy_iconv_warning($buggyiconvnomb);
293        $output .= $this->cron_overdue_warning($cronoverdue);
294        $output .= $this->db_problems($dbproblems);
295        $output .= $this->maintenance_mode_warning($maintenancemode);
296        $output .= $this->cache_warnings($cachewarnings);
297        $output .= $this->registration_warning($registered);
298
299        //////////////////////////////////////////////////////////////////////////////////////////////////
300        ////  IT IS ILLEGAL AND A VIOLATION OF THE GPL TO HIDE, REMOVE OR MODIFY THIS COPYRIGHT NOTICE ///
301        $output .= $this->moodle_copyright();
302        //////////////////////////////////////////////////////////////////////////////////////////////////
303
304        $output .= $this->footer();
305
306        return $output;
307    }
308
309    /**
310     * Display the plugin management page (admin/plugins.php).
311     *
312     * The filtering options array may contain following items:
313     *  bool contribonly - show only contributed extensions
314     *  bool updatesonly - show only plugins with an available update
315     *
316     * @param core_plugin_manager $pluginman
317     * @param \core\update\checker $checker
318     * @param array $options filtering options
319     * @return string HTML to output.
320     */
321    public function plugin_management_page(core_plugin_manager $pluginman, \core\update\checker $checker, array $options = array()) {
322
323        $output = '';
324
325        $output .= $this->header();
326        $output .= $this->heading(get_string('pluginsoverview', 'core_admin'));
327        $output .= $this->check_for_updates_button($checker, $this->page->url);
328        $output .= $this->plugins_overview_panel($pluginman, $options);
329        $output .= $this->plugins_control_panel($pluginman, $options);
330        $output .= $this->footer();
331
332        return $output;
333    }
334
335    /**
336     * Renders a button to fetch for available updates.
337     *
338     * @param \core\update\checker $checker
339     * @param moodle_url $reloadurl
340     * @return string HTML
341     */
342    public function check_for_updates_button(\core\update\checker $checker, $reloadurl) {
343
344        $output = '';
345
346        if ($checker->enabled()) {
347            $output .= $this->container_start('checkforupdates');
348            $output .= $this->single_button(
349                new moodle_url($reloadurl, array('fetchupdates' => 1)),
350                get_string('checkforupdates', 'core_plugin')
351            );
352            if ($timefetched = $checker->get_last_timefetched()) {
353                $timefetched = userdate($timefetched, get_string('strftimedatetime', 'core_langconfig'));
354                $output .= $this->container(get_string('checkforupdateslast', 'core_plugin', $timefetched), 'lasttimefetched');
355            }
356            $output .= $this->container_end();
357        }
358
359        return $output;
360    }
361
362    /**
363     * Display a page to confirm the plugin uninstallation.
364     *
365     * @param core_plugin_manager $pluginman
366     * @param \core\plugininfo\base $pluginfo
367     * @param moodle_url $continueurl URL to continue after confirmation
368     * @param moodle_url $cancelurl URL to to go if cancelled
369     * @return string
370     */
371    public function plugin_uninstall_confirm_page(core_plugin_manager $pluginman, \core\plugininfo\base $pluginfo, moodle_url $continueurl, moodle_url $cancelurl) {
372        $output = '';
373
374        $pluginname = $pluginman->plugin_name($pluginfo->component);
375
376        $confirm = '<p>' . get_string('uninstallconfirm', 'core_plugin', array('name' => $pluginname)) . '</p>';
377        if ($extraconfirm = $pluginfo->get_uninstall_extra_warning()) {
378            $confirm .= $extraconfirm;
379        }
380
381        $output .= $this->output->header();
382        $output .= $this->output->heading(get_string('uninstalling', 'core_plugin', array('name' => $pluginname)));
383        $output .= $this->output->confirm($confirm, $continueurl, $cancelurl);
384        $output .= $this->output->footer();
385
386        return $output;
387    }
388
389    /**
390     * Display a page with results of plugin uninstallation and offer removal of plugin files.
391     *
392     * @param core_plugin_manager $pluginman
393     * @param \core\plugininfo\base $pluginfo
394     * @param progress_trace_buffer $progress
395     * @param moodle_url $continueurl URL to continue to remove the plugin folder
396     * @return string
397     */
398    public function plugin_uninstall_results_removable_page(core_plugin_manager $pluginman, \core\plugininfo\base $pluginfo,
399                                                            progress_trace_buffer $progress, moodle_url $continueurl) {
400        $output = '';
401
402        $pluginname = $pluginman->plugin_name($pluginfo->component);
403
404        // Do not show navigation here, they must click one of the buttons.
405        $this->page->set_pagelayout('maintenance');
406        $this->page->set_cacheable(false);
407
408        $output .= $this->output->header();
409        $output .= $this->output->heading(get_string('uninstalling', 'core_plugin', array('name' => $pluginname)));
410
411        $output .= $this->output->box($progress->get_buffer(), 'generalbox uninstallresultmessage');
412
413        $confirm = $this->output->container(get_string('uninstalldeleteconfirm', 'core_plugin',
414            array('name' => $pluginname, 'rootdir' => $pluginfo->rootdir)), 'uninstalldeleteconfirm');
415
416        if ($repotype = $pluginman->plugin_external_source($pluginfo->component)) {
417            $confirm .= $this->output->container(get_string('uninstalldeleteconfirmexternal', 'core_plugin', $repotype),
418                'uninstalldeleteconfirmexternal');
419        }
420
421        // After any uninstall we must execute full upgrade to finish the cleanup!
422        $output .= $this->output->confirm($confirm, $continueurl, new moodle_url('/admin/index.php'));
423        $output .= $this->output->footer();
424
425        return $output;
426    }
427
428    /**
429     * Display a page with results of plugin uninstallation and inform about the need to remove plugin files manually.
430     *
431     * @param core_plugin_manager $pluginman
432     * @param \core\plugininfo\base $pluginfo
433     * @param progress_trace_buffer $progress
434     * @return string
435     */
436    public function plugin_uninstall_results_page(core_plugin_manager $pluginman, \core\plugininfo\base $pluginfo, progress_trace_buffer $progress) {
437        $output = '';
438
439        $pluginname = $pluginfo->component;
440
441        $output .= $this->output->header();
442        $output .= $this->output->heading(get_string('uninstalling', 'core_plugin', array('name' => $pluginname)));
443
444        $output .= $this->output->box($progress->get_buffer(), 'generalbox uninstallresultmessage');
445
446        $output .= $this->output->box(get_string('uninstalldelete', 'core_plugin',
447            array('name' => $pluginname, 'rootdir' => $pluginfo->rootdir)), 'generalbox uninstalldelete');
448        $output .= $this->output->continue_button(new moodle_url('/admin/index.php'));
449        $output .= $this->output->footer();
450
451        return $output;
452    }
453
454    /**
455     * Display the plugin management page (admin/environment.php).
456     * @param array $versions
457     * @param string $version
458     * @param boolean $envstatus final result of env check (true/false)
459     * @param array $environment_results array of results gathered
460     * @return string HTML to output.
461     */
462    public function environment_check_page($versions, $version, $envstatus, $environment_results) {
463        $output = '';
464        $output .= $this->header();
465
466        // Print the component download link
467        $output .= html_writer::tag('div', html_writer::link(
468                    new moodle_url('/admin/environment.php', array('action' => 'updatecomponent', 'sesskey' => sesskey())),
469                    get_string('updatecomponent', 'admin')),
470                array('class' => 'reportlink'));
471
472        // Heading.
473        $output .= $this->heading(get_string('environment', 'admin'));
474
475        // Box with info and a menu to choose the version.
476        $output .= $this->box_start();
477        $output .= html_writer::tag('div', get_string('adminhelpenvironment'));
478        $select = new single_select(new moodle_url('/admin/environment.php'), 'version', $versions, $version, null);
479        $select->label = get_string('moodleversion');
480        $output .= $this->render($select);
481        $output .= $this->box_end();
482
483        // The results
484        $output .= $this->environment_check_table($envstatus, $environment_results);
485
486        $output .= $this->footer();
487        return $output;
488    }
489
490    /**
491     * Output a warning message, of the type that appears on the admin notifications page.
492     * @param string $message the message to display.
493     * @param string $type type class
494     * @return string HTML to output.
495     */
496    protected function warning($message, $type = 'warning') {
497        return $this->box($message, 'generalbox admin' . $type);
498    }
499
500    /**
501     * Render an appropriate message if dataroot is insecure.
502     * @param bool $insecuredataroot
503     * @return string HTML to output.
504     */
505    protected function insecure_dataroot_warning($insecuredataroot) {
506        global $CFG;
507
508        if ($insecuredataroot == INSECURE_DATAROOT_WARNING) {
509            return $this->warning(get_string('datarootsecuritywarning', 'admin', $CFG->dataroot));
510
511        } else if ($insecuredataroot == INSECURE_DATAROOT_ERROR) {
512            return $this->warning(get_string('datarootsecurityerror', 'admin', $CFG->dataroot), 'error');
513
514        } else {
515            return '';
516        }
517    }
518
519    /**
520     * Render an appropriate message if dataroot is insecure.
521     * @param bool $errorsdisplayed
522     * @return string HTML to output.
523     */
524    protected function display_errors_warning($errorsdisplayed) {
525        if (!$errorsdisplayed) {
526            return '';
527        }
528
529        return $this->warning(get_string('displayerrorswarning', 'admin'));
530    }
531
532    /**
533     * Render an appropriate message if iconv is buggy and mbstring missing.
534     * @param bool $buggyiconvnomb
535     * @return string HTML to output.
536     */
537    protected function buggy_iconv_warning($buggyiconvnomb) {
538        if (!$buggyiconvnomb) {
539            return '';
540        }
541
542        return $this->warning(get_string('warningiconvbuggy', 'admin'));
543    }
544
545    /**
546     * Render an appropriate message if cron has not been run recently.
547     * @param bool $cronoverdue
548     * @return string HTML to output.
549     */
550    public function cron_overdue_warning($cronoverdue) {
551        global $CFG;
552        if (!$cronoverdue) {
553            return '';
554        }
555
556        if (empty($CFG->cronclionly)) {
557            $url = new moodle_url('/admin/cron.php');
558            if (!empty($CFG->cronremotepassword)) {
559                $url = new moodle_url('/admin/cron.php', array('password' => $CFG->cronremotepassword));
560            }
561
562            return $this->warning(get_string('cronwarning', 'admin', $url->out()) . '&nbsp;' .
563                    $this->help_icon('cron', 'admin'));
564        }
565
566        // $CFG->cronclionly is not empty: cron can run only from CLI.
567        return $this->warning(get_string('cronwarningcli', 'admin') . '&nbsp;' .
568                $this->help_icon('cron', 'admin'));
569    }
570
571    /**
572     * Render an appropriate message if there are any problems with the DB set-up.
573     * @param bool $dbproblems
574     * @return string HTML to output.
575     */
576    public function db_problems($dbproblems) {
577        if (!$dbproblems) {
578            return '';
579        }
580
581        return $this->warning($dbproblems);
582    }
583
584    /**
585     * Renders cache warnings if there are any.
586     *
587     * @param string[] $cachewarnings
588     * @return string
589     */
590    public function cache_warnings(array $cachewarnings) {
591        if (!count($cachewarnings)) {
592            return '';
593        }
594        return join("\n", array_map(array($this, 'warning'), $cachewarnings));
595    }
596
597    /**
598     * Render an appropriate message if the site in in maintenance mode.
599     * @param bool $maintenancemode
600     * @return string HTML to output.
601     */
602    public function maintenance_mode_warning($maintenancemode) {
603        if (!$maintenancemode) {
604            return '';
605        }
606
607        $url = new moodle_url('/admin/settings.php', array('section' => 'maintenancemode'));
608        $url = $url->out(); // get_string() does not support objects in params
609
610        return $this->warning(get_string('sitemaintenancewarning2', 'admin', $url));
611    }
612
613    /**
614     * Display a warning about installing development code if necesary.
615     * @param int $maturity
616     * @return string HTML to output.
617     */
618    protected function maturity_warning($maturity) {
619        if ($maturity == MATURITY_STABLE) {
620            return ''; // No worries.
621        }
622
623        $maturitylevel = get_string('maturity' . $maturity, 'admin');
624        return $this->warning(
625                    $this->container(get_string('maturitycorewarning', 'admin', $maturitylevel)) .
626                    $this->container($this->doc_link('admin/versions', get_string('morehelp'))),
627                'error');
628    }
629
630    /*
631     * If necessary, displays a warning about upgrading a test site.
632     *
633     * @param string $testsite
634     * @return string HTML
635     */
636    protected function test_site_warning($testsite) {
637
638        if (!$testsite) {
639            return '';
640        }
641
642        $warning = (get_string('testsiteupgradewarning', 'admin', $testsite));
643        return $this->warning($warning, 'error');
644    }
645
646    /**
647     * Output the copyright notice.
648     * @return string HTML to output.
649     */
650    protected function moodle_copyright() {
651        global $CFG;
652
653        //////////////////////////////////////////////////////////////////////////////////////////////////
654        ////  IT IS ILLEGAL AND A VIOLATION OF THE GPL TO HIDE, REMOVE OR MODIFY THIS COPYRIGHT NOTICE ///
655        $copyrighttext = '<a href="http://moodle.org/">Moodle</a> '.
656                         '<a href="http://docs.moodle.org/dev/Releases" title="'.$CFG->version.'">'.$CFG->release.'</a><br />'.
657                         'Copyright &copy; 1999 onwards, Martin Dougiamas<br />'.
658                         'and <a href="http://moodle.org/dev">many other contributors</a>.<br />'.
659                         '<a href="http://docs.moodle.org/dev/License">GNU Public License</a>';
660        //////////////////////////////////////////////////////////////////////////////////////////////////
661
662        return $this->box($copyrighttext, 'copyright');
663    }
664
665    /**
666     * Display a warning about installing development code if necesary.
667     * @param int $maturity
668     * @return string HTML to output.
669     */
670    protected function maturity_info($maturity) {
671        if ($maturity == MATURITY_STABLE) {
672            return ''; // No worries.
673        }
674
675        $level = 'warning';
676
677        if ($maturity == MATURITY_ALPHA) {
678            $level = 'error';
679        }
680
681        $maturitylevel = get_string('maturity' . $maturity, 'admin');
682        $warningtext = get_string('maturitycoreinfo', 'admin', $maturitylevel);
683        $warningtext .= ' ' . $this->doc_link('admin/versions', get_string('morehelp'));
684        return $this->warning($warningtext, $level);
685    }
686
687    /**
688     * Displays the info about available Moodle core and plugin updates
689     *
690     * The structure of the $updates param has changed since 2.4. It contains not only updates
691     * for the core itself, but also for all other installed plugins.
692     *
693     * @param array|null $updates array of (string)component => array of \core\update\info objects or null
694     * @param int|null $fetch timestamp of the most recent updates fetch or null (unknown)
695     * @return string
696     */
697    protected function available_updates($updates, $fetch) {
698
699        $updateinfo = '';
700        $someupdateavailable = false;
701        if (is_array($updates)) {
702            if (is_array($updates['core'])) {
703                $someupdateavailable = true;
704                $updateinfo .= $this->heading(get_string('updateavailable', 'core_admin'), 3);
705                foreach ($updates['core'] as $update) {
706                    $updateinfo .= $this->moodle_available_update_info($update);
707                }
708                $updateinfo .= html_writer::tag('p', get_string('updateavailablerecommendation', 'core_admin'),
709                    array('class' => 'updateavailablerecommendation'));
710            }
711            unset($updates['core']);
712            // If something has left in the $updates array now, it is updates for plugins.
713            if (!empty($updates)) {
714                $someupdateavailable = true;
715                $updateinfo .= $this->heading(get_string('updateavailableforplugin', 'core_admin'), 3);
716                $pluginsoverviewurl = new moodle_url('/admin/plugins.php', array('updatesonly' => 1));
717                $updateinfo .= $this->container(get_string('pluginsoverviewsee', 'core_admin',
718                    array('url' => $pluginsoverviewurl->out())));
719            }
720        }
721
722        if (!$someupdateavailable) {
723            $now = time();
724            if ($fetch and ($fetch <= $now) and ($now - $fetch < HOURSECS)) {
725                $updateinfo .= $this->heading(get_string('updateavailablenot', 'core_admin'), 3);
726            }
727        }
728
729        $updateinfo .= $this->container_start('checkforupdates');
730        $fetchurl = new moodle_url('/admin/index.php', array('fetchupdates' => 1, 'sesskey' => sesskey(), 'cache' => 0));
731        $updateinfo .= $this->single_button($fetchurl, get_string('checkforupdates', 'core_plugin'));
732        if ($fetch) {
733            $updateinfo .= $this->container(get_string('checkforupdateslast', 'core_plugin',
734                userdate($fetch, get_string('strftimedatetime', 'core_langconfig'))));
735        }
736        $updateinfo .= $this->container_end();
737
738        return $this->warning($updateinfo);
739    }
740
741    /**
742     * Display a warning about not being registered on Moodle.org if necesary.
743     *
744     * @param boolean $registered true if the site is registered on Moodle.org
745     * @return string HTML to output.
746     */
747    protected function registration_warning($registered) {
748
749        if (!$registered) {
750
751            $registerbutton = $this->single_button(new moodle_url('/admin/registration/register.php',
752                    array('huburl' =>  HUB_MOODLEORGHUBURL, 'hubname' => 'Moodle.org')),
753                    get_string('register', 'admin'));
754
755            return $this->warning( get_string('registrationwarning', 'admin')
756                    . '&nbsp;' . $this->help_icon('registration', 'admin') . $registerbutton );
757        }
758
759        return '';
760    }
761
762    /**
763     * Helper method to render the information about the available Moodle update
764     *
765     * @param \core\update\info $updateinfo information about the available Moodle core update
766     */
767    protected function moodle_available_update_info(\core\update\info $updateinfo) {
768
769        $boxclasses = 'moodleupdateinfo';
770        $info = array();
771
772        if (isset($updateinfo->release)) {
773            $info[] = html_writer::tag('span', get_string('updateavailable_release', 'core_admin', $updateinfo->release),
774                array('class' => 'info release'));
775        }
776
777        if (isset($updateinfo->version)) {
778            $info[] = html_writer::tag('span', get_string('updateavailable_version', 'core_admin', $updateinfo->version),
779                array('class' => 'info version'));
780        }
781
782        if (isset($updateinfo->maturity)) {
783            $info[] = html_writer::tag('span', get_string('maturity'.$updateinfo->maturity, 'core_admin'),
784                array('class' => 'info maturity'));
785            $boxclasses .= ' maturity'.$updateinfo->maturity;
786        }
787
788        if (isset($updateinfo->download)) {
789            $info[] = html_writer::link($updateinfo->download, get_string('download'), array('class' => 'info download'));
790        }
791
792        if (isset($updateinfo->url)) {
793            $info[] = html_writer::link($updateinfo->url, get_string('updateavailable_moreinfo', 'core_plugin'),
794                array('class' => 'info more'));
795        }
796
797        $box  = $this->output->box_start($boxclasses);
798        $box .= $this->output->box(implode(html_writer::tag('span', ' ', array('class' => 'separator')), $info), '');
799        $box .= $this->output->box_end();
800
801        return $box;
802    }
803
804    /**
805     * Display a link to the release notes.
806     * @return string HTML to output.
807     */
808    protected function release_notes_link() {
809        $releasenoteslink = get_string('releasenoteslink', 'admin', 'http://docs.moodle.org/dev/Releases');
810        $releasenoteslink = str_replace('target="_blank"', 'onclick="this.target=\'_blank\'"', $releasenoteslink); // extremely ugly validation hack
811        return $this->box($releasenoteslink, 'generalbox releasenoteslink');
812    }
813
814    /**
815     * Display the reload link that appears on several upgrade/install pages.
816     * @return string HTML to output.
817     */
818    function upgrade_reload($url) {
819        return html_writer::empty_tag('br') .
820                html_writer::tag('div',
821                    html_writer::link($url, $this->pix_icon('i/reload', '', '', array('class' => 'icon icon-pre')) .
822                            get_string('reload'), array('title' => get_string('reload'))),
823                array('class' => 'continuebutton')) . html_writer::empty_tag('br');
824    }
825
826    /**
827     * Displays all known plugins and information about their installation or upgrade
828     *
829     * This default implementation renders all plugins into one big table. The rendering
830     * options support:
831     *     (bool)full = false: whether to display up-to-date plugins, too
832     *     (bool)xdep = false: display the plugins with unsatisified dependecies only
833     *
834     * @param core_plugin_manager $pluginman provides information about the plugins.
835     * @param int $version the version of the Moodle code from version.php.
836     * @param array $options rendering options
837     * @return string HTML code
838     */
839    public function plugins_check_table(core_plugin_manager $pluginman, $version, array $options = array()) {
840
841        $plugininfo = $pluginman->get_plugins();
842
843        if (empty($plugininfo)) {
844            return '';
845        }
846
847        $options['full'] = isset($options['full']) ? (bool)$options['full'] : false;
848        $options['xdep'] = isset($options['xdep']) ? (bool)$options['xdep'] : false;
849
850        $table = new html_table();
851        $table->id = 'plugins-check';
852        $table->head = array(
853            get_string('displayname', 'core_plugin').' / '.get_string('rootdir', 'core_plugin'),
854            get_string('versiondb', 'core_plugin'),
855            get_string('versiondisk', 'core_plugin'),
856            get_string('requires', 'core_plugin'),
857            get_string('source', 'core_plugin').' / '.get_string('status', 'core_plugin'),
858        );
859        $table->colclasses = array(
860            'displayname', 'versiondb', 'versiondisk', 'requires', 'status',
861        );
862        $table->data = array();
863
864        // Number of displayed plugins per type.
865        $numdisplayed = array();
866        // Number of plugins known to the plugin manager.
867        $sumtotal = 0;
868        // Number of plugins requiring attention.
869        $sumattention = 0;
870        // List of all components we can cancel installation of.
871        $installabortable = $pluginman->list_cancellable_installations();
872        // List of all components we can cancel upgrade of.
873        $upgradeabortable = $pluginman->list_restorable_archives();
874
875        foreach ($plugininfo as $type => $plugins) {
876
877            $header = new html_table_cell($pluginman->plugintype_name_plural($type));
878            $header->header = true;
879            $header->colspan = count($table->head);
880            $header = new html_table_row(array($header));
881            $header->attributes['class'] = 'plugintypeheader type-' . $type;
882
883            $numdisplayed[$type] = 0;
884
885            if (empty($plugins) and $options['full']) {
886                $msg = new html_table_cell(get_string('noneinstalled', 'core_plugin'));
887                $msg->colspan = count($table->head);
888                $row = new html_table_row(array($msg));
889                $row->attributes['class'] .= 'msg msg-noneinstalled';
890                $table->data[] = $header;
891                $table->data[] = $row;
892                continue;
893            }
894
895            $plugintyperows = array();
896
897            foreach ($plugins as $name => $plugin) {
898                $sumtotal++;
899                $row = new html_table_row();
900                $row->attributes['class'] = 'type-' . $plugin->type . ' name-' . $plugin->type . '_' . $plugin->name;
901
902                if ($this->page->theme->resolve_image_location('icon', $plugin->type . '_' . $plugin->name, null)) {
903                    $icon = $this->output->pix_icon('icon', '', $plugin->type . '_' . $plugin->name, array('class' => 'smallicon pluginicon'));
904                } else {
905                    $icon = '';
906                }
907
908                $displayname = new html_table_cell(
909                    $icon.
910                    html_writer::span($plugin->displayname, 'pluginname').
911                    html_writer::div($plugin->get_dir(), 'plugindir')
912                );
913
914                $versiondb = new html_table_cell($plugin->versiondb);
915                $versiondisk = new html_table_cell($plugin->versiondisk);
916
917                if ($isstandard = $plugin->is_standard()) {
918                    $row->attributes['class'] .= ' standard';
919                    $sourcelabel = html_writer::span(get_string('sourcestd', 'core_plugin'), 'sourcetext label');
920                } else {
921                    $row->attributes['class'] .= ' extension';
922                    $sourcelabel = html_writer::span(get_string('sourceext', 'core_plugin'), 'sourcetext label label-info');
923                }
924
925                $coredependency = $plugin->is_core_dependency_satisfied($version);
926                $otherpluginsdependencies = $pluginman->are_dependencies_satisfied($plugin->get_other_required_plugins());
927                $dependenciesok = $coredependency && $otherpluginsdependencies;
928
929                $statuscode = $plugin->get_status();
930                $row->attributes['class'] .= ' status-' . $statuscode;
931                $statusclass = 'statustext label ';
932                switch ($statuscode) {
933                    case core_plugin_manager::PLUGIN_STATUS_NEW:
934                        $statusclass .= $dependenciesok ? 'label-success' : 'label-warning';
935                        break;
936                    case core_plugin_manager::PLUGIN_STATUS_UPGRADE:
937                        $statusclass .= $dependenciesok ? 'label-info' : 'label-warning';
938                        break;
939                    case core_plugin_manager::PLUGIN_STATUS_MISSING:
940                    case core_plugin_manager::PLUGIN_STATUS_DOWNGRADE:
941                    case core_plugin_manager::PLUGIN_STATUS_DELETE:
942                        $statusclass .= 'label-important';
943                        break;
944                    case core_plugin_manager::PLUGIN_STATUS_NODB:
945                    case core_plugin_manager::PLUGIN_STATUS_UPTODATE:
946                        $statusclass .= $dependenciesok ? '' : 'label-warning';
947                        break;
948                }
949                $status = html_writer::span(get_string('status_' . $statuscode, 'core_plugin'), $statusclass);
950
951                if (!empty($installabortable[$plugin->component])) {
952                    $status .= $this->output->single_button(
953                        new moodle_url($this->page->url, array('abortinstall' => $plugin->component)),
954                        get_string('cancelinstallone', 'core_plugin'),
955                        'post',
956                        array('class' => 'actionbutton cancelinstallone')
957                    );
958                }
959
960                if (!empty($upgradeabortable[$plugin->component])) {
961                    $status .= $this->output->single_button(
962                        new moodle_url($this->page->url, array('abortupgrade' => $plugin->component)),
963                        get_string('cancelupgradeone', 'core_plugin'),
964                        'post',
965                        array('class' => 'actionbutton cancelupgradeone')
966                    );
967                }
968
969                $availableupdates = $plugin->available_updates();
970                if (!empty($availableupdates)) {
971                    foreach ($availableupdates as $availableupdate) {
972                        $status .= $this->plugin_available_update_info($pluginman, $availableupdate);
973                    }
974                }
975
976                $status = new html_table_cell($sourcelabel.' '.$status);
977
978                $requires = new html_table_cell($this->required_column($plugin, $pluginman, $version));
979
980                $statusisboring = in_array($statuscode, array(
981                        core_plugin_manager::PLUGIN_STATUS_NODB, core_plugin_manager::PLUGIN_STATUS_UPTODATE));
982
983                if ($options['xdep']) {
984                    // we want to see only plugins with failed dependencies
985                    if ($dependenciesok) {
986                        continue;
987                    }
988
989                } else if ($statusisboring and $dependenciesok and empty($availableupdates)) {
990                    // no change is going to happen to the plugin - display it only
991                    // if the user wants to see the full list
992                    if (empty($options['full'])) {
993                        continue;
994                    }
995
996                } else {
997                    $sumattention++;
998                }
999
1000                // The plugin should be displayed.
1001                $numdisplayed[$type]++;
1002                $row->cells = array($displayname, $versiondb, $versiondisk, $requires, $status);
1003                $plugintyperows[] = $row;
1004            }
1005
1006            if (empty($numdisplayed[$type]) and empty($options['full'])) {
1007                continue;
1008            }
1009
1010            $table->data[] = $header;
1011            $table->data = array_merge($table->data, $plugintyperows);
1012        }
1013
1014        // Total number of displayed plugins.
1015        $sumdisplayed = array_sum($numdisplayed);
1016
1017        if ($options['xdep']) {
1018            // At the plugins dependencies check page, display the table only.
1019            return html_writer::table($table);
1020        }
1021
1022        $out = $this->output->container_start('', 'plugins-check-info');
1023
1024        if ($sumdisplayed == 0) {
1025            $out .= $this->output->heading(get_string('pluginchecknone', 'core_plugin'));
1026
1027        } else {
1028            if (empty($options['full'])) {
1029                $out .= $this->output->heading(get_string('plugincheckattention', 'core_plugin'));
1030            } else {
1031                $out .= $this->output->heading(get_string('plugincheckall', 'core_plugin'));
1032            }
1033        }
1034
1035        $out .= $this->output->container_start('actions');
1036
1037        $installableupdates = $pluginman->filter_installable($pluginman->available_updates());
1038        if ($installableupdates) {
1039            $out .= $this->output->single_button(
1040                new moodle_url($this->page->url, array('installupdatex' => 1)),
1041                get_string('updateavailableinstallall', 'core_admin', count($installableupdates)),
1042                'post',
1043                array('class' => 'singlebutton updateavailableinstallall')
1044            );
1045        }
1046
1047        if ($installabortable) {
1048            $out .= $this->output->single_button(
1049                new moodle_url($this->page->url, array('abortinstallx' => 1)),
1050                get_string('cancelinstallall', 'core_plugin', count($installabortable)),
1051                'post',
1052                array('class' => 'singlebutton cancelinstallall')
1053            );
1054        }
1055
1056        if ($upgradeabortable) {
1057            $out .= $this->output->single_button(
1058                new moodle_url($this->page->url, array('abortupgradex' => 1)),
1059                get_string('cancelupgradeall', 'core_plugin', count($upgradeabortable)),
1060                'post',
1061                array('class' => 'singlebutton cancelupgradeall')
1062            );
1063        }
1064
1065        $out .= html_writer::div(html_writer::link(new moodle_url($this->page->url, array('showallplugins' => 0)),
1066            get_string('plugincheckattention', 'core_plugin')).' '.html_writer::span($sumattention, 'badge'));
1067
1068        $out .= html_writer::div(html_writer::link(new moodle_url($this->page->url, array('showallplugins' => 1)),
1069            get_string('plugincheckall', 'core_plugin')).' '.html_writer::span($sumtotal, 'badge'));
1070
1071        $out .= $this->output->container_end(); // End of .actions container.
1072        $out .= $this->output->container_end(); // End of #plugins-check-info container.
1073
1074        if ($sumdisplayed > 0 or $options['full']) {
1075            $out .= html_writer::table($table);
1076        }
1077
1078        return $out;
1079    }
1080
1081    /**
1082     * Display the continue / cancel widgets for the plugins management pages.
1083     *
1084     * @param null|moodle_url $continue URL for the continue button, should it be displayed
1085     * @param null|moodle_url $cancel URL for the cancel link, defaults to the current page
1086     * @return string HTML
1087     */
1088    public function plugins_management_confirm_buttons(moodle_url $continue=null, moodle_url $cancel=null) {
1089
1090        $out = html_writer::start_div('plugins-management-confirm-buttons');
1091
1092        if (!empty($continue)) {
1093            $out .= $this->output->single_button($continue, get_string('continue'), 'post', array('class' => 'continue'));
1094        }
1095
1096        if (empty($cancel)) {
1097            $cancel = $this->page->url;
1098        }
1099        $out .= html_writer::div(html_writer::link($cancel, get_string('cancel')), 'cancel');
1100
1101        return $out;
1102    }
1103
1104    /**
1105     * Displays the information about missing dependencies
1106     *
1107     * @param core_plugin_manager $pluginman
1108     * @return string
1109     */
1110    protected function missing_dependencies(core_plugin_manager $pluginman) {
1111
1112        $dependencies = $pluginman->missing_dependencies();
1113
1114        if (empty($dependencies)) {
1115            return '';
1116        }
1117
1118        $available = array();
1119        $unavailable = array();
1120        $unknown = array();
1121
1122        foreach ($dependencies as $component => $remoteinfo) {
1123            if ($remoteinfo === false) {
1124                // The required version is not available. Let us check if there
1125                // is at least some version in the plugins directory.
1126                $remoteinfoanyversion = $pluginman->get_remote_plugin_info($component, ANY_VERSION, false);
1127                if ($remoteinfoanyversion === false) {
1128                    $unknown[$component] = $component;
1129                } else {
1130                    $unavailable[$component] = $remoteinfoanyversion;
1131                }
1132            } else {
1133                $available[$component] = $remoteinfo;
1134            }
1135        }
1136
1137        $out  = $this->output->container_start('plugins-check-dependencies');
1138
1139        if ($unavailable or $unknown) {
1140            $out .= $this->output->heading(get_string('misdepsunavail', 'core_plugin'));
1141            if ($unknown) {
1142                $out .= $this->output->notification(get_string('misdepsunknownlist', 'core_plugin', implode($unknown, ', ')));
1143            }
1144            if ($unavailable) {
1145                $unavailablelist = array();
1146                foreach ($unavailable as $component => $remoteinfoanyversion) {
1147                    $unavailablelistitem = html_writer::link('https://moodle.org/plugins/view.php?plugin='.$component,
1148                        '<strong>'.$remoteinfoanyversion->name.'</strong>');
1149                    if ($remoteinfoanyversion->version) {
1150                        $unavailablelistitem .= ' ('.$component.' &gt; '.$remoteinfoanyversion->version->version.')';
1151                    } else {
1152                        $unavailablelistitem .= ' ('.$component.')';
1153                    }
1154                    $unavailablelist[] = $unavailablelistitem;
1155                }
1156                $out .= $this->output->notification(get_string('misdepsunavaillist', 'core_plugin',
1157                    implode($unavailablelist, ', ')));
1158            }
1159            $out .= $this->output->container_start('plugins-check-dependencies-actions');
1160            $out .= ' '.html_writer::link(new moodle_url('/admin/tool/installaddon/'),
1161                get_string('dependencyuploadmissing', 'core_plugin'));
1162            $out .= $this->output->container_end(); // End of .plugins-check-dependencies-actions container.
1163        }
1164
1165        if ($available) {
1166            $out .= $this->output->heading(get_string('misdepsavail', 'core_plugin'));
1167            $out .= $this->output->container_start('plugins-check-dependencies-actions');
1168
1169            $installable = $pluginman->filter_installable($available);
1170            if ($installable) {
1171                $out .= $this->output->single_button(
1172                    new moodle_url($this->page->url, array('installdepx' => 1)),
1173                    get_string('dependencyinstallmissing', 'core_plugin', count($installable)),
1174                    'post',
1175                    array('class' => 'singlebutton dependencyinstallmissing')
1176                );
1177            }
1178
1179            $out .= html_writer::div(html_writer::link(new moodle_url('/admin/tool/installaddon/'),
1180                get_string('dependencyuploadmissing', 'core_plugin')), 'dependencyuploadmissing');
1181
1182            $out .= $this->output->container_end(); // End of .plugins-check-dependencies-actions container.
1183
1184            $out .= $this->available_missing_dependencies_list($pluginman, $available);
1185        }
1186
1187        $out .= $this->output->container_end(); // End of .plugins-check-dependencies container.
1188
1189        return $out;
1190    }
1191
1192    /**
1193     * Displays the list if available missing dependencies.
1194     *
1195     * @param core_plugin_manager $pluginman
1196     * @param array $dependencies
1197     * @return string
1198     */
1199    protected function available_missing_dependencies_list(core_plugin_manager $pluginman, array $dependencies) {
1200        global $CFG;
1201
1202        $table = new html_table();
1203        $table->id = 'plugins-check-available-dependencies';
1204        $table->head = array(
1205            get_string('displayname', 'core_plugin'),
1206            get_string('release', 'core_plugin'),
1207            get_string('version', 'core_plugin'),
1208            get_string('supportedmoodleversions', 'core_plugin'),
1209            get_string('info', 'core'),
1210        );
1211        $table->colclasses = array('displayname', 'release', 'version', 'supportedmoodleversions', 'info');
1212        $table->data = array();
1213
1214        foreach ($dependencies as $plugin) {
1215
1216            $supportedmoodles = array();
1217            foreach ($plugin->version->supportedmoodles as $moodle) {
1218                if ($CFG->branch == str_replace('.', '', $moodle->release)) {
1219                    $supportedmoodles[] = html_writer::span($moodle->release, 'label label-success');
1220                } else {
1221                    $supportedmoodles[] = html_writer::span($moodle->release, 'label');
1222                }
1223            }
1224
1225            $requriedby = $pluginman->other_plugins_that_require($plugin->component);
1226            if ($requriedby) {
1227                foreach ($requriedby as $ix => $val) {
1228                    $inf = $pluginman->get_plugin_info($val);
1229                    if ($inf) {
1230                        $requriedby[$ix] = $inf->displayname.' ('.$inf->component.')';
1231                    }
1232                }
1233                $info = html_writer::div(
1234                    get_string('requiredby', 'core_plugin', implode(', ', $requriedby)),
1235                    'requiredby'
1236                );
1237            } else {
1238                $info = '';
1239            }
1240
1241            $info .= $this->output->container_start('actions');
1242
1243            $info .= html_writer::div(
1244                html_writer::link('https://moodle.org/plugins/view.php?plugin='.$plugin->component,
1245                    get_string('misdepinfoplugin', 'core_plugin')),
1246                'misdepinfoplugin'
1247            );
1248
1249            $info .= html_writer::div(
1250                html_writer::link('https://moodle.org/plugins/pluginversion.php?id='.$plugin->version->id,
1251                    get_string('misdepinfoversion', 'core_plugin')),
1252                'misdepinfoversion'
1253            );
1254
1255            $info .= html_writer::div(html_writer::link($plugin->version->downloadurl, get_string('download')), 'misdepdownload');
1256
1257            if ($pluginman->is_remote_plugin_installable($plugin->component, $plugin->version->version, $reason)) {
1258                $info .= $this->output->single_button(
1259                    new moodle_url($this->page->url, array('installdep' => $plugin->component)),
1260                    get_string('dependencyinstall', 'core_plugin'),
1261                    'post',
1262                    array('class' => 'singlebutton dependencyinstall')
1263                );
1264            } else {
1265                $reasonhelp = $this->info_remote_plugin_not_installable($reason);
1266                if ($reasonhelp) {
1267                    $info .= html_writer::div($reasonhelp, 'reasonhelp dependencyinstall');
1268                }
1269            }
1270
1271            $info .= $this->output->container_end(); // End of .actions container.
1272
1273            $table->data[] = array(
1274                html_writer::div($plugin->name, 'name').' '.html_writer::div($plugin->component, 'component'),
1275                $plugin->version->release,
1276                $plugin->version->version,
1277                implode($supportedmoodles, ' '),
1278                $info
1279            );
1280        }
1281
1282        return html_writer::table($table);
1283    }
1284
1285    /**
1286     * Explain why {@link core_plugin_manager::is_remote_plugin_installable()} returned false.
1287     *
1288     * @param string $reason the reason code as returned by the plugin manager
1289     * @return string
1290     */
1291    protected function info_remote_plugin_not_installable($reason) {
1292
1293        if ($reason === 'notwritableplugintype' or $reason === 'notwritableplugin') {
1294            return $this->output->help_icon('notwritable', 'core_plugin', get_string('notwritable', 'core_plugin'));
1295        }
1296
1297        if ($reason === 'remoteunavailable') {
1298            return $this->output->help_icon('notdownloadable', 'core_plugin', get_string('notdownloadable', 'core_plugin'));
1299        }
1300
1301        return false;
1302    }
1303
1304    /**
1305     * Formats the information that needs to go in the 'Requires' column.
1306     * @param \core\plugininfo\base $plugin the plugin we are rendering the row for.
1307     * @param core_plugin_manager $pluginman provides data on all the plugins.
1308     * @param string $version
1309     * @return string HTML code
1310     */
1311    protected function required_column(\core\plugininfo\base $plugin, core_plugin_manager $pluginman, $version) {
1312
1313        $requires = array();
1314        $displayuploadlink = false;
1315        $displayupdateslink = false;
1316
1317        foreach ($pluginman->resolve_requirements($plugin, $version) as $reqname => $reqinfo) {
1318            if ($reqname === 'core') {
1319                if ($reqinfo->status == $pluginman::REQUIREMENT_STATUS_OK) {
1320                    $class = 'requires-ok';
1321                    $label = '';
1322                } else {
1323                    $class = 'requires-failed';
1324                    $label = html_writer::span(get_string('dependencyfails', 'core_plugin'), 'label label-important');
1325                }
1326                $requires[] = html_writer::tag('li',
1327                    html_writer::span(get_string('moodleversion', 'core_plugin', $plugin->versionrequires), 'dep dep-core').
1328                    ' '.$label, array('class' => $class));
1329
1330            } else {
1331                $actions = array();
1332
1333                if ($reqinfo->status == $pluginman::REQUIREMENT_STATUS_OK) {
1334                    $label = '';
1335                    $class = 'requires-ok';
1336
1337                } else if ($reqinfo->status == $pluginman::REQUIREMENT_STATUS_MISSING) {
1338                    if ($reqinfo->availability == $pluginman::REQUIREMENT_AVAILABLE) {
1339                        $label = html_writer::span(get_string('dependencymissing', 'core_plugin'), 'label label-warning');
1340                        $label .= ' '.html_writer::span(get_string('dependencyavailable', 'core_plugin'), 'label label-warning');
1341                        $class = 'requires-failed requires-missing requires-available';
1342                        $actions[] = html_writer::link(
1343                            new moodle_url('https://moodle.org/plugins/view.php', array('plugin' => $reqname)),
1344                            get_string('misdepinfoplugin', 'core_plugin')
1345                        );
1346
1347                    } else {
1348                        $label = html_writer::span(get_string('dependencymissing', 'core_plugin'), 'label label-important');
1349                        $label .= ' '.html_writer::span(get_string('dependencyunavailable', 'core_plugin'),
1350                            'label label-important');
1351                        $class = 'requires-failed requires-missing requires-unavailable';
1352                    }
1353                    $displayuploadlink = true;
1354
1355                } else if ($reqinfo->status == $pluginman::REQUIREMENT_STATUS_OUTDATED) {
1356                    if ($reqinfo->availability == $pluginman::REQUIREMENT_AVAILABLE) {
1357                        $label = html_writer::span(get_string('dependencyfails', 'core_plugin'), 'label label-warning');
1358                        $label .= ' '.html_writer::span(get_string('dependencyavailable', 'core_plugin'), 'label label-warning');
1359                        $class = 'requires-failed requires-outdated requires-available';
1360                        $displayupdateslink = true;
1361
1362                    } else {
1363                        $label = html_writer::span(get_string('dependencyfails', 'core_plugin'), 'label label-important');
1364                        $label .= ' '.html_writer::span(get_string('dependencyunavailable', 'core_plugin'),
1365                            'label label-important');
1366                        $class = 'requires-failed requires-outdated requires-unavailable';
1367                    }
1368                    $displayuploadlink = true;
1369                }
1370
1371                if ($reqinfo->reqver != ANY_VERSION) {
1372                    $str = 'otherpluginversion';
1373                } else {
1374                    $str = 'otherplugin';
1375                }
1376
1377                $requires[] = html_writer::tag('li', html_writer::span(
1378                    get_string($str, 'core_plugin', array('component' => $reqname, 'version' => $reqinfo->reqver)),
1379                    'dep dep-plugin').' '.$label.' '.html_writer::span(implode(' | ', $actions), 'actions'),
1380                    array('class' => $class)
1381                );
1382            }
1383        }
1384
1385        if (!$requires) {
1386            return '';
1387        }
1388
1389        $out = html_writer::tag('ul', implode("\n", $requires));
1390
1391        if ($displayuploadlink) {
1392            $out .= html_writer::div(
1393                html_writer::link(
1394                    new moodle_url('/admin/tool/installaddon/'),
1395                    get_string('dependencyuploadmissing', 'core_plugin')
1396                ),
1397                'dependencyuploadmissing'
1398            );
1399        }
1400
1401        if ($displayupdateslink) {
1402            $out .= html_writer::div(
1403                html_writer::link(
1404                    new moodle_url($this->page->url, array('sesskey' => sesskey(), 'fetchupdates' => 1)),
1405                    get_string('checkforupdates', 'core_plugin')
1406                ),
1407                'checkforupdates'
1408            );
1409        }
1410
1411        return $out;
1412
1413    }
1414
1415    /**
1416     * Prints an overview about the plugins - number of installed, number of extensions etc.
1417     *
1418     * @param core_plugin_manager $pluginman provides information about the plugins
1419     * @param array $options filtering options
1420     * @return string as usually
1421     */
1422    public function plugins_overview_panel(core_plugin_manager $pluginman, array $options = array()) {
1423
1424        $plugininfo = $pluginman->get_plugins();
1425
1426        $numtotal = $numextension = $numupdatable = 0;
1427
1428        foreach ($plugininfo as $type => $plugins) {
1429            foreach ($plugins as $name => $plugin) {
1430                if ($plugin->available_updates()) {
1431                    $numupdatable++;
1432                }
1433                if ($plugin->get_status() === core_plugin_manager::PLUGIN_STATUS_MISSING) {
1434                    continue;
1435                }
1436                $numtotal++;
1437                if (!$plugin->is_standard()) {
1438                    $numextension++;
1439                }
1440            }
1441        }
1442
1443        $infoall = html_writer::link(
1444            new moodle_url($this->page->url, array('contribonly' => 0, 'updatesonly' => 0)),
1445            get_string('overviewall', 'core_plugin'),
1446            array('title' => get_string('filterall', 'core_plugin'))
1447        ).' '.html_writer::span($numtotal, 'badge number number-all');
1448
1449        $infoext = html_writer::link(
1450            new moodle_url($this->page->url, array('contribonly' => 1, 'updatesonly' => 0)),
1451            get_string('overviewext', 'core_plugin'),
1452            array('title' => get_string('filtercontribonly', 'core_plugin'))
1453        ).' '.html_writer::span($numextension, 'badge number number-additional');
1454
1455        if ($numupdatable) {
1456            $infoupdatable = html_writer::link(
1457                new moodle_url($this->page->url, array('contribonly' => 0, 'updatesonly' => 1)),
1458                get_string('overviewupdatable', 'core_plugin'),
1459                array('title' => get_string('filterupdatesonly', 'core_plugin'))
1460            ).' '.html_writer::span($numupdatable, 'badge badge-info number number-updatable');
1461        } else {
1462            // No updates, or the notifications disabled.
1463            $infoupdatable = '';
1464        }
1465
1466        $out = html_writer::start_div('', array('id' => 'plugins-overview-panel'));
1467
1468        if (!empty($options['updatesonly'])) {
1469            $out .= $this->output->heading(get_string('overviewupdatable', 'core_plugin'), 3);
1470        } else if (!empty($options['contribonly'])) {
1471            $out .= $this->output->heading(get_string('overviewext', 'core_plugin'), 3);
1472        }
1473
1474        if ($numupdatable) {
1475            $installableupdates = $pluginman->filter_installable($pluginman->available_updates());
1476            if ($installableupdates) {
1477                $out .= $this->output->single_button(
1478                    new moodle_url($this->page->url, array('installupdatex' => 1)),
1479                    get_string('updateavailableinstallall', 'core_admin', count($installableupdates)),
1480                    'post',
1481                    array('class' => 'singlebutton updateavailableinstallall')
1482                );
1483            }
1484        }
1485
1486        $out .= html_writer::div($infoall, 'info info-all').
1487            html_writer::div($infoext, 'info info-ext').
1488            html_writer::div($infoupdatable, 'info info-updatable');
1489
1490        $out .= html_writer::end_div(); // End of #plugins-overview-panel block.
1491
1492        return $out;
1493    }
1494
1495    /**
1496     * Displays all known plugins and links to manage them
1497     *
1498     * This default implementation renders all plugins into one big table.
1499     *
1500     * @param core_plugin_manager $pluginman provides information about the plugins.
1501     * @param array $options filtering options
1502     * @return string HTML code
1503     */
1504    public function plugins_control_panel(core_plugin_manager $pluginman, array $options = array()) {
1505
1506        $plugininfo = $pluginman->get_plugins();
1507
1508        // Filter the list of plugins according the options.
1509        if (!empty($options['updatesonly'])) {
1510            $updateable = array();
1511            foreach ($plugininfo as $plugintype => $pluginnames) {
1512                foreach ($pluginnames as $pluginname => $pluginfo) {
1513                    $pluginavailableupdates = $pluginfo->available_updates();
1514                    if (!empty($pluginavailableupdates)) {
1515                        foreach ($pluginavailableupdates as $pluginavailableupdate) {
1516                            $updateable[$plugintype][$pluginname] = $pluginfo;
1517                        }
1518                    }
1519                }
1520            }
1521            $plugininfo = $updateable;
1522        }
1523
1524        if (!empty($options['contribonly'])) {
1525            $contribs = array();
1526            foreach ($plugininfo as $plugintype => $pluginnames) {
1527                foreach ($pluginnames as $pluginname => $pluginfo) {
1528                    if (!$pluginfo->is_standard()) {
1529                        $contribs[$plugintype][$pluginname] = $pluginfo;
1530                    }
1531                }
1532            }
1533            $plugininfo = $contribs;
1534        }
1535
1536        if (empty($plugininfo)) {
1537            return '';
1538        }
1539
1540        $table = new html_table();
1541        $table->id = 'plugins-control-panel';
1542        $table->head = array(
1543            get_string('displayname', 'core_plugin'),
1544            get_string('version', 'core_plugin'),
1545            get_string('availability', 'core_plugin'),
1546            get_string('actions', 'core_plugin'),
1547            get_string('notes','core_plugin'),
1548        );
1549        $table->headspan = array(1, 1, 1, 2, 1);
1550        $table->colclasses = array(
1551            'pluginname', 'version', 'availability', 'settings', 'uninstall', 'notes'
1552        );
1553
1554        foreach ($plugininfo as $type => $plugins) {
1555            $heading = $pluginman->plugintype_name_plural($type);
1556            $pluginclass = core_plugin_manager::resolve_plugininfo_class($type);
1557            if ($manageurl = $pluginclass::get_manage_url()) {
1558                $heading .= $this->output->action_icon($manageurl, new pix_icon('i/settings',
1559                    get_string('settings', 'core_plugin')));
1560            }
1561            $header = new html_table_cell(html_writer::tag('span', $heading, array('id'=>'plugin_type_cell_'.$type)));
1562            $header->header = true;
1563            $header->colspan = array_sum($table->headspan);
1564            $header = new html_table_row(array($header));
1565            $header->attributes['class'] = 'plugintypeheader type-' . $type;
1566            $table->data[] = $header;
1567
1568            if (empty($plugins)) {
1569                $msg = new html_table_cell(get_string('noneinstalled', 'core_plugin'));
1570                $msg->colspan = array_sum($table->headspan);
1571                $row = new html_table_row(array($msg));
1572                $row->attributes['class'] .= 'msg msg-noneinstalled';
1573                $table->data[] = $row;
1574                continue;
1575            }
1576
1577            foreach ($plugins as $name => $plugin) {
1578                $row = new html_table_row();
1579                $row->attributes['class'] = 'type-' . $plugin->type . ' name-' . $plugin->type . '_' . $plugin->name;
1580
1581                if ($this->page->theme->resolve_image_location('icon', $plugin->type . '_' . $plugin->name)) {
1582                    $icon = $this->output->pix_icon('icon', '', $plugin->type . '_' . $plugin->name, array('class' => 'icon pluginicon'));
1583                } else {
1584                    $icon = $this->output->pix_icon('spacer', '', 'moodle', array('class' => 'icon pluginicon noicon'));
1585                }
1586                $status = $plugin->get_status();
1587                $row->attributes['class'] .= ' status-'.$status;
1588                $pluginname  = html_writer::tag('div', $icon.$plugin->displayname, array('class' => 'displayname')).
1589                               html_writer::tag('div', $plugin->component, array('class' => 'componentname'));
1590                $pluginname  = new html_table_cell($pluginname);
1591
1592                $version = html_writer::div($plugin->versiondb, 'versionnumber');
1593                if ((string)$plugin->release !== '') {
1594                    $version = html_writer::div($plugin->release, 'release').$version;
1595                }
1596                $version = new html_table_cell($version);
1597
1598                $isenabled = $plugin->is_enabled();
1599                if (is_null($isenabled)) {
1600                    $availability = new html_table_cell('');
1601                } else if ($isenabled) {
1602                    $row->attributes['class'] .= ' enabled';
1603                    $availability = new html_table_cell(get_string('pluginenabled', 'core_plugin'));
1604                } else {
1605                    $row->attributes['class'] .= ' disabled';
1606                    $availability = new html_table_cell(get_string('plugindisabled', 'core_plugin'));
1607                }
1608
1609                $settingsurl = $plugin->get_settings_url();
1610                if (!is_null($settingsurl)) {
1611                    $settings = html_writer::link($settingsurl, get_string('settings', 'core_plugin'), array('class' => 'settings'));
1612                } else {
1613                    $settings = '';
1614                }
1615                $settings = new html_table_cell($settings);
1616
1617                if ($uninstallurl = $pluginman->get_uninstall_url($plugin->component, 'overview')) {
1618                    $uninstall = html_writer::link($uninstallurl, get_string('uninstall', 'core_plugin'));
1619                } else {
1620                    $uninstall = '';
1621                }
1622                $uninstall = new html_table_cell($uninstall);
1623
1624                if ($plugin->is_standard()) {
1625                    $row->attributes['class'] .= ' standard';
1626                    $source = '';
1627                } else {
1628                    $row->attributes['class'] .= ' extension';
1629                    $source = html_writer::div(get_string('sourceext', 'core_plugin'), 'source label label-info');
1630                }
1631
1632                if ($status === core_plugin_manager::PLUGIN_STATUS_MISSING) {
1633                    $msg = html_writer::div(get_string('status_missing', 'core_plugin'), 'statusmsg label label-important');
1634                } else if ($status === core_plugin_manager::PLUGIN_STATUS_NEW) {
1635                    $msg = html_writer::div(get_string('status_new', 'core_plugin'), 'statusmsg label label-success');
1636                } else {
1637                    $msg = '';
1638                }
1639
1640                $requriedby = $pluginman->other_plugins_that_require($plugin->component);
1641                if ($requriedby) {
1642                    $requiredby = html_writer::tag('div', get_string('requiredby', 'core_plugin', implode(', ', $requriedby)),
1643                        array('class' => 'requiredby'));
1644                } else {
1645                    $requiredby = '';
1646                }
1647
1648                $updateinfo = '';
1649                if (is_array($plugin->available_updates())) {
1650                    foreach ($plugin->available_updates() as $availableupdate) {
1651                        $updateinfo .= $this->plugin_available_update_info($pluginman, $availableupdate);
1652                    }
1653                }
1654
1655                $notes = new html_table_cell($source.$msg.$requiredby.$updateinfo);
1656
1657                $row->cells = array(
1658                    $pluginname, $version, $availability, $settings, $uninstall, $notes
1659                );
1660                $table->data[] = $row;
1661            }
1662        }
1663
1664        return html_writer::table($table);
1665    }
1666
1667    /**
1668     * Helper method to render the information about the available plugin update
1669     *
1670     * @param core_plugin_manager $pluginman plugin manager instance
1671     * @param \core\update\info $updateinfo information about the available update for the plugin
1672     */
1673    protected function plugin_available_update_info(core_plugin_manager $pluginman, \core\update\info $updateinfo) {
1674
1675        $boxclasses = 'pluginupdateinfo';
1676        $info = array();
1677
1678        if (isset($updateinfo->release)) {
1679            $info[] = html_writer::div(
1680                get_string('updateavailable_release', 'core_plugin', $updateinfo->release),
1681                'info release'
1682            );
1683        }
1684
1685        if (isset($updateinfo->maturity)) {
1686            $info[] = html_writer::div(
1687                get_string('maturity'.$updateinfo->maturity, 'core_admin'),
1688                'info maturity'
1689            );
1690            $boxclasses .= ' maturity'.$updateinfo->maturity;
1691        }
1692
1693        if (isset($updateinfo->download)) {
1694            $info[] = html_writer::div(
1695                html_writer::link($updateinfo->download, get_string('download')),
1696                'info download'
1697            );
1698        }
1699
1700        if (isset($updateinfo->url)) {
1701            $info[] = html_writer::div(
1702                html_writer::link($updateinfo->url, get_string('updateavailable_moreinfo', 'core_plugin')),
1703                'info more'
1704            );
1705        }
1706
1707        $box = html_writer::start_div($boxclasses);
1708        $box .= html_writer::div(
1709            get_string('updateavailable', 'core_plugin', $updateinfo->version),
1710            'version'
1711        );
1712        $box .= html_writer::div(
1713            implode(html_writer::span(' ', 'separator'), $info),
1714            'infos'
1715        );
1716
1717        if ($pluginman->is_remote_plugin_installable($updateinfo->component, $updateinfo->version, $reason)) {
1718            $box .= $this->output->single_button(
1719                new moodle_url($this->page->url, array('installupdate' => $updateinfo->component,
1720                    'installupdateversion' => $updateinfo->version)),
1721                get_string('updateavailableinstall', 'core_admin'),
1722                'post',
1723                array('class' => 'singlebutton updateavailableinstall')
1724            );
1725        } else {
1726            $reasonhelp = $this->info_remote_plugin_not_installable($reason);
1727            if ($reasonhelp) {
1728                $box .= html_writer::div($reasonhelp, 'reasonhelp updateavailableinstall');
1729            }
1730        }
1731        $box .= html_writer::end_div();
1732
1733        return $box;
1734    }
1735
1736    /**
1737     * This function will render one beautiful table with all the environmental
1738     * configuration and how it suits Moodle needs.
1739     *
1740     * @param boolean $result final result of the check (true/false)
1741     * @param environment_results[] $environment_results array of results gathered
1742     * @return string HTML to output.
1743     */
1744    public function environment_check_table($result, $environment_results) {
1745        global $CFG;
1746
1747        // Table headers
1748        $servertable = new html_table();//table for server checks
1749        $servertable->head  = array(
1750            get_string('name'),
1751            get_string('info'),
1752            get_string('report'),
1753            get_string('plugin'),
1754            get_string('status'),
1755        );
1756        $servertable->colclasses = array('centeralign name', 'centeralign info', 'leftalign report', 'leftalign plugin', 'centeralign status');
1757        $servertable->attributes['class'] = 'admintable environmenttable generaltable';
1758        $servertable->id = 'serverstatus';
1759
1760        $serverdata = array('ok'=>array(), 'warn'=>array(), 'error'=>array());
1761
1762        $othertable = new html_table();//table for custom checks
1763        $othertable->head  = array(
1764            get_string('info'),
1765            get_string('report'),
1766            get_string('plugin'),
1767            get_string('status'),
1768        );
1769        $othertable->colclasses = array('aligncenter info', 'alignleft report', 'alignleft plugin', 'aligncenter status');
1770        $othertable->attributes['class'] = 'admintable environmenttable generaltable';
1771        $othertable->id = 'otherserverstatus';
1772
1773        $otherdata = array('ok'=>array(), 'warn'=>array(), 'error'=>array());
1774
1775        // Iterate over each environment_result
1776        $continue = true;
1777        foreach ($environment_results as $environment_result) {
1778            $errorline   = false;
1779            $warningline = false;
1780            $stringtouse = '';
1781            if ($continue) {
1782                $type = $environment_result->getPart();
1783                $info = $environment_result->getInfo();
1784                $status = $environment_result->getStatus();
1785                $plugin = $environment_result->getPluginName();
1786                $error_code = $environment_result->getErrorCode();
1787                // Process Report field
1788                $rec = new stdClass();
1789                // Something has gone wrong at parsing time
1790                if ($error_code) {
1791                    $stringtouse = 'environmentxmlerror';
1792                    $rec->error_code = $error_code;
1793                    $status = get_string('error');
1794                    $errorline = true;
1795                    $continue = false;
1796                }
1797
1798                if ($continue) {
1799                    if ($rec->needed = $environment_result->getNeededVersion()) {
1800                        // We are comparing versions
1801                        $rec->current = $environment_result->getCurrentVersion();
1802                        if ($environment_result->getLevel() == 'required') {
1803                            $stringtouse = 'environmentrequireversion';
1804                        } else {
1805                            $stringtouse = 'environmentrecommendversion';
1806                        }
1807
1808                    } else if ($environment_result->getPart() == 'custom_check') {
1809                        // We are checking installed & enabled things
1810                        if ($environment_result->getLevel() == 'required') {
1811                            $stringtouse = 'environmentrequirecustomcheck';
1812                        } else {
1813                            $stringtouse = 'environmentrecommendcustomcheck';
1814                        }
1815
1816                    } else if ($environment_result->getPart() == 'php_setting') {
1817                        if ($status) {
1818                            $stringtouse = 'environmentsettingok';
1819                        } else if ($environment_result->getLevel() == 'required') {
1820                            $stringtouse = 'environmentmustfixsetting';
1821                        } else {
1822                            $stringtouse = 'environmentshouldfixsetting';
1823                        }
1824
1825                    } else {
1826                        if ($environment_result->getLevel() == 'required') {
1827                            $stringtouse = 'environmentrequireinstall';
1828                        } else {
1829                            $stringtouse = 'environmentrecommendinstall';
1830                        }
1831                    }
1832
1833                    // Calculate the status value
1834                    if ($environment_result->getBypassStr() != '') {            //Handle bypassed result (warning)
1835                        $status = get_string('bypassed');
1836                        $warningline = true;
1837                    } else if ($environment_result->getRestrictStr() != '') {   //Handle restricted result (error)
1838                        $status = get_string('restricted');
1839                        $errorline = true;
1840                    } else {
1841                        if ($status) {                                          //Handle ok result (ok)
1842                            $status = get_string('ok');
1843                        } else {
1844                            if ($environment_result->getLevel() == 'optional') {//Handle check result (warning)
1845                                $status = get_string('check');
1846                                $warningline = true;
1847                            } else {                                            //Handle error result (error)
1848                                $status = get_string('check');
1849                                $errorline = true;
1850                            }
1851                        }
1852                    }
1853                }
1854
1855                // Build the text
1856                $linkparts = array();
1857                $linkparts[] = 'admin/environment';
1858                $linkparts[] = $type;
1859                if (!empty($info)){
1860                   $linkparts[] = $info;
1861                }
1862                // Plugin environments do not have docs pages yet.
1863                if (empty($CFG->docroot) or $environment_result->plugin) {
1864                    $report = get_string($stringtouse, 'admin', $rec);
1865                } else {
1866                    $report = $this->doc_link(join($linkparts, '/'), get_string($stringtouse, 'admin', $rec));
1867                }
1868
1869                // Format error or warning line
1870                if ($errorline || $warningline) {
1871                    $messagetype = $errorline? 'error':'warn';
1872                } else {
1873                    $messagetype = 'ok';
1874                }
1875                $status = '<span class="'.$messagetype.'">'.$status.'</span>';
1876                // Here we'll store all the feedback found
1877                $feedbacktext = '';
1878                // Append the feedback if there is some
1879                $feedbacktext .= $environment_result->strToReport($environment_result->getFeedbackStr(), $messagetype);
1880                //Append the bypass if there is some
1881                $feedbacktext .= $environment_result->strToReport($environment_result->getBypassStr(), 'warn');
1882                //Append the restrict if there is some
1883                $feedbacktext .= $environment_result->strToReport($environment_result->getRestrictStr(), 'error');
1884
1885                $report .= $feedbacktext;
1886
1887                // Add the row to the table
1888                if ($environment_result->getPart() == 'custom_check'){
1889                    $otherdata[$messagetype][] = array ($info, $report, $plugin, $status);
1890                } else {
1891                    $serverdata[$messagetype][] = array ($type, $info, $report, $plugin, $status);
1892                }
1893            }
1894        }
1895
1896        //put errors first in
1897        $servertable->data = array_merge($serverdata['error'], $serverdata['warn'], $serverdata['ok']);
1898        $othertable->data = array_merge($otherdata['error'], $otherdata['warn'], $otherdata['ok']);
1899
1900        // Print table
1901        $output = '';
1902        $output .= $this->heading(get_string('serverchecks', 'admin'));
1903        $output .= html_writer::table($servertable);
1904        if (count($othertable->data)){
1905            $output .= $this->heading(get_string('customcheck', 'admin'));
1906            $output .= html_writer::table($othertable);
1907        }
1908
1909        // Finally, if any error has happened, print the summary box
1910        if (!$result) {
1911            $output .= $this->box(get_string('environmenterrortodo', 'admin'), 'environmentbox errorbox');
1912        }
1913
1914        return $output;
1915    }
1916
1917    /**
1918     * Render a simple page for providing the upgrade key.
1919     *
1920     * @param moodle_url|string $url
1921     * @return string
1922     */
1923    public function upgradekey_form_page($url) {
1924
1925        $output = '';
1926        $output .= $this->header();
1927        $output .= $this->container_start('upgradekeyreq');
1928        $output .= $this->heading(get_string('upgradekeyreq', 'core_admin'));
1929        $output .= html_writer::start_tag('form', array('method' => 'POST', 'action' => $url));
1930        $output .= html_writer::empty_tag('input', array('name' => 'upgradekey', 'type' => 'password'));
1931        $output .= html_writer::empty_tag('input', array('value' => get_string('submit'), 'type' => 'submit'));
1932        $output .= html_writer::end_tag('form');
1933        $output .= $this->container_end();
1934        $output .= $this->footer();
1935
1936        return $output;
1937    }
1938}
Note: See TracBrowser for help on using the repository browser.