To ensure that the filter options for the day filter menu matches
the menu pattern and pass accessibility checks, we need to:
* Group the due date filter options, labelled by the "Due date"
"heading".
* Set the "Due date" heading with a presentation role to prevent
assistive technologies from announcing it when the user goes through
the menu options.
The asynchronouse backup/restore tests are only concerned with testing
the implementation of the accompanying task class directly. When they
try to do so at a distance via the task manager API they introduce
random failures by failing to account for different queued tasks that
come from other components (e.g. Workplace).
Part of MDL-87351
- Discourage tool_moodlenet unless pointing to custom installation
- Clear activity chooser footer if set to MoodleNet
- Cleanup happens for: moodle.net URL, www.moodle.net, or empty config
- Preserves custom/local MoodleNet installations
* In order to meet WCAG 2.2 criterion for minimum target size and make
it easier for users who have mobility limitations to use the quiz
editing page, we need to use the Bootstrap icon button styles and
increase the size and the spacing for the following buttons:
* Add/remove page break button
* Lock/unlock question dependency button
* This commit also makes the icons within the buttons as decorative and
moves the accessible name to the button elements themselves via the
aria-label attribute.
* Adjust Behat tests for checking the dependency buttons.
* Add accessibility Behat coverage for the quiz edit page.
The YUI dragdrop handles rely on the button's title attribute for its
accessible label. We should label it appropriately using the
aria-label attribute.
* Lighten the background for the question formulation container.
* Lighten the background for the question feedback container while
slightly darkening the text font as well.
This allows for tests to interact with multiple elements of this type
during scenarios, whereas previously Behat would always try to interact
with the first (even when referring to latter file managers).
When run from behat/cli/run.php, the pause command may fail because
it thinks the terminal is not interactive, even if the input and
output is passed through from an interactive terminal run.
* The arrow icons produced by the `$OUTPUT->larrow()` and
`$OUTPUT->rarrow()` functions are announced by screen readers, and they
do not make sense when heard by screen reader users. To fix this,
we need to override the accessible names of the previous and next
activity links using the `aria-label` attribute and specify whether the
activity links point to the previous or next activities.
* The label for the jump menu "Jump to" is not informative enough to
convey the element's purpose. Let's improve it's accessible label to
"Jump to activity".
Both the pgsql and mysql steps we were using use `docker:stable`, which
has been abandoned and is not a recommended approach. They are also both
abandoned.
This commit moves to using a service entry for postgres; and a manual
step for mysql.
We can't use the services entry for MySQL because GHA does not support
providing arguments to service containers.
Since Chrome 142, public servers accessing resources on local networks
gets blocked by default. Users need to allow access for such requests
to proceed.
This patch introduces a new config setting `ltiallowlocalnetwork`.
This determines if the local-network-access flag should be added to LTI
iframes so that Chrome users get prompted when a local network access
is being made.
`\core\output\core_renderer::confirm()`'s `$displayoptions` parameter
now also accepts a `headinglevel` option that developers can use to
specify the heading level of the confirmation's heading. If not
specified, the confirmation heading will be rendered in an `h4` tag.
scoreGiven was being passed as a string (e.g. "8.0"), which caused
validation errors in some LMS implementations such as Rustici Engine.
According to the LTI specification, scoreGiven must be numeric if
present.
Co-authored-by: Jake Dallimore <jake@moodle.com>
https://github.com/packbackbooks/lti-1-3-php-library/issues/169 blocks
us from using the new build.1edtech certification tooling. This issue
commits that fix as a library customisation/hack for stables, so the
suite can be used for annual/bi-annual re-certification.
* Add a slight delay for displaying the message content of the YUI
alert dialogue's ARIA live container to allow screen readers to
announce the alert message accordingly.
Adjusts the window size to accommodate wide tables.
This ensures that columns which were previously clipped
are now visible and accessible to the Behat driver.
The sortable list module in 4.5 still depends on jQuery instead of
native events. We need to adjust the usage of sortable list for the
edit questions page of the feedback activity accordingly.
Improve upgrade execution by gathering block instance IDs upfront
and processing deletions of related records in context, block_positions, user_preferences, and block_instances tables in batches.
Refactor get_nearest_editable_subcategory to improve performance.
This refactor maintains functionality and signature of
get_nearest_editable_subcategory but improves perofrmance
for varied datasets. This makes rendering of the
my courses page.
* Set proper label via `aria-label`.
* Instead of changing the button's label to 'Show'/'Hide', set the
button's `aria-expanded` attribute accordingly.
* Remove unnecessary event handling for the toggle button when pressing
Enter or Space key. This is already natively supported and triggers
the click event.
* Adjust Behat tests accordingly.
Avoids PHP warnings during Behat initialisation:
- file_put_contents(...): Failed to open stream: No such file or directory;
- rename(...): No such file or directory
Change the query used to check if a user has a capability but is
assigned a role that prohibits that capability. This is based on the
query added by Petr Skoda for MDL-57027.
If the `\core_shutdown_manager::initialize` method is called multiple
times, it should only succeed once.
Unfortunately whilst logging existed, the shutdown manager did not
actually exit.
* Check the accessibility of the questionnaire, especially when
there are dependent questions.
* Use generators for a more efficient and faster test execution.
Making a visual distinction for dependent questions compared to other
questions does not add much value in the perspective of users. We should
just stop adding the `.feedback_is_dependent` class for dependent
questions.
- The current context may be necessary when deleting a frontpage block displayed on every page with javascript disabled
- The current context may be necessary when a frontpage block is displayed on every page and the question bank is viewed
- Also handle a NULL currentcontext for question_page_type_list() correctly
* Fix missing labels for the checkboxes that enable notification plugins
* Add an accessible name for the Default notification preferences table
* Fix missing table header for the preference column of the Default
notification preferences table.
* Accessibility Behat test coverage for the Notification settings
admin page
* Remove the unnecessary title attributes for the visually hidden labels
* Fix missing column heading for the preference column
* Fix incorrect label for the toggle controls
* Make the preference name a table heading with a row scope so that the
toggle controls will be programmatically associated to it.
* Apply a col scope for the processor column headings to
programmatically associate the toggle controls to their respective
columns.
Whilst `register_shutdown_function` works as a queue, `pcntl_signal`
does not.
To preserve the behaviour of existing signal handlers, as are typically
found in CLI wrappers like PHPUnit and Behat, we should store any
existing handler
Include the category and field names for accessible names of the delete
and action buttons to help assistive technology users better understand
the buttons' purpose.
* Use native HTML buttons for the edit and delete buttons. This provides
default button behaviours which helps keyboard users activate the
buttons using either the Space or Enter key.
* Move the accessible label out of the pix icon and to the action button
itself.
* Style buttons to ensure that they have a minimum clickable size of
24x24 pixels to sufficiently meet WCAG 2.2 SC 2.5.8 - Target Size
(Minimum) (Level AA).
* Fix empty column heading in admin settings page
* Add accessible labels for the move buttons
* Fix drag and drop Behat test
* Add accessibility Behat coverage
When the login form is not shown but $CFG->loginautofocus is turned on,
we need to verify first that the username and password fields exist
before we move the focus. Otherwise, the JS will break.
Visually hidden links on login error/info disrupt tab order. We must
remove them.
Instead, announce the div containing the login error/info messages on
page reload.
The visually hidden signup link has also been removed.
The title attribute with value "View profile" on profile links is
not necessary as the user's name on the link itself is sufficient
to convey the purpose of the link.
Standard after a POST submission is to redirect back to where user came
from (in this case), to avoid awkward page reload behaviour. Also fix
bug where deleting an attempt for a user, where the attempt didn't exist
would delete all attempts for that user.
unset_excluded_fields() was using isset() to determine if the field
targeted for removal is present in the provided data structure. However,
isset() returns false if the field exists, but contains null. This means
the field will not be unset when it should be.
This resolves this by changing the isset() to a property_exists() check
for objects, and array_key_exists() check for arrays. It also expands
the function to properly handle arrays of arrays, or arrays of values,
which was not fully covered before and is used by some third-party
question types.
Updated the Google Drive integration to use the drive.file scope instead
of the broader drive scope. This change removes support for shared drives,
which rely on full access. As a result, unit tests were updated to reflect
this behavior by bypassing shared drive checks and expectations.
Boost theme removes the last item action.
This adds an extra node so the profile run details page breadcrumb is clickable in both Classic and Boost themes.
* Set the action label properly.
* Set the kebab icon as a decorative icon.
* Move the title attribute to the menu button itself instead of the
kebab icon.
When the bulk actions are first rendered, the item count in the
aria-live region will not be announced by screen readers as aria-live
regions need to be present in the DOM and changed before screen readers
can announce their content.
This commit ensures that the item selection count will be announced
when the bulk actions get added to the DOM by calling
`updateBulkItemSelection()` after rendering the bulk actions HTML. This
removes the non-breaking space in the template, effectively causing a
change in DOM without affecting the visuals, and allowing screen readers
to announce the contents of the item count.
Add a status role for the container containing the number of selected
items for bulk actions so that screen readers will announce this
number when an item gets selected for bulk action.
- Fixing the exceptions shows an incorrectly formatted table
- The filler cell is only used to take space on the left rows but when the right rows are empty, it is not needed.
The change in the calendar button from an `<a>` tag to a native
`<button>` tag means the `\HTML_QuickForm_group::getValue()` will have
a different result and the `test_onquickformevent()` tests must be
adjusted accordingly.
- Since `Geoplugin` is not free anymore, a new admin setting called `GeoPlugin API key` has been added for user to input
their API key if they still want to use `Geoplugin` service.
- The `iplookup_find_location()` method has been improved to handle error responses more effectively.
Rounding time could lead to newest enrolments being excluded, resulting in
these courses not appearing under the "My courses" tab in the Dashboard until the rounded time aligned with the actual time.
enrol_get_all_users_courses() now uses the PSR-20 clock to provide stable
and testable time values.
Adds support for the timefinish attribute to the quiz attempt
generator allowing Behat scenarios to specify the exact completion
time of an attempt.
This is necessary to simulate a scenario where the student finished
the attempt few minutes ago for example.
This commit also adds two scenarios that automates MDLQA-307.
For no very obvious reason, the date in the 'You have just
submitted your assignemnt' message was formatted differently
from the default used on-screen.
This commit makes it consistent.
* Make the calendar icon decorative.
* Mark up the calendar button accordingly:
- Render it as a `<button type="button">`
- Add label using `aria-label`.
- Use a more suitable label of "Date picker" rather than "Calendar"
- Add a `title` attribute to show a tooltip for sighted users.
- Disable/enable it accordingly by setting/removing the `disabled`
attribute.
The removal in d0d62fd0 of the `.form-inline` class caused the
mis-alignment of checkbox inputs in the "Search options" container.
Restore behaviour provided by the aforementioned class in descendent
elements by applying corresponding styles, that were lost with that
change.
* Set `alt` param as empty, but add `title` attribute for the sake of
sighted users.
* Add a visually hidden string that indicates the element is required.
The welcome message on login was incorrectly replacing the dashboard
page header.The change ensures the welcome message appears as a
paragraph while maintaining the dashboard page heading.
* Make the accessible labels of the previous and next month links more
informative by indicating the name of the previous/next months.
* Make titles on the previous and next month links reflect the actual
month and show titles only when the calendar is rendered within a block.
This is because the title attribute is only used for the sake for
sighted users who may need to know the meaning of the previous/next
month links, especially when the calendar is displayed in compact form
where the previous/next month name is not shown.
This backports the applicable part of MDL-85210 to 4.5.
move_question_set_references expected the set reference to use the old
filter format.
This change converts the filter to the new format if required, before
updating the category and context ids.
A multianswer question with a missing database record no longer throws
an exception, so doesn't work for the "broken question" test, so switch
to ddwtos.
If a multianswer question has its question_multianswer record missing
for some reason, attempting to backup and restore a bank containing the
question will result a dml_missing_record exception.
The qtype_multianswer::get_question_options() method already copes with
the sequence from this record being empty, so we can just remove the
MUST_EXIST check and let it fall back to that.
The upgrade step for Microsoft OAuth2 issuers has been modified
to address an oversight in MDL-84432. The upgrade now only updates
service base urls for multi-tenant issuers.
Co-authored-by: Raju Tummoji <raju.tummoji@moodle.com>
This change addresses necessary adjustments to how OBV2.0 badges are
sent to backpacks, specifically to ensure compatibility and correct
functionality following recent updates to Canvas Credentials' conditions.
It ensures our badge integration continues to operate smoothly despite
these external changes.
This follows the recommendation on the ARIA Authoring Practices Guide
(APG) for modal dialogues:
> It is strongly recommended that the tab sequence of all dialogs
> include a visible element with role button that closes the dialog,
such as a close icon or cancel button.
https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/
I’ve updated the query to use sql_isnotempty, which generates the correct SQL for the selected database.
I have aso added an "order by" because after some testing I noticed that Oracle and MySQL retun the results
in different order which feels inconsistent and makes it more difficult to test.
This changeset adds a new `\core\deprecation::emit_deprecation` method
with the same signature as the `emit_deprecation_if_found()` method.
It is intended to be used in places where something is guaranteed to
have been deprecated, and will throw appropriate debugging if the
deprecated attribute is not found.
The `emit_deprecation_if_found()` method should still be used where the
item being checked is not known to be deprecated or not, for example in
calling code.
This commit introduces a mandatory service selection step in our Behat tests
to ensure consistent behavior in environments with multiple third-party services.
Only allow the drag and drop functionality in the course index on pages
that provide alternatives to move course items such as the course
homepage and the course section view pages.
This is to meet the WCAG 2.2 Level AA Success Criterion 2.5.7 for
dragging movements.
See: https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements
This check exists to determine whether a given tool URL is a cartridge,
specifically when the URL does not end in .xml. It hits the URL to
determine this. In tests, we have many mock tool URLs, which won't
resolve, and running this code causes large hangs and random failures.
Any tests covering cartridge support still work fine, provided they
continue to use URLs ending in .xml; this change only skips the check
during tests for other non-xml URLs.
The drag handle and actions menu should not be within the accessible
labels of the question items. In order to enhance the question edit
form with these, they need to be rendered via JS outside of container
of the questions' accessible name.
The label context data in the fieldset's legend tag should not be
escaped and allow raw HTML given that legend tags can contain
phrasing content and headings.
See developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/legend.
When trying to resolve a corrupt cache where it is not possible to
complete the Moodle setup/bootstrap, it is necessary to ignore the
current cache to load the cache purging infrastructure.
When the assignment gets deleted between the creation of the ad-hoc task
mod_assign\task\send_assignment_due_soon_notification_to_user or
mod_assign\task\send_assignment_overdue_notification_to_user and its
execution, the ad-hoc task fails with a dml_missing_record_exception and
the task gets stuck.
In this case we do not want the task to fail and just return with an
appropriate mtrace.
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
To prevent the debugging messages from appearing during the upgrade,
I set a flag to hide them.
For the test file, I adjusted the parameters in
the unassign_capability() function, which seemed to be using
the parameter intended for assign_capability().
The parameter are usable in course participants page because user
could add bulk notes linked to users. But that script is not used
in report/participants, so we don't need those arguments on the call.
Backported from MDL-75669.
The required icon in mforms is not necessary. The div containing it
already has a title attribute that enables mouse users to hover on the
icon and see its meaning.
Screen reader users will know whether a field is required or not via
the `aria-required` attribute.
Labelling the required icon via `aria-label` does not pass the
a11y audit.
Given these, it only makes sense to make the required icon decorative
for mforms.
Co-authored-by: Jun Pataleta <jun@moodle.com>
When we build the options for a question category selector, the
"nochildrenof" option isn't correctly compared to the category ID. This
means we can select a category's own children as its new parent.
Previously, when the selected value in a choicelist was 0 but not in
the first position, the behavior was incorrect.
This commit fixes that issue, ensuring the choicelist behaves as expected
regardless of the position of the 0 value.
Using $CFG->recovergradesdefault and/or $gradeitem->refresh_grades()
are problematic when viewing a quiz. When reenrolling a user with
previous attempts, a teacher can choose not to recover the user's grades,
even when recovergradesdefault=true. This must be respected when
the user views the quiz. For site with recovergradesdefault=false,
the users always see a grade of 0, which is wrong.
This change shows the correct grade score and feedback to users and
avoids unintentionally recovering the grades.
Adds a unit test for the debugging message triggered when readfile_accel() detects
a non-empty output buffer. The readfile_accel() function directly manipulates the
output buffers, so calling it from within PHPUnit triggers an error like "Test code
or tested code closed output buffers other than its own".
As a workaround, the test runs a CLI script in a separate process, allowing buffer
behaviour to be isolated and debugging output to be captured for assertions.
Correct the error handling in readfile_accel to properly log errors when
working on a stored_file, rather than hiding the true error behind the
incorrect "Object of class stored_file could not be converted to
string."
Co-authored-by: Simey Lameze <simey@moodle.com>
Co-authored-by: Trisha Milan <trishamilan@catalyst-au.net>
This defines new group which can be used
to limit execution of these tests to one plugin only.
For example to execute all tests for Label module use:
phpunit --testsuite=mod_label_testsuite
phpunit --group=plugin_checks --filter=mod_label
or
phpunit --filter=mod_label
If question_numerical record for a question has been deleted, when its
options are loaded its answers will not have a tolerance property. This
can lead to duplication.
Also, older questions may not have a question_numerical_options record.
To avoid this, we use 0 as a default tolerance for all answers if there
is no matching record, and do the same when reading the question
structure from backups. We also generate default values for the rest of
the options.
If we restore a question (or any other) which has had its
qtype_xxx_options record deleted, we get a notification output when we
try to build the options.
This may be called from an AJAX request (such as when we duplicate a
quiz), and outputting the notification breaks the AJAX response.
Returning false also means we don't get the answers attached to the
questiondata options, so the structure doesn't match the restored data,
and we get duplication.
This emits the errors via debugging instead, which allows it to be
supressed or logged, and allows get_question_options() to continue
running.
This adds an ad-hoc task to clean up duplicate subquestions created by
the bug.
When the upgrade is run, it will run a query to check if any
subquestions have been duplicated (if there are multiple questions with
the same parent, text and stamp), and queue the cleanup task if there
are.
For each stamp identified, the task will find instances of the question
that are not referred to in their parent's sequence field, confirm that
they have 0 usages, and delete them.
qtype_multichoice::get_question_options() will create a default options
object if no qtype_multichoice_options record exists. This means if we
restore a backup containing a multichoice question without any options
(see previous commit), it will always create a duplicate.
This change generates a default set of options for the backupdata if
none exists, so the identity hash will match if the same question exists
in the database without options, and we dont get duplicates.
Historically, multianswer would re-use question IDs from subquestions,
so it was necessary to delete qtype-specific data if the qtype changed.
Since versioning was introduced, editing creates new versions of the
qtype and subquestions. Deleting the data means the original versions of
the subquestions cannot function correctly, so we shouldn't do that
anymore.
When using `clock::now()` the frozen cloxk and incrementing clock will now
always return a `DateTimeImmutable` that uses the configured Moodle system
time. In unit tests this will be Australia/Perth.
Before this change, it would sometimes be UCT.
Passing the same object means enrol_cohort does not recognise a change
in role when an edit or batch course upload operation is done.
* enrol/editinstance.php was modifying $instance before passing it to
enrol_plugin::update_instance() so the latter never sees a difference
versus $data. This is redundant since update_instance() is doing the
same thing a second time.
* admin/tool/uploadcourse/classes/course.php is passing the same object
as both arguments to enrol_plugin::update_instance().
There is an expectation that update_enrol_plugin_data() is to mutate its
$instance argument and then return it based on how derived classes in
enrol_guest and enrol_self behave, so cloning $instance within
update_enrol_plugin_data() before mutating it isn't an option.
Fixes the test_sequential_score_posts() unit test in lineitem_test
by removing dynamic class property assignments, which were triggering
deprecation notices.
The 'in' rule currently behaves the same way that 'eq' does when used
with multi-selects, which is not correct. It should be modelled by
checking whether the selected values are a subset of the rule values
(i.e. selected values are 'in' the rule values). This patch implements
that for core form rules as well as for the admin settings show/hide.
Several behat features are updated as well, because these were verifying
the incorrect behaviour for multi-select in rules.
When a forum activity used a rubrics with a scale for grading, it was not treated as an advanced grading method, causing
the code to mishandle the grading object and not return any grades.
If this is not passed in to grade_update(), then it's not passed on to
update_raw_grade(), resulting in time() being used instead, which isn't
correct. The grade timemodified value should be set to the timestamp
provided by the tool in the score post JSON, not the time of the score
post itself.
Co-authored-by: Jayce Birrell <jayce.birrell@moodle.com>
This tests highlights a problem with the score handling logic and
will currently fail. On score post, the current time is used for
grade->timemodified instead of the score->timestamp provided by the
tool in the POST JSON.
Because of historical requirements involving fieldsets in question
type forms (see 958e7671), we should use ARIA label attribute on
grouped elements rather than normal labels in order to make them
accessible.
Co-authored-by: Jun Pataleta <jun@moodle.com>
The test_restore_course_with_same_stamp_questions() test assumes
that all question types using answers will also use the table
"question_answers" to store said answers. However, some 3rd party
qtypes might use custom tables and for those, the test would fail.
Removes the preventDefault() call that previously prevented the
save/cancel modal from automatically closing when the 'Save' action
is applied for a specific bulk action on the assignment submissions
page.
This function was slow because using case-insensitive LIKE on the large
user_preferences table means that Postgres does not use its index and
has to sequential-scan the table.
@@ -6,6 +6,150 @@ More detailed information on key changes can be found in the [Developer update n
The format of this change log follows the advice given at [Keep a CHANGELOG](https://keepachangelog.com).
## 4.5.10+
### core
#### Added
- When creating upgrade notes, the issue number will be inferred from the current Git branch name by default
For more information see [MDL-87100](https://tracker.moodle.org/browse/MDL-87100)
- There is a new Behat `toast_message` named selector to more easily assert the presence of Toast messages on the page
For more information see [MDL-87443](https://tracker.moodle.org/browse/MDL-87443)
- The `core/toast` JS module now accepts a `visuallyHidden` configuration parameter to render visually hidden toast messages for screen reader users.
For more information see [MDL-87993](https://tracker.moodle.org/browse/MDL-87993)
### tool_behat
#### Added
- The `behat_session_trait::ensure_element_[does_not_]exists(...)` methods now accept optional `$container` parameter to define the parent node to look within
For more information see [MDL-75067](https://tracker.moodle.org/browse/MDL-75067)
## 4.5.9
### core
#### Changed
-`\core\output\core_renderer::confirm()`'s `$displayoptions` parameter now also accepts a `headinglevel` option that developers can use to specify the heading level of the confirmation's heading. If not specified, the confirmation heading will be rendered in an `h4` tag.
For more information see [MDL-87694](https://tracker.moodle.org/browse/MDL-87694)
## 4.5.8
### core
#### Changed
- The Hook Manager now uses localcache instead of caching via MUC.
For more information see [MDL-87107](https://tracker.moodle.org/browse/MDL-87107)
#### Fixed
-`restore_qtype_plugin::unset_excluded_fields` now returns the modified questiondata structure,
in order to support structures that contain arrays.
If your qtype plugin overrides `restore_qtype_plugin::remove_excluded_question_data` without
calling the parent method, you may need to modify your overridden method to use the returned
value.
For more information see [MDL-85975](https://tracker.moodle.org/browse/MDL-85975)
- When responding to pcntl signals, call existing signal handlers.
For more information see [MDL-87079](https://tracker.moodle.org/browse/MDL-87079)
### mod_glossary
#### Added
- Function mod_glossary_rating_can_see_item_ratings is now implemented for checking permissions to view ratings.
For more information see [MDL-86960](https://tracker.moodle.org/browse/MDL-86960)
## 4.5.7
### core
#### Added
- The Behat `::execute()` method now accepts an array-style callable in addition to the string `classname::method` format.
For more information see [MDL-86231](https://tracker.moodle.org/browse/MDL-86231)
- The `\externallib_advanced_testcase` has been replaced by `\core_external\tests\externallib_testcase` and is now autoloadable.
For more information see [MDL-86283](https://tracker.moodle.org/browse/MDL-86283)
### core_badges
#### Added
- A number of new static methods have been added to `core_badges\backpack_api` to support the new Canvas Credentials backpack provider. These methods allow you to retrieve lists of providers and regions, check if Canvas Credentials fields should be displayed, and get a region URL or API URL based on a given region ID. The new methods include `get_providers`, `get_regions`, `display_canvas_credentials_fields`, `get_region_url`, `get_region_api_url`, `get_regionid_from_url`, and `is_canvas_credentials_region`.
For more information see [MDL-86174](https://tracker.moodle.org/browse/MDL-86174)
### core_grades
#### Added
- New 'is_gradable()' function has been created to return whether the item has any gradeitem that is GRADE_TYPE_VALUE or GRADE_TYPE_SCALE.
For more information see [MDL-85837](https://tracker.moodle.org/browse/MDL-85837)
### core_message
#### Added
- The `contexturl` property to `\core\message\message` instances can now contain `\core\url` values in addition to plain strings
For more information see [MDL-83080](https://tracker.moodle.org/browse/MDL-83080)
## 4.5.6
### core
#### Added
- Add a new method has_valid_group in \core\report_helper that will return true or false depending if the user has a valid group. This is mainly false in case the user is not in any group in SEPARATEGROUPS. Used in report_log and report_loglive
For more information see [MDL-84464](https://tracker.moodle.org/browse/MDL-84464)
#### Changed
- The `\core\attribute\deprecated` attribute constructor `$replacement` parameter now defaults to null, and can be omitted
For more information see [MDL-84531](https://tracker.moodle.org/browse/MDL-84531)
- Added a new `\core\deprecation::emit_deprecation()` method which should be used in places where a deprecation is known to occur. This method will throw debugging if no deprecation notice was found, for example:
For more information see [MDL-85897](https://tracker.moodle.org/browse/MDL-85897)
### core_message
#### Added
- The web service `core_message_get_member_info` additionally returns `cancreatecontact` which is a boolean value for a user's permission to add a contact.
For more information see [MDL-72123](https://tracker.moodle.org/browse/MDL-72123)
- The `behat_session_trait::ensure_element_[does_not_]exists(...)` methods now accept optional `$container` parameter to define the parent node to look within
For more information see [MDL-75067](https://tracker.moodle.org/browse/MDL-75067)
And this is the same example but passing the items in the creation:
{{< php >}}
```php
/** @var core_renderer $output*/
$output=$PAGE->get_renderer('core');
@@ -72,32 +72,64 @@ $menu = new action_menu([
]);
echo$output->render($menu);
{{< / php >}}
```
### Setup the menu trigger
By default, the action menu trigger is a cog icon. However, the class has methods to convert it to a kebab menu or even display any arbitrary content.
By default, the action menu trigger is a button that uses the `t/edit_menu` icon and is displayed with a caret. However, the class has methods to convert it to a kebab menu or even display any arbitrary content.
// This example displays an "Edit" label for the trigger.
$menu=newaction_menu();
$menu->set_menu_trigger(get_string('edit'));
{{< / php >}}
```
##### Trigger with an icon
This example displays an icon for the trigger. When rendering the menu trigger button as an icon button, ensure that the icon is rendered as a decorative image. If you are using a `pix_icon`, pass an empty `$alt` parameter to make the icon decorative.
The accessible name of the icon button should be set within the button element itself. You can set an accessible name for the icon trigger button either by:
* Using the `::set_action_label()` method.
```php
$menu=newaction_menu();
// Make sure the pix icon is rendered as a decorative image by passing an empty alt parameter.
$icon=$output->pix_icon('t/edit','');
$menu->set_menu_trigger($icon);
$menu->set_action_label(get_string('edit'));
```
* Or alternatively, by adding a visually hidden text alongside the icon.
```php
$menu=newaction_menu();
// Make sure the pix icon is rendered as a decorative image by passing an empty alt parameter.
$icon=$output->pix_icon('t/edit','');
// Add a visually hidden text label for the trigger button.
{"version":3,"file":"footer.min.js","sources":["../src/footer.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Activity chooser footer handlers for tool_installaddon.\n *\n * @module tool_installaddon/footer\n * @copyright 2026 Safat Shahin <safat.shahin@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\nimport selectors from 'core_course/local/activitychooser/selectors';\n\n/**\n * Handle clicks in the chooser footer when installaddon is the active footer plugin.\n *\n * @param {Event} e The event being triggered\n * @param {Object} footerData The footer data generated for the chooser\n * @param {Object} modal The chooser modal\n */\nexport const footerClickListener = (e, footerData, modal) => {\n const closeOption = e.target.closest(selectors.actions.closeOption);\n\n if (!closeOption) {\n return;\n }\n\n const moduleName = closeOption.dataset.modname;\n\n if (!moduleName) {\n return;\n }\n\n const carousel = $(modal.getBody()[0].querySelector(selectors.regions.carousel));\n\n // Trigger the transition between 'pages'.\n carousel.carousel('prev');\n modal.setFooter(footerData.customfootertemplate);\n carousel.one('slid.bs.carousel', () => {\n const allModules = modal.getBody()[0].querySelector(selectors.regions.modules);\n const caller = allModules.querySelector(selectors.regions.getModuleSelector(moduleName));\n if (caller) {\n caller.focus();\n }\n });\n};\n"],"names":["e","footerData","modal","closeOption","target","closest","selectors","actions","moduleName","dataset","modname","carousel","getBody","querySelector","regions","setFooter","customfootertemplate","one","caller","modules","getModuleSelector","focus"],"mappings":";;;;;;;oNAiCmC,CAACA,EAAGC,WAAYC,eACzCC,YAAcH,EAAEI,OAAOC,QAAQC,mBAAUC,QAAQJ,iBAElDA,yBAICK,WAAaL,YAAYM,QAAQC,YAElCF,wBAICG,UAAW,mBAAET,MAAMU,UAAU,GAAGC,cAAcP,mBAAUQ,QAAQH,WAGtEA,SAASA,SAAS,QAClBT,MAAMa,UAAUd,WAAWe,sBAC3BL,SAASM,IAAI,oBAAoB,WAEvBC,OADahB,MAAMU,UAAU,GAAGC,cAAcP,mBAAUQ,QAAQK,SAC5CN,cAAcP,mBAAUQ,QAAQM,kBAAkBZ,aACxEU,QACAA,OAAOG"}
$string['acknowledgementtext']='I understand that it is my responsibility to have full backups of this site prior to installing additional plugins. I accept and understand that plugins (especially but not only those originating in unofficial sources) may contain security holes, can make the site unavailable, or cause private data leaks or loss.';
$string['activitychooserfootertext']='Browse more activities on';
$string['featuredisabled']='The plugin installer is disabled on this site.';
$string['installaddon']='Install plugin!';
$string['installaddons']='Install plugins';
@@ -44,6 +45,8 @@ $string['installfromzipsubmit'] = 'Install plugin from the ZIP file';
$string['installfromziptype']='Plugin type';
$string['installfromziptype_help']='For plugins that correctly declare their component name, the installer is able to detect the plugin type automatically. If the auto-detection fails, choose the correct type of plugin manually. Warning: The installation procedure can fail badly if an incorrect plugin type is specified.';
@@ -71,7 +71,7 @@ $string['setupfactor:instructionsverification'] = '3. Enter the verification cod
$string['setupfactor:intro']='To set up this method, you need to have a device with an authenticator app. If you don\'t have an app, you can download one. For example, <a href="https://2fas.com/" target="_blank">2FAS Auth</a>, <a href="https://freeotp.github.io/" target="_blank">FreeOTP</a>, Google Authenticator, Microsoft Authenticator or Twilio Authy.';
$string['setupfactor:key']='Secret key: ';
$string['setupfactor:link']='Or enter details manually.';
$string['setupfactor:link_help']='If you are on a mobile device and already have an authenticator app installed this link may work. Note that using TOTP on the same device as you login on can weaken the benefits of MFA.';
$string['setupfactor:link_help']='If you are on a mobile device and already have an authenticator app installed this link may work. Note that using TOTP on the same device as you login on can weaken the benefits of MFA.';
$string['setupfactor:linklabel']='Open app already installed on this device';
$string['defaultmoodlenetname_desc']='The name of the MoodleNet instance available via the activity chooser.';
$string['removalwarning_feature']='If you need to continue using MoodleNet, contact your site administrator about setting up a self-hosted MoodleNet instance.';
$string['removalwarning_service']='After the date, you will no longer be able to browse or add content from MoodleNet Central.';
$string['removalwarning_title']='The MoodleNet service will be shut down on 20 April 2026.';
$string['enablemoodlenet_desc']='If enabled, a user with the capability to create and manage activities can browse MoodleNet via the activity chooser and import MoodleNet resources into their course. In addition, a user with the capability to restore backups can select a backup file on MoodleNet and restore it into Moodle.';
$string['errorduringdownload']='An error occurred while downloading the file: {$a}';
@@ -31,7 +31,7 @@ $string['auth_shib_contact_administrator'] = 'In case you are not associated wit
$string['auth_shibbolethdescription']='Using this method users are created and authenticated using Shibboleth. For set-up details, see the <a href="{$a}">Shibboleth README</a>.';
$string['auth_shibboleth_errormsg']='Please select the organization you are member of!';
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.