MDL-37658 add new logging API with basic implemenation

This commit is contained in:
Petr Škoda 2014-01-13 09:08:58 +08:00
parent 76e4de31cc
commit 7eaca5a810
42 changed files with 2168 additions and 172 deletions

View File

@ -137,21 +137,6 @@ $temp->add(new admin_setting_configselect('deleteincompleteusers', new lang_stri
48 => new lang_string('numdays', '', 2),
24 => new lang_string('numdays', '', 1))));
$temp->add(new admin_setting_configcheckbox('logguests', new lang_string('logguests', 'admin'),
new lang_string('logguests_help', 'admin'), 1));
$temp->add(new admin_setting_configselect('loglifetime', new lang_string('loglifetime', 'admin'), new lang_string('configloglifetime', 'admin'), 0, array(0 => new lang_string('neverdeletelogs'),
1000 => new lang_string('numdays', '', 1000),
365 => new lang_string('numdays', '', 365),
180 => new lang_string('numdays', '', 180),
150 => new lang_string('numdays', '', 150),
120 => new lang_string('numdays', '', 120),
90 => new lang_string('numdays', '', 90),
60 => new lang_string('numdays', '', 60),
35 => new lang_string('numdays', '', 35),
10 => new lang_string('numdays', '', 10),
5 => new lang_string('numdays', '', 5),
2 => new lang_string('numdays', '', 2))));
$temp->add(new admin_setting_configcheckbox('disablegradehistory', new lang_string('disablegradehistory', 'grades'),
new lang_string('disablegradehistory_help', 'grades'), 0));

View File

@ -0,0 +1,166 @@
<?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/>.
/**
* Log store manager.
*
* @package tool_log
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_log\log;
defined('MOODLE_INTERNAL') || die();
class manager implements \core\log\manager {
/** @var \core\log\reader[] $readers list of initialised log readers */
protected $readers;
/** @var \tool_log\log\writer[] $writers list of initialised log writers */
protected $writers;
/** @var \tool_log\log\store[] $stores */
protected $stores;
/**
* Delayed initialisation of singleton.
*/
protected function init() {
if (isset($this->stores)) {
// Do not bother checking readers and writers here
// because everything is init here.
return;
}
$this->stores = array();
$this->readers = array();
$this->writers = array();
// Register shutdown handler - this may be useful for buffering, file handle closing, etc.
\core_shutdown_manager::register_function(array($this, 'dispose'));
$plugins = get_config('tool_log', 'enabled_stores');
if (empty($plugins)) {
return;
}
$plugins = explode(',', $plugins);
foreach ($plugins as $plugin) {
$classname = "\\$plugin\\log\\store";
if (class_exists($classname)) {
$store = new $classname($this);
$this->stores[$plugin] = $store;
if ($store instanceof \tool_log\log\writer) {
$this->writers[$plugin] = $store;
}
if ($store instanceof \core\log\reader) {
$this->readers[$plugin] = $store;
}
}
}
}
/**
* Called from the observer only.
*
* @param \core\event\base $event
*/
public function process(\core\event\base $event) {
$this->init();
foreach ($this->writers as $plugin => $writer) {
try {
$writer->write($event, $this);
} catch (\Exception $e) {
debugging('Exception detected when logging event '.$event->eventname.' in '.$plugin.': '.$e->getMessage(), DEBUG_NORMAL, $e->getTrace());
}
}
}
/**
* Returns list of available log readers.
*
* This way the reports find out available sources of data.
*
* @param \context $context
* @return \core\log\reader[] list of available log data readers
*/
public function get_readers(\context $context) {
$this->init();
$return = array();
foreach ($this->readers as $plugin => $reader) {
if ($reader->can_access($context)) {
$return[$plugin] = $reader;
}
}
return $return;
}
/**
* Intended for store management, do not use from reports.
*
* @return store[] Returns list of available store plugins.
*/
public static function get_store_plugins() {
return \core_component::get_plugin_list_with_class('logstore', 'log\store');
}
/**
* Usually called automatically from shutdown manager,
* this allows us to implement buffering of write operations.
*/
public function dispose() {
if ($this->stores) {
foreach ($this->stores as $store) {
$store->dispose();
}
}
$this->stores = null;
$this->readers = null;
$this->writers = null;
}
/**
* Execute cron actions.
*/
public function cron() {
$this->init();
foreach ($this->stores['legacy'] as $store) {
$store->cron();
}
}
/**
* Legacy add_to_log() redirection.
*
* To be used only from deprecated add_to_log() function and event trigger() method.
*
* NOTE: this is hardcoded to legacy log store plugin, hopefully we can get rid of it soon.
*
* @param int $courseid The course id
* @param string $module The module name e.g. forum, journal, resource, course, user etc
* @param string $action 'view', 'update', 'add' or 'delete', possibly followed by another word to clarify.
* @param string $url The file and parameters used to see the results of the action
* @param string $info Additional description information
* @param int $cm The course_module->id if there is one
* @param int|\stdClass $user If log regards $user other than $USER
*/
public function legacy_add_to_log($courseid, $module, $action, $url='', $info='', $cm=0, $user=0) {
$this->init();
if (isset($this->stores['legacy'])) {
$this->stores['legacy']->legacy_add_to_log($courseid, $module, $action, $url, $info, $cm, $user);
}
}
}

View File

@ -0,0 +1,43 @@
<?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 tool_log
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_log\log;
defined('MOODLE_INTERNAL') || die();
class observer {
/**
* Redirect all events to this log manager, but only if this
* log manager is actually used.
*
* @param \core\event\base $event
*/
public static function store(\core\event\base $event) {
$logmanager = get_log_manager();
if (get_class($logmanager) === 'tool_log\log\manager') {
/** @var \tool_log\log\manager $logmanager */
$logmanager->process($event);
}
}
}

View File

@ -0,0 +1,49 @@
<?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/>.
/**
* Log store interface.
*
* @package tool_log
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_log\log;
defined('MOODLE_INTERNAL') || die();
interface store {
/**
* Create new instance of store,
* the calling code must make sure only one instance exists.
*
* @param manager $manager
*/
public function __construct(\tool_log\log\manager $manager);
/**
* Notify store no more events are going to be written/read from it.
* @return void
*/
public function dispose();
/**
* Execute cron actions.
* @return void
*/
public function cron();
}

View File

@ -0,0 +1,37 @@
<?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/>.
/**
* Log store writer interface.
*
* @package core
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_log\log;
defined('MOODLE_INTERNAL') || die();
interface writer extends store {
/**
* Write one event to the store.
*
* @param \core\event\base $event
* @return void
*/
public function write(\core\event\base $event);
}

View File

