Skip to content

Commit

Permalink
Issue 73: Transform old MNet assignments into new web services assign…
Browse files Browse the repository at this point in the history
…ment
  • Loading branch information
Sasha Anastasi committed Aug 29, 2024
1 parent 69ac1a6 commit 2f0fef0
Show file tree
Hide file tree
Showing 5 changed files with 348 additions and 1 deletion.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,24 @@ If you need help, try the [Moodle-Mahara Integration forum](https://mahara.org/i

Submitting of group portfolios is not yet supported.

Convert MNet submissions
------------------------

To manually run the upgrade step which converts applicable submissions from [the original MNet plugin](https://github.com/MaharaProject/moodle-assignsubmission_mahara):

1. for each Mahara instance you wish to convert submissions from:
1. apply the patch (maharaws.patch).
2. ensure a functional LTI connection exists between the instance and your Moodle site.
2. if using multiple Mahara endpoints:
1. uncheck the assignsubmission_maharaws config setting _force_global_credentials_
2. clear the global credential fields (url, key, secret).
3. for each course assignment whose submissions you wish to convert:
1. disable _Mahara portfolio_ submission type.
2. enable _Mahara_ submission type and input the relevant LTI credentials.
3. uncomment version **2024081601** in version.php
4. uncomment the version **2024081601** upgrade step in db/upgrade.php
5. run the Moodle site upgrade

Bugs and improvements?
------------------------

Expand Down
145 changes: 145 additions & 0 deletions db/upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,5 +209,150 @@ function xmldb_assignsubmission_maharaws_upgrade($oldversion) {
upgrade_plugin_savepoint(true, 2021081800, 'assignsubmission', 'maharaws');
}

// Uncomment this upgrade step to convert records from assignsubmission_mahara to assignsubmission_maharaws
/*
if ($oldversion < 2024081601) {
$assign = new assign(null, null, null);
$wsplugin = $assign->get_submission_plugin_by_type('maharaws');
$data = [];
$records = $DB->get_records('assignsubmission_mahara');
if (!empty(get_config('assignsubmission_maharaws', 'force_global_credentials'))) {
// if force globals, proceed with whole table.
$data = $wsplugin->run_get_views_by_id($data, $records);
} else {
set_config('force_global_credentials', '1', 'assignsubmission_maharaws');
// if globals available, save in a variable
$globals = [];
foreach (['url','key','secret'] as $config) {
if (isset($globals)) {
if ($result = get_config('assignsubmission_maharaws', $config)) {
$globals[$config] = trim($result);
} else {
unset($globals);
}
}
}
// arrange table records in assignment clusters
$assignments = [];
foreach ($records as $record) {
$assignments[$record->assignment][] = (object)[
'id' => $record->id,
'viewid' => $record->viewid,
'iscollection' => $record->iscollection
];
}
foreach ($assignments as $assid => $assignment) {
// get maharaws config for this assignment
$locals = true;
$dbparams = [
'assignment' => $assid,
'plugin' => 'maharaws',
'subtype' => 'assignsubmission'
];
if ($result = $DB->get_records('assign_plugin_config', $dbparams)) {
$resultarray = [];
foreach($result as $resultitem) {
$resultarray[$resultitem->name] = trim($resultitem->value);
}
if (empty($resultarray['enabled'])) {
mtrace("assignsubmission_maharaws disabled for assignment {$assid}: skipping");
$records = array_filter($records, function($a) use($assid) {
return $a->assignment != $assid;
});
continue;
}
foreach (['url','key','secret'] as $config) {
if (empty($resultarray[$config])) {
unset($locals);
}
}
} else {
unset($locals);
}
if (isset($locals)) {
foreach (['url','key','secret'] as $config) {
set_config($config, $resultarray[$config], 'assignsubmission_maharaws');
}
$data = $wsplugin->run_get_views_by_id($data, $assignment);
foreach (['url','key','secret'] as $config) {
if (!empty($globals)) {
set_config($config, $globals[$config], 'assignsubmission_maharaws');
} else {
unset_config($config, 'assignsubmission_maharaws');
}
}
} elseif (isset($globals)) {
$data = $wsplugin->run_get_views_by_id($data, $assignment);
} else {
mtrace("no maharaws endpoint configured for assignment {$assid}: skipping");
$records = array_filter($records, function($a) use($assid) {
return $a->assignment != $assid;
});
continue;
}
}
set_config('force_global_credentials', '0', 'assignsubmission_maharaws');
}
foreach ($records as $record) {
$dataitem = $data[$record->id];
$todb = new \stdClass();
$todb->assignment = $record->assignment;
$todb->submission = $record->submission;
$todb->viewid = $record->viewid;
$todb->viewurl = '';
$todb->viewtitle = $record->viewtitle;
$todb->iscollection = $record->iscollection;
$status = $record->viewstatus;
if ($status == assign_submission_mahara::STATUS_RELEASED ||
$status == assign_submission_mahara::STATUS_SELECTED ||
$status == assign_submission_mahara::STATUS_SUBMITTED) {
$todb->viewstatus = $status;
}
if (!$todb->iscollection) {
if ($todb->viewstatus == assign_submission_mahara::STATUS_SELECTED) {
$urlstring = '/user/' . $dataitem['owner'] .'/'. $dataitem['urlid'];
$todb->viewurl = $dataitem['endpointurl'] . $urlstring;
} else {
$todb->viewurl = '/view/view.php?id=' . $todb->viewid;
}
} else {
switch ($dataitem['complexity']) {
case 0:
//simple collection
if ($todb->viewstatus == assign_submission_mahara::STATUS_SELECTED) {
$urlstring = '/view/view.php?id=' . $dataitem['viewid'];
$todb->viewurl = $dataitem['endpointurl'] . $urlstring;
} else {
$todb->viewurl = '/view/view.php?id=' . $dataitem['viewid'];
}
break;
case 1:
//progresscompletion
if ($todb->viewstatus == assign_submission_mahara::STATUS_SELECTED) {
$urlstring = '/collection/progresscompletion.php?id=' . $todb->viewid;
$todb->viewurl = $dataitem['endpointurl'] . $urlstring;
} else {
$todb->viewurl = '/collection/progresscompletion.php?id=' . $todb->viewid;
}
break;
case 2:
//smartevidence
if ($todb->viewstatus == assign_submission_mahara::STATUS_SELECTED) {
$urlstring = '/module/framework/matrix.php?id=' . $todb->viewid;
$todb->viewurl = $dataitem['endpointurl'] . $urlstring;
} else {
$todb->viewurl = '/module/framework/matrix.php?id=' . $todb->viewid;
}
break;
}
}
$currid = $DB->insert_record('assignsubmission_maharaws', $todb);
mtrace($currid);
}
// Mahara savepoint reached.
upgrade_plugin_savepoint(true, 2024081601, 'assignsubmission', 'maharaws');
}
*/

return true;
}
29 changes: 29 additions & 0 deletions locallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -1330,4 +1330,33 @@ public function get_config_default($config) {
}
return false;
}

