AssetManager::createJsFiles()   B
last analyzed

Complexity

Conditions 11
Paths 6

Size

Total Lines 33
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 16
c 1
b 0
f 0
dl 0
loc 33
rs 7.3166
cc 11
nc 6
nop 1

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Jaxon\Plugin\Code;
4
5
use Jaxon\App\Config\ConfigManager;
6
use Jaxon\Plugin\AbstractPlugin;
7
use Jaxon\Request\Handler\ParameterReader;
8
use Jaxon\Utils\Http\UriException;
9
10
use function file_put_contents;
11
use function is_dir;
12
use function is_file;
13
use function is_writable;
14
use function rtrim;
15
16
class AssetManager
17
{
18
    /**
19
     * @var ConfigManager
20
     */
21
    protected $xConfigManager;
22
23
    /**
24
     * @var ParameterReader
25
     */
26
    private $xParameterReader;
27
28
    /**
29
     * @var MinifierInterface
30
     */
31
    private $xMinifier;
32
33
    /**
34
     * Default library URL
35
     *
36
     * @var string
37
     */
38
    const JS_LIB_URL = 'https://cdn.jsdelivr.net/gh/jaxon-php/[email protected]/dist';
39
40
    /**
41
     * The constructor
42
     *
43
     * @param ConfigManager $xConfigManager
44
     * @param ParameterReader $xParameterReader
45
     * @param MinifierInterface $xMinifier
46
     */
47
    public function __construct(ConfigManager $xConfigManager, ParameterReader $xParameterReader, MinifierInterface $xMinifier)
48
    {
49
        $this->xConfigManager = $xConfigManager;
50
        $this->xParameterReader = $xParameterReader;
51
        $this->xMinifier = $xMinifier;
52
    }
53
54
    /**
55
     * Get app js options
56
     *
57
     * @return string
58
     */
59
    public function getJsOptions(): string
60
    {
61
        return $this->xConfigManager->getOption('js.app.options', '');
62
    }
63
64
    /**
65
     * Check if the assets of this plugin shall be included in Jaxon generated code.
66
     *
67
     * @param AbstractPlugin $xPlugin
68
     *
69
     * @return bool
70
     */
71
    public function shallIncludeAssets(AbstractPlugin $xPlugin): bool
72
    {
73
        $sPluginOptionName = 'assets.include.' . $xPlugin->getName();
74
        if($this->xConfigManager->hasOption($sPluginOptionName))
75
        {
76
            return $this->xConfigManager->getOption($sPluginOptionName);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->xConfigMan...ion($sPluginOptionName) could return the type null which is incompatible with the type-hinted return boolean. Consider adding an additional type-check to rule them out.
Loading history...
77
        }
78
        return $this->xConfigManager->getOption('assets.include.all', true);
79
    }
80
81
    /**
82
     * Get the HTML tags to include Jaxon javascript files into the page
83
     *
84
     * @return array
85
     */
86
    public function getJsLibFiles(): array
87
    {
88
        $sJsExtension = $this->xConfigManager->getOption('js.app.minify') ? '.min.js' : '.js';
89
        // The URI for the javascript library files
90
        $sJsLibUri = $this->xConfigManager->getOption('js.lib.uri', self::JS_LIB_URL);
91
        $sJsLibUri = rtrim($sJsLibUri, '/');
92
93
        // Add component files to the javascript file array;
94
        $aJsFiles = [
95
            $this->xConfigManager->getOption('js.lib.jq', "$sJsLibUri/libs/chibi/chibi$sJsExtension"),
96
            "$sJsLibUri/jaxon.core$sJsExtension",
97
        ];
98
        if($this->xConfigManager->getOption('core.debug.on'))
99
        {
100
            $sLanguage = $this->xConfigManager->getOption('core.language');
101
            $aJsFiles[] = "$sJsLibUri/jaxon.debug$sJsExtension";
102
            $aJsFiles[] = "$sJsLibUri/lang/jaxon.$sLanguage$sJsExtension";
103
        }
104
105
        return $aJsFiles;
106
    }
107
108
    /**
109
     * Get the mappings between previous and current config options
110
     *
111
     * @return array
112
     * @throws UriException
113
     */
114
    public function getOptionVars(): array
115
    {
116
        if(!$this->xConfigManager->hasOption('core.request.uri'))
117
        {
118
            $this->xConfigManager->setOption('core.request.uri', $this->xParameterReader->uri());
119
        }
120
        return [
121
            'sResponseType'         => 'JSON',
122
            'sVersion'              => $this->xConfigManager->getOption('core.version'),
123
            'sLanguage'             => $this->xConfigManager->getOption('core.language'),
124
            'bLanguage'             => $this->xConfigManager->hasOption('core.language'),
125
            'sRequestURI'           => $this->xConfigManager->getOption('core.request.uri'),
126
            'sDefaultMode'          => $this->xConfigManager->getOption('core.request.mode'),
127
            'sDefaultMethod'        => $this->xConfigManager->getOption('core.request.method'),
128
            'sCsrfMetaName'         => $this->xConfigManager->getOption('core.request.csrf_meta'),
129
            'bDebug'                => $this->xConfigManager->getOption('core.debug.on'),
130
            'bVerboseDebug'         => $this->xConfigManager->getOption('core.debug.verbose'),
131
            'sDebugOutputID'        => $this->xConfigManager->getOption('core.debug.output_id'),
132
            'nResponseQueueSize'    => $this->xConfigManager->getOption('js.lib.queue_size'),
133
            'sStatusMessages'       => $this->xConfigManager->getOption('js.lib.show_status') ? 'true' : 'false',
134
            'sWaitCursor'           => $this->xConfigManager->getOption('js.lib.show_cursor') ? 'true' : 'false',
135
            'sDefer'                => $this->xConfigManager->getOption('js.app.options', ''),
136
        ];
137
    }
138
139
    /**
140
     * Get the javascript file name
141
     *
142
     * @return bool
143
     */
144
    public function shallCreateJsFiles(): bool
145
    {
146
        // Check config options
147
        // - The js.app.export option must be set to true
148
        // - The js.app.uri and js.app.dir options must be set to non null values
149
        if(!$this->xConfigManager->getOption('js.app.export', false) ||
150
            !$this->xConfigManager->getOption('js.app.uri') ||
151
            !$this->xConfigManager->getOption('js.app.dir'))
152
        {
153
            return false;
154
        }
155
        return true;
156
    }
157
158
    /**
159
     * Write javascript files and return the corresponding URI
160
     *
161
     * @param CodeGenerator $codeGenerator
162
     *
163
     * @return string
164
     */
165
    public function createJsFiles(CodeGenerator $xCodeGenerator): string
166
    {
167
        if(!$this->shallCreateJsFiles())
168
        {
169
            return '';
170
        }
171
172
        // Check dir access
173
        $sJsFileName = $this->xConfigManager->getOption('js.app.file') ?: $xCodeGenerator->getHash();
174
        $sJsDirectory = rtrim($this->xConfigManager->getOption('js.app.dir'), '\/') . DIRECTORY_SEPARATOR;
0 ignored issues
show
Bug introduced by
It seems like $this->xConfigManager->getOption('js.app.dir') can also be of type null; however, parameter $string of rtrim() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

174
        $sJsDirectory = rtrim(/** @scrutinizer ignore-type */ $this->xConfigManager->getOption('js.app.dir'), '\/') . DIRECTORY_SEPARATOR;
Loading history...
175
        // - The js.app.dir must be writable
176
        if(!$sJsFileName || !is_dir($sJsDirectory) || !is_writable($sJsDirectory))
177
        {
178
            return '';
179
        }
180
181
        $sJsFilePath = $sJsDirectory . $sJsFileName . '.js';
182
        $sJsMinFilePath = $sJsDirectory . $sJsFileName . '.min.js';
183
        $sJsFileUri = rtrim($this->xConfigManager->getOption('js.app.uri'), '/') . "/$sJsFileName";
184
        if(!is_file($sJsFilePath) && !@file_put_contents($sJsFilePath, $xCodeGenerator->getJsScript()))
185
        {
186
            return '';
187
        }
188
        if(!$this->xConfigManager->getOption('js.app.minify', false))
189
        {
190
            return $sJsFileUri . '.js';
191
        }
192
        if(!is_file($sJsMinFilePath) && !$this->xMinifier->minify($sJsFilePath, $sJsMinFilePath))
193
        {
194
            // If the file cannot be minified, return the plain js file.
195
            return $sJsFileUri . '.js';
196
        }
197
        return $sJsFileUri . '.min.js';
198
    }
199
}
200