Skip to content

Commit edf0bdb

Browse files
committed
- backport JsonArray, SchemaLockedArray, XArray::getKeys, XArray::toFlattenedArray to php72 without breaking API
- switch to github actions
1 parent c700f4a commit edf0bdb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+2085
-329
lines changed

.github/workflows/build.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: build
2+
3+
on:
4+
push:
5+
branches: [ php72 ]
6+
pull_request:
7+
branches: [ php72 ]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
php: [7.2, 7.3, 7.4]
15+
16+
steps:
17+
- uses: actions/checkout@v2
18+
19+
- name: Validate dependencies
20+
run: composer validate
21+
22+
- name: Get dependency cache directory
23+
id: composer-cache
24+
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
25+
26+
- name: Cache dependencies
27+
uses: actions/cache@v2
28+
with:
29+
path: ${{ steps.composer-cache.outputs.dir }}
30+
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.json') }}
31+
restore-keys: |
32+
${{ runner.os }}-php-
33+
34+
- name: Install dependencies
35+
run: composer install --prefer-dist --no-progress --no-suggest
36+
37+
- name: Run static analysis
38+
run: vendor/bin/phpstan analyse
39+
40+
- name: Run test suite
41+
run: vendor/bin/phpunit --configuration phpunit.xml.dist --coverage-clover=coverage.xml
42+
43+
- uses: codecov/codecov-action@v1

.travis.yml

Lines changed: 0 additions & 18 deletions
This file was deleted.

README.md

Lines changed: 103 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
A utility for traversing PHP arrays with an XPath-like syntax.
44

