165 lines
2.8 KiB
PHP
165 lines
2.8 KiB
PHP
|
<?php
|
||
|
|
||
|
namespace alveolata\xml;
|
||
|
|
||
|
require_once(DIR_ALVEOLATA . '/string/functions.php');
|
||
|
require_once(DIR_ALVEOLATA . '/list/functions.php');
|
||
|
require_once(DIR_ALVEOLATA . '/xml/abstract/interface.php');
|
||
|
require_once(DIR_ALVEOLATA . '/xml/concrete/complex/type.php');
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @author Christian Fraß <frass@greenscale.de>
|
||
|
*/
|
||
|
class implementation_complex implements interface_node
|
||
|
{
|
||
|
|
||
|
/**
|
||
|
* @var \alveolata\xml\struct_complex
|
||
|
*/
|
||
|
private $subject;
|
||
|
|
||
|
|
||
|
/**
|
||
|
*/
|
||
|
public function __construct(
|
||
|
struct_complex $subject
|
||
|
)
|
||
|
{
|
||
|
$this->subject = $subject;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @implementation
|
||
|
*/
|
||
|
public function find(
|
||
|
\Closure $sub,
|
||
|
\Closure $predicate,
|
||
|
?int $max_depth
|
||
|
) : array
|
||
|
{
|
||
|
return (
|
||
|
((! \is_null($max_depth)) && ($max_depth <= 0))
|
||
|
? []
|
||
|
: \alveolata\list_\reduce(
|
||
|
(
|
||
|
\is_null($this->subject->children)
|
||
|
? []
|
||
|
: \alveolata\list_\map(
|
||
|
$this->subject->children,
|
||
|
fn($child) => ($sub)(
|
||
|
$child,
|
||
|
$predicate,
|
||
|
(\is_null($max_depth) ? null : ($max_depth - 1))
|
||
|
)
|
||
|
)
|
||
|
),
|
||
|
(
|
||
|
($predicate)($this->subject)
|
||
|
? [$this->subject]
|
||
|
: []
|
||
|
),
|
||
|
fn($x, $y) => \array_merge($x, $y)
|
||
|
)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @implementation
|
||
|
*/
|
||
|
public function transform(
|
||
|
\Closure $sub,
|
||
|
\Closure $function
|
||
|
)
|
||
|
{
|
||
|
return ($function)(
|
||
|
new struct_complex(
|
||
|
$this->subject->name,
|
||
|
$this->subject->attributes,
|
||
|
(
|
||
|
\is_null($this->subject->children)
|
||
|
? null
|
||
|
: \alveolata\list_\map(
|
||
|
$this->subject->children,
|
||
|
fn($child) => ($sub)($child, $function)
|
||
|
)
|
||
|
)
|
||
|
)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @implementation
|
||
|
*/
|
||
|
public function to_raw(
|
||
|
\Closure $sub
|
||
|
)
|
||
|
{
|
||
|
return [
|
||
|
'kind' => 'complex',
|
||
|
'data' => [
|
||
|
'name' => $this->subject->name,
|
||
|
'attributes' => $this->subject->attributes,
|
||
|
'children' => (
|
||
|
\is_null($this->subject->children)
|
||
|
? null
|
||
|
: \alveolata\list_\map(
|
||
|
$this->subject->children,
|
||
|
fn($child) => ($sub)($child)
|
||
|
)
|
||
|
),
|
||
|
],
|
||
|
];
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @implementation
|
||
|
*/
|
||
|
public function to_string(
|
||
|
\Closure $sub,
|
||
|
int $depth
|
||
|
) : string
|
||
|
{
|
||
|
return \alveolata\string\coin(
|
||
|
(
|
||
|
\is_null($this->subject->children)
|
||
|
? '<{{name}}{{attributes}}/>'
|
||
|
: '<{{name}}{{attributes}}>{{children}}</{{name}}>'
|
||
|
),
|
||
|
[
|
||
|
'name' => $this->subject->name,
|
||
|
'attributes' => \implode(
|
||
|
'',
|
||
|
\alveolata\list_\map(
|
||
|
\alveolata\list_\filter(
|
||
|
\array_keys($this->subject->attributes),
|
||
|
fn($key) => (! \is_null($this->subject->attributes[$key]))
|
||
|
),
|
||
|
fn($key) => \alveolata\string\coin(
|
||
|
' {{key}}="{{value}}"',
|
||
|
[
|
||
|
'key' => $key,
|
||
|
'value' => $this->subject->attributes[$key],
|
||
|
]
|
||
|
)
|
||
|
)
|
||
|
),
|
||
|
'children' => \implode(
|
||
|
'',
|
||
|
\alveolata\list_\map(
|
||
|
$this->subject->children,
|
||
|
fn($child) => ($sub)($child, ['depth' => ($depth + 1)])
|
||
|
)
|
||
|
),
|
||
|
]
|
||
|
);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
?>
|