register_hook('PLUGIN_MOVE_HANDLERS_REGISTER', 'BEFORE', $this, 'handle_move', array()); $controller->register_hook('PLUGIN_MOVE_MEDIA_RENAME', 'AFTER', $this, 'fileSystemStoreUpdate', array()); } /** * Update the metadatas * @param Doku_Event $event * @param $params */ function fileSystemStoreUpdate(Doku_Event $event, $params) { $affectedPagesId = $event->data["affected_pages"]; $sourceImageId = $event->data["src_id"]; $targetImageId = $event->data["dst_id"]; /** * Advertise the move */ ExecutionContext::getActualOrCreateFromEnv() ->setRuntimeObject(action_plugin_combo_linkmove::FILE_MOVE_OPERATION, $sourceImageId); try { foreach ($affectedPagesId as $affectedPageId) { $affectedPage = MarkupPath::createMarkupFromId($affectedPageId) ->setReadStore(MetadataDokuWikiStore::class); foreach (MetadataImage::PERSISTENT_IMAGE_NAMES as $persistentImage) { try { $metadata = MetadataSystem::getForName($persistentImage) ->setResource($affectedPage) ->setReadStore(MetadataDokuWikiStore::class); } catch (ExceptionNotFound $e) { LogUtility::internalError("Hardcoded should exists"); continue; } try { $value = $metadata->getValue(); } catch (ExceptionNotFound $e) { // no value continue; } if ($value === $sourceImageId) { try { $metadata ->setValue($targetImageId) ->persist(); } catch (ExceptionBadArgument $e) { LogUtility::error("The target path image ($targetImageId) is not a path", self::CANONICAL, $e); } } } /** * Deprecated but yeah */ $pageImages = PageImages::createForPage($affectedPage); $sourceImagePath = ":$sourceImageId"; $row = $pageImages->getRow($sourceImagePath); if ($row === null) { // This is a move of an image in the markup continue; } $souceImageWikiPath = WikiPath::createMediaPathFromId($sourceImagePath); $pageImages->remove($souceImageWikiPath); try { $imageUsage = $row[PageImageUsage::getPersistentName()] ?? null; $imageUsageValue = null; if ($imageUsage !== null) { $imageUsageValue = $imageUsage->getValue(); } $pageImages ->addImage($targetImageId, $imageUsageValue) ->persist(); } catch (ExceptionCompile $e) { LogUtility::log2file($e->getMessage(), LogUtility::LVL_MSG_ERROR, $e->getCanonical(), $e); } } } finally { /** * Stop advertising the move */ ExecutionContext::getActualOrCreateFromEnv() ->closeAndRemoveRuntimeVariableIfExists(action_plugin_combo_linkmove::FILE_MOVE_OPERATION); } } /** * Handle the move of a image * @param Doku_Event $event * @param $params */ function handle_move(Doku_Event $event, $params) { /** * The handlers is the name of the component (ie refers to the {@link syntax_plugin_combo_media} handler) * and 'move_combo_img' to the below method */ $event->data['handlers'][syntax_plugin_combo_media::COMPONENT] = array($this, 'move_combo_img'); $event->data['handlers'][syntax_plugin_combo_frontmatter::COMPONENT] = array($this, 'move_combo_frontmatter_img'); } /** * * @param $match * @param $state * @param $pos * @param $plugin * @param helper_plugin_move_handler $handler */ public function move_combo_img($match, $state, $pos, $plugin, helper_plugin_move_handler $handler) { /** * The original move method * is {@link helper_plugin_move_handler::media()} * Rewrite the media links match * from {@link syntax_plugin_combo_media} */ $handler->media($match, $state, $pos); } /** * * @param $match * @param $state * @param $pos * @param $plugin * @param helper_plugin_move_handler $handler * @return string */ public function move_combo_frontmatter_img($match, $state, $pos, $plugin, helper_plugin_move_handler $handler) { /** * The original move method * is {@link helper_plugin_move_handler::media()} */ $page = MarkupPath::createMarkupFromId("move-fake-id"); try { $metadataFrontmatterStore = MetadataFrontmatterStore::createFromFrontmatterString($page, $match); } catch (ExceptionCompile $e) { LogUtility::msg("The frontmatter could not be loaded. " . $e->getMessage(), LogUtility::LVL_MSG_ERROR, $e->getCanonical()); return $match; } $data = $metadataFrontmatterStore->getData(); /** * Advertise the move */ $moveOpeation = true; ExecutionContext::getActualOrCreateFromEnv() ->setRuntimeObject(action_plugin_combo_linkmove::FILE_MOVE_OPERATION, $moveOpeation); try { foreach ($data as $key => $value) { try { $metadata = MetadataSystem::getForName($key) ->setResource($page) ->setReadStore($metadataFrontmatterStore) ->setWriteStore($metadataFrontmatterStore); } catch (ExceptionNotFound $e) { continue; } /** * Old deprecated */ if ($metadata instanceof PageImages) { $pageImagesObject = $metadata; $images = $metadata->getValueAsPageImages(); if (empty($images)) { return $match; } try { foreach ($images as $image) { $path = $image->getImagePath(); $imageId = $path->toAbsolutePath()->toAbsoluteId(); $before = $imageId; $this->moveImage($imageId, $handler); if ($before !== $imageId) { $pageImagesObject->remove($path); $pageImagesObject->addImage($imageId, $image->getUsages()); } } $pageImagesObject->sendToWriteStore(); } catch (ExceptionCompile $e) { // Could not resolve the image, image does not exist, ... return the data without modification if (PluginUtility::isDevOrTest()) { throw new ExceptionRuntime($e->getMessage(), $e->getCanonical(), 0, $e); } else { LogUtility::log2file($e->getMessage(), LogUtility::LVL_MSG_ERROR, $e->getCanonical()); } continue; } } if (!($metadata instanceof MetadataImage)) { continue; } try { $imageId = $metadata->getValue()->toAbsoluteId(); } catch (ExceptionNotFound $e) { continue; } $before = $imageId; try { $this->moveImage($imageId, $handler); if ($before !== $imageId) { $metadata->setValue($imageId)->persist(); } } catch (\Exception $e) { if (PluginUtility::isDevOrTest()) { throw new ExceptionRuntime($e->getMessage(), self::CANONICAL, 0, $e); } else { LogUtility::log2file($e->getMessage(), LogUtility::LVL_MSG_ERROR, self::CANONICAL, $e); } continue; } } } finally { /** * Close the move */ ExecutionContext::getActualOrCreateFromEnv() ->closeAndRemoveRuntimeVariableIfExists(action_plugin_combo_linkmove::FILE_MOVE_OPERATION); } /** * All good, * We don't modify the file system metadata for the page * because the handler does not give it unfortunately */ return $metadataFrontmatterStore->toFrontmatterString(); } /** * Move a single image and update the JSon * @param $relativeOrAbsoluteWikiId * @param helper_plugin_move_handler $handler * @throws ExceptionCompile on bad argument */ private function moveImage(&$relativeOrAbsoluteWikiId, helper_plugin_move_handler $handler) { try { $newId = $handler->resolveMoves($relativeOrAbsoluteWikiId, "media"); $relativeOrAbsoluteWikiId = WikiPath::IdToAbsolutePath($newId); } catch (Exception $e) { 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); } } }