Add missing entry for custom $CFG->localrequestdir locations in the
preconfigured array for $CFG->xsendfilealiases in config-dist.php.
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
We should not rely solely on the provided size information.
Therefore the system needs to recalculate the size of each file in the zip file,
whether small or big.
The changes also cover the filemanager.js file if an error appears.
Various re-factors over recent releases appear to have led to quite a
drift between actual functionality and what these scenarios assert for
imagined functionality. Page elements and content are referenced that
don't exist in multiple places.
Prior to this change, assertions of "should exist" and "should not
exist" in table content, where the step provided only a single column,
could give false positives and pass (when they shouldn't).
This commit is upgrading the joubel/core library to the one
tagged as 1.26 (which also increases the coreApi minorVersion).
That's why the previous commit was duplicating the existing
h5plib_v124.
This tag is also pointing to the same tag that the mod_hvp is using
too: https://github.com/h5p/moodle-mod_hvp/releases/tag/1.26.1
- Added a new method called get_messages_by_component()
This method will help to retreive the redirected messages
of specific component only
- Added a new method called get_messages_by_component_and_type()
This method will help to retreive the redirected messages
of specific component and type only
It should always be the case that a question category and its parent
category belong to the same context. However, over the years, we have
observed that this becomes violated by some data in some Moodle sites.
(The suspicion is that this is a backup/restor bug of some sort which
has never been tracked down.)
Since this happens, we should make the code robust to it, which is what
this change does. It ensure that when loading child categories, we only
consider ones in the same context.
* Fix the selector used to identify the preview icon element;
* Remove redundant code for handling it's click event, because it
already registers itself with a popup action which handles that.
The new API replaces identical behaviour in existing calling code, but
allows for profile field types to override/separate the logic used to
show the field and determine whether it's empty
* Changing the name of an activity should change the access restriction messages.
* Introduction of a marker as data-cm-name-for to be able to change any
occurence of a course module name in the page when this one changes.
The UX team proposal is to display two different notifications, to avoid confusion:
1. When the user is in preview mode:
Message: 'You are in preview mode.'
Notification Type: Information (blue), with the information permanently visible and not dismissible,
ensuring continuous awareness.
2. When activity tracking is disabled:
Message: 'Attempt tracking is not enabled for this activity. You can enable it in Settings.'
Notification Type: Warning (yellow) with a close icon for dismissal if tracking is intentionally disabled.
These notifications should only be visible to teachers and content creators, not students.
If a teacher also has a student role, this information should not appear when logged in as a student.
That's why the pre-existing is_tracking_enabled() function has been updated to only check if tracking
is on for an activity, without considering user capabilities (that's why the $user parameter has been
removed from this function too). Besides, a new function called can_submit() has been created to find
out if users are allowed to submit an activity.
* When forced groupmode is enabled for the course:
- the group selection in the activity card be disabled
- the activity action menu groupmode will not be visible.
- only the icon will be visible
* Add new test to check for visibility
The aria-labelledby attribute for the action menu link's <a> tag is
unnecessary as the <span> tag containing the action menu link's text
is already within the <a> tag and already serves as the link's label by
default.
For sites that rely on environment variables to set configuration,
ensure they are also present when executing task process.
Co-authored-by: Olivier Wenger <olivier.wenger@liip.ch>
Occurs when a plugin in incorrectly removed (via file system only,
rather than following proper uninstall process), and also contains
it's own sub-plugins.
In the above scenario, the update would request and receive back a
response for a plugin whose name was comprised of an empty string,
subsequently causing errors when processing said response.
If an existing session is active at the time of launch, that user id
appears in the user_updated log. This log should show the launching user
updating their own record, not someone else. To resolve this, auth the
user before making any record updates so that the event gets the correct
user id.
If an existing session is active at the time of launch, that user id
appears in the user_created log, incorrectly (it should be system/0).
This patch makes sure that any existing session is terminated before
creation of a new user during launches.
Instead of manually including composer's auto-loading
stuff and then run PHPUnit\TextUI\Command::main(), now
we are using the PHPUnit "binary".
That way behaviour should be 100% the same than
running vendor/bin/phpunit (recommended instead of util.php --run).
Also, note that, for other util.php commands, we still need
composer's auto-loading to happen, so we have moved it immediately
after the --run command.
Finally, a few more file_exists() conditions have been added
to ensure that PHPUnit is properly installed. Redundant but...
In the course external create/update methods, we must ensure that
the correct form element names are used. Specifically because the
textarea field type uses non-standard name.
This ensures compliance with the following WCAG criterion:
"H71: Providing a description for groups of form controls using fieldset
and legend elements".
This is consistent with the API used for other form element types,
in order to provide screen-readable text in the fieldset legend while
not necessarily wanting to display said label.
The new class property is automatically exported to the template via
the `templatable_form_element` trait.
The test now checks for the required icons, without needing to specify a count.
Allowing developers to add custom icons to the folder pix/f/mycustomicon.svg without needing to alter any unit test.
It's better for the task to fail gracefully rather than silently
swallow any errors, so that the task API can schedule re-tries.
If the endpoint is temporarily down and/or misbehaving, this will
allow admins to have clearer failures.
Also correctly extract the original file extension.
Co-authored-by: Andrew Nicols <andrew@nicols.co.uk>
Co-authored-by: Mazitov Artem <maz@2i.tusur.ru>
Implement grade validation for numeric grade overrides by setting
the type attribute for the grade input to number and setting a min
and max attribute values. Submitting the form with invalid values
will trigger built-in validation of the inputs.
* First parameter should be the field name that the format property
points to.
* No need for VALUE_REQUIRED since it's the default for the $required
parameter.
* Third parameter is the default value and not a description string.
* 'Content format' is passed to the $default parameter which is
incorrect.
* Also removed passing of VALUE_REQUIRED because it's already the
default value for the $required parameter.
- If a text format property defines the 'optional' attribute as true,
then the $required parameter that
is passed to \core\external\exporter::get_format_structure() should be
VALUE_OPTIONAL.
- If a default value is provided for a format property,
\core\external\exporter::get_format_structure() should pass the default
value to the external_format_value constructor.
- Added validation for external_format_value for the default parameter.
Debugging will be shown in case an invalid default value is passed.
- Amended unit tests for better coverage.
Since 4be39296 the root HTML element contains the iso6391 language
code of the current language pack. However various JS modules need
access to the original Moodle language pack code, so expose that
in the `M.cfg` structure.
The curent patch revealed a bug inside set_matrix_power_levels
where returned user power levels contained an array of objects.
Other methods were failing and giving incorrect responses
as they were expecting arrays.
When xdebug is set to break on exceptions it stops on all exceptions,
including _caught_ exceptions.
As a result we regularly hit this uniqid helper issue if debugging with
xdebug.
The solution is to check if the helper exists using the hasHelper method
instead of catching an exception when it does not exist.
This random error was caused because when reviewing an attempt,
the first pageid to display is calculated based on the timeseen
field in the lesson_attempst table.
In Oracle, sometimes it returned the second pageid (because both
had the same timeseen), so which led to these random failures.
Apart from adding 1-second wait when the attempt is created (to
guarantee the first page is returned properly), a few more
improvements have been also made, like removing manual steps for
setting the lesson activity or adding some extra checks to
confirm the information displayed is expected.
This works around a problem in SQL Server, which caused it to throw a
DML exception if the same column is duplicated in `ORDER BY` clause.
Backported from MDL-79270.
Tabs use the value of the data-target attribute of the active tab link
to find and display the appropriate tab content. In some situations the
elementid value that is used to generate the data-target may contain
certain characters that have a special meaning in the selector context
(e.g. ".", ",", "#") and because of that the target element cannot be
correctly identified. To fix this problem the elementid value needs to
be escaped prior to generating the data-target attribute.
The addition of text format on the output of the answer responses broke
the matching later when comparing the valid answer against the sent
response, as the answer response was not correspondingly formatted.
I decided to use the un formatted answer response as the key, to keep it
as close as identical to prior behaviour
* Create SRLogger that extends from the default Logger class. This
logger outputs the feedback to a sr-only ARIA live region to allow
screen readers to announce the feedback from mutations.
* Update the course editor to use the SRLogger.
* Create a mechanism for logging mutation feedbacks.
* The mutation feedbacks are displayed as a toast by default.
* Apply this logging mechanism on the course homepage to provide
feedback for the results of actions performed on course modules and
course sections.
There are checks to urls that attempt to limit recurrsion when
parse_file is called. This is problematic for css import urls that
can call an indefinite amount of nested import urls. An import limit
has been introduced to address this. Fragments have also been removed.
get_gradable_users now has extra param to retrieve only active
users. Grade reports hase their own grade_report::get_gradable_users
since they decided whether to inlcude active users from report preferences
We should verify that schedule and audience users are active accounts,
and that we don't try to send report schedules either from/to them if
they aren't.
Since version 6.4 and later, TinyMCE had a feature `ui_mode: split`.
It enables support for editors in scrollable containers,
and Moodle has some pages, especially the course pages, that are using the scrollable containers.
Therefore, all workaround that is addressed should be replaced by the feature to avoid future problems
regarding the overflow and the z-index issues.
If a quiz activity has negative grading enabled for incorrect answers,
students can achieve overall negative grades in this quiz. If at least
one student achieves a negative grade, the chart at the bottom of the
quiz 'Results' tab will fail to display. This patch add a search for
negative results, removes them from the band below 0 and adds them to
the 0 band. This will make the chart render correctly again.
Co-authored-by: Susana Leitão <sleitao@uporto.pt>
Co-authored-by: Matthias Opitz <m.opitz@ucl.ac.uk>
Removed whitespace at end of lines
In MDL-78744, when the overallcompletion state was added to be displayed
in the activity card, only COMPLETE/INCOMPLETE status were considered.
However, depending on the activity completion settings, there are a
couple of states more that should also be included (COMPLETE_FAIL and
COMPLETE_PASS).
A new method has been added to the cm_completion_details class to
calculate whether a module should be considered or not completed,
based on their completion options and the current value for the
overall complete state.
* Add support for grade report plugins that define an
`editingmode_title` lang string. If the grade report plugin defines this
language string, it will be used for the page title's unique
identifying information when editing mode is turned on.
* Make the headings for the single view easier to read and understand
* When on editing mode, update the heading for the grade and user
screens to convey to the user that the page is currently on editing
mode. This is helpful for screen reader users as they can immediately
know the current display mode of the single view report page when this
gets read via the page title.
Besides adding the is_guest() check in the check_password_policy() condition,
I also changed the temporary user ID because the temporary user and
the guest must not share the same ID. Otherwise, it will raise an error.
Co-authored-by: Andrei Bautu <abautu@gmail.com>
In certain scenarios, a user row can be the last row in the grader
report table. The current logic does not take this into account and
always pins the last row regardless of the type.
This change ensures that the last row is not a user row before executing
the logic responsible for pinning this row.
When duplicating a course module, availability restrictions was not rendering
properly. That happened because 'editing' was not being exported for template
for a single course module. This patch adds 'editing' to the cm exported data.
The new activity card design, planned for Moodle 4.3, reintroduces
the resource MIME icon that was removed in Moodle 4.0.
This is a backport of MDL-78285.
The placeholders for the hints are properly replaced by this change and any formulas present are replaced.
The validation is performed by the existing function qtype_calculated_find_formula_errors(),
which is called by the calculate() function,
which in turn is called by the variable substituter "vs" using the replace_expressions_in_text() function.
vs -> replace_expressions_in_text() -> calculate() -> qtype_calculated_find_formula_errors().
Previously, $CFG->sessionlockdebug was reporting long session locks for
all requests, even if they defined READ_ONLY_SESSION. This change
ensures that only sessions with locks are reported.
It is correct that the database default should be 0, to match
other similar columns, but when sites are upgraded, we need
to set the settings for all existing quizzes to match the previous
behaviour.
This resolves accessibility issues where Moodle language pack codes
didn't always map to correspondingly named iso6391 codes.
Where this value is defined in the language configuration, it will
now be used.
The PSR-4 specification does not preclude a single namespaces from
having multiple sources. This is the case for several PSR standards
including standard packagist packages distributed by PSR:
- PSR-7 - HTTP Message Interfaces: \Psr\Http\Message
- PSR-17 - HTTP Factories: \Psr\Http\Message
- PSR-15 - http-server-handler: \Psr\Http\Server
- PSR-15 - http-server-middleware: \Psr\Http\Server
With the h2 heading not being rendered on the zero-state pages of the
Single view report, we need to increase the heading level of the
"Search for a user to view all their grades" and
"Select a grade item above" headings from h3 to h2.
In order to prevent rendering an empty heading <h2>, we need to make
sure that the $heading parameter passed to print_grade_page_head() is
not an empty string.
PHP 8.3 deprecates the use of `get_class()` without arguments. The
following alternatives should instead be used as appropriate:
- `get_class($this)` - The equivalent for instance methods
- `self::class` - The current class
Note that the behaviour of `get_class()` in a static method was
equivalent to `self::class` and _not_ `static::class`. That is to say
that the previous behaviour did not respect late static binding.
- Fix the arrow placement for bootstrap popovers in RTL mode.
- Remove unneded css parser workaround for popover arrows.
After MDL-67386 was integrated those changes were not needed anymore.
The metadata information was not restored when an H5P file was uploaded
(it was saved when it was edited directly from the Content bank, but the
original information in the H5P file was lost).
This patch includes all the metadata fields and its values in the original
H5P file to preserve this information too.
The Course backup area was not displaying the course backups when
accessing to the Restore page for an activity because the context
was not updated properly for this area.
In pages which result in the theme_boost/embedded template being used,
blocks may be rendered and the resulting HTML ignored, leaving any JS
they may have added to run without a corresponding DOM element to act
on. This fixes that case for comments, making sure we exit gracefully
during the init if the element can't be found.
* Feature: We can use a minimum grade different than zero
- Use correct minimum input values.
- Use data generators for faster test execution.
* Scenario: Disable category overriding
- Use the field name to ensure that the correct field is being tested.
* <h6> tags cannot be in table cells. Replace them with <div> tags.
* Group the ascending/descending sort menu items to better indicate
where they belong to.
- Fix margins in elements displayed in the right side of activity cards.
Replace right margins with left margins to avoid extra space when editing
mode is off and action menu is not displayed.
- Fix groupmode icon spacing when displayed in small resolutions with edit
mode disabled
* Make sure that we respect the fullnamedisplay and alternativefullnameformat
parameters to decide on the initials for a given user
* Add further tests
Co-authored-by: Tatsunori Uchino <tats.u@live.jp>
When bulk-updating course module visibility, set_coursemodule_visibily
was triggering a partial cache purge and rebuild for each course module.
This potentially led to 2 cache sets each requiring a lock to be
acquired and released per course module, plus any other cache updates
for other changes to the course in the same request.
This adds a new $rebuildcache paramter to the
set_coursemodule_visibilty, which is true by default to retain the
existing behaviour. If set false, it will skip doing the partial purge
and rebuild for that course module, and it is up to the calling code to
ensure the cache is updated as requried.
To assist with this, there is a new
course_modinfo::purge_course_module_cache_multiple() method, which
allows multiple course modules to be purged from the cache in a single
cache set.
Based on the feedback given by the UX team:
- The text has been increased to display more (50 vs 55).
- A tooltip has been added to display the full course name on hover,
following the accessibility guidelines.
* When reloading a section, we also forced the reloading of
course modules, resulting in doing the same work twice (once for
the section reload and once for the course module reload)
* Debounce the reloading process so prevent unwanted duplicate
reloads
If `moduleName` param is passed in config object for modalform, it will be
used to instantiate modal class, otherwise 'core/modal_save_cancel' is
used.
Co-authored-by: Marina Glancy <marina@moodle.com>
The UX team confirmed a badge shouldn't be awarded when the criteria
use a passing grade and the user gets a failing grade.
So the COMPLETION_COMPLETE_FAIL status won't be considered
completed for activities with completion that require a passing
grade.
The "flag" field isn't a boolean state (1/0), it's a cumulative
count of how many times the tag has been flagged by users. This
should be accounted for to ensure that column aggregation and
filtering performs correctly.
This changes the cache purge code to select IDs for deletion
first, rather than using a subquery in a DELETE, since this
risks causing a deadlock in MySQL.
* The arrow characters in link_arrow_right() and link_arrow_left()
functions get announced by screen readers. This causes confusion
and is unnecessary.
We no longer need special handling of this field type, because it
now returns language strings rather than HTML markup for a checkbox
element on display.
The correct way to get an ad-hoc task to run as the main admin account
is to leave userid as null.
Setting it causes fatal errors if the main admin account is set to
auth: nologin.
This was causing the toast notification upon the clipboard action
result to immediately disappear as the modal was closed. The toast
module can happily handle this for us itself, so remove from the
template.
The UX team confirmed that an activity shouldn't be considered completed
when the criteria use a passing grade and the user gets a failing grade.
So the COMPLETION_COMPLETE_FAIL status won't be considered
completed from now on.
When we have a pagination on grader page and search for user
that is not on first page, saving was throwing an error
since page didn't have enough data
During the bootstrap of PHPUnit we ensure that the database has been
reset to its initial state.
We do this by checking the internally-stored DB write count between
runs. If the count is not yet set (null), or it has been increased, we
force a reset.
When running an isolated test the test runner resets the database, it
then sets up a new isolated test environment by writing a new PHPUnit
test case and passing it to a new PHP Process using standard in. As part
of this, the bootstrap is run for that process.
Because we are in a new process, the db write count is fresh and not yet
set. This has been leading to an additional db reset before the isolated
test.
To handle this we want to _not_ perform a reset during the
initialisation for isolated runs. We know that the DB is in a fresh
state before we start the run.
To support this we need to know whether the test is an isolated test
during the bootstrap, which means we cannot use the previous approach to
calculating this.
Instead we look at the PHP_SELF value. PHP sets this to "Standard input
code" when run from stdin, instead of running a file.
There should not be any other legitimate reason to run a PHPUnit
bootstrap via this stdin approach.
Unfortunately this approach is a little bit risky as it depends on the
presence of a specific string, however this string has been in place
since 2016, and there is no legitimate way of calculating this.
I did consider looking at whether the called script included `/vendor/`
and `/phpunit`, but this is also likely a risky approach if someone
calls PHPUnit in an unexpected way.
This approach is itself unit tested so any change to PHP's stdin string
before we deprecate this approach entirely in 12 months time will be
caught.
This hack was introduced to work around a bug in MySQL 5.6.14 and
MariaDB at the time.
https://bugs.mysql.com/bug.php?id=69882
It was addressed a few months later in 5.6.16, and 5.7.4.
MariaDB merged version 5.6.16 of MySQL's InnoDB engine in MariaDB
10.0.11 and got hte patch from there.
Moodle has required MySQL 8.0, and MariaDB 10.6.7 since Moodle 4.2 and
it is therefore safe to remove these hacks.
Previously if $CFG->usetags was not enabled the course question bank
page would show:
Exception - qbank_tagquestion\plugin_feature::get_question_filters():
Return value must be of type array, none returned
This is now fixed.
* In matching types of questions, sometimes the user does not answer all
questions. We now display "None" in the result report. The answer can
be either correct or incorrect.
* Fix "unknown" answer constant name.
These templates are needed by plugins which use the now-deprecated
searchwidget (located in grade/amd/src/searchwidget/basewidget.js)
in order to keep that deprecated widget working during the deprecation
time period. This also clarifies the js deprecation notice.
Previously, we replaced information in the same communication record
in the database, now there will be a unique record per provider.
This ensures when switching between different providers, the correct
actions such as room member management can be actioned for the correct
provider.
This also includes the required updates for the instances to no
longer assume a provider must be enabled to be relevant. Specifying a
provider is optional to fetch a specific provider instance, the default
will use the currently enabled provider.
Drawers are floating elements that should cover the page content but not
the top navbar or the sticky footer. This patch gives the drawer a
consistent z-index of $zindex-fixed -1 as oposed to the $zindex-fixed
used in the rest of floating elements.
However, in mobile the drawers acts a standard web drawer, covering the
full page content, event the other floating elements. This is why in
mobile the z-index should be higher than $zindex-fixed.
This fixes a regression introduced by MDL-78324 in which the
notification was being called before the promise had resolved. This
change just reverts that.
This template shouldn't really be using string helpers inside string
helpers like it does, and this is unsupported in 4.3. This just moves
the string resolution to js land and then passes that resolved string
into the template instead.
Instead of replacing the body, revert to the desired behavior in which
the payment methods are injected into the body, retaining the desired
markup classes, etc.
Basically the changes imply that:
- For some tests that are using reflection, we need to ensure
that the backup controller is passed.
- And, whenever used explicitly in tests, it has to be destroyed.
(note that this leaves out tests running get_package(), because
that method now instantiates and destroys the controller by itself.
only tests that get a controller need to destroy it).
- Move from some old functions to the new ones introduced in the issue.
Including in this commit:
- Moved the backup controller instantiation out of the constructor
- Created a new get_backup_controller() method to retreive the controller when needed
- Removed some constructor-promoted properties
- Added resourcefilename to resource_packager constructor
- Made resource_packager to abstract class (cannot be instantiated)
- Removed constructor-promoted properties and declare them "normally"
- Backup controller is called and destroyed in get_package() method.
Only PHPUnit tests will need to play with the destroy method because
they use the reflection method
- Made course_partial_packager extend course_packager and removed constructor-promoted properties
- Removed the get_all_task_settings() method and replaced it with get_all_activity_tasks() method
- Fixed bugs related to Partial course sharing
The API was incorrectly assuming that all uses of the API were for a
course, and that the instanceid of the communication instance was a
course id. These assumptions are both entirely wrong.
The API is intended to support a range of uses including use at the
site, user, and activity levels.
Furthermore, if a group were to be used, then the instanceid should be
of that group's id, and therefore the contextid would need to be fetched
or that group's course instead.
The only solution here is to add a new contextid field to the table, and
implement it all parts of the API.
Moves the data-filtercondition property to an element that always
exists regardless of whether the selected category from the filter
has questions or not. This will effectively solve the exception
that is being thrown due to the non-existing element and also
enable creation of random questions in a category that does not
have any questions yet. Also, the data-filtercondition attribute
is no longer used when creating a random question in a new category
as this value is not relevant in this case. Instead, a default
filter condition is generated in the webservice for the random
question based on the newly created category.
Group visibility was not taken into account when
generating SQL for getting enrolled users restricted
to a list of groups. This may have allowed users to
infer membership of groups they were not allowed to
see members of.
In some places we prevented cache poisoning, in others we did not. We
also did not place any restriction on the minimum value for a revision.
This change introduces a new set of functions for configonly endpoints
which validates the revision numbers passed in. If the revision is
either too old, or too new, it is rejected and the file content is not
cached. The content is still served, but caching headers are not sent,
and any local storage caching is prevented.
The current time is used as the maximum version, with 60 seconds added
to allow for any clock skew between cluster nodes. Previously some
locations used one hour, but there should never be such a large clock
skew on a correctly configured system.
Co-authored-by: Andrew Nicols <andrew@nicols.co.uk>
* We need to set a different meetingID when duplicating or importing a
BigBlueButtonBN activity to prevent unwanted sharing of recordings between
meetings.
With the new flow, users can go to the login page from the confirmed page,
and if the user successfully logs in, the user will be directed to the confirmed page.
To avoid that, the confirmed page can only be seen by users who are not logged in.
Render the output in shutdown handler was causing
issues in phpunit test_psr_classloader
This is an small fix to check that the output has been started.
Previously, the type of share (course/activity) was being injected into
the string, but not from a translation, so did not fully translate. The
MoodleNet type (resource) was working, but has also been replaced here
to avoid inserting one string into another (this was also unnecessary
while resource is the only possible option). This also meant the latter
string could be deprecated.
The Moodle XML export of multiple choice calculated questions was
missing proper escaping of answers. Also the indentation of the
generated xml was off.
Signed-off-by: Daniel Ziegenberg <daniel@ziegenberg.at>
Filters were not being passed from the question bank when viewing a question's history,
mearning that questions not visible with the default filters applied would not have
any version shown on this history view unless the required filters were re-applied manually.
This change ensures the filters are passed in the URL to history.php. It also removes the Filter
UI from the History view, since it doesn't make sense to change the filters that are passed.
The Binary datafilter was returning a single value where all parts of
the API expect an array of values. This was working in most places by
fluke as this value was a single-character string, so doing $value[0]
returned the value. However, it was not working when deciding which
option to mark as selected when re-displaying the filter.
This change makes the filter return an array containing a single integer
value to match the rest of the API, then internally selects that single
value for comparison when deciding if an option should be selected.
1.9 backups used current plugin version as oldversion.
But quiz uses some hardcoded version numbers when processing
restore which is lower then current plugin number, so some quiz
logic was ignored.
See define_structure(), process_quiz_question_instance() within
restore_quiz_stepslib.php
Within the forum_get_discussion_neighbours() function of forum
when the discussions timemodified (last post) is the same, there
is a bug that does strange things when calculating the prev and
next discussions.
Note that, in real life, this is really hard to achieve, but in tests,
when multiple discussions and post can be created by generators in the
same second (specially when the test machine is quick), chances of
facing that problem are higher.
By adding 1 second wait, we ensure that the discussions won't have
the same timemodified (last post) and workaround the problem.
No mater of that, the problem deserves an issue to be created
so we guarantee from code that it also works ok when the same
timemodified (last post) situation happens.
Note that normally this doesn't matter much, but there are situations
when we want the discussion list ordering fully consistent /
deterministic.
Specifically, when discussions (or forum posts )are created in the
same second, or when the discussion titles are repeated, or 2
discussions have the same number of votes... (any criteria in general),
in the context of testing, we don't want the order
to be non-consistent, so we need to provide an extra sorting
criterion to make it fully deterministic.
So, in this case, we are adding a sort by discussion.id <<DIRECTION>>
that is an unique value, primary key... so cheap to calculate and,
that way, when the 1st sorting column has repeated values, the id
will decide.
The selection gets lost while opening the modal dialogue to update an
embedded media. Caching the current selection allows us to update the
previously selected node instead of updating the first embedded media.
Signed-off-by: Gregor Eichelberger <gregor.eichelberger@tuwien.ac.at>
Associate column headings of user report tables to the user ID that the
report is being generated for. This will prevent duplicate IDs for the
report columns when multiple user report tables are displayed on the
User report page.
* The table cells mentioned in the `headers` attribute of other table
cells need to be using the table header <th> tag. Otherwise, HTML
validation fails.
when `log_out` is called from `\core\oauth2\client` it will delete the refresh token,
what it actually needs to use it to get a new access token
actually logging out is not needed here, the only thing we need to make sure is,
the invalid access token is removed from the session
that is done by storing `null`
- Switch use PARAM_TEXT instead of PARAM_URL for resource URL
- Added noreferrer to the Go to MoodleNet drafts button, to avoid the risks associated with opening in
_blank without removing access to the referrer and opener
Previously, quiz statistics processing happened on a scheduled task.
This task looked for all quizzes with completed attempts, then
determined if those quizzes had a statistics calculation that's newer
than the most recent attempt, then ran the statistics calculation if
needed. It was hard coded to stop processing after 1 hour.
The queries involved in determining which quizzes needed processing
weren't terribly efficient, and combined with the 1 hour limit this made
the statistics unusable on large sites, where they are the most useful.
This converts the scheduled task to an ad-hoc task, and uses an event
observer for mod_quiz\event\attempt_submitted to queue a task when
it is needed. This removes the need for a query to work out what needs
processing, and allows the task processing to be scaled up as needed.
Currently, Moodle uses fetchOBject() from ADOdb to get the table columns.
Sadly, the current ADOdb, especially the fetchObject() function, still creates dynamic properties.
Altering the fetchObject() with fetchRow() to avoid the dynamic properties deprecation error on PHP 8.2
Currently, Moodle uses fetchOBject() from ADOdb to get the table columns.
Sadly, the current ADOdb, especially the fetchObject() function, still creates dynamic properties.
Altering the fetchObject() with fetchRow() to avoid the dynamic properties deprecation error on PHP 8.2
After MDL-75762 the overall average row in the grader report
was no longer properly pinned and hidden behind the sticky footer.
This change ensures that the overall average row is pinned again
at the top of the sticky footer when vertically scrolling. Also,
leveragning on the new sticky footer 'toggled' event it is making
sure that the row is properly pinned on narrower screens where the
sticky footer appears and disappears dynamically when scrolling.
New event in core/sticky-footer that is fired when the sticky footer has
been enabled or disabled. Leveraging this event, modules can create
event listeners and execute actions once the sticky footer has been
toggled.
Avoids validating form data which is carried over from the
simple dynamic form to the advanced form page when creating
or editing grade items, categories and outcomes in the
Gradebook setup.
We encountered errors on the plugin check page while upgrading from version 3.11 to 4.3.
The plugins marked with the status "To be deleted" have a null value for the $component property,
which results in the following error message:
"Deprecated: strpos(): Passing null to parameter #1 ($haystack) of type string is
deprecated in lib/classes/component.php on line 1056."
To avoid this error, we need to set an empty string as the default value for the $component property.
This new parameter / property will decide if we want to reduce
the run data before processing it:
- By default it will be disabled in table mode.
- By default it will be enabled in graph mode.
- The defaults can be changed by adding reducedata=[0|1] in the URLs
- Once data reduction is enabled, it stays enabled while
navigating within the xhprof reports.
This covers the 2 new functions with unit tests:
- xhprof_topo_sort()
- reduce_run_data()
Note that the example graph used in the provider is the
one shown in the issue to explain the reduction procedure.
Here we are reducing the xhprof runs data by removing the
__Mustache==>__Mustache calls and all the orphaned data.
To save N iterations what we are doing is:
0. The information is "topologically" sorted, so we ensure that
all the parents in the data are processed before the children.
(this will help a lot when cleaning orphaned data, see below).
1. First pass, all the candidate (by regexp) calls are removed
from the run data.
2. Second pass, all the orphaned information (calls that have
ended losing his parent) are also removed, so data is consistent.
Note that, normally we would need N passes to remove all the
orphaned data (because each pass creates new orphan candidates),
but, as far as we have ensured that the information is topologically
sorted (see point 0 above), all this can be done in one unique pass.
TODO:
- Add unit tests.
- Enable some system to be able to decide which utilities we
want to get the data reduced and which ones will continue
using the complete data. Right now the reduction is being
applied to all the utilities (both table and graph views).
- Document the change and, if implemented, the way to select
between complete/reduced data.
- Consider adding some caching to speed-up the reduction process
(some TODOs have been left in the code pointing to the critical
points).
After modifying the 'overflow-y' css attribute of the #page element
in MDL-75762, the user name column is no longer properly pinned.
The existing 'top' css attribute on the column cells does not work
well with the newly assigned overlow on the #page element and
causes the columns to be partially cut off by the page when
scrolling horizontally. Re-adjusting the 'top' css attribute to '0'
solves this problem.
* Use a unique ID the date nodes in the HTML tree to be able to find the current node.
* Look for nodes in the same tree "leaf" and work on conflicts in this single leaf/branch.
These fields only exist for LTI 1.1 and LTI 1.3 edits, so can be
ignored in LTI 2.0 edits. This change fixes this for the tool
type edit (edit_form) and for the tool instance form (mod_form).
Specifically in the case where multiple content items are returned, and
when we hit the content_item_to_form() method, ensure that content-item-
specific values do not influence the final value of launchcontainer,
which must use the value set in tool configuration.
* calendar_get_link_previous() and calendar_get_link_next() are no
longer used anywhere except from the already deprecated
calendar_top_controls() so we should deprecate these as well.
If a quiz had a long job to calculate statstics running, this would
cause pages that may also attempt a recalculation (the statistics report
page or question bank) to load very slowly, and possibly result in a
database deadlock.
This change will firstly prevent the question bank page performing
analysis calculations at all, since these are not required for this
page, which will speed up loading and prevent deadlocks on this page.
Secondly, this adds a lock to the recalcuation process so that it cannot
run twice concurrently. This will present the user with a message to
indicate that it is waiting for a running calculation until it is
complete, and eventually it will timeout with a message and debugging.
This was causing the adhoc task to fail with a nopermission error, when
a user was unenrolled from a course before their assignment submission
could be converted into a pdf.
Comments from MDL-56810 indicate the correct approach is to not attempt
a conversion in those cases.
2023-09-07 09:26:09 +12:00
2150 changed files with 20320 additions and 7815 deletions
*@licensehttp://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define("tool_analytics/model",["jquery","core/str","core/log","core/notification","core/modal_save_cancel","core/modal_cancel","core/modal_events","core/templates"],(function($,Str,log,Notification,ModalSaveCancel,ModalCancel,ModalEvents,Templates){varactionsList={clear:{title:{key:"clearpredictions",component:"tool_analytics"},body:{key:"clearmodelpredictions",component:"tool_analytics"}},delete:{title:{key:"delete",component:"tool_analytics"},body:{key:"deletemodelconfirmation",component:"tool_analytics"}}};return{confirmAction:function(actionId,actionType){$('[data-action-id="'+actionId+'"]').on("click",(function(ev){ev.preventDefault();vara=$(ev.currentTarget);if(void0!==actionsList[actionType]){varwrap,reqStrings=[actionsList[actionType].title,actionsList[actionType].body];reqStrings[1].param=(wrap=$(a).closest("[data-model-name]")).length?wrap.attr("data-model-name"):(log.error("Unexpected DOM error - unable to obtain the model name"),"");varstringsPromise=Str.get_strings(reqStrings),modalPromise=ModalSaveCancel.create({});$.when(stringsPromise,modalPromise).then((function(strings,modal){returnmodal.setTitle(strings[0]),modal.setBody(strings[1]),modal.setSaveButtonText(strings[0]),modal.getRoot().on(ModalEvents.save,(function(){window.location.href=a.attr("href")})),modal.show(),modal})).fail(Notification.exception)}elselog.error('Action "'+actionType+'" is not allowed.')}))},selectEvaluationOptions:function(actionId,trainedOnlyExternally){$('[data-action-id="'+actionId+'"]').on("click",(function(ev){ev.preventDefault();vara=$(ev.currentTarget),timeSplittingMethods=$(this).attr("data-timesplitting-methods");ModalSaveCancel.create({title:Str.get_string("evaluatemodel","tool_analytics"),body:Templates.render("tool_analytics/evaluation_options",{trainedexternally:trainedOnlyExternally,timesplittingmethods:JSON.parse(timeSplittingMethods)}),removeOnClose:!0,buttons:{save:Str.get_string("evaluate","tool_analytics")},show:!0}).then((modal=>(modal.getRoot().on(ModalEvents.save,(function(){"trainedmodel"==$("input[name='evaluationmode']:checked").val()&&a.attr("href",a.attr("href")+"&mode=trainedmodel");vartimeSplittingMethod=$("#id-evaluation-timesplitting").val();a.attr("href",a.attr("href")+"×plitting="+timeSplittingMethod),window.location.href=a.attr("href")})),modal))).catch(Notification.exception)}))},selectExportOptions:function(actionId,isTrained){$('[data-action-id="'+actionId+'"]').on("click",(function(ev){ev.preventDefault();vara=$(ev.currentTarget);if(!isTrained)returna.attr("href",a.attr("href")+"&action=exportmodel&includeweights=0"),void(window.location.href=a.attr("href"));varstringsPromise=Str.get_strings([{key:"export",component:"tool_analytics"}]),modalPromise=ModalCancel.create({body:Templates.render("tool_analytics/export_options",{}),removeOnClose:!0});$.when(stringsPromise,modalPromise).then((function(strings,modal){returnmodal.setTitle(strings[0]),modal.setSaveButtonText(strings[0]),modal.getRoot().on(ModalEvents.save,(function(){"exportdata"==$("input[name='exportoption']:checked").val()?a.attr("href",a.attr("href")+"&action=exportdata"):(a.attr("href",a.attr("href")+"&action=exportmodel"),$("#id-includeweights").is(":checked")?a.attr("href",a.attr("href")+"&includeweights=1"):a.attr("href",a.attr("href")+"&includeweights=0")),window.location.href=a.attr("href")})),modal.show(),modal})).fail(Notification.exception)}))}}}));
define("tool_analytics/model",["jquery","core/str","core/log","core/notification","core/modal_save_cancel","core/modal_cancel","core/modal_events","core/templates"],(function($,Str,log,Notification,ModalSaveCancel,ModalCancel,ModalEvents,Templates){varactionsList={clear:{title:{key:"clearpredictions",component:"tool_analytics"},body:{key:"clearmodelpredictions",component:"tool_analytics"}},delete:{title:{key:"delete",component:"tool_analytics"},body:{key:"deletemodelconfirmation",component:"tool_analytics"}}};return{confirmAction:function(actionId,actionType){$('[data-action-id="'+actionId+'"]').on("click",(function(ev){ev.preventDefault();vara=$(ev.currentTarget);if(void0!==actionsList[actionType]){varwrap,reqStrings=[actionsList[actionType].title,actionsList[actionType].body];reqStrings[1].param=(wrap=$(a).closest("[data-model-name]")).length?wrap.attr("data-model-name"):(log.error("Unexpected DOM error - unable to obtain the model name"),"");varstringsPromise=Str.get_strings(reqStrings),modalPromise=ModalSaveCancel.create({});$.when(stringsPromise,modalPromise).then((function(strings,modal){returnmodal.setTitle(strings[0]),modal.setBody(strings[1]),modal.setSaveButtonText(strings[0]),modal.getRoot().on(ModalEvents.save,(function(){window.location.href=a.attr("href")})),modal.show(),modal})).fail(Notification.exception)}elselog.error('Action "'+actionType+'" is not allowed.')}))},selectEvaluationOptions:function(actionId,trainedOnlyExternally){$('[data-action-id="'+actionId+'"]').on("click",(function(ev){ev.preventDefault();vara=$(ev.currentTarget),timeSplittingMethods=$(this).attr("data-timesplitting-methods");ModalSaveCancel.create({title:Str.get_string("evaluatemodel","tool_analytics"),body:Templates.render("tool_analytics/evaluation_options",{trainedexternally:trainedOnlyExternally,timesplittingmethods:JSON.parse(timeSplittingMethods)}),removeOnClose:!0,buttons:{save:Str.get_string("evaluate","tool_analytics")},show:!0}).then((modal=>(modal.getRoot().on(ModalEvents.save,(function(){"trainedmodel"==$("input[name='evaluationmode']:checked").val()&&a.attr("href",a.attr("href")+"&mode=trainedmodel");vartimeSplittingMethod=$("#id-evaluation-timesplitting").val();a.attr("href",a.attr("href")+"×plitting="+timeSplittingMethod),window.location.href=a.attr("href")})),modal))).catch(Notification.exception)}))},selectExportOptions:function(actionId,isTrained){$('[data-action-id="'+actionId+'"]').on("click",(function(ev){ev.preventDefault();vara=$(ev.currentTarget);if(!isTrained)returna.attr("href",a.attr("href")+"&action=exportmodel&includeweights=0"),void(window.location.href=a.attr("href"));varstringsPromise=Str.get_strings([{key:"export",component:"tool_analytics"}]),modalPromise=ModalSaveCancel.create({body:Templates.render("tool_analytics/export_options",{}),removeOnClose:!0});$.when(stringsPromise,modalPromise).then((function(strings,modal){returnmodal.setTitle(strings[0]),modal.setSaveButtonText(strings[0]),modal.getRoot().on(ModalEvents.save,(function(){"exportdata"==$("input[name='exportoption']:checked").val()?a.attr("href",a.attr("href")+"&action=exportdata"):(a.attr("href",a.attr("href")+"&action=exportmodel"),$("#id-includeweights").is(":checked")?a.attr("href",a.attr("href")+"&includeweights=1"):a.attr("href",a.attr("href")+"&includeweights=0")),window.location.href=a.attr("href")})),modal.show(),modal})).fail(Notification.exception)}))}}}));
Forms are constructed using lib/formslib.php. Using the addElement methods in php a set of different form element types can be added to a form. For more info visit the [Moodledocs](https://docs.moodle.org/dev/lib/formslib.php_Form_Definition) page for forms
Forms are constructed using lib/formslib.php. Using the addElement methods in php a set of different form element types can be added to a form. For more info visit the [Moodledocs](https://moodledev.io/docs/apis/subsystems/form) page for forms
@@ -61,7 +61,7 @@ Disabled toggle with extra classes.
## Use toggle as a template block
It is also possible to include *core/toggle* in any other template using [blocks](https://docs.moodle.org/dev/Templates#Blocks), instead of rendering it with a context.
It is also possible to include *core/toggle* in any other template using [blocks](https://moodledev.io/docs/guides/templates#blocks), instead of rendering it with a context.
The parameters that you can define are:
* id: Unique id for the toggle input.
* extraclasses: Any extra classes added to the toggle input outer container.
$string['info']='<p>Use any time-based one-time password (TOTP) authenticator app on your device to generate a verification code, even when it is offline.</p>
*@licensehttp://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define("factor_webauthn/register",["factor_webauthn/utils"],(function(utils){return{init:function(createArgs){document.getElementById("factor_webauthn-register").addEventListener("click",(asyncfunction(e){if(e.preventDefault(),!navigator.credentials||!navigator.credentials.create)thrownewError("Browser not supported.");if(!1===(createArgs=JSON.parse(createArgs)).success)thrownewError(createArgs.msg||"unknown error occured");utils.recursiveBase64StrToArrayBuffer(createArgs);constcred=awaitnavigator.credentials.create(createArgs),authenticatorResponse={transports:cred.response.getTransports?cred.response.getTransports():null,clientDataJSON:cred.response.clientDataJSON?utils.arrayBufferToBase64(cred.response.clientDataJSON):null,attestationObject:cred.response.attestationObject?utils.arrayBufferToBase64(cred.response.attestationObject):null};document.getElementById("id_response_input").value=JSON.stringify(authenticatorResponse)}))}}}));
define("factor_webauthn/register",["factor_webauthn/utils","core/log"],(function(utils,Log){return{init:function(createArgs){createArgs=JSON.parse(createArgs),document.getElementById("factor_webauthn-register").addEventListener("click",(asyncfunction(e){if(e.preventDefault(),!navigator.credentials||!navigator.credentials.create)thrownewError("Browser not supported.");if(!1===createArgs.success)thrownewError(createArgs.msg||"unknown error occured");try{utils.recursiveBase64StrToArrayBuffer(createArgs);constcred=awaitnavigator.credentials.create(createArgs),authenticatorResponse={transports:cred.response.getTransports?cred.response.getTransports():null,clientDataJSON:cred.response.clientDataJSON?utils.arrayBufferToBase64(cred.response.clientDataJSON):null,attestationObject:cred.response.attestationObject?utils.arrayBufferToBase64(cred.response.attestationObject):null};document.getElementById("id_response_input").value=JSON.stringify(authenticatorResponse)}catch(e){Log.debug("The request timed out or you have canceled the request. Please try again later.")}}))}}}));
{"version":3,"file":"register.min.js","sources":["../src/register.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 * For collecting WebAuthn authenticator details on factor setup\n *\n * @module factor_webauthn/register\n * @copyright Catalyst IT\n * @author Alex Morris <alex.morris@catalyst.net.nz>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(['factor_webauthn/utils'], function(utils) {\n return {\n init: function(createArgs) {\n document.getElementById('factor_webauthn-register').addEventListener('click', async function(e) {\n e.preventDefault();\n if (!navigator.credentials || !navigator.credentials.create) {\n throw new Error('Browser not supported.');\n }\n\n createArgs = JSON.parse(createArgs);\n\n if (createArgs.success === false) {\n throw new Error(createArgs.msg || 'unknown error occured');\n }\n\n utils.recursiveBase64StrToArrayBuffer(createArgs);\n\n const cred = await navigator.credentials.create(createArgs);\n\n const authenticatorResponse = {\n transports: cred.response.getTransports ? cred.response.getTransports() : null,\n clientDataJSON: cred.response.clientDataJSON ? utils.arrayBufferToBase64(cred.response.clientDataJSON) : null,\n attestationObject:\n cred.response.attestationObject ? utils.arrayBufferToBase64(cred.response.attestationObject) : null\n };\n\n document.getElementById('id_response_input').value = JSON.stringify(authenticatorResponse);\n });\n }\n };\n});\n"],"names":["define","utils","init","createArgs","document","getElementById","addEventListener","async","e","preventDefault","navigator","credentials","create","Error","JSON","parse","success","msg","recursiveBase64StrToArrayBuffer","cred","authenticatorResponse","transports","response","getTransports","clientDataJSON","arrayBufferToBase64","attestationObject","value","stringify"],"mappings":";;;;;;;;AAwBAA,kCAAO,CAAC,0BAA0B,SAASC,aAChC,CACHC,KAAM,SAASC,YACXC,SAASC,eAAe,4BAA4BC,iBAAiB,SAASC,eAAeC,MACzFA,EAAEC,kBACGC,UAAUC,cAAgBD,UAAUC,YAAYC,aAC3C,IAAIC,MAAM,8BAKO,KAF3BV,WAAaW,KAAKC,MAAMZ,aAETa,cACL,IAAIH,MAAMV,WAAWc,KAAO,yBAGtChB,MAAMiB,gCAAgCf,kBAEhCgB,WAAaT,UAAUC,YAAYC,OAAOT,YAE1CiB,sBAAwB,CAC1BC,WAAYF,KAAKG,SAASC,cAAgBJ,KAAKG,SAASC,gBAAkB,KAC1EC,eAAgBL,KAAKG,SAASE,eAAiBvB,MAAMwB,oBAAoBN,KAAKG,SAASE,gBAAkB,KACzGE,kBACIP,KAAKG,SAASI,kBAAoBzB,MAAMwB,oBAAoBN,KAAKG,SAASI,mBAAqB,MAGvGtB,SAASC,eAAe,qBAAqBsB,MAAQb,KAAKc,UAAUR"}
{"version":3,"file":"register.min.js","sources":["../src/register.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 * For collecting WebAuthn authenticator details on factor setup\n *\n * @module factor_webauthn/register\n * @copyright Catalyst IT\n * @author Alex Morris <alex.morris@catalyst.net.nz>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(['factor_webauthn/utils', 'core/log'], function(utils, Log) {\n return {\n init: function(createArgs) {\n createArgs = JSON.parse(createArgs);\n document.getElementById('factor_webauthn-register').addEventListener('click', async function(e) {\n e.preventDefault();\n if (!navigator.credentials || !navigator.credentials.create) {\n throw new Error('Browser not supported.');\n }\n\n if (createArgs.success === false) {\n throw new Error(createArgs.msg || 'unknown error occured');\n }\n\n try {\n utils.recursiveBase64StrToArrayBuffer(createArgs);\n const cred = await navigator.credentials.create(createArgs);\nconst authenticatorResponse = {\n transports: cred.response.getTransports ? cred.response.getTransports() : null,\n clientDataJSON: cred.response.clientDataJSON ?\n utils.arrayBufferToBase64(cred.response.clientDataJSON) : null,\n attestationObject: cred.response.attestationObject ?\n utils.arrayBufferToBase64(cred.response.attestationObject) : null,\n };\n document.getElementById('id_response_input').value = JSON.stringify(authenticatorResponse);\n } catch (e) {\n Log.debug('The request timed out or you have canceled the request. Please try again later.');\n }\n });\n }\n };\n});\n"],"names":["define","utils","Log","init","createArgs","JSON","parse","document","getElementById","addEventListener","async","e","preventDefault","navigator","credentials","create","Error","success","msg","recursiveBase64StrToArrayBuffer","cred","authenticatorResponse","transports","response","getTransports","clientDataJSON","arrayBufferToBase64","attestationObject","value","stringify","debug"],"mappings":";;;;;;;;AAwBAA,kCAAO,CAAC,wBAAyB,aAAa,SAASC,MAAOC,WACnD,CACHC,KAAM,SAASC,YACXA,WAAaC,KAAKC,MAAMF,YACxBG,SAASC,eAAe,4BAA4BC,iBAAiB,SAASC,eAAeC,MACzFA,EAAEC,kBACGC,UAAUC,cAAgBD,UAAUC,YAAYC,aAC3C,IAAIC,MAAM,8BAGO,IAAvBZ,WAAWa,cACL,IAAID,MAAMZ,WAAWc,KAAO,6BAIlCjB,MAAMkB,gCAAgCf,kBAChCgB,WAAaP,UAAUC,YAAYC,OAAOX,YAC1CiB,sBAAwB,CAC1BC,WAAYF,KAAKG,SAASC,cAAgBJ,KAAKG,SAASC,gBAAkB,KAC1EC,eAAgBL,KAAKG,SAASE,eAC1BxB,MAAMyB,oBAAoBN,KAAKG,SAASE,gBAAkB,KAC9DE,kBAAmBP,KAAKG,SAASI,kBAC7B1B,MAAMyB,oBAAoBN,KAAKG,SAASI,mBAAqB,MAErEpB,SAASC,eAAe,qBAAqBoB,MAAQvB,KAAKwB,UAAUR,uBACtE,MAAOV,GACLT,IAAI4B,MAAM"}
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.