xref: /template/strap/action/imgmove.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
121913ab3SNickeau<?php
221913ab3SNickeau
3*04fd306cSNickeauuse ComboStrap\ExceptionBadArgument;
4*04fd306cSNickeauuse ComboStrap\ExceptionCompile;
5*04fd306cSNickeauuse ComboStrap\ExceptionNotFound;
6*04fd306cSNickeauuse ComboStrap\ExceptionRuntime;
7*04fd306cSNickeauuse ComboStrap\ExecutionContext;
837748cd8SNickeauuse ComboStrap\LogUtility;
9*04fd306cSNickeauuse ComboStrap\MarkupPath;
10*04fd306cSNickeauuse ComboStrap\Meta\Api\MetadataImage;
11*04fd306cSNickeauuse ComboStrap\Meta\Api\MetadataSystem;
12*04fd306cSNickeauuse ComboStrap\Meta\Field\PageImages;
13*04fd306cSNickeauuse ComboStrap\Meta\Store\MetadataDokuWikiStore;
14c3437056SNickeauuse ComboStrap\MetadataFrontmatterStore;
15c3437056SNickeauuse ComboStrap\PageImageUsage;
1621913ab3SNickeauuse ComboStrap\PluginUtility;
17*04fd306cSNickeauuse ComboStrap\WikiPath;
1821913ab3SNickeau
19*04fd306cSNickeaurequire_once(__DIR__ . '/../vendor/autoload.php');
2021913ab3SNickeau
2121913ab3SNickeau/**
2221913ab3SNickeau * Handle the move of a image
2321913ab3SNickeau */
2421913ab3SNickeauclass action_plugin_combo_imgmove extends DokuWiki_Action_Plugin
2521913ab3SNickeau{
26*04fd306cSNickeau    const CANONICAL = "imgmove";
2721913ab3SNickeau
2821913ab3SNickeau    /**
2921913ab3SNickeau     * As explained https://www.dokuwiki.org/plugin:move
3021913ab3SNickeau     * @param Doku_Event_Handler $controller
3121913ab3SNickeau     */
3221913ab3SNickeau    function register(Doku_Event_Handler $controller)
3321913ab3SNickeau    {
3421913ab3SNickeau        $controller->register_hook('PLUGIN_MOVE_HANDLERS_REGISTER', 'BEFORE', $this, 'handle_move', array());
35c3437056SNickeau
36c3437056SNickeau
37c3437056SNickeau        $controller->register_hook('PLUGIN_MOVE_MEDIA_RENAME', 'AFTER', $this, 'fileSystemStoreUpdate', array());
38c3437056SNickeau    }
39c3437056SNickeau
40c3437056SNickeau    /**
41c3437056SNickeau     * Update the metadatas
42c3437056SNickeau     * @param Doku_Event $event
43c3437056SNickeau     * @param $params
44c3437056SNickeau     */
45c3437056SNickeau    function fileSystemStoreUpdate(Doku_Event $event, $params)
46c3437056SNickeau    {
47c3437056SNickeau
48*04fd306cSNickeau
49c3437056SNickeau        $affectedPagesId = $event->data["affected_pages"];
50c3437056SNickeau        $sourceImageId = $event->data["src_id"];
51c3437056SNickeau        $targetImageId = $event->data["dst_id"];
52*04fd306cSNickeau
53*04fd306cSNickeau        /**
54*04fd306cSNickeau         * Advertise the move
55*04fd306cSNickeau         */
56*04fd306cSNickeau        ExecutionContext::getActualOrCreateFromEnv()
57*04fd306cSNickeau            ->setRuntimeObject(action_plugin_combo_linkmove::FILE_MOVE_OPERATION, $sourceImageId);
58*04fd306cSNickeau        try {
59c3437056SNickeau            foreach ($affectedPagesId as $affectedPageId) {
60*04fd306cSNickeau                $affectedPage = MarkupPath::createMarkupFromId($affectedPageId)
61c3437056SNickeau                    ->setReadStore(MetadataDokuWikiStore::class);
62c3437056SNickeau
63*04fd306cSNickeau                foreach (MetadataImage::PERSISTENT_IMAGE_NAMES as $persistentImage) {
64*04fd306cSNickeau                    try {
65*04fd306cSNickeau                        $metadata = MetadataSystem::getForName($persistentImage)
66*04fd306cSNickeau                            ->setResource($affectedPage)
67*04fd306cSNickeau                            ->setReadStore(MetadataDokuWikiStore::class);
68*04fd306cSNickeau                    } catch (ExceptionNotFound $e) {
69*04fd306cSNickeau                        LogUtility::internalError("Hardcoded should exists");
70*04fd306cSNickeau                        continue;
71*04fd306cSNickeau                    }
72*04fd306cSNickeau                    try {
73*04fd306cSNickeau                        $value = $metadata->getValue();
74*04fd306cSNickeau                    } catch (ExceptionNotFound $e) {
75*04fd306cSNickeau                        // no value
76*04fd306cSNickeau                        continue;
77*04fd306cSNickeau                    }
78*04fd306cSNickeau                    if ($value === $sourceImageId) {
79*04fd306cSNickeau                        try {
80*04fd306cSNickeau                            $metadata
81*04fd306cSNickeau                                ->setValue($targetImageId)
82*04fd306cSNickeau                                ->persist();
83*04fd306cSNickeau                        } catch (ExceptionBadArgument $e) {
84*04fd306cSNickeau                            LogUtility::error("The target path image ($targetImageId) is not a path", self::CANONICAL, $e);
85*04fd306cSNickeau                        }
86*04fd306cSNickeau                    }
87*04fd306cSNickeau                }
88c3437056SNickeau
89*04fd306cSNickeau
90*04fd306cSNickeau                /**
91*04fd306cSNickeau                 * Deprecated but yeah
92*04fd306cSNickeau                 */
93*04fd306cSNickeau                $pageImages = PageImages::createForPage($affectedPage);
94c3437056SNickeau                $sourceImagePath = ":$sourceImageId";
95c3437056SNickeau                $row = $pageImages->getRow($sourceImagePath);
96c3437056SNickeau                if ($row === null) {
97c3437056SNickeau                    // This is a move of an image in the markup
98c3437056SNickeau                    continue;
99c3437056SNickeau                }
100*04fd306cSNickeau                $souceImageWikiPath = WikiPath::createMediaPathFromId($sourceImagePath);
101*04fd306cSNickeau                $pageImages->remove($souceImageWikiPath);
102c3437056SNickeau                try {
103c3437056SNickeau                    $imageUsage = $row[PageImageUsage::getPersistentName()];
104c3437056SNickeau                    $imageUsageValue = null;
105c3437056SNickeau                    if ($imageUsage !== null) {
106c3437056SNickeau                        $imageUsageValue = $imageUsage->getValue();
107c3437056SNickeau                    }
108c3437056SNickeau                    $pageImages
109c3437056SNickeau                        ->addImage($targetImageId, $imageUsageValue)
110c3437056SNickeau                        ->persist();
111*04fd306cSNickeau                } catch (ExceptionCompile $e) {
112*04fd306cSNickeau                    LogUtility::log2file($e->getMessage(), LogUtility::LVL_MSG_ERROR, $e->getCanonical(), $e);
113c3437056SNickeau                }
114c3437056SNickeau
115*04fd306cSNickeau            }
116*04fd306cSNickeau        } finally {
117*04fd306cSNickeau            /**
118*04fd306cSNickeau             * Stop advertising the move
119*04fd306cSNickeau             */
120*04fd306cSNickeau            ExecutionContext::getActualOrCreateFromEnv()
121*04fd306cSNickeau                ->closeAndRemoveRuntimeVariableIfExists(action_plugin_combo_linkmove::FILE_MOVE_OPERATION);
122c3437056SNickeau        }
123c3437056SNickeau
12421913ab3SNickeau    }
12521913ab3SNickeau
12621913ab3SNickeau    /**
12721913ab3SNickeau     * Handle the move of a image
12821913ab3SNickeau     * @param Doku_Event $event
12921913ab3SNickeau     * @param $params
13021913ab3SNickeau     */
13121913ab3SNickeau    function handle_move(Doku_Event $event, $params)
13221913ab3SNickeau    {
13321913ab3SNickeau        /**
13421913ab3SNickeau         * The handlers is the name of the component (ie refers to the {@link syntax_plugin_combo_media} handler)
13521913ab3SNickeau         * and 'move_combo_img' to the below method
13621913ab3SNickeau         */
13721913ab3SNickeau        $event->data['handlers'][syntax_plugin_combo_media::COMPONENT] = array($this, 'move_combo_img');
13837748cd8SNickeau        $event->data['handlers'][syntax_plugin_combo_frontmatter::COMPONENT] = array($this, 'move_combo_frontmatter_img');
139c3437056SNickeau
14021913ab3SNickeau    }
14121913ab3SNickeau
14221913ab3SNickeau    /**
14321913ab3SNickeau     *
14421913ab3SNickeau     * @param $match
14521913ab3SNickeau     * @param $state
14621913ab3SNickeau     * @param $pos
14721913ab3SNickeau     * @param $plugin
14821913ab3SNickeau     * @param helper_plugin_move_handler $handler
14921913ab3SNickeau     */
15021913ab3SNickeau    public function move_combo_img($match, $state, $pos, $plugin, helper_plugin_move_handler $handler)
15121913ab3SNickeau    {
15221913ab3SNickeau        /**
15321913ab3SNickeau         * The original move method
15421913ab3SNickeau         * is {@link helper_plugin_move_handler::media()}
155c3437056SNickeau         * Rewrite the media links match
156c3437056SNickeau         * from {@link syntax_plugin_combo_media}
15721913ab3SNickeau         */
15821913ab3SNickeau        $handler->media($match, $state, $pos);
15921913ab3SNickeau
16021913ab3SNickeau    }
16121913ab3SNickeau
16237748cd8SNickeau    /**
16337748cd8SNickeau     *
16437748cd8SNickeau     * @param $match
16537748cd8SNickeau     * @param $state
16637748cd8SNickeau     * @param $pos
16737748cd8SNickeau     * @param $plugin
16837748cd8SNickeau     * @param helper_plugin_move_handler $handler
16937748cd8SNickeau     * @return string
17037748cd8SNickeau     */
17137748cd8SNickeau    public function move_combo_frontmatter_img($match, $state, $pos, $plugin, helper_plugin_move_handler $handler)
17237748cd8SNickeau    {
17337748cd8SNickeau        /**
17437748cd8SNickeau         * The original move method
17537748cd8SNickeau         * is {@link helper_plugin_move_handler::media()}
17637748cd8SNickeau         */
177*04fd306cSNickeau        $page = MarkupPath::createMarkupFromId("move-fake-id");
178c3437056SNickeau        try {
179c3437056SNickeau            $metadataFrontmatterStore = MetadataFrontmatterStore::createFromFrontmatterString($page, $match);
180*04fd306cSNickeau        } catch (ExceptionCompile $e) {
181c3437056SNickeau            LogUtility::msg("The frontmatter could not be loaded. " . $e->getMessage(), LogUtility::LVL_MSG_ERROR, $e->getCanonical());
18237748cd8SNickeau            return $match;
183c3437056SNickeau        }
184*04fd306cSNickeau        $data = $metadataFrontmatterStore->getData();
185*04fd306cSNickeau
186*04fd306cSNickeau        /**
187*04fd306cSNickeau         * Advertise the move
188*04fd306cSNickeau         */
189*04fd306cSNickeau        $moveOpeation = true;
190*04fd306cSNickeau        ExecutionContext::getActualOrCreateFromEnv()
191*04fd306cSNickeau            ->setRuntimeObject(action_plugin_combo_linkmove::FILE_MOVE_OPERATION, $moveOpeation);
192*04fd306cSNickeau        try {
193*04fd306cSNickeau            foreach ($data as $key => $value) {
194*04fd306cSNickeau
195*04fd306cSNickeau                try {
196*04fd306cSNickeau                    $metadata = MetadataSystem::getForName($key)
197*04fd306cSNickeau                        ->setResource($page)
198*04fd306cSNickeau                        ->setReadStore($metadataFrontmatterStore)
199*04fd306cSNickeau                        ->setWriteStore($metadataFrontmatterStore);
200*04fd306cSNickeau                } catch (ExceptionNotFound $e) {
201*04fd306cSNickeau                    continue;
20237748cd8SNickeau                }
20337748cd8SNickeau
204*04fd306cSNickeau                /**
205*04fd306cSNickeau                 * Old deprecated
206*04fd306cSNickeau                 */
207*04fd306cSNickeau                if ($metadata instanceof PageImages) {
208*04fd306cSNickeau                    $pageImagesObject = $metadata;
209*04fd306cSNickeau                    $images = $metadata->getValueAsPageImages();
210*04fd306cSNickeau                    if (empty($images)) {
211*04fd306cSNickeau                        return $match;
212*04fd306cSNickeau                    }
21337748cd8SNickeau                    try {
214c3437056SNickeau
215c3437056SNickeau                        foreach ($images as $image) {
216*04fd306cSNickeau                            $path = $image->getImagePath();
217*04fd306cSNickeau                            $imageId = $path->toAbsolutePath()->toAbsoluteId();
218c3437056SNickeau                            $before = $imageId;
219c3437056SNickeau                            $this->moveImage($imageId, $handler);
220*04fd306cSNickeau                            if ($before !== $imageId) {
221*04fd306cSNickeau                                $pageImagesObject->remove($path);
222c3437056SNickeau                                $pageImagesObject->addImage($imageId, $image->getUsages());
22337748cd8SNickeau                            }
22437748cd8SNickeau                        }
22537748cd8SNickeau
226c3437056SNickeau                        $pageImagesObject->sendToWriteStore();
227c3437056SNickeau
228*04fd306cSNickeau                    } catch (ExceptionCompile $e) {
229c3437056SNickeau                        // Could not resolve the image, image does not exist, ... return the data without modification
230c3437056SNickeau                        if (PluginUtility::isDevOrTest()) {
231*04fd306cSNickeau                            throw new ExceptionRuntime($e->getMessage(), $e->getCanonical(), 0, $e);
232c3437056SNickeau                        } else {
233c3437056SNickeau                            LogUtility::log2file($e->getMessage(), LogUtility::LVL_MSG_ERROR, $e->getCanonical());
234c3437056SNickeau                        }
235*04fd306cSNickeau                        continue;
23637748cd8SNickeau                    }
237*04fd306cSNickeau                }
238*04fd306cSNickeau                if (!($metadata instanceof MetadataImage)) {
239*04fd306cSNickeau                    continue;
240*04fd306cSNickeau                }
241*04fd306cSNickeau                try {
242*04fd306cSNickeau                    $imageId = $metadata->getValue()->toAbsoluteId();
243*04fd306cSNickeau                } catch (ExceptionNotFound $e) {
244*04fd306cSNickeau                    continue;
245*04fd306cSNickeau                }
246*04fd306cSNickeau                $before = $imageId;
247*04fd306cSNickeau                try {
248*04fd306cSNickeau                    $this->moveImage($imageId, $handler);
249*04fd306cSNickeau                    if ($before !== $imageId) {
250*04fd306cSNickeau                        $metadata->setValue($imageId)->persist();
251*04fd306cSNickeau                    }
252*04fd306cSNickeau                } catch (\Exception $e) {
253*04fd306cSNickeau                    if (PluginUtility::isDevOrTest()) {
254*04fd306cSNickeau                        throw new ExceptionRuntime($e->getMessage(), self::CANONICAL, 0, $e);
255*04fd306cSNickeau                    } else {
256*04fd306cSNickeau                        LogUtility::log2file($e->getMessage(), LogUtility::LVL_MSG_ERROR, self::CANONICAL, $e);
257*04fd306cSNickeau                    }
258*04fd306cSNickeau                    continue;
259*04fd306cSNickeau                }
260*04fd306cSNickeau            }
261*04fd306cSNickeau        } finally {
262*04fd306cSNickeau            /**
263*04fd306cSNickeau             * Close the move
264*04fd306cSNickeau             */
265*04fd306cSNickeau            ExecutionContext::getActualOrCreateFromEnv()
266*04fd306cSNickeau                ->closeAndRemoveRuntimeVariableIfExists(action_plugin_combo_linkmove::FILE_MOVE_OPERATION);
267*04fd306cSNickeau        }
268*04fd306cSNickeau
26937748cd8SNickeau
27037748cd8SNickeau        /**
27137748cd8SNickeau         * All good,
272c3437056SNickeau         * We don't modify the file system metadata for the page
27337748cd8SNickeau         * because the handler does not give it unfortunately
27437748cd8SNickeau         */
275c3437056SNickeau        return $metadataFrontmatterStore->toFrontmatterString();
27637748cd8SNickeau
27737748cd8SNickeau    }
27837748cd8SNickeau
27937748cd8SNickeau    /**
28037748cd8SNickeau     * Move a single image and update the JSon
281c3437056SNickeau     * @param $relativeOrAbsoluteWikiId
28237748cd8SNickeau     * @param helper_plugin_move_handler $handler
283*04fd306cSNickeau     * @throws ExceptionCompile on bad argument
28437748cd8SNickeau     */
285c3437056SNickeau    private function moveImage(&$relativeOrAbsoluteWikiId, helper_plugin_move_handler $handler)
28637748cd8SNickeau    {
28737748cd8SNickeau        try {
288c3437056SNickeau            $newId = $handler->resolveMoves($relativeOrAbsoluteWikiId, "media");
289*04fd306cSNickeau            $relativeOrAbsoluteWikiId = WikiPath::IdToAbsolutePath($newId);
29037748cd8SNickeau        } catch (Exception $e) {
291*04fd306cSNickeau            throw new ExceptionCompile("A move error has occurred while trying to move the image ($relativeOrAbsoluteWikiId). The target resolution function send the following error message: " . $e->getMessage(), self::CANONICAL);
29237748cd8SNickeau        }
29337748cd8SNickeau    }
29437748cd8SNickeau
29521913ab3SNickeau
29621913ab3SNickeau}
297