Version Description
- New: Multisite compatibility
- Fix: Undefined index post_views_column on post_views_counter/includes/settings.php
- Tweak: Improved user IP handling
Download this release
Release Info
Developer | dfactory |
Plugin | Post Views Counter |
Version | 1.2.8 |
Comparing to | |
See all releases |
Code changes from version 1.2.7 to 1.2.8
- includes/counter.php +54 -8
- includes/functions.php +51 -26
- includes/settings.php +3 -3
- js/admin-dashboard.js +83 -83
- js/admin-post.js +32 -32
- js/admin-quick-edit.js +54 -54
- js/admin-settings.js +101 -101
- js/frontend.js +39 -39
- post-views-counter.php +77 -10
- readme.txt +12 -6
includes/counter.php
CHANGED
@@ -42,22 +42,27 @@ class Post_Views_Counter_Counter {
|
|
42 |
// get user id, from current user or static var in rest api request
|
43 |
$user_id = get_current_user_id();
|
44 |
|
|
|
|
|
|
|
45 |
// empty id?
|
46 |
if ( empty( $id ) )
|
47 |
return;
|
|
|
|
|
48 |
|
49 |
// get ips
|
50 |
$ips = Post_Views_Counter()->options['general']['exclude_ips'];
|
51 |
|
52 |
// whether to count this ip
|
53 |
-
if ( ! empty( $ips ) && filter_var( preg_replace( '/[^0-9a-fA-F:., ]/', '', $
|
54 |
// check ips
|
55 |
foreach ( $ips as $ip ) {
|
56 |
if ( strpos( $ip, '*' ) !== false ) {
|
57 |
-
if ( $this->ipv4_in_range( $
|
58 |
return;
|
59 |
} else {
|
60 |
-
if ( $
|
61 |
return;
|
62 |
}
|
63 |
}
|
@@ -192,11 +197,14 @@ class Post_Views_Counter_Counter {
|
|
192 |
if ( is_admin() && ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) )
|
193 |
return;
|
194 |
|
|
|
|
|
|
|
195 |
// is cookie set?
|
196 |
-
if ( isset( $_COOKIE[
|
197 |
$visited_posts = $expirations = array();
|
198 |
|
199 |
-
foreach ( $_COOKIE[
|
200 |
// is cookie valid?
|
201 |
if ( preg_match( '/^(([0-9]+b[0-9]+a?)+)$/', $content ) === 1 ) {
|
202 |
// get single id with expiration
|
@@ -229,10 +237,13 @@ class Post_Views_Counter_Counter {
|
|
229 |
private function save_cookie( $id, $cookie = array(), $expired = true ) {
|
230 |
$expiration = $this->get_timestamp( Post_Views_Counter()->options['general']['time_between_counts']['type'], Post_Views_Counter()->options['general']['time_between_counts']['number'] );
|
231 |
|
|
|
|
|
|
|
232 |
// is this a new cookie?
|
233 |
if ( empty( $cookie ) ) {
|
234 |
// set cookie
|
235 |
-
setcookie( '
|
236 |
} else {
|
237 |
if ( $expired ) {
|
238 |
// add new id or chang expiration date if id already exists
|
@@ -294,7 +305,7 @@ class Post_Views_Counter_Counter {
|
|
294 |
|
295 |
foreach ( $cookies as $key => $value ) {
|
296 |
// set cookie
|
297 |
-
setcookie( '
|
298 |
}
|
299 |
}
|
300 |
}
|
@@ -539,7 +550,7 @@ class Post_Views_Counter_Counter {
|
|
539 |
* @param string $range IP range
|
540 |
* @return boolean Whether IP is in range
|
541 |
*/
|
542 |
-
function ipv4_in_range( $ip, $range ) {
|
543 |
$start = str_replace( '*', '0', $range );
|
544 |
$end = str_replace( '*', '255', $range );
|
545 |
$ip = (float) sprintf( "%u", ip2long( $ip ) );
|
@@ -547,6 +558,41 @@ class Post_Views_Counter_Counter {
|
|
547 |
return ( $ip >= (float) sprintf( "%u", ip2long( $start ) ) && $ip <= (float) sprintf( "%u", ip2long( $end ) ) );
|
548 |
}
|
549 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
550 |
/**
|
551 |
* Register REST API endpoints.
|
552 |
*
|
42 |
// get user id, from current user or static var in rest api request
|
43 |
$user_id = get_current_user_id();
|
44 |
|
45 |
+
// get user IP address
|
46 |
+
$user_ip = $this->get_user_ip();
|
47 |
+
|
48 |
// empty id?
|
49 |
if ( empty( $id ) )
|
50 |
return;
|
51 |
+
|
52 |
+
do_action( 'pvc_before_check_visit', $id, $user_id, $user_ip );
|
53 |
|
54 |
// get ips
|
55 |
$ips = Post_Views_Counter()->options['general']['exclude_ips'];
|
56 |
|
57 |
// whether to count this ip
|
58 |
+
if ( ! empty( $ips ) && filter_var( preg_replace( '/[^0-9a-fA-F:., ]/', '', $user_ip ), FILTER_VALIDATE_IP ) ) {
|
59 |
// check ips
|
60 |
foreach ( $ips as $ip ) {
|
61 |
if ( strpos( $ip, '*' ) !== false ) {
|
62 |
+
if ( $this->ipv4_in_range( $user_ip, $ip ) )
|
63 |
return;
|
64 |
} else {
|
65 |
+
if ( $user_ip === $ip )
|
66 |
return;
|
67 |
}
|
68 |
}
|
197 |
if ( is_admin() && ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) )
|
198 |
return;
|
199 |
|
200 |
+
// assign cookie name
|
201 |
+
$cookie_name = 'pvc_visits' . ( is_multisite() ? '_' . get_current_blog_id() : '' );
|
202 |
+
|
203 |
// is cookie set?
|
204 |
+
if ( isset( $_COOKIE[$cookie_name] ) && ! empty( $_COOKIE[$cookie_name] ) ) {
|
205 |
$visited_posts = $expirations = array();
|
206 |
|
207 |
+
foreach ( $_COOKIE[$cookie_name] as $content ) {
|
208 |
// is cookie valid?
|
209 |
if ( preg_match( '/^(([0-9]+b[0-9]+a?)+)$/', $content ) === 1 ) {
|
210 |
// get single id with expiration
|
237 |
private function save_cookie( $id, $cookie = array(), $expired = true ) {
|
238 |
$expiration = $this->get_timestamp( Post_Views_Counter()->options['general']['time_between_counts']['type'], Post_Views_Counter()->options['general']['time_between_counts']['number'] );
|
239 |
|
240 |
+
// assign cookie name
|
241 |
+
$cookie_name = 'pvc_visits' . ( is_multisite() ? '_' . get_current_blog_id() : '' );
|
242 |
+
|
243 |
// is this a new cookie?
|
244 |
if ( empty( $cookie ) ) {
|
245 |
// set cookie
|
246 |
+
setcookie( $cookie_name . '[0]', $expiration . 'b' . $id, $expiration, COOKIEPATH, COOKIE_DOMAIN, (isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] !== 'off' ? true : false ), true );
|
247 |
} else {
|
248 |
if ( $expired ) {
|
249 |
// add new id or chang expiration date if id already exists
|
305 |
|
306 |
foreach ( $cookies as $key => $value ) {
|
307 |
// set cookie
|
308 |
+
setcookie( $cookie_name . '[' . $key . ']', $value, $cookie['expiration'], COOKIEPATH, COOKIE_DOMAIN, (isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] !== 'off' ? true : false ), true );
|
309 |
}
|
310 |
}
|
311 |
}
|
550 |
* @param string $range IP range
|
551 |
* @return boolean Whether IP is in range
|
552 |
*/
|
553 |
+
public function ipv4_in_range( $ip, $range ) {
|
554 |
$start = str_replace( '*', '0', $range );
|
555 |
$end = str_replace( '*', '255', $range );
|
556 |
$ip = (float) sprintf( "%u", ip2long( $ip ) );
|
558 |
return ( $ip >= (float) sprintf( "%u", ip2long( $start ) ) && $ip <= (float) sprintf( "%u", ip2long( $end ) ) );
|
559 |
}
|
560 |
|
561 |
+
/**
|
562 |
+
* Get user real IP address.
|
563 |
+
*
|
564 |
+
* @return string
|
565 |
+
*/
|
566 |
+
public function get_user_ip() {
|
567 |
+
$ip_keys = array( 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR' );
|
568 |
+
foreach ( $ip_keys as $key ) {
|
569 |
+
if ( array_key_exists( $key, $_SERVER ) === true ) {
|
570 |
+
foreach ( explode( ',', $_SERVER[$key] ) as $ip ) {
|
571 |
+
// trim for safety measures
|
572 |
+
$ip = trim( $ip );
|
573 |
+
// attempt to validate IP
|
574 |
+
if ( $this->validate_user_ip( $ip ) ) {
|
575 |
+
return $ip;
|
576 |
+
}
|
577 |
+
}
|
578 |
+
}
|
579 |
+
}
|
580 |
+
return isset( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : '';
|
581 |
+
}
|
582 |
+
|
583 |
+
/**
|
584 |
+
* Ensure an ip address is both a valid IP and does not fall within a private network range.
|
585 |
+
*
|
586 |
+
* @param $ip
|
587 |
+
* @return bool
|
588 |
+
*/
|
589 |
+
public function validate_user_ip( $ip ) {
|
590 |
+
if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) === false ) {
|
591 |
+
return false;
|
592 |
+
}
|
593 |
+
return true;
|
594 |
+
}
|
595 |
+
|
596 |
/**
|
597 |
* Register REST API endpoints.
|
598 |
*
|
includes/functions.php
CHANGED
@@ -67,7 +67,8 @@ if ( ! function_exists( 'pvc_get_views' ) ) {
|
|
67 |
$range = array();
|
68 |
$defaults = array(
|
69 |
'fields' => 'views',
|
70 |
-
'
|
|
|
71 |
'views_query' => array(
|
72 |
'year' => '',
|
73 |
'month' => '',
|
@@ -78,9 +79,25 @@ if ( ! function_exists( 'pvc_get_views' ) ) {
|
|
78 |
|
79 |
$args = apply_filters( 'pvc_get_views_args', array_merge( $defaults, $args ) );
|
80 |
|
81 |
-
// check post
|
82 |
-
if ( empty( $args['post_type'] ) )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
$args['post_type'] = $defaults['post_type'];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
|
85 |
// check fields
|
86 |
if ( ! in_array( $args['fields'], array( 'views', 'date=>views' ), true ) )
|
@@ -106,6 +123,8 @@ if ( ! function_exists( 'pvc_get_views' ) ) {
|
|
106 |
if ( ! empty( $args['views_query']['day'] ) )
|
107 |
$day = str_pad( (int) $args['views_query']['day'], 2, 0, STR_PAD_LEFT );
|
108 |
|
|
|
|
|
109 |
// year
|
110 |
if ( isset( $year ) ) {
|
111 |
// year, week
|
@@ -132,9 +151,9 @@ if ( ! function_exists( 'pvc_get_views' ) ) {
|
|
132 |
// get month of sunday
|
133 |
$sunday_month = $date->format( 'm' );
|
134 |
|
135 |
-
$
|
136 |
} else
|
137 |
-
$
|
138 |
// year, month
|
139 |
} elseif ( isset( $month ) ) {
|
140 |
// year, month, day
|
@@ -143,7 +162,7 @@ if ( ! function_exists( 'pvc_get_views' ) ) {
|
|
143 |
// prepare range
|
144 |
$range[(string) ( $year . $month . $day )] = 0;
|
145 |
|
146 |
-
$
|
147 |
// year, month
|
148 |
} else {
|
149 |
if ( $args['fields'] === 'date=>views' ) {
|
@@ -158,9 +177,9 @@ if ( ! function_exists( 'pvc_get_views' ) ) {
|
|
158 |
$range[(string) ( $year . $month . str_pad( $i, 2, 0, STR_PAD_LEFT ) )] = 0;
|
159 |
}
|
160 |
|
161 |
-
$
|
162 |
} else
|
163 |
-
$
|
164 |
}
|
165 |
// year
|
166 |
} else {
|
@@ -173,34 +192,34 @@ if ( ! function_exists( 'pvc_get_views' ) ) {
|
|
173 |
// create date
|
174 |
$date = new DateTime( $year . '-12-01' );
|
175 |
|
176 |
-
$
|
177 |
} else
|
178 |
-
$
|
179 |
}
|
180 |
// month
|
181 |
} elseif ( isset( $month ) ) {
|
182 |
// month, day
|
183 |
if ( isset( $day ) ) {
|
184 |
-
$
|
185 |
// month
|
186 |
} else {
|
187 |
-
$
|
188 |
}
|
189 |
// week
|
190 |
} elseif ( isset( $week ) ) {
|
191 |
-
$
|
192 |
// day
|
193 |
} elseif ( isset( $day ) ) {
|
194 |
-
$
|
195 |
}
|
196 |
|
197 |
global $wpdb;
|
198 |
|
199 |
$query = "SELECT " . ( $args['fields'] === 'date=>views' ? 'pvc.period, ' : '' ) . "SUM( IFNULL( pvc.count, 0 ) ) AS post_views
|
200 |
FROM " . $wpdb->prefix . "posts wpp
|
201 |
-
LEFT JOIN " . $wpdb->prefix . "post_views pvc ON pvc.id = wpp.ID
|
202 |
-
WHERE wpp.post_type
|
203 |
-
GROUP BY pvc.period
|
204 |
HAVING post_views > 0";
|
205 |
|
206 |
// get cached data
|
@@ -218,13 +237,12 @@ if ( ! function_exists( 'pvc_get_views' ) ) {
|
|
218 |
}
|
219 |
|
220 |
$post_views = $range;
|
221 |
-
} else
|
222 |
$post_views = (int) $wpdb->get_var( $query );
|
223 |
-
}
|
224 |
|
225 |
// set the cache expiration, 5 minutes by default
|
226 |
$expire = absint( apply_filters( 'pvc_object_cache_expire', 5 * 60 ) );
|
227 |
-
|
228 |
wp_cache_add( md5( $query ), $post_views, 'pvc-get_views', $expire );
|
229 |
}
|
230 |
|
@@ -325,7 +343,9 @@ if ( ! function_exists( 'pvc_most_viewed_posts' ) ) {
|
|
325 |
'show_post_views' => true,
|
326 |
'show_post_thumbnail' => false,
|
327 |
'show_post_excerpt' => false,
|
328 |
-
'no_posts_message' => __( 'No Posts', 'post-views-counter' )
|
|
|
|
|
329 |
);
|
330 |
|
331 |
$args = apply_filters( 'pvc_most_viewed_posts_args', wp_parse_args( $args, $defaults ) );
|
@@ -351,16 +371,18 @@ if ( ! function_exists( 'pvc_most_viewed_posts' ) ) {
|
|
351 |
|
352 |
$html .= '
|
353 |
<li>';
|
|
|
|
|
354 |
|
355 |
if ( $args['show_post_thumbnail'] && has_post_thumbnail( $post->ID ) ) {
|
356 |
$html .= '
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
}
|
361 |
|
362 |
$html .= '
|
363 |
-
|
364 |
|
365 |
$excerpt = '';
|
366 |
|
@@ -376,7 +398,10 @@ if ( ! function_exists( 'pvc_most_viewed_posts' ) ) {
|
|
376 |
|
377 |
if ( ! empty( $excerpt ) )
|
378 |
$html .= '
|
379 |
-
|
|
|
|
|
|
|
380 |
|
381 |
$html .= '
|
382 |
</li>';
|
67 |
$range = array();
|
68 |
$defaults = array(
|
69 |
'fields' => 'views',
|
70 |
+
'post_id' => '',
|
71 |
+
'post_type' => '',
|
72 |
'views_query' => array(
|
73 |
'year' => '',
|
74 |
'month' => '',
|
79 |
|
80 |
$args = apply_filters( 'pvc_get_views_args', array_merge( $defaults, $args ) );
|
81 |
|
82 |
+
// check post types
|
83 |
+
if ( is_array( $args['post_type'] ) && ! empty( $args['post_type'] ) ) {
|
84 |
+
$post_types = array();
|
85 |
+
|
86 |
+
foreach( $args['post_type'] as $post_type ) {
|
87 |
+
$post_types[] = "'" . $post_type . "'";
|
88 |
+
}
|
89 |
+
|
90 |
+
$args['post_type'] = implode( ', ', $post_types );
|
91 |
+
} elseif ( ! is_string( $args['post_type'] ) )
|
92 |
$args['post_type'] = $defaults['post_type'];
|
93 |
+
else
|
94 |
+
$args['post_type'] = "'" . $args['post_type'] . "'";
|
95 |
+
|
96 |
+
// check post ids
|
97 |
+
if ( is_array( $args['post_id'] ) && ! empty( $args['post_id'] ) )
|
98 |
+
$args['post_id'] = implode( ', ', array_unique( array_map( 'intval', $args['post_id'] ) ) );
|
99 |
+
else
|
100 |
+
$args['post_id'] = (int) $args['post_id'];
|
101 |
|
102 |
// check fields
|
103 |
if ( ! in_array( $args['fields'], array( 'views', 'date=>views' ), true ) )
|
123 |
if ( ! empty( $args['views_query']['day'] ) )
|
124 |
$day = str_pad( (int) $args['views_query']['day'], 2, 0, STR_PAD_LEFT );
|
125 |
|
126 |
+
$views_query = '';
|
127 |
+
|
128 |
// year
|
129 |
if ( isset( $year ) ) {
|
130 |
// year, week
|
151 |
// get month of sunday
|
152 |
$sunday_month = $date->format( 'm' );
|
153 |
|
154 |
+
$views_query = " AND pvc.type = 0 AND pvc.period >= '" . $year . $monday_month . $monday . "' AND pvc.period <= '" . $date->format( 'Y' ) . $sunday_month . $date->format( 'd' ) . "'";
|
155 |
} else
|
156 |
+
$views_query = " AND pvc.type = 1 AND pvc.period = '" . $year . $week . "'";
|
157 |
// year, month
|
158 |
} elseif ( isset( $month ) ) {
|
159 |
// year, month, day
|
162 |
// prepare range
|
163 |
$range[(string) ( $year . $month . $day )] = 0;
|
164 |
|
165 |
+
$views_query = " AND pvc.type = 0 AND pvc.period = '" . $year . $month . $day . "'";
|
166 |
// year, month
|
167 |
} else {
|
168 |
if ( $args['fields'] === 'date=>views' ) {
|
177 |
$range[(string) ( $year . $month . str_pad( $i, 2, 0, STR_PAD_LEFT ) )] = 0;
|
178 |
}
|
179 |
|
180 |
+
$views_query = " AND pvc.type = 0 AND pvc.period >= '" . $year . $month . "01' AND pvc.period <= '" . $year . $month . $last . "'";
|
181 |
} else
|
182 |
+
$views_query = " AND pvc.type = 2 AND pvc.period = '" . $year . $month . "'";
|
183 |
}
|
184 |
// year
|
185 |
} else {
|
192 |
// create date
|
193 |
$date = new DateTime( $year . '-12-01' );
|
194 |
|
195 |
+
$views_query = " AND pvc.type = 2 AND pvc.period >= '" . $year . "01' AND pvc.period <= '" . $year . "12'";
|
196 |
} else
|
197 |
+
$views_query = " AND pvc.type = 3 AND pvc.period = '" . $year . "'";
|
198 |
}
|
199 |
// month
|
200 |
} elseif ( isset( $month ) ) {
|
201 |
// month, day
|
202 |
if ( isset( $day ) ) {
|
203 |
+
$views_query = " AND pvc.type = 0 AND RIGHT( pvc.period, 4 ) = '" . $month . $day . "'";
|
204 |
// month
|
205 |
} else {
|
206 |
+
$views_query = " AND pvc.type = 2 AND RIGHT( pvc.period, 2 ) = '" . $month . "'";
|
207 |
}
|
208 |
// week
|
209 |
} elseif ( isset( $week ) ) {
|
210 |
+
$views_query = " AND pvc.type = 1 AND RIGHT( pvc.period, 2 ) = '" . $week . "'";
|
211 |
// day
|
212 |
} elseif ( isset( $day ) ) {
|
213 |
+
$views_query = " AND pvc.type = 0 AND RIGHT( pvc.period, 2 ) = '" . $day . "'";
|
214 |
}
|
215 |
|
216 |
global $wpdb;
|
217 |
|
218 |
$query = "SELECT " . ( $args['fields'] === 'date=>views' ? 'pvc.period, ' : '' ) . "SUM( IFNULL( pvc.count, 0 ) ) AS post_views
|
219 |
FROM " . $wpdb->prefix . "posts wpp
|
220 |
+
LEFT JOIN " . $wpdb->prefix . "post_views pvc ON pvc.id = wpp.ID" . ( $views_query !== '' ? ' ' . $views_query : ' AND pvc.type = 4' ) . ( ! empty( $args['post_id'] ) ? ' AND pvc.id IN (' . $args['post_id'] . ')' : '' ) . "
|
221 |
+
" . ( $args['post_type'] !== '' ? "WHERE wpp.post_type IN (" . $args['post_type'] . ")" : '' ) . "
|
222 |
+
" . ( $views_query !== '' ? 'GROUP BY pvc.period' : '' ) . "
|
223 |
HAVING post_views > 0";
|
224 |
|
225 |
// get cached data
|
237 |
}
|
238 |
|
239 |
$post_views = $range;
|
240 |
+
} else
|
241 |
$post_views = (int) $wpdb->get_var( $query );
|
|
|
242 |
|
243 |
// set the cache expiration, 5 minutes by default
|
244 |
$expire = absint( apply_filters( 'pvc_object_cache_expire', 5 * 60 ) );
|
245 |
+
|
246 |
wp_cache_add( md5( $query ), $post_views, 'pvc-get_views', $expire );
|
247 |
}
|
248 |
|
343 |
'show_post_views' => true,
|
344 |
'show_post_thumbnail' => false,
|
345 |
'show_post_excerpt' => false,
|
346 |
+
'no_posts_message' => __( 'No Posts', 'post-views-counter' ),
|
347 |
+
'item_before' => '',
|
348 |
+
'item_after' => ''
|
349 |
);
|
350 |
|
351 |
$args = apply_filters( 'pvc_most_viewed_posts_args', wp_parse_args( $args, $defaults ) );
|
371 |
|
372 |
$html .= '
|
373 |
<li>';
|
374 |
+
|
375 |
+
$html .= apply_filters( 'pvc_most_viewed_posts_item_before', $args['item_before'], $post );
|
376 |
|
377 |
if ( $args['show_post_thumbnail'] && has_post_thumbnail( $post->ID ) ) {
|
378 |
$html .= '
|
379 |
+
<span class="post-thumbnail">
|
380 |
+
' . get_the_post_thumbnail( $post->ID, $args['thumbnail_size'] ) . '
|
381 |
+
</span>';
|
382 |
}
|
383 |
|
384 |
$html .= '
|
385 |
+
<a class="post-title" href="' . get_permalink( $post->ID ) . '">' . get_the_title( $post->ID ) . '</a>' . ($args['show_post_views'] ? ' <span class="count">(' . number_format_i18n( pvc_get_post_views( $post->ID ) ) . ')</span>' : '');
|
386 |
|
387 |
$excerpt = '';
|
388 |
|
398 |
|
399 |
if ( ! empty( $excerpt ) )
|
400 |
$html .= '
|
401 |
+
|
402 |
+
<div class="post-excerpt">' . esc_html( $excerpt ) . '</div>';
|
403 |
+
|
404 |
+
$html .= apply_filters( 'pvc_most_viewed_posts_item_after', $args['item_after'], $post );
|
405 |
|
406 |
$html .= '
|
407 |
</li>';
|
includes/settings.php
CHANGED
@@ -159,7 +159,7 @@ class Post_Views_Counter_Settings {
|
|
159 |
* @return mixed
|
160 |
*/
|
161 |
public function options_page() {
|
162 |
-
$tab_key = (isset( $_GET['tab'] ) ? $_GET['tab'] : 'general');
|
163 |
|
164 |
echo '
|
165 |
<div class="wrap">' . screen_icon() . '
|
@@ -586,7 +586,7 @@ class Post_Views_Counter_Settings {
|
|
586 |
$input = Post_Views_Counter()->defaults['general'];
|
587 |
$input['wp_postviews_import'] = true;
|
588 |
|
589 |
-
$sql =
|
590 |
|
591 |
foreach ( $views as $view ) {
|
592 |
$sql[] = "(" . $view['post_id'] . ", 4, 'total', " . $view['meta_value'] . ")";
|
@@ -623,7 +623,7 @@ class Post_Views_Counter_Settings {
|
|
623 |
$input['counter_mode'] = isset( $input['counter_mode'], $this->modes[$input['counter_mode']] ) ? $input['counter_mode'] : Post_Views_Counter()->defaults['general']['counter_mode'];
|
624 |
|
625 |
// post views column
|
626 |
-
$input['post_views_column'] = $input['post_views_column'];
|
627 |
|
628 |
// time between counts
|
629 |
$input['time_between_counts']['number'] = (int) ( isset( $input['time_between_counts']['number'] ) ? $input['time_between_counts']['number'] : Post_Views_Counter()->defaults['general']['time_between_counts']['number'] );
|
159 |
* @return mixed
|
160 |
*/
|
161 |
public function options_page() {
|
162 |
+
$tab_key = (isset( $_GET['tab'] ) ? esc_attr( $_GET['tab'] ) : 'general');
|
163 |
|
164 |
echo '
|
165 |
<div class="wrap">' . screen_icon() . '
|
586 |
$input = Post_Views_Counter()->defaults['general'];
|
587 |
$input['wp_postviews_import'] = true;
|
588 |
|
589 |
+
$sql = array();
|
590 |
|
591 |
foreach ( $views as $view ) {
|
592 |
$sql[] = "(" . $view['post_id'] . ", 4, 'total', " . $view['meta_value'] . ")";
|
623 |
$input['counter_mode'] = isset( $input['counter_mode'], $this->modes[$input['counter_mode']] ) ? $input['counter_mode'] : Post_Views_Counter()->defaults['general']['counter_mode'];
|
624 |
|
625 |
// post views column
|
626 |
+
$input['post_views_column'] = isset( $input['post_views_column'] );
|
627 |
|
628 |
// time between counts
|
629 |
$input['time_between_counts']['number'] = (int) ( isset( $input['time_between_counts']['number'] ) ? $input['time_between_counts']['number'] : Post_Views_Counter()->defaults['general']['time_between_counts']['number'] );
|
js/admin-dashboard.js
CHANGED
@@ -1,99 +1,99 @@
|
|
1 |
( function ( $ ) {
|
2 |
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
|
11 |
-
|
12 |
|
13 |
-
|
14 |
|
15 |
-
|
16 |
|
17 |
-
|
18 |
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
|
|
|
90 |
}
|
91 |
-
}
|
92 |
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
|
99 |
} )( jQuery );
|
1 |
( function ( $ ) {
|
2 |
|
3 |
+
// set global options
|
4 |
+
// Chart.defaults.global.tooltips.titleMarginBottom = 0;
|
5 |
+
// Chart.defaults.global.tooltips.footerMarginTop = 4;
|
6 |
|
7 |
+
window.onload = function () {
|
8 |
+
updateChart( 'this_month' );
|
9 |
+
};
|
10 |
|
11 |
+
function updateChart( period ) {
|
12 |
|
13 |
+
var container = document.getElementById( 'pvc_dashboard_container' );
|
14 |
|
15 |
+
if ( $( container ).length > 0 ) {
|
16 |
|
17 |
+
$( container ).addClass( 'loading' ).append( '<span class="spinner is-active"></span>' );
|
18 |
|
19 |
+
$.ajax( {
|
20 |
+
url: pvcArgs.ajaxURL,
|
21 |
+
type: 'POST',
|
22 |
+
dataType: 'json',
|
23 |
+
data: ( {
|
24 |
+
action: 'pvc_dashboard_chart',
|
25 |
+
nonce: pvcArgs.nonce,
|
26 |
+
period: period
|
27 |
+
} ),
|
28 |
+
success: function ( args ) {
|
29 |
+
$( container ).removeClass( 'loading' );
|
30 |
+
$( container ).find( '.spinner' ).removeClass( 'is-active' );
|
31 |
|
32 |
+
var config = {
|
33 |
+
type: 'line',
|
34 |
+
data: args.data,
|
35 |
+
options: {
|
36 |
+
responsive: true,
|
37 |
+
legend: {
|
38 |
+
display: false,
|
39 |
+
position: 'bottom',
|
40 |
+
},
|
41 |
+
scales: {
|
42 |
+
xAxes: [ {
|
43 |
+
display: true,
|
44 |
+
scaleLabel: {
|
45 |
+
display: true,
|
46 |
+
labelString: args.text.xAxes,
|
47 |
+
fontSize: 14,
|
48 |
+
fontFamily: '-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif'
|
49 |
+
}
|
50 |
+
} ],
|
51 |
+
yAxes: [ {
|
52 |
+
display: true,
|
53 |
+
scaleLabel: {
|
54 |
+
display: false,
|
55 |
+
labelString: args.text.yAxes
|
56 |
+
}
|
57 |
+
} ]
|
58 |
+
},
|
59 |
+
hover: {
|
60 |
+
mode: 'label'
|
61 |
+
},
|
62 |
+
tooltips: {
|
63 |
+
custom: function ( tooltip ) {
|
64 |
+
// console.log( tooltip );
|
65 |
+
},
|
66 |
+
callbacks: {
|
67 |
+
title: function ( tooltip ) {
|
68 |
+
return args.data.dates[tooltip[0].index];
|
69 |
+
}
|
70 |
+
}
|
71 |
+
}
|
72 |
+
}
|
73 |
+
};
|
74 |
|
75 |
+
$.each( config.data.datasets, function ( i, dataset ) {
|
76 |
+
dataset.fill = args.design.fill;
|
77 |
+
dataset.borderColor = args.design.borderColor;
|
78 |
+
dataset.backgroundColor = args.design.backgroundColor;
|
79 |
+
dataset.borderWidth = args.design.borderWidth;
|
80 |
+
dataset.borderDash = args.design.borderDash;
|
81 |
+
dataset.pointBorderColor = args.design.pointBorderColor;
|
82 |
+
dataset.pointBackgroundColor = args.design.pointBackgroundColor;
|
83 |
+
dataset.pointBorderWidth = args.design.pointBorderWidth;
|
84 |
+
} );
|
85 |
|
86 |
+
window.chartPVC = new Chart( document.getElementById( 'pvc_chart' ).getContext( '2d' ), config );
|
87 |
+
}
|
88 |
+
} );
|
89 |
|
90 |
+
}
|
91 |
}
|
|
|
92 |
|
93 |
+
function updateLegend() {
|
94 |
+
$legendContainer = $( '#legendContainer' );
|
95 |
+
$legendContainer.empty();
|
96 |
+
$legendContainer.append( window.chartPVC.generateLegend() );
|
97 |
+
}
|
98 |
|
99 |
} )( jQuery );
|
js/admin-post.js
CHANGED
@@ -1,49 +1,49 @@
|
|
1 |
( function ( $ ) {
|
2 |
|
3 |
-
|
4 |
-
|
5 |
-
// post views input
|
6 |
-
$( '#post-views .edit-post-views' ).click( function () {
|
7 |
-
if ( $( '#post-views-input-container' ).is( ":hidden" ) ) {
|
8 |
-
$( '#post-views-input-container' ).slideDown( 'fast' );
|
9 |
-
$( this ).hide();
|
10 |
-
}
|
11 |
-
return false;
|
12 |
-
} );
|
13 |
|
14 |
-
|
15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
|
17 |
-
|
|
|
18 |
|
19 |
-
|
20 |
-
$( '#post-views .edit-post-views' ).show();
|
21 |
|
22 |
-
|
23 |
-
|
24 |
-
$( '#post-views-input' ).val( views );
|
25 |
|
26 |
-
|
|
|
|
|
27 |
|
28 |
-
|
29 |
-
} );
|
30 |
|
31 |
-
|
32 |
-
|
33 |
|
34 |
-
|
|
|
35 |
|
36 |
-
|
37 |
-
$( '#post-views .edit-post-views' ).show();
|
38 |
|
39 |
-
|
|
|
40 |
|
41 |
-
|
42 |
-
$( '#post-views-input' ).val( views );
|
43 |
|
44 |
-
|
45 |
-
|
46 |
|
47 |
-
|
|
|
|
|
|
|
48 |
|
49 |
} )( jQuery );
|
1 |
( function ( $ ) {
|
2 |
|
3 |
+
$( document ).ready( function () {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
|
5 |
+
// post views input
|
6 |
+
$( '#post-views .edit-post-views' ).click( function () {
|
7 |
+
if ( $( '#post-views-input-container' ).is( ":hidden" ) ) {
|
8 |
+
$( '#post-views-input-container' ).slideDown( 'fast' );
|
9 |
+
$( this ).hide();
|
10 |
+
}
|
11 |
+
return false;
|
12 |
+
} );
|
13 |
|
14 |
+
// save post views
|
15 |
+
$( '#post-views .save-post-views' ).click( function () {
|
16 |
|
17 |
+
var views = $.trim( $( '#post-views-display b' ).text() );
|
|
|
18 |
|
19 |
+
$( '#post-views-input-container' ).slideUp( 'fast' );
|
20 |
+
$( '#post-views .edit-post-views' ).show();
|
|
|
21 |
|
22 |
+
views = parseInt( $( '#post-views-input' ).val() );
|
23 |
+
// reassign value as integer
|
24 |
+
$( '#post-views-input' ).val( views );
|
25 |
|
26 |
+
$( '#post-views-display b' ).text( views );
|
|
|
27 |
|
28 |
+
return false;
|
29 |
+
} );
|
30 |
|
31 |
+
// cancel post views
|
32 |
+
$( '#post-views .cancel-post-views' ).click( function () {
|
33 |
|
34 |
+
var views = $.trim( $( '#post-views-display b' ).text() );
|
|
|
35 |
|
36 |
+
$( '#post-views-input-container' ).slideUp( 'fast' );
|
37 |
+
$( '#post-views .edit-post-views' ).show();
|
38 |
|
39 |
+
views = parseInt( $( '#post-views-current' ).val() );
|
|
|
40 |
|
41 |
+
$( '#post-views-display b' ).text( views );
|
42 |
+
$( '#post-views-input' ).val( views );
|
43 |
|
44 |
+
return false;
|
45 |
+
} );
|
46 |
+
|
47 |
+
} );
|
48 |
|
49 |
} )( jQuery );
|
js/admin-quick-edit.js
CHANGED
@@ -1,57 +1,57 @@
|
|
1 |
( function ( $ ) {
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
} );
|
40 |
-
|
41 |
-
// get the data
|
42 |
-
var $post_views = $bulk_row.find( 'input[name="post_views"]' ).val();
|
43 |
-
|
44 |
-
// save the data
|
45 |
-
$.ajax( {
|
46 |
-
url: ajaxurl, // this is a variable that WordPress has already defined for us
|
47 |
-
type: 'post',
|
48 |
-
async: false,
|
49 |
-
cache: false,
|
50 |
-
data: {
|
51 |
-
action: 'save_bulk_post_views', // this is the name of our WP AJAX function that we'll set up next
|
52 |
-
post_ids: $post_ids, // and these are the 2 parameters we're passing to our function
|
53 |
-
post_views: $post_views,
|
54 |
-
}
|
55 |
-
} );
|
56 |
-
} );
|
57 |
} )( jQuery );
|
1 |
( function ( $ ) {
|
2 |
+
// we create a copy of the WP inline edit post function
|
3 |
+
var $wp_inline_edit = inlineEditPost.edit;
|
4 |
+
// and then we overwrite the function with our own code
|
5 |
+
inlineEditPost.edit = function ( id ) {
|
6 |
+
// call the original WP edit function
|
7 |
+
// we don't want to leave WordPress hanging
|
8 |
+
$wp_inline_edit.apply( this, arguments );
|
9 |
+
|
10 |
+
// get the post ID
|
11 |
+
var $post_id = 0;
|
12 |
+
|
13 |
+
if ( typeof ( id ) == 'object' )
|
14 |
+
$post_id = parseInt( this.getId( id ) );
|
15 |
+
|
16 |
+
if ( $post_id > 0 ) {
|
17 |
+
// define the edit row
|
18 |
+
var $edit_row = $( '#edit-' + $post_id );
|
19 |
+
var $post_row = $( '#post-' + $post_id );
|
20 |
+
|
21 |
+
// get the data
|
22 |
+
var $post_views = $( '.column-post_views', $post_row ).text();
|
23 |
+
|
24 |
+
// populate the data
|
25 |
+
$( ':input[name="post_views"]', $edit_row ).val( $post_views );
|
26 |
+
}
|
27 |
+
|
28 |
+
return false;
|
29 |
+
};
|
30 |
+
|
31 |
+
$( document ).on( 'click', '#bulk_edit', function () {
|
32 |
+
// define the bulk edit row
|
33 |
+
var $bulk_row = $( '#bulk-edit' );
|
34 |
+
|
35 |
+
// get the selected post ids that are being edited
|
36 |
+
var $post_ids = new Array();
|
37 |
+
$bulk_row.find( '#bulk-titles' ).children().each( function () {
|
38 |
+
$post_ids.push( $( this ).attr( 'id' ).replace( /^(ttle)/i, '' ) );
|
39 |
+
} );
|
40 |
+
|
41 |
+
// get the data
|
42 |
+
var $post_views = $bulk_row.find( 'input[name="post_views"]' ).val();
|
43 |
+
|
44 |
+
// save the data
|
45 |
+
$.ajax( {
|
46 |
+
url: ajaxurl, // this is a variable that WordPress has already defined for us
|
47 |
+
type: 'post',
|
48 |
+
async: false,
|
49 |
+
cache: false,
|
50 |
+
data: {
|
51 |
+
action: 'save_bulk_post_views', // this is the name of our WP AJAX function that we'll set up next
|
52 |
+
post_ids: $post_ids, // and these are the 2 parameters we're passing to our function
|
53 |
+
post_views: $post_views,
|
54 |
+
}
|
55 |
+
} );
|
56 |
} );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
} )( jQuery );
|
js/admin-settings.js
CHANGED
@@ -1,71 +1,71 @@
|
|
1 |
( function ( $ ) {
|
2 |
|
3 |
-
|
4 |
|
5 |
-
|
6 |
|
7 |
-
|
8 |
|
9 |
-
|
10 |
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
|
25 |
-
|
26 |
|
27 |
-
|
28 |
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
|
39 |
-
|
40 |
-
|
41 |
|
42 |
-
|
43 |
-
|
44 |
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
|
68 |
-
|
69 |
|
70 |
} )( jQuery );
|
71 |
|
@@ -77,57 +77,57 @@
|
|
77 |
* Author URL: elmahdim.com
|
78 |
*/
|
79 |
!function ( e ) {
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
|
|
|
|
|
|
128 |
} )
|
129 |
-
|
130 |
-
l.find( '[checked="checked"]' ).closest( "label" ).addClass( "checked" ), l.find( "input" ).is( "input:disabled" ) && l.find( "input:disabled" ).closest( "label" ).off().addClass( "disabled" )
|
131 |
-
} )
|
132 |
-
}
|
133 |
}( jQuery, window, document );
|
1 |
( function ( $ ) {
|
2 |
|
3 |
+
$( document ).ready( function () {
|
4 |
|
5 |
+
$( '.post-views-counter-settings' ).checkBo();
|
6 |
|
7 |
+
var ip_boxes = $( '#pvc_exclude_ips' ).find( '.ip-box' ).length;
|
8 |
|
9 |
+
$( '#pvc_exclude_ips .ip-box:first' ).find( '.remove-exclude-ip' ).hide();
|
10 |
|
11 |
+
// ask whether to reset options to defaults
|
12 |
+
$( document ).on( 'click', '.reset_pvc_settings', function () {
|
13 |
+
return confirm( pvcArgsSettings.resetToDefaults );
|
14 |
+
} );
|
15 |
|
16 |
+
// ask whether to reset views
|
17 |
+
$( document ).on( 'click', 'input[name="post_views_counter_reset_views"]', function () {
|
18 |
+
return confirm( pvcArgsSettings.resetViews );
|
19 |
+
} );
|
20 |
|
21 |
+
// remove ip box
|
22 |
+
$( document ).on( 'click', '.remove-exclude-ip', function ( e ) {
|
23 |
+
e.preventDefault();
|
24 |
|
25 |
+
ip_boxes--;
|
26 |
|
27 |
+
var parent = $( this ).parent();
|
28 |
|
29 |
+
// remove ip box
|
30 |
+
parent.slideUp( 'fast', function () {
|
31 |
+
$( this ).remove();
|
32 |
+
} );
|
33 |
+
} );
|
34 |
|
35 |
+
// add ip box
|
36 |
+
$( document ).on( 'click', '.add-exclude-ip', function () {
|
37 |
+
ip_boxes++;
|
38 |
|
39 |
+
var parent = $( this ).parents( '#pvc_exclude_ips' ),
|
40 |
+
new_ip_box = parent.find( '.ip-box:last' ).clone().hide();
|
41 |
|
42 |
+
// clear value
|
43 |
+
new_ip_box.find( 'input' ).val( '' );
|
44 |
|
45 |
+
if ( ip_boxes > 1 ) {
|
46 |
+
new_ip_box.find( '.remove-exclude-ip' ).show();
|
47 |
+
}
|
48 |
|
49 |
+
// add and display new ip box
|
50 |
+
parent.find( '.ip-box:last' ).after( new_ip_box ).next().slideDown( 'fast' );
|
51 |
+
} );
|
52 |
|
53 |
+
// add current ip
|
54 |
+
$( document ).on( 'click', '.add-current-ip', function () {
|
55 |
+
// fill input with user's current ip
|
56 |
+
$( this ).parents( '#pvc_exclude_ips' ).find( '.ip-box' ).last().find( 'input' ).val( $( this ).attr( 'data-rel' ) );
|
57 |
+
} );
|
58 |
|
59 |
+
// toggle user roles
|
60 |
+
$( '#pvc_exclude-roles, #pvc_restrict_display-roles' ).change( function () {
|
61 |
+
if ( $( this ).is( ':checked' ) ) {
|
62 |
+
$( '.pvc_user_roles' ).slideDown( 'fast' );
|
63 |
+
} else {
|
64 |
+
$( '.pvc_user_roles' ).slideUp( 'fast' );
|
65 |
+
}
|
66 |
+
} );
|
67 |
|
68 |
+
} );
|
69 |
|
70 |
} )( jQuery );
|
71 |
|
77 |
* Author URL: elmahdim.com
|
78 |
*/
|
79 |
!function ( e ) {
|
80 |
+
e.fn.checkBo = function ( c ) {
|
81 |
+
return c = e.extend( { }, { checkAllButton: null, checkAllTarget: null, checkAllTextDefault: null, checkAllTextToggle: null }, c ), this.each( function () {
|
82 |
+
function t( e ) {
|
83 |
+
this.input = e
|
84 |
+
}
|
85 |
+
function n() {
|
86 |
+
var c = e( this ).is( ":checked" );
|
87 |
+
e( this ).closest( "label" ).toggleClass( "checked", c )
|
88 |
+
}
|
89 |
+
function i( e, c, t ) {
|
90 |
+
e.text( e.parent( a ).hasClass( "checked" ) ? t : c )
|
91 |
+
}
|
92 |
+
function h( c ) {
|
93 |
+
var t = c.attr( "data-show" );
|
94 |
+
c = c.attr( "data-hide" ), e( t ).removeClass( "is-hidden" ), e( c ).addClass( "is-hidden" )
|
95 |
+
}
|
96 |
+
var l = e( this ), a = l.find( ".cb-checkbox" ), d = l.find( ".cb-radio" ), o = l.find( ".cb-switcher" ), s = a.find( "input:checkbox" ), f = d.find( "input:radio" );
|
97 |
+
s.wrap( '<span class="cb-inner"><i></i></span>' ), f.wrap( '<span class="cb-inner"><i></i></span>' );
|
98 |
+
var k = new t( "input:checkbox" ), r = new t( "input:radio" );
|
99 |
+
if ( t.prototype.checkbox = function ( e ) {
|
100 |
+
var c = e.find( this.input ).is( ":checked" );
|
101 |
+
e.find( this.input ).prop( "checked", !c ).trigger( "change" )
|
102 |
+
}, t.prototype.radiobtn = function ( c, t ) {
|
103 |
+
var n = e( 'input:radio[name="' + t + '"]' );
|
104 |
+
n.prop( "checked", !1 ), n.closest( n.closest( d ) ).removeClass( "checked" ), c.addClass( "checked" ), c.find( this.input ).get( 0 ).checked = c.hasClass( "checked" ), c.find( this.input ).change()
|
105 |
+
}, s.on( "change", n ), f.on( "change", n ), a.find( "a" ).on( "click", function ( e ) {
|
106 |
+
e.stopPropagation()
|
107 |
+
} ), a.on( "click", function ( c ) {
|
108 |
+
c.preventDefault(), k.checkbox( e( this ) ), c = e( this ).attr( "data-toggle" ), e( c ).toggleClass( "is-hidden" ), h( e( this ) )
|
109 |
+
} ), d.on( "click", function ( c ) {
|
110 |
+
c.preventDefault(), r.radiobtn( e( this ), e( this ).find( "input:radio" ).attr( "name" ) ), h( e( this ) )
|
111 |
+
} ), e.fn.toggleCheckbox = function () {
|
112 |
+
this.prop( "checked", !this.is( ":checked" ) )
|
113 |
+
}, e.fn.switcherChecker = function () {
|
114 |
+
var c = e( this ), t = c.find( "input" ), n = c.find( ".cb-state" );
|
115 |
+
t.is( ":checked" ) ? ( c.addClass( "checked" ), n.html( t.attr( "data-state-on" ) ) ) : ( c.removeClass( "checked" ), n.html( t.attr( "data-state-off" ) ) )
|
116 |
+
}, o.on( "click", function ( c ) {
|
117 |
+
c.preventDefault(), c = e( this ), c.find( "input" ).toggleCheckbox(), c.switcherChecker(), e( c.attr( "data-toggle" ) ).toggleClass( "is-hidden" )
|
118 |
+
} ), o.each( function () {
|
119 |
+
e( this ).switcherChecker()
|
120 |
+
} ), c.checkAllButton && c.checkAllTarget ) {
|
121 |
+
var u = e( this );
|
122 |
+
u.find( e( c.checkAllButton ) ).on( "click", function () {
|
123 |
+
u.find( c.checkAllTarget ).find( "input:checkbox" ).each( function () {
|
124 |
+
u.find( e( c.checkAllButton ) ).hasClass( "checked" ) ? u.find( c.checkAllTarget ).find( "input:checkbox" ).prop( "checked", !0 ).change() : u.find( c.checkAllTarget ).find( "input:checkbox" ).prop( "checked", !1 ).change()
|
125 |
+
} ), i( u.find( e( c.checkAllButton ) ).find( ".toggle-text" ), c.checkAllTextDefault, c.checkAllTextToggle )
|
126 |
+
} ), u.find( c.checkAllTarget ).find( a ).on( "click", function () {
|
127 |
+
u.find( c.checkAllButton ).find( "input:checkbox" ).prop( "checked", !1 ).change().removeClass( "checked" ), i( u.find( e( c.checkAllButton ) ).find( ".toggle-text" ), c.checkAllTextDefault, c.checkAllTextToggle )
|
128 |
+
} )
|
129 |
+
}
|
130 |
+
l.find( '[checked="checked"]' ).closest( "label" ).addClass( "checked" ), l.find( "input" ).is( "input:disabled" ) && l.find( "input:disabled" ).closest( "label" ).off().addClass( "disabled" )
|
131 |
} )
|
132 |
+
}
|
|
|
|
|
|
|
133 |
}( jQuery, window, document );
|
js/frontend.js
CHANGED
@@ -1,44 +1,44 @@
|
|
1 |
( function ( $ ) {
|
2 |
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
}
|
21 |
-
|
22 |
-
|
23 |
-
// admin ajax request
|
24 |
-
} else {
|
25 |
-
|
26 |
-
var request = {
|
27 |
-
action: 'pvc-check-post',
|
28 |
-
pvc_nonce: pvcArgsFrontend.nonce,
|
29 |
-
id: pvcArgsFrontend.postID
|
30 |
-
};
|
31 |
-
|
32 |
-
$.ajax( {
|
33 |
-
url: pvcArgsFrontend.requestURL,
|
34 |
-
type: 'post',
|
35 |
-
async: true,
|
36 |
-
cache: false,
|
37 |
-
data: request
|
38 |
-
} );
|
39 |
-
|
40 |
-
}
|
41 |
-
|
42 |
-
} );
|
43 |
|
44 |
} )( jQuery );
|
1 |
( function ( $ ) {
|
2 |
|
3 |
+
$( document ).ready( function () {
|
4 |
+
|
5 |
+
// rest api request
|
6 |
+
if ( pvcArgsFrontend.mode == 'rest_api' ) {
|
7 |
+
|
8 |
+
var request = {
|
9 |
+
id: pvcArgsFrontend.postID
|
10 |
+
};
|
11 |
+
|
12 |
+
$.ajax( {
|
13 |
+
url: pvcArgsFrontend.requestURL + '?id=' + pvcArgsFrontend.postID,
|
14 |
+
type: 'post',
|
15 |
+
async: true,
|
16 |
+
cache: false,
|
17 |
+
data: request,
|
18 |
+
beforeSend: function ( xhr ) {
|
19 |
+
xhr.setRequestHeader( 'X-WP-Nonce', pvcArgsFrontend.nonce );
|
20 |
+
}
|
21 |
+
} );
|
22 |
+
|
23 |
+
// admin ajax request
|
24 |
+
} else {
|
25 |
+
|
26 |
+
var request = {
|
27 |
+
action: 'pvc-check-post',
|
28 |
+
pvc_nonce: pvcArgsFrontend.nonce,
|
29 |
+
id: pvcArgsFrontend.postID
|
30 |
+
};
|
31 |
+
|
32 |
+
$.ajax( {
|
33 |
+
url: pvcArgsFrontend.requestURL,
|
34 |
+
type: 'post',
|
35 |
+
async: true,
|
36 |
+
cache: false,
|
37 |
+
data: request
|
38 |
+
} );
|
39 |
+
|
40 |
}
|
41 |
+
|
42 |
+
} );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
|
44 |
} )( jQuery );
|
post-views-counter.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
/*
|
3 |
Plugin Name: Post Views Counter
|
4 |
Description: Post Views Counter allows you to display how many times a post, page or custom post type had been viewed in a simple, fast and reliable way.
|
5 |
-
Version: 1.2.
|
6 |
Author: dFactory
|
7 |
Author URI: http://www.dfactory.eu/
|
8 |
Plugin URI: http://www.dfactory.eu/plugins/post-views-counter/
|
@@ -31,7 +31,7 @@ if ( ! class_exists( 'Post_Views_Counter' ) ) :
|
|
31 |
* Post Views Counter final class.
|
32 |
*
|
33 |
* @class Post_Views_Counter
|
34 |
-
* @version 1.2.
|
35 |
*/
|
36 |
final class Post_Views_Counter {
|
37 |
|
@@ -80,7 +80,7 @@ if ( ! class_exists( 'Post_Views_Counter' ) ) :
|
|
80 |
'link_to_post' => true,
|
81 |
'icon_class' => 'dashicons-chart-bar'
|
82 |
),
|
83 |
-
'version' => '1.2.
|
84 |
);
|
85 |
|
86 |
/**
|
@@ -162,8 +162,8 @@ if ( ! class_exists( 'Post_Views_Counter' ) ) :
|
|
162 |
* @return void
|
163 |
*/
|
164 |
public function __construct() {
|
165 |
-
register_activation_hook( __FILE__, array( $this, '
|
166 |
-
register_deactivation_hook( __FILE__, array( $this, '
|
167 |
|
168 |
// settings
|
169 |
$this->options = array(
|
@@ -181,9 +181,37 @@ if ( ! class_exists( 'Post_Views_Counter' ) ) :
|
|
181 |
}
|
182 |
|
183 |
/**
|
184 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
185 |
*/
|
186 |
-
public function
|
187 |
global $wpdb, $charset_collate;
|
188 |
|
189 |
// required for dbdelta
|
@@ -212,11 +240,50 @@ if ( ! class_exists( 'Post_Views_Counter' ) ) :
|
|
212 |
}
|
213 |
|
214 |
/**
|
215 |
-
*
|
|
|
|
|
|
|
216 |
*/
|
217 |
-
public function
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
218 |
// delete default options
|
219 |
-
if ( $
|
220 |
delete_option( 'post_views_counter_settings_general' );
|
221 |
delete_option( 'post_views_counter_settings_display' );
|
222 |
|
2 |
/*
|
3 |
Plugin Name: Post Views Counter
|
4 |
Description: Post Views Counter allows you to display how many times a post, page or custom post type had been viewed in a simple, fast and reliable way.
|
5 |
+
Version: 1.2.8
|
6 |
Author: dFactory
|
7 |
Author URI: http://www.dfactory.eu/
|
8 |
Plugin URI: http://www.dfactory.eu/plugins/post-views-counter/
|
31 |
* Post Views Counter final class.
|
32 |
*
|
33 |
* @class Post_Views_Counter
|
34 |
+
* @version 1.2.8
|
35 |
*/
|
36 |
final class Post_Views_Counter {
|
37 |
|
80 |
'link_to_post' => true,
|
81 |
'icon_class' => 'dashicons-chart-bar'
|
82 |
),
|
83 |
+
'version' => '1.2.8'
|
84 |
);
|
85 |
|
86 |
/**
|
162 |
* @return void
|
163 |
*/
|
164 |
public function __construct() {
|
165 |
+
register_activation_hook( __FILE__, array( $this, 'multisite_activation' ) );
|
166 |
+
register_deactivation_hook( __FILE__, array( $this, 'multisite_deactivation' ) );
|
167 |
|
168 |
// settings
|
169 |
$this->options = array(
|
181 |
}
|
182 |
|
183 |
/**
|
184 |
+
* Multisite activation.
|
185 |
+
*
|
186 |
+
* @global object $wpdb
|
187 |
+
* @param bool $networkwide
|
188 |
+
*/
|
189 |
+
public function multisite_activation( $networkwide ) {
|
190 |
+
if ( is_multisite() && $networkwide ) {
|
191 |
+
global $wpdb;
|
192 |
+
|
193 |
+
$activated_blogs = array();
|
194 |
+
$current_blog_id = $wpdb->blogid;
|
195 |
+
$blogs_ids = $wpdb->get_col( $wpdb->prepare( 'SELECT blog_id FROM ' . $wpdb->blogs, '' ) );
|
196 |
+
|
197 |
+
foreach ( $blogs_ids as $blog_id ) {
|
198 |
+
switch_to_blog( $blog_id );
|
199 |
+
$this->activate_single();
|
200 |
+
$activated_blogs[] = (int) $blog_id;
|
201 |
+
}
|
202 |
+
|
203 |
+
switch_to_blog( $current_blog_id );
|
204 |
+
update_site_option( 'post_views_counter_activated_blogs', $activated_blogs, array() );
|
205 |
+
} else
|
206 |
+
$this->activate_single();
|
207 |
+
}
|
208 |
+
|
209 |
+
/**
|
210 |
+
* Single site activation.
|
211 |
+
*
|
212 |
+
* @global array $wp_roles
|
213 |
*/
|
214 |
+
public function activate_single() {
|
215 |
global $wpdb, $charset_collate;
|
216 |
|
217 |
// required for dbdelta
|
240 |
}
|
241 |
|
242 |
/**
|
243 |
+
* Multisite deactivation.
|
244 |
+
*
|
245 |
+
* @global array $wpdb
|
246 |
+
* @param bool $networkwide
|
247 |
*/
|
248 |
+
public function multisite_deactivation( $networkwide ) {
|
249 |
+
if ( is_multisite() && $networkwide ) {
|
250 |
+
global $wpdb;
|
251 |
+
|
252 |
+
$current_blog_id = $wpdb->blogid;
|
253 |
+
$blogs_ids = $wpdb->get_col( $wpdb->prepare( 'SELECT blog_id FROM ' . $wpdb->blogs, '' ) );
|
254 |
+
|
255 |
+
if ( ! ($activated_blogs = get_site_option( 'post_views_counter_activated_blogs', false, false )) )
|
256 |
+
$activated_blogs = array();
|
257 |
+
|
258 |
+
foreach ( $blogs_ids as $blog_id ) {
|
259 |
+
switch_to_blog( $blog_id );
|
260 |
+
$this->deactivate_single( true );
|
261 |
+
|
262 |
+
if ( in_array( (int) $blog_id, $activated_blogs, true ) )
|
263 |
+
unset( $activated_blogs[array_search( $blog_id, $activated_blogs )] );
|
264 |
+
}
|
265 |
+
|
266 |
+
switch_to_blog( $current_blog_id );
|
267 |
+
update_site_option( 'post_views_counter_activated_blogs', $activated_blogs );
|
268 |
+
} else
|
269 |
+
$this->deactivate_single();
|
270 |
+
}
|
271 |
+
|
272 |
+
/**
|
273 |
+
* Single site deactivation.
|
274 |
+
*
|
275 |
+
* @global array $wp_roles
|
276 |
+
* @param bool $multi
|
277 |
+
*/
|
278 |
+
public function deactivate_single( $multi = false ) {
|
279 |
+
if ( $multi ) {
|
280 |
+
$options = get_option( 'post_views_counter_settings_general' );
|
281 |
+
$check = $options['deactivation_delete'];
|
282 |
+
} else
|
283 |
+
$check = $this->options['general']['deactivation_delete'];
|
284 |
+
|
285 |
// delete default options
|
286 |
+
if ( $check ) {
|
287 |
delete_option( 'post_views_counter_settings_general' );
|
288 |
delete_option( 'post_views_counter_settings_display' );
|
289 |
|
readme.txt
CHANGED
@@ -3,8 +3,8 @@ Contributors: dfactory
|
|
3 |
Donate link: http://www.dfactory.eu/
|
4 |
Tags: counter, hits, posts, postviews, post views, views, count, statistics, stats, analytics, pageviews, tracking
|
5 |
Requires at least: 4.0
|
6 |
-
Tested up to: 4.
|
7 |
-
Stable tag: 1.2.
|
8 |
License: MIT License
|
9 |
License URI: http://opensource.org/licenses/MIT
|
10 |
|
@@ -32,6 +32,7 @@ For more information, check out plugin page at [dFactory](http://www.dfactory.eu
|
|
32 |
* One-click data import from WP-PostViews
|
33 |
* Sortable admin column
|
34 |
* Post views display position, automatic or manual via shortcode
|
|
|
35 |
* W3 Cache/WP SuperCache compatible
|
36 |
* Optional object cache support
|
37 |
* WPML and Polylang compatible
|
@@ -59,6 +60,11 @@ No questions yet.
|
|
59 |
|
60 |
== Changelog ==
|
61 |
|
|
|
|
|
|
|
|
|
|
|
62 |
= 1.2.7 =
|
63 |
* Fix: Chart data not updating for object cached installs due to missing expire parameter
|
64 |
* Fix: Bug preventing hiding the counter based on user role.
|
@@ -156,7 +162,7 @@ Initial release
|
|
156 |
|
157 |
== Upgrade Notice ==
|
158 |
|
159 |
-
= 1.2.
|
160 |
-
*
|
161 |
-
* Fix:
|
162 |
-
*
|
3 |
Donate link: http://www.dfactory.eu/
|
4 |
Tags: counter, hits, posts, postviews, post views, views, count, statistics, stats, analytics, pageviews, tracking
|
5 |
Requires at least: 4.0
|
6 |
+
Tested up to: 4.8.1
|
7 |
+
Stable tag: 1.2.8
|
8 |
License: MIT License
|
9 |
License URI: http://opensource.org/licenses/MIT
|
10 |
|
32 |
* One-click data import from WP-PostViews
|
33 |
* Sortable admin column
|
34 |
* Post views display position, automatic or manual via shortcode
|
35 |
+
* Multisite compatibile
|
36 |
* W3 Cache/WP SuperCache compatible
|
37 |
* Optional object cache support
|
38 |
* WPML and Polylang compatible
|
60 |
|
61 |
== Changelog ==
|
62 |
|
63 |
+
= 1.2.8 =
|
64 |
+
* New: Multisite compatibility
|
65 |
+
* Fix: Undefined index post_views_column on post_views_counter/includes/settings.php
|
66 |
+
* Tweak: Improved user IP handling
|
67 |
+
|
68 |
= 1.2.7 =
|
69 |
* Fix: Chart data not updating for object cached installs due to missing expire parameter
|
70 |
* Fix: Bug preventing hiding the counter based on user role.
|
162 |
|
163 |
== Upgrade Notice ==
|
164 |
|
165 |
+
= 1.2.8 =
|
166 |
+
* New: Multisite compatibility
|
167 |
+
* Fix: Undefined index post_views_column on post_views_counter/includes/settings.php
|
168 |
+
* Tweak: Improved user IP handling
|