Completed
Push — master ( 89bfcf...4ab803 )
by Vladimir
02:41
created

Website::deletionWatcher()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 1
1
<?php
2
3
/**
4
 * @copyright 2017 Vladimir Jimenez
5
 * @license   https://github.com/allejo/stakx/blob/master/LICENSE.md MIT
6
 */
7
8
namespace allejo\stakx;
9
10
use allejo\stakx\Command\BuildableCommand;
11
use allejo\stakx\Core\StakxLogger;
12
use allejo\stakx\Exception\FileAwareException;
13
use allejo\stakx\Manager\AssetManager;
14
use allejo\stakx\Manager\CollectionManager;
15
use allejo\stakx\Manager\DataManager;
16
use allejo\stakx\Manager\MenuManager;
17
use allejo\stakx\Manager\PageManager;
18
use allejo\stakx\Manager\ThemeManager;
19
use allejo\stakx\Manager\TwigManager;
20
use allejo\stakx\System\FileExplorer;
21
use allejo\stakx\System\Filesystem;
22
use allejo\stakx\System\Folder;
23
use allejo\stakx\Twig\StakxTwigTextProfiler;
24
use Highlight\Highlighter;
25
use Kwf\FileWatcher\Event\AbstractEvent;
26
use Kwf\FileWatcher\Event\Create;
27
use Kwf\FileWatcher\Event\Modify;
28
use Kwf\FileWatcher\Event\Move;
29
use Kwf\FileWatcher\Watcher;
30
use Symfony\Component\Console\Output\OutputInterface;
31
32
class Website
33
{
34
    /**
35
     * The location of where the compiled website will be written to.
36
     *
37
     * @var Folder
38
     */
39
    private $outputDirectory;
40
41
    /**
42
     * The main configuration to be used to build the specified website.
43
     *
44
     * @var Configuration
45
     */
46
    private $configuration;
47
48
    /**
49
     * When set to true, the Stakx website will be built without a configuration file.
50
     *
51
     * @var bool
52
     */
53
    private $confLess;
54
55
    /**
56
     * @var StakxLogger
57
     */
58
    private $output;
59
60
    /**
61
     * @var AssetManager
62
     */
63
    private $am;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $am. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
64
65
    /**
66
     * @var CollectionManager
67
     */
68
    private $cm;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $cm. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
69
70
    /**
71
     * @var DataManager
72
     */
73
    private $dm;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $dm. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
74
75
    /**
76
     * @var Filesystem
77
     */
78
    private $fs;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $fs. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
79
80
    /** @var MenuManager */
81
    private $mm;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $mm. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
82
83
    /**
84
     * @var PageManager
85
     */
86
    private $pm;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $pm. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
87
88
    /**
89
     * @var ThemeManager
90
     */
91
    private $tm;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $tm. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
92
93
    /** @var Compiler */
94
    private $compiler;
95
96
    /** @var array */
97
    private $creationQueue;
98
99
    /**
100
     * Website constructor.
101
     *
102
     * @param OutputInterface $output
103
     */
104
    public function __construct(OutputInterface $output)
105
    {
106
        $this->creationQueue = array();
107
        $this->output = new StakxLogger($output);
108
        $this->cm = new CollectionManager();
109
        $this->dm = new DataManager();
110
        $this->mm = new MenuManager();
111
        $this->pm = new PageManager();
112
        $this->fs = new Filesystem();
113
    }
114
115
    /**
116
     * Compile the website.
117
     *
118
     * @param bool $tracking Whether or not to keep track of files as they're compiled to save time in 'watch'
119
     */
120
    public function build($tracking = false)
121
    {
122
        Service::setParameter(BuildableCommand::WATCHING, $tracking);
123
124
        // Configure the environment
125
        $this->createFolderStructure();
126
        $this->configureHighlighter();
127
128
        // Our output directory
129
        $this->outputDirectory = new Folder($this->getConfiguration()->getTargetFolder());
130
        $this->outputDirectory->setTargetDirectory($this->getConfiguration()->getBaseUrl());
131
132
        // Parse DataItems
133
        $this->dm->setLogger($this->output);
134
        $this->dm->parseDataItems($this->getConfiguration()->getDataFolders());
135
        $this->dm->parseDataSets($this->getConfiguration()->getDataSets());
136
137
        // Prepare Collections
138
        $this->cm->setLogger($this->output);
139
        $this->cm->parseCollections($this->getConfiguration()->getCollectionsFolders());
140
141
        // Handle PageViews
142
        $this->pm->setLogger($this->output);
143
        $this->pm->setCollections($this->cm->getCollections());
0 ignored issues
show
Documentation introduced by
$this->cm->getCollections() is of type array<integer,object<all...ent\TrackableDocument>>, but the function expects a array<integer,array<inte...Document\ContentItem>>>.

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...
144
        $this->pm->setDatasets($this->dm->getDataItems());
145
        $this->pm->parsePageViews($this->getConfiguration()->getPageViewFolders());
146
147
        // Handle the site's menu
148
        $this->mm->setLogger($this->output);
149
        $this->mm->buildFromPageViews($this->pm->getStaticPageViews());
150
151
        // Configure our Twig environment
152
        $theme = $this->configuration->getTheme();
153
        $twigEnv = new TwigManager();
154
        $twigEnv->configureTwig($this->getConfiguration(), array(
155
            'safe'    => Service::getParameter(BuildableCommand::SAFE_MODE),
156
            'globals' => array(
157
                array('name' => 'site', 'value' => $this->getConfiguration()->getConfiguration()),
158
                array('name' => 'collections', 'value' => $this->cm->getJailedCollections()),
159
                array('name' => 'menu', 'value' => $this->mm->getSiteMenu()),
160
                array('name' => 'pages', 'value' => $this->pm->getJailedStaticPageViews()),
161
                array('name' => 'data', 'value' => $this->dm->getJailedDataItems()),
162
            ),
163
        ));
164
165
        $profiler = null;
166
167
        if (Service::getParameter(BuildableCommand::BUILD_PROFILE))
168
        {
169
            $profiler = new \Twig_Profiler_Profile();
170
            TwigManager::getInstance()->addExtension(new \Twig_Extension_Profiler($profiler));
171
        }
172
173
        // Compile everything
174
        $this->compiler = new Compiler();
175
        $this->compiler->setLogger($this->output);
176
        $this->compiler->setRedirectTemplate($this->getConfiguration()->getRedirectTemplate());
177
        $this->compiler->setPageViews($this->pm->getPageViews(), $this->pm->getPageViewsFlattened());
0 ignored issues
show
Documentation introduced by
$this->pm->getPageViews() is of type array<integer,object<all...ent\TrackableDocument>>, but the function expects a array<integer,array<inte...kx\Document\PageView>>>.

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...
Documentation introduced by
$this->pm->getPageViewsFlattened() is of type array<integer,object<all...ent\TrackableDocument>>, but the function expects a array<integer,object<all...akx\Document\PageView>>.

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...
178
        $this->compiler->setTargetFolder($this->outputDirectory);
179
        $this->compiler->setThemeName($theme);
180
        $this->compiler->compileAll();
181
182
        if (Service::getParameter(BuildableCommand::BUILD_PROFILE))
183
        {
184
            $dumper = new StakxTwigTextProfiler();
185
            $dumper->setTemplateMappings($this->compiler->getTemplateMappings());
186
            $text = $dumper->dump($profiler);
0 ignored issues
show
Bug introduced by
It seems like $profiler defined by null on line 165 can be null; however, Twig_Profiler_Dumper_Text::dump() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
187
            $this->output->writeln($text);
188
        }
189
190
        // At this point, we are looking at static files to copy over meaning we need to ignore all of the files that
191
        // make up the source of a stakx website
192
        $assetsToIgnore = array_merge(
193
            Configuration::$stakxSourceFiles,
194
            $this->getConfiguration()->getExcludes()
195
        );
196
197
        //
198
        // Theme Management
199
        //
200
        if (!is_null($theme))
201
        {
202
            $this->output->notice("Looking for '${theme}' theme...");
203
204
            $this->tm = new ThemeManager($theme);
205
            $this->tm->configureFinder($this->getConfiguration()->getIncludes(), $assetsToIgnore);
206
            $this->tm->setLogger($this->output);
207
            $this->tm->setFolder($this->outputDirectory);
208
            $this->tm->copyFiles();
209
        }
210
211
        //
212
        // Static file management
213
        //
214
        $this->am = new AssetManager();
215
        $this->am->configureFinder($this->getConfiguration()->getIncludes(), $assetsToIgnore);
216
        $this->am->setLogger($this->output);
217
        $this->am->setFolder($this->outputDirectory);
218
        $this->am->copyFiles();
219
    }
220
221
    public function watch()
222
    {
223
        $this->output->writeln('Building website...');
224
        $this->build(true);
225
        $this->output->writeln(sprintf('Watching %s', getcwd()));
226
227
        $exclusions = array_merge($this->getConfiguration()->getExcludes(), array(
228
            $this->getConfiguration()->getTargetFolder()
229
        ));
230
        $fileExplorer = FileExplorer::create(
231
            getcwd(), $exclusions, $this->getConfiguration()->getIncludes()
232
        );
233
234
        $newWatcher = Watcher::create(getcwd());
235
        $newWatcher
236
            ->setLogger($this->output)
237
            ->setExcludePatterns(array_merge(
238
                $exclusions, FileExplorer::$vcsPatterns, array(Configuration::CACHE_FOLDER)
239
            ))
240
            ->setIterator($fileExplorer->getExplorer())
241
            ->addListener(Create::NAME, function ($e) { $this->watchListenerFunction($e); })
242
            ->addListener(Modify::NAME, function ($e) { $this->watchListenerFunction($e); })
243
            ->addListener(Move::NAME,   function ($e) { $this->watchListenerFunction($e); })
244
        ;
245
246
        $this->output->writeln('Watch started successfully');
247
248
        $newWatcher->start();
249
    }
250
251
    private function watchListenerFunction(AbstractEvent $event)
252
    {
253
        $filePath = $this->fs->getRelativePath($event->filename);
254
255
        try
256
        {
257
            switch ($event::getEventName())
258
            {
259
                case Create::NAME:
260
                    $this->creationWatcher($filePath);
261
                    break;
262
263
                case Modify::NAME:
264
                    $this->modificationWatcher($filePath);
265
                    break;
266
267
                case Move::NAME:
268
                    $newFile = $this->fs->getRelativePath($event->destFilename);
0 ignored issues
show
Bug introduced by
The property destFilename does not seem to exist. Did you mean filename?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
269
270
                    $this->deletionWatcher($filePath);
0 ignored issues
show
Unused Code introduced by
The call to the method allejo\stakx\Website::deletionWatcher() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
271
                    $this->creationWatcher($newFile);
272
                    break;
273
            }
274
        }
275
        catch (FileAwareException $e)
276
        {
277
            $this->output->writeln(sprintf("Your website failed to build with the following error in file '%s': %s",
278
                $e->getPath(),
279
                $e->getMessage()
280
            ));
281
        }
282
        catch (\Exception $e)
283
        {
284
            $this->output->writeln(sprintf('Your website failed to build with the following error: %s',
285
                $e->getMessage()
286
            ));
287
        }
288
    }
289
290
    /**
291
     * @return Configuration
292
     */
293
    public function getConfiguration()
294
    {
295
        return $this->configuration;
296
    }
297
298
    /**
299
     * @param string $configFile
300
     *
301
     * @throws \LogicException
302
     */
303
    public function setConfiguration($configFile)
304
    {
305
        if (!$this->fs->exists($configFile) && !$this->isConfLess())
306
        {
307
            $this->output->error('You are trying to build a website in a directory without a configuration file. Is this what you meant to do?');
308
            $this->output->error("To build a website without a configuration, use the '--no-conf' option");
309
310
            throw new \LogicException('Cannot build a website without a configuration when not in Configuration-less mode');
311
        }
312
313
        if ($this->isConfLess())
314
        {
315
            $configFile = '';
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $configFile. This often makes code more readable.
Loading history...
316
        }
317
318
        $this->configuration = new Configuration();
319
        $this->configuration->setLogger($this->output);
320
        $this->configuration->parse($configFile);
321
322
        Service::setParameter('build.preserveCase', $this->configuration->getConfiguration()['build']['preserveCase']);
323
    }
324
325
    /**
326
     * Get whether or not the website is being built in Configuration-less mode.
327
     *
328
     * @return bool True when being built with no configuration file
329
     */
330
    public function isConfLess()
331
    {
332
        return $this->confLess;
333
    }
334
335
    /**
336
     * Set whether or not the website should be built with a configuration.
337
     *
338
     * @param bool $status True when a website should be built without a configuration
339
     */
340
    public function setConfLess($status)
341
    {
342
        $this->confLess = $status;
343
    }
344
345
    /**
346
     * @param string $filePath
347
     */
348
    private function creationWatcher($filePath, $newlyCreate = true)
349
    {
350
        if ($newlyCreate)
351
        {
352
            $this->output->writeln(sprintf('File creation detected: %s', $filePath));
353
        }
354
355
        if ($this->pm->shouldBeTracked($filePath))
356
        {
357
            try
358
            {
359
                $this->pm->createNewItem($filePath);
360
                $pageView = $this->pm->refreshItem($filePath);
361
362
                $this->compiler->compilePageView($pageView);
363
364
                unset($this->creationQueue[$filePath]);
365
            }
366
            catch (\Exception $e)
367
            {
368
                $this->creationQueue[$filePath] = true;
369
            }
370
        }
371
        elseif ($this->cm->shouldBeTracked($filePath))
372
        {
373
            try
374
            {
375
                $contentItem = $this->cm->createNewItem($filePath);
376
                TwigManager::getInstance()->addGlobal('collections', $this->cm->getCollections());
377
378
                $this->pm->trackNewContentItem($contentItem);
0 ignored issues
show
Compatibility introduced by
$contentItem of type object<allejo\stakx\Document\TrackableDocument> is not a sub-type of object<allejo\stakx\Document\ContentItem>. It seems like you assume a concrete implementation of the interface allejo\stakx\Document\TrackableDocument 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...
379
                $this->compiler->compileContentItem($contentItem);
0 ignored issues
show
Deprecated Code introduced by
The method allejo\stakx\Compiler::compileContentItem() has been deprecated.

This method has been deprecated.

Loading history...
380
                $this->compiler->compileSome(array(
381
                    'namespace'  => 'collections',
382
                    'dependency' => $contentItem->getNamespace(),
383
                ));
384
385
                unset($this->creationQueue[$filePath]);
386
            }
387
            catch (\Exception $e)
388
            {
389
                $this->creationQueue[$filePath] = true;
390
            }
391
        }
392 View Code Duplication
        elseif ($this->dm->shouldBeTracked($filePath))
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
            $change = $this->dm->createNewItem($filePath);
395
            TwigManager::getInstance()->addGlobal('data', $this->dm->getDataItems());
396
397
            $this->compiler->compileSome(array(
398
                'namespace'  => 'data',
399
                'dependency' => $change,
400
            ));
401
        }
402
        elseif (!is_null($this->tm) && $this->tm->shouldBeTracked($filePath))
403
        {
404
            $this->tm->createNewItem($filePath);
405
        }
406
        elseif ($this->am->shouldBeTracked($filePath))
407
        {
408
            $this->am->createNewItem($filePath);
409
        }
410
    }
