diff --git a/2.x-activity-module/README.md b/2.x-activity-module/README.md index 21c2a49..805bbb4 100644 --- a/2.x-activity-module/README.md +++ b/2.x-activity-module/README.md @@ -83,5 +83,8 @@ menu when editing a course. If you need help with any of the settings here, please contact [support@talis.com](mailto:support@talis.com) with screen shots of the above settings pages. +## Performance tips - +When using large numbers (greater than 5) inline lti resources on a single course page it is recommended that they do not default to expanded. +This can lead to high volumes of simultaneous LTI requests, slowing down responses and, on rare occasions, the possibility that some requests +may not return if too many courses are being loaded by multiple users. \ No newline at end of file diff --git a/2.x-activity-module/mod/aspirelists/db/upgrade.php b/2.x-activity-module/mod/aspirelists/db/upgrade.php index 1f840f6..68e98db 100644 --- a/2.x-activity-module/mod/aspirelists/db/upgrade.php +++ b/2.x-activity-module/mod/aspirelists/db/upgrade.php @@ -123,4 +123,8 @@ function xmldb_aspirelists_upgrade($oldversion) { upgrade_mod_savepoint(true, 2016061400, 'aspirelists'); } + if ($oldversion < 2017022000){ + upgrade_mod_savepoint(true, 2017022000, 'aspirelists'); + } + } \ No newline at end of file diff --git a/2.x-activity-module/mod/aspirelists/lib.php b/2.x-activity-module/mod/aspirelists/lib.php index 8462f8b..19b0f3a 100644 --- a/2.x-activity-module/mod/aspirelists/lib.php +++ b/2.x-activity-module/mod/aspirelists/lib.php @@ -154,6 +154,17 @@ function aspirelists_add_lti_properties(&$aspirelist) } } } + // Custom Attrs to track inline resource usage + if(isset($aspirelist->display)){ + $customLTIParams[] = 'display_inline='.(string)$aspirelist->display; + } + if(isset($aspirelist->showexpanded)){ + $customLTIParams[] = 'display_inline_expanded='.(string)$aspirelist->showexpanded; + } + $plugin = get_config('mod_aspirelists'); + if(isset($plugin->version)){ + $customLTIParams[] = 'moodle_lti_plugin_version='.$plugin->version; + } $aspirelist->instructorcustomparameters= implode("\n", $customLTIParams); $aspirelist->debuglaunch = false; } diff --git a/2.x-activity-module/mod/aspirelists/renderer.php b/2.x-activity-module/mod/aspirelists/renderer.php index 96a29cc..6e0a66c 100644 --- a/2.x-activity-module/mod/aspirelists/renderer.php +++ b/2.x-activity-module/mod/aspirelists/renderer.php @@ -18,11 +18,13 @@ function display_aspirelists(stdClass $aspirelist){ if(isset($aspirelist->showexpanded) && $aspirelist->showexpanded == '1') { $style = ""; + $srcType = 'src'; } else { $style = "display: none;"; + $srcType = 'data-intended-src'; } - $output .= $this->output->container(''); + $output .= $this->output->container(''); return $output; } } diff --git a/2.x-activity-module/mod/aspirelists/tests/lib_test.php b/2.x-activity-module/mod/aspirelists/tests/lib_test.php index ce96dac..691f01c 100644 --- a/2.x-activity-module/mod/aspirelists/tests/lib_test.php +++ b/2.x-activity-module/mod/aspirelists/tests/lib_test.php @@ -13,18 +13,11 @@ public function test_constants() public function test_add_lti_properties() { $this->resetAfterTest(true); - $year = date('Y').(date('y')+1); - $course = $this->getDataGenerator()->create_course(array('idnumber'=>'TEST01_'.$year)); - /** @var mod_aspirelists_generator $generator */ - $generator = $this->getDataGenerator()->get_plugin_generator('mod_aspirelists'); - $list = $generator->create_instance(array('course' => $course->id, 'name'=>'Course readings')); - set_config('courseCodeField', 'idnumber', 'mod_aspirelists'); - set_config('targetAspire', 'https://test.rl.talisaspire.com', 'mod_aspirelists'); - set_config('targetKG', 'module', 'mod_aspirelists'); - set_config('moduleCodeRegex', '^([A-Za-z0-9]{6})_[0-9]{6}$', 'mod_aspirelists'); - set_config('timePeriodRegex', '^[A-Za-z0-9]{6}_([0-9]{6})$', 'mod_aspirelists'); - $mapping = array($year=>date('Y-').(date('Y')+1)); - set_config('timePeriodMapping', json_encode($mapping), 'mod_aspirelists'); + $year = $this->getDefaultYear(); + $course = $this->createCourse($year); + $list = $this->createList(array('course' => $course->id, 'name'=>'Course readings')); + $timePeriodMapping = $this->getTimePeriodMapping($year); + $this->setDefaultPluginConfig($timePeriodMapping); aspirelists_add_lti_properties($list); $this->assertEquals('https://test.rl.talisaspire.com/lti/launch', $list->toolurl); @@ -35,17 +28,19 @@ public function test_add_lti_properties() $this->assertRegExp("/^launch_identifier=\w*\n/", $list->instructorcustomparameters); $this->assertContains("knowledge_grouping_code=TEST01\n", $list->instructorcustomparameters); - $this->assertContains("time_period=" . $mapping[$year], $list->instructorcustomparameters); + $this->assertContains("time_period=" . $timePeriodMapping[$year], $list->instructorcustomparameters); $this->assertFalse($list->debuglaunch); // Change configuration - set_config('courseCodeField', 'shortname', 'mod_aspirelists'); - set_config('targetAspire', 'https://test.rl.talisaspire.com', 'mod_aspirelists'); - set_config('targetKG', 'course', 'mod_aspirelists'); - set_config('moduleCodeRegex', '', 'mod_aspirelists'); - set_config('timePeriodRegex', '', 'mod_aspirelists'); - set_config('timePeriodMapping', '', 'mod_aspirelists'); - $list = $generator->create_instance(array('course' => $course->id, 'name'=>'Course readings')); + $this->setPluginConfig(array( + 'courseCodeField' => 'shortname', + 'targetAspire' => 'https://test.rl.talisaspire.com', + 'targetKG' => 'course', + 'moduleCodeRegex' => '', + 'timePeriodRegex' => '', + 'timePeriodMapping' => '' + )); + $list = $this->createList(array('course' => $course->id, 'name'=>'Course readings')); aspirelists_add_lti_properties($list); $this->assertEquals('https://test.rl.talisaspire.com/lti/launch', $list->toolurl); $this->assertRegExp("/^launch_identifier=\w*\n/", $list->instructorcustomparameters); @@ -54,4 +49,108 @@ public function test_add_lti_properties() $this->assertNotContains("time_period=", $list->instructorcustomparameters); } + /** + * @dataProvider add_lti_properties_includes_launch_env_info_Provider + */ + public function test_add_lti_properties_includes_launch_env_info($displayVal, $showExpandedVal) + { + $this->resetAfterTest(true); + $course = $this->createCourse($this->getDefaultYear()); + $list = $this->createList(array('course' => $course->id, 'name'=>'Add LTI Properties - Course readings')); + $this->setDefaultPluginConfig(); + + $list->display = $displayVal; + $list->showexpanded = $showExpandedVal; + + aspirelists_add_lti_properties($list); + + $this->assertContains("display_inline=" . $displayVal, $list->instructorcustomparameters); + $this->assertContains("display_inline_expanded=" . $showExpandedVal, $list->instructorcustomparameters); + } + + public function add_lti_properties_includes_launch_env_info_Provider(){ + return array( + array("1", "1"), + array("0", "0"), + array("1", "0"), + array("0", "1") + ); + } + + /** + * Create a new course + * + * @param $year string the year this course is for + * @return mixed + */ + protected function createCourse($year){ + return $this->getDataGenerator()->create_course(array('idnumber'=>'TEST01_'.$year)); + } + + /** + * Create a new list + * + * @param array $listAttrs + * @return mixed + */ + protected function createList(array $listAttrs){ + /** @var mod_aspirelists_generator $generator */ + $generator = $this->getDataGenerator()->get_plugin_generator('mod_aspirelists'); + return $generator->create_instance($listAttrs); + } + + /** + * Set the config for this plugin + * + * Expects an associative array of parameters + * @param array $config + */ + protected function setPluginConfig(array $config) + { + $pluginName = 'mod_aspirelists'; + foreach ($config as $key => $val) { + set_config($key, $val, $pluginName); + } + } + + /** + * Get a default year value for testing purposes + * + * @return string + */ + protected function getDefaultYear(){ + return date('Y').(date('y')+1); + } + + /** + * Get date mapping for the timePeriodMapping + * @param $year + * @return array + */ + protected function getTimePeriodMapping($year){ + return array($year => date('Y-') . (date('Y') + 1)); + } + + /** + * Set a default plugin config + * + * Useful if there are no specific configs being tested by + * this test + * + * @param array $timePeriodMapping + */ + protected function setDefaultPluginConfig(array $timePeriodMapping = null){ + if($timePeriodMapping === null) { + $timePeriodMapping = $this->getTimePeriodMapping($this->getDefaultYear()); + } + $this->setPluginConfig(array( + 'courseCodeField' => 'idnumber', + 'targetAspire' => 'https://test.rl.talisaspire.com', + 'targetKG' => 'module', 'mod_aspirelists', + 'moduleCodeRegex' => '^([A-Za-z0-9]{6})_[0-9]{6}$', + 'timePeriodRegex' => '^[A-Za-z0-9]{6}_([0-9]{6})$', + 'timePeriodMapping' => json_encode($timePeriodMapping) + )); + } + } \ No newline at end of file diff --git a/2.x-activity-module/mod/aspirelists/version.php b/2.x-activity-module/mod/aspirelists/version.php index 4615668..d3e291e 100644 --- a/2.x-activity-module/mod/aspirelists/version.php +++ b/2.x-activity-module/mod/aspirelists/version.php @@ -7,7 +7,7 @@ $plugin = new stdClass(); } -$plugin->version = 2016061400; // Version for this plugin - based on the date and then an increment number +$plugin->version = 2017022000; // Version for this plugin - based on the date and then an increment number $plugin->requires = 2012062507; // See http://docs.moodle.org/dev/Moodle_Versions $plugin->cron = 0; $plugin->component = 'mod_aspirelists'; diff --git a/2.x-activity-module/mod/aspirelists/yui/build/moodle-mod_aspirelists-inline_display/moodle-mod_aspirelists-inline_display-debug.js b/2.x-activity-module/mod/aspirelists/yui/build/moodle-mod_aspirelists-inline_display/moodle-mod_aspirelists-inline_display-debug.js index b6f95dd..dfaf614 100644 --- a/2.x-activity-module/mod/aspirelists/yui/build/moodle-mod_aspirelists-inline_display/moodle-mod_aspirelists-inline_display-debug.js +++ b/2.x-activity-module/mod/aspirelists/yui/build/moodle-mod_aspirelists-inline_display/moodle-mod_aspirelists-inline_display-debug.js @@ -6,6 +6,7 @@ NS = M.mod_aspirelists.inline_display = {}; NS.init_view = function(accordionOpen, accordionClosed) { Y.delegate('click', this.toggle_inline_list, Y.config.doc, '.aspirelists_inline_readings_toggle .activityinstance a', this); Y.on('domready', this.resize_embedded_lists); + Y.on('resize', this.resize_embedded_lists); this.accordionOpen = accordionOpen; this.accordionClosed = accordionClosed; }; @@ -27,6 +28,11 @@ NS.toggle_inline_list = function(e) { if(n.getStyle('display') === 'none') { + if(n.getAttribute('src') === ''){ + // if the iFrame's src has not yet been set then time to set it + var src = n.getData('intended-src'); + n.setAttribute('src', src); + } n.show(); NS.toggleAccordionIndicator(n, NS.accordionOpen); } else { @@ -35,7 +41,7 @@ NS.toggle_inline_list = function(e) } }); } -} +}; NS.resize_embedded_lists = function(e) { @@ -58,7 +64,7 @@ NS.resize_embedded_lists = function(e) o.setAttribute('width', width); }); -} +}; }, '@VERSION@', {"requires": ["base", "node", "event", "event-delegate"]}); diff --git a/2.x-activity-module/mod/aspirelists/yui/build/moodle-mod_aspirelists-inline_display/moodle-mod_aspirelists-inline_display-min.js b/2.x-activity-module/mod/aspirelists/yui/build/moodle-mod_aspirelists-inline_display/moodle-mod_aspirelists-inline_display-min.js index 0508e82..b82b4a2 100644 --- a/2.x-activity-module/mod/aspirelists/yui/build/moodle-mod_aspirelists-inline_display/moodle-mod_aspirelists-inline_display-min.js +++ b/2.x-activity-module/mod/aspirelists/yui/build/moodle-mod_aspirelists-inline_display/moodle-mod_aspirelists-inline_display-min.js @@ -1 +1 @@ -YUI.add("moodle-mod_aspirelists-inline_display",function(e,t){M.mod_aspirelists=M.mod_aspirelists||{},NS=M.mod_aspirelists.inline_display={},NS.init_view=function(t,n){e.delegate("click",this.toggle_inline_list,e.config.doc,".aspirelists_inline_readings_toggle .activityinstance a",this),e.on("domready",this.resize_embedded_lists),this.accordionOpen=t,this.accordionClosed=n},NS.toggleAccordionIndicator=function(e,t){e.ancestor(".aspirelists").all("span.aspirelists_inline_accordion").each(function(e){e.setHTML(t)})},NS.toggle_inline_list=function(e){e.preventDefault();var t=e.target.ancestor(".aspirelists");t&&t.all(".aspirelists_inline_list").each(function(e){e.getStyle("display")==="none"?(e.show(),NS.toggleAccordionIndicator(e,NS.accordionOpen)):(e.hide(),NS.toggleAccordionIndicator(e,NS.accordionClosed))})},NS.resize_embedded_lists=function(t){e.all(".aspirelists_inline_list").each(function(e){var t=e.ancestor(".aspirelists").get("offsetWidth"),n=e.ancestor(".aspirelists").getComputedStyle("margin"),r=e.ancestor(".aspirelists").getComputedStyle("padding-left");n&&(t-=parseFloat(n,10)*2),r&&(t-=parseFloat(r,10)*2);var i=e.ancestor(".mod-indent-outer");if(i){var s=i.getComputedStyle("padding-left"),o=e.getComputedStyle("margin-left");o&&(t-=parseFloat(o,10)*2),s&&(t-=parseFloat(s,10)*2)}e.setAttribute("width",t)})}},"@VERSION@",{requires:["base","node","event","event-delegate"]}); +YUI.add("moodle-mod_aspirelists-inline_display",function(e,t){M.mod_aspirelists=M.mod_aspirelists||{},NS=M.mod_aspirelists.inline_display={},NS.init_view=function(t,n){e.delegate("click",this.toggle_inline_list,e.config.doc,".aspirelists_inline_readings_toggle .activityinstance a",this),e.on("domready",this.resize_embedded_lists),e.on("resize",this.resize_embedded_lists),this.accordionOpen=t,this.accordionClosed=n},NS.toggleAccordionIndicator=function(e,t){e.ancestor(".aspirelists").all("span.aspirelists_inline_accordion").each(function(e){e.setHTML(t)})},NS.toggle_inline_list=function(e){e.preventDefault();var t=e.target.ancestor(".aspirelists");t&&t.all(".aspirelists_inline_list").each(function(e){if(e.getStyle("display")==="none"){if(e.getAttribute("src")===""){var t=e.getData("intended-src");e.setAttribute("src",t)}e.show(),NS.toggleAccordionIndicator(e,NS.accordionOpen)}else e.hide(),NS.toggleAccordionIndicator(e,NS.accordionClosed)})},NS.resize_embedded_lists=function(t){e.all(".aspirelists_inline_list").each(function(e){var t=e.ancestor(".aspirelists").get("offsetWidth"),n=e.ancestor(".aspirelists").getComputedStyle("margin"),r=e.ancestor(".aspirelists").getComputedStyle("padding-left");n&&(t-=parseFloat(n,10)*2),r&&(t-=parseFloat(r,10)*2);var i=e.ancestor(".mod-indent-outer");if(i){var s=i.getComputedStyle("padding-left"),o=e.getComputedStyle("margin-left");o&&(t-=parseFloat(o,10)*2),s&&(t-=parseFloat(s,10)*2)}e.setAttribute("width",t)})}},"@VERSION@",{requires:["base","node","event","event-delegate"]}); diff --git a/2.x-activity-module/mod/aspirelists/yui/build/moodle-mod_aspirelists-inline_display/moodle-mod_aspirelists-inline_display.js b/2.x-activity-module/mod/aspirelists/yui/build/moodle-mod_aspirelists-inline_display/moodle-mod_aspirelists-inline_display.js index b6f95dd..dfaf614 100644 --- a/2.x-activity-module/mod/aspirelists/yui/build/moodle-mod_aspirelists-inline_display/moodle-mod_aspirelists-inline_display.js +++ b/2.x-activity-module/mod/aspirelists/yui/build/moodle-mod_aspirelists-inline_display/moodle-mod_aspirelists-inline_display.js @@ -6,6 +6,7 @@ NS = M.mod_aspirelists.inline_display = {}; NS.init_view = function(accordionOpen, accordionClosed) { Y.delegate('click', this.toggle_inline_list, Y.config.doc, '.aspirelists_inline_readings_toggle .activityinstance a', this); Y.on('domready', this.resize_embedded_lists); + Y.on('resize', this.resize_embedded_lists); this.accordionOpen = accordionOpen; this.accordionClosed = accordionClosed; }; @@ -27,6 +28,11 @@ NS.toggle_inline_list = function(e) { if(n.getStyle('display') === 'none') { + if(n.getAttribute('src') === ''){ + // if the iFrame's src has not yet been set then time to set it + var src = n.getData('intended-src'); + n.setAttribute('src', src); + } n.show(); NS.toggleAccordionIndicator(n, NS.accordionOpen); } else { @@ -35,7 +41,7 @@ NS.toggle_inline_list = function(e) } }); } -} +}; NS.resize_embedded_lists = function(e) { @@ -58,7 +64,7 @@ NS.resize_embedded_lists = function(e) o.setAttribute('width', width); }); -} +}; }, '@VERSION@', {"requires": ["base", "node", "event", "event-delegate"]}); diff --git a/2.x-activity-module/mod/aspirelists/yui/src/inline_display/js/inline_display.js b/2.x-activity-module/mod/aspirelists/yui/src/inline_display/js/inline_display.js index 3c090c7..bece6e4 100644 --- a/2.x-activity-module/mod/aspirelists/yui/src/inline_display/js/inline_display.js +++ b/2.x-activity-module/mod/aspirelists/yui/src/inline_display/js/inline_display.js @@ -4,6 +4,7 @@ NS = M.mod_aspirelists.inline_display = {}; NS.init_view = function(accordionOpen, accordionClosed) { Y.delegate('click', this.toggle_inline_list, Y.config.doc, '.aspirelists_inline_readings_toggle .activityinstance a', this); Y.on('domready', this.resize_embedded_lists); + Y.on('resize', this.resize_embedded_lists); this.accordionOpen = accordionOpen; this.accordionClosed = accordionClosed; }; @@ -25,6 +26,11 @@ NS.toggle_inline_list = function(e) { if(n.getStyle('display') === 'none') { + if(n.getAttribute('src') === ''){ + // if the iFrame's src has not yet been set then time to set it + var src = n.getData('intended-src'); + n.setAttribute('src', src); + } n.show(); NS.toggleAccordionIndicator(n, NS.accordionOpen); } else { @@ -33,7 +39,7 @@ NS.toggle_inline_list = function(e) } }); } -} +}; NS.resize_embedded_lists = function(e) { @@ -56,4 +62,4 @@ NS.resize_embedded_lists = function(e) o.setAttribute('width', width); }); -} +};