Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/#154 better handling of mysql sql modes in setup #155

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions composer.json
Expand Up @@ -10,5 +10,9 @@
"license": ["GPL-2.0"],
"require-dev": {
"phpunit/phpunit": "^8"
},
"require": {
"ext-mysqli": "*",
"ext-json": "*"
}
}
146 changes: 81 additions & 65 deletions contenido/classes/class.systemtest.php
Expand Up @@ -339,7 +339,8 @@ public function runTests($testFileSystem = true) {

$this->storeResult($this->testIconv(), self::C_SEVERITY_ERROR, i18n("PHP iconv functions are not available."), i18n("PHP has been compiled with the --without-iconv directive. CONTENIDO won't work without the iconv functions."), i18n("iconv is available"));

$result = $this->testMySQL($this->_config['db']['connection']['host'], $this->_config['db']['connection']['user'], $this->_config['db']['connection']['password']);
$cfgDbCon = $this->_config['db']['connection'];
$result = $this->testMySQL($cfgDbCon['host'], $cfgDbCon['user'], $cfgDbCon['password'], !empty($cfgDbCon['options']) ? $cfgDbCon['options'] : []);
switch ($result) {
case self::CON_MYSQL_OK:
$this->storeResult(true, self::C_SEVERITY_ERROR, "", "", i18n("Database connection works"));
Expand Down Expand Up @@ -374,19 +375,19 @@ public function runTests($testFileSystem = true) {
*/
public function storeResult($result, $severity, $errorHeadline = "", $errorMessage = "", $successHeadline = "", $successMessage = "") {
if ($result) {
$this->_messages[] = array(
$this->_messages[] = [
"result" => $result,
"severity" => $severity,
"headline" => $successHeadline,
"message" => $successMessage
);
];
} else {
$this->_messages[] = array(
$this->_messages[] = [
"result" => $result,
"severity" => $severity,
"headline" => $errorHeadline,
"message" => $errorMessage
);
];
}
}

Expand Down Expand Up @@ -476,7 +477,7 @@ protected function getFileInfo($sFilename) {
break;
}

$aFileinfo = array();
$aFileinfo = [];
$aFileinfo["info"] = $info;
$aFileinfo["type"] = $type;
$aFileinfo["owner"]["read"] = ($oiFilePermissions & 0x0100) ? true : false;
Expand Down Expand Up @@ -708,33 +709,33 @@ protected function getAsBytes($val) {
* with the cDB object on the first place and a bool on the second
*/
protected function doMySQLConnect($host, $username, $password) {
$aOptions = array(
'connection' => array(
$aOptions = [
'connection' => [
'host' => $host,
'user' => $username,
'password' => $password
)
);
]
];
$db = null;
try {
$db = new cDb($aOptions);
} catch (cDbException $e) {
return array(
return [
$db,
false
);
];
}

if ($db->connect() == 0) {
return array(
return [
$db,
false
);
];
} else {
return array(
return [
$db,
true
);
];
}
}

Expand Down Expand Up @@ -1017,27 +1018,36 @@ public function testMySQLiExtension() {
* @param string $host
* @param string $username
* @param string $password
* @param array $options
*
* @return bool
* true if the test passed and false if not
*
* @throws cDbException
*/
public function testMySQLModeStrict($host, $username, $password) {
// host, user and password
$dbCfg = array(
'connection' => array(
public function testMySQLModeStrict($host, $username, $password, array $options = []) {
// host, user, password and options
$dbCfg = [
'connection' => [
'host' => $host,
'user' => $username,
'password' => $password
)
);
'password' => $password,
'options' => $options,
],
];

// Get not supported SQL modes
$notSupportedSqlModes = array_map('trim', explode(',', CON_DB_NOT_SUPPORTED_SQL_MODES));

// Retrieve SQL modes set in current connection session and compare against not supported ones
$db = new cDb($dbCfg);
$db->query('SELECT LOWER(@@GLOBAL.sql_mode) AS sql_mode');
$db->query('SELECT UPPER(@@SESSION.sql_mode) AS sql_mode');
if ($db->nextRecord()) {
if (cString::findFirstPos($db->f('sql_mode'), 'strict_trans_tables') !== false || cString::findFirstPos($db->f('sql_mode'), 'strict_all_tables') !== false) {
return false;
$sqlModes = array_map('trim', explode(',', $db->f('sql_mode')));
foreach ($sqlModes as $sqlMode) {
if (in_array($sqlMode, $notSupportedSqlModes)) {
return false;
}
}
}
return true;
Expand All @@ -1048,13 +1058,14 @@ public function testMySQLModeStrict($host, $username, $password) {
* @param string $host
* @param string $username
* @param string $password
* @param array $options
*
* @return int
* 1 if the test passed and > 1 if not
*
* @throws cDbException
*/
public function testMySQL($host, $username, $password) {
public function testMySQL($host, $username, $password, array $options = []) {
list($handle, $status) = $this->doMySQLConnect($host, $username, $password);

$errorMessage = "";
Expand All @@ -1075,7 +1086,7 @@ public function testMySQL($host, $username, $password) {
return self::CON_MYSQL_CANT_CONNECT;
}

if (!$this->testMySQLModeStrict($host, $username, $password)) {
if (!$this->testMySQLModeStrict($host, $username, $password, $options)) {
return self::CON_MYSQL_STRICT_MODE;
}

Expand All @@ -1097,74 +1108,74 @@ public function testFilesystem($testConfig = true, $testFrontend = true) {

$status = true;

$files = array(
$files = [
// check files
array(
[
'filename' => $this->_config['path']['contenido_logs'] . "errorlog.txt",
'severity' => self::C_SEVERITY_WARNING
),
array(
],
[
'filename' => $this->_config['path']['contenido_logs'] . "setuplog.txt",
'severity' => self::C_SEVERITY_WARNING
),
array(
],
[
'filename' => $this->_config['path']['contenido_cronlog'] . "pseudo-cron.log",
'severity' => self::C_SEVERITY_WARNING
),
array(
],
[
'filename' => $this->_config['path']['contenido_cronlog'] . "session_cleanup.php.job",
'severity' => self::C_SEVERITY_WARNING
),
array(
],
[
'filename' => $this->_config['path']['contenido_cronlog'] . "send_reminder.php.job",
'severity' => self::C_SEVERITY_WARNING
),
array(
],
[
'filename' => $this->_config['path']['contenido_cronlog'] . "optimize_database.php.job",
'severity' => self::C_SEVERITY_WARNING
),
array(
],
[
'filename' => $this->_config['path']['contenido_cronlog'] . "move_old_stats.php.job",
'severity' => self::C_SEVERITY_WARNING
),
array(
],
[
'filename' => $this->_config['path']['contenido_cronlog'] . "move_articles.php.job",
'severity' => self::C_SEVERITY_WARNING
),
array(
],
[
'filename' => $this->_config['path']['contenido_cronlog'] . "linkchecker.php.job",
'severity' => self::C_SEVERITY_WARNING
),
array(
],
[
'filename' => $this->_config['path']['contenido_cronlog'] . "run_newsletter_job.php.job",
'severity' => self::C_SEVERITY_WARNING
),
array(
],
[
'filename' => $this->_config['path']['contenido_cronlog'] . "setfrontenduserstate.php.job",
'severity' => self::C_SEVERITY_WARNING
),
array(
],
[
'filename' => $this->_config['path']['contenido_cronlog'] . "advance_workflow.php.job",
'severity' => self::C_SEVERITY_WARNING
),
array(
],
[
'filename' => $this->_config['path']['contenido_cache'],
'severity' => self::C_SEVERITY_WARNING,
'dir' => true
),
array(
],
[
'filename' => $this->_config['path']['contenido_temp'],
'severity' => self::C_SEVERITY_WARNING,
'dir' => true
),
array(
],
[
'filename' => $this->_config['path']['contenido_config'] . "config.php",
'severity' => self::C_SEVERITY_ERROR,
'config' => $testConfig
)
);
]
];

$frontendFiles = array(
$frontendFiles = [
"cache",
"cache/code",
"css",
Expand All @@ -1181,7 +1192,7 @@ public function testFilesystem($testConfig = true, $testFrontend = true) {
"js",
"templates",
"upload"
);
];

$ret = true;
foreach ($files as $key => $file) {
Expand Down Expand Up @@ -1337,7 +1348,7 @@ protected function testSingleFile($filename, $severity, $dir = false) {
* @throws cInvalidArgumentException
*/
public function testFrontendFolderCreation() {
$directories = array(
$directories = [
"cms/cache",
"cms/cache/code",
"cms/css",
Expand All @@ -1353,7 +1364,7 @@ public function testFrontendFolderCreation() {
"cms/js",
"cms/templates",
"cms/upload"
);
];

$ret = true;

Expand Down Expand Up @@ -1453,7 +1464,12 @@ public function checkSetupMysql($setupType, $databaseName, $databasePrefix, $cha
switch ($setupType) {
case "setup":

$db = getSetupMySQLDBConnection(false);
try {
$db = getSetupMySQLDBConnection(false);
} catch (Exception $e) {
$this->storeResult(false, cSystemtest::C_SEVERITY_ERROR, i18n("Could not connect to MySQL database", "setup"), $e->getMessage());
return;
}

// Check if the database exists
$status = checkMySQLDatabaseExists($db, $databaseName);
Expand Down
4 changes: 2 additions & 2 deletions contenido/classes/db/class.db.driver.handler.php
Expand Up @@ -274,7 +274,7 @@ public static function setDefaultConfiguration(array $defaultDbCfg) {
* Either The connection (object, resource, integer) or NULL
*/
protected function _getConnection($data) {
$hash = md5($this->_driverType . '-' . (is_array($data) ? implode('-', $data) : (string)$data));
$hash = md5($this->_driverType . '-' . (is_array($data) ? json_encode($data) : (string)$data));

return (isset(self::$_connectionCache[$hash])) ? self::$_connectionCache[$hash] : NULL;
}
Expand All @@ -288,7 +288,7 @@ protected function _getConnection($data) {
* The connection to store in cache
*/
protected function _setConnection($data, $connection) {
$hash = md5($this->_driverType . '-' . (is_array($data) ? implode('-', $data) : (string)$data));
$hash = md5($this->_driverType . '-' . (is_array($data) ? json_encode($data) : (string)$data));
self::$_connectionCache[$hash] = $connection;
}

Expand Down
55 changes: 55 additions & 0 deletions contenido/includes/defines.php
@@ -0,0 +1,55 @@
<?php
/**
* This file contains CONTENIDO constants.
*
* @package Core
* @subpackage Backend
* @author Murat Purc <murat@purc.de>
* @copyright four for business AG <www.4fb.de>
* @license http://www.contenido.org/license/LIZENZ.txt
* @link http://www.4fb.de
* @link http://www.contenido.org
*/

defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');

// CONTENIDO version
defined('CON_VERSION') || define('CON_VERSION', '4.10.1');

// Not supported MySQL SQL modes
if (!defined('CON_DB_NOT_SUPPORTED_SQL_MODES')) {
define(
'CON_DB_NOT_SUPPORTED_SQL_MODES',
'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE'
);
}

// Flag to strip slashes
if (function_exists('get_magic_quotes_gpc')) {
define('CON_STRIPSLASHES', !get_magic_quotes_gpc());
} else {
define('CON_STRIPSLASHES', true);
}

define('CON_PREDICT_SUFFICIENT', 1);
define('CON_PREDICT_NOTPREDICTABLE', 2);
define('CON_PREDICT_CHANGEPERM_SAMEOWNER', 3);
define('CON_PREDICT_CHANGEPERM_SAMEGROUP', 4);
define('CON_PREDICT_CHANGEPERM_OTHERS', 5);
define('CON_PREDICT_CHANGEUSER', 6);
define('CON_PREDICT_CHANGEGROUP', 7);
define('CON_PREDICT_WINDOWS', 8);

define('CON_BASEDIR_NORESTRICTION', 1);
define('CON_BASEDIR_DOTRESTRICTION', 2);
define('CON_BASEDIR_RESTRICTIONSUFFICIENT', 3);
define('CON_BASEDIR_INCOMPATIBLE', 4);

define('CON_IMAGERESIZE_GD', 1);
define('CON_IMAGERESIZE_IMAGEMAGICK', 2);
define('CON_IMAGERESIZE_CANTCHECK', 3);
define('CON_IMAGERESIZE_NOTHINGAVAILABLE', 4);

define('CON_EXTENSION_AVAILABLE', 1);
define('CON_EXTENSION_UNAVAILABLE', 2);
define('CON_EXTENSION_CANTCHECK', 3);