28238 Commits

Author SHA1 Message Date
martinlanghoff
1a9b67874f accesslib: has_capability() now supports fake $USER for forum cron
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!
2007-09-19 07:20:24 +00:00
martinlanghoff
a5d81e5e5e user/index: make use of the smarter print_user_picture() -
Switch to using the smarter codepath in print_user_picture. Saves
20 DB queries in the normal page. One per user acct.
2007-09-19 07:20:01 +00:00
martinlanghoff
f312c5925f course/participants: fix sort order when last access is null 2007-09-19 07:19:46 +00:00
martinlanghoff
aebfa1546e weblib: print_user()/print_user_picture() optimisations
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 ;-)
2007-09-19 07:19:35 +00:00
martinlanghoff
1cf2e21b6e moodlelib: require_login() - rework course/category visibility checks
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
2007-09-19 07:19:20 +00:00
martinlanghoff
3511647c44 datalib:course_parent_visible() rework, remove category_parent_visible()
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().
2007-09-19 07:19:05 +00:00
martinlanghoff
82c62d1b17 datalib: get_my_courses() - add course visibility checks
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.
2007-09-19 07:18:54 +00:00
martinlanghoff
956b2f102e accesslib: get_user_courses_bycap() also returns categorypath
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...
2007-09-19 07:18:37 +00:00
martinlanghoff
3d034f77a8 accesslib: has_cap_fad() - merge switchrole with defaultuserrole
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
2007-09-19 07:18:23 +00:00
martinlanghoff
ceaf847554 accesslib: remove unused static var 2007-09-19 07:18:10 +00:00
martinlanghoff
56d219eaef accesslib: remove deprecated load_defaultuser_role() 2007-09-19 07:17:57 +00:00
martinlanghoff
20aecba887 moodlelib:remove_course_contents() does not need to 'clearcache'
Now that delete_context() marks things dirty, we no longer
need to clearcache. Which is deprecated anyway.
2007-09-19 07:17:45 +00:00
martinlanghoff
e7c8160b6f accesslib: delete_context() now appropriately marks the context dirty. 2007-09-19 07:17:34 +00:00
martinlanghoff
57770b87d0 Interactive enrolment/unenrolments: make sure we unset mycourses 2007-09-19 07:17:23 +00:00
martinlanghoff
55e68c29c8 accesslib: load_all_capabilities() must clear USER->mycourses 2007-09-19 07:17:08 +00:00
martinlanghoff
7293b3c6bd accesslib: drop rdef mangling part two
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.
2007-09-19 07:16:56 +00:00
martinlanghoff
955679bcf3 moodlelib: require_login() - assign tempguest role using load_temp_role()
And remove the explicit handling of deprecated $USER->capabilities
2007-09-19 07:16:43 +00:00
martinlanghoff
343effbede accesslib: intro load_temp_role() for temporary guest access
Loads a "ghost" role assignment, and all the needed rdef data
into an accessinfo array.

Also minor phpdoc update on get_role_access()
2007-09-19 07:16:29 +00:00
martinlanghoff
3ac81bd159 accesslib: drop rdef mangling for default role - check in has_cap_fad()
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.
2007-09-19 07:16:18 +00:00
martinlanghoff
33b6014f72 accesslib:load_all_capabilities() - fix guest user setup for multi-enrol
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.
2007-09-19 07:16:04 +00:00
martinlanghoff
51be70d2e2 accesslib/moodlelib: check $USER->access[rsw] for roleswitches 2007-09-19 07:15:50 +00:00
martinlanghoff
0e801c6c9d course/unenrol: check $USER->access[rsw] for role switches 2007-09-19 07:15:38 +00:00
martinlanghoff
92e531681d accesslib: Document accessdata, public api, stale accessdata 2007-09-19 07:15:27 +00:00
martinlanghoff
31c2de8234 accesslib: rename "sess" and "accessinfo" to accessdata
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...
2007-09-19 07:15:12 +00:00
martinlanghoff
0c24aa1929 accesslib:require_capability() revamp to check for USER->access
$USER->capabilities is deprecated.
2007-09-19 07:14:59 +00:00
martinlanghoff
0d8a77c978 accesslib:context_moved() remove debugging msgs 2007-09-19 07:14:48 +00:00
martinlanghoff
88903eeab9 course/index: Move categories around using move_category()
Use the newfangled move_category() when moving categories
around, to ensure we Do The Right Thing in the backend,
decoupled from UI stuff.
2007-09-19 07:14:34 +00:00
martinlanghoff
19f601d178 course/lib: move_courses() calls content_moved(), intro move_category()
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.
2007-09-19 07:14:23 +00:00
martinlanghoff
b4ab7f2ec9 accesslib:content_moved() fix bug in depth handling
the depth was getting a bit out-of-control when moving
up the tree. Fix it...
2007-09-19 07:14:11 +00:00
martinlanghoff
a372aab507 course: Changing a course cat from course/edit calls context_moved()
Changes to course cat from the main course settings form now calls
context_moved(), and accesslib data is properly maintained.
2007-09-19 07:13:57 +00:00
martinlanghoff
ca92b39158 accesslib: create_context() fix to also populate the depth
Set the depth field correctly.
2007-09-19 07:13:45 +00:00
martinlanghoff
e4fec27340 accesslib: Introducing context_moved() - call after moving courses/coursecats
With the new accesslib, moving courses and categories has a major
impact on enrolments and unenrolments.

At _least_ we need to signal accesslib that it has happened. So here
is context_moved() for exactly that.

