vendor/jackalope/jackalope/src/Jackalope/Query/Row.php line 230

Open in your IDE?
  1. <?php
  2. namespace Jackalope\Query;
  3. use Iterator;
  4. use PHPCR\Query\RowInterface;
  5. use PHPCR\RepositoryException;
  6. use PHPCR\ItemNotFoundException;
  7. use Jackalope\FactoryInterface;
  8. use Jackalope\ObjectManager;
  9. /**
  10.  * {@inheritDoc}
  11.  *
  12.  * Jackalope: Contrary to most other Jackalope classes, the Row implements
  13.  * Iterator and not IteratorAggregate to avoid overhead when iterating over a
  14.  * row.
  15.  *
  16.  * @license http://www.apache.org/licenses Apache License Version 2.0, January 2004
  17.  * @license http://opensource.org/licenses/MIT MIT License
  18.  *
  19.  * @api
  20.  */
  21. class Row implements IteratorRowInterface
  22. {
  23.     /**
  24.      * @var ObjectManager
  25.      */
  26.     protected $objectManager;
  27.     /**
  28.      * @var FactoryInterface
  29.      */
  30.     protected $factory;
  31.     /**
  32.      * Columns of this result row: array of array with fields dcr:name and
  33.      * dcr:value
  34.      *
  35.      * @var array
  36.      */
  37.     protected $columns = [];
  38.     /**
  39.      * Which column we are on when iterating over the columns
  40.      * @var integer
  41.      */
  42.     protected $position 0;
  43.     /**
  44.      * The score this row has for each selector
  45.      *
  46.      * @var array of float
  47.      */
  48.     protected $score = [];
  49.     /**
  50.      * The path to the node for each selector
  51.      *
  52.      * @var array of string
  53.      */
  54.     protected $path = [];
  55.     /**
  56.      * Cached list of values extracted from columns to avoid double work.
  57.      *
  58.      * @var array
  59.      *
  60.      * @see Row::getValues()
  61.      */
  62.     protected $values = [];
  63.     /**
  64.      * The default selector name
  65.      * @var string
  66.      */
  67.     protected $defaultSelectorName;
  68.     /**
  69.      * Create new Row instance.
  70.      *
  71.      * @param FactoryInterface $factory       the object factory
  72.      * @param ObjectManager    $objectManager
  73.      * @param array            $columns       array of array with fields dcr:name and dcr:value
  74.      */
  75.     public function __construct(FactoryInterface $factoryObjectManager $objectManager$columns)
  76.     {
  77.         $this->factory $factory;
  78.         $this->objectManager $objectManager;
  79.         // TODO all of the normalization logic should better be moved to the Jackrabbit transport layer
  80.         foreach ($columns as $column) {
  81.             $pos strpos($column['dcr:name'], '.');
  82.             if (false !== $pos) {
  83.                 // jackalope-doctrine-dbal has the selector name both in the dcr:name and as separate column dcr:selectorName
  84.                 $selectorName substr($column['dcr:name'], 0$pos);
  85.                 $column['dcr:name'] = substr($column['dcr:name'], $pos 1);
  86.             } elseif (isset($column['dcr:selectorName'])) {
  87.                 $selectorName $column['dcr:selectorName'];
  88.             } else {
  89.                 $selectorName '';
  90.             }
  91.             if ('jcr:score' === $column['dcr:name']) {
  92.                 $this->score[$selectorName] = (float) $column['dcr:value'];
  93.             } elseif ('jcr:path' === $column['dcr:name']) {
  94.                 $this->path[$selectorName] = $column['dcr:value'];
  95.             } else {
  96.                 $this->columns[] = $column;
  97.                 $this->values[$selectorName][$column['dcr:name']] = $column['dcr:value'];
  98.             }
  99.         }
  100.         $this->defaultSelectorName key($this->path);
  101.         if (isset($this->values[''])) {
  102.             foreach ($this->values[''] as $key => $value) {
  103.                 $this->values[$this->defaultSelectorName][$key] = $value;
  104.             }
  105.             unset($this->values['']);
  106.         }
  107.     }
  108.     /**
  109.      * {@inheritDoc}
  110.      *
  111.      * @api
  112.      */
  113.     public function getValues()
  114.     {
  115.         $values = [];
  116.         foreach ($this->values as $selectorName => $columns) {
  117.             foreach ($columns as $key => $value) {
  118.                 $values[$selectorName.'.'.$key] = $value;
  119.             }
  120.         }
  121.         return $values;
  122.     }
  123.     /**
  124.      * {@inheritDoc}
  125.      *
  126.      * @api
  127.      */
  128.     public function getValue($columnName)
  129.     {
  130.         if (false === strpos($columnName'.')) {
  131.             $columnName $this->defaultSelectorName.'.'.$columnName;
  132.         }
  133.         $values $this->getValues();
  134.         if (!array_key_exists($columnName$values)) {
  135.             throw new ItemNotFoundException("Column '$columnName' not found");
  136.         }
  137.         $value $values[$columnName];
  138.         // According to JSR-283 6.7.39 a query should only return
  139.         // single-valued properties. We join the values when it's a string
  140.         // for multi-values boolean/binary values we can't provide a
  141.         // defined result so we return null
  142.         if (is_array($value)) {
  143.             if (count($value) && is_scalar($value[0]) && !is_bool($value[0])) {
  144.                 $value implode(' '$value);
  145.             } else {
  146.                 $value null;
  147.             }
  148.         }
  149.         return $value;
  150.     }
  151.     /**
  152.      * {@inheritDoc}
  153.      *
  154.      * @api
  155.      */
  156.     public function getNode($selectorName null)
  157.     {
  158.         $path $this->getPath($selectorName);
  159.         if (!$path) {
  160.             // handle outer joins
  161.             return null;
  162.         }
  163.         return $this->objectManager->getNodeByPath($this->getPath($selectorName));
  164.     }
  165.     /**
  166.      * {@inheritDoc}
  167.      *
  168.      * @api
  169.      */
  170.     public function getPath($selectorName null)
  171.     {
  172.         if (null === $selectorName) {
  173.             $selectorName $this->defaultSelectorName;
  174.         }
  175.         // do not use isset, the path might be null on outer joins
  176.         if (!array_key_exists($selectorName$this->path)) {
  177.             throw new RepositoryException('Attempting to get the path for a non existent selector: '.$selectorName);
  178.         }
  179.         return $this->path[$selectorName];
  180.     }
  181.     /**
  182.      * {@inheritDoc}
  183.      *
  184.      * @api
  185.      */
  186.     public function getScore($selectorName null)
  187.     {
  188.         if (null === $selectorName) {
  189.             $selectorName $this->defaultSelectorName;
  190.         }
  191.         if (!array_key_exists($selectorName$this->score)) {
  192.             throw new RepositoryException('Attempting to get the score for a non existent selector: '.$selectorName);
  193.         }
  194.         return $this->score[$selectorName];
  195.     }
  196.     /**
  197.      * Implement Iterator
  198.      */
  199.     public function rewind()
  200.     {
  201.         $this->position 0;
  202.     }
  203.     /**
  204.      * Implement Iterator
  205.      */
  206.     public function current()
  207.     {
  208.         return $this->columns[$this->position]['dcr:value'];
  209.     }
  210.     /**
  211.      * Implement Iterator
  212.      */
  213.     public function key()
  214.     {
  215.         return $this->columns[$this->position]['dcr:name'];
  216.     }
  217.     /**
  218.      * Implement Iterator
  219.      */
  220.     public function next()
  221.     {
  222.         ++$this->position;
  223.     }
  224.     /**
  225.      * Implement Iterator
  226.      *
  227.      * @return boolean whether the current position is valid
  228.      */
  229.     public function valid()
  230.     {
  231.         return isset($this->columns[$this->position]);
  232.     }
  233. }