Completed
Pull Request — master (#75)
by Vladimir
02:24
created

Compiler::buildRepeaterPageViewHTML()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 1

Importance

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