blob: 382420db0560bc2a867f2309329f556806eb0a78 [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
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
Andrey Andreev80500af2013-01-01 08:16:53 +020021 * @copyright Copyright (c) 2006 - 2013, 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 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020027defined('BASEPATH') OR exit('No direct script access allowed');
Derek Jones8dca0412010-03-05 13:01:44 -060028
Derek Jones8dca0412010-03-05 13:01:44 -060029/**
30 * CodeIgniter Driver Library Class
31 *
32 * This class enables you to create "Driver" libraries that add runtime ability
33 * to extend the capabilities of a class via additional driver objects
34 *
35 * @package CodeIgniter
36 * @subpackage Libraries
37 * @category Libraries
38 * @author EllisLab Dev Team
Barry Mienydd671972010-10-04 16:33:58 +020039 * @link
Derek Jones8dca0412010-03-05 13:01:44 -060040 */
41class CI_Driver_Library {
42
Timothy Warren0688ac92012-04-20 10:25:04 -040043 /**
44 * Array of drivers that are available to use with the driver class
45 *
46 * @var array
47 */
48 protected $valid_drivers = array();
Andrey Andreev56454792012-05-17 14:32:19 +030049
Timothy Warren0688ac92012-04-20 10:25:04 -040050 /**
51 * Name of the current class - usually the driver class
52 *
53 * @var string
54 */
Darren Hillc4e266b2011-08-30 15:40:27 -040055 protected $lib_name;
Barry Mienydd671972010-10-04 16:33:58 +020056
Darren Hill6fbf6bd2011-08-31 14:15:35 -040057 /**
58 * Get magic method
59 *
Darren Hillc4e266b2011-08-30 15:40:27 -040060 * The first time a child is used it won't exist, so we instantiate it
61 * subsequents calls will go straight to the proper child.
Darren Hill6fbf6bd2011-08-31 14:15:35 -040062 *
dchill426262d052012-11-24 18:41:13 -050063 * @param string Child class name
64 * @return object Child class
Darren Hill6fbf6bd2011-08-31 14:15:35 -040065 */
Darren Hillc4e266b2011-08-30 15:40:27 -040066 public function __get($child)
Andrey Andreev2e3e2302012-10-09 15:52:34 +030067 {
Darren Hill6fbf6bd2011-08-31 14:15:35 -040068 // Try to load the driver
dchill42c5872252012-07-30 14:53:11 -040069 return $this->load_driver($child);
Darren Hill6fbf6bd2011-08-31 14:15:35 -040070 }
Darren Hillc4e266b2011-08-30 15:40:27 -040071
Darren Hill6fbf6bd2011-08-31 14:15:35 -040072 /**
73 * Load driver
74 *
Darren Hillc4e266b2011-08-30 15:40:27 -040075 * Separate load_driver call to support explicit driver load by library or user
Darren Hill6fbf6bd2011-08-31 14:15:35 -040076 *
dchill426262d052012-11-24 18:41:13 -050077 * @param string Driver name (w/o parent prefix)
78 * @return object Child class
Darren Hill6fbf6bd2011-08-31 14:15:35 -040079 */
Darren Hillc4e266b2011-08-30 15:40:27 -040080 public function load_driver($child)
Derek Jones8dca0412010-03-05 13:01:44 -060081 {
dchill426262d052012-11-24 18:41:13 -050082 // Get CodeIgniter instance and subclass prefix
Andrey Andreev662e3422013-01-28 21:19:13 +020083 $prefix = config_item('subclass_prefix');
dchill426262d052012-11-24 18:41:13 -050084
Pascal Kriete14287f32011-02-14 13:39:34 -050085 if ( ! isset($this->lib_name))
Derek Jones8dca0412010-03-05 13:01:44 -060086 {
dchill426262d052012-11-24 18:41:13 -050087 // Get library name without any prefix
88 $this->lib_name = str_replace(array('CI_', $prefix), '', get_class($this));
Derek Jones8dca0412010-03-05 13:01:44 -060089 }
90
dchill426262d052012-11-24 18:41:13 -050091 // The child will be prefixed with the parent lib
92 $child_name = $this->lib_name.'_'.$child;
Andrey Andreev83d15052011-12-22 13:35:42 +020093
dchill426262d052012-11-24 18:41:13 -050094 // See if requested child is a valid driver
Andrey Andreev7e83f322012-11-25 16:03:21 +020095 if ( ! in_array($child, $this->valid_drivers))
Derek Jones8dca0412010-03-05 13:01:44 -060096 {
dchill426262d052012-11-24 18:41:13 -050097 // The requested driver isn't valid!
98 $msg = 'Invalid driver requested: '.$child_name;
99 log_message('error', $msg);
100 show_error($msg);
101 }
Derek Jones8dca0412010-03-05 13:01:44 -0600102
dchill426262d052012-11-24 18:41:13 -0500103 // Get package paths and filename case variations to search
Andrey Andreev662e3422013-01-28 21:19:13 +0200104 $CI = get_instance();
dchill426262d052012-11-24 18:41:13 -0500105 $paths = $CI->load->get_package_paths(TRUE);
dchill426262d052012-11-24 18:41:13 -0500106
107 // Is there an extension?
108 $class_name = $prefix.$child_name;
Andrey Andreev662e3422013-01-28 21:19:13 +0200109 $found = class_exists($class_name, FALSE);
dchill426262d052012-11-24 18:41:13 -0500110 if ( ! $found)
111 {
112 // Check for subclass file
113 foreach ($paths as $path)
114 {
Andrey Andreev7e83f322012-11-25 16:03:21 +0200115 // Does the file exist?
116 $file = $path.'libraries/'.$this->lib_name.'/drivers/'.$prefix.$child_name.'.php';
117 if (file_exists($file))
dchill426262d052012-11-24 18:41:13 -0500118 {
Andrey Andreev7e83f322012-11-25 16:03:21 +0200119 // Yes - require base class from BASEPATH
120 $basepath = BASEPATH.'libraries/'.$this->lib_name.'/drivers/'.$child_name.'.php';
121 if ( ! file_exists($basepath))
dchill426262d052012-11-24 18:41:13 -0500122 {
Andrey Andreev7e83f322012-11-25 16:03:21 +0200123 $msg = 'Unable to load the requested class: CI_'.$child_name;
124 log_message('error', $msg);
125 show_error($msg);
dchill426262d052012-11-24 18:41:13 -0500126 }
Andrey Andreev7e83f322012-11-25 16:03:21 +0200127
128 // Include both sources and mark found
Andrey Andreev662e3422013-01-28 21:19:13 +0200129 include_once($basepath);
130 include_once($file);
Andrey Andreev7e83f322012-11-25 16:03:21 +0200131 $found = TRUE;
132 break;
dchill426262d052012-11-24 18:41:13 -0500133 }
134 }
135 }
136
137 // Do we need to search for the class?
138 if ( ! $found)
139 {
140 // Use standard class name
141 $class_name = 'CI_'.$child_name;
Andrey Andreev662e3422013-01-28 21:19:13 +0200142 if ( ! class_exists($class_name, FALSE))
dchill426262d052012-11-24 18:41:13 -0500143 {
144 // Check package paths
145 foreach ($paths as $path)
146 {
Andrey Andreev7e83f322012-11-25 16:03:21 +0200147 // Does the file exist?
148 $file = $path.'libraries/'.$this->lib_name.'/drivers/'.$child_name.'.php';
149 if (file_exists($file))
dchill426262d052012-11-24 18:41:13 -0500150 {
Andrey Andreev7e83f322012-11-25 16:03:21 +0200151 // Include source
Andrey Andreev662e3422013-01-28 21:19:13 +0200152 include_once($file);
Andrey Andreev7e83f322012-11-25 16:03:21 +0200153 break;
Derek Jones8dca0412010-03-05 13:01:44 -0600154 }
155 }
Derek Jones8dca0412010-03-05 13:01:44 -0600156 }
Derek Jones8dca0412010-03-05 13:01:44 -0600157 }
Barry Mienydd671972010-10-04 16:33:58 +0200158
dchill426262d052012-11-24 18:41:13 -0500159 // Did we finally find the class?
Andrey Andreev662e3422013-01-28 21:19:13 +0200160 if ( ! class_exists($class_name, FALSE))
dchill426262d052012-11-24 18:41:13 -0500161 {
Andrey Andreev662e3422013-01-28 21:19:13 +0200162 if (class_exists($child_name, FALSE))
William Knauss401fb492012-11-27 00:01:03 -0500163 {
164 $class_name = $child_name;
165 }
166 else
167 {
168 $msg = 'Unable to load the requested driver: '.$class_name;
169 log_message('error', $msg);
170 show_error($msg);
171 }
dchill426262d052012-11-24 18:41:13 -0500172 }
173
Andrey Andreev7e83f322012-11-25 16:03:21 +0200174 // Instantiate, decorate and add child
175 $obj = new $class_name();
dchill426262d052012-11-24 18:41:13 -0500176 $obj->decorate($this);
177 $this->$child = $obj;
178 return $this->$child;
Derek Jones8dca0412010-03-05 13:01:44 -0600179 }
Derek Jones8dca0412010-03-05 13:01:44 -0600180
Derek Jones8dca0412010-03-05 13:01:44 -0600181}
Derek Jones8dca0412010-03-05 13:01:44 -0600182
Timothy Warren0688ac92012-04-20 10:25:04 -0400183// --------------------------------------------------------------------------
Derek Jones8dca0412010-03-05 13:01:44 -0600184
185/**
186 * CodeIgniter Driver Class
187 *
188 * This class enables you to create drivers for a Library based on the Driver Library.
189 * It handles the drivers' access to the parent library
190 *
191 * @package CodeIgniter
192 * @subpackage Libraries
193 * @category Libraries
194 * @author EllisLab Dev Team
Barry Mienydd671972010-10-04 16:33:58 +0200195 * @link
Derek Jones8dca0412010-03-05 13:01:44 -0600196 */
197class CI_Driver {
Barry Mienydd671972010-10-04 16:33:58 +0200198
Timothy Warren0688ac92012-04-20 10:25:04 -0400199 /**
200 * Instance of the parent class
201 *
202 * @var object
203 */
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300204 protected $_parent;
Derek Jones8dca0412010-03-05 13:01:44 -0600205
Timothy Warren0688ac92012-04-20 10:25:04 -0400206 /**
207 * List of methods in the parent class
208 *
209 * @var array
210 */
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300211 protected $_methods = array();
Andrey Andreev56454792012-05-17 14:32:19 +0300212
Timothy Warren0688ac92012-04-20 10:25:04 -0400213 /**
214 * List of properties in the parent class
215 *
216 * @var array
217 */
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300218 protected $_properties = array();
Derek Jones8dca0412010-03-05 13:01:44 -0600219
Timothy Warren0688ac92012-04-20 10:25:04 -0400220 /**
221 * Array of methods and properties for the parent class(es)
222 *
Andrey Andreev5fd3ae82012-10-24 14:55:35 +0300223 * @static
224 * @var array
Timothy Warren0688ac92012-04-20 10:25:04 -0400225 */
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300226 protected static $_reflections = array();
Derek Jones8dca0412010-03-05 13:01:44 -0600227
228 /**
229 * Decorate
230 *
231 * Decorates the child with the parent driver lib's methods and properties
232 *
Derek Jones8dca0412010-03-05 13:01:44 -0600233 * @param object
234 * @return void
235 */
Greg Akera9263282010-11-10 15:26:43 -0600236 public function decorate($parent)
Derek Jones8dca0412010-03-05 13:01:44 -0600237 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300238 $this->_parent = $parent;
Barry Mienydd671972010-10-04 16:33:58 +0200239
Derek Jones8dca0412010-03-05 13:01:44 -0600240 // Lock down attributes to what is defined in the class
241 // and speed up references in magic methods
Barry Mienydd671972010-10-04 16:33:58 +0200242
Derek Jones8dca0412010-03-05 13:01:44 -0600243 $class_name = get_class($parent);
Barry Mienydd671972010-10-04 16:33:58 +0200244
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300245 if ( ! isset(self::$_reflections[$class_name]))
Derek Jones8dca0412010-03-05 13:01:44 -0600246 {
247 $r = new ReflectionObject($parent);
Barry Mienydd671972010-10-04 16:33:58 +0200248
Derek Jones8dca0412010-03-05 13:01:44 -0600249 foreach ($r->getMethods() as $method)
250 {
251 if ($method->isPublic())
252 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300253 $this->_methods[] = $method->getName();
Derek Jones8dca0412010-03-05 13:01:44 -0600254 }
255 }
256
Pascal Kriete14287f32011-02-14 13:39:34 -0500257 foreach ($r->getProperties() as $prop)
Derek Jones8dca0412010-03-05 13:01:44 -0600258 {
259 if ($prop->isPublic())
260 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300261 $this->_properties[] = $prop->getName();
Derek Jones8dca0412010-03-05 13:01:44 -0600262 }
263 }
Barry Mienydd671972010-10-04 16:33:58 +0200264
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300265 self::$_reflections[$class_name] = array($this->_methods, $this->_properties);
Derek Jones8dca0412010-03-05 13:01:44 -0600266 }
267 else
268 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300269 list($this->_methods, $this->_properties) = self::$_reflections[$class_name];
Derek Jones8dca0412010-03-05 13:01:44 -0600270 }
271 }
Barry Mienydd671972010-10-04 16:33:58 +0200272
Derek Jones8dca0412010-03-05 13:01:44 -0600273 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200274
Derek Jones8dca0412010-03-05 13:01:44 -0600275 /**
276 * __call magic method
277 *
278 * Handles access to the parent driver library's methods
279 *
Derek Jones8dca0412010-03-05 13:01:44 -0600280 * @param string
281 * @param array
282 * @return mixed
283 */
284 public function __call($method, $args = array())
285 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300286 if (in_array($method, $this->_methods))
Derek Jones8dca0412010-03-05 13:01:44 -0600287 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300288 return call_user_func_array(array($this->_parent, $method), $args);
Derek Jones8dca0412010-03-05 13:01:44 -0600289 }
290
291 $trace = debug_backtrace();
292 _exception_handler(E_ERROR, "No such method '{$method}'", $trace[1]['file'], $trace[1]['line']);
293 exit;
294 }
295
296 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200297
Derek Jones8dca0412010-03-05 13:01:44 -0600298 /**
299 * __get magic method
300 *
301 * Handles reading of the parent driver library's properties
302 *
Derek Jones8dca0412010-03-05 13:01:44 -0600303 * @param string
304 * @return mixed
305 */
Greg Akera9263282010-11-10 15:26:43 -0600306 public function __get($var)
Derek Jones8dca0412010-03-05 13:01:44 -0600307 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300308 if (in_array($var, $this->_properties))
Derek Jones8dca0412010-03-05 13:01:44 -0600309 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300310 return $this->_parent->$var;
Derek Jones8dca0412010-03-05 13:01:44 -0600311 }
312 }
313
314 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200315
Derek Jones8dca0412010-03-05 13:01:44 -0600316 /**
317 * __set magic method
318 *
319 * Handles writing to the parent driver library's properties
320 *
Derek Jones8dca0412010-03-05 13:01:44 -0600321 * @param string
322 * @param array
323 * @return mixed
324 */
Greg Akera9263282010-11-10 15:26:43 -0600325 public function __set($var, $val)
Derek Jones8dca0412010-03-05 13:01:44 -0600326 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300327 if (in_array($var, $this->_properties))
Derek Jones8dca0412010-03-05 13:01:44 -0600328 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300329 $this->_parent->$var = $val;
Derek Jones8dca0412010-03-05 13:01:44 -0600330 }
331 }
Barry Mienydd671972010-10-04 16:33:58 +0200332
Derek Jones8dca0412010-03-05 13:01:44 -0600333}
Derek Jones8dca0412010-03-05 13:01:44 -0600334
335/* End of file Driver.php */
Andrey Andreev2e3e2302012-10-09 15:52:34 +0300336/* Location: ./system/libraries/Driver.php */