Passed
Push — master ( 781931...9601bc )
by Alexander
02:28
created

AssetUtil::createAsset()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 4
c 0
b 0
f 0
nc 4
nop 2
dl 0
loc 9
ccs 5
cts 5
cp 1
crap 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Assets;
6
7
use Yiisoft\Aliases\Aliases;
8
9
use function is_subclass_of;
10
use function mb_strlen;
11
use function strncmp;
12
use function strpos;
13
use function substr_compare;
14
15
/**
16
 * AssetUtil shared functions.
17
 */
18
final class AssetUtil
19
{
20
    /**
21
     * Creates a new asset bundle instance.
22
     *
23
     * If the name is a class name, an instance of this class will be created,
24
     * otherwise an instance of the {@see AssetBundle} will be created.
25
     *
26
     * @param string $name The asset bundle name. Usually the asset bundle class name (without leading backslash).
27
     * @param array $config The asset bundle instance configuration. If specified, it will be applied to the instance.
28
     *
29
     * @return AssetBundle The created asset bundle.
30
     *
31
     * @psalm-suppress UnsafeInstantiation
32
     */
33 40
    public static function createAsset(string $name, array $config = []): AssetBundle
34
    {
35 40
        $bundle = is_subclass_of($name, AssetBundle::class) ? new $name() : new AssetBundle();
36
37 40
        foreach ($config as $property => $value) {
38 16
            $bundle->{$property} = $value;
39
        }
40
41 40
        return $bundle;
42
    }
43
44
    /**
45
     * Resolves the actual URL for the specified asset.
46
     *
47
     * @param AssetBundle $bundle The asset bundle which the asset file belongs to.
48
     * @param string $assetPath The asset path. This should be one of the assets listed
49
     * in {@see AssetBundle::$js} or {@see AssetBundle::$css}.
50
     * @param array $assetMap Mapping from source asset files (keys) to target asset files (values)
51
     * {@see AssetPublisher::$assetMap}.
52
     *
53
     * @return string|null The actual URL for the specified asset, or null if there is no mapping.
54
     */
55 31
    public static function resolveAsset(AssetBundle $bundle, string $assetPath, array $assetMap): ?string
56
    {
57 31
        if (isset($assetMap[$assetPath])) {
58 1
            return $assetMap[$assetPath];
59
        }
60
61 30
        if (!empty($bundle->sourcePath) && self::isRelative($assetPath)) {
62 6
            $assetPath = $bundle->sourcePath . '/' . $assetPath;
63
        }
64
65 30
        $n = mb_strlen($assetPath, 'utf-8');
66
67 30
        foreach ($assetMap as $from => $to) {
68
            $n2 = mb_strlen($from, 'utf-8');
69
            if ($n2 <= $n && substr_compare($assetPath, $from, $n - $n2, $n2) === 0) {
70
                return $to;
71
            }
72
        }
73
74 30
        return null;
75
    }
76
77
    /**
78
     * Resolve path aliases for {@see AssetBundle} properties:
79
     *
80
     * - {@see AssetBundle::basePath}
81
     * - {@see AssetBundle::baseUrl}
82
     * - {@see AssetBundle::sourcePath}
83
     *
84
     * @param AssetBundle $bundle The asset bundle instance to resolving path aliases.
85
     * @param Aliases $aliases The aliases instance to resolving path aliases.
86
     *
87
     * @return AssetBundle The asset bundle instance with resolved paths.
88
     */
89 3
    public static function resolvePathAliases(AssetBundle $bundle, Aliases $aliases): AssetBundle
90
    {
91 3
        if ($bundle->basePath !== null) {
92 3
            $bundle->basePath = $aliases->get($bundle->basePath);
93
        }
94
95 3
        if ($bundle->baseUrl !== null) {
96 3
            $bundle->baseUrl = $aliases->get($bundle->baseUrl);
97
        }
98
99 3
        if ($bundle->sourcePath !== null) {
100 1
            $bundle->sourcePath = $aliases->get($bundle->sourcePath);
101
        }
102
103 3
        return $bundle;
104
    }
105
106
    /**
107
     * Returns a value indicating whether a URL is relative.
108
     *
109
     * A relative URL does not have host info part.
110
     *
111
     * @param string $url The URL to be checked.
112
     *
113
     * @return bool Whether the URL is relative.
114
     */
115 30
    public static function isRelative(string $url): bool
116
    {
117 30
        return strncmp($url, '//', 2) && strpos($url, '://') === false;
118
    }
119
}
120