Both of them are dead code in 18_STABLE and HEAD. And if
role_add_lastaccess_entries() is ever used on a large site it will
hammer the DB to bits.
Remove before anyone is foolish enough to try it.
We had a 1s race condition where a user could get their rights loaded
at the exact time an admin is changing roles/caps and see the "old"
data. Or even see a half-updated view of the access controls.
Yuck.
So we fix the race condition backdating the dirtyness. Cheap, but
effective. And then we backdate it some more to cover for minor clock
flutter on clusters (you still need ntp however!).
Saves >10DBq and 18 includes at the homepage for all nonadmin users.
For non admin users, this makes the homepage _much_ more lightweight.
Before: inc 101 DBq 51 time 1.2s
After: inc 76 DBq 36 time 0.2s
So this commit shaves 1 full second for the non-logged-in homepage.
Still pretty bad on the includes, but shaved a good 25 files and 15 DBqs.
If cron hasn't run for a few days, it would take
several runs for chat_update_chat_times() to get things back on track.
Now it's all fixed in one go, saving a bit of DB traffic. It all adds
up...
Delete stale msgs in one DB query rather than in 1-per-chat-instance.
(From 600 DB queries to 1 on a site with 600 chat instances.)
Also - a walkthrough of chat_update_chat_times(), which seems buggy.
has_capability() can handle the fake user that forum cron sets up
and will load the appropriate accessdata into $USER->access.
This makes forum cron work again. A test comparison between before
this patchseries yields:
With 1 forum post, sent total 24 times
- Before 11 000 DB queries (approx)
- After 506 DB queries
With 6 forum posts, sent a total of 452 times
- Before 47 876 DB queries
- After 8 256 DB queries
There is a very high variability, but we are going from 100-500
queries per sent email to 18-21 queries per sent email. The
variability probably stems from 2 of the 6 posts being in a 200-user
forum.
Still huge - by the time we are sending the email, we should know
everything we need to know about the user, the forum/thread/post and
the form. The average should be well below 1 DB query per email sent!
print_user_picture() was forcing an unneeded dbquery
if you need an imagealt. And who doesn't need one these days.
So - teach print_user_picture() to take either $userid
_or_ $userobj as the first parameter. If that first
parameter has the fields we need, never touch the db.
In other words, only touch the DB as a last resort.
There is a bit of ugliness in testing whether we have
the fields or not, because these fields are inconsistently
with/without NOT NULL in the DB definitions. So we cannot
use isset() because it barfs on nulls. And we cannot use empty()
because it will match both on "missing key" and ''.
And while at it, silence warnings that we are missing string
for the year(s). Also fixes a missing string bug in really boring
courses that noone's visitied in many years ;-)
Reworked the logic of the visibility checks so that we evaluate in a
chain:
- can view course (visible or user can see hidden)
- can view category (visible or user can see hidden)
Without this patch, users that could see hidden categories could not get
into courses inside of them.
While at it, fix reference to the old $USER->switchrole
Reworked course_parent_visible() to always return in a constant
number of db queries (2 worst case) regardless of nesting depth.
The rewritten version has a small cache, but if you are going to
walk many courses, it's still 1~2 DB queries per category seen,
so the right thing to do is to check it in the caller, as seen
in get_my_courses().
Reworked gmc to perform the course visibility checks. These are
very cheap if $CFG->allowvisiblecoursesinhiddencategories is true.
However, where we have to enforce category visibility, it adds a bit
of work. In simple terms, it adds a DB query to read all the categories,
and extra checks to make sure we are doing the right thing WRT
- course visibility vs the permission to see hidden courses
- category visibility vs the permission to see hidden categories
and still do it quickly.
Costs next to nothing according to testing, and allows us to walk
the categories very cheaply. We'll need this in get_my_courses()...
What a cheapskates I am...
If you are a teacher in course X, you have at least
teacher-in-X + defaultloggedinuser-sitewide. So in the
course you'll have techer+defaultloggedinuser.
We try to mimic that in switchrole.
Thanks to Petr for pointing me to a similar fix in CVS.
Probably related: MDL-10945
We had quite a bit of leftover rdef and ra mangling.
Be more thorough and clear it up.
While at it, make load_user_accessdata() and load_all_capabilities()
more consistent.
There are some exceptions when checking for caps that are inherited
from the default role. Move the check into has_cap_fad() and stop
mangling the data we put in $ad[rdef].
We now also set $ad[dr] to record default roles added.
This will later allow us to share rdef across many users in $ACCESS.
Affects:
load_user_accessdata()
has_cap_fad()
While at it, document has_cap_fad() a bit.
When setting things up for the guest user, the RA entry in accessdata
was not multi-enrol-friendly. Must have glossed it over in the
multi-enrol rework.
The name for new data structure holding access control data
is "accessdata". And we have a new moniker "fad", short for
"from accessdata".
So
- has_cap_fromsess() -> has_cap_fad()
- access_inaccessdata() -> path_inaccessdata()
- aggr_roles_fromsess() -> aggr_roles_fad()
- $sess -> $ad
- $access -> $ad
Consistency, save typing, shorter codelines...
move_courses() now calls content_moved() which will take care of any
accesslib-required changes. And introducing move_category() which
also calls content_moved() when needed.