Completed
Push — master ( 7e0874...14a89c )
by Vladimir
04:01 queued 01:49
created

Compiler::buildDynamicPageViewHTML()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19

Duplication

Lines 19
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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