| Current Path : /home/jeromecohp/www/tmp/yooessentials/modules/core/src/Source/ |
| Current File : /home/jeromecohp/www/tmp/yooessentials/modules/core/src/Source/SourceResolver.php |
<?php
/**
* @package Essentials YOOtheme Pro (Freemium) 1.6.8
* @author ZOOlanders https://www.zoolanders.com
* @copyright Copyright (C) Joolanders, SL
* @license http://www.gnu.org/licenses/gpl.html GNU/GPL
*/
namespace ZOOlanders\YOOessentials\Source;
use YOOtheme\Arr;
use YOOtheme\Builder\Source;
use YOOtheme\Builder\Source\SourceQuery;
use YOOtheme\Builder\Source\SourceTransform;
use YOOtheme\Event;
class SourceResolver
{
/**
* @var Source
*/
protected $source;
/**
* @var SourceTransform
*/
protected $sourceTransform;
public function __construct(Source $source, SourceTransform $sourceTransform)
{
$this->source = $source;
$this->sourceTransform = $sourceTransform;
}
public function setSource(Source $source)
{
$this->source = $source;
}
/**
* Render callback.
*
* @param object $node
* @param array $params
*/
public function resolveNode($node, array $params = []): object
{
$node = $this->prepareNode($node);
if (!$result = $this->querySource($node, $params)) {
return $node;
}
$name = $node->source->query->name;
// add field name
if (isset($node->source->query->field)) {
$name .= ".{$node->source->query->field->name}";
}
// get source data
if (is_array($data = Arr::get($result, "data.{$name}"))) {
// map source properties
if ($data) {
$this->mapSource($node, $params + compact('data'));
}
}
return $node;
}
/**
* Map source properties.
*
* @param object $node
* @param array $params
*
* @return object|bool
*/
protected function mapSource($node, array $params): object
{
if (empty($params['data'][0])) {
$this->sourceTransform->mapSource($node, $params);
} else {
$nodes = [];
// clone node for each item
foreach ($params['data'] as $data) {
$clone = clone $node;
$clone->source = (object) [
'props' => $node->source->props,
];
if ($this->sourceTransform->mapSource($clone, compact('data') + $params)) {
$nodes[] = $clone;
}
}
$values = array_column($nodes, 'props');
foreach (($node->source->props ?? []) as $name => $prop) {
$node->props[$name] = array_column($values, $name);
}
}
return $node;
}
/**
* Query source data.
*
* @param object $node
* @param array $params
*
* @return array|void
*/
public function querySource($node, array $params)
{
if (empty($node->source->query->name) || empty($node->source->props)) {
return;
}
// execute query without validation rules
$query = (new SourceQuery())->create($node);
$result = $this->source->query(
[
'kind' => 'Document',
'definitions' => [$query],
],
$params,
new \ArrayObject(),
null,
null,
null,
[]
);
if (!empty($result->errors)) {
Event::emit('source.error', $result->errors, $node);
}
return $result->toArray();
}
protected function toString($str)
{
if (is_scalar($str) || is_callable([$str, '__toString'])) {
return (string) $str;
}
return '';
}
protected function prepareNode($node): object
{
$node = json_decode(json_encode($node), false);
$node->props = (array) $node->props;
return $node;
}
}