blob: 1d084c8e411552ec783cc6018d7beba8e8f22dfb [file] [log] [blame]
Andrey Andreev83d15052011-12-22 13:35:42 +02001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Jones8dca0412010-03-05 13:01:44 -06002/**
3 * CodeIgniter
4 *
Phil Sturgeon07c1ac82012-03-09 17:03:37 +00005 * An open source application development framework for PHP 5.2.4 or newer
Derek Jones8dca0412010-03-05 13:01:44 -06006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Andrey Andreev83d15052011-12-22 13:35:42 +02008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Andrey Andreev83d15052011-12-22 13:35:42 +020010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * This source file is subject to the Open Software License (OSL 3.0) that is
12 * bundled with this package in the files license.txt / license.rst. It is
13 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
Derek Jones8dca0412010-03-05 13:01:44 -060018 *
19 * @package CodeIgniter
20 * @author EllisLab Dev Team
Greg Aker0defe5d2012-01-01 18:46:41 -060021 * @copyright Copyright (c) 2006 - 2012, EllisLab, Inc. (http://ellislab.com/)
Derek Jonesf4a4bd82011-10-20 12:18:42 -050022 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Jones8dca0412010-03-05 13:01:44 -060023 * @link http://codeigniter.com
24 * @since Version 1.0
25 * @filesource
26 */
27
Derek Jones8dca0412010-03-05 13:01:44 -060028/**
29 * CodeIgniter Driver Library Class
30 *
31 * This class enables you to create "Driver" libraries that add runtime ability
32 * to extend the capabilities of a class via additional driver objects
33 *
34 * @package CodeIgniter
35 * @subpackage Libraries
36 * @category Libraries
37 * @author EllisLab Dev Team
Barry Mienydd671972010-10-04 16:33:58 +020038 * @link
Derek Jones8dca0412010-03-05 13:01:44 -060039 */
40class CI_Driver_Library {
41
Timothy Warren0688ac92012-04-20 10:25:04 -040042 /**
43 * Array of drivers that are available to use with the driver class
44 *
45 * @var array
46 */
47 protected $valid_drivers = array();
Andrey Andreev56454792012-05-17 14:32:19 +030048
Timothy Warren0688ac92012-04-20 10:25:04 -040049 /**
50 * Name of the current class - usually the driver class
51 *
52 * @var string
53 */
Darren Hillc4e266b2011-08-30 15:40:27 -040054 protected $lib_name;
Barry Mienydd671972010-10-04 16:33:58 +020055
Darren Hill6fbf6bd2011-08-31 14:15:35 -040056 /**
57 * Get magic method
58 *
Darren Hillc4e266b2011-08-30 15:40:27 -040059 * The first time a child is used it won't exist, so we instantiate it
60 * subsequents calls will go straight to the proper child.
Darren Hill6fbf6bd2011-08-31 14:15:35 -040061 *
62 * @param string Child class name
63 * @return object Child class
64 */
Darren Hillc4e266b2011-08-30 15:40:27 -040065 public function __get($child)
dchill42c5079de2012-07-23 10:53:47 -040066 {
Darren Hill6fbf6bd2011-08-31 14:15:35 -040067 // Try to load the driver
dchill42c5872252012-07-30 14:53:11 -040068 return $this->load_driver($child);
Darren Hill6fbf6bd2011-08-31 14:15:35 -040069 }
Darren Hillc4e266b2011-08-30 15:40:27 -040070
Darren Hill6fbf6bd2011-08-31 14:15:35 -040071 /**
72 * Load driver
73 *
Darren Hillc4e266b2011-08-30 15:40:27 -040074 * Separate load_driver call to support explicit driver load by library or user
Darren Hill6fbf6bd2011-08-31 14:15:35 -040075 *
76 * @param string Child class name
77 * @return object Child class
78 */
Darren Hillc4e266b2011-08-30 15:40:27 -040079 public function load_driver($child)
Derek Jones8dca0412010-03-05 13:01:44 -060080 {
Pascal Kriete14287f32011-02-14 13:39:34 -050081 if ( ! isset($this->lib_name))
Derek Jones8dca0412010-03-05 13:01:44 -060082 {
Barry Mienydd671972010-10-04 16:33:58 +020083 $this->lib_name = get_class($this);
Derek Jones8dca0412010-03-05 13:01:44 -060084 }
85
86 // The class will be prefixed with the parent lib
87 $child_class = $this->lib_name.'_'.$child;
Andrey Andreev83d15052011-12-22 13:35:42 +020088
Phil Sturgeoneb2dcda2011-04-02 14:44:58 +010089 // Remove the CI_ prefix and lowercase
Darren Hill4d1cd4c2011-08-31 13:59:09 -040090 $lib_name = ucfirst(strtolower(str_replace('CI_', '', $this->lib_name)));
91 $driver_name = strtolower(str_replace('CI_', '', $child_class));
Andrey Andreev83d15052011-12-22 13:35:42 +020092
Phil Sturgeoneb2dcda2011-04-02 14:44:58 +010093 if (in_array($driver_name, array_map('strtolower', $this->valid_drivers)))
Derek Jones8dca0412010-03-05 13:01:44 -060094 {
95 // check and see if the driver is in a separate file
96 if ( ! class_exists($child_class))
97 {
98 // check application path first
Phil Sturgeon02d45b52011-08-14 09:56:47 -060099 foreach (get_instance()->load->get_package_paths(TRUE) as $path)
Derek Jones8dca0412010-03-05 13:01:44 -0600100 {
Phil Sturgeoneb2dcda2011-04-02 14:44:58 +0100101 // loves me some nesting!
102 foreach (array(ucfirst($driver_name), $driver_name) as $class)
Derek Jones8dca0412010-03-05 13:01:44 -0600103 {
Greg Aker3a746652011-04-19 10:59:47 -0500104 $filepath = $path.'libraries/'.$lib_name.'/drivers/'.$class.'.php';
Derek Jones8dca0412010-03-05 13:01:44 -0600105
Phil Sturgeoneb2dcda2011-04-02 14:44:58 +0100106 if (file_exists($filepath))
107 {
108 include_once $filepath;
Darren Hillc4e266b2011-08-30 15:40:27 -0400109 break 2;
Derek Jones8dca0412010-03-05 13:01:44 -0600110 }
111 }
112 }
Barry Mienydd671972010-10-04 16:33:58 +0200113
Derek Jones8dca0412010-03-05 13:01:44 -0600114 // it's a valid driver, but the file simply can't be found
115 if ( ! class_exists($child_class))
116 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300117 log_message('error', 'Unable to load the requested driver: '.$child_class);
118 show_error('Unable to load the requested driver: '.$child_class);
Derek Jones8dca0412010-03-05 13:01:44 -0600119 }
120 }
121
122 $obj = new $child_class;
123 $obj->decorate($this);
124 $this->$child = $obj;
125 return $this->$child;
126 }
Barry Mienydd671972010-10-04 16:33:58 +0200127
Derek Jones8dca0412010-03-05 13:01:44 -0600128 // The requested driver isn't valid!
Darren Hillc4e266b2011-08-30 15:40:27 -0400129 log_message('error', 'Invalid driver requested: '.$child_class);
130 show_error('Invalid driver requested: '.$child_class);
Derek Jones8dca0412010-03-05 13:01:44 -0600131 }
Derek Jones8dca0412010-03-05 13:01:44 -0600132
Derek Jones8dca0412010-03-05 13:01:44 -0600133}
Derek Jones8dca0412010-03-05 13:01:44 -0600134
Timothy Warren0688ac92012-04-20 10:25:04 -0400135// --------------------------------------------------------------------------
Derek Jones8dca0412010-03-05 13:01:44 -0600136
137/**
138 * CodeIgniter Driver Class
139 *
140 * This class enables you to create drivers for a Library based on the Driver Library.
141 * It handles the drivers' access to the parent library
142 *
143 * @package CodeIgniter
144 * @subpackage Libraries
145 * @category Libraries
146 * @author EllisLab Dev Team
Barry Mienydd671972010-10-04 16:33:58 +0200147 * @link
Derek Jones8dca0412010-03-05 13:01:44 -0600148 */
149class CI_Driver {
Barry Mienydd671972010-10-04 16:33:58 +0200150
Timothy Warren0688ac92012-04-20 10:25:04 -0400151 /**
152 * Instance of the parent class
153 *
154 * @var object
155 */
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300156 protected $_parent;
Derek Jones8dca0412010-03-05 13:01:44 -0600157
Timothy Warren0688ac92012-04-20 10:25:04 -0400158 /**
159 * List of methods in the parent class
160 *
161 * @var array
162 */
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300163 protected $_methods = array();
Andrey Andreev56454792012-05-17 14:32:19 +0300164
Timothy Warren0688ac92012-04-20 10:25:04 -0400165 /**
166 * List of properties in the parent class
167 *
168 * @var array
169 */
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300170 protected $_properties = array();
Derek Jones8dca0412010-03-05 13:01:44 -0600171
Timothy Warren0688ac92012-04-20 10:25:04 -0400172 /**
173 * Array of methods and properties for the parent class(es)
174 *
175 * @var array
176 */
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300177 protected static $_reflections = array();
Derek Jones8dca0412010-03-05 13:01:44 -0600178
179 /**
180 * Decorate
181 *
182 * Decorates the child with the parent driver lib's methods and properties
183 *
Derek Jones8dca0412010-03-05 13:01:44 -0600184 * @param object
185 * @return void
186 */
Greg Akera9263282010-11-10 15:26:43 -0600187 public function decorate($parent)
Derek Jones8dca0412010-03-05 13:01:44 -0600188 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300189 $this->_parent = $parent;
Barry Mienydd671972010-10-04 16:33:58 +0200190
Derek Jones8dca0412010-03-05 13:01:44 -0600191 // Lock down attributes to what is defined in the class
192 // and speed up references in magic methods
Barry Mienydd671972010-10-04 16:33:58 +0200193
Derek Jones8dca0412010-03-05 13:01:44 -0600194 $class_name = get_class($parent);
Barry Mienydd671972010-10-04 16:33:58 +0200195
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300196 if ( ! isset(self::$_reflections[$class_name]))
Derek Jones8dca0412010-03-05 13:01:44 -0600197 {
198 $r = new ReflectionObject($parent);
Barry Mienydd671972010-10-04 16:33:58 +0200199
Derek Jones8dca0412010-03-05 13:01:44 -0600200 foreach ($r->getMethods() as $method)
201 {
202 if ($method->isPublic())
203 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300204 $this->_methods[] = $method->getName();
Derek Jones8dca0412010-03-05 13:01:44 -0600205 }
206 }
207
Pascal Kriete14287f32011-02-14 13:39:34 -0500208 foreach ($r->getProperties() as $prop)
Derek Jones8dca0412010-03-05 13:01:44 -0600209 {
210 if ($prop->isPublic())
211 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300212 $this->_properties[] = $prop->getName();
Derek Jones8dca0412010-03-05 13:01:44 -0600213 }
214 }
Barry Mienydd671972010-10-04 16:33:58 +0200215
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300216 self::$_reflections[$class_name] = array($this->_methods, $this->_properties);
Derek Jones8dca0412010-03-05 13:01:44 -0600217 }
218 else
219 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300220 list($this->_methods, $this->_properties) = self::$_reflections[$class_name];
Derek Jones8dca0412010-03-05 13:01:44 -0600221 }
222 }
Barry Mienydd671972010-10-04 16:33:58 +0200223
Derek Jones8dca0412010-03-05 13:01:44 -0600224 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200225
Derek Jones8dca0412010-03-05 13:01:44 -0600226 /**
227 * __call magic method
228 *
229 * Handles access to the parent driver library's methods
230 *
Derek Jones8dca0412010-03-05 13:01:44 -0600231 * @param string
232 * @param array
233 * @return mixed
234 */
235 public function __call($method, $args = array())
236 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300237 if (in_array($method, $this->_methods))
Derek Jones8dca0412010-03-05 13:01:44 -0600238 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300239 return call_user_func_array(array($this->_parent, $method), $args);
Derek Jones8dca0412010-03-05 13:01:44 -0600240 }
241
242 $trace = debug_backtrace();
243 _exception_handler(E_ERROR, "No such method '{$method}'", $trace[1]['file'], $trace[1]['line']);
244 exit;
245 }
246
247 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200248
Derek Jones8dca0412010-03-05 13:01:44 -0600249 /**
250 * __get magic method
251 *
252 * Handles reading of the parent driver library's properties
253 *
Derek Jones8dca0412010-03-05 13:01:44 -0600254 * @param string
255 * @return mixed
256 */
Greg Akera9263282010-11-10 15:26:43 -0600257 public function __get($var)
Derek Jones8dca0412010-03-05 13:01:44 -0600258 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300259 if (in_array($var, $this->_properties))
Derek Jones8dca0412010-03-05 13:01:44 -0600260 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300261 return $this->_parent->$var;
Derek Jones8dca0412010-03-05 13:01:44 -0600262 }
263 }
264
265 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200266
Derek Jones8dca0412010-03-05 13:01:44 -0600267 /**
268 * __set magic method
269 *
270 * Handles writing to the parent driver library's properties
271 *
Derek Jones8dca0412010-03-05 13:01:44 -0600272 * @param string
273 * @param array
274 * @return mixed
275 */
Greg Akera9263282010-11-10 15:26:43 -0600276 public function __set($var, $val)
Derek Jones8dca0412010-03-05 13:01:44 -0600277 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300278 if (in_array($var, $this->_properties))
Derek Jones8dca0412010-03-05 13:01:44 -0600279 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300280 $this->_parent->$var = $val;
Derek Jones8dca0412010-03-05 13:01:44 -0600281 }
282 }
Barry Mienydd671972010-10-04 16:33:58 +0200283
Derek Jones8dca0412010-03-05 13:01:44 -0600284}
Derek Jones8dca0412010-03-05 13:01:44 -0600285
286/* End of file Driver.php */
Darren Hillc4e266b2011-08-30 15:40:27 -0400287/* Location: ./system/libraries/Driver.php */