MDL-42890 tool_log Default legacy reader should handle CRUD queries

This commit is contained in:
Ankit Agarwal
2014-03-14 12:07:17 +08:00
parent c0e88129d1
commit dc06500559
3 changed files with 178 additions and 1 deletions
@@ -42,6 +42,9 @@ class store implements \tool_log\log\store, \core\log\sql_select_reader {
'origin' => 'ip'
);
/** @var string Regex to replace the crud params */
const CRUD_REGEX = "/(crud).*?(<>|=|!=).*?'(.*?)'/s";
public function get_events_select($selectwhere, array $params, $sort, $limitfrom, $limitnum) {
global $DB;
@@ -54,7 +57,7 @@ class store implements \tool_log\log\store, \core\log\sql_select_reader {
unset($params[$from]);
}
}
$selectwhere = preg_replace_callback(self::CRUD_REGEX, 'self::replace_crud', $selectwhere);
$events = array();
$records = array();
@@ -82,6 +85,7 @@ class store implements \tool_log\log\store, \core\log\sql_select_reader {
unset($params[$from]);
}
}
$selectwhere = preg_replace_callback(self::CRUD_REGEX, 'self::replace_crud', $selectwhere);
try {
return $DB->count_records_select('log', $selectwhere, $params);
@@ -209,4 +213,81 @@ class store implements \tool_log\log\store, \core\log\sql_select_reader {
}
}
}
/**
* Generate a replace string for crud related sql conditions. This function is called as callback to preg_replace_callback()
* on the actual sql.
*
* @param array $match matched string for the passed pattern
*
* @return string The sql string to use instead of original
*/
protected static function replace_crud($match) {
$return = '';
unset($match[0]); // The first entry is the whole string.
foreach ($match as $m) {
// We can hard code LIKE here because we are not worried about case sensitivity and we don't want this to be faster.
switch ($m) {
case 'crud' :
$replace = 'action';
break;
case 'c' :
switch ($match[2]) {
case '=' :
$replace = " LIKE '%add%'";
break;
case '!=' :
case '<>' :
$replace = " NOT LIKE '%add%'";
break;
default:
$replace = '';
}
break;
case 'r' :
switch ($match[2]) {
case '=' :
$replace = " LIKE '%view%' OR action LIKE '%report%'";
break;
case '!=' :
case '<>' :
$replace = " NOT LIKE '%view%' AND action NOT LIKE '%report%'";
break;
default:
$replace = '';
}
break;
case 'u' :
switch ($match[2]) {
case '=' :
$replace = " LIKE '%update%'";
break;
case '!=' :
case '<>' :
$replace = " NOT LIKE '%update%'";
break;
default:
$replace = '';
}
break;
case 'd' :
switch ($match[2]) {
case '=' :
$replace = " LIKE '%delete%'";
break;
case '!=' :
case '<>' :
$replace = " NOT LIKE '%delete%'";
break;
default:
$replace = '';
}
break;
default :
$replace = '';
}
$return .= $replace;
}
return $return;
}
}
+41
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/>.
/**
* Fixtures for legacy logging testing.
*
* @package logstore_legacy
* @copyright 2014 onwards Ankit Agarwal <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace logstore_legacy\test;
defined('MOODLE_INTERNAL') || die();
class unittest_logstore_legacy extends \logstore_legacy\log\store {
/**
* Wrapper to make protected method accessible during testing.
*
* @param array $match matched string for the passed pattern
*
* @return string The sql string to use instead of original
*/
public static function replace_crud($match) {
return parent::replace_crud($match);
}
}
@@ -25,6 +25,7 @@
defined('MOODLE_INTERNAL') || die();
require_once(__DIR__ . '/fixtures/event.php');
require_once(__DIR__ . '/fixtures/store.php');
class logstore_legacy_store_testcase extends advanced_testcase {
public function test_log_writing() {
@@ -160,4 +161,58 @@ class logstore_legacy_store_testcase extends advanced_testcase {
set_config('loglegacy', 0, 'logstore_legacy');
get_log_manager(true);
}
/**
* Test replace_crud
*/
public function test_replace_crud() {
$crudregex = logstore_legacy\test\unittest_logstore_legacy::CRUD_REGEX;
$selectwhere = "edulevel = 0";
$updatewhere = preg_replace_callback($crudregex,
'logstore_legacy\test\unittest_logstore_legacy::replace_crud', $selectwhere);
$this->assertEquals($selectwhere, $updatewhere);
$selectwhere = "edulevel = 0 and crud = 'u'";
$updatewhere = preg_replace_callback($crudregex,
'logstore_legacy\test\unittest_logstore_legacy::replace_crud', $selectwhere);
$this->assertEquals("edulevel = 0 and action LIKE '%update%'", $updatewhere);
$selectwhere = "edulevel = 0 and crud != 'u'";
$updatewhere = preg_replace_callback($crudregex,
'logstore_legacy\test\unittest_logstore_legacy::replace_crud', $selectwhere);
$this->assertEquals("edulevel = 0 and action NOT LIKE '%update%'", $updatewhere);
$selectwhere = "edulevel = 0 and crud <> 'u'";
$updatewhere = preg_replace_callback($crudregex,
'logstore_legacy\test\unittest_logstore_legacy::replace_crud', $selectwhere);
$this->assertEquals("edulevel = 0 and action NOT LIKE '%update%'", $updatewhere);
$selectwhere = "edulevel = 0 and crud = 'r'";
$updatewhere = preg_replace_callback($crudregex,
'logstore_legacy\test\unittest_logstore_legacy::replace_crud', $selectwhere);
$this->assertEquals("edulevel = 0 and action LIKE '%view%' OR action LIKE '%report%'", $updatewhere);
$selectwhere = "edulevel = 0 and crud != 'r'";
$updatewhere = preg_replace_callback($crudregex,
'logstore_legacy\test\unittest_logstore_legacy::replace_crud', $selectwhere);
$this->assertEquals("edulevel = 0 and action NOT LIKE '%view%' AND action NOT LIKE '%report%'", $updatewhere);
$selectwhere = "edulevel = 0 and crud <> 'r'";
$updatewhere = preg_replace_callback($crudregex,
'logstore_legacy\test\unittest_logstore_legacy::replace_crud', $selectwhere);
$this->assertEquals("edulevel = 0 and action NOT LIKE '%view%' AND action NOT LIKE '%report%'", $updatewhere);
// The slq is incorrect, since quotes must not be present. Make sure this is not parsed.
$selectwhere = "edulevel = 0 and 'crud' != 'u'";
$updatewhere = preg_replace_callback($crudregex,
'logstore_legacy\test\unittest_logstore_legacy::replace_crud', $selectwhere);
$this->assertNotEquals("edulevel = 0 and action NOT LIKE '%update%'", $updatewhere);
$selectwhere = "edulevel = 0 and crud = 'u' OR crud != 'r' or crud <> 'd'";
$updatewhere = preg_replace_callback($crudregex,
'logstore_legacy\test\unittest_logstore_legacy::replace_crud', $selectwhere);
$this->assertEquals("edulevel = 0 and action LIKE '%update%' OR action NOT LIKE '%view%' AND action NOT LIKE '%report%' or action NOT LIKE '%delete%'", $updatewhere);
}
}