PluginProbe
Boxzilla – WordPress Popup Builder / 3.2.1
Boxzilla – WordPress Popup Builder v3.2.1
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
boxzilla / src / class-loader.php

class-loader.php in Boxzilla – WordPress Popup Builder 3.2.1, at src/class-loader.php

334 lines 7.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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_footer', array( $this, 'print_boxes_content' ) );
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 *
69 * @return boolean
70 */
71 protected function match_patterns( $string, $patterns ) {
72 $string = strtolower( $string );
73
74 foreach( $patterns as $pattern ) {
75
76 $pattern = rtrim( $pattern, '/' );
77 $pattern = strtolower( $pattern );
78
79 if( function_exists( 'fnmatch' ) ) {
80 $match = fnmatch( $pattern, $string );
81 } else {
82 $match = ( $pattern === $string );
83 }
84
85 if( $match ) {
86 return true;
87 }
88 }
89
90 return false;
91 }
92
93 /**
94 * @return string
95 */
96 protected function get_request_url() {
97 // strip trailing slashes
98 $request_uri = rtrim( $_SERVER['REQUEST_URI'], '/' );
99
100 // strip ? and query string
101 $qpos = strpos( $request_uri, '?' );
102 if( $qpos ) {
103 $request_uri = substr( $request_uri, 0, $qpos );
104 }
105
106 return $request_uri;
107 }
108
109 /**
110 * Check if this rule passes (conditional matches expected value)
111 *
112 * @param string $condition
113 * @param string $value
114 * @param boolean $qualifier
115 *
116 * @return bool
117 */
118 protected function match_rule( $condition, $value, $qualifier = true ) {
119
120 $matched = false;
121
122 // cast value to array & trim whitespace or excess comma's
123 $value = array_map( 'trim', explode( ',', rtrim( trim( $value ), ',' ) ) );
124
125 switch ( $condition ) {
126 case 'everywhere';
127 $matched = true;
128 break;
129
130 case 'is_url':
131 $matched = $this->match_patterns( $this->get_request_url(), $value );
132 break;
133
134 case 'is_referer':
135 if( ! empty( $_SERVER['HTTP_REFERER'] ) ) {
136 $referer = $_SERVER['HTTP_REFERER'];
137 $matched = $this->match_patterns( $referer, $value );
138 }
139 break;
140
141 case 'is_post_type':
142 $post_type = (string) get_post_type();
143 $matched = in_array( $post_type, (array) $value );
144 break;
145
146 case 'is_single':
147 case 'is_post':
148 // convert to empty string if array with just empty string in it
149 $value = ( $value === array( '' ) ) ? '' : $value;
150 $matched = is_single( $value );
151 break;
152
153 case 'is_post_in_category':
154 $matched = is_singular( 'post' ) && has_category( $value );
155 break;
156
157
158 case 'is_page':
159 $matched = is_page( $value );
160 break;
161
162 case 'is_post_with_tag':
163 $matched = is_singular( 'post' ) && has_tag( $value );
164 break;
165
166 case 'is_user_logged_in':
167 $matched = is_user_logged_in();
168 break;
169 }
170
171 /**
172 * Filters whether a given box rule matches the condition and expected value.
173 *
174 * The dynamic portion of the hook, `$condition`, refers to the condition being matched.
175 *
176 * @param boolean $matched
177 * @param array $value
178 */
179 $matched = apply_filters( 'boxzilla_box_rule_matches_' . $condition, $matched, $value );
180
181 // if qualifier is set to false, we need to reverse this value here.
182 if( ! $qualifier ) {
183 $matched = ! $matched;
184 }
185
186 return $matched;
187 }
188
189 /**
190 * Checks which boxes should be loaded for this request.
191 *
192 * @return array
193 */
194 private function filter_boxes() {
195
196 $box_ids_to_load = array();
197 $rules = $this->get_filter_rules();
198
199 foreach( $rules as $box_id => $box_rules ) {
200
201 $matched = false;
202 $comparision = isset( $box_rules['comparision'] ) ? $box_rules['comparision'] : 'any';
203
204 // loop through all rules for all boxes
205 foreach ( $box_rules as $rule ) {
206
207 // skip faulty values (and comparision rule)
208 if( empty( $rule['condition'] ) ) {
209 continue;
210 }
211
212 $qualifier = isset( $rule['qualifier'] ) ? $rule['qualifier'] : true;
213 $matched = $this->match_rule( $rule['condition'], $rule['value'], $qualifier );
214
215 // break out of loop if we've already matched
216 if( $comparision === 'any' && $matched ) {
217 break;
218 }
219
220 // no need to continue if this rule didn't match
221 if( $comparision === 'all' && ! $matched ) {
222 break;
223 }
224 }
225
226 // value of $matched at this point determines whether box should be loaded
227 $load_box = $matched;
228
229 /**
230 * Filters whether a box should be loaded into the page HTML.
231 *
232 * The dynamic portion of the hook, `$box_id`, refers to the ID of the box. Return true if you want to output the box.
233 *
234 * @param boolean $load_box
235 */
236 $load_box = apply_filters( 'boxzilla_load_box_' . $box_id, $load_box );
237
238 /**
239 * Filters whether a box should be loaded into the page HTML.
240 *
241 * @param boolean $load_box
242 * @param int $box_id
243 */
244 $load_box = apply_filters( 'boxzilla_load_box', $load_box, $box_id );
245
246 // if matched, box should be loaded on this page
247 if ( $load_box ) {
248 $box_ids_to_load[] = $box_id;
249 }
250
251 }
252
253 return $box_ids_to_load;
254 }
255
256 /**
257 * Load plugin styles
258 */
259 public function load_assets() {
260 $pre_suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
261 wp_enqueue_script('boxzilla', $this->plugin->url('/assets/js/script' . $pre_suffix . '.js' ), array(), $this->plugin->version(), true );
262
263 // create boxzilla_Global_Options object
264 $plugin_options = $this->options;
265 $boxes = $this->get_matched_boxes();
266
267 $data = array(
268 'testMode' => (bool) $plugin_options['test_mode'],
269 'boxes' => array_map( function(Box $box) { return $box->get_client_options(); }, $boxes ),
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
300 if( count( $this->box_ids_to_load ) === 0 ) {
301 $boxes = array();
302 return $boxes;
303 }
304
305 // query Box posts
306 $posts = get_posts(
307 array(
308 'post_type' => 'boxzilla-box',
309 'post_status' => 'publish',
310 'post__in' => $this->box_ids_to_load,
311 'numberposts' => -1
312 )
313 );
314
315 // create `Box` instances out of \WP_Post instances
316 $boxes = array();
317 foreach ( $posts as $key => $post ) {
318 // skip posts with no content
319 $post_content = trim( $post->post_content );
320 if( empty( $post_content ) ) {
321 continue;
322 }
323
324 $boxes[ $key ] = new Box( $post );
325 }
326 }
327
328 return $boxes;
329 }
330
331 }
332
333
334