├── pix ├── .DS_Store ├── rank_list.svg ├── help_progress_level.svg ├── reset.svg ├── a0.svg ├── rank_group_list.svg ├── help.svg ├── a52.svg ├── info.svg ├── icon.svg ├── level.svg ├── lv0.svg ├── a49.svg ├── lv4.svg ├── lv1.svg ├── lv7.svg ├── lv13.svg ├── lv14.svg ├── lv15.svg ├── lv11.svg ├── a9.svg ├── lv2.svg ├── lv5.svg ├── badgex.svg ├── lv12.svg ├── lv9.svg ├── lv10.svg ├── lv6.svg ├── lv3.svg ├── lv8.svg ├── a11.svg ├── a35.svg ├── a47.svg ├── a29.svg ├── a26.svg ├── a1.svg ├── a8.svg ├── rank.svg ├── a18.svg ├── a68.svg ├── a50.svg ├── a58.svg ├── a33.svg ├── a30.svg ├── a19.svg ├── a62.svg ├── a42.svg └── a31.svg ├── version.php ├── db ├── tasks.php ├── access.php ├── install.xml └── upgrade.php ├── classes ├── output │ ├── renderer.php │ └── rankgroup.php └── task │ └── cleargame.php ├── perfil_gamer.php ├── rank_group_game.php ├── help_game.php ├── download.php ├── CHANGES.md ├── templates ├── rankgroup.mustache ├── help.mustache └── rank.mustache ├── .travis.yml ├── rank_game.php ├── README.md ├── reset_points_course.php ├── block_game.php └── settings.php /pix/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JotaDF/moodle-block_game/HEAD/pix/.DS_Store -------------------------------------------------------------------------------- /pix/rank_list.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pix/help_progress_level.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 72.3% 11 | 12 | 13 | -------------------------------------------------------------------------------- /pix/reset.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /version.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Game block version identification 19 | * 20 | * @package block_game 21 | * @copyright 2019 Jose Wilson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die(); 26 | 27 | $plugin->version = 2025102202; 28 | $plugin->requires = 2023042400; 29 | $plugin->maturity = MATURITY_STABLE; 30 | $plugin->release = '2.0 Version for Moodle 5.0 onwards'; 31 | $plugin->component = 'block_game'; 32 | -------------------------------------------------------------------------------- /db/tasks.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Block Game config form definition class 19 | * 20 | * @package block_game 21 | * @copyright 2019 Jose Wilson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die(); 26 | 27 | $tasks = [ 28 | [ 29 | 'classname' => 'block_game\task\cleargame', 30 | 'blocking' => 0, 31 | 'minute' => '30', 32 | 'hour' => '*', 33 | 'day' => '*', 34 | 'month' => '*', 35 | 'dayofweek' => '*', 36 | ], 37 | ]; 38 | -------------------------------------------------------------------------------- /pix/a0.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 14 | 15 | -------------------------------------------------------------------------------- /pix/rank_group_list.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 25 | 26 | 27 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /db/access.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Block Game capabilities definition 19 | * 20 | * @package block_game 21 | * @copyright 2019 Jose Wilson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | defined('MOODLE_INTERNAL') || die(); 26 | 27 | $capabilities = [ 28 | 'block/game:myaddinstance' => [ 29 | 'captype' => 'write', 30 | 'contextlevel' => CONTEXT_SYSTEM, 31 | 'archetypes' => [ 32 | 'user' => CAP_ALLOW, 33 | ], 34 | 'clonepermissionsfrom' => 'moodle/my:manageblocks', 35 | ], 36 | 'block/game:addinstance' => [ 37 | 'riskbitmask' => RISK_SPAM | RISK_XSS, 38 | 'captype' => 'write', 39 | 'contextlevel' => CONTEXT_BLOCK, 40 | 'archetypes' => [ 41 | 'editingteacher' => CAP_ALLOW, 42 | 'manager' => CAP_ALLOW, 43 | ], 44 | 'clonepermissionsfrom' => 'moodle/site:manageblocks', 45 | ], 46 | ]; 47 | -------------------------------------------------------------------------------- /classes/output/renderer.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Game block renderer. 19 | * 20 | * @package block_game 21 | * @copyright 2018 Willian Mano http://conecti.me 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace block_game\output; 26 | 27 | use plugin_renderer_base; 28 | use renderable; 29 | 30 | /** 31 | * Ranking block renderer. 32 | * 33 | * @package block_game 34 | * @copyright 2020 Willian Mano http://conecti.me 35 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 36 | */ 37 | class renderer extends plugin_renderer_base { 38 | /** 39 | * Defer the block instance in course to template. 40 | * 41 | * @param renderable $page 42 | * 43 | * @return bool|string 44 | * 45 | * @throws \moodle_exception 46 | */ 47 | public function render_block(renderable $page) { 48 | $data = $page->export_for_template($this); 49 | 50 | return parent::render_from_template('block_game/block', $data); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /pix/help.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /classes/task/cleargame.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Block Game config task definition class 19 | * 20 | * @package block_game 21 | * @copyright 2019 Jose Wilson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | namespace block_game\task; 25 | 26 | /** 27 | * Task to clear course deleted game 28 | * 29 | * @package block_game 30 | * @copyright 2019 Jose Wilson 31 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 32 | */ 33 | class cleargame extends \core\task\scheduled_task { 34 | /** 35 | * Task to clear deleted users and courses from the block game. 36 | * 37 | * @return string 38 | * 39 | * @throws \coding_exception 40 | */ 41 | public function get_name() { 42 | return get_string('cleargametask', 'block_game'); 43 | } 44 | 45 | /** 46 | * Execute the task. 47 | */ 48 | public function execute() { 49 | global $CFG; 50 | require_once($CFG->dirroot . '/blocks/game/lib.php'); 51 | block_game_clear_course_deleted_game(); 52 | block_game_clear_user_deleted_game(); 53 | return true; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /pix/a52.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /perfil_gamer.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Profile view 19 | * 20 | * @package block_game 21 | * @copyright 2019 Jose Wilson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | require_once(dirname(__FILE__) . '/../../config.php'); 26 | require_once($CFG->dirroot . '/blocks/game/lib.php'); 27 | require_once($CFG->libdir . '/completionlib.php'); 28 | require_once($CFG->libdir . '/filelib.php'); 29 | require_once($CFG->libdir . '/badgeslib.php'); 30 | 31 | global $USER, $COURSE, $OUTPUT, $CFG; 32 | 33 | $courseid = required_param('id', PARAM_INT); 34 | $course = $DB->get_record('course', ['id' => $courseid], '*', MUST_EXIST); 35 | 36 | require_login($course); 37 | 38 | $PAGE->set_pagelayout('course'); 39 | $PAGE->set_url('/blocks/game/perfil_gamer.php', ['id' => $courseid]); 40 | $PAGE->set_context(context_course::instance($courseid)); 41 | $PAGE->set_title(get_string('perfil_gamer_title', 'block_game')); 42 | $PAGE->set_heading(get_string('perfil_gamer_title', 'block_game')); 43 | 44 | echo $OUTPUT->header(); 45 | if ($courseid == SITEID) { 46 | $renderer = $PAGE->get_renderer('block_game'); 47 | 48 | $contentrenderable = new \block_game\output\profile($USER, $courseid); 49 | 50 | echo $renderer->render($contentrenderable); 51 | } else { 52 | $renderer = $PAGE->get_renderer('block_game'); 53 | 54 | $contentrenderable = new \block_game\output\profilecourse($USER, $courseid); 55 | 56 | echo $renderer->render($contentrenderable); 57 | } 58 | echo $OUTPUT->footer(); 59 | -------------------------------------------------------------------------------- /rank_group_game.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Rank Group view 19 | * 20 | * @package block_game 21 | * @copyright 2019 Jose Wilson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | require_once(dirname(__FILE__) . '/../../config.php'); 26 | require_once($CFG->dirroot . '/blocks/game/lib.php'); 27 | require_once($CFG->libdir . '/filelib.php'); 28 | 29 | require_login(); 30 | 31 | global $USER, $COURSE, $OUTPUT, $CFG; 32 | 33 | $courseid = required_param('id', PARAM_INT); 34 | 35 | $course = $DB->get_record('course', ['id' => $courseid], '*', MUST_EXIST); 36 | 37 | require_login($course); 38 | $PAGE->set_pagelayout('course'); 39 | $PAGE->set_url('/blocks/game/rank_game.php', ['id' => $courseid]); 40 | $PAGE->set_context(context_course::instance($courseid)); 41 | $PAGE->set_title(get_string('rank_group_game_title', 'block_game')); 42 | $PAGE->set_heading(get_string('rank_group_game_title', 'block_game')); 43 | 44 | $cfggame = get_config('block_game'); 45 | $gameconfig = ($courseid == SITEID) ? $cfggame : block_game_get_config_block($courseid); 46 | echo $OUTPUT->header(); 47 | 48 | if (isset($gameconfig->show_rank) && $gameconfig->show_rank == 1) { 49 | $rankgrouppage = new \block_game\output\rankgroup($course, $gameconfig, $courseid == SITEID); 50 | echo $OUTPUT->render($rankgrouppage); 51 | } else { 52 | echo "..."; 53 | $context = context_course::instance($courseid, MUST_EXIST); 54 | if (has_capability('moodle/course:update', $context, $USER->id)) { 55 | echo get_string('not_initial_config_game', 'block_game'); 56 | } 57 | } 58 | echo $OUTPUT->footer(); 59 | -------------------------------------------------------------------------------- /pix/info.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 23 | 24 | -------------------------------------------------------------------------------- /pix/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 20 | 22 | 24 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /help_game.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Help page 19 | * 20 | * @package block_game 21 | * @copyright 2019 Jose Wilson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | require_once(dirname(__FILE__) . '/../../config.php'); 26 | require_once($CFG->dirroot . '/blocks/game/lib.php'); 27 | require_login(); 28 | 29 | global $USER, $COURSE, $OUTPUT, $CFG; 30 | 31 | 32 | $courseid = required_param('id', PARAM_INT); 33 | 34 | $course = $DB->get_record('course', ['id' => $courseid], '*', MUST_EXIST); 35 | 36 | require_login($course); 37 | $PAGE->set_pagelayout('course'); 38 | $PAGE->set_url('/blocks/game/help_game.php', ['id' => $courseid]); 39 | $PAGE->set_context(context_course::instance($courseid)); 40 | $PAGE->set_title(get_string('help_game_title', 'block_game')); 41 | $PAGE->set_heading(get_string('help_game_title', 'block_game')); 42 | 43 | $cfggame = get_config('block_game'); 44 | $isfrontpage = $courseid == SITEID; 45 | $gameconfig = $isfrontpage ? $cfggame : block_game_get_config_block($courseid); 46 | $notconfigured = !$isfrontpage && empty($gameconfig->show_info); 47 | $sections = !$isfrontpage ? block_game_get_sections_course($courseid) : []; 48 | 49 | echo $OUTPUT->header(); 50 | if (!$notconfigured) { 51 | $helppage = new \block_game\output\help($course, $gameconfig, $cfggame, $isfrontpage, $notconfigured, $sections); 52 | echo $OUTPUT->render($helppage); 53 | } else { 54 | echo "..."; 55 | $context = context_course::instance($courseid, MUST_EXIST); 56 | if (has_capability('moodle/course:update', $context, $USER->id)) { 57 | echo get_string('not_initial_config_game', 'block_game'); 58 | } 59 | } 60 | echo $OUTPUT->footer(); 61 | -------------------------------------------------------------------------------- /download.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Download page 19 | * 20 | * @package block_game 21 | * @copyright 2019 Jose Wilson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | require_once(dirname(__FILE__) . '/../../config.php'); 26 | require_once($CFG->dirroot . '/blocks/game/lib.php'); 27 | require_once($CFG->libdir . "/dataformatlib.php"); 28 | 29 | require_login(); 30 | 31 | $id = required_param('id', PARAM_INT); 32 | $op = optional_param('op', '', PARAM_ALPHA); 33 | $dataformat = optional_param('dataformat', '', PARAM_ALPHA); 34 | 35 | if ($op === "ranking") { 36 | $columns = [get_string('order', 'block_game'), 37 | get_string('name', 'block_game'), 38 | get_string('score_atv', 'block_game'), 39 | get_string('score_mod', 'block_game'), 40 | get_string('score_section', 'block_game'), 41 | get_string('score_bonus_day', 'block_game'), 42 | get_string('score_total', 'block_game')]; 43 | $rs = block_game_rank_list($id); 44 | $ord = 1; 45 | $rows = []; 46 | foreach ($rs as $gamer) { 47 | $ordtxt = $ord; 48 | $usertxt = $gamer->firstname . ' ' . $gamer->lastname; 49 | $scoreatv = $gamer->sum_score_activities; 50 | $scoremod = $gamer->sum_score_module_completed; 51 | $scoresection = $gamer->sum_score_section; 52 | $scorebonusday = $gamer->sum_score_bonus_day; 53 | $scoretxt = $gamer->pt; 54 | $rows[] = [$ordtxt, $usertxt, $scoreatv, $scoremod, 55 | $scoresection, $scorebonusday, $scoretxt]; 56 | 57 | $ord++; 58 | } 59 | 60 | download_as_dataformat('ranking', $dataformat, $columns, $rows); 61 | } 62 | -------------------------------------------------------------------------------- /pix/level.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 19 | 20 | 24 | 25 | 27 | 30 | 32 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /pix/lv0.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 19 | 20 | 24 | 25 | 27 | 30 | 32 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /pix/a49.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pix/lv4.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 21 | 22 | 24 | 27 | 29 | 31 | 32 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | moodle-block_game 2 | ======================== 3 | 4 | Changes 5 | ------- 6 | ### Changes Version 2.0 Version for Moodle 5.0 onwards 7 | 8 | * 2025-08-01 - Adaptations to support Moodle 5.0 9 | * 2025-08-04 - Correction in Group Ranking 10 | 11 | Changes 12 | ------- 13 | ### Changes Version 1.32 Version for Moodle 3.5 onwards 14 | 15 | * 2023-05-31 - Adaptations to support Moodle 4.1 16 | 17 | Changes 18 | ------- 19 | ### Changes Version 1.31 Version for Moodle 3.5 onwards 20 | 21 | * 2022-04-04 - **Score by badges issued by moodle** 22 | * 2022-04-04 - **Changing player profile layout** 23 | * 2022-04-04 - **increased from 12 to 15 levels** 24 | * 2022-11-10 - **configure the score for completion within the activity/resource form** 25 | * 2022-11-10 - Fix in function in lib 26 | 27 | ### Changes Version 1.30 Version for Moodle 3.5 onwards 28 | 29 | * 2021-06-14 - **Allow changing avatar images in plugin settings** 30 | * 2021-06-14 - **Allow changing images of levels in plugin settings** 31 | * 2021-06-14 - **Allow scoring completion of features/activities in block settings** 32 | * 2021-06-14 - Changes in the layout of the ranking list 33 | * 2021-06-14 - Update of the game help 34 | * 2021-07-20 - **Possibility of download the ranking list** 35 | * 2021-07-27 - **Fixed section completion with group restriction** 36 | * 2021-08-06 - **Task to clear deleted users and courses from the block game** 37 | 38 | ### Changes Version 1.20 Version for Moodle 3.5 onwards 39 | 40 | * 2021-05-12 - Check compatibility for Moodle 3.11, no functionality change 41 | * 2021-05-12 - Changes in the layout of the block 42 | * 2021-05-12 - Changes in the layout of the player's profile 43 | * 2021-05-12 - Changes in the layout of the ranking list 44 | * 2021-05-12 - **Reordering avatars by level of interest** 45 | * 2021-05-12 - Update of the game help 46 | * 2021-05-12 - Replacement of all images and .png format to .svg, 75% reduction in the size of the end of the plugin 47 | 48 | ### Changes Version 1.15 Version for Moodle 3.4 onwards (2021033031) 49 | 50 | * 2021-04-20 - Check compatibility for Moodle 3.10 51 | * 2021-04-20 - General configuration of the plugin 52 | * 2021-04-20 - Ranking by group 53 | * 2021-04-20 - Option to change the avatar within the course 54 | * 2021-04-20 - Scoring option when completing section activities 55 | * 2021-04-20 - Option to reset the game points in the course 56 | * 2021-04-20 - Changes in the layout of the block 57 | * 2021-04-20 - Bugfix: Incompatibility of the keyword "rank" with the database 58 | * 2021-04-25 - Bugfix: Missing sesskey check - CSRF vulnerability. 59 | 60 | ### Changes Version 1.13 for Moodle 3.2 onwards (2019112101) 61 | 62 | * 2020-07-08 - Change plugin version and release scheme to the scheme promoted by moodle.org, no functionality change 63 | * 2019-11-21 - Initial version 64 | -------------------------------------------------------------------------------- /pix/lv1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 21 | 22 | 24 | 27 | 29 | 31 | 32 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /pix/lv7.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 21 | 22 | 24 | 27 | 29 | 31 | 32 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /pix/lv13.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 21 | 22 | 24 | 27 | 29 | 30 | 31 | 33 | 3 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /pix/lv14.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 21 | 22 | 24 | 27 | 29 | 30 | 31 | 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /pix/lv15.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 21 | 22 | 24 | 27 | 29 | 30 | 31 | 33 | 5 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /templates/rankgroup.mustache: -------------------------------------------------------------------------------- 1 | {{! 2 | This file is part of Moodle - http://moodle.org/ 3 | 4 | Moodle is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Moodle is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Moodle. If not, see . 16 | }} 17 | {{! 18 | @template block_game/rankgroup 19 | 20 | This template renders the rank group. 21 | Example context (json): 22 | { 23 | "isfrontpage": false, 24 | "coursefullname": "Curso de História do Brasil", 25 | "notconfigured": false, 26 | "groups": [ 27 | { 28 | "ord": "1", 29 | "picture": "", 30 | "groupname": "Grupo Independência", 31 | "members": "8 alunos", 32 | "score": "320" 33 | }, 34 | { 35 | "ord": "2", 36 | "picture": "", 37 | "groupname": "Grupo Proclamação", 38 | "members": "10 alunos", 39 | "score": "295" 40 | }, 41 | { 42 | "ord": "3", 43 | "picture": "", 44 | "groupname": "Grupo Revolução", 45 | "members": "6 alunos", 46 | "score": "280" 47 | } 48 | ] 49 | } 50 | }} 51 |
52 |

