xref: /plugin/combo/ComboStrap/Meta/Field/PageImages.php (revision 70bbd7f1f72440223cc13f3495efdcb2b0a11514)
104fd306cSNickeau<?php
204fd306cSNickeau
304fd306cSNickeau
404fd306cSNickeaunamespace ComboStrap\Meta\Field;
504fd306cSNickeau
604fd306cSNickeau
704fd306cSNickeauuse ComboStrap\ExceptionCompile;
804fd306cSNickeauuse ComboStrap\ExceptionNotFound;
904fd306cSNickeauuse ComboStrap\FileSystems;
1004fd306cSNickeauuse ComboStrap\FirstRasterImage;
1104fd306cSNickeauuse ComboStrap\LogUtility;
1204fd306cSNickeauuse ComboStrap\MarkupPath;
1304fd306cSNickeauuse ComboStrap\Meta\Api\Metadata;
1404fd306cSNickeauuse ComboStrap\Meta\Api\MetadataTabular;
1504fd306cSNickeauuse ComboStrap\Meta\Store\MetadataDokuWikiStore;
1604fd306cSNickeauuse ComboStrap\MetaManagerForm;
1704fd306cSNickeauuse ComboStrap\PageImageUsage;
1804fd306cSNickeauuse ComboStrap\WikiPath;
1904fd306cSNickeau
2004fd306cSNickeau/**
2104fd306cSNickeau * @deprecated
2204fd306cSNickeau */
2304fd306cSNickeauclass PageImages extends MetadataTabular
2404fd306cSNickeau{
2504fd306cSNickeau
2604fd306cSNickeau
2704fd306cSNickeau    const CANONICAL = "page:image";
2804fd306cSNickeau    public const PROPERTY_NAME = 'images';
2904fd306cSNickeau    public const PERSISTENT_NAME = 'images';
3004fd306cSNickeau
3104fd306cSNickeau    /**
3204fd306cSNickeau     * The name should be plural, this one was not
3304fd306cSNickeau     */
3404fd306cSNickeau    const OLD_PROPERTY_NAME = "image";
3504fd306cSNickeau
3604fd306cSNickeau
3704fd306cSNickeau    /**
3804fd306cSNickeau     * PageImages constructor.
3904fd306cSNickeau     */
4004fd306cSNickeau    public function __construct()
4104fd306cSNickeau    {
4204fd306cSNickeau        parent::__construct();
4304fd306cSNickeau    }
4404fd306cSNickeau
4504fd306cSNickeau
4604fd306cSNickeau    public static function createForPage(MarkupPath $page): PageImages
4704fd306cSNickeau    {
4804fd306cSNickeau        return (new PageImages())
4904fd306cSNickeau            ->setResource($page);
5004fd306cSNickeau
5104fd306cSNickeau    }
5204fd306cSNickeau
5304fd306cSNickeau    public static function create(): PageImages
5404fd306cSNickeau    {
5504fd306cSNickeau        return new PageImages();
5604fd306cSNickeau    }
5704fd306cSNickeau
5804fd306cSNickeau
5904fd306cSNickeau    /**
6004fd306cSNickeau     * @param $persistentValue
6104fd306cSNickeau     * @return PageImage[]
6204fd306cSNickeau     * @throws ExceptionCompile
6304fd306cSNickeau     */
6404fd306cSNickeau    public function toPageImageArray($persistentValue): array
6504fd306cSNickeau    {
6604fd306cSNickeau
6704fd306cSNickeau        if ($persistentValue === null) {
6804fd306cSNickeau            return [];
6904fd306cSNickeau        }
7004fd306cSNickeau
7104fd306cSNickeau        /**
7204fd306cSNickeau         * @var MarkupPath $page ;
7304fd306cSNickeau         */
7404fd306cSNickeau        $page = $this->getResource();
7504fd306cSNickeau
7604fd306cSNickeau        if (is_array($persistentValue)) {
7704fd306cSNickeau            $images = [];
7804fd306cSNickeau            foreach ($persistentValue as $key => $value) {
7904fd306cSNickeau                $usage = null;
8004fd306cSNickeau                if (is_numeric($key)) {
8104fd306cSNickeau                    if (is_array($value)) {
8204fd306cSNickeau                        if (isset($value[PageImageUsage::PERSISTENT_NAME])) {
8304fd306cSNickeau                            $usage = $value[PageImageUsage::PERSISTENT_NAME];
8404fd306cSNickeau                            if (is_string($usage)) {
8504fd306cSNickeau                                $usage = explode(",", $usage);
8604fd306cSNickeau                            }
8704fd306cSNickeau                        }
8804fd306cSNickeau                        $imagePath = $value[PageImagePath::PERSISTENT_NAME];
8904fd306cSNickeau                    } else {
9004fd306cSNickeau                        $imagePath = $value;
9104fd306cSNickeau                    }
9204fd306cSNickeau                } else {
9304fd306cSNickeau                    $imagePath = $key;
9404fd306cSNickeau                    if (is_array($value) && isset($value[PageImageUsage::PERSISTENT_NAME])) {
9504fd306cSNickeau                        $usage = $value[PageImageUsage::PERSISTENT_NAME];
9604fd306cSNickeau                        if (!is_array($usage)) {
9704fd306cSNickeau                            $usage = explode(",", $usage);;
9804fd306cSNickeau                        }
9904fd306cSNickeau                    }
10004fd306cSNickeau                }
10104fd306cSNickeau                WikiPath::addRootSeparatorIfNotPresent($imagePath);
10204fd306cSNickeau                $imagePathObject = WikiPath::createMediaPathFromPath($imagePath);
10304fd306cSNickeau                $pageImage = PageImage::create($imagePathObject, $page);
10404fd306cSNickeau                if ($usage !== null) {
10504fd306cSNickeau                    $pageImage->setUsages($usage);
10604fd306cSNickeau                }
10704fd306cSNickeau                $images[$imagePath] = $pageImage;
10804fd306cSNickeau
10904fd306cSNickeau            }
11004fd306cSNickeau            return $images;
11104fd306cSNickeau        } else {
11204fd306cSNickeau            /**
11304fd306cSNickeau             * A single path image
11404fd306cSNickeau             */
11504fd306cSNickeau            WikiPath::addRootSeparatorIfNotPresent($persistentValue);
11604fd306cSNickeau            $imagePathObject = WikiPath::createMediaPathFromPath($persistentValue);
11704fd306cSNickeau            $images = [$persistentValue => PageImage::create($imagePathObject, $page)];
11804fd306cSNickeau        }
11904fd306cSNickeau
12004fd306cSNickeau        return $images;
12104fd306cSNickeau
12204fd306cSNickeau    }
12304fd306cSNickeau
12404fd306cSNickeau
12504fd306cSNickeau    /**
12604fd306cSNickeau     * @throws ExceptionCompile
12704fd306cSNickeau     */
12804fd306cSNickeau    public function setFromStoreValue($value): Metadata
12904fd306cSNickeau    {
13004fd306cSNickeau        $this->setFromStoreValueWithoutException($value);
13104fd306cSNickeau        $this->checkImageExistence();
13204fd306cSNickeau        return $this;
13304fd306cSNickeau    }
13404fd306cSNickeau
13504fd306cSNickeau
13604fd306cSNickeau    static public function getCanonical(): string
13704fd306cSNickeau    {
13804fd306cSNickeau        return self::CANONICAL;
13904fd306cSNickeau    }
14004fd306cSNickeau
14104fd306cSNickeau    static public function getName(): string
14204fd306cSNickeau    {
14304fd306cSNickeau        return self::PROPERTY_NAME;
14404fd306cSNickeau    }
14504fd306cSNickeau
14604fd306cSNickeau    static public function getPersistentName(): string
14704fd306cSNickeau    {
14804fd306cSNickeau        return self::PERSISTENT_NAME;
14904fd306cSNickeau    }
15004fd306cSNickeau
15104fd306cSNickeau    /**
15204fd306cSNickeau     * @throws ExceptionCompile
15304fd306cSNickeau     */
15404fd306cSNickeau    public function toStoreValue(): ?array
15504fd306cSNickeau    {
15604fd306cSNickeau        $this->buildCheck();
15704fd306cSNickeau        if (!\action_plugin_combo_linkmove::isMoveOperation()) {
15804fd306cSNickeau            $this->checkImageExistence();
15904fd306cSNickeau        }
16004fd306cSNickeau        return parent::toStoreValue();
16104fd306cSNickeau    }
16204fd306cSNickeau
16304fd306cSNickeau    public function toStoreDefaultValue(): ?array
16404fd306cSNickeau    {
16504fd306cSNickeau        return null;
16604fd306cSNickeau    }
16704fd306cSNickeau
16804fd306cSNickeau    static public function getPersistenceType(): string
16904fd306cSNickeau    {
17004fd306cSNickeau        return MetadataDokuWikiStore::PERSISTENT_DOKUWIKI_KEY;
17104fd306cSNickeau    }
17204fd306cSNickeau
17304fd306cSNickeau
17404fd306cSNickeau    /**
17504fd306cSNickeau     * @return PageImage[]
17604fd306cSNickeau     */
17704fd306cSNickeau    public function getValueAsPageImages(): array
17804fd306cSNickeau    {
17904fd306cSNickeau        $this->buildCheck();
18004fd306cSNickeau
18104fd306cSNickeau        try {
18204fd306cSNickeau            $rows = parent::getValue();
18304fd306cSNickeau        } catch (ExceptionNotFound $e) {
18404fd306cSNickeau            return [];
18504fd306cSNickeau        }
18604fd306cSNickeau        $pageImages = [];
18704fd306cSNickeau        foreach ($rows as $row) {
18804fd306cSNickeau            /**
18904fd306cSNickeau             * @var PageImagePath $pageImagePath
19004fd306cSNickeau             */
19104fd306cSNickeau            $pageImagePath = $row[PageImagePath::getPersistentName()];
19204fd306cSNickeau            try {
19304fd306cSNickeau                $pageImagePathValue = $pageImagePath->getValue();
19404fd306cSNickeau            } catch (ExceptionNotFound $e) {
19504fd306cSNickeau                LogUtility::internalError("The page path didn't have any values in the rows", self::CANONICAL);
19604fd306cSNickeau                continue;
19704fd306cSNickeau            }
19804fd306cSNickeau            $pageImage = PageImage::create($pageImagePathValue, $this->getResource());
19904fd306cSNickeau
20004fd306cSNickeau            /**
20104fd306cSNickeau             * @var PageImageUsage $pageImageUsage
20204fd306cSNickeau             */
203*70bbd7f1Sgerardnico            $pageImageUsage = $row[PageImageUsage::getPersistentName()] ?? null;
20404fd306cSNickeau            if ($pageImageUsage !== null) {
20504fd306cSNickeau                try {
20604fd306cSNickeau                    $usages = $pageImageUsage->getValue();
20704fd306cSNickeau                    $pageImage->setUsages($usages);
20804fd306cSNickeau                } catch (ExceptionNotFound $e) {
20904fd306cSNickeau                    // ok, no images
21004fd306cSNickeau                } catch (ExceptionCompile $e) {
21104fd306cSNickeau                    LogUtility::internalError("Bad Usage value. Should not happen on get. Error: " . $e->getMessage(), self::CANONICAL, $e);
21204fd306cSNickeau                }
21304fd306cSNickeau            }
21404fd306cSNickeau            $pageImages[] = $pageImage;
21504fd306cSNickeau        }
21604fd306cSNickeau        return $pageImages;
21704fd306cSNickeau    }
21804fd306cSNickeau
21904fd306cSNickeau    /**
22004fd306cSNickeau     * @throws ExceptionCompile
22104fd306cSNickeau     */
22204fd306cSNickeau    public function addImage(string $wikiImagePath, $usages = null): PageImages
22304fd306cSNickeau    {
22404fd306cSNickeau
22504fd306cSNickeau        $pageImagePath = PageImagePath::createFromParent($this)->setFromStoreValue($wikiImagePath);
22604fd306cSNickeau        $row[PageImagePath::getPersistentName()] = $pageImagePath;
22704fd306cSNickeau        if ($usages !== null) {
22804fd306cSNickeau            $pageImageUsage = PageImageUsage::createFromParent($this)
22904fd306cSNickeau                ->setFromStoreValue($usages);
23004fd306cSNickeau            $row[PageImageUsage::getPersistentName()] = $pageImageUsage;
23104fd306cSNickeau        }
23204fd306cSNickeau        $this->rows[] = $row;
23304fd306cSNickeau
23404fd306cSNickeau        /**
23504fd306cSNickeau         * What fucked up is fucked up
23604fd306cSNickeau         * The runtime {@link Doku_Renderer_metadata::_recordMediaUsage()}
23704fd306cSNickeau         * ```
23804fd306cSNickeau         * meta['relation']['media'][$src] = $exist
23904fd306cSNickeau         * ```
24004fd306cSNickeau         * is only set when parsing to add page to the index
24104fd306cSNickeau         */
24204fd306cSNickeau        return $this;
24304fd306cSNickeau    }
24404fd306cSNickeau
24504fd306cSNickeau
24604fd306cSNickeau    static public function getTab(): string
24704fd306cSNickeau    {
24804fd306cSNickeau        return MetaManagerForm::TAB_IMAGE_VALUE;
24904fd306cSNickeau    }
25004fd306cSNickeau
25104fd306cSNickeau
25204fd306cSNickeau    static public function getDescription(): string
25304fd306cSNickeau    {
25404fd306cSNickeau        return "The illustrative images of the page";
25504fd306cSNickeau    }
25604fd306cSNickeau
25704fd306cSNickeau    static public function getLabel(): string
25804fd306cSNickeau    {
25904fd306cSNickeau        return "Page Images";
26004fd306cSNickeau    }
26104fd306cSNickeau
26204fd306cSNickeau
26304fd306cSNickeau    static public function isMutable(): bool
26404fd306cSNickeau    {
26504fd306cSNickeau        /**
26604fd306cSNickeau         * Deprecated, storage is frozen
26704fd306cSNickeau         * We don't take it anymore
26804fd306cSNickeau         */
26904fd306cSNickeau        return false;
27004fd306cSNickeau    }
27104fd306cSNickeau
27204fd306cSNickeau    /**
27304fd306cSNickeau     *
27404fd306cSNickeau     * We check the existence of the image also when persisting,
27504fd306cSNickeau     * not when building
27604fd306cSNickeau     * because when moving a media, the images does not exist any more
27704fd306cSNickeau     *
27804fd306cSNickeau     * We can then build the the pageimages with non-existing images
27904fd306cSNickeau     * but we can't save
28004fd306cSNickeau     *
28104fd306cSNickeau     * @throws ExceptionCompile
28204fd306cSNickeau     */
28304fd306cSNickeau    private function checkImageExistence()
28404fd306cSNickeau    {
28504fd306cSNickeau        foreach ($this->getValueAsPageImages() as $pageImage) {
28604fd306cSNickeau            if (!FileSystems::exists($pageImage->getImagePath())) {
28704fd306cSNickeau                throw new ExceptionCompile("The image ({$pageImage->getImagePath()}) does not exist", $this->getCanonical());
28804fd306cSNickeau            }
28904fd306cSNickeau        }
29004fd306cSNickeau    }
29104fd306cSNickeau
29204fd306cSNickeau
29304fd306cSNickeau    static function getChildrenClass(): array
29404fd306cSNickeau    {
29504fd306cSNickeau        return [PageImagePath::class, PageImageUsage::class];
29604fd306cSNickeau    }
29704fd306cSNickeau
29804fd306cSNickeau    public function getUidClass(): string
29904fd306cSNickeau    {
30004fd306cSNickeau        return PageImagePath::class;
30104fd306cSNickeau    }
30204fd306cSNickeau
30304fd306cSNickeau
30404fd306cSNickeau    /**
30504fd306cSNickeau     * @return array|array[] - the default row
30604fd306cSNickeau     */
30704fd306cSNickeau    public function getDefaultValue(): array
30804fd306cSNickeau    {
30904fd306cSNickeau
31004fd306cSNickeau        $pageImagePath = null;
31104fd306cSNickeau        // Not really the default value but yeah
31204fd306cSNickeau        try {
31304fd306cSNickeau            $firstImage = FirstRasterImage::createForPage($this->getResource())->getValue();
31404fd306cSNickeau            $pageImagePath = PageImagePath::createFromParent($this)->setFromStoreValueWithoutException($firstImage);
31504fd306cSNickeau        } catch (ExceptionNotFound $e) {
31604fd306cSNickeau            // no first image
31704fd306cSNickeau        }
31804fd306cSNickeau        $pageImageUsage = PageImageUsage::createFromParent($this)->setFromStoreValueWithoutException([PageImageUsage::DEFAULT]);
31904fd306cSNickeau        return [
32004fd306cSNickeau            [
32104fd306cSNickeau                PageImagePath::getPersistentName() => $pageImagePath,
32204fd306cSNickeau                PageImageUsage::getPersistentName() => $pageImageUsage
32304fd306cSNickeau            ]
32404fd306cSNickeau        ];
32504fd306cSNickeau
32604fd306cSNickeau    }
32704fd306cSNickeau
32804fd306cSNickeau    public static function getOldPersistentNames(): array
32904fd306cSNickeau    {
33004fd306cSNickeau        return [self::OLD_PROPERTY_NAME];
33104fd306cSNickeau    }
33204fd306cSNickeau
33304fd306cSNickeau    /**
33404fd306cSNickeau     * @param array $data
33504fd306cSNickeau     * @return void
33604fd306cSNickeau     *
33704fd306cSNickeau     * Trick to advertise the image
33804fd306cSNickeau     * saved in {@link \ComboStrap\Meta\Api\Metadata}
33904fd306cSNickeau     * if the frontmatter is not used
34004fd306cSNickeau     *
34104fd306cSNickeau     */
34204fd306cSNickeau    public function modifyMetaDokuWikiArray(array &$data)
34304fd306cSNickeau    {
34404fd306cSNickeau        $pageImages = $this->getValueAsPageImages();
34504fd306cSNickeau        foreach ($pageImages as $pageImage) {
34604fd306cSNickeau            /**
34704fd306cSNickeau             * {@link Doku_Renderer_metadata::_recordMediaUsage()}
34804fd306cSNickeau             */
34904fd306cSNickeau            $dokuPath = $pageImage->getImagePath();
35004fd306cSNickeau            $data[MetadataDokuWikiStore::CURRENT_METADATA]['relation']['media'][$dokuPath->getWikiId()] = FileSystems::exists($dokuPath);
35104fd306cSNickeau        }
35204fd306cSNickeau
35304fd306cSNickeau    }
35404fd306cSNickeau
35504fd306cSNickeau
35604fd306cSNickeau}
357