diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..efb8d3b --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,12 @@ +# .github/workflows/ci.yml +name: ci + +on: [push, pull_request] + +jobs: + ci: + uses: catalyst/catalyst-moodle-workflows/.github/workflows/ci.yml@main + secrets: + moodle_org_token: ${{ secrets.MOODLE_ORG_TOKEN }} + with: + disable_behat: true diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 85658ae..0000000 --- a/.travis.yml +++ /dev/null @@ -1,114 +0,0 @@ -language: php - -cache: - directories: - - $HOME/.composer/cache - - $HOME/.npm - -php: - - 7.2 - -sudo: required - -addons: - firefox: "35.0.1" - postgresql: "9.6" - -services: - - mysql - -matrix: - include: - - php: 7.0 - env: DB=mysqli MOODLE_BRANCH=MOODLE_35_STABLE - - php: 7.0 - env: DB=pgsql MOODLE_BRANCH=MOODLE_35_STABLE - - php: 7.1 - env: DB=mysqli MOODLE_BRANCH=MOODLE_35_STABLE - - php: 7.1 - env: DB=pgsql MOODLE_BRANCH=MOODLE_35_STABLE - - php: 7.1 - env: DB=mysqli MOODLE_BRANCH=MOODLE_37_STABLE - - php: 7.1 - env: DB=pgsql MOODLE_BRANCH=MOODLE_37_STABLE - - php: 7.1 - env: DB=mysqli MOODLE_BRANCH=MOODLE_38_STABLE - - php: 7.1 - env: DB=pgsql MOODLE_BRANCH=MOODLE_38_STABLE - - php: 7.2 - env: DB=mysqli MOODLE_BRANCH=MOODLE_35_STABLE - - php: 7.2 - env: DB=pgsql MOODLE_BRANCH=MOODLE_35_STABLE - - php: 7.2 - env: DB=mysqli MOODLE_BRANCH=MOODLE_36_STABLE - - php: 7.2 - env: DB=pgsql MOODLE_BRANCH=MOODLE_36_STABLE - - php: 7.2 - env: DB=pgsql MOODLE_BRANCH=MOODLE_37_STABLE - - php: 7.2 - env: DB=mysqli MOODLE_BRANCH=MOODLE_37_STABLE - - php: 7.2 - env: DB=pgsql MOODLE_BRANCH=MOODLE_38_STABLE - - php: 7.2 - env: DB=mysqli MOODLE_BRANCH=MOODLE_38_STABLE - - php: 7.2 - env: DB=pgsql MOODLE_BRANCH=MOODLE_39_STABLE - - php: 7.2 - env: DB=mysqli MOODLE_BRANCH=MOODLE_39_STABLE - - php: 7.2 - env: DB=pgsql MOODLE_BRANCH=master - - php: 7.2 - env: DB=mysqli MOODLE_BRANCH=master - - php: 7.3 - env: DB=pgsql MOODLE_BRANCH=MOODLE_37_STABLE - - php: 7.3 - env: DB=mysqli MOODLE_BRANCH=MOODLE_37_STABLE - - php: 7.3 - env: DB=mysqli MOODLE_BRANCH=MOODLE_38_STABLE - - php: 7.3 - env: DB=pgsql MOODLE_BRANCH=MOODLE_38_STABLE - - php: 7.3 - env: DB=mysqli MOODLE_BRANCH=MOODLE_39_STABLE - - php: 7.3 - env: DB=pgsql MOODLE_BRANCH=MOODLE_39_STABLE - - php: 7.3 - env: DB=pgsql MOODLE_BRANCH=master - - php: 7.3 - env: DB=mysqli MOODLE_BRANCH=master - - php: 7.4 - env: DB=mysqli MOODLE_BRANCH=MOODLE_38_STABLE - - php: 7.4 - env: DB=pgsql MOODLE_BRANCH=MOODLE_38_STABLE - - php: 7.4 - env: DB=pgsql MOODLE_BRANCH=MOODLE_39_STABLE - - php: 7.4 - env: DB=mysqli MOODLE_BRANCH=MOODLE_39_STABLE - - php: 7.4 - env: DB=pgsql MOODLE_BRANCH=master - - php: 7.4 - env: DB=mysqli MOODLE_BRANCH=master - -before_install: - - sudo hostname short-hostname - - phpenv config-rm xdebug.ini - - cd ../.. - - export MOODLE_VERSION=$(echo "$MOODLE_BRANCH" | cut -d'_' -f 2) - - if [ "$MOODLE_VERSION" = 36 ] || [ "$MOODLE_VERSION" -le 34 ]; then NVMVERSION=8.9; else NVMVERSION=14.0.0; fi - - nvm install $NVMVERSION; - - nvm use $NVMVERSION; - - composer create-project -n --no-dev --prefer-dist moodlehq/moodle-plugin-ci ci ^3; - - export PATH="$(cd ci/bin; pwd):$(cd ci/vendor/bin; pwd):$PATH" - -install: - - moodle-plugin-ci install -vvv - -script: - - moodle-plugin-ci phplint - - moodle-plugin-ci phpcpd - - moodle-plugin-ci phpmd - - moodle-plugin-ci codechecker - - moodle-plugin-ci validate - - moodle-plugin-ci savepoints || travis_terminate 1; - - moodle-plugin-ci grunt || travis_terminate 1; - - moodle-plugin-ci phpunit - - moodle-plugin-ci behat diff --git a/README.md b/README.md index ce7b871..b9dfbaa 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -[![Build Status](https://travis-ci.org/catalyst/moodle-tool_crawler.svg?branch=master)](https://travis-ci.org/catalyst/moodle-tool_crawler) +[![ci](https://github.com/catalyst/moodle-tool_crawler/actions/workflows/ci.yml/badge.svg?branch=MOODLE_310_STABLE)](https://github.com/catalyst/moodle-tool_crawler/actions/workflows/ci.yml?branch=MOODLE_310_STABLE) + +# moodle-tool_crawler * [What is this?](#what-is-this) * [How does it work?](#how-does-it-work) @@ -30,23 +32,24 @@ Since the plugin cronjob comes in from outside it needs to authenticate in Moodl # Branches -| Moodle verion | Branch | -| ----------------- | ----------- | -| Moodle 3.4 to 3.8 | master | -| Totara 12+ | master | +| Moodle version | Branch | +| ----------------- | --------------------- | +| Moodle 3.10+ | MOODLE_310_STABLE | +| Moodle 3.4 to 3.9 | master | +| Totara 12+ | master | # Installation The plugin has a dependency on the [moodle-auth_basic](https://moodle.org/plugins/auth_basic). To install the dependency plugin as a git submodule: ``` -git submodule add https://github.com/catalyst/moodle-auth_basic auth/basic +git submodule add git@github.com:catalyst/moodle-auth_basic.git auth/basic ``` Install plugin moodle-tool_crawler as a git submodule: ``` -git submodule add https://github.com/central-queensland-uni/moodle-tool_crawler.git admin/tool/crawler +git submodule add git@github.com:catalyst/moodle-tool_crawler.git admin/tool/crawler ``` # Configuration @@ -156,7 +159,7 @@ be able to see the line "You are logged in as ". Once Basic HTTP auth works test running the robot task from the CLI: ``` -php admin/tool/task/cli/schedule_task.php --execute='\tool_crawler\task\crawl_task' +php admin/cli/scheduled_task.php --execute='\tool_crawler\task\crawl_task' Execute scheduled task: Parallel crawling task (tool_crawler\task\crawl_task) ... used 22 dbqueries ... used 0.039698123931885 seconds @@ -168,7 +171,7 @@ will run in parallel, depending on the crawl_task setting. You can manually run the adhoc tasks from the CLI with: ``` -php admin/tool/task/cli/adhoc_task.php --execute +php admin/cli/adhoc_task.php --execute Execute adhoc task: tool_crawler\task\adhoc_crawl_task ... used 5733 dbqueries ... used 58.239180088043 seconds diff --git a/classes/helper.php b/classes/helper.php index cbd4f61..2490e2d 100644 --- a/classes/helper.php +++ b/classes/helper.php @@ -252,18 +252,18 @@ public static function send_email($courseid) { /** * Count broken links * - * @param $courseid + * @param int $courseid * @throws \dml_exception */ - public static function count_broken_links($courseid) { + public static function count_broken_links(int $courseid) { global $DB; $sql = "SELECT count(1) AS count FROM {tool_crawler_url} b LEFT JOIN {tool_crawler_edge} l ON l.b = b.id LEFT JOIN {tool_crawler_url} a ON l.a = a.id LEFT JOIN {course} c ON c.id = a.courseid - WHERE b.httpcode != '200' AND c.id = $courseid"; - return $DB->count_records_sql($sql); + WHERE b.httpcode != '200' AND c.id = :courseid"; + return $DB->count_records_sql($sql, ['courseid'=> $courseid]); } } \ No newline at end of file diff --git a/classes/robot/crawler.php b/classes/robot/crawler.php index 5d1f312..142790d 100644 --- a/classes/robot/crawler.php +++ b/classes/robot/crawler.php @@ -529,6 +529,7 @@ public function process_queue($verbose = false) { // Iterate through the queue. $cronstart = time(); $cronstop = $cronstart + $config->maxcrontime; + $hastime = true; // Get an instance of the currently configured lock_factory. $lockfactory = \core\lock\lock_config::get_lock_factory('tool_crawler_process_queue'); @@ -550,7 +551,16 @@ public function process_queue($verbose = false) { } } // While we are not exceeding the maxcron time, and the queue is not empty. - while (time() < $cronstop) { + while ($hastime) { + + if (\core\local\cli\shutdown::should_gracefully_exit() || + \core\task\manager::static_caches_cleared_since($cronstart)) { + if ($verbose) { + echo "Shutting down crawler early\n"; + } + return true; + } + if (empty($nodes)) { // Grab a list of items from the front of the queue. We need the first 1000 // in case other workers are already locked and processing items at the front of the queue. @@ -625,6 +635,8 @@ public function process_queue($verbose = false) { } finally { $lock->release(); } + + $hastime = time() < $cronstop; } if ($courselock) { $courselock->release(); @@ -906,8 +918,9 @@ public function parse_html($node, $external, $verbose = false) { } while ($walk); $text = self::clean_html_node_content($e); + $text = trim($text); if ($verbose > 1) { - printf (" - Found link to: %-20s / %-50s => %-50s\n", $text, $e->href, $href); + printf (" - Found link to: %-30s -> %s\n", "'$text'", $href); } $this->link_from_node_to_url($node, $href, $text, $idattr); } @@ -1134,7 +1147,12 @@ private static function determine_filesize($curlhandle, $method, $success, $body public function scrape($url) { global $CFG; - $cookiefilelocation = $CFG->dataroot . '/tool_crawler_cookies.txt'; + + static $cookiefilelocation = ''; + if (!$cookiefilelocation) { + $cookiefilelocation = make_request_directory() . '/tool_crawler_cookies.txt'; + } + $config = self::get_config(); $version = moodle_major_version(); diff --git a/classes/table/course_links.php b/classes/table/course_links.php index e265d6d..45baa21 100644 --- a/classes/table/course_links.php +++ b/classes/table/course_links.php @@ -30,19 +30,22 @@ use tool_crawler\helper; use moodle_url; use html_writer; +use stdClass; class course_links extends table_sql implements renderable { private $courseid; + + private $page; /** * table constructor. * - * @param $uniqueid table unique id + * @param string $uniqueid table unique id * @param \moodle_url $url base url + * @param int $courseid course id * @param int $page current page * @param int $perpage number of records per page * @throws \coding_exception - * @throws \coding_exception */ public function __construct($uniqueid, \moodle_url $url, $courseid, $page = 0, $perpage = 20) { parent::__construct($uniqueid); @@ -165,30 +168,30 @@ public function query_db($pagesize, $useinitialsbar = true) { /** * - * @param $row + * @param stdClass $row * @return string */ - protected function col_lastcrawledtime($row) { + protected function col_lastcrawledtime(stdClass $row) { return userdate($row->lastcrawled); } /** * - * @param $row - * @return string + * @param stdClass $row + * @return stdClass $row * @throws \coding_exception */ - protected function col_priority($row) { + protected function col_priority(stdClass $row) { return tool_crawler_priority_level($row->priority); } /** * - * @param $row + * @param stdClass $row * @return mixed * @throws \coding_exception */ - protected function col_httpcode($row) { + protected function col_httpcode(stdClass $row) { $text = tool_crawler_http_code($row); if ($translation = \tool_crawler\helper::translate_httpcode($row->httpcode)) { $text .= "
" . $translation; @@ -198,11 +201,11 @@ protected function col_httpcode($row) { /** * - * @param $row + * @param stdClass $row * @return mixed * @throws \coding_exception */ - protected function col_target($row) { + protected function col_target(stdClass $row) { $text = trim($row->text); if ($text == "") { $text = get_string('missing', 'tool_crawler'); @@ -216,11 +219,11 @@ protected function col_target($row) { /** * - * @param $row + * @param stdClass $row * @return mixed * @throws \coding_exception */ - protected function col_url($row) { + protected function col_url(stdClass $row) { return tool_crawler_link($row->url, $row->title, $row->redirect, false, $this->courseid); } diff --git a/cli/crawler.php b/cli/crawler.php index 8307d4e..1ecd03b 100644 --- a/cli/crawler.php +++ b/cli/crawler.php @@ -52,6 +52,8 @@ die(); } +\core\local\cli\shutdown::script_supports_graceful_exit(); + tool_crawler_crawl($options['verbose']); exit(0); diff --git a/db/uninstall.php b/db/uninstall.php index 595011b..83f09b9 100644 --- a/db/uninstall.php +++ b/db/uninstall.php @@ -18,6 +18,7 @@ * Link checker robot plugin uninstall script. * * @package tool_crawler + * @copyright 2019 Nicolas Roeser * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ diff --git a/lang/en/tool_crawler.php b/lang/en/tool_crawler.php index d76645d..4b515ed 100644 --- a/lang/en/tool_crawler.php +++ b/lang/en/tool_crawler.php @@ -80,6 +80,11 @@ $string['crawlend'] = 'Crawl end'; $string['crawlstart'] = 'Crawl start'; $string['cronticks'] = 'Cron ticks'; +$string['debugging'] = 'Verbose debugging'; +$string['debugoff'] = 'Debugging off'; +$string['debugnormal'] = 'Normal debugging'; +$string['debugverbose'] = 'Verbose debugging'; +$string['debuggingdesc'] = 'This turns on debugging in the task output'; $string['disablebot'] = 'Disable the link crawler robot'; $string['disablebotdesc'] = 'Make the crawler do nothing when a scheduled task is executed. This effectively prevents crawling of links and running of bot cleanup functions. Intended to deactivate or temporarily pause the crawler without having to disable all its scheduled tasks.'; $string['duration'] = 'Duration'; diff --git a/lib.php b/lib.php index 29fbb7e..3d4f906 100644 --- a/lib.php +++ b/lib.php @@ -45,6 +45,11 @@ function tool_crawler_crawl($verbose = false) { $robot = new crawler(); $url = new url(); $config = $robot::get_config(); + + if ($config->debugging) { + $verbose = $config->debugging; + } + $crawlstart = $config->crawlstart; $crawlend = $config->crawlend; @@ -179,7 +184,7 @@ function tool_crawler_extend_navigation_course($navigation, $course, $coursecont if ($coursereports && ($siteconfig || $courseconfig)) { $node = $coursereports->add( get_string('pluginname', 'tool_crawler'), - null, + new moodle_url('/admin/tool/crawler/report.php', array('report' => 'queued', 'course' => $course->id)), navigation_node::TYPE_CONTAINER, null, 'linkchecker', diff --git a/locallib.php b/locallib.php index 2e16c16..a9b7166 100644 --- a/locallib.php +++ b/locallib.php @@ -42,17 +42,21 @@ * @param string $redirect The final URL if a redirect was served. * @param string $labelishtml Whether the $label parameter contains an HTML snippet (if true) or plain text (if false). Defaults to * plain text. + * @param int $courseid course id * @return string HTML snippet which can be used in output. */ function tool_crawler_link($url, $label, $redirect = '', $labelishtml = false, $courseid = 0) { + if (empty($label)) { + // Ensure that label is always at least a string. + $label = ''; + } if (!$labelishtml) { $label = htmlspecialchars($label, ENT_NOQUOTES | ENT_HTML401); } - $html = html_writer::link(new moodle_url('url.php', array('courseid' => $courseid, 'url' => $url)), $label) . - ' ' . - html_writer::link($url, '↗', array('target' => 'link')) . - '
' . htmlspecialchars($url, ENT_NOQUOTES | ENT_HTML401) . ''; + $canviewsitelevelreports = has_capability('moodle/site:config', context_system::instance()); + $html = $canviewsitelevelreports ? html_writer::link(new moodle_url('url.php', array('courseid' => $courseid, 'url' => $url)), $label) : $label; + $html .= '
' . html_writer::link($url, htmlspecialchars($url, ENT_NOQUOTES | ENT_HTML401), ['target' => 'link']) . ''; if ($redirect) { $linkhtmlsnippet = html_writer::link($redirect, htmlspecialchars($redirect, ENT_NOQUOTES | ENT_HTML401)); @@ -175,11 +179,11 @@ function tool_crawler_sql_oversize_filter($tablealias = null) { $tbl = ''; } - $where = "( ${tbl}filesize > ? - OR ( ${tbl}filesize IS NULL - AND ${tbl}lastcrawled IS NOT NULL + $where = "( {$tbl}filesize > ? + OR ( {$tbl}filesize IS NULL + AND {$tbl}lastcrawled IS NOT NULL ) - OR ${tbl}filesizestatus = ? + OR {$tbl}filesizestatus = ? )"; $bigfilesize = get_config('tool_crawler', 'bigfilesize'); @@ -238,6 +242,7 @@ function tool_crawler_url_gen_table($data) { * Generates and returns a full HTML page with details about a URL. * * @param string $url The URL. + * @param int $courseid course id * @return string A HTML page about the URL. */ function tool_crawler_url_create_page($url, $courseid = 0) { diff --git a/renderer.php b/renderer.php index 8997df8..b4eab9c 100644 --- a/renderer.php +++ b/renderer.php @@ -29,7 +29,7 @@ class tool_crawler_renderer extends plugin_renderer_base { /** * Render table. - * @param dismissed_notice $table dismissed notice table + * @param course_links $table course_links table * @return false|string */ public function render_course_links(course_links $table) { diff --git a/report.php b/report.php index c455b0b..46acff1 100644 --- a/report.php +++ b/report.php @@ -54,10 +54,13 @@ $coursecontext = context_course::instance($courseid); require_capability('moodle/course:update', $coursecontext); + $coursename = format_string($course->fullname, true, array('context' => $coursecontext)); $PAGE->set_context($coursecontext); $PAGE->set_url($navurl); - $PAGE->set_pagelayout('admin'); $PAGE->set_title( get_string($report, 'tool_crawler') ); + $PAGE->set_heading($coursename); + $PAGE->set_pagelayout('incourse'); + $PAGE->add_body_class('limitedwidth'); $sqlfilter = ' AND c.id = '.$courseid; } else { diff --git a/settings.php b/settings.php index 9a4f170..9d22073 100644 --- a/settings.php +++ b/settings.php @@ -222,5 +222,16 @@ new lang_string('disablebot', 'tool_crawler'), new lang_string('disablebotdesc', 'tool_crawler'), '0' )); + + $options = [ + 0 => new lang_string('debugoff', 'tool_crawler'), + 1 => new lang_string('debugnormal', 'tool_crawler'), + 2 => new lang_string('debugverbose', 'tool_crawler'), + ]; + $settings->add(new admin_setting_configselect('tool_crawler/debugging', + new lang_string('debugging', 'tool_crawler'), + new lang_string('debuggingdesc', 'tool_crawler'), + 0, + $options)); } } diff --git a/tabs.php b/tabs.php index b446016..76307c1 100644 --- a/tabs.php +++ b/tabs.php @@ -24,21 +24,31 @@ defined('MOODLE_INTERNAL') || die(); -$rows = [ +$adminrows = [ new tabobject('settings', new moodle_url('/admin/settings.php?section=tool_crawler'), get_string('settings', 'tool_crawler')), new tabobject('index', new moodle_url('/admin/tool/crawler/index.php'), - get_string('status', 'tool_crawler')), - new tabobject('queued', new moodle_url('/admin/tool/crawler/report.php?report=queued'), + get_string('status', 'tool_crawler')) +]; + +$courseid = optional_param('course', 0, PARAM_INT); +$courseparam = $courseid ? ['course' => $courseid] : []; +$courserows = [ + new tabobject('queued', new moodle_url('/admin/tool/crawler/report.php', ['report' => 'queued'] + $courseparam), get_string('queued', 'tool_crawler')), - new tabobject('recent', new moodle_url('/admin/tool/crawler/report.php?report=recent'), + new tabobject('recent', new moodle_url('/admin/tool/crawler/report.php', ['report' => 'recent'] + $courseparam), get_string('recent', 'tool_crawler')), - new tabobject('broken', new moodle_url('/admin/tool/crawler/report.php?report=broken'), + new tabobject('broken', new moodle_url('/admin/tool/crawler/report.php', ['report' => 'broken'] + $courseparam), get_string('broken', 'tool_crawler')), - new tabobject('oversize', new moodle_url('/admin/tool/crawler/report.php?report=oversize'), - get_string('oversize', 'tool_crawler')), + new tabobject('oversize', new moodle_url('/admin/tool/crawler/report.php', ['report' => 'oversize'] + $courseparam), + get_string('oversize', 'tool_crawler')) ]; +$rows = array_merge( + has_capability('moodle/site:config', context_system::instance()) ? $adminrows : [], + $courserows +); + $section = optional_param('section', '', PARAM_RAW); if ($section == 'tool_crawler') { $report = 'settings'; diff --git a/tests/phpunit/robot_cleanup_test.php b/tests/phpunit/robot_cleanup_test.php index d0bf400..204551f 100644 --- a/tests/phpunit/robot_cleanup_test.php +++ b/tests/phpunit/robot_cleanup_test.php @@ -39,6 +39,11 @@ */ class tool_crawler_robot_cleanup_test extends advanced_testcase { + /** + * @var \tool_crawler\robot\crawler Crawler to use in tests. + */ + private $robot; + /** * Prepare the config options for plugin which are used for robot_cleanup task logic * diff --git a/tests/phpunit/robot_crawler_test.php b/tests/phpunit/robot_crawler_test.php index 1252369..2be224e 100644 --- a/tests/phpunit/robot_crawler_test.php +++ b/tests/phpunit/robot_crawler_test.php @@ -39,6 +39,11 @@ */ class tool_crawler_robot_crawler_test extends advanced_testcase { + /** + * @var \tool_crawler\robot\crawler Crawler to use in tests. + */ + private $robot; + /** * Setup robot crawler testcase and parent setup */ @@ -224,11 +229,13 @@ public function test_uri_escaping() { $expectedpattern = '@' . preg_quote('

