Completed
Pull Request — master (#41)
by Vladimir
02:38
created

Website::build()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 85
Code Lines 50

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 50
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 85
rs 8.6875

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->setCollections($this->cm->getCollections());
146
        $this->pm->parsePageViews($this->getConfiguration()->getPageViewFolders());
147
148
        // Handle the site's menu
149
        $this->mm->setLogger($this->output);
150
        $this->mm->buildFromPageViews($this->pm->getStaticPageViews());
151
152
        // Configure our Twig environment
153
        $twigEnv = new TwigManager();
154
        $twigEnv->configureTwig($this->getConfiguration(), array(
155
            'safe'    => $this->safeMode,
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->getDataItems())
162
            )
163
        ));
164
165
        // Compile everything
166
        $this->compiler = new Compiler();
167
        $this->compiler->setLogger($this->output);
168
        $this->compiler->setRedirectTemplate($this->getConfiguration()->getRedirectTemplate());
169
        $this->compiler->setPageViews($this->pm->getAllPageViews());
0 ignored issues
show
Documentation introduced by
$this->pm->getAllPageViews() is of type array<integer,array<inte...takx\Object\PageView>>>, but the function expects a array<integer,object<all...stakx\Object\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...
170
        $this->compiler->setTargetFolder($this->outputDirectory);
171
        $this->compiler->compileAll();
172
173
        // At this point, we are looking at static files to copy over meaning we need to ignore all of the files that
174
        // make up the source of a stakx website
175
        $assetsToIgnore = array_merge(
176
            Configuration::$stakxSourceFiles,
177
            $this->getConfiguration()->getExcludes()
178
        );
179
180
        //
181
        // Theme Management
182
        //
183
        $theme = $this->configuration->getTheme();
184
185
        if (!is_null($theme))
186
        {
187
            $this->output->notice("Looking for '${theme}' theme...");
188
189
            $this->tm = new ThemeManager($theme);
190
            $this->tm->configureFinder($this->getConfiguration()->getIncludes(), $assetsToIgnore);
191
            $this->tm->setLogger($this->output);
192
            $this->tm->enableTracking($tracking);
193
            $this->tm->setFolder($this->outputDirectory);
194
            $this->tm->copyFiles();
195
        }
196
197
        //
198
        // Static file management
199
        //
200
        $this->am = new AssetManager();
201
        $this->am->configureFinder($this->getConfiguration()->getIncludes(), $assetsToIgnore);
202
        $this->am->setLogger($this->output);
203
        $this->am->setFolder($this->outputDirectory);
204
        $this->am->enableTracking($tracking);
205
        $this->am->copyFiles();
206
    }
207
208
    public function watch ()
209
    {
210
        $this->output->writeln('Building website...');
211
        $this->build(true);
212
        $this->output->writeln(sprintf('Watching %s', getcwd()));
213
214
        $fileExplorer = FileExplorer::create(
215
            getcwd(),
216
            array_merge($this->getConfiguration()->getExcludes(), array(
217
                $this->getConfiguration()->getTargetFolder()
218
            )),
219
            $this->getConfiguration()->getIncludes()
220
        );
221
        $tracker    = new Tracker();
222
        $watcher    = new Watcher($tracker, $this->fs);
223
        $listener   = $watcher->watch(getcwd(), $fileExplorer->getExplorer());
224
        $targetPath = $this->getConfiguration()->getTargetFolder();
225
226
        $this->output->writeln('Watch started successfully');
227
228
        $listener->onAnything(function (Event $event, FileResource $resouce, $path) use ($targetPath)
229
        {
230
            $filePath = $this->fs->getRelativePath($path);
231
232
            try
233
            {
234
                switch ($event->getCode())
235
                {
236
                    case Event::RESOURCE_CREATED:
237
                        $this->creationWatcher($filePath);
238
                        break;
239
240
                    case Event::RESOURCE_MODIFIED:
241
                        $this->modificationWatcher($filePath);
242
                        break;
243
                }
244
            }
245
            catch (\Exception $e)
246
            {
247
                $this->output->error(sprintf("Your website failed to build with the following error: %s",
248
                    $e->getMessage()
249
                ));
250
            }
251
        });
252
253
        $watcher->start();
254
    }
255
256
    /**
257
     * @return Configuration
258
     */
259
    public function getConfiguration ()
260
    {
261
        return $this->configuration;
262
    }
263
264
    /**
265
     * @param string $configFile
266
     *
267
     * @throws \LogicException
268
     */
269
    public function setConfiguration ($configFile)
270
    {
271
        if (!$this->fs->exists($configFile) && !$this->isConfLess())
272
        {
273
            $this->output->error("You are trying to build a website in a directory without a configuration file. Is this what you meant to do?");
274
            $this->output->error("To build a website without a configuration, use the '--no-conf' option");
275
276
            throw new \LogicException("Cannot build a website without a configuration when not in Configuration-less mode");
277
        }
278
279
        if ($this->isConfLess())
280
        {
281
            $configFile = "";
282
        }
283
284
        $this->configuration = new Configuration();
285
        $this->configuration->setLogger($this->output);
286
        $this->configuration->parseConfiguration($configFile);
287
    }