53 | {{#isfrontpage}} 54 | {{#str}} general, block_game {{/str}} 55 | {{/isfrontpage}} 56 | {{^isfrontpage}} 57 | ({{coursefullname}}) 58 | {{/isfrontpage}} 59 |

60 |
61 | 62 | {{#notconfigured}} 63 |

{{#str}} not_initial_config_game, block_game {{/str}}

64 | {{/notconfigured}} 65 | 66 | {{^notconfigured}} 67 | 68 | {{#groups}} 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | {{/groups}} 77 |
{{ord}}º{{{picture}}}{{groupname}} ({{members}}){{score}}{{#str}} abbreviate_score, block_game {{/str}}

78 | {{/notconfigured}} 79 |
80 | -------------------------------------------------------------------------------- /pix/lv11.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 21 | 22 | 24 | 27 | 29 | 31 | 32 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | os: linux 4 | dist: xenial 5 | sudo: false 6 | 7 | services: 8 | - mysql 9 | - postgresql 10 | - docker 11 | 12 | cache: 13 | directories: 14 | - $HOME/.composer/cache 15 | - $HOME/.npm 16 | - $HOME/.nvm 17 | 18 | jobs: 19 | include: 20 | - php: 7.4 21 | env: MOODLE_BRANCH=master DB=pgsql 22 | - php: 7.4 23 | env: MOODLE_BRANCH=master DB=mysqli 24 | - php: 7.4 25 | env: MOODLE_BRANCH=MOODLE_310_STABLE DB=pgsql 26 | - php: 7.4 27 | env: MOODLE_BRANCH=MOODLE_39_STABLE DB=mysqli 28 | - php: 7.4 29 | env: MOODLE_BRANCH=MOODLE_38_STABLE DB=pgsql 30 | 31 | - php: 7.3 32 | env: MOODLE_BRANCH=master DB=pgsql 33 | - php: 7.3 34 | env: MOODLE_BRANCH=master DB=mysqli 35 | - php: 7.3 36 | env: MOODLE_BRANCH=MOODLE_37_STABLE DB=pgsql 37 | - php: 7.3 38 | env: MOODLE_BRANCH=MOODLE_36_STABLE DB=mysqli 39 | 40 | - php: 7.2 41 | env: MOODLE_BRANCH=MOODLE_310_STABLE DB=pgsql 42 | - php: 7.2 43 | env: MOODLE_BRANCH=MOODLE_39_STABLE DB=mysqli 44 | - php: 7.2 45 | env: MOODLE_BRANCH=MOODLE_35_STABLE DB=pgsql 46 | 47 | - php: 7.1 48 | env: MOODLE_BRANCH=MOODLE_38_STABLE DB=pgsql 49 | - php: 7.1 50 | env: MOODLE_BRANCH=MOODLE_37_STABLE DB=mysqli 51 | - php: 7.0 52 | env: MOODLE_BRANCH=MOODLE_34_STABLE DB=mysqli 53 | - php: 7.0 54 | env: MOODLE_BRANCH=MOODLE_34_STABLE DB=pgsql 55 | 56 | # Cannot test with Moodle 3.2 and 3.3 any more because the new composer 2 57 | # does require all components to be named properly (case-sensitively) and 58 | # those branches have phpunit/Dbunit, failing. See MDL-64725. 59 | 60 | # Cannot test with PHP 7.0 any more because we are now using the :void return type. 61 | # Note that, still, the plugin will work ok, it's just the phpunit tests which cannot 62 | # be executed with that PHP versions. 63 | 64 | before_install: 65 | - phpenv config-rm xdebug.ini 66 | - cd ../.. 67 | - composer create-project -n --no-dev --prefer-dist moodlehq/moodle-plugin-ci ci ^3 68 | - export PATH="$(cd ci/bin; pwd):$(cd ci/vendor/bin; pwd):$PATH" 69 | - export IGNORE_PATHS=moodle/tests/fixtures,moodle/Sniffs 70 | - > 71 | if [ -n "$DOCKER_USER" ] && [ -n "$DOCKER_TOKEN" ]; then 72 | echo "$DOCKER_TOKEN" | docker login -u "$DOCKER_USER" --password-stdin 73 | echo "Using authenticated connection (no pull limits)" 74 | else 75 | echo "Using unauthenticated docker (pull limits may apply). Setup DOCKER_USER and DOCKER_TOKEN if needed." 76 | fi 77 | install: 78 | - moodle-plugin-ci install 79 | 80 | script: 81 | - moodle-plugin-ci phplint 82 | - moodle-plugin-ci phpcpd 83 | - moodle-plugin-ci phpmd 84 | - moodle-plugin-ci codechecker 85 | - moodle-plugin-ci validate 86 | - moodle-plugin-ci savepoints 87 | - moodle-plugin-ci mustache 88 | - moodle-plugin-ci grunt 89 | - moodle-plugin-ci phpdoc 90 | - moodle-plugin-ci phpunit 91 | - moodle-plugin-ci behat -------------------------------------------------------------------------------- /rank_game.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Rank view 19 | * 20 | * @package block_game 21 | * @copyright 2019 Jose Wilson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | require_once(dirname(__FILE__) . '/../../config.php'); 26 | require_once($CFG->dirroot . '/blocks/game/lib.php'); 27 | require_once($CFG->libdir . '/grouplib.php'); 28 | require_once($CFG->libdir . '/filelib.php'); 29 | 30 | require_login(); 31 | 32 | global $USER, $COURSE, $OUTPUT, $CFG; 33 | 34 | $courseid = required_param('id', PARAM_INT); 35 | $groupid = optional_param('group', 0, PARAM_INT); 36 | 37 | $course = $DB->get_record('course', ['id' => $courseid], '*', MUST_EXIST); 38 | 39 | require_login($course); 40 | 41 | $context = context_course::instance($courseid); 42 | $PAGE->set_pagelayout('course'); 43 | $PAGE->set_url('/blocks/game/rank_game.php', ['id' => $courseid]); 44 | $PAGE->set_context(context_course::instance($courseid)); 45 | $PAGE->set_title(get_string('rank_game_title', 'block_game')); 46 | $PAGE->set_heading(get_string('rank_game_title', 'block_game')); 47 | 48 | echo $OUTPUT->header(); 49 | $game = new stdClass(); 50 | $game->config = get_config('block_game'); 51 | 52 | /* Now verify grading user has access to all groups or is member of the same group when separate groups used in course */ 53 | $ok = false; 54 | if ($course->groupmode == 1 && !has_capability('moodle/course:viewhiddenactivities', $context)) { 55 | if (groups_is_member($groupid, $USER->id)) { 56 | $ok = true; 57 | } 58 | } else { 59 | $ok = true; 60 | } 61 | if (has_capability('moodle/course:update', $context, $USER->id)) { 62 | echo $OUTPUT->download_dataformat_selector( 63 | get_string('downloadthis', 'block_game'), 64 | 'download.php', 65 | 'dataformat', 66 | ['id' => $courseid, 'op' => 'ranking'] 67 | ); 68 | } 69 | 70 | if ($ok) { 71 | if ($courseid == SITEID) { 72 | $renderer = $PAGE->get_renderer('block_game'); 73 | 74 | $rankpage = new \block_game\output\rank($course, $USER, $game->config, $groupid); 75 | echo $renderer->render($rankpage); 76 | } else { 77 | $game->config = block_game_get_config_block($courseid); 78 | $renderer = $PAGE->get_renderer('block_game'); 79 | 80 | $rankpage = new \block_game\output\rank($course, $USER, $game->config, $groupid); 81 | echo $renderer->render($rankpage); 82 | } 83 | } 84 | echo $OUTPUT->footer(); 85 | -------------------------------------------------------------------------------- /pix/a9.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/help.mustache: -------------------------------------------------------------------------------- 1 | {{! 2 | This file is part of Moodle - http://moodle.org/ 3 | 4 | Moodle is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Moodle is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Moodle. If not, see . 16 | }} 17 | {{! 18 | @template block_game/help 19 | 20 | This template renders the help. 21 | Example context (json): 22 | { 23 | "isfrontpage": false, 24 | "coursefullname": "Curso de Ciências 2025", 25 | "notconfigured": false, 26 | "config": { 27 | "wwwroot": "https://moodle.exemplo.com" 28 | }, 29 | "features": [ 30 | { 31 | "title": "Sistema de Pontuação", 32 | "image": "score.png", 33 | "text": "Os alunos acumulam pontos ao concluir atividades e módulos. Isso incentiva a participação contínua e melhora o desempenho geral." 34 | }, 35 | { 36 | "title": "Níveis de Progresso", 37 | "image": "level.png", 38 | "text": "Cada aluno possui um nível, que aumenta conforme sua pontuação. Você pode configurar os níveis e os requisitos para cada um." 39 | }, 40 | { 41 | "title": "Ranking e Conquistas", 42 | "image": "ranking.png", 43 | "text": "Os alunos são ranqueados por curso com base em sua pontuação total. Distintivos e conquistas são atribuídos automaticamente aos melhores colocados." 44 | } 45 | ] 46 | } 47 | }} 48 |
49 |

50 | {{#isfrontpage}} 51 | ({{#str}} general, block_game {{/str}}) 52 | {{/isfrontpage}} 53 | {{^isfrontpage}} 54 | ({{coursefullname}}) 55 | {{/isfrontpage}} 56 |

57 |

58 | 59 | {{#notconfigured}} 60 |

...

61 | {{#str}} not_initial_config_game, block_game {{/str}} 62 |

63 | {{/notconfigured}} 64 | 65 | {{^notconfigured}} 66 | 67 | {{#features}} 68 | 69 | 70 | 71 | 72 | 75 | 79 | 80 | {{/features}} 81 |

{{title}}

73 | {{title}} 74 | 76 |

{{{text}}}

77 |
78 |
82 | {{/notconfigured}} 83 |
84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Moodle block Game repository 2 | =========================== 3 | VERSION 2.0 4 | ------------ 5 | The goal of the Block Game plugin is to apply gamification techniques to the moodle platform in a simple and uncomplicated way. 6 | 7 | The plugin uses the following possible and configurable aspects: 8 | 9 | **Use Avatar:** 10 | Allows the user to choose or change their avatar at any time. When the dotted icon appears it means the user has not yet chosen yours by clicking on it, or your avatar, it takes you to the selection page, just click on the desired avatar to make the choice. 11 | Selecting some avatars will require the user to reach a certain level to unlock them. 12 | 13 | **Allow avatar change in course:** 14 | Allows the user to choose yours in whatever course the block is added! This option makes the plugin more flexible and can be used in only one or more courses, without the need to include the block in the general area of ​​the platform! 15 | 16 | **Show Player Information:** 17 | Allows the user to access an area that consolidates the information of the same in the game, if accessed in the context of the platform presents information of all courses that the user participates using the block. 18 | 19 | **Scoring system:** 20 | The game has scoring system because the player's score will define his rating and the level he is at. 21 | - Score Activity Notes - Allows notes (numeric scale) to be converted to game points. 22 | - Bonus of the Day - Allows you to set a score that the player will receive daily if they access the platform and / or course. 23 | - Badge Bonus - Allows you to set a score the player will receive upon completing a course. It will also receive a badge as a reward. 24 | 25 | **Show Ranking:** 26 | Allows you to show either the individual student rating on the platform or course and the classified list. 27 | - Preserve User Identity - If showing the rating, lets you preserve the identity of users in the classified list. 28 | 29 | **Show Group Ranking:** 30 | Allows you to show the group classified list of students on a course. 31 | - Possibility to calculate the score by sum or average. 32 | 33 | **Show Points:** 34 | Allows you to display or not the user score. 35 | 36 | **Show Level:** 37 | Allows you to display or not the level system. If configured to display you can configure the number of levels and the score required to reach each level. 38 | Still regarding the level the block has a progress bar that shows the user how much is left to reach the next level. 39 | 40 | *All images used in the plugin are under the Creative Commons license.* 41 | 42 | Installation 43 | ------------ 44 | ***Important: Compatible with MySQL and PostgreSQL only*** 45 | 46 | **First way** 47 | 48 | - Download this repository 49 | - Access the administration area-> plugins-> install plugin, upload the file and click install. 50 | 51 | **Second way** 52 | 53 | - Download this repository 54 | - Extract the content 55 | - Put the folder into the folder blocks of your moodle 56 | - Access the notification area in moodle and install 57 | 58 | Post instalation 59 | ---------------- 60 | 61 | After installing the block, simply add it to the course and / or in the main page of moodle. 62 | 63 | The entire configuration of the plugin is in the configuration of the block. 64 | -------------------------------------------------------------------------------- /pix/lv2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 21 | 22 | 24 | 27 | 29 | 31 | 32 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /pix/lv5.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 21 | 22 | 24 | 27 | 29 | 31 | 32 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /pix/badgex.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 17 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 63 | 64 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /pix/lv12.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 21 | 22 | 24 | 27 | 29 | 31 | 32 | 34 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /pix/lv9.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 21 | 22 | 24 | 27 | 29 | 31 | 32 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /pix/lv10.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 21 | 22 | 24 | 27 | 29 | 31 | 32 | 34 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /pix/lv6.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 21 | 22 | 24 | 27 | 29 | 31 | 32 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /reset_points_course.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Reset page 19 | * 20 | * @package block_game 21 | * @copyright 2019 Jose Wilson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | require_once(dirname(__FILE__) . '/../../config.php'); 26 | require_once($CFG->dirroot . '/blocks/game/lib.php'); 27 | require_once($CFG->libdir . '/completionlib.php'); 28 | 29 | require_login(); 30 | 31 | global $USER, $OUTPUT, $CFG; 32 | 33 | $confirm = optional_param('c', 0, PARAM_INT); 34 | $courseid = required_param('id', PARAM_INT); 35 | $course = $DB->get_record('course', ['id' => $courseid], '*', MUST_EXIST); 36 | 37 | require_login($course); 38 | 39 | $PAGE->set_pagelayout('course'); 40 | $PAGE->set_url('/blocks/game/reset_points_course.php', ['id' => $courseid]); 41 | $PAGE->set_context(context_course::instance($courseid)); 42 | $PAGE->set_title(get_string('reset_points_title', 'block_game')); 43 | $PAGE->set_heading(get_string('reset_points_title', 'block_game')); 44 | 45 | echo $OUTPUT->header(); 46 | $outputhtml = '
'; 47 | 48 | if ($courseid != SITEID) { 49 | $context = context_course::instance($courseid, MUST_EXIST); 50 | if (has_capability('moodle/course:update', $context, $USER->id)) { 51 | $outputhtml .= '
'; 52 | 53 | $outputhtml .= '

( ' . get_string('reset_points_title', 'block_game') . ': ' 54 | . $course->fullname . ' )


'; 55 | 56 | $outputhtml .= '
'; 57 | if ($confirm > 0) { 58 | require_sesskey(); 59 | if (block_game_reset_points_game($courseid)) { 60 | $outputhtml .= '' . get_string('reset_points_sucess', 'block_game') 61 | . '

' . get_string('ok', 'block_game') . ''; 63 | } else { 64 | $outputhtml .= '' . get_string('reset_points_error', 'block_game') . '
'; 65 | } 66 | } else { 67 | $outputhtml .= '' . get_string('label_confirm_reset_points', 'block_game') . '

'; 68 | $outputhtml .= '' 69 | . get_string('no', 'block_game') . '' . ' ' . get_string('yes', 'block_game') . '' . '
'; 71 | } 72 | $outputhtml .= '
'; 73 | $outputhtml .= '
'; 74 | } else { 75 | $outputhtml .= '' . get_string('reset_points_not_permission', 'block_game') . '
'; 76 | } 77 | } 78 | $outputhtml .= '
'; 79 | echo $outputhtml; 80 | echo $OUTPUT->footer(); 81 | -------------------------------------------------------------------------------- /pix/lv3.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 21 | 22 | 24 | 27 | 29 | 31 | 32 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /db/install.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |
51 |
52 |
53 | -------------------------------------------------------------------------------- /classes/output/rankgroup.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Rank Group definition 19 | * 20 | * @package block_game 21 | * @copyright 2019 Jose Wilson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | namespace block_game\output; 26 | 27 | use renderable; 28 | use templatable; 29 | use stdClass; 30 | use renderer_base; 31 | 32 | /** 33 | * Renderable class for the ranking group page. 34 | * 35 | * @package block_game 36 | * @copyright 2025 José Wilson 37 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 | */ 39 | class rankgroup implements renderable, templatable { 40 | /** @var title */ 41 | public $title; 42 | /** @var coursefullname */ 43 | public $coursefullname; 44 | /** @var isfrontpage */ 45 | public $isfrontpage; 46 | /** @var notconfigured */ 47 | public $notconfigured; 48 | /** @var groups */ 49 | public $groups = []; 50 | /** 51 | * Rankgroup constructor. 52 | * 53 | * @param stdClass $course 54 | * @param stdClass $config 55 | * @param bool $isfrontpage 56 | */ 57 | public function __construct(stdClass $course, stdClass $config, bool $isfrontpage) { 58 | $this->title = get_string('rank_group_game_title', 'block_game'); 59 | $this->coursefullname = $course->fullname; 60 | $this->isfrontpage = $isfrontpage; 61 | $this->notconfigured = !(isset($config->show_rank) && $config->show_rank == 1); 62 | 63 | if ($this->notconfigured || $isfrontpage) { 64 | return; 65 | } 66 | 67 | global $DB; 68 | 69 | $rankingdata = (isset($config->rank_group_calc) && $config->rank_group_calc == 1) 70 | ? block_game_ranking_group_md($course->id) 71 | : block_game_ranking_group($course->id); 72 | 73 | $ord = 1; 74 | foreach ($rankingdata as $groupdata) { 75 | $grouprecord = $DB->get_record('groups', ['id' => $groupdata->id], '*', MUST_EXIST); 76 | 77 | $score = isset($config->rank_group_calc) && $config->rank_group_calc == 1 78 | ? number_format($groupdata->md, 2) 79 | : number_format($groupdata->pt, 2); 80 | 81 | $this->groups[] = [ 82 | 'ord' => $ord, 83 | 'groupname' => $groupdata->name, 84 | 'members' => $groupdata->members, 85 | 'score' => $score, 86 | 'picture' => print_group_picture($grouprecord, $course->id, false, true, true), 87 | ]; 88 | 89 | $ord++; 90 | } 91 | } 92 | /** 93 | * Export the data. 94 | * @param renderer_base $output 95 | * @return array|\stdClass 96 | */ 97 | public function export_for_template(renderer_base $output) { 98 | return [ 99 | 'title' => $this->title, 100 | 'coursefullname' => $this->coursefullname, 101 | 'isfrontpage' => $this->isfrontpage, 102 | 'notconfigured' => $this->notconfigured, 103 | 'groups' => $this->groups, 104 | ]; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /pix/lv8.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | 21 | 22 | 24 | 27 | 29 | 31 | 32 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /pix/a11.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pix/a35.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /block_game.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Game block definition 19 | * 20 | * @package block_game 21 | * @copyright 2019 Jose Wilson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | defined('MOODLE_INTERNAL') || die(); 25 | 26 | require_once($CFG->dirroot . '/blocks/game/lib.php'); 27 | require_once($CFG->libdir . '/filelib.php'); 28 | 29 | /** 30 | * Block Game config form definition class 31 | * 32 | * @package block_game 33 | * @copyright 2019 Jose Wilson 34 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 | */ 36 | class block_game extends block_base { 37 | /** @var stdClass|null */ 38 | public $course = null; 39 | /** 40 | * Sets the block title 41 | * 42 | * @return none 43 | */ 44 | public function init() { 45 | $this->title = get_string('game_title_default', 'block_game'); 46 | } 47 | 48 | /** 49 | * Controls the block title based on instance configuration 50 | * 51 | * @return bool 52 | */ 53 | public function specialization() { 54 | global $course; 55 | 56 | // Need the bigger course object. 57 | $this->course = $course; 58 | 59 | // Override the block title if an alternative is set. 60 | if (isset($this->config->game_title) && trim($this->config->game_title) != '') { 61 | $this->title = format_string($this->config->game_title); 62 | } 63 | } 64 | 65 | /** 66 | * Defines where the block can be added 67 | * 68 | * @return array 69 | */ 70 | public function applicable_formats() { 71 | return [ 72 | 'course-view' => true, 73 | 'site-index' => true, 74 | 'mod' => true, 75 | 'my' => true, 76 | ]; 77 | } 78 | 79 | /** 80 | * Controls global configurability of block 81 | * 82 | * @return bool 83 | */ 84 | public function instance_allow_config() { 85 | return false; 86 | } 87 | 88 | /** 89 | * Controls global configurability of block 90 | * 91 | * @return bool 92 | */ 93 | public function has_config() { 94 | return true; 95 | } 96 | 97 | /** 98 | * Controls if a block header is shown based on instance configuration 99 | * 100 | * @return bool 101 | */ 102 | public function hide_header() { 103 | return isset($this->config->show_header) && $this->config->show_header == 0; 104 | } 105 | 106 | /** 107 | * Creates the block's main content 108 | * 109 | * @return string 110 | */ 111 | public function get_content() { 112 | global $USER, $COURSE; 113 | if ($this->content !== null) { 114 | return $this->content; 115 | } 116 | 117 | $this->content = new \stdClass(); 118 | $this->content->text = ''; 119 | $this->content->footer = ''; 120 | 121 | $renderer = $this->page->get_renderer('block_game'); 122 | 123 | $contentrenderable = new \block_game\output\block($this->config, $USER, $COURSE); 124 | 125 | $this->content->text = $renderer->render($contentrenderable); 126 | 127 | return $this->content; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /pix/a47.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pix/a29.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pix/a26.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pix/a1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 15 | 17 | 19 | 21 | 22 | 23 | 26 | 27 | 30 | 33 | 34 | 35 | 36 | 42 | 43 | 45 | 47 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /pix/a8.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 11 | 13 | 15 | 16 | 17 | 18 | 21 | 24 | 25 | 26 | 27 | 31 | 32 | 33 | 34 | 36 | 39 | 41 | 42 | 43 | 44 | 45 | 46 | 49 | 52 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /pix/rank.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /pix/a18.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pix/a68.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pix/a50.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pix/a58.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/rank.mustache: -------------------------------------------------------------------------------- 1 | {{! 2 | This file is part of Moodle - http://moodle.org/ 3 | 4 | Moodle is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | Moodle is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with Moodle. If not, see . 16 | }} 17 | {{! 18 | @template block_game/rank 19 | 20 | This template renders the rank. 21 | Example context (json): 22 | { 23 | "coursefullname": "Curso de Física Moderna", 24 | "showgroupmenu": true, 25 | "groupmenu": "", 26 | "headers": [ 27 | { "label": "Posição", "class": "rank-col" }, 28 | { "label": "Nome", "class": "name-col" }, 29 | { "label": "Atividades", "class": "score-col" }, 30 | { "label": "Módulos", "class": "score-col" }, 31 | { "label": "Seções", "class": "score-col" }, 32 | { "label": "Bônus", "class": "score-col" }, 33 | { "label": "Medalhas", "class": "score-col" }, 34 | { "label": "Total", "class": "score-total" } 35 | ], 36 | "gamers": [ 37 | { 38 | "ord": "1º", 39 | "user": " Ana Paula", 40 | "sum_score_activities": "150", 41 | "sum_score_module_completed": "90", 42 | "sum_score_section": "60", 43 | "sum_score_bonus_day": "20", 44 | "sum_score_badges": "30", 45 | "score": "350", 46 | "showdetails": true 47 | }, 48 | { 49 | "ord": "2º", 50 | "user": " Carlos Mendes", 51 | "sum_score_activities": "130", 52 | "sum_score_module_completed": "80", 53 | "sum_score_section": "55", 54 | "sum_score_bonus_day": "15", 55 | "sum_score_badges": "25", 56 | "score": "305", 57 | "showdetails": true 58 | }, 59 | { 60 | "ord": "3º", 61 | "user": " Joana Dias", 62 | "sum_score_activities": "120", 63 | "sum_score_module_completed": "70", 64 | "sum_score_section": "50", 65 | "sum_score_bonus_day": "10", 66 | "sum_score_badges": "20", 67 | "score": "270", 68 | "showdetails": true 69 | } 70 | ], 71 | "notstarted": true, 72 | "notstartedtext": "5 alunos ainda não iniciaram a participação no jogo." 73 | } 74 | }} 75 |
76 |

{{coursefullname}}

77 | {{#showgroupmenu}} 78 | {{{groupmenu}}} 79 | {{/showgroupmenu}} 80 | 81 | 82 | 83 | 84 | {{#headers}} 85 | 86 | {{/headers}} 87 | 88 | 89 | 90 | {{#gamers}} 91 | 92 | 93 | 94 | {{#showdetails}} 95 | 96 | 97 | 98 | 99 | 100 | {{/showdetails}} 101 | 102 | 103 | {{/gamers}} 104 | 105 |
{{{label}}}
{{{ord}}}{{{user}}}{{sum_score_activities}}{{sum_score_module_completed}}{{sum_score_section}}{{sum_score_bonus_day}}{{sum_score_badges}}{{{score}}}
106 | 107 | {{#notstarted}} 108 |
({{notstarted}} {{notstartedtext}}) 109 | {{/notstarted}} 110 |
111 | -------------------------------------------------------------------------------- /pix/a33.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pix/a30.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pix/a19.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /db/upgrade.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Game block language strings 19 | * 20 | * @package block_game 21 | * @copyright 2019 Jose Wilson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | 25 | /** 26 | * Update block_game 27 | * 28 | * @param int $oldversion 29 | * @return bool always true 30 | */ 31 | function xmldb_block_game_upgrade($oldversion) { 32 | global $CFG, $DB; 33 | $dbman = $DB->get_manager(); 34 | 35 | if ($oldversion < 2020012905) { 36 | // Add field 'score_bonus_day' to 'block_game'. 37 | $table = new xmldb_table('block_game'); 38 | $field = new xmldb_field('score_bonus_day', XMLDB_TYPE_INTEGER, '10', null, null, null, '0', 'score_activities'); 39 | if (!$dbman->field_exists($table, $field)) { 40 | $dbman->add_field($table, $field); 41 | } 42 | // Define table block_xp_filters to be created. 43 | $table = new xmldb_table('block_game_completed_atv'); 44 | // Adding fields to table block_game_completed_atv. 45 | $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null); 46 | $table->add_field('courseid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 47 | $table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 48 | $table->add_field('moduleid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null); 49 | $table->add_field('score', XMLDB_TYPE_INTEGER, '10', null, null, null, '0'); 50 | $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, null, null, null); 51 | // Adding keys to table block_game_completed_atv. 52 | $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']); 53 | $table->add_key('courseid', XMLDB_KEY_FOREIGN, ['courseid'], 'course', ['id']); 54 | $table->add_key('userid', XMLDB_KEY_FOREIGN, ['userid'], 'user', ['id']); 55 | // Conditionally launch create table for block_game_completed_atv. 56 | if (!$dbman->table_exists($table)) { 57 | $dbman->create_table($table); 58 | } 59 | // Block_game savepoint reached. 60 | upgrade_block_savepoint(true, 2020012905, 'game'); 61 | } 62 | if ($oldversion < 2020042983) { 63 | // Add field 'score_bonus_day' to 'block_game'. 64 | $table = new xmldb_table('block_game'); 65 | $field = new xmldb_field('score_section', XMLDB_TYPE_INTEGER, '10', null, null, null, '0', 'score_badges'); 66 | if (!$dbman->field_exists($table, $field)) { 67 | $dbman->add_field($table, $field); 68 | } 69 | // Block_game savepoint reached. 70 | upgrade_block_savepoint(true, 2020042983, 'game'); 71 | } 72 | if ($oldversion < 2020042996) { 73 | // Add field 'score_bonus_day' to 'block_game'. 74 | $table = new xmldb_table('block_game'); 75 | $field = new xmldb_field('ranking', XMLDB_TYPE_INTEGER, '10', null, null, null, '0', 'level'); 76 | if (!$dbman->field_exists($table, $field)) { 77 | $dbman->add_field($table, $field); 78 | } 79 | // Block_game savepoint reached. 80 | upgrade_block_savepoint(true, 2020042996, 'game'); 81 | } 82 | if ($oldversion < 2021051022) { 83 | // Add field 'score_bonus_day' to 'block_game'. 84 | $table = new xmldb_table('block_game'); 85 | $field = new xmldb_field('score_module_completed', XMLDB_TYPE_INTEGER, '10', null, null, null, '0', 'score_activities'); 86 | if (!$dbman->field_exists($table, $field)) { 87 | $dbman->add_field($table, $field); 88 | } 89 | // Block_game savepoint reached. 90 | upgrade_block_savepoint(true, 2021051022, 'game'); 91 | } 92 | if ($oldversion < 2022042725) { 93 | // Define table block_game_completed_atv to be dropped. 94 | $table = new xmldb_table('block_game_completed_atv'); 95 | // Conditionally launch drop table for role_sortorder. 96 | if ($dbman->table_exists($table)) { 97 | $dbman->drop_table($table); 98 | } 99 | // Block_game savepoint reached. 100 | upgrade_block_savepoint(true, 2022042725, 'game'); 101 | } 102 | return true; 103 | } 104 | -------------------------------------------------------------------------------- /pix/a62.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pix/a42.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /settings.php: -------------------------------------------------------------------------------- 1 | . 16 | 17 | /** 18 | * Block Game config form definition class 19 | * 20 | * @package block_game 21 | * @copyright 2019 Jose Wilson 22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 | */ 24 | defined('MOODLE_INTERNAL') || die(); 25 | 26 | if ($ADMIN->fulltree) { 27 | $settings->add(new admin_setting_heading( 28 | 'block_game/displaysettings', 29 | get_string('defaultdisplaysettings', 'block_game'), 30 | '' 31 | )); 32 | 33 | $settings->add(new admin_setting_configcheckbox( 34 | 'block_game/use_avatar', 35 | get_string('config_avatar', 'block_game'), 36 | '', 37 | 1 38 | )); 39 | 40 | $settings->add(new admin_setting_configstoredfile( 41 | 'block_game/imagens_avatar', 42 | new lang_string('imagemavatar', 'block_game'), 43 | new lang_string('imagemavatardesc', 'block_game'), 44 | 'imagens_avatar', 45 | 0, 46 | ['subdirs' => 0, 'maxfiles' => 68, 'accepted_types' => ['.svg']] 47 | )); 48 | 49 | $settings->add(new admin_setting_configcheckbox( 50 | 'block_game/change_avatar_course', 51 | get_string('config_avatar_course', 'block_game'), 52 | '', 53 | 0 54 | )); 55 | 56 | $settings->add(new admin_setting_configcheckbox( 57 | 'block_game/show_info', 58 | get_string('config_info', 'block_game'), 59 | get_string('config_info_help', 'block_game'), 60 | 1 61 | )); 62 | 63 | $settings->add(new admin_setting_configcheckbox( 64 | 'block_game/score_activities', 65 | get_string('config_score_activities', 'block_game'), 66 | '', 67 | 1 68 | )); 69 | 70 | $bonusdayoptions = [0 => 0, 1 => 1, 3 => 3, 5 => 5, 10 => 10, 15 => 15, 20 => 20, 50 => 50, 100 => 100]; 71 | $settings->add(new admin_setting_configselect( 72 | 'block_game/bonus_day', 73 | get_string('config_bonus_day', 'block_game'), 74 | '', 75 | -2, 76 | $bonusdayoptions 77 | )); 78 | 79 | $bonusbadgeoptions = [0 => 0, 50 => 50, 100 => 100, 200 => 200, 500 => 500, 1000 => 1000, 2000 => 2000]; 80 | $settings->add(new admin_setting_configselect( 81 | 'block_game/bonus_badge', 82 | get_string('config_bonus_badge', 'block_game'), 83 | '', 84 | -2, 85 | $bonusbadgeoptions 86 | )); 87 | 88 | $settings->add(new admin_setting_configcheckbox( 89 | 'block_game/show_rank', 90 | get_string('config_rank', 'block_game'), 91 | '', 92 | 1 93 | )); 94 | 95 | $settings->add(new admin_setting_configcheckbox( 96 | 'block_game/show_identity', 97 | get_string('config_identity', 'block_game'), 98 | '', 99 | 1 100 | )); 101 | 102 | $settings->add(new admin_setting_configcheckbox( 103 | 'block_game/show_score', 104 | get_string('config_score', 'block_game'), 105 | '', 106 | 1 107 | )); 108 | 109 | $settings->add(new admin_setting_configcheckbox( 110 | 'block_game/show_level', 111 | get_string('config_level', 'block_game'), 112 | '', 113 | 1 114 | )); 115 | 116 | $settings->add(new admin_setting_configstoredfile( 117 | 'block_game/imagens_levels', 118 | new lang_string('imagemlevels', 'block_game'), 119 | new lang_string('imagemlevelsdesc', 'block_game'), 120 | 'imagens_levels', 121 | 0, 122 | ['subdirs' => 0, 'maxfiles' => 16, 'accepted_types' => ['.svg']] 123 | )); 124 | 125 | // Options controlling level up. 126 | $leveloptions = [4 => 4, 6 => 6, 8 => 8, 10 => 10, 12 => 12, 13 => 13, 14 => 14, 15 => 15]; 127 | $settings->add(new admin_setting_configselect( 128 | 'block_game/level_number', 129 | get_string('config_level_number', 'block_game'), 130 | '', 131 | 15, 132 | $leveloptions 133 | )); 134 | 135 | $leveluppoints = [1 => 300, 2 => 500, 3 => 1000, 4 => 2000, 136 | 5 => 4000, 6 => 6000, 7 => 10000, 8 => 20000, 137 | 9 => 30000, 10 => 50000, 11 => 70000, 12 => 100000, 13 => 150000, 14 => 250000, 15 => 500000]; 138 | for ($i = 1; $i <= 15; $i++) { 139 | $settings->add(new admin_setting_configtext( 140 | 'block_game/level_up' . $i, 141 | get_string('config_level_up' . $i, 'block_game'), 142 | '', 143 | $leveluppoints[$i], 144 | PARAM_INT 145 | )); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /pix/a31.svg: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------