1<?php 2 3 4namespace ComboStrap\Meta\Field; 5 6 7use ComboStrap\ExceptionCompile; 8use ComboStrap\ExceptionNotFound; 9use ComboStrap\FileSystems; 10use ComboStrap\FirstRasterImage; 11use ComboStrap\LogUtility; 12use ComboStrap\MarkupPath; 13use ComboStrap\Meta\Api\Metadata; 14use ComboStrap\Meta\Api\MetadataTabular; 15use ComboStrap\Meta\Store\MetadataDokuWikiStore; 16use ComboStrap\MetaManagerForm; 17use ComboStrap\PageImageUsage; 18use ComboStrap\WikiPath; 19 20/** 21 * @deprecated 22 */ 23class PageImages extends MetadataTabular 24{ 25 26 27 const CANONICAL = "page:image"; 28 public const PROPERTY_NAME = 'images'; 29 public const PERSISTENT_NAME = 'images'; 30 31 /** 32 * The name should be plural, this one was not 33 */ 34 const OLD_PROPERTY_NAME = "image"; 35 36 37 /** 38 * PageImages constructor. 39 */ 40 public function __construct() 41 { 42 parent::__construct(); 43 } 44 45 46 public static function createForPage(MarkupPath $page): PageImages 47 { 48 return (new PageImages()) 49 ->setResource($page); 50 51 } 52 53 public static function create(): PageImages 54 { 55 return new PageImages(); 56 } 57 58 59 /** 60 * @param $persistentValue 61 * @return PageImage[] 62 * @throws ExceptionCompile 63 */ 64 public function toPageImageArray($persistentValue): array 65 { 66 67 if ($persistentValue === null) { 68 return []; 69 } 70 71 /** 72 * @var MarkupPath $page ; 73 */ 74 $page = $this->getResource(); 75 76 if (is_array($persistentValue)) { 77 $images = []; 78 foreach ($persistentValue as $key => $value) { 79 $usage = null; 80 if (is_numeric($key)) { 81 if (is_array($value)) { 82 if (isset($value[PageImageUsage::PERSISTENT_NAME])) { 83 $usage = $value[PageImageUsage::PERSISTENT_NAME]; 84 if (is_string($usage)) { 85 $usage = explode(",", $usage); 86 } 87 } 88 $imagePath = $value[PageImagePath::PERSISTENT_NAME]; 89 } else { 90 $imagePath = $value; 91 } 92 } else { 93 $imagePath = $key; 94 if (is_array($value) && isset($value[PageImageUsage::PERSISTENT_NAME])) { 95 $usage = $value[PageImageUsage::PERSISTENT_NAME]; 96 if (!is_array($usage)) { 97 $usage = explode(",", $usage);; 98 } 99 } 100 } 101 WikiPath::addRootSeparatorIfNotPresent($imagePath); 102 $imagePathObject = WikiPath::createMediaPathFromPath($imagePath); 103 $pageImage = PageImage::create($imagePathObject, $page); 104 if ($usage !== null) { 105 $pageImage->setUsages($usage); 106 } 107 $images[$imagePath] = $pageImage; 108 109 } 110 return $images; 111 } else { 112 /** 113 * A single path image 114 */ 115 WikiPath::addRootSeparatorIfNotPresent($persistentValue); 116 $imagePathObject = WikiPath::createMediaPathFromPath($persistentValue); 117 $images = [$persistentValue => PageImage::create($imagePathObject, $page)]; 118 } 119 120 return $images; 121 122 } 123 124 125 /** 126 * @throws ExceptionCompile 127 */ 128 public function setFromStoreValue($value): Metadata 129 { 130 $this->setFromStoreValueWithoutException($value); 131 $this->checkImageExistence(); 132 return $this; 133 } 134 135 136 static public function getCanonical(): string 137 { 138 return self::CANONICAL; 139 } 140 141 static public function getName(): string 142 { 143 return self::PROPERTY_NAME; 144 } 145 146 static public function getPersistentName(): string 147 { 148 return self::PERSISTENT_NAME; 149 } 150 151 /** 152 * @throws ExceptionCompile 153 */ 154 public function toStoreValue(): ?array 155 { 156 $this->buildCheck(); 157 if (!\action_plugin_combo_linkmove::isMoveOperation()) { 158 $this->checkImageExistence(); 159 } 160 return parent::toStoreValue(); 161 } 162 163 public function toStoreDefaultValue(): ?array 164 { 165 return null; 166 } 167 168 static public function getPersistenceType(): string 169 { 170 return MetadataDokuWikiStore::PERSISTENT_DOKUWIKI_KEY; 171 } 172 173 174 /** 175 * @return PageImage[] 176 */ 177 public function getValueAsPageImages(): array 178 { 179 $this->buildCheck(); 180 181 try { 182 $rows = parent::getValue(); 183 } catch (ExceptionNotFound $e) { 184 return []; 185 } 186 $pageImages = []; 187 foreach ($rows as $row) { 188 /** 189 * @var PageImagePath $pageImagePath 190 */ 191 $pageImagePath = $row[PageImagePath::getPersistentName()]; 192 try { 193 $pageImagePathValue = $pageImagePath->getValue(); 194 } catch (ExceptionNotFound $e) { 195 LogUtility::internalError("The page path didn't have any values in the rows", self::CANONICAL); 196 continue; 197 } 198 $pageImage = PageImage::create($pageImagePathValue, $this->getResource()); 199 200 /** 201 * @var PageImageUsage $pageImageUsage 202 */ 203 $pageImageUsage = $row[PageImageUsage::getPersistentName()] ?? null; 204 if ($pageImageUsage !== null) { 205 try { 206 $usages = $pageImageUsage->getValue(); 207 $pageImage->setUsages($usages); 208 } catch (ExceptionNotFound $e) { 209 // ok, no images 210 } catch (ExceptionCompile $e) { 211 LogUtility::internalError("Bad Usage value. Should not happen on get. Error: " . $e->getMessage(), self::CANONICAL, $e); 212 } 213 } 214 $pageImages[] = $pageImage; 215 } 216 return $pageImages; 217 } 218 219 /** 220 * @throws ExceptionCompile 221 */ 222 public function addImage(string $wikiImagePath, $usages = null): PageImages 223 { 224 225 $pageImagePath = PageImagePath::createFromParent($this)->setFromStoreValue($wikiImagePath); 226 $row[PageImagePath::getPersistentName()] = $pageImagePath; 227 if ($usages !== null) { 228 $pageImageUsage = PageImageUsage::createFromParent($this) 229 ->setFromStoreValue($usages); 230 $row[PageImageUsage::getPersistentName()] = $pageImageUsage; 231 } 232 $this->rows[] = $row; 233 234 /** 235 * What fucked up is fucked up 236 * The runtime {@link Doku_Renderer_metadata::_recordMediaUsage()} 237 * ``` 238 * meta['relation']['media'][$src] = $exist 239 * ``` 240 * is only set when parsing to add page to the index 241 */ 242 return $this; 243 } 244 245 246 static public function getTab(): string 247 { 248 return MetaManagerForm::TAB_IMAGE_VALUE; 249 } 250 251 252 static public function getDescription(): string 253 { 254 return "The illustrative images of the page"; 255 } 256 257 static public function getLabel(): string 258 { 259 return "Page Images"; 260 } 261 262 263 static public function isMutable(): bool 264 { 265 /** 266 * Deprecated, storage is frozen 267 * We don't take it anymore 268 */ 269 return false; 270 } 271 272 /** 273 * 274 * We check the existence of the image also when persisting, 275 * not when building 276 * because when moving a media, the images does not exist any more 277 * 278 * We can then build the the pageimages with non-existing images 279 * but we can't save 280 * 281 * @throws ExceptionCompile 282 */ 283 private function checkImageExistence() 284 { 285 foreach ($this->getValueAsPageImages() as $pageImage) { 286 if (!FileSystems::exists($pageImage->getImagePath())) { 287 throw new ExceptionCompile("The image ({$pageImage->getImagePath()}) does not exist", $this->getCanonical()); 288 } 289 } 290 } 291 292 293 static function getChildrenClass(): array 294 { 295 return [PageImagePath::class, PageImageUsage::class]; 296 } 297 298 public function getUidClass(): string 299 { 300 return PageImagePath::class; 301 } 302 303 304 /** 305 * @return array|array[] - the default row 306 */ 307 public function getDefaultValue(): array 308 { 309 310 $pageImagePath = null; 311 // Not really the default value but yeah 312 try { 313 $firstImage = FirstRasterImage::createForPage($this->getResource())->getValue(); 314 $pageImagePath = PageImagePath::createFromParent($this)->setFromStoreValueWithoutException($firstImage); 315 } catch (ExceptionNotFound $e) { 316 // no first image 317 } 318 $pageImageUsage = PageImageUsage::createFromParent($this)->setFromStoreValueWithoutException([PageImageUsage::DEFAULT]); 319 return [ 320 [ 321 PageImagePath::getPersistentName() => $pageImagePath, 322 PageImageUsage::getPersistentName() => $pageImageUsage 323 ] 324 ]; 325 326 } 327 328 public static function getOldPersistentNames(): array 329 { 330 return [self::OLD_PROPERTY_NAME]; 331 } 332 333 /** 334 * @param array $data 335 * @return void 336 * 337 * Trick to advertise the image 338 * saved in {@link \ComboStrap\Meta\Api\Metadata} 339 * if the frontmatter is not used 340 * 341 */ 342 public function modifyMetaDokuWikiArray(array &$data) 343 { 344 $pageImages = $this->getValueAsPageImages(); 345 foreach ($pageImages as $pageImage) { 346 /** 347 * {@link Doku_Renderer_metadata::_recordMediaUsage()} 348 */ 349 $dokuPath = $pageImage->getImagePath(); 350 $data[MetadataDokuWikiStore::CURRENT_METADATA]['relation']['media'][$dokuPath->getWikiId()] = FileSystems::exists($dokuPath); 351 } 352 353 } 354 355 356} 357