411
412
    /**
413
     * @param string $filePath
414
     */
415
    private function modificationWatcher($filePath)
416
    {
417
        $this->output->writeln(sprintf('File change detected: %s', $filePath));
418
419
        if (isset($this->creationQueue[$filePath]))
420
        {
421
            $this->creationWatcher($filePath, false);
422
        }
423
        elseif ($this->compiler->isParentTemplate($filePath))
424
        {
425
            TwigManager::getInstance()->clearTemplateCache();
0 ignored issues
show
Deprecated Code introduced by
The method Twig_Environment::clearTemplateCache() has been deprecated with message: since 1.18.3 (to be removed in 2.0)

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
426
            $this->compiler->refreshParent($filePath);
427
        }
428
        elseif ($this->compiler->isImportDependency($filePath))
429
        {
430
            TwigManager::getInstance()->clearTemplateCache();
0 ignored issues
show
Deprecated Code introduced by
The method Twig_Environment::clearTemplateCache() has been deprecated with message: since 1.18.3 (to be removed in 2.0)

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
431
            $this->compiler->compileImportDependencies($filePath);
432
        }
433
        elseif ($this->pm->isTracked($filePath))
434
        {
435
            $change = $this->pm->refreshItem($filePath);
436
437
            TwigManager::getInstance()->clearTemplateCache();
0 ignored issues
show
Deprecated Code introduced by
The method Twig_Environment::clearTemplateCache() has been deprecated with message: since 1.18.3 (to be removed in 2.0)

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
438
            $this->compiler->compilePageView($change);
439
        }
440
        elseif ($this->cm->isTracked($filePath))
441
        {
442
            $contentItem = &$this->cm->getContentItem($filePath);
443
            $contentItem->refreshFileContent();
444
445
            $this->compiler->compileContentItem($contentItem);
0 ignored issues
show
Deprecated Code introduced by
The method allejo\stakx\Compiler::compileContentItem() has been deprecated.

This method has been deprecated.

Loading history...
446
            $this->compiler->compileSome(array(
447
                'namespace'  => 'collections',
448
                'dependency' => $contentItem->getNamespace(),
449
            ));
450
        }
451 View Code Duplication
        elseif ($this->dm->isTracked($filePath))
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...
452
        {
453
            $change = $this->dm->refreshItem($filePath);
454
            TwigManager::getInstance()->addGlobal('data', $this->dm->getDataItems());
455
456
            $this->compiler->compileSome(array(
457
                'namespace'  => 'data',
458
                'dependency' => $change,
459
            ));
460
        }
461
        elseif (!is_null($this->tm) && $this->tm->isTracked($filePath))
462
        {
463
            $this->tm->refreshItem($filePath);
464
        }
465
        elseif ($this->am->isTracked($filePath))
466
        {
467
            $this->am->refreshItem($filePath);
468
        }
469
    }
