Completed
Pull Request — master (#41)
by Vladimir
03:10
created

Website::build()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 87
Code Lines 52

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 52
nc 2
nop 1
dl 0
loc 87
rs 8.6296
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace allejo\stakx\Object;
4
5
use allejo\stakx\Compiler;
6
use allejo\stakx\Core\StakxLogger;
7
use allejo\stakx\Manager\AssetManager;
8
use allejo\stakx\Manager\MenuManager;
9
use allejo\stakx\Manager\PageManager;
10
use allejo\stakx\Manager\ThemeManager;
11
use allejo\stakx\Manager\TwigManager;
12
use allejo\stakx\System\FileExplorer;
13
use allejo\stakx\System\Filesystem;
14
use allejo\stakx\Manager\CollectionManager;
15
use allejo\stakx\Manager\DataManager;
16
use allejo\stakx\System\Folder;
17
use JasonLewis\ResourceWatcher\Event;
18
use JasonLewis\ResourceWatcher\Resource\FileResource;
19
use JasonLewis\ResourceWatcher\Tracker;
20
use JasonLewis\ResourceWatcher\Watcher;
21
use Symfony\Component\Console\Output\OutputInterface;
22
23
class Website
24
{
25
    /**
26
     * The location of where the compiled website will be written to
27
     *
28
     * @var Folder
29
     */
30
    private $outputDirectory;
31
32
    /**
33
     * The main configuration to be used to build the specified website
34
     *
35
     * @var Configuration
36
     */
37
    private $configuration;
38
39
    /**
40
     * When set to true, the Stakx website will be built without a configuration file
41
     *
42
     * @var bool
43
     */
44
    private $confLess;
45
46
    /**
47
     * When set to true, Twig templates will not have access to filters or functions which provide access to the
48
     * filesystem
49
     *
50
     * @var bool
51
     */
52
    private $safeMode;
53
54
    /**
55
     * When set to true, Stakx will not clean the _site folder after a rebuild
56
     *
57
     * @var bool
58
     */
59
    private $noClean;
60
61
    /**
62
     * @var StakxLogger
63
     */
64
    private $output;
65
66
    /**
67
     * @var AssetManager
68
     */
69
    private $am;
70
71
    /**
72
     * @var CollectionManager
73
     */
74
    private $cm;
75
76
    /**
77
     * @var DataManager
78
     */
79
    private $dm;
80
81
    /**
82
     * @var Filesystem
83
     */
84
    private $fs;
85
86
    /** @var MenuManager */
87
    private $mm;
88
89
    /**
90
     * @var PageManager
91
     */
92
    private $pm;
93
94
    /**
95
     * @var ThemeManager
96
     */
97
    private $tm;
98
99
    /** @var Compiler */
100
    private $compiler;
101
102
    /**
103
     * Website constructor.
104
     *
105
     * @param OutputInterface $output
106
     */
107
    public function __construct (OutputInterface $output)
108
    {
109
        $this->output = new StakxLogger($output);
110
        $this->cm = new CollectionManager();
111
        $this->dm = new DataManager();
112
        $this->mm = new MenuManager();
113
        $this->pm = new PageManager();
114
        $this->fs = new Filesystem();
115
    }
116
117
    /**
118
     * Compile the website.
119
     *
120
     * @param bool $tracking Whether or not to keep track of files as they're compiled to save time in 'watch'
121
     */
122
    public function build ($tracking = false)
123
    {
124
        // Configure the environment
125
        $this->createFolderStructure(!$this->noClean);
126
127
        // Our output directory
128
        $this->outputDirectory = new Folder($this->getConfiguration()->getTargetFolder());
129
        $this->outputDirectory->setTargetDirectory($this->getConfiguration()->getBaseUrl());
130
131
        // Parse DataItems
132
        $this->dm->setLogger($this->output);
133
        $this->dm->enableTracking($tracking);
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->enableTracking($tracking);
140
        $this->cm->parseCollections($this->getConfiguration()->getCollectionsFolders());
141
142
        // Handle PageViews
143
        $this->pm->setLogger($this->output);
144
        $this->pm->enableTracking($tracking);
145
        $this->pm->setTargetFolder($this->outputDirectory);
0 ignored issues
show
Bug introduced by
The method setTargetFolder() does not seem to exist on object<allejo\stakx\Manager\PageManager>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
146
        $this->pm->setCollections($this->cm->getCollections());
147
        $this->pm->setRedirectTemplate($this->getConfiguration()->getRedirectTemplate());
0 ignored issues
show
Bug introduced by
The method setRedirectTemplate() does not seem to exist on object<allejo\stakx\Manager\PageManager>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
148
        $this->pm->parsePageViews($this->getConfiguration()->getPageViewFolders());
149
150
        // Handle the site's menu
151
        $this->mm->setLogger($this->output);
152
        $this->mm->buildFromPageViews($this->pm->getStaticPages());
153
154
        // Configure our Twig environment
155
        $twigEnv = new TwigManager();
156
        $twigEnv->configureTwig($this->getConfiguration(), array(
157
            'safe'    => $this->safeMode,
158
            'globals' => array(
159
                array('name' => 'site',        'value' => $this->getConfiguration()->getConfiguration()),
160
                array('name' => 'collections', 'value' => $this->cm->getJailedCollections()),
161
                array('name' => 'menu',        'value' => $this->mm->getSiteMenu()),
162
                array('name' => 'pages',       'value' => $this->pm->getJailedStaticPages()),
163
                array('name' => 'data',        'value' => $this->dm->getDataItems())
164
            )
165
        ));
166
167
        // Compile everything
168
        $this->compiler = new Compiler();
169
        $this->compiler->setLogger($this->output);
170
        $this->compiler->setRedirectTemplate($this->getConfiguration()->getRedirectTemplate());
171
        $this->compiler->setPageViews($this->pm->getPageViews());
172
        $this->compiler->setTargetFolder($this->outputDirectory);
173
        $this->compiler->compileAll();
174
175
        // At this point, we are looking at static files to copy over meaning we need to ignore all of the files that
176
        // make up the source of a stakx website
177
        $assetsToIgnore = array_merge(
178
            Configuration::$stakxSourceFiles,
179
            $this->getConfiguration()->getExcludes()
180
        );
181
182
        //
183
        // Theme Management
184
        //
185
        $theme = $this->configuration->getTheme();
186
187
        if (!is_null($theme))
188
        {
189
            $this->output->notice("Looking for '${theme}' theme...");
190
191
            $this->tm = new ThemeManager($theme);
192
            $this->tm->configureFinder($this->getConfiguration()->getIncludes(), $assetsToIgnore);
193
            $this->tm->setLogger($this->output);
194
            $this->tm->enableTracking($tracking);
195
            $this->tm->setFolder($this->outputDirectory);
196
            $this->tm->copyFiles();
197
        }
198
199
        //
200
        // Static file management
201
        //
202
        $this->am = new AssetManager();
203
        $this->am->configureFinder($this->getConfiguration()->getIncludes(), $assetsToIgnore);
204
        $this->am->setLogger($this->output);
205
        $this->am->setFolder($this->outputDirectory);
206
        $this->am->enableTracking($tracking);
207
        $this->am->copyFiles();
208
    }
209
210
    public function watch ()
211
    {
212
        $this->output->writeln('Building website...');
213
        $this->build(true);
214
        $this->output->writeln(sprintf('Watching %s', getcwd()));
215
216
        $fileExplorer = FileExplorer::create(
217
            getcwd(),
218
            array_merge($this->getConfiguration()->getExcludes(), array(
219
                $this->getConfiguration()->getTargetFolder()
220
            )),
221
            $this->getConfiguration()->getIncludes()
222
        );
223
        $tracker    = new Tracker();
224
        $watcher    = new Watcher($tracker, $this->fs);
225
        $listener   = $watcher->watch(getcwd(), $fileExplorer->getExplorer());
226
        $targetPath = $this->getConfiguration()->getTargetFolder();
227
228
        $this->output->writeln('Watch started successfully');
229
230
        $listener->onAnything(function (Event $event, FileResource $resouce, $path) use ($targetPath)
231
        {
232
            $filePath = $this->fs->getRelativePath($path);
233
234
            try
235
            {
236
                switch ($event->getCode())
237
                {
238
                    case Event::RESOURCE_CREATED:
239
                        $this->creationWatcher($filePath);
240
                        break;
241
242
                    case Event::RESOURCE_MODIFIED:
243
                        $this->modificationWatcher($filePath);
244
                        break;
245
                }
246
            }
247
            catch (\Exception $e)
248
            {
249
                $this->output->error(sprintf("Your website failed to build with the following error: %s",
250
                    $e->getMessage()
251
                ));
252
            }
253
        });
254
255
        $watcher->start();
256
    }
257
258
    /**
259
     * @return Configuration
260
     */
261
    public function getConfiguration ()
262
    {
263
        return $this->configuration;
264
    }
265
266
    /**
267
     * @param string $configFile
268
     *
269
     * @throws \LogicException
270
     */
271
    public function setConfiguration ($configFile)
272
    {
273
        if (!$this->fs->exists($configFile) && !$this->isConfLess())
274
        {
275
            $this->output->error("You are trying to build a website in a directory without a configuration file. Is this what you meant to do?");
276
            $this->output->error("To build a website without a configuration, use the '--no-conf' option");
277
278
            throw new \LogicException("Cannot build a website without a configuration when not in Configuration-less mode");
279
        }
280
281
        if ($this->isConfLess())
282
        {
283
            $configFile = "";
284
        }
285
286
        $this->configuration = new Configuration();
287
        $this->configuration->setLogger($this->output);
288
        $this->configuration->parseConfiguration($configFile);
289
    }
290
291
    /**
292
     * Get whether or not the website is being built in Configuration-less mode
293
     *
294
     * @return bool True when being built with no configuration file
295
     */
296
    public function isConfLess ()
297
    {
298
        return $this->confLess;
299
    }
300
301
    /**
302
     * Set whether or not the website should be built with a configuration
303
     *
304
     * @param bool $status True when a website should be built without a configuration
305
     */
306
    public function setConfLess ($status)
307
    {
308
        $this->confLess = $status;
309
    }
310
311
    /**
312
     * Get whether or not the website is being built in safe mode.
313
     *
314
     * Safe mode is defined as disabling file system access from Twig and disabling user Twig extensions
315
     *
316
     * @return bool True when the website is being built in safe mode
317
     */
318
    public function isSafeMode ()
319
    {
320
        return $this->safeMode;
321
    }
322
323
    /**
324
     * Set whether a website should be built in safe mode
325
     *
326
     * @param bool $bool True if a website should be built in safe mode
327
     */
328
    public function setSafeMode ($bool)
329
    {
330
        $this->safeMode = $bool;
331
    }
332
333
    /**
334
     * @return boolean
335
     */
336
    public function isNoClean()
337
    {
338
        return $this->noClean;
339
    }
340
341
    /**
342
     * @param boolean $noClean
343
     */
344
    public function setNoClean($noClean)
345
    {
346
        $this->noClean = $noClean;
347
    }
348
349
    private function creationWatcher ($filePath)
350
    {
351
        $this->output->writeln(sprintf("File creation detected: %s", $filePath));
352
353
        if ($this->pm->isHandled($filePath))
354
        {
355
            $this->pm->createNewItem($filePath);
356
            $this->pm->refreshItem($filePath);
357
        }
358
        else if ($this->cm->isHandled($filePath))
359
        {
360
            $contentItem = $this->cm->createNewItem($filePath);
361
362
            $this->pm->updateTwigVariable('collections', $this->cm->getCollections());
0 ignored issues
show
Bug introduced by
The method updateTwigVariable() does not seem to exist on object<allejo\stakx\Manager\PageManager>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
363
            $this->pm->updatePageView($contentItem);
364
//            $this->pm->compileContentItem($contentItem);
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
365
//            $this->pm->compileSome(array(
366
//                'namespace' => 'collections',
367
//                'dependency' => $contentItem->getCollection()
368
//            ));
369
        }
370
        else if ($this->dm->isHandled($filePath))
371
        {
372
            $change = $this->dm->createNewItem($filePath);
0 ignored issues
show
Unused Code introduced by
$change is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
373
374
            $this->pm->updateTwigVariable('data', $this->dm->getDataItems());
0 ignored issues
show
Bug introduced by
The method updateTwigVariable() does not seem to exist on object<allejo\stakx\Manager\PageManager>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
375
//            $this->pm->compileSome(array(
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
376
//                'namespace' => 'data',
377
//                'dependency' => $change
378
//            ));
379
        }
380
        else if (!is_null($this->tm) && $this->tm->isHandled($filePath))
381
        {
382
            $this->tm->createNewItem($filePath);
383
        }
384
        else if ($this->am->isHandled($filePath))
385
        {
386
            $this->am->createNewItem($filePath);
387
        }
388
    }
389
390
    private function modificationWatcher ($filePath)
391
    {
392
        $this->output->writeln(sprintf("File change detected: %s", $filePath));
393
394
        if ($this->pm->isTracked($filePath))
395
        {
396
            $this->pm->refreshItem($filePath);
397
        }
398
        else if ($this->cm->isTracked($filePath))
399
        {
400
            $contentItem = &$this->cm->getContentItem($filePath);
401
            $contentItem->refreshFileContent();
402
403
//            $this->pm->compileContentItem($contentItem);
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
404
//            $this->pm->compileSome(array(
405
//                'namespace' => 'collections',
406
//                'dependency' => $contentItem->getCollection()
407
//            ));
408
        }
409
        else if ($this->dm->isTracked($filePath))
410
        {
411
            $change = $this->dm->refreshItem($filePath);
0 ignored issues
show
Unused Code introduced by
$change is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
412
413
//            $this->pm->updateTwigVariable('data', $this->dm->getDataItems());
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
414
//            $this->pm->compileSome(array(
415
//                'namespace' => 'data',
416
//                'dependency' => $change
417
//            ));
418
        }
419
        else if (!is_null($this->tm) && $this->tm->isTracked($filePath))
420
        {
421
            $this->tm->refreshItem($filePath);
422
        }
423
        else if ($this->am->isTracked($filePath))
424
        {
425
            $this->am->refreshItem($filePath);
426
        }
427
    }
428
429
    /**
430
     * Prepare the Stakx environment by creating necessary cache folders
431
     *
432
     * @param bool $cleanDirectory Clean the target directory
433
     */
434
    private function createFolderStructure ($cleanDirectory)
435
    {
436
        $tarDir = $this->fs->absolutePath($this->configuration->getTargetFolder());
437
438
        if ($cleanDirectory)
439
        {
440
            $this->fs->remove($tarDir);
441
        }
442
443
        $this->fs->remove($this->fs->absolutePath('.stakx-cache'));
444
        $this->fs->mkdir($this->fs->absolutePath('.stakx-cache/twig'));
445
        $this->fs->mkdir($tarDir);
446
    }
447
}