Skip to content

Commit

Permalink
Blueprints parser, mapper, and validator autogenerated from JSON Sche…
Browse files Browse the repository at this point in the history
…ma (#23)

Solves the Blueprint parsing problem as follows:

* JSON Schema is the source of truth for the Blueprint data structure
* Model classes are generated from JSON Schema
* Input Validation is done against the JSON Schema
* Mapping validated input into model instances is indirectly done based on the JSON Schema

## Summary of the approach

We use [Janephp](https://github.com/janephp/janephp/) to infer the PHP model class structure from the JSON schema

We then use Jane's output to generate PHP code using [Nette PHP generator](https://github.com/nette/php-generator):

* Model classes
* Interfaces for groups of related classes: `StepDefinitionInterface`, `ResourceDefinitionInterface`.
* Interface resolution map for the [JsonMapper library](https://jsonmapper.net/).
* PHP docstrings with more accurate types than Jane to guide the mapping process

From there, the data pipeline looks as follows:

1. Parse raw JSON
2. Validate it with Opis
3. Map it into PHP models using JsonMapper

Or, if you're consuming the PHP API directly:

1. Create Model instances
2. Validate them with Opis

## Remaining work

- [ ] Solve merge conflicts

## Rationale

Parsing and mapping JSON [in TypeScript is a simple problem, but in PHP it's surprisingly involved](WordPress/blueprints#13 (comment)). This PR combines three previously explored approaches into a single pipeline:

* WordPress/blueprints#17
* WordPress/blueprints#19
* WordPress/blueprints#21
  • Loading branch information
Coyote100333 authored Feb 23, 2024
1 parent 3470d80 commit a82a531
Show file tree
Hide file tree
Showing 97 changed files with 4,458 additions and 5,641 deletions.
10 changes: 6 additions & 4 deletions blueprint_compiling.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<?php

use WordPress\Blueprints\ContainerBuilder;
use WordPress\Blueprints\Model\BlueprintComposer;
use WordPress\Blueprints\Model\BlueprintBuilder;
use WordPress\Blueprints\Runtime\NativePHPRuntime;

require 'vendor/autoload.php';

$composer = BlueprintComposer::create()
$blueprint = BlueprintBuilder::create()
->withWordPressVersion( 'https://wordpress.org/latest.zip' )
->withSiteOptions( [
'blogname' => 'My Playground Blog',
Expand All @@ -30,14 +30,16 @@
INSERT INTO `tmp_table` VALUES (2);
SQL
)
->withFile( 'wordpress.txt', 'Data' );
->withFile( 'wordpress.txt', 'Data' )
->toBlueprint();


$c = ( new ContainerBuilder() )->build(
new NativePHPRuntime(
__DIR__ . '/new-wp'
)
);

$results = $c['blueprint.engine']->runBlueprint( $composer );
$results = $c['blueprint.engine']->runBlueprint( $blueprint );

var_dump( $results );
12 changes: 8 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,28 @@
"symfony/http-client": "^7.0",
"symfony/http-kernel": "^7.0",
"pimple/pimple": "^3.0",
"swaggest/json-schema": "^0.12.42",
"swaggest/php-code-builder": "^0.2.41"
"opis/json-schema": "^2.3",
"nette/php-generator": "^4.1",
"json-mapper/json-mapper": "^2.21"
},
"require-dev": {
"pestphp/pest": "^2.33"
"pestphp/pest": "^2.33",
"jane-php/json-schema": "^7.6"
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"allow-plugins": {
"pestphp/pest-plugin": true
"pestphp/pest-plugin": true,
"php-http/discovery": true
}
},
"autoload": {
"psr-4": {
"WordPress\\": "src/WordPress"
},
"files": [
"src/WordPress/Blueprints/functions.php",
"src/WordPress/Zip/functions.php",
"src/WordPress/Blueprints/functions.php",
"src/WordPress/Streams/stream_str_replace.php"
Expand Down
Loading

0 comments on commit a82a531

Please sign in to comment.