Completed
Push — master ( faeebb...68bc9e )
by Doğa
02:46
created

Asset::loadFromCdn()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Flynt\Utils;
4
5
// TODO: add async & defer (see https://matthewhorne.me/defer-async-wordpress-scripts/); also add to cdn fallback
6
7
class Asset
8
{
9
    const DEFAULT_OPTIONS = [
10
        'dependencies' => [],
11
        'version' => null,
12
        'inFooter' => true,
13
        'media' => 'all',
14
        'cdn' => []
15
    ];
16
17
    protected static $assetManifest;
18
    protected static $loadFromCdn = false;
19
20
    public static function requireUrl($asset)
21
    {
22
        return self::get('url', $asset);
23
    }
24
25
    public static function requirePath($asset)
26
    {
27
        return self::get('path', $asset);
28
    }
29
30
    public static function register($options)
31
    {
32
        return self::add('register', $options);
33
    }
34
35
    public static function enqueue($options)
36
    {
37
        return self::add('enqueue', $options);
38
    }
39
40
    protected static function get($returnType, $asset)
41
    {
42
        $distPath = get_template_directory() . '/dist';
43
44
        if (!isset(self::$assetManifest)) {
45
            $manifestPath = $distPath . '/rev-manifest.json';
46
            if (is_file($manifestPath)) {
47
                self::$assetManifest = json_decode(file_get_contents($manifestPath), true);
48
            } else {
49
                self::$assetManifest = [];
50
            }
51
        }
52
53
        if (array_key_exists($asset, self::$assetManifest)) {
54
            $assetSuffix = self::$assetManifest[$asset];
55
        } else {
56
            $assetSuffix = $asset;
57
        }
58
59
        if ('path' == $returnType) {
60
            return $distPath . '/' . $assetSuffix;
61
        } else if ('url' == $returnType) {
62
            $distUrl = get_template_directory_uri() . '/dist';
63
            return $distUrl . '/' . $assetSuffix;
64
        }
65
66
        return false;
67
    }
68
69
    protected static function add($funcType, $options)
70
    {
71
        $options = array_merge(self::DEFAULT_OPTIONS, $options);
72
73
        if (!array_key_exists('name', $options)) {
74
            trigger_error('Cannot add asset: Name not provided!', E_USER_WARNING);
75
            return false;
76
        }
77
78
        if (!array_key_exists('path', $options)) {
79
            trigger_error('Cannot add asset: Path not provided!', E_USER_WARNING);
80
            return false;
81
        }
82
83
        $funcName = "wp_{$funcType}_{$options['type']}";
84
        $lastVar = $options['type'] === 'script' ? $options['inFooter'] : $options['media'];
85
86
        // allow external urls
87
        $path = $options['path'];
88
        if (!(StringHelpers::startsWith('http://', $path))
89
            && !(StringHelpers::startsWith('https://', $path))
90
            && !(StringHelpers::startsWith('//', $path))
91
        ) {
92
            $path = Asset::requireUrl($path);
93
        }
94
95
        if ('script' === $options['type']
96
            && true === self::$loadFromCdn
97
            && !empty($options['cdn'])
98
            && !empty($options['cdn']['check'])
99
            && !empty($options['cdn']['url'])
100
        ) {
101
            // if the script isn't registered or enqueued yet
102
            if (!wp_script_is($options['name'], 'registered')
103
                && !wp_script_is($options['name'], 'enqueued')
104
            ) {
105
                $localPath = $path;
106
                $path = $options['cdn']['url'];
107
            } else {
108
                // script already registered / enqueued
109
                // get registered script and compare paths
110
                $scriptPath = wp_scripts()->registered[$options['name']]->src;
111
112
                // deregister script and set cdn options to re-register down below
113
                if ($options['cdn']['url'] !== $scriptPath) {
114
                    wp_deregister_script($options['name']);
115
                    $localPath = $path;
116
                    $path = $options['cdn']['url'];
117
                }
118
            }
119
        }
120
121
        if (function_exists($funcName)) {
122
            $funcName(
123
                $options['name'],
124
                $path,
125
                $options['dependencies'],
126
                $options['version'],
127
                $lastVar
128
            );
129
130
            if (isset($localPath)) {
131
                $cdnCheck = $options['cdn']['check'];
132
                wp_add_inline_script(
133
                    $options['name'],
134
                    "${cdnCheck}||document.write(\"<script src=\\\"${localPath}\\\"><\/script>\")"
135
                );
136
            }
137
138
            return true;
139
        }
140
141
        return false;
142
    }
143
144
    /**
145
     * Getter and setter for the loadFromCdn setting.
146
     *
147
     * @param boolean $load (optional) Value to set the parameter to.
148
     **/
149
    public static function loadFromCdn($load = null)
150
    {
151
        if (!isset($load)) {
152
            return self::$loadFromCdn;
153
        }
154
        self::$loadFromCdn = (bool) $load;
155
    }
156
}
157