@ -0,0 +1,89 @@
<?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/>.
/**
* Subplugin info class.
*
* @package tool_log
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_log\plugininfo;
use core\plugininfo\base, moodle_url, part_of_admin_tree, admin_settingpage;
defined('MOODLE_INTERNAL') || die();
/**
* Plugin info class for logging store plugins.
*/
class logstore extends base {
public function is_enabled() {
$enabled = get_config('tool_log', 'enabled_stores');
if (!$enabled) {
return false;
}
$enabled = array_flip(explode(',', $enabled));
return isset($enabled['logstore_'.$this->name]);
}
public function get_settings_section_name() {
return 'logsetting' . $this->name;
}
public function load_settings(part_of_admin_tree $adminroot, $parentnodename, $hassiteconfig) {
global $CFG, $USER, $DB, $OUTPUT, $PAGE; // In case settings.php wants to refer to them.
$ADMIN = $adminroot; // May be used in settings.php.
$section = $this->get_settings_section_name();
if (!$this->is_installed_and_upgraded()) {
return;
}
if (!$hassiteconfig or !file_exists($this->full_path('settings.php'))) {
return;
}
$settings = new admin_settingpage($section, $this->displayname, 'moodle/site:config', $this->is_enabled() === false);
include($this->full_path('settings.php'));
if ($settings) {
$ADMIN->add($parentnodename, $settings);
}
}
public static function get_manage_url() {
return new moodle_url('/admin/settings.php', array('section'=>'managelogging'));
}
public function is_uninstall_allowed() {
return true;
}
public function uninstall_cleanup() {
$enabled = get_config('tool_log', 'enabled_stores');
if ($enabled) {
$enabled = array_flip(explode(',', $enabled));
unset($enabled['logstore_'.$this->name]);
$enabled = array_flip($enabled);
set_config('enabled_stores', implode(',', $enabled), 'tool_log');
}
parent::uninstall_cleanup();
}
}

View File

@ -0,0 +1,229 @@
<?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/>.
/**
* Store management setting.
*
* @package tool_log
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once("$CFG->libdir/adminlib.php");
class tool_log_setting_managestores extends admin_setting {
/**
* Calls parent::__construct with specific arguments
*/
public function __construct() {
$this->nosave = true;
parent::__construct('tool_log_manageui', get_string('managelogging', 'tool_log'), '', '');
}
/**
* Always returns true, does nothing.
*
* @return true
*/
public function get_setting() {
return true;
}
/**
* Always returns true, does nothing.
*
* @return true
*/
public function get_defaultsetting() {
return true;
}
/**
* Always returns '', does not write anything.
*
* @param mixed $data ignored
* @return string Always returns ''
*/
public function write_setting($data) {
// Do not write any setting.
return '';
}
/**
* Checks if $query is one of the available log plugins.
*
* @param string $query The string to search for
* @return bool Returns true if found, false if not
*/
public function is_related($query) {
if (parent::is_related($query)) {
return true;
}
$query = core_text::strtolower($query);
$plugins = \tool_log\log\manager::get_store_plugins();
foreach ($plugins as $plugin => $fulldir) {
if (strpos(core_text::strtolower($plugin), $query) !== false) {
return true;
}
$localised = get_string('pluginname', $plugin);
if (strpos(core_text::strtolower($localised), $query) !== false) {
return true;
}
}
return false;
}
/**
* Builds the XHTML to display the control.
*
* @param string $data Unused
* @param string $query
* @return string
*/
public function output_html($data, $query='') {
global $OUTPUT, $PAGE;
// Display strings.
$strup = get_string('up');
$strdown = get_string('down');
$strsettings = get_string('settings');
$strenable = get_string('enable');
$strdisable = get_string('disable');
$struninstall = get_string('uninstallplugin', 'core_admin');
$strversion = get_string('version');
$pluginmanager = core_plugin_manager::instance();
$available = \tool_log\log\manager::get_store_plugins();
$enabled = get_config('tool_log', 'enabled_stores');
if (!$enabled) {
$enabled = array();
} else {
$enabled = array_flip(explode(',', $enabled));
}
$allstores = array();
foreach ($enabled as $key => $store) {
$allstores[$key] = true;
$enabled[$key] = true;
}
foreach ($available as $key => $store) {
$allstores[$key] = true;
$available[$key] = true;
}
$return = $OUTPUT->heading(get_string('actlogshdr', 'tool_log'), 3, 'main', true);
$return .= $OUTPUT->box_start('generalbox loggingui');
$table = new html_table();
$table->head = array(get_string('name'), $strversion, $strenable, $strup.'/'.$strdown, $strsettings, $struninstall);
$table->colclasses = array('leftalign', 'centeralign', 'centeralign', 'centeralign', 'centeralign', 'centeralign');
$table->id = 'logstoreplugins';
$table->attributes['class'] = 'admintable generaltable';
$table->data = array();
// Iterate through store plugins and add to the display table.
$updowncount = 1;
$storecount = count($enabled);
$url = new moodle_url('/admin/tool/log/stores.php', array('sesskey'=>sesskey()));
$printed = array();
foreach ($allstores as $store => $unused) {
$plugininfo = $pluginmanager->get_plugin_info($store);
$version = get_config($store, 'version');
if ($version === false) {
$version = '';
}
if (get_string_manager()->string_exists('pluginname', $store)) {
$name = get_string('pluginname', $store);
} else {
$name = $store;
}
// Hide/show links.
if (isset($enabled[$store])) {
$aurl = new moodle_url($url, array('action'=>'disable', 'store'=>$store));
$hideshow = "<a href=\"$aurl\">";
$hideshow .= "<img src=\"" . $OUTPUT->pix_url('t/hide') . "\" class=\"iconsmall\" alt=\"$strdisable\" /></a>";
$isenabled = true;
$displayname = "<span>$name</span>";
} else if (isset($available[$store])) {
$aurl = new moodle_url($url, array('action'=>'enable', 'store'=>$store));
$hideshow = "<a href=\"$aurl\">";
$hideshow .= "<img src=\"" . $OUTPUT->pix_url('t/show') . "\" class=\"iconsmall\" alt=\"$strenable\" /></a>";
$isenabled = false;
$displayname = "<span class=\"dimmed_text\">$name</span>";
} else {
$hideshow = '';
$isenabled = false;
$displayname = '<span class="notifyproblem">'.$name.'</span>';
}
if ($PAGE->theme->resolve_image_location('icon', $store, false)) {
$icon = $OUTPUT->pix_icon('icon', '', $store, array('class' => 'icon pluginicon'));
} else {
$icon = $OUTPUT->pix_icon('spacer', '', 'moodle', array('class' => 'icon pluginicon noicon'));
}
// Up/down link (only if store is enabled).
$updown = '';
if ($isenabled) {
if ($updowncount > 1) {
$aurl = new moodle_url($url, array('action'=>'up', 'store'=>$store));
$updown .= "<a href=\"$aurl\">";
$updown .= "<img src=\"" . $OUTPUT->pix_url('t/up') . "\" alt=\"$strup\" class=\"iconsmall\" /></a>&nbsp;";
} else {
$updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"iconsmall\" alt=\"\" />&nbsp;";
}
if ($updowncount < $storecount) {
$aurl = new moodle_url($url, array('action'=>'down', 'store'=>$store));
$updown .= "<a href=\"$aurl\">";
$updown .= "<img src=\"" . $OUTPUT->pix_url('t/down') . "\" alt=\"$strdown\" class=\"iconsmall\" /></a>";
} else {
$updown .= "<img src=\"" . $OUTPUT->pix_url('spacer') . "\" class=\"iconsmall\" alt=\"\" />";
}
++$updowncount;
}
// Add settings link.
if (!$version) {
$settings = '';
} else if ($surl = $plugininfo->get_settings_url()) {
$settings = html_writer::link($surl, $strsettings);
} else {
$settings = '';
}
// Add uninstall info.
$uninstall = '';
if ($uninstallurl = core_plugin_manager::instance()->get_uninstall_url($store, 'manage')) {
$uninstall = html_writer::link($uninstallurl, $struninstall);
}
// Add a row to the table.
$table->data[] = array($icon.$displayname, $version, $hideshow, $updown, $settings, $uninstall);
$printed[$store] = true;
}
$return .= html_writer::table($table);
$return .= get_string('configlogplugins', 'tool_log').'<br />'.get_string('tablenosave', 'admin');
$return .= $OUTPUT->box_end();
return highlight($query, $return);
}
}

