1<?php
2
3
4namespace ComboStrap;
5
6
7/**
8 * Class MetadataArrayStore
9 * @package ComboStrap
10 * A store based on a single array for a single resource
11 */
12abstract class MetadataSingleArrayStore extends MetadataStoreAbs
13{
14
15
16    /**
17     * @var bool
18     */
19    protected $hasChanged = false;
20
21    protected $data;
22
23    /**
24     * MetadataSingleArrayStore constructor.
25     * @param ResourceCombo $page
26     * @param $data
27     */
28    public function __construct(ResourceCombo $page, $data = null)
29    {
30        if($data!==null) {
31            foreach ($data as $key => $value) {
32                $key = $this->toNormalizedKey($key);
33                $this->data[$key] = $value;
34            }
35        }
36        parent::__construct($page);
37    }
38
39
40    public function set(Metadata $metadata)
41    {
42        $this->checkResource($metadata->getResource());
43        $this->setFromPersistentName($metadata::getPersistentName(), $metadata->toStoreValue());
44    }
45
46    public function get(Metadata $metadata, $default = null)
47    {
48        $this->checkResource($metadata->getResource());
49        $value = $this->data[$metadata::getPersistentName()];
50        if ($value !== null) {
51            return $value;
52        }
53        foreach ($metadata::getOldPersistentNames() as $name) {
54            $value = $this->data[$name];
55            if ($value !== null) {
56                $this->data[$metadata::getPersistentName()] = $value;
57                unset($this->data[$name]);
58                return $value;
59            }
60        }
61        return $default;
62    }
63
64    public function persist()
65    {
66        if (PluginUtility::isDevOrTest()) {
67            throw new ExceptionComboRuntime("Not yet implemented, use sendToStore");
68        }
69    }
70
71    public function isHierarchicalTextBased(): bool
72    {
73        return true;
74    }
75
76
77    public function getData(): ?array
78    {
79        if (!is_array($this->data)){
80            $class = get_class($this->data);
81            LogUtility::msg("Error: The data set for the metadata ($this) was not an array but a $class");
82            return null;
83        }
84        return $this->data;
85    }
86
87
88    public function reset()
89    {
90        $this->data = null;
91    }
92
93    public function getFromPersistentName(string $name, $default = null)
94    {
95
96        $value = $this->data[$name];
97        if ($value !== null) {
98            return $value;
99        }
100        return $default;
101    }
102
103    public function setFromPersistentName(string $name, $value)
104    {
105        $actualValue = $this->data[$name];
106        if ($actualValue !== $value) {
107            $this->hasChanged = true;
108        }
109
110        $name = $this->toNormalizedKey($name);
111        if ($value === null || $value === "") {
112            // remove
113            unset($this->data[$name]);
114            return;
115        }
116        $this->data[$name] = $value;
117
118    }
119
120
121    public function hasProperty(string $name): bool
122    {
123        return isset($this->data[$name]);
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