Completed
Push — master ( f8c34a...03d8b8 )
by Denis
02:13
created

src/Asset/File.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * JBZoo Assets
4
 *
5
 * This file is part of the JBZoo CCK package.
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 *
9
 * @package   Assets
10
 * @license   MIT
11
 * @copyright Copyright (C) JBZoo.com,  All rights reserved.
12
 * @link      https://github.com/JBZoo/Assets
13
 * @author    Sergey Kalistratov <[email protected]>
14
 */
15
16
namespace JBZoo\Assets\Asset;
17
18
use JBZoo\Assets\Exception;
19
use JBZoo\Assets\Filter\Filter;
20
use JBZoo\Utils\FS;
21
use JBZoo\Utils\Url;
22
use JBZoo\Utils\Arr;
23
use JBZoo\Path\Path;
24
use JBZoo\Less\Less;
25
use JBZoo\Assets\Filter\FilterManager;
26
27
/**
28
 * Class File
29
 * @package JBZoo\Assets\Asset
30
 */
31
class File extends Asset
32
{
33
34
    const ASSET_TYPE_FILE = 'file';
35
36
    /**
37
     * Allowed asset extensions.
38
     *
39
     * @var array
40
     */
41
    protected $_allowed = ['css', 'js', 'less'];
42
43
    /**
44
     * Get asset ext.
45
     *
46
     * @return string
47
     */
48
    public function getExt()
49
    {
50
        return FS::ext($this->_source);
51
    }
52
53
    /**
54
     * Load file by type.
55
     *
56
     * @param array $filters
57
     * @return array
58
     * @throws Exception
59
     */
60
    public function load(array $filters = [])
61
    {
62
        $assetExt = $this->getExt();
63
64
        if (!Arr::in($assetExt, $this->_allowed)) {
65
            $allowed = implode(' ', $this->_allowed);
66
            throw new Exception(sprintf('Invalid asset ext "%s", allowed is "%s"', $assetExt, $allowed));
67
        }
68
69
        if (!self::isExternal($this->_source)) {
70
            list($assetExt, $path) = $this->_findSource();
71
72
            $fManager = new FilterManager();
73
74
            if (count($filters)) {
75
                foreach ($filters as $name) {
76
                    /** @var Filter $filter */
77
                    $filter = $fManager->get($name);
78
                    $filter->setAsset($this);
79
                    $path = $filter->process();
80
                }
81
            }
82
83
            return [$assetExt, $this->_timestamp($path)];
84
        }
85
86
        return [$assetExt, $this->_source];
87
    }
88
89
90
    /**
91
     * @param $path
92
     * @return null|string
93
     */
94
    public function getContent($path)
95
    {
96
        if (is_file($path)) {
97
            return file_get_contents($path);
98
        }
99
100
        return null;
101
    }
102
103
    /**
104
     * Gets full source file path.
105
     *
106
     * @return string
107
     */
108
    public function getFullPath()
109
    {
110
        return FS::clean($this->_root . '/' . $this->_source, '/');
111
    }
112
113
    /**
114
     * Find source in variants.
115
     *
116
     * @return array
117
     */
118
    protected function _findSource()
119
    {
120
        $ext    = $this->getExt();
121
        $jbPath = Path::getInstance();
122
        $path   = $this->getFullPath();
123
124
        if ($jbPath->isVirtual($this->_source)) {
125
            $path          = $jbPath->get($this->_source);
126
            $this->_source = $jbPath->url($this->_source, false);
127
        }
128
129
        if ($ext === 'less') {
130
            $ext           = 'css';
131
            $path          = $this->_lessProcess($path);
0 ignored issues
show
It seems like $path can also be of type array or null; however, JBZoo\Assets\Asset\File::_lessProcess() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
132
            $this->_source = FS::getRelative($path, $this->_root);
133
        }
134
135
        return [$ext, $path];
136
    }
137
138
    /**
139
     * Check external source.
140
     *
141
     * @param string $source
142
     * @return bool
143
     */
144
    public static function isExternal($source)
145
    {
146
        if (strpos($source, '://') || preg_match('/^\/\//', $source)) {
147
            return true;
148
        }
149
150
        return false;
151
    }
152
153
    /**
154
     * Process compile less.
155
     *
156
     * @param string $path
157
     * @return string
158
     * @throws \JBZoo\Less\Exception
159
     */
160
    protected function _lessProcess($path)
161
    {
162
        $less = new Less((array)$this->_params);
163
        return $less->compile($path);
164
    }
165
166
    /**
167
     * Add timestamp.
168
     *
169
     * @param string $path
170
     * @return bool|string
171
     */
172
    protected function _timestamp($path)
173
    {
174
        if (FS::isFile($path)) {
175
            $relative = FS::getRelative($path, $this->_root, '/');
176
            return Url::root() . '/' . $relative . '?' . filemtime($path);
177
        }
178
179
        return false;
180
    }
181
}
182