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