Completed
Push — master ( 952fde...7bae76 )
by Vladimir
11s
created

Compiler::compileAll()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 2
1
<?php
2
3
/**
4
 * @copyright 2018 Vladimir Jimenez
5
 * @license   https://github.com/stakx-io/stakx/blob/master/LICENSE.md MIT
6
 */
7
8
namespace allejo\stakx;
9
10
use allejo\stakx\Document\BasePageView;
11
use allejo\stakx\Document\DynamicPageView;
12
use allejo\stakx\Document\PermalinkDocument;
13
use allejo\stakx\Document\RepeaterPageView;
14
use allejo\stakx\Document\StaticPageView;
15
use allejo\stakx\Document\TemplateReadyDocument;
16
use allejo\stakx\Event\CompileProcessPostRenderPageView;
17
use allejo\stakx\Event\CompileProcessPreRenderPageView;
18
use allejo\stakx\Event\CompileProcessTemplateCreation;
19
use allejo\stakx\Exception\FileAwareException;
20
use allejo\stakx\Filesystem\Folder;
21
use allejo\stakx\FrontMatter\ExpandedValue;
22
use allejo\stakx\Manager\CollectionManager;
23
use allejo\stakx\Manager\DataManager;
24
use allejo\stakx\Manager\MenuManager;
25
use allejo\stakx\Manager\PageManager;
26
use allejo\stakx\Templating\TemplateBridgeInterface;
27
use allejo\stakx\Templating\TemplateErrorInterface;
28
use allejo\stakx\Templating\TemplateInterface;
29
use Psr\Log\LoggerInterface;
30
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
31
32
/**
33
 * This class takes care of rendering the Twig body of PageViews with the respective information and it also takes care
34
 * of writing the rendered Twig to the filesystem.
35
 *
36
 * @internal
37
 *
38
 * @since 0.1.1
39
 */
