Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2780ae2

Browse files
committed
initial commit
0 parents  commit 2780ae2

File tree

9 files changed

+378
-0
lines changed

9 files changed

+378
-0
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.idea
2+
vendor
3+
composer.lock
4+
*.swp
5+
.DS_Store

.travis.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
language: php
2+
3+
php:
4+
- 7
5+
- 5.6
6+
- 5.5
7+
- 5.4
8+
- hhvm
9+
10+
install:
11+
- composer install --prefer-source
12+
13+
script:
14+
- vendor/bin/peridot specs/

LICENSE

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2014 - 2015 Brian Scaturro
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is furnished
8+
to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.

README.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# ObjectPath
2+
3+
Allows traversal of objects and arrays with a simple string syntax. Extracted from
4+
Peridot's matcher library: [Leo](https://github.com/peridot-php/leo).
5+
6+
## Usage
7+
8+
```php
9+
$data = [
10+
'name' => 'Brian',
11+
'hobbies' => [
12+
'reading',
13+
'programming',
14+
'lion taming'
15+
],
16+
'address' => [
17+
'street' => '1234 Lane',
18+
'zip' => '12345'
19+
]
20+
];
21+
22+
use Peridot\ObjectPath\ObjectPath;
23+
24+
$path = new ObjectPath($data);
25+
$reading = $path->get('hobbies[0]');
26+
$zip = $path->get('address[zip]');
27+
28+
// the result of get() is an ObjectPathValue instance
29+
$value = $reading->getPropertyValue();
30+
31+
// The syntax also works for objects and nested structures
32+
33+
$data = new stdClass();
34+
35+
$data->name = 'Brian';
36+
$data->address = new stdClass();
37+
$data->address->zip = '12345';
38+
39+
$hobby = new stdClass();
40+
$hobby->name = 'reading';
41+
$hobby->style = 'relaxing';
42+
$data->hobbies = [$hobby];
43+
44+
$path = new ObjectPath($data);
45+
$name = $path->get('name');
46+
$zip = $path->get('address->zip');
47+
$reading = $path->get('hobbies[0]->name');
48+
```
49+
50+
## Tests
51+
52+
```
53+
$ composer install
54+
$ vendor/bin/peridot specs/
55+
```

composer.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "peridot-php/object-path",
3+
"description": "A string syntax to fetch values from array and object hierarchies",
4+
"keywords": ["object", "array", "traversal"],
5+
"license": "MIT",
6+
"authors": [
7+
{
8+
"name": "Brian Scaturro",
9+
"email": "[email protected]"
10+
}
11+
],
12+
"require": {
13+
"php":">=5.4.0"
14+
},
15+
"autoload": {
16+
"psr-4": {
17+
"Peridot\\ObjectPath\\": "src/"
18+
}
19+
},
20+
"require-dev": {
21+
"peridot-php/peridot-jumpstart": "~1.0"
22+
}
23+
}

peridot.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
use Evenement\EventEmitterInterface;
3+
use Peridot\Plugin\Watcher\WatcherPlugin;
4+
use Peridot\Reporter\Dot\DotReporterPlugin;
5+
use Peridot\Reporter\ListReporter\ListReporterPlugin;
6+
7+
return function(EventEmitterInterface $emitter) {
8+
$watcher = new WatcherPlugin($emitter);
9+
$watcher->track(__DIR__ . '/src');
10+
11+
$dot = new DotReporterPlugin($emitter);
12+
$list = new ListReporterPlugin($emitter);
13+
14+
$debug = getenv('DEBUG');
15+
16+
if ($debug) {
17+
$emitter->on('error', function ($number, $message, $file, $line) {
18+
print "Error: $number - $message:$file:$line\n";
19+
});
20+
}
21+
};

specs/object-path.spec.php

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
use Peridot\ObjectPath\ObjectPath;
3+
4+
describe('ObjectPath', function() {
5+
6+
context('when using an object', function() {
7+
beforeEach(function() {
8+
$object = new stdClass();
9+
$object->name = new stdClass();
10+
$object->name->first = "brian";
11+
$object->name->last = "scaturro";
12+
$object->projects = [
13+
'php' => ['peridot', 'leo'],
14+
'coffeescript' => ['alerts', 'pressbox'],
15+
];
16+
$this->object = $object;
17+
18+
$this->path = new ObjectPath($this->object);
19+
});
20+
21+
describe('->get()', function() {
22+
it('should be able to get a nested value', function() {
23+
$first = $this->path->get('name->first');
24+
expect($first->getPropertyValue())->to->equal('brian');
25+
});
26+
27+
it('should return last value if it is an object', function() {
28+
$this->object->name->origin = new stdClass();
29+
$this->object->name->origin->country = "Ireland";
30+
$origin = $this->path->get('name->origin');
31+
expect($origin->getPropertyValue())->to->equal($this->object->name->origin);
32+
});
33+
34+
it('should return array properties', function() {
35+
$peridot = $this->path->get('projects[php][0]');
36+
expect($peridot->getPropertyValue())->to->equal('peridot');
37+
});
38+
39+
it('should return null if property does not exist', function() {
40+
expect($this->path->get('nickname'))->to->be->null;
41+
});
42+
});
43+
});
44+
45+
context('when using an array', function() {
46+
beforeEach(function() {
47+
$this->array = [
48+
'name' => [
49+
'first' => 'brian',
50+
'last' => 'scaturro'
51+
],
52+
'string',
53+
1
54+
];
55+
$this->path = new ObjectPath($this->array);
56+
});
57+
58+
it('should be able to get an array value', function() {
59+
$one = $this->path->get('[1]');
60+
expect($one->getPropertyValue())->to->equal(1);
61+
});
62+
63+
it('should be able to get nested values', function() {
64+
$name = $this->path->get('[name][first]');
65+
expect($name->getPropertyValue())->to->equal('brian');
66+
expect($name->getPropertyName())->to->equal('first');
67+
});
68+
});
69+
70+
});

