/libraries/joomla/registry/registry.php

https://bitbucket.org/pastor399/newcastleunifc · PHP · 470 lines · 206 code · 47 blank · 217 comment · 29 complexity · dadbebe4164dacac513d24de5d4b710b MD5 · raw file

  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 string $default An optional value for the parameter.
  93. *
  94. * @return string 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, (string) $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, then re-key the array so it's sequential.
  306. */
  307. $nodes = array_values(array_filter(explode('.', $path), 'strlen'));
  308. if ($nodes)
  309. {
  310. // Initialize the current node to be the registry root.
  311. $node = $this->data;
  312. // Traverse the registry to find the correct node for the result.
  313. for ($i = 0, $n = count($nodes) - 1; $i < $n; $i++)
  314. {
  315. if (!isset($node->$nodes[$i]) && ($i != $n))
  316. {
  317. $node->$nodes[$i] = new stdClass;
  318. }
  319. $node = $node->$nodes[$i];
  320. }
  321. // Get the old value if exists so we can return it
  322. $result = $node->$nodes[$i] = $value;
  323. }
  324. return $result;
  325. }
  326. /**
  327. * Transforms a namespace to an array
  328. *
  329. * @return array An associative array holding the namespace data
  330. *
  331. * @since 11.1
  332. */
  333. public function toArray()
  334. {
  335. return (array) $this->asArray($this->data);
  336. }
  337. /**
  338. * Transforms a namespace to an object
  339. *
  340. * @return object An an object holding the namespace data
  341. *
  342. * @since 11.1
  343. */
  344. public function toObject()
  345. {
  346. return $this->data;
  347. }
  348. /**
  349. * Get a namespace in a given string format
  350. *
  351. * @param string $format Format to return the string in
  352. * @param mixed $options Parameters used by the formatter, see formatters for more info
  353. *
  354. * @return string Namespace in string format
  355. *
  356. * @since 11.1
  357. */
  358. public function toString($format = 'JSON', $options = array())
  359. {
  360. // Return a namespace in a given format
  361. $handler = JRegistryFormat::getInstance($format);
  362. return $handler->objectToString($this->data, $options);
  363. }
  364. /**
  365. * Method to recursively bind data to a parent object.
  366. *
  367. * @param object $parent The parent object on which to attach the data values.
  368. * @param mixed $data An array or object of data to bind to the parent object.
  369. *
  370. * @return void
  371. *
  372. * @since 11.1
  373. */
  374. protected function bindData($parent, $data)
  375. {
  376. // Ensure the input data is an array.
  377. if (is_object($data))
  378. {
  379. $data = get_object_vars($data);
  380. }
  381. else
  382. {
  383. $data = (array) $data;
  384. }
  385. foreach ($data as $k => $v)
  386. {
  387. if ((is_array($v) && JArrayHelper::isAssociative($v)) || is_object($v))
  388. {
  389. $parent->$k = new stdClass;
  390. $this->bindData($parent->$k, $v);
  391. }
  392. else
  393. {
  394. $parent->$k = $v;
  395. }
  396. }
  397. }
  398. /**
  399. * Method to recursively convert an object of data to an array.
  400. *
  401. * @param object $data An object of data to return as an array.
  402. *
  403. * @return array Array representation of the input object.
  404. *
  405. * @since 11.1
  406. */
  407. protected function asArray($data)
  408. {
  409. $array = array();
  410. foreach (get_object_vars((object) $data) as $k => $v)
  411. {
  412. if (is_object($v))
  413. {
  414. $array[$k] = $this->asArray($v);
  415. }
  416. else
  417. {
  418. $array[$k] = $v;
  419. }
  420. }
  421. return $array;
  422. }
  423. }