View File

@ -0,0 +1,35 @@
<?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 tool_log
* @category event
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$observers = array (
array (
'eventname' => '*',
'callback' => '\tool_log\log\observer::store',
'internal' => false, // This means that we get events only after transaction commit.
'priority' => 1000,
),
);

View File

@ -0,0 +1,41 @@
<?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/>.
/**
* Logging support.
*
* @package tool_log
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
function xmldb_tool_log_install() {
global $CFG;
$enabled = array();
if (file_exists("$CFG->dirroot/$CFG->admin/tool/log/store/standard")) {
$enabled[] = 'logstore_standard';
}
if (file_exists("$CFG->dirroot/$CFG->admin/tool/log/store/legacy")) {
$enabled[] = 'logstore_legacy';
}
set_config('enabled_stores', implode(',', $enabled), 'tool_log');
}

View File

@ -0,0 +1,24 @@
<?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/>.
/**
* Logging subplugins.
*
* @package tool_log
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$subplugins = array('logstore'=>'admin/tool/log/store');

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/>.
/**
* Store management UI lang strings.
*
* @package tool_log
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['actlogshdr'] = 'Available log stores';
$string['configlogplugins'] = 'Please enable all required plugins and arrange then in appropriate order.';
$string['logging'] = 'Logging';
$string['managelogging'] = 'Manage log stores';
$string['pluginname'] = 'Log store manager';

37
admin/tool/log/lib.php Normal file
View File

@ -0,0 +1,37 @@
<?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/>.
/**
* Log tool API.
*
* @package tool_log
* @copyright 2014 Petr Skoda {@link http://skodak.org/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
/**
* Execute cron actions.
*/
function tool_log_cron() {
// Execute cron only if this log manager used.
$logmanager = get_log_manager();
if (get_class($logmanager) === 'tool_log\log\manager') {
/** @var \tool_log\log\manager $logmanager */
$logmanager->cron();
}
}

View File

@ -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/>.
/**
* Logging settings.
*
* @package tool_log
* @copyright 2013 Petr Skoda {@link http://skodak.org/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
if ($hassiteconfig) {
$ADMIN->add('modules', new admin_category('logging', new lang_string('logging', 'tool_log')));
$temp = new admin_settingpage('managelogging', new lang_string('managelogging', 'tool_log'));
$temp->add(new tool_log_setting_managestores());
$ADMIN->add('logging', $temp);
foreach (core_plugin_manager::instance()->get_plugins_of_type('logstore') as $plugin) {
/** @var \tool_log\plugininfo\logstore $plugin */
$plugin->load_settings($ADMIN, 'logging', $hassiteconfig);
}
}

View File

@ -0,0 +1,114 @@
<?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/>.
/**
* External database writer.
*
* @package logstore_database
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace logstore_database\log;
defined('MOODLE_INTERNAL') || die();
class store implements \tool_log\log\writer {
/** @var \tool_log\log\manager $manager */
protected $manager;
/** @var \moodle_database $extdb */
protected $extdb;
public function __construct(\tool_log\log\manager $manager) {
$this->manager = $manager;
}
protected function init() {
if (isset($this->extdb)) {
return !empty($this->extdb);
}
$dbdriver = $this->get_config('dbdriver');
if (!$dbdriver) {
$this->extdb = false;
return false;
}
list($dbtype, $dblibrary) = explode('/', $dbdriver);
if (!$db = \moodle_database::get_driver_instance($dbtype, $dblibrary, true)) {
debugging("Unknown driver $dblibrary/$dbtype", DEBUG_DEVELOPER);
$this->extdb = false;
return false;
}
$dboptions = array();
$dboptions['dbpersist'] = $this->get_config('dbpersist', '0');
$dboptions['dbsocket'] = $this->get_config('dbsocket', '');
$dboptions['dbport'] = $this->get_config('dbport', '');
$dboptions['dbschema'] = $this->get_config('dbschema', '');
$dboptions['dbcollation'] = $this->get_config('dbcollation', '');
try {
$db->connect($this->get_config('dbhost'), $this->get_config('dbuser'), $this->get_config('dbpass'),
$this->get_config('dbname'), $this->get_config('dbprefix'), $dboptions);
} catch (\moodle_exception $e) {
debugging('Cannot connect to external database: '.$e->getMessage(), DEBUG_DEVELOPER);
$this->extdb = false;
return false;
}
$this->extdb = $db;
return true;
}
protected function get_config($name, $default = null) {
$value = \get_config('logstore_database', $name);
if ($value !== false) {
return $value;
}
return $default;
}
public function write(\core\event\base $event) {
if (!$this->init()) {
return;
}
if (!$dbtable = $this->get_config('dbtable')) {
return;
}
$data = $event->get_data();
if (CLI_SCRIPT) {
$data['origin'] = 'cli';
} else {
$data['origin'] = getremoteaddr();
}
$data['realuserid'] = \core\session\manager::is_loggedinas() ? $_SESSION['USER']->realuser : null;
$this->extdb->insert_record($dbtable, $data);
}
public function cron() {
}
public function dispose() {
if ($this->extdb) {
$this->extdb->dispose();
}
$this->extdb = null;
}
}

View File

