Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion classes/local/api/plugins.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
namespace local_devkit\local\api;

use core\plugin_manager;
use core\plugininfo\base;

/**
* Plugins API.
Expand Down Expand Up @@ -44,7 +45,7 @@ class plugins {
*/
public static function list(bool $includestandard = false): array {
$manager = plugin_manager::instance();
/** @var array<string, array<string, \core\plugininfo\base>> $plugininfo */
/** @var array<string, array<string, base>> $plugininfo */
$plugininfo = $manager->get_plugins();

$results = [];
Expand Down
128 changes: 128 additions & 0 deletions classes/local/rector/rules/NormaliseGlobalDbRector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?php
// This file is part of Moodle - https://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 <https://www.gnu.org/licenses/>.

declare(strict_types=1);

namespace local_devkit\local\rector\rules;

use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Global_;
use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

use function count;

/**
* Replaces `global $DB;` with `$DB = \core\di::get(\moodle_database::class);`.
*
* phpcs:disable moodle.NamingConventions.ValidFunctionName
*
* @package local_devkit
* @copyright 2026 Felix
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class NormaliseGlobalDbRector extends AbstractRector {
/**
* Definition
*/
public function getRuleDefinition(): RuleDefinition {
return new RuleDefinition(
'Replaces global $DB with $DB = \core\di::get(\moodle_database::class)',
[
new CodeSample(
"global \$DB;\n\$DB->get_record('user', ['id' => 1]);",
"\$DB = \\core\\di::get(\\moodle_database::class);\n\$DB->get_record('user', ['id' => 1]);",
),
new CodeSample(
"global \$CFG, \$DB, \$USER;\n\$DB->get_records('course');",
"global \$CFG, \$USER;\n\$DB = \\core\\di::get(\\moodle_database::class);\n\$DB->get_records('course');",
),
],
);
}

/**
* {@inheritDoc}
* @return array<class-string<Node>>
*/
#[\Override]
public function getNodeTypes(): array {
return [Global_::class];
}

#[\Override]
public function refactor(Node $node): Node|array|null {
if (!$node instanceof Global_) {
return null;
}

$dbvar = null;
foreach ($node->vars as $var) {
if ($var instanceof Variable && $var->name === 'DB') {
$dbvar = $var;
break;
}
}

if ($dbvar === null) {
return null;
}

$assignment = new Expression($this->createDbAssignment());

if (count($node->vars) === 1) {
return $assignment;
}

$node->vars = array_values(
array_filter(
$node->vars,
fn($var) => $var !== $dbvar,
),
);

return [$node, $assignment];
}

/**
* Creates the assignment expression for $DB = \core\di::get(\moodle_database::class)
*/
private function createDbAssignment(): Assign {
return new Assign(
new Variable('DB'),
new StaticCall(
new Name('\\core\\di'),
'get',
[
new Arg(
new ClassConstFetch(
new Name('\\moodle_database'),
'class',
),
),
],
),
);
}
}
124 changes: 124 additions & 0 deletions classes/local/rector/rules/RemoveCfgWwwrootFromMoodleUrlRector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<?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/>.

declare(strict_types=1);

namespace local_devkit\local\rector\rules;

use core\url;
use moodle_url;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\BinaryOp\Concat;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Variable;
use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

/**
* Removes unneeded $CFG->wwwroot from moodle_url usage.
*
* phpcs:disable moodle.NamingConventions.ValidFunctionName
*
* @package local_devkit
* @copyright 2026 Felix
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
final class RemoveCfgWwwrootFromMoodleUrlRector extends AbstractRector {
/**
* Definition
*/
public function getRuleDefinition(): RuleDefinition {
return new RuleDefinition(
'Removes $CFG->wwwroot concatenation from moodle_url instantiation and upgrades to \core\url',
[
new CodeSample(
'new moodle_url($CFG->wwwroot . \'/mod/assign/view.php\');',
'new \core\url(\'/mod/assign/view.php\');',
),
],
);
}

/**
* {@inheritDoc}
* @return array<class-string<Node>>
*/
#[\Override]
public function getNodeTypes(): array {
return [New_::class];
}

#[\Override]
public function refactor(Node $node): ?Node {
if (!$node instanceof New_) {
return null;
}

if (!$this->is_moodle_url($node)) {
return null;
}

if ($node->args === []) {
return null;
}

$arg0 = $node->args[0];

if (!$arg0 instanceof Arg) {
return null;
}

if (!$arg0->value instanceof Concat) {
return null;
}

if (!$this->is_cfg_wwwroot_property($arg0->value->left)) {
return null;
}

$arg0->value = $arg0->value->right;

return $node;
}

/**
* Checks if the given node's class is a moodle url class.
*/
private function is_moodle_url(New_ $node): bool {
$classes = [
moodle_url::class,
url::class,
];
return $this->isNames($node->class, $classes);
}

/**
* Checks if an AST node matches `$CFG->wwwroot`
*/
private function is_cfg_wwwroot_property(Node $node): bool {
if (!$node instanceof PropertyFetch) {
return false;
}

// Check if the variable is named `$CFG` and property is `wwwroot`.
return $node->var instanceof Variable
&& $this->isName($node->var, 'CFG')
&& $this->isName($node->name, 'wwwroot');
}
}
Loading