diff --git a/.github/workflows/moodle-plugin-ci.yml b/.github/workflows/moodle-plugin-ci.yml new file mode 100644 index 0000000..a1410b6 --- /dev/null +++ b/.github/workflows/moodle-plugin-ci.yml @@ -0,0 +1,169 @@ +# Title of the workflow +name: Moodle Plugin CI + +# Run this workflow every time a new commit pushed to your repository or PR +# created. +on: [push] + +jobs: + # Set the job key. The key is displayed as the job name + # when a job name is not provided + test: + # Virtual environment to use. + runs-on: ubuntu-22.04 + + # DB services you need for testing. + services: + postgres: + image: postgres:14 + env: + POSTGRES_USER: 'postgres' + POSTGRES_HOST_AUTH_METHOD: 'trust' + ports: + - 5432:5432 + options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 3 + + mariadb: + image: mariadb:10 + env: + MYSQL_USER: 'root' + MYSQL_ALLOW_EMPTY_PASSWORD: "true" + MYSQL_CHARACTER_SET_SERVER: "utf8mb4" + MYSQL_COLLATION_SERVER: "utf8mb4_unicode_ci" + ports: + - 3306:3306 + options: --health-cmd="mysqladmin ping" --health-interval 10s --health-timeout 5s --health-retries 3 + + # Determines build matrix. This is a list of PHP versions, databases and + # branches to test our project against. For each combination a separate + # build will be created. For example below 6 builds will be created in + # total (7.4-pgsql, 7.4-mariadb, 8.0-pgsql, 8.0-mariadb, etc.). If we add + # another branch, total number of builds will become 12. + strategy: + fail-fast: false + matrix: + include: + - php: '8.3' + moodle-branch: 'main' + database: 'pgsql' + - php: '8.3' + moodle-branch: 'MOODLE_404_STABLE' + database: 'pgsql' + - php: '8.2' + moodle-branch: 'MOODLE_403_STABLE' + database: 'mariadb' + - php: '8.1' + moodle-branch: 'MOODLE_402_STABLE' + database: 'pgsql' + - php: '8.1' + moodle-branch: 'MOODLE_401_STABLE' + database: 'mariadb' + + steps: + # Check out this repository code in ./plugin directory + - name: Check out repository code + uses: actions/checkout@v4 + with: + path: plugin + + # Install PHP of required version. For possible options see https://github.com/shivammathur/setup-php + - name: Setup PHP ${{ matrix.php }} + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: ${{ matrix.extensions }} + ini-values: max_input_vars=5000 + # If you are not using code coverage, keep "none". Otherwise, use "pcov" (Moodle 3.10 and up) or "xdebug". + # If you try to use code coverage with "none", it will fallback to phpdbg (which has known problems). + coverage: none + + # Install this project into a directory called "ci", updating PATH and + # locale, define nvm location. + - name: Initialise moodle-plugin-ci + run: | + composer create-project -n --no-dev --prefer-dist moodlehq/moodle-plugin-ci ci ^4 + echo $(cd ci/bin; pwd) >> $GITHUB_PATH + echo $(cd ci/vendor/bin; pwd) >> $GITHUB_PATH + sudo locale-gen en_AU.UTF-8 + echo "NVM_DIR=$HOME/.nvm" >> $GITHUB_ENV + + # Run the default install. + # Optionally, it is possible to specify a different Moodle repo to use + # (https://github.com/moodle/moodle.git is used by default) and define + # ignore directives or any other env vars for install step. For more + # details on configuring for specific requirements please refer to the + # 'Help' page. + # + # env: + # MOODLE_REPO=https://github.com/username/moodle.git + # IGNORE_PATHS: 'ignore' + # IGNORE_NAMES: 'ignore_name.php' + # MUSTACHE_IGNORE_NAMES: 'broken.mustache' + # CODECHECKER_IGNORE_PATHS: 'ignoreme' + # CODECHECKER_IGNORE_NAMES: 'ignoreme_name.php' + # + # Other env vars are available for install, namely: + # - DB_USER / DB_PASS / DB_NAME / DB_HOST / DB_PORT: used + # by install to feed the corresponding --db-xxxx options. + # - MOODLE_APP: used to install dependencies to run Behat tests + # using the Moodle App. + - name: Install moodle-plugin-ci + run: | + moodle-plugin-ci install --plugin ./plugin --db-host=127.0.0.1 + env: + DB: ${{ matrix.database }} + MOODLE_BRANCH: ${{ matrix.moodle-branch }} + # Uncomment this to run Behat tests using the Moodle App. + # MOODLE_APP: 'true' + + # Steps that are run for the purpose of testing. Any of these steps + # can be re-ordered or removed to your liking. And of course, you can + # add any of your own custom steps. + - name: PHP Lint + if: ${{ !cancelled() }} # prevents CI run stopping if step failed. + run: moodle-plugin-ci phplint + + - name: PHP Mess Detector + continue-on-error: true + if: ${{ !cancelled() }} + run: moodle-plugin-ci phpmd + + - name: Moodle Code Checker + if: ${{ !cancelled() }} + run: moodle-plugin-ci phpcs --max-warnings 3 + + - name: Moodle PHPDoc Checker + if: ${{ !cancelled() }} + run: moodle-plugin-ci phpdoc --max-warnings 0 + + - name: Validating + if: ${{ !cancelled() }} + run: moodle-plugin-ci validate + + - name: Check upgrade savepoints + if: ${{ !cancelled() }} + run: moodle-plugin-ci savepoints + + - name: Mustache Lint + if: ${{ !cancelled() }} + run: moodle-plugin-ci mustache + + - name: PHPUnit tests + if: ${{ !cancelled() }} + run: moodle-plugin-ci phpunit + + # This step allows to upload Behat faildump (screenshots) as workflow artifact + # so it can be downloaded and inspected. You don't need this step if you + # are not running Behat test. Artifact will be retained for 7 days. + - name: Upload Behat Faildump + if: ${{ failure() && steps.behat.outcome == 'failure' }} + uses: actions/upload-artifact@v4 + with: + name: Behat Faildump (${{ join(matrix.*, ', ') }}) + path: ${{ github.workspace }}/moodledata/behat_dump + retention-days: 7 + if-no-files-found: ignore + + - name: Mark cancelled jobs as failed. + if: ${{ cancelled() }} + run: exit 1 \ No newline at end of file diff --git a/classes/external/external.php b/classes/external/external.php index e9014c6..5ad179a 100644 --- a/classes/external/external.php +++ b/classes/external/external.php @@ -48,7 +48,7 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @since Moodle 3.3 */ -class mod_panoptocourseembed_external extends external_api { +class external extends external_api { /** * Describes the parameters for get_panoptocourseembeds_by_courses. diff --git a/contentitem_return.php b/contentitem_return.php index f6e1be3..4404b65 100644 --- a/contentitem_return.php +++ b/contentitem_return.php @@ -121,20 +121,97 @@ /** * Trigger the handleError callback with the errors. */ - 0): ?> - parent.document.CALLBACKS.handleError(); - + 0): ?> + parent.document.CALLBACKS.handleError(); + /** * Create and dispatch a custom event 'sessionSelected' with session details. - * This event should close the panopto popup and pass the new content URL to the existing iframe. + * This event should close the Panopto popup and pass the new content URL to the existing iframe. */ const detailObject = { - title: "", - ltiViewerUrl: "out(false) ?>", - contentUrl: "", - customData: "", - width: , - height: + title: "", + + ltiViewerUrl: "out(false) ?>", + + contentUrl: "", + + customData: "", + + width: , + + height: }; const sessionSelectedEvent = new CustomEvent('sessionSelected', { @@ -144,5 +221,13 @@ }); parent.document.body.dispatchEvent(sessionSelectedEvent); - + diff --git a/db/services.php b/db/services.php index cae4f1b..e2b1402 100644 --- a/db/services.php +++ b/db/services.php @@ -27,10 +27,11 @@ $functions = [ 'mod_panoptocourseembed_get_panoptocourseembeds_by_courses' => [ - 'classname' => 'mod_panoptocourseembed_external', + 'classname' => 'mod_panoptocourseembed\external\external', 'methodname' => 'get_panoptocourseembeds_by_courses', 'description' => - 'Returns a list of panoptocourseembeds in a provided list of courses, if no list is provided all panoptocourseembeds that the user can view will be returned.', + 'Returns a list of panoptocourseembeds in a provided list of courses, + if no list is provided all panoptocourseembeds that the user can view will be returned.', 'type' => 'read', 'capabilities' => 'mod/panoptocourseembed:view', 'services' => [MOODLE_OFFICIAL_MOBILE_SERVICE], diff --git a/lang/en/panoptocourseembed.php b/lang/en/panoptocourseembed.php index fd81b99..0c59c19 100644 --- a/lang/en/panoptocourseembed.php +++ b/lang/en/panoptocourseembed.php @@ -22,6 +22,9 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +$string['default_panopto_server'] = 'Default Panopto Server'; +$string['default_panopto_server_desc'] = 'The FQDN of the Panopto server we will try to use in the case a course is not provisioned with Panopto via the block. E.g. demo.hosted.panopto.com'; +$string['folderview'] = 'Embed Folder View'; $string['indicator:cognitivedepth'] = 'Panopto course embed cognitive'; $string['indicator:cognitivedepth_help'] = 'This indicator is based on the cognitive depth reached by the student in a Panopto course embed resource.'; $string['indicator:cognitivedepthdef'] = 'Panopto course embed cognitive'; @@ -32,21 +35,18 @@ $string['indicator:socialbreadthdef'] = 'Panopto course embed social'; $string['indicator:socialbreadthdef_help'] = 'The participant has reached this percentage of the social engagement offered by the Panopto course embed resources during this analysis interval (Levels = No participation, Participant alone)'; $string['indicator:socialbreadthdef_link'] = 'Learning_analytics_indicators#Social_breadth'; -$string['panoptocourseembed:addinstance'] = 'Add a new Panopto course embed'; -$string['panoptocourseembed:view'] = 'View Panopto course embed'; +$string['is_responsive'] = 'Responsive folders and videos'; +$string['is_responsive_desc'] = 'If this setting is turned on, both folder and videos will be responsive on the page. This will affect only new embeds, after settings is turned on.'; $string['modulename'] = 'Panopto course embed'; $string['modulename_help'] = 'The Panopto course embed module enables Panopto video sessions and folder views to be inserted into the course page in between links to other resources and activities.'; $string['modulename_link'] = 'mod/panoptocourseembed/view'; $string['modulenameplural'] = 'Panopto course embeds'; $string['no_existing_lti_tools'] = 'No pre-configured LTI tool exists for your Panopto server. Please contact your Moodle administrator and make sure that the one time admin setup was completed.'; -$string['privacy:metadata'] = 'The Panopto course embed resource plugin does not store any personal data.'; +$string['panoptocourseembed:addinstance'] = 'Add a new Panopto course embed'; +$string['panoptocourseembed:view'] = 'View Panopto course embed'; $string['pluginadministration'] = 'Panopto course embed administration'; $string['pluginname'] = 'Panopto course embed'; +$string['privacy:metadata'] = 'The Panopto course embed resource plugin does not store any personal data.'; +$string['replacevideo'] = 'Replace Video'; $string['search:activity'] = 'Panopto course embed'; $string['selectvideo'] = 'Select Video'; -$string['replacevideo'] = 'Replace Video'; -$string['folderview'] = 'Embed Folder View'; -$string['default_panopto_server'] = 'Default Panopto Server'; -$string['default_panopto_server_desc'] = 'The FQDN of the Panopto server we will try to use in the case a course is not provisioned with Panopto via the block. E.g. demo.hosted.panopto.com'; -$string['is_responsive'] = 'Responsive folders and videos'; -$string['is_responsive_desc'] = 'If this setting is turned on, both folder and videos will be responsive on the page. This will affect only new embeds, after settings is turned on.'; diff --git a/lib.php b/lib.php index e95cebf..e602e05 100644 --- a/lib.php +++ b/lib.php @@ -21,7 +21,6 @@ * @copyright Panopto 2021 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -defined('MOODLE_INTERNAL') || die(); /** * Get activity name diff --git a/mod_form.php b/mod_form.php index ec0a3da..765885c 100644 --- a/mod_form.php +++ b/mod_form.php @@ -28,6 +28,8 @@ require_once($CFG->dirroot.'/course/moodleform_mod.php'); require_once($CFG->dirroot . '/blocks/panopto/lib/lti/panoptoblock_lti_utility.php'); +require_login(); + /** * This class contains the forms to create and edit an instance of this module * diff --git a/renderer.php b/renderer.php index 458c22a..77edb89 100644 --- a/renderer.php +++ b/renderer.php @@ -21,7 +21,10 @@ * @copyright Panopto 2021 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ + +// @codingStandardsIgnoreStart defined('MOODLE_INTERNAL') || die(); +// @codingStandardsIgnoreEnd /** * This class renders the course embed pages. diff --git a/tests/generator/lib.php b/tests/generator/lib.php index 53b3367..b9b5e34 100644 --- a/tests/generator/lib.php +++ b/tests/generator/lib.php @@ -39,7 +39,7 @@ class mod_panoptocourseembed_generator extends testing_module_generator { * @param array $record Record for the instance. * @param array|null $options Options for the instance. */ - public function create_instance($record = null, array $options = null) { + public function create_instance($record = null, ?array $options = null) { $record = (array)$record; $record['showdescription'] = 1; return parent::create_instance($record, $options); diff --git a/tests/mod_panoptocourseembed_external_testcase.php b/tests/mod_panoptocourseembed_external_testcase.php index c3e19e7..69616cb 100644 --- a/tests/mod_panoptocourseembed_external_testcase.php +++ b/tests/mod_panoptocourseembed_external_testcase.php @@ -24,14 +24,12 @@ */ namespace mod_panoptocourseembed\tests; -use mod_panoptocourseembed\external\mod_panoptocourseembed_external; use externallib_advanced_testcase; defined('MOODLE_INTERNAL') || die(); global $CFG; require_once($CFG->dirroot . '/webservice/tests/helpers.php'); -require_once($CFG->dirroot . '/mod/panoptocourseembed/classes/external/external.php'); /** * External mod_panoptocourseembed functions unit tests @@ -45,7 +43,6 @@ class mod_panoptocourseembed_external_testcase extends externallib_advanced_test /** * Test get panoptocourseembeds by courses. - * @covers ::mod_panoptocourseembed_get_panoptocourseembeds_by_courses */ public function test_mod_panoptocourseembed_get_panoptocourseembeds_by_courses(): void { global $DB; @@ -82,7 +79,7 @@ public function test_mod_panoptocourseembed_get_panoptocourseembeds_by_courses() self::setUser($student); - $returndescription = mod_panoptocourseembed_external::get_panoptocourseembeds_by_courses_returns(); + $returndescription = \mod_panoptocourseembed\external\external::get_panoptocourseembeds_by_courses_returns(); // Create what we expect to be returned when querying the two courses. $expectedfields = ['id', 'coursemodule', 'course', 'name', 'intro', 'introformat', 'introfiles', 'timemodified', @@ -113,7 +110,7 @@ public function test_mod_panoptocourseembed_get_panoptocourseembeds_by_courses() $expectedpanoptocourseembeds = [$expected2, $expected1]; // Call the external function passing course ids. - $result = mod_panoptocourseembed_external::get_panoptocourseembeds_by_courses([$course2->id, $course1->id]); + $result = \mod_panoptocourseembed\external\external::get_panoptocourseembeds_by_courses([$course2->id, $course1->id]); $result = \external_api::clean_returnvalue($returndescription, $result); $this->assertEquals($expectedpanoptocourseembeds, $result['panoptocourseembeds']); @@ -130,12 +127,12 @@ public function test_mod_panoptocourseembed_get_panoptocourseembeds_by_courses() array_shift($expectedpanoptocourseembeds); // Call the external function without passing course id. - $result = mod_panoptocourseembed_external::get_panoptocourseembeds_by_courses(); + $result = \mod_panoptocourseembed\external\external::get_panoptocourseembeds_by_courses(); $result = \external_api::clean_returnvalue($returndescription, $result); $this->assertEquals($expectedpanoptocourseembeds, $result['panoptocourseembeds']); // Call for the second course we unenrolled the user from, expected warning. - $result = mod_panoptocourseembed_external::get_panoptocourseembeds_by_courses([$course2->id]); + $result = \mod_panoptocourseembed\external\external::get_panoptocourseembeds_by_courses([$course2->id]); $this->assertCount(1, $result['warnings']); $this->assertEquals('1', $result['warnings'][0]['warningcode']); $this->assertEquals($course2->id, $result['warnings'][0]['itemid']); diff --git a/version.php b/version.php index 4856c77..305de58 100644 --- a/version.php +++ b/version.php @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die(); // The current module version (Date: YYYYMMDDXX). -$plugin->version = 2024070900; +$plugin->version = 2024120600; // Requires this Moodle version 4.1.0. $plugin->requires = 2022112800;