PageRenderTime 29ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/joomla/registry/registry.php

http://github.com/joomla/joomla-platform
PHP | 472 lines | 206 code | 48 blank | 218 comment | 29 complexity | c9a77ea8735289e3033fa9454e1528e7 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * @package Joomla.Platform
  4. * @subpackage Registry
  5. *
  6. * @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE
  8. */
  9. defined('JPATH_PLATFORM') or die;
  10. jimport('joomla.utilities.arrayhelper');
  11. /**
  12. * JRegistry class
  13. *
  14. * @package Joomla.Platform
  15. * @subpackage Registry
  16. * @since 11.1
  17. */
  18. class JRegistry implements JsonSerializable
  19. {
  20. /**
  21. * Registry Object
  22. *
  23. * @var object
  24. * @since 11.1
  25. */
  26. protected $data;
  27. /**
  28. * @var array JRegistry instances container.
  29. * @since 11.3
  30. */
  31. protected static $instances = array();
  32. /**
  33. * Constructor
  34. *
  35. * @param mixed $data The data to bind to the new JRegistry object.
  36. *
  37. * @since 11.1
  38. */
  39. public function __construct($data = null)
  40. {
  41. // Instantiate the internal data object.
  42. $this->data = new stdClass;
  43. // Optionally load supplied data.
  44. if (is_array($data) || is_object($data))
  45. {
  46. $this->bindData($this->data, $data);
  47. }
  48. elseif (!empty($data) && is_string($data))
  49. {
  50. $this->loadString($data);
  51. }
  52. }
  53. /**
  54. * Magic function to clone the registry object.
  55. *
  56. * @return JRegistry
  57. *
  58. * @since 11.1
  59. */
  60. public function __clone()
  61. {
  62. $this->data = unserialize(serialize($this->data));
  63. }
  64. /**
  65. * Magic function to render this object as a string using default args of toString method.
  66. *
  67. * @return string
  68. *
  69. * @since 11.1
  70. */
  71. public function __toString()
  72. {
  73. return $this->toString();
  74. }
  75. /**
  76. * Implementation for the JsonSerializable interface.
  77. * Allows us to pass JRegistry objects to json_encode.
  78. *
  79. * @return object
  80. *
  81. * @since 12.2
  82. * @note The interface is only present in PHP 5.4 and up.
  83. */
  84. public function jsonSerialize()
  85. {
  86. return $this->data;
  87. }
  88. /**
  89. * Sets a default value if not already assigned.
  90. *
  91. * @param string $key The name of the parameter.
  92. * @param mixed $default An optional value for the parameter.
  93. *
  94. * @return mixed The value set, or the default if the value was not previously set (or null).
  95. *
  96. * @since 11.1
  97. */
  98. public function def($key, $default = '')
  99. {
  100. $value = $this->get($key, $default);
  101. $this->set($key, $value);
  102. return $value;
  103. }
  104. /**
  105. * Check if a registry path exists.
  106. *
  107. * @param string $path Registry path (e.g. joomla.content.showauthor)
  108. *
  109. * @return boolean
  110. *
  111. * @since 11.1
  112. */
  113. public function exists($path)
  114. {
  115. // Explode the registry path into an array
  116. if ($nodes = explode('.', $path))
  117. {
  118. // Initialize the current node to be the registry root.
  119. $node = $this->data;
  120. // Traverse the registry to find the correct node for the result.
  121. for ($i = 0, $n = count($nodes); $i < $n; $i++)
  122. {
  123. if (isset($node->$nodes[$i]))
  124. {
  125. $node = $node->$nodes[$i];
  126. }
  127. else
  128. {
  129. break;
  130. }
  131. if ($i + 1 == $n)
  132. {
  133. return true;
  134. }
  135. }
  136. }
  137. return false;
  138. }
  139. /**
  140. * Get a registry value.
  141. *
  142. * @param string $path Registry path (e.g. joomla.content.showauthor)
  143. * @param mixed $default Optional default value, returned if the internal value is null.
  144. *
  145. * @return mixed Value of entry or null
  146. *
  147. * @since 11.1
  148. */
  149. public function get($path, $default = null)
  150. {
  151. $result = $default;
  152. if (!strpos($path, '.'))
  153. {
  154. return (isset($this->data->$path) && $this->data->$path !== null && $this->data->$path !== '') ? $this->data->$path : $default;
  155. }
  156. // Explode the registry path into an array
  157. $nodes = explode('.', $path);
  158. // Initialize the current node to be the registry root.
  159. $node = $this->data;
  160. $found = false;
  161. // Traverse the registry to find the correct node for the result.
  162. foreach ($nodes as $n)
  163. {
  164. if (isset($node->$n))
  165. {
  166. $node = $node->$n;
  167. $found = true;
  168. }
  169. else
  170. {
  171. $found = false;
  172. break;
  173. }
  174. }
  175. if ($found && $node !== null && $node !== '')
  176. {
  177. $result = $node;
  178. }
  179. return $result;
  180. }
  181. /**
  182. * Returns a reference to a global JRegistry object, only creating it
  183. * if it doesn't already exist.
  184. *
  185. * This method must be invoked as:
  186. * <pre>$registry = JRegistry::getInstance($id);</pre>
  187. *
  188. * @param string $id An ID for the registry instance
  189. *
  190. * @return JRegistry The JRegistry object.
  191. *
  192. * @since 11.1
  193. */
  194. public static function getInstance($id)
  195. {
  196. if (empty(self::$instances[$id]))
  197. {
  198. self::$instances[$id] = new JRegistry;
  199. }
  200. return self::$instances[$id];
  201. }
  202. /**
  203. * Load a associative array of values into the default namespace
  204. *
  205. * @param array $array Associative array of value to load
  206. *
  207. * @return boolean True on success
  208. *
  209. * @since 11.1
  210. */
  211. public function loadArray($array)
  212. {
  213. $this->bindData($this->data, $array);
  214. return true;
  215. }
  216. /**
  217. * Load the public variables of the object into the default namespace.
  218. *
  219. * @param object $object The object holding the publics to load
  220. *
  221. * @return boolean True on success
  222. *
  223. * @since 11.1
  224. */
  225. public function loadObject($object)
  226. {
  227. $this->bindData($this->data, $object);
  228. return true;
  229. }
  230. /**
  231. * Load the contents of a file into the registry
  232. *
  233. * @param string $file Path to file to load
  234. * @param string $format Format of the file [optional: defaults to JSON]
  235. * @param array $options Options used by the formatter
  236. *
  237. * @return boolean True on success
  238. *
  239. * @since 11.1
  240. */
  241. public function loadFile($file, $format = 'JSON', $options = array())
  242. {
  243. $data = file_get_contents($file);
  244. return $this->loadString($data, $format, $options);
  245. }
  246. /**
  247. * Load a string into the registry
  248. *
  249. * @param string $data String to load into the registry
  250. * @param string $format Format of the string
  251. * @param array $options Options used by the formatter
  252. *
  253. * @return boolean True on success
  254. *
  255. * @since 11.1
  256. */
  257. public function loadString($data, $format = 'JSON', $options = array())
  258. {
  259. // Load a string into the given namespace [or default namespace if not given]
  260. $handler = JRegistryFormat::getInstance($format);
  261. $obj = $handler->stringToObject($data, $options);
  262. $this->loadObject($obj);
  263. return true;
  264. }
  265. /**
  266. * Merge a JRegistry object into this one
  267. *
  268. * @param JRegistry $source Source JRegistry object to merge.
  269. *
  270. * @return boolean True on success
  271. *
  272. * @since 11.1
  273. */
  274. public function merge($source)
  275. {
  276. if (!$source instanceof JRegistry)
  277. {
  278. return false;
  279. }
  280. // Load the variables into the registry's default namespace.
  281. foreach ($source->toArray() as $k => $v)
  282. {
  283. if (($v !== null) && ($v !== ''))
  284. {
  285. $this->data->$k = $v;
  286. }
  287. }
  288. return true;
  289. }
  290. /**
  291. * Set a registry value.
  292. *
  293. * @param string $path Registry Path (e.g. joomla.content.showauthor)
  294. * @param mixed $value Value of entry
  295. *
  296. * @return mixed The value of the that has been set.
  297. *
  298. * @since 11.1
  299. */
  300. public function set($path, $value)
  301. {
  302. $result = null;
  303. /**
  304. * Explode the registry path into an array and remove empty
  305. * nodes caused by passing in double dotted strings. ex: joomla..test.
  306. * Finally, re-key the array so it is sequential.
  307. */
  308. $nodes = array_values(array_filter(explode('.', $path), 'strlen'));
  309. if ($nodes)
  310. {
  311. // Initialize the current node to be the registry root.
  312. $node = $this->data;
  313. // Traverse the registry to find the correct node for the result.
  314. for ($i = 0, $n = count($nodes) - 1; $i < $n; $i++)
  315. {
  316. if (!isset($node->$nodes[$i]) && ($i != $n))
  317. {
  318. $node->$nodes[$i] = new stdClass;
  319. }
  320. $node = $node->$nodes[$i];
  321. }
  322. // Get the old value if exists so we can return it
  323. $result = $node->$nodes[$i] = $value;
  324. }
  325. return $result;
  326. }
  327. /**
  328. * Transforms a namespace to an array
  329. *
  330. * @return array An associative array holding the namespace data
  331. *
  332. * @since 11.1
  333. */
  334. public function toArray()
  335. {
  336. return (array) $this->asArray($this->data);
  337. }
  338. /**
  339. * Transforms a namespace to an object
  340. *
  341. * @return object An an object holding the namespace data
  342. *
  343. * @since 11.1
  344. */
  345. public function toObject()
  346. {
  347. return $this->data;
  348. }
  349. /**
  350. * Get a namespace in a given string format
  351. *
  352. * @param string $format Format to return the string in
  353. * @param mixed $options Parameters used by the formatter, see formatters for more info
  354. *
  355. * @return string Namespace in string format
  356. *
  357. * @since 11.1
  358. */
  359. public function toString($format = 'JSON', $options = array())
  360. {
  361. // Return a namespace in a given format
  362. $handler = JRegistryFormat::getInstance($format);
  363. return $handler->objectToString($this->data, $options);
  364. }
  365. /**
  366. * Method to recursively bind data to a parent object.
  367. *
  368. * @param object $parent The parent object on which to attach the data values.
  369. * @param mixed $data An array or object of data to bind to the parent object.
  370. *
  371. * @return void
  372. *
  373. * @since 11.1
  374. */
  375. protected function bindData($parent, $data)
  376. {
  377. // Ensure the input data is an array.
  378. if (is_object($data))
  379. {
  380. $data = get_object_vars($data);
  381. }
  382. else
  383. {
  384. $data = (array) $data;
  385. }
  386. foreach ($data as $k => $v)
  387. {
  388. if ((is_array($v) && JArrayHelper::isAssociative($v)) || is_object($v))
  389. {
  390. $parent->$k = new stdClass;
  391. $this->bindData($parent->$k, $v);
  392. }
  393. else
  394. {
  395. $parent->$k = $v;
  396. }
  397. }
  398. }
  399. /**
  400. * Method to recursively convert an object of data to an array.
  401. *
  402. * @param object $data An object of data to return as an array.
  403. *
  404. * @return array Array representation of the input object.
  405. *
  406. * @since 11.1
  407. */
  408. protected function asArray($data)
  409. {
  410. $array = array();
  411. foreach (get_object_vars((object) $data) as $k => $v)
  412. {
  413. if (is_object($v))
  414. {
  415. $array[$k] = $this->asArray($v);
  416. }
  417. else
  418. {
  419. $array[$k] = $v;
  420. }
  421. }
  422. return $array;
  423. }
  424. }