1<?php
2
3
4namespace ComboStrap;
5
6
7use syntax_plugin_combo_frontmatter;
8
9class PageDescription extends MetadataText
10{
11    /**
12     * The description sub key in the dokuwiki meta
13     * that has the description text
14     */
15    const ABSTRACT_KEY = "abstract";
16    public const PROPERTY_NAME = "description";
17    const DESCRIPTION_ORIGIN = "origin";
18    const PLUGIN_DESCRIPTION_META = "plugin_description";
19
20
21    /**
22     * @var string - the origin of the description
23     */
24    private $descriptionOrigin;
25
26
27    public const DESCRIPTION_PROPERTY = "description";
28    /**
29     * To indicate from where the description comes
30     * This is when it's the original dokuwiki description
31     */
32    public const DESCRIPTION_DOKUWIKI_ORIGIN = "dokuwiki";
33    /**
34     * The origin of the description was set to frontmatter
35     * due to historic reason to say to it comes from combo
36     * (You may set it via the metadata manager and get this origin)
37     */
38    public const DESCRIPTION_COMBO_ORIGIN = syntax_plugin_combo_frontmatter::CANONICAL;
39    private $defaultValue;
40
41    public static function createForPage($page): PageDescription
42    {
43        return (new PageDescription())
44            ->setResource($page);
45    }
46
47    public function getTab(): string
48    {
49        return MetaManagerForm::TAB_PAGE_VALUE;
50    }
51
52    public function getDescription(): string
53    {
54        return "The description is a paragraph that describe your page. It's advertised to external application and used in templating.";
55    }
56
57    public function getLabel(): string
58    {
59        return "Description";
60    }
61
62    static public function getName(): string
63    {
64        return self::DESCRIPTION_PROPERTY;
65    }
66
67    public function getPersistenceType(): string
68    {
69        return MetadataDokuWikiStore::PERSISTENT_METADATA;
70    }
71
72    public function getDataType(): string
73    {
74        return DataType::PARAGRAPH_TYPE_VALUE;
75    }
76
77
78    public function getMutable(): bool
79    {
80        return true;
81    }
82
83    /**
84     * @return string|null - the dokuwiki calculated description
85     *
86     */
87    public function getDefaultValue(): ?string
88    {
89
90        $this->buildCheck();
91        return $this->defaultValue;
92
93    }
94
95
96    public function buildFromStoreValue($value): Metadata
97    {
98
99        $metaDataStore = $this->getReadStore();
100        if (!($metaDataStore instanceof MetadataDokuWikiStore)) {
101            parent::buildFromStoreValue($value);
102            return $this;
103        }
104
105        if ($value !== null && is_array($value)) {
106            $description = $value[self::ABSTRACT_KEY];
107            if ($description !== null) {
108                $this->descriptionOrigin = $value[self::DESCRIPTION_ORIGIN];
109                parent::buildFromStoreValue($description);
110                return $this;
111            }
112        }
113        /**
114         * Plugin Plugin Description Integration
115         */
116        $value = $metaDataStore->getFromPersistentName(self::PLUGIN_DESCRIPTION_META);
117        if ($value !== null) {
118            $keywords = $value["keywords"];
119            if ($keywords !== null) {
120                parent::buildFromStoreValue($keywords);
121                $this->descriptionOrigin = self::PLUGIN_DESCRIPTION_META;
122                return $this;
123            }
124        }
125
126        /**
127         * No description set, null
128         */
129        parent::buildFromStoreValue(null);
130
131        /**
132         * Default value is derived from the meta store
133         * We need to set it at build time because the store may change
134         * after the build
135         */
136        $this->defaultValue = $this->getGeneratedValueFromDokuWikiStore($metaDataStore);
137
138        return $this;
139    }
140
141
142    public function setValue($value): Metadata
143    {
144
145        if ($value === "" || $value === null) {
146
147            if ($this->getReadStore() instanceof MetadataDokuWikiStore) {
148                // we need to know the origin of the actual description
149                if ($this->descriptionOrigin === null) {
150                    /**
151                     * we don't do {@link Metadata::buildCheck() build check} otherwise we get a loop
152                     * because it will use back this method {@link Metadata::setValue()}
153                     */
154                    $this->buildFromReadStore();
155                }
156                if ($this->descriptionOrigin === PageDescription::DESCRIPTION_COMBO_ORIGIN) {
157                    throw new ExceptionCombo("The description cannot be empty", PageDescription::DESCRIPTION_PROPERTY);
158                } else {
159                    // The original description is from Dokuwiki, we don't send an error
160                    // otherwise all page without a first description would get an error
161                    // (What fucked up is fucked up)
162                    return $this;
163                }
164            }
165
166        }
167
168        parent::setValue($value);
169        return $this;
170    }
171
172    /**
173     * @return string|array
174     */
175    public function toStoreValue()
176    {
177        $metaDataStore = $this->getWriteStore();
178        if (!($metaDataStore instanceof MetadataDokuWikiStore)) {
179            return parent::toStoreValue();
180        }
181        /**
182         * For dokuwiki, this is an array
183         */
184        return array(
185            self::ABSTRACT_KEY => $this->getValue(),
186            self::DESCRIPTION_ORIGIN => PageDescription::DESCRIPTION_COMBO_ORIGIN
187        );
188    }
189
190    public function getCanonical(): string
191    {
192        return $this->getName();
193    }
194
195    public function getDescriptionOrigin(): string
196    {
197        return $this->descriptionOrigin;
198    }
199
200    private function getGeneratedValueFromDokuWikiStore(MetadataDokuWikiStore $metaDataStore): ?string
201    {
202
203        /**
204         * The generated is in the current metadata
205         */
206        $descriptionArray = $metaDataStore->getCurrentFromName(self::PROPERTY_NAME);
207        if (empty($descriptionArray)) {
208            return null;
209        }
210        if (!array_key_exists(self::ABSTRACT_KEY, $descriptionArray)) {
211            return null;
212        }
213        $value = $descriptionArray[self::ABSTRACT_KEY];
214
215
216        /**
217         * Dokuwiki description
218         * With some trick
219         * TODO: Generate our own description ?
220         */
221        // suppress the carriage return
222        $description = str_replace("\n", " ", $value);
223        // suppress the h1
224        $resourceCombo = $this->getResource();
225        if ($resourceCombo instanceof Page) {
226            $description = str_replace($resourceCombo->getH1OrDefault(), "", $description);
227        }
228        // Suppress the star, the tab, About
229        $description = preg_replace('/(\*|\t|About)/im', "", $description);
230        // Suppress all double space and trim
231        return trim(preg_replace('/  /m', " ", $description));
232    }
233
234
235}
236