PageRenderTime 66ms CodeModel.GetById 6ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/vendor/joomla/registry/src/Registry.php

https://bitbucket.org/programmerlab/ourteam.co.in
PHP | 649 lines | 272 code | 73 blank | 304 comment | 37 complexity | c03d3b5865cf725413bfefe7246521a5 MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0, 0BSD, MIT, LGPL-2.1
  1. <?php
  2. /**
  3. * Part of the Joomla Framework Registry Package
  4. *
  5. * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved.
  6. * @license GNU General Public License version 2 or later; see LICENSE
  7. */
  8. namespace Joomla\Registry;
  9. use Joomla\Utilities\ArrayHelper;
  10. /**
  11. * Registry class
  12. *
  13. * @since 1.0
  14. */
  15. class Registry implements \JsonSerializable, \ArrayAccess, \IteratorAggregate, \Countable
  16. {
  17. /**
  18. * Registry Object
  19. *
  20. * @var object
  21. * @since 1.0
  22. */
  23. protected $data;
  24. /**
  25. * Registry instances container.
  26. *
  27. * @var array
  28. * @since 1.0
  29. */
  30. protected static $instances = array();
  31. /**
  32. * Constructor
  33. *
  34. * @param mixed $data The data to bind to the new Registry object.
  35. *
  36. * @since 1.0
  37. */
  38. public function __construct($data = null)
  39. {
  40. // Instantiate the internal data object.
  41. $this->data = new \stdClass;
  42. // Optionally load supplied data.
  43. if (is_array($data) || is_object($data))
  44. {
  45. $this->bindData($this->data, $data);
  46. }
  47. elseif (!empty($data) && is_string($data))
  48. {
  49. $this->loadString($data);
  50. }
  51. }
  52. /**
  53. * Magic function to clone the registry object.
  54. *
  55. * @return Registry
  56. *
  57. * @since 1.0
  58. */
  59. public function __clone()
  60. {
  61. $this->data = unserialize(serialize($this->data));
  62. }
  63. /**
  64. * Magic function to render this object as a string using default args of toString method.
  65. *
  66. * @return string
  67. *
  68. * @since 1.0
  69. */
  70. public function __toString()
  71. {
  72. return $this->toString();
  73. }
  74. /**
  75. * Count elements of the data object
  76. *
  77. * @return integer The custom count as an integer.
  78. *
  79. * @link http://php.net/manual/en/countable.count.php
  80. * @since 1.3.0
  81. */
  82. public function count()
  83. {
  84. $i = 0;
  85. foreach ($this->data as $item)
  86. {
  87. $i++;
  88. }
  89. return $i++;
  90. }
  91. /**
  92. * Implementation for the JsonSerializable interface.
  93. * Allows us to pass Registry objects to json_encode.
  94. *
  95. * @return object
  96. *
  97. * @since 1.0
  98. * @note The interface is only present in PHP 5.4 and up.
  99. */
  100. public function jsonSerialize()
  101. {
  102. return $this->data;
  103. }
  104. /**
  105. * Sets a default value if not already assigned.
  106. *
  107. * @param string $key The name of the parameter.
  108. * @param mixed $default An optional value for the parameter.
  109. *
  110. * @return mixed The value set, or the default if the value was not previously set (or null).
  111. *
  112. * @since 1.0
  113. */
  114. public function def($key, $default = '')
  115. {
  116. $value = $this->get($key, $default);
  117. $this->set($key, $value);
  118. return $value;
  119. }
  120. /**
  121. * Check if a registry path exists.
  122. *
  123. * @param string $path Registry path (e.g. joomla.content.showauthor)
  124. *
  125. * @return boolean
  126. *
  127. * @since 1.0
  128. */
  129. public function exists($path)
  130. {
  131. // Explode the registry path into an array
  132. $nodes = explode('.', $path);
  133. if ($nodes)
  134. {
  135. // Initialize the current node to be the registry root.
  136. $node = $this->data;
  137. // Traverse the registry to find the correct node for the result.
  138. for ($i = 0, $n = count($nodes); $i < $n; $i++)
  139. {
  140. if (isset($node->$nodes[$i]))
  141. {
  142. $node = $node->$nodes[$i];
  143. }
  144. else
  145. {
  146. break;
  147. }
  148. if ($i + 1 == $n)
  149. {
  150. return true;
  151. }
  152. }
  153. }
  154. return false;
  155. }
  156. /**
  157. * Get a registry value.
  158. *
  159. * @param string $path Registry path (e.g. joomla.content.showauthor)
  160. * @param mixed $default Optional default value, returned if the internal value is null.
  161. *
  162. * @return mixed Value of entry or null
  163. *
  164. * @since 1.0
  165. */
  166. public function get($path, $default = null)
  167. {
  168. $result = $default;
  169. if (!strpos($path, '.'))
  170. {
  171. return (isset($this->data->$path) && $this->data->$path !== null && $this->data->$path !== '') ? $this->data->$path : $default;
  172. }
  173. // Explode the registry path into an array
  174. $nodes = explode('.', $path);
  175. // Initialize the current node to be the registry root.
  176. $node = $this->data;
  177. $found = false;
  178. // Traverse the registry to find the correct node for the result.
  179. foreach ($nodes as $n)
  180. {
  181. if (isset($node->$n))
  182. {
  183. $node = $node->$n;
  184. $found = true;
  185. }
  186. else
  187. {
  188. $found = false;
  189. break;
  190. }
  191. }
  192. if ($found && $node !== null && $node !== '')
  193. {
  194. $result = $node;
  195. }
  196. return $result;
  197. }
  198. /**
  199. * Returns a reference to a global Registry object, only creating it
  200. * if it doesn't already exist.
  201. *
  202. * This method must be invoked as:
  203. * <pre>$registry = Registry::getInstance($id);</pre>
  204. *
  205. * @param string $id An ID for the registry instance
  206. *
  207. * @return Registry The Registry object.
  208. *
  209. * @since 1.0
  210. */
  211. public static function getInstance($id)
  212. {
  213. if (empty(self::$instances[$id]))
  214. {
  215. self::$instances[$id] = new self;
  216. }
  217. return self::$instances[$id];
  218. }
  219. /**
  220. * Gets this object represented as an ArrayIterator.
  221. *
  222. * This allows the data properties to be accessed via a foreach statement.
  223. *
  224. * @return \ArrayIterator This object represented as an ArrayIterator.
  225. *
  226. * @see IteratorAggregate::getIterator()
  227. * @since 1.3.0
  228. */
  229. public function getIterator()
  230. {
  231. return new \ArrayIterator($this->data);
  232. }
  233. /**
  234. * Load a associative array of values into the default namespace
  235. *
  236. * @param array $array Associative array of value to load
  237. *
  238. * @return Registry Return this object to support chaining.
  239. *
  240. * @since 1.0
  241. */
  242. public function loadArray($array)
  243. {
  244. $this->bindData($this->data, $array);
  245. return $this;
  246. }
  247. /**
  248. * Load the public variables of the object into the default namespace.
  249. *
  250. * @param object $object The object holding the publics to load
  251. *
  252. * @return Registry Return this object to support chaining.
  253. *
  254. * @since 1.0
  255. */
  256. public function loadObject($object)
  257. {
  258. $this->bindData($this->data, $object);
  259. return $this;
  260. }
  261. /**
  262. * Load the contents of a file into the registry
  263. *
  264. * @param string $file Path to file to load
  265. * @param string $format Format of the file [optional: defaults to JSON]
  266. * @param array $options Options used by the formatter
  267. *
  268. * @return Registry Return this object to support chaining.
  269. *
  270. * @since 1.0
  271. */
  272. public function loadFile($file, $format = 'JSON', $options = array())
  273. {
  274. $data = file_get_contents($file);
  275. return $this->loadString($data, $format, $options);
  276. }
  277. /**
  278. * Load a string into the registry
  279. *
  280. * @param string $data String to load into the registry
  281. * @param string $format Format of the string
  282. * @param array $options Options used by the formatter
  283. *
  284. * @return Registry Return this object to support chaining.
  285. *
  286. * @since 1.0
  287. */
  288. public function loadString($data, $format = 'JSON', $options = array())
  289. {
  290. // Load a string into the given namespace [or default namespace if not given]
  291. $handler = AbstractRegistryFormat::getInstance($format);
  292. $obj = $handler->stringToObject($data, $options);
  293. $this->loadObject($obj);
  294. return $this;
  295. }
  296. /**
  297. * Merge a Registry object into this one
  298. *
  299. * @param Registry $source Source Registry object to merge.
  300. * @param boolean $recursive True to support recursive merge the children values.
  301. *
  302. * @return Registry Return this object to support chaining.
  303. *
  304. * @since 1.0
  305. */
  306. public function merge($source, $recursive = false)
  307. {
  308. if (!$source instanceof Registry)
  309. {
  310. return false;
  311. }
  312. $this->bindData($this->data, $source->toArray(), $recursive, false);
  313. return $this;
  314. }
  315. /**
  316. * Method to extract a sub-registry from path
  317. *
  318. * @param string $path Registry path (e.g. joomla.content.showauthor)
  319. *
  320. * @return Registry|null Registry object if data is present
  321. *
  322. * @since 1.2.0
  323. */
  324. public function extract($path)
  325. {
  326. $data = $this->get($path);
  327. if (is_null($data))
  328. {
  329. return null;
  330. }
  331. return new Registry($data);
  332. }
  333. /**
  334. * Checks whether an offset exists in the iterator.
  335. *
  336. * @param mixed $offset The array offset.
  337. *
  338. * @return boolean True if the offset exists, false otherwise.
  339. *
  340. * @since 1.0
  341. */
  342. public function offsetExists($offset)
  343. {
  344. return (boolean) ($this->get($offset) !== null);
  345. }
  346. /**
  347. * Gets an offset in the iterator.
  348. *
  349. * @param mixed $offset The array offset.
  350. *
  351. * @return mixed The array value if it exists, null otherwise.
  352. *
  353. * @since 1.0
  354. */
  355. public function offsetGet($offset)
  356. {
  357. return $this->get($offset);
  358. }
  359. /**
  360. * Sets an offset in the iterator.
  361. *
  362. * @param mixed $offset The array offset.
  363. * @param mixed $value The array value.
  364. *
  365. * @return void
  366. *
  367. * @since 1.0
  368. */
  369. public function offsetSet($offset, $value)
  370. {
  371. $this->set($offset, $value);
  372. }
  373. /**
  374. * Unsets an offset in the iterator.
  375. *
  376. * @param mixed $offset The array offset.
  377. *
  378. * @return void
  379. *
  380. * @since 1.0
  381. */
  382. public function offsetUnset($offset)
  383. {
  384. $this->set($offset, null);
  385. }
  386. /**
  387. * Set a registry value.
  388. *
  389. * @param string $path Registry Path (e.g. joomla.content.showauthor)
  390. * @param mixed $value Value of entry
  391. *
  392. * @return mixed The value of the that has been set.
  393. *
  394. * @since 1.0
  395. */
  396. public function set($path, $value)
  397. {
  398. $result = null;
  399. /**
  400. * Explode the registry path into an array and remove empty
  401. * nodes that occur as a result of a double dot. ex: joomla..test
  402. * Finally, re-key the array so they are sequential.
  403. */
  404. $nodes = array_values(array_filter(explode('.', $path), 'strlen'));
  405. if ($nodes)
  406. {
  407. // Initialize the current node to be the registry root.
  408. $node = $this->data;
  409. // Traverse the registry to find the correct node for the result.
  410. for ($i = 0, $n = count($nodes) - 1; $i < $n; $i++)
  411. {
  412. if (!isset($node->$nodes[$i]) && ($i != $n))
  413. {
  414. $node->$nodes[$i] = new \stdClass;
  415. }
  416. $node = $node->$nodes[$i];
  417. }
  418. // Get the old value if exists so we can return it
  419. $result = $node->$nodes[$i] = $value;
  420. }
  421. return $result;
  422. }
  423. /**
  424. * Transforms a namespace to an array
  425. *
  426. * @return array An associative array holding the namespace data
  427. *
  428. * @since 1.0
  429. */
  430. public function toArray()
  431. {
  432. return (array) $this->asArray($this->data);
  433. }
  434. /**
  435. * Transforms a namespace to an object
  436. *
  437. * @return object An an object holding the namespace data
  438. *
  439. * @since 1.0
  440. */
  441. public function toObject()
  442. {
  443. return $this->data;
  444. }
  445. /**
  446. * Get a namespace in a given string format
  447. *
  448. * @param string $format Format to return the string in
  449. * @param mixed $options Parameters used by the formatter, see formatters for more info
  450. *
  451. * @return string Namespace in string format
  452. *
  453. * @since 1.0
  454. */
  455. public function toString($format = 'JSON', $options = array())
  456. {
  457. // Return a namespace in a given format
  458. $handler = AbstractRegistryFormat::getInstance($format);
  459. return $handler->objectToString($this->data, $options);
  460. }
  461. /**
  462. * Method to recursively bind data to a parent object.
  463. *
  464. * @param object $parent The parent object on which to attach the data values.
  465. * @param mixed $data An array or object of data to bind to the parent object.
  466. * @param boolean $recursive True to support recursive bindData.
  467. * @param boolean $allowNull True to allow null values.
  468. *
  469. * @return void
  470. *
  471. * @since 1.0
  472. */
  473. protected function bindData($parent, $data, $recursive = true, $allowNull = true)
  474. {
  475. // Ensure the input data is an array.
  476. if (is_object($data))
  477. {
  478. $data = get_object_vars($data);
  479. }
  480. else
  481. {
  482. $data = (array) $data;
  483. }
  484. foreach ($data as $k => $v)
  485. {
  486. if (!$allowNull && !(($v !== null) && ($v !== '')))
  487. {
  488. continue;
  489. }
  490. if ($recursive && ((is_array($v) && ArrayHelper::isAssociative($v)) || is_object($v)))
  491. {
  492. if (!isset($parent->$k))
  493. {
  494. $parent->$k = new \stdClass;
  495. }
  496. $this->bindData($parent->$k, $v);
  497. }
  498. else
  499. {
  500. $parent->$k = $v;
  501. }
  502. }
  503. }
  504. /**
  505. * Method to recursively convert an object of data to an array.
  506. *
  507. * @param object $data An object of data to return as an array.
  508. *
  509. * @return array Array representation of the input object.
  510. *
  511. * @since 1.0
  512. */
  513. protected function asArray($data)
  514. {
  515. $array = array();
  516. if (is_object($data))
  517. {
  518. $data = get_object_vars($data);
  519. }
  520. foreach ($data as $k => $v)
  521. {
  522. if (is_object($v) || is_array($v))
  523. {
  524. $array[$k] = $this->asArray($v);
  525. }
  526. else
  527. {
  528. $array[$k] = $v;
  529. }
  530. }
  531. return $array;
  532. }
  533. /**
  534. * Dump to one dimension array.
  535. *
  536. * @param string $separator The key separator.
  537. *
  538. * @return string[] Dumped array.
  539. *
  540. * @since 1.3.0
  541. */
  542. public function flatten($separator = '.')
  543. {
  544. $array = array();
  545. $this->toFlatten($separator, $this->data, $array);
  546. return $array;
  547. }
  548. /**
  549. * Method to recursively convert data to one dimension array.
  550. *
  551. * @param string $separator The key separator.
  552. * @param array|object $data Data source of this scope.
  553. * @param array &$array The result array, it is pass by reference.
  554. * @param string $prefix Last level key prefix.
  555. *
  556. * @return void
  557. *
  558. * @since 1.3.0
  559. */
  560. protected function toFlatten($separator = '.', $data = null, &$array = array(), $prefix = '')
  561. {
  562. $data = (array) $data;
  563. foreach ($data as $k => $v)
  564. {
  565. $key = $prefix ? $prefix . $separator . $k : $k;
  566. if (is_object($v) || is_array($v))
  567. {
  568. $this->toFlatten($separator, $v, $array, $key);
  569. }
  570. else
  571. {
  572. $array[$key] = $v;
  573. }
  574. }
  575. }
  576. }