diff --git a/lang/en/cache.php b/lang/en/cache.php index 0c9686d152c..760173eb3c1 100644 --- a/lang/en/cache.php +++ b/lang/en/cache.php @@ -40,6 +40,7 @@ $string['cachedef_calendar_subscriptions'] = 'Calendar subscriptions'; $string['cachedef_config'] = 'Config settings'; $string['cachedef_coursecat'] = 'Course categories lists for particular user'; $string['cachedef_coursecatrecords'] = 'Course categories records'; +$string['cachedef_coursecontacts'] = 'List of course contacts'; $string['cachedef_coursecattree'] = 'Course categories tree'; $string['cachedef_databasemeta'] = 'Database meta information'; $string['cachedef_eventinvalidation'] = 'Event invalidation'; diff --git a/lib/coursecatlib.php b/lib/coursecatlib.php index 53ec5f90ee2..607342d7db3 100644 --- a/lib/coursecatlib.php +++ b/lib/coursecatlib.php @@ -37,6 +37,8 @@ class coursecat implements renderable, cacheable_object, IteratorAggregate { /** @var coursecat stores pseudo category with id=0. Use coursecat::get(0) to retrieve */ protected static $coursecat0; + const CACHE_COURSE_CONTACTS_TTL = 3600; // do not fetch course contacts more often than once per hour + /** @var array list of all fields and their short name and default value for caching */ protected static $coursecatfields = array( 'id' => array('id', 0), @@ -668,9 +670,29 @@ class coursecat implements renderable, cacheable_object, IteratorAggregate { return; } $managerroles = explode(',', $CFG->coursecontact); + $cache = cache::make('core', 'coursecontacts'); + $cacheddata = $cache->get_many(array_merge(array('basic'), array_keys($courses))); + // check if cache was set for the current course contacts and it is not yet expired + if (empty($cacheddata['basic']) || $cacheddata['basic']['roles'] !== $CFG->coursecontact || + $cacheddata['basic']['lastreset'] < time() - self::CACHE_COURSE_CONTACTS_TTL) { + // reset cache + $cache->purge(); + $cache->set('basic', array('roles' => $CFG->coursecontact, 'lastreset' => time())); + $cacheddata = $cache->get_many(array_merge(array('basic'), array_keys($courses))); + } + $courseids = array(); + foreach (array_keys($courses) as $id) { + if ($cacheddata[$id] !== false) { + $courses[$id]->managers = $cacheddata[$id]; + } else { + $courseids[] = $id; + } + } - // List of ids of courses for which we need to retrieve contacts - $courseids = array_keys($courses); + // $courseids now stores list of ids of courses for which we still need to retrieve contacts + if (empty($courseids)) { + return; + } // first build the array of all context ids of the courses and their categories $allcontexts = array(); @@ -724,6 +746,13 @@ class coursecat implements renderable, cacheable_object, IteratorAggregate { } } } + + // set the cache + $values = array(); + foreach ($courseids as $id) { + $values[$id] = $courses[$id]->managers; + } + $cache->set_many($values); } /** @@ -2288,4 +2317,4 @@ class coursecat_sortable_records extends ArrayObject { } return 0; } -} \ No newline at end of file +} diff --git a/lib/db/caches.php b/lib/db/caches.php index 401259a2bd0..b1e4da456ca 100644 --- a/lib/db/caches.php +++ b/lib/db/caches.php @@ -224,6 +224,12 @@ $definitions = array( 'changesincoursecat', ), ), + // Cache course contacts for the courses + 'coursecontacts' => array( + 'mode' => cache_store::MODE_APPLICATION, + 'persistent' => true, + 'simplekeys' => true, + ), // Used to store data for repositories to avoid repetitive DB queries within one request 'repositories' => array( 'mode' => cache_store::MODE_REQUEST,