xref: /plugin/combo/action/metaprocessing.php (revision 657b6da49858ff4f3676e3f57c04fe7930f9e190)
104fd306cSNickeau<?php
204fd306cSNickeau
304fd306cSNickeau
404fd306cSNickeauuse ComboStrap\ExceptionNotFound;
504fd306cSNickeauuse ComboStrap\ExceptionRuntimeInternal;
604fd306cSNickeauuse ComboStrap\ExecutionContext;
704fd306cSNickeauuse ComboStrap\LogUtility;
804fd306cSNickeauuse ComboStrap\MarkupPath;
904fd306cSNickeauuse ComboStrap\Meta\Api\MetadataSystem;
10*657b6da4Sgerardnicouse ComboStrap\Meta\Field\PageH1;
11*657b6da4Sgerardnicouse ComboStrap\Meta\Field\PageImages;
12*657b6da4Sgerardnicouse ComboStrap\Meta\Store\MetadataDokuWikiStore;
1304fd306cSNickeauuse ComboStrap\MetadataDokuWikiArrayStore;
1404fd306cSNickeauuse ComboStrap\MetadataFrontmatterStore;
1504fd306cSNickeauuse ComboStrap\MetadataMutation;
1604fd306cSNickeauuse ComboStrap\PluginUtility;
1704fd306cSNickeauuse ComboStrap\References;
1804fd306cSNickeau
1904fd306cSNickeau/**
2004fd306cSNickeau *
2104fd306cSNickeau * Handle meta rendering processing
2204fd306cSNickeau * * notifiy of changes
2304fd306cSNickeau * * and other
2404fd306cSNickeau *
2504fd306cSNickeau *
2604fd306cSNickeau * The changes notification takes place at the document level
2704fd306cSNickeau * because we want to notify modication on array level (such as references, images)
2804fd306cSNickeau * and not only on scalar.
2904fd306cSNickeau */
3004fd306cSNickeauclass action_plugin_combo_metaprocessing extends DokuWiki_Action_Plugin
3104fd306cSNickeau{
3204fd306cSNickeau
3304fd306cSNickeau
3404fd306cSNickeau    private array $beforeMetaArray;
3504fd306cSNickeau
3604fd306cSNickeau    public function register(Doku_Event_Handler $controller)
3704fd306cSNickeau    {
3804fd306cSNickeau        /**
3904fd306cSNickeau         * https://www.dokuwiki.org/devel:event:parser_metadata_render
4004fd306cSNickeau         */
4104fd306cSNickeau        $controller->register_hook('PARSER_METADATA_RENDER', 'BEFORE', $this, 'metadataProcessingBefore', array());
4204fd306cSNickeau        $controller->register_hook('PARSER_METADATA_RENDER', 'AFTER', $this, 'metadataProcessingAfter', array());
4304fd306cSNickeau
4404fd306cSNickeau
4504fd306cSNickeau    }
4604fd306cSNickeau
4704fd306cSNickeau
4804fd306cSNickeau    function metadataProcessingBefore($event)
4904fd306cSNickeau    {
5004fd306cSNickeau
5104fd306cSNickeau        /**
5204fd306cSNickeau         * Capture the before state
5304fd306cSNickeau         */
5404fd306cSNickeau        if (isset($this->beforeMetaArray)) {
5504fd306cSNickeau            throw new ExceptionRuntimeInternal("The before variable should be unset in the after method");
5604fd306cSNickeau        }
5704fd306cSNickeau        $this->beforeMetaArray = $event->data;
5804fd306cSNickeau    }
5904fd306cSNickeau
6004fd306cSNickeau    function metadataProcessingAfter($event)
6104fd306cSNickeau    {
6204fd306cSNickeau
6304fd306cSNickeau        $afterMetaArray = &$event->data;
6404fd306cSNickeau        $beforeMetaArray = $this->beforeMetaArray;
6504fd306cSNickeau        unset($this->beforeMetaArray);
6604fd306cSNickeau
6704fd306cSNickeau        $afterId = $afterMetaArray["page"];
6804fd306cSNickeau        $beforeId = $beforeMetaArray["page"];
6904fd306cSNickeau        if ($afterId !== $beforeId) {
7004fd306cSNickeau            LogUtility::internalError("The before ($beforeId) and after id ($afterId) are not the same", get_class($this));
7104fd306cSNickeau            return;
7204fd306cSNickeau        }
7304fd306cSNickeau
7404fd306cSNickeau        /**
7504fd306cSNickeau         * To avoid
7604fd306cSNickeau         * Console Info: slot_footer.xhtml: Cache (1681473480)
7704fd306cSNickeau         * 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
7804fd306cSNickeau         * See {@link \ComboStrap\Test\TestUtility::WaitToCreateCacheFile1SecLater()}
7904fd306cSNickeau         */
8004fd306cSNickeau        if (PluginUtility::isDevOrTest()) {
8104fd306cSNickeau            sleep(1);
8204fd306cSNickeau        }
8304fd306cSNickeau
8404fd306cSNickeau        $page = MarkupPath::createMarkupFromId($afterId);
8504fd306cSNickeau
8604fd306cSNickeau        $primaryMetas = action_plugin_combo_pageprimarymetamutation::PRIMARY_METAS;
8704fd306cSNickeau        $referencesAttributes = [References::getPersistentName()];
8804fd306cSNickeau        $qualityMetadata = action_plugin_combo_qualitymutation::getQualityMetas();
8904fd306cSNickeau        $attributes = array_merge($primaryMetas, $referencesAttributes, $qualityMetadata);
9004fd306cSNickeau
9104fd306cSNickeau        $beforeStore = MetadataDokuWikiArrayStore::getOrCreateFromResource($page, $beforeMetaArray);
9204fd306cSNickeau        $afterStore = MetadataDokuWikiArrayStore::getOrCreateFromResource($page, $afterMetaArray);
9304fd306cSNickeau        /**
9404fd306cSNickeau         * The data should be formatted as if it was for the frontmatter
9504fd306cSNickeau         * TODO: make it a default for the mutation system ??
9604fd306cSNickeau         */
9704fd306cSNickeau        $targetStoreFormat = MetadataFrontmatterStore::class;
9804fd306cSNickeau        foreach ($attributes as $attribute) {
9904fd306cSNickeau
10004fd306cSNickeau            try {
10104fd306cSNickeau                $beforeMeta = MetadataSystem::getForName($attribute)
10204fd306cSNickeau                    ->setReadStore($beforeStore)
10304fd306cSNickeau                    ->setWriteStore($targetStoreFormat)
10404fd306cSNickeau                    ->setResource($page);
10504fd306cSNickeau                $afterMeta = MetadataSystem::getForName($attribute)
10604fd306cSNickeau                    ->setReadStore($afterStore)
10704fd306cSNickeau                    ->setWriteStore($targetStoreFormat)
10804fd306cSNickeau                    ->setResource($page);
10904fd306cSNickeau            } catch (ExceptionNotFound $e) {
11004fd306cSNickeau                LogUtility::internalError("The metadata was not found for the attribute ($attribute)");
11104fd306cSNickeau                continue;
11204fd306cSNickeau            }
11304fd306cSNickeau
11414735bf4Sgerardnico            try {
11514735bf4Sgerardnico                $beforeMeta->getValue();
11604fd306cSNickeau                $valueBefore = $beforeMeta->toStoreValue();
11714735bf4Sgerardnico            } catch (Exception $e) {
11814735bf4Sgerardnico                // first value
11914735bf4Sgerardnico                $valueBefore = null;
12014735bf4Sgerardnico            }
12104fd306cSNickeau
12214735bf4Sgerardnico            $valueAfter = $afterMeta->toStoreValue();
12304fd306cSNickeau            MetadataMutation::notifyMetadataMutation($attribute, $valueBefore, $valueAfter, $page);
12414735bf4Sgerardnico
12504fd306cSNickeau        }
12604fd306cSNickeau
127*657b6da4Sgerardnico
128*657b6da4Sgerardnico        /**
129*657b6da4Sgerardnico         * We got a conflict Dokuwiki stores a `title` meta in the current
130*657b6da4Sgerardnico         * Because we may delete the first heading, the stored title is the second
131*657b6da4Sgerardnico         * heading, we update it
132*657b6da4Sgerardnico         * See first line of {@link \Doku_Renderer_metadata::header()}
133*657b6da4Sgerardnico         */
134*657b6da4Sgerardnico        $isWikiDisabled = ExecutionContext::getActualOrCreateFromEnv()
135*657b6da4Sgerardnico            ->getConfig()
136*657b6da4Sgerardnico            ->isHeadingWikiComponentDisabled();
137*657b6da4Sgerardnico        if ($isWikiDisabled) {
138*657b6da4Sgerardnico            $event->data[MetadataDokuWikiStore::CURRENT_METADATA]['title'] = $event->data[MetadataDokuWikiStore::CURRENT_METADATA][PageH1::H1_PARSED];
139*657b6da4Sgerardnico        }
140*657b6da4Sgerardnico
14104fd306cSNickeau        /**
14204fd306cSNickeau         * Trick, don't know if this is always true
14304fd306cSNickeau         */
14404fd306cSNickeau        PageImages::createForPage($page)->modifyMetaDokuWikiArray($event->data);
14504fd306cSNickeau
14604fd306cSNickeau    }
14704fd306cSNickeau
14804fd306cSNickeau}
149