@ -0,0 +1,26 @@
<?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/>.
/**
* Log store lang strings.
*
* @package logstore_database
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['pluginname'] = 'External database log';
$string['pluginname_desc'] = 'External database log plugin, the data is stored in external database table.';

View File

@ -0,0 +1,54 @@
<?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/>.
/**
* External database log store settings.
*
* @package logstore_database
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
if ($hassiteconfig) {
$options = array(
'' => get_string('choose'),
'native/mysqli' => moodle_database::get_driver_instance('mysqli', 'native')->get_name(),
'native/mariadb'=> moodle_database::get_driver_instance('mariadb', 'native')->get_name(),
'native/pgsql' => moodle_database::get_driver_instance('pgsql', 'native')->get_name(),
'native/oci' => moodle_database::get_driver_instance('oci', 'native')->get_name(),
'native/sqlsrv' => moodle_database::get_driver_instance('sqlsrv', 'native')->get_name(),
'native/mssql' => moodle_database::get_driver_instance('mssql', 'native')->get_name(),
);
// TODO: Localise these settings.
$settings->add(new admin_setting_configselect('logstore_database/dbdriver', 'dbdriver', '', '', $options));
$settings->add(new admin_setting_configtext('logstore_database/dbhost', 'dbhost', '', ''));
$settings->add(new admin_setting_configtext('logstore_database/dbuser', 'dbuser', '', ''));
$settings->add(new admin_setting_configtext('logstore_database/dbpass', 'dbpass', '', ''));
$settings->add(new admin_setting_configtext('logstore_database/dbname', 'dbname', '', ''));
$settings->add(new admin_setting_configtext('logstore_database/dbname', 'dbprefix', '', ''));
$settings->add(new admin_setting_configcheckbox('logstore_database/dbpersist', 'dbpersist', '', '0'));
$settings->add(new admin_setting_configtext('logstore_database/dbsocket', 'dbsocket', '', ''));
$settings->add(new admin_setting_configtext('logstore_database/dbport', 'dbport', '', ''));
$settings->add(new admin_setting_configtext('logstore_database/dbschema', 'dbschema', '', ''));
$settings->add(new admin_setting_configtext('logstore_database/dbcollation', 'dbcollation', '', ''));
}

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/>.
/**
* External database log store.
*
* @package logstore_standard
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2014011300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2014011000; // Requires this Moodle version.
$plugin->component = 'logstore_database'; // Full name of the plugin (used for diagnostics).

View File

@ -0,0 +1,53 @@
<?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/>.
namespace logstore_legacy\event;
defined('MOODLE_INTERNAL') || die();
/**
* Legacy log emulation event class.
*
* @package core
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class legacy_logged extends \core\event\base {
public function init() {
throw new \coding_exception('legacy events cannot be triggered');
}
public static function get_name() {
return get_string('event_legacy_logged', 'logstore_legacy');
}
public function get_description() {
return $this->other['module'].' '.$this->other['action'].' '.$this->other['info'];
}
public function get_url() {
global $CFG;
require_once("$CFG->dirroot/course/lib.php");
$url = \make_log_url($this->other['module'], $this->other['url']);
if (!$url) {
return null;
}
return new \moodle_url($url);
}
}

View File

@ -0,0 +1,191 @@
<?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/>.
/**
* Legacy log reader.
*
* @package logstore_legacy
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace logstore_legacy\log;
defined('MOODLE_INTERNAL') || die();
class store implements \tool_log\log\store, \core\log\reader {
public function __construct(\tool_log\log\manager $manager) {
}
public function get_name() {
return get_string('pluginname', 'logstore_legacy');
}
public function get_description() {
return get_string('pluginname_desc', 'logstore_legacy');
}
public function can_access(\context $context) {
return has_capability('logstore/legacy:read', $context);
}
public function get_events($selectwhere, array $params, $sort, $limitfrom, $limitnum) {
global $DB;
$selectwhere = str_replace('timecreated', 'time', $selectwhere);
$sort = str_replace('timecreated', 'time', $sort);
$events = array();
try {
$records = $DB->get_records_select('log', $selectwhere, $params, $sort, '*', $limitfrom, $limitnum);
} catch (\moodle_exception $ex) {
debugging("error converting legacy event data", $ex->getMessage().$ex->debuginfo);
}
foreach ($records as $data) {
$events[$data->id] = \logstore_legacy\event\legacy_logged::restore_legacy($data);
}
return $events;
}
public function get_events_count($selectwhere, array $params) {
global $DB;
$selectwhere = str_replace('timecreated', 'time', $selectwhere);
try {
return $DB->count_records_select('log', $selectwhere, $params);
} catch (\moodle_exception $ex) {
debugging("error converting legacy event data", $ex->getMessage().$ex->debuginfo);
return 0;
}
}
public function cron() {
global $CFG, $DB;
// Delete old logs to save space (this might need a timer to slow it down...).
if (!empty($CFG->loglifetime)) { // value in days
$loglifetime = time(0) - ($CFG->loglifetime * 3600 * 24);
$DB->delete_records_select("log", "time < ?", array($loglifetime));
mtrace(" Deleted old log records");
}
}
public function dispose() {
}
/**
* Legacy add_to_log() code.
*
* @param int $courseid The course id
* @param string $module The module name e.g. forum, journal, resource, course, user etc
* @param string $action 'view', 'update', 'add' or 'delete', possibly followed by another word to clarify.
* @param string $url The file and parameters used to see the results of the action
* @param string $info Additional description information
* @param int $cm The course_module->id if there is one
* @param int|\stdClass $user If log regards $user other than $USER
*/
public function legacy_add_to_log($courseid, $module, $action, $url, $info, $cm, $user) {
// Note that this function intentionally does not follow the normal Moodle DB access idioms.
// This is for a good reason: it is the most frequently used DB update function,
// so it has been optimised for speed.
global $DB, $CFG, $USER;
if ($this->legacy_logging_enabled()) {
return;
}
if ($cm === '' || is_null($cm)) { // Postgres won't translate empty string to its default.
$cm = 0;
}
if ($user) {
$userid = $user;
} else {
if (\core\session\manager::is_loggedinas()) { // Don't log.
return;
}
$userid = empty($USER->id) ? '0' : $USER->id;
}
if (isset($CFG->logguests) and !$CFG->logguests) {
if (!$userid or isguestuser($userid)) {
return;
}
}
$REMOTE_ADDR = getremoteaddr();
$timenow = time();
if (!empty($url)) { // Could break doing html_entity_decode on an empty var.
$url = html_entity_decode($url, ENT_QUOTES, 'UTF-8');
} else {
$url = '';
}
// Restrict length of log lines to the space actually available in the
// database so that it doesn't cause a DB error. Log a warning so that
// developers can avoid doing things which are likely to cause this on a
// routine basis.
if(!empty($info) && \core_text::strlen($info)>255) {
$info = \core_text::substr($info,0,252).'...';
debugging('Warning: logged very long info',DEBUG_DEVELOPER);
}
// If the 100 field size is changed, also need to alter print_log in course/lib.php.
if(!empty($url) && \core_text::strlen($url)>100) {
$url = \core_text::substr($url,0,97).'...';
debugging('Warning: logged very long URL',DEBUG_DEVELOPER);
}
if (defined('MDL_PERFDB')) { global $PERF ; $PERF->logwrites++;};
$log = array('time'=>$timenow, 'userid'=>$userid, 'course'=>$courseid, 'ip'=>$REMOTE_ADDR, 'module'=>$module,
'cmid'=>$cm, 'action'=>$action, 'url'=>$url, 'info'=>$info);
try {
$DB->insert_record_raw('log', $log, false);
} catch (\dml_exception $e) {
debugging('Error: Could not insert a new entry to the Moodle log. '. $e->error, DEBUG_ALL);
// MDL-11893, alert $CFG->supportemail if insert into log failed.
if ($CFG->supportemail and empty($CFG->noemailever)) {
// Function email_to_user is not usable because email_to_user tries to write to the logs table,
// and this will get caught in an infinite loop, if disk is full.
$site = get_site();
$subject = 'Insert into log failed at your moodle site '.$site->fullname;
$message = "Insert into log table failed at ". date('l dS \of F Y h:i:s A') .".\n It is possible that your disk is full.\n\n";
$message .= "The failed query parameters are:\n\n" . var_export($log, true);
$lasttime = get_config('admin', 'lastloginserterrormail');
if(empty($lasttime) || time() - $lasttime > 60*60*24) { // limit to 1 email per day
// Using email directly rather than messaging as they may not be able to log in to access a message.
mail($CFG->supportemail, $subject, $message);
set_config('lastloginserterrormail', time(), 'admin');
}
}
}
}
/**
* Did admin request to keep adding new data to legacy log table?
* @return bool
*/
protected function legacy_logging_enabled() {
return (bool)get_config('logstore_legacy', 'loglegacy');
}
}

