1<?php 2 3use ComboStrap\DokuPath; 4use ComboStrap\ExceptionCombo; 5use ComboStrap\ExceptionComboRuntime; 6use ComboStrap\LogUtility; 7use ComboStrap\MetadataDokuWikiStore; 8use ComboStrap\MetadataFrontmatterStore; 9use ComboStrap\Page; 10use ComboStrap\Metadata; 11use ComboStrap\PageImages; 12use ComboStrap\PageImageUsage; 13use ComboStrap\PluginUtility; 14 15require_once(__DIR__ . '/../ComboStrap/PluginUtility.php'); 16 17/** 18 * Handle the move of a image 19 */ 20class action_plugin_combo_imgmove extends DokuWiki_Action_Plugin 21{ 22 const CANONICAL = "move"; 23 24 /** 25 * As explained https://www.dokuwiki.org/plugin:move 26 * @param Doku_Event_Handler $controller 27 */ 28 function register(Doku_Event_Handler $controller) 29 { 30 $controller->register_hook('PLUGIN_MOVE_HANDLERS_REGISTER', 'BEFORE', $this, 'handle_move', array()); 31 32 33 $controller->register_hook('PLUGIN_MOVE_MEDIA_RENAME', 'AFTER', $this, 'fileSystemStoreUpdate', array()); 34 } 35 36 /** 37 * Update the metadatas 38 * @param Doku_Event $event 39 * @param $params 40 */ 41 function fileSystemStoreUpdate(Doku_Event $event, $params) 42 { 43 44 $affectedPagesId = $event->data["affected_pages"]; 45 $sourceImageId = $event->data["src_id"]; 46 $targetImageId = $event->data["dst_id"]; 47 foreach ($affectedPagesId as $affectedPageId) { 48 $affectedPage = Page::createPageFromId($affectedPageId) 49 ->setReadStore(MetadataDokuWikiStore::class); 50 51 $pageImages = PageImages::createForPage($affectedPage); 52 53 $sourceImagePath = ":$sourceImageId"; 54 $row = $pageImages->getRow($sourceImagePath); 55 56 if ($row === null) { 57 // This is a move of an image in the markup 58 continue; 59 } 60 $pageImages->remove($sourceImagePath); 61 try { 62 $imageUsage = $row[PageImageUsage::getPersistentName()]; 63 $imageUsageValue = null; 64 if ($imageUsage !== null) { 65 $imageUsageValue = $imageUsage->getValue(); 66 } 67 $pageImages 68 ->addImage($targetImageId, $imageUsageValue) 69 ->persist(); 70 } catch (ExceptionCombo $e) { 71 LogUtility::log2file($e->getMessage(), LogUtility::LVL_MSG_ERROR, $e->getCanonical()); 72 } 73 74 75 } 76 77 } 78 79 /** 80 * Handle the move of a image 81 * @param Doku_Event $event 82 * @param $params 83 */ 84 function handle_move(Doku_Event $event, $params) 85 { 86 /** 87 * The handlers is the name of the component (ie refers to the {@link syntax_plugin_combo_media} handler) 88 * and 'move_combo_img' to the below method 89 */ 90 $event->data['handlers'][syntax_plugin_combo_media::COMPONENT] = array($this, 'move_combo_img'); 91 $event->data['handlers'][syntax_plugin_combo_frontmatter::COMPONENT] = array($this, 'move_combo_frontmatter_img'); 92 93 } 94 95 /** 96 * 97 * @param $match 98 * @param $state 99 * @param $pos 100 * @param $plugin 101 * @param helper_plugin_move_handler $handler 102 */ 103 public function move_combo_img($match, $state, $pos, $plugin, helper_plugin_move_handler $handler) 104 { 105 /** 106 * The original move method 107 * is {@link helper_plugin_move_handler::media()} 108 * Rewrite the media links match 109 * from {@link syntax_plugin_combo_media} 110 */ 111 $handler->media($match, $state, $pos); 112 113 } 114 115 /** 116 * 117 * @param $match 118 * @param $state 119 * @param $pos 120 * @param $plugin 121 * @param helper_plugin_move_handler $handler 122 * @return string 123 */ 124 public function move_combo_frontmatter_img($match, $state, $pos, $plugin, helper_plugin_move_handler $handler) 125 { 126 /** 127 * The original move method 128 * is {@link helper_plugin_move_handler::media()} 129 */ 130 $page = Page::createPageFromId("move-fake-id"); 131 try { 132 $metadataFrontmatterStore = MetadataFrontmatterStore::createFromFrontmatterString($page, $match); 133 } catch (ExceptionCombo $e) { 134 LogUtility::msg("The frontmatter could not be loaded. " . $e->getMessage(), LogUtility::LVL_MSG_ERROR, $e->getCanonical()); 135 return $match; 136 } 137 $pageImagesObject = PageImages::createForPage($page) 138 ->setReadStore($metadataFrontmatterStore); 139 $images = $pageImagesObject->getValueAsPageImages(); 140 if ($images === null) { 141 return $match; 142 } 143 144 try { 145 146 foreach ($images as $image) { 147 $path = $image->getImage()->getPath(); 148 if (!($path instanceof DokuPath)) { 149 continue; 150 } 151 $imageId = $path->toAbsolutePath()->toString(); 152 $before = $imageId; 153 $this->moveImage($imageId, $handler); 154 if ($before != $imageId) { 155 $pageImagesObject->remove($before); 156 $pageImagesObject->addImage($imageId, $image->getUsages()); 157 } 158 } 159 160 $pageImagesObject->sendToWriteStore(); 161 162 } catch (ExceptionCombo $e) { 163 // Could not resolve the image, image does not exist, ... return the data without modification 164 if (PluginUtility::isDevOrTest()) { 165 throw new ExceptionComboRuntime($e->getMessage(), $e->getCanonical(), 0, $e); 166 } else { 167 LogUtility::log2file($e->getMessage(), LogUtility::LVL_MSG_ERROR, $e->getCanonical()); 168 } 169 return $match; 170 } 171 172 /** 173 * All good, 174 * We don't modify the file system metadata for the page 175 * because the handler does not give it unfortunately 176 */ 177 return $metadataFrontmatterStore->toFrontmatterString(); 178 179 } 180 181 /** 182 * Move a single image and update the JSon 183 * @param $relativeOrAbsoluteWikiId 184 * @param helper_plugin_move_handler $handler 185 * @throws ExceptionCombo on bad argument 186 */ 187 private function moveImage(&$relativeOrAbsoluteWikiId, helper_plugin_move_handler $handler) 188 { 189 try { 190 $newId = $handler->resolveMoves($relativeOrAbsoluteWikiId, "media"); 191 $relativeOrAbsoluteWikiId = DokuPath::IdToAbsolutePath($newId); 192 } catch (Exception $e) { 193 throw new ExceptionCombo("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); 194 } 195 } 196 197 198} 199