1<?php namespace ILIAS\GlobalScreen\Scope\Layout\Collector;
2
3use ILIAS\GlobalScreen\Client\Client;
4use ILIAS\GlobalScreen\Client\ClientSettings;
5use ILIAS\GlobalScreen\Client\ItemState;
6use ILIAS\GlobalScreen\Client\ModeToggle;
7use ILIAS\GlobalScreen\Collector\AbstractBaseCollector;
8use ILIAS\GlobalScreen\Scope\Layout\Factory\BreadCrumbsModification;
9use ILIAS\GlobalScreen\Scope\Layout\Factory\ContentModification;
10use ILIAS\GlobalScreen\Scope\Layout\Factory\FooterModification;
11use ILIAS\GlobalScreen\Scope\Layout\Factory\LayoutModification;
12use ILIAS\GlobalScreen\Scope\Layout\Factory\LogoModification;
13use ILIAS\GlobalScreen\Scope\Layout\Factory\MainBarModification;
14use ILIAS\GlobalScreen\Scope\Layout\Factory\MetaBarModification;
15use ILIAS\GlobalScreen\Scope\Layout\Factory\NullModification;
16use ILIAS\GlobalScreen\Scope\Layout\Factory\PageBuilderModification;
17use ILIAS\GlobalScreen\Scope\Layout\Factory\ShortTitleModification;
18use ILIAS\GlobalScreen\Scope\Layout\Factory\TitleModification;
19use ILIAS\GlobalScreen\Scope\Layout\Factory\ViewTitleModification;
20use ILIAS\GlobalScreen\Scope\Layout\MetaContent\MetaContent;
21use ILIAS\GlobalScreen\Scope\Layout\ModificationHandler;
22use ILIAS\GlobalScreen\Scope\Layout\Provider\ModificationProvider;
23use ILIAS\GlobalScreen\ScreenContext\Stack\CalledContexts;
24use ILIAS\UI\Component\Layout\Page\Page;
25use LogicException;
26
27/**
28 * Class MainLayoutCollector
29 *
30 * @internal
31 *
32 * @author Fabian Schmid <fs@studer-raimann.ch>
33 */
34class MainLayoutCollector extends AbstractBaseCollector
35{
36
37    /**
38     * @var ModificationHandler
39     */
40    private $modification_handler;
41    /**
42     * @var ModificationProvider[]
43     */
44    private $providers = [];
45
46
47    /**
48     * MainLayoutCollector constructor.
49     *
50     * @param array $providers
51     */
52    public function __construct(array $providers)
53    {
54        $this->providers = $providers;
55        $this->modification_handler = new ModificationHandler();
56    }
57
58
59    public function collectStructure() : void
60    {
61        // Client
62        $settings = new ClientSettings();
63        $settings->setHashing(true);
64        $settings->setLogging(false);
65
66        $client = new Client($settings);
67        $client->init($this->getMetaContent());
68
69        $called_contexts = $this->getContextStack();
70
71        $final_content_modification = new NullModification();
72        $final_logo_modification = new NullModification();
73        $final_breadcrumbs_modification = new NullModification();
74        $final_main_bar_modification = new NullModification();
75        $final_meta_bar_modification = new NullModification();
76        $final_page_modification = new NullModification();
77        $final_footer_modification = new NullModification();
78        $final_title_modification = new NullModification();
79        $final_short_title_modification = new NullModification();
80        $final_view_title_modification = new NullModification();
81
82        foreach ($this->providers as $provider) {
83            $context_collection = $provider->isInterestedInContexts();
84            if (!$context_collection->hasMatch($called_contexts)) {
85                continue;
86            }
87
88            // CONTENT
89            $content_modification = $provider->getContentModification($called_contexts);
90            $this->replaceModification($final_content_modification, $content_modification, ContentModification::class);
91            // LOGO
92            $logo_modification = $provider->getLogoModification($called_contexts);
93            $this->replaceModification($final_logo_modification, $logo_modification, LogoModification::class);
94            // BREADCRUMBS
95            $breadcrumbs_modification = $provider->getBreadCrumbsModification($called_contexts);
96            $this->replaceModification($final_breadcrumbs_modification, $breadcrumbs_modification, BreadCrumbsModification::class);
97            // MAINBAR
98            $main_bar_modification = $provider->getMainBarModification($called_contexts);
99            $this->replaceModification($final_main_bar_modification, $main_bar_modification, MainBarModification::class);
100            // METABAR
101            $meta_bar_modification = $provider->getMetaBarModification($called_contexts);
102            $this->replaceModification($final_meta_bar_modification, $meta_bar_modification, MetaBarModification::class);
103            // FOOTER
104            $footer_modification = $provider->getFooterModification($called_contexts);
105            $this->replaceModification($final_footer_modification, $footer_modification, FooterModification::class);
106            // PAGE
107            $page_modification = $provider->getPageBuilderDecorator($called_contexts);
108            $this->replaceModification($final_page_modification, $page_modification, PageBuilderModification::class);
109            // Pagetitle
110            $title_modification = $provider->getTitleModification($called_contexts);
111            $this->replaceModification($final_title_modification, $title_modification, TitleModification::class);
112
113            $short_title_modification = $provider->getShortTitleModification($called_contexts);
114            $this->replaceModification($final_short_title_modification, $short_title_modification, ShortTitleModification::class);
115
116            $view_title_modification = $provider->getViewTitleModification($called_contexts);
117            $this->replaceModification($final_view_title_modification, $view_title_modification, ViewTitleModification::class);
118        }
119
120        if ($final_content_modification->hasValidModification()) {
121            $this->modification_handler->modifyContentWithClosure($final_content_modification->getModification());
122        }
123        if ($final_logo_modification->hasValidModification()) {
124            $this->modification_handler->modifyLogoWithClosure($final_logo_modification->getModification());
125        }
126        if ($final_breadcrumbs_modification->hasValidModification()) {
127            $this->modification_handler->modifyBreadCrumbsWithClosure($final_breadcrumbs_modification->getModification());
128        }
129        if ($final_main_bar_modification->hasValidModification()) {
130            $this->modification_handler->modifyMainBarWithClosure($final_main_bar_modification->getModification());
131        }
132        if ($final_meta_bar_modification->hasValidModification()) {
133            $this->modification_handler->modifyMetaBarWithClosure($final_meta_bar_modification->getModification());
134        }
135        if ($final_footer_modification->hasValidModification()) {
136            $this->modification_handler->modifyFooterWithClosure($final_footer_modification->getModification());
137        }
138        if ($final_page_modification->hasValidModification()) {
139            $this->modification_handler->modifyPageBuilderWithClosure($final_page_modification->getModification());
140        }
141        if ($final_title_modification->hasValidModification()) {
142            $this->modification_handler->modifyTitleWithClosure($final_title_modification->getModification());
143        }
144        if ($final_short_title_modification->hasValidModification()) {
145            $this->modification_handler->modifyShortTitleWithClosure($final_short_title_modification->getModification());
146        }
147        if ($final_view_title_modification->hasValidModification()) {
148            $this->modification_handler->modifyViewTitleWithClosure($final_view_title_modification->getModification());
149        }
150    }
151
152
153    public function filterItemsByVisibilty(bool $skip_async = false) : void
154    {
155        // TODO: Implement filterItemsByVisibilty() method.
156    }
157
158
159    public function prepareItemsForUIRepresentation() : void
160    {
161        // TODO: Implement prepareItemsForUIRepresentation() method.
162    }
163
164    public function cleanupItemsForUIRepresentation() : void
165    {
166        // TODO: Implement cleanupItemsForUIRepresentation() method.
167    }
168
169    public function sortItemsForUIRepresentation() : void
170    {
171        // TODO: Implement sortItemsForUIRepresentation() method.
172    }
173
174
175    /**
176     * @inheritDoc
177     */
178    public function getItemsForUIRepresentation() : \Generator
179    {
180        // TODO: Implement getItemsForUIRepresentation() method.
181    }
182
183
184    /**
185     * @inheritDoc
186     */
187    public function hasItems() : bool
188    {
189        return true;
190    }
191
192
193    /**
194     * @param LayoutModification      $current_modification
195     * @param LayoutModification|null $candicate
196     * @param string                  $type
197     */
198    private function replaceModification(LayoutModification &$current_modification, ?LayoutModification $candicate, string $type)
199    {
200        if (is_a($candicate, $type) && $candicate->hasValidModification()) {
201            if ($candicate->getPriority() === $current_modification->getPriority()) {
202                throw new LogicException("There are competing Modifications for $type with the same priority ({$candicate->getPriority()})");
203            } elseif ($candicate->getPriority() > $current_modification->getPriority()) {
204                $current_modification = $candicate;
205            }
206        }
207    }
208
209
210    /**
211     * @return Page
212     */
213    public function getFinalPage() : Page
214    {
215        $this->collectOnce();
216
217        return $this->modification_handler->getPageWithPagePartProviders();
218    }
219
220
221    /**
222     * @return CalledContexts
223     */
224    private function getContextStack() : CalledContexts
225    {
226        global $DIC;
227        $called_contexts = $DIC->globalScreen()->tool()->context()->stack();
228
229        return $called_contexts;
230    }
231
232
233    /**
234     * @return MetaContent
235     */
236    private function getMetaContent() : MetaContent
237    {
238        global $DIC;
239
240        return $DIC->globalScreen()->layout()->meta();
241    }
242}
243