This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Critical CSS settings AJAX logic. |
||
4 | */ |
||
5 | |||
6 | if ( ! defined( 'ABSPATH' ) ) { |
||
7 | exit; |
||
8 | } |
||
9 | |||
10 | class autoptimizeCriticalCSSSettingsAjax { |
||
11 | View Code Duplication | public function __construct() |
|
0 ignored issues
–
show
|
|||
12 | { |
||
13 | // fetch all options at once and populate them individually explicitely as globals. |
||
14 | $all_options = autoptimizeCriticalCSSBase::fetch_options(); |
||
0 ignored issues
–
show
Are you sure the assignment to
$all_options is correct as \autoptimizeCriticalCSSBase::fetch_options() (which targets autoptimizeCriticalCSSBase::fetch_options() ) seems to always return null.
This check looks for function or method calls that always return null and whose return value is assigned to a variable. class A
{
function getObject()
{
return null;
}
}
$a = new A();
$object = $a->getObject();
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||
15 | foreach ( $all_options as $_option => $_value ) { |
||
0 ignored issues
–
show
|
|||
16 | global ${$_option}; |
||
17 | ${$_option} = $_value; |
||
18 | } |
||
19 | $this->run(); |
||
20 | } |
||
21 | |||
22 | public function run() { |
||
23 | // add filters. |
||
24 | add_action( 'wp_ajax_fetch_critcss', array( $this, 'critcss_fetch_callback' ) ); |
||
25 | add_action( 'wp_ajax_save_critcss', array( $this, 'critcss_save_callback' ) ); |
||
26 | add_action( 'wp_ajax_rm_critcss', array( $this, 'critcss_rm_callback' ) ); |
||
27 | add_action( 'wp_ajax_rm_critcss_all', array( $this, 'critcss_rm_all_callback' ) ); |
||
28 | add_action( 'wp_ajax_ao_ccss_export', array( $this, 'ao_ccss_export_callback' ) ); |
||
29 | add_action( 'wp_ajax_ao_ccss_import', array( $this, 'ao_ccss_import_callback' ) ); |
||
30 | } |
||
31 | |||
32 | public function critcss_fetch_callback() { |
||
33 | // Ajax handler to obtain a critical CSS file from the filesystem. |
||
34 | // Check referer. |
||
35 | check_ajax_referer( 'fetch_critcss_nonce', 'critcss_fetch_nonce' ); |
||
36 | |||
37 | // Initialize error flag. |
||
38 | $error = true; |
||
39 | |||
40 | // Allow no content for MANUAL rules (as they may not exist just yet). |
||
41 | View Code Duplication | if ( current_user_can( 'manage_options' ) && empty( $_POST['critcssfile'] ) ) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
42 | $content = ''; |
||
43 | $error = false; |
||
44 | } elseif ( current_user_can( 'manage_options' ) && $this->critcss_check_filename( $_POST['critcssfile'] ) ) { |
||
45 | // Or check user permissios and filename. |
||
46 | // Set file path and obtain its content. |
||
47 | $critcssfile = AO_CCSS_DIR . strip_tags( $_POST['critcssfile'] ); |
||
48 | if ( file_exists( $critcssfile ) ) { |
||
49 | $content = file_get_contents( $critcssfile ); |
||
50 | $error = false; |
||
51 | } |
||
52 | } |
||
53 | |||
54 | // Prepare response. |
||
55 | if ( $error ) { |
||
56 | $response['code'] = '500'; |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$response was never initialized. Although not strictly required by PHP, it is generally a good practice to add $response = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
57 | $response['string'] = 'Error reading file ' . $critcssfile . '.'; |
||
0 ignored issues
–
show
The variable
$critcssfile 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
![]() |
|||
58 | } else { |
||
59 | $response['code'] = '200'; |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$response was never initialized. Although not strictly required by PHP, it is generally a good practice to add $response = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
60 | $response['string'] = $content; |
||
0 ignored issues
–
show
The variable
$content 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
![]() |
|||
61 | } |
||
62 | |||
63 | // Dispatch respose. |
||
64 | echo json_encode( $response ); |
||
65 | |||
66 | // Close ajax request. |
||
67 | wp_die(); |
||
68 | } |
||
69 | |||
70 | public function critcss_save_callback() { |
||
71 | $error = false; |
||
72 | $status = false; |
||
73 | $response = array(); |
||
74 | |||
75 | // Ajax handler to write a critical CSS to the filesystem |
||
76 | // Check referer. |
||
77 | check_ajax_referer( 'save_critcss_nonce', 'critcss_save_nonce' ); |
||
78 | |||
79 | // Allow empty contents for MANUAL rules (as they are fetched later). |
||
80 | if ( current_user_can( 'manage_options' ) && empty( $_POST['critcssfile'] ) ) { |
||
81 | $critcssfile = false; |
||
82 | $status = true; |
||
83 | } elseif ( current_user_can( 'manage_options' ) && $this->critcss_check_filename( $_POST['critcssfile'] ) ) { |
||
84 | // Or check user permissios and filename |
||
85 | // Set critical CSS content. |
||
86 | $critcsscontents = stripslashes( $_POST['critcsscontents'] ); |
||
87 | |||
88 | // If there is content and it's valid, write the file. |
||
89 | if ( $critcsscontents && autoptimizeCriticalCSSCore::ao_ccss_check_contents( $critcsscontents ) ) { |
||
90 | // Set file path and status. |
||
91 | $critcssfile = AO_CCSS_DIR . strip_tags( $_POST['critcssfile'] ); |
||
92 | $status = file_put_contents( $critcssfile, $critcsscontents, LOCK_EX ); |
||
93 | // Or set as error. |
||
94 | } else { |
||
95 | $error = true; |
||
96 | } |
||
97 | // Or just set an error. |
||
98 | } else { |
||
99 | $error = true; |
||
100 | } |
||
101 | |||
102 | // Prepare response. |
||
103 | View Code Duplication | if ( ! $status || $error ) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
104 | $response['code'] = '500'; |
||
105 | $response['string'] = 'Error saving file ' . $critcssfile . '.'; |
||
0 ignored issues
–
show
The variable
$critcssfile 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
![]() |
|||
106 | } else { |
||
107 | $response['code'] = '200'; |
||
108 | if ( $critcssfile ) { |
||
0 ignored issues
–
show
The expression
$critcssfile of type false|string is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
|||
109 | $response['string'] = 'File ' . $critcssfile . ' saved.'; |
||
110 | } else { |
||
111 | $response['string'] = 'Empty content do not need to be saved.'; |
||
112 | } |
||
113 | } |
||
114 | |||
115 | // Dispatch respose. |
||
116 | echo json_encode( $response ); |
||
117 | |||
118 | // Close ajax request. |
||
119 | wp_die(); |
||
120 | } |
||
121 | |||
122 | |||
123 | public function critcss_rm_callback() { |
||
124 | // Ajax handler to delete a critical CSS from the filesystem |
||
125 | // Check referer. |
||
126 | check_ajax_referer( 'rm_critcss_nonce', 'critcss_rm_nonce' ); |
||
127 | |||
128 | // Initialize error and status flags. |
||
129 | $error = true; |
||
130 | $status = false; |
||
131 | |||
132 | // Allow no file for MANUAL rules (as they may not exist just yet). |
||
133 | View Code Duplication | if ( current_user_can( 'manage_options' ) && empty( $_POST['critcssfile'] ) ) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
134 | $error = false; |
||
135 | } elseif ( current_user_can( 'manage_options' ) && $this->critcss_check_filename( $_POST['critcssfile'] ) ) { |
||
136 | // Or check user permissios and filename |
||
137 | // Set file path and delete it. |
||
138 | $critcssfile = AO_CCSS_DIR . strip_tags( $_POST['critcssfile'] ); |
||
139 | if ( file_exists( $critcssfile ) ) { |
||
140 | $status = unlink( $critcssfile ); |
||
141 | $error = false; |
||
142 | } |
||
143 | } |
||
144 | |||
145 | // Prepare response. |
||
146 | View Code Duplication | if ( $error ) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
147 | $response['code'] = '500'; |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$response was never initialized. Although not strictly required by PHP, it is generally a good practice to add $response = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
148 | $response['string'] = 'Error removing file ' . $critcssfile . '.'; |
||
0 ignored issues
–
show
The variable
$critcssfile 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
![]() |
|||
149 | } else { |
||
150 | $response['code'] = '200'; |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$response was never initialized. Although not strictly required by PHP, it is generally a good practice to add $response = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
151 | if ( $status ) { |
||
152 | $response['string'] = 'File ' . $critcssfile . ' removed.'; |
||
153 | } else { |
||
154 | $response['string'] = 'No file to be removed.'; |
||
155 | } |
||
156 | } |
||
157 | |||
158 | // Dispatch respose. |
||
159 | echo json_encode( $response ); |
||
160 | |||
161 | // Close ajax request. |
||
162 | wp_die(); |
||
163 | } |
||
164 | |||
165 | public function critcss_rm_all_callback() { |
||
166 | // Ajax handler to delete a critical CSS from the filesystem |
||
167 | // Check referer. |
||
168 | check_ajax_referer( 'rm_critcss_all_nonce', 'critcss_rm_all_nonce' ); |
||
169 | |||
170 | // Initialize error and status flags. |
||
171 | $error = true; |
||
172 | $status = false; |
||
173 | |||
174 | // Remove all ccss files on filesystem. |
||
175 | if ( current_user_can( 'manage_options' ) ) { |
||
176 | if ( file_exists( AO_CCSS_DIR ) && is_dir( AO_CCSS_DIR ) ) { |
||
177 | array_map( 'unlink', glob( AO_CCSS_DIR . 'ccss_*.css', GLOB_BRACE ) ); |
||
178 | $error = false; |
||
179 | $status = true; |
||
180 | } |
||
181 | } |
||
182 | |||
183 | // Prepare response. |
||
184 | if ( $error ) { |
||
185 | $response['code'] = '500'; |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$response was never initialized. Although not strictly required by PHP, it is generally a good practice to add $response = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
186 | $response['string'] = 'Error removing all critical CSS files.'; |
||
187 | } else { |
||
188 | $response['code'] = '200'; |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$response was never initialized. Although not strictly required by PHP, it is generally a good practice to add $response = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
189 | if ( $status ) { |
||
190 | $response['string'] = 'Critical CSS Files removed.'; |
||
191 | } else { |
||
192 | $response['string'] = 'No file removed.'; |
||
193 | } |
||
194 | } |
||
195 | |||
196 | // Dispatch respose. |
||
197 | echo json_encode( $response ); |
||
198 | |||
199 | // Close ajax request. |
||
200 | wp_die(); |
||
201 | } |
||
202 | |||
203 | public function ao_ccss_export_callback() { |
||
204 | // Ajax handler export settings |
||
205 | // Check referer. |
||
206 | check_ajax_referer( 'ao_ccss_export_nonce', 'ao_ccss_export_nonce' ); |
||
207 | |||
208 | if ( ! class_exists( 'ZipArchive' ) ) { |
||
209 | $response['code'] = '500'; |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$response was never initialized. Although not strictly required by PHP, it is generally a good practice to add $response = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
210 | $response['msg'] = 'PHP ZipArchive not present, cannot create zipfile'; |
||
211 | echo json_encode( $response ); |
||
212 | wp_die(); |
||
213 | } |
||
214 | |||
215 | // Init array, get options and prepare the raw object. |
||
216 | $settings = array(); |
||
217 | $settings['rules'] = get_option( 'autoptimize_ccss_rules' ); |
||
218 | $settings['additional'] = get_option( 'autoptimize_ccss_additional' ); |
||
219 | $settings['viewport'] = get_option( 'autoptimize_ccss_viewport' ); |
||
220 | $settings['finclude'] = get_option( 'autoptimize_ccss_finclude' ); |
||
221 | $settings['rtimelimit'] = get_option( 'autoptimize_ccss_rtimelimit' ); |
||
222 | $settings['noptimize'] = get_option( 'autoptimize_ccss_noptimize' ); |
||
223 | $settings['debug'] = get_option( 'autoptimize_ccss_debug' ); |
||
224 | $settings['key'] = get_option( 'autoptimize_ccss_key' ); |
||
225 | |||
226 | // Initialize error flag. |
||
227 | $error = true; |
||
228 | |||
229 | // Check user permissions. |
||
230 | if ( current_user_can( 'manage_options' ) ) { |
||
231 | // Prepare settings file path and content. |
||
232 | $exportfile = AO_CCSS_DIR . 'settings.json'; |
||
233 | $contents = json_encode( $settings ); |
||
234 | $status = file_put_contents( $exportfile, $contents, LOCK_EX ); |
||
235 | $error = false; |
||
236 | } |
||
237 | |||
238 | // Prepare archive. |
||
239 | $zipfile = AO_CCSS_DIR . date( 'Ymd-H\hi' ) . '_ao_ccss_settings.zip'; |
||
240 | $file = pathinfo( $zipfile, PATHINFO_BASENAME ); |
||
241 | $zip = new ZipArchive(); |
||
242 | $ret = $zip->open( $zipfile, ZipArchive::CREATE ); |
||
243 | if ( true !== $ret ) { |
||
244 | $error = true; |
||
245 | } else { |
||
246 | $zip->addFile( AO_CCSS_DIR . 'settings.json', 'settings.json' ); |
||
247 | if ( file_exists( AO_CCSS_DIR . 'queue.json' ) ) { |
||
248 | $zip->addFile( AO_CCSS_DIR . 'queue.json', 'queue.json' ); |
||
249 | } |
||
250 | $options = array( |
||
251 | 'add_path' => './', |
||
252 | 'remove_all_path' => true, |
||
253 | ); |
||
254 | $zip->addGlob( AO_CCSS_DIR . '*.css', 0, $options ); |
||
255 | $zip->close(); |
||
256 | } |
||
257 | |||
258 | // Prepare response. |
||
259 | View Code Duplication | if ( ! $status || $error ) { |
|
0 ignored issues
–
show
The variable
$status 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
![]() This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
260 | $response['code'] = '500'; |
||
0 ignored issues
–
show
The variable
$response 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
![]() |
|||
261 | $response['msg'] = 'Error saving file ' . $file . ', code: ' . $ret; |
||
262 | } else { |
||
263 | $response['code'] = '200'; |
||
264 | $response['msg'] = 'File ' . $file . ' saved.'; |
||
265 | $response['file'] = $file; |
||
266 | } |
||
267 | |||
268 | // Dispatch respose. |
||
269 | echo json_encode( $response ); |
||
270 | |||
271 | // Close ajax request. |
||
272 | wp_die(); |
||
273 | } |
||
274 | |||
275 | public function ao_ccss_import_callback() { |
||
276 | // Ajax handler import settings |
||
277 | // Check referer. |
||
278 | check_ajax_referer( 'ao_ccss_import_nonce', 'ao_ccss_import_nonce' ); |
||
279 | |||
280 | // Initialize error flag. |
||
281 | $error = false; |
||
282 | |||
283 | // Process an uploaded file with no errors. |
||
284 | if ( current_user_can( 'manage_options' ) && ! $_FILES['file']['error'] && $_FILES['file']['size'] < 500001 && strpos( $_FILES['file']['name'], '.zip' ) === strlen( $_FILES['file']['name'] ) - 4 ) { |
||
285 | // create tmp dir with hard guess name in AO_CCSS_DIR. |
||
286 | $_secret_dir = wp_hash( uniqid( md5( AUTOPTIMIZE_CACHE_URL ), true ) ); |
||
287 | $_import_tmp_dir = trailingslashit( AO_CCSS_DIR . $_secret_dir ); |
||
288 | mkdir( $_import_tmp_dir ); |
||
289 | |||
290 | // Save file to that tmp directory but give it our own name to prevent directory traversal risks when using original name. |
||
291 | $zipfile = $_import_tmp_dir . uniqid( 'import_settings-', true ) . '.zip'; |
||
292 | move_uploaded_file( $_FILES['file']['tmp_name'], $zipfile ); |
||
293 | |||
294 | // Extract archive in the tmp directory. |
||
295 | $zip = new ZipArchive; |
||
296 | if ( $zip->open( $zipfile ) === true ) { |
||
297 | // loop through all files in the zipfile. |
||
298 | for ($i = 0; $i < $zip->numFiles; $i++) { |
||
299 | // but only extract known good files. |
||
300 | if ( preg_match('/^settings\.json$|^ccss_[a-z0-9]{32}\.css$/', $zip->getNameIndex( $i ) ) > 0 ) { |
||
301 | $zip->extractTo( AO_CCSS_DIR, $zip->getNameIndex( $i ) ); |
||
302 | } |
||
303 | } |
||
304 | $zip->close(); |
||
305 | } else { |
||
306 | $error = 'could not extract'; |
||
307 | } |
||
308 | |||
309 | // and remove temp. dir with all contents (the import-zipfile). |
||
310 | $this->rrmdir( $_import_tmp_dir ); |
||
311 | |||
312 | if ( ! $error ) { |
||
0 ignored issues
–
show
The expression
$error of type false|string is loosely compared to false ; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
|||
313 | // Archive extraction ok, continue importing settings from AO_CCSS_DIR. |
||
314 | // Settings file. |
||
315 | $importfile = AO_CCSS_DIR . 'settings.json'; |
||
316 | |||
317 | if ( file_exists( $importfile ) ) { |
||
318 | // Get settings and turn them into an object. |
||
319 | $settings = json_decode( file_get_contents( $importfile ), true ); |
||
320 | |||
321 | // Update options. |
||
322 | update_option( 'autoptimize_ccss_rules', $settings['rules'] ); |
||
323 | update_option( 'autoptimize_ccss_additional', $settings['additional'] ); |
||
324 | update_option( 'autoptimize_ccss_viewport', $settings['viewport'] ); |
||
325 | update_option( 'autoptimize_ccss_finclude', $settings['finclude'] ); |
||
326 | update_option( 'autoptimize_ccss_rtimelimit', $settings['rtimelimit'] ); |
||
327 | update_option( 'autoptimize_ccss_noptimize', $settings['noptimize'] ); |
||
328 | update_option( 'autoptimize_ccss_debug', $settings['debug'] ); |
||
329 | update_option( 'autoptimize_ccss_key', $settings['key'] ); |
||
330 | } else { |
||
331 | // Settings file doesn't exist, update error flag. |
||
332 | $error = 'settings file does not exist'; |
||
333 | } |
||
334 | } |
||
335 | } else { |
||
336 | $error = 'file could not be saved'; |
||
337 | } |
||
338 | |||
339 | // Prepare response. |
||
340 | if ( $error ) { |
||
0 ignored issues
–
show
The expression
$error of type false|string is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
|||
341 | $response['code'] = '500'; |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$response was never initialized. Although not strictly required by PHP, it is generally a good practice to add $response = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
342 | $response['msg'] = 'Error importing settings: ' . $error; |
||
343 | } else { |
||
344 | $response['code'] = '200'; |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$response was never initialized. Although not strictly required by PHP, it is generally a good practice to add $response = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
|||
345 | $response['msg'] = 'Settings imported successfully'; |
||
346 | } |
||
347 | |||
348 | // Dispatch respose. |
||
349 | echo json_encode( $response ); |
||
350 | |||
351 | // Close ajax request. |
||
352 | wp_die(); |
||
353 | } |
||
354 | |||
355 | public function critcss_check_filename( $filename ) { |
||
356 | // Try to avoid directory traversal when reading/writing/deleting critical CSS files. |
||
357 | if ( strpos( $filename, 'ccss_' ) !== 0 ) { |
||
358 | return false; |
||
359 | } elseif ( substr( $filename, -4, 4 ) !== '.css' ) { |
||
360 | return false; |
||
361 | } elseif ( sanitize_file_name( $filename ) !== $filename ) { |
||
362 | // Use WordPress core's sanitize_file_name to see if anything fishy is going on. |
||
363 | return false; |
||
364 | } else { |
||
365 | return true; |
||
366 | } |
||
367 | } |
||
368 | |||
369 | public function rrmdir( $path ) { |
||
370 | // recursively remove a directory as found on |
||
371 | // https://andy-carter.com/blog/recursively-remove-a-directory-in-php. |
||
372 | $files = glob($path . '/*'); |
||
373 | foreach ( $files as $file ) { |
||
374 | is_dir( $file ) ? $this->rrmdir( $file ) : unlink( $file ); |
||
375 | } |
||
376 | rmdir( $path ); |
||
377 | |||
378 | return; |
||
379 | } |
||
380 | } |
||
381 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.