blackprint / engine
PHP Engine for Blackprint
Fund package maintenance!
stefansarya
Requires
- php: ^8.1
- ext-json: *
- php-ds/php-ds: ^1.4
README
Blackprint Engine for PHP
Run exported Blackprint on PHP environment.
Documentation
Warning: This project haven't reach it stable version (semantic versioning at v1.0.0)
But please try to use it and help improve this project
This engine is designed to be similar with engine-js
, some API and property will be similar.
Minimum PHP version >= 8.1
Defining Blackprint Node and Interface
Because PHP does support class-based programming and to make the node import more effective and easier, this engine will only support Node/Interface that declared with classes.
But before that, we need to create a folder to store our Node/Interface logic. For the example /BPNode
.
Registering Namespace folder
require_once('../vendor/autoload.php'); // This can be called on different PHP libraries \Blackprint\registerNamespace(__DIR__.'/BPNode'); // When registering with Namespace, the default root namespace is always "BPNode" // Please name your nodes namespace along with your library name to avoid conflict with other library
Define Node and Interface
After the namespace folder ./BPNode
has been registered, you can now create a folder with your library name. For the example: ./BPNode/Example
.
// file: ./BPNode/Example/Hello.php namespace \BPNode\Example; // The class name must match with the file name // This will be registered as Node definition class Hello extends \Blackprint\Node { // Please remember to capitalize the port name // Set the output port structure for your node (Optional) static $output = [ 'Changed'=> Types::Trigger, // Callable: $this->output['Changed']() 'Output'=> Types::Number, // $this->output['Value'] = 246 ]; // Set the input port structure for your node (Optional) static $input = [ 'Multiply'=> Types::Number, // $val = $this->output['Value'] ] function __construct($instance){ // Call the parent constructor first, passing the $instance (Blackprint\Engine) parent::__construct($instance); // Set the Interface, let it empty if you want // to use default empty interface "setInterface()" $iface = $this->setInterface('BPIC/Example/Hello'); $iface->title = "Hello"; // Set the title for debugging } }
Let's also define our custom interface, this is optional and needed only if you want to provide access for other developer. Just like an API (Application Programming Interface).
// same file: ./BPNode/Example/Hello.php namespace \BPNode\Example; // Your Interface namespace must use "BPIC" as the prefix \Blackprint\registerInterface('BPIC/Example/Hello', HelloIFace::class); class HelloIFace extends \Blackprint\Interfaces { function __construct($node){ // Call the parent constructor first, passing the $node (Blackprint\Node) parent::__construct($node); // $this->node => Blackprint\Node // Define IFace's data (optional if you want to export/import data from JSON) // Because getter/setter feature only available on class, we will create from `class MyData` $this->data = new MyData($this); // $this->data->value === 123 (if the default value is not replaced when importing JSON) } function recalculate(){ // Get value from input port $multiplyBy = $this->node->input['Multiply']; // Assign new value to output port $this->node->output['Output'] = $this->data->value * $multiplyBy; } } // Getter and setter should be changed with basic property accessor class MyData { // Constructor promotion, $iface as private MyData property function __construct(private $iface){} // Draft: please design it like below after // this PR was merged to PHP https://github.com/php/php-src/pull/6873 private $_value = 123; public $value { get { return $this->_value }; set { $this->_value = $value; $this->iface->recalculate(); // Call recalculate() on HelloIFace }; }; // Current polyfill for property accessor (https://github.com/php/php-src/pull/6873) private $data = ["value"=> 123]; function __get($key) { return $this->data[$key]; } function __set($key, $val) { $this->data[$key] = &$val; if($key === 'value') $this->iface->recalculate($val); // Call recalculate() on HelloIFace } }
Creating new Engine instance
// Create Blackprint Engine instance $instance = new Blackprint\Engine(); // You can import nodes with JSON // if the nodes haven't been registered, this will throw an error $instance->importJSON(`{...}`); // You can also create the node dynamically $iface = $instance->createNode('Example/Hello', /* [..options..] */); // ---- // Change the default data 'value' property $iface->data->value = 123; // Assign the 'Multiply' input port = 2 $iface->node->input['Multiply'] = 2; // Get the value from 'Output' output port echo $iface->node->output['Output']; // 246
Example
This repository provide an example with the JSON too, and you can try it with PHP CLI:
# Change your working directory into empty folder first $ git clone --depth 1 https://github.com/Blackprint/engine-php . $ composer install $ php ./example/init.php