View File

@ -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/>.
/**
* Defines the capabilities used by standard log store.
*
* @package logstore_legacy
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = array(
'logstore/legacy:read' => array(
'riskbitmask' => RISK_PERSONAL,
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => array(
'manager' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
),
),
);

View File

@ -0,0 +1,30 @@
<?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/>.
/**
* Legacy log reader lang strings.
*
* @package logstore_legacy
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['event_legacy_logged'] = 'Legacy event';
$string['legacy:read'] = 'Read logs';
$string['loglegacy'] = 'Log legacy data';
$string['loglegacy_help'] = 'Add new records to the legacy log table. It is recommended to disable this for performance reasons.';
$string['pluginname'] = 'Legacy log';
$string['pluginname_desc'] = 'Legacy log plugin, it can be used for reading of legacy log data stored in mdl_log table.';

View File

@ -0,0 +1,52 @@
<?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/>.
/**
* Legacy logging settings.
*
* @package logstore_legacy
* @copyright 2014 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
if ($hassiteconfig) {
$settings->add(new admin_setting_configcheckbox('logstore_legacy/loglegacy',
new lang_string('loglegacy', 'logstore_legacy'),
new lang_string('loglegacy_help', 'logstore_legacy'), 0));
$settings->add(new admin_setting_configcheckbox('logguests',
new lang_string('logguests', 'admin'),
new lang_string('logguests_help', 'admin'), 1));
$options = array(0 => new lang_string('neverdeletelogs'),
1000 => new lang_string('numdays', '', 1000),
365 => new lang_string('numdays', '', 365),
180 => new lang_string('numdays', '', 180),
150 => new lang_string('numdays', '', 150),
120 => new lang_string('numdays', '', 120),
90 => new lang_string('numdays', '', 90),
60 => new lang_string('numdays', '', 60),
35 => new lang_string('numdays', '', 35),
10 => new lang_string('numdays', '', 10),
5 => new lang_string('numdays', '', 5),
2 => new lang_string('numdays', '', 2));
$settings->add(new admin_setting_configselect('loglifetime',
new lang_string('loglifetime', 'admin'),
new lang_string('configloglifetime', 'admin'), 0, $options));
}

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/>.
/**
* Legacy log reader.
*
* @package logstore_legacy
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2014011300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2014011000; // Requires this Moodle version.
$plugin->component = 'logstore_legacy'; // Full name of the plugin (used for diagnostics).

View File

@ -0,0 +1,114 @@
<?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/>.
/**
* Standard log reader/writer.
*
* @package logstore_standard
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace logstore_standard\log;
defined('MOODLE_INTERNAL') || die();
class store implements \tool_log\log\writer, \core\log\sql_reader {
/** @var string $logguests true if logging guest access */
protected $logguests;
public function __construct(\tool_log\log\manager $manager) {
$this->logguests = get_config('logstore_standard', 'logguests');
if ($this->logguests === false) {
// Log everything before setting is saved for the first time.
$this->logguests = '1';
}
}
public function write(\core\event\base $event) {
global $DB;
// Filter events.
if (!CLI_SCRIPT and !$this->logguests) {
// Always log inside CLI scripts because we do not login there.
if (!isloggedin() or isguestuser()) {
return;
}
}
$data = $event->get_data();
$data['other'] = serialize($data['other']);
if (CLI_SCRIPT) {
$data['origin'] = 'cli';
} else {
$data['origin'] = getremoteaddr();
}
$data['realuserid'] = \core\session\manager::is_loggedinas() ? $_SESSION['USER']->realuser : null;
$DB->insert_record('logstore_standard_log', $data);
}
public function get_name() {
return get_string('pluginname', 'logstore_standard');
}
public function get_description() {
return get_string('pluginname_desc', 'logstore_standard');
}
public function can_access(\context $context) {
return has_capability('logstore/standard:read', $context);
}
public function get_events($selectwhere, array $params, $sort, $limitfrom, $limitnum) {
global $DB;
$events = array();
$records = $DB->get_records_select('logstore_standard_log', $selectwhere, $params, $sort, '*', $limitfrom, $limitnum);
foreach ($records as $data) {
$extra = array('origin'=>$data->origin, 'realuserid'=>$data->realuserid);
$data = (array)$data;
$id = $data['id'];
$data['other'] = unserialize($data['other']);
if ($data['other'] === false) {
$data['other'] = array();
}
unset($data['origin']);
unset($data['realuserid']);
unset($data['id']);
$events[$id] = \core\event\base::restore($data, $extra);
}
return $events;
}
public function get_events_count($selectwhere, array $params) {
global $DB;
return $DB->count_records_select('logstore_standard_log', $selectwhere, $params);
}
public function get_log_table() {
return 'logstore_standard_log';
}
public function cron() {
}
public function dispose() {
}
}

View File

