Completed
Push — master ( b82aa8...9291f8 )
by Vladimir
02:16
created

Compiler::compileStandardRedirects()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18

Duplication

Lines 13
Ratio 72.22 %

Code Coverage

Tests 11
CRAP Score 2

Importance

Changes 0
Metric Value
dl 13
loc 18
ccs 11
cts 11
cp 1
rs 9.6666
c 0
b 0
f 0
cc 2
nc 2
nop 1
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\ContentItem;
12
use allejo\stakx\Document\DynamicPageView;
13
use allejo\stakx\Document\PermalinkDocument;
14
use allejo\stakx\Document\RepeaterPageView;
15
use allejo\stakx\Document\StaticPageView;
16
use allejo\stakx\Document\TemplateReadyDocument;
17
use allejo\stakx\Event\CompileProcessPostRenderPageView;
18
use allejo\stakx\Event\CompileProcessPreRenderPageView;
19
use allejo\stakx\Event\CompileProcessTemplateCreation;
20
use allejo\stakx\Exception\FileAwareException;
21
use allejo\stakx\Filesystem\Folder;
22
use allejo\stakx\FrontMatter\ExpandedValue;
23
use allejo\stakx\Manager\CollectionManager;
24
use allejo\stakx\Manager\DataManager;
25
use allejo\stakx\Manager\MenuManager;
26
use allejo\stakx\Manager\PageManager;
27
use allejo\stakx\Templating\TemplateBridgeInterface;
28
use allejo\stakx\Templating\TemplateErrorInterface;
29
use allejo\stakx\Templating\TemplateInterface;
30
use Psr\Log\LoggerInterface;
31
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
32
33
/**
34
 * This class takes care of rendering the Twig body of PageViews with the respective information and it also takes care
35
 * of writing the rendered Twig to the filesystem.
36
 *
37
 * @since 0.1.1
38
 */
39
class Compiler
40
{
41
    /** @var string|false */
42
    private $redirectTemplate;
43
44
    /**
45
     * All of the PageViews handled by this Compiler instance indexed by their file paths relative to the site root.
46
     *
47
     * ```
48
     * array['_pages/index.html.twig'] = &PageView;
49
     * ```
50
     *
51
     * @var BasePageView[]
52
     */
53
    private $pageViewsFlattened;
54
55
    /** @var string[] */
56
    private $templateMapping;
57
58
    /** @var Folder */
59
    private $folder;
60
61
    /** @var string */
62
    private $theme;
63
64
    private $templateBridge;
65
    private $pageManager;
66
    private $eventDispatcher;
67
    private $configuration;
68
    private $logger;
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;
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
        $this->templateBridge->setGlobalVariable('repeaters', $pageManager->getJailedRepeaterPageViews());
97 12
    }
98
99
    /**
100
     * @param Folder $folder
101
     */
102 12
    public function setTargetFolder(Folder $folder)
103
    {
104 12
        $this->folder = $folder;
105 12
    }
106
107
    /**
108
     * @param string $themeName
109
     */
110
    public function setThemeName($themeName)
111
    {
112
        $this->theme = $themeName;
113
    }
114
115
    ///
116
    // Twig parent templates
117
    ///
118
119
    public function getTemplateMappings()
120
    {
121
        return $this->templateMapping;
122
    }
123
124
    ///
125
    // Rendering HTML Functionality
126
    ///
127
128
    /**
129
     * Get the HTML for a Static PageView.
130
     *
131
     * This function just **renders** the HTML but does not write it to the filesystem. Use `compilePageView()` for that
132
     * instead.
133
     *
134
     * @param StaticPageView $pageView
135
     *
136
     * @throws TemplateErrorInterface
137
     *
138
     * @return string the HTML for a Static PageView
139
     */
140 10
    public function renderStaticPageView(StaticPageView $pageView)
141
    {
142 10
        $pageView->compile();
143
144 10
        return $this->buildStaticPageViewHTML($pageView);
145
    }
146
147
    /**
148
     * Get the HTML for a Dynamic PageView and ContentItem.
149
     *
150
     * This function just **renders** the HTML but does not write it to the filesystem. Use `compileDynamicPageView()`
151
     * for that instead.
152
     *
153
     * @param DynamicPageView       $pageView
154
     * @param TemplateReadyDocument $contentItem
155
     *
156
     * @throws TemplateErrorInterface
157
     *
158
     * @return string
159
     */
