by Ivan Chepurnyi
// ... some xml/json/yaml file initialization
foreach ($loadedData as $item) {
$this->process($item);
}
foreach ($data as $item) {
$row = [];
foreach ($columns as $column) {
$row[] = $column->export($item);
}
$csv->write($row);
}
class ClassOne
{
public function __construct(ClassTwo $dependency) {}
}
class ClassTwo
{
public function __construct(ClassThree $dependency) {}
}
class ClassThree
{
public function __construct(ClassFour $dependencyOne, ClassFive $dependencyTwo) {}
}
// ..
Translate your XML/JSON/YAML file into executable PHP code and include it when you need processed structure
Pre-compile second loop and execute it within the main one
Resolve dependencies and compile resolution into executable code
Didn't find one... So I wrote it myself.
composer require "ecomdev/compiler"
<objects>
<item id="object_one" type="object" />
<item id="object_two" type="object" />
<item id="object_three" type="object" />
<type id="object" class="Some\ClassName"/>
</objects>
use EcomDev\Compiler\Statement\Builder;
class Parser implements EcomDev\Compiler\ParserInterface
{
// .. constructor with builder as dependency
public function parse($value)
{
$xml = simplexml_load_string($value);
$info = $this->readXml($xml);
return $this->getPhpCode($info, $this->builder);
}
// .. other methods
}
private function readXml($xml)
{
$info = [];
foreach ($xml->children() as $node) {
if ($node->getName() === 'type') {
$info['types'][(string)$node->id] = (string)$node->class;
} elseif ($node->getName() === 'object') {
$info['objects'][(string)$node->id] = (string)$node->type;
}
}
return $info;
}
private function getPhpCode($info, $builder) {
$compiledArray = [];
foreach ($info['objects'] as $objectId => $type) {
$compiledArray[$objectId] = $builder->instance($info['types'][$type]);
}
return $builder->container(
$builder->returnValue($compiledArray)
);
}
return [
'object_one' => new Some\ClassName(),
'object_two' => new Some\ClassName(),
'object_three' => new Some\ClassName()
];
public function __construct(
EcomDev\Compiler\Builder $builder,
EcomDev\Compiler\Compiler $compiler)
{
$this->builder = $builder;
$this->compiler = $compiler;
}
public function export($data, $columns)
{
$statements = $this->compileColumns($columns, $this->builder);
$source = new \EcomDev\Compiler\Source\StaticData(
'your_id', 'your_checksum', $statements
);
$reference = $this->compiler->compile($source);
$closure = $this->compiler->interpret($reference);
foreach ($data as $item) {
$row = $closure($item, $columns);
}
}
public function compileColumns($columns, $builder)
{
$item = $builder->variable('item');
$compiledArray = [];
foreach ($columns as $id => $column) {
$compiledArray[] = $builder->chainVariable('columns')[$id]
->export($item);
}
$closure = $builder->closure(
[$item, $builder->variable('columns')],
$builder->container([$builder->returnValue($compiledArray)])
);
return $builder->container([$builder->returnValue($closure)]);
}
return function ($item, $columns) {
return [
$columns['id1']->export($item),
$columns['id2']->export($item),
$columns['id3']->export($item),
// ...
];
};
class SomeClass implements EcomDev\Compiler\ExportableInterface
{
public function __construct($foo, $bar) { /* */ }
public function export() {
return [
'foo' => $this->foo,
'bar' => $this->bar
];
}
}
Will be automatically compiled into:
new SomeClass('fooValue', 'barValue');
Every handle that is added to the Magento\Framework\View\Result changes the cache key for the whole generated structure.
Scheduled structure is generated from XML object at all times
1. Make every handle a compiled php code
2. Include compiled handles at loading phase
I am already working on it
Will be release in April 2016
https://github.com/EcomDev/compiler
https://github.com/EcomDev/EcomDev_LayoutCompiler
Coming soon
@IvanChepurnyi
ivan@ecomdev.org