Highway to PSR2
[openemr.git] / common / database / Connector.php
blob4d95533c285e7bb4ef68d6448047f418f0648c0a
1 <?php
2 /**
3 * This singleton class provides a pooled Doctrine connection to consumers. All connection data
4 * is configurable via sqlconf.php.
6 * If needed, the instance can be used in a transactional context:
7 * <code>
8 * $database = \common\database\Connector::Instance();
9 * $entityManager = $database->entityManager;
10 * $entityManager->getConnection()->beginTransaction();
11 * try {
12 * // Entity work here...
13 * $entityManager->persist($someEntityToBePersisted);
14 * $entityManager->flush();
15 * $entityManager->getConnection()->commit();
16 * } catch (Exception $e) {
17 * $entityManager->getConnection()->rollBack();
18 * throw $e;
19 * }
20 * </code>
22 * Copyright (C) 2016 Matthew Vita <matthewvita48@gmail.com>
24 * LICENSE: This program is free software; you can redistribute it and/or
25 * modify it under the terms of the GNU General Public License
26 * as published by the Free Software Foundation; either version 2
27 * of the License, or (at your option) any later version.
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
32 * You should have received a copy of the GNU General Public License
33 * along with this program. If not, see <http://opensource.org/licenses/gpl-license.php>.
35 * @package OpenEMR
36 * @author Matthew Vita <matthewvita48@gmail.com>
37 * @link http://www.open-emr.org
40 namespace common\database;
42 use \Doctrine\ORM\Tools\Setup;
43 use \Doctrine\ORM\EntityManager;
44 use \common\database\Auditor;
46 final class Connector
48 /**
49 * The pooled Doctrine connection.
51 public $entityManager;
53 /**
54 * Logger for noting connection/configuration information.
56 private $logger;
58 /**
59 * Default constructor.
61 private function __construct()
63 $this->logger = new \common\logging\Logger("\common\database\Connector");
64 $this->createConnection();
67 /**
68 * The only public method for consumers to either create or gain access to the sole singleton
69 * instance of the class.
71 * @return Connector instance
73 public static function Instance()
75 static $singletonInstance = null;
76 if ($singletonInstance === null) {
77 $singletonInstance = new Connector();
80 return $singletonInstance;
83 /**
84 * Creates the pooled Doctrine connection. All connection data is configurable via sqlconf.php.
85 * By default, the connection is pooled, in a nondev mode, and uses the pdo_mysql driver. Note
86 * that $GLOBALS["doctrine_connection_pooling"] and $GLOBALS["doctrine_dev_mode"] are used instead
87 * of $sqlconf[] because editing the sqlconf.php is not allowed (will mess up endusers trying to
88 * upgrade their install).
90 * @todo document throwables
92 private function createConnection()
94 global $sqlconf;
95 $entityPath = array(__DIR__ . "../entities");
97 $this->logger->trace("Connecting with " . ($GLOBALS["doctrine_connection_pooling"] ? "pooled" : "non-pooled") . " mode");
98 $connection = array(
99 'driver' => "pdo_mysql",
100 'host' => $sqlconf["host"],
101 'port' => $sqlconf["port"],
102 'user' => $sqlconf["login"],
103 'password' => $sqlconf["pass"],
104 'dbname' => $sqlconf["dbase"],
105 'pooled' => $GLOBALS["doctrine_connection_pooling"]
108 global $disable_utf8_flag;
110 $driverOptionsString = '';
112 if (!$disable_utf8_flag) {
113 $this->logger->trace("Enabling utf8");
114 $connection['charset'] = 'utf8';
115 $driverOptionsString = 'SET NAMES utf8';
118 $this->logger->trace("Clearing sql mode");
119 if (!empty($driverOptionsString)) {
120 $driverOptionsString .= ',sql_mode = \'\'';
121 } else {
122 $driverOptionsString = 'SET sql_mode = \'\'';
125 $this->logger->trace("Setting time zone");
126 $driverOptionsString .= ", time_zone = '" . (new \DateTime())->format("P") . "'";
128 // 1002 is the integer value of PDO::MYSQL_ATTR_INIT_COMMAND, which is
129 // executed when connecting to the MySQL server. Note if utf8 or sql
130 // mode commands fail, the connection will not be made.
131 $connection['driverOptions'] = array(
132 1002 => $driverOptionsString
135 $this->logger->trace("Wiring up Doctrine entities");
136 $configuration = Setup::createAnnotationMetadataConfiguration($entityPath, false, null, null, false);
137 $configuration->setAutoGenerateProxyClasses(true);
139 $this->logger->trace("Creating connection");
140 $this->entityManager = EntityManager::create($connection, $configuration);
142 $this->logger->trace("Wiring up SQL auditor to store audit entries in `log` table");
143 $this->entityManager->getConfiguration()->setSQLLogger(new Auditor());