| @@ -1,8 +1,12 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | 3 | namespace Boxzilla; |
| 4 | 4 | |
| 5 | +if (! defined('ABSPATH')) { | |
| 6 | + exit; | |
| 7 | +} | |
| 8 | + | |
| 5 | 9 | class BoxLoader |
| 6 | 10 | { |
| 7 | 11 | /** |
| 8 | 12 | * @var Plugin |
| @@ -38,9 +42,9 @@ | ||
| 38 | 42 | { |
| 39 | 43 | $this->box_ids_to_load = $this->filter_boxes(); |
| 40 | 44 | |
| 41 | 45 | // Only add other hooks if necessary |
| 42 | - add_action('wp_head', [$this, 'print_preload_js']); | |
| 46 | + add_action('wp_head', [$this, 'print_preload_js'], 10, 0); | |
| 43 | 47 | if (count($this->box_ids_to_load) > 0) { |
| 44 | 48 | add_action('wp_footer', [ $this, 'print_boxes_content' ], 1); |
| 45 | 49 | add_action('wp_enqueue_scripts', [ $this, 'load_assets' ], 90); |
| 46 | 50 | } |
| @@ -49,12 +53,12 @@ | ||
| 49 | 53 | /** |
| 50 | 54 | * Prints the preload API so that the Boxzilla JS API can be used before Boxzilla itself is loaded |
| 51 | 55 | * This allows us to defer the Boxzilla script itself. |
| 52 | 56 | */ |
| 53 | - public function print_preload_js() | |
| 57 | + public function print_preload_js(): void | |
| 54 | 58 | { |
| 55 | 59 | echo '<script>'; |
| 56 | - echo file_get_contents(BOXZILLA_DIR . '/assets/js/preload.js'); | |
| 60 | + include BOXZILLA_DIR . '/assets/js/preload.js'; | |
| 57 | 61 | echo '</script>'; |
| 58 | 62 | } |
| 59 | 63 | |
| 60 | 64 | /** |
| @@ -61,9 +65,9 @@ | ||
| 61 | 65 | * Get global rules for all boxes |
| 62 | 66 | * |
| 63 | 67 | * @return array |
| 64 | 68 | */ |
| 65 | - protected function get_filter_rules() | |
| 69 | + protected function get_filter_rules(): array | |
| 66 | 70 | { |
| 67 | 71 | $rules = get_option('boxzilla_rules', []); |
| 68 | 72 | return is_array($rules) ? $rules : []; |
| 69 | 73 | } |
| @@ -73,10 +77,10 @@ | ||
| 73 | 77 | * Match a string against an array of patterns, glob-style. |
| 74 | 78 | * |
| 75 | 79 | * @param string $string |
| 76 | 80 | * @param array $patterns |
| 77 | - * @param boolean $contains | |
| 78 | - * @return boolean | |
| 81 | + * @param bool $contains | |
| 82 | + * @return bool | |
| 79 | 83 | */ |
| 80 | 84 | protected function match_patterns($string, array $patterns, $contains = false) |
| 81 | 85 | { |
| 82 | 86 | $string = strtolower($string); |
| @@ -107,9 +111,9 @@ | ||
| 107 | 111 | * @return string |
| 108 | 112 | */ |
| 109 | 113 | protected function get_request_url() |
| 110 | 114 | { |
| 111 | - return rtrim($_SERVER['REQUEST_URI'], '/'); | |
| 115 | + return rtrim(wp_unslash($_SERVER['REQUEST_URI'] ?? ''), '/'); | |
| 112 | 116 | } |
| 113 | 117 | |
| 114 | 118 | /** |
| 115 | 119 | * Check if this rule passes (conditional matches expected value) |
| @@ -138,9 +142,9 @@ | ||
| 138 | 142 | break; |
| 139 | 143 | |
| 140 | 144 | case 'is_referer': |
| 141 | 145 | if (! empty($_SERVER['HTTP_REFERER'])) { |
| 142 | - $referer = $_SERVER['HTTP_REFERER']; | |
| 146 | + $referer = wp_unslash($_SERVER['HTTP_REFERER']); | |
| 143 | 147 | $matched = $this->match_patterns($referer, $values, $qualifier === 'contains' || $qualifier === 'not_contains'); |
| 144 | 148 | } |
| 145 | 149 | break; |
| 146 | 150 | |
| @@ -207,9 +211,9 @@ | ||
| 207 | 211 | |
| 208 | 212 | // loop through all rules for all boxes |
| 209 | 213 | foreach ($box_rules as $rule) { |
| 210 | 214 | // skip faulty values (and comparision rule) |
| 211 | - if (empty($rule['condition'])) { | |
| 215 | + if (! is_array($rule) || empty($rule['condition'])) { | |
| 212 | 216 | continue; |
| 213 | 217 | } |
| 214 | 218 | |
| 215 | 219 | $qualifier = isset($rule['qualifier']) ? $rule['qualifier'] : true; |
| @@ -267,9 +271,8 @@ | ||
| 267 | 271 | { |
| 268 | 272 | wp_enqueue_style('boxzilla', $this->plugin->url('/assets/css/styles.css'), [], $this->plugin->version()); |
| 269 | 273 | wp_enqueue_script('boxzilla', $this->plugin->url('/assets/js/script.js'), [], $this->plugin->version(), [ |
| 270 | 274 | 'strategy' => 'defer', |
| 271 | - 'in_footer' => true, | |
| 272 | 275 | ]); |
| 273 | 276 | |
| 274 | 277 | // create boxzilla_Global_Options object |
| 275 | 278 | $plugin_options = $this->options; |
| @@ -283,11 +286,9 @@ | ||
| 283 | 286 | }, |
| 284 | 287 | $boxes |
| 285 | 288 | ), |
| 286 | 289 | ]; |
| 287 | - | |
| 288 | - wp_localize_script('boxzilla', 'boxzilla_options', $data); | |
| 289 | - | |
| 290 | + wp_add_inline_script('boxzilla', 'var boxzilla_options = ' . wp_json_encode($data) . ';', 'before'); | |
| 290 | 291 | do_action('boxzilla_load_assets', $this); |
| 291 | 292 | } |
| 292 | 293 | |
| 293 | 294 | public function print_boxes_content() |
| @@ -298,9 +299,9 @@ | ||
| 298 | 299 | } |
| 299 | 300 | |
| 300 | 301 | echo '<div style="display: none;">'; |
| 301 | 302 | foreach ($boxes as $box) { |
| 302 | - echo "<div id=\"boxzilla-box-{$box->ID}-content\">", $box->get_content(), "</div>"; | |
| 303 | + printf('<div id="boxzilla-box-%d-content">%s</div>', absint($box->ID), $box->get_content()); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | |
| 303 | 304 | } |
| 304 | 305 | echo '</div>'; |
| 305 | 306 | } |
| 306 | 307 | |
| @@ -312,9 +313,9 @@ | ||
| 312 | 313 | public function get_matched_boxes() |
| 313 | 314 | { |
| 314 | 315 | static $boxes; |
| 315 | 316 | |
| 316 | - if (is_null($boxes)) { | |
| 317 | + if ($boxes === null) { | |
| 317 | 318 | if (count($this->box_ids_to_load) === 0) { |
| 318 | 319 | return []; |
| 319 | 320 | } |
| 320 | 321 | |