From acecf6a48652bd6167ff93f42b6ad738f09009d2 Mon Sep 17 00:00:00 2001 From: Russell Boyatt Date: Thu, 19 Apr 2018 13:44:06 +0100 Subject: [PATCH 1/5] Cache results of reading list queries to Talis Aspire to help limit blocking calls. --- 2.4/blocks/aspirelists/block_aspirelists.php | 321 +++++++++--------- .../classes/task/expire_list_cache.php | 16 + 2.4/blocks/aspirelists/db/caches.php | 9 + 2.4/blocks/aspirelists/db/tasks.php | 13 + .../aspirelists/lang/en/block_aspirelists.php | 3 + 2.4/blocks/aspirelists/version.php | 2 +- 6 files changed, 211 insertions(+), 153 deletions(-) create mode 100644 2.4/blocks/aspirelists/classes/task/expire_list_cache.php create mode 100644 2.4/blocks/aspirelists/db/caches.php create mode 100644 2.4/blocks/aspirelists/db/tasks.php diff --git a/2.4/blocks/aspirelists/block_aspirelists.php b/2.4/blocks/aspirelists/block_aspirelists.php index 9e09de4..6c13835 100644 --- a/2.4/blocks/aspirelists/block_aspirelists.php +++ b/2.4/blocks/aspirelists/block_aspirelists.php @@ -8,187 +8,204 @@ function init() { } function get_content() { - global $CFG; - global $COURSE; + global $CFG; + global $COURSE; if ($this->content !== NULL) { return $this->content; } - $site = get_config('aspirelists', 'targetAspire'); - $httpsAlias = get_config('aspirelists', 'targetAspireAlias'); - - if (empty($site)) - { - $this->content->text = get_string('no_base_url_configured', 'block_aspirelists'); - return $this->content; - } - - $targetKG = get_config('aspirelists', 'targetKG'); - if (empty($targetKG)) - { - $targetKG = "modules"; // default to modules - } - $hrefTarget = get_config('aspirelists', 'openNewWindow'); $target ='_self'; if($hrefTarget == 1){ - $target = '_blank'; + $target = '_blank'; } $this->content = new stdClass; - if ($COURSE->idnumber) - { - // get the code from the global course object - $codeGlobal = $COURSE->idnumber; - $moduleCodeRegEx = '/'.get_config('aspirelists', 'moduleCodeRegex').'/'; - $timePeriodRegEx = '/'.get_config('aspirelists', 'timePeriodRegex').'/'; + if ($COURSE->idnumber) + { + $cache = cache::make('block_aspirelists', 'aspirelists'); + $lists = $cache->get('list-' . $COURSE->idnumber); + + if(!$lists) { + // get the code from the global course object + $lists = $this->getTalisAspireList($COURSE->idnumber); + $cache->set('list-' . $COURSE->idnumber, $lists); + } + + $output = ''; - $urlModuleCode = ''; - $urlTimePeriod = ''; + foreach ($lists as $list) + { + $itemNoun = ($list['count'] == 1) ? get_string("item", 'block_aspirelists') : get_string("items", 'block_aspirelists'); // get a friendly, human readable noun for the items - // decide how to split up the moodle course id. - if($moduleCodeRegEx != '//') + // finally, we're ready to output information to the browser + + // item count display + $itemCountHtml = ''; + if ($list['count'] > 0) // add the item count if there are any { - $results = array(); - if (preg_match($moduleCodeRegEx, $codeGlobal, $results) == 1) // we have a match - { - $urlModuleCode = strtolower($results[1]); // make sure is lowercase fr URL. - } - else - { - // we'll see if something matches anyway? - $urlModuleCode = strtolower($codeGlobal); - } + $itemCountHtml = html_writer::tag('span', " ({$list['count']} {$itemNoun})" ,array('class'=>'aspirelists-item-count')); } - if( $timePeriodRegEx != '//') + + // last update display + $lastUpdatedHtml = ''; + if (isset($list["lastUpdatedDate"])) { - $results = array(); - if (preg_match($timePeriodRegEx, $codeGlobal, $results) == 1) // we have a match - { - $mapping = json_decode(get_config('aspirelists', 'timePeriodMapping'),true); - if($mapping != null) - { - $urlTimePeriod = strtolower($mapping[$results[1]]); // make sure is lowercase for URL. - } - else - { - // there is no mapping so just use the result - $urlTimePeriod = strtolower($results[1]); - } - } + $lastUpdatedHtml = html_writer::tag('span',', '.get_string('lastUpdated','block_aspirelists').' '.$this->contextualTime(strtotime($list["lastUpdatedDate"])) , array('class'=>'aspirelists-last-updated')); } - // build the target URL of the JSON data we'll be requesting from Aspire + // put it all together + $output .= html_writer::tag('p', + html_writer::tag('a', $list['name'] , array('href' => $list['url'], 'target' => $target)) . html_writer::empty_tag('br') . $itemCountHtml . $lastUpdatedHtml ); + } + + if ($output=='') + { + $this->content->text = html_writer::tag('p', get_config('aspirelists', 'noResourceListsMessage')); + } + else + { + $this->content->text = $output; + } + } + + return $this->content; + } + + private function getTalisAspireList($codeGlobal) + { + $site = get_config('aspirelists', 'targetAspire'); + $httpsAlias = get_config('aspirelists', 'targetAspireAlias'); - if(!empty($httpsAlias)) + if (empty($site)) + { + $this->content->text = get_string('no_base_url_configured', 'block_aspirelists'); + return $this->content; + } + + $targetKG = get_config('aspirelists', 'targetKG'); + if (empty($targetKG)) + { + $targetKG = "modules"; // default to modules + } + + $moduleCodeRegEx = '/'.get_config('aspirelists', 'moduleCodeRegex').'/'; + $timePeriodRegEx = '/'.get_config('aspirelists', 'timePeriodRegex').'/'; + + $urlModuleCode = ''; + $urlTimePeriod = ''; + + // decide how to split up the moodle course id. + if($moduleCodeRegEx != '//') + { + $results = array(); + if (preg_match($moduleCodeRegEx, $codeGlobal, $results) == 1) // we have a match + { + $urlModuleCode = strtolower($results[1]); // make sure is lowercase fr URL. + } + else + { + // we'll see if something matches anyway? + $urlModuleCode = strtolower($codeGlobal); + } + } + + if( $timePeriodRegEx != '//') + { + $results = array(); + if (preg_match($timePeriodRegEx, $codeGlobal, $results) == 1) // we have a match + { + $mapping = json_decode(get_config('aspirelists', 'timePeriodMapping'),true); + if($mapping != null) { - $baseUrl = $httpsAlias; + $urlTimePeriod = strtolower($mapping[$results[1]]); // make sure is lowercase for URL. } else { - $baseUrl = $site; + // there is no mapping so just use the result + $urlTimePeriod = strtolower($results[1]); } + } + } - if($urlTimePeriod != ''){ - $url = "{$baseUrl}/{$targetKG}/{$urlModuleCode}/lists/{$urlTimePeriod}.json"; - } - else + // build the target URL of the JSON data we'll be requesting from Aspire + if(!empty($httpsAlias)) + { + $baseUrl = $httpsAlias; + } + else + { + $baseUrl = $site; + } + + if($urlTimePeriod != ''){ + $url = "{$baseUrl}/{$targetKG}/{$urlModuleCode}/lists/{$urlTimePeriod}.json"; + } + else + { + $url = "{$baseUrl}/{$targetKG}/{$urlModuleCode}/lists.json"; + } + + // using php curl, we'll now request the JSON data from Aspire + $ch = curl_init(); + $options = array( + CURLOPT_URL => $url, // tell curl the URL + CURLOPT_HEADER => false, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_CONNECTTIMEOUT => 20, + CURLOPT_TIMEOUT => 20, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1 + ); + curl_setopt_array($ch, $options); + $response = curl_exec($ch); // execute the request and get a response + + $output = ''; + $lists = array(); + if ($response) // if we get a valid response from curl... + { + $data = json_decode($response,true); // decode the returned JSON data + // JSON data will be using the non https alias. + if(isset($data["$site/$targetKG/$urlModuleCode"]) && isset($data["$site/$targetKG/$urlModuleCode"]['http://purl.org/vocab/resourcelist/schema#usesList'])) // if there are any lists... + { + foreach ($data["$site/$targetKG/$urlModuleCode"]['http://purl.org/vocab/resourcelist/schema#usesList'] as $usesList) // for each list this module uses... { - $url = "{$baseUrl}/{$targetKG}/{$urlModuleCode}/lists.json"; + $list = array(); + $list["url"] = clean_param($usesList["value"], PARAM_URL); // extract the list URL + $list["name"] = clean_param($data[$list["url"]]['http://rdfs.org/sioc/spec/name'][0]['value'], PARAM_TEXT); // extract the list name + + // let's try and get a last updated date + if (isset($data[$list["url"]]['http://purl.org/vocab/resourcelist/schema#lastUpdated'])) // if there is a last updated date... + { + // set up the timezone + date_default_timezone_set('Europe/London'); + + // ..and extract the date in a friendly, human readable format... + $list['lastUpdatedDate'] = date('l j F Y', + strtotime(clean_param($data[$list["url"]]['http://purl.org/vocab/resourcelist/schema#lastUpdated'][0]['value'], PARAM_TEXT))); + } + + // now let's count the number of items + $itemCount = 0; + if (isset($data[$list["url"]]['http://purl.org/vocab/resourcelist/schema#contains'])) // if the list contains anything... + { + foreach ($data[$list["url"]]['http://purl.org/vocab/resourcelist/schema#contains'] as $things) // loop through the list of things the list contains... + { + if (preg_match('/\/items\//',clean_param($things['value'], PARAM_URL))) // if the thing is an item, increment the item count (lists can contain sections, too) + { + $itemCount++; + } + } + } + $list['count'] = $itemCount; + array_push($lists,$list); } - // using php curl, we'll now request the JSON data from Aspire - $ch = curl_init(); - $options = array( - CURLOPT_URL => $url, // tell curl the URL - CURLOPT_HEADER => false, - CURLOPT_RETURNTRANSFER => true, - CURLOPT_CONNECTTIMEOUT => 20, - CURLOPT_TIMEOUT => 20, - CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1 - ); - curl_setopt_array($ch, $options); - $response = curl_exec($ch); // execute the request and get a response - - $output = ''; - if ($response) // if we get a valid response from curl... - { - $data = json_decode($response,true); // decode the returned JSON data - // JSON data will be using the non https alias. - if(isset($data["$site/$targetKG/$urlModuleCode"]) && isset($data["$site/$targetKG/$urlModuleCode"]['http://purl.org/vocab/resourcelist/schema#usesList'])) // if there are any lists... - { - $lists = array(); - foreach ($data["$site/$targetKG/$urlModuleCode"]['http://purl.org/vocab/resourcelist/schema#usesList'] as $usesList) // for each list this module uses... - { - $list = array(); - $list["url"] = clean_param($usesList["value"], PARAM_URL); // extract the list URL - $list["name"] = clean_param($data[$list["url"]]['http://rdfs.org/sioc/spec/name'][0]['value'], PARAM_TEXT); // extract the list name - - // let's try and get a last updated date - if (isset($data[$list["url"]]['http://purl.org/vocab/resourcelist/schema#lastUpdated'])) // if there is a last updated date... - { - // set up the timezone - date_default_timezone_set('Europe/London'); - - // ..and extract the date in a friendly, human readable format... - $list['lastUpdatedDate'] = date('l j F Y', - strtotime(clean_param($data[$list["url"]]['http://purl.org/vocab/resourcelist/schema#lastUpdated'][0]['value'], PARAM_TEXT))); - } - - // now let's count the number of items - $itemCount = 0; - if (isset($data[$list["url"]]['http://purl.org/vocab/resourcelist/schema#contains'])) // if the list contains anything... - { - foreach ($data[$list["url"]]['http://purl.org/vocab/resourcelist/schema#contains'] as $things) // loop through the list of things the list contains... - { - if (preg_match('/\/items\//',clean_param($things['value'], PARAM_URL))) // if the thing is an item, increment the item count (lists can contain sections, too) - { - $itemCount++; - } - } - } - $list['count'] = $itemCount; - array_push($lists,$list); - } - usort($lists,array($this,'sortByName')); - foreach ($lists as $list) - { - $itemNoun = ($list['count'] == 1) ? get_string("item", 'block_aspirelists') : get_string("items", 'block_aspirelists'); // get a friendly, human readable noun for the items - - // finally, we're ready to output information to the browser - - // item count display - $itemCountHtml = ''; - if ($list['count'] > 0) // add the item count if there are any - { - $itemCountHtml = html_writer::tag('span', " ({$list['count']} {$itemNoun})" ,array('class'=>'aspirelists-item-count')); - } - - // last update display - $lastUpdatedHtml = ''; - if (isset($list["lastUpdatedDate"])) - { - $lastUpdatedHtml = html_writer::tag('span',', '.get_string('lastUpdated','block_aspirelists').' '.$this->contextualTime(strtotime($list["lastUpdatedDate"])) , array('class'=>'aspirelists-last-updated')); - } - - // put it all together - $output .= html_writer::tag('p', - html_writer::tag('a', $list['name'] , array('href' => $list['url'], 'target' => $target)) . html_writer::empty_tag('br') . $itemCountHtml . $lastUpdatedHtml ); - } - } - } - if ($output=='') - { - $this->content->text = html_writer::tag('p', get_config('aspirelists', 'noResourceListsMessage')); - } - else - { - $this->content->text = $output; - } - } + usort($lists,array($this,'sortByName')); + } + } - return $this->content; + return $lists; } function has_config() { diff --git a/2.4/blocks/aspirelists/classes/task/expire_list_cache.php b/2.4/blocks/aspirelists/classes/task/expire_list_cache.php new file mode 100644 index 0000000..720e340 --- /dev/null +++ b/2.4/blocks/aspirelists/classes/task/expire_list_cache.php @@ -0,0 +1,16 @@ +purge(); + } +} \ No newline at end of file diff --git a/2.4/blocks/aspirelists/db/caches.php b/2.4/blocks/aspirelists/db/caches.php new file mode 100644 index 0000000..c45fce3 --- /dev/null +++ b/2.4/blocks/aspirelists/db/caches.php @@ -0,0 +1,9 @@ + array( + 'mode' => cache_store::MODE_APPLICATION + ) + +); \ No newline at end of file diff --git a/2.4/blocks/aspirelists/db/tasks.php b/2.4/blocks/aspirelists/db/tasks.php new file mode 100644 index 0000000..0af8e37 --- /dev/null +++ b/2.4/blocks/aspirelists/db/tasks.php @@ -0,0 +1,13 @@ + 'block_aspirelists\task\expire_list_cache', + 'blocking' => 0, + 'minute' => '0', + 'hour' => '04', + 'day' => '*', + 'dayofweek' => '*', + 'month' => '*' + ) +); \ No newline at end of file diff --git a/2.4/blocks/aspirelists/lang/en/block_aspirelists.php b/2.4/blocks/aspirelists/lang/en/block_aspirelists.php index 9ccec47..d2d79ea 100644 --- a/2.4/blocks/aspirelists/lang/en/block_aspirelists.php +++ b/2.4/blocks/aspirelists/lang/en/block_aspirelists.php @@ -61,3 +61,6 @@ // added this to prove this was really a UTF-8 FILE!! on a mac 'file filename.txt' reports a UTF-8 file as ASCII if there are NO diacritics in the file! $spuriousVar = 'î'; + +$string['cachedef_aspirelists'] = 'Talis Aspire reading lists'; +$string['expirelisttask'] = 'Expire Talis Aspire list cache'; \ No newline at end of file diff --git a/2.4/blocks/aspirelists/version.php b/2.4/blocks/aspirelists/version.php index a2e08db..00188fa 100644 --- a/2.4/blocks/aspirelists/version.php +++ b/2.4/blocks/aspirelists/version.php @@ -4,6 +4,6 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 201803081830; // YYYYMMDDHHMM (year, month, day, 24-hr time) +$plugin->version = 201803081833; // YYYYMMDDHHMM (year, month, day, 24-hr time) $plugin->requires = 2012120300; // YYYYMMDDHH (This is the release version for Moodle 2.4) $plugin->component = 'block_aspirelists'; \ No newline at end of file From 4ba188d78b0b18a668e460a330917dbcdb682906 Mon Sep 17 00:00:00 2001 From: Russell Boyatt Date: Tue, 19 Jun 2018 13:51:17 +0100 Subject: [PATCH 2/5] Switching everything to 4 space for tab-width. --- 2.4/blocks/aspirelists/block_aspirelists.php | 416 +++++++++---------- 1 file changed, 208 insertions(+), 208 deletions(-) diff --git a/2.4/blocks/aspirelists/block_aspirelists.php b/2.4/blocks/aspirelists/block_aspirelists.php index 6c13835..59df9df 100644 --- a/2.4/blocks/aspirelists/block_aspirelists.php +++ b/2.4/blocks/aspirelists/block_aspirelists.php @@ -3,247 +3,247 @@ // Released under the LGPL Licence - http://www.gnu.org/licenses/lgpl.html. Anyone is free to change or redistribute this code. class block_aspirelists extends block_base { - function init() { - $this->title = get_config('aspirelists', 'blockTitle'); - } + function init() { + $this->title = get_config('aspirelists', 'blockTitle'); + } - function get_content() { - global $CFG; - global $COURSE; + function get_content() { + global $CFG; + global $COURSE; - if ($this->content !== NULL) { - return $this->content; - } + if ($this->content !== NULL) { + return $this->content; + } - $hrefTarget = get_config('aspirelists', 'openNewWindow'); - $target ='_self'; - if($hrefTarget == 1){ - $target = '_blank'; - } + $hrefTarget = get_config('aspirelists', 'openNewWindow'); + $target ='_self'; + if($hrefTarget == 1){ + $target = '_blank'; + } - $this->content = new stdClass; + $this->content = new stdClass; - if ($COURSE->idnumber) - { - $cache = cache::make('block_aspirelists', 'aspirelists'); - $lists = $cache->get('list-' . $COURSE->idnumber); + if ($COURSE->idnumber) + { + $cache = cache::make('block_aspirelists', 'aspirelists'); + $lists = $cache->get('list-' . $COURSE->idnumber); - if(!$lists) { - // get the code from the global course object - $lists = $this->getTalisAspireList($COURSE->idnumber); - $cache->set('list-' . $COURSE->idnumber, $lists); - } + if(!$lists) { + // get the code from the global course object + $lists = $this->getTalisAspireList($COURSE->idnumber); + $cache->set('list-' . $COURSE->idnumber, $lists); + } - $output = ''; + $output = ''; - foreach ($lists as $list) - { - $itemNoun = ($list['count'] == 1) ? get_string("item", 'block_aspirelists') : get_string("items", 'block_aspirelists'); // get a friendly, human readable noun for the items + foreach ($lists as $list) + { + $itemNoun = ($list['count'] == 1) ? get_string("item", 'block_aspirelists') : get_string("items", 'block_aspirelists'); // get a friendly, human readable noun for the items + + // finally, we're ready to output information to the browser + + // item count display + $itemCountHtml = ''; + if ($list['count'] > 0) // add the item count if there are any + { + $itemCountHtml = html_writer::tag('span', " ({$list['count']} {$itemNoun})" ,array('class'=>'aspirelists-item-count')); + } + + // last update display + $lastUpdatedHtml = ''; + if (isset($list["lastUpdatedDate"])) + { + $lastUpdatedHtml = html_writer::tag('span',', '.get_string('lastUpdated','block_aspirelists').' '.$this->contextualTime(strtotime($list["lastUpdatedDate"])) , array('class'=>'aspirelists-last-updated')); + } + + // put it all together + $output .= html_writer::tag('p', + html_writer::tag('a', $list['name'] , array('href' => $list['url'], 'target' => $target)) . html_writer::empty_tag('br') . $itemCountHtml . $lastUpdatedHtml ); + } - // finally, we're ready to output information to the browser + if ($output=='') + { + $this->content->text = html_writer::tag('p', get_config('aspirelists', 'noResourceListsMessage')); + } + else + { + $this->content->text = $output; + } + } - // item count display - $itemCountHtml = ''; - if ($list['count'] > 0) // add the item count if there are any + return $this->content; + } + + private function getTalisAspireList($codeGlobal) + { + $site = get_config('aspirelists', 'targetAspire'); + $httpsAlias = get_config('aspirelists', 'targetAspireAlias'); + + if (empty($site)) { - $itemCountHtml = html_writer::tag('span', " ({$list['count']} {$itemNoun})" ,array('class'=>'aspirelists-item-count')); + $this->content->text = get_string('no_base_url_configured', 'block_aspirelists'); + return $this->content; } - // last update display - $lastUpdatedHtml = ''; - if (isset($list["lastUpdatedDate"])) + $targetKG = get_config('aspirelists', 'targetKG'); + if (empty($targetKG)) { - $lastUpdatedHtml = html_writer::tag('span',', '.get_string('lastUpdated','block_aspirelists').' '.$this->contextualTime(strtotime($list["lastUpdatedDate"])) , array('class'=>'aspirelists-last-updated')); + $targetKG = "modules"; // default to modules } - // put it all together - $output .= html_writer::tag('p', - html_writer::tag('a', $list['name'] , array('href' => $list['url'], 'target' => $target)) . html_writer::empty_tag('br') . $itemCountHtml . $lastUpdatedHtml ); - } - - if ($output=='') - { - $this->content->text = html_writer::tag('p', get_config('aspirelists', 'noResourceListsMessage')); - } - else - { - $this->content->text = $output; - } - } - - return $this->content; - } - - private function getTalisAspireList($codeGlobal) - { - $site = get_config('aspirelists', 'targetAspire'); - $httpsAlias = get_config('aspirelists', 'targetAspireAlias'); - - if (empty($site)) - { - $this->content->text = get_string('no_base_url_configured', 'block_aspirelists'); - return $this->content; - } - - $targetKG = get_config('aspirelists', 'targetKG'); - if (empty($targetKG)) - { - $targetKG = "modules"; // default to modules - } + $moduleCodeRegEx = '/'.get_config('aspirelists', 'moduleCodeRegex').'/'; + $timePeriodRegEx = '/'.get_config('aspirelists', 'timePeriodRegex').'/'; - $moduleCodeRegEx = '/'.get_config('aspirelists', 'moduleCodeRegex').'/'; - $timePeriodRegEx = '/'.get_config('aspirelists', 'timePeriodRegex').'/'; + $urlModuleCode = ''; + $urlTimePeriod = ''; - $urlModuleCode = ''; - $urlTimePeriod = ''; + // decide how to split up the moodle course id. + if($moduleCodeRegEx != '//') + { + $results = array(); + if (preg_match($moduleCodeRegEx, $codeGlobal, $results) == 1) // we have a match + { + $urlModuleCode = strtolower($results[1]); // make sure is lowercase fr URL. + } + else + { + // we'll see if something matches anyway? + $urlModuleCode = strtolower($codeGlobal); + } + } - // decide how to split up the moodle course id. - if($moduleCodeRegEx != '//') - { - $results = array(); - if (preg_match($moduleCodeRegEx, $codeGlobal, $results) == 1) // we have a match - { - $urlModuleCode = strtolower($results[1]); // make sure is lowercase fr URL. - } - else - { - // we'll see if something matches anyway? - $urlModuleCode = strtolower($codeGlobal); - } - } + if( $timePeriodRegEx != '//') + { + $results = array(); + if (preg_match($timePeriodRegEx, $codeGlobal, $results) == 1) // we have a match + { + $mapping = json_decode(get_config('aspirelists', 'timePeriodMapping'),true); + if($mapping != null) + { + $urlTimePeriod = strtolower($mapping[$results[1]]); // make sure is lowercase for URL. + } + else + { + // there is no mapping so just use the result + $urlTimePeriod = strtolower($results[1]); + } + } + } - if( $timePeriodRegEx != '//') - { - $results = array(); - if (preg_match($timePeriodRegEx, $codeGlobal, $results) == 1) // we have a match - { - $mapping = json_decode(get_config('aspirelists', 'timePeriodMapping'),true); - if($mapping != null) + // build the target URL of the JSON data we'll be requesting from Aspire + if(!empty($httpsAlias)) { - $urlTimePeriod = strtolower($mapping[$results[1]]); // make sure is lowercase for URL. + $baseUrl = $httpsAlias; } else { - // there is no mapping so just use the result - $urlTimePeriod = strtolower($results[1]); + $baseUrl = $site; } - } - } - // build the target URL of the JSON data we'll be requesting from Aspire - if(!empty($httpsAlias)) - { - $baseUrl = $httpsAlias; + if($urlTimePeriod != ''){ + $url = "{$baseUrl}/{$targetKG}/{$urlModuleCode}/lists/{$urlTimePeriod}.json"; + } + else + { + $url = "{$baseUrl}/{$targetKG}/{$urlModuleCode}/lists.json"; + } + + // using php curl, we'll now request the JSON data from Aspire + $ch = curl_init(); + $options = array( + CURLOPT_URL => $url, // tell curl the URL + CURLOPT_HEADER => false, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_CONNECTTIMEOUT => 20, + CURLOPT_TIMEOUT => 20, + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1 + ); + curl_setopt_array($ch, $options); + $response = curl_exec($ch); // execute the request and get a response + + $output = ''; + $lists = array(); + if ($response) // if we get a valid response from curl... + { + $data = json_decode($response,true); // decode the returned JSON data + // JSON data will be using the non https alias. + if(isset($data["$site/$targetKG/$urlModuleCode"]) && isset($data["$site/$targetKG/$urlModuleCode"]['http://purl.org/vocab/resourcelist/schema#usesList'])) // if there are any lists... + { + foreach ($data["$site/$targetKG/$urlModuleCode"]['http://purl.org/vocab/resourcelist/schema#usesList'] as $usesList) // for each list this module uses... + { + $list = array(); + $list["url"] = clean_param($usesList["value"], PARAM_URL); // extract the list URL + $list["name"] = clean_param($data[$list["url"]]['http://rdfs.org/sioc/spec/name'][0]['value'], PARAM_TEXT); // extract the list name + + // let's try and get a last updated date + if (isset($data[$list["url"]]['http://purl.org/vocab/resourcelist/schema#lastUpdated'])) // if there is a last updated date... + { + // set up the timezone + date_default_timezone_set('Europe/London'); + + // ..and extract the date in a friendly, human readable format... + $list['lastUpdatedDate'] = date('l j F Y', + strtotime(clean_param($data[$list["url"]]['http://purl.org/vocab/resourcelist/schema#lastUpdated'][0]['value'], PARAM_TEXT))); + } + + // now let's count the number of items + $itemCount = 0; + if (isset($data[$list["url"]]['http://purl.org/vocab/resourcelist/schema#contains'])) // if the list contains anything... + { + foreach ($data[$list["url"]]['http://purl.org/vocab/resourcelist/schema#contains'] as $things) // loop through the list of things the list contains... + { + if (preg_match('/\/items\//',clean_param($things['value'], PARAM_URL))) // if the thing is an item, increment the item count (lists can contain sections, too) + { + $itemCount++; + } + } + } + $list['count'] = $itemCount; + array_push($lists,$list); + } + usort($lists,array($this,'sortByName')); + } + } + + return $lists; } - else - { - $baseUrl = $site; + + function has_config() { + return true; } - if($urlTimePeriod != ''){ - $url = "{$baseUrl}/{$targetKG}/{$urlModuleCode}/lists/{$urlTimePeriod}.json"; + function applicable_formats() { + return array( + 'course-view' => true, + 'site' => true + ); } - else - { - $url = "{$baseUrl}/{$targetKG}/{$urlModuleCode}/lists.json"; + + function contextualTime($small_ts, $large_ts=false) { + if(!$large_ts) $large_ts = time(); + $n = $large_ts - $small_ts; + if($n <= 1) return 'less than 1 second ago'; + if($n < (60)) return $n . ' seconds ago'; + if($n < (60*60)) { $minutes = round($n/60); return 'about ' . $minutes . ' minute' . ($minutes > 1 ? 's' : '') . ' ago'; } + if($n < (60*60*16)) { $hours = round($n/(60*60)); return 'about ' . $hours . ' hour' . ($hours > 1 ? 's' : '') . ' ago'; } + if($n < (time() - strtotime('yesterday'))) return 'yesterday'; + if($n < (60*60*24)) { $hours = round($n/(60*60)); return 'about ' . $hours . ' hour' . ($hours > 1 ? 's' : '') . ' ago'; } + if($n < (60*60*24*6.5)) return 'about ' . round($n/(60*60*24)) . ' days ago'; + if($n < (time() - strtotime('last week'))) return 'last week'; + if(round($n/(60*60*24*7)) == 1) return 'about a week ago'; + if($n < (60*60*24*7*3.5)) return 'about ' . round($n/(60*60*24*7)) . ' weeks ago'; + if($n < (time() - strtotime('last month'))) return 'last month'; + if(round($n/(60*60*24*7*4)) == 1) return 'about a month ago'; + if($n < (60*60*24*7*4*11.5)) return 'about ' . round($n/(60*60*24*7*4)) . ' months ago'; + if($n < (time() - strtotime('last year'))) return 'last year'; + if(round($n/(60*60*24*7*52)) == 1) return 'about a year ago'; + if($n >= (60*60*24*7*4*12)) return 'about ' . round($n/(60*60*24*7*52)) . ' years ago'; + return false; } - // using php curl, we'll now request the JSON data from Aspire - $ch = curl_init(); - $options = array( - CURLOPT_URL => $url, // tell curl the URL - CURLOPT_HEADER => false, - CURLOPT_RETURNTRANSFER => true, - CURLOPT_CONNECTTIMEOUT => 20, - CURLOPT_TIMEOUT => 20, - CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1 - ); - curl_setopt_array($ch, $options); - $response = curl_exec($ch); // execute the request and get a response - - $output = ''; - $lists = array(); - if ($response) // if we get a valid response from curl... + function sortByName($a,$b) { - $data = json_decode($response,true); // decode the returned JSON data - // JSON data will be using the non https alias. - if(isset($data["$site/$targetKG/$urlModuleCode"]) && isset($data["$site/$targetKG/$urlModuleCode"]['http://purl.org/vocab/resourcelist/schema#usesList'])) // if there are any lists... - { - foreach ($data["$site/$targetKG/$urlModuleCode"]['http://purl.org/vocab/resourcelist/schema#usesList'] as $usesList) // for each list this module uses... - { - $list = array(); - $list["url"] = clean_param($usesList["value"], PARAM_URL); // extract the list URL - $list["name"] = clean_param($data[$list["url"]]['http://rdfs.org/sioc/spec/name'][0]['value'], PARAM_TEXT); // extract the list name - - // let's try and get a last updated date - if (isset($data[$list["url"]]['http://purl.org/vocab/resourcelist/schema#lastUpdated'])) // if there is a last updated date... - { - // set up the timezone - date_default_timezone_set('Europe/London'); - - // ..and extract the date in a friendly, human readable format... - $list['lastUpdatedDate'] = date('l j F Y', - strtotime(clean_param($data[$list["url"]]['http://purl.org/vocab/resourcelist/schema#lastUpdated'][0]['value'], PARAM_TEXT))); - } - - // now let's count the number of items - $itemCount = 0; - if (isset($data[$list["url"]]['http://purl.org/vocab/resourcelist/schema#contains'])) // if the list contains anything... - { - foreach ($data[$list["url"]]['http://purl.org/vocab/resourcelist/schema#contains'] as $things) // loop through the list of things the list contains... - { - if (preg_match('/\/items\//',clean_param($things['value'], PARAM_URL))) // if the thing is an item, increment the item count (lists can contain sections, too) - { - $itemCount++; - } - } - } - $list['count'] = $itemCount; - array_push($lists,$list); - } - usort($lists,array($this,'sortByName')); - } + return strcmp($a["name"], $b["name"]); } - return $lists; - } - - function has_config() { - return true; - } - - function applicable_formats() { - return array( - 'course-view' => true, - 'site' => true - ); - } - - function contextualTime($small_ts, $large_ts=false) { - if(!$large_ts) $large_ts = time(); - $n = $large_ts - $small_ts; - if($n <= 1) return 'less than 1 second ago'; - if($n < (60)) return $n . ' seconds ago'; - if($n < (60*60)) { $minutes = round($n/60); return 'about ' . $minutes . ' minute' . ($minutes > 1 ? 's' : '') . ' ago'; } - if($n < (60*60*16)) { $hours = round($n/(60*60)); return 'about ' . $hours . ' hour' . ($hours > 1 ? 's' : '') . ' ago'; } - if($n < (time() - strtotime('yesterday'))) return 'yesterday'; - if($n < (60*60*24)) { $hours = round($n/(60*60)); return 'about ' . $hours . ' hour' . ($hours > 1 ? 's' : '') . ' ago'; } - if($n < (60*60*24*6.5)) return 'about ' . round($n/(60*60*24)) . ' days ago'; - if($n < (time() - strtotime('last week'))) return 'last week'; - if(round($n/(60*60*24*7)) == 1) return 'about a week ago'; - if($n < (60*60*24*7*3.5)) return 'about ' . round($n/(60*60*24*7)) . ' weeks ago'; - if($n < (time() - strtotime('last month'))) return 'last month'; - if(round($n/(60*60*24*7*4)) == 1) return 'about a month ago'; - if($n < (60*60*24*7*4*11.5)) return 'about ' . round($n/(60*60*24*7*4)) . ' months ago'; - if($n < (time() - strtotime('last year'))) return 'last year'; - if(round($n/(60*60*24*7*52)) == 1) return 'about a year ago'; - if($n >= (60*60*24*7*4*12)) return 'about ' . round($n/(60*60*24*7*52)) . ' years ago'; - return false; - } - - function sortByName($a,$b) - { - return strcmp($a["name"], $b["name"]); - } - } From 1d37b26f97f950f9d235eb9b73a7c4e06bb88cc1 Mon Sep 17 00:00:00 2001 From: Russell Boyatt Date: Sun, 15 Jul 2018 17:03:03 +0100 Subject: [PATCH 3/5] Defining class constant for list cache. --- 2.4/blocks/aspirelists/block_aspirelists.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/2.4/blocks/aspirelists/block_aspirelists.php b/2.4/blocks/aspirelists/block_aspirelists.php index 59df9df..b3a2f2d 100644 --- a/2.4/blocks/aspirelists/block_aspirelists.php +++ b/2.4/blocks/aspirelists/block_aspirelists.php @@ -3,6 +3,9 @@ // Released under the LGPL Licence - http://www.gnu.org/licenses/lgpl.html. Anyone is free to change or redistribute this code. class block_aspirelists extends block_base { + + const CACHEPREFIX = "list-"; + function init() { $this->title = get_config('aspirelists', 'blockTitle'); } @@ -26,12 +29,12 @@ function get_content() { if ($COURSE->idnumber) { $cache = cache::make('block_aspirelists', 'aspirelists'); - $lists = $cache->get('list-' . $COURSE->idnumber); + $lists = $cache->get(block_aspirelists::CACHEPREFIX . $COURSE->idnumber); if(!$lists) { // get the code from the global course object $lists = $this->getTalisAspireList($COURSE->idnumber); - $cache->set('list-' . $COURSE->idnumber, $lists); + $cache->set(block_aspirelists::CACHEPREFIX . $COURSE->idnumber, $lists); } $output = ''; From 3486640c7feb0ea58e5d0a529309d0932585317d Mon Sep 17 00:00:00 2001 From: Russell Boyatt Date: Sun, 15 Jul 2018 17:05:02 +0100 Subject: [PATCH 4/5] Tidy up of whitespace characters before several equal statements. --- 2.4/blocks/aspirelists/block_aspirelists.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/2.4/blocks/aspirelists/block_aspirelists.php b/2.4/blocks/aspirelists/block_aspirelists.php index b3a2f2d..f60ba40 100644 --- a/2.4/blocks/aspirelists/block_aspirelists.php +++ b/2.4/blocks/aspirelists/block_aspirelists.php @@ -7,7 +7,7 @@ class block_aspirelists extends block_base { const CACHEPREFIX = "list-"; function init() { - $this->title = get_config('aspirelists', 'blockTitle'); + $this->title = get_config('aspirelists', 'blockTitle'); } function get_content() { @@ -24,7 +24,7 @@ function get_content() { $target = '_blank'; } - $this->content = new stdClass; + $this->content = new stdClass; if ($COURSE->idnumber) { @@ -66,11 +66,11 @@ function get_content() { if ($output=='') { - $this->content->text = html_writer::tag('p', get_config('aspirelists', 'noResourceListsMessage')); + $this->content->text = html_writer::tag('p', get_config('aspirelists', 'noResourceListsMessage')); } else { - $this->content->text = $output; + $this->content->text = $output; } } @@ -154,12 +154,12 @@ private function getTalisAspireList($codeGlobal) // using php curl, we'll now request the JSON data from Aspire $ch = curl_init(); $options = array( - CURLOPT_URL => $url, // tell curl the URL - CURLOPT_HEADER => false, + CURLOPT_URL => $url, // tell curl the URL + CURLOPT_HEADER => false, CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 20, CURLOPT_TIMEOUT => 20, - CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1 + CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1 ); curl_setopt_array($ch, $options); $response = curl_exec($ch); // execute the request and get a response From eb3c606763cf749995ca5b21f6980915ffcfc21d Mon Sep 17 00:00:00 2001 From: Russell Boyatt Date: Sun, 15 Jul 2018 17:50:36 +0100 Subject: [PATCH 5/5] Adding flag to enable or disable caching of lists. --- 2.4/blocks/aspirelists/block_aspirelists.php | 28 +++++++++++++------ .../aspirelists/lang/en/block_aspirelists.php | 5 +++- 2.4/blocks/aspirelists/settings.php | 2 ++ 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/2.4/blocks/aspirelists/block_aspirelists.php b/2.4/blocks/aspirelists/block_aspirelists.php index f60ba40..e0ccdf2 100644 --- a/2.4/blocks/aspirelists/block_aspirelists.php +++ b/2.4/blocks/aspirelists/block_aspirelists.php @@ -24,18 +24,28 @@ function get_content() { $target = '_blank'; } - $this->content = new stdClass; + $this->content = new stdClass; - if ($COURSE->idnumber) - { - $cache = cache::make('block_aspirelists', 'aspirelists'); - $lists = $cache->get(block_aspirelists::CACHEPREFIX . $COURSE->idnumber); + $cachingEnabled = get_config('aspirelists', 'caching'); - if(!$lists) { - // get the code from the global course object + if ($COURSE->idnumber) + { + if($cachingEnabled) + { + $cache = cache::make('block_aspirelists', 'aspirelists'); + $lists = $cache->get(block_aspirelists::CACHEPREFIX . $COURSE->idnumber); + + if(!$lists) { + // get the code from the global course object + $lists = $this->getTalisAspireList($COURSE->idnumber); + $cache->set(block_aspirelists::CACHEPREFIX . $COURSE->idnumber, $lists); + } + } + else + { $lists = $this->getTalisAspireList($COURSE->idnumber); - $cache->set(block_aspirelists::CACHEPREFIX . $COURSE->idnumber, $lists); - } + } + $output = ''; diff --git a/2.4/blocks/aspirelists/lang/en/block_aspirelists.php b/2.4/blocks/aspirelists/lang/en/block_aspirelists.php index d2d79ea..d48828f 100644 --- a/2.4/blocks/aspirelists/lang/en/block_aspirelists.php +++ b/2.4/blocks/aspirelists/lang/en/block_aspirelists.php @@ -42,6 +42,9 @@ $string['config_noResourceListsMessage'] = 'Message: no lists available'; $string['config_noResourceListsMessage_desc'] = 'The text of the message to display when there are no lists available.'; +$string['config_caching'] = 'List caching'; +$string['config_caching_desc'] = 'Enables the caching of list data from Talis Aspire to improve performance.'; + $string['modules'] = 'Modules'; $string['courses'] = 'Courses'; $string['units'] = 'Units'; @@ -63,4 +66,4 @@ $spuriousVar = 'î'; $string['cachedef_aspirelists'] = 'Talis Aspire reading lists'; -$string['expirelisttask'] = 'Expire Talis Aspire list cache'; \ No newline at end of file +$string['expirelisttask'] = 'Expire Talis Aspire list cache'; diff --git a/2.4/blocks/aspirelists/settings.php b/2.4/blocks/aspirelists/settings.php index ac5bdab..64a9ba8 100644 --- a/2.4/blocks/aspirelists/settings.php +++ b/2.4/blocks/aspirelists/settings.php @@ -28,3 +28,5 @@ $settings->add(new admin_setting_configtext('aspirelists/blockTitle',get_string('config_AspireBlockTitle', 'block_aspirelists'),get_string('config_AspireBlockTitle_desc', 'block_aspirelists'), get_string('aspirelists', 'block_aspirelists') )); $settings->add(new admin_setting_configtext('aspirelists/noResourceListsMessage',get_string('config_noResourceListsMessage', 'block_aspirelists'),get_string('config_noResourceListsMessage_desc', 'block_aspirelists'), get_string('no_resource_lists_msg', 'block_aspirelists') )); + + $settings->add(new admin_setting_configcheckbox('aspirelists/caching', get_string('config_caching', 'block_aspirelists'), get_string('config_caching_desc', 'block_aspirelists'), 0));