/**
* Helper function to call webservice function with specified parameters.
*
* @param array $data
* @param array $records
* @return array
*/
function run_get_views_by_id(array $data, array $records): array {
$items = [];
foreach ($records as $record) {
$items[] = [
'id' => $record->id,
'viewid' => $record->viewid,
'iscollection' => $record->iscollection
];
}
try{
$returned = $this->webservice_call("mahara_submission_get_views_by_id", ['items' => $items]);
} catch (Exception $e) {
throw new moodle_exception('errorwsrequest', 'assignsubmission_maharaws', '', $e->getMessage());
}
$returned['ids'] = array_map('intval', explode(',', $returned['ids']));
for ($i = 0; $i<count($returned['ids']); $i++) {
$data[$returned['ids'][$i]] = $returned['data'][$i];
$data[$returned['ids'][$i]]['endpointurl'] = trim(get_config('assignsubmission_maharaws', 'url'));
}
return $data;
}
}
153 changes: 153 additions & 0 deletions maharaws.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
diff --git a/htdocs/auth/webservice/version.php b/htdocs/auth/webservice/version.php
index daf3fb64dd..cbc02e0765 100644
--- a/htdocs/auth/webservice/version.php
+++ b/htdocs/auth/webservice/version.php
@@ -12,7 +12,7 @@
defined('INTERNAL') || die();

