vendor/pimcore/pimcore/lib/Config/Config.php line 298

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Commercial License (PCL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  13.  */
  14. /**
  15.  * ----------------------------------------------------------------------------------
  16.  * based on Zend\Config https://github.com/zendframework/zend-config
  17.  * ----------------------------------------------------------------------------------
  18.  */
  19. /**
  20.  * @see       https://github.com/zendframework/zend-config for the canonical source repository
  21.  *
  22.  * @copyright Copyright (c) 2005-2017 Zend Technologies USA Inc. (http://www.zend.com)
  23.  * @license   https://github.com/zendframework/zend-config/blob/master/LICENSE.md New BSD License
  24.  */
  25. namespace Pimcore\Config;
  26. use ArrayAccess;
  27. use Countable;
  28. use Exception;
  29. use Iterator;
  30. /**
  31.  * Provides a property based interface to an array.
  32.  * The data are read-only unless $allowModifications is set to true
  33.  * on construction.
  34.  *
  35.  * Implements Countable, Iterator and ArrayAccess
  36.  * to facilitate easy access to the data.
  37.  */
  38. final class Config implements CountableIteratorArrayAccess
  39. {
  40.     /**
  41.      * Whether modifications to configuration data are allowed.
  42.      *
  43.      * @var bool
  44.      */
  45.     protected $allowModifications;
  46.     /**
  47.      * Data within the configuration.
  48.      *
  49.      * @var array
  50.      */
  51.     protected $data = [];
  52.     /**
  53.      * Used when unsetting values during iteration to ensure we do not skip
  54.      * the next element.
  55.      *
  56.      * @var bool
  57.      */
  58.     protected $skipNextIteration;
  59.     /**
  60.      * Constructor.
  61.      *
  62.      * Data is read-only unless $allowModifications is set to true
  63.      * on construction.
  64.      *
  65.      * @param  array   $array
  66.      * @param  bool $allowModifications
  67.      */
  68.     public function __construct(array $array$allowModifications false)
  69.     {
  70.         $this->allowModifications = (bool) $allowModifications;
  71.         foreach ($array as $key => $value) {
  72.             if (is_array($value)) {
  73.                 $this->data[$key] = new static($value$this->allowModifications);
  74.             } else {
  75.                 $this->data[$key] = $value;
  76.             }
  77.         }
  78.     }
  79.     /**
  80.      * Retrieve a value and return $default if there is no element set.
  81.      *
  82.      * @param  string $name
  83.      * @param  mixed  $default
  84.      *
  85.      * @return mixed
  86.      */
  87.     public function get($name$default null)
  88.     {
  89.         if (array_key_exists($name$this->data)) {
  90.             return $this->data[$name];
  91.         }
  92.         return $default;
  93.     }
  94.     /**
  95.      * Magic function so that $obj->value will work.
  96.      *
  97.      * @param  string $name
  98.      *
  99.      * @return mixed
  100.      */
  101.     public function __get($name)
  102.     {
  103.         return $this->get($name);
  104.     }
  105.     /**
  106.      * Set a value in the config.
  107.      *
  108.      * Only allow setting of a property if $allowModifications  was set to true
  109.      * on construction. Otherwise, throw an exception.
  110.      *
  111.      * @param  string|null $name
  112.      * @param  mixed  $value
  113.      *
  114.      * @return void
  115.      *
  116.      * @throws Exception
  117.      */
  118.     public function __set($name$value)
  119.     {
  120.         if ($this->allowModifications) {
  121.             if (is_array($value)) {
  122.                 $value = new static($valuetrue);
  123.             }
  124.             if (null === $name) {
  125.                 $this->data[] = $value;
  126.             } else {
  127.                 $this->data[$name] = $value;
  128.             }
  129.         } else {
  130.             throw new Exception('Config is read only');
  131.         }
  132.     }
  133.     /**
  134.      * Deep clone of this instance to ensure that nested Zend\Configs are also
  135.      * cloned.
  136.      *
  137.      * @return void
  138.      */
  139.     public function __clone()
  140.     {
  141.         $array = [];
  142.         foreach ($this->data as $key => $value) {
  143.             if ($value instanceof self) {
  144.                 $array[$key] = clone $value;
  145.             } else {
  146.                 $array[$key] = $value;
  147.             }
  148.         }
  149.         $this->data $array;
  150.     }
  151.     /**
  152.      * Return an associative array of the stored data.
  153.      *
  154.      * @return array
  155.      */
  156.     public function toArray()
  157.     {
  158.         $array = [];
  159.         $data $this->data;
  160.         foreach ($data as $key => $value) {
  161.             if ($value instanceof self) {
  162.                 $array[$key] = $value->toArray();
  163.             } else {
  164.                 $array[$key] = $value;
  165.             }
  166.         }
  167.         return $array;
  168.     }
  169.     /**
  170.      * isset() overloading
  171.      *
  172.      * @param  string $name
  173.      *
  174.      * @return bool
  175.      */
  176.     public function __isset($name)
  177.     {
  178.         return isset($this->data[$name]);
  179.     }
  180.     /**
  181.      * unset() overloading
  182.      *
  183.      * @param  string $name
  184.      *
  185.      * @return void
  186.      *
  187.      * @throws Exception
  188.      */
  189.     public function __unset($name)
  190.     {
  191.         if (! $this->allowModifications) {
  192.             throw new Exception('Config is read only');
  193.         } elseif (isset($this->data[$name])) {
  194.             unset($this->data[$name]);
  195.             $this->skipNextIteration true;
  196.         }
  197.     }
  198.     /**
  199.      * {@inheritdoc}
  200.      */
  201.     public function count()
  202.     {
  203.         return count($this->data);
  204.     }
  205.     /**
  206.      * {@inheritdoc}
  207.      */
  208.     public function current()
  209.     {
  210.         $this->skipNextIteration false;
  211.         return current($this->data);
  212.     }
  213.     /**
  214.      * {@inheritdoc}
  215.      */
  216.     public function key()
  217.     {
  218.         return key($this->data);
  219.     }
  220.     /**
  221.      * {@inheritdoc}
  222.      */
  223.     public function next()
  224.     {
  225.         if ($this->skipNextIteration) {
  226.             $this->skipNextIteration false;
  227.             return;
  228.         }
  229.         next($this->data);
  230.     }
  231.     /**
  232.      * {@inheritdoc}
  233.      */
  234.     public function rewind()
  235.     {
  236.         $this->skipNextIteration false;
  237.         reset($this->data);
  238.     }
  239.     /**
  240.      * {@inheritdoc}
  241.      */
  242.     public function valid()
  243.     {
  244.         return $this->key() !== null;
  245.     }
  246.     /**
  247.      * {@inheritdoc}
  248.      */
  249.     public function offsetExists($offset)
  250.     {
  251.         return $this->__isset($offset);
  252.     }
  253.     /**
  254.      * {@inheritdoc}
  255.      */
  256.     public function offsetGet($offset)
  257.     {
  258.         return $this->__get($offset);
  259.     }
  260.     /**
  261.      * {@inheritdoc}
  262.      */
  263.     public function offsetSet($offset$value)
  264.     {
  265.         $this->__set($offset$value);
  266.     }
  267.     /**
  268.      * {@inheritdoc}
  269.      */
  270.     public function offsetUnset($offset)
  271.     {
  272.         $this->__unset($offset);
  273.     }
  274.     /**
  275.      * @internal
  276.      *
  277.      * Merge another Config with this one.
  278.      *
  279.      * For duplicate keys, the following will be performed:
  280.      * - Nested Configs will be recursively merged.
  281.      * - Items in $merge with INTEGER keys will be appended.
  282.      * - Items in $merge with STRING keys will overwrite current values.
  283.      *
  284.      * @param  Config $merge
  285.      *
  286.      * @return self
  287.      */
  288.     public function merge(Config $merge)
  289.     {
  290.         foreach ($merge as $key => $value) {
  291.             if (array_key_exists($key$this->data)) {
  292.                 if (is_int($key)) {
  293.                     $this->data[] = $value;
  294.                 } elseif ($value instanceof self && $this->data[$key] instanceof self) {
  295.                     $this->data[$key]->merge($value);
  296.                 } else {
  297.                     if ($value instanceof self) {
  298.                         $this->data[$key] = new static($value->toArray(), $this->allowModifications);
  299.                     } else {
  300.                         $this->data[$key] = $value;
  301.                     }
  302.                 }
  303.             } else {
  304.                 if ($value instanceof self) {
  305.                     $this->data[$key] = new static($value->toArray(), $this->allowModifications);
  306.                 } else {
  307.                     $this->data[$key] = $value;
  308.                 }
  309.             }
  310.         }
  311.         return $this;
  312.     }
  313.     /**
  314.      * @internal
  315.      *
  316.      * Prevent any more modifications being made to this instance.
  317.      *
  318.      * Useful after merge() has been used to merge multiple Config objects
  319.      * into one object which should then not be modified again.
  320.      *
  321.      * @return void
  322.      */
  323.     public function setReadOnly()
  324.     {
  325.         $this->allowModifications false;
  326.         /** @var Config $value */
  327.         foreach ($this->data as $value) {
  328.             if ($value instanceof self) {
  329.                 $value->setReadOnly();
  330.             }
  331.         }
  332.     }
  333.     /**
  334.      * @internal
  335.      *
  336.      * Returns whether this Config object is read only or not.
  337.      *
  338.      * @return bool
  339.      */
  340.     public function isReadOnly()
  341.     {
  342.         return ! $this->allowModifications;
  343.     }
  344.     /**
  345.      * {@inheritdoc}
  346.      */
  347.     public function __toString()
  348.     {
  349.         if (empty($this->data)) {
  350.             return '';
  351.         }
  352.         return is_string($this->data) ? (string)$this->data json_encode($this->dataJSON_PRETTY_PRINT);
  353.     }
  354. }