Commit 41f61293 authored by victor's avatar victor 🙇
Browse files

MDL-63062 block_recentlyaccessedcourses: add block and styles

parent 98a52c80
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
// This file is part of 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/>.
/**
* Javascript to initialise the Recently accessed courses block.
*
* @module block_recentlyaccessedcourses/main.js
* @package block_recentlyaccessedcourses
* @copyright 2018 Victor Deniz <victor@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define(
[
'jquery',
'core_course/repository',
'core/templates',
'core/notification'
],
function(
$,
CoursesRepository,
Templates,
Notification
) {
var SELECTORS = {
COURSES_VIEW: '[data-region="recentlyaccessedcourses-view"]',
COURSES_VIEW_CONTENT: '[data-region="recentlyaccessedcourses-view-content"]'
};
var NUM_COURSES_TOTAL = 10;
/**
* Get enrolled courses from backend.
*
* @method getRecentCourses
* @param {int} userid User from which the courses will be obtained
* @param {int} limit Only return this many results
* @return {array} Courses user has accessed
*/
var getRecentCourses = function(userid, limit) {
return CoursesRepository.getLastAccessedCourses(userid, limit);
};
/**
* Render the dashboard courses.
*
* @method renderCourses
* @param {object} root The root element for the courses view.
* @param {array} courses containing array of returned courses.
* @return {promise} Resolved with HTML and JS strings
*/
var renderCourses = function(root, courses) {
if (courses.length > 0) {
return Templates.render('block_recentlyaccessedcourses/view-cards', {
courses: courses
});
} else {
var nocoursesimgurl = root.attr('data-nocoursesimgurl');
return Templates.render('block_recentlyaccessedcourses/no-courses', {
nocoursesimgurl: nocoursesimgurl
});
}
};
/**
* Get and show the recent courses into the block.
*
* @param {int} userid User from which the courses will be obtained
* @param {object} root The root element for the recentlyaccessedcourses block.
*/
var init = function(userid, root) {
root = $(root);
var recentcoursesViewRoot = root.find(SELECTORS.COURSES_VIEW);
var recentcoursesViewContent = root.find(SELECTORS.COURSES_VIEW_CONTENT);
var coursesPromise = getRecentCourses(userid, NUM_COURSES_TOTAL);
coursesPromise.then(function(courses) {
var pagedContentPromise = renderCourses(recentcoursesViewRoot, courses);
pagedContentPromise.then(function(html, js) {
return Templates.replaceNodeContents(recentcoursesViewContent, html, js);
}).catch(Notification.exception);
return coursesPromise;
}).catch(Notification.exception);
};
return {
init: init
};
});
<?php
// This file is part of 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/>.
/**
* Class definition for the Recently accessed courses block.
*
* @package block_recentlyaccessedcourses
* @copyright 2018 Victor Deniz <victor@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Recently accessed courses block class.
*
* @package block_recentlyaccessedcourses
* @copyright Victor Deniz <victor@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class block_recentlyaccessedcourses extends block_base {
/**
* Initialize class member variables
*/
public function init() {
$this->title = get_string('pluginname', 'block_recentlyaccessedcourses');
}
/**
* Returns the contents.
*
* @return stdClass contents of block
*/
public function get_content() {
if (isset($this->content)) {
return $this->content;
}
$renderable = new block_recentlyaccessedcourses\output\main();
$renderer = $this->page->get_renderer('block_recentlyaccessedcourses');
$this->content = new stdClass();
$this->content->text = $renderer->render($renderable);
$this->content->footer = '';
return $this->content;
}
/**
* Locations where block can be displayed.
*
* @return array
*/
public function applicable_formats() {
return array('my' => true);
}
}
<?php
// This file is part of 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/>.
/**
* Class containing data for the Recently accessed courses block.
*
* @package block_recentlyaccessedcourses
* @copyright 2018 Victor Deniz <victor@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace block_recentlyaccessedcourses\output;
defined('MOODLE_INTERNAL') || die();
use renderable;
use renderer_base;
use templatable;
/**
* Class containing data for Recently accessed courses block.
*
* @package block_recentlyaccessedcourses
* @copyright 2018 Victor Deniz <victor@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class main implements renderable, templatable {
/**
* Export this data so it can be used as the context for a mustache template.
*
* @param renderer_base $output
* @return \stdClass|array
*/
public function export_for_template(renderer_base $output) {
global $USER;
$nocoursesurl = $output->image_url('courses', 'block_recentlyaccessedcourses')->out();
return [
'userid' => $USER->id,
'nocoursesimgurl' => $nocoursesurl
];
}
}
<?php
// This file is part of 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/>.
/**
* Recently accessed courses block renderer
*
* @package block_recentlyaccessedcourses
* @copyright 2018 Victor Deniz <victor@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace block_recentlyaccessedcourses\output;
defined('MOODLE_INTERNAL') || die;
use plugin_renderer_base;
/**
* Recently accessed courses block renderer
*
* @package block_recentlyaccessedcourses
* @copyright 2018 Victor Deniz <victor@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class renderer extends plugin_renderer_base {
/**
* Return the main content for the Recently accessed courses block.
*
* @param main $main The main renderable
* @return string HTML string
*/
public function render_recentcourses(main $main) {
return $this->render_from_template('block_recentlyaccessedcourses/main', $main->export_for_template($this));
}
}
<?php
// This file is part of 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/>.
/**
* Privacy Subsystem implementation for Recently accessed courses block.
*
* @package block_recentlyaccessedcourses
* @copyright 2018 Victor Deniz <victor@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace block_recentlyaccessedcourses\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for Recently accessed courses block.
*
* @copyright 2018 Victor Deniz <victor@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason() : string {
return 'privacy:metadata';
}
}
<?php
// This file is part of 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/>.
/**
* Capabilities for the Recently accessed courses block.
*
* @package block_recentlyaccessedcourses
* @copyright 2018 Victor Deniz <victor@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = array(
'block/recentlyaccessedcourses:myaddinstance' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'user' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/my:manageblocks'
),
'block/recentlyaccessedcourses:addinstance' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_BLOCK,
'archetypes' => array(
'manager' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/site:manageblocks'
)
);
<?php
// This file is part of 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/>.
/**
* Recently accessed courses block installation.
*
* @package block_recentlyaccessedcourses
* @copyright 2018 Victor Deniz <victor@moodle.com> based on code from 2018 Ryan Wyllie <ryan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Add the Recently accessed courses block to the dashboard for all users by default
* when it is installed.
*/
function xmldb_block_recentlyaccessedcourses_install() {
global $DB;
if ($DB->count_records('block_instances') < 1) {
// Only add the recentlyaccessedcourses block if it's being installed on an existing site.
// For new sites it will be added by blocks_add_default_system_blocks().
return;
}
if ($defaultmypage = $DB->get_record('my_pages', array('userid' => null, 'name' => '__default', 'private' => 1))) {
$subpagepattern = $defaultmypage->id;
} else {
$subpagepattern = null;
}
$page = new moodle_page();
$systemcontext = context_system::instance();
$page->set_context($systemcontext);
// Add the block to the default /my.
$page->blocks->add_region('content');
$page->blocks->add_block('recentlyaccessedcourses', 'content', 0, false, 'my-index', $subpagepattern);
// Now we need to find all users that have viewed their dashboard because it'll have
// made duplicates of the default block_instances for them so they won't see the new
// recentlyaccessedcourses block without the admin resetting all of the dashboards.
//
// Instead we'll just add the recentlyaccessedcourses block to their dashboards here.
$sql = "SELECT parentcontextid, subpagepattern
FROM {block_instances}
WHERE pagetypepattern = 'my-index'
AND parentcontextid != ?";
$params = [$systemcontext->id];
$existingrecords = $DB->get_recordset_sql($sql, $params);
$blockinstances = [];
$seencontexts = [];
$now = time();
foreach ($existingrecords as $existingrecord) {
$parentcontextid = $existingrecord->parentcontextid;
if (isset($seencontexts[$parentcontextid])) {
// If we've seen this context already then skip it because we don't want
// to add duplicate recentlyaccessedcourses blocks to the same context. This happens
// if something funny is going on with the subpagepattern.
continue;
} else {
$seencontexts[$parentcontextid] = true;
}
$blockinstances[] = [
'blockname' => 'recentlyaccessedcourses',
'parentcontextid' => $parentcontextid,
'showinsubcontexts' => false,
'pagetypepattern' => 'my-index',
'subpagepattern' => $existingrecord->subpagepattern,
'defaultregion' => 'content',
'defaultweight' => 0,
'configdata' => '',
'timecreated' => $now,
'timemodified' => $now,
];
if (count($blockinstances) >= 1000) {
// Insert after every 1000 records so that the memory usage doesn't
// get out of control.
$DB->insert_records('block_instances', $blockinstances);
$blockinstances = [];
}
}
$existingrecords->close();
if (!empty($blockinstances)) {
// Insert what ever is left over.
$DB->insert_records('block_instances', $blockinstances);
}
}
<?php
// This file is part of 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/>.
/**
* Strings for the Recently accessed courses block.
*
* @package block_recentlyaccessedcourses
* @copyright 2018 Victor Deniz <victor@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['nocourses'] = 'No recent courses';
$string['pluginname'] = 'Recently accessed courses';
$string['privacy:metadata'] = 'The timeline block does not store any personal data.';
$string['recentlyaccessedcourses:addinstance'] = 'Add a new Recently accessed courses block';
$string['recentlyaccessedcourses:myaddinstance'] = 'Add a new Recently accessed courses block to Dashboard';
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="157 -1305 148 125" preserveAspectRatio="xMinYMid meet">
<defs>
<style>
.cls-1 {
clip-path: url(#clip-Courses);
}
.cls-2 {
fill: #eee;
}
.cls-3 {
fill: #c4c8cc;
}
.cls-4 {
fill: #fff;
}
</style>
<clipPath id="clip-Courses">
<rect x="157" y="-1305" width="148" height="125"/>
</clipPath>
</defs>
<g id="Courses" class="cls-1">
<g id="Group_44" data-name="Group 44" transform="translate(-268 -1781)">
<ellipse id="Ellipse_41" data-name="Ellipse 41" class="cls-2" cx="74" cy="14.785" rx="74" ry="14.785" transform="translate(425 571.43)"/>
<rect id="Rectangle_87" data-name="Rectangle 87" class="cls-3" width="95.097" height="110.215" transform="translate(451.909 476)"/>
<g id="Group_43" data-name="Group 43" transform="translate(464.04 494)">
<rect id="Rectangle_88" data-name="Rectangle 88" class="cls-4" width="31.043" height="34" transform="translate(0)"/>
<rect id="Rectangle_89" data-name="Rectangle 89" class="cls-4" width="31.043" height="34" transform="translate(0 42)"/>
<rect id="Rectangle_90" data-name="Rectangle 90" class="cls-4" width="31.067" height="34" transform="translate(39.005)"/>
<rect id="Rectangle_91" data-name="Rectangle 91" class="cls-4" width="31.067" height="34" transform="translate(39.005 42)"/>
<rect id="Rectangle_92" data-name="Rectangle 92" class="cls-3" width="23.023" height="3.18" transform="translate(3.081 16.549)"/>
<rect id="Rectangle_93" data-name="Rectangle 93" class="cls-3" width="23.023" height="3.18" transform="translate(3.081 58.549)"/>
<rect id="Rectangle_94" data-name="Rectangle 94" class="cls-3" width="23.023" height="3.18" transform="translate(43.122 16.549)"/>
<rect id="Rectangle_95" data-name="Rectangle 95" class="cls-3" width="23.023" height="3.18" transform="translate(43.122 58.549)"/>
<rect id="Rectangle_96" data-name="Rectangle 96" class="cls-3" width="14.014" height="3.18" transform="translate(3.081 21.825)"/>
<rect id="Rectangle_97" data-name="Rectangle 97" class="cls-3" width="18.845" height="3.18" transform="translate(3.081 26.825)"/>
<rect id="Rectangle_98" data-name="Rectangle 98" class="cls-3" width="14.014" height="3.18" transform="translate(3.081 63.825)"/>
<rect id="Rectangle_99" data-name="Rectangle 99" class="cls-3" width="18.845" height="3.18" transform="translate(3.081 68.825)"/>
<rect id="Rectangle_100" data-name="Rectangle 100" class="cls-3" width="14.014" height="3.18" transform="translate(43.122 21.825)"/>
<rect id="Rectangle_101" data-name="Rectangle 101" class="cls-3" width="18.845" height="3.18" transform="translate(43.122 26.825)"/>
<rect id="Rectangle_102" data-name="Rectangle 102" class="cls-3" width="14.014" height="3.18" transform="translate(43.122 63.825)"/>
<rect id="Rectangle_103" data-name="Rectangle 103" class="cls-3" width="18.845" height="3.18" transform="translate(43.122 68.825)"/>
<ellipse id="Ellipse_42" data-name="Ellipse 42" class="cls-3" cx="5.658" cy="5.652" rx="5.658" ry="5.652" transform="translate(3.003 3.55)"/>
<ellipse id="Ellipse_43" data-name="Ellipse 43" class="cls-3" cx="5.658" cy="5.652" rx="5.658" ry="5.652" transform="translate(3.003 45.55)"/>
<ellipse id="Ellipse_44" data-name="Ellipse 44" class="cls-3" cx="5.658" cy="5.652" rx="5.658" ry="5.652" transform="translate(43.044 3.55)"/>
<ellipse id="Ellipse_45" data-name="Ellipse 45" class="cls-3" cx="5.658" cy="5.652" rx="5.658" ry="5.652" transform="translate(43.044 45.55)"/>
</g>
</g>
</g>
</svg>
{{!
This file is part of 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/>.
}}
{{!
@template block_recentlyaccessedcourses/main
This template renders the main content area for the Recently accessed courses block.
Example context (json):
{
"userid": 2,
"nocoursesimgurl": "https://moodlesite/theme/image.php/boost/block_recentlyaccessedcourses/1535727318/courses"
}
}}
<div id="block-recentlyaccessedcourses-{{uniqid}}" class="block-recentlyaccessedcourses" data-region="recentlyaccessedcourses"
data-userid="{{userid}}">
<div class="container-fluid p-0">
{{> block_recentlyaccessedcourses/recentlyaccessedcourses-view }}