Skip to content

Commit

Permalink
- backport JsonArray, SchemaLockedArray, XArray::getKeys, XArray::toF…
Browse files Browse the repository at this point in the history
…lattenedArray to php72 without breaking API

- switch to github actions
  • Loading branch information
modethirteen committed Dec 15, 2020
1 parent c700f4a commit edf0bdb
Show file tree
Hide file tree
Showing 56 changed files with 2,085 additions and 329 deletions.
43 changes: 43 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: build

on:
push:
branches: [ php72 ]
pull_request:
branches: [ php72 ]

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
php: [7.2, 7.3, 7.4]

steps:
- uses: actions/checkout@v2

- name: Validate dependencies
run: composer validate

- name: Get dependency cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"

- name: Cache dependencies
uses: actions/cache@v2
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.json') }}
restore-keys: |
${{ runner.os }}-php-
- name: Install dependencies
run: composer install --prefer-dist --no-progress --no-suggest

- name: Run static analysis
run: vendor/bin/phpstan analyse

- name: Run test suite
run: vendor/bin/phpunit --configuration phpunit.xml.dist --coverage-clover=coverage.xml

- uses: codecov/codecov-action@v1
18 changes: 0 additions & 18 deletions .travis.yml

This file was deleted.

112 changes: 103 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

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

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

## Requirements

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

## Installation

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

```sh
$ ./composer.phar require modethirteen/xarray
./composer.phar require modethirteen/xarray
```

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

```json
{
"require": {
"modethirteen/xarray": "dev-master"
"modethirteen/xarray": "dev-main"
}
}
```

"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.
`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.

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

## Usage

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

// get the array
// which key paths have been defined in the XArray?
$keys = $x1->getKeys(); // ['foo', 'foo/bar', 'qux']

// reduce output to the key paths that have values
$flattened = $x1->toFlattenedArray(); // ['foo/bar' => 'baz', 'qux' => ['fred', 'quxx']]

// get the array (the underlying array data structure)
$array1 = $x1->toArray();

// create a new XArray from the existing array
Expand Down Expand Up @@ -130,3 +136,91 @@ $array2 = $x->toArray();
// MutableXArray mutates the source array
assert($array1 === $array2);
```

### SchemaLockedArray.php (extends XArray.php)

```php
// SchemaLockedArray will block the setting of any values if the key path is not allowlisted in a schema
$x = new SchemaLockedArray(new SchemaBuilder());

// throws SchemaLockedArrayUndefinedKeyException
$x->setVal('foo', 'bar');

// a schema can be built with a fluent API
$schemaBuilder = (new SchemaBuilder())
->with('foo')

// also allowlists bar
->with('bar/baz')

// also allowlists plugh and plugh/xyzzy
->with('plugh/xyzzy/fred');

// a schema can also be inferred from another XArray by analyzing the array's defined key paths
$x = new XArray([
'foo' => 'qux',
'bar' => [
'baz' => true
],
'plugh' => [
'xyzzy' => [
'fred' => [
'sodium',
'iodine'
]
]
]
]);
$schemaBuilder = SchemaBuilder::newFromXArray($x);

// either way, the SchemaLockedArray will only ever have the key paths that are defined in the schema
$x = new SchemaLockedArray($schemaBuilder);

// ...leading to a very predictable array tree structure when outputted
$array = $x->toArray();
```

### JsonArray.php (extends XArray.php)

```php
// Like XArray, JsonArray can be built from a source array
$array = [
'foo' => [
'bar',
'baz'
]
];
$x = new JsonArray($array);

// JsonArray can also be built from a JSON string
$json = <<<JSON
{
"several": [
"mental",
false,
-272603442,
[
"create",
true,
"knew",
true,
1946718342.0231495,
true
],
true,
2140278260.1038685
],
"while": false,
"excited": -1390968618.495607,
"method": false,
"truck": -1519363135.2899814,
"also": -927199622.0916243
}
JSON;
$x = JsonArray::newFromJsonArrayFromJson($json);

// JsonArray has options for serializing JSON output
$json = $x->withUnescapedSlashes()
->withPrettyPrint()
->toJson();
```
10 changes: 5 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@
"role": "maintainer"
}
],
"minimum-stability": "dev",
"support": {
"issues": "https://github.com/modethirteen/XArray.php/issues"
},
"require": {
"php": ">=7.2.0"
"php": ">=7.2.0",
"ext-json": "*"
},
"require-dev": {
"phpstan/phpstan": "0.11.1",
"phpunit/phpunit": "7.4.3"
"phpstan/phpstan": "~0.12",
"phpunit/phpunit": "~7.4.3"
},
"autoload": {
"psr-4": {
Expand All @@ -29,7 +29,7 @@
},
"autoload-dev": {
"psr-4": {
"modethirteen\\XArray\\tests\\": ["tests/"]
"modethirteen\\XArray\\Tests\\": ["tests/"]
}
}
}
7 changes: 7 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
parameters:
bootstrapFiles:
- %currentWorkingDirectory%/_bootstrap.php
checkMissingIterableValueType: false
level: 7
paths:
- src
30 changes: 30 additions & 0 deletions src/Exception/SchemaLockedArrayUndefinedKeyException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php declare(strict_types=1);
/**
* XArray
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace modethirteen\XArray\Exception;

use Exception;

class SchemaLockedArrayUndefinedKeyException extends Exception {

/**
* @param string $key
*/
public function __construct(string $key) {
parent::__construct('Could not set array key not defined in schema: ' . $key);
}
}

81 changes: 81 additions & 0 deletions src/JsonArray.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php declare(strict_types=1);
/**
* XArray
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace modethirteen\XArray;

class JsonArray extends XArray {

/**
* @var bool
*/
private $isPrettyPrintEnabled = false;

/**
* @var bool
*/
private $isUnescapedSlashesEnabled = false;

/**
* @param string $json
* @return JsonArray
*/
public static function newJsonArrayFromJson(string $json) : JsonArray {
return new JsonArray(json_decode($json, true));
}

/**
* @return string
*/
public function toJson() : string {
$options = 0;
if($this->isPrettyPrintEnabled) {
$options = $options | JSON_PRETTY_PRINT;
}
if($this->isUnescapedSlashesEnabled) {
$options = $options | JSON_UNESCAPED_SLASHES;
}
$result = $options > 0 ? json_encode($this->array, $options) : json_encode($this->array);
return is_string($result) ? $result : '{}';
}

/**
* Remove forward slash escaping with serializing to JSON text
*
* @note slashes should always remain escaped if JSON is embedded in, or contains, HTML
* @return JsonArray
*/
public function withUnescapedSlashes() : JsonArray {

// even though this is a clone, we should not create a new array reference - there is no change to the underlying array data
$instance = clone $this;
$instance->isUnescapedSlashesEnabled = true;
return $instance;
}

/**
* Add line spacing and indentation when serializing to JSON text
*
* @note Even though this is a clone, we should not create a new array reference - there is no change to the underlying array data
* @return JsonArray
*/
public function withPrettyPrint() : JsonArray {

// even though this is a clone, we should not create a new array reference - there is no change to the underlying array data
$instance = clone $this;
$instance->isPrettyPrintEnabled = true;
return $instance;
}
}
Loading

0 comments on commit edf0bdb

Please sign in to comment.