@ -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/>.
/**
* Defines the capabilities used by standard log store.
*
* @package logstore_standard
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = array(
'logstore/standard:read' => array(
'riskbitmask' => RISK_PERSONAL,
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => array(
'manager' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
),
),
);

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="admin/tool/log/store/standard/db" VERSION="20131222" COMMENT="XMLDB file for Moodle admin/tool/log/store/standard"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../../../../lib/xmldb/xmldb.xsd"
>
<TABLES>
<TABLE NAME="logstore_standard_log" COMMENT="Standard log table">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="eventname" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="component" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="action" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="target" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="objecttable" TYPE="char" LENGTH="50" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="objectid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="crud" TYPE="char" LENGTH="1" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="edulevel" TYPE="int" LENGTH="1" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="contextid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="contextlevel" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="contextinstanceid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="relateduserid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="other" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="origin" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" COMMENT="IP address, cli, cron"/>
<FIELD NAME="realuserid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="real user id when logged-in-as"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="timecreated" UNIQUE="false" FIELDS="timecreated"/>
</INDEXES>
</TABLE>
</TABLES>
</XMLDB>

View File

@ -0,0 +1,27 @@
<?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/>.
/**
* Log store lang strings.
*
* @package logstore_standard
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['pluginname'] = 'Standard log';
$string['pluginname_desc'] = 'Standard log plugin, the data is stored in Moodle database table.';
$string['standard:read'] = 'Read logs';

View File

@ -0,0 +1,32 @@
<?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/>.
/**
* Standard log store settings.
*
* @package logstore_standard
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
if ($hassiteconfig) {
// TODO: Localise these settings.
$settings->add(new admin_setting_configcheckbox('logstore_standard/logguests', 'Log guest actions', '', '1'));
}

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/>.
/**
* Standard log store.
*
* @package logstore_standard
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2014011300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2014011000; // Requires this Moodle version.
$plugin->component = 'logstore_standard'; // Full name of the plugin (used for diagnostics).

98
admin/tool/log/stores.php Normal file
View File

@ -0,0 +1,98 @@
<?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/>.
/**
* Logging store management.
*
* @package tool_log
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once('../../../config.php');
require_once($CFG->libdir.'/adminlib.php');
$action = required_param('action', PARAM_ALPHANUMEXT);
$enrol = required_param('store', PARAM_PLUGIN);
$PAGE->set_url('/admin/tool/log/stores.php');
$PAGE->set_context(context_system::instance());
require_login();
require_capability('moodle/site:config', context_system::instance());
require_sesskey();
$all = \tool_log\log\manager::get_store_plugins();
$enabled = get_config('tool_log', 'enabled_stores');
if (!$enabled) {
$enabled = array();
} else {
$enabled = array_flip(explode(',', $enabled));
}
$return = new moodle_url('/admin/settings.php', array('section'=>'managelogging'));
$syscontext = context_system::instance();
switch ($action) {
case 'disable':
unset($enabled[$enrol]);
set_config('enabled_stores', implode(',', array_keys($enabled)), 'tool_log');
break;
case 'enable':
if (!isset($all[$enrol])) {
break;
}
$enabled = array_keys($enabled);
$enabled[] = $enrol;
set_config('enabled_stores', implode(',', $enabled), 'tool_log');
break;
case 'up':
if (!isset($enabled[$enrol])) {
break;
}
$enabled = array_keys($enabled);
$enabled = array_flip($enabled);
$current = $enabled[$enrol];
if ($current == 0) {
break; // Already at the top.
}
$enabled = array_flip($enabled);
$enabled[$current] = $enabled[$current - 1];
$enabled[$current - 1] = $enrol;
set_config('enabled_stores', implode(',', $enabled), 'tool_log');
break;
case 'down':
if (!isset($enabled[$enrol])) {
break;
}
$enabled = array_keys($enabled);
$enabled = array_flip($enabled);
$current = $enabled[$enrol];
if ($current == count($enabled) - 1) {
break; // Already at the end.
}
$enabled = array_flip($enabled);
$enabled[$current] = $enabled[$current + 1];
$enabled[$current + 1] = $enrol;
set_config('enabled_stores', implode(',', $enabled), 'tool_log');
break;
}
redirect($return);

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/>.
/**
* Default log manager.
*
* @package tool_log
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2014011300; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2014011000; // Requires this Moodle version.
$plugin->component = 'tool_log'; // Full name of the plugin (used for diagnostics).

View File

@ -1007,7 +1007,6 @@ $string['taskcontextcleanup'] = 'Cleanup contexts';
$string['taskcreatecontexts'] = 'Create missing contexts';
$string['taskdeletecachetext'] = 'Delete old text cache records';
$string['taskdeleteincompleteusers'] = 'Delete incomplete users';
$string['taskdeletelogs'] = 'Delete logs';
$string['taskdeleteunconfirmedusers'] = 'Delete unconfirmed users';
$string['taskeventscron'] = 'Background processing for events';
$string['taskfiletrashcleanup'] = 'Cleanup files in trash';

View File

@ -347,6 +347,83 @@ abstract class base implements \IteratorAggregate {
return $event;
}
/**
* Create fake event from legacy log data.
*
* @param stdClass $legacy
* @return base
*/
public static final function restore_legacy($legacy) {
$classname = get_called_class();
$event = new $classname();
$event->restored = true;
$event->triggered = true;
$event->dispatched = true;
$context = false;
$component = 'legacy';
if ($legacy->cmid) {
$context = \context_module::instance($legacy->cmid, IGNORE_MISSING);
$component = 'mod_'.$legacy->module;
} else if ($legacy->course) {
$context = \context_course::instance($legacy->course, IGNORE_MISSING);
}
if (!$context) {
$context = \context_system::instance();
}
$event->data = array();
$event->data['eventname'] = $legacy->module.'_'.$legacy->action;
$event->data['component'] = $component;
$event->data['action'] = $legacy->action;
$event->data['target'] = null;
$event->data['objecttable'] = null;
$event->data['objectid'] = null;
if (strpos($legacy->action, 'view') !== false) {
$event->data['crud'] = 'r';
} else if (strpos($legacy->action, 'print') !== false) {
$event->data['crud'] = 'r';
} else if (strpos($legacy->action, 'update') !== false) {
$event->data['crud'] = 'u';
} else if (strpos($legacy->action, 'hide') !== false) {
$event->data['crud'] = 'u';
} else if (strpos($legacy->action, 'move') !== false) {
$event->data['crud'] = 'u';
} else if (strpos($legacy->action, 'write') !== false) {
$event->data['crud'] = 'u';
} else if (strpos($legacy->action, 'tag') !== false) {
$event->data['crud'] = 'u';
} else if (strpos($legacy->action, 'remove') !== false) {
$event->data['crud'] = 'u';
} else if (strpos($legacy->action, 'delete') !== false) {
$event->data['crud'] = 'p';
} else if (strpos($legacy->action, 'create') !== false) {
$event->data['crud'] = 'c';
} else if (strpos($legacy->action, 'post') !== false) {
$event->data['crud'] = 'c';
} else if (strpos($legacy->action, 'add') !== false) {
$event->data['crud'] = 'c';
} else {
// End of guessing...
$event->data['crud'] = 'r';
}
$event->data['edulevel'] = $event::LEVEL_OTHER;
$event->data['contextid'] = $context->id;
$event->data['contextlevel'] = $context->contextlevel;
$event->data['contextinstanceid'] = $context->instanceid;
$event->data['userid'] = ($legacy->userid ? $legacy->userid : null);
$event->data['courseid'] = ($legacy->course ? $legacy->course : null);
$event->data['relateduserid'] = ($legacy->userid ? $legacy->userid : null);
$event->data['timecreated'] = $legacy->time;
$event->logextra = array('origin'=>$legacy->ip, 'realuserid'=>null);
$event->data['other'] = (array)$legacy;
return $event;
}
/**
* Returns event context.
* @return \context
@ -504,7 +581,10 @@ abstract class base implements \IteratorAggregate {
if (isset($CFG->loglifetime) and $CFG->loglifetime != -1) {
if ($data = $this->get_legacy_logdata()) {
call_user_func_array('add_to_log', $data);
$manager = get_log_manager();
if (method_exists($manager, 'legacy_add_to_log')) {
call_user_func_array(array($manager, 'legacy_add_to_log'), $data);
}
}
}

View File

@ -0,0 +1,36 @@
<?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/>.
/**
* Dummy storage manager, returns nothing.
* used when no other manager available.
*
* @package core
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\log;
defined('MOODLE_INTERNAL') || die();
class dummy_manager implements manager {
public function get_readers(\context $context) {
return array();
}
public function dispose() {
}
}

View File

@ -15,44 +15,38 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* A scheduled task.
* Log storage manager interface.
*
* @package core
* @copyright 2013 onwards Martin Dougiamas http://dougiamas.com
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\task;
namespace core\log;
defined('MOODLE_INTERNAL') || die();
/**
* Simple task to delete old log records.
* Interface describing log readers.
*
* This is intended for reports, use get_log_manager() to get
* the configured instance.
*
* @package core\log
*/
class delete_logs_task extends scheduled_task {
interface manager {
/**
* Get a descriptive name for this task (shown to admins).
* Return list of available log readers in given
* context for current user.
*
* @return string
* @param \context $context
* @return \core\log\reader[]
*/
public function get_name() {
return get_string('taskdeletelogs', 'admin');
}
public function get_readers(\context $context);
/**
* Do the job.
* Throw exceptions on errors (the job will be retried).
* Dispose all initialised stores.
* @return void
*/
public function execute() {
global $CFG, $DB;
$timenow = time();
// Delete old logs to save space.
// Value in days.
if (!empty($CFG->loglifetime)) {
$loglifetime = $timenow - ($CFG->loglifetime * 3600 * 24);
$DB->delete_records_select("log", "time < ?", array($loglifetime));
}
}
public function dispose();
}

View File

@ -0,0 +1,72 @@
<?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/>.
/**
* Log storage reader interface.
*
* @package core
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\log;
defined('MOODLE_INTERNAL') || die();
interface reader {
/**
* Localised name of the reader.
*
* To be used in selection for in reports.
*
* @return string
*/
public function get_name();
/**
* Longer description of the log data source.
* @return string
*/
public function get_description();
/**
* Can the current user access this store?
* @param \context $context
* @return bool
*/
public function can_access(\context $context);
/**
* Fetch records using given criteria.
*
* @param string $selectwhere
* @param array $params
* @param string $sort
* @param int $limitfrom
* @param int $limitnum
* @return \core\event\base[]
*/
public function get_events($selectwhere, array $params, $sort, $limitfrom, $limitnum);
/**
* Return number of events matching given criteria.
*
* @param string $selectwhere
* @param array $params
* @return int
*/
public function get_events_count($selectwhere, array $params);
}

