Completed
Push — master ( 408bbf...c4988a )
by Maxim
02:29
created

AssetManager   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 157
Duplicated Lines 14.01 %

Importance

Changes 0
Metric Value
dl 22
loc 157
rs 10
c 0
b 0
f 0
wmc 22

9 Methods

Rating   Name   Duplication   Size   Complexity  
A applyJs() 10 10 3
A applyCss() 10 10 3
A registerAsset() 0 6 2
A getLink() 0 10 3
A __construct() 0 5 1
A getLinks() 0 8 2
A publishAsset() 0 14 4
A getWebDir() 0 5 2
A getPath() 0 7 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace WebComplete\mvc\assets;
4
5
use Symfony\Component\Filesystem\Filesystem;
6
use WebComplete\mvc\exception\Exception;
7
8
class AssetManager
9
{
10
11
    /**
12
     * @var AbstractAsset[]
13
     */
14
    protected $assets = [];
15
    /**
16
     * @var string
17
     */
18
    protected $webRoot;
19
    /**
20
     * @var string
21
     */
22
    protected $assetDirName;
23
    /**
24
     * @var Filesystem
25
     */
26
    protected $filesystem;
27
28
    /**
29
     * @param Filesystem $filesystem
30
     * @param string $webRoot
31
     * @param string $assetDirName
32
     */
33
    public function __construct(Filesystem $filesystem, string $webRoot, string $assetDirName)
34
    {
35
        $this->filesystem = $filesystem;
36
        $this->webRoot = \rtrim($webRoot, '/');
37
        $this->assetDirName = $assetDirName;
38
    }
39
40
    /**
41
     * @param AbstractAsset $asset
42
     *
43
     * @throws \Symfony\Component\Filesystem\Exception\IOException
44
     */
45
    public function registerAsset(AbstractAsset $asset)
46
    {
47
        if ($asset->publish) {
48
            $this->publishAsset($asset);
49
        }
50
        $this->assets[\get_class($asset)] = $asset;
51
    }
52
53
    /**
54
     * @param string $assetClass
55
     * @param $file
56
     *
57
     * @return string
58
     * @throws Exception
59
     */
60
    public function getPath(string $assetClass, $file): string
61
    {
62
        if (!isset($this->assets[$assetClass])) {
63
            throw new Exception('Asset ' . $assetClass . ' is not registered');
64
        }
65
66
        return $this->getWebDir($this->assets[$assetClass]) . \ltrim($file, '/');
67
    }
68
69
    /**
70
     * @return string
71
     */
72 View Code Duplication
    public function applyCss(): string
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...
73
    {
74
        $result = [];
75
        foreach ($this->assets as $asset) {
76
            $links = $this->getLinks($asset, $asset->css());
77
            foreach ($links as $link) {
78
                $result[] = '<link rel="stylesheet" href="' . $link . '">';
79
            }
80
        }
81
        return \implode('', $result);
82
    }
83
84
    /**
85
     * @return string
86
     */
87 View Code Duplication
    public function applyJs(): string
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...
88
    {
89
        $result = [];
90
        foreach ($this->assets as $asset) {
91
            $links = $this->getLinks($asset, $asset->js());
92
            foreach ($links as $link) {
93
                $result[] = '<script src="' . $link . '"></script>';
94
            }
95
        }
96
        return \implode('', $result);
97
    }
98
99
    /**
100
     * @param AbstractAsset $asset
101
     *
102
     * @throws \Symfony\Component\Filesystem\Exception\IOException
103
     */
104
    protected function publishAsset(AbstractAsset $asset)
105
    {
106
        $hash = $asset->getHash();
107
        $dir = $this->webRoot . '/' . $this->assetDirName . '/' . $hash;
108
        if ($asset->useLinks) {
109
            if (!$this->filesystem->exists($dir)) {
110
                $this->filesystem->symlink($asset->getBasePath(), $dir, true);
111
            }
112
        } else {
113
            if ($this->filesystem->exists($dir)) {
114
                $this->filesystem->remove($dir);
115
            }
116
            $this->filesystem->mirror($asset->getBasePath(), $dir);
117
            $this->filesystem->chmod($dir, 0755, 000, true);
118
        }
119
    }
120
121
    /**
122
     * @param AbstractAsset $asset
123
     *
124
     * @return string
125
     */
126
    private function getWebDir(AbstractAsset $asset): string
127
    {
128
        return $asset->publish
129
            ? '/' . $this->assetDirName . '/' . $asset->getHash() . '/'
130
            : '/';
131
    }
132
133
    /**
134
     * @param AbstractAsset $asset
135
     * @param array $files
136
     *
137
     * @return array
138
     */
139
    private function getLinks(AbstractAsset $asset, array $files): array
140
    {
141
        $result = [];
142
        $dir = $this->getWebDir($asset);
143
        foreach ($files as $file) {
144
            $result[] = $this->getLink($file, $dir);
145
        }
146
        return $result;
147
    }
148
149
    /**
150
     * @param $file
151
     * @param $dir
152
     *
153
     * @return string
154
     */
155
    private function getLink($file, $dir): string
156
    {
157
        $link = $file;
158
        if (false === \strpos($file, 'http') && false === \strpos($file, '//')) {
159
            $filePath = $dir . \ltrim($file, '/');
160
            $timestamp = \filemtime($this->webRoot . $filePath);
161
            $link = $filePath . '?' . $timestamp;
0 ignored issues
show
Bug introduced by
Are you sure $timestamp of type integer|false can be used in concatenation? ( Ignorable by Annotation )

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

161
            $link = $filePath . '?' . /** @scrutinizer ignore-type */ $timestamp;
Loading history...
162
        }
163
164
        return $link;
165
    }
166
}
167