Skip to content

Commit

Permalink
Merge branch 'mdl67898-check-setting-admintree' of https://github.com…
Browse files Browse the repository at this point in the history
  • Loading branch information
ilyatregubov committed Nov 23, 2023
2 parents e93a025 + dc7953c commit abf2c56
Show file tree
Hide file tree
Showing 16 changed files with 760 additions and 6 deletions.
4 changes: 4 additions & 0 deletions admin/settings/plugins.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,10 @@
$temp = new admin_settingpage('manageantiviruses', new lang_string('antivirussettings', 'antivirus'));
$temp->add(new admin_setting_manageantiviruses());

// Status check.
$temp->add(new admin_setting_heading('antivirus/statuschecks', new lang_string('statuschecks'), ''));
$temp->add(new admin_setting_check('antivirus/checkantivirus', new \core\check\environment\antivirus()));

// Common settings.
$temp->add(new admin_setting_heading('antiviruscommonsettings', new lang_string('antiviruscommonsettings', 'antivirus'), ''));

Expand Down
3 changes: 3 additions & 0 deletions lang/en/moodle.php
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,7 @@
$string['changessaved'] = 'Changes saved';
$string['check'] = 'Check';
$string['checkactual'] = 'Actual';
$string['checkerror'] = 'Error getting result of check \'{$a}\'. Check the browser console for more information.';
$string['checkexpected'] = 'Expected';
$string['checks'] = 'Checks';
$string['checksok'] = 'All \'{$a}\' checks OK';
Expand All @@ -1075,6 +1076,7 @@
$string['checkinginstances'] = 'Checking instances';
$string['checkingsections'] = 'Checking sections';
$string['checklanguage'] = 'Check language';
$string['checkloading'] = 'Getting the result of check \'{$a}\'';
$string['checknone'] = 'Check none';
$string['childcoursenotfound'] = 'Child course not found!';
$string['childcourses'] = 'Child courses';
Expand Down Expand Up @@ -2171,6 +2173,7 @@
$string['statsuserwrites'] = 'Posts';
$string['statswrites'] = 'Posts';
$string['status'] = 'Status';
$string['statuschecks'] = 'Status checks';
$string['statuscritical'] = 'Critical';
$string['statusinfo'] = 'Info';
$string['statusna'] = 'N/A';
Expand Down
97 changes: 97 additions & 0 deletions lib/adminlib.php
Original file line number Diff line number Diff line change
Expand Up @@ -11679,3 +11679,100 @@ public function load_choices() {
return true;
}
}

/**
* Displays the result of a check via ajax.
*
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Matthew Hilton <matthewhilton@catalyst-au.net>
* @copyright Catalyst IT, 2023
*/
class admin_setting_check extends admin_setting {

/** @var \core\check\check $check the check to use **/
private $check;

/** @var bool $includedetails if the details of result are included. **/
private $includedetails;

/**
* Creates check setting.
*
* @param string $name name of setting
* @param \core\check\check $check The check linked to this setting.
* @param bool $includedetails if the details of the result are included
*/
public function __construct(string $name, \core\check\check $check, bool $includedetails = false) {
$this->check = $check;
$this->includedetails = $includedetails;
$heading = $check->get_name();

parent::__construct($name, $heading, '', '');
}

/**
* Returns the check linked to this setting.
*
* @return \core\check\check
*/
public function get_check() {
return $this->check;
}

/**
* Returns setting (unused)
*
* @return true
*/
public function get_setting() {
return true;
}

/**
* Writes the setting (unused)
*
* @param mixed $data
*/
public function write_setting($data) {
return '';
}

/**
* Outputs the admin setting HTML to be rendered.
*
* @param mixed $data
* @param string $query
* @return string html
*/
public function output_html($data, $query = '') {
global $PAGE, $OUTPUT;

$domref = uniqid($this->check->get_ref());

// The actual result is obtained via ajax,
// since its likely somewhat slow to obtain.
$context = [
'domselector' => '[data-check-reference="' . $domref . '"]',
'admintreeid' => $this->get_id(),
'settingname' => $this->name,
'includedetails' => $this->includedetails,
];
$PAGE->requires->js_call_amd('core/check/check_result', 'getAndRender', $context);

// Render a generic loading icon while waiting for ajax.
$loadingstr = get_string('checkloading', '', $this->check->get_name());
$loadingicon = $OUTPUT->pix_icon('i/loading', $loadingstr);

// Wrap it in a notification so we reduce style changes when loading is finished.
$output = $OUTPUT->notification($loadingicon . $loadingstr, \core\output\notification::NOTIFY_INFO, false);

// Add the action link.
$output .= $OUTPUT->render($this->check->get_action_link());

// Wrap in a div with a reference. The JS getAndRender will replace this with the response from the webservice.
$statusdiv = \html_writer::div($output, '', ['data-check-reference' => $domref]);

return format_admin_setting($this, $this->visiblename, '', $statusdiv);
}
}

