Issues (4)

src/Builder/Html/HtmlBuilder.php (1 issue)

Labels
Severity
1
<?php
2
3
namespace Lagdo\UiBuilder\Builder\Html;
4
5
use Lagdo\UiBuilder\Element\ElementInterface;
6
use Closure;
7
use LogicException;
8
9
use function preg_replace;
10
use function stripos;
11
use function strlen;
12
use function strtolower;
13
use function substr;
14
15
class HtmlBuilder
16
{
17
    /**
18
     * @var array<string, Closure>
19
     */
20
    protected $elementBuilders = [];
21
22
    /**
23
     * The constructor
24
     */
25
    public function __construct()
26
    {
27
        $this->addElementBuilder('set', function(Element|null $element,
28
            string $tagName, string $method, array $arguments) {
29
            if ($element === null) {
30
                throw new LogicException('Attributes can be set for elements only');
31
            }
32
            $element->attributes[$tagName] = $arguments[0] ?? null;
33
            return $element;
34
        });
35
    }
36
37
    /**
38
     * @template T of Element
39
     * @param string $name
40
     * @param array $arguments
41
     * @psalm-param class-string<T> $class
42
     *
43
     * @return T
0 ignored issues
show
The type Lagdo\UiBuilder\Builder\Html\T was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
44
     */
45
    public function createElement(string $name, array $arguments = [],
46
        string $class = Element::class): mixed
47
    {
48
        return new $class($this, $name, $arguments);
49
    }
50
51
    /**
52
     * @param string $tagPrefix
53
     * @param Closure $elementBuilder
54
     *
55
     * @return void
56
     */
57
    public function addElementBuilder(string $tagPrefix, Closure $elementBuilder)
58
    {
59
        // Do not overwrite existing builders.
60
        if(!isset($this->elementBuilders[$tagPrefix]))
61
        {
62
            $this->elementBuilders[$tagPrefix] = $elementBuilder;
63
        }
64
    }
65
66
    /**
67
     * @param string $method
68
     * @param array $arguments
69
     * @param Element|null $element
70
     *
71
     * @return ElementInterface
72
     * @throws LogicException When element is not initialized yet
73
     */
74
    public function make(string $method, array $arguments, Element|null $element = null): ElementInterface
75
    {
76
        $tagName = strtolower(preg_replace('/(?<!^)([A-Z])/', '-$1', $method));
77
        foreach($this->elementBuilders as $tagPrefix => $elementBuilder)
78
        {
79
            if (stripos($tagName, "$tagPrefix-") === 0) {
80
                $tagName = substr($tagName, strlen($tagPrefix) + 1);
81
                return $elementBuilder($element, $tagName, $method, $arguments);
82
            }
83
        }
84
        return $this->createElement($tagName, $arguments);
85
    }
86
87
    /**
88
     * @param string $name
89
     *
90
     * @return Element
91
     */
92
    public function tag(string $name, ...$arguments): Element
93
    {
94
        return $this->createElement($name, $arguments);
95
    }
96
97
    /**
98
     * @param array $arguments
99
     *
100
     * @return string
101
     */
102
    public function build(array $arguments): string
103
    {
104
        // The "root" element below will not be printed.
105
        $scope = new Scope($this->createElement('root'));
106
        $scope->build($arguments);
107
        return $scope->html();
108
    }
109
}
110