Open to refactoring later into something along the lines of

 - move_course()
 - move_category()

However, at this stage the most important of those two: move_course()
does not fit very well with the code in course/edit. So keep it simple
for now.
2007-09-19 07:13:33 +00:00
martinlanghoff
c633af7a5a course/edit: mark the course contextpath as dirty to force a reload
Combined with the path creation in create_context() we can now create
a course, enter and edit it immediately. Amazing.

Like - 21st century technology.
2007-09-19 07:13:20 +00:00
martinlanghoff
e40413befa accesslib: create_context() now populates the path of new contexts
... and it populates the context cache too.

Unfortunately, it needs an INSERT followed by an UPDATE. Other than
a stored procedure, I don't know how to deal with this better.

(We could save the SELECT though! that's a thought...)

OTOH, we are getting so much mileage out of the path field
that it's probably a hit we have to take in the chin and move on.
2007-09-19 07:13:08 +00:00
martinlanghoff
4881f2d329 accesslib: simplify and speedup create_context()
Callers _must_ do their homework before calling create_context().
This allows us to save 2/3 queries per call (!!!).

As it stands, callers are all in accesslib anyway.
2007-09-19 07:12:56 +00:00
martinlanghoff
3d3def3a4e course/unenrol codepaths mark the context dirty - bugfix
Oops. one if() branch was missing the mark_context_dirty(). Fixed.
2007-09-19 07:12:43 +00:00
martinlanghoff
54f9d9aee7 accesslib:reload_all_capabilities() - force a reload of mycourses
unset $USER->mycourses to force a reload of mycourses too.
2007-09-19 07:12:33 +00:00
martinlanghoff
d32dd61154 enrol/paypal: mark the contextpath as dirty on unenrolment
so the unenrolment is effective immediately.
2007-09-19 07:12:22 +00:00
martinlanghoff
f055618837 enrol/mnet: mark context as dirty after unenrol
So the unenrolment is effective immediately.
2007-09-19 07:12:10 +00:00
martinlanghoff
2d0de2d88b deprecatedlib: Legacy interactive enrol/unenrol codepaths mark the context dirty
My heart is not so cold. These old buddies also need love and care...
2007-09-19 07:11:56 +00:00
martinlanghoff
a9d4ea7849 All interactive enrol/unenrol codepaths mark the context dirty
Manually enrolling and unenrolling self, and other users should
transparently set the context dirty. So walk all callers to
role_assign() and role_unassign() and mark the context dirty
where appropriate.

OTOH, most automated-backend enrol/unenrol mechanisms should not.
The backend lookups that happen when you login are well covered
by the login/enrolment process, and don't need to be marked dirty.
2007-09-19 07:11:42 +00:00
martinlanghoff
df75ca2289 cron: call cleanup_dirty_contexts() 2007-09-19 07:11:31 +00:00
martinlanghoff
ef989bd95e accesslib: Introduce (and use) reload_all_capabilities()
If accessinfo is stale, we need to reload it without losing
out "interesting" state -- transparently for the end user.

That means preserving active role switches, loginas (site and course
level), etc. The logic for that is encapsulated in
reload_all_capabilities().

Also affected:
 - has_capability() which now calls reload_all_capabilities()
 - role_switch() - minor tidyup
2007-09-19 07:11:18 +00:00
martinlanghoff
2123166d62 accesslib: get_user_courses_bycap() fix bug introduced by refactor
The refactor that created make_context_subobj() triggered a bug.
Smack in the hand to the sloppy programmer using variables outside
of the context they were meant to be used in!
2007-09-19 07:11:04 +00:00
martinlanghoff
e6560e39d7 admin/roles: context-specific role changes mark the context as dirty
And will force a reload of $USER->access for logged-in users that need
to read _this_ context. Much lower impact - still not a great idea to
edit assignments/caps on very busy courses, but impact should be low.
2007-09-19 07:10:52 +00:00
martinlanghoff
b3dc845cab admin/roles: sitewide role changes mark site context as dirty
And will force a reload of $USER->access for all logged-in users
on their next request.

We will have to tell admins of large sites to avoid making role changes
at busy times, as it does generate extra load.
2007-09-19 07:10:37 +00:00
martinlanghoff
148eb2a749 accesslib: Introduce $DIRTYCONTEXTS, $USER->access[time],is_contextpath_clean()
has_capability() now (ab)uses a new global: DIRTYCONTEXTS where we
load the contexts that have changed since since $USER->access[time]

The shallow/easy checks are done in has_capability(), deeper checks
go into the newfangled is_contextpath_clean().

The only complication now is to reload the relevant caps without losing
switches, loginas, etc...
2007-09-19 07:10:24 +00:00
martinlanghoff
0d25cd3a81 accesslib: Introduce functions to deal with dirty contexts
The accessinfo held in $USER->access can easily get out of
sync with reality if and admin has removed our access,
or expanded it after we loaded our accessinfo.

To handle this, we'll use the config_plugins table with an
'accesslib/dirtycontexts' plugin signature to store the paths of
recently changed contexts. To handle those dirrrty entries, here
we introduce

  get_dirty_contexts() - for lib/setup
  mark_context_dirty()
  cleanup_dirty_contexts() - for cron
2007-09-19 07:10:09 +00:00
martinlanghoff
690c946c15 get_role_users() callers rework to use the new $gethidden 2007-09-19 07:09:50 +00:00
martinlanghoff
47b18c1c12 group/assign: fixed performance of assigning users to groups
- page would not display on a course with 600 users
2007-09-19 07:09:36 +00:00