"Fossies" - the Fresh Open Source Software Archive

Member "grav/system/src/Grav/Framework/Collection/AbstractIndexCollection.php" (19 Mar 2020, 10225 Bytes) of package /linux/www/grav-v1.6.23.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "AbstractIndexCollection.php" see the Fossies "Dox" file reference documentation.

    1 <?php
    2 
    3 /**
    4  * @package    Grav\Framework\Collection
    5  *
    6  * @copyright  Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
    7  * @license    MIT License; see LICENSE file for details.
    8  */
    9 
   10 namespace Grav\Framework\Collection;
   11 
   12 use ArrayIterator;
   13 use Closure;
   14 
   15 /**
   16  * Abstract Index Collection.
   17  */
   18 abstract class AbstractIndexCollection implements CollectionInterface
   19 {
   20     /** @var array */
   21     private $entries;
   22 
   23     /**
   24      * Initializes a new IndexCollection.
   25      *
   26      * @param array $entries
   27      */
   28     public function __construct(array $entries = [])
   29     {
   30         $this->entries = $entries;
   31     }
   32 
   33     /**
   34      * {@inheritDoc}
   35      */
   36     public function toArray()
   37     {
   38         return $this->loadElements($this->entries);
   39     }
   40 
   41     /**
   42      * {@inheritDoc}
   43      */
   44     public function first()
   45     {
   46         $value = reset($this->entries);
   47         $key = key($this->entries);
   48 
   49         return $this->loadElement($key, $value);
   50     }
   51 
   52     /**
   53      * {@inheritDoc}
   54      */
   55     public function last()
   56     {
   57         $value = end($this->entries);
   58         $key = key($this->entries);
   59 
   60         return $this->loadElement($key, $value);
   61     }
   62 
   63     /**
   64      * {@inheritDoc}
   65      */
   66     public function key()
   67     {
   68         return key($this->entries);
   69     }
   70 
   71     /**
   72      * {@inheritDoc}
   73      */
   74     public function next()
   75     {
   76         $value = next($this->entries);
   77         $key = key($this->entries);
   78 
   79         return $this->loadElement($key, $value);
   80     }
   81 
   82     /**
   83      * {@inheritDoc}
   84      */
   85     public function current()
   86     {
   87         $value = current($this->entries);
   88         $key = key($this->entries);
   89 
   90         return $this->loadElement($key, $value);
   91     }
   92 
   93     /**
   94      * {@inheritDoc}
   95      */
   96     public function remove($key)
   97     {
   98         if (!array_key_exists($key, $this->entries)) {
   99             return null;
  100         }
  101 
  102         $value = $this->entries[$key];
  103         unset($this->entries[$key]);
  104 
  105         return $this->loadElement($key, $value);
  106     }
  107 
  108     /**
  109      * {@inheritDoc}
  110      */
  111     public function removeElement($element)
  112     {
  113         $key = $this->isAllowedElement($element) ? $element->getKey() : null;
  114 
  115         if (!$key || !isset($this->entries[$key])) {
  116             return false;
  117         }
  118 
  119         unset($this->entries[$key]);
  120 
  121         return true;
  122     }
  123 
  124     /**
  125      * Required by interface ArrayAccess.
  126      *
  127      * {@inheritDoc}
  128      */
  129     public function offsetExists($offset)
  130     {
  131         return $this->containsKey($offset);
  132     }
  133 
  134     /**
  135      * Required by interface ArrayAccess.
  136      *
  137      * {@inheritDoc}
  138      */
  139     public function offsetGet($offset)
  140     {
  141         return $this->get($offset);
  142     }
  143 
  144     /**
  145      * Required by interface ArrayAccess.
  146      *
  147      * {@inheritDoc}
  148      */
  149     public function offsetSet($offset, $value)
  150     {
  151         if (null === $offset) {
  152             $this->add($value);
  153         }
  154 
  155         $this->set($offset, $value);
  156     }
  157 
  158     /**
  159      * Required by interface ArrayAccess.
  160      *
  161      * {@inheritDoc}
  162      */
  163     public function offsetUnset($offset)
  164     {
  165         return $this->remove($offset);
  166     }
  167 
  168     /**
  169      * {@inheritDoc}
  170      */
  171     public function containsKey($key)
  172     {
  173         return isset($this->entries[$key]) || array_key_exists($key, $this->entries);
  174     }
  175 
  176     /**
  177      * {@inheritDoc}
  178      */
  179     public function contains($element)
  180     {
  181         $key = $this->isAllowedElement($element) ? $element->getKey() : null;
  182 
  183         return $key && isset($this->entries[$key]);
  184     }
  185 
  186     /**
  187      * {@inheritDoc}
  188      */
  189     public function exists(Closure $p)
  190     {
  191         return $this->loadCollection($this->entries)->exists($p);
  192     }
  193 
  194     /**
  195      * {@inheritDoc}
  196      */
  197     public function indexOf($element)
  198     {
  199         $key = $this->isAllowedElement($element) ? $element->getKey() : null;
  200 
  201         return $key && isset($this->entries[$key]) ? $key : null;
  202     }
  203 
  204     /**
  205      * {@inheritDoc}
  206      */
  207     public function get($key)
  208     {
  209         if (!isset($this->entries[$key])) {
  210             return null;
  211         }
  212 
  213         return $this->loadElement($key, $this->entries[$key]);
  214     }
  215 
  216     /**
  217      * {@inheritDoc}
  218      */
  219     public function getKeys()
  220     {
  221         return array_keys($this->entries);
  222     }
  223 
  224     /**
  225      * {@inheritDoc}
  226      */
  227     public function getValues()
  228     {
  229         return array_values($this->loadElements($this->entries));
  230     }
  231 
  232     /**
  233      * {@inheritDoc}
  234      */
  235     public function count()
  236     {
  237         return \count($this->entries);
  238     }
  239 
  240     /**
  241      * {@inheritDoc}
  242      */
  243     public function set($key, $value)
  244     {
  245         if (!$this->isAllowedElement($value)) {
  246             throw new \InvalidArgumentException('Invalid argument $value');
  247         }
  248 
  249         if ($key !== $value->getKey()) {
  250             $value->setKey($key);
  251         }
  252 
  253         $this->entries[$key] = $this->getElementMeta($value);
  254     }
  255 
  256     /**
  257      * {@inheritDoc}
  258      */
  259     public function add($element)
  260     {
  261         if (!$this->isAllowedElement($element)) {
  262             throw new \InvalidArgumentException('Invalid argument $element');
  263         }
  264 
  265         $this->entries[$element->getKey()] = $this->getElementMeta($element);
  266 
  267         return true;
  268     }
  269 
  270     /**
  271      * {@inheritDoc}
  272      */
  273     public function isEmpty()
  274     {
  275         return empty($this->entries);
  276     }
  277 
  278     /**
  279      * Required by interface IteratorAggregate.
  280      *
  281      * {@inheritDoc}
  282      */
  283     public function getIterator()
  284     {
  285         return new ArrayIterator($this->loadElements());
  286     }
  287 
  288     /**
  289      * {@inheritDoc}
  290      */
  291     public function map(Closure $func)
  292     {
  293         return $this->loadCollection($this->entries)->map($func);
  294     }
  295 
  296     /**
  297      * {@inheritDoc}
  298      */
  299     public function filter(Closure $p)
  300     {
  301         return $this->loadCollection($this->entries)->filter($p);
  302     }
  303 
  304     /**
  305      * {@inheritDoc}
  306      */
  307     public function forAll(Closure $p)
  308     {
  309         return $this->loadCollection($this->entries)->forAll($p);
  310     }
  311 
  312     /**
  313      * {@inheritDoc}
  314      */
  315     public function partition(Closure $p)
  316     {
  317         return $this->loadCollection($this->entries)->partition($p);
  318     }
  319 
  320     /**
  321      * Returns a string representation of this object.
  322      *
  323      * @return string
  324      */
  325     public function __toString()
  326     {
  327         return __CLASS__ . '@' . spl_object_hash($this);
  328     }
  329 
  330     /**
  331      * {@inheritDoc}
  332      */
  333     public function clear()
  334     {
  335         $this->entries = [];
  336     }
  337 
  338     /**
  339      * {@inheritDoc}
  340      */
  341     public function slice($offset, $length = null)
  342     {
  343         return $this->loadElements(\array_slice($this->entries, $offset, $length, true));
  344     }
  345 
  346     /**
  347      * @param int $start
  348      * @param int|null $limit
  349      * @return static
  350      */
  351     public function limit($start, $limit = null)
  352     {
  353         return $this->createFrom(\array_slice($this->entries, $start, $limit, true));
  354     }
  355 
  356     /**
  357      * Reverse the order of the items.
  358      *
  359      * @return static
  360      */
  361     public function reverse()
  362     {
  363         return $this->createFrom(array_reverse($this->entries));
  364     }
  365 
  366     /**
  367      * Shuffle items.
  368      *
  369      * @return static
  370      */
  371     public function shuffle()
  372     {
  373         $keys = $this->getKeys();
  374         shuffle($keys);
  375 
  376         return $this->createFrom(array_replace(array_flip($keys), $this->entries));
  377     }
  378 
  379     /**
  380      * Select items from collection.
  381      *
  382      * Collection is returned in the order of $keys given to the function.
  383      *
  384      * @param array $keys
  385      * @return static
  386      */
  387     public function select(array $keys)
  388     {
  389         $list = [];
  390         foreach ($keys as $key) {
  391             if (isset($this->entries[$key])) {
  392                 $list[$key] = $this->entries[$key];
  393             }
  394         }
  395 
  396         return $this->createFrom($list);
  397     }
  398 
  399     /**
  400      * Un-select items from collection.
  401      *
  402      * @param array $keys
  403      * @return static
  404      */
  405     public function unselect(array $keys)
  406     {
  407         return $this->select(array_diff($this->getKeys(), $keys));
  408     }
  409 
  410     /**
  411      * Split collection into chunks.
  412      *
  413      * @param int $size     Size of each chunk.
  414      * @return array
  415      */
  416     public function chunk($size)
  417     {
  418         return $this->loadCollection($this->entries)->chunk($size);
  419     }
  420 
  421     /**
  422      * @return string
  423      */
  424     public function serialize()
  425     {
  426         return serialize(['entries' => $this->entries]);
  427     }
  428 
  429     /**
  430      * @param string $serialized
  431      */
  432     public function unserialize($serialized)
  433     {
  434         $data = unserialize($serialized, ['allowed_classes' => false]);
  435 
  436         $this->entries = $data['entries'];
  437     }
  438 
  439     /**
  440      * Implements JsonSerializable interface.
  441      *
  442      * @return array
  443      */
  444     public function jsonSerialize()
  445     {
  446         return $this->loadCollection()->jsonSerialize();
  447     }
  448 
  449     /**
  450      * Creates a new instance from the specified elements.
  451      *
  452      * This method is provided for derived classes to specify how a new
  453      * instance should be created when constructor semantics have changed.
  454      *
  455      * @param array $entries Elements.
  456      *
  457      * @return static
  458      */
  459     protected function createFrom(array $entries)
  460     {
  461         return new static($entries);
  462     }
  463 
  464     /**
  465      * @return array
  466      */
  467     protected function getEntries() : array
  468     {
  469         return $this->entries;
  470     }
  471 
  472     /**
  473      * @param array $entries
  474      */
  475     protected function setEntries(array $entries) : void
  476     {
  477         $this->entries = $entries;
  478     }
  479 
  480     /**
  481      * @param string $key
  482      * @param mixed $value
  483      * @return mixed|null
  484      */
  485     abstract protected function loadElement($key, $value);
  486 
  487     /**
  488      * @param array|null $entries
  489      * @return array
  490      */
  491     abstract protected function loadElements(array $entries = null) : array;
  492 
  493     /**
  494      * @param array|null $entries
  495      * @return CollectionInterface
  496      */
  497     abstract protected function loadCollection(array $entries = null) : CollectionInterface;
  498 
  499     /**
  500      * @param mixed $value
  501      * @return bool
  502      */
  503     abstract protected function isAllowedElement($value) : bool;
  504 
  505     /**
  506      * @param mixed $element
  507      * @return mixed
  508      */
  509     abstract protected function getElementMeta($element);
  510 }