Completed
Pull Request — master (#168)
by Doğa
12:03 queued 06:02
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
// BUG: When there are several scripts registered, some with a CDN, some without, the CDN setting is only applied if it was set in the first instance.
7
8
class Asset
9
{
10
    const DEFAULT_OPTIONS = [
11
        'dependencies' => [],
12
        'version' => null,
13
        'inFooter' => true,
14
        'media' => 'all',
15
        'cdn' => []
16
    ];
17
18
    protected static $assetManifest;
19
    protected static $loadFromCdn = false;
20
21
    public static function requireUrl($asset)
22
    {
23
        return self::get('url', $asset);
24
    }
25
26
    public static function requirePath($asset)
27
    {
28
        return self::get('path', $asset);
29
    }
30
31
    public static function register($options)
32
    {
33
        return self::add('register', $options);
34
    }
35
36
    public static function enqueue($options)
37
    {
38
        return self::add('enqueue', $options);
39
    }
40
41
    protected static function get($returnType, $asset)
42
    {
43
        $distPath = get_template_directory() . '/dist';
44
45
        if (!isset(self::$assetManifest)) {
46
            $manifestPath = $distPath . '/rev-manifest.json';
47
            if (is_file($manifestPath)) {
48
                self::$assetManifest = json_decode(file_get_contents($manifestPath), true);
49
            } else {
50
                self::$assetManifest = [];
51
            }
52
        }
53
54
        if (array_key_exists($asset, self::$assetManifest)) {
55
            $assetSuffix = self::$assetManifest[$asset];
56
        } else {
57
            $assetSuffix = $asset;
58
        }
59
60
        if ('path' == $returnType) {
61
            return $distPath . '/' . $assetSuffix;
62
        } else if ('url' == $returnType) {
63
            $distUrl = get_template_directory_uri() . '/dist';
64
            return $distUrl . '/' . $assetSuffix;
65
        }
66
67
        return false;
68
    }
69
70
    protected static function add($funcType, $options)
71
    {
72
        $options = array_merge(self::DEFAULT_OPTIONS, $options);
73
74
        if (!array_key_exists('name', $options)) {
75
            trigger_error('Cannot add asset: Name not provided!', E_USER_WARNING);
76
            return false;
77
        }
78
79
        if (!array_key_exists('path', $options)) {
80
            trigger_error('Cannot add asset: Path not provided!', E_USER_WARNING);
81
            return false;
82
        }
83
84
        $funcName = "wp_{$funcType}_{$options['type']}";
85
        $lastVar = $options['type'] === 'script' ? $options['inFooter'] : $options['media'];
86
87
        // allow external urls
88
        $path = $options['path'];
89
        if (!(StringHelpers::startsWith('http://', $path))
90
            && !(StringHelpers::startsWith('https://', $path))
91
            && !(StringHelpers::startsWith('//', $path))
92
        ) {
93
            $path = Asset::requireUrl($path);
94
        }
95
96
        if ('script' === $options['type']
97
            && true === self::$loadFromCdn
98
            && !empty($options['cdn'])
99
            && !empty($options['cdn']['check'])
100
            && !empty($options['cdn']['url'])
101
            && !wp_script_is($options['name'], 'registered')
102
            && !wp_script_is($options['name'], 'enqueued')
103
        ) {
104
            $cdnCheck = $options['cdn']['check'];
105
            $localPath = $path;
106
            $path = $options['cdn']['url'];
107
        }
108
109
        if (function_exists($funcName)) {
110
            $funcName(
111
                $options['name'],
112
                $path,
113
                $options['dependencies'],
114
                $options['version'],
115
                $lastVar
116
            );
117
118
            if (isset($localPath)) {
119
                wp_add_inline_script(
120
                    $options['name'],
121
                    "${cdnCheck}||document.write(\"<script src=\\\"${localPath}\\\"><\/script>\")"
0 ignored issues
show
Bug introduced by
The variable $cdnCheck does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
122
                );
123
            }
124
125
            return true;
126
        }
127
128
        return false;
129
    }
130
131
    /**
132
     * Getter and setter for the loadFromCdn setting.
133
     *
134
     * @param boolean $load (optional) Value to set the parameter to.
135
     **/
136
    public static function loadFromCdn($load = null)
137
    {
138
        if (!isset($load)) {
139
            return self::$loadFromCdn;
140
        }
141
        self::$loadFromCdn = (bool) $load;
142
    }
143
}
144