5-
[![travis-ci.org](https://travis-ci.org/modethirteen/XArray.php.svg?branch=master)](https://travis-ci.org/modethirteen/XArray.php)
6-
[![codecov.io](https://codecov.io/github/modethirteen/XArray.php/coverage.svg?branch=master)](https://codecov.io/github/modethirteen/XArray.php?branch=master)
5+
[![github.com](https://github.com/modethirteen/XArray/workflows/build/badge.svg)](https://github.com/modethirteen/XArray/actions?query=workflow%3Abuild)
6+
[![codecov.io](https://codecov.io/github/modethirteen/XArray/coverage.svg?branch=main)](https://codecov.io/github/modethirteen/XArray?branch=main)
77
[![Latest Stable Version](https://poser.pugx.org/modethirteen/xarray/version.svg)](https://packagist.org/packages/modethirteen/xarray)
88
[![Latest Unstable Version](https://poser.pugx.org/modethirteen/xarray/v/unstable)](https://packagist.org/packages/modethirteen/xarray)
99

1010
## Requirements
1111

12-
* PHP 5.4, 5.5, 5.6 (0.1.x)
13-
* PHP 7.2+ (master, 1.x)
12+
* PHP 7.2+ (php72, 1.x)
13+
* PHP 7.4+ (main, 2.x)
1414

1515
## Installation
1616

@@ -19,22 +19,22 @@ Use [Composer](https://getcomposer.org/). There are two ways to add XArray to yo
1919
From the composer CLI:
2020

2121
```sh
22-
$ ./composer.phar require modethirteen/xarray
22+
./composer.phar require modethirteen/xarray
2323
```
2424

2525
Or add modethirteen/xarray to your project's composer.json:
2626

2727
```json
2828
{
2929
"require": {
30-
"modethirteen/xarray": "dev-master"
30+
"modethirteen/xarray": "dev-main"
3131
}
3232
}
3333
```
3434

35-
"dev-master" is the master development branch. If you are using XArray in a production environment, it is advised that you use a stable release.
35+
`dev-main` is the main development branch. If you are using XArray in a production environment, it is advised that you use a stable release.
3636

37-
Assuming you have setup Composer's autoloader, XArray can be found in the modethirteen\XArray\ namespace.
37+
Assuming you have setup Composer's autoloader, XArray can be found in the `modethirteen\XArray\` namespace.
3838

3939
## Usage
4040

@@ -53,7 +53,13 @@ $result = $x1->getVal('foo/bar'); // 'baz'
5353
$result = $x1->getVal('qux'); // 'fred'
5454
$results = $x1->getAll('qux'); // ['fred', 'quxx']
5555

56-
// get the array
56+
// which key paths have been defined in the XArray?
57+
$keys = $x1->getKeys(); // ['foo', 'foo/bar', 'qux']
58+
59+
// reduce output to the key paths that have values
60+
$flattened = $x1->toFlattenedArray(); // ['foo/bar' => 'baz', 'qux' => ['fred', 'quxx']]
61+
62+
// get the array (the underlying array data structure)
5763
$array1 = $x1->toArray();
5864

5965
// create a new XArray from the existing array
@@ -130,3 +136,91 @@ $array2 = $x->toArray();
130136
// MutableXArray mutates the source array
131137
assert($array1 === $array2);
132138
```
139+
140+
### SchemaLockedArray.php (extends XArray.php)
141+
142+
```php
143+
// SchemaLockedArray will block the setting of any values if the key path is not allowlisted in a schema
144+
$x = new SchemaLockedArray(new SchemaBuilder());
145+
146+
// throws SchemaLockedArrayUndefinedKeyException
147+
$x->setVal('foo', 'bar');
148+
149+
// a schema can be built with a fluent API
150+
$schemaBuilder = (new SchemaBuilder())
151+
->with('foo')
152+
153+
// also allowlists bar
154+
->with('bar/baz')
155+
156+
// also allowlists plugh and plugh/xyzzy
157+
->with('plugh/xyzzy/fred');
158+
159+
// a schema can also be inferred from another XArray by analyzing the array's defined key paths
160+
$x = new XArray([
161+
'foo' => 'qux',
162+
'bar' => [
163+
'baz' => true
164+
],
165+
'plugh' => [
166+
'xyzzy' => [
167+
'fred' => [
168+
'sodium',
169+
'iodine'
170+
]
171+
]
172+
]
173+
]);
174+
$schemaBuilder = SchemaBuilder::newFromXArray($x);
175+
176+
// either way, the SchemaLockedArray will only ever have the key paths that are defined in the schema
177+
$x = new SchemaLockedArray($schemaBuilder);
178+
179+
// ...leading to a very predictable array tree structure when outputted
180+
$array = $x->toArray();
181+
```
182+
183+
### JsonArray.php (extends XArray.php)
184+
185+
```php
186+
// Like XArray, JsonArray can be built from a source array
187+
$array = [
188+
'foo' => [
189+
'bar',
190+
'baz'
191+
]
192+
];
193+
$x = new JsonArray($array);
194+
195+
// JsonArray can also be built from a JSON string
196+
$json = <<<JSON
197+
{
198+
"several": [
199+
"mental",
200+
false,
201+
-272603442,
202+
[
203+
"create",
204+
true,
205+
"knew",
206+
true,
207+
1946718342.0231495,
208+
true
209+
],
210+
true,
211+
2140278260.1038685
212+
],
213+
"while": false,
214+
"excited": -1390968618.495607,
215+
"method": false,
216+
"truck": -1519363135.2899814,
217+
"also": -927199622.0916243
218+
}
219+
JSON;
220+
$x = JsonArray::newFromJsonArrayFromJson($json);
221+
222+
// JsonArray has options for serializing JSON output
223+
$json = $x->withUnescapedSlashes()
224+
->withPrettyPrint()
225+
->toJson();
226+
```

composer.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@
1010
"role": "maintainer"
1111
}
1212
],
13-
"minimum-stability": "dev",
1413
"support": {
1514
"issues": "https://github.com/modethirteen/XArray.php/issues"
1615
},
1716
"require": {
18-
"php": ">=7.2.0"
17+
"php": ">=7.2.0",
18+
"ext-json": "*"
1919
},
2020
"require-dev": {
21-
"phpstan/phpstan": "0.11.1",
22-
"phpunit/phpunit": "7.4.3"
21+
"phpstan/phpstan": "~0.12",
22+
"phpunit/phpunit": "~7.4.3"
2323
},
2424
"autoload": {
2525
"psr-4": {
@@ -29,7 +29,7 @@
2929
},
3030
"autoload-dev": {
3131
"psr-4": {
32-
"modethirteen\\XArray\\tests\\": ["tests/"]
32+
"modethirteen\\XArray\\Tests\\": ["tests/"]
3333
}
3434
}
3535
}

phpstan.neon

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
parameters:
2+
bootstrapFiles:
3+
- %currentWorkingDirectory%/_bootstrap.php
4+
checkMissingIterableValueType: false
5+
level: 7
6+
paths:
7+
- src
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php declare(strict_types=1);
2+
/**
3+
* XArray
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
namespace modethirteen\XArray\Exception;
18+
19+
use Exception;
20+
21+
class SchemaLockedArrayUndefinedKeyException extends Exception {
22+
23+
/**
24+
* @param string $key
25+
*/
26+
public function __construct(string $key) {
27+
parent::__construct('Could not set array key not defined in schema: ' . $key);
28+
}
29+
}
30+

src/JsonArray.php

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php declare(strict_types=1);
2+
/**
3+
* XArray
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
namespace modethirteen\XArray;
18+
19+
class JsonArray extends XArray {
20+
21+
/**
22+
* @var bool
23+
*/
24+
private $isPrettyPrintEnabled = false;
25+
26+
/**
27+
* @var bool
28+
*/
29+
private $isUnescapedSlashesEnabled = false;
30+
31+
/**
32+
* @param string $json
33+
* @return JsonArray
34+
*/
35+
public static function newJsonArrayFromJson(string $json) : JsonArray {
36+
return new JsonArray(json_decode($json, true));
37+
}
38+
39+
/**
40+
* @return string
41+
*/
42+
public function toJson() : string {
43+
$options = 0;
44+
if($this->isPrettyPrintEnabled) {
45+
$options = $options | JSON_PRETTY_PRINT;
46+
}
47+
if($this->isUnescapedSlashesEnabled) {
48+
$options = $options | JSON_UNESCAPED_SLASHES;
49+
}
50+
$result = $options > 0 ? json_encode($this->array, $options) : json_encode($this->array);
51+
return is_string($result) ? $result : '{}';
52+
}
53+
54+
/**
55+
* Remove forward slash escaping with serializing to JSON text
56+
*
57+
* @note slashes should always remain escaped if JSON is embedded in, or contains, HTML
58+
* @return JsonArray
59+
*/
60+
public function withUnescapedSlashes() : JsonArray {
61+
62+
// even though this is a clone, we should not create a new array reference - there is no change to the underlying array data
63+
$instance = clone $this;
64+
$instance->isUnescapedSlashesEnabled = true;
65+
return $instance;
66+
}
67+
68+
/**
69+
* Add line spacing and indentation when serializing to JSON text
70+
*
71+
* @note Even though this is a clone, we should not create a new array reference - there is no change to the underlying array data
72+
* @return JsonArray
73+
*/
74+
public function withPrettyPrint() : JsonArray {
75+
76+
// even though this is a clone, we should not create a new array reference - there is no change to the underlying array data
77+
$instance = clone $this;
78+
$instance->isPrettyPrintEnabled = true;
79+
return $instance;
80+
}
81+
}

0 commit comments

Comments
 (0)