98 lines
2.6 KiB
PHP
98 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace NoccyLabs\GdLabel\Loader;
|
|
|
|
use NoccyLabs\CssLike\Stylesheet;
|
|
use NoccyLabs\GdLabel\Label;
|
|
use SimpleXMLElement;
|
|
use NoccyLabs\GdLabel\Element;
|
|
|
|
class XmlLoader
|
|
{
|
|
|
|
public function loadFile($filename)
|
|
{
|
|
$xml = simplexml_load_file($filename);
|
|
|
|
$label = new Label();
|
|
$styles = new Stylesheet();
|
|
|
|
foreach ($xml->style as $style) {
|
|
if (($src = (string)@$style['src'])) {
|
|
$ss = file_get_contents($src);
|
|
} else {
|
|
$ss = (string)$style;
|
|
}
|
|
$ssb = new Stylesheet();
|
|
$ssb->parseString($ss);
|
|
$styles->appendStylesheet($ssb);
|
|
}
|
|
|
|
$rules = $styles->select("label");
|
|
foreach ($rules as $prop=>$value) {
|
|
$label->setProp($prop, $value);
|
|
}
|
|
|
|
$this->parseAttributes($xml, $label, $styles);
|
|
|
|
foreach ($xml->children() as $child) {
|
|
if ($child->getName() == "style") {
|
|
continue;
|
|
}
|
|
$this->parseElement($child, $label, $styles);
|
|
}
|
|
|
|
return $label;
|
|
}
|
|
|
|
private function parseElement(SimpleXmlElement $xml, Element $elem, Stylesheet $style)
|
|
{
|
|
$name = $xml->getName();
|
|
|
|
$fqcn = "NoccyLabs\\GdLabel\\Elements\\".ucwords($name)."Element";
|
|
if (!class_exists($fqcn)) {
|
|
throw new \RuntimeException("Invalid element {$name} (expected {$fqcn})");
|
|
}
|
|
|
|
$obj = new $fqcn();
|
|
|
|
$rules = $style->select($name);
|
|
foreach ($rules as $prop=>$value) {
|
|
$elem->setProp($prop, $value);
|
|
}
|
|
|
|
$this->parseAttributes($xml, $obj, $style);
|
|
|
|
foreach ($xml->children() as $child) {
|
|
$this->parseElement($child, $obj, $style);
|
|
}
|
|
|
|
$elem->addChild($obj);
|
|
}
|
|
|
|
private function parseAttributes(SimpleXmlElement $xml, Element $elem, Stylesheet $style)
|
|
{
|
|
$props = [];
|
|
foreach ($xml->attributes() as $attr) {
|
|
$name = $this->camelToDash($attr->getName());
|
|
$value = (string)$attr;
|
|
$props[$name] = $value;
|
|
}
|
|
if (array_key_exists("class", $props)) {
|
|
$classes = explode(" ",trim($props['class']));
|
|
foreach ($classes as $class) {
|
|
$rule = $style->select(".".$class);
|
|
$props = array_merge($rule, $props);
|
|
}
|
|
}
|
|
foreach ($props as $prop=>$value) {
|
|
$elem->setProp($prop, $value);
|
|
}
|
|
}
|
|
|
|
private function camelToDash($name)
|
|
{
|
|
return strtolower(preg_replace("/([A-Z]{1})/", "-\$1", $name));
|
|
}
|
|
|
|
} |