$config = new stdClass();
-$config->version = 2021121600;
+$config->version = 2024081600;
$config->release = '2.0.7';
$config->requires_config = 0;
$config->requires_parent = 0;
diff --git a/htdocs/module/lti/webservice/services.php b/htdocs/module/lti/webservice/services.php
index d2940470b0..109c948825 100644
--- a/htdocs/module/lti/webservice/services.php
+++ b/htdocs/module/lti/webservice/services.php
@@ -30,6 +30,7 @@ $services = array(
'functions' => [
'mahara_user_get_extended_context',
'mahara_submission_get_views_for_user',
+ 'mahara_submission_get_views_by_id',
'mahara_submission_submit_view_for_assessment',
'mahara_submission_release_submitted_view',
'module_lti_launch',
diff --git a/htdocs/webservice/functions/mahara_view_external.php b/htdocs/webservice/functions/mahara_view_external.php
index fc146d48cc..57bb1cfea2 100644
--- a/htdocs/webservice/functions/mahara_view_external.php
+++ b/htdocs/webservice/functions/mahara_view_external.php
@@ -910,4 +910,104 @@ class mahara_view_external extends external_api {
)
);
}
+
+ /**
+ * Webservice parameter definition for input of get_views_by_id method
+ *
+ * Returns description of method parameters
+ *
+ * @return external_function_parameters
+ */
+ public static function get_views_by_id_parameters() {
+ return new external_function_parameters([
+ 'items' => new external_multiple_structure(
+ new external_single_structure([
+ 'id' => new external_value(PARAM_INT, get_string('viewid', WEBSERVICE_LANG)),
+ 'viewid' => new external_value(PARAM_NUMBER, get_string('viewid', WEBSERVICE_LANG)),
+ 'iscollection' => new external_value(PARAM_BOOL, get_string('iscollection', WEBSERVICE_LANG))
+ ])
+ )
+ ]);
+ }
+
+ /**
+ * Webservice parameter definition for output of get_views_by_id method
+ *
+ * Returns description of method result value
+ *
+ * @return external_description
+ */
+ public static function get_views_by_id_returns() {
+ return new external_single_structure([
+ 'ids' => new external_value(PARAM_TEXT, 'comma-delimited list with ids of the submission record in the LMS'),
+ 'data' => new external_multiple_structure(
+ new external_single_structure([
+ 'owner' => new external_value(PARAM_TEXT, get_string('portfolioownerusername', WEBSERVICE_LANG)),
+ 'urlid' => new external_value(PARAM_TEXT, get_string('viewurldescription', 'view')),
+ 'complexity' => new external_value(PARAM_NUMBER, '0:coll-simple;1:coll-progress;2:coll-framework;3:view'),
+ 'viewid' => new external_value(PARAM_NUMBER, get_string('viewid', WEBSERVICE_LANG))
+ ])
+ )
+ ]);
+ }
+
+ /**
+ * Get portfolio pages or collections by id
+ *
+ * @param array $items array of view or collection ids
+ * @return array An array of arrays describing views and collections
+ */
+ public static function get_views_by_id($items) {
+ $params = self::validate_parameters(self::get_views_by_id_parameters(), ['items' => $items]);
+ $returned = [
+ 'ids' => '',
+ 'data' => []
+ ];
+ if (empty($params['items'])) {
+ return $returned;
+ }
+ foreach ($params['items'] as $item) {
+ $viewid = $item['viewid'];
+ if (empty($viewid)) {
+ log_debug("{$item['id']} is missing viewid: skipping");
+ continue;
+ }
+ $owner = null;
+ $urlid = null;
+ $complexity = 0;
+ if (!empty($item['iscollection'])) {
+ log_debug("{$item['id']} is a collection");
+ require_once('collection.php');
+ $collection = new Collection($viewid);
+
+ $owner = '';
+ $urlid = '';
+ $complexity += $collection->get('progresscompletion') ? 1 : 0;
+ $complexity += $collection->get('framework') ? 2 : 0;
+ $viewid = current($collection->get_viewids());
+ } else {
+ log_debug("{$item['id']} is a view");
+ require_once('view.php');
+ $view = new View($viewid);
+
+ $viewid = 0;
+ $owner = $view->get_owner_object()->get('username');
+ $urlid = $view->get('urlid');
+ $complexity = 3;
+ }
+ $data = array(
+ 'viewid' => $viewid,
+ 'owner' => $owner,
+ 'urlid' => $urlid,
+ 'complexity' => $complexity
+ );
+ if(!empty($returned['ids'])) {
+ $returned['ids'] .= ',';
+ }
+ $returned['ids'] .= $item['id'];
+ $returned['data'][]= $data;
+ }
+ log_debug('get_views_by_id Results: '.var_export($returned, true));
+ return $returned;
+ }
}
diff --git a/htdocs/webservice/services.php b/htdocs/webservice/services.php
index 785f6d0a52..e1c70864fb 100644
--- a/htdocs/webservice/services.php
+++ b/htdocs/webservice/services.php
@@ -248,6 +248,14 @@ $functions = array(
'type' => 'read',
),

+ 'mahara_submission_get_views_by_id' => array(
+ 'classname' => 'mahara_view_external',
+ 'methodname' => 'get_views_by_id',
+ 'classpath' => WEBSERVICE_DIRECTORY,
+ 'description' => 'Get views and collections by id',
+ 'type' => 'read',
+ ),
+
'mahara_submission_submit_view_for_assessment' => array(
'classname' => 'mahara_view_external',
'methodname' => 'submit_view_for_assessment',
4 changes: 3 additions & 1 deletion version.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@

defined('MOODLE_INTERNAL') || die();

$plugin->version = 2023110900;
$plugin->version = 2024081600;
//replace version with the below to run the mnet import
//$plugin->version = 2024081601;
$plugin->release = 2023110900;
$plugin->requires = 2020061500;
$plugin->component = 'assignsubmission_maharaws';
Expand Down

0 comments on commit 2f0fef0

Please sign in to comment.