121913ab3SNickeau<?php 221913ab3SNickeau 304fd306cSNickeauuse ComboStrap\ExceptionBadArgument; 404fd306cSNickeauuse ComboStrap\ExceptionCompile; 504fd306cSNickeauuse ComboStrap\ExceptionNotFound; 604fd306cSNickeauuse ComboStrap\ExceptionRuntime; 704fd306cSNickeauuse ComboStrap\ExecutionContext; 837748cd8SNickeauuse ComboStrap\LogUtility; 904fd306cSNickeauuse ComboStrap\MarkupPath; 1004fd306cSNickeauuse ComboStrap\Meta\Api\MetadataImage; 1104fd306cSNickeauuse ComboStrap\Meta\Api\MetadataSystem; 1204fd306cSNickeauuse ComboStrap\Meta\Field\PageImages; 1304fd306cSNickeauuse ComboStrap\Meta\Store\MetadataDokuWikiStore; 14c3437056SNickeauuse ComboStrap\MetadataFrontmatterStore; 15c3437056SNickeauuse ComboStrap\PageImageUsage; 1621913ab3SNickeauuse ComboStrap\PluginUtility; 1704fd306cSNickeauuse ComboStrap\WikiPath; 1821913ab3SNickeau 1904fd306cSNickeaurequire_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{ 2604fd306cSNickeau 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 4804fd306cSNickeau 49c3437056SNickeau $affectedPagesId = $event->data["affected_pages"]; 50c3437056SNickeau $sourceImageId = $event->data["src_id"]; 51c3437056SNickeau $targetImageId = $event->data["dst_id"]; 5204fd306cSNickeau 5304fd306cSNickeau /** 5404fd306cSNickeau * Advertise the move 5504fd306cSNickeau */ 5604fd306cSNickeau ExecutionContext::getActualOrCreateFromEnv() 5704fd306cSNickeau ->setRuntimeObject(action_plugin_combo_linkmove::FILE_MOVE_OPERATION, $sourceImageId); 5804fd306cSNickeau try { 59c3437056SNickeau foreach ($affectedPagesId as $affectedPageId) { 6004fd306cSNickeau $affectedPage = MarkupPath::createMarkupFromId($affectedPageId) 61c3437056SNickeau ->setReadStore(MetadataDokuWikiStore::class); 62c3437056SNickeau 6304fd306cSNickeau foreach (MetadataImage::PERSISTENT_IMAGE_NAMES as $persistentImage) { 6404fd306cSNickeau try { 6504fd306cSNickeau $metadata = MetadataSystem::getForName($persistentImage) 6604fd306cSNickeau ->setResource($affectedPage) 6704fd306cSNickeau ->setReadStore(MetadataDokuWikiStore::class); 6804fd306cSNickeau } catch (ExceptionNotFound $e) { 6904fd306cSNickeau LogUtility::internalError("Hardcoded should exists"); 7004fd306cSNickeau continue; 7104fd306cSNickeau } 7204fd306cSNickeau try { 7304fd306cSNickeau $value = $metadata->getValue(); 7404fd306cSNickeau } catch (ExceptionNotFound $e) { 7504fd306cSNickeau // no value 7604fd306cSNickeau continue; 7704fd306cSNickeau } 7804fd306cSNickeau if ($value === $sourceImageId) { 7904fd306cSNickeau try { 8004fd306cSNickeau $metadata 8104fd306cSNickeau ->setValue($targetImageId) 8204fd306cSNickeau ->persist(); 8304fd306cSNickeau } catch (ExceptionBadArgument $e) { 8404fd306cSNickeau LogUtility::error("The target path image ($targetImageId) is not a path", self::CANONICAL, $e); 8504fd306cSNickeau } 8604fd306cSNickeau } 8704fd306cSNickeau } 88c3437056SNickeau 8904fd306cSNickeau 9004fd306cSNickeau /** 9104fd306cSNickeau * Deprecated but yeah 9204fd306cSNickeau */ 9304fd306cSNickeau $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 } 10004fd306cSNickeau $souceImageWikiPath = WikiPath::createMediaPathFromId($sourceImagePath); 10104fd306cSNickeau $pageImages->remove($souceImageWikiPath); 102c3437056SNickeau try { 103*70bbd7f1Sgerardnico $imageUsage = $row[PageImageUsage::getPersistentName()] ?? null; 104c3437056SNickeau $imageUsageValue = null; 105c3437056SNickeau if ($imageUsage !== null) { 106c3437056SNickeau $imageUsageValue = $imageUsage->getValue(); 107c3437056SNickeau } 108c3437056SNickeau $pageImages 109c3437056SNickeau ->addImage($targetImageId, $imageUsageValue) 110c3437056SNickeau ->persist(); 11104fd306cSNickeau } catch (ExceptionCompile $e) { 11204fd306cSNickeau LogUtility::log2file($e->getMessage(), LogUtility::LVL_MSG_ERROR, $e->getCanonical(), $e); 113c3437056SNickeau } 114c3437056SNickeau 11504fd306cSNickeau } 11604fd306cSNickeau } finally { 11704fd306cSNickeau /** 11804fd306cSNickeau * Stop advertising the move 11904fd306cSNickeau */ 12004fd306cSNickeau ExecutionContext::getActualOrCreateFromEnv() 12104fd306cSNickeau ->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 */ 17704fd306cSNickeau $page = MarkupPath::createMarkupFromId("move-fake-id"); 178c3437056SNickeau try { 179c3437056SNickeau $metadataFrontmatterStore = MetadataFrontmatterStore::createFromFrontmatterString($page, $match); 18004fd306cSNickeau } catch (ExceptionCompile $e) { 181c3437056SNickeau LogUtility::msg("The frontmatter could not be loaded. " . $e->getMessage(), LogUtility::LVL_MSG_ERROR, $e->getCanonical()); 18237748cd8SNickeau return $match; 183c3437056SNickeau } 18404fd306cSNickeau $data = $metadataFrontmatterStore->getData(); 18504fd306cSNickeau 18604fd306cSNickeau /** 18704fd306cSNickeau * Advertise the move 18804fd306cSNickeau */ 18904fd306cSNickeau $moveOpeation = true; 19004fd306cSNickeau ExecutionContext::getActualOrCreateFromEnv() 19104fd306cSNickeau ->setRuntimeObject(action_plugin_combo_linkmove::FILE_MOVE_OPERATION, $moveOpeation); 19204fd306cSNickeau try { 19304fd306cSNickeau foreach ($data as $key => $value) { 19404fd306cSNickeau 19504fd306cSNickeau try { 19604fd306cSNickeau $metadata = MetadataSystem::getForName($key) 19704fd306cSNickeau ->setResource($page) 19804fd306cSNickeau ->setReadStore($metadataFrontmatterStore) 19904fd306cSNickeau ->setWriteStore($metadataFrontmatterStore); 20004fd306cSNickeau } catch (ExceptionNotFound $e) { 20104fd306cSNickeau continue; 20237748cd8SNickeau } 20337748cd8SNickeau 20404fd306cSNickeau /** 20504fd306cSNickeau * Old deprecated 20604fd306cSNickeau */ 20704fd306cSNickeau if ($metadata instanceof PageImages) { 20804fd306cSNickeau $pageImagesObject = $metadata; 20904fd306cSNickeau $images = $metadata->getValueAsPageImages(); 21004fd306cSNickeau if (empty($images)) { 21104fd306cSNickeau return $match; 21204fd306cSNickeau } 21337748cd8SNickeau try { 214c3437056SNickeau 215c3437056SNickeau foreach ($images as $image) { 21604fd306cSNickeau $path = $image->getImagePath(); 21704fd306cSNickeau $imageId = $path->toAbsolutePath()->toAbsoluteId(); 218c3437056SNickeau $before = $imageId; 219c3437056SNickeau $this->moveImage($imageId, $handler); 22004fd306cSNickeau if ($before !== $imageId) { 22104fd306cSNickeau $pageImagesObject->remove($path); 222c3437056SNickeau $pageImagesObject->addImage($imageId, $image->getUsages()); 22337748cd8SNickeau } 22437748cd8SNickeau } 22537748cd8SNickeau 226c3437056SNickeau $pageImagesObject->sendToWriteStore(); 227c3437056SNickeau 22804fd306cSNickeau } catch (ExceptionCompile $e) { 229c3437056SNickeau // Could not resolve the image, image does not exist, ... return the data without modification 230c3437056SNickeau if (PluginUtility::isDevOrTest()) { 23104fd306cSNickeau throw new ExceptionRuntime($e->getMessage(), $e->getCanonical(), 0, $e); 232c3437056SNickeau } else { 233c3437056SNickeau LogUtility::log2file($e->getMessage(), LogUtility::LVL_MSG_ERROR, $e->getCanonical()); 234c3437056SNickeau } 23504fd306cSNickeau continue; 23637748cd8SNickeau } 23704fd306cSNickeau } 23804fd306cSNickeau if (!($metadata instanceof MetadataImage)) { 23904fd306cSNickeau continue; 24004fd306cSNickeau } 24104fd306cSNickeau try { 24204fd306cSNickeau $imageId = $metadata->getValue()->toAbsoluteId(); 24304fd306cSNickeau } catch (ExceptionNotFound $e) { 24404fd306cSNickeau continue; 24504fd306cSNickeau } 24604fd306cSNickeau $before = $imageId; 24704fd306cSNickeau try { 24804fd306cSNickeau $this->moveImage($imageId, $handler); 24904fd306cSNickeau if ($before !== $imageId) { 25004fd306cSNickeau $metadata->setValue($imageId)->persist(); 25104fd306cSNickeau } 25204fd306cSNickeau } catch (\Exception $e) { 25304fd306cSNickeau if (PluginUtility::isDevOrTest()) { 25404fd306cSNickeau throw new ExceptionRuntime($e->getMessage(), self::CANONICAL, 0, $e); 25504fd306cSNickeau } else { 25604fd306cSNickeau LogUtility::log2file($e->getMessage(), LogUtility::LVL_MSG_ERROR, self::CANONICAL, $e); 25704fd306cSNickeau } 25804fd306cSNickeau continue; 25904fd306cSNickeau } 26004fd306cSNickeau } 26104fd306cSNickeau } finally { 26204fd306cSNickeau /** 26304fd306cSNickeau * Close the move 26404fd306cSNickeau */ 26504fd306cSNickeau ExecutionContext::getActualOrCreateFromEnv() 26604fd306cSNickeau ->closeAndRemoveRuntimeVariableIfExists(action_plugin_combo_linkmove::FILE_MOVE_OPERATION); 26704fd306cSNickeau } 26804fd306cSNickeau 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 28304fd306cSNickeau * @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"); 28904fd306cSNickeau $relativeOrAbsoluteWikiId = WikiPath::IdToAbsolutePath($newId); 29037748cd8SNickeau } catch (Exception $e) { 29104fd306cSNickeau 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