160
    public function renderDynamicPageView(DynamicPageView $pageView, TemplateReadyDocument $contentItem)
161
    {
162
        $template = $this->createTwigTemplate($pageView);
163
164
        return $this->buildDynamicPageViewHTML($template, $contentItem);
165
    }
166
167
    /**
168
     * Get the HTML for a Repeater PageView.
169
     *
170
     * @param RepeaterPageView $pageView
171
     * @param ExpandedValue    $expandedValue
172
     *
173
     * @throws TemplateErrorInterface
174
     *
175
     * @return string
176
     */
177
    public function renderRepeaterPageView(RepeaterPageView $pageView, ExpandedValue $expandedValue)
178
    {
179
        $template = $this->createTwigTemplate($pageView);
180
181
        return $this->buildRepeaterPageViewHTML($template, $pageView, $expandedValue);
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...
182
    }
183
184
    ///
185
    // IO Functionality
186
    ///
187
188
    /**
189
     * Compile all of the PageViews registered with the compiler.
190
     *
191
     * @since 0.1.0
192
     */
193 12
    public function compileAll()
194
    {
195 12
        foreach ($this->pageViewsFlattened as &$pageView)
196
        {
197 12
            $this->compilePageView($pageView);
198
        }
199 12
    }
200
201
    /**
202
     * Compile an individual PageView item.
203
     *
204
     * This function will take care of determining *how* to treat the PageView and write the compiled output to a the
205
     * respective target file.
206
     *
207
     * @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...
208
     *
209
     * @since 0.1.1
210
     */
211 12
    public function compilePageView(BasePageView &$pageView)
212
    {
213 12
        Service::setOption('currentTemplate', $pageView->getAbsoluteFilePath());
214 12
        $this->logger->debug('Compiling {type} PageView: {pageview}', [
215 12
            'pageview' => $pageView->getRelativeFilePath(),
216 12
            'type' => $pageView->getType(),
217
        ]);
218
219
        try
220
        {
221 12
            switch ($pageView->getType())
222
            {
223 12
                case BasePageView::STATIC_TYPE:
224 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...
225 10
                    $this->compileStandardRedirects($pageView);
226 10
                    break;
227
228 3
                case BasePageView::DYNAMIC_TYPE:
229
                    $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...
230
                    $this->compileStandardRedirects($pageView);
231
                    break;
232
233 3
                case BasePageView::REPEATER_TYPE:
234 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...
235 3
                    $this->compileExpandedRedirects($pageView);
236 12
                    break;
237
            }
238
        }
239
        catch (TemplateErrorInterface $e)
240
        {
241
            throw new FileAwareException(
242
                $e->getMessage(),
243
                $e->getCode(),
244
                $e,
245
                $pageView->getRelativeFilePath(),
246
                $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...
247
            );
248
        }
249 12
    }
250
251
    /**
252
     * Write the compiled output for a static PageView.
253
     *
254
     * @since 0.1.1
255
     *
256
     * @throws TemplateErrorInterface
257
     */
258 10
    private function compileStaticPageView(StaticPageView &$pageView)
259
    {
260 10
        $this->writeToFilesystem(
261 10
            $pageView->getTargetFile(),
262 10
            $this->renderStaticPageView($pageView),
263 10
            BasePageView::STATIC_TYPE
264
        );
265 10
    }
266
267
    /**
268
     * Write the compiled output for a dynamic PageView.
269
     *
270
     * @param DynamicPageView $pageView
271
     *
272
     * @since 0.1.1
273
     *
274
     * @throws TemplateErrorInterface
275
     */
276
    private function compileDynamicPageView(DynamicPageView &$pageView)
