Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 310] [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Legacy log store tests.
  19   *
  20   * @package    logstore_legacy
  21   * @copyright  2014 Petr Skoda {@link http://skodak.org/}
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  
  27  require_once (__DIR__ . '/fixtures/event.php');
  28  require_once (__DIR__ . '/fixtures/store.php');
  29  
  30  class logstore_legacy_store_testcase extends advanced_testcase {
  31      public function test_log_writing() {
  32          global $DB;
  33          $this->resetAfterTest();
  34  
  35          $this->setAdminUser();
  36          $user1 = $this->getDataGenerator()->create_user();
  37          $user2 = $this->getDataGenerator()->create_user();
  38          $course1 = $this->getDataGenerator()->create_course();
  39          $module1 = $this->getDataGenerator()->create_module('resource', array('course' => $course1));
  40          $course2 = $this->getDataGenerator()->create_course();
  41          $module2 = $this->getDataGenerator()->create_module('resource', array('course' => $course2));
  42  
  43          // Enable legacy logging plugin.
  44          set_config('enabled_stores', 'logstore_legacy', 'tool_log');
  45          set_config('loglegacy', 1, 'logstore_legacy');
  46          $manager = get_log_manager(true);
  47  
  48          $stores = $manager->get_readers();
  49          $this->assertCount(1, $stores);
  50          $this->assertEquals(array('logstore_legacy'), array_keys($stores));
  51          $store = $stores['logstore_legacy'];
  52          $this->assertInstanceOf('logstore_legacy\log\store', $store);
  53          $this->assertInstanceOf('core\log\sql_reader', $store);
  54          $this->assertTrue($store->is_logging());
  55  
  56          $logs = $DB->get_records('log', array(), 'id ASC');
  57          $this->assertCount(0, $logs);
  58  
  59          $this->setCurrentTimeStart();
  60  
  61          $this->setUser(0);
  62          $event1 = \logstore_legacy\event\unittest_executed::create(
  63              array('context' => context_module::instance($module1->cmid), 'other' => array('sample' => 5, 'xx' => 10)));
  64          $event1->trigger();
  65  
  66          $this->setUser($user1);
  67          $event2 = \logstore_legacy\event\unittest_executed::create(
  68              array('context' => context_course::instance($course2->id), 'other' => array('sample' => 6, 'xx' => 11)));
  69          $event2->trigger();
  70  
  71          $this->setUser($user2);
  72          add_to_log($course1->id, 'xxxx', 'yyyy', '', '7', 0, 0);
  73          $this->assertDebuggingCalled();
  74  
  75          add_to_log($course2->id, 'aaa', 'bbb', 'info.php', '666', $module2->cmid, $user1->id);
  76          $this->assertDebuggingCalled();
  77  
  78          $logs = $DB->get_records('log', array(), 'id ASC');
  79          $this->assertCount(4, $logs);
  80  
  81          $log = array_shift($logs);
  82          $this->assertNotEmpty($log->id);
  83          $this->assertTimeCurrent($log->time);
  84          $this->assertEquals(0, $log->userid);
  85          $this->assertSame('0.0.0.0', $log->ip);
  86          $this->assertEquals($course1->id, $log->course);
  87          $this->assertSame('core_unittest', $log->module);
  88          $this->assertEquals($module1->cmid, $log->cmid);
  89          $this->assertSame('view', $log->action);
  90          $this->assertSame('unittest.php?id=5', $log->url);
  91          $this->assertSame('bbb', $log->info);
  92  
  93          $oldlogid = $log->id;
  94          $log = array_shift($logs);
  95          $this->assertGreaterThan($oldlogid, $log->id);
  96          $this->assertNotEmpty($log->id);
  97          $this->assertTimeCurrent($log->time);
  98          $this->assertEquals($user1->id, $log->userid);
  99          $this->assertSame('0.0.0.0', $log->ip);
 100          $this->assertEquals($course2->id, $log->course);
 101          $this->assertSame('core_unittest', $log->module);
 102          $this->assertEquals(0, $log->cmid);
 103          $this->assertSame('view', $log->action);
 104          $this->assertSame('unittest.php?id=6', $log->url);
 105          $this->assertSame('bbb', $log->info);
 106  
 107          $oldlogid = $log->id;
 108          $log = array_shift($logs);
 109          $this->assertGreaterThan($oldlogid, $log->id);
 110          $this->assertNotEmpty($log->id);
 111          $this->assertTimeCurrent($log->time);
 112          $this->assertEquals($user2->id, $log->userid);
 113          $this->assertSame('0.0.0.0', $log->ip);
 114          $this->assertEquals($course1->id, $log->course);
 115          $this->assertSame('xxxx', $log->module);
 116          $this->assertEquals(0, $log->cmid);
 117          $this->assertSame('yyyy', $log->action);
 118          $this->assertSame('', $log->url);
 119          $this->assertSame('7', $log->info);
 120  
 121          $oldlogid = $log->id;
 122          $log = array_shift($logs);
 123          $this->assertGreaterThan($oldlogid, $log->id);
 124          $this->assertNotEmpty($log->id);
 125          $this->assertTimeCurrent($log->time);
 126          $this->assertEquals($user1->id, $log->userid);
 127          $this->assertSame('0.0.0.0', $log->ip);
 128          $this->assertEquals($course2->id, $log->course);
 129          $this->assertSame('aaa', $log->module);
 130          $this->assertEquals($module2->cmid, $log->cmid);
 131          $this->assertSame('bbb', $log->action);
 132          $this->assertSame('info.php', $log->url);
 133          $this->assertSame('666', $log->info);
 134  
 135          // Test if disabling works.
 136          set_config('enabled_stores', 'logstore_legacy', 'tool_log');
 137          set_config('loglegacy', 0, 'logstore_legacy');
 138          $manager = get_log_manager(true);
 139          $stores = $manager->get_readers();
 140          $store = $stores['logstore_legacy'];
 141          $this->assertFalse($store->is_logging());
 142  
 143          \logstore_legacy\event\unittest_executed::create(
 144              array('context' => \context_system::instance(), 'other' => array('sample' => 5, 'xx' => 10)))->trigger();
 145          add_to_log($course1->id, 'xxxx', 'yyyy', '', '7', 0, 0);
 146          $this->assertDebuggingCalled();
 147          $this->assertEquals(4, $DB->count_records('log'));
 148  
 149          // Another way to disable legacy completely.
 150          set_config('enabled_stores', 'logstore_standard', 'tool_log');
 151          set_config('loglegacy', 1, 'logstore_legacy');
 152          get_log_manager(true);
 153  
 154          \logstore_legacy\event\unittest_executed::create(
 155              array('context' => \context_system::instance(), 'other' => array('sample' => 5, 'xx' => 10)))->trigger();
 156          add_to_log($course1->id, 'xxxx', 'yyyy', '', '7', 0, 0);
 157          $this->assertDebuggingCalled();
 158          $this->assertEquals(4, $DB->count_records('log'));
 159          // Set everything back.
 160          set_config('enabled_stores', '', 'tool_log');
 161          set_config('loglegacy', 0, 'logstore_legacy');
 162          get_log_manager(true);
 163      }
 164  
 165      /**
 166       * Test replace_sql_legacy()
 167       */
 168      public function test_replace_sql_legacy() {
 169          $selectwhere = "userid = :userid AND courseid = :courseid AND eventname = :eventname AND timecreated > :since";
 170          $params = array('userid' => 2, 'since' => 3, 'courseid' => 4, 'eventname' => '\core\event\course_created');
 171          $expectedselect = "module = 'course' AND action = 'new' AND userid = :userid AND url = :url AND time > :since";
 172          $expectedparams = $params + array('url' => "view.php?id=4");
 173  
 174          list($replaceselect, $replaceparams) = \logstore_legacy\test\unittest_logstore_legacy::replace_sql_legacy($selectwhere, $params);
 175          $this->assertEquals($replaceselect, $expectedselect);
 176          $this->assertEquals($replaceparams, $expectedparams);
 177  
 178          // Test CRUD related changes.
 179          $selectwhere = "edulevel = 0";
 180          list($updatewhere, $replaceparams) = \logstore_legacy\test\unittest_logstore_legacy::replace_sql_legacy($selectwhere, $params);
 181          $this->assertEquals($selectwhere, $updatewhere);
 182  
 183          $selectwhere = "edulevel = 0 and crud = 'u'";
 184          list($updatewhere, $replaceparams) = \logstore_legacy\test\unittest_logstore_legacy::replace_sql_legacy($selectwhere, $params);
 185          $this->assertEquals("edulevel = 0 and action LIKE '%update%'", $updatewhere);
 186  
 187          $selectwhere = "edulevel = 0 and crud != 'u'";
 188          list($updatewhere, $replaceparams) = \logstore_legacy\test\unittest_logstore_legacy::replace_sql_legacy($selectwhere, $params);
 189          $this->assertEquals("edulevel = 0 and action NOT LIKE '%update%'", $updatewhere);
 190  
 191          $selectwhere = "edulevel = 0 and crud <> 'u'";
 192          list($updatewhere, $replaceparams) = \logstore_legacy\test\unittest_logstore_legacy::replace_sql_legacy($selectwhere, $params);
 193          $this->assertEquals("edulevel = 0 and action NOT LIKE '%update%'", $updatewhere);
 194  
 195          $selectwhere = "edulevel = 0 and crud = 'r'";
 196          list($updatewhere, $replaceparams) = \logstore_legacy\test\unittest_logstore_legacy::replace_sql_legacy($selectwhere, $params);
 197          $this->assertEquals("edulevel = 0 and action LIKE '%view%' OR action LIKE '%report%'", $updatewhere);
 198  
 199          $selectwhere = "edulevel = 0 and crud != 'r'";
 200          list($updatewhere, $replaceparams) = \logstore_legacy\test\unittest_logstore_legacy::replace_sql_legacy($selectwhere, $params);
 201          $this->assertEquals("edulevel = 0 and action NOT LIKE '%view%' AND action NOT LIKE '%report%'", $updatewhere);
 202  
 203          $selectwhere = "edulevel = 0 and crud <> 'r'";
 204          list($updatewhere, $replaceparams) = \logstore_legacy\test\unittest_logstore_legacy::replace_sql_legacy($selectwhere, $params);
 205          $this->assertEquals("edulevel = 0 and action NOT LIKE '%view%' AND action NOT LIKE '%report%'", $updatewhere);
 206  
 207          // The slq is incorrect, since quotes must not be present. Make sure this is not parsed.
 208          $selectwhere = "edulevel = 0 and 'crud' != 'u'";
 209          list($updatewhere, $replaceparams) = \logstore_legacy\test\unittest_logstore_legacy::replace_sql_legacy($selectwhere, $params);
 210          $this->assertNotEquals("edulevel = 0 and action NOT LIKE '%update%'", $updatewhere);
 211  
 212          $selectwhere = "edulevel = 0 and crud = 'u' OR crud != 'r' or crud <> 'd'";
 213          list($updatewhere, $replaceparams) = \logstore_legacy\test\unittest_logstore_legacy::replace_sql_legacy($selectwhere, $params);
 214          $this->assertEquals("edulevel = 0 and action LIKE '%update%' OR action NOT LIKE '%view%' AND action NOT LIKE '%report%' or action NOT LIKE '%delete%'", $updatewhere);
 215  
 216          // The anonymous select returns all data.
 217          $selectwhere = "anonymous = 0";
 218          list($updatewhere, $replaceparams) = \logstore_legacy\test\unittest_logstore_legacy::replace_sql_legacy($selectwhere, $params);
 219          $this->assertSame("0 = 0", $updatewhere);
 220  
 221          // Test legacy field names are mapped.
 222          $selectwhere = "timecreated = :timecreated and courseid = :courseid and contextinstanceid = :contextinstanceid and origin = :origin";
 223          $params = array('timecreated' => 2, 'courseid' => 3, 'contextinstanceid' => 4, 'origin' => 5 );
 224          $expectedparams = array('time' => 2, 'course' => 3, 'cmid' => 4, 'ip' => 5);
 225          list($updatewhere, $replaceparams) = \logstore_legacy\test\unittest_logstore_legacy::replace_sql_legacy($selectwhere, $params);
 226          $this->assertEquals("time = :time and course = :course and cmid = :cmid and ip = :ip", $updatewhere);
 227          $this->assertSame($expectedparams, $replaceparams);
 228  
 229          // Test sorting parameters.
 230          $selectwhere = "courseid = 3";
 231          $params = array();
 232          $sort = 'timecreated DESC';
 233          list($updatewhere, $replaceparams, $sort) =
 234                  \logstore_legacy\test\unittest_logstore_legacy::replace_sql_legacy($selectwhere, $params, $sort);
 235          $this->assertSame('time DESC', $sort);
 236  
 237          $sort = 'courseid DESC';
 238          list($updatewhere, $replaceparams, $sort) =
 239              \logstore_legacy\test\unittest_logstore_legacy::replace_sql_legacy($selectwhere, $params, $sort);
 240          $this->assertSame('course DESC', $sort);
 241  
 242          $sort = 'contextinstanceid DESC';
 243          list($updatewhere, $replaceparams, $sort) =
 244              \logstore_legacy\test\unittest_logstore_legacy::replace_sql_legacy($selectwhere, $params, $sort);
 245          $this->assertSame('cmid DESC', $sort);
 246  
 247          $sort = 'origin DESC';
 248          list($updatewhere, $replaceparams, $sort) =
 249              \logstore_legacy\test\unittest_logstore_legacy::replace_sql_legacy($selectwhere, $params, $sort);
 250          $this->assertSame('ip DESC', $sort);
 251      }
 252  
 253      /*
 254       * Test logmanager::get_supported_reports returns all reports that require this store.
 255       */
 256      public function test_get_supported_reports() {
 257          $logmanager = get_log_manager();
 258          $allreports = \core_component::get_plugin_list('report');
 259  
 260          // Make sure all supported reports are installed.
 261          $expectedreports = array_intersect_key([
 262              'log' => 'report_log',
 263              'loglive' => 'report_loglive',
 264              'outline' => 'report_outline',
 265              'participation' => 'report_participation',
 266              'stats' => 'report_stats'
 267          ], $allreports);
 268  
 269          $supportedreports = $logmanager->get_supported_reports('logstore_legacy');
 270  
 271          foreach ($expectedreports as $expectedreport) {
 272              $this->assertArrayHasKey($expectedreport, $supportedreports);
 273          }
 274      }
 275  
 276      /**
 277       * Test that the legacy log cleanup works correctly.
 278       */
 279      public function test_cleanup_task() {
 280          global $DB;
 281  
 282          $this->resetAfterTest();
 283  
 284          // Create some records spread over various days; test multiple iterations in cleanup.
 285          $record = (object) array('time' => time());
 286          $DB->insert_record('log', $record);
 287          $record->time -= 3600 * 24 * 30;
 288          $DB->insert_record('log', $record);
 289          $record->time -= 3600 * 24 * 30;
 290          $DB->insert_record('log', $record);
 291          $record->time -= 3600 * 24 * 30;
 292          $DB->insert_record('log', $record);
 293          $this->assertEquals(4, $DB->count_records('log'));
 294  
 295          // Remove all logs before "today".
 296          set_config('loglifetime', 1);
 297  
 298          $this->expectOutputString(" Deleted old legacy log records\n");
 299          $clean = new \logstore_legacy\task\cleanup_task();
 300          $clean->execute();
 301  
 302          $this->assertEquals(1, $DB->count_records('log'));
 303      }
 304  }