xref: /plugin/combo/ComboStrap/MetadataFrontmatterStore.php (revision c3437056399326d621a01da73b649707fbb0ae69)
1*c3437056SNickeau<?php
2*c3437056SNickeau
3*c3437056SNickeau
4*c3437056SNickeaunamespace ComboStrap;
5*c3437056SNickeau
6*c3437056SNickeau
7*c3437056SNickeauuse syntax_plugin_combo_frontmatter;
8*c3437056SNickeau
9*c3437056SNickeauclass MetadataFrontmatterStore extends MetadataSingleArrayStore
10*c3437056SNickeau{
11*c3437056SNickeau
12*c3437056SNickeau    const NAME = "frontmatter";
13*c3437056SNickeau    const CANONICAL = self::NAME;
14*c3437056SNickeau
15*c3437056SNickeau    /**
16*c3437056SNickeau     * @var bool Do we have a frontmatter on the page
17*c3437056SNickeau     */
18*c3437056SNickeau    private $isPresent = false;
19*c3437056SNickeau    /**
20*c3437056SNickeau     * @var string
21*c3437056SNickeau     */
22*c3437056SNickeau    private $contentWithoutFrontMatter;
23*c3437056SNickeau
24*c3437056SNickeau    /**
25*c3437056SNickeau     * @throws ExceptionCombo
26*c3437056SNickeau     */
27*c3437056SNickeau    private function syncData()
28*c3437056SNickeau    {
29*c3437056SNickeau
30*c3437056SNickeau        /**
31*c3437056SNickeau         * @var Page $resourceCombo
32*c3437056SNickeau         */
33*c3437056SNickeau        $resourceCombo = $this->getResource();
34*c3437056SNickeau
35*c3437056SNickeau        /**
36*c3437056SNickeau         * Resource Id special
37*c3437056SNickeau         */
38*c3437056SNickeau        $guidObject = $resourceCombo->getUidObject();
39*c3437056SNickeau        if (
40*c3437056SNickeau            !$this->hasProperty($guidObject::getPersistentName())
41*c3437056SNickeau            &&
42*c3437056SNickeau            $guidObject->getValue() !== null
43*c3437056SNickeau        ) {
44*c3437056SNickeau            $this->setFromPersistentName($guidObject::getPersistentName(), $guidObject->getValue());
45*c3437056SNickeau        }
46*c3437056SNickeau
47*c3437056SNickeau        /**
48*c3437056SNickeau         * Read store
49*c3437056SNickeau         */
50*c3437056SNickeau        $dokuwikiStore = MetadataDokuWikiStore::getOrCreateFromResource($resourceCombo);
51*c3437056SNickeau        $metaFilePath = $dokuwikiStore->getMetaFilePath();
52*c3437056SNickeau        if ($metaFilePath !== null) {
53*c3437056SNickeau            $metaModifiedTime = FileSystems::getModifiedTime($metaFilePath);
54*c3437056SNickeau            $pageModifiedTime = FileSystems::getModifiedTime($resourceCombo->getPath());
55*c3437056SNickeau            $diff = $pageModifiedTime->diff($metaModifiedTime);
56*c3437056SNickeau            if ($diff === false) {
57*c3437056SNickeau                throw new ExceptionCombo("Unable to calculate the diff between the page and metadata file");
58*c3437056SNickeau            }
59*c3437056SNickeau            $secondDiff = intval($diff->format('%s'));
60*c3437056SNickeau            if ($secondDiff > 0) {
61*c3437056SNickeau                $resourceCombo->renderMetadataAndFlush();
62*c3437056SNickeau            }
63*c3437056SNickeau        }
64*c3437056SNickeau        /**
65*c3437056SNickeau         * Update the mutable data
66*c3437056SNickeau         * (ie delete insert)
67*c3437056SNickeau         */
68*c3437056SNickeau        foreach (Metadata::MUTABLE_METADATA as $metaKey) {
69*c3437056SNickeau            $metadata = Metadata::getForName($metaKey);
70*c3437056SNickeau            if ($metadata === null) {
71*c3437056SNickeau                $msg = "The metadata $metaKey should be defined";
72*c3437056SNickeau                if (PluginUtility::isDevOrTest()) {
73*c3437056SNickeau                    throw new ExceptionCombo($msg);
74*c3437056SNickeau                } else {
75*c3437056SNickeau                    LogUtility::msg($msg);
76*c3437056SNickeau                }
77*c3437056SNickeau            }
78*c3437056SNickeau            $metadata
79*c3437056SNickeau                ->setResource($resourceCombo)
80*c3437056SNickeau                ->setReadStore($dokuwikiStore)
81*c3437056SNickeau                ->setWriteStore($this);
82*c3437056SNickeau
83*c3437056SNickeau            $sourceValue = $this->get($metadata);
84*c3437056SNickeau            $targetValue = $metadata->getValue();
85*c3437056SNickeau            $defaultValue = $metadata->getDefaultValue();
86*c3437056SNickeau            /**
87*c3437056SNickeau             * Strict because otherwise the comparison `false = null` is true
88*c3437056SNickeau             */
89*c3437056SNickeau            $targetValueShouldBeStore = !in_array($targetValue, [$defaultValue, null], true);
90*c3437056SNickeau            if ($targetValueShouldBeStore) {
91*c3437056SNickeau                if ($sourceValue !== $targetValue) {
92*c3437056SNickeau                    $this->set($metadata);
93*c3437056SNickeau                }
94*c3437056SNickeau            } else {
95*c3437056SNickeau                if ($sourceValue !== null) {
96*c3437056SNickeau                    $this->remove($metadata);
97*c3437056SNickeau                }
98*c3437056SNickeau            }
99*c3437056SNickeau        }
100*c3437056SNickeau    }
101*c3437056SNickeau
102*c3437056SNickeau    /**
103*c3437056SNickeau     * Update the frontmatter with the managed metadata
104*c3437056SNickeau     * Used after a submit from the form
105*c3437056SNickeau     * @return Message
106*c3437056SNickeau     */
107*c3437056SNickeau    public function sync(): Message
108*c3437056SNickeau    {
109*c3437056SNickeau
110*c3437056SNickeau        /**
111*c3437056SNickeau         * Default update value for the frontmatter
112*c3437056SNickeau         */
113*c3437056SNickeau        $updateFrontMatter = PluginUtility::getConfValue(syntax_plugin_combo_frontmatter::CONF_ENABLE_FRONT_MATTER_ON_SUBMIT, syntax_plugin_combo_frontmatter::CONF_ENABLE_FRONT_MATTER_ON_SUBMIT_DEFAULT);
114*c3437056SNickeau
115*c3437056SNickeau
116*c3437056SNickeau        if ($this->isPresent()) {
117*c3437056SNickeau            $updateFrontMatter = 1;
118*c3437056SNickeau        }
119*c3437056SNickeau
120*c3437056SNickeau
121*c3437056SNickeau        if ($updateFrontMatter === 0) {
122*c3437056SNickeau            return Message::createInfoMessage("The frontmatter is not enabled")
123*c3437056SNickeau                ->setStatus(syntax_plugin_combo_frontmatter::UPDATE_EXIT_CODE_NOT_ENABLED);
124*c3437056SNickeau        }
125*c3437056SNickeau
126*c3437056SNickeau        try {
127*c3437056SNickeau            $this->syncData();
128*c3437056SNickeau        } catch (ExceptionCombo $e) {
129*c3437056SNickeau            return Message::createInfoMessage($e->getMessage())
130*c3437056SNickeau                ->setStatus(syntax_plugin_combo_frontmatter::UPDATE_EXIT_CODE_ERROR);
131*c3437056SNickeau        }
132*c3437056SNickeau
133*c3437056SNickeau
134*c3437056SNickeau        /**
135*c3437056SNickeau         * Same ?
136*c3437056SNickeau         */
137*c3437056SNickeau        if (!$this->hasStateChanged()) {
138*c3437056SNickeau            return Message::createInfoMessage("The frontmatter are the same (no update)")
139*c3437056SNickeau                ->setStatus(syntax_plugin_combo_frontmatter::UPDATE_EXIT_CODE_NOT_CHANGED);
140*c3437056SNickeau        }
141*c3437056SNickeau
142*c3437056SNickeau        $this->persist();
143*c3437056SNickeau
144*c3437056SNickeau        return Message::createInfoMessage("The frontmatter was changed")
145*c3437056SNickeau            ->setStatus(syntax_plugin_combo_frontmatter::UPDATE_EXIT_CODE_DONE);
146*c3437056SNickeau
147*c3437056SNickeau    }
148*c3437056SNickeau
149*c3437056SNickeau
150*c3437056SNickeau    public function isPresent(): bool
151*c3437056SNickeau    {
152*c3437056SNickeau        return $this->isPresent;
153*c3437056SNickeau    }
154*c3437056SNickeau
155*c3437056SNickeau    /**
156*c3437056SNickeau     * MetadataFrontmatterStore constructor.
157*c3437056SNickeau     * @param ResourceCombo $page
158*c3437056SNickeau     * @param array|null $data
159*c3437056SNickeau     */
160*c3437056SNickeau    public function __construct(ResourceCombo $page, array $data = null)
161*c3437056SNickeau    {
162*c3437056SNickeau        parent::__construct($page, $data);
163*c3437056SNickeau    }
164*c3437056SNickeau
165*c3437056SNickeau    /**
166*c3437056SNickeau     * @param $match
167*c3437056SNickeau     * @return array|null - null if decodage problem, empty array if no json or an associative array
168*c3437056SNickeau     * @deprecated used {@link MetadataFrontmatterStore::loadAsString()} instead
169*c3437056SNickeau     */
170*c3437056SNickeau    public static function frontMatterMatchToAssociativeArray($match): ?array
171*c3437056SNickeau    {
172*c3437056SNickeau        $jsonString = self::stripFrontmatterTag($match);
173*c3437056SNickeau
174*c3437056SNickeau        // Empty front matter
175*c3437056SNickeau        if (trim($jsonString) == "") {
176*c3437056SNickeau            return [];
177*c3437056SNickeau        }
178*c3437056SNickeau
179*c3437056SNickeau        // Otherwise you get an object ie $arrayFormat-> syntax
180*c3437056SNickeau        $arrayFormat = true;
181*c3437056SNickeau        return json_decode($jsonString, $arrayFormat);
182*c3437056SNickeau    }
183*c3437056SNickeau
184*c3437056SNickeau    public static function stripFrontmatterTag($match)
185*c3437056SNickeau    {
186*c3437056SNickeau        // strip
187*c3437056SNickeau        //   from start `---json` + eol = 8
188*c3437056SNickeau        //   from end   `---` + eol = 4
189*c3437056SNickeau        return substr($match, 7, -3);
190*c3437056SNickeau    }
191*c3437056SNickeau
192*c3437056SNickeau
193*c3437056SNickeau    public static function getOrCreateFromResource(ResourceCombo $resourceCombo): MetadataStore
194*c3437056SNickeau    {
195*c3437056SNickeau        return new MetadataFrontmatterStore($resourceCombo, null);
196*c3437056SNickeau    }
197*c3437056SNickeau
198*c3437056SNickeau    public static function createFromArray(ResourceCombo $page, array $jsonArray): MetadataFrontmatterStore
199*c3437056SNickeau    {
200*c3437056SNickeau        return new MetadataFrontmatterStore($page, $jsonArray);
201*c3437056SNickeau    }
202*c3437056SNickeau
203*c3437056SNickeau    /**
204*c3437056SNickeau     * @throws ExceptionCombo
205*c3437056SNickeau     */
206*c3437056SNickeau    public static function createFromFrontmatterString($page, $frontmatter = null): MetadataFrontmatterStore
207*c3437056SNickeau    {
208*c3437056SNickeau        if ($frontmatter === null) {
209*c3437056SNickeau            return new MetadataFrontmatterStore($page, []);
210*c3437056SNickeau        }
211*c3437056SNickeau        $jsonArray = self::frontMatterMatchToAssociativeArray($frontmatter);
212*c3437056SNickeau        if ($jsonArray === null) {
213*c3437056SNickeau            throw new ExceptionCombo("The frontmatter is not valid");
214*c3437056SNickeau        }
215*c3437056SNickeau        return new MetadataFrontmatterStore($page, $jsonArray);
216*c3437056SNickeau    }
217*c3437056SNickeau
218*c3437056SNickeau    /**
219*c3437056SNickeau     * @throws ExceptionCombo
220*c3437056SNickeau     */
221*c3437056SNickeau    public static function createFromPage(Page $page): MetadataFrontmatterStore
222*c3437056SNickeau    {
223*c3437056SNickeau        $content = FileSystems::getContent($page->getPath());
224*c3437056SNickeau        $frontMatterStartTag = syntax_plugin_combo_frontmatter::START_TAG;
225*c3437056SNickeau        if (strpos($content, $frontMatterStartTag) === 0) {
226*c3437056SNickeau
227*c3437056SNickeau            /**
228*c3437056SNickeau             * Extract the actual values
229*c3437056SNickeau             */
230*c3437056SNickeau            $pattern = syntax_plugin_combo_frontmatter::PATTERN;
231*c3437056SNickeau            $split = preg_split("/($pattern)/ms", $content, 2, PREG_SPLIT_DELIM_CAPTURE);
232*c3437056SNickeau
233*c3437056SNickeau            /**
234*c3437056SNickeau             * The split normally returns an array
235*c3437056SNickeau             * where the first element is empty followed by the frontmatter
236*c3437056SNickeau             */
237*c3437056SNickeau            $emptyString = array_shift($split);
238*c3437056SNickeau            if (!empty($emptyString)) {
239*c3437056SNickeau                throw new ExceptionCombo("The frontmatter is not the first element");
240*c3437056SNickeau            }
241*c3437056SNickeau
242*c3437056SNickeau            $frontMatterMatch = array_shift($split);
243*c3437056SNickeau            /**
244*c3437056SNickeau             * Building the document again
245*c3437056SNickeau             */
246*c3437056SNickeau            $contentWithoutFrontMatter = "";
247*c3437056SNickeau            while (($element = array_shift($split)) != null) {
248*c3437056SNickeau                $contentWithoutFrontMatter .= $element;
249*c3437056SNickeau            }
250*c3437056SNickeau
251*c3437056SNickeau            return MetadataFrontmatterStore::createFromFrontmatterString($page, $frontMatterMatch)
252*c3437056SNickeau                ->setIsPresent(true)
253*c3437056SNickeau                ->setContentWithoutFrontMatter($contentWithoutFrontMatter);
254*c3437056SNickeau
255*c3437056SNickeau        }
256*c3437056SNickeau        return (new MetadataFrontmatterStore($page))
257*c3437056SNickeau            ->setIsPresent(false)
258*c3437056SNickeau            ->setContentWithoutFrontMatter($content);
259*c3437056SNickeau
260*c3437056SNickeau    }
261*c3437056SNickeau
262*c3437056SNickeau
263*c3437056SNickeau    public function __toString()
264*c3437056SNickeau    {
265*c3437056SNickeau        return self::NAME;
266*c3437056SNickeau    }
267*c3437056SNickeau
268*c3437056SNickeau
269*c3437056SNickeau    public function getJsonString(): string
270*c3437056SNickeau    {
271*c3437056SNickeau
272*c3437056SNickeau        $jsonArray = $this->getData();
273*c3437056SNickeau        ksort($jsonArray);
274*c3437056SNickeau        return self::toFrontmatterJsonString($jsonArray);
275*c3437056SNickeau
276*c3437056SNickeau    }
277*c3437056SNickeau
278*c3437056SNickeau    /**
279*c3437056SNickeau     * This formatting make the object on one line for a list of object
280*c3437056SNickeau     * making the frontmatter compacter (one line, one meta)
281*c3437056SNickeau     * @param $jsonArray
282*c3437056SNickeau     * @return string
283*c3437056SNickeau     */
284*c3437056SNickeau    public static function toFrontmatterJsonString($jsonArray): string
285*c3437056SNickeau    {
286*c3437056SNickeau
287*c3437056SNickeau        if (sizeof($jsonArray) === 0) {
288*c3437056SNickeau            return "{}";
289*c3437056SNickeau        }
290*c3437056SNickeau        $jsonString = "";
291*c3437056SNickeau        self::jsonFlatRecursiveEncoding($jsonArray, $jsonString);
292*c3437056SNickeau
293*c3437056SNickeau        /**
294*c3437056SNickeau         * Double Guard (frontmatter should be quick enough)
295*c3437056SNickeau         * to support this overhead
296*c3437056SNickeau         */
297*c3437056SNickeau        $decoding = json_decode($jsonString);
298*c3437056SNickeau        if ($decoding === null) {
299*c3437056SNickeau            throw new ExceptionComboRuntime("The generated frontmatter json is no a valid json");
300*c3437056SNickeau        }
301*c3437056SNickeau        return $jsonString;
302*c3437056SNickeau    }
303*c3437056SNickeau
304*c3437056SNickeau    private static function jsonFlatRecursiveEncoding(array $jsonProperty, &$jsonString, $level = 0, $endOfFieldCharacter = DOKU_LF, $type = Json::TYPE_OBJECT, $parentType = Json::TYPE_OBJECT)
305*c3437056SNickeau    {
306*c3437056SNickeau        /**
307*c3437056SNickeau         * Open the root object
308*c3437056SNickeau         */
309*c3437056SNickeau        if ($type === Json::TYPE_OBJECT) {
310*c3437056SNickeau            $jsonString .= "{";
311*c3437056SNickeau        } else {
312*c3437056SNickeau            $jsonString .= "[";
313*c3437056SNickeau        }
314*c3437056SNickeau
315*c3437056SNickeau        /**
316*c3437056SNickeau         * Level indentation
317*c3437056SNickeau         */
318*c3437056SNickeau        $levelSpaceIndentation = str_repeat(" ", ($level + 1) * Json::TAB_SPACES_COUNTER);
319*c3437056SNickeau
320*c3437056SNickeau        /**
321*c3437056SNickeau         * Loop
322*c3437056SNickeau         */
323*c3437056SNickeau        $elementCounter = 0;
324*c3437056SNickeau        foreach ($jsonProperty as $key => $value) {
325*c3437056SNickeau
326*c3437056SNickeau            $elementCounter++;
327*c3437056SNickeau
328*c3437056SNickeau            /**
329*c3437056SNickeau             * Close the previous property
330*c3437056SNickeau             */
331*c3437056SNickeau            $isFirstProperty = $elementCounter === 1;
332*c3437056SNickeau            if ($isFirstProperty && $parentType !== Json::PARENT_TYPE_ARRAY) {
333*c3437056SNickeau                // go the line if this is not a list of object
334*c3437056SNickeau                $jsonString .= DOKU_LF;
335*c3437056SNickeau            }
336*c3437056SNickeau            if (!$isFirstProperty) {
337*c3437056SNickeau                $jsonString .= ",$endOfFieldCharacter";
338*c3437056SNickeau            }
339*c3437056SNickeau            if ($endOfFieldCharacter === DOKU_LF) {
340*c3437056SNickeau                $tab = $levelSpaceIndentation;
341*c3437056SNickeau            } else {
342*c3437056SNickeau                $tab = " ";
343*c3437056SNickeau            }
344*c3437056SNickeau            $jsonString .= $tab;
345*c3437056SNickeau
346*c3437056SNickeau            /**
347*c3437056SNickeau             * Recurse
348*c3437056SNickeau             */
349*c3437056SNickeau            $jsonEncodedKey = json_encode($key);
350*c3437056SNickeau            if (is_array($value)) {
351*c3437056SNickeau                $childLevel = $level + 1;
352*c3437056SNickeau                if (is_numeric($key)) {
353*c3437056SNickeau                    /**
354*c3437056SNickeau                     * List of object
355*c3437056SNickeau                     */
356*c3437056SNickeau                    $childType = Json::TYPE_OBJECT;
357*c3437056SNickeau                    $childEndOField = "";
358*c3437056SNickeau                } else {
359*c3437056SNickeau                    /**
360*c3437056SNickeau                     * Array
361*c3437056SNickeau                     */
362*c3437056SNickeau                    $jsonString .= "$jsonEncodedKey: ";
363*c3437056SNickeau                    $childType = Json::TYPE_OBJECT;
364*c3437056SNickeau                    if ($value[0] !== null) {
365*c3437056SNickeau                        $childType = Json::PARENT_TYPE_ARRAY;
366*c3437056SNickeau                    }
367*c3437056SNickeau                    $childEndOField = $endOfFieldCharacter;
368*c3437056SNickeau                }
369*c3437056SNickeau                self::jsonFlatRecursiveEncoding($value, $jsonString, $childLevel, $childEndOField, $childType, $type);
370*c3437056SNickeau
371*c3437056SNickeau            } else {
372*c3437056SNickeau                /**
373*c3437056SNickeau                 * Single property
374*c3437056SNickeau                 */
375*c3437056SNickeau                $jsonEncodedValue = json_encode($value);
376*c3437056SNickeau                $jsonString .= "$jsonEncodedKey: $jsonEncodedValue";
377*c3437056SNickeau
378*c3437056SNickeau            }
379*c3437056SNickeau
380*c3437056SNickeau        }
381*c3437056SNickeau
382*c3437056SNickeau        /**
383*c3437056SNickeau         * Close the object or array
384*c3437056SNickeau         */
385*c3437056SNickeau        $closingLevelSpaceIndentation = str_repeat(" ", $level * Json::TAB_SPACES_COUNTER);
386*c3437056SNickeau        if ($type === Json::TYPE_OBJECT) {
387*c3437056SNickeau            if ($parentType !== Json::PARENT_TYPE_ARRAY) {
388*c3437056SNickeau                $jsonString .= DOKU_LF . $closingLevelSpaceIndentation;
389*c3437056SNickeau            } else {
390*c3437056SNickeau                $jsonString .= " ";
391*c3437056SNickeau            }
392*c3437056SNickeau            $jsonString .= "}";
393*c3437056SNickeau        } else {
394*c3437056SNickeau            /**
395*c3437056SNickeau             * The array is not going one level back
396*c3437056SNickeau             */
397*c3437056SNickeau            $jsonString .= DOKU_LF . $closingLevelSpaceIndentation . "]";
398*c3437056SNickeau        }
399*c3437056SNickeau    }
400*c3437056SNickeau
401*c3437056SNickeau
402*c3437056SNickeau    public function toFrontmatterString(): string
403*c3437056SNickeau    {
404*c3437056SNickeau        $frontmatterStartTag = syntax_plugin_combo_frontmatter::START_TAG;
405*c3437056SNickeau        $frontmatterEndTag = syntax_plugin_combo_frontmatter::END_TAG;
406*c3437056SNickeau        $jsonArray = $this->getData();
407*c3437056SNickeau        ksort($jsonArray);
408*c3437056SNickeau        $jsonEncode = self::toFrontmatterJsonString($jsonArray);
409*c3437056SNickeau
410*c3437056SNickeau        return <<<EOF
411*c3437056SNickeau$frontmatterStartTag
412*c3437056SNickeau$jsonEncode
413*c3437056SNickeau$frontmatterEndTag
414*c3437056SNickeauEOF;
415*c3437056SNickeau
416*c3437056SNickeau
417*c3437056SNickeau    }
418*c3437056SNickeau
419*c3437056SNickeau    private function setIsPresent(bool $bool): MetadataFrontmatterStore
420*c3437056SNickeau    {
421*c3437056SNickeau        $this->isPresent = $bool;
422*c3437056SNickeau        return $this;
423*c3437056SNickeau    }
424*c3437056SNickeau
425*c3437056SNickeau    public function persist()
426*c3437056SNickeau    {
427*c3437056SNickeau        if ($this->contentWithoutFrontMatter === null) {
428*c3437056SNickeau            LogUtility::msg("The content without frontmatter should have been set. Did you you use the createFromPage constructor");
429*c3437056SNickeau            return $this;
430*c3437056SNickeau        }
431*c3437056SNickeau        $targetFrontMatterJsonString = $this->toFrontmatterString();
432*c3437056SNickeau
433*c3437056SNickeau        /**
434*c3437056SNickeau         * EOL for the first frontmatter
435*c3437056SNickeau         */
436*c3437056SNickeau        $sep = "";
437*c3437056SNickeau        if (strlen($this->contentWithoutFrontMatter) > 0) {
438*c3437056SNickeau            $firstChar = $this->contentWithoutFrontMatter[0];
439*c3437056SNickeau            if (!in_array($firstChar, ["\n", "\r"])) {
440*c3437056SNickeau                $sep = "\n";
441*c3437056SNickeau            }
442*c3437056SNickeau        }
443*c3437056SNickeau
444*c3437056SNickeau        /**
445*c3437056SNickeau         * Build the new document
446*c3437056SNickeau         */
447*c3437056SNickeau        $newPageContent = <<<EOF
448*c3437056SNickeau$targetFrontMatterJsonString$sep$this->contentWithoutFrontMatter
449*c3437056SNickeauEOF;
450*c3437056SNickeau        $resourceCombo = $this->getResource();
451*c3437056SNickeau        if ($resourceCombo instanceof Page) {
452*c3437056SNickeau            $resourceCombo->upsertContent($newPageContent, "Metadata frontmatter store upsert");
453*c3437056SNickeau        }
454*c3437056SNickeau        return $this;
455*c3437056SNickeau    }
456*c3437056SNickeau
457*c3437056SNickeau    private function setContentWithoutFrontMatter(string $contentWithoutFrontMatter): MetadataFrontmatterStore
458*c3437056SNickeau    {
459*c3437056SNickeau        $this->contentWithoutFrontMatter = $contentWithoutFrontMatter;
460*c3437056SNickeau        return $this;
461*c3437056SNickeau    }
462*c3437056SNickeau
463*c3437056SNickeau
464*c3437056SNickeau}
465