Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
90.91% |
10 / 11 |
CRAP | |
85.00% |
34 / 40 |
Path | |
0.00% |
0 / 1 |
|
90.91% |
10 / 11 |
21.35 | |
85.00% |
34 / 40 |
parse | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
|||
__construct | |
0.00% |
0 / 1 |
6.60 | |
45.45% |
5 / 11 |
|||
__toString | |
100.00% |
1 / 1 |
2 | |
100.00% |
2 / 2 |
|||
__clone | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
count | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
get | |
100.00% |
1 / 1 |
5 | |
100.00% |
11 / 11 |
|||
push | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
getSteps | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
setSteps | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
getArrayExpectation | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
setArrayExpectation | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
<?php | |
/** | |
* Copyright (c) Tony Bogdanov <tonybogdanov@gmail.com> | |
* | |
* For the full copyright and license information, please view the LICENSE | |
* file that was distributed with this source code. | |
*/ | |
namespace DataTraveller\Path; | |
use DataExpectation\ArrayExpectation; | |
use DataExpectation\Exceptions\UnexpectedDataException; | |
use DataTraveller\Exceptions\MissingDataException; | |
use DataTraveller\Path\Exceptions\InvalidPathException; | |
use DataTraveller\Path\Step\LiteralStep; | |
use DataTraveller\Path\Step\StepInterface; | |
use Nette\Tokenizer\Exception; | |
use SebastianBergmann\Timer\RuntimeException; | |
/** | |
* Class Path | |
* | |
* @package DataTraveller\Path | |
* @author TonyBogdanov <tonybogdanov@gmail.com> | |
*/ | |
class Path implements \Countable { | |
/** | |
* @var StepInterface[] | |
*/ | |
protected $steps; | |
/** | |
* @var ArrayExpectation | |
*/ | |
protected $arrayExpectation; | |
/** | |
* @param string $value | |
* @param bool $disableRegex | |
* | |
* @return Path | |
* @throws InvalidPathException | |
*/ | |
public static function parse( string $value, bool $disableRegex = false ): Path { | |
try { | |
return new static( ( new Parser( $disableRegex ) )->parse( $value ) ); | |
} catch ( Exception $e ) { | |
throw new InvalidPathException( sprintf( 'Invalid path: %s', $value ), 0, $e ); | |
} | |
} | |
/** | |
* Path constructor. | |
* | |
* @param StepInterface[] $steps | |
*/ | |
public function __construct( array $steps = [] ) { | |
$this->steps = array_map( function ( $step ): StepInterface { | |
if ( $step instanceof StepInterface ) { | |
return $step; | |
} | |
if ( is_string( $step ) ) { | |
return new LiteralStep( $step ); | |
} | |
throw new RuntimeException( sprintf( | |
'Invalid path step, expected a string or an instance of %1$s, got %2$s instead.', | |
StepInterface::class, | |
is_object( $step ) ? get_class( $step ) : gettype( $step ) | |
) ); | |
}, $steps ); | |
$this->arrayExpectation = new ArrayExpectation(); | |
} | |
/** | |
* @return string | |
*/ | |
public function __toString(): string { | |
return implode( '.', array_map( function ( StepInterface $step ) { | |
return $step instanceof LiteralStep ? str_replace( '.', '\\.', $step ) : $step; | |
}, $this->steps ) ); | |
} | |
public function __clone() { | |
$this->steps = array_map( function ( StepInterface $step ) { | |
return clone $step; | |
}, $this->steps ); | |
$this->arrayExpectation = clone $this->arrayExpectation; | |
} | |
/** | |
* @return int | |
*/ | |
public function count(): int { | |
return count( $this->steps ); | |
} | |
/** | |
* @param $data | |
* @param Path|null $trail | |
* | |
* @return mixed | |
* @throws MissingDataException | |
* @throws UnexpectedDataException | |
*/ | |
public function get( $data, Path $trail = null ) { | |
if ( 0 === count( $this->steps ) ) { | |
return $data; | |
} | |
if ( ! isset( $trail ) ) { | |
$trail = new static(); | |
} | |
$this->arrayExpectation->expect( $data, $trail ); | |
$step = $this->steps[0]; | |
$trail->push( $step ); | |
foreach ( $data as $key => $value ) { | |
if ( $step->expect( $key ) ) { | |
return ( new Path( array_slice( $this->steps, 1 ) ) )->get( $value, $trail ); | |
} | |
} | |
throw new MissingDataException( $trail ); | |
} | |
/** | |
* @param StepInterface $step | |
* | |
* @return Path | |
*/ | |
public function push( StepInterface $step ): Path { | |
$this->steps[] = $step; | |
return $this; | |
} | |
/** | |
* @return StepInterface[] | |
*/ | |
public function getSteps(): array { | |
return $this->steps; | |
} | |
/** | |
* @param StepInterface[] $steps | |
* | |
* @return $this | |
*/ | |
public function setSteps( array $steps ) { | |
$this->steps = $steps; | |
return $this; | |
} | |
/** | |
* @return ArrayExpectation | |
*/ | |
public function getArrayExpectation(): ArrayExpectation { | |
return $this->arrayExpectation; | |
} | |
/** | |
* @param ArrayExpectation $arrayExpectation | |
* | |
* @return $this | |
*/ | |
public function setArrayExpectation( ArrayExpectation $arrayExpectation ) { | |
$this->arrayExpectation = $arrayExpectation; | |
return $this; | |
} | |
} |