PluginProbe
Boxzilla – WordPress Popup Builder / 3.2.21
Boxzilla – WordPress Popup Builder v3.2.21
3.4.11 3.4.10 3.4.9 3.4.3 3.4.4 3.4.5 3.4.6 3.4.7 3.4.8 trunk 3.0 3.0.1 3.0.2 3.0.3 3.1 3.1.1 3.1.10 3.1.11 3.1.12 3.1.13 3.1.14 3.1.15 3.1.16 3.1.17 3.1.18 All 72 releases
← All changes | src/class-loader.php +333 -316 3.1.133.2.21 View file →
@@ -1,316 +1,333 @@
1 -<?php
2 -
3 -namespace Boxzilla;
4 -
5 -class BoxLoader {
6 -
7 - /**
8 - * @var Plugin
9 - */
10 - private $plugin;
11 -
12 - /**
13 - * @var array
14 - */
15 - private $box_ids_to_load = array();
16 -
17 - /**
18 - * @var array
19 - */
20 - protected $options;
21 -
22 - /**
23 - * Constructor
24 - *
25 - * @param Plugin $plugin
26 - * @param array $options
27 - */
28 - public function __construct( Plugin $plugin, array $options ) {
29 - $this->plugin = $plugin;
30 - $this->options = $options;
31 - }
32 -
33 - /**
34 - * Initializes the plugin, runs on `wp` hook.
35 - */
36 - public function init() {
37 -
38 - $this->box_ids_to_load = $this->filter_boxes();
39 -
40 - // Only add other hooks if necessary
41 - if( count( $this->box_ids_to_load ) > 0 ) {
42 - add_action( 'wp_enqueue_scripts', array( $this, 'load_assets' ), 90 );
43 - }
44 - }
45 -
46 - /**
47 - * Get global rules for all boxes
48 - *
49 - * @return array
50 - */
51 - protected function get_filter_rules() {
52 - $rules = get_option( 'boxzilla_rules', array() );
53 -
54 - if( ! is_array( $rules ) ) {
55 - return array();
56 - }
57 -
58 - return $rules;
59 - }
60 -
61 -
62 - /**
63 - * Match a string against an array of patterns, glob-style.
64 - *
65 - * @param string $string
66 - * @param array $patterns
67 - *
68 - * @return boolean
69 - */
70 - protected function match_patterns( $string, $patterns ) {
71 - $string = strtolower( $string );
72 -
73 - foreach( $patterns as $pattern ) {
74 -
75 - $pattern = rtrim( $pattern, '/' );
76 - $pattern = strtolower( $pattern );
77 -
78 - if( function_exists( 'fnmatch' ) ) {
79 - $match = fnmatch( $pattern, $string );
80 - } else {
81 - $match = ( $pattern === $string );
82 - }
83 -
84 - if( $match ) {
85 - return true;
86 - }
87 - }
88 -
89 - return false;
90 - }
91 -
92 - /**
93 - * @return string
94 - */
95 - protected function get_request_url() {
96 - // strip trailing slashes
97 - $request_uri = rtrim( $_SERVER['REQUEST_URI'], '/' );
98 -
99 - // strip ? and query string
100 - $qpos = strpos( $request_uri, '?' );
101 - if( $qpos ) {
102 - $request_uri = substr( $request_uri, 0, $qpos );
103 - }
104 -
105 - return $request_uri;
106 - }
107 -
108 - /**
109 - * Check if this rule passes (conditional matches expected value)
110 - *
111 - * @param string $condition
112 - * @param string $value
113 - * @param boolean $qualifier
114 - *
115 - * @return bool
116 - */
117 - protected function match_rule( $condition, $value, $qualifier = true ) {
118 -
119 - $matched = false;
120 -
121 - // cast value to array & trim whitespace or excess comma's
122 - $value = array_map( 'trim', explode( ',', rtrim( trim( $value ), ',' ) ) );
123 -
124 - switch ( $condition ) {
125 - case 'everywhere';
126 - $matched = true;
127 - break;
128 -
129 - case 'is_url':
130 - $matched = $this->match_patterns( $this->get_request_url(), $value );
131 - break;
132 -
133 - case 'is_referer':
134 - if( ! empty( $_SERVER['HTTP_REFERER'] ) ) {
135 - $referer = $_SERVER['HTTP_REFERER'];
136 - $matched = $this->match_patterns( $referer, $value );
137 - }
138 - break;
139 -
140 - case 'is_post_type':
141 - $post_type = (string) get_post_type();
142 - $matched = in_array( $post_type, (array) $value );
143 - break;
144 -
145 - case 'is_single':
146 - case 'is_post':
147 - // convert to empty string if array with just empty string in it
148 - $value = ( $value === array( '' ) ) ? '' : $value;
149 - $matched = is_single( $value );
150 - break;
151 -
152 - case 'is_post_in_category':
153 - $matched = is_singular( 'post' ) && has_category( $value );
154 - break;
155 -
156 -
157 - case 'is_page':
158 - $matched = is_page( $value );
159 - break;
160 -
161 - case 'is_post_with_tag':
162 - $matched = is_singular( 'post' ) && has_tag( $value );
163 - break;
164 - }
165 -
166 - /**
167 - * Filters whether a given box rule matches the condition and expected value.
168 - *
169 - * The dynamic portion of the hook, `$condition`, refers to the condition being matched.
170 - *
171 - * @param boolean $matched
172 - * @param array $value
173 - */
174 - $matched = apply_filters( 'boxzilla_box_rule_matches_' . $condition, $matched, $value );
175 -
176 - // if qualifier is set to false, we need to reverse this value here.
177 - if( ! $qualifier ) {
178 - $matched = ! $matched;
179 - }
180 -
181 - return $matched;
182 - }
183 -
184 - /**
185 - * Checks which boxes should be loaded for this request.
186 - *
187 - * @return array
188 - */
189 - private function filter_boxes() {
190 -
191 - $box_ids_to_load = array();
192 - $rules = $this->get_filter_rules();
193 -
194 - foreach( $rules as $box_id => $box_rules ) {
195 -
196 - $matched = false;
197 - $comparision = isset( $box_rules['comparision'] ) ? $box_rules['comparision'] : 'any';
198 -
199 - // loop through all rules for all boxes
200 - foreach ( $box_rules as $rule ) {
201 -
202 - // skip faulty values (and comparision rule)
203 - if( empty( $rule['condition'] ) ) {
204 - continue;
205 - }
206 -
207 - $qualifier = isset( $rule['qualifier'] ) ? $rule['qualifier'] : true;
208 - $matched = $this->match_rule( $rule['condition'], $rule['value'], $qualifier );
209 -
210 - // break out of loop if we've already matched
211 - if( $comparision === 'any' && $matched ) {
212 - break;
213 - }
214 -
215 - // no need to continue if this rule didn't match
216 - if( $comparision === 'all' && ! $matched ) {
217 - break;
218 - }
219 - }
220 -
221 - // value of $matched at this point determines whether box should be loaded
222 - $load_box = $matched;
223 -
224 - /**
225 - * Filters whether a box should be loaded into the page HTML.
226 - *
227 - * The dynamic portion of the hook, `$box_id`, refers to the ID of the box. Return true if you want to output the box.
228 - *
229 - * @param boolean $load_box
230 - */
231 - $load_box = apply_filters( 'boxzilla_load_box_' . $box_id, $load_box );
232 -
233 - /**
234 - * Filters whether a box should be loaded into the page HTML.
235 - *
236 - * @param boolean $load_box
237 - * @param int $box_id
238 - */
239 - $load_box = apply_filters( 'boxzilla_load_box', $load_box, $box_id );
240 -
241 - // if matched, box should be loaded on this page
242 - if ( $load_box ) {
243 - $box_ids_to_load[] = $box_id;
244 - }
245 -
246 - }
247 -
248 - return $box_ids_to_load;
249 - }
250 -
251 - /**
252 - * Load plugin styles
253 - */
254 - public function load_assets() {
255 - $pre_suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
256 - wp_enqueue_script('boxzilla', $this->plugin->url('/assets/js/script' . $pre_suffix . '.js' ), array(), $this->plugin->version(), true );
257 -
258 - $this->pass_box_options();
259 -
260 - do_action( 'boxzilla_load_assets', $this );
261 - }
262 -
263 - /**
264 - * Get an array of Box objects. These are the boxes that will be loaded for the current request.
265 - *
266 - * @return Box[]
267 - */
268 - public function get_matched_boxes() {
269 - static $boxes;
270 -
271 - if( is_null( $boxes ) ) {
272 -
273 - if( count( $this->box_ids_to_load ) === 0 ) {
274 - $boxes = array();
275 - return $boxes;
276 - }
277 -
278 - // query Box posts
279 - $boxes = get_posts(
280 - array(
281 - 'post_type' => 'boxzilla-box',
282 - 'post_status' => 'publish',
283 - 'post__in' => $this->box_ids_to_load,
284 - 'numberposts' => -1
285 - )
286 - );
287 -
288 - // create `Box` instances out of \WP_Post instances
289 - foreach ( $boxes as $key => $box ) {
290 - $boxes[ $key ] = new Box( $box );
291 - }
292 - }
293 -
294 - return $boxes;
295 - }
296 -
297 - /**
298 - * Create array of Box options and pass it to JavaScript script.
299 - */
300 - public function pass_box_options() {
301 -
302 - // create boxzilla_Global_Options object
303 - $plugin_options = $this->options;
304 - $boxes = $this->get_matched_boxes();
305 -
306 - $data = array(
307 - 'testMode' => (bool) $plugin_options['test_mode'],
308 - 'boxes' => array_map( function(Box $box) { return $box->get_client_options(); }, $boxes ),
309 - );
310 -
311 - wp_localize_script( 'boxzilla', 'boxzilla_options', $data );
312 - }
313 -
314 -}
315 -
316 -
1 +<?php
2 +
3 +namespace Boxzilla;
4 +
5 +class BoxLoader {
6 +
7 +
8 + /**
9 + * @var Plugin
10 + */
11 + private $plugin;
12 +
13 + /**
14 + * @var array
15 + */
16 + private $box_ids_to_load = array();
17 +
18 + /**
19 + * @var array
20 + */
21 + protected $options;
22 +
23 + /**
24 + * Constructor
25 + *
26 + * @param Plugin $plugin
27 + * @param array $options
28 + */
29 + public function __construct( Plugin $plugin, array $options ) {
30 + $this->plugin = $plugin;
31 + $this->options = $options;
32 + }
33 +
34 + /**
35 + * Initializes the plugin, runs on `wp` hook.
36 + */
37 + public function init() {
38 + $this->box_ids_to_load = $this->filter_boxes();
39 +
40 + // Only add other hooks if necessary
41 + if ( count( $this->box_ids_to_load ) > 0 ) {
42 + add_action( 'wp_footer', array( $this, 'print_boxes_content' ), 1 );
43 + add_action( 'wp_enqueue_scripts', array( $this, 'load_assets' ), 90 );
44 + }
45 + }
46 +
47 + /**
48 + * Get global rules for all boxes
49 + *
50 + * @return array
51 + */
52 + protected function get_filter_rules() {
53 + $rules = get_option( 'boxzilla_rules', array() );
54 +
55 + if ( ! is_array( $rules ) ) {
56 + return array();
57 + }
58 +
59 + return $rules;
60 + }
61 +
62 +
63 + /**
64 + * Match a string against an array of patterns, glob-style.
65 + *
66 + * @param string $string
67 + * @param array $patterns
68 + * @param boolean $contains
69 + * @return boolean
70 + */
71 + protected function match_patterns( $string, array $patterns, $contains = false ) {
72 + $string = strtolower( $string );
73 +
74 + foreach ( $patterns as $pattern ) {
75 + $pattern = rtrim( $pattern, '/' );
76 + $pattern = strtolower( $pattern );
77 +
78 + if ( $contains ) {
79 + // contains means we should do a simple occurrence check
80 + // does not support wildcards
81 + $match = strpos( $string, $pattern ) !== false;
82 + } else if ( function_exists( 'fnmatch' ) ) {
83 + $match = fnmatch( $pattern, $string );
84 + } else {
85 + $match = ( $pattern === $string );
86 + }
87 +
88 + if ( $match ) {
89 + return true;
90 + }
91 + }
92 +
93 + return false;
94 + }
95 +
96 + /**
97 + * @return string
98 + */
99 + protected function get_request_url() {
100 + return rtrim( $_SERVER['REQUEST_URI'], '/' );
101 + }
102 +
103 + /**
104 + * Check if this rule passes (conditional matches expected value)
105 + *
106 + * @param string $condition
107 + * @param string $value
108 + * @param boolean $qualifier
109 + *
110 + * @return bool
111 + */
112 + protected function match_rule( $condition, $value, $qualifier = true ) {
113 + $matched = false;
114 +
115 + // cast value to array & trim whitespace or excess comma's
116 + $values = array_map( 'trim', explode( ',', rtrim( trim( $value ), ',' ) ) );
117 +
118 + switch ( $condition ) {
119 + case 'everywhere':
120 + $matched = true;
121 + break;
122 +
123 + case 'is_url':
124 + $url = $this->get_request_url();
125 + $matched = $this->match_patterns( $url, $values, $qualifier === 'contains' || $qualifier === 'not_contains' );
126 + break;
127 +
128 + case 'is_referer':
129 + if ( ! empty( $_SERVER['HTTP_REFERER'] ) ) {
130 + $referer = $_SERVER['HTTP_REFERER'];
131 + $matched = $this->match_patterns( $referer, $values, $qualifier === 'contains' || $qualifier === 'not_contains' );
132 + }
133 + break;
134 +
135 + case 'is_post_type':
136 + $post_type = (string) get_post_type();
137 + $matched = in_array( $post_type, $values, true );
138 + break;
139 +
140 + case 'is_single':
141 + case 'is_post':
142 + // convert to empty string if array with just empty string in it
143 + $value = ( $values === array( '' ) ) ? '' : $values;
144 + $matched = is_single( $value );
145 + break;
146 +
147 + case 'is_post_in_category':
148 + $matched = is_singular() && has_category( $values );
149 + break;
150 +
151 + case 'is_page':
152 + $matched = is_page( $values );
153 + break;
154 +
155 + case 'is_post_with_tag':
156 + $matched = is_singular() && has_tag( $values );
157 + break;
158 +
159 + case 'is_user_logged_in':
160 + $matched = is_user_logged_in();
161 + break;
162 + }
163 +
164 + /**
165 + * Filters whether a given box rule matches the condition and expected value.
166 + *
167 + * The dynamic portion of the hook, `$condition`, refers to the condition being matched.
168 + *
169 + * @param boolean $matched
170 + * @param array $values
171 + */
172 + $matched = apply_filters( 'boxzilla_box_rule_matches_' . $condition, $matched, $values );
173 +
174 + // if qualifier is set to false, we need to reverse this value here.
175 + if ( ! $qualifier || $qualifier === 'not_contains' ) {
176 + $matched = ! $matched;
177 + }
178 +
179 + return $matched;
180 + }
181 +
182 + /**
183 + * Checks which boxes should be loaded for this request.
184 + *
185 + * @return array
186 + */
187 + private function filter_boxes() {
188 + $box_ids_to_load = array();
189 + $rules = $this->get_filter_rules();
190 +
191 + foreach ( $rules as $box_id => $box_rules ) {
192 + $matched = false;
193 + $comparision = isset( $box_rules['comparision'] ) ? $box_rules['comparision'] : 'any';
194 +
195 + // loop through all rules for all boxes
196 + foreach ( $box_rules as $rule ) {
197 +
198 + // skip faulty values (and comparision rule)
199 + if ( empty( $rule['condition'] ) ) {
200 + continue;
201 + }
202 +
203 + $qualifier = isset( $rule['qualifier'] ) ? $rule['qualifier'] : true;
204 + $matched = $this->match_rule( $rule['condition'], $rule['value'], $qualifier );
205 +
206 + // break out of loop if we've already matched
207 + if ( $comparision === 'any' && $matched ) {
208 + break;
209 + }
210 +
211 + // no need to continue if this rule didn't match
212 + if ( $comparision === 'all' && ! $matched ) {
213 + break;
214 + }
215 + }
216 +
217 + // value of $matched at this point determines whether box should be loaded
218 + $load_box = $matched;
219 +
220 + /**
221 + * Filters whether a box should be loaded into the page HTML.
222 + *
223 + * The dynamic portion of the hook, `$box_id`, refers to the ID of the box. Return true if you want to output the box.
224 + *
225 + * @param boolean $load_box
226 + */
227 + $load_box = apply_filters( 'boxzilla_load_box_' . $box_id, $load_box );
228 +
229 + /**
230 + * Filters whether a box should be loaded into the page HTML.
231 + *
232 + * @param boolean $load_box
233 + * @param int $box_id
234 + */
235 + $load_box = apply_filters( 'boxzilla_load_box', $load_box, $box_id );
236 +
237 + // if matched, box should be loaded on this page
238 + if ( $load_box ) {
239 + $box_ids_to_load[] = $box_id;
240 + }
241 + }
242 +
243 + /**
244 + * Filters which boxes should be loaded on this page, expects an array of post ID's.
245 + *
246 + * @param array $box_ids_to_load
247 + */
248 + return apply_filters( 'boxzilla_load_boxes', $box_ids_to_load );
249 + }
250 +
251 + /**
252 + * Load plugin styles
253 + */
254 + public function load_assets() {
255 + $pre_suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
256 + wp_enqueue_script( 'boxzilla', $this->plugin->url( '/assets/js/script' . $pre_suffix . '.js' ), array(), $this->plugin->version(), true );
257 +
258 + // create boxzilla_Global_Options object
259 + $plugin_options = $this->options;
260 + $boxes = $this->get_matched_boxes();
261 +
262 + $data = array(
263 + 'testMode' => (bool) $plugin_options['test_mode'],
264 + 'boxes' => (array) array_map(
265 + function ( Box $box ) {
266 + return $box->get_client_options();
267 + },
268 + $boxes
269 + ),
270 + );
271 +
272 + wp_localize_script( 'boxzilla', 'boxzilla_options', $data );
273 +
274 + do_action( 'boxzilla_load_assets', $this );
275 + }
276 +
277 + public function print_boxes_content() {
278 + $boxes = $this->get_matched_boxes();
279 + if ( empty( $boxes ) ) {
280 + return;
281 + }
282 +
283 + echo '<div style="display: none;">';
284 + foreach ( $boxes as $box ) {
285 + echo sprintf( '<div id="boxzilla-box-%d-content">', $box->ID ) . $box->get_content() . '</div>';
286 + }
287 + echo '</div>';
288 + }
289 +
290 + /**
291 + * Get an array of Box objects. These are the boxes that will be loaded for the current request.
292 + *
293 + * @return Box[]
294 + */
295 + public function get_matched_boxes() {
296 + static $boxes;
297 +
298 + if ( is_null( $boxes ) ) {
299 + if ( count( $this->box_ids_to_load ) === 0 ) {
300 + $boxes = array();
301 + return $boxes;
302 + }
303 +
304 + // query Box posts
305 + $q = new \WP_Query();
306 + $posts = $q->query(
307 + array(
308 + 'post_type' => 'boxzilla-box',
309 + 'post_status' => 'publish',
310 + 'post__in' => $this->box_ids_to_load,
311 + 'posts_per_page' => count( $this->box_ids_to_load ),
312 + 'ignore_sticky_posts' => true,
313 + 'no_found_rows' => true,
314 + )
315 + );
316 +
317 + // create `Box` instances out of \WP_Post instances
318 + $boxes = array();
319 + foreach ( $posts as $key => $post ) {
320 + $box = new Box( $post );
321 +
322 + // skip boxes without any content
323 + if ( $box->get_content() === '' ) {
324 + continue;
325 + }
326 +
327 + $boxes[ $key ] = $box;
328 + }
329 + }
330 +
331 + return $boxes;
332 + }
333 +}