/libraries/joomla/registry/registry.php

https://github.com/dextercowley/joomla-platform · PHP · 454 lines · 202 code · 45 blank · 207 comment · 29 complexity · e7696fd9e28f279f978a08a4d409b7e6 MD5 · raw file

  1. <?php
  2. /**
  3. * @package Joomla.Platform
  4. * @subpackage Registry
  5. *
  6. * @copyright Copyright (C) 2005 - 2012 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
  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. * Sets a default value if not already assigned.
  77. *
  78. * @param string $key The name of the parameter.
  79. * @param string $default An optional value for the parameter.
  80. *
  81. * @return string The value set, or the default if the value was not previously set (or null).
  82. *
  83. * @since 11.1
  84. */
  85. public function def($key, $default = '')
  86. {
  87. $value = $this->get($key, (string) $default);
  88. $this->set($key, $value);
  89. return $value;
  90. }
  91. /**
  92. * Check if a registry path exists.
  93. *
  94. * @param string $path Registry path (e.g. joomla.content.showauthor)
  95. *
  96. * @return boolean
  97. *
  98. * @since 11.1
  99. */
  100. public function exists($path)
  101. {
  102. // Explode the registry path into an array
  103. if ($nodes = explode('.', $path))
  104. {
  105. // Initialize the current node to be the registry root.
  106. $node = $this->data;
  107. // Traverse the registry to find the correct node for the result.
  108. for ($i = 0, $n = count($nodes); $i < $n; $i++)
  109. {
  110. if (isset($node->$nodes[$i]))
  111. {
  112. $node = $node->$nodes[$i];
  113. }
  114. else
  115. {
  116. break;
  117. }
  118. if ($i + 1 == $n)
  119. {
  120. return true;
  121. }
  122. }
  123. }
  124. return false;
  125. }
  126. /**
  127. * Get a registry value.
  128. *
  129. * @param string $path Registry path (e.g. joomla.content.showauthor)
  130. * @param mixed $default Optional default value, returned if the internal value is null.
  131. *
  132. * @return mixed Value of entry or null
  133. *
  134. * @since 11.1
  135. */
  136. public function get($path, $default = null)
  137. {
  138. // Initialise variables.
  139. $result = $default;
  140. if (!strpos($path, '.'))
  141. {
  142. return (isset($this->data->$path) && $this->data->$path !== null && $this->data->$path !== '') ? $this->data->$path : $default;
  143. }
  144. // Explode the registry path into an array
  145. $nodes = explode('.', $path);
  146. // Initialize the current node to be the registry root.
  147. $node = $this->data;
  148. $found = false;
  149. // Traverse the registry to find the correct node for the result.
  150. foreach ($nodes as $n)
  151. {
  152. if (isset($node->$n))
  153. {
  154. $node = $node->$n;
  155. $found = true;
  156. }
  157. else
  158. {
  159. $found = false;
  160. break;
  161. }
  162. }
  163. if ($found && $node !== null && $node !== '')
  164. {
  165. $result = $node;
  166. }
  167. return $result;
  168. }
  169. /**
  170. * Returns a reference to a global JRegistry object, only creating it
  171. * if it doesn't already exist.
  172. *
  173. * This method must be invoked as:
  174. * <pre>$registry = JRegistry::getInstance($id);</pre>
  175. *
  176. * @param string $id An ID for the registry instance
  177. *
  178. * @return JRegistry The JRegistry object.
  179. *
  180. * @since 11.1
  181. */
  182. public static function getInstance($id)
  183. {
  184. if (empty(self::$instances[$id]))
  185. {
  186. self::$instances[$id] = new JRegistry;
  187. }
  188. return self::$instances[$id];
  189. }
  190. /**
  191. * Load a associative array of values into the default namespace
  192. *
  193. * @param array $array Associative array of value to load
  194. *
  195. * @return boolean True on success
  196. *
  197. * @since 11.1
  198. */
  199. public function loadArray($array)
  200. {
  201. $this->bindData($this->data, $array);
  202. return true;
  203. }
  204. /**
  205. * Load the public variables of the object into the default namespace.
  206. *
  207. * @param object $object The object holding the publics to load
  208. *
  209. * @return boolean True on success
  210. *
  211. * @since 11.1
  212. */
  213. public function loadObject($object)
  214. {
  215. $this->bindData($this->data, $object);
  216. return true;
  217. }
  218. /**
  219. * Load the contents of a file into the registry
  220. *
  221. * @param string $file Path to file to load
  222. * @param string $format Format of the file [optional: defaults to JSON]
  223. * @param array $options Options used by the formatter
  224. *
  225. * @return boolean True on success
  226. *
  227. * @since 11.1
  228. */
  229. public function loadFile($file, $format = 'JSON', $options = array())
  230. {
  231. // Get the contents of the file
  232. jimport('joomla.filesystem.file');
  233. $data = JFile::read($file);
  234. return $this->loadString($data, $format, $options);
  235. }
  236. /**
  237. * Load a string into the registry
  238. *
  239. * @param string $data String to load into the registry
  240. * @param string $format Format of the string
  241. * @param array $options Options used by the formatter
  242. *
  243. * @return boolean True on success
  244. *
  245. * @since 11.1
  246. */
  247. public function loadString($data, $format = 'JSON', $options = array())
  248. {
  249. // Load a string into the given namespace [or default namespace if not given]
  250. $handler = JRegistryFormat::getInstance($format);
  251. $obj = $handler->stringToObject($data, $options);
  252. $this->loadObject($obj);
  253. return true;
  254. }
  255. /**
  256. * Merge a JRegistry object into this one
  257. *
  258. * @param JRegistry $source Source JRegistry object to merge.
  259. *
  260. * @return boolean True on success
  261. *
  262. * @since 11.1
  263. */
  264. public function merge($source)
  265. {
  266. if (!$source instanceof JRegistry)
  267. {
  268. return false;
  269. }
  270. // Load the variables into the registry's default namespace.
  271. foreach ($source->toArray() as $k => $v)
  272. {
  273. if (($v !== null) && ($v !== ''))
  274. {
  275. $this->data->$k = $v;
  276. }
  277. }
  278. return true;
  279. }
  280. /**
  281. * Set a registry value.
  282. *
  283. * @param string $path Registry Path (e.g. joomla.content.showauthor)
  284. * @param mixed $value Value of entry
  285. *
  286. * @return mixed The value of the that has been set.
  287. *
  288. * @since 11.1
  289. */
  290. public function set($path, $value)
  291. {
  292. $result = null;
  293. // Explode the registry path into an array
  294. if ($nodes = explode('.', $path))
  295. {
  296. // Initialize the current node to be the registry root.
  297. $node = $this->data;
  298. // Traverse the registry to find the correct node for the result.
  299. for ($i = 0, $n = count($nodes) - 1; $i < $n; $i++)
  300. {
  301. if (!isset($node->$nodes[$i]) && ($i != $n))
  302. {
  303. $node->$nodes[$i] = new stdClass;
  304. }
  305. $node = $node->$nodes[$i];
  306. }
  307. // Get the old value if exists so we can return it
  308. $result = $node->$nodes[$i] = $value;
  309. }
  310. return $result;
  311. }
  312. /**
  313. * Transforms a namespace to an array
  314. *
  315. * @return array An associative array holding the namespace data
  316. *
  317. * @since 11.1
  318. */
  319. public function toArray()
  320. {
  321. return (array) $this->asArray($this->data);
  322. }
  323. /**
  324. * Transforms a namespace to an object
  325. *
  326. * @return object An an object holding the namespace data
  327. *
  328. * @since 11.1
  329. */
  330. public function toObject()
  331. {
  332. return $this->data;
  333. }
  334. /**
  335. * Get a namespace in a given string format
  336. *
  337. * @param string $format Format to return the string in
  338. * @param mixed $options Parameters used by the formatter, see formatters for more info
  339. *
  340. * @return string Namespace in string format
  341. *
  342. * @since 11.1
  343. */
  344. public function toString($format = 'JSON', $options = array())
  345. {
  346. // Return a namespace in a given format
  347. $handler = JRegistryFormat::getInstance($format);
  348. return $handler->objectToString($this->data, $options);
  349. }
  350. /**
  351. * Method to recursively bind data to a parent object.
  352. *
  353. * @param object $parent The parent object on which to attach the data values.
  354. * @param mixed $data An array or object of data to bind to the parent object.
  355. *
  356. * @return void
  357. *
  358. * @since 11.1
  359. */
  360. protected function bindData($parent, $data)
  361. {
  362. // Ensure the input data is an array.
  363. if (is_object($data))
  364. {
  365. $data = get_object_vars($data);
  366. }
  367. else
  368. {
  369. $data = (array) $data;
  370. }
  371. foreach ($data as $k => $v)
  372. {
  373. if ((is_array($v) && JArrayHelper::isAssociative($v)) || is_object($v))
  374. {
  375. $parent->$k = new stdClass;
  376. $this->bindData($parent->$k, $v);
  377. }
  378. else
  379. {
  380. $parent->$k = $v;
  381. }
  382. }
  383. }
  384. /**
  385. * Method to recursively convert an object of data to an array.
  386. *
  387. * @param object $data An object of data to return as an array.
  388. *
  389. * @return array Array representation of the input object.
  390. *
  391. * @since 11.1
  392. */
  393. protected function asArray($data)
  394. {
  395. $array = array();
  396. foreach (get_object_vars((object) $data) as $k => $v)
  397. {
  398. if (is_object($v))
  399. {
  400. $array[$k] = $this->asArray($v);
  401. }
  402. else
  403. {
  404. $array[$k] = $v;
  405. }
  406. }
  407. return $array;
  408. }
  409. }