Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
37 / 37
100.00% covered (success)
100.00%
8 / 8
CRAP
100.00% covered (success)
100.00%
1 / 1
Cms
100.00% covered (success)
100.00%
37 / 37
100.00% covered (success)
100.00%
8 / 8
15
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 __get
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 nodes
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 node
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
 menu
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 render
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 liveReload
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 nodeFactory
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Cosray;
6
7use Cosray\Exception\RuntimeException;
8use Cosray\Field\Services;
9use Cosray\Finder\Menu;
10use Cosray\Finder\Node;
11use Cosray\Finder\Nodes;
12use Cosray\Finder\Render;
13use Cosray\Node\Factory;
14use Cosray\Node\Types;
15use Cosray\Node\Wrapper;
16use Cosray\Util\LiveReload;
17
18/**
19 * @property-read Nodes $nodes
20 * @property-read Node $node
21 */
22class Cms
23{
24    private readonly Factory $nodeFactory;
25    private readonly Types $types;
26
27    public function __construct(
28        private readonly Context $context,
29        Services $services,
30    ) {
31        $uid = $context->config->uid;
32        $this->types = $services->types;
33        $this->nodeFactory = new Factory(
34            $context->container,
35            $services,
36            new Uid($uid->alphabet, $uid->length),
37        );
38    }
39
40    public function __get(string $key): Nodes|Node|Menu
41    {
42        return match ($key) {
43            'nodes' => new Nodes($this->context, $this, $this->nodeFactory, $this->types),
44            'node' => new Node($this->context, $this, $this->nodeFactory, $this->types),
45            default => throw new RuntimeException('Property not supported'),
46        };
47    }
48
49    public function nodes(
50        string $query = '',
51    ): Nodes {
52        return new Nodes($this->context, $this, $this->nodeFactory, $this->types)->filter($query);
53    }
54
55    /**
56     * @param list<string> $types
57     * @return array<int, Wrapper>
58     */
59    public function node(
60        string $query,
61        array $types = [],
62        int $limit = 0,
63        string $order = '',
64    ): array {
65        $finder = new Nodes($this->context, $this, $this->nodeFactory, $this->types)->filter($query);
66
67        if ($types !== []) {
68            $finder->types(...$types);
69        }
70
71        if ($order !== '') {
72            $finder->order($order);
73        }
74
75        if ($limit > 0) {
76            $finder->limit($limit);
77        }
78
79        return iterator_to_array($finder);
80    }
81
82    public function menu(string $menu): Menu
83    {
84        return new Menu($this->context, $menu, $this);
85    }
86
87    /** @param array<string, mixed> $templateContext */
88    public function render(
89        string $id,
90        array $templateContext = [],
91        ?bool $deleted = false,
92        ?bool $published = true,
93    ): Markup {
94        return new Markup((string) new Render(
95            $this->context,
96            $this,
97            $this->nodeFactory,
98            $this->types,
99            $id,
100            $templateContext,
101            $deleted,
102            $published,
103        ));
104    }
105
106    /**
107     * The script tag for the dev server's live reload, or an empty string.
108     * `celema/server` only sets the script URL while running with
109     * `--watch`, so layouts can include it unconditionally.
110     */
111    public function liveReload(): Markup
112    {
113        $url = LiveReload::url($this->context->request);
114
115        return new Markup(
116            $url === null ? '' : '<script src="' . htmlspecialchars($url, ENT_QUOTES) . '" defer></script>',
117        );
118    }
119
120    public function nodeFactory(): Factory
121    {
122        return $this->nodeFactory;
123    }
124}