first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
@@ -0,0 +1,299 @@
<?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 block_recent_activity
*
* @package block_recent_activity
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once($CFG->dirroot.'/course/lib.php');
/**
* class block_recent_activity
*
* @package block_recent_activity
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class block_recent_activity extends block_base {
/**
* Use {@link block_recent_activity::get_timestart()} to access
*
* @var int stores the time since when we want to show recent activity
*/
protected $timestart = null;
/**
* Initialises the block
*/
function init() {
$this->title = get_string('pluginname', 'block_recent_activity');
}
/**
* Returns the content object
*
* @return stdObject
*/
function get_content() {
if ($this->content !== NULL) {
return $this->content;
}
if (empty($this->instance)) {
$this->content = '';
return $this->content;
}
$this->content = new stdClass;
$this->content->text = '';
$this->content->footer = '';
$renderer = $this->page->get_renderer('block_recent_activity');
$this->content->text = $renderer->recent_activity($this->page->course,
$this->get_timestart(),
$this->get_recent_enrolments(),
$this->get_structural_changes(),
$this->get_modules_recent_activity());
return $this->content;
}
/**
* Returns the time since when we want to show recent activity
*
* For guest users it is 2 days, for registered users it is the time of last access to the course
*
* @return int
*/
protected function get_timestart() {
global $USER;
if ($this->timestart === null) {
$this->timestart = round(time() - COURSE_MAX_RECENT_PERIOD, -2); // better db caching for guests - 100 seconds
if (!isguestuser()) {
if (!empty($USER->lastcourseaccess[$this->page->course->id])) {
if ($USER->lastcourseaccess[$this->page->course->id] > $this->timestart) {
$this->timestart = $USER->lastcourseaccess[$this->page->course->id];
}
}
}
}
return $this->timestart;
}
/**
* Returns all recent enrolments.
*
* This function previously used get_recent_enrolments located in lib/deprecatedlib.php which would
* return an empty array which was identified in MDL-36993. The use of this function outside the
* deprecated lib was removed in MDL-40649.
*
* @todo MDL-36993 this function always return empty array
* @return array array of entries from {user} table
*/
protected function get_recent_enrolments() {
return array();
}
/**
* Returns list of recent changes in course structure
*
* It includes adding, editing or deleting of the resources or activities
* Excludes changes on modules without a view link (i.e. labels), and also
* if activity was both added and deleted
*
* @return array array of changes. Each element is an array containing attributes:
* 'action' - one of: 'add mod', 'update mod', 'delete mod'
* 'module' - instance of cm_info (for 'delete mod' it is an object with attributes modname and modfullname)
*/
protected function get_structural_changes() {
global $DB;
$course = $this->page->course;
$context = context_course::instance($course->id);
$canviewdeleted = has_capability('block/recent_activity:viewdeletemodule', $context);
$canviewupdated = has_capability('block/recent_activity:viewaddupdatemodule', $context);
if (!$canviewdeleted && !$canviewupdated) {
return;
}
$timestart = $this->get_timestart();
$changelist = array();
// The following query will retrieve the latest action for each course module in the specified course.
// Also the query filters out the modules that were created and then deleted during the given interval.
$sql = "SELECT
cmid, MIN(action) AS minaction, MAX(action) AS maxaction, MAX(modname) AS modname
FROM {block_recent_activity}
WHERE timecreated > ? AND courseid = ?
GROUP BY cmid
ORDER BY MAX(timecreated) DESC";
$params = array($timestart, $course->id);
$logs = $DB->get_records_sql($sql, $params);
if (isset($logs[0])) {
// If special record for this course and cmid=0 is present, migrate logs.
self::migrate_logs($course);
$logs = $DB->get_records_sql($sql, $params);
}
if ($logs) {
$modinfo = get_fast_modinfo($course);
foreach ($logs as $log) {
// We used aggregate functions since constants CM_CREATED, CM_UPDATED and CM_DELETED have ascending order (0,1,2).
$wasdeleted = ($log->maxaction == block_recent_activity_observer::CM_DELETED);
$wascreated = ($log->minaction == block_recent_activity_observer::CM_CREATED);
if ($wasdeleted && $wascreated) {
// Activity was created and deleted within this interval. Do not show it.
continue;
} else if ($wasdeleted && $canviewdeleted) {
if (plugin_supports('mod', $log->modname, FEATURE_NO_VIEW_LINK, false)) {
// Better to call cm_info::has_view() because it can be dynamic.
// But there is no instance of cm_info now.
continue;
}
// Unfortunately we do not know if the mod was visible.
$modnames = get_module_types_names();
$changelist[$log->cmid] = array('action' => 'delete mod',
'module' => (object)array(
'modname' => $log->modname,
'modfullname' => isset($modnames[$log->modname]) ? $modnames[$log->modname] : $log->modname
));
} else if (!$wasdeleted && isset($modinfo->cms[$log->cmid]) && $canviewupdated) {
// Module was either added or updated during this interval and it currently exists.
// If module was both added and updated show only "add" action.
$cm = $modinfo->cms[$log->cmid];
if ($cm->has_view() && $cm->uservisible) {
$changelist[$log->cmid] = array(
'action' => $wascreated ? 'add mod' : 'update mod',
'module' => $cm
);
}
}
}
}
return $changelist;
}
/**
* Returns list of recent activity within modules
*
* For each used module type executes callback MODULE_print_recent_activity()
*
* @return array array of pairs moduletype => content
*/
protected function get_modules_recent_activity() {
$context = context_course::instance($this->page->course->id);
$viewfullnames = has_capability('moodle/site:viewfullnames', $context);
$hascontent = false;
$modinfo = get_fast_modinfo($this->page->course);
$usedmodules = $modinfo->get_used_module_names();
$recentactivity = array();
foreach ($usedmodules as $modname => $modfullname) {
// Each module gets it's own logs and prints them
ob_start();
$hascontent = component_callback('mod_'. $modname, 'print_recent_activity',
array($this->page->course, $viewfullnames, $this->get_timestart()), false);
if ($hascontent) {
$recentactivity[$modname] = ob_get_contents();
}
ob_end_clean();
}
return $recentactivity;
}
/**
* Which page types this block may appear on.
*
* @return array page-type prefix => true/false.
*/
function applicable_formats() {
return array('all' => true, 'my' => false, 'tag' => false);
}
/**
* Migrates entries from table {log} into {block_recent_activity}
*
* We only migrate logs for the courses that actually have recent activity
* block and that are being viewed within COURSE_MAX_RECENT_PERIOD time
* after the upgrade.
*
* The presence of entry in {block_recent_activity} with the cmid=0 indicates
* that the course needs log migration. Those entries were installed in
* db/upgrade.php when the table block_recent_activity was created.
*
* @param stdClass $course
*/
protected static function migrate_logs($course) {
global $DB;
if (!$logstarted = $DB->get_record('block_recent_activity',
array('courseid' => $course->id, 'cmid' => 0),
'id, timecreated')) {
return;
}
$DB->delete_records('block_recent_activity', array('id' => $logstarted->id));
try {
$logs = $DB->get_records_select('log',
"time > ? AND time < ? AND course = ? AND
module = 'course' AND
(action = 'add mod' OR action = 'update mod' OR action = 'delete mod')",
array(time()-COURSE_MAX_RECENT_PERIOD, $logstarted->timecreated, $course->id),
'id ASC', 'id, time, userid, cmid, action, info');
} catch (Exception $e) {
// Probably table {log} was already removed.
return;
}
if (!$logs) {
return;
}
$modinfo = get_fast_modinfo($course);
$entries = array();
foreach ($logs as $log) {
$info = explode(' ', $log->info);
if (count($info) != 2) {
continue;
}
$modname = $info[0];
$instanceid = $info[1];
$entry = array('courseid' => $course->id, 'userid' => $log->userid,
'timecreated' => $log->time, 'modname' => $modname);
if ($log->action == 'delete mod') {
if (!$log->cmid) {
continue;
}
$entry['action'] = 2;
$entry['cmid'] = $log->cmid;
} else {
if (!isset($modinfo->instances[$modname][$instanceid])) {
continue;
}
if ($log->action == 'add mod') {
$entry['action'] = 0;
} else {
$entry['action'] = 1;
}
$entry['cmid'] = $modinfo->instances[$modname][$instanceid]->id;
}
$entries[] = $entry;
}
$DB->insert_records('block_recent_activity', $entries);
}
}
@@ -0,0 +1,73 @@
<?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/>.
/**
* Event observer.
*
* @package block_recent_activity
* @copyright 2014 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Event observer.
* Stores all actions about modules create/update/delete in plugin own's table.
* This allows the block to avoid expensive queries to the log table.
*
* @package block_recent_activity
* @copyright 2014 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class block_recent_activity_observer {
/** @var int indicates that course module was created */
const CM_CREATED = 0;
/** @var int indicates that course module was udpated */
const CM_UPDATED = 1;
/** @var int indicates that course module was deleted */
const CM_DELETED = 2;
/**
* Store all actions about modules create/update/delete in own table.
*
* @param \core\event\base $event
*/
public static function store(\core\event\base $event) {
global $DB;
$eventdata = new \stdClass();
switch ($event->eventname) {
case '\core\event\course_module_created':
$eventdata->action = self::CM_CREATED;
break;
case '\core\event\course_module_updated':
$eventdata->action = self::CM_UPDATED;
break;
case '\core\event\course_module_deleted':
$eventdata->action = self::CM_DELETED;
$eventdata->modname = $event->other['modulename'];
break;
default:
return;
}
$eventdata->timecreated = $event->timecreated;
$eventdata->courseid = $event->courseid;
$eventdata->cmid = $event->objectid;
$eventdata->userid = $event->userid;
$DB->insert_record('block_recent_activity', $eventdata);
}
}
@@ -0,0 +1,117 @@
<?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 block_recent_activity.
*
* @package block_recent_activity
* @category privacy
* @copyright 2018 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace block_recent_activity\privacy;
use core_privacy\local\metadata\collection;
use core_privacy\local\request\approved_contextlist;
use core_privacy\local\request\contextlist;
use core_privacy\local\request\userlist;
use core_privacy\local\request\approved_userlist;
defined('MOODLE_INTERNAL') || die();
/**
* The block_recent_activity does not keep any data for more than COURSE_MAX_RECENT_PERIOD.
*
* @copyright 2018 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements
\core_privacy\local\metadata\provider,
\core_privacy\local\request\core_userlist_provider,
\core_privacy\local\request\plugin\provider {
/**
* Returns metadata.
*
* @param collection $collection The initialised collection to add items to.
* @return collection A listing of user data stored through this system.
*/
public static function get_metadata(collection $collection): collection {
// This plugin defines a db table but it is not considered personal data and, therefore, not exported or deleted.
$collection->add_database_table('block_recent_activity', [
'courseid' => 'privacy:metadata:block_recent_activity:courseid',
'cmid' => 'privacy:metadata:block_recent_activity:cmid',
'timecreated' => 'privacy:metadata:block_recent_activity:timecreated',
'userid' => 'privacy:metadata:block_recent_activity:userid',
'action' => 'privacy:metadata:block_recent_activity:action',
'modname' => 'privacy:metadata:block_recent_activity:modname'
], 'privacy:metadata:block_recent_activity');
return $collection;
}
/**
* Get the list of contexts that contain user information for the specified user.
*
* @param int $userid The user to search.
* @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin.
*/
public static function get_contexts_for_userid(int $userid): contextlist {
return new contextlist();
}
/**
* Get the list of users who have data within a context.
*
* @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination.
*/
public static function get_users_in_context(userlist $userlist) {
}
/**
* Export all user data for the specified user, in the specified contexts.
*
* @param approved_contextlist $contextlist The approved contexts to export information for.
*/
public static function export_user_data(approved_contextlist $contextlist) {
}
/**
* Delete all data for all users in the specified context.
*
* @param \context $context The specific context to delete data for.
*/
public static function delete_data_for_all_users_in_context(\context $context) {
}
/**
* Delete multiple users within a single context.
*
* @param approved_userlist $userlist The approved context and user information to delete information for.
*/
public static function delete_data_for_users(approved_userlist $userlist) {
}
/**
* Delete all user data for the specified user, in the specified contexts.
*
* @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
*/
public static function delete_data_for_user(approved_contextlist $contextlist) {
}
}
@@ -0,0 +1,61 @@
<?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/>.
/**
* Task for updating RSS feeds for rss client block
*
* @package block_recent_activity
* @author Farhan Karmali <farhan6318@gmail.com>
* @copyright Farhan Karmali 2018
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace block_recent_activity\task;
defined('MOODLE_INTERNAL') || die();
/**
* Task for updating RSS feeds for rss client block
*
* @package block_recent_activity
* @author Farhan Karmali <farhan6318@gmail.com>
* @copyright Farhan Karmali 2018
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class cleanup extends \core\task\scheduled_task {
/**
* Name for this task.
*
* @return string
*/
public function get_name() {
return get_string('cleanuptask', 'block_recent_activity');
}
/**
* Remove old entries from table block_recent_activity
*/
public function execute() {
global $CFG, $DB;
require_once("{$CFG->dirroot}/course/lib.php");
// Those entries will never be displayed as RECENT anyway.
$DB->delete_records_select('block_recent_activity', 'timecreated < ?', [
time() - COURSE_MAX_RECENT_PERIOD,
]);
}
}
+57
View File
@@ -0,0 +1,57 @@
<?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/>.
/**
* Recent activity block caps.
*
* @package block_recent_activity
* @copyright Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = array(
'block/recent_activity:addinstance' => array(
'riskbitmask' => RISK_SPAM | RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_BLOCK,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/site:manageblocks'
),
'block/recent_activity:viewaddupdatemodule' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_COURSE,
'archetypes' => array(
'user' => CAP_ALLOW
)
),
'block/recent_activity:viewdeletemodule' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_COURSE,
'archetypes' => array(
'user' => CAP_ALLOW
)
)
);
+47
View File
@@ -0,0 +1,47 @@
<?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/>.
/**
* Event observer.
*
* @package block_recent_activity
* @category event
* @copyright 2014 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$observers = array (
array (
'eventname' => '\core\event\course_module_created',
'callback' => 'block_recent_activity_observer::store',
'internal' => false, // This means that we get events only after transaction commit.
'priority' => 1000,
),
array (
'eventname' => '\core\event\course_module_updated',
'callback' => 'block_recent_activity_observer::store',
'internal' => false, // This means that we get events only after transaction commit.
'priority' => 1000,
),
array (
'eventname' => '\core\event\course_module_deleted',
'callback' => 'block_recent_activity_observer::store',
'internal' => false, // This means that we get events only after transaction commit.
'priority' => 1000,
),
);
+25
View File
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="blocks/recent_activity/db" VERSION="20140120" COMMENT="XMLDB file for Moodle blocks/recent_activity"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
<TABLES>
<TABLE NAME="block_recent_activity" COMMENT="Recent activity block">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Course id"/>
<FIELD NAME="cmid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Course module id"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="User performing the action"/>
<FIELD NAME="action" TYPE="int" LENGTH="1" NOTNULL="true" SEQUENCE="false" COMMENT="0 created, 1 updated, 2 deleted"/>
<FIELD NAME="modname" TYPE="char" LENGTH="20" NOTNULL="false" SEQUENCE="false" COMMENT="module type name (for delete action)"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="coursetime" UNIQUE="false" FIELDS="courseid, timecreated"/>
</INDEXES>
</TABLE>
</TABLES>
</XMLDB>
+39
View File
@@ -0,0 +1,39 @@
<?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/>.
/**
* Task definition for block_recent_activity.
* @author Farhan Karmali <farhan6318@gmail.com>
* @copyright Farhan Karmali 2018
* @package block_recent_activity
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$tasks = array(
array(
'classname' => '\block_recent_activity\task\cleanup',
'blocking' => 0,
'minute' => 'R',
'hour' => 'R',
'day' => '*',
'month' => '*',
'dayofweek' => '*',
'disabled' => 0
)
);
+59
View File
@@ -0,0 +1,59 @@
<?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/>.
/**
* This file keeps track of upgrades to the recent activity block
*
* Sometimes, changes between versions involve alterations to database structures
* and other major things that may break installations.
*
* The upgrade function in this file will attempt to perform all the necessary
* actions to upgrade your older installation to the current version.
*
* If there's something it cannot do itself, it will tell you what you need to do.
*
* The commands in here will all be database-neutral, using the methods of
* database_manager class
*
* Please do not forget to use upgrade_set_timeout()
* before any action that may take longer time to finish.
*
* @package block_recent_activity
* @copyright 2014 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Upgrade code for the recent activity block.
*
* @param int $oldversion
* @param object $block
*/
function xmldb_block_recent_activity_upgrade($oldversion, $block) {
// Automatically generated Moodle v4.1.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.2.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.3.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.4.0 release upgrade line.
// Put any upgrade step following this.
return true;
}
@@ -0,0 +1,38 @@
<?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 component 'block_recent_activity', language 'en', branch 'MOODLE_20_STABLE'
*
* @package block_recent_activity
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['cleanuptask'] = 'Cleanup task for recent activity block';
$string['pluginname'] = 'Recent activity';
$string['privacy:metadata'] = 'The recent activity block contains a cache of data stored elsewhere in Moodle.';
$string['privacy:metadata:block_recent_activity'] = 'Temporary log of recent teacher activity. Removed after two days';
$string['privacy:metadata:block_recent_activity:action'] = 'Action: created, updated or deleted';
$string['privacy:metadata:block_recent_activity:cmid'] = 'Course activity ID';
$string['privacy:metadata:block_recent_activity:courseid'] = 'Course ID';
$string['privacy:metadata:block_recent_activity:modname'] = 'Module type name (for delete action)';
$string['privacy:metadata:block_recent_activity:timecreated'] = 'Time when action was performed';
$string['privacy:metadata:block_recent_activity:userid'] = 'User performing the action';
$string['recent_activity:addinstance'] = 'Add a new recent activity block';
$string['recent_activity:viewaddupdatemodule'] = 'View added and updated modules in recent activity block';
$string['recent_activity:viewdeletemodule'] = 'View deleted modules in recent activity block';
+128
View File
@@ -0,0 +1,128 @@
<?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/>.
/**
* Renderer for block recent_activity
*
* @package block_recent_activity
* @copyright 2012 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
/**
* recent_activity block rendrer
*
* @package block_recent_activity
* @copyright 2012 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class block_recent_activity_renderer extends plugin_renderer_base {
/**
* Renders HTML to display recent_activity block
*
* @param stdClass $course
* @param int $timestart
* @param array $recentenrolments array of changes in enrolments
* @param array $structuralchanges array of changes in course structure
* @param array $modulesrecentactivity array of changes in modules (provided by modules)
* @return string
*/
public function recent_activity($course, $timestart, $recentenrolments, $structuralchanges,
$modulesrecentactivity) {
$output = html_writer::tag('div',
get_string('activitysince', '', userdate($timestart)),
array('class' => 'activityhead'));
$output .= html_writer::tag('div',
html_writer::link(new moodle_url('/course/recent.php', array('id' => $course->id)),
get_string('recentactivityreport')),
array('class' => 'activityhead mb-3'));
$content = false;
// Firstly, have there been any new enrolments?
if ($recentenrolments) {
$content = true;
$context = context_course::instance($course->id);
$viewfullnames = has_capability('moodle/site:viewfullnames', $context);
$output .= html_writer::start_tag('div', array('class' => 'newusers'));
$output .= $this->heading(get_string("newusers").':', 3);
//Accessibility: new users now appear in an <OL> list.
$output .= html_writer::start_tag('ol', array('class' => 'list'));
foreach ($recentenrolments as $user) {
$output .= html_writer::tag('li',
html_writer::link(new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $course->id)),
fullname($user, $viewfullnames)),
array('class' => 'name'));
}
$output .= html_writer::end_tag('ol');
$output .= html_writer::end_tag('div');
}
// Next, have there been any modifications to the course structure?
if (!empty($structuralchanges)) {
$content = true;
$output .= $this->heading(get_string("courseupdates") . ':', 6);
foreach ($structuralchanges as $changeinfo => $change) {
$output .= $this->structural_change($change);
}
}
// Now display new things from each module
foreach ($modulesrecentactivity as $modname => $moduleactivity) {
$content = true;
$output .= $moduleactivity;
}
if (! $content) {
$output .= html_writer::tag('p', get_string('nothingnew'), array('class' => 'message'));
}
return $output;
}
/**
* Renders HTML for one change in course structure
*
* @see block_recent_activity::get_structural_changes()
* @param array $change array containing attributes
* 'action' - one of: 'add mod', 'update mod', 'delete mod'
* 'module' - instance of cm_info (for 'delete mod' it is an object with attributes modname and modfullname)
* @return string
*/
protected function structural_change($change) {
$cm = $change['module'];
switch ($change['action']) {
case 'delete mod':
$text = get_string('deletedactivity', 'moodle', $cm->modfullname);
break;
case 'add mod':
$text = get_string('added', 'moodle', $cm->modfullname). '<br />'.
html_writer::link($cm->url, format_string($cm->name, true));
break;
case 'update mod':
$text = get_string('updated', 'moodle', $cm->modfullname). '<br />'.
html_writer::link($cm->url, format_string($cm->name, true));
break;
default:
return '';
}
return html_writer::tag('p', $text, array('class' => 'activity'));
}
}
+7
View File
@@ -0,0 +1,7 @@
.block_recent_activity .unlist li {
margin-bottom: 1em;
}
.block_recent_activity li .head .date {
float: right;
}
@@ -0,0 +1,203 @@
@block @block_recent_activity
Feature: View structural changes in recent activity block
In order to know when activities were changed
As a user
In need to see the structural changes in recent activity block
Background:
Given the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Terry1 | Teacher1 | teacher1@example.com |
| assistant1 | Terry2 | Teacher2 | teacher2@example.com |
| student1 | Sam1 | Student1 | student1@example.com |
| student2 | Sam2 | Student2 | student2@example.com |
| student3 | Sam3 | Student3 | student3@example.com |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| assistant1 | C1 | teacher |
| student1 | C1 | student |
| student2 | C1 | student |
| student3 | C1 | student |
And the following "groups" exist:
| name | course | idnumber |
| Group 1 | C1 | G1 |
| Group 2 | C1 | G2 |
And the following "groupings" exist:
| name | course | idnumber |
| Grouping 1 | C1 | GG1 |
| Grouping 2 | C1 | GG2 |
| Grouping 3 | C1 | GG3 |
And the following "group members" exist:
| user | group |
| student1 | G1 |
| student2 | G2 |
| student3 | G1 |
| student3 | G2 |
| assistant1 | G1 |
And the following "grouping groups" exist:
| grouping | group |
| GG1 | G1 |
| GG2 | G2 |
| GG3 | G1 |
| GG3 | G2 |
Scenario: Check that Added module information is displayed respecting view capability
Given the following "activities" exist:
| activity | course | name | idnumber | groupmode | grouping | visible |
| forum | C1 | ForumVisibleGroups | forum1 | 2 | | 1 |
| forum | C1 | ForumSeparateGroups | forum2 | 1 | | 1 |
| forum | C1 | ForumHidden | forum3 | 1 | | 0 |
| forum | C1 | ForumNoGroups | forum4 | 0 | | 1 |
| forum | C1 | ForumVisibleGroupsG1 | forum5 | 2 | GG1 | 1 |
| forum | C1 | ForumSeparateGroupsG1 | forum6 | 1 | GG1 | 1 |
| forum | C1 | ForumVisibleGroupsG2 | forum7 | 2 | GG2 | 1 |
| forum | C1 | ForumSeparateGroupsG2 | forum8 | 1 | GG2 | 1 |
And I am on the "ForumVisibleGroupsG1" "forum activity editing" page logged in as teacher1
And I set the following fields to these values:
| Access restrictions | Grouping: Grouping 1 |
And I press "Save and return to course"
And I am on the "ForumSeparateGroupsG1" "forum activity editing" page
And I set the following fields to these values:
| Access restrictions | Grouping: Grouping 1 |
And I press "Save and return to course"
And I am on the "ForumVisibleGroupsG2" "forum activity editing" page
And I set the following fields to these values:
| Access restrictions | Grouping: Grouping 2 |
And I press "Save and return to course"
And I am on the "ForumSeparateGroupsG2" "forum activity editing" page
And I set the following fields to these values:
| Access restrictions | Grouping: Grouping 2 |
And I press "Save and return to course"
And I am on "Course 1" course homepage with editing mode on
When I add the "Recent activity" block
Then I should see "ForumVisibleGroups" in the "Recent activity" "block"
And I should see "ForumSeparateGroups" in the "Recent activity" "block"
And I should see "ForumNoGroups" in the "Recent activity" "block"
And I should see "ForumHidden" in the "Recent activity" "block"
And I should see "ForumVisibleGroupsG1" in the "Recent activity" "block"
And I should see "ForumSeparateGroupsG1" in the "Recent activity" "block"
And I should see "ForumVisibleGroupsG2" in the "Recent activity" "block"
And I should see "ForumSeparateGroupsG2" in the "Recent activity" "block"
And I am on the "Course 1" course page logged in as student1
And I should see "ForumVisibleGroups" in the "Recent activity" "block"
And I should see "ForumSeparateGroups" in the "Recent activity" "block"
And I should see "ForumNoGroups" in the "Recent activity" "block"
And I should not see "ForumHidden" in the "Recent activity" "block"
And I should see "ForumVisibleGroupsG1" in the "Recent activity" "block"
And I should see "ForumSeparateGroupsG1" in the "Recent activity" "block"
And I should not see "ForumVisibleGroupsG2" in the "Recent activity" "block"
And I should not see "ForumSeparateGroupsG2" in the "Recent activity" "block"
And I am on the "Course 1" course page logged in as student2
And I should see "ForumVisibleGroups" in the "Recent activity" "block"
And I should see "ForumSeparateGroups" in the "Recent activity" "block"
And I should see "ForumNoGroups" in the "Recent activity" "block"
And I should not see "ForumHidden" in the "Recent activity" "block"
And I should not see "ForumVisibleGroupsG1" in the "Recent activity" "block"
And I should not see "ForumSeparateGroupsG1" in the "Recent activity" "block"
And I should see "ForumVisibleGroupsG2" in the "Recent activity" "block"
And I should see "ForumSeparateGroupsG2" in the "Recent activity" "block"
And I am on the "Course 1" course page logged in as student3
And I should see "ForumVisibleGroups" in the "Recent activity" "block"
And I should see "ForumSeparateGroups" in the "Recent activity" "block"
And I should see "ForumNoGroups" in the "Recent activity" "block"
And I should not see "ForumHidden" in the "Recent activity" "block"
And I should see "ForumVisibleGroupsG1" in the "Recent activity" "block"
And I should see "ForumSeparateGroupsG1" in the "Recent activity" "block"
And I should see "ForumVisibleGroupsG2" in the "Recent activity" "block"
And I should see "ForumSeparateGroupsG2" in the "Recent activity" "block"
# Teachers have capability to see all groups and hidden activities
And I am on the "Course 1" course page logged in as assistant1
And I should see "ForumHidden" in the "Recent activity" "block"
And I should see "ForumVisibleGroupsG1" in the "Recent activity" "block"
And I should see "ForumSeparateGroupsG1" in the "Recent activity" "block"
And I should see "ForumVisibleGroupsG2" in the "Recent activity" "block"
And I should see "ForumSeparateGroupsG2" in the "Recent activity" "block"
Scenario: Updates and deletes in recent activity block
Given the following "activity" exists:
| activity | forum |
| course | C1 |
| idnumber | forum1 |
| name | ForumNew |
When I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I add the "Recent activity" block
Then I should see "Added Forum" in the "Recent activity" "block"
And I should see "ForumNew" in the "Recent activity" "block"
And I log out
# Update forum as a teacher after a second to ensure we have a new timestamp for recent activity.
And I wait "1" seconds
And I am on the "Course 1" course page logged in as student1
And I should see "Added Forum" in the "Recent activity" "block"
And I should see "ForumNew" in the "Recent activity" "block"
And I log out
# Update forum as a teacher after a second to ensure we have a new timestamp for recent activity.
And I wait "1" seconds
# Update forum as a teacher
And I am on the "ForumNew" "forum activity editing" page logged in as teacher1
And I set the following fields to these values:
| name | ForumUpdated |
And I press "Save and return to course"
And I log out
And I wait "1" seconds
# Student 1 already saw that forum was created, now he can see that forum was updated
And I am on the "Course 1" course page logged in as student1
And I should not see "Added Forum" in the "Recent activity" "block"
And I should not see "ForumNew" in the "Recent activity" "block"
And I should see "Updated Forum" in the "Recent activity" "block"
And I should see "ForumUpdated" in the "Recent activity" "block"
And I log out
And I wait "1" seconds
# Student 2 has bigger interval and he can see one entry that forum was created but with the new name
And I am on the "Course 1" course page logged in as student2
And I should see "Added Forum" in the "Recent activity" "block"
And I should not see "ForumNew" in the "Recent activity" "block"
And I should not see "Updated Forum" in the "Recent activity" "block"
And I should see "ForumUpdated" in the "Recent activity" "block"
And I log out
And I wait "1" seconds
# Delete forum as a teacher
And I log in as "teacher1"
And I am on "Course 1" course homepage with editing mode on
And I delete "ForumUpdated" activity
And I run all adhoc tasks
And I log out
And I wait "1" seconds
# Students 1 and 2 see that forum was deleted
And I am on the "Course 1" course page logged in as student1
And I should not see "Added Forum" in the "Recent activity" "block"
And I should not see "ForumNew" in the "Recent activity" "block"
And I should not see "Updated Forum" in the "Recent activity" "block"
And I should not see "ForumUpdated" in the "Recent activity" "block"
And I should see "Deleted Forum" in the "Recent activity" "block"
And I log out
And I wait "1" seconds
# Student 3 never knew that forum was created, so he does not see anything
And I am on the "Course 1" course page logged in as student3
And I should not see "Added Forum" in the "Recent activity" "block"
And I should not see "ForumNew" in the "Recent activity" "block"
And I should not see "Updated Forum" in the "Recent activity" "block"
And I should not see "ForumUpdated" in the "Recent activity" "block"
And I should not see "Deleted Forum" in the "Recent activity" "block"
+29
View File
@@ -0,0 +1,29 @@
<?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/>.
/**
* Version details
*
* @package block_recent_activity
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024042200; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2024041600; // Requires this Moodle version.
$plugin->component = 'block_recent_activity'; // Full name of the plugin (used for diagnostics)