From 1aa8e5d7239f9f38cb0a92c8ab4ae7861b8abe81 Mon Sep 17 00:00:00 2001 From: Felix Yeung <19355619+imfelixyeung@users.noreply.github.com> Date: Mon, 20 Jul 2026 20:17:56 +0100 Subject: [PATCH 01/38] feat: add enrol stubs --- phpstan/stubs/public/enrol/_plugins.stub | 40 ++++++++++++++++++++++++ phpstan/stubs/public/lib/enrollib.stub | 26 +++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 phpstan/stubs/public/enrol/_plugins.stub create mode 100644 phpstan/stubs/public/lib/enrollib.stub diff --git a/phpstan/stubs/public/enrol/_plugins.stub b/phpstan/stubs/public/enrol/_plugins.stub new file mode 100644 index 00000000..5a8ebdd1 --- /dev/null +++ b/phpstan/stubs/public/enrol/_plugins.stub @@ -0,0 +1,40 @@ + Date: Mon, 20 Jul 2026 20:18:05 +0100 Subject: [PATCH 02/38] feat: add base event stubs --- .../stubs/public/lib/classes/event/base.stub | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 phpstan/stubs/public/lib/classes/event/base.stub diff --git a/phpstan/stubs/public/lib/classes/event/base.stub b/phpstan/stubs/public/lib/classes/event/base.stub new file mode 100644 index 00000000..7d975ed5 --- /dev/null +++ b/phpstan/stubs/public/lib/classes/event/base.stub @@ -0,0 +1,51 @@ + + */ +abstract class base implements IteratorAggregate { + public const LEVEL_OTHER = 0; + public const LEVEL_TEACHING = 1; + public const LEVEL_PARTICIPATING = 2; + + /** + * @param array{ + * objectid?: int|null, + * context?: \core\context, + * userid?: int, + * courseid?: int|null, + * relateduserid?: int|null, + * anonymous?: bool|1|2, + * other?: mixed|null, + * } $data + * @return static returns instance of new event + * @throws coding_exception&Throwable + */ + final public static function create(?array $data = null) { + } +} From 861935d82642946cff8771ad225933f25593f105 Mon Sep 17 00:00:00 2001 From: Felix Yeung <19355619+imfelixyeung@users.noreply.github.com> Date: Mon, 20 Jul 2026 20:40:22 +0100 Subject: [PATCH 03/38] feat: add createElement stub --- .../stubs/public/lib/pear/HTML/QuickForm.stub | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/phpstan/stubs/public/lib/pear/HTML/QuickForm.stub b/phpstan/stubs/public/lib/pear/HTML/QuickForm.stub index 2b4dd7b9..04bd721c 100644 --- a/phpstan/stubs/public/lib/pear/HTML/QuickForm.stub +++ b/phpstan/stubs/public/lib/pear/HTML/QuickForm.stub @@ -52,4 +52,56 @@ class HTML_QuickForm extends HTML_Common { */ public function &addElement($element, ...$args) { } + + /** + * @param string $elementType + * @param mixed[] $args + * @return ( + * $elementType is 'advcheckbox' ? MoodleQuickForm_advcheckbox : + * $elementType is 'autocomplete' ? MoodleQuickForm_autocomplete : + * $elementType is 'button' ? MoodleQuickForm_button : + * $elementType is 'cancel' ? MoodleQuickForm_cancel : + * $elementType is 'course' ? MoodleQuickForm_course : + * $elementType is 'cohort' ? MoodleQuickForm_cohort : + * $elementType is 'searchableselector' ? MoodleQuickForm_searchableselector : + * $elementType is 'checkbox' ? MoodleQuickForm_checkbox : + * $elementType is 'choicedropdown' ? MoodleQuickForm_choicedropdown : + * $elementType is 'date_selector' ? MoodleQuickForm_date_selector : + * $elementType is 'date_time_selector' ? MoodleQuickForm_date_time_selector : + * $elementType is 'duration' ? MoodleQuickForm_duration : + * $elementType is 'editor' ? MoodleQuickForm_editor : + * $elementType is 'filemanager' ? MoodleQuickForm_filemanager : + * $elementType is 'filepicker' ? MoodleQuickForm_filepicker : + * $elementType is 'filetypes' ? MoodleQuickForm_filetypes : + * $elementType is 'float' ? MoodleQuickForm_float : + * $elementType is 'grading' ? MoodleQuickForm_grading : + * $elementType is 'group' ? MoodleQuickForm_group : + * $elementType is 'header' ? MoodleQuickForm_header : + * $elementType is 'hidden' ? MoodleQuickForm_hidden : + * $elementType is 'listing' ? MoodleQuickForm_listing : + * $elementType is 'defaultcustom' ? MoodleQuickForm_defaultcustom : + * $elementType is 'modgrade' ? MoodleQuickForm_modgrade : + * $elementType is 'modvisible' ? MoodleQuickForm_modvisible : + * $elementType is 'password' ? MoodleQuickForm_password : + * $elementType is 'passwordunmask' ? MoodleQuickForm_passwordunmask : + * $elementType is 'questioncategory' ? MoodleQuickForm_questioncategory : + * $elementType is 'radio' ? MoodleQuickForm_radio : + * $elementType is 'recaptcha' ? MoodleQuickForm_recaptcha : + * $elementType is 'select' ? MoodleQuickForm_select : + * $elementType is 'selectgroups' ? MoodleQuickForm_selectgroups : + * $elementType is 'selectwithlink' ? MoodleQuickForm_selectwithlink : + * $elementType is 'selectyesno' ? MoodleQuickForm_selectyesno : + * $elementType is 'static' ? MoodleQuickForm_static : + * $elementType is 'submit' ? MoodleQuickForm_submit : + * $elementType is 'tags' ? MoodleQuickForm_tags : + * $elementType is 'text' ? MoodleQuickForm_text : + * $elementType is 'textarea' ? MoodleQuickForm_textarea : + * $elementType is 'url' ? MoodleQuickForm_url : + * $elementType is 'warning' ? MoodleQuickForm_warning : + * HTML_QuickForm_element + * ) + * @throws HTML_QuickForm_Error&Throwable + */ + public function &createElement($elementType, ...$args) { + } } From e4136229ebb534095f3ece83a83ffe80a8d2feb9 Mon Sep 17 00:00:00 2001 From: Felix Yeung <19355619+imfelixyeung@users.noreply.github.com> Date: Mon, 20 Jul 2026 21:04:51 +0100 Subject: [PATCH 04/38] feat: add filelib related stubs --- .../public/lib/filestorage/file_storage.stub | 43 +++++++++++++++++++ .../public/lib/filestorage/stored_file.stub | 14 ++++++ 2 files changed, 57 insertions(+) diff --git a/phpstan/stubs/public/lib/filestorage/file_storage.stub b/phpstan/stubs/public/lib/filestorage/file_storage.stub index ce551b78..2bda2a7c 100644 --- a/phpstan/stubs/public/lib/filestorage/file_storage.stub +++ b/phpstan/stubs/public/lib/filestorage/file_storage.stub @@ -3,10 +3,53 @@ use stored_file; class file_storage { + /** + * @param int $fileid + * @return stored_file|false + */ + public function get_file_by_id($fileid) { + } + /** * @param string $pathnamehash * @return stored_file|false */ public function get_file_by_hash($pathnamehash) { } + + /** + * @param int $contextid + * @param string $component + * @param string $filearea + * @param int $itemid + * @param string $filepath + * @param string $filename + * @return stored_file|false + */ + public function get_file($contextid, $component, $filearea, $itemid, $filepath, $filename) { + } + + /** + * @param int $contextid + * @param string $component + * @param string $filearea + * @param int $itemid + * @param int $filepath + * @param bool $recursive + * @param bool $includedirs + * @param string $sort + * @return array + */ + public function get_directory_files($contextid, $component, $filearea, $itemid, $filepath, $recursive = false, $includedirs = true, $sort = "filepath, filename") { + } + + /** + * @param int $contextid context ID + * @param string $component component + * @param string|false $filearea + * @param int|false $itemid + * @return true + */ + public function delete_area_files($contextid, $component = false, $filearea = false, $itemid = false) { + } } diff --git a/phpstan/stubs/public/lib/filestorage/stored_file.stub b/phpstan/stubs/public/lib/filestorage/stored_file.stub index d06878e1..e7168b6c 100644 --- a/phpstan/stubs/public/lib/filestorage/stored_file.stub +++ b/phpstan/stubs/public/lib/filestorage/stored_file.stub @@ -1,4 +1,18 @@ Date: Mon, 20 Jul 2026 22:28:20 +0100 Subject: [PATCH 05/38] feat: add fullname() stub --- phpstan/stubs/public/lib/moodlelib.stub | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/phpstan/stubs/public/lib/moodlelib.stub b/phpstan/stubs/public/lib/moodlelib.stub index 27f00ab7..6432ae73 100644 --- a/phpstan/stubs/public/lib/moodlelib.stub +++ b/phpstan/stubs/public/lib/moodlelib.stub @@ -314,3 +314,11 @@ function unset_user_preference($name, $user = null) { */ function get_user_preferences($name = null, $default = null, $user = null) { } + +/** + * @param stdClass|null|false $user + * @param bool $override + * @return ($user is object ? string : '') + */ +function fullname($user, $override = false) { +} From cc1a2d9e485189a70fab3e86ef61b8b7b1b5ad3a Mon Sep 17 00:00:00 2001 From: Felix Yeung <19355619+imfelixyeung@users.noreply.github.com> Date: Tue, 21 Jul 2026 18:12:54 +0100 Subject: [PATCH 06/38] feat: add lock stubs --- phpstan/stubs/public/lib/classes/lock/lock.stub | 6 ++++++ .../stubs/public/lib/classes/lock/lock_factory.stub | 13 +++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 phpstan/stubs/public/lib/classes/lock/lock.stub create mode 100644 phpstan/stubs/public/lib/classes/lock/lock_factory.stub diff --git a/phpstan/stubs/public/lib/classes/lock/lock.stub b/phpstan/stubs/public/lib/classes/lock/lock.stub new file mode 100644 index 00000000..49790372 --- /dev/null +++ b/phpstan/stubs/public/lib/classes/lock/lock.stub @@ -0,0 +1,6 @@ + Date: Tue, 21 Jul 2026 18:24:15 +0100 Subject: [PATCH 07/38] feat: add grade stubs --- .../stubs/public/lib/grade/grade_grade.stub | 12 +++++++++ .../stubs/public/lib/grade/grade_item.stub | 25 +++++++++++++++++++ .../stubs/public/lib/grade/grade_object.stub | 4 +++ 3 files changed, 41 insertions(+) create mode 100644 phpstan/stubs/public/lib/grade/grade_grade.stub create mode 100644 phpstan/stubs/public/lib/grade/grade_item.stub create mode 100644 phpstan/stubs/public/lib/grade/grade_object.stub diff --git a/phpstan/stubs/public/lib/grade/grade_grade.stub b/phpstan/stubs/public/lib/grade/grade_grade.stub new file mode 100644 index 00000000..1f9e1976 --- /dev/null +++ b/phpstan/stubs/public/lib/grade/grade_grade.stub @@ -0,0 +1,12 @@ + + */ + public static function fetch_users_grades($grade_item, $userids, $include_missing = true) { + } +} diff --git a/phpstan/stubs/public/lib/grade/grade_item.stub b/phpstan/stubs/public/lib/grade/grade_item.stub new file mode 100644 index 00000000..24d9fd76 --- /dev/null +++ b/phpstan/stubs/public/lib/grade/grade_item.stub @@ -0,0 +1,25 @@ + $params + * @return grade_item|false + */ + public static function fetch($params) { + } + + /** + * @param array $params + * @return grade_item[]|false + */ + public static function fetch_all($params) { + } +} diff --git a/phpstan/stubs/public/lib/grade/grade_object.stub b/phpstan/stubs/public/lib/grade/grade_object.stub new file mode 100644 index 00000000..2e230ea0 --- /dev/null +++ b/phpstan/stubs/public/lib/grade/grade_object.stub @@ -0,0 +1,4 @@ + Date: Tue, 21 Jul 2026 18:50:22 +0100 Subject: [PATCH 08/38] feat: add modinfo related stubs --- .../stubs/public/course/classes/cm_info.stub | 62 +++++++++++++++++++ .../stubs/public/course/classes/modinfo.stub | 14 +++++ phpstan/stubs/public/lib/completionlib.stub | 5 ++ phpstan/stubs/public/lib/grouplib.stub | 5 ++ phpstan/stubs/public/lib/modinfolib.stub | 11 ++++ 5 files changed, 97 insertions(+) create mode 100644 phpstan/stubs/public/course/classes/cm_info.stub create mode 100644 phpstan/stubs/public/course/classes/modinfo.stub create mode 100644 phpstan/stubs/public/lib/completionlib.stub create mode 100644 phpstan/stubs/public/lib/grouplib.stub create mode 100644 phpstan/stubs/public/lib/modinfolib.stub diff --git a/phpstan/stubs/public/course/classes/cm_info.stub b/phpstan/stubs/public/course/classes/cm_info.stub new file mode 100644 index 00000000..73c16f04 --- /dev/null +++ b/phpstan/stubs/public/course/classes/cm_info.stub @@ -0,0 +1,62 @@ + + */ +class cm_info implements IteratorAggregate { +} diff --git a/phpstan/stubs/public/course/classes/modinfo.stub b/phpstan/stubs/public/course/classes/modinfo.stub new file mode 100644 index 00000000..a399e13c --- /dev/null +++ b/phpstan/stubs/public/course/classes/modinfo.stub @@ -0,0 +1,14 @@ + $sections + * @property-read cm_info[] $cms + * @property-read array> $instances + * @property-read array> $groups + */ +class modinfo { +} diff --git a/phpstan/stubs/public/lib/completionlib.stub b/phpstan/stubs/public/lib/completionlib.stub new file mode 100644 index 00000000..6bcfaeec --- /dev/null +++ b/phpstan/stubs/public/lib/completionlib.stub @@ -0,0 +1,5 @@ + Date: Tue, 21 Jul 2026 22:29:23 +0100 Subject: [PATCH 09/38] feat: add accesslib stubs --- phpstan/stubs/public/lib/accesslib.stub | 89 +++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/phpstan/stubs/public/lib/accesslib.stub b/phpstan/stubs/public/lib/accesslib.stub index 10d5f830..348b4ccd 100644 --- a/phpstan/stubs/public/lib/accesslib.stub +++ b/phpstan/stubs/public/lib/accesslib.stub @@ -1,6 +1,95 @@ Date: Tue, 21 Jul 2026 22:29:36 +0100 Subject: [PATCH 10/38] feat: add moodleform stubs --- phpstan/stubs/public/lib/formslib.stub | 32 ++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/phpstan/stubs/public/lib/formslib.stub b/phpstan/stubs/public/lib/formslib.stub index 97f9d647..00ff271b 100644 --- a/phpstan/stubs/public/lib/formslib.stub +++ b/phpstan/stubs/public/lib/formslib.stub @@ -1,4 +1,36 @@ |null $attributes + * @param bool $editable + * @param array $ajaxformdata + */ + public function __construct( + $action = null, + $customdata = null, + $method = 'post', + $target = '', + $attributes = null, + $editable = true, + $ajaxformdata = null, + ) { + } + + /** + * @param array $data + * @param array $files + * @return array + */ + public function validation($data, $files) { + } +} + class MoodleQuickForm extends HTML_QuickForm_DHTMLRulesTableless { } From fea91cc6c745fb88164663e861bc422a11c8d4a8 Mon Sep 17 00:00:00 2001 From: Felix Yeung <19355619+imfelixyeung@users.noreply.github.com> Date: Tue, 21 Jul 2026 22:31:13 +0100 Subject: [PATCH 11/38] feat: add string related stubs --- .../stubs/public/lib/classes/lang_string.stub | 28 +++++++++++ phpstan/stubs/public/lib/moodlelib.stub | 50 ++++++++++++++++--- 2 files changed, 70 insertions(+), 8 deletions(-) create mode 100644 phpstan/stubs/public/lib/classes/lang_string.stub diff --git a/phpstan/stubs/public/lib/classes/lang_string.stub b/phpstan/stubs/public/lib/classes/lang_string.stub new file mode 100644 index 00000000..607d498b --- /dev/null +++ b/phpstan/stubs/public/lib/classes/lang_string.stub @@ -0,0 +1,28 @@ + + */ +class lang_string { + /** + * @param string $identifier + * @param string|null $component + * @param get_string_a $a + * @param string|null $lang + * @throws coding_exception&Throwable + */ + public function __construct( + string $identifier, + ?string $component = '', + mixed $a = null, + ?string $lang = null, + ) { + } +} diff --git a/phpstan/stubs/public/lib/moodlelib.stub b/phpstan/stubs/public/lib/moodlelib.stub index 6432ae73..46b56480 100644 --- a/phpstan/stubs/public/lib/moodlelib.stub +++ b/phpstan/stubs/public/lib/moodlelib.stub @@ -1,5 +1,8 @@ : string|T|null) - * @throws coding_exception&\Throwable + * @throws coding_exception&Throwable */ function get_user_preferences($name = null, $default = null, $user = null) { } @@ -322,3 +325,34 @@ function get_user_preferences($name = null, $default = null, $user = null) { */ function fullname($user, $override = false) { } + +/** + * @phpstan-import-type get_string_a from lang_string + * @param non-empty-string $identifier + * @param string $component + * @param ( + * string|object|int|float|bool|Stringable + * |array< + * string, + * string|object|int|float|bool|Stringable + * > + * ) $a + * @param bool $lazyload + * @return ($lazyload is false ? string : lang_string) + * @throws coding_exception&Throwable + */ +function get_string($identifier, $component = '', $a = null, $lazyload = false) { +} + +/** + * @param string[] $array + * @param string $component + * @return stdClass + */ +function get_strings($array, $component = '') { + $string = new stdClass(); + foreach ($array as $item) { + $string->$item = get_string($item, $component); + } + return $string; +} From 0d3be601f66be95874c963e3b68c2450f1ba3580 Mon Sep 17 00:00:00 2001 From: Felix Yeung <19355619+imfelixyeung@users.noreply.github.com> Date: Tue, 21 Jul 2026 22:43:00 +0100 Subject: [PATCH 12/38] feat: add clean param stubs --- phpstan/stubs/public/lib/moodlelib.stub | 97 +++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/phpstan/stubs/public/lib/moodlelib.stub b/phpstan/stubs/public/lib/moodlelib.stub index 46b56480..54c0c8a2 100644 --- a/phpstan/stubs/public/lib/moodlelib.stub +++ b/phpstan/stubs/public/lib/moodlelib.stub @@ -238,6 +238,103 @@ function optional_param($parname, $default, $type) { function optional_param_array($parname, $default, $type) { } +/** + * @param array|null $param the variable array we are cleaning + * @param PARAM_ALPHA|PARAM_ALPHAEXT|PARAM_ALPHANUM|PARAM_ALPHANUMEXT|PARAM_AUTH|PARAM_BASE64|PARAM_BOOL|PARAM_CAPABILITY|PARAM_CLEANHTML|PARAM_EMAIL|PARAM_FILE|PARAM_FLOAT|PARAM_LOCALISEDFLOAT|PARAM_HOST|PARAM_INT|PARAM_LANG|PARAM_LOCALURL|PARAM_NOTAGS|PARAM_PATH|PARAM_PEM|PARAM_PERMISSION|PARAM_RAW|PARAM_RAW_TRIMMED|PARAM_SAFEDIR|PARAM_SAFEPATH|PARAM_SEQUENCE|PARAM_TAG|PARAM_TAGLIST|PARAM_TEXT|PARAM_THEME|PARAM_URL|PARAM_USERNAME|PARAM_STRINGID|PARAM_TIMEZONE|PARAM_COMPONENT|PARAM_AREA|PARAM_PLUGIN $type + * @param bool $recursive clean recursive arrays + * @return ( + * $type is PARAM_ALPHA ? string|null : + * $type is PARAM_ALPHAEXT ? string|null : + * $type is PARAM_ALPHANUM ? string|null : + * $type is PARAM_ALPHANUMEXT ? string|null : + * $type is PARAM_AUTH ? string : + * $type is PARAM_BASE64 ? string : + * $type is PARAM_BOOL ? 0|1 : + * $type is PARAM_CAPABILITY ? string : + * $type is PARAM_CLEANHTML ? string : + * $type is PARAM_EMAIL ? string : + * $type is PARAM_FILE ? string : + * $type is PARAM_FLOAT ? float : + * $type is PARAM_LOCALISEDFLOAT ? float|false : + * $type is PARAM_HOST ? string : + * $type is PARAM_INT ? int : + * $type is PARAM_LANG ? string : + * $type is PARAM_LOCALURL ? string : + * $type is PARAM_NOTAGS ? string : + * $type is PARAM_PATH ? string : + * $type is PARAM_PEM ? string : + * $type is PARAM_PERMISSION ? CAP_INHERIT|CAP_ALLOW|CAP_PREVENT|CAP_PROHIBIT : + * $type is PARAM_RAW ? mixed : + * $type is PARAM_RAW_TRIMMED ? string : + * $type is PARAM_SAFEDIR ? string : + * $type is PARAM_SAFEPATH ? string : + * $type is PARAM_SEQUENCE ? string|null : + * $type is PARAM_TAG ? string : + * $type is PARAM_TAGLIST ? string : + * $type is PARAM_TEXT ? string : + * $type is PARAM_THEME ? string : + * $type is PARAM_URL ? string : + * $type is PARAM_USERNAME ? string : + * $type is PARAM_STRINGID ? string : + * $type is PARAM_TIMEZONE ? string : + * $type is PARAM_COMPONENT ? string : + * $type is PARAM_AREA ? string : + * $type is PARAM_PLUGIN ? string : + * mixed + * )[] + * @throws coding_exception&Throwable + */ +function clean_param_array(?array $param, $type, $recursive = false) { +} + +/** + * @param mixed $param + * @param PARAM_ALPHA|PARAM_ALPHAEXT|PARAM_ALPHANUM|PARAM_ALPHANUMEXT|PARAM_AUTH|PARAM_BASE64|PARAM_BOOL|PARAM_CAPABILITY|PARAM_CLEANHTML|PARAM_EMAIL|PARAM_FILE|PARAM_FLOAT|PARAM_LOCALISEDFLOAT|PARAM_HOST|PARAM_INT|PARAM_LANG|PARAM_LOCALURL|PARAM_NOTAGS|PARAM_PATH|PARAM_PEM|PARAM_PERMISSION|PARAM_RAW|PARAM_RAW_TRIMMED|PARAM_SAFEDIR|PARAM_SAFEPATH|PARAM_SEQUENCE|PARAM_TAG|PARAM_TAGLIST|PARAM_TEXT|PARAM_THEME|PARAM_URL|PARAM_USERNAME|PARAM_STRINGID|PARAM_TIMEZONE|PARAM_COMPONENT|PARAM_AREA|PARAM_PLUGIN $type + * @return ( + * $type is PARAM_ALPHA ? string|null : + * $type is PARAM_ALPHAEXT ? string|null : + * $type is PARAM_ALPHANUM ? string|null : + * $type is PARAM_ALPHANUMEXT ? string|null : + * $type is PARAM_AUTH ? string : + * $type is PARAM_BASE64 ? string : + * $type is PARAM_BOOL ? 0|1 : + * $type is PARAM_CAPABILITY ? string : + * $type is PARAM_CLEANHTML ? string : + * $type is PARAM_EMAIL ? string : + * $type is PARAM_FILE ? string : + * $type is PARAM_FLOAT ? float : + * $type is PARAM_LOCALISEDFLOAT ? float|false : + * $type is PARAM_HOST ? string : + * $type is PARAM_INT ? int : + * $type is PARAM_LANG ? string : + * $type is PARAM_LOCALURL ? string : + * $type is PARAM_NOTAGS ? string : + * $type is PARAM_PATH ? string : + * $type is PARAM_PEM ? string : + * $type is PARAM_PERMISSION ? CAP_INHERIT|CAP_ALLOW|CAP_PREVENT|CAP_PROHIBIT : + * $type is PARAM_RAW ? mixed : + * $type is PARAM_RAW_TRIMMED ? string : + * $type is PARAM_SAFEDIR ? string : + * $type is PARAM_SAFEPATH ? string : + * $type is PARAM_SEQUENCE ? string|null : + * $type is PARAM_TAG ? string : + * $type is PARAM_TAGLIST ? string : + * $type is PARAM_TEXT ? string : + * $type is PARAM_THEME ? string : + * $type is PARAM_URL ? string : + * $type is PARAM_USERNAME ? string : + * $type is PARAM_STRINGID ? string : + * $type is PARAM_TIMEZONE ? string : + * $type is PARAM_COMPONENT ? string : + * $type is PARAM_AREA ? string : + * $type is PARAM_PLUGIN ? string : + * mixed + * )[] + * @throws coding_exception&Throwable + */ +function clean_param($param, $type) { +} + /** * @param string $name * @param string|int|bool|null $value From c2ded46778e1ee546b05a33d95168cc502da39ad Mon Sep 17 00:00:00 2001 From: Felix Yeung <19355619+imfelixyeung@users.noreply.github.com> Date: Tue, 21 Jul 2026 22:47:00 +0100 Subject: [PATCH 13/38] feat: add get_course_and_cm_from_cmid stub --- phpstan/stubs/public/lib/modinfolib.stub | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/phpstan/stubs/public/lib/modinfolib.stub b/phpstan/stubs/public/lib/modinfolib.stub index 3027f721..a2d53585 100644 --- a/phpstan/stubs/public/lib/modinfolib.stub +++ b/phpstan/stubs/public/lib/modinfolib.stub @@ -1,5 +1,8 @@ Date: Tue, 21 Jul 2026 22:51:58 +0100 Subject: [PATCH 14/38] feat: add grades stubs --- phpstan/stubs/public/lib/grade/constants.stub | 6 +++++ phpstan/stubs/public/lib/gradelib.stub | 26 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 phpstan/stubs/public/lib/grade/constants.stub create mode 100644 phpstan/stubs/public/lib/gradelib.stub diff --git a/phpstan/stubs/public/lib/grade/constants.stub b/phpstan/stubs/public/lib/grade/constants.stub new file mode 100644 index 00000000..44be05d2 --- /dev/null +++ b/phpstan/stubs/public/lib/grade/constants.stub @@ -0,0 +1,6 @@ + Date: Tue, 21 Jul 2026 22:55:07 +0100 Subject: [PATCH 15/38] fix: resolve phpstan issues --- phpstan/stubs/public/lib/modinfolib.stub | 1 + 1 file changed, 1 insertion(+) diff --git a/phpstan/stubs/public/lib/modinfolib.stub b/phpstan/stubs/public/lib/modinfolib.stub index a2d53585..7b2ee9fb 100644 --- a/phpstan/stubs/public/lib/modinfolib.stub +++ b/phpstan/stubs/public/lib/modinfolib.stub @@ -1,6 +1,7 @@ Date: Tue, 21 Jul 2026 23:34:35 +0100 Subject: [PATCH 16/38] feat: add navigation_node::text stub --- .../lib/classes/navigation/navigation_node.stub | 12 ++++++++++++ .../stubs/public/lib/classes/output/renderable.stub | 6 ++++++ 2 files changed, 18 insertions(+) create mode 100644 phpstan/stubs/public/lib/classes/navigation/navigation_node.stub create mode 100644 phpstan/stubs/public/lib/classes/output/renderable.stub diff --git a/phpstan/stubs/public/lib/classes/navigation/navigation_node.stub b/phpstan/stubs/public/lib/classes/navigation/navigation_node.stub new file mode 100644 index 00000000..aa7a19bf --- /dev/null +++ b/phpstan/stubs/public/lib/classes/navigation/navigation_node.stub @@ -0,0 +1,12 @@ + Date: Wed, 22 Jul 2026 17:40:49 +0100 Subject: [PATCH 17/38] feat: add category::get stub --- .../classes/cacheable_object_interface.stub | 6 +++++ .../stubs/public/course/classes/category.stub | 26 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 phpstan/stubs/public/cache/classes/cacheable_object_interface.stub create mode 100644 phpstan/stubs/public/course/classes/category.stub diff --git a/phpstan/stubs/public/cache/classes/cacheable_object_interface.stub b/phpstan/stubs/public/cache/classes/cacheable_object_interface.stub new file mode 100644 index 00000000..9e2e8932 --- /dev/null +++ b/phpstan/stubs/public/cache/classes/cacheable_object_interface.stub @@ -0,0 +1,6 @@ + + */ +class core_course_category implements cacheable_object_interface, IteratorAggregate, renderable { + /** + * @param int $id + * @param IGNORE_MISSING|IGNORE_MULTIPLE|MUST_EXIST $strictness + * @param bool $alwaysreturnhidden + * @param int|stdClass|null $user + * @return ($strictness is MUST_EXIST ? self : null|self) + * @throws moodle_exception&Throwable + */ + public static function get($id, $strictness = MUST_EXIST, $alwaysreturnhidden = false, $user = null) { + } +} From 8adf6170ccf00a39f4d89bab286abc8e367269c1 Mon Sep 17 00:00:00 2001 From: Felix Yeung <19355619+imfelixyeung@users.noreply.github.com> Date: Wed, 22 Jul 2026 18:20:19 +0100 Subject: [PATCH 18/38] fix: less picky get_string --- phpstan/stubs/public/lib/moodlelib.stub | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan/stubs/public/lib/moodlelib.stub b/phpstan/stubs/public/lib/moodlelib.stub index 54c0c8a2..12e994e0 100644 --- a/phpstan/stubs/public/lib/moodlelib.stub +++ b/phpstan/stubs/public/lib/moodlelib.stub @@ -425,7 +425,7 @@ function fullname($user, $override = false) { /** * @phpstan-import-type get_string_a from lang_string - * @param non-empty-string $identifier + * @param string $identifier * @param string $component * @param ( * string|object|int|float|bool|Stringable From d724dd291624f9c0c6ab39eebf1b5d5491eed492 Mon Sep 17 00:00:00 2001 From: Felix Yeung <19355619+imfelixyeung@users.noreply.github.com> Date: Wed, 22 Jul 2026 18:21:22 +0100 Subject: [PATCH 19/38] feat: add unit tests stubs --- .../phpunit/classes/advanced_testcase.stub | 15 ++++++++++++++ .../lib/phpunit/classes/base_testcase.stub | 6 ++++++ phpstan/stubs/public/lib/setuplib.stub | 7 +++++++ phpstan/stubs/vendor/phpunit.stub | 20 +++++++++++++++++++ 4 files changed, 48 insertions(+) create mode 100644 phpstan/stubs/public/lib/phpunit/classes/advanced_testcase.stub create mode 100644 phpstan/stubs/public/lib/phpunit/classes/base_testcase.stub create mode 100644 phpstan/stubs/public/lib/setuplib.stub create mode 100644 phpstan/stubs/vendor/phpunit.stub diff --git a/phpstan/stubs/public/lib/phpunit/classes/advanced_testcase.stub b/phpstan/stubs/public/lib/phpunit/classes/advanced_testcase.stub new file mode 100644 index 00000000..1acbc2be --- /dev/null +++ b/phpstan/stubs/public/lib/phpunit/classes/advanced_testcase.stub @@ -0,0 +1,15 @@ + Date: Wed, 22 Jul 2026 18:21:44 +0100 Subject: [PATCH 20/38] feat: add form stubs --- .../stubs/public/course/moodleform_mod.stub | 14 +++++ phpstan/stubs/public/lib/formslib.stub | 51 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 phpstan/stubs/public/course/moodleform_mod.stub diff --git a/phpstan/stubs/public/course/moodleform_mod.stub b/phpstan/stubs/public/course/moodleform_mod.stub new file mode 100644 index 00000000..79748b2e --- /dev/null +++ b/phpstan/stubs/public/course/moodleform_mod.stub @@ -0,0 +1,14 @@ + $data * @param array $files From 91a62dece82a24323647d3aba9359d2e5c5c424c Mon Sep 17 00:00:00 2001 From: Felix Yeung <19355619+imfelixyeung@users.noreply.github.com> Date: Wed, 22 Jul 2026 18:21:56 +0100 Subject: [PATCH 21/38] feat: add debugging stub --- phpstan/stubs/public/lib/weblib.stub | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/phpstan/stubs/public/lib/weblib.stub b/phpstan/stubs/public/lib/weblib.stub index eadb3fe7..4d1b59d4 100644 --- a/phpstan/stubs/public/lib/weblib.stub +++ b/phpstan/stubs/public/lib/weblib.stub @@ -15,3 +15,13 @@ define('FORMAT_MARKDOWN', '4'); */ function format_text($text, $format = \FORMAT_MOODLE, $options = null, $courseiddonotuse = null) { } + + +/** + * @param string $message + * @param DEBUG_NONE|DEBUG_MINIMAL|DEBUG_NORMAL|DEBUG_ALL|DEBUG_DEVELOPER $level + * @param mixed[] $backtrace + * @return bool + */ +function debugging($message = '', $level = DEBUG_NORMAL, $backtrace = null) { +} From 08546cac2379817aed3698c2576a2426df98aa5e Mon Sep 17 00:00:00 2001 From: Felix Yeung <19355619+imfelixyeung@users.noreply.github.com> Date: Wed, 22 Jul 2026 18:22:12 +0100 Subject: [PATCH 22/38] feat: add groups stubs --- phpstan/stubs/public/lib/grouplib.stub | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/phpstan/stubs/public/lib/grouplib.stub b/phpstan/stubs/public/lib/grouplib.stub index 7765df5d..0bf6688b 100644 --- a/phpstan/stubs/public/lib/grouplib.stub +++ b/phpstan/stubs/public/lib/grouplib.stub @@ -1,5 +1,24 @@ Date: Wed, 22 Jul 2026 18:22:29 +0100 Subject: [PATCH 23/38] feat: add grade_tree stub --- phpstan/stubs/public/grade/lib.stub | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 phpstan/stubs/public/grade/lib.stub diff --git a/phpstan/stubs/public/grade/lib.stub b/phpstan/stubs/public/grade/lib.stub new file mode 100644 index 00000000..af1b8f9c --- /dev/null +++ b/phpstan/stubs/public/grade/lib.stub @@ -0,0 +1,10 @@ + Date: Wed, 22 Jul 2026 18:22:35 +0100 Subject: [PATCH 24/38] fix: typo --- phpstan/stubs/public/lib/moodlelib.stub | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan/stubs/public/lib/moodlelib.stub b/phpstan/stubs/public/lib/moodlelib.stub index 12e994e0..bf647e6b 100644 --- a/phpstan/stubs/public/lib/moodlelib.stub +++ b/phpstan/stubs/public/lib/moodlelib.stub @@ -329,7 +329,7 @@ function clean_param_array(?array $param, $type, $recursive = false) { * $type is PARAM_AREA ? string : * $type is PARAM_PLUGIN ? string : * mixed - * )[] + * ) * @throws coding_exception&Throwable */ function clean_param($param, $type) { From e083bc91855004371e3fbd8eb805b3c4a0247a18 Mon Sep 17 00:00:00 2001 From: Felix Yeung <19355619+imfelixyeung@users.noreply.github.com> Date: Wed, 22 Jul 2026 18:22:44 +0100 Subject: [PATCH 25/38] feat: add email_to_user stub --- phpstan/stubs/public/lib/moodlelib.stub | 29 +++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/phpstan/stubs/public/lib/moodlelib.stub b/phpstan/stubs/public/lib/moodlelib.stub index bf647e6b..bb35d0d0 100644 --- a/phpstan/stubs/public/lib/moodlelib.stub +++ b/phpstan/stubs/public/lib/moodlelib.stub @@ -423,6 +423,35 @@ function get_user_preferences($name = null, $default = null, $user = null) { function fullname($user, $override = false) { } +/** + * @param stdClass $user + * @param stdClass|string $from + * @param string $subject + * @param string $messagetext + * @param string $messagehtml + * @param string $attachment + * @param string $attachname + * @param bool $usetrueaddress + * @param string $replyto + * @param string $replytoname + * @param int $wordwrapwidth + * @return bool + */ +function email_to_user( + $user, + $from, + $subject, + $messagetext, + $messagehtml = '', + $attachment = '', + $attachname = '', + $usetrueaddress = true, + $replyto = '', + $replytoname = '', + $wordwrapwidth = 79, +) { +} + /** * @phpstan-import-type get_string_a from lang_string * @param string $identifier From 656bcc745eb33cdf4bf5abcc5ab0e4d4085f49c7 Mon Sep 17 00:00:00 2001 From: Felix Yeung <19355619+imfelixyeung@users.noreply.github.com> Date: Fri, 24 Jul 2026 18:02:03 +0100 Subject: [PATCH 26/38] style: apply formatting --- phpstan/stubs/public/lib/weblib.stub | 1 - 1 file changed, 1 deletion(-) diff --git a/phpstan/stubs/public/lib/weblib.stub b/phpstan/stubs/public/lib/weblib.stub index 4d1b59d4..cef5a18c 100644 --- a/phpstan/stubs/public/lib/weblib.stub +++ b/phpstan/stubs/public/lib/weblib.stub @@ -16,7 +16,6 @@ define('FORMAT_MARKDOWN', '4'); function format_text($text, $format = \FORMAT_MOODLE, $options = null, $courseiddonotuse = null) { } - /** * @param string $message * @param DEBUG_NONE|DEBUG_MINIMAL|DEBUG_NORMAL|DEBUG_ALL|DEBUG_DEVELOPER $level From 5b726ab04d911baaab726fc81e085d7c47758173 Mon Sep 17 00:00:00 2001 From: Felix Yeung <19355619+imfelixyeung@users.noreply.github.com> Date: Fri, 24 Jul 2026 18:02:10 +0100 Subject: [PATCH 27/38] feat: add more stubs --- .../stubs/public/course/classes/category.stub | 14 +++++ phpstan/stubs/public/lib/completionlib.stub | 22 ++++++++ phpstan/stubs/public/lib/datalib.stub | 51 +++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 phpstan/stubs/public/lib/datalib.stub diff --git a/phpstan/stubs/public/course/classes/category.stub b/phpstan/stubs/public/course/classes/category.stub index 6f5220d4..61e3c6cd 100644 --- a/phpstan/stubs/public/course/classes/category.stub +++ b/phpstan/stubs/public/course/classes/category.stub @@ -10,6 +10,20 @@ use const IGNORE_MULTIPLE; use const MUST_EXIST; /** + * @property-read int $id + * @property-read string $name + * @property-read string $idnumber + * @property-read string $description + * @property-read int $descriptionformat + * @property-read int $parent + * @property-read int $sortorder + * @property-read int $coursecount + * @property-read int $visible + * @property-read int $visibleold + * @property-read int $timemodified + * @property-read int $depth + * @property-read string $path + * @property-read string $theme * @implements IteratorAggregate */ class core_course_category implements cacheable_object_interface, IteratorAggregate, renderable { diff --git a/phpstan/stubs/public/lib/completionlib.stub b/phpstan/stubs/public/lib/completionlib.stub index 6bcfaeec..19b89496 100644 --- a/phpstan/stubs/public/lib/completionlib.stub +++ b/phpstan/stubs/public/lib/completionlib.stub @@ -1,5 +1,27 @@ id + * @param bool $wholecourse + * @param int $userid + * @param mixed $unused + * @return stdClass + */ + public function get_data($cm, $wholecourse = false, $userid = 0, $unused = null) { + } + + /** + * @param string $error + * @return never + * @throws moodle_exception + */ + public function internal_systemerror($error) { + } +} diff --git a/phpstan/stubs/public/lib/datalib.stub b/phpstan/stubs/public/lib/datalib.stub new file mode 100644 index 00000000..35a5ad21 --- /dev/null +++ b/phpstan/stubs/public/lib/datalib.stub @@ -0,0 +1,51 @@ + $courses + * @param int|null $userid + * @param int $includeinvisible + * @return stdClass[] + */ +function get_all_instances_in_courses($modulename, $courses, $userid = null, $includeinvisible = false) { +} + +/** + * @param string $modulename + * @param int|stdClass $course + * @param int $userid + * @param int $includeinvisible + * @return stdClass[] + */ +function get_all_instances_in_course($modulename, $course, $userid = null, $includeinvisible = false) { + return get_all_instances_in_courses($modulename, [$course->id => $course], $userid, $includeinvisible); +} From ea1b0e13c22fdf3a1d994cc868e5ca11ded32b7a Mon Sep 17 00:00:00 2001 From: Felix Yeung <19355619+imfelixyeung@users.noreply.github.com> Date: Tue, 28 Jul 2026 18:39:51 +0100 Subject: [PATCH 28/38] feat: add more stubs --- phpstan/stubs/public/lib/completionlib.stub | 2 +- phpstan/stubs/public/lib/datalib.stub | 2 ++ phpstan/stubs/public/lib/moodlelib.stub | 7 +++++++ .../public/lib/phpmailer/moodle_phpmailer.stub | 4 ++++ phpstan/stubs/public/user/selector/lib.stub | 15 +++++++++++++++ phpstan/stubs/vendor/phpmailer.stub | 6 ++++++ 6 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 phpstan/stubs/public/lib/phpmailer/moodle_phpmailer.stub create mode 100644 phpstan/stubs/public/user/selector/lib.stub create mode 100644 phpstan/stubs/vendor/phpmailer.stub diff --git a/phpstan/stubs/public/lib/completionlib.stub b/phpstan/stubs/public/lib/completionlib.stub index 19b89496..0a5d6de8 100644 --- a/phpstan/stubs/public/lib/completionlib.stub +++ b/phpstan/stubs/public/lib/completionlib.stub @@ -20,7 +20,7 @@ class completion_info { /** * @param string $error * @return never - * @throws moodle_exception + * @throws moodle_exception&Throwable */ public function internal_systemerror($error) { } diff --git a/phpstan/stubs/public/lib/datalib.stub b/phpstan/stubs/public/lib/datalib.stub index 35a5ad21..1cac4f0b 100644 --- a/phpstan/stubs/public/lib/datalib.stub +++ b/phpstan/stubs/public/lib/datalib.stub @@ -11,6 +11,8 @@ * @param string $page * @param string $recordsperpage * @param string $fields + * @param string $extraselect + * @param mixed[]|null $extraparams * @return ($get is true ? stdClass[] : int) */ function get_users( diff --git a/phpstan/stubs/public/lib/moodlelib.stub b/phpstan/stubs/public/lib/moodlelib.stub index bb35d0d0..0ffd0941 100644 --- a/phpstan/stubs/public/lib/moodlelib.stub +++ b/phpstan/stubs/public/lib/moodlelib.stub @@ -423,6 +423,13 @@ function get_user_preferences($name = null, $default = null, $user = null) { function fullname($user, $override = false) { } +/** + * @param 'get'|'buffer'|'close'|'flush' $action + * @return ($action is 'get' ? moodle_phpmailer : null) + */ +function get_mailer($action = 'get') { +} + /** * @param stdClass $user * @param stdClass|string $from diff --git a/phpstan/stubs/public/lib/phpmailer/moodle_phpmailer.stub b/phpstan/stubs/public/lib/phpmailer/moodle_phpmailer.stub new file mode 100644 index 00000000..36b1f549 --- /dev/null +++ b/phpstan/stubs/public/lib/phpmailer/moodle_phpmailer.stub @@ -0,0 +1,4 @@ + Date: Wed, 29 Jul 2026 17:51:48 +0100 Subject: [PATCH 29/38] feat: more stubs --- phpstan/stubs/public/lib/classes/text.stub | 12 ++++++++++++ phpstan/stubs/public/lib/formslib.stub | 6 ++++++ 2 files changed, 18 insertions(+) create mode 100644 phpstan/stubs/public/lib/classes/text.stub diff --git a/phpstan/stubs/public/lib/classes/text.stub b/phpstan/stubs/public/lib/classes/text.stub new file mode 100644 index 00000000..3814c7af --- /dev/null +++ b/phpstan/stubs/public/lib/classes/text.stub @@ -0,0 +1,12 @@ + $data * @param array $files From 7a94061ab9ebb020fa7bc3f5bf33b50ae36ed679 Mon Sep 17 00:00:00 2001 From: Felix Yeung <19355619+imfelixyeung@users.noreply.github.com> Date: Sat, 1 Aug 2026 01:08:58 +0100 Subject: [PATCH 30/38] feat: add more stubs --- .../backup/converter/moodle1/handlerlib.stub | 28 +++++++++++++++++++ .../stubs/public/course/moodleform_mod.stub | 6 ++++ .../lib/classes/output/html_writer.stub | 25 +++++++++++++++++ phpstan/stubs/public/lib/weblib.stub | 6 ++++ phpstan/stubs/public/user/profile/lib.stub | 12 ++++++++ 5 files changed, 77 insertions(+) create mode 100644 phpstan/stubs/public/backup/converter/moodle1/handlerlib.stub create mode 100644 phpstan/stubs/public/lib/classes/output/html_writer.stub create mode 100644 phpstan/stubs/public/user/profile/lib.stub diff --git a/phpstan/stubs/public/backup/converter/moodle1/handlerlib.stub b/phpstan/stubs/public/backup/converter/moodle1/handlerlib.stub new file mode 100644 index 00000000..0e272045 --- /dev/null +++ b/phpstan/stubs/public/backup/converter/moodle1/handlerlib.stub @@ -0,0 +1,28 @@ +xmlwriter + * @param string $filename + * @return void + */ + protected function open_xml_writer($filename) { + } + + /** + * @phpstan-assert null $this->xmlwriter + * @return void + */ + protected function close_xml_writer() { + } +} + +abstract class moodle1_mod_handler extends moodle1_plugin_handler { + /** + * @param int $instance + * @param string $modname + * @return mixed + */ + protected function get_cminfo($instance, $modname = null) { + } +} diff --git a/phpstan/stubs/public/course/moodleform_mod.stub b/phpstan/stubs/public/course/moodleform_mod.stub index 79748b2e..dd701f9d 100644 --- a/phpstan/stubs/public/course/moodleform_mod.stub +++ b/phpstan/stubs/public/course/moodleform_mod.stub @@ -11,4 +11,10 @@ abstract class moodleform_mod extends moodleform { */ protected function standard_intro_elements($customlabel = null) { } + + /** + * @return stdClass|null + */ + public function get_data() { + } } diff --git a/phpstan/stubs/public/lib/classes/output/html_writer.stub b/phpstan/stubs/public/lib/classes/output/html_writer.stub new file mode 100644 index 00000000..e151723a --- /dev/null +++ b/phpstan/stubs/public/lib/classes/output/html_writer.stub @@ -0,0 +1,25 @@ + 'choosedots'], + ?array $attributes = null, + array $disabled = [], + ): string { + } +} diff --git a/phpstan/stubs/public/lib/weblib.stub b/phpstan/stubs/public/lib/weblib.stub index cef5a18c..2a13a789 100644 --- a/phpstan/stubs/public/lib/weblib.stub +++ b/phpstan/stubs/public/lib/weblib.stub @@ -6,6 +6,12 @@ define('FORMAT_PLAIN', '2'); define('FORMAT_WIKI', '3'); define('FORMAT_MARKDOWN', '4'); +/** + * @return stdClass|false + */ +function data_submitted() { +} + /** * @param string $text * @param \FORMAT_MOODLE|\FORMAT_HTML|\FORMAT_PLAIN|\FORMAT_MARKDOWN $format diff --git a/phpstan/stubs/public/user/profile/lib.stub b/phpstan/stubs/public/user/profile/lib.stub new file mode 100644 index 00000000..c09adf9f --- /dev/null +++ b/phpstan/stubs/public/user/profile/lib.stub @@ -0,0 +1,12 @@ + Date: Sat, 1 Aug 2026 01:19:27 +0100 Subject: [PATCH 31/38] feat: format in batches --- scripts/phpstan/format-stubs.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/phpstan/format-stubs.sh b/scripts/phpstan/format-stubs.sh index 7aa75263..3071b957 100755 --- a/scripts/phpstan/format-stubs.sh +++ b/scripts/phpstan/format-stubs.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash -# Formats each stub. +# Formats stub files in batches. # # Note that we don't use `./vendor/bin/pint phpstan/stubs/**/*.stub` # in case there are too many stubs to pass to pint. set -euo pipefail +readonly BATCH_SIZE=50 + find phpstan/stubs -type f -name '*.stub' -print0 | -while IFS= read -r -d '' stub; do - ./vendor/bin/pint "$stub" -done +xargs -0 -n "$BATCH_SIZE" ./vendor/bin/pint From 3cb9f3a23f8070b712162d116bd953bd776337bd Mon Sep 17 00:00:00 2001 From: Felix Yeung <19355619+imfelixyeung@users.noreply.github.com> Date: Sat, 1 Aug 2026 01:24:07 +0100 Subject: [PATCH 32/38] feat: add --check flag support --- scripts/phpstan/format-stubs.sh | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/scripts/phpstan/format-stubs.sh b/scripts/phpstan/format-stubs.sh index 3071b957..ac839313 100755 --- a/scripts/phpstan/format-stubs.sh +++ b/scripts/phpstan/format-stubs.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash # Formats stub files in batches. +# Optionally --check to run in CI mode. # # Note that we don't use `./vendor/bin/pint phpstan/stubs/**/*.stub` # in case there are too many stubs to pass to pint. @@ -8,5 +9,31 @@ set -euo pipefail readonly BATCH_SIZE=50 +pint_args=() + +case "${1:-}" in + "") + ;; + --check) + pint_args+=(--test) + ;; + *) + echo "Usage: $0 [--check]" >&2 + exit 1 + ;; +esac + +status=0 + +set +e find phpstan/stubs -type f -name '*.stub' -print0 | -xargs -0 -n "$BATCH_SIZE" ./vendor/bin/pint + xargs -0 -n "$BATCH_SIZE" ./vendor/bin/pint "${pint_args[@]}" +xargs_status=$? +set -e + +# xargs returns 123 if any invocation exited with status 1-125. +if [ "$xargs_status" -ne 0 ]; then + status=1 +fi + +exit "$status" From 62fb4d09abced13afb58f47af628c10d057b5018 Mon Sep 17 00:00:00 2001 From: Felix Yeung <19355619+imfelixyeung@users.noreply.github.com> Date: Sat, 1 Aug 2026 01:28:35 +0100 Subject: [PATCH 33/38] fix: resolve phpstan issues --- .../stubs/public/backup/converter/moodle1/handlerlib.stub | 8 ++++++++ phpstan/stubs/public/backup/util/interfaces.stub | 4 ++++ phpstan/stubs/public/backup/util/xml.stub | 3 +++ phpstan/stubs/public/lib/classes/output/html_writer.stub | 2 +- 4 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 phpstan/stubs/public/backup/util/interfaces.stub create mode 100644 phpstan/stubs/public/backup/util/xml.stub diff --git a/phpstan/stubs/public/backup/converter/moodle1/handlerlib.stub b/phpstan/stubs/public/backup/converter/moodle1/handlerlib.stub index 0e272045..2bd80946 100644 --- a/phpstan/stubs/public/backup/converter/moodle1/handlerlib.stub +++ b/phpstan/stubs/public/backup/converter/moodle1/handlerlib.stub @@ -1,6 +1,11 @@ xmlwriter * @param string $filename @@ -17,6 +22,9 @@ abstract class moodle1_xml_handler extends moodle1_handler { } } +abstract class moodle1_plugin_handler extends moodle1_xml_handler {} + + abstract class moodle1_mod_handler extends moodle1_plugin_handler { /** * @param int $instance diff --git a/phpstan/stubs/public/backup/util/interfaces.stub b/phpstan/stubs/public/backup/util/interfaces.stub new file mode 100644 index 00000000..5815fcad --- /dev/null +++ b/phpstan/stubs/public/backup/util/interfaces.stub @@ -0,0 +1,4 @@ + Date: Mon, 10 Aug 2026 18:12:31 +0100 Subject: [PATCH 34/38] feat: add progress bar stubs --- .../public/lib/classes/output/progress_bar.stub | 6 ++++++ .../lib/classes/output/stored_progress_bar.stub | 6 ++++++ .../classes/task/stored_progress_task_trait.stub | 16 ++++++++++++++++ 3 files changed, 28 insertions(+) create mode 100644 phpstan/stubs/public/lib/classes/output/progress_bar.stub create mode 100644 phpstan/stubs/public/lib/classes/output/stored_progress_bar.stub create mode 100644 phpstan/stubs/public/lib/classes/task/stored_progress_task_trait.stub diff --git a/phpstan/stubs/public/lib/classes/output/progress_bar.stub b/phpstan/stubs/public/lib/classes/output/progress_bar.stub new file mode 100644 index 00000000..7e807e14 --- /dev/null +++ b/phpstan/stubs/public/lib/classes/output/progress_bar.stub @@ -0,0 +1,6 @@ +progress + */ + protected function start_stored_progress(): void { + } +} From 460131fac9ac8cc6ac621470d1d345d9dd4053c0 Mon Sep 17 00:00:00 2001 From: Felix Yeung <19355619+imfelixyeung@users.noreply.github.com> Date: Mon, 10 Aug 2026 18:12:46 +0100 Subject: [PATCH 35/38] style: auto format --- .../stubs/public/backup/converter/moodle1/handlerlib.stub | 7 ++++--- phpstan/stubs/public/backup/util/xml.stub | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/phpstan/stubs/public/backup/converter/moodle1/handlerlib.stub b/phpstan/stubs/public/backup/converter/moodle1/handlerlib.stub index 2bd80946..564ab55f 100644 --- a/phpstan/stubs/public/backup/converter/moodle1/handlerlib.stub +++ b/phpstan/stubs/public/backup/converter/moodle1/handlerlib.stub @@ -1,6 +1,7 @@ Date: Mon, 10 Aug 2026 18:15:30 +0100 Subject: [PATCH 36/38] feat: add editor_tiny\plugin_with_configuration stubs --- .../lib/editor/tiny/classes/editor.stub | 6 ++++++ .../classes/plugin_with_configuration.stub | 21 +++++++++++++++++++ phpstan/stubs/public/lib/editorlib.stub | 4 ++++ 3 files changed, 31 insertions(+) create mode 100644 phpstan/stubs/public/lib/editor/tiny/classes/editor.stub create mode 100644 phpstan/stubs/public/lib/editor/tiny/classes/plugin_with_configuration.stub create mode 100644 phpstan/stubs/public/lib/editorlib.stub diff --git a/phpstan/stubs/public/lib/editor/tiny/classes/editor.stub b/phpstan/stubs/public/lib/editor/tiny/classes/editor.stub new file mode 100644 index 00000000..00c7c481 --- /dev/null +++ b/phpstan/stubs/public/lib/editor/tiny/classes/editor.stub @@ -0,0 +1,6 @@ + $options + * @param array $fpoptions + * @param editor $editor + * @return array + */ + public static function get_plugin_configuration_for_context( + context $context, + array $options, + array $fpoptions, + ?editor $editor = null, + ): array; +} diff --git a/phpstan/stubs/public/lib/editorlib.stub b/phpstan/stubs/public/lib/editorlib.stub new file mode 100644 index 00000000..0ec62085 --- /dev/null +++ b/phpstan/stubs/public/lib/editorlib.stub @@ -0,0 +1,4 @@ + Date: Wed, 26 Aug 2026 22:25:17 +0100 Subject: [PATCH 37/38] feat: add more stubs --- .../stubs/public/ai/classes/placement.stub | 27 +++++++++++++++++++ .../lib/classes/output/templatable.stub | 6 +++++ 2 files changed, 33 insertions(+) create mode 100644 phpstan/stubs/public/ai/classes/placement.stub diff --git a/phpstan/stubs/public/ai/classes/placement.stub b/phpstan/stubs/public/ai/classes/placement.stub new file mode 100644 index 00000000..3e7b53ba --- /dev/null +++ b/phpstan/stubs/public/ai/classes/placement.stub @@ -0,0 +1,27 @@ +[] + */ + abstract public static function get_action_list(): array; + + /** + * @return array{'action': string}[] + */ + public static function get_actions_available(context $context, bool $checkcontext = true): array { + return []; + } + + /** + * @return array{'action': string}[] + */ + public function get_sub_actions(string $classname): array { + return []; + } +} diff --git a/phpstan/stubs/public/lib/classes/output/templatable.stub b/phpstan/stubs/public/lib/classes/output/templatable.stub index e15c1391..98926bc2 100644 --- a/phpstan/stubs/public/lib/classes/output/templatable.stub +++ b/phpstan/stubs/public/lib/classes/output/templatable.stub @@ -2,5 +2,11 @@ namespace core\output; +use stdClass; + interface templatable { + /** + * @return stdClass|array + */ + public function export_for_template(renderer_base $output); } From d5f15a933e06af9bfb298b1d5de4ba9a9355d63c Mon Sep 17 00:00:00 2001 From: Felix Yeung <19355619+imfelixyeung@users.noreply.github.com> Date: Wed, 26 Aug 2026 22:28:57 +0100 Subject: [PATCH 38/38] fix: add missing stub --- phpstan/stubs/public/ai/classes/aiactions/base.stub | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 phpstan/stubs/public/ai/classes/aiactions/base.stub diff --git a/phpstan/stubs/public/ai/classes/aiactions/base.stub b/phpstan/stubs/public/ai/classes/aiactions/base.stub new file mode 100644 index 00000000..2fdbc4b1 --- /dev/null +++ b/phpstan/stubs/public/ai/classes/aiactions/base.stub @@ -0,0 +1,6 @@ +