288
289
    /**
290
     * Get whether or not the website is being built in Configuration-less mode
291
     *
292
     * @return bool True when being built with no configuration file
293
     */
294
    public function isConfLess ()
295
    {
296
        return $this->confLess;
297
    }
298
299
    /**
300
     * Set whether or not the website should be built with a configuration
301
     *
302
     * @param bool $status True when a website should be built without a configuration
303
     */
304
    public function setConfLess ($status)
305
    {
306
        $this->confLess = $status;
307
    }
308
309
    /**
310
     * Get whether or not the website is being built in safe mode.
311
     *
312
     * Safe mode is defined as disabling file system access from Twig and disabling user Twig extensions
313
     *
314
     * @return bool True when the website is being built in safe mode
315
     */
316
    public function isSafeMode ()
317
    {
318
        return $this->safeMode;
319
    }
320
321
    /**
322
     * Set whether a website should be built in safe mode
323
     *
324
     * @param bool $bool True if a website should be built in safe mode
325
     */
326
    public function setSafeMode ($bool)
327
    {
328
        $this->safeMode = $bool;
329
    }
330
331
    /**
332
     * @return boolean
333
     */
334
    public function isNoClean()
335
    {
336
        return $this->noClean;
337
    }
338
339
    /**
340
     * @param boolean $noClean
341
     */
342
    public function setNoClean($noClean)
343
    {
344
        $this->noClean = $noClean;
345
    }
346
347
    private function creationWatcher ($filePath)
348
    {
349
        $this->output->writeln(sprintf("File creation detected: %s", $filePath));
350
351
        if ($this->pm->isHandled($filePath))
352
        {
353
            $this->pm->createNewItem($filePath);
354
            $this->pm->refreshItem($filePath);
355
        }
356
        else if ($this->cm->isHandled($filePath))
357
        {
358
            $contentItem = $this->cm->createNewItem($filePath);
359
360
            $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...
361
            $this->pm->trackNewContentItem($contentItem);
362
//            $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...
363
//            $this->pm->compileSome(array(
364
//                'namespace' => 'collections',
365
//                'dependency' => $contentItem->getCollection()
366
//            ));
367
        }
368
        else if ($this->dm->isHandled($filePath))
369
        {
370
            $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...
371
372
            $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...
373
//            $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...
374
//                'namespace' => 'data',
375
//                'dependency' => $change
376
//            ));
377
        }
378
        else if (!is_null($this->tm) && $this->tm->isHandled($filePath))
379
        {
380
            $this->tm->createNewItem($filePath);
381
        }
382
        else if ($this->am->isHandled($filePath))
383
        {
384
            $this->am->createNewItem($filePath);
385
        }
386
    }
387
388
    private function modificationWatcher ($filePath)
389
    {
390
        $this->output->writeln(sprintf("File change detected: %s", $filePath));
391
392
        if ($this->pm->isTracked($filePath))
393
        {
394
            $this->pm->refreshItem($filePath);
395
        }
396
        else if ($this->cm->isTracked($filePath))
397
        {
398
            $contentItem = &$this->cm->getContentItem($filePath);
399
            $contentItem->refreshFileContent();
400
401
//            $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...
402
//            $this->pm->compileSome(array(
403
//                'namespace' => 'collections',
404
//                'dependency' => $contentItem->getCollection()
405
//            ));
406
        }
407
        else if ($this->dm->isTracked($filePath))
408
        {
409
            $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...
410
411
//            $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...
412
//            $this->pm->compileSome(array(
413
//                'namespace' => 'data',
414
//                'dependency' => $change
415
//            ));
416
        }
417
        else if (!is_null($this->tm) && $this->tm->isTracked($filePath))
418
        {
419
            $this->tm->refreshItem($filePath);
420
        }
421
        else if ($this->am->isTracked($filePath))
422
        {
423
            $this->am->refreshItem($filePath);
424
        }
425
    }
426
427
    /**
428
     * Prepare the Stakx environment by creating necessary cache folders
429
     *
430
     * @param bool $cleanDirectory Clean the target directory
431
     */
432
    private function createFolderStructure ($cleanDirectory)
433
    {
434
        $tarDir = $this->fs->absolutePath($this->configuration->getTargetFolder());
435
436
        if ($cleanDirectory)
437
        {
438
            $this->fs->remove($tarDir);
439
        }
440
441
        $this->fs->remove($this->fs->absolutePath('.stakx-cache'));
442
        $this->fs->mkdir($this->fs->absolutePath('.stakx-cache/twig'));
443
        $this->fs->mkdir($tarDir);
444
    }
445
}