View File

@ -0,0 +1,43 @@
<?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/>.
/**
* Log storage sql reader interface.
*
* @package core
* @copyright 2013 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core\log;
defined('MOODLE_INTERNAL') || die();
interface sql_reader extends reader {
/**
* Returns name of the table or database view that
* holds the log data in standardised format.
*
* Note: this table must be used for reading only,
* it is strongly recommended to use this in complex reports only.
*
* TODO: define the standard log columns - watch out for "level" reserved word!
*
* @return string
*/
public function get_log_table();
}

View File

@ -1028,6 +1028,10 @@ class core_plugin_manager {
'local' => array(
),
'logstore' => array(
'database', 'legacy', 'standard',
),
'message' => array(
'email', 'jabber', 'popup'
),
@ -1117,7 +1121,7 @@ class core_plugin_manager {
'tool' => array(
'assignmentupgrade', 'behat', 'capability', 'customlang',
'dbtransfer', 'generator', 'health', 'innodb', 'installaddon',
'langimport', 'multilangupgrade', 'phpunit', 'profiling',
'langimport', 'log', 'multilangupgrade', 'phpunit', 'profiling',
'qeupgradehelper', 'replace', 'spamcleaner', 'task', 'timezoneimport',
'unittest', 'uploadcourse', 'uploaduser', 'unsuproles', 'xmldb'
),

View File

@ -1583,6 +1583,41 @@ function coursemodule_visible_for_user($cm, $userid=0) {
/// LOG FUNCTIONS /////////////////////////////////////////////////////
/**
* Get instance of log manager.
*
* @param bool $forcereload
* @return \core\log\manager
*/
function get_log_manager($forcereload = false) {
/** @var \core\log\manager $singleton */
static $singleton = null;
if ($forcereload and isset($singleton)) {
$singleton->dispose();
$singleton = null;
}
if (isset($singleton)) {
return $singleton;
}
$classname = '\tool_log\log\manager';
if (defined('LOG_MANAGER_CLASS')) {
$classname = LOG_MANAGER_CLASS;
}
if (!class_exists($classname)) {
if (!empty($classname)) {
debugging("Cannot find log manager class '$classname'.", DEBUG_DEVELOPER);
}
$classname = '\core\log\dummy_manager';
}
$singleton = new $classname();
return $singleton;
}
/**
* Add an entry to the config log table.
*
@ -1613,109 +1648,6 @@ function add_to_config_log($name, $oldvalue, $value, $plugin) {
$DB->insert_record('config_log', $log);
}
/**
* Add an entry to the log table.
*
* Add an entry to the log table. These are "action" focussed rather
* than web server hits, and provide a way to easily reconstruct what
* any particular student has been doing.
*
* @package core
* @category log
* @global moodle_database $DB
* @global stdClass $CFG
* @global stdClass $USER
* @uses SITEID
* @uses DEBUG_DEVELOPER
* @uses DEBUG_ALL
* @param int $courseid The course id
* @param string $module The module name e.g. forum, journal, resource, course, user etc
* @param string $action 'view', 'update', 'add' or 'delete', possibly followed by another word to clarify.
* @param string $url The file and parameters used to see the results of the action
* @param string $info Additional description information
* @param string $cm The course_module->id if there is one
* @param string $user If log regards $user other than $USER
* @return void
*/
function add_to_log($courseid, $module, $action, $url='', $info='', $cm=0, $user=0) {
// Note that this function intentionally does not follow the normal Moodle DB access idioms.
// This is for a good reason: it is the most frequently used DB update function,
// so it has been optimised for speed.
global $DB, $CFG, $USER;
if ($cm === '' || is_null($cm)) { // postgres won't translate empty string to its default
$cm = 0;
}
if ($user) {
$userid = $user;
} else {
if (\core\session\manager::is_loggedinas()) { // Don't log
return;
}
$userid = empty($USER->id) ? '0' : $USER->id;
}
if (isset($CFG->logguests) and !$CFG->logguests) {
if (!$userid or isguestuser($userid)) {
return;
}
}
$REMOTE_ADDR = getremoteaddr();
$timenow = time();
$info = $info;
if (!empty($url)) { // could break doing html_entity_decode on an empty var.
$url = html_entity_decode($url, ENT_QUOTES, 'UTF-8');
} else {
$url = '';
}
// Restrict length of log lines to the space actually available in the
// database so that it doesn't cause a DB error. Log a warning so that
// developers can avoid doing things which are likely to cause this on a
// routine basis.
if(!empty($info) && core_text::strlen($info)>255) {
$info = core_text::substr($info,0,252).'...';
debugging('Warning: logged very long info',DEBUG_DEVELOPER);
}
// If the 100 field size is changed, also need to alter print_log in course/lib.php
if(!empty($url) && core_text::strlen($url)>100) {
$url = core_text::substr($url,0,97).'...';
debugging('Warning: logged very long URL',DEBUG_DEVELOPER);
}
if (defined('MDL_PERFDB')) { global $PERF ; $PERF->logwrites++;};
$log = array('time'=>$timenow, 'userid'=>$userid, 'course'=>$courseid, 'ip'=>$REMOTE_ADDR, 'module'=>$module,
'cmid'=>$cm, 'action'=>$action, 'url'=>$url, 'info'=>$info);
try {
$DB->insert_record_raw('log', $log, false);
} catch (dml_exception $e) {
debugging('Error: Could not insert a new entry to the Moodle log. '. $e->error, DEBUG_ALL);
// MDL-11893, alert $CFG->supportemail if insert into log failed
if ($CFG->supportemail and empty($CFG->noemailever)) {
// email_to_user is not usable because email_to_user tries to write to the logs table,
// and this will get caught in an infinite loop, if disk is full
$site = get_site();
$subject = 'Insert into log failed at your moodle site '.$site->fullname;
$message = "Insert into log table failed at ". date('l dS \of F Y h:i:s A') .".\n It is possible that your disk is full.\n\n";
$message .= "The failed query parameters are:\n\n" . var_export($log, true);
$lasttime = get_config('admin', 'lastloginserterrormail');
if(empty($lasttime) || time() - $lasttime > 60*60*24) { // limit to 1 email per day
//using email directly rather than messaging as they may not be able to log in to access a message
mail($CFG->supportemail, $subject, $message);
set_config('lastloginserterrormail', time(), 'admin');
}
}
}
}
/**
* Store user last access times - called when use enters a course or site
*

View File

@ -59,15 +59,6 @@ $tasks = array(
'dayofweek' => '*',
'month' => '*'
),
array(
'classname' => 'core\task\delete_logs_task',
'blocking' => 0,
'minute' => '0',
'hour' => '2',
'day' => '*',
'dayofweek' => '*',
'month' => '*'
),
array(
'classname' => 'core\task\backup_cleanup_task',
'blocking' => 0,

View File

@ -30,6 +30,36 @@
defined('MOODLE_INTERNAL') || die();
/**
* Add an entry to the log table.
*
* Add an entry to the log table. These are "action" focussed rather
* than web server hits, and provide a way to easily reconstruct what
* any particular student has been doing.
*
* @deprecated since 2.7 use new events instead
*
* @param int $courseid The course id
* @param string $module The module name e.g. forum, journal, resource, course, user etc
* @param string $action 'view', 'update', 'add' or 'delete', possibly followed by another word to clarify.
* @param string $url The file and parameters used to see the results of the action
* @param string $info Additional description information
* @param int $cm The course_module->id if there is one
* @param int|stdClass $user If log regards $user other than $USER
* @return void
*/
function add_to_log($courseid, $module, $action, $url='', $info='', $cm=0, $user=0) {
// TODO: Uncomment after all add_to_log() are removed from standard distribution - ideally before 2.7 release.
//debugging('ideally all add_to_log() calls should be replaced() with new events', DEBUG_DEVELOPER);
// This is a nasty hack that allows us to put all the legacy stuff into legacy storage,
// this way we may move all the legacy settings there too.
$manager = get_log_manager();
if (method_exists($manager, 'legacy_add_to_log')) {
$manager->legacy_add_to_log($courseid, $module, $action, $url, $info, $cm, $user);
}
}
/**
* Adds a file upload to the log table so that clam can resolve the filename to the user later if necessary
*
@ -4318,17 +4348,3 @@ function can_use_html_editor() {
debugging('can_use_html_editor has been deprecated please update your code to assume it returns true.', DEBUG_DEVELOPER);
return true;
}
/**
* Returns whether ajax is enabled/allowed or not.
* This function is deprecated and always returns true.
*
* @param array $unused - not used any more.
* @return bool
* @deprecated since 2.7 MDL-33099 - please do not use this function any more.
* @todo MDL-44088 This will be removed in Moodle 2.9.
*/
function ajaxenabled(array $browsers = null) {
debugging('ajaxenabled() is deprecated - please update your code to assume it returns true.', DEBUG_DEVELOPER);
return true;
}

View File

@ -566,6 +566,8 @@ class core_event_testcase extends advanced_testcase {
}
public function test_trigger_problems() {
$this->resetAfterTest(true);
$event = \core_tests\event\unittest_executed::create(array('courseid'=>1, 'context'=>\context_system::instance(), 'other'=>array('sample'=>5, 'xx'=>10)));
$event->trigger();
try {
@ -597,6 +599,8 @@ class core_event_testcase extends advanced_testcase {
}
public function test_bad_events() {
$this->resetAfterTest(true);
try {
$event = \core_tests\event\unittest_executed::create(array('courseid'=>1, 'other'=>array('sample'=>5, 'xx'=>10)));
$this->fail('Exception expected when context and contextid missing');
@ -654,7 +658,8 @@ class core_event_testcase extends advanced_testcase {
}
public function test_problematic_events() {
global $CFG;
$this->resetAfterTest(true);
$event1 = \core_tests\event\problematic_event1::create(array('context'=>\context_system::instance()));
$this->assertDebuggingNotCalled();
$this->assertNull($event1->xxx);
@ -703,6 +708,8 @@ class core_event_testcase extends advanced_testcase {
public function test_record_snapshots() {
global $DB;
$this->resetAfterTest(true);
$event = \core_tests\event\unittest_executed::create(array('courseid'=>1, 'context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10)));
$course1 = $DB->get_record('course', array('id'=>1));
$this->assertNotEmpty($course1);