1 <?php
2 /**
3 * @package Joomla.Platform
4 * @subpackage Database
5 *
6 * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 */
9
10 defined('JPATH_PLATFORM') or die;
11
12 /**
13 * Joomla Platform Database Factory class
14 *
15 * @since 12.1
16 */
17 class JDatabaseFactory
18 {
19 /**
20 * Contains the current JDatabaseFactory instance
21 *
22 * @var JDatabaseFactory
23 * @since 12.1
24 */
25 private static $_instance = null;
26
27 /**
28 * Method to return a JDatabaseDriver instance based on the given options. There are three global options and then
29 * the rest are specific to the database driver. The 'database' option determines which database is to
30 * be used for the connection. The 'select' option determines whether the connector should automatically select
31 * the chosen database.
32 *
33 * Instances are unique to the given options and new objects are only created when a unique options array is
34 * passed into the method. This ensures that we don't end up with unnecessary database connection resources.
35 *
36 * @param string $name Name of the database driver you'd like to instantiate
37 * @param array $options Parameters to be passed to the database driver.
38 *
39 * @return JDatabaseDriver A database driver object.
40 *
41 * @since 12.1
42 * @throws RuntimeException
43 */
44 public function getDriver($name = 'mysqli', $options = array())
45 {
46 // Sanitize the database connector options.
47 $options['driver'] = preg_replace('/[^A-Z0-9_\.-]/i', '', $name);
48 $options['database'] = (isset($options['database'])) ? $options['database'] : null;
49 $options['select'] = (isset($options['select'])) ? $options['select'] : true;
50
51 // Derive the class name from the driver.
52 $class = 'JDatabaseDriver' . ucfirst(strtolower($options['driver']));
53
54 // If the class still doesn't exist we have nothing left to do but throw an exception. We did our best.
55 if (!class_exists($class))
56 {
57 throw new JDatabaseExceptionUnsupported(sprintf('Unable to load Database Driver: %s', $options['driver']));
58 }
59
60 // Create our new JDatabaseDriver connector based on the options given.
61 try
62 {
63 $instance = new $class($options);
64 }
65 catch (RuntimeException $e)
66 {
67 throw new JDatabaseExceptionConnecting(sprintf('Unable to connect to the Database: %s', $e->getMessage()), $e->getCode(), $e);
68 }
69
70 return $instance;
71 }
72
73 /**
74 * Gets an exporter class object.
75 *
76 * @param string $name Name of the driver you want an exporter for.
77 * @param JDatabaseDriver $db Optional JDatabaseDriver instance
78 *
79 * @return JDatabaseExporter An exporter object.
80 *
81 * @since 12.1
82 * @throws RuntimeException
83 */
84 public function getExporter($name, JDatabaseDriver $db = null)
85 {
86 // Derive the class name from the driver.
87 $class = 'JDatabaseExporter' . ucfirst(strtolower($name));
88
89 // Make sure we have an exporter class for this driver.
90 if (!class_exists($class))
91 {
92 // If it doesn't exist we are at an impasse so throw an exception.
93 throw new JDatabaseExceptionUnsupported('Database Exporter not found.');
94 }
95
96 $o = new $class;
97
98 if ($db instanceof JDatabaseDriver)
99 {
100 $o->setDbo($db);
101 }
102
103 return $o;
104 }
105
106 /**
107 * Gets an importer class object.
108 *
109 * @param string $name Name of the driver you want an importer for.
110 * @param JDatabaseDriver $db Optional JDatabaseDriver instance
111 *
112 * @return JDatabaseImporter An importer object.
113 *
114 * @since 12.1
115 * @throws RuntimeException
116 */
117 public function getImporter($name, JDatabaseDriver $db = null)
118 {
119 // Derive the class name from the driver.
120 $class = 'JDatabaseImporter' . ucfirst(strtolower($name));
121
122 // Make sure we have an importer class for this driver.
123 if (!class_exists($class))
124 {
125 // If it doesn't exist we are at an impasse so throw an exception.
126 throw new JDatabaseExceptionUnsupported('Database importer not found.');
127 }
128
129 $o = new $class;
130
131 if ($db instanceof JDatabaseDriver)
132 {
133 $o->setDbo($db);
134 }
135
136 return $o;
137 }
138
139 /**
140 * Gets an instance of the factory object.
141 *
142 * @return JDatabaseFactory
143 *
144 * @since 12.1
145 */
146 public static function getInstance()
147 {
148 return self::$_instance ? self::$_instance : new JDatabaseFactory;
149 }
150
151 /**
152 * Get the current query object or a new JDatabaseQuery object.
153 *
154 * @param string $name Name of the driver you want an query object for.
155 * @param JDatabaseDriver $db Optional JDatabaseDriver instance
156 *
157 * @return JDatabaseQuery The current query object or a new object extending the JDatabaseQuery class.
158 *
159 * @since 12.1
160 * @throws RuntimeException
161 */
162 public function getQuery($name, JDatabaseDriver $db = null)
163 {
164 // Derive the class name from the driver.
165 $class = 'JDatabaseQuery' . ucfirst(strtolower($name));
166
167 // Make sure we have a query class for this driver.
168 if (!class_exists($class))
169 {
170 // If it doesn't exist we are at an impasse so throw an exception.
171 throw new JDatabaseExceptionUnsupported('Database Query class not found');
172 }
173
174 return new $class($db);
175 }
176
177 /**
178 * Gets an instance of a factory object to return on subsequent calls of getInstance.
179 *
180 * @param JDatabaseFactory $instance A JDatabaseFactory object.
181 *
182 * @return void
183 *
184 * @since 12.1
185 */
186 public static function setInstance(JDatabaseFactory $instance = null)
187 {
188 self::$_instance = $instance;
189 }
190 }
191