', '@') . '.*' . - preg_quote(']*' . // XXX: Not *100%* reliable, as '>' *might* be contained in attribute values. - preg_quote('href="' . $escapedexpected . '">↗
' . $escapedexpected . '', '@') . + preg_quote('href="' . $escapedexpected . '">' . $escapedexpected . '
', '@') . '@'; - self::assertRegExp($expectedpattern, $page); + + // Workaround to ensure greater compatbilitiy since assertRegExp is deprecated. + self::assertTrue(preg_match($expectedpattern, $page) === 1); } /** @@ -273,7 +280,9 @@ public function test_redirection_uri_escaping() { '.*' . preg_quote('
Redirect: ' . $escapedredirecturl . '

', '@') . '@'; - self::assertRegExp($expectedpattern, $page); + + // Workaround to ensure greater compatbilitiy since assertRegExp is deprecated. + self::assertTrue(preg_match($expectedpattern, $page) === 1); } /** @@ -569,7 +578,7 @@ public function url_validity_check_provider() { * Check url validity * * @param string $url the url to test - * @param $expected the expected result + * @param bool $expected the expected result */ public function test_invalid_url($url, $expected) { $baseurl = 'https://www.example.com/moodle'; @@ -598,8 +607,8 @@ public function page_title_validity_check_provider() { * * Test for Issue #143: invalid character in page title. * - * @param $url the url to test - * @param $expected + * @param array $node The node to test. + * @param string $expected */ public function test_check_page_title_validity($node, $expected) { $this->resetAfterTest(true); diff --git a/version.php b/version.php index 203e887..62f8b8e 100644 --- a/version.php +++ b/version.php @@ -27,9 +27,10 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2020101303; // The current plugin version (Date: YYYYMMDDXX) -$plugin->release = 2020101303; // The current plugin version (Date: YYYYMMDDXX) +$plugin->version = 2025020401; // The current plugin version (Date: YYYYMMDDXX) +$plugin->release = 2025020401; // The current plugin version (Date: YYYYMMDDXX) $plugin->requires = 2016021800; // Requires this Moodle version. +$plugin->supported = [34, 405]; $plugin->component = 'tool_crawler'; // To check on upgrade, that module sits in correct place. $plugin->maturity = MATURITY_STABLE; $plugin->dependencies = array(