diff --git a/.github/workflows/moodle-ci.yml b/.github/workflows/moodle-ci.yml index 225002c..9fe5a35 100644 --- a/.github/workflows/moodle-ci.yml +++ b/.github/workflows/moodle-ci.yml @@ -1,5 +1,8 @@ +# 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: paths-ignore: @@ -8,11 +11,14 @@ on: paths-ignore: - 'node_modules/**' - jobs: + # Set the job key. The key is displayed as the job name + # when a job name is not provided test: - runs-on: ubuntu-latest + # Virtual environment to use. + runs-on: ubuntu-22.04 + # DB services you need for testing. services: postgres: image: postgres:13 @@ -22,6 +28,7 @@ jobs: ports: - 5432:5432 options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 3 + mariadb: image: mariadb:10 env: @@ -29,18 +36,31 @@ jobs: 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' + - php: '8.4' moodle-branch: 'main' database: 'pgsql' + - php: '8.4' + moodle-branch: 'MOODLE_501_STABLE' + database: 'mariadb' + - php: '8.3' + moodle-branch: 'MOODLE_500_STABLE' + database: 'pgsql' + - php: '8.3' + moodle-branch: 'MOODLE_405_STABLE' + database: 'mariadb' - php: '8.3' moodle-branch: 'MOODLE_404_STABLE' database: 'pgsql' @@ -55,78 +75,93 @@ jobs: database: 'mariadb' steps: + # Check out this repository code in ./plugin directory - name: Check out repository code - uses: actions/checkout@v2 + 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 - # none to use phpdbg fallback. Specify pcov (Moodle 3.10 and up) or xdebug to use them instead. + # 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 ^3 + 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: ${{ always() }} + if: ${{ !cancelled() }} # prevents CI run stopping if step failed. run: moodle-plugin-ci phplint - - name: PHP Copy/Paste Detector - continue-on-error: true # This step will show errors but will not fail - if: ${{ always() }} - run: moodle-plugin-ci phpcpd - - name: PHP Mess Detector - continue-on-error: true # This step will show errors but will not fail - if: ${{ always() }} + continue-on-error: true + if: ${{ !cancelled() }} run: moodle-plugin-ci phpmd - name: Moodle Code Checker - if: ${{ always() }} - # Allow 3 warnings for privacy provider interfaces (Moodle <3.6) - run: moodle-plugin-ci codechecker --max-warnings 3 + if: ${{ !cancelled() }} + run: moodle-plugin-ci phpcs --max-warnings 3 - name: Moodle PHPDoc Checker - if: ${{ always() }} - run: moodle-plugin-ci phpdoc + if: ${{ !cancelled() }} + run: moodle-plugin-ci phpdoc --max-warnings 0 - name: Validating - if: ${{ always() }} + if: ${{ !cancelled() }} run: moodle-plugin-ci validate - name: Check upgrade savepoints - if: ${{ always() }} + if: ${{ !cancelled() }} run: moodle-plugin-ci savepoints -# Mustache and Grunt are failing so commenting out for now -# - name: Mustache Lint -# if: ${{ always() }} -# run: moodle-plugin-ci mustache - -# - name: Grunt -# if: ${{ always() }} -# run: moodle-plugin-ci grunt --max-lint-warnings 0 - - name: PHPUnit tests - if: ${{ always() }} - run: moodle-plugin-ci phpunit --fail-on-warning + if: ${{ !cancelled() }} + run: moodle-plugin-ci phpunit - - name: Behat features - if: ${{ always() }} - run: moodle-plugin-ci behat --profile chrome \ No newline at end of file + - name: Mark cancelled jobs as failed. + if: ${{ cancelled() }} + run: exit 1 \ No newline at end of file diff --git a/README.md b/README.md index e1ce47e..d56ae62 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ enabled by confirming that its corresponding icon under the 'Enable' column show You can build all modules in Moodle by using the grunt amd command. To update the amd module from this plugin: 1. Execute `npm install` on the root of the Moodle project. -2. Navigate to `/lib/editor/tiny/panoptoltibutton/amd/` and execute: +2. Navigate to `/lib/editor/tiny/plugins/panoptoltibutton/amd/` and execute: ``` $ npx grunt amd diff --git a/classes/plugininfo.php b/classes/plugininfo.php index 9862941..b0aaa52 100644 --- a/classes/plugininfo.php +++ b/classes/plugininfo.php @@ -44,9 +44,8 @@ */ class plugininfo extends plugin implements plugin_with_buttons, - plugin_with_menuitems, - plugin_with_configuration { - + plugin_with_configuration, + plugin_with_menuitems { /** * Get a list of the buttons provided by this plugin. * @@ -105,7 +104,7 @@ public static function get_plugin_configuration_for_context( 'resourcebase' => $resourcebase, 'panoptoltibuttondescription' => get_string('panopto_button_description', 'tiny_panoptoltibutton'), 'panoptoltibuttonlongdescription' => get_string('panopto_button_long_description', 'tiny_panoptoltibutton'), - 'unprovisionederror' => get_string('panopto_button_unprovisioned_error', 'tiny_panoptoltibutton') + 'unprovisionederror' => get_string('panopto_button_unprovisioned_error', 'tiny_panoptoltibutton'), ]; } } diff --git a/classes/privacy/provider.php b/classes/privacy/provider.php index 77a6692..be5f993 100644 --- a/classes/privacy/provider.php +++ b/classes/privacy/provider.php @@ -36,14 +36,13 @@ class provider implements // This plugin does not store any personal user data. \core_privacy\local\metadata\null_provider { - /** * Get the language string identifier with the component's language * file to explain why this plugin stores no data. * * @return string */ - public static function get_reason() : string { + public static function get_reason(): string { return 'privacy:metadata'; } } diff --git a/contentitem.php b/contentitem.php index f4ff44e..ae01763 100644 --- a/contentitem.php +++ b/contentitem.php @@ -55,8 +55,7 @@ $ltiviewerurl = new moodle_url(LTI_TINY_PATH); $resourcelinkid = sha1($ltiviewerurl->out(false) . '&' . $courseid . - '&' . $course->timecreated - ); + '&' . $course->timecreated); $lti->id = $resourcelinkid; } if (!isset($SESSION->lti_initiatelogin_status)) { @@ -80,7 +79,18 @@ // Prepare the request. $request = lti_build_content_item_selection_request( - $id, $course, $returnurl, '', '', [], [], false, false, false, false, false + $id, + $course, + $returnurl, + '', + '', + [], + [], + false, + false, + false, + false, + false ); // Get the launch HTML. diff --git a/contentitem_return.php b/contentitem_return.php index 4678fe6..d82f23a 100644 --- a/contentitem_return.php +++ b/contentitem_return.php @@ -15,15 +15,19 @@ // along with Moodle. If not, see . /** - * Handles content item return. + * This script handles the content item return process. + * + * It processes LTI content item returns, validates the response, and either + * triggers an error callback or dispatches the content items to the parent window. * * @package tiny_panoptoltibutton - * @copyright 2023 Panopto + * @copyright 2025 Panopto * @author Panopto * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require_once(dirname(__FILE__) . '/../../../../../config.php'); +require_once($CFG->dirroot . '/blocks/panopto/lib/panopto_data.php'); require_once($CFG->dirroot . '/blocks/panopto/lib/lti/panoptoblock_lti_utility.php'); require_once($CFG->dirroot . '/mod/lti/lib.php'); require_once($CFG->dirroot . '/mod/lti/locallib.php'); @@ -61,13 +65,11 @@ $errors = []; -// Affirm that the content item is a JSON object. if (!is_object($contentitems) && !is_array($contentitems)) { $errors[] = 'invalidjson'; } if ($islti1p3) { - // Update content items data if this is lti 1.3 and not embed. $doctarget = $contentitems->{'@graph'}[0]->placementAdvice->presentationDocumentTarget ? $contentitems->{'@graph'}[0]->placementAdvice->presentationDocumentTarget : ($contentitems->{'@graph'}[0]->iframe ? "iframe" : "frame"); @@ -80,12 +82,70 @@ } } +// Provision the course for LTI. +\panopto_data::provision_course_for_lti($courseid); ?> diff --git a/db/access.php b/db/access.php new file mode 100644 index 0000000..fb15994 --- /dev/null +++ b/db/access.php @@ -0,0 +1,39 @@ +. + +/** + * Capability definitions for the tiny_panoptoltibutton plugin. + * + * @package tiny_panoptoltibutton + * @copyright 2025 Panopto + * @author Panopto + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +$capabilities = [ + 'tiny/panoptoltibutton:use' => [ + 'captype' => 'write', + 'contextlevel' => CONTEXT_COURSE, + 'archetypes' => [ + 'editingteacher' => CAP_ALLOW, + 'teacher' => CAP_ALLOW, + 'manager' => CAP_ALLOW, + ], + 'clonepermissionsfrom' => 'moodle/course:manageactivities', + ], +]; diff --git a/js/panopto_tinymce_panoptoltibutton.js b/js/panopto_tinymce_panoptoltibutton.js index 8d530cb..c784a83 100644 --- a/js/panopto_tinymce_panoptoltibutton.js +++ b/js/panopto_tinymce_panoptoltibutton.js @@ -125,7 +125,7 @@ var panopto_tinymce_panoptoltibutton = { TEMPLATES = { ltiLink: Handlebars.compile('