src/ObjectPath.php

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
<?php
2+
3+
namespace Peridot\ObjectPath;
4+
5+
/**
6+
* ObjectPath is a utility for parsing object and array strings into
7+
* ObjectPathValues.
8+
*
9+
* @package Peridot\ObjectPath
10+
*/
11+
class ObjectPath
12+
{
13+
/**
14+
* The subject to match path expressions against.
15+
*
16+
* @var array|object
17+
*/
18+
protected $subject;
19+
20+
/**
21+
* A pattern for matching array keys
22+
*
23+
* @var string
24+
*/
25+
private static $arrayKey = '/\[([^\]]+)\]/';
26+
27+
/**
28+
* @param array|object $subject
29+
*/
30+
public function __construct($subject)
31+
{
32+
$this->subject = $subject;
33+
}
34+
35+
/**
36+
* Returns an ObjectPathValue if the property described by $path
37+
* can be located in the subject.
38+
*
39+
* A path expression uses object and array syntax.
40+
*
41+
* @code
42+
*
43+
* $person = new stdClass();
44+
* $person->name = new stdClass();
45+
* $person->name->first = 'brian';
46+
* $person->name->last = 'scaturro';
47+
* $person->hobbies = ['programming', 'reading', 'board games'];
48+
*
49+
* $path = new ObjectPath($person);
50+
* $first = $path->get('name->first');
51+
* $reading = $path->get('hobbies[0]');
52+
*
53+
* @endcode
54+
*
55+
* @param string $path
56+
* @return ObjectPathValue
57+
*/
58+
public function get($path)
59+
{
60+
$parts = $this->getPathParts($path);
61+
$properties = $this->getPropertyCollection($this->subject);
62+
$pathValue = null;
63+
while ($properties && $parts) {
64+
$key = array_shift($parts);
65+
$key = $this->normalizeKey($key);
66+
$pathValue = array_key_exists($key, $properties) ? new ObjectPathValue($key, $properties[$key]) : null;
67+
68+
if (! array_key_exists($key, $properties)) {
69+
break;
70+
}
71+
72+
$properties = $this->getPropertyCollection($properties[$key]);
73+
}
74+
return $pathValue;
75+
}
76+
77+
/**
78+
* Breaks a path expression into an array used
79+
* for navigating a path.
80+
*
81+
* @param $path
82+
* @return array
83+
*/
84+
public function getPathParts($path)
85+
{
86+
$path = preg_replace('/\[/', '->[', $path);
87+
if (preg_match('/^->/', $path)) {
88+
$path = substr($path, 2);
89+
}
90+
91+
return explode('->', $path);
92+
}
93+
94+
/**
95+
* Returns a property as an array.
96+
*
97+
* @param $subject
98+
* @return array
99+
*/
100+
protected function getPropertyCollection($subject)
101+
{
102+
if (is_object($subject)) {
103+
return get_object_vars($subject);
104+
}
105+
106+
return $subject;
107+
}
108+
109+
/**
110+
* Return a key that can be used on the current subject.
111+
*
112+
* @param $key
113+
* @param $matches
114+
* @return mixed
115+
*/
116+
protected function normalizeKey($key)
117+
{
118+
if (preg_match(static::$arrayKey, $key, $matches)) {
119+
$key = $matches[1];
120+
return $key;
121+
}
122+
return $key;
123+
}
124+
}

src/ObjectPathValue.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace Peridot\ObjectPath;
4+
5+
/**
6+
* An ObjectPathValue is the result of parsing a path expression via ObjectPath.
7+
*
8+
* @package Peridot\ObjectPath
9+
*/
10+
class ObjectPathValue
11+
{
12+
/**
13+
* @var string
14+
*/
15+
protected $propertyName;
16+
17+
/**
18+
* @var mixed
19+
*/
20+
protected $propertyValue;
21+
22+
/**
23+
* @param $name
24+
* @param $value
25+
*/
26+
public function __construct($name, $value)
27+
{
28+
$this->propertyName = $name;
29+
$this->propertyValue = $value;
30+
}
31+
32+
/**
33+
* @return string
34+
*/
35+
public function getPropertyName()
36+
{
37+
return $this->propertyName;
38+
}
39+
40+
/**
41+
* @return mixed
42+
*/
43+
public function getPropertyValue()
44+
{
45+
return $this->propertyValue;
46+
}
47+
}

0 commit comments

Comments
 (0)