trebel / schematic
Schematic: Schema exchange protocol
Requires
- php: >=7.4
This package is not auto-updated.
Last update: 2025-06-13 05:59:56 UTC
README
The purpose of this library is to create a schema transfer protocol with the ability to export and import XML.
How does it work
The library helps us create new data types with strict validation and a defined structure.
Data types:
In current version, there are 4 data types: Field, List, Operator, Schema. Every created object is immutable, once created, you cannot change it.
Data type: Trebel\Schematic\Field
Fields are the smallest points of data types, the value of any "Field" must be primitive or we can see below can be Operator:
namespace Example\Fields\User; use Trebel\Schematic\Field; class ID extends Field { function __construct($value) { parent::__construct($value); } public function validate($value): bool { return ctype_digit($value) && $value > 0; } } class Name extends Field { function __construct($value) { parent::__construct($value); } public function validate($value): bool { return is_string($value) && strlen($value) > 0 && strlen($value) < 255; } }
Data type: Trebel\Schematic\Schema
Schema data type is object-like type, each schema can contain Field, List, or other Schema data types.
namespace Example; use Trebel\Schematic\Schema; class Person extends Schema { function __construct(...$args){ parent::__construct(...$args); } public static $schema = [ 'Example\Fields\User\ID', 'Example\Fields\User\Name', ]; }
Then we can create our first Schema object:
$person = new Example\Person([ new Example\UserId(1234), new Example\UserName('Jhone'), ]) echo $person->id . "\n"; // Ourput: "1234" echo $person->id->innerItem() . "\n"; // Ourput: 1234 // absolute value
ID
is required field for each Schema data type
Data type: Trebel\Schematic\Collection (List)
Collection Why not List? beacouse of list is reserved word in PHP
Lists are data types similar to arrays, and the only difference between a Schema and a List is that List can only handle one type, while Schema can handle any.
namespace Example; use Trebel\Schematic\Collection; class Persons extends Collection { protected static $type = 'Example\Person'; // Required function __construct(...$arg) { parent::__construct(...$arg); } } // To use Lists $persons = new Examples\Persons([ new Persons( ... ), new Persons( ... ) ])
Data type: Trebel\Schematic\Operator
Operators are special types, not to define an element, but to modify it.
For example, suppose we have a schema Car with fields ID and Price, and in the case where we want to change the price to add or subtract existing price, we can create Increase operator inside Price
$carTwo = new Schemas\Car([ new Fields\Car\ID(31), new Fields\Car\Price( new Operators\Increase(123), ) ]);
In this version, the operators only work on the Field and List data types. There are defined operators
Push (Trebel\Schematic\Operators\Push),
Pull (Trebel\Schematic\Operators\Pull)
for List data type
Increase (Trebel\Schematic\Operators\Increase)
for Field data type
But you can create your own data types as well.
To support any operator on a Field or List, you need to define all the operators within the types.
class Cars extends Collection { public static $type = 'Examples\Schemas\Car'; public static $operators = [ 'Trebel\Schematic\Operators\Push', 'Trebel\Schematic\Operators\Pull', ]; function __construct(...$arg) { parent::__construct(...$arg); } }
// Example new Lists\Cars([ new Operators\Push( new Schemas\Car([ new Fields\Car\ID(33), new Fields\Car\Name('Ford'), new Fields\Car\Price(15000) ]) ), // Pay attention that Pull operator can be not completed schema new Operators\Pull( new Schemas\Car([ new Fields\Car\ID(31)] )), ])
Export / Import
The main part of the library is the ability to export and import XML schemas using a specific protocol.
Export Schema
$exporter = new Trebel\Schematic\Tools\Exporter($schema); $exporter->export($pathToExport);
You can only import a schema, not a field, list, or operator.
Let's look at a specific example:
$person = new Schemas\Person([ new Fields\User\ID(15), new Lists\Cars([ new Operators\Push( new Schemas\Car([ new Fields\Car\ID(33), new Fields\Car\Name('Ford'), new Fields\Car\Price(15000) ]) ), new Operators\Pull( new Schemas\Car([ new Fields\Car\ID(31)] )), ]) ]) $exporter = new Trebel\Schematic\Tools\Exporter($person); $exporter->export('/tmp/example/index.xml');
Outpout xml files could be:
File: /tmp/example/index.xml
<?xml version="1.0" encoding="UTF-8"?> <Content> <Person> <ID>15</ID> <Cars> <Push> <Car src="Car/33.xml"/> </Push> <Pull> <Car src="Car/31.xml"/> </Pull> </Cars> </Person> </Content>
File: /tmp/example/Car/33.xml
<?xml version="1.0" encoding="UTF-8"?> <Content> <Car> <ID>33</ID> <Name>Ford</Name> <Price>15000</Price> </Car> </Content>
and the same for Car/31.xml
Another example:
$car = new Schemas\Car([ new Fields\Car\ID(31), new Fields\Car\Price( new Operators\Increase(500), ) ]);
output:
<?xml version="1.0" encoding="UTF-8"?> <Content> <Car> <ID>31</ID> <Price> <Increase>500</Increase> </Price> </Car> </Content>
Import Schema
$importer = new Trebel\Schematic\Tools\Importer([ .. list of supported schmeas]); $schema = $importer->import($pathToSchema);
Concrete example:
$importer = new Tools\Importer([ 'Examples\Schemas\Car', 'Examples\Schemas\Person', 'Examples\Schemas\Toyota', ]); $car = $importer->import('/tmp/car/index.xml');
Conclusion
For more information, check out the tutorials located in the examples
folder