12 changes: 12 additions & 0 deletions lib/amd/build/check/check_result.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions lib/amd/build/check/check_result.min.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions lib/amd/build/check/repository.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions lib/amd/build/check/repository.min.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 63 additions & 0 deletions lib/amd/src/check/check_result.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Check API result functions
*
* @module core/check
* @author Matthew Hilton <matthewhilton@catalyst-au.net>
* @copyright Catalyst IT, 2023
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

import {getCheckResult} from './repository';
import {getString} from 'core/str';
import * as Templates from 'core/templates';

/**
* Get the result of a check and replace a given DOM element with the result.
*
* @method getAndRender
* @param {String} domSelector A CSS selector for a dom element to replace the the HTML for.
* @param {String} adminTreeId Id of the admin_setting that called this webservice. Used to retrieve the check registered to it.
* @param {String} settingName Name of setting (used to find the parent node in the admin tree)
* @param {Boolean} includeDetails If true, details will be included in the check.
* By default only the status and the summary is returned.
*/
export async function getAndRender(domSelector, adminTreeId, settingName, includeDetails) {
const element = document.querySelector(domSelector);

if (!element) {
window.console.error('Check selector not found');
return;
}

try {
const result = await getCheckResult(adminTreeId, settingName, includeDetails);
const decoded = new DOMParser().parseFromString(result.html, "text/html").documentElement.textContent;
element.innerHTML = decoded;
} catch (e) {
window.console.error(e);

// Render error as a red notification.
element.innerHTML = await Templates.render('core/notification', {
iserror: true,
closebutton: false,
announce: 0,
extraclasses: '',
message: await getString('checkerror', 'core', adminTreeId)
});
}
}
42 changes: 42 additions & 0 deletions lib/amd/src/check/repository.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Check API webservice repository
*
* @module core/check
* @author Matthew Hilton <matthewhilton@catalyst-au.net>
* @copyright Catalyst IT, 2023
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

import {call as fetchMany} from 'core/ajax';

/**
* Call check_get_result webservice function
*
* @param {String} adminTreeId Id of the admin_setting that called this webservice. Used to retrieve the check registered to it.
* @param {String} settingName Setting name (used to find it's parent)
* @param {Boolean} includeDetails If details should be included in the response
*/
export const getCheckResult = (adminTreeId, settingName, includeDetails) => fetchMany([{
methodname: 'core_check_get_result_admintree',
args: {
admintreeid: adminTreeId,
settingname: settingName,
includedetails: includeDetails,
},
}])[0];

22 changes: 18 additions & 4 deletions lib/classes/check/check.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
*/
namespace core\check;

defined('MOODLE_INTERNAL') || die();
use coding_exception;

/**
* Base class for checks
Expand All @@ -37,17 +37,31 @@ abstract class check {
/**
* @var string $component - The component / plugin this task belongs to.
*
* This is autopopulated by the check manager.
* This can be autopopulated by the check manager.
* Otherwise, it is dynamically determined by get_component().
*/
protected $component = 'core';
protected $component = '';

/**
* Get the frankenstyle component name
*
* @return string
*/
public function get_component(): string {
return $this->component;
// Return component if has been set by the manager.
if (!empty($this->component)) {
return $this->component;
}

// Else work it out based on the classname.
// Because the first part of the classname is always the component.
$parts = explode("\\", get_called_class());

if (empty($parts)) {
throw new coding_exception("Unable to determine component for check");
}

return $parts[0];
}

/**
Expand Down
Loading

0 comments on commit abf2c56

Please sign in to comment.