1<?php
2
3
4use ComboStrap\ExceptionNotFound;
5use ComboStrap\ExceptionRuntimeInternal;
6use ComboStrap\ExecutionContext;
7use ComboStrap\LogUtility;
8use ComboStrap\MarkupPath;
9use ComboStrap\Meta\Api\Metadata;
10use ComboStrap\Meta\Api\MetadataSystem;
11use ComboStrap\MetadataDokuWikiArrayStore;
12use ComboStrap\MetadataFrontmatterStore;
13use ComboStrap\MetadataMutation;
14use ComboStrap\Meta\Field\PageImages;
15use ComboStrap\PluginUtility;
16use ComboStrap\References;
17
18/**
19 *
20 * Handle meta rendering processing
21 * * notifiy of changes
22 * * and other
23 *
24 *
25 * The changes notification takes place at the document level
26 * because we want to notify modication on array level (such as references, images)
27 * and not only on scalar.
28 */
29class action_plugin_combo_metaprocessing extends DokuWiki_Action_Plugin
30{
31
32
33    private array $beforeMetaArray;
34
35    public function register(Doku_Event_Handler $controller)
36    {
37        /**
38         * https://www.dokuwiki.org/devel:event:parser_metadata_render
39         */
40        $controller->register_hook('PARSER_METADATA_RENDER', 'BEFORE', $this, 'metadataProcessingBefore', array());
41        $controller->register_hook('PARSER_METADATA_RENDER', 'AFTER', $this, 'metadataProcessingAfter', array());
42
43
44    }
45
46
47    function metadataProcessingBefore($event)
48    {
49
50        /**
51         * Capture the before state
52         */
53        if (isset($this->beforeMetaArray)) {
54            throw new ExceptionRuntimeInternal("The before variable should be unset in the after method");
55        }
56        $this->beforeMetaArray = $event->data;
57    }
58
59    function metadataProcessingAfter($event)
60    {
61
62        $afterMetaArray = &$event->data;
63        $beforeMetaArray = $this->beforeMetaArray;
64        unset($this->beforeMetaArray);
65
66        $afterId = $afterMetaArray["page"];
67        $beforeId = $beforeMetaArray["page"];
68        if ($afterId !== $beforeId) {
69            LogUtility::internalError("The before ($beforeId) and after id ($afterId) are not the same", get_class($this));
70            return;
71        }
72
73        /**
74         * To avoid
75         * Console Info: slot_footer.xhtml: Cache (1681473480)
76         * is older than dependent C:\Users\GERARD~1\AppData\Local\Temp\dwtests-1681473476.2836\data\meta\cache_manager_slot_test.meta (1681473480), cache is not usable
77         * See {@link \ComboStrap\Test\TestUtility::WaitToCreateCacheFile1SecLater()}
78         */
79        if(PluginUtility::isDevOrTest()){
80            sleep(1);
81        }
82
83        $page = MarkupPath::createMarkupFromId($afterId);
84
85        $primaryMetas = action_plugin_combo_pageprimarymetamutation::PRIMARY_METAS;
86        $referencesAttributes = [References::getPersistentName()];
87        $qualityMetadata = action_plugin_combo_qualitymutation::getQualityMetas();
88        $attributes = array_merge($primaryMetas, $referencesAttributes, $qualityMetadata);
89
90        $beforeStore = MetadataDokuWikiArrayStore::getOrCreateFromResource($page, $beforeMetaArray);
91        $afterStore = MetadataDokuWikiArrayStore::getOrCreateFromResource($page, $afterMetaArray);
92        /**
93         * The data should be formatted as if it was for the frontmatter
94         * TODO: make it a default for the mutation system ??
95         */
96        $targetStoreFormat = MetadataFrontmatterStore::class;
97        foreach ($attributes as $attribute) {
98
99            try {
100                $beforeMeta = MetadataSystem::getForName($attribute)
101                    ->setReadStore($beforeStore)
102                    ->setWriteStore($targetStoreFormat)
103                    ->setResource($page);
104                $afterMeta = MetadataSystem::getForName($attribute)
105                    ->setReadStore($afterStore)
106                    ->setWriteStore($targetStoreFormat)
107                    ->setResource($page);
108            } catch (ExceptionNotFound $e) {
109                LogUtility::internalError("The metadata was not found for the attribute ($attribute)");
110                continue;
111            }
112
113            try {
114                $beforeMeta->getValue();
115                $valueBefore = $beforeMeta->toStoreValue();
116            } catch (Exception $e) {
117                // first value
118                $valueBefore = null;
119            }
120
121            $valueAfter = $afterMeta->toStoreValue();
122            MetadataMutation::notifyMetadataMutation($attribute, $valueBefore, $valueAfter, $page);
123
124        }
125
126        /**
127         * Trick, don't know if this is always true
128         */
129        PageImages::createForPage($page)->modifyMetaDokuWikiArray($event->data);
130
131    }
132
133}
134