1<?php 2 3namespace dokuwiki\plugin\wordimport\docx; 4 5/** 6 * An image 7 * 8 * This is a paragraph with a drawing element containing an image 9 */ 10class Image extends Paragraph 11{ 12 /** @var string The reference ID for this image */ 13 protected $rId = ''; 14 /** @var string The description text for this image */ 15 protected $alt = ''; 16 17 /** @inheritdoc */ 18 public function parse() 19 { 20 parent::parse(); 21 22 $blip = $this->p->xpath('w:r/w:drawing/wp:inline//a:blip')[0]; 23 $this->rId = (string) $blip->attributes('r', true)->embed; 24 25 $alt = $this->p->xpath('w:r/w:drawing/wp:inline/wp:docPr')[0]; 26 $this->alt = $this->clean((string)$alt['descr']); 27 } 28 29 /** 30 * The relationship ID points to an image in the relationships file. If we are in an import process, 31 * eg. $docx->getPageId() is set, we copy the image to the media folder here before referencing it in 32 * the DokuWiki syntax. Images are named after their relationship ID. 33 * 34 * @inheritdoc 35 */ 36 public function __toString(): string 37 { 38 try { 39 $src = $this->docx->getRelationships()->getTarget('image', $this->rId); 40 $src = $this->docx->getFilePath($src); 41 } catch (\Exception $e) { 42 return ''; // we don't have an image for this. Ignore 43 } 44 45 [$ext, $mime] = mimetype($src); 46 if (!$mime) return ''; // not a supported image 47 if (!str_starts_with($mime, 'image/')) return ''; // not an image 48 49 $pageid = $this->docx->getPageId(); 50 if ($pageid) { 51 $target = $pageid . ':' . $this->rId . '.' . $ext; 52 $this->copyImage($src, $target); 53 } else { 54 $target = $this->rId . '.' . $ext; 55 } 56 $target = cleanID($target); 57 58 $target = $this->alignmentPadding($target); 59 return '{{' . $target . '|' . $this->alt . '}}'; 60 } 61 62 /** 63 * Copy an image to the media folder 64 * 65 * Will do nothing if the image already exists and is the same 66 * 67 * @param string $src The full path to the source image 68 * @param string $target The target media id 69 * @throws \Exception when the media could not be saved 70 */ 71 protected function copyImage($src, $target) 72 { 73 if (file_exists(mediaFN($target)) && md5_file($src) === md5_file(mediaFN($target))) { 74 // image exists and is the same 75 return; 76 } 77 78 $auth = auth_quickaclcheck(getNS($target) . ':*'); 79 $res = media_save(['name' => $src], $target, true, $auth, 'copy'); 80 if (is_array($res)) { 81 throw new \Exception('Failed to save media: ' . $res[0]); 82 } 83 84 // clear the message generated by media_save 85 global $MSG; 86 $MSG = []; 87 } 88 89 /** 90 * Remove any character we can't allow inside an image tag 91 * @param string $string 92 * @return string 93 */ 94 protected function clean($string): string 95 { 96 return str_replace(["\n", '{', '}', '|'], ' ', $string); 97 } 98} 99