1: <?php
2: /* SVN FILE: $Id$ */
3: /**
4: * Object class, allowing __construct and __destruct in PHP4.
5: *
6: * Also includes methods for logging and the special method RequestAction,
7: * to call other Controllers' Actions from anywhere.
8: *
9: * PHP versions 4 and 5
10: *
11: * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
12: * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
13: *
14: * Licensed under The MIT License
15: * Redistributions of files must retain the above copyright notice.
16: *
17: * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
18: * @link http://cakephp.org CakePHP(tm) Project
19: * @package cake
20: * @subpackage cake.cake.libs
21: * @since CakePHP(tm) v 0.2.9
22: * @version $Revision$
23: * @modifiedby $LastChangedBy$
24: * @lastmodified $Date$
25: * @license http://www.opensource.org/licenses/mit-license.php The MIT License
26: */
27: /**
28: * Object class, allowing __construct and __destruct in PHP4.
29: *
30: * Also includes methods for logging and the special method RequestAction,
31: * to call other Controllers' Actions from anywhere.
32: *
33: * @package cake
34: * @subpackage cake.cake.libs
35: */
36: class Object {
37: /**
38: * Log object
39: *
40: * @var CakeLog
41: * @access protected
42: */
43: var $_log = null;
44: /**
45: * A hack to support __construct() on PHP 4
46: * Hint: descendant classes have no PHP4 class_name() constructors,
47: * so this constructor gets called first and calls the top-layer __construct()
48: * which (if present) should call parent::__construct()
49: *
50: * @return Object
51: */
52: function Object() {
53: $args = func_get_args();
54: if (method_exists($this, '__destruct')) {
55: register_shutdown_function (array(&$this, '__destruct'));
56: }
57: call_user_func_array(array(&$this, '__construct'), $args);
58: }
59: /**
60: * Class constructor, overridden in descendant classes.
61: */
62: function __construct() {
63: }
64:
65: /**
66: * Object-to-string conversion.
67: * Each class can override this method as necessary.
68: *
69: * @return string The name of this class
70: * @access public
71: */
72: function toString() {
73: $class = get_class($this);
74: return $class;
75: }
76: /**
77: * Calls a controller's method from any location.
78: *
79: * @param mixed $url String or array-based url.
80: * @param array $extra if array includes the key "return" it sets the AutoRender to true.
81: * @return mixed Boolean true or false on success/failure, or contents
82: * of rendered action if 'return' is set in $extra.
83: * @access public
84: */
85: function requestAction($url, $extra = array()) {
86: if (empty($url)) {
87: return false;
88: }
89: if (!class_exists('dispatcher')) {
90: require CAKE . 'dispatcher.php';
91: }
92: if (in_array('return', $extra, true)) {
93: $extra = array_merge($extra, array('return' => 0, 'autoRender' => 1));
94: }
95: if (is_array($url) && !isset($extra['url'])) {
96: $extra['url'] = array();
97: }
98: $params = array_merge(array('autoRender' => 0, 'return' => 1, 'bare' => 1, 'requested' => 1), $extra);
99: $dispatcher = new Dispatcher;
100: return $dispatcher->dispatch($url, $params);
101: }
102: /**
103: * Calls a method on this object with the given parameters. Provides an OO wrapper
104: * for call_user_func_array, and improves performance by using straight method calls
105: * in most cases.
106: *
107: * @param string $method Name of the method to call
108: * @param array $params Parameter list to use when calling $method
109: * @return mixed Returns the result of the method call
110: * @access public
111: */
112: function dispatchMethod($method, $params = array()) {
113: switch (count($params)) {
114: case 0:
115: return $this->{$method}();
116: case 1:
117: return $this->{$method}($params[0]);
118: case 2:
119: return $this->{$method}($params[0], $params[1]);
120: case 3:
121: return $this->{$method}($params[0], $params[1], $params[2]);
122: case 4:
123: return $this->{$method}($params[0], $params[1], $params[2], $params[3]);
124: case 5:
125: return $this->{$method}($params[0], $params[1], $params[2], $params[3], $params[4]);
126: default:
127: return call_user_func_array(array(&$this, $method), $params);
128: break;
129: }
130: }
131: /**
132: * Stop execution of the current script
133: *
134: * @param $status see http://php.net/exit for values
135: * @return void
136: * @access public
137: */
138: function _stop($status = 0) {
139: exit($status);
140: }
141: /**
142: * API for logging events.
143: *
144: * @param string $msg Log message
145: * @param integer $type Error type constant. Defined in app/config/core.php.
146: * @return boolean Success of log write
147: * @access public
148: */
149: function log($msg, $type = LOG_ERROR) {
150: if (!class_exists('CakeLog')) {
151: uses('cake_log');
152: }
153: if (is_null($this->_log)) {
154: $this->_log = new CakeLog();
155: }
156: if (!is_string($msg)) {
157: $msg = print_r($msg, true);
158: }
159: return $this->_log->write($type, $msg);
160: }
161: /**
162: * Allows setting of multiple properties of the object in a single line of code.
163: *
164: * @param array $properties An associative array containing properties and corresponding values.
165: * @return void
166: * @access protected
167: */
168: function _set($properties = array()) {
169: if (is_array($properties) && !empty($properties)) {
170: $vars = get_object_vars($this);
171: foreach ($properties as $key => $val) {
172: if (array_key_exists($key, $vars)) {
173: $this->{$key} = $val;
174: }
175: }
176: }
177: }
178: /**
179: * Used to report user friendly errors.
180: * If there is a file app/error.php or app/app_error.php this file will be loaded
181: * error.php is the AppError class it should extend ErrorHandler class.
182: *
183: * @param string $method Method to be called in the error class (AppError or ErrorHandler classes)
184: * @param array $messages Message that is to be displayed by the error class
185: * @return error message
186: * @access public
187: */
188: function cakeError($method, $messages = array()) {
189: if (!class_exists('ErrorHandler')) {
190: App::import('Core', 'Error');
191:
192: if (file_exists(APP . 'error.php')) {
193: include_once (APP . 'error.php');
194: } elseif (file_exists(APP . 'app_error.php')) {
195: include_once (APP . 'app_error.php');
196: }
197: }
198:
199: if (class_exists('AppError')) {
200: $error = new AppError($method, $messages);
201: } else {
202: $error = new ErrorHandler($method, $messages);
203: }
204: return $error;
205: }
206: /**
207: * Checks for a persistent class file, if found file is opened and true returned
208: * If file is not found a file is created and false returned
209: * If used in other locations of the model you should choose a unique name for the persistent file
210: * There are many uses for this method, see manual for examples
211: *
212: * @param string $name name of the class to persist
213: * @param string $object the object to persist
214: * @return boolean Success
215: * @access protected
216: * @todo add examples to manual
217: */
218: function _persist($name, $return = null, &$object, $type = null) {
219: $file = CACHE . 'persistent' . DS . strtolower($name) . '.php';
220: if ($return === null) {
221: if (!file_exists($file)) {
222: return false;
223: } else {
224: return true;
225: }
226: }
227:
228: if (!file_exists($file)) {
229: $this->_savePersistent($name, $object);
230: return false;
231: } else {
232: $this->__openPersistent($name, $type);
233: return true;
234: }
235: }
236: /**
237: * You should choose a unique name for the persistent file
238: *
239: * There are many uses for this method, see manual for examples
240: *
241: * @param string $name name used for object to cache
242: * @param object $object the object to persist
243: * @return boolean true on save, throws error if file can not be created
244: * @access protected
245: */
246: function _savePersistent($name, &$object) {
247: $file = 'persistent' . DS . strtolower($name) . '.php';
248: $objectArray = array(&$object);
249: $data = str_replace('\\', '\\\\', serialize($objectArray));
250: $data = '<?php $' . Inflector::slug($name) . ' = \'' . str_replace('\'', '\\\'', $data) . '\' ?>';
251: $duration = '+999 days';
252: if (Configure::read() >= 1) {
253: $duration = '+10 seconds';
254: }
255: cache($file, $data, $duration);
256: }
257: /**
258: * Open the persistent class file for reading
259: * Used by Object::_persist()
260: *
261: * @param string $name Name of persisted class
262: * @param string $type Type of persistance (e.g: registry)
263: * @return void
264: * @access private
265: */
266: function __openPersistent($name, $type = null) {
267: $file = CACHE . 'persistent' . DS . strtolower($name) . '.php';
268: include($file);
269:
270: switch ($type) {
271: case 'registry':
272: $vars = unserialize(${$name});
273: foreach ($vars['0'] as $key => $value) {
274: if (strpos($key, '_behavior') !== false) {
275: App::import('Behavior', Inflector::classify(substr($key, 0, -9)));
276: } else {
277: App::import('Model', Inflector::camelize($key));
278: }
279: unset ($value);
280: }
281: unset($vars);
282: $vars = unserialize(${$name});
283: foreach ($vars['0'] as $key => $value) {
284: ClassRegistry::addObject($key, $value);
285: unset ($value);
286: }
287: unset($vars);
288: break;
289: default:
290: $vars = unserialize(${Inflector::slug($name)});
291: $this->{$name} = $vars['0'];
292: unset($vars);
293: break;
294: }
295: }
296: }
297: ?>