PluginProbe
Statify / 1.6.3
Statify v1.6.3
2.0.2 2.0.1 trunk 0.7 0.8 0.9 1.0 1.2.8 1.3.0 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.7.0 1.7.1 1.7.2 All 32 releases
statify / inc / class-statify-frontend.php

class-statify-frontend.php in Statify 1.6.3, at inc/class-statify-frontend.php

322 lines 7.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Statify: Statify_Frontend class
4 *
5 * This file contains the derived class for the plugin's frontend features.
6 *
7 * @package Statify
8 * @since 1.4.0
9 */
10
11 // Quit if accessed outside WP context.
12 defined( 'ABSPATH' ) || exit;
13
14 /**
15 * Statify_Frontend
16 *
17 * @since 1.4.0
18 */
19 class Statify_Frontend extends Statify {
20
21 /**
22 * Track the page view
23 *
24 * @since 0.1.0
25 * @version 1.4.2
26 *
27 * @return bool
28 */
29 public static function track_visit() {
30
31 /* Init vars */
32 $use_snippet = self::$_options['snippet'];
33 $is_snippet = $use_snippet && get_query_var( 'statify_target' );
34
35 /* Set target & referrer */
36 if ( $is_snippet ) {
37 $target = urldecode( get_query_var( 'statify_target' ) );
38 $referrer = urldecode( get_query_var( 'statify_referrer' ) );
39 } elseif ( ! $use_snippet ) {
40 $target = filter_var(
41 ( isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '/' ),
42 FILTER_SANITIZE_URL
43 );
44 if ( is_null( $target ) || false === $target ) {
45 $target = '/';
46 } else {
47 $target = wp_unslash( $target );
48 }
49
50 $referrer = filter_var(
51 ( isset( $_SERVER['HTTP_REFERER'] ) ? wp_unslash( $_SERVER['HTTP_REFERER'] ) : '' ),
52 FILTER_SANITIZE_URL
53 );
54 if ( is_null( $referrer ) || false === $referrer ) {
55 $referrer = '';
56 }
57 } else {
58 return false;
59 }
60
61 /* Invalid target? */
62 if ( empty( $target ) || ! wp_validate_redirect( $target, false ) ) {
63 return self::_jump_out( $is_snippet );
64 }
65
66 /* Check whether tracking should be skipped for this view. */
67 if ( self::_skip_tracking() ) {
68 return self::_jump_out( $is_snippet );
69 }
70
71 /* Global vars */
72 global $wpdb, $wp_rewrite;
73
74 /* Init rows */
75 $data = array(
76 'created' => '',
77 'referrer' => '',
78 'target' => '',
79 );
80
81 // Set request timestamp.
82 $data['created'] = strftime( '%Y-%m-%d', current_time( 'timestamp' ) );
83
84 $needles = array( home_url(), network_admin_url() );
85
86 // Sanitize referrer url.
87 if ( ! empty( $referrer ) && self::strposa( $referrer, $needles ) === false ) {
88 $data['referrer'] = esc_url_raw( $referrer, array( 'http', 'https' ) );
89 }
90
91 /* Relative target url */
92 $data['target'] = user_trailingslashit( str_replace( home_url( '/', 'relative' ), '/', $target ) );
93
94 // Trim target url.
95 if ( $wp_rewrite->permalink_structure ) {
96 $data['target'] = wp_parse_url( $data['target'], PHP_URL_PATH );
97 }
98
99 // Sanitize target url.
100 $data['target'] = esc_url_raw( $data['target'] );
101
102 // Insert.
103 $wpdb->insert( $wpdb->statify, $data );
104
105 /**
106 * Fires after a visit was stored in the database
107 *
108 * @since 1.5.5
109 *
110 * @param array $data
111 * @param int $wpdb->insert_id
112 */
113 do_action( 'statify__visit_saved', $data, $wpdb->insert_id );
114
115 // Jump!
116 return self::_jump_out( $is_snippet );
117 }
118
119 /**
120 * Find the position of the first occurrence of a substring in a string about a array.
121 *
122 * @param string $haystack The string to search in.
123 * @param array $needle The string to search for.
124 * @param int $offset Search will start this number of characters counted from the beginning of the string.
125 *
126 * @return bool
127 */
128 private static function strposa( $haystack, array $needle, $offset = 0 ) {
129
130 foreach ( $needle as $query ) {
131 if ( strpos( $haystack, $query, $offset ) !== false ) {
132 return true;
133 } // Stop on first true result.
134 }
135
136 return false;
137 }
138
139 /**
140 * Rules to skip the tracking
141 *
142 * @since 1.2.6
143 * @version 1.6.3
144 *
145 * @hook boolean statify__skip_tracking
146 * @see https://wordpress.org/plugins/statify/
147 *
148 * @return boolean $skip_hook TRUE if NO tracking is desired
149 */
150 private static function _skip_tracking() {
151
152 if ( function_exists( 'apply_filters_deprecated' ) ) {
153 apply_filters_deprecated( 'statify_skip_tracking', array( '' ), '1.5.0', 'statify__skip_tracking' );
154 }
155 // Skip tracking via Hook.
156 $skip_hook = apply_filters( 'statify__skip_tracking', null );
157 if ( null !== $skip_hook ) {
158 return $skip_hook;
159 }
160
161 // Skip tracking via User Agent.
162 $user_agent = filter_var(
163 ( isset( $_SERVER['HTTP_USER_AGENT'] ) ? wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) : '' ),
164 FILTER_SANITIZE_STRING
165 );
166 if ( is_null( $user_agent )
167 || false === $user_agent
168 || ! preg_match( '/(?:Windows|Macintosh|Linux|iPhone|iPad)/', $user_agent ) ) {
169 return true;
170 }
171
172 // Skip tracking via Referrer check and Conditional_Tags.
173 return ( self::check_referrer() || is_trackback() || is_robots() || is_user_logged_in()
174 || self::_is_internal()
175 );
176 }
177
178 /**
179 * Rules to detect internal calls to skip tracking and not print code snippet.
180 *
181 * @since 1.6.1
182 *
183 * @return boolean $skip_hook TRUE if NO tracking is desired
184 */
185 private static function _is_internal() {
186 return is_feed() || is_preview() || is_404() || is_search();
187 }
188
189 /**
190 * Compare the referrer url to the blacklist data.
191 * De/activate this feature via settings in the Dashboard widget.
192 *
193 * @since 1.5.0
194 * @version 1.6.3
195 *
196 * @return boolean TRUE of referrer matches blacklist entry and should thus be excluded.
197 */
198 private static function check_referrer() {
199
200 // Return false if the blacklist filter is inactive.
201 if ( ! self::$_options['blacklist'] ) {
202 return false;
203 }
204
205 $referrer = filter_var(
206 ( isset( $_SERVER['HTTP_REFERER'] ) ? wp_unslash( $_SERVER['HTTP_REFERER'] ) : '' ),
207 FILTER_SANITIZE_URL
208 );
209 if ( ! is_null( $referrer ) && false !== $referrer ) {
210 $referrer = wp_parse_url( $referrer, PHP_URL_HOST );
211 }
212
213 // Fallback for wp_parse_url() returning array instead of host only.
214 if ( is_array( $referrer ) && isset( $referrer['host'] ) ) {
215 $referrer = $referrer['host'];
216 }
217
218 // Return false if there still is no referrer to checj.
219 if ( ! is_string( $referrer ) ) {
220 return false;
221 }
222
223 // Finally compare referrer against the blacklist.
224 $blacklist = self::get_blacklist_keys();
225 foreach ( $blacklist as $item ) {
226 if ( strpos( $referrer, $item ) !== false ) {
227 return true;
228 }
229 }
230
231 return false;
232 }
233
234 /**
235 * Get a array from the blacklist option of 'Settings' - 'Discussion' - 'Comment Blacklist'.
236 *
237 * @since 2016-12-21
238 *
239 * @return array
240 */
241 private static function get_blacklist_keys() {
242
243 $blacklist = trim( get_option( 'blacklist_keys' ) );
244
245 if ( empty( $blacklist ) ) {
246 return array();
247 }
248
249 return (array) explode( "\n", $blacklist );
250 }
251
252 /**
253 * Send JavaScript headers or return false
254 *
255 * @since 1.1.0
256 * @version 1.3.1
257 *
258 * @param boolean $is_snippet Snippet type.
259 *
260 * @return mixed Exit or return depending on snippet type.
261 */
262 private static function _jump_out( $is_snippet ) {
263
264 if ( $is_snippet ) {
265 nocache_headers();
266 header( 'Content-type: text/javascript', true, 204 );
267 exit;
268 }
269
270 return false;
271 }
272
273
274 /**
275 * Declare GET variables for further use
276 *
277 * @since 1.1.0
278 * @version 1.3.1
279 *
280 * @param array $vars Input with existing variables.
281 *
282 * @return array $vars Output with plugin variables
283 */
284 public static function query_vars( $vars ) {
285
286 $vars[] = 'statify_referrer';
287 $vars[] = 'statify_target';
288
289 return $vars;
290 }
291
292
293 /**
294 * Print JavaScript snippet
295 *
296 * @since 1.1.0
297 * @version 1.4.1
298 */
299 public static function wp_footer() {
300
301 /* Skip by option */
302 if ( ! self::$_options['snippet'] ) {
303 return;
304 }
305
306 /* Skip by internal rules (#84) */
307 if ( self::_is_internal() ) {
308 return;
309 }
310
311 /* Load template */
312 load_template(
313 wp_normalize_path(
314 sprintf(
315 '%s/views/js-snippet.php',
316 STATIFY_DIR
317 )
318 )
319 );
320 }
321 }
322