277
    {
278
        $contentItems = $pageView->getCollectableItems();
279
        $template = $this->createTwigTemplate($pageView);
280
281
        foreach ($contentItems as &$contentItem)
282
        {
283
            if ($contentItem->isDraft() && !Service::hasRunTimeFlag(RuntimeStatus::USING_DRAFTS))
284
            {
285
                $this->logger->debug('{file}: marked as a draft', [
286
                    'file' => $contentItem->getRelativeFilePath(),
287
                ]);
288
289
                continue;
290
            }
291
292
            $this->writeToFilesystem(
293
                $contentItem->getTargetFile(),
294
                $this->buildDynamicPageViewHTML($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...
295
                BasePageView::DYNAMIC_TYPE
296
            );
297
298
            $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...
299
        }
300
    }
301
302
    /**
303
     * Write the compiled output for a repeater PageView.
304
     *
305
     * @param RepeaterPageView $pageView
306
     *
307
     * @since 0.1.1
308
     *
309
     * @throws TemplateErrorInterface
310
     */
311 3
    private function compileRepeaterPageView(RepeaterPageView &$pageView)
312
    {
313 3
        $template = $this->createTwigTemplate($pageView);
314 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...
315
316 3
        foreach ($permalinks as $permalink)
317
        {
318 3
            $this->writeToFilesystem(
319 3
                $pageView->getTargetFile($permalink->getEvaluated()),
320 3
                $this->buildRepeaterPageViewHTML($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...
321 3
                BasePageView::REPEATER_TYPE
322
            );
323
        }
324 3
    }
325
326
    /**
327
     * Write the given $output to the $targetFile as a $fileType PageView.
328
     *
329
     * @param string $targetFile
330
     * @param string $output
331
     * @param string $fileType
332
     */
333 12
    private function writeToFilesystem($targetFile, $output, $fileType)
334
    {
335 12
        $this->logger->notice('Writing {type} PageView file: {file}', [
336 12
            'type' => $fileType,
337 12
            'file' => $targetFile,
338
        ]);
339 12
        $this->folder->writeFile($targetFile, $output);
340 12
    }
341
342
    ///
343
    // Redirect handling
344
    ///
345
346
    /**
347
     * Write redirects for standard redirects.
348
     *
349
     * @throws TemplateErrorInterface
350
     *
351
     * @since 0.1.1
352
     */
353 10
    private function compileStandardRedirects(PermalinkDocument &$pageView)
354
    {
355 10
        $redirects = $pageView->getRedirects();
356
357 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...
358
        {
359 1
            $redirectPageView = BasePageView::createRedirect(
360 1
                $redirect,
361 1
                $pageView->getPermalink(),
362 1
                $this->redirectTemplate
363
            );
364 1
            $redirectPageView->evaluateFrontMatter([], [
365 1
                'site' => $this->configuration->getConfiguration(),
366
            ]);
367
368 1
            $this->compileStaticPageView($redirectPageView);
369
        }
370 10
    }
371
372
    /**
373
     * Write redirects for expanded redirects.
374
     *
375
     * @param RepeaterPageView $pageView
376
     *
377
     * @since 0.1.1
378
     */
379 3
    private function compileExpandedRedirects(RepeaterPageView &$pageView)
380
    {
381 3
        $permalinks = $pageView->getRepeaterPermalinks();
382
383
        /** @var ExpandedValue[] $repeaterRedirect */
384 3
        foreach ($pageView->getRepeaterRedirects() as $repeaterRedirect)
385
        {
386
            /**
387
             * @var int
388
             * @var ExpandedValue $redirect
389
             */
390 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...
391
            {
392 1
                $redirectPageView = BasePageView::createRedirect(
393 1
                    $redirect->getEvaluated(),
394 1
                    $permalinks[$index]->getEvaluated(),
395 1
                    $this->redirectTemplate
396
                );
397 1
                $redirectPageView->evaluateFrontMatter([], [
398 1
                    'site' => $this->configuration->getConfiguration(),
399
                ]);
400
401 1
                $this->compilePageView($redirectPageView);
402
            }
403
        }
404 3
    }
405
406
    ///
407
    // Twig Functionality
408
    ///
409
410
    /**
411
     * Get the compiled HTML for a specific iteration of a repeater PageView.
412
     *
413
     * @param TemplateInterface $template
414
     * @param RepeaterPageView  $pageView
415
     * @param ExpandedValue     $expandedValue
416
     *
417
     * @since  0.1.1
418
     *
419
     * @return string
420
     */
421 3
    private function buildRepeaterPageViewHTML(TemplateInterface &$template, RepeaterPageView &$pageView, ExpandedValue &$expandedValue)
422
    {
423
        $defaultContext = [
424 3
            'this' => $pageView->createJail(),
425
        ];
426
427 3
        $pageView->evaluateFrontMatter([
428 3
            'permalink' => $expandedValue->getEvaluated(),
429 3
            'iterators' => $expandedValue->getIterators(),
430
        ]);
431
432 3
        $preEvent = new CompileProcessPreRenderPageView(BasePageView::REPEATER_TYPE);
433 3
        $this->eventDispatcher->dispatch(CompileProcessPreRenderPageView::NAME, $preEvent);
434
435 3
        $context = array_merge($preEvent->getCustomVariables(), $defaultContext);
436
        $output = $template
437 3
            ->render($context)
438
        ;
439
440 3
        $postEvent = new CompileProcessPostRenderPageView(BasePageView::REPEATER_TYPE, $output);
441 3
        $this->eventDispatcher->dispatch(CompileProcessPostRenderPageView::NAME, $postEvent);
442
443 3
        return $postEvent->getCompiledOutput();
444
    }
445
446
    /**
447
     * Get the compiled HTML for a specific ContentItem.
448
     *
449
     * @since  0.1.1
450
     *
451
     * @return string
452
     */
453 View Code Duplication
    private function buildDynamicPageViewHTML(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...
454
    {
455
        $defaultContext = [
456
            'this' => $twigItem->createJail(),
457
        ];
458
459
        $preEvent = new CompileProcessPreRenderPageView(BasePageView::DYNAMIC_TYPE);
460
        $this->eventDispatcher->dispatch(CompileProcessPreRenderPageView::NAME, $preEvent);
461
462
        $context = array_merge($preEvent->getCustomVariables(), $defaultContext);
463
        $output = $template
464
            ->render($context)
465
        ;
466
467
        $postEvent = new CompileProcessPostRenderPageView(BasePageView::DYNAMIC_TYPE, $output);
468
        $this->eventDispatcher->dispatch(CompileProcessPostRenderPageView::NAME, $postEvent);
469
470
        return $postEvent->getCompiledOutput();
471
    }
472
473
    /**
474
     * Get the compiled HTML for a static PageView.
475
     *
476
     * @since  0.1.1
477
     *
478
     * @throws TemplateErrorInterface
479
     *
480
     * @return string
481
     */
482 10 View Code Duplication
    private function buildStaticPageViewHTML(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...
483
    {
484
        $defaultContext = [
485 10
            'this' => $pageView->createJail(),
486
        ];
487
488 10
        $preEvent = new CompileProcessPreRenderPageView(BasePageView::STATIC_TYPE);
489 10
        $this->eventDispatcher->dispatch(CompileProcessPreRenderPageView::NAME, $preEvent);
490
491 10
        $context = array_merge($preEvent->getCustomVariables(), $defaultContext);
492
        $output = $this
493 10
            ->createTwigTemplate($pageView)
494 10
            ->render($context)
495
        ;
496
497 10
        $postEvent = new CompileProcessPostRenderPageView(BasePageView::STATIC_TYPE, $output);
498 10
        $this->eventDispatcher->dispatch(CompileProcessPostRenderPageView::NAME, $postEvent);
499
500 10
        return $postEvent->getCompiledOutput();
501
    }
502
503
    /**
504
     * Create a Twig template that just needs an array to render.
505
     *
506
     * @since  0.1.1
507
     *
508
     * @throws TemplateErrorInterface
509
     *
510
     * @return TemplateInterface
511
     */
512 12
    private function createTwigTemplate(BasePageView &$pageView)
513
    {
514
        try
515
        {
516 12
            $template = $this->templateBridge->createTemplate($pageView->getContent());
517
518 12
            $this->templateMapping[$template->getTemplateName()] = $pageView->getRelativeFilePath();
519
520 12
            $event = new CompileProcessTemplateCreation($pageView, $template, $this->theme);
521 12
            $this->eventDispatcher->dispatch(CompileProcessTemplateCreation::NAME, $event);
522
523 12
            return $template;
524
        }
525
        catch (TemplateErrorInterface $e)
526
        {
527
            $e
528
                ->setTemplateLine($e->getTemplateLine() + $pageView->getLineOffset())
529
                ->setContent($pageView->getContent())
530
                ->setName($pageView->getRelativeFilePath())
531
                ->setRelativeFilePath($pageView->getRelativeFilePath())
532
                ->buildException()
533
            ;
534
535
            throw $e;
536
        }
537
    }
538
}
539