Skip to content

Commit

Permalink
Merge pull request #52 from odeialba/SV-26
Browse files Browse the repository at this point in the history
SV-26 Set up the plugin to work on the mobile app
  • Loading branch information
odeialba authored Jan 30, 2024
2 parents 995b128 + 8f0d491 commit 0921b6e
Show file tree
Hide file tree
Showing 12 changed files with 521 additions and 4 deletions.
1 change: 1 addition & 0 deletions .github/workflows/moodle-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ jobs:
env:
DB: ${{ matrix.database }}
MOODLE_BRANCH: ${{ matrix.moodle-branch }}
MUSTACHE_IGNORE_NAMES: 'mobile*.mustache'

- name: PHP Lint
if: ${{ always() }}
Expand Down
118 changes: 118 additions & 0 deletions classes/output/mobile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php
// This file is part of the mod_sortvoting plugin for Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

namespace mod_sortvoting\output;
use context_module;

defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/mod/sortvoting/lib.php');

/**
* Class mobile
*
* @package mod_sortvoting
* @copyright 2024 Odei Alba <odeialba@odeialba.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class mobile {
/**
* Returns the javascript needed to initialize SortVoting in the app.
*
* @param array $args Arguments from tool_mobile_get_content WS
* @return array javascript
*/
public static function mobile_init($args) {
global $CFG;

return [
'templates' => [],
'javascript' => file_get_contents($CFG->dirroot . "/mod/sortvoting/mobile/js/init.js"),
];
}

