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