40
class Compiler
41
{
42
    /** @var string|false */
43
    private $redirectTemplate;
44
45
    /**
46
     * All of the PageViews handled by this Compiler instance indexed by their file paths relative to the site root.
47
     *
48
     * ```
49
     * array['_pages/index.html.twig'] = &PageView;
50
     * ```
51
     *
52
     * @var BasePageView[]
53
     */
54
    private $pageViewsFlattened;
55
56
    /** @var string[] */
57
    private $templateMapping;
58
59
    /** @var Folder */
60
    private $folder;
61
62
    /** @var string */
63
    private $theme;
64
65
    private $templateBridge;
66
    private $pageManager;
67
    private $eventDispatcher;
68
    private $configuration;
69
70 12
    public function __construct(
71
        TemplateBridgeInterface $templateBridge,
72
        Configuration $configuration,
73
        CollectionManager $collectionManager,
74
        DataManager $dataManager,
75
        MenuManager $menuManager,
76
        PageManager $pageManager,
77
        EventDispatcherInterface $eventDispatcher,
78
        LoggerInterface $logger
79
    ) {
80 12
        $this->templateBridge = $templateBridge;
81 12
        $this->theme = '';
82 12
        $this->pageManager = $pageManager;
83 12
        $this->eventDispatcher = $eventDispatcher;
84 12
        $this->logger = $logger;
0 ignored issues
show
Bug introduced by
The property logger does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
85 12
        $this->configuration = $configuration;
86
87 12
        $this->pageViewsFlattened = &$pageManager->getPageViewsFlattened();
88 12
        $this->redirectTemplate = $this->configuration->getRedirectTemplate();
89
90
        // Global variables maintained by stakx
91 12
        $this->templateBridge->setGlobalVariable('site', $configuration->getConfiguration());
92 12
        $this->templateBridge->setGlobalVariable('data', $dataManager->getJailedDataItems());
93 12
        $this->templateBridge->setGlobalVariable('collections', $collectionManager->getJailedCollections());
94 12
        $this->templateBridge->setGlobalVariable('menu', $menuManager->getSiteMenu());
95 12
        $this->templateBridge->setGlobalVariable('pages', $pageManager->getJailedStaticPageViews());
96 12
    }
97
98
    /**
99
     * @param Folder $folder
100
     */
101 12
    public function setTargetFolder(Folder $folder)
102
    {
103 12
        $this->folder = $folder;
104 12
    }
105
106
    /**
107
     * @param string $themeName
108
     */
109
    public function setThemeName($themeName)
110
    {
111
        $this->theme = $themeName;
112
    }
113
114
    ///
115
    // Twig parent templates
116
    ///
117
118
    public function getTemplateMappings()
119
    {
120
        return $this->templateMapping;
121
    }
122
123
    ///
124
    // IO Functionality
125
    ///
126
127
    /**
128
     * Compile all of the PageViews registered with the compiler.
129
     *
130
     * @since 0.1.0
131
     */
132 12
    public function compileAll()
133
    {
134 12
        foreach ($this->pageViewsFlattened as &$pageView)
135
        {
136 12
            $this->compilePageView($pageView);
137
        }
138 12
    }
139
140
    /**
141
     * Compile an individual PageView item.
142
     *
143
     * This function will take care of determining *how* to treat the PageView and write the compiled output to a the
144
     * respective target file.
145
     *
146
     * @param DynamicPageView|RepeaterPageView|StaticPageView $pageView The PageView that needs to be compiled
0 ignored issues
show
Documentation introduced by
Should the type for parameter $pageView not be BasePageView?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
147
     *
148
     * @since 0.1.1
149
     */
150 12
    public function compilePageView(BasePageView &$pageView)
151
    {
152 12
        $this->templateBridge->setGlobalVariable('__currentTemplate', $pageView->getAbsoluteFilePath());
153 12
        $this->logger->debug('Compiling {type} PageView: {pageview}', [
154 12
            'pageview' => $pageView->getRelativeFilePath(),
155 12
            'type' => $pageView->getType(),
156
        ]);
157
158
        try
159
        {
160 12
            switch ($pageView->getType())
161
            {
162
                case BasePageView::STATIC_TYPE:
163 10
                    $this->compileStaticPageView($pageView);
0 ignored issues
show
Compatibility introduced by
$pageView of type object<allejo\stakx\Document\BasePageView> is not a sub-type of object<allejo\stakx\Document\StaticPageView>. It seems like you assume a child class of the class allejo\stakx\Document\BasePageView to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
164 10
                    $this->compileStandardRedirects($pageView);
165 10
                    break;
166
167
                case BasePageView::DYNAMIC_TYPE:
168
                    $this->compileDynamicPageView($pageView);
0 ignored issues
show
Compatibility introduced by
$pageView of type object<allejo\stakx\Document\BasePageView> is not a sub-type of object<allejo\stakx\Document\DynamicPageView>. It seems like you assume a child class of the class allejo\stakx\Document\BasePageView to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
169
                    $this->compileStandardRedirects($pageView);
170
                    break;
171
172
                case BasePageView::REPEATER_TYPE:
173 3
                    $this->compileRepeaterPageView($pageView);
0 ignored issues
show
Compatibility introduced by
$pageView of type object<allejo\stakx\Document\BasePageView> is not a sub-type of object<allejo\stakx\Document\RepeaterPageView>. It seems like you assume a child class of the class allejo\stakx\Document\BasePageView to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
174 3
                    $this->compileExpandedRedirects($pageView);
175 12
                    break;
176
            }
177
        }
178
        catch (TemplateErrorInterface $e)
179
        {
180
            throw new FileAwareException(
181
                $e->getMessage(),
182
                $e->getCode(),
183
                $e,
184
                $pageView->getRelativeFilePath(),
185
                $e->getTemplateLine() + $pageView->getLineOffset()
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface allejo\stakx\Document\PermalinkDocument as the method getLineOffset() does only exist in the following implementations of said interface: allejo\stakx\Document\BasePageView, allejo\stakx\Document\ContentItem, allejo\stakx\Document\DynamicPageView, allejo\stakx\Document\PermalinkFrontMatterDocument, allejo\stakx\Document\RepeaterPageView, allejo\stakx\Document\StaticPageView.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
186
            );
187
        }
188 12
    }
189
190
    /**
191
     * Write the compiled output for a static PageView.
192
     *
193
     * @since 0.1.1
194
     *
195
     * @throws TemplateErrorInterface
196
     */
197 10
    private function compileStaticPageView(StaticPageView &$pageView)
198
    {
199 10
        $pageView->compile();
200
201 10
        $this->writeToFilesystem(
202 10
            $pageView->getTargetFile(),
203 10
            $this->renderStaticPageView($pageView),
204 10
            BasePageView::STATIC_TYPE
205
        );
206 10
    }
207
208
    /**
209
     * Write the compiled output for a dynamic PageView.
210
     *
211
     * @param DynamicPageView $pageView
212
     *
213
     * @since 0.1.1
214
     *
215
     * @throws TemplateErrorInterface
216
     */
217
    private function compileDynamicPageView(DynamicPageView &$pageView)
218
    {
219
        $contentItems = $pageView->getCollectableItems();
220
        $template = $this->createTwigTemplate($pageView);
221
222
        foreach ($contentItems as &$contentItem)
223
        {
224
            if ($contentItem->isDraft() && !Service::hasRunTimeFlag(RuntimeStatus::USING_DRAFTS))
225
            {
226
                $this->logger->debug('{file}: marked as a draft', [
227
                    'file' => $contentItem->getRelativeFilePath(),
228
                ]);
229
230
                continue;
231
            }
232
233
            $this->writeToFilesystem(
234
                $contentItem->getTargetFile(),
235
                $this->renderDynamicPageView($template, $contentItem),
0 ignored issues
show
Documentation introduced by
$contentItem is of type object<allejo\stakx\Document\CollectableItem>, but the function expects a object<allejo\stakx\Docu...\TemplateReadyDocument>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
236
                BasePageView::DYNAMIC_TYPE
237
            );
238
239
            $this->compileStandardRedirects($contentItem);
0 ignored issues
show
Documentation introduced by
$contentItem is of type object<allejo\stakx\Docu...\TemplateReadyDocument>, but the function expects a object<allejo\stakx\Document\PermalinkDocument>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
240
        }
241
    }
242
243
    /**
244
     * Write the compiled output for a repeater PageView.
245
     *
246
     * @param RepeaterPageView $pageView
247
     *
248
     * @since 0.1.1
249
     *
250
     * @throws TemplateErrorInterface
251
     */
252 3
    private function compileRepeaterPageView(RepeaterPageView &$pageView)
253
    {
254 3
        $pageView->rewindPermalink();
255
256 3
        $template = $this->createTwigTemplate($pageView);
257 3
        $permalinks = $pageView->getRepeaterPermalinks();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class allejo\stakx\Document\BasePageView as the method getRepeaterPermalinks() does only exist in the following sub-classes of allejo\stakx\Document\BasePageView: allejo\stakx\Document\RepeaterPageView. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
258
259 3
        foreach ($permalinks as $permalink)
260
        {
261 3
            $pageView->bumpPermalink();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class allejo\stakx\Document\BasePageView as the method bumpPermalink() does only exist in the following sub-classes of allejo\stakx\Document\BasePageView: allejo\stakx\Document\RepeaterPageView. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
262
263 3
            $this->writeToFilesystem(
264 3
                $pageView->getTargetFile(),
265 3
                $this->renderRepeaterPageView($template, $pageView, $permalink),
0 ignored issues
show
Compatibility introduced by
$pageView of type object<allejo\stakx\Document\BasePageView> is not a sub-type of object<allejo\stakx\Document\RepeaterPageView>. It seems like you assume a child class of the class allejo\stakx\Document\BasePageView to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
266 3
                BasePageView::REPEATER_TYPE
267
            );
268
        }
269 3
    }
270
271
    /**
272
     * Write the given $output to the $targetFile as a $fileType PageView.
273
     *
274
     * @param string $targetFile
275
     * @param string $output
276
     * @param string $fileType
277
     */
278 12
    private function writeToFilesystem($targetFile, $output, $fileType)
279
    {
280 12
        $this->logger->notice('Writing {type} PageView file: {file}', [
281 12
            'type' => $fileType,
282 12
            'file' => $targetFile,
283
        ]);
284 12
        $this->folder->writeFile($targetFile, $output);
285 12
    }
286
287
    ///
288
    // Redirect handling
289
    ///
290
291
    /**
292
     * Write redirects for standard redirects.
293
     *
294
     * @throws TemplateErrorInterface
295
     *
296
     * @since 0.1.1
297
     */
298 10
    private function compileStandardRedirects(PermalinkDocument &$pageView)
299
    {
300 10
        $redirects = $pageView->getRedirects();
301
302 10 View Code Duplication
        foreach ($redirects as $redirect)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
303
        {
304 1
            $redirectPageView = BasePageView::createRedirect(
305 1
                $redirect,
306 1
                $pageView->getPermalink(),
307 1
                $this->redirectTemplate
308
            );
309 1
            $redirectPageView->evaluateFrontMatter([], [
310 1
                'site' => $this->configuration->getConfiguration(),
311
            ]);
312
313 1
            $this->compileStaticPageView($redirectPageView);
314
        }
315 10
    }
316
317
    /**
318
     * Write redirects for expanded redirects.
319
     *
320
     * @param RepeaterPageView $pageView
321
     *
322
     * @since 0.1.1
323
     */
324 3
    private function compileExpandedRedirects(RepeaterPageView &$pageView)
325
    {
326 3
        $permalinks = $pageView->getRepeaterPermalinks();
327
328
        /** @var ExpandedValue[] $repeaterRedirect */
329 3
        foreach ($pageView->getRepeaterRedirects() as $repeaterRedirect)
330
        {
331
            /**
332
             * @var int
333
             * @var ExpandedValue $redirect
334
             */
335 1 View Code Duplication
            foreach ($repeaterRedirect as $index => $redirect)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
336
            {
337 1
                $redirectPageView = BasePageView::createRedirect(
338 1
                    $redirect->getEvaluated(),
339 1
                    $permalinks[$index]->getEvaluated(),
340 1
                    $this->redirectTemplate
341
                );
342 1
                $redirectPageView->evaluateFrontMatter([], [
343 1
                    'site' => $this->configuration->getConfiguration(),
344
                ]);
345
346 1
                $this->compilePageView($redirectPageView);
347
            }
348
        }
349 3
    }
350
351
    ///
352
    // Twig Functionality
353
    ///
354
355
    /**
356
     * Get the compiled HTML for a specific iteration of a repeater PageView.
357
     *
358
     * @param TemplateInterface $template
359
     * @param RepeaterPageView  $pageView
360
     * @param ExpandedValue     $expandedValue
361
     *
362
     * @since  0.1.1
363
     *
364
     * @return string
365
     */
366 3
    private function renderRepeaterPageView(TemplateInterface &$template, RepeaterPageView &$pageView, ExpandedValue &$expandedValue)
367
    {
368
        $defaultContext = [
369 3
            'this' => $pageView->createJail(),
370
        ];
371
372 3
        $pageView->evaluateFrontMatter([
373 3
            'permalink' => $expandedValue->getEvaluated(),
374 3
            'iterators' => $expandedValue->getIterators(),
375
        ]);
376
377 3
        $preEvent = new CompileProcessPreRenderPageView(BasePageView::REPEATER_TYPE);
378 3
        $this->eventDispatcher->dispatch(CompileProcessPreRenderPageView::NAME, $preEvent);
379
380 3
        $context = array_merge($preEvent->getCustomVariables(), $defaultContext);
381
        $output = $template
382 3
            ->render($context)
383
        ;
384
385 3
        $postEvent = new CompileProcessPostRenderPageView(BasePageView::REPEATER_TYPE, $output);
386 3
        $this->eventDispatcher->dispatch(CompileProcessPostRenderPageView::NAME, $postEvent);
387
388 3
        return $postEvent->getCompiledOutput();
389
    }
390
391
    /**
392
     * Get the compiled HTML for a specific ContentItem.
393
     *
394
     * @since  0.1.1
395
     *
396
     * @return string
397
     */
398 View Code Duplication
    private function renderDynamicPageView(TemplateInterface &$template, TemplateReadyDocument &$twigItem)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
399
    {
400
        $defaultContext = [
401
            'this' => $twigItem->createJail(),
402
        ];
403
404
        $preEvent = new CompileProcessPreRenderPageView(BasePageView::DYNAMIC_TYPE);
405
        $this->eventDispatcher->dispatch(CompileProcessPreRenderPageView::NAME, $preEvent);
406
407
        $context = array_merge($preEvent->getCustomVariables(), $defaultContext);
408
        $output = $template
409
            ->render($context)
410
        ;
411
412
        $postEvent = new CompileProcessPostRenderPageView(BasePageView::DYNAMIC_TYPE, $output);
413
        $this->eventDispatcher->dispatch(CompileProcessPostRenderPageView::NAME, $postEvent);
414
415
        return $postEvent->getCompiledOutput();
416
    }
417
418
    /**
419
     * Get the compiled HTML for a static PageView.
420
     *
421
     * @since  0.1.1
422
     *
423
     * @throws TemplateErrorInterface
424
     *
425
     * @return string
426
     */
427 10 View Code Duplication
    private function renderStaticPageView(StaticPageView &$pageView)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
428
    {
429
        $defaultContext = [
430 10
            'this' => $pageView->createJail(),
431
        ];
432
433 10
        $preEvent = new CompileProcessPreRenderPageView(BasePageView::STATIC_TYPE);
434 10
        $this->eventDispatcher->dispatch(CompileProcessPreRenderPageView::NAME, $preEvent);
435
436 10
        $context = array_merge($preEvent->getCustomVariables(), $defaultContext);
437
        $output = $this
438 10
            ->createTwigTemplate($pageView)
439 10
            ->render($context)
440
        ;
441
442 10
        $postEvent = new CompileProcessPostRenderPageView(BasePageView::STATIC_TYPE, $output);
443 10
        $this->eventDispatcher->dispatch(CompileProcessPostRenderPageView::NAME, $postEvent);
444
445 10
        return $postEvent->getCompiledOutput();
446
    }
447
448
    /**
449
     * Create a Twig template that just needs an array to render.
450
     *
451
     * @since  0.1.1
452
     *
453
     * @throws TemplateErrorInterface
454
     *
455
     * @return TemplateInterface
456
     */
457 12
    private function createTwigTemplate(BasePageView &$pageView)
458
    {
459
        try
460
        {
461 12
            $template = $this->templateBridge->createTemplate($pageView->getContent());
462
463 12
            $this->templateMapping[$template->getTemplateName()] = $pageView->getRelativeFilePath();
464
465 12
            $event = new CompileProcessTemplateCreation($pageView, $template, $this->theme);
466 12
            $this->eventDispatcher->dispatch(CompileProcessTemplateCreation::NAME, $event);
467
468 12
            return $template;
469
        }
470
        catch (TemplateErrorInterface $e)
471
        {
472
            $e
473
                ->setTemplateLine($e->getTemplateLine() + $pageView->getLineOffset())
474
                ->setContent($pageView->getContent())
475
                ->setName($pageView->getRelativeFilePath())
476
                ->setRelativeFilePath($pageView->getRelativeFilePath())
477
                ->buildException()
478
            ;
479
480
            throw $e;
481
        }
482
    }
483
}
484