Passed
Pull Request — master (#50)
by Wilmer
02:02
created

AssetBundle::isRelative()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
1
<?php
2
declare(strict_types = 1);
3
4
namespace Yiisoft\Asset;
5
6
use Yiisoft\Aliases\Aliases;
7
use Yiisoft\Arrays\ArrayHelper;
8
use Yiisoft\View\WebView;
9
10
/**
11
 * AssetBundle represents a collection of asset files, such as CSS, JS, images.
12
 *
13
 * Each asset bundle has a unique name that globally identifies it among all asset bundles used in an application. The
14
 * name is the [fully qualified class name](http://php.net/manual/en/language.namespaces.rules.php) of the class
15
 * representing it.
16
 *
17
 * An asset bundle can depend on other asset bundles. When registering an asset bundle with a view, all its dependent
18
 * asset bundles will be automatically registered.
19
 */
20
class AssetBundle
21
{
22
    /**
23
     * @var string the Web-accessible directory that contains the asset files in this bundle.
24
     *
25
     * If {@see sourcePath} is set, this property will be *overwritten* by {@see AssetManager} when it publishes the
26
     * asset files from {@see sourcePath}.
27
     *
28
     * You can use either a directory or an alias of the directory.
29
     */
30
    public $basePath;
31
32
    /**
33
     * @var string the base URL for the relative asset files listed in {@see js} and {@see css}.
34
     *
35
     * If {@see {sourcePath} is set, this property will be *overwritten* by {@see {AssetManager} when it publishes the
36
     * asset files from {@see {sourcePath}.
37
     *
38
     * You can use either a URL or an alias of the URL.
39
     */
40
    public $baseUrl;
41
42
    /**
43
     * @var array list of CSS files that this bundle contains. Each CSS file can be specified in one of the three
44
     *            formats as explained in {@see js}.
45
     *
46
     * Note that only a forward slash "/" should be used as directory separator.
47
     */
48
    public $css = [];
49
50
    /**
51
     * @var array the options that will be passed to {@see View::registerCssFile()} when registering the CSS files in
52
     *            this bundle.
53
     */
54
    public $cssOptions = [];
55
56
    /**
57
     * @var array list of bundle class names that this bundle depends on.
58
     *
59
     * For example:
60
     *
61
     * ```php
62
     * public $depends = [
63
     *    \Yiisoft\Web\YiiAsset::class,
64
     *    \yii\bootstrap\BootstrapAsset::class,
65
     * ];
66
     * ```
67
     */
68
    public $depends = [];
69
70
    /**
71
     * @var array list of JavaScript files that this bundle contains. Each JavaScript file can be specified in one of
72
     *            the following formats:
73
     *
74
     * - an absolute URL representing an external asset. For example,
75
     *   `http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js` or
76
     *   `//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js`.
77
     * - a relative path representing a local asset (e.g. `js/main.js`). The actual file path of a local asset can be
78
     *   determined by prefixing [[basePath]] to the relative path, and the actual URL of the asset can be determined
79
     *   by prefixing [[baseUrl]] to the relative path.
80
     * - an array, with the first entry being the URL or relative path as described before, and a list of key => value
81
     *   pairs that will be used to overwrite {@see jsOptions} settings for this entry.
82
     *
83
     * Note that only a forward slash "/" should be used as directory separator.
84
     */
85
    public $js = [];
86
87
    /**
88
     * @var array the options that will be passed to {@see View::registerJsFile()} when registering the JS files in this
89
     *            bundle.
90
     */
91
    public $jsOptions = [];
92
93
    /**
94
     * @var array the options to be passed to {@see AssetManager::publish()} when the asset bundle  is being published.
95
     *            This property is used only when {@see sourcePath} is set.
96
     */
97
    public $publishOptions = [];
98
99
    /**
100
     * @var string the directory that contains the source asset files for this asset bundle. A source asset file is a
101
     *             file that is part of your source code repository of your Web application.
102
     *
103
     * You must set this property if the directory containing the source asset files is not Web accessible. By setting
104
     * this property, [[AssetManager]] will publish the source asset files to a Web-accessible directory automatically
105
     * when the asset bundle is registered on a page.
106
     *
107
     * If you do not set this property, it means the source asset files are located under {@see basePath}.
108
     *
109
     * You can use either a directory or an alias of the directory.
110
     *
111
     * {@see publishOptions}
112
     */
113
    public $sourcePath;
114
115
    /**
116
     * Publishes the asset bundle if its source code is not under Web-accessible directory.
117
     *
118
     * It will also try to convert non-CSS or JS files (e.g. LESS, Sass) into the corresponding CSS or JS files using
119
     * {@see AssetManager::converter|asset converter}.
120
     *
121
     * @param AssetManager $am the asset manager to perform the asset publishing
122
     * @return void
123
     */
124 13
    public function publish(AssetManager $am): void
125
    {
126 13
        if ($this->sourcePath !== null && !isset($this->basePath, $this->baseUrl)) {
127 2
            [$this->basePath, $this->baseUrl] = $am->publish($this->sourcePath, $this->publishOptions);
128
        }
129
130 13
        if (isset($this->basePath, $this->baseUrl) && ($converter = $am->getConverter()) !== null) {
131 13
            foreach ($this->js as $i => $js) {
132 13
                if (is_array($js)) {
133 1
                    $file = array_shift($js);
134 1
                    if ($this->isRelative($file)) {
135 1
                        $js = ArrayHelper::merge($this->jsOptions, $js);
136 1
                        array_unshift($js, $converter->convert($file, $this->basePath));
137 1
                        $this->js[$i] = $js;
138
                    }
139 13
                } elseif ($this->isRelative($js)) {
140 13
                    $this->js[$i] = $converter->convert($js, $this->basePath);
141
                }
142
            }
143 13
            foreach ($this->css as $i => $css) {
144 11
                if (is_array($css)) {
145 1
                    $file = array_shift($css);
146 1
                    if ($this->isRelative($file)) {
147 1
                        $css = ArrayHelper::merge($this->cssOptions, $css);
148 1
                        array_unshift($css, $converter->convert($file, $this->basePath));
149 1
                        $this->css[$i] = $css;
150
                    }
151 11
                } elseif ($this->isRelative($css)) {
152 11
                    $this->css[$i] = $converter->convert($css, $this->basePath);
153
                }
154
            }
155
        }
156
    }
157
158
    /**
159
     * Registers this asset bundle with a view.
160
     *
161
     * @param WebView $webView to be registered with
162
     *
163
     * @return AssetBundle the registered asset bundle instance
164
     */
165 12
    public static function register(WebView $webView): AssetBundle
166
    {
167 12
        return $webView->registerAssetBundle(static::class);
168
    }
169
170
    /**
171
     * Registers the CSS and JS files with the given view.
172
     *
173
     * @param Webview $view the view that the asset files are to be registered with.
174
     * @return void
175
     */
176 8
    public function registerAssetFiles(WebView $view): void
177
    {
178 8
        $manager = $view->getAssetManager();
179
180 8
        foreach ($this->js as $js) {
181 8
            if (is_array($js)) {
182 1
                $file = array_shift($js);
183 1
                $options = ArrayHelper::merge($this->jsOptions, $js);
184 1
                $view->registerJsFile($manager->getAssetUrl($this, $file), $options);
185
            } else {
186 8
                if ($js !== null) {
187 8
                    $view->registerJsFile($manager->getAssetUrl($this, $js), $this->jsOptions);
188
                }
189
            }
190
        }
191
192 8
        foreach ($this->css as $css) {
193 7
            if (is_array($css)) {
194 1
                $file = array_shift($css);
195 1
                $options = ArrayHelper::merge($this->cssOptions, $css);
196 1
                $view->registerCssFile($manager->getAssetUrl($this, $file), $options);
197
            } else {
198 7
                if ($css !== null) {
199 7
                    $view->registerCssFile($manager->getAssetUrl($this, $css), $this->cssOptions);
200
                }
201
            }
202
        }
203
    }
204
205
    /**
206
     * Returns a value indicating whether a URL is relative.
207
     * A relative URL does not have host info part.
208
     * @param string $url the URL to be checked
209
     * @return bool whether the URL is relative
210
     */
211 13
    protected function isRelative($url)
212
    {
213 13
        return strncmp($url, '//', 2) && strpos($url, '://') === false;
214
    }
215
}
216