blob: 8f5107b0dde3041076d31c625cd8c2306dcfb6ff [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
96 if ( ! in_array($child, array_map('strtolower', $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 // All driver files should be in a library subdirectory - capitalized
105 $subdir = ucfirst(strtolower($this->lib_name));
106
107 // Get package paths and filename case variations to search
108 $paths = $CI->load->get_package_paths(TRUE);
109 $cases = array(ucfirst($child_name), strtolower($child_name));
110
111 // Is there an extension?
112 $class_name = $prefix.$child_name;
113 $found = class_exists($class_name);
114 if ( ! $found)
115 {
116 // Check for subclass file
117 foreach ($paths as $path)
118 {
119 // Extension will be in drivers subdirectory
120 $path .= 'libraries/'.$subdir.'/drivers/';
121
122 // Try filename with caps and all lowercase
123 foreach ($cases as $name)
124 {
125 // Does the file exist?
126 $file = $path.$prefix.$name.'.php';
127 if (file_exists($file))
128 {
129 // Yes - require base class from BASEPATH
130 $basepath = BASEPATH.'libraries/'.$subdir.'/drivers/'.ucfirst($child_name).'.php';
131 if ( ! file_exists($basepath))
Phil Sturgeoneb2dcda2011-04-02 14:44:58 +0100132 {
dchill426262d052012-11-24 18:41:13 -0500133 $msg = 'Unable to load the requested class: CI_'.$child_name;
134 log_message('error', $msg);
135 show_error($msg);
136 }
137
138 // Include both sources and mark found
139 include($basepath);
140 include($file);
141 $found = TRUE;
142 break 2;
143 }
144 }
145 }
146 }
147
148 // Do we need to search for the class?
149 if ( ! $found)
150 {
151 // Use standard class name
152 $class_name = 'CI_'.$child_name;
153 $found = class_exists($class_name);
154 if ( ! $found)
155 {
156 // Check package paths
157 foreach ($paths as $path)
158 {
159 // Class will be in drivers subdirectory
160 $path .= 'libraries/'.$subdir.'/drivers/';
161
162 // Try filename with caps and all lowercase
163 foreach ($cases as $name)
164 {
165 // Does the file exist?
166 $file = $path.$name.'.php';
167 if (file_exists($file))
168 {
169 // Include source
170 include($file);
Darren Hillc4e266b2011-08-30 15:40:27 -0400171 break 2;
Derek Jones8dca0412010-03-05 13:01:44 -0600172 }
173 }
174 }
Derek Jones8dca0412010-03-05 13:01:44 -0600175 }
Derek Jones8dca0412010-03-05 13:01:44 -0600176 }
Barry Mienydd671972010-10-04 16:33:58 +0200177
dchill426262d052012-11-24 18:41:13 -0500178 // Did we finally find the class?
179 if ( ! class_exists($class_name))
180 {
181 $msg = 'Unable to load the requested driver: '.$class_name;
182 log_message('error', $msg);
183 show_error($msg);
184 }
185
186 // Instantiate, decorate, and add child
187 $obj = new $class_name;
188 $obj->decorate($this);
189 $this->$child = $obj;
190 return $this->$child;
Derek Jones8dca0412010-03-05 13:01:44 -0600191 }
Derek Jones8dca0412010-03-05 13:01:44 -0600192
Derek Jones8dca0412010-03-05 13:01:44 -0600193}
Derek Jones8dca0412010-03-05 13:01:44 -0600194
Timothy Warren0688ac92012-04-20 10:25:04 -0400195// --------------------------------------------------------------------------
Derek Jones8dca0412010-03-05 13:01:44 -0600196
197/**
198 * CodeIgniter Driver Class
199 *
200 * This class enables you to create drivers for a Library based on the Driver Library.
201 * It handles the drivers' access to the parent library
202 *
203 * @package CodeIgniter
204 * @subpackage Libraries
205 * @category Libraries
206 * @author EllisLab Dev Team
Barry Mienydd671972010-10-04 16:33:58 +0200207 * @link
Derek Jones8dca0412010-03-05 13:01:44 -0600208 */
209class CI_Driver {
Barry Mienydd671972010-10-04 16:33:58 +0200210
Timothy Warren0688ac92012-04-20 10:25:04 -0400211 /**
212 * Instance of the parent class
213 *
214 * @var object
215 */
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300216 protected $_parent;
Derek Jones8dca0412010-03-05 13:01:44 -0600217
Timothy Warren0688ac92012-04-20 10:25:04 -0400218 /**
219 * List of methods in the parent class
220 *
221 * @var array
222 */
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300223 protected $_methods = array();
Andrey Andreev56454792012-05-17 14:32:19 +0300224
Timothy Warren0688ac92012-04-20 10:25:04 -0400225 /**
226 * List of properties in the parent class
227 *
228 * @var array
229 */
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300230 protected $_properties = array();
Derek Jones8dca0412010-03-05 13:01:44 -0600231
Timothy Warren0688ac92012-04-20 10:25:04 -0400232 /**
233 * Array of methods and properties for the parent class(es)
234 *
Andrey Andreev5fd3ae82012-10-24 14:55:35 +0300235 * @static
236 * @var array
Timothy Warren0688ac92012-04-20 10:25:04 -0400237 */
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300238 protected static $_reflections = array();
Derek Jones8dca0412010-03-05 13:01:44 -0600239
240 /**
241 * Decorate
242 *
243 * Decorates the child with the parent driver lib's methods and properties
244 *
Derek Jones8dca0412010-03-05 13:01:44 -0600245 * @param object
246 * @return void
247 */
Greg Akera9263282010-11-10 15:26:43 -0600248 public function decorate($parent)
Derek Jones8dca0412010-03-05 13:01:44 -0600249 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300250 $this->_parent = $parent;
Barry Mienydd671972010-10-04 16:33:58 +0200251
Derek Jones8dca0412010-03-05 13:01:44 -0600252 // Lock down attributes to what is defined in the class
253 // and speed up references in magic methods
Barry Mienydd671972010-10-04 16:33:58 +0200254
Derek Jones8dca0412010-03-05 13:01:44 -0600255 $class_name = get_class($parent);
Barry Mienydd671972010-10-04 16:33:58 +0200256
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300257 if ( ! isset(self::$_reflections[$class_name]))
Derek Jones8dca0412010-03-05 13:01:44 -0600258 {
259 $r = new ReflectionObject($parent);
Barry Mienydd671972010-10-04 16:33:58 +0200260
Derek Jones8dca0412010-03-05 13:01:44 -0600261 foreach ($r->getMethods() as $method)
262 {
263 if ($method->isPublic())
264 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300265 $this->_methods[] = $method->getName();
Derek Jones8dca0412010-03-05 13:01:44 -0600266 }
267 }
268
Pascal Kriete14287f32011-02-14 13:39:34 -0500269 foreach ($r->getProperties() as $prop)
Derek Jones8dca0412010-03-05 13:01:44 -0600270 {
271 if ($prop->isPublic())
272 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300273 $this->_properties[] = $prop->getName();
Derek Jones8dca0412010-03-05 13:01:44 -0600274 }
275 }
Barry Mienydd671972010-10-04 16:33:58 +0200276
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300277 self::$_reflections[$class_name] = array($this->_methods, $this->_properties);
Derek Jones8dca0412010-03-05 13:01:44 -0600278 }
279 else
280 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300281 list($this->_methods, $this->_properties) = self::$_reflections[$class_name];
Derek Jones8dca0412010-03-05 13:01:44 -0600282 }
283 }
Barry Mienydd671972010-10-04 16:33:58 +0200284
Derek Jones8dca0412010-03-05 13:01:44 -0600285 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200286
Derek Jones8dca0412010-03-05 13:01:44 -0600287 /**
288 * __call magic method
289 *
290 * Handles access to the parent driver library's methods
291 *
Derek Jones8dca0412010-03-05 13:01:44 -0600292 * @param string
293 * @param array
294 * @return mixed
295 */
296 public function __call($method, $args = array())
297 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300298 if (in_array($method, $this->_methods))
Derek Jones8dca0412010-03-05 13:01:44 -0600299 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300300 return call_user_func_array(array($this->_parent, $method), $args);
Derek Jones8dca0412010-03-05 13:01:44 -0600301 }
302
303 $trace = debug_backtrace();
304 _exception_handler(E_ERROR, "No such method '{$method}'", $trace[1]['file'], $trace[1]['line']);
305 exit;
306 }
307
308 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200309
Derek Jones8dca0412010-03-05 13:01:44 -0600310 /**
311 * __get magic method
312 *
313 * Handles reading of the parent driver library's properties
314 *
Derek Jones8dca0412010-03-05 13:01:44 -0600315 * @param string
316 * @return mixed
317 */
Greg Akera9263282010-11-10 15:26:43 -0600318 public function __get($var)
Derek Jones8dca0412010-03-05 13:01:44 -0600319 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300320 if (in_array($var, $this->_properties))
Derek Jones8dca0412010-03-05 13:01:44 -0600321 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300322 return $this->_parent->$var;
Derek Jones8dca0412010-03-05 13:01:44 -0600323 }
324 }
325
326 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200327
Derek Jones8dca0412010-03-05 13:01:44 -0600328 /**
329 * __set magic method
330 *
331 * Handles writing to the parent driver library's properties
332 *
Derek Jones8dca0412010-03-05 13:01:44 -0600333 * @param string
334 * @param array
335 * @return mixed
336 */
Greg Akera9263282010-11-10 15:26:43 -0600337 public function __set($var, $val)
Derek Jones8dca0412010-03-05 13:01:44 -0600338 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300339 if (in_array($var, $this->_properties))
Derek Jones8dca0412010-03-05 13:01:44 -0600340 {
Andrey Andreev8486e9c2012-03-26 20:24:12 +0300341 $this->_parent->$var = $val;
Derek Jones8dca0412010-03-05 13:01:44 -0600342 }
343 }
Barry Mienydd671972010-10-04 16:33:58 +0200344
Derek Jones8dca0412010-03-05 13:01:44 -0600345}
Derek Jones8dca0412010-03-05 13:01:44 -0600346
347/* End of file Driver.php */
Andrey Andreev2e3e2302012-10-09 15:52:34 +0300348/* Location: ./system/libraries/Driver.php */