diff --git a/.travis.yml b/.travis.yml index 5de5ca6..975912f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,37 +1,58 @@ language: php -sudo: required +sudo: true addons: firefox: "47.0.1" - postgresql: "9.3" apt: packages: - - oracle-java8-installer - - oracle-java8-set-default + - openjdk-8-jre-headless cache: directories: - $HOME/.composer/cache - $HOME/.npm -php: - - 7.0 - - 7.1 - -env: - global: - - MOODLE_BRANCH=MOODLE_34_STABLE - matrix: - - DB=pgsql - - DB=mysqli +# Alternate tests - 3.4 -> master on mysql/postgres and php. +matrix: + include: + - php: 7.0 + env: DB=pgsql MOODLE_BRANCH=MOODLE_34_STABLE + services: postgresql + addons: + - postgresql: "9.4" + - php: 7.0 + env: DB=mysqli MOODLE_BRANCH=MOODLE_35_STABLE + services: mysql + addons: + - mysql: "5.7" + - php: 7.2 + env: DB=pgsql MOODLE_BRANCH=MOODLE_36_STABLE + services: postgresql + addons: + - postgresql: "9.4" + - php: 7.2 + env: DB=mysqli MOODLE_BRANCH=MOODLE_37_STABLE + services: mysql + addons: + - mysql: "5.7" + - php: 7.3 + env: DB=pgsql MOODLE_BRANCH=MOODLE_37_STABLE + services: postgresql + addons: + - postgresql: "9.4" + - php: 7.3 + env: DB=pgsql MOODLE_BRANCH=master + services: postgresql + addons: + - postgresql: "9.4" before_install: - phpenv config-rm xdebug.ini - nvm install 8.9 - nvm use 8.9 - cd ../.. - - composer create-project -n --no-dev --prefer-dist moodlerooms/moodle-plugin-ci ci ^2 + - composer create-project -n --no-dev --prefer-dist blackboard-open-source/moodle-plugin-ci ci ^2 - export PATH="$(cd ci/bin; pwd):$(cd ci/vendor/bin; pwd):$PATH" install: diff --git a/lang/en/tool_mergeusers.php b/lang/en/tool_mergeusers.php index 3c0dc7c..94ab694 100644 --- a/lang/en/tool_mergeusers.php +++ b/lang/en/tool_mergeusers.php @@ -46,7 +46,6 @@ to that problem, repeat the merging action to complete it with success.'; $string['tableskipped'] = 'For logging or security reasons we are skipping {$a}.
To remove these entries, delete the old user once this script has run successfully.'; -$string['errordatabase'] = 'Error: Database type {$a} not supported.'; $string['invaliduser'] = 'Invalid user'; $string['cligathering:description'] = "Introduce pairs of user's id to merge the first one into the\n second one. The first user id (fromid) will 'lose' all its data to be 'migrated'\n diff --git a/lib/mergeusertool.php b/lib/mergeusertool.php index 8bbaf49..7a35b5f 100644 --- a/lib/mergeusertool.php +++ b/lib/mergeusertool.php @@ -55,12 +55,6 @@ */ class MergeUserTool { - - /** - * @var bool true if current database is supported; false otherwise. - */ - protected $supportedDatabase; - /** * @var array associative array showing the user-related fields per database table, * without the $CFG->prefix on each. @@ -129,35 +123,13 @@ class MergeUserTool */ public function __construct(tool_mergeusers_config $config = null, tool_mergeusers_logger $logger = null) { - global $CFG; - $this->logger = (is_null($logger)) ? new tool_mergeusers_logger() : $logger; $config = (is_null($config)) ? tool_mergeusers_config::instance() : $config; - $this->supportedDatabase = true; $this->checkTransactionSupport(); - switch ($CFG->dbtype) { - case 'sqlsrv': - case 'mssql': - $this->sqlListTables = "SELECT name FROM sys.Tables WHERE name LIKE '" . - $CFG->prefix . "%' AND type = 'U' ORDER BY name"; - break; - case 'mysqli': - case 'mariadb': - $this->sqlListTables = "SHOW TABLES like '" . $CFG->prefix . "%'"; - break; - case 'pgsql': - $this->sqlListTables = "SELECT table_name FROM information_schema.tables WHERE table_name LIKE '" . - $CFG->prefix . "%' AND table_schema = 'public'"; - break; - default: - $this->supportedDatabase = false; - $this->sqlListTables = ""; - } - - // these are tables we don't want to modify due to logging or security reasons. - // we flip key<-->value to accelerate lookups. + // These are tables we don't want to modify due to logging or security reasons. + // We flip key<-->value to accelerate lookups. $this->tablesToSkip = array_flip($config->exceptions); $excluded = explode(',', get_config('tool_mergeusers', 'excluded_exceptions')); $excluded = array_flip($excluded); @@ -167,16 +139,11 @@ public function __construct(tool_mergeusers_config $config = null, tool_mergeuse } } - // these are special cases, corresponding to tables with compound indexes that - // need a special treatment. + // These are special cases, corresponding to tables with compound indexes that need a special treatment. $this->tablesWithCompoundIndex = $config->compoundindexes; // Initializes user-related field names. - $userFieldNames = array(); - foreach ($config->userfieldnames as $tablename => $fields) { - $userFieldNames[$tablename] = "'" . implode("','", $fields) . "'"; - } - $this->userFieldNames = $userFieldNames; + $this->userFieldNames = $config->userfieldnames; // Load available TableMerger tools. $tableMergers = array(); @@ -194,7 +161,7 @@ public function __construct(tool_mergeusers_config $config = null, tool_mergeuse new moodle_url('/admin/tool/mergeusers/index.php'), $class); } } - // append any additional table to skip. + // Append any additional table to skip. $tablesProcessedByTableMergers = array_merge($tablesProcessedByTableMergers, $tm->getTablesToSkip()); $tableMergers[$tableName] = $tm; } @@ -204,11 +171,7 @@ public function __construct(tool_mergeusers_config $config = null, tool_mergeuse $this->alwaysRollback = !empty($config->alwaysRollback); $this->debugdb = !empty($config->debugdb); - // this will abort execution if local database is not supported. - $this->checkDatabaseSupport(); - - // initializes the list of fields and tables to check in the current database, - // given the local configuration. + // Initializes the list of fields and tables to check in the current database, given the local configuration. $this->init(); } @@ -258,14 +221,9 @@ public function merge($toid, $fromid) */ private function _merge($toid, $fromid) { - global $CFG, $DB; + global $DB; // initial checks. - // database type is supported? - if (!$this->supportedDatabase) { - return array(false, array(get_string('errordatabase', 'tool_mergeusers', $CFG->dbtype))); - } - // are they the same? if ($fromid == $toid) { // yes. do nothing. @@ -366,27 +324,26 @@ private function _merge($toid, $fromid) */ private function init() { - global $CFG, $DB; + global $DB; $userFieldsPerTable = array(); - $tableNames = $DB->get_records_sql($this->sqlListTables); - $prefixLength = strlen($CFG->prefix); + // Name of tables comes without db prefix. + $tableNames = $DB->get_tables(false); - foreach ($tableNames as $fullTableName => $toIgnore) { + foreach ($tableNames as $tableName) { - if (!trim($fullTableName)) { - //This section should never be executed due to the way Moodle returns its resultsets - // Skipping due to blank table name + if (!trim($tableName)) { + // This section should never be executed due to the way Moodle returns its resultsets. + // Skipping due to blank table name. continue; } else { - $tableName = substr($fullTableName, $prefixLength); - // table specified to be excluded. + // Table specified to be excluded. if (isset($this->tablesToSkip[$tableName])) { - $this->tablesSkipped[$tableName] = $fullTableName; + $this->tablesSkipped[$tableName] = $tableName; continue; } - // table specified to be processed additionally by a TableMerger. + // Table specified to be processed additionally by a TableMerger. if (isset($this->tablesProcessedByTableMergers[$tableName])) { continue; } @@ -397,10 +354,11 @@ private function init() $this->userFieldNames[$tableName] : $this->userFieldNames['default']; - $currentFields = $this->getCurrentUserFieldNames($fullTableName, $userFields); + $arrayUserFields = array_flip($userFields); + $currentFields = $this->getCurrentUserFieldNames($tableName, $arrayUserFields); if ($currentFields !== false) { - $userFieldsPerTable[$tableName] = array_values($currentFields); + $userFieldsPerTable[$tableName] = $currentFields; } } @@ -436,25 +394,6 @@ private function init() $this->tablesWithCompoundIndex = $existingCompoundIndexes; } - /** - * Check whether current Moodle's database type is supported. - * If it is not supported, it aborts the execution with an error message, checking whether - * it is on a CLI script or on web. - */ - private function checkDatabaseSupport() - { - global $CFG; - - if (!$this->supportedDatabase) { - if (CLI_SCRIPT) { - cli_error('Error: ' . __METHOD__ . ':: ' . get_string('errordatabase', 'tool_mergeusers', $CFG->dbtype)); - } else { - print_error('errordatabase', 'tool_mergeusers', new moodle_url('/admin/tool/mergeusers/index.php'), - $CFG->dbtype); - } - } - } - /** * Checks whether the current database supports transactions. * If settings of this plugin are set up to allow only transactions, @@ -492,16 +431,15 @@ public function checkTransactionSupport() */ private function getCurrentUserFieldNames($tableName, $userFields) { - global $CFG, $DB; - return $DB->get_fieldset_sql(" - SELECT DISTINCT column_name - FROM - INFORMATION_SCHEMA.Columns - WHERE - TABLE_NAME = ? AND - (TABLE_SCHEMA = ? OR TABLE_CATALOG=?) AND - COLUMN_NAME IN (" . $userFields . ")", - array($tableName, $CFG->dbname, $CFG->dbname)); + global $DB; + $columns = $DB->get_columns($tableName,false); + $usercolumns = []; + foreach($columns as $column) { + if (isset($userFields[$column->name])) { + $usercolumns[$column->name] = $column->name; + } + } + return $usercolumns; } /** @@ -512,7 +450,7 @@ private function updateGrades($toid, $fromid) { global $DB, $CFG; require_once($CFG->libdir.'/gradelib.php'); - $sql = "SELECT iteminstance, itemmodule, courseid + $sql = "SELECT DISTINCT gi.iteminstance, gi.itemmodule, gi.courseid FROM {grade_grades} gg INNER JOIN {grade_items} gi on gg.itemid = gi.id WHERE itemtype = 'mod' AND (gg.userid = :toid OR gg.userid = :fromid)";