Passed
Push — master ( 9f96f6...0f86e3 )
by Dev
12:11 queued 07:09
created

StaticService::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 13
c 1
b 0
f 0
nc 1
nop 10
dl 0
loc 25
ccs 0
cts 25
cp 0
crap 2
rs 9.8333

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace PiedWeb\CMSBundle\Service;
4
5
use Doctrine\ORM\EntityManagerInterface;
6
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
7
use Liip\ImagineBundle\Imagine\Data\DataManager;
8
use Liip\ImagineBundle\Imagine\Filter\FilterManager;
9
use PiedWeb\CMSBundle\Entity\PageInterface as Page;
10
use PiedWeb\CMSBundle\EventListener\MediaCacheGeneratorTrait;
11
use PiedWeb\CMSBundle\Service\PageCanonicalService as PageCanonical;
12
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
13
use Symfony\Component\Filesystem\Filesystem;
14
use Symfony\Component\HttpFoundation\Request;
15
use Symfony\Component\HttpFoundation\RequestStack;
16
use Symfony\Contracts\Translation\TranslatorInterface;
17
use Twig\Environment as Twig;
18
use \WyriHaximus\HtmlCompress\Factory as HtmlCompressor;
19
20
class StaticService
21
{
22
    //use MediaCacheGeneratorTrait;
23
24
    /**
25
     * @var EntityManagerInterface
26
     */
27
    private $em;
28
29
    /**
30
     * @var Filesystem
31
     */
32
    private $filesystem;
33
34
    /**
35
     * @var \Twig_environement
0 ignored issues
show
Bug introduced by
The type Twig_environement was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
36
     */
37
    private $twig;
38
39
    /**
40
     * @var string
41
     */
42
    private $webDir;
43
44
    /**
45
     * @var string
46
     */
47
    private $staticDir;
48
49
    /**
50
     * @var RequestStack
51
     */
52
    private $requesStack;
53
54
    /**
55
     * @var \PiedWeb\CMSBundle\Service\PageCanonicalService
56
     */
57
    private $pageCanonical;
58
59
    /**
60
     * @var TranslatorInterface
61
     */
62
    private $translator;
63
64
    private $parser;
65
66
    private $params;
67
68
    protected $redirections = '';
69
70
    private $cacheManager;
71
    private $dataManager;
72
    private $filterManager;
73
74
    public function __construct(
75
        EntityManagerInterface $em,
76
        Twig $twig,
77
        ParameterBagInterface $params,
78
        RequestStack $requesStack,
79
        PageCanonical $pageCanonical,
80
        TranslatorInterface $translator,
81
        CacheManager $cacheManager,
82
        DataManager $dataManager,
83
        FilterManager $filterManager,
84
        string $webDir
85
    ) {
86
        $this->em = $em;
87
        $this->filesystem = new Filesystem();
88
        $this->twig = $twig;
0 ignored issues
show
Documentation Bug introduced by
It seems like $twig of type Twig\Environment is incompatible with the declared type Twig_environement of property $twig.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
89
        $this->params = $params;
90
        $this->requesStack = $requesStack;
91
        $this->webDir = $webDir;
92
        $this->pageCanonical = $pageCanonical;
93
        $this->translator = $translator;
94
        $this->cacheManager = $cacheManager;
95
        $this->dataManager = $dataManager;
96
        $this->filterManager = $filterManager;
97
        $this->staticDir = $this->webDir.'/../static';
98
        $this->parser = HtmlCompressor::construct();
99
    }
100
101
    /**
102
     * @throws \RuntimeException
103
     * @throws \LogicException
104
     */
105
    public function dump()
106
    {
107
        if (!method_exists($this->filesystem, 'dumpFile')) {
108
            throw new \RuntimeException('Method dumpFile() is not available. Upgrade your Filesystem.');
109
        }
110
111
        $this->rmdir($this->staticDir);
112
        $this->pageToStatic();
113
        $this->assetsToStatic();
114
        $this->htaccessToStatic();
115
        $this->mediaToDownload();
116
    }
117
118
    protected function htaccessToStatic()
119
    {
120
        if (!$this->params->has('app.static_domain')) {
121
            throw new \Exception('Before, you need to configure (in config/services.yaml) app.static_domain.');
122
        }
123
124
        $htaccess = $this->twig->render('@PiedWebCMS/static/htaccess.twig', [
125
            'domain' => $this->params->get('app.static_domain'),
126
            'redirections' => $this->redirections,
127
        ]);
128
        $this->filesystem->dumpFile($this->staticDir.'/.htaccess', $htaccess);
129
    }
130
131
    protected static function rmdir($dir)
132
    {
133
        if (is_link($dir)) {
134
            unlink($dir);
135
        }
136
137
        if (!is_dir($dir)) {
138
            return false;
139
        }
140
141
        $dir_handle = opendir($dir);
142
        if (!$dir_handle) {
0 ignored issues
show
introduced by
$dir_handle is of type false|resource, thus it always evaluated to false.
Loading history...
143
            return false;
144
        }
145
146
        while ($file = readdir($dir_handle)) {
147
            if ('.' != $file && '..' != $file) {
148
                if (!is_dir($dir.'/'.$file)) {
149
                    unlink($dir.'/'.$file);
150
                } else {
151
                    self::rmdir($dir.'/'.$file);
152
                }
153
            }
154
        }
155
        closedir($dir_handle);
156
        rmdir($dir);
157
158
        return true;
159
    }
160
161
    protected function symlink(string $target, string $link): bool
162
    {
163
        // Check for symlinks
164
        if (is_link($target)) {
165
            return symlink(readlink($target), $link);
166
        }
167
168
        return symlink(
169
            $target,
170
            $link
171
        );
172
    }
173
174
    /**
175
     * We create symlink for all assets
176
     * and we copy feed.xml, sitemap.xml, robots.txt (avoid new page not yet generated try to be indexed by bots).
177
     */
178
    protected function assetsToStatic(): self
179
    {
180
        $dir = dir($this->webDir);
181
        while (false !== $entry = $dir->read()) {
182
            if ('.' == $entry || '..' == $entry) {
183
                continue;
184
            }
185
            if (in_array($entry, ['robots.txt', 'feed.xml', 'sitemap.xml', 'sitemap.txt'])) {
186
                copy(
187
                    str_replace($this->params->get('kernel.project_dir').'/', '../', $this->webDir.'/'.$entry),
188
                    $this->staticDir.'/'.$entry
189
                );
190
            } elseif ('index.php' != $entry) {
191
                $this->symlink(
192
                    str_replace($this->params->get('kernel.project_dir').'/', '../', $this->webDir.'/'.$entry),
193
                    $this->staticDir.'/'.$entry
194
                );
195
            }
196
        }
197
        $dir->close();
198
199
        return $this;
200
    }
201
202
    protected function mediaToDownload()
203
    {
204
        $this->filesystem->mkdir($this->staticDir.'/download/');
205
        symlink($this->webDir.'/../media', $this->staticDir.'/download/media');
206
207
        /* create download symlink *
208
        if (!file_exists($this->staticDir.'/download')) {
209
            mkdir($this->staticDir.'/download');
210
        }
211
        $this->symlink(
212
            str_replace($this->params->get('kernel.project_dir').'/', '../', $this->webDir.'/../media'),
213
            $this->staticDir.'/download/media'
214
        );
215
        /**/
216
    }
217
218
    protected function pageToStatic(): self
219
    {
220
        $pages = $this->getPages();
221
222
        // todo i18n error
223
        $locales = explode('|', $this->params->get('app.locales'));
224
225
        foreach ($locales as $locale) {
226
            $this->filesystem->mkdir($this->staticDir.'/'.$locale);
227
            $this->generateErrorPage($locale);
228
        }
229
230
        foreach ($pages as $page) {
231
            // set current locale to avoid twig error
232
            $request = new Request();
233
            $request->setLocale($page->getLocale());
234
            $this->requesStack->push($request);
235
236
            $page->setTranslatableLocale($page->getLocale());
237
            $this->em->refresh($page);
238
239
            $this->translator->setLocale($page->getLocale());
240
241
            $slug = '' == $page->getRealSlug() ? 'index' : $page->getRealSlug();
242
            $route = $this->pageCanonical->generatePathForPage($slug);
243
            $filepath = $this->staticDir.$route.'.html';
244
245
            // check if it's a redirection
246
            if (false !== $page->getRedirection()) {
247
                $this->redirections .= 'Redirect ';
248
                $this->redirections .= $page->getRedirectionCode().' '.$route.' '.$page->getRedirection();
249
                $this->redirections .= PHP_EOL;
250
                continue;
251
            }
252
253
            $dump = $this->render($page);
254
            $this->filesystem->dumpFile($filepath, $dump);
255
256
            if ($page->getChildrenPages()->count() > 0) {
257
                $dump = $this->renderFeed($page);
258
                $this->filesystem->dumpFile(preg_replace('/.html$/', '.xml', $filepath), $dump);
259
            }
260
        }
261
262
        return $this;
263
    }
264
265
    protected function generateErrorPage($locale = null)
266
    {
267
        if (null !== $locale) {
268
            $request = new Request();
269
            $request->setLocale($locale);
270
            $this->requesStack->push($request);
271
        }
272
273
        $dump = $this->parser->compress($this->twig->render('@Twig/Exception/error.html.twig'));
274
        $this->filesystem->dumpFile($this->staticDir.(null !== $locale ? '/'.$locale : '').'/_error.html', $dump);
275
    }
276
277
    protected function getPages()
278
    {
279
        $qb = $this->em->getRepository($this->params->get('app.entity_page'))->getQueryToFindPublished('p');
0 ignored issues
show
Bug introduced by
The method getQueryToFindPublished() does not exist on Doctrine\Persistence\ObjectRepository. It seems like you code against a sub-type of Doctrine\Persistence\ObjectRepository such as Doctrine\ORM\EntityRepository. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

279
        $qb = $this->em->getRepository($this->params->get('app.entity_page'))->/** @scrutinizer ignore-call */ getQueryToFindPublished('p');
Loading history...
280
281
        return $qb->getQuery()->getResult();
282
    }
283
284
    protected function render(Page $page)
285
    {
286
        $template = $this->params->get('app.default_page_template');
287
288
        return $this->parser->compress($this->twig->render($template, ['page' => $page]));
289
    }
290
291
    // todo i18n feed ...
292
    protected function renderFeed(Page $page)
293
    {
294
        $template = '@PiedWebCMS/page/rss.xml.twig';
295
296
        return $this->parser->compress($this->twig->render($template, ['page' => $page]));
297
    }
298
}
299