/**
* Returns the SortVoting form view for the mobile app.
*
* @param mixed $args
* @return array HTML, javascript and other data.
*/
public static function mobile_sort_voting_view($args): array {
global $OUTPUT, $DB, $CFG;
$args = (object) $args;

$cm = get_coursemodule_from_id('sortvoting', $args->cmid);
$sortvotingid = $cm->instance;
$userid = $args->userid;

$sortvoting = $DB->get_record("sortvoting", ["id" => $sortvotingid]);
$options = $DB->get_records('sortvoting_options', ['sortvotingid' => $sortvotingid], 'id ASC');
$existingvotes = $DB->get_records_menu(
'sortvoting_answers',
[
'sortvotingid' => $sortvotingid,
'userid' => $userid,
],
'id ASC',
'optionid, position'
);

$allowupdate = true;
if (!$sortvoting->allowupdate && count($existingvotes) === count($options)) {
$allowupdate = false;
}

$defaultposition = (count($existingvotes) > 0) ? (count($existingvotes) + 1) : 1;
$optionsclean = [];
foreach ($options as $option) {
$position = isset($existingvotes[$option->id]) ? $existingvotes[$option->id] : $defaultposition++;
$optionsclean[] = [
'id' => $option->id,
'text' => $option->text,
'position' => $position,
];
}

// Sort $optionsclean by position.
usort($optionsclean, function ($a, $b) {
return $a['position'] <=> $b['position'];
});

$canseeresults = \mod_sortvoting\permission::can_see_results($sortvoting, context_module::instance($cm->id));

// Result of existing votes.
$existingvotes = $canseeresults ? sortvoting_get_response_data($sortvoting) : [];

$data = [
'description' => html_to_text($sortvoting->intro),
'allowupdate' => $allowupdate,
'options' => $optionsclean,
'max' => count($options),
'canseeresults' => $canseeresults,
'votes' => $existingvotes,
];

return [
'templates' => [
[
'id' => 'main',
'html' => $OUTPUT->render_from_template('mod_sortvoting/mobile_sort_voting_view', $data),
],
],
'javascript' => file_get_contents($CFG->dirroot . "/mod/sortvoting/mobile/js/mobile_sortvoting.js"),
'otherdata' => '',
];
}
}
2 changes: 1 addition & 1 deletion classes/output/sort_voting_results.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public function __construct(\stdClass $sortvoting) {
*/
public function export_for_template(renderer_base $output): array {
$existingvotes = sortvoting_get_response_data($this->sortvoting);
$maxvotescount = (int) max(array_column($existingvotes, 'votescount'));
$maxvotescount = empty($existingvotes) ? 0 : (int) max(array_column($existingvotes, 'votescount'));

return ['votes' => $existingvotes, 'maxvotescount' => $maxvotescount];
}
Expand Down
54 changes: 54 additions & 0 deletions db/mobile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php
// This file is part of the mod_sortvoting plugin for Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Mobile app areas for Preference Sort Voting
*
* @package mod_sortvoting
* @copyright 2024 Odei Alba <odeialba@odeialba.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

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

$addons = [
'mod_sortvoting' => [
"handlers" => [ // Different places where the add-on will display content.
'coursesortvotingview' => [ // Handler unique name (can be anything).
'displaydata' => [
'title' => 'pluginname',
'icon' => $CFG->wwwroot . '/mod/sortvoting/pix/monologo.png',
'class' => '',
],
'delegate' => 'CoreCourseModuleDelegate', // Delegate (where to display the link to the add-on).
'method' => 'mobile_sort_voting_view', // Main function in \mod_sortvoting\output\mobile.
'init' => 'mobile_init',
'styles' => [
'url' => $CFG->wwwroot . '/mod/sortvoting/style/mobile.css',
'version' => '0.1',
],
],
],
'lang' => [
['pluginname', 'mod_sortvoting'],
['instructions', 'mod_sortvoting'],
['votesuccess', 'mod_sortvoting'],
['position', 'mod_sortvoting'],
['option', 'mod_sortvoting'],
['save', 'core'],
],
],
];
1 change: 1 addition & 0 deletions db/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@
'type' => 'write',
'capabilities' => 'mod/sortvoting:vote',
'ajax' => true,
'services' => [MOODLE_OFFICIAL_MOBILE_SERVICE, 'local_mobile'],
],
];
2 changes: 1 addition & 1 deletion lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ function sortvoting_get_response_data(stdClass $sortvoting, bool $onlyactive = t

$position = 1;
$previousvote = null;
$maxvotescount = (int) max(array_column($existingvotes, 'votescount'));
$maxvotescount = empty($existingvotes) ? 0 : (int) max(array_column($existingvotes, 'votescount'));
foreach ($existingvotes as $key => $vote) {
if ($previousvote !== null && $previousvote->avg !== $vote->avg) {
$position++;
Expand Down
86 changes: 86 additions & 0 deletions mobile/js/init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// This file is part of the mod_sortvoting plugin for Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* AMD module used when saving a new sort voting on mobile.
*
* @copyright 2024 Odei Alba <odeialba@odeialba.com>
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

const context = this;

/**
* Class to handle sort votings.
*/
class AddonModSortVotingProvider {
/**
* Send the responses to a sort voting.
*
* @param sortvotingid Sort voting ID to submit.
* @param votes The responses to send.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with boolean: true if responses sent to server, false and rejected if failure.
*/
submitResponses(sortvotingid, votes, siteId) {
siteId = siteId || context.CoreSitesProvider.getCurrentSiteId();

// TODO: Add offline option.
// Now try to delete the responses in the server.
return this.submitResponsesOnline(sortvotingid, votes, siteId).then(() => {
return true;
}).catch((error) => {
// The WebService has thrown an error, this means that responses cannot be submitted.
return Promise.reject(error);
});
}

/**
* Send responses from a sort voting to Moodle. It will fail if offline or cannot connect.
*
* @param sortvotingid Sort voting ID to submit.
* @param votes The responses to send.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved if deleted, rejected if failure.
*/
submitResponsesOnline(sortvotingid, votes, siteId) {
return context.CoreSitesProvider.getSite(siteId).then((site) => {
var params = {
sortvotingid: sortvotingid,
votes: votes
};

return site.write('mod_sortvoting_save_vote', params).then((response) => {
if (!response || response.success === false) {
// TODO: Add warnings array to save_vote returns.
// Couldn't save the responses. Reject the promise.
var error = response && response.warnings && response.warnings[0] ?
response.warnings[0] : new context.CoreError('');

return Promise.reject(error);
}
});
});
}

}

const sortVotingProvider = new AddonModSortVotingProvider();

const result = {
sortVotingProvider: sortVotingProvider,
};

result;
Loading

0 comments on commit 0921b6e

Please sign in to comment.