blob: 72f376466ef5779b86576f517699cd39856211d4 [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
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 */
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
83 $CI = get_instance();
84 $prefix = (string) $CI->config->item('subclass_prefix');
85
Pascal Kriete14287f32011-02-14 13:39:34 -050086 if ( ! isset($this->lib_name))
Derek Jones8dca0412010-03-05 13:01:44 -060087 {
dchill426262d052012-11-24 18:41:13 -050088 // Get library name without any prefix
89 $this->lib_name = str_replace(array('CI_', $prefix), '', get_class($this));
Derek Jones8dca0412010-03-05 13:01:44 -060090 }
91
dchill426262d052012-11-24 18:41:13 -050092 // The child will be prefixed with the parent lib
93 $child_name = $this->lib_name.'_'.$child;
Andrey Andreev83d15052011-12-22 13:35:42 +020094
dchill426262d052012-11-24 18:41:13 -050095 // See if requested child is a valid driver
Andrey Andreev7e83f322012-11-25 16:03:21 +020096 if ( ! in_array($child, $this->valid_drivers))
Derek Jones8dca0412010-03-05 13:01:44 -060097 {
dchill426262d052012-11-24 18:41:13 -050098 // The requested driver isn't valid!
99 $msg = 'Invalid driver requested: '.$child_name;
100 log_message('error', $msg);
101 show_error($msg);
102 }
Derek Jones8dca0412010-03-05 13:01:44 -0600103
dchill426262d052012-11-24 18:41:13 -0500104 // Get package paths and filename case variations to search
105 $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;
109 $found = class_exists($class_name);
110 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
129 include($basepath);
130 include($file);
131 $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;
142 $found = class_exists($class_name);
143 if ( ! $found)
144 {
145 // Check package paths
146 foreach ($paths as $path)
147 {
Andrey Andreev7e83f322012-11-25 16:03:21 +0200148 // Does the file exist?
149 $file = $path.'libraries/'.$this->lib_name.'/drivers/'.$child_name.'.php';
150 if (file_exists($file))
dchill426262d052012-11-24 18:41:13 -0500151 {
Andrey Andreev7e83f322012-11-25 16:03:21 +0200152 // Include source
153 include($file);
154 break;
Derek Jones8dca0412010-03-05 13:01:44 -0600155 }
156 }
Derek Jones8dca0412010-03-05 13:01:44 -0600157 }
Derek Jones8dca0412010-03-05 13:01:44 -0600158 }
Barry Mienydd671972010-10-04 16:33:58 +0200159
dchill426262d052012-11-24 18:41:13 -0500160 // Did we finally find the class?
161 if ( ! class_exists($class_name))
162 {
163 $msg = 'Unable to load the requested driver: '.$class_name;
164 log_message('error', $msg);
165 show_error($msg);
166 }
167
Andrey Andreev7e83f322012-11-25 16:03:21 +0200168 // Instantiate, decorate and add child
169 $obj = new $class_name();
dchill426262d052012-11-24 18:41:13 -0500170 $obj->decorate($this);
171 $this->$child = $obj;
172 return $this->$child;
Derek Jones8dca0412010-03-05 13:01:44 -0600173 }
Derek Jones8dca0412010-03-05 13:01:44 -0600174
Derek Jones8dca0412010-03-05 13:01:44 -0600175}
Derek Jones8dca0412010-03-05 13:01:44 -0600176
Timothy Warren0688ac92012-04-20 10:25:04 -0400177// --------------------------------------------------------------------------
Derek Jones8dca0412010-03-05 13:01:44 -0600178
179/**
180 * CodeIgniter Driver Class
181 *
182 * This class enables you to create drivers for a Library based on the Driver Library.
183 * It handles the drivers' access to the parent library
184 *
185 * @package CodeIgniter
186 * @subpackage Libraries
187 * @category Libraries
188 * @author EllisLab Dev Team
Barry Mienydd671972010-10-04 16:33:58 +0200189 * @link
Derek Jones8dca0412010-03-05 13:01:44 -0600190 */
191class CI_Driver {
Barry Mienydd671972010-10-04 16:33:58 +0200192
Timothy Warren0688ac92012-04-20 10:25:04 -0400193 /**
194 * Instance of the parent class
195 *
196 * @var object
197 */
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300198 protected $_parent;
Derek Jones8dca0412010-03-05 13:01:44 -0600199
Timothy Warren0688ac92012-04-20 10:25:04 -0400200 /**
201 * List of methods in the parent class
202 *
203 * @var array
204 */
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300205 protected $_methods = array();
Andrey Andreev56454792012-05-17 14:32:19 +0300206
Timothy Warren0688ac92012-04-20 10:25:04 -0400207 /**
208 * List of properties in the parent class
209 *
210 * @var array
211 */
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300212 protected $_properties = array();
Derek Jones8dca0412010-03-05 13:01:44 -0600213
Timothy Warren0688ac92012-04-20 10:25:04 -0400214 /**
215 * Array of methods and properties for the parent class(es)
216 *
Andrey Andreev5fd3ae82012-10-24 14:55:35 +0300217 * @static
218 * @var array
Timothy Warren0688ac92012-04-20 10:25:04 -0400219 */
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300220 protected static $_reflections = array();
Derek Jones8dca0412010-03-05 13:01:44 -0600221
222 /**
223 * Decorate
224 *
225 * Decorates the child with the parent driver lib's methods and properties
226 *
Derek Jones8dca0412010-03-05 13:01:44 -0600227 * @param object
228 * @return void
229 */
Greg Akera9263282010-11-10 15:26:43 -0600230 public function decorate($parent)
Derek Jones8dca0412010-03-05 13:01:44 -0600231 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300232 $this->_parent = $parent;
Barry Mienydd671972010-10-04 16:33:58 +0200233
Derek Jones8dca0412010-03-05 13:01:44 -0600234 // Lock down attributes to what is defined in the class
235 // and speed up references in magic methods
Barry Mienydd671972010-10-04 16:33:58 +0200236
Derek Jones8dca0412010-03-05 13:01:44 -0600237 $class_name = get_class($parent);
Barry Mienydd671972010-10-04 16:33:58 +0200238
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300239 if ( ! isset(self::$_reflections[$class_name]))
Derek Jones8dca0412010-03-05 13:01:44 -0600240 {
241 $r = new ReflectionObject($parent);
Barry Mienydd671972010-10-04 16:33:58 +0200242
Derek Jones8dca0412010-03-05 13:01:44 -0600243 foreach ($r->getMethods() as $method)
244 {
245 if ($method->isPublic())
246 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300247 $this->_methods[] = $method->getName();
Derek Jones8dca0412010-03-05 13:01:44 -0600248 }
249 }
250
Pascal Kriete14287f32011-02-14 13:39:34 -0500251 foreach ($r->getProperties() as $prop)
Derek Jones8dca0412010-03-05 13:01:44 -0600252 {
253 if ($prop->isPublic())
254 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300255 $this->_properties[] = $prop->getName();
Derek Jones8dca0412010-03-05 13:01:44 -0600256 }
257 }
Barry Mienydd671972010-10-04 16:33:58 +0200258
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300259 self::$_reflections[$class_name] = array($this->_methods, $this->_properties);
Derek Jones8dca0412010-03-05 13:01:44 -0600260 }
261 else
262 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300263 list($this->_methods, $this->_properties) = self::$_reflections[$class_name];
Derek Jones8dca0412010-03-05 13:01:44 -0600264 }
265 }
Barry Mienydd671972010-10-04 16:33:58 +0200266
Derek Jones8dca0412010-03-05 13:01:44 -0600267 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200268
Derek Jones8dca0412010-03-05 13:01:44 -0600269 /**
270 * __call magic method
271 *
272 * Handles access to the parent driver library's methods
273 *
Derek Jones8dca0412010-03-05 13:01:44 -0600274 * @param string
275 * @param array
276 * @return mixed
277 */
278 public function __call($method, $args = array())
279 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300280 if (in_array($method, $this->_methods))
Derek Jones8dca0412010-03-05 13:01:44 -0600281 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300282 return call_user_func_array(array($this->_parent, $method), $args);
Derek Jones8dca0412010-03-05 13:01:44 -0600283 }
284
285 $trace = debug_backtrace();
286 _exception_handler(E_ERROR, "No such method '{$method}'", $trace[1]['file'], $trace[1]['line']);
287 exit;
288 }
289
290 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200291
Derek Jones8dca0412010-03-05 13:01:44 -0600292 /**
293 * __get magic method
294 *
295 * Handles reading of the parent driver library's properties
296 *
Derek Jones8dca0412010-03-05 13:01:44 -0600297 * @param string
298 * @return mixed
299 */
Greg Akera9263282010-11-10 15:26:43 -0600300 public function __get($var)
Derek Jones8dca0412010-03-05 13:01:44 -0600301 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300302 if (in_array($var, $this->_properties))
Derek Jones8dca0412010-03-05 13:01:44 -0600303 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300304 return $this->_parent->$var;
Derek Jones8dca0412010-03-05 13:01:44 -0600305 }
306 }
307
308 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200309
Derek Jones8dca0412010-03-05 13:01:44 -0600310 /**
311 * __set magic method
312 *
313 * Handles writing to the parent driver library's properties
314 *
Derek Jones8dca0412010-03-05 13:01:44 -0600315 * @param string
316 * @param array
317 * @return mixed
318 */
Greg Akera9263282010-11-10 15:26:43 -0600319 public function __set($var, $val)
Derek Jones8dca0412010-03-05 13:01:44 -0600320 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300321 if (in_array($var, $this->_properties))
Derek Jones8dca0412010-03-05 13:01:44 -0600322 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300323 $this->_parent->$var = $val;
Derek Jones8dca0412010-03-05 13:01:44 -0600324 }
325 }
Barry Mienydd671972010-10-04 16:33:58 +0200326
Derek Jones8dca0412010-03-05 13:01:44 -0600327}
Derek Jones8dca0412010-03-05 13:01:44 -0600328
329/* End of file Driver.php */
Andrey Andreev2e3e2302012-10-09 15:52:34 +0300330/* Location: ./system/libraries/Driver.php */