Skip to content

Commit

Permalink
2022122000 Release Code (#59)
Browse files Browse the repository at this point in the history
* Fix deprecated fields

* Retrieve strings from plugin

* Fix for user_picture deprecation

* added cutoff date field.

* added due date, and cutoff date validation.

* review requested changes.

* Provision course on student submission

* Verify panopto in view submission

* Initial LTI 1.3 params

* Add require_sesskey

* Add error check

* mod_lti dependency

* thumbnail fields missing from backup api

* install xml tool generated

* Frankenstyle naming conventions

* add_external_location_link implementation

* Github actions

* ignore node_modules folder

* Comment out Mustache and Grunt checks

* Code checker fixes

* Code check space fix

* Fix parameters order

* Validation for thumb and frame sizes

* Validation for title and url

* PR feedback

* Replace function with inline code

* Fix indent for compliance

* Get target server provisioned course

* Convert grade from int to number

* Fix variable naming convention

* Added email and username to privacy logic

* LTI 1.3 updates

* Update login request for view_submission

* Make launch data public

* lti 1.3 thumbnailurl

* code needed to get lti 1.3 working with panoptoblock_lti_utility.

* swapped broken thumbnail field.

* Remove verify oauth signature

* updated version for 2022122000 release.

Co-authored-by: Adis <[email protected]>
  • Loading branch information
jmalmsten-panopto and zeroAps authored Dec 21, 2022
1 parent bcb62ad commit 0698c2b
Show file tree
Hide file tree
Showing 21 changed files with 525 additions and 490 deletions.
129 changes: 129 additions & 0 deletions .github/workflows/moodle-plugin-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
name: Moodle Plugin CI

on:
push:
paths-ignore:
- 'node_modules/**'
pull_request:
paths-ignore:
- 'node_modules/**'


jobs:
test:
runs-on: ubuntu-latest

services:
postgres:
image: postgres:12
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

strategy:
fail-fast: false
matrix:
include:
- php: '8.0'
moodle-branch: 'master'
database: 'pgsql'
- php: '8.0'
moodle-branch: 'MOODLE_400_STABLE'
database: 'mariadb'
- php: '7.4'
moodle-branch: 'MOODLE_311_STABLE'
database: 'pgsql'
- php: '7.4'
moodle-branch: 'MOODLE_39_STABLE'
database: 'mariadb'

steps:
- name: Check out repository code
uses: actions/checkout@v2
with:
path: plugin

- 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.
coverage: none

- name: Initialise moodle-plugin-ci
run: |
composer create-project -n --no-dev --prefer-dist moodlehq/moodle-plugin-ci ci ^3
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
- 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 }}

- name: PHP Lint
if: ${{ always() }}
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() }}
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

- name: Moodle PHPDoc Checker
if: ${{ always() }}
run: moodle-plugin-ci phpdoc

- name: Validating
if: ${{ always() }}
run: moodle-plugin-ci validate

- name: Check upgrade savepoints
if: ${{ always() }}
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

- name: Behat features
if: ${{ always() }}
run: moodle-plugin-ci behat --profile chrome
4 changes: 4 additions & 0 deletions backup/moodle2/backup_panoptosubmission_stepslib.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ protected function define_structure() {
'introformat',
'timeavailable',
'timedue',
'cutofftime',
'preventlate',
'resubmit',
'emailteachers',
Expand All @@ -64,6 +65,9 @@ protected function define_structure() {
'source',
'width',
'height',
'thumbnailsource',
'thumbnailwidth',
'thumbnailheight',
'grade',
'submissioncomment',
'format',
Expand Down
18 changes: 17 additions & 1 deletion classes/privacy/provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ class provider implements \core_privacy\local\metadata\provider,
*/
public static function get_metadata(collection $collection) : collection {

$collection->add_external_location_link(
'panoptosubmission_submission',
[
'userid' => 'privacy:metadata:panoptosubmission_submission:userid',
'username' => 'privacy:metadata:panoptosubmission_submission:username',
'email' => 'privacy:metadata:panoptosubmission_submission:email'
],
'privacy:metadata:panoptosubmission_submission'
);

$collection->add_subsystem_link('core_message', [], 'privacy:metadata:emailteachersexplanation');

$collection->add_database_table(
Expand All @@ -64,7 +74,8 @@ public static function get_metadata(collection $collection) : collection {
);

$collection->add_user_preference('panoptosubmission_filter',
'privacy:metadata:panoptosubmissionfilter');
'privacy:metadata:panoptosubmissionfilter'
);
$collection->add_user_preference('panoptosubmission_group_filter',
'privacy:metadata:panoptosubmissiongroupfilter'
);
Expand Down Expand Up @@ -399,6 +410,7 @@ protected static function get_panoptosubmission_by_context($context) {
"a.grade, " .
"a.timedue, " .
"a.timeavailable, " .
"a.cutofftime, " .
"a.timemodified " .
"FROM {panoptosubmission} a " .
"JOIN {course_modules} cm ON a.id = cm.instance " .
Expand Down Expand Up @@ -431,6 +443,10 @@ protected static function get_panoptosubmission_output($panoptosubmissiondata) {
$panoptosubmission->timedue = transform::datetime($panoptosubmissiondata->timedue);
}

if ($panoptosubmissiondata->cutofftime != 0) {
$panoptosubmission->cutofftime = transform::datetime($panoptosubmissiondata->cutofftime);
}

return $panoptosubmission;
}

Expand Down
15 changes: 13 additions & 2 deletions contentitem.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,33 @@
require_once(dirname(dirname(dirname(__FILE__))) . '/mod/lti/lib.php');
require_once(dirname(dirname(dirname(__FILE__))) . '/mod/lti/locallib.php');
require_once(dirname(__FILE__) . '/locallib.php');
require_once(dirname(__FILE__) . '/lib/panoptosubmission_lti_utility.php');
require_once($CFG->dirroot . '/blocks/panopto/lib/lti/panoptoblock_lti_utility.php');

$courseid = required_param('courseid', PARAM_INT);

// Check access and capabilities.
$course = get_course($courseid);
require_login($course);

$toolid = \panoptosubmission_lti_utility::get_course_tool_id($courseid);
$toolid = \panoptoblock_lti_utility::get_course_tool_id($courseid, 'panopto_student_submission_tool');

// If no lti tool exists then we can not continue.
if (is_null($toolid)) {
throw new moodle_exception('no_existing_lti_tools', 'panoptosubmission');
return;
}

// LTI 1.3 login request.
$config = lti_get_type_type_config($toolid);
if ($config->lti_ltiversion === LTI_VERSION_1P3) {
if (!isset($SESSION->lti_initiatelogin_status)) {
echo lti_initiate_login($courseid, "mod_panoptosubmission", null, $config);
exit;
} else {
unset($SESSION->lti_initiatelogin_status);
}
}

// Set the return URL. We send the launch container along to help us avoid
// frames-within-frames when the user returns.
$returnurlparams = [
Expand Down
91 changes: 73 additions & 18 deletions contentitem_return.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,41 @@
*/

require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
require_once(dirname(__FILE__) . '/lib/panoptosubmission_lti_utility.php');

require_once($CFG->dirroot . '/blocks/panopto/lib/lti/panoptoblock_lti_utility.php');
require_once($CFG->dirroot . '/blocks/panopto/lib/panopto_data.php');
require_once(dirname(dirname(dirname(__FILE__))) . '/mod/lti/lib.php');
require_once(dirname(dirname(dirname(__FILE__))) . '/mod/lti/locallib.php');

$courseid = required_param('course', PARAM_INT);
$contentitemsraw = required_param('content_items', PARAM_RAW_TRIMMED);
$id = required_param('id', PARAM_INT);
$jwt = optional_param('JWT', '', PARAM_RAW);

require_login($courseid);

$context = context_course::instance($courseid);

$contentitems = json_decode($contentitemsraw);
$config = lti_get_type_type_config($id);
$islti1p3 = $config->lti_ltiversion === LTI_VERSION_1P3;
$items = '';

if (!empty($jwt)) {
$params = lti_convert_from_jwt($id, $jwt);
$consumerkey = $params['oauth_consumer_key'] ?? '';
$messagetype = $params['lti_message_type'] ?? '';
$version = $params['lti_version'] ?? '';
$items = $params['content_items'] ?? '';
$errormsg = $params['lti_errormsg'] ?? '';
$msg = $params['lti_msg'] ?? '';
} else {
$consumerkey = required_param('oauth_consumer_key', PARAM_RAW);
$messagetype = required_param('lti_message_type', PARAM_TEXT);
$version = required_param('lti_version', PARAM_TEXT);
$items = optional_param('content_items', '', PARAM_RAW_TRIMMED);
$errormsg = optional_param('lti_errormsg', '', PARAM_TEXT);
$msg = optional_param('lti_msg', '', PARAM_TEXT);
}

$contentitems = json_decode($items);

$errors = [];

Expand All @@ -43,23 +67,55 @@
$errors[] = 'invalidjson';
}

// Get and validate frame and thumbnail sizes.
$framewidth = 720;
if (!empty($contentitems->{'@graph'}[0]->placementAdvice->displayWidth)) {
$framewidth = $contentitems->{'@graph'}[0]->placementAdvice->displayWidth;
$fwidth = $contentitems->{'@graph'}[0]->placementAdvice->displayWidth;
if (!empty($fwidth)) {
$framewidth = is_numeric($fwidth) ? $fwidth : $framewidth;
}

$frameheight = 480;
if (!empty($contentitems->{'@graph'}[0]->placementAdvice->displayHeight)) {
$frameheight = $contentitems->{'@graph'}[0]->placementAdvice->displayHeight;
$fheight = $contentitems->{'@graph'}[0]->placementAdvice->displayHeight;
if (!empty($fheight)) {
$frameheight = is_numeric($fheight) ? $fheight : $frameheight;
}

$thumbnailwidth = 128;
if (!empty($contentitems->{'@graph'}[0]->thumbnail->width)) {
$thumbnailwidth = $contentitems->{'@graph'}[0]->thumbnail->width;
$twidth = $contentitems->{'@graph'}[0]->thumbnail->width;
if (!empty($twidth)) {
$thumbnailwidth = is_numeric($twidth) ? $twidth : $thumbnailwidth;
}

$thumbnailheight = 72;
if (!empty($contentitems->{'@graph'}[0]->thumbnail->height)) {
$thumbnailheight = $contentitems->{'@graph'}[0]->thumbnail->height;
$theight = $contentitems->{'@graph'}[0]->thumbnail->height;
if (!empty($theight)) {
$thumbnailheight = is_numeric($theight) ? $theight : $thumbnailheight;
}

$title = "";
$itemtitle = $contentitems->{'@graph'}[0]->title;
if (!empty($itemtitle)) {
$invalidcharacters = array("$", "%", "#", "<", ">");
$cleantitle = str_replace($invalidcharacters, "", $itemtitle);
$title = is_string($cleantitle) ? $cleantitle : $title;
}

$url = "";
$contenturl = $contentitems->{'@graph'}[0]->url;
if (!empty($contenturl)) {
$panoptodata = new \panopto_data($courseid);
$baseurl = parse_url($contenturl, PHP_URL_HOST);
if (strcmp($panoptodata->servername, $baseurl) === 0) {
$url = $contenturl;
}
}

$thumbnailurl = "";
$thumbnailurlfinal = !empty($contentitems->{'@graph'}[0]->thumbnail->id)
? $contentitems->{'@graph'}[0]->thumbnail->id
: $contentitems->{'@graph'}[0]->thumbnail->{'@id'};
if (!empty($thumbnailurlfinal)) {
$thumbnailurl = is_string($thumbnailurlfinal) ? $thumbnailurlfinal : $thumbnailurl;
}

$customdata = $contentitems->{'@graph'}[0]->custom;
Expand All @@ -78,22 +134,21 @@
var sessionSelectedEvent;
var detailObject = {
'detail': {
'title': "<?php echo $contentitems->{'@graph'}[0]->title ?>",
'title': "<?php echo $title ?>",
'ltiViewerUrl': "<?php echo $ltiviewerurl->out(false) ?>",
'contentUrl': "<?php echo $contentitems->{'@graph'}[0]->url ?>",
'contentUrl': "<?php echo $url ?>",
'customData': "<?php echo urlencode(json_encode($customdata)) ?>",
'width': <?php echo $framewidth ?>,
'height': <?php echo $frameheight ?>,
'thumbnailUrl': "<?php echo $contentitems->{'@graph'}[0]->thumbnail->id ?>",
'thumbnailUrl': "<?php echo $thumbnailurlfinal ?>",
'thumbnailWidth': <?php echo $thumbnailwidth ?>,
'thumbnailHeight': <?php echo $thumbnailheight ?>,
}
};

if(typeof window.CustomEvent === 'function') {
if (typeof window.CustomEvent === 'function') {
sessionSelectedEvent = new CustomEvent('sessionSelected', detailObject);
}
else {
} else {
// ie >= 9
sessionSelectedEvent = document.createEvent('CustomEvent');
sessionSelectedEvent.initCustomEvent('sessionSelected', false, false, detailObject);
Expand Down
Loading

0 comments on commit 0698c2b

Please sign in to comment.