1<?php
2
3namespace ComboStrap\Meta\Api;
4
5use ComboStrap\CacheExpirationDate;
6use ComboStrap\CacheExpirationFrequency;
7use ComboStrap\Canonical;
8use ComboStrap\DisqusIdentifier;
9use ComboStrap\DokuwikiId;
10use ComboStrap\EndDate;
11use ComboStrap\ExceptionBadArgument;
12use ComboStrap\ExceptionNotFound;
13use ComboStrap\ExceptionRuntimeInternal;
14use ComboStrap\ExecutionContext;
15use ComboStrap\FeaturedIcon;
16use ComboStrap\FirstImage;
17use ComboStrap\FirstRasterImage;
18use ComboStrap\FirstSvgIllustration;
19use ComboStrap\Label;
20use ComboStrap\Lang;
21use ComboStrap\LdJson;
22use ComboStrap\Lead;
23use ComboStrap\Locale;
24use ComboStrap\LogUtility;
25use ComboStrap\LowQualityCalculatedIndicator;
26use ComboStrap\LowQualityPageOverwrite;
27use ComboStrap\Meta\Field\Aliases;
28use ComboStrap\Meta\Field\AliasPath;
29use ComboStrap\Meta\Field\AliasType;
30use ComboStrap\Meta\Field\AncestorImage;
31use ComboStrap\Meta\Field\FacebookImage;
32use ComboStrap\Meta\Field\FeaturedImage;
33use ComboStrap\Meta\Field\FeaturedRasterImage;
34use ComboStrap\Meta\Field\FeaturedSvgImage;
35use ComboStrap\Meta\Field\PageH1;
36use ComboStrap\Meta\Field\PageImage;
37use ComboStrap\Meta\Field\PageImagePath;
38use ComboStrap\Meta\Field\PageImages;
39use ComboStrap\Meta\Field\PageTemplateName;
40use ComboStrap\Meta\Field\Region;
41use ComboStrap\Meta\Field\SocialCardImage;
42use ComboStrap\Meta\Field\TwitterImage;
43use ComboStrap\ModificationDate;
44use ComboStrap\CreationDate;
45use ComboStrap\PageDescription;
46use ComboStrap\PageId;
47use ComboStrap\PageImageUsage;
48use ComboStrap\PageKeywords;
49use ComboStrap\PageLevel;
50use ComboStrap\PagePath;
51use ComboStrap\PagePublicationDate;
52use ComboStrap\PageTitle;
53use ComboStrap\PageType;
54use ComboStrap\PageUrlPath;
55use ComboStrap\PluginUtility;
56use ComboStrap\QualityDynamicMonitoringOverwrite;
57use ComboStrap\References;
58use ComboStrap\ReplicationDate;
59use ComboStrap\ResourceName;
60use ComboStrap\Slug;
61use ComboStrap\StartDate;
62
63class MetadataSystem
64{
65
66    /**
67     * All known metadatas
68     */
69    public const METADATAS = [
70        Aliases::PROPERTY_NAME => Aliases::class,
71        Canonical::PROPERTY_NAME => Canonical::class,
72        EndDate::PROPERTY_NAME => EndDate::class,
73        PageType::PROPERTY_NAME => PageType::class,
74        PageH1::PROPERTY_NAME => PageH1::class,
75        PageUrlPath::PROPERTY_NAME => PageUrlPath::class,
76        Lang::PROPERTY_NAME => Lang::class,
77        LdJson::PROPERTY_NAME => LdJson::class,
78        LdJson::OLD_ORGANIZATION_PROPERTY => LdJson::class,
79        PageTitle::PROPERTY_NAME => PageTitle::class,
80        PagePublicationDate::PROPERTY_NAME => PagePublicationDate::class,
81        PagePublicationDate::OLD_META_KEY => PagePublicationDate::class,
82        Region::PROPERTY_NAME => Region::class,
83        ResourceName::PROPERTY_NAME => ResourceName::class,
84        StartDate::PROPERTY_NAME => StartDate::class,
85        PageDescription::PROPERTY_NAME => PageDescription::class,
86        DisqusIdentifier::PROPERTY_NAME => DisqusIdentifier::class,
87        Slug::PROPERTY_NAME => Slug::class,
88        PageKeywords::PROPERTY_NAME => PageKeywords::class,
89        CacheExpirationFrequency::PROPERTY_NAME => CacheExpirationFrequency::class,
90        QualityDynamicMonitoringOverwrite::PROPERTY_NAME => QualityDynamicMonitoringOverwrite::class,
91        LowQualityPageOverwrite::PROPERTY_NAME => LowQualityPageOverwrite::class,
92        Locale::PROPERTY_NAME => Locale::class,
93        CacheExpirationDate::PROPERTY_NAME => CacheExpirationDate::class,
94        FeaturedImage::PROPERTY_NAME => FeaturedImage::class,
95        FeaturedSvgImage::PROPERTY_NAME => FeaturedSvgImage::class,
96        FeaturedRasterImage::PROPERTY_NAME => FeaturedRasterImage::class,
97        FeaturedIcon::PROPERTY_NAME => FeaturedIcon::class,
98        Lead::PROPERTY_NAME => Lead::class,
99        Label::PROPERTY_NAME => Label::class,
100        TwitterImage::PROPERTY_NAME => TwitterImage::class,
101        FacebookImage::PROPERTY_NAME => FacebookImage::class,
102        AliasPath::PROPERTY_NAME => Aliases::class,
103        AliasType::PROPERTY_NAME => Aliases::class,
104        PageImages::PROPERTY_NAME => PageImages::class,
105        PageImages::OLD_PROPERTY_NAME => PageImages::class,
106        PageImagePath::PROPERTY_NAME => PageImages::class,
107        PageImageUsage::PROPERTY_NAME => PageImages::class,
108        SocialCardImage::PROPERTY_NAME => SocialCardImage::class,
109        AncestorImage::PROPERTY_NAME => AncestorImage::class,
110        FirstImage::PROPERTY_NAME => FirstImage::class,
111        Region::OLD_REGION_PROPERTY => Region::class,
112        PageTemplateName::PROPERTY_NAME => PageTemplateName::class,
113        PageTemplateName::PROPERTY_NAME_OLD => PageTemplateName::class,
114        DokuwikiId::DOKUWIKI_ID_ATTRIBUTE => DokuwikiId::class,
115        ReplicationDate::PROPERTY_NAME => ReplicationDate::class,
116        References::PROPERTY_NAME => References::class,
117        LowQualityCalculatedIndicator::PROPERTY_NAME => LowQualityCalculatedIndicator::class,
118        PagePath::PROPERTY_NAME => PagePath::class,
119        CreationDate::PROPERTY_NAME => CreationDate::class,
120        ModificationDate::PROPERTY_NAME => ModificationDate::class,
121        PageLevel::PROPERTY_NAME => PageLevel::class,
122        PageId::PROPERTY_NAME => PageId::class
123    ];
124
125
126    /**
127     * @return Metadata[]
128     */
129    public static function getMetadataObjects(): array
130    {
131        /**
132         * TODO: create a metadata metadata object and a metadata processing object
133         *   We can't cache as we mix for now, in the same object
134         *     * the metadata metadata (ie {@link Metadata::isOnForm()}, ...
135         *     * and the process object {@link Metadata::setReadStore()}, writestore, value
136         */
137        $metadatas = [];
138        foreach (self::METADATAS as $metadataClass) {
139            $metadatas[] = new $metadataClass();
140        }
141        return $metadatas;
142
143    }
144
145    /**
146     * @return Metadata[]
147     */
148    public static function getMetadataClasses(): array
149    {
150        return self::METADATAS;
151    }
152
153    /**
154     * @param object|string $class
155     * @param Metadata|null $parent
156     * @return Metadata
157     * @throws ExceptionBadArgument - if the class is not a metadata class
158     */
159    public static function toMetadataObject($class, Metadata $parent = null): Metadata
160    {
161        if (!is_subclass_of($class, Metadata::class)) {
162            throw new ExceptionBadArgument("The class ($class) is not a metadata class");
163        }
164        return new $class($parent);
165    }
166
167    /**
168     * @return Metadata[]
169     */
170    public static function getMutableMetadata(): array
171    {
172        $metas = [];
173        foreach (MetadataSystem::getMetadataObjects() as $metadata) {
174            if ($metadata::isMutable()) {
175                $metas[] = $metadata;
176            }
177        }
178        return $metas;
179    }
180
181
182    /**
183     * @throws ExceptionNotFound
184     */
185    public static function getForName(string $name): Metadata
186    {
187
188        $name = strtolower(trim($name));
189        $metadataClass = self::METADATAS[$name] ?? null;
190        if ($metadataClass !== null) {
191            return new $metadataClass();
192        }
193        throw new ExceptionNotFound("No metadata found with the name ($name)");
194
195    }
196}
197