vendor/jackalope/jackalope/src/Jackalope/NodePathIterator.php line 80

Open in your IDE?
  1. <?php
  2. namespace Jackalope;
  3. use ArrayAccess;
  4. use Countable;
  5. use InvalidArgumentException;
  6. use SeekableIterator;
  7. /**
  8.  * @license http://www.apache.org/licenses Apache License Version 2.0, January 2004
  9.  * @license http://opensource.org/licenses/MIT MIT License
  10.  */
  11. class NodePathIterator implements SeekableIteratorArrayAccessCountable
  12. {
  13.     /**
  14.      * @var int
  15.      */
  16.     protected $position 0;
  17.     /**
  18.      * @var array
  19.      */
  20.     protected $nodes = [];
  21.     /**
  22.      * @var array
  23.      */
  24.     protected $paths;
  25.     protected $typeFilter;
  26.     protected $class;
  27.     /**
  28.      * @var int
  29.      */
  30.     protected $count 0;
  31.     protected $batchSize;
  32.     public function __construct(
  33.         ObjectManager $objectManager,
  34.         $paths,
  35.         $class Node::class,
  36.         $typeFilter = [],
  37.         $batchSize 50
  38.     ) {
  39.         $this->objectManager $objectManager;
  40.         $this->paths array_values((array) $paths); // ensure paths are indexed numerically
  41.         $this->batchSize $batchSize;
  42.         $this->typeFilter $typeFilter;
  43.         $this->class $class;
  44.         $this->loadBatch();
  45.     }
  46.     /**
  47.      * Return the batchSize
  48.      *
  49.      * @return integer
  50.      */
  51.     public function getBatchSize()
  52.     {
  53.         return $this->batchSize;
  54.     }
  55.     /**
  56.      * Return the type filter
  57.      *
  58.      * @return string
  59.      */
  60.     public function getTypeFilter()
  61.     {
  62.         return $this->typeFilter;
  63.     }
  64.     /**
  65.      * {@inheritDoc}
  66.      */
  67.     public function current()
  68.     {
  69.         return $this->nodes[$this->paths[$this->position]];
  70.     }
  71.     /**
  72.      * {@inheritDoc}
  73.      */
  74.     public function next()
  75.     {
  76.         $this->position++;
  77.     }
  78.     /**
  79.      * {@inheritDoc}
  80.      */
  81.     public function rewind()
  82.     {
  83.         $this->position 0;
  84.     }
  85.     /**
  86.      * {@inheritDoc}
  87.      */
  88.     public function valid()
  89.     {
  90.         if (!isset($this->paths[$this->position])) {
  91.             return false;
  92.         }
  93.         $path $this->paths[$this->position];
  94.         // skip any paths which have been filtered in userland
  95.         // and move on
  96.         if ($path === null) {
  97.             $this->position++;
  98.             return $this->valid();
  99.         }
  100.         if (!array_key_exists($path$this->nodes)) {
  101.             $this->loadBatch();
  102.         }
  103.         if (empty($this->nodes[$path])) {
  104.             $this->position++;
  105.             return $this->valid();
  106.         }
  107.         return true;
  108.     }
  109.     /**
  110.      * {@inheritDoc}
  111.      */
  112.     public function key()
  113.     {
  114.         return $this->paths[$this->position];
  115.     }
  116.     /**
  117.      * Load a batch of records according to the
  118.      * batch size.
  119.      *
  120.      * @param integer $position - Optional position to start from
  121.      */
  122.     protected function loadBatch($position null)
  123.     {
  124.         if (=== count($this->paths)) {
  125.             return;
  126.         }
  127.         $paths array_slice(
  128.             $this->paths,
  129.             $position $position $this->position,
  130.             $this->batchSize
  131.         );
  132.         $nodes $this->objectManager->getNodesByPathAsArray(
  133.             $paths,
  134.             $this->class,
  135.             $this->typeFilter
  136.         );
  137.         foreach ($paths as $path) {
  138.             if (isset($nodes[$path]) && $nodes[$path] !== '') {
  139.                 $this->nodes[$path] =  $nodes[$path];
  140.                 $this->count++;
  141.             } else {
  142.                 $this->nodes[$path] =  null;
  143.             }
  144.         }
  145.     }
  146.     /**
  147.      * Ensure that the given path is loaded from the database.
  148.      * We will iterate over the batches until we either get to
  149.      * the end or we find the node we are looking for.
  150.      *
  151.      * Subsequent calls will start loading from the first path
  152.      * which does not have a corresponding array key in the nodes array
  153.      * - if the node is indeed not already loaded.
  154.      *
  155.      * @param integer $offset
  156.      */
  157.     protected function ensurePathLoaded($offset)
  158.     {
  159.         if (count($this->paths) > 0) {
  160.             if (!array_key_exists($offset$this->nodes)) {
  161.                 // start loading batches from the position of the first
  162.                 // "missing" node
  163.                 $position null;
  164.                 foreach ($this->paths as $position => $path) {
  165.                     if (!array_key_exists($path$this->nodes)) {
  166.                         break;
  167.                     }
  168.                 }
  169.                 while (isset($this->paths[$position])) {
  170.                     // keep loading batches until we get to the end of the paths
  171.                     // or we find the one we want.
  172.                     $this->loadBatch($position);
  173.                     $position += $this->batchSize;
  174.                     if (array_key_exists($offset$this->nodes)) {
  175.                         break;
  176.                     }
  177.                 }
  178.             }
  179.         }
  180.         // if it wasn't found, it doesn't exist, set it to null
  181.         if (!array_key_exists($offset$this->nodes)) {
  182.             $this->nodes[$offset] = null;
  183.         }
  184.     }
  185.     /**
  186.      * {@inheritDoc}
  187.      */
  188.     public function offsetExists($offset)
  189.     {
  190.         $this->ensurePathLoaded($offset);
  191.         return $this->nodes[$offset] === null false true;
  192.     }
  193.     /**
  194.      * {@inheritDoc}
  195.      */
  196.     public function offsetGet($offset)
  197.     {
  198.         $this->ensurePathLoaded($offset);
  199.         return $this->nodes[$offset];
  200.     }
  201.     /**
  202.      * {@inheritDoc}
  203.      */
  204.     public function offsetSet($offset$value)
  205.     {
  206.         throw new InvalidArgumentException('Node path collection is read only');
  207.     }
  208.     /**
  209.      * {@inheritDoc}
  210.      */
  211.     public function offsetUnset($offset)
  212.     {
  213.         throw new InvalidArgumentException('Node path collection is read only');
  214.     }
  215.     /**
  216.      * {@inheritDoc}
  217.      */
  218.     public function seek($position)
  219.     {
  220.         $this->position $position;
  221.     }
  222.     /**
  223.      * {@inheritDoc}
  224.      */
  225.     public function count()
  226.     {
  227.         $this->ensurePathLoaded(count($this->paths));
  228.         return $this->count;
  229.     }
  230. }