1<?php
2
3
4namespace ComboStrap;
5
6
7use ComboStrap\Meta\Api\Metadata;
8use ComboStrap\Meta\Store\MetadataDokuWikiStore;
9use ComboStrap\Meta\Api\MetadataStoreAbs;
10
11/**
12 * Class MetadataArrayStore
13 * @package ComboStrap
14 * A store based on a single array for a single resource
15 */
16abstract class MetadataSingleArrayStore extends MetadataStoreAbs
17{
18
19
20    /**
21     * @var bool
22     */
23    protected bool $hasChanged = false;
24
25    protected array $data = [];
26
27    /**
28     * MetadataSingleArrayStore constructor.
29     * @param ResourceCombo $page
30     * @param $data
31     */
32    public function __construct(ResourceCombo $page, $data = null)
33    {
34        if ($data !== null) {
35            foreach ($data as $key => $value) {
36                $key = $this->toNormalizedKey($key);
37                $this->data[$key] = $value;
38            }
39        }
40        parent::__construct($page);
41    }
42
43
44    public function set(Metadata $metadata)
45    {
46        $this->checkResource($metadata->getResource());
47        $this->setFromPersistentName($metadata::getPersistentName(), $metadata->toStoreValue());
48    }
49
50    public function get(Metadata $metadata, $default = null)
51    {
52        $this->checkResource($metadata->getResource());
53        $value = $this->data[$metadata::getPersistentName()] ?? null;
54        if ($value !== null) {
55            return $value;
56        }
57        foreach ($metadata::getOldPersistentNames() as $name) {
58            $value = $this->data[$name] ?? null;
59            if ($value !== null) {
60                $this->data[$metadata::getPersistentName()] = $value;
61                unset($this->data[$name]);
62                return $value;
63            }
64        }
65        return $default;
66    }
67
68    public function persist()
69    {
70        if (PluginUtility::isDevOrTest()) {
71            throw new ExceptionRuntime("Not yet implemented, use sendToStore");
72        }
73    }
74
75    public function isHierarchicalTextBased(): bool
76    {
77        return true;
78    }
79
80
81    public function getData(): array
82    {
83        return $this->data;
84    }
85
86
87    public function reset()
88    {
89        $this->data = [];
90    }
91
92    public function getFromName(string $name, $default = null)
93    {
94
95        $value = $this->data[$name] ?? null;
96        if ($value !== null) {
97            return $value;
98        }
99        return $default;
100    }
101
102    public function setFromPersistentName(string $name, $value, $default = null)
103    {
104        $actualValue = $this->data[$name] ?? null;
105        if ($actualValue !== $value) {
106            $this->hasChanged = true;
107        }
108
109        $name = $this->toNormalizedKey($name);
110        if ($value === null || $value === "") {
111            // remove
112            unset($this->data[$name]);
113            return;
114        }
115        $this->data[$name] = $value;
116
117    }
118
119
120    public function hasProperty(string $name): bool
121    {
122        $var = $this->data[$name] ?? null;
123        return isset($var);
124    }
125
126    public function remove(Metadata $metadata): MetadataSingleArrayStore
127    {
128        $this->checkResource($metadata->getResource());
129        $this->setFromPersistentName($metadata->getName(), null);
130        return $this;
131    }
132
133    private function toNormalizedKey(string $key): string
134    {
135        return trim($key);
136    }
137
138    /**
139     * Used to update the data from an other external process
140     * (ie
141     *    {@link MetadataDokuWikiStore::renderAndPersist() metadata renderer}
142     *    or {@link \action_plugin_combo_metamanager::handleViewerPost() metadata manager
143     * )
144     * @param $data
145     */
146    public function setData($data)
147    {
148        if ($data !== $this->data) {
149            $this->hasChanged = true;
150        }
151        $this->data = $data;
152    }
153
154    /**
155     * @return bool - true if the data has changed
156     */
157    public function hasStateChanged(): bool
158    {
159        return $this->hasChanged;
160    }
161
162
163}
164