470
471
    /**
472
     * @param string $filePath
473
     */
474
    private function deletionWatcher($filePath)
0 ignored issues
show
Unused Code introduced by
The parameter $filePath is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
475
    {
476
    }
477
478
    /**
479
     * Prepare the Stakx environment by creating necessary cache folders.
480
     */
481
    private function createFolderStructure()
482
    {
483
        $targetDir = $this->fs->absolutePath($this->configuration->getTargetFolder());
484
485
        if (!Service::getParameter(BuildableCommand::NO_CLEAN))
486
        {
487
            $this->fs->remove($targetDir);
488
        }
489
490
        if (!Service::getParameter(BuildableCommand::USE_CACHE))
491
        {
492
            $this->fs->remove($this->fs->absolutePath(Configuration::CACHE_FOLDER));
493
            $this->fs->mkdir($this->fs->absolutePath($this->fs->appendPath(Configuration::CACHE_FOLDER, 'twig')));
494
        }
495
496
        $this->fs->mkdir($targetDir);
497
    }
498
499
    private function configureHighlighter()
500
    {
501
        // Configure our highlighter
502
        Service::setParameter(Configuration::HIGHLIGHTER_ENABLED, $this->getConfiguration()->isHighlighterEnabled());
503
504
        if (Service::getParameter(Configuration::HIGHLIGHTER_ENABLED))
505
        {
506
            foreach ($this->getConfiguration()->getHighlighterCustomLanguages() as $lang => $path)
507
            {
508
                $fullPath = $this->fs->absolutePath($path);
509
510
                if (!$this->fs->exists($fullPath))
511
                {
512
                    $this->output->warning('The following language definition could not be found: {lang}', array(
513
                        'lang' => $path
514
                    ));
515
                    continue;
516
                }
517
518
                Highlighter::registerLanguage($lang, $fullPath);
519
                $this->output->debug('Loading custom language {lang} from {path}...', array(
520
                    'lang' => $lang,
521
                    'path' => $path
522
                ));
523
            }
524
        }
525
    }
526
}
527