From bfa2f33c65611516ca774ac450d800a0df305edb Mon Sep 17 00:00:00 2001 From: Damien Metzger Date: Wed, 3 Jul 2013 11:04:34 +0200 Subject: [PATCH] [*] IN : the installer can now attempt to create the database for you --- classes/db/DbMySQLi.php | 15 +- classes/db/DbPDO.php | 516 +++++++++++----------- classes/db/MySQL.php | 6 + install-dev/controllers/http/database.php | 30 +- install-dev/models/database.php | 11 +- install-dev/theme/js/database.js | 115 +++-- 6 files changed, 380 insertions(+), 313 deletions(-) diff --git a/classes/db/DbMySQLi.php b/classes/db/DbMySQLi.php index e89d59ccc..43c4eaf52 100644 --- a/classes/db/DbMySQLi.php +++ b/classes/db/DbMySQLi.php @@ -52,6 +52,18 @@ class DbMySQLiCore extends Db return $this->link; } + + public static function createDatabase($host, $user, $password, $dbname) + { + if (strpos($host, ':') !== false) + { + list($host, $port) = explode(':', $host); + $link = @new mysqli($host, $this->user, $this->password, null, $port); + } + else + $link = @new mysqli($host, $user, $password); + return $link->query('CREATE DATABASE `'.bqSQL($dbname).'`'); + } /** * @see DbCore::disconnect() @@ -169,7 +181,8 @@ class DbMySQLiCore extends Db if (!$link->options(MYSQLI_OPT_CONNECT_TIMEOUT, $timeout)) return 1; - if (!$link->real_connect($server, $user, $pwd, $db)) + // There is an @ because mysqli throw a warning when the database does not exists + if (!@$link->real_connect($server, $user, $pwd, $db)) return (mysqli_connect_errno() == 1049) ? 2 : 1; $link->close(); diff --git a/classes/db/DbPDO.php b/classes/db/DbPDO.php index 7c6a43977..e257b753c 100644 --- a/classes/db/DbPDO.php +++ b/classes/db/DbPDO.php @@ -1,253 +1,263 @@ - -* @copyright 2007-2013 PrestaShop SA -* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) -* International Registered Trademark & Property of PrestaShop SA -*/ - -/** - * This class is currently only here for tests - * - * @since 1.5.0 - */ -class DbPDOCore extends Db -{ - protected static function _getPDO($host, $user, $password, $dbname, $timeout = 5) - { - $dsn = 'mysql:'; - if ($dbname) - $dsn .= 'dbname='.$dbname.';'; - if (preg_match('/^(.*):([0-9]+)$/', $host, $matches)) - $dsn .= 'host='.$matches[1].';port='.$matches[2]; - elseif (preg_match('#^.*:(/.*)$#', $host, $matches)) - $dsn .= 'unix_socket='.$matches[1]; - else - $dsn .= 'host='.$host; - - return new PDO($dsn, $user, $password, array(PDO::ATTR_TIMEOUT => $timeout, PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true)); - } - - /** - * @see DbCore::connect() - */ - public function connect() - { - try { - $this->link = $this->_getPDO($this->server, $this->user, $this->password, $this->database, 5); - } catch (PDOException $e) { - die(sprintf(Tools::displayError('Link to database cannot be established: %s'), utf8_encode($e->getMessage()))); - } - - // UTF-8 support - if ($this->link->exec('SET NAMES \'utf8\'') === false) - die(Tools::displayError('PrestaShop Fatal error: no utf-8 support. Please check your server configuration.')); - - return $this->link; - } - - /** - * @see DbCore::disconnect() - */ - public function disconnect() - { - unset($this->link); - } - - /** - * @see DbCore::_query() - */ - protected function _query($sql) - { - return $this->link->query($sql); - } - - /** - * @see DbCore::nextRow() - */ - public function nextRow($result = false) - { - if (!$result) - $result = $this->result; - return $result->fetch(PDO::FETCH_ASSOC); - } - - /** - * @see DbCore::_numRows() - */ - protected function _numRows($result) - { - return $result->rowCount(); - } - - /** - * @see DbCore::Insert_ID() - */ - public function Insert_ID() - { - return $this->link->lastInsertId(); - } - - /** - * @see DbCore::Affected_Rows() - */ - public function Affected_Rows() - { - return $this->result->rowCount(); - } - - /** - * @see DbCore::getMsgError() - */ - public function getMsgError($query = false) - { - $error = $this->link->errorInfo(); - return ($error[0] == '00000') ? '' : $error[2]; - } - - /** - * @see DbCore::getNumberError() - */ - public function getNumberError() - { - $error = $this->link->errorInfo(); - return isset($error[1]) ? $error[1] : 0; - } - - /** - * @see DbCore::getVersion() - */ - public function getVersion() - { - return $this->getValue('SELECT VERSION()'); - } - - /** - * @see DbCore::_escape() - */ - public function _escape($str) - { - $search = array("\\", "\0", "\n", "\r", "\x1a", "'", '"'); - $replace = array("\\\\", "\\0", "\\n", "\\r", "\Z", "\'", '\"'); - return str_replace($search, $replace, $str); - } - - /** - * @see DbCore::set_db() - */ - public function set_db($db_name) - { - return $this->link->exec('USE '.pSQL($db_name)); - } - - /** - * @see Db::hasTableWithSamePrefix() - */ - public static function hasTableWithSamePrefix($server, $user, $pwd, $db, $prefix) - { - try { - $link = DbPDO::_getPDO($server, $user, $pwd, $db, 5); - } catch (PDOException $e) { - return false; - } - - $sql = 'SHOW TABLES LIKE \''.$prefix.'%\''; - $result = $link->query($sql); - return (bool)$result->fetch(); - } - - public static function checkCreatePrivilege($server, $user, $pwd, $db, $prefix, $engine = null) - { - try { - $link = DbPDO::_getPDO($server, $user, $pwd, $db, 5); - } catch (PDOException $e) { - return false; - } - - $sql = ' - CREATE TABLE `'.$prefix.'test` ( - `test` tinyint(1) unsigned NOT NULL - ) ENGINE=MyISAM'; - $result = $link->query($sql); - if (!$result) - { - $error = $link->errorInfo(); - return $error[2]; - } - $link->query('DROP TABLE `'.$prefix.'test`'); - return true; - } - - /** - * @see Db::checkConnection() - */ - public static function tryToConnect($server, $user, $pwd, $db, $newDbLink = true, $engine = null, $timeout = 5) - { - try { - $link = DbPDO::_getPDO($server, $user, $pwd, $db, $timeout); - } catch (PDOException $e) { - return ($e->getCode() == 1049) ? 2 : 1; - } - unset($link); - return 0; - } - - public function getBestEngine() - { - $value = 'InnoDB'; - - $sql = 'SHOW VARIABLES WHERE Variable_name = \'have_innodb\''; - $result = $this->link->query($sql); - if (!$result) - $value = 'MyISAM'; - $row = $result->fetch(); - if (!$row || strtolower($row['Value']) != 'yes') - $value = 'MyISAM'; - - /* MySQL >= 5.6 */ - $sql = 'SHOW ENGINES'; - $result = $this->link->query($sql); - while ($row = $result->fetch()) - if ($row['Engine'] == 'InnoDB') - { - if (in_array($row['Support'], array('DEFAULT', 'YES'))) - $value = 'InnoDB'; - break; - } - return $value; - } - - /** - * @see Db::checkEncoding() - */ - public static function tryUTF8($server, $user, $pwd) - { - try { - $link = DbPDO::_getPDO($server, $user, $pwd, false, 5); - } catch (PDOException $e) { - return false; - } - $result = $link->exec('SET NAMES \'utf8\''); - unset($link); - - return ($result === false) ? false : true; - } -} + +* @copyright 2007-2013 PrestaShop SA +* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +/** + * This class is currently only here for tests + * + * @since 1.5.0 + */ +class DbPDOCore extends Db +{ + protected static function _getPDO($host, $user, $password, $dbname, $timeout = 5) + { + $dsn = 'mysql:'; + if ($dbname) + $dsn .= 'dbname='.$dbname.';'; + if (preg_match('/^(.*):([0-9]+)$/', $host, $matches)) + $dsn .= 'host='.$matches[1].';port='.$matches[2]; + elseif (preg_match('#^.*:(/.*)$#', $host, $matches)) + $dsn .= 'unix_socket='.$matches[1]; + else + $dsn .= 'host='.$host; + + return new PDO($dsn, $user, $password, array(PDO::ATTR_TIMEOUT => $timeout, PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true)); + } + + public static function createDatabase($host, $user, $password, $dbname) + { + try { + $link = DbPDO::_getPDO($host, $user, $password, false); + return $link->exec('CREATE DATABASE `'.bqSQL($dbname).'`'); + } catch (PDOException $e) { + return false; + } + } + + /** + * @see DbCore::connect() + */ + public function connect() + { + try { + $this->link = $this->_getPDO($this->server, $this->user, $this->password, $this->database, 5); + } catch (PDOException $e) { + die(sprintf(Tools::displayError('Link to database cannot be established: %s'), utf8_encode($e->getMessage()))); + } + + // UTF-8 support + if ($this->link->exec('SET NAMES \'utf8\'') === false) + die(Tools::displayError('PrestaShop Fatal error: no utf-8 support. Please check your server configuration.')); + + return $this->link; + } + + /** + * @see DbCore::disconnect() + */ + public function disconnect() + { + unset($this->link); + } + + /** + * @see DbCore::_query() + */ + protected function _query($sql) + { + return $this->link->query($sql); + } + + /** + * @see DbCore::nextRow() + */ + public function nextRow($result = false) + { + if (!$result) + $result = $this->result; + return $result->fetch(PDO::FETCH_ASSOC); + } + + /** + * @see DbCore::_numRows() + */ + protected function _numRows($result) + { + return $result->rowCount(); + } + + /** + * @see DbCore::Insert_ID() + */ + public function Insert_ID() + { + return $this->link->lastInsertId(); + } + + /** + * @see DbCore::Affected_Rows() + */ + public function Affected_Rows() + { + return $this->result->rowCount(); + } + + /** + * @see DbCore::getMsgError() + */ + public function getMsgError($query = false) + { + $error = $this->link->errorInfo(); + return ($error[0] == '00000') ? '' : $error[2]; + } + + /** + * @see DbCore::getNumberError() + */ + public function getNumberError() + { + $error = $this->link->errorInfo(); + return isset($error[1]) ? $error[1] : 0; + } + + /** + * @see DbCore::getVersion() + */ + public function getVersion() + { + return $this->getValue('SELECT VERSION()'); + } + + /** + * @see DbCore::_escape() + */ + public function _escape($str) + { + $search = array("\\", "\0", "\n", "\r", "\x1a", "'", '"'); + $replace = array("\\\\", "\\0", "\\n", "\\r", "\Z", "\'", '\"'); + return str_replace($search, $replace, $str); + } + + /** + * @see DbCore::set_db() + */ + public function set_db($db_name) + { + return $this->link->exec('USE '.pSQL($db_name)); + } + + /** + * @see Db::hasTableWithSamePrefix() + */ + public static function hasTableWithSamePrefix($server, $user, $pwd, $db, $prefix) + { + try { + $link = DbPDO::_getPDO($server, $user, $pwd, $db, 5); + } catch (PDOException $e) { + return false; + } + + $sql = 'SHOW TABLES LIKE \''.$prefix.'%\''; + $result = $link->query($sql); + return (bool)$result->fetch(); + } + + public static function checkCreatePrivilege($server, $user, $pwd, $db, $prefix, $engine = null) + { + try { + $link = DbPDO::_getPDO($server, $user, $pwd, $db, 5); + } catch (PDOException $e) { + return false; + } + + $sql = ' + CREATE TABLE `'.$prefix.'test` ( + `test` tinyint(1) unsigned NOT NULL + ) ENGINE=MyISAM'; + $result = $link->query($sql); + if (!$result) + { + $error = $link->errorInfo(); + return $error[2]; + } + $link->query('DROP TABLE `'.$prefix.'test`'); + return true; + } + + /** + * @see Db::checkConnection() + */ + public static function tryToConnect($server, $user, $pwd, $db, $newDbLink = true, $engine = null, $timeout = 5) + { + try { + $link = DbPDO::_getPDO($server, $user, $pwd, $db, $timeout); + } catch (PDOException $e) { + return ($e->getCode() == 1049) ? 2 : 1; + } + unset($link); + return 0; + } + + public function getBestEngine() + { + $value = 'InnoDB'; + + $sql = 'SHOW VARIABLES WHERE Variable_name = \'have_innodb\''; + $result = $this->link->query($sql); + if (!$result) + $value = 'MyISAM'; + $row = $result->fetch(); + if (!$row || strtolower($row['Value']) != 'yes') + $value = 'MyISAM'; + + /* MySQL >= 5.6 */ + $sql = 'SHOW ENGINES'; + $result = $this->link->query($sql); + while ($row = $result->fetch()) + if ($row['Engine'] == 'InnoDB') + { + if (in_array($row['Support'], array('DEFAULT', 'YES'))) + $value = 'InnoDB'; + break; + } + return $value; + } + + /** + * @see Db::checkEncoding() + */ + public static function tryUTF8($server, $user, $pwd) + { + try { + $link = DbPDO::_getPDO($server, $user, $pwd, false, 5); + } catch (PDOException $e) { + return false; + } + $result = $link->exec('SET NAMES \'utf8\''); + unset($link); + + return ($result === false) ? false : true; + } +} diff --git a/classes/db/MySQL.php b/classes/db/MySQL.php index d66f488da..c681a2ef2 100644 --- a/classes/db/MySQL.php +++ b/classes/db/MySQL.php @@ -46,6 +46,12 @@ class MySQLCore extends Db return $this->link; } + + public static function createDatabase($host, $user, $password, $dbname) + { + $link = mysql_connect($host, $user, $password); + return mysql_query('CREATE DATABASE `'.bqSQL($dbname).'`'); + } /** * @see DbCore::disconnect() diff --git a/install-dev/controllers/http/database.php b/install-dev/controllers/http/database.php index 3a603acdc..d6e950fc7 100644 --- a/install-dev/controllers/http/database.php +++ b/install-dev/controllers/http/database.php @@ -95,8 +95,8 @@ class InstallControllerHttpDatabase extends InstallControllerHttp { if (Tools::getValue('checkDb')) $this->processCheckDb(); - else if (Tools::getValue('sendMail')) - $this->processSendMail(); + elseif (Tools::getValue('createDb')) + $this->processCreateDb(); } /** @@ -120,28 +120,20 @@ class InstallControllerHttpDatabase extends InstallControllerHttp } /** - * Send a test email + * Attempt to create the database */ - public function processSendMail() + public function processCreateDb() { - $smtp_checked = (Tools::getValue('smtpChecked') == 'true'); - $server = Tools::getValue('smtpSrv'); - $encryption = Tools::getValue('smtpEnc'); - $port = Tools::getValue('smtpPort'); - $login = Tools::getValue('smtpLogin'); - $password = Tools::getValue('smtpPassword'); - $email = Tools::getValue('testEmail'); + $server = Tools::getValue('dbServer'); + $database = Tools::getValue('dbName'); + $login = Tools::getValue('dbLogin'); + $password = Tools::getValue('dbPassword'); - require_once _PS_INSTALL_MODELS_PATH_.'mail.php'; - $this->model_mail = new InstallModelMail($smtp_checked, $server, $login, $password, $port, $encryption, $email); - $result = $this->model_mail->send( - $this->l('Test message from PrestaShop'), - $this->l('This is a test message, your server is now available to send email') - ); + $success = $this->model_database->createDatabase($server, $database, $login, $password); $this->ajaxJsonAnswer( - $result === false, - ($result === false) ? $this->l('A test e-mail has been sent to %s', $email) : $this->l('An error occurred while sending email, please verify your parameters') + $success, + $success ? $this->l('Database is created') : $this->l('Cannot create the database automatically') ); } diff --git a/install-dev/models/database.php b/install-dev/models/database.php index 7105ebe9b..3620f677b 100644 --- a/install-dev/models/database.php +++ b/install-dev/models/database.php @@ -81,7 +81,10 @@ class InstallModelDatabase extends InstallAbstractModel break; case 2: - $errors[] = $this->language->l('Connection to MySQL server succeeded, but database "%s" not found', $database).$dbtype; + $errors[] = $this->language->l('Connection to MySQL server succeeded, but database "%s" not found', $database).$dbtype.'

+ '.sprintf(' + ', + $this->language->l('Attempt to create the database automatically')); break; } } @@ -89,6 +92,12 @@ class InstallModelDatabase extends InstallAbstractModel return $errors; } + public function createDatabase($server, $database, $login, $password) + { + $class = Db::getClass(); + return $class::createDatabase($server, $login, $password, $database); + } + public function getBestEngine($server, $database, $login, $password) { $class = Db::getClass(); diff --git a/install-dev/theme/js/database.js b/install-dev/theme/js/database.js index 0650f49ef..f19e8f651 100644 --- a/install-dev/theme/js/database.js +++ b/install-dev/theme/js/database.js @@ -1,39 +1,76 @@ -$(document).ready(function() -{ - // Check database configuration - $('#btTestDB').click(function() - { - $("#dbResultCheck").slideUp('slow'); - $.ajax({ - url: 'index.php', - data: { - 'checkDb': 'true', - 'dbServer': $('#dbServer').val(), - 'dbName': $('#dbName').val(), - 'dbLogin': $('#dbLogin').val(), - 'dbPassword': $('#dbPassword').val(), - 'dbEngine': $('#dbEngine').val(), - 'db_prefix': $('#db_prefix').val(), - 'clear': $('#db_clear').prop('checked') ? '1' : '0' - }, - dataType: 'json', - cache: false, - success: function(json) - { - $("#dbResultCheck") - .addClass((json.success) ? 'okBlock' : 'errorBlock') - .removeClass((json.success) ? 'errorBlock' : 'okBlock') - .html(json.message) - .slideDown('slow'); - }, - error: function(xhr) - { - $("#dbResultCheck") - .addClass('errorBlock') - .removeClass('okBlock') - .html('An error occurred:

'+xhr.responseText) - .slideDown('slow'); - } - }); - }); -}); \ No newline at end of file +$(document).ready(function() +{ + // Check database configuration + $('#btTestDB').click(function() + { + $("#dbResultCheck").slideUp('slow'); + $.ajax({ + url: 'index.php', + data: { + 'checkDb': 'true', + 'dbServer': $('#dbServer').val(), + 'dbName': $('#dbName').val(), + 'dbLogin': $('#dbLogin').val(), + 'dbPassword': $('#dbPassword').val(), + 'dbEngine': $('#dbEngine').val(), + 'db_prefix': $('#db_prefix').val(), + 'clear': $('#db_clear').prop('checked') ? '1' : '0' + }, + dataType: 'json', + cache: false, + success: function(json) + { + $("#dbResultCheck") + .addClass((json.success) ? 'okBlock' : 'errorBlock') + .removeClass((json.success) ? 'errorBlock' : 'okBlock') + .html(json.message) + .slideDown('slow'); + }, + error: function(xhr) + { + $("#dbResultCheck") + .addClass('errorBlock') + .removeClass('okBlock') + .html('An error occurred:

' + xhr.responseText) + .slideDown('slow'); + } + }); + }); +}); + +function bindCreateDB() +{ + // Attempt to create the database + $('#btCreateDB').click(function() + { + $("#dbResultCheck").slideUp('fast'); + $.ajax({ + url: 'index.php', + data: { + 'createDb': 'true', + 'dbServer': $('#dbServer').val(), + 'dbName': $('#dbName').val(), + 'dbLogin': $('#dbLogin').val(), + 'dbPassword': $('#dbPassword').val() + }, + dataType: 'json', + cache: false, + success: function(json) + { + $("#dbResultCheck") + .addClass((json.success) ? 'okBlock' : 'errorBlock') + .removeClass((json.success) ? 'errorBlock' : 'okBlock') + .html(json.message) + .slideDown('slow'); + }, + error: function(xhr) + { + $("#dbResultCheck") + .addClass('errorBlock') + .removeClass('okBlock') + .html('An error occurred:

' + xhr.responseText) + .slideDown('slow'); + } + }); + }); +} \ No newline at end of file