PluginProbe
Boxzilla – WordPress Popup Builder / 3.3.0
Boxzilla – WordPress Popup Builder v3.3.0
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.3.0, at src/class-loader.php

329 lines 7.9 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 /**
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 return is_array($rules) ? $rules : array();
55 }
56
57
58 /**
59 * Match a string against an array of patterns, glob-style.
60 *
61 * @param string $string
62 * @param array $patterns
63 * @param boolean $contains
64 * @return boolean
65 */
66 protected function match_patterns( $string, array $patterns, $contains = false ) {
67 $string = strtolower( $string );
68
69 foreach ( $patterns as $pattern ) {
70 $pattern = rtrim( $pattern, '/' );
71 $pattern = strtolower( $pattern );
72
73 if ( $contains ) {
74 // contains means we should do a simple occurrence check
75 // does not support wildcards
76 $match = strpos( $string, $pattern ) !== false;
77 } elseif ( function_exists( 'fnmatch' ) ) {
78 $match = fnmatch( $pattern, $string );
79 } else {
80 $match = ( $pattern === $string );
81 }
82
83 if ( $match ) {
84 return true;
85 }
86 }
87
88 return false;
89 }
90
91 /**
92 * @return string
93 */
94 protected function get_request_url() {
95 return rtrim( $_SERVER['REQUEST_URI'], '/' );
96 }
97
98 /**
99 * Check if this rule passes (conditional matches expected value)
100 *
101 * @param string $condition
102 * @param string $value
103 * @param boolean $qualifier
104 *
105 * @return bool
106 */
107 protected function match_rule( $condition, $value, $qualifier = true ) {
108 $matched = false;
109
110 // cast value to array & trim whitespace or excess comma's
111 $values = array_map( 'trim', explode( ',', rtrim( trim( $value ), ',' ) ) );
112
113 switch ( $condition ) {
114 case 'everywhere':
115 $matched = true;
116 break;
117
118 case 'is_url':
119 $url = $this->get_request_url();
120 $matched = $this->match_patterns( $url, $values, $qualifier === 'contains' || $qualifier === 'not_contains' );
121 break;
122
123 case 'is_referer':
124 if ( ! empty( $_SERVER['HTTP_REFERER'] ) ) {
125 $referer = $_SERVER['HTTP_REFERER'];
126 $matched = $this->match_patterns( $referer, $values, $qualifier === 'contains' || $qualifier === 'not_contains' );
127 }
128 break;
129
130 case 'is_post_type':
131 $post_type = (string) get_post_type();
132 $matched = in_array( $post_type, $values, true );
133 break;
134
135 case 'is_single':
136 case 'is_post':
137 // convert to empty string if array with just empty string in it
138 $value = ( $values === array( '' ) ) ? '' : $values;
139 $matched = is_single( $value );
140 break;
141
142 case 'is_post_in_category':
143 $matched = is_singular() && has_category( $values );
144 break;
145
146 case 'is_page':
147 $matched = is_page( $values );
148 break;
149
150 case 'is_post_with_tag':
151 $matched = is_singular() && has_tag( $values );
152 break;
153
154 case 'is_user_logged_in':
155 $matched = is_user_logged_in();
156 break;
157 }
158
159 /**
160 * Filters whether a given box rule matches the condition and expected value.
161 *
162 * The dynamic portion of the hook, `$condition`, refers to the condition being matched.
163 *
164 * @param boolean $matched
165 * @param array $values
166 */
167 $matched = apply_filters( 'boxzilla_box_rule_matches_' . $condition, $matched, $values );
168
169 // if qualifier is set to false, we need to reverse this value here.
170 if ( ! $qualifier || $qualifier === 'not_contains' ) {
171 $matched = ! $matched;
172 }
173
174 return $matched;
175 }
176
177 /**
178 * Checks which boxes should be loaded for this request.
179 *
180 * @return array
181 */
182 private function filter_boxes() {
183 $box_ids_to_load = array();
184 $rules = $this->get_filter_rules();
185
186 foreach ( $rules as $box_id => $box_rules ) {
187 $matched = false;
188 $comparision = isset( $box_rules['comparision'] ) ? $box_rules['comparision'] : 'any';
189
190 // loop through all rules for all boxes
191 foreach ( $box_rules as $rule ) {
192
193 // skip faulty values (and comparision rule)
194 if ( empty( $rule['condition'] ) ) {
195 continue;
196 }
197
198 $qualifier = isset( $rule['qualifier'] ) ? $rule['qualifier'] : true;
199 $matched = $this->match_rule( $rule['condition'], $rule['value'], $qualifier );
200
201 // break out of loop if we've already matched
202 if ( $comparision === 'any' && $matched ) {
203 break;
204 }
205
206 // no need to continue if this rule didn't match
207 if ( $comparision === 'all' && ! $matched ) {
208 break;
209 }
210 }
211
212 // value of $matched at this point determines whether box should be loaded
213 $load_box = $matched;
214
215 /**
216 * Filters whether a box should be loaded into the page HTML.
217 *
218 * The dynamic portion of the hook, `$box_id`, refers to the ID of the box. Return true if you want to output the box.
219 *
220 * @param boolean $load_box
221 */
222 $load_box = apply_filters( 'boxzilla_load_box_' . $box_id, $load_box );
223
224 /**
225 * Filters whether a box should be loaded into the page HTML.
226 *
227 * @param boolean $load_box
228 * @param int $box_id
229 */
230 $load_box = apply_filters( 'boxzilla_load_box', $load_box, $box_id );
231
232 // if matched, box should be loaded on this page
233 if ( $load_box ) {
234 $box_ids_to_load[] = $box_id;
235 }
236 }
237
238 /**
239 * Filters which boxes should be loaded on this page, expects an array of post ID's.
240 *
241 * @param array $box_ids_to_load
242 */
243 return apply_filters( 'boxzilla_load_boxes', $box_ids_to_load );
244 }
245
246 /**
247 * Load plugin styles
248 */
249 public function load_assets() {
250 wp_enqueue_style( 'boxzilla', $this->plugin->url( '/assets/css/styles.css' ), array(), $this->plugin->version() );
251 wp_enqueue_script( 'boxzilla', $this->plugin->url( '/assets/js/script.js' ), array(), $this->plugin->version(), true );
252
253 // create boxzilla_Global_Options object
254 $plugin_options = $this->options;
255 $boxes = $this->get_matched_boxes();
256
257 $data = array(
258 'testMode' => (bool) $plugin_options['test_mode'],
259 'boxes' => (array) array_map(
260 function ( Box $box ) {
261 return $box->get_client_options();
262 },
263 $boxes
264 ),
265 );
266
267 wp_localize_script( 'boxzilla', 'boxzilla_options', $data );
268
269 do_action( 'boxzilla_load_assets', $this );
270 }
271
272 public function print_boxes_content() {
273 $boxes = $this->get_matched_boxes();
274 if ( empty( $boxes ) ) {
275 return;
276 }
277
278 echo '<div style="display: none;">';
279 foreach ( $boxes as $box ) {
280 echo sprintf( '<div id="boxzilla-box-%d-content">', $box->ID ) . $box->get_content() . '</div>';
281 }
282 echo '</div>';
283 }
284
285 /**
286 * Get an array of Box objects. These are the boxes that will be loaded for the current request.
287 *
288 * @return Box[]
289 */
290 public function get_matched_boxes() {
291 static $boxes;
292
293 if ( is_null( $boxes ) ) {
294 if ( count( $this->box_ids_to_load ) === 0 ) {
295 $boxes = array();
296 return $boxes;
297 }
298
299 // query Box posts
300 $q = new \WP_Query();
301 $posts = $q->query(
302 array(
303 'post_type' => 'boxzilla-box',
304 'post_status' => 'publish',
305 'post__in' => $this->box_ids_to_load,
306 'posts_per_page' => count( $this->box_ids_to_load ),
307 'ignore_sticky_posts' => true,
308 'no_found_rows' => true,
309 )
310 );
311
312 // create `Box` instances out of \WP_Post instances
313 $boxes = array();
314 foreach ( $posts as $key => $post ) {
315 $box = new Box( $post );
316
317 // skip boxes without any content
318 if ( $box->get_content() === '' ) {
319 continue;
320 }
321
322 $boxes[ $key ] = $box;
323 }
324 }
325
326 return $boxes;
327 }
328 }
329