+ * Just add elements to the form as needed and return the list of IDs. The + * system will call disabledIf and handle other behaviour for each returned + * ID. + * + * @return string[] Array of string IDs of added items, empty array if none + */ + abstract public function add_completion_rules(): array; + + /** + * Called during validation. Override to indicate, based on the data, whether + * a custom completion rule is enabled (selected). + * + * @param array $data Input data (not yet validated) + * @return bool True if one or more rules is enabled, false if none are; + * default returns false + */ + public function completion_rule_enabled(array $data): bool { + return false; + } + + /** + * Form adjustments after setting data + * + * @return void + */ + public function definition_after_data() { + // Nothing for now. + } +} diff --git a/mod/bigbluebuttonbn/classes/local/extension/mod_instance_helper.php b/mod/bigbluebuttonbn/classes/local/extension/mod_instance_helper.php index fcc14b28eae..8cdbf2dd9e1 100644 --- a/mod/bigbluebuttonbn/classes/local/extension/mod_instance_helper.php +++ b/mod/bigbluebuttonbn/classes/local/extension/mod_instance_helper.php @@ -49,4 +49,12 @@ class mod_instance_helper { */ public function delete_instance(int $cmid): void { } + + /** + * Get any join table name that is used to store additional data for the instance. + * @return string[] + */ + public function get_join_tables(): array { + return []; + } } diff --git a/mod/bigbluebuttonbn/classes/test/subplugins_test_helper_trait.php b/mod/bigbluebuttonbn/classes/test/subplugins_test_helper_trait.php index 4c2351fbdd9..c3d31fe2cdd 100644 --- a/mod/bigbluebuttonbn/classes/test/subplugins_test_helper_trait.php +++ b/mod/bigbluebuttonbn/classes/test/subplugins_test_helper_trait.php @@ -26,6 +26,7 @@ namespace mod_bigbluebuttonbn\test; use core_component; +use core_h5p\core; use core_plugin_manager; use mod_bigbluebuttonbn\extension; use ReflectionClass; @@ -67,14 +68,62 @@ trait subplugins_test_helper_trait { $fillfilemap->setAccessible(true); $fillfilemap->invoke(null); + $mockedsubplugins = $mockedcomponent->getProperty('subplugins'); + $mockedsubplugins->setAccessible(true); + $subplugins = $mockedsubplugins->getValue(); + $subplugins['mod_bigbluebuttonbn'][extension::BBB_EXTENSION_PLUGIN_NAME][] = $pluginname; + $mockedsubplugins->setValue($subplugins); + + // Now write the content of the cache in a file so we can use it later. + $content = core_component::get_cache_content(); + self::write_fake_component_cache($content); + // Make sure the plugin is installed. ob_start(); upgrade_noncore(false); upgrade_finished(); ob_end_clean(); - \core_plugin_manager::reset_caches(); - $this->resetDebugging(); // We might have debugging messages here that we need to get rid of. - // End of the component loader mock. + + // Cache has been cleared so let's write it again. + self::write_fake_component_cache($content); + + } + + /** + * Write the content of the cache in a file for later use. + * + * This is used exclusively in behat test as the cache is filled with new values at each session/page load. + * + * @param string $content content of the cache + * @return void + */ + protected function write_fake_component_cache($content) { + global $CFG; + $cachefile = "$CFG->cachedir/core_component.php"; + if (file_exists($cachefile)) { + // Stale cache detected! + unlink($cachefile); + } + + // Permissions might not be setup properly in installers. + $dirpermissions = !isset($CFG->directorypermissions) ? 02777 : $CFG->directorypermissions; + $filepermissions = !isset($CFG->filepermissions) ? ($dirpermissions & 0666) : $CFG->filepermissions; + + clearstatcache(); + $cachedir = dirname($cachefile); + if (!is_dir($cachedir)) { + mkdir($cachedir, $dirpermissions, true); + } + + if ($fp = @fopen($cachefile . '.tmp', 'xb')) { + fwrite($fp, $content); + fclose($fp); + @rename($cachefile . '.tmp', $cachefile); + @chmod($cachefile, $filepermissions); + } + @unlink($cachefile . '.tmp'); // Just in case anything fails (race condition). + core_component::invalidate_opcode_php_cache($cachefile); + } /** * Uninstall a fake extension plugin @@ -86,12 +135,22 @@ trait subplugins_test_helper_trait { * @return void */ protected function uninstall_fake_plugin(string $pluginname): void { + global $CFG; + require_once("$CFG->libdir/adminlib.php"); // We just need access to fill_all_caches so everything goes back to normal. // If we don't do this, there are some side effects that will make other test fails // (such as mod_bigbluebuttonbn\task\upgrade_recordings_task_test::test_upgrade_recordings_imported_basic). + $cachefile = "$CFG->cachedir/core_component.php"; + if (file_exists($cachefile)) { + // Stale cache detected! + unlink($cachefile); + } $mockedcomponent = new ReflectionClass(core_component::class); // Here we reset the plugin caches. - $fillclassmap = $mockedcomponent->getMethod('fill_all_caches'); + $mockedplugintypes = $mockedcomponent->getProperty('plugintypes'); + $mockedplugintypes->setAccessible(true); + $mockedplugintypes->setValue(null); + $fillclassmap = $mockedcomponent->getMethod('init'); $fillclassmap->setAccessible(true); $fillclassmap->invoke(null); diff --git a/mod/bigbluebuttonbn/db/caches.php b/mod/bigbluebuttonbn/db/caches.php index 806addc32d9..fd8adde08a1 100644 --- a/mod/bigbluebuttonbn/db/caches.php +++ b/mod/bigbluebuttonbn/db/caches.php @@ -56,4 +56,12 @@ $definitions = [ 'currentfetch' => [ 'mode' => cache_store::MODE_REQUEST, ], + + // The 'subplugins' cache stores a cache of subplugins data to accelerate some of the subplugin discovery features. + 'subplugins' => [ + 'mode' => cache_store::MODE_APPLICATION, + 'invalidationevents' => [ + 'mod_bigbluebuttonbn/subpluginschanged', + ], + ], ]; diff --git a/mod/bigbluebuttonbn/lang/en/bigbluebuttonbn.php b/mod/bigbluebuttonbn/lang/en/bigbluebuttonbn.php index 90fcef3b667..18b847bb193 100644 --- a/mod/bigbluebuttonbn/lang/en/bigbluebuttonbn.php +++ b/mod/bigbluebuttonbn/lang/en/bigbluebuttonbn.php @@ -655,6 +655,7 @@ $string['cachedef_currentfetch'] = 'Data to list any recording fetched recently. $string['cachedef_serverinfo'] = 'Remote server information'; $string['cachedef_recordings'] = 'Recording metadata'; $string['cachedef_validatedurls'] = 'Cache of validated URL checks'; +$string['cachedef_subplugins'] = 'Cache used by subplugin routines to accelerate when needed the plugin discovery process.'; $string['taskname:check_pending_recordings'] = 'Fetch pending recordings'; $string['taskname:check_dismissed_recordings'] = 'Check for recordings that haven\'t been found yet'; $string['userlimitreached'] = 'The number of users allowed in a session has been reached.'; diff --git a/mod/bigbluebuttonbn/lib.php b/mod/bigbluebuttonbn/lib.php index 936b0ebd4be..b013b7ac936 100644 --- a/mod/bigbluebuttonbn/lib.php +++ b/mod/bigbluebuttonbn/lib.php @@ -361,32 +361,24 @@ function bigbluebuttonbn_reset_userdata(stdClass $data) { * @return null|cached_cm_info */ function bigbluebuttonbn_get_coursemodule_info($coursemodule) { - global $DB; - - $dbparams = ['id' => $coursemodule->instance]; - $customcompletionfields = custom_completion::get_defined_custom_rules(); - $fieldsarray = array_merge([ - 'id', - 'name', - 'intro', - 'introformat', - ], $customcompletionfields); - $fields = join(',', $fieldsarray); - $bigbluebuttonbn = $DB->get_record('bigbluebuttonbn', $dbparams, $fields); - if (!$bigbluebuttonbn) { + $instance = instance::get_from_instanceid($coursemodule->instance); + if (empty($instance)) { return null; } $info = new cached_cm_info(); - $info->name = $bigbluebuttonbn->name; + // Warning here: if any of the instance method calls ::get_cm this will result is a recursive call. + // So best is just to access instance variables not linked to the cm. + $info->name = $instance->get_instance_var('name'); if ($coursemodule->showdescription) { // Convert intro to html. Do not filter cached version, filters run at display time. - $info->content = format_module_intro('bigbluebuttonbn', $bigbluebuttonbn, $coursemodule->id, false); + $info->content = format_module_intro('bigbluebuttonbn', $instance->get_instance_data(), $coursemodule->id, false); } + $customcompletionfields = custom_completion::get_defined_custom_rules(); // Populate the custom completion rules as key => value pairs, but only if the completion mode is 'automatic'. if ($coursemodule->completion == COMPLETION_TRACKING_AUTOMATIC) { foreach ($customcompletionfields as $completiontype) { $info->customdata['customcompletionrules'][$completiontype] = - $bigbluebuttonbn->$completiontype ?? 0; + $instance->get_instance_var($completiontype) ?? 0; } } diff --git a/mod/bigbluebuttonbn/mod_form.php b/mod/bigbluebuttonbn/mod_form.php index 96884691f80..c37105c6865 100644 --- a/mod/bigbluebuttonbn/mod_form.php +++ b/mod/bigbluebuttonbn/mod_form.php @@ -24,6 +24,7 @@ * @author Fred Dixon (ffdixon [at] blindsidenetworks [dt] com) */ +use mod_bigbluebuttonbn\extension; use mod_bigbluebuttonbn\instance; use mod_bigbluebuttonbn\local\helpers\roles; use mod_bigbluebuttonbn\local\proxy\bigbluebutton_proxy; @@ -40,6 +41,10 @@ require_once($CFG->dirroot . '/course/moodleform_mod.php'); */ class mod_bigbluebuttonbn_mod_form extends moodleform_mod { + /** + * @var array $formextensions extensions to this form + */ + protected $formextensions = []; /** * Define (add) particular settings this activity can have. * @@ -67,6 +72,8 @@ class mod_bigbluebuttonbn_mod_form extends moodleform_mod { $context = context_course::instance($course->id); $bigbluebuttonbn = empty($this->get_current()->id) ? null : $this->get_current(); + $this->formextensions = extension::mod_form_addons_instances($mform, $bigbluebuttonbn, $this->get_suffix()); + $instancetyperofiles = $this->get_instance_type_profiles(); $this->bigbluebuttonbn_mform_add_block_profiles($mform, $instancetyperofiles); // Data for participant selection. @@ -85,6 +92,9 @@ class mod_bigbluebuttonbn_mod_form extends moodleform_mod { $this->bigbluebuttonbn_mform_add_block_guest_access($mform, $cfg, $this->current); // Add block 'Schedule'. $this->bigbluebuttonbn_mform_add_block_schedule($mform, $this->current); + // Now add subplugins form elements. + $this->add_subplugins_elements(); + // Add standard elements, common to all modules. $this->standard_coursemodule_elements(); // Add standard buttons, common to all modules. @@ -171,6 +181,9 @@ class mod_bigbluebuttonbn_mod_form extends moodleform_mod { $defaultvalues[$completionattendanceenabledel] = 1; } } + foreach ($this->formextensions as $formextension) { + $formextension->data_preprocessing($defaultvalues); + } } /** @@ -193,7 +206,11 @@ class mod_bigbluebuttonbn_mod_form extends moodleform_mod { $errors['voicebridge'] = get_string('mod_form_field_voicebridge_notunique_error', 'bigbluebuttonbn'); } } - return $errors; + $additionalsubpluginerrors = []; + foreach ($this->formextensions as $formextension) { + $additionalsubpluginerrors = array_merge($additionalsubpluginerrors, $formextension->validation($data, $files)); + } + return array_merge($errors, $additionalsubpluginerrors); } /** @@ -259,7 +276,11 @@ class mod_bigbluebuttonbn_mod_form extends moodleform_mod { $mform->addHelpButton($completionengagementgroupel, 'completionengagementgroup', 'bigbluebuttonbn'); $mform->disabledIf($completionengagementgroupel, $completionel, 'neq', COMPLETION_AGGREGATION_ANY); - return [$completionattendancegroupel, $completionengagementgroupel]; + $completionrules = [$completionattendancegroupel, $completionengagementgroupel]; + foreach ($this->formextensions as $formextension) { + $completionrules = array_merge($completionrules, $formextension->add_completion_rules()); + } + return $completionrules; } /** @@ -270,12 +291,23 @@ class mod_bigbluebuttonbn_mod_form extends moodleform_mod { */ public function completion_rule_enabled($data) { $suffix = $this->get_suffix(); - return (!empty($data['completionattendanceenabled' . $suffix]) && $data['completionattendance' . $suffix] != 0) - || !empty($data['completionengagementchats' . $suffix]) - || !empty($data['completionengagementtalks' . $suffix]) - || !empty($data['completionengagementraisehand' . $suffix]) - || !empty($data['completionengagementpollvotes' . $suffix]) - || !empty($data['completionengagementemojis' . $suffix]); + $rules = [ + 'completionattendanceenabled', + 'completionattendance', + 'completionengagementchats', + 'completionengagementtalks', + 'completionengagementraisehand', + 'completionengagementpollvotes', + 'completionengagementemojis' + ]; + $enabled = array_reduce($rules, function($carry, $rule) use ($data, $suffix) { + return $carry || !empty($data[$rule . $suffix]); + }, false); + + foreach ($this->formextensions as $formextension) { + $enabled = $enabled || $formextension->completion_rule_enabled($data); + } + return $enabled; } /** @@ -297,6 +329,9 @@ class mod_bigbluebuttonbn_mod_form extends moodleform_mod { $data->{'completionattendance' . $suffix} = 0; } } + foreach ($this->formextensions as $formextension) { + $formextension->data_postprocessing($data); + } } /** @@ -720,7 +755,9 @@ class mod_bigbluebuttonbn_mod_form extends moodleform_mod { public function definition_after_data() { global $COURSE; parent::definition_after_data(); - // Completion: If necessary, un-freeze group fields. + foreach ($this->formextensions as $formextension) { + $formextension->definition_after_data(); + } $completion = new completion_info($COURSE); if ($completion->is_enabled()) { $mform = $this->_form; @@ -737,4 +774,14 @@ class mod_bigbluebuttonbn_mod_form extends moodleform_mod { } } } + + /** + * Add subplugins form elements + * @return void + */ + private function add_subplugins_elements() { + foreach ($this->formextensions as $formextension) { + $formextension->add_fields(); + } + } } diff --git a/mod/bigbluebuttonbn/tests/behat/behat_mod_bigbluebuttonbn.php b/mod/bigbluebuttonbn/tests/behat/behat_mod_bigbluebuttonbn.php index d0b650ed781..963efc50ffb 100644 --- a/mod/bigbluebuttonbn/tests/behat/behat_mod_bigbluebuttonbn.php +++ b/mod/bigbluebuttonbn/tests/behat/behat_mod_bigbluebuttonbn.php @@ -28,8 +28,9 @@ require_once(__DIR__ . '/../../../../lib/behat/behat_base.php'); use Behat\Behat\Hook\Scope\BeforeScenarioScope; use Behat\Gherkin\Node\TableNode; use mod_bigbluebuttonbn\instance; +use mod_bigbluebuttonbn\test\subplugins_test_helper_trait; use Moodle\BehatExtension\Exception\SkippedException; - +require_once(__DIR__ . '../../../classes/test/subplugins_test_helper_trait.php'); /** * Behat custom steps and configuration for mod_bigbluebuttonbn. * @@ -38,6 +39,12 @@ use Moodle\BehatExtension\Exception\SkippedException; * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class behat_mod_bigbluebuttonbn extends behat_base { + use subplugins_test_helper_trait; + + /** + * @var array List of installed subplugins. + */ + protected $installedsubplugins = []; /** * BeforeScenario hook to reset the remote testpoint. @@ -241,4 +248,36 @@ XPATH ] ); } + + /** + * Install the simple subplugin + * + * Important note here. Originally we had a step that was installing the plugin, however + * because of race condition (mainly javascript calls), the hack to the core_component was + * randomly lost due to the component cache being cleared. So we have to install the plugin before + * any interaction with the site. + * @BeforeScenario @with_bbbext_simple + */ + public function install_simple_subplugin() { + $this->setup_fake_plugin("simple"); + $mockedcomponent = new ReflectionClass(core_component::class); + $mockedplugintypes = $mockedcomponent->getProperty('plugintypes'); + $mockedplugintypes->setAccessible(true); + $mockedplugintypes->setValue(null); + $init = $mockedcomponent->getMethod('init'); + $init->setAccessible(true); + $init->invoke(null); + // I enable the plugin. + $manager = core_plugin_manager::resolve_plugininfo_class(\mod_bigbluebuttonbn\extension::BBB_EXTENSION_PLUGIN_NAME); + $manager::enable_plugin("simple", true); + } + + /** + * Uninstall the simple subplugin + * + * @AfterScenario @with_bbbext_simple + */ + public function uninstall_simple_subplugin() { + $this->uninstall_fake_plugin("simple"); + } } diff --git a/mod/bigbluebuttonbn/tests/behat/subplugins.feature b/mod/bigbluebuttonbn/tests/behat/subplugins.feature new file mode 100644 index 00000000000..9a0dab11973 --- /dev/null +++ b/mod/bigbluebuttonbn/tests/behat/subplugins.feature @@ -0,0 +1,45 @@ +@mod @mod_bigbluebuttonbn @with_bbbext_simple +Feature: BigBlueButtonBN Subplugins test + As a BigBlueButtonBN user + I can list the subplugins the admin settings pages + I can see the additional settings coming from the subplugins in the edit form + Background: Make sure that the BigBlueButtonBN plugin is enabled + Given I accept dpa and enable bigbluebuttonbn plugin + And the following "courses" exist: + | fullname | shortname | category | + | Test course | Test course | 0 | + And the following "activities" exist: + | activity | course | name | type | + | bigbluebuttonbn | Test course | BBB Instance name | 0 | + + Scenario: Add a subplugin and check that the settings are available + Given I log in as "admin" + When I navigate to "Plugins > Activity modules > BigBlueButton > Manage BigBlueButton extension plugins" in site administration + Then I should see "Simple" + + Scenario: I check that new fields are available and editable in the instance edit form + Given I am on the "BBB Instance name" "bigbluebuttonbn activity editing" page logged in as "admin" + When I expand all fieldsets + And I should see "New field" + + @javascript + Scenario: I check that new fields are available and when I edit the field the value is saved + Given I am on the "BBB Instance name" "bigbluebuttonbn activity editing" page logged in as "admin" + And I expand all fieldsets + And I press "Save and display" + And I expand all fieldsets + And I should see "New field cannot be empty" + And I set the field "New field" to "50" + And I press "Save and display" + And I am on the "BBB Instance name" "bigbluebuttonbn activity editing" page + When I expand all fieldsets + Then the following fields match these values: + | New field | 50 | + + Scenario: I check that new fields are not available when subplugin is disabled + Given I log in as "admin" + And I navigate to "Plugins > Activity modules > BigBlueButton > Manage BigBlueButton extension plugins" in site administration + And I click on "Disable" "link" + And I am on the "BBB Instance name" "bigbluebuttonbn activity editing" page + When I expand all fieldsets + Then I should not see "New field" diff --git a/mod/bigbluebuttonbn/tests/fixtures/extension/simple/backup/moodle2/backup_bbbext_simple_subplugin.class.php b/mod/bigbluebuttonbn/tests/fixtures/extension/simple/backup/moodle2/backup_bbbext_simple_subplugin.class.php index 6efd870c2ae..e609840abe9 100644 --- a/mod/bigbluebuttonbn/tests/fixtures/extension/simple/backup/moodle2/backup_bbbext_simple_subplugin.class.php +++ b/mod/bigbluebuttonbn/tests/fixtures/extension/simple/backup/moodle2/backup_bbbext_simple_subplugin.class.php @@ -25,7 +25,7 @@ class backup_bbbext_simple_subplugin extends backup_subplugin { /** - * Returns the subplugin information to attach to submission element. + * Returns the subplugin information to attach the BigBlueButton instance. * * @return backup_subplugin_element */ diff --git a/mod/bigbluebuttonbn/tests/fixtures/extension/simple/backup/moodle2/restore_bbbext_simple_subplugin.class.php b/mod/bigbluebuttonbn/tests/fixtures/extension/simple/backup/moodle2/restore_bbbext_simple_subplugin.class.php index 1a1b143676e..0ed2f51f310 100644 --- a/mod/bigbluebuttonbn/tests/fixtures/extension/simple/backup/moodle2/restore_bbbext_simple_subplugin.class.php +++ b/mod/bigbluebuttonbn/tests/fixtures/extension/simple/backup/moodle2/restore_bbbext_simple_subplugin.class.php @@ -25,7 +25,7 @@ */ class restore_bbbext_simple_subplugin extends restore_subplugin { /** - * Returns the paths to be handled by the subplugin at workshop level + * Returns the paths to be handled by the subplugin. * * @return array */ @@ -43,7 +43,7 @@ class restore_bbbext_simple_subplugin extends restore_subplugin { } /** - * Processes one feedback_comments element. + * Processes one subplugin instance additional parameter. * * @param mixed $data */ diff --git a/mod/bigbluebuttonbn/tests/fixtures/extension/simple/classes/bigbluebuttonbn/mod_form_addons.php b/mod/bigbluebuttonbn/tests/fixtures/extension/simple/classes/bigbluebuttonbn/mod_form_addons.php new file mode 100644 index 00000000000..e9dd30d760b --- /dev/null +++ b/mod/bigbluebuttonbn/tests/fixtures/extension/simple/classes/bigbluebuttonbn/mod_form_addons.php @@ -0,0 +1,119 @@ +. +namespace bbbext_simple\bigbluebuttonbn; + +use stdClass; + +/** + * A class for the main mod form extension + * + * @package mod_bigbluebuttonbn + * @copyright 2023 onwards, Blindside Networks Inc + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @author Laurent David (laurent@call-learning.fr) + */ +class mod_form_addons extends \mod_bigbluebuttonbn\local\extension\mod_form_addons { + /** + * Allows modules to modify the data returned by form get_data(). + * This method is also called in the bulk activity completion form. + * + * Only available on moodleform_mod. + * + * @param stdClass $data passed by reference + */ + public function data_postprocessing(\stdClass &$data): void { + // Nothing for now. + } + + /** + * Allow module to modify the data at the pre-processing stage. + * + * This method is also called in the bulk activity completion form. + * + * @param array|null $defaultvalues + */ + public function data_preprocessing(?array &$defaultvalues): void { + // This is where we can add the data from the flexurl table to the data provided. + if (!empty($defaultvalues['id'])) { + global $DB; + $flexurlrecord = $DB->get_record('bbbext_simple', [ + 'bigbluebuttonbnid' => $defaultvalues['id'], + ]); + if ($flexurlrecord) { + $defaultvalues['newfield'] = $flexurlrecord->newfield; + } + } + } + + /** + * Can be overridden to add custom completion rules if the module wishes + * them. If overriding this, you should also override completion_rule_enabled. + *
+ * Just add elements to the form as needed and return the list of IDs. The + * system will call disabledIf and handle other behaviour for each returned + * ID. + * + * @return array Array of string IDs of added items, empty array if none + */ + public function add_completion_rules(): array { + return []; + } + + /** + * Called during validation. Override to indicate, based on the data, whether + * a custom completion rule is enabled (selected). + * + * @param array $data Input data (not yet validated) + * @return bool True if one or more rules is enabled, false if none are; + * default returns false + */ + public function completion_rule_enabled(array $data): bool { + return false; + } + + /** + * Form adjustments after setting data + * + * @return void + */ + public function definition_after_data() { + // Nothing for now. + } + + /** + * Add new form field definition + */ + public function add_fields(): void { + $this->mform->addElement('header', 'simple', get_string('pluginname', 'bbbext_simple')); + $this->mform->addElement('text', 'newfield', get_string('newfield', 'bbbext_simple')); + $this->mform->setType('newfield', PARAM_TEXT); + } + + /** + * Validate form and returns an array of errors indexed by field name + * + * @param array $data + * @param array $files + * @return array + */ + public function validation(array $data, array $files): array { + $errors = []; + if (empty($data['newfield'])) { + $errors['newfield'] = get_string('newfielderror', 'bbbext_simple'); + } + return $errors; + } +} diff --git a/mod/bigbluebuttonbn/tests/fixtures/extension/simple/classes/bigbluebuttonbn/mod_instance_helper.php b/mod/bigbluebuttonbn/tests/fixtures/extension/simple/classes/bigbluebuttonbn/mod_instance_helper.php index ee893bcc6b2..af79fe7e4bf 100644 --- a/mod/bigbluebuttonbn/tests/fixtures/extension/simple/classes/bigbluebuttonbn/mod_instance_helper.php +++ b/mod/bigbluebuttonbn/tests/fixtures/extension/simple/classes/bigbluebuttonbn/mod_instance_helper.php @@ -35,7 +35,7 @@ class mod_instance_helper extends \mod_bigbluebuttonbn\local\extension\mod_insta global $DB; $DB->insert_record('bbbext_simple', (object) [ 'bigbluebuttonbnid' => $bigbluebuttonbn->id, - 'newfield' => 2 + 'newfield' => $bigbluebuttonbn->newfield ?? '' ]); } @@ -49,8 +49,16 @@ class mod_instance_helper extends \mod_bigbluebuttonbn\local\extension\mod_insta $record = $DB->get_record('bbbext_simple', [ 'bigbluebuttonbnid' => $bigbluebuttonbn->id, ]); - $record->newfield = $bigbluebuttonbn->newfield; - $DB->update_record('bbbext_simple', $record); + // Just in case the instance was created before the extension was installed. + if (empty($record)) { + $record = new stdClass(); + $record->bigbluebuttonbnid = $bigbluebuttonbn->id; + $record->newfield = $bigbluebuttonbn->newfield; + $DB->insert_record('bbbext_simple', $record); + } else { + $record->newfield = $bigbluebuttonbn->newfield; + $DB->update_record('bbbext_simple', $record); + } } /** @@ -64,4 +72,12 @@ class mod_instance_helper extends \mod_bigbluebuttonbn\local\extension\mod_insta 'bigbluebuttonbnid' => $id, ]); } + + /** + * Get any join table name that is used to store additional data for the instance. + * @return string[] + */ + public function get_join_tables(): array { + return ['bbbext_simple']; + } } diff --git a/mod/bigbluebuttonbn/tests/fixtures/extension/simple/lang/en/bbbext_simple.php b/mod/bigbluebuttonbn/tests/fixtures/extension/simple/lang/en/bbbext_simple.php index 76d377cc8fe..41f55b72143 100644 --- a/mod/bigbluebuttonbn/tests/fixtures/extension/simple/lang/en/bbbext_simple.php +++ b/mod/bigbluebuttonbn/tests/fixtures/extension/simple/lang/en/bbbext_simple.php @@ -24,4 +24,6 @@ defined('MOODLE_INTERNAL') || die(); $string['config_extension'] = 'Sample config extension setting'; +$string['newfield'] = 'New field'; +$string['newfielderror'] = 'New field cannot be empty'; $string['pluginname'] = 'Simple BigBlueButtonPlugin'; diff --git a/mod/bigbluebuttonbn/tests/local/extension_test.php b/mod/bigbluebuttonbn/tests/local/extension_test.php index ac36caef844..f7827373174 100644 --- a/mod/bigbluebuttonbn/tests/local/extension_test.php +++ b/mod/bigbluebuttonbn/tests/local/extension_test.php @@ -45,6 +45,7 @@ class extension_test extends \advanced_testcase { public function setUp(): void { $this->resetAfterTest(true); $this->setup_fake_plugin('simple'); + $this->resetDebugging(); // We might have debugging messages issued from setup_fake_plugin here that we need to get rid of. } @@ -87,7 +88,7 @@ class extension_test extends \advanced_testcase { * Test the add module callback * * @return void - * @covers \mod_bigbluebuttonbn\local\extension\mod_instance_helpe + * @covers \mod_bigbluebuttonbn\local\extension\mod_instance_helper */ public function test_mod_instance_helper_add() { global $DB; @@ -106,7 +107,7 @@ class extension_test extends \advanced_testcase { * Test the update module callback * * @return void - * @covers \mod_bigbluebuttonbn\local\extension\mod_instance_helpe + * @covers \mod_bigbluebuttonbn\local\extension\mod_instance_helper */ public function test_mod_instance_helper_update() { global $DB; @@ -127,7 +128,7 @@ class extension_test extends \advanced_testcase { * Test delete module callback * * @return void - * @covers \mod_bigbluebuttonbn\local\extension\mod_instance_helpe + * @covers \mod_bigbluebuttonbn\local\extension\mod_instance_helper */ public function test_mod_instance_helper_delete() { global $DB; diff --git a/mod/bigbluebuttonbn/version.php b/mod/bigbluebuttonbn/version.php index a970f87fb90..0c03a9efe17 100644 --- a/mod/bigbluebuttonbn/version.php +++ b/mod/bigbluebuttonbn/version.php @@ -27,6 +27,6 @@ defined('MOODLE_INTERNAL') || die; -$plugin->version = 2023042800; +$plugin->version = 2023080600; $plugin->requires = 2023041800; $plugin->component = 'mod_bigbluebuttonbn';