Нет описания

ConnectionFactory.php 3.2KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. <?php
  2. namespace MailPoet\Doctrine;
  3. if (!defined('ABSPATH')) exit;
  4. use MailPoet\Config\Env;
  5. use MailPoet\Doctrine\Types\BigIntType;
  6. use MailPoet\Doctrine\Types\JsonOrSerializedType;
  7. use MailPoet\Doctrine\Types\JsonType;
  8. use MailPoet\Doctrine\Types\SerializedArrayType;
  9. use MailPoet\Doctrine\Types\DateTimeTzToStringType;
  10. use MailPoetVendor\Doctrine\DBAL\DriverManager;
  11. use MailPoetVendor\Doctrine\DBAL\Driver\PDO\MySQL\Driver;
  12. use MailPoetVendor\Doctrine\DBAL\Platforms\MySqlPlatform;
  13. use MailPoetVendor\Doctrine\DBAL\Types\Type;
  14. use PDO;
  15. class ConnectionFactory {
  16. const DRIVER = 'pdo_mysql';
  17. const PLATFORM_CLASS = MySqlPlatform::class;
  18. private $minWaitTimeout = 60;
  19. private $types = [
  20. BigIntType::NAME => BigIntType::class,
  21. DateTimeTzToStringType::NAME => DateTimeTzToStringType::class,
  22. JsonType::NAME => JsonType::class,
  23. JsonOrSerializedType::NAME => JsonOrSerializedType::class,
  24. SerializedArrayType::NAME => SerializedArrayType::class,
  25. ];
  26. public function createConnection() {
  27. global $wpdb;
  28. $platformClass = self::PLATFORM_CLASS;
  29. $connectionParams = [
  30. 'wrapperClass' => SerializableConnection::class,
  31. 'driver' => self::DRIVER,
  32. 'driverClass' => Driver::class,
  33. 'platform' => new $platformClass,
  34. 'user' => Env::$dbUsername,
  35. 'password' => Env::$dbPassword,
  36. 'dbname' => Env::$dbName,
  37. 'driverOptions' => $this->getDriverOptions(Env::$dbTimezoneOffset, Env::$dbCharset, Env::$dbCollation),
  38. ];
  39. if (!empty(Env::$dbCharset)) {
  40. $connectionParams['charset'] = Env::$dbCharset;
  41. }
  42. if (!empty(Env::$dbSocket)) {
  43. $connectionParams['unix_socket'] = Env::$dbSocket;
  44. } else {
  45. $connectionParams['host'] = Env::$dbIsIpv6 ? ('[' . Env::$dbHost . ']') : Env::$dbHost;
  46. if (!empty(Env::$dbPort)) {
  47. $connectionParams['port'] = Env::$dbPort;
  48. } else {
  49. $connectionParams['port'] = $wpdb->get_var('SELECT @@port');
  50. }
  51. }
  52. $this->setupTypes();
  53. return DriverManager::getConnection($connectionParams);
  54. }
  55. private function getDriverOptions($timezoneOffset, $charset, $collation) {
  56. $driverOptions = [
  57. "@@session.time_zone = '$timezoneOffset'",
  58. "@@session.sql_mode = REPLACE(
  59. REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY', ''),
  60. 'ANSI_QUOTES', ''
  61. )", // This is needed because ONLY_FULL_GROUP_BY mode in MariaDB is much more restrictive than in MySQL
  62. // We need to use CONVERT for MySQL 8, Maria DB bug which triggers #1232 - Incorrect argument type to variable 'wait_timeout`
  63. // https://stackoverflow.com/questions/35187378/mariadb-type-error-when-setting-session-variable
  64. "@@session.wait_timeout = GREATEST(CONVERT(COALESCE(@@wait_timeout, 0), SIGNED), $this->minWaitTimeout)",
  65. ];
  66. if (!empty(Env::$dbCharset)) {
  67. $driverOptions[] = "NAMES $charset" . (empty($collation) ? '' : " COLLATE $collation");
  68. }
  69. return [
  70. PDO::MYSQL_ATTR_INIT_COMMAND => 'SET ' . implode(', ', $driverOptions),
  71. ];
  72. }
  73. private function setupTypes() {
  74. foreach ($this->types as $name => $class) {
  75. if (Type::hasType($name)) {
  76. Type::overrideType($name, $class);
  77. } else {
  78. Type::addType($name, $class);
  79. }
  80. }
  81. }
  82. }