1<?php
2
3
4namespace ComboStrap;
5
6
7use ComboStrap\Meta\Api\MetadataSystem;
8use ComboStrap\Meta\Field\Aliases;
9use ComboStrap\Meta\Field\AncestorImage;
10use ComboStrap\Meta\Field\FacebookImage;
11use ComboStrap\Meta\Field\FeaturedImage;
12use ComboStrap\Meta\Field\FeaturedRasterImage;
13use ComboStrap\Meta\Field\FeaturedSvgImage;
14use ComboStrap\Meta\Field\PageH1;
15use ComboStrap\Meta\Field\PageTemplateName;
16use ComboStrap\Meta\Field\Region;
17use ComboStrap\Meta\Field\TwitterImage;
18use ComboStrap\Meta\Form\FormMeta;
19use ComboStrap\Meta\Form\FormMetaTab;
20use ComboStrap\Meta\Store\MetadataDbStore;
21use ComboStrap\Meta\Store\MetadataDokuWikiStore;
22
23class MetaManagerForm
24{
25
26    public const TAB_PAGE_VALUE = "page";
27    public const TAB_TYPE_VALUE = "type";
28    public const TAB_CACHE_VALUE = "cache";
29    public const TAB_REDIRECTION_VALUE = "redirection";
30    public const TAB_LANGUAGE_VALUE = "language";
31    public const TAB_INTEGRATION_VALUE = "integration";
32    public const TAB_QUALITY_VALUE = "quality";
33    public const TAB_IMAGE_VALUE = "image";
34    private MarkupPath $page;
35
36
37    private const META_ORDERS = [ResourceName::PROPERTY_NAME,
38        PageTitle::PROPERTY_NAME,
39        Lead::PROPERTY_NAME,
40        PageH1::PROPERTY_NAME,
41        Label::PROPERTY_NAME,
42        PageDescription::PROPERTY_NAME,
43        PageKeywords::PROPERTY_NAME,
44        PagePath::PROPERTY_NAME,
45        Canonical::PROPERTY_NAME,
46        Slug::PROPERTY_NAME,
47        PageUrlPath::PROPERTY_NAME,
48        PageTemplateName::PROPERTY_NAME,
49        ModificationDate::PROPERTY_NAME,
50        CreationDate::PROPERTY_NAME,
51        FeaturedImage::PROPERTY_NAME,
52        FeaturedRasterImage::PROPERTY_NAME,
53        FeaturedSvgImage::PROPERTY_NAME,
54        FeaturedIcon::PROPERTY_NAME,
55        TwitterImage::PROPERTY_NAME,
56        FacebookImage::PROPERTY_NAME,
57        AncestorImage::PROPERTY_NAME,
58        FirstImage::PROPERTY_NAME,
59        Aliases::PROPERTY_NAME,
60        PageType::PROPERTY_NAME,
61        PagePublicationDate::PROPERTY_NAME,
62        StartDate::PROPERTY_NAME,
63        EndDate::PROPERTY_NAME,
64        LdJson::PROPERTY_NAME,
65        LowQualityPageOverwrite::PROPERTY_NAME,
66        QualityDynamicMonitoringOverwrite::PROPERTY_NAME,
67        Locale::PROPERTY_NAME,
68        Lang::PROPERTY_NAME,
69        Region::PROPERTY_NAME,
70        ReplicationDate::PROPERTY_NAME,
71        PageId::PROPERTY_NAME,
72        CacheExpirationFrequency::PROPERTY_NAME,
73        CacheExpirationDate::PROPERTY_NAME,
74        PageLevel::PROPERTY_NAME
75    ];
76
77    /**
78     * @var MetadataFormDataStore
79     */
80    private $targetFormDataStore;
81
82    /**
83     * MetaManager constructor.
84     */
85    public function __construct($page)
86    {
87        $this->page = $page;
88        $this->targetFormDataStore = MetadataFormDataStore::getOrCreateFromResource($page);
89    }
90
91    public static function createForPage(MarkupPath $page): MetaManagerForm
92    {
93        return new MetaManagerForm($page);
94    }
95
96    /**
97     * @return FormMeta
98     */
99    function toFormMeta(): FormMeta
100    {
101
102        /**
103         * Case when the page was changed externally
104         * with a new frontmatter
105         * The frontmatter data should be first replicated into the metadata file
106         */
107        $fetcherMarkup = $this->page->getInstructionsDocument();
108        $fetcherMarkup->getInstructions();
109
110
111        /**
112         * Creation
113         */
114        $name = $this->page->getPathObject()->toAbsoluteId();
115        $formMeta = FormMeta::create($name)
116            ->setType(FormMeta::FORM_NAV_TABS_TYPE);
117
118
119        /**
120         * The manager
121         */
122        $dokuwikiFsStore = MetadataDokuWikiStore::getOrCreateFromResource($this->page);
123        try {
124            $dbStore = MetadataDbStore::getOrCreateFromResource($this->page);
125        } catch (ExceptionNotExists|ExceptionSqliteNotAvailable $e) {
126            LogUtility::error("Error with the db store" . $e->getMessage(), "metamanageform", $e);
127            $dbStore = $dokuwikiFsStore;
128        }
129        $metadataNameInOrder = self::META_ORDERS;
130
131
132        foreach ($metadataNameInOrder as $metadataName) {
133            try {
134                $metadataObject = MetadataSystem::getForName($metadataName);
135            } catch (ExceptionNotFound $e) {
136                LogUtility::internalError("The metadata ($metadataName) was not found");
137                continue;
138            }
139            if (!$metadataObject::isOnForm()) {
140                LogUtility::internalError("This metadata should not be on the order list as it's not for the form");
141                continue;
142            }
143            $store = $dokuwikiFsStore;
144            if ($metadataName == ReplicationDate::PROPERTY_NAME) {
145                /**
146                 * Date is only written in the database
147                 * to not trigger a new rendering
148                 * (every metadata updates trigger a new rendering)
149                 */
150                $store = $dbStore;
151            }
152            $metadataObject
153                ->setResource($this->page)
154                ->setReadStore($store)
155                ->buildFromReadStore()
156                ->setWriteStore($this->targetFormDataStore);
157            $formMeta->addFormFieldFromMetadata($metadataObject);
158        }
159
160        /**
161         * Metadata that are not in the order list
162         */
163        foreach (MetadataSystem::getMetadataClasses() as $metadata) {
164            if (!$metadata::isOnForm()) {
165                continue;
166            }
167            if (!in_array($metadata::getName(), $metadataNameInOrder)) {
168                $metadataObject = (new $metadata())
169                    ->setResource($this->page)
170                    ->setReadStore($dokuwikiFsStore)
171                    ->buildFromReadStore()
172                    ->setWriteStore($this->targetFormDataStore);
173                $formMeta->addFormFieldFromMetadata($metadataObject);
174            }
175        }
176
177
178        /**
179         * Tabs (for whatever reason, javascript keep the order of the properties
180         * and therefore the order of the tabs)
181         */
182        $formMeta
183            ->addTab(
184                FormMetaTab::create(self::TAB_PAGE_VALUE)
185                    ->setLabel("Page")
186                    ->setWidthLabel(3)
187                    ->setWidthField(9)
188            )
189            ->addTab(
190                FormMetaTab::create(self::TAB_TYPE_VALUE)
191                    ->setLabel("Page Type")
192                    ->setWidthLabel(3)
193                    ->setWidthField(9)
194            )
195            ->addTab(
196                FormMetaTab::create(self::TAB_REDIRECTION_VALUE)
197                    ->setLabel("Redirection")
198                    ->setWidthLabel(3)
199                    ->setWidthField(9)
200            )
201            ->addTab(
202                FormMetaTab::create(self::TAB_IMAGE_VALUE)
203                    ->setLabel("Images")
204                    ->setWidthLabel(3)
205                    ->setWidthField(9)
206            )
207            ->addTab(
208                FormMetaTab::create(self::TAB_QUALITY_VALUE)
209                    ->setLabel("Quality")
210                    ->setWidthLabel(6)
211                    ->setWidthField(6)
212            )->addTab(
213                FormMetaTab::create(self::TAB_LANGUAGE_VALUE)
214                    ->setLabel("Language")
215                    ->setWidthLabel(2)
216                    ->setWidthField(10)
217            )->addTab(
218                FormMetaTab::create(self::TAB_INTEGRATION_VALUE)
219                    ->setLabel("Integration")
220                    ->setWidthLabel(4)
221                    ->setWidthField(8)
222            )->addTab(
223                FormMetaTab::create(self::TAB_CACHE_VALUE)
224                    ->setLabel("Cache")
225                    ->setWidthLabel(6)
226                    ->setWidthField(6)
227            );
228
229
230        return $formMeta;
231
232    }
233
234
235    public function toFormData(): array
236    {
237        return $this->toFormMeta()->toFormData();
238    }
239
240
241}
242