columns.php
10 years ago
counter.php
10 years ago
cron.php
10 years ago
dashboard.php
10 years ago
frontend.php
10 years ago
functions.php
10 years ago
query.php
10 years ago
settings.php
10 years ago
update.php
10 years ago
widgets.php
10 years ago
query.php
255 lines
| 1 | <?php |
| 2 | // exit if accessed directly |
| 3 | if ( ! defined( 'ABSPATH' ) ) |
| 4 | exit; |
| 5 | |
| 6 | /** |
| 7 | * Post_Views_Counter_Query class. |
| 8 | */ |
| 9 | class Post_Views_Counter_Query { |
| 10 | |
| 11 | public function __construct() { |
| 12 | // actions |
| 13 | add_action( 'pre_get_posts', array( $this, 'extend_pre_query' ), 1 ); |
| 14 | |
| 15 | // filters |
| 16 | add_filter( 'query_vars', array( $this, 'query_vars' ) ); |
| 17 | add_filter( 'posts_join', array( $this, 'posts_join' ), 10, 2 ); |
| 18 | add_filter( 'posts_groupby', array( $this, 'posts_groupby' ), 10, 2 ); |
| 19 | add_filter( 'posts_orderby', array( $this, 'posts_orderby' ), 10, 2 ); |
| 20 | add_filter( 'posts_fields', array( $this, 'posts_fields' ), 10, 2 ); |
| 21 | add_filter( 'the_posts', array( $this, 'the_posts' ), 10, 2 ); |
| 22 | } |
| 23 | |
| 24 | /** |
| 25 | * Register views_query var. |
| 26 | * |
| 27 | * @param array $query_vars |
| 28 | * @return array |
| 29 | */ |
| 30 | public function query_vars( $query_vars ) { |
| 31 | $query_vars[] = 'views_query'; |
| 32 | |
| 33 | return $query_vars; |
| 34 | } |
| 35 | |
| 36 | /** |
| 37 | * Extend query with post_views orderby parameter. |
| 38 | * |
| 39 | * @param object $query |
| 40 | */ |
| 41 | public function extend_pre_query( $query ) { |
| 42 | if ( isset( $query->query_vars['orderby'] ) && $query->query_vars['orderby'] === 'post_views' ) |
| 43 | $query->pvc_orderby = true; |
| 44 | } |
| 45 | |
| 46 | /** |
| 47 | * Modify the db query to use post_views parameter. |
| 48 | * |
| 49 | * @global object $wpdb |
| 50 | * @param string $join |
| 51 | * @param object $query |
| 52 | * @return string |
| 53 | */ |
| 54 | public function posts_join( $join, $query ) { |
| 55 | $sql = ''; |
| 56 | |
| 57 | if ( ! empty( $query->query['views_query'] ) ) { |
| 58 | if ( isset( $query->query['views_query']['year'] ) ) |
| 59 | $year = (int)$query->query['views_query']['year']; |
| 60 | |
| 61 | if ( isset( $query->query['views_query']['month'] ) ) |
| 62 | $month = (int)$query->query['views_query']['month']; |
| 63 | |
| 64 | if ( isset( $query->query['views_query']['week'] ) ) |
| 65 | $week = (int)$query->query['views_query']['week']; |
| 66 | |
| 67 | if ( isset( $query->query['views_query']['day'] ) ) |
| 68 | $day = (int)$query->query['views_query']['day']; |
| 69 | |
| 70 | // year |
| 71 | if ( isset( $year ) ) { |
| 72 | // year, week |
| 73 | if ( isset( $week ) && $this->is_valid_date( 'yw', $year, 0, 0, $week ) ) { |
| 74 | $sql = " AND pvc.type = 1 AND pvc.period = '" . str_pad( $year, 4, 0, STR_PAD_LEFT ) . str_pad( $week, 2, 0, STR_PAD_LEFT ) . "'"; |
| 75 | // year, month |
| 76 | } elseif ( isset( $month ) ) { |
| 77 | // year, month, day |
| 78 | if ( isset( $day ) && $this->is_valid_date( 'ymd', $year, $month, $day ) ) { |
| 79 | $sql = " AND pvc.type = 0 AND pvc.period = '" . str_pad( $year, 4, 0, STR_PAD_LEFT ) . str_pad( $month, 2, 0, STR_PAD_LEFT ) . str_pad( $day, 2, 0, STR_PAD_LEFT ) . "'"; |
| 80 | // year, month |
| 81 | } elseif ( $this->is_valid_date( 'ym', $year, $month ) ) { |
| 82 | $sql = " AND pvc.type = 2 AND pvc.period = '" . str_pad( $year, 4, 0, STR_PAD_LEFT ) . str_pad( $month, 2, 0, STR_PAD_LEFT ) . "'"; |
| 83 | } |
| 84 | // year |
| 85 | } elseif ( $this->is_valid_date( 'y', $year ) ) { |
| 86 | $sql = " AND pvc.type = 3 AND pvc.period = '" . str_pad( $year, 4, 0, STR_PAD_LEFT ) . "'"; |
| 87 | } |
| 88 | // month |
| 89 | } elseif ( isset( $month ) ) { |
| 90 | // month, day |
| 91 | if ( isset( $day ) && $this->is_valid_date( 'md', 0, $month, $day ) ) { |
| 92 | $sql = " AND pvc.type = 0 AND RIGHT( pvc.period, 4 ) = '" . str_pad( $month, 2, 0, STR_PAD_LEFT ) . str_pad( $day, 2, 0, STR_PAD_LEFT ) . "'"; |
| 93 | // month |
| 94 | } elseif ( $this->is_valid_date( 'm', 0, $month ) ) { |
| 95 | $sql = " AND pvc.type = 2 AND RIGHT( pvc.period, 2 ) = '" . str_pad( $month, 2, 0, STR_PAD_LEFT ) . "'"; |
| 96 | } |
| 97 | // week |
| 98 | } elseif ( isset( $week ) && $this->is_valid_date( 'w', 0, 0, 0, $week ) ) { |
| 99 | $sql = " AND pvc.type = 1 AND RIGHT( pvc.period, 2 ) = '" . str_pad( $week, 2, 0, STR_PAD_LEFT ) . "'"; |
| 100 | // day |
| 101 | } elseif ( isset( $day ) && $this->is_valid_date( 'd', 0, 0, $day ) ) { |
| 102 | $sql = " AND pvc.type = 0 AND RIGHT( pvc.period, 2 ) = '" . str_pad( $day, 2, 0, STR_PAD_LEFT ) . "'"; |
| 103 | } |
| 104 | |
| 105 | if ( $sql !== '' ) |
| 106 | $query->pvc_query = true; |
| 107 | } |
| 108 | |
| 109 | // is it sorted by post views? |
| 110 | if ( ( $sql === '' && isset( $query->pvc_orderby ) && $query->pvc_orderby ) || apply_filters( 'pvc_extend_post_object', false, $query ) === true ) |
| 111 | $sql = ' AND pvc.type = 4'; |
| 112 | |
| 113 | // add date range |
| 114 | if ( $sql !== '' ) { |
| 115 | global $wpdb; |
| 116 | |
| 117 | $join .= " LEFT JOIN " . $wpdb->prefix . "post_views pvc ON pvc.id = " . $wpdb->prefix . "posts.ID" . $sql; |
| 118 | } |
| 119 | |
| 120 | return $join; |
| 121 | } |
| 122 | |
| 123 | /** |
| 124 | * Group posts using the post ID. |
| 125 | * |
| 126 | * @global object $wpdb |
| 127 | * @param string $groupby |
| 128 | * @param object $query |
| 129 | * @return string |
| 130 | */ |
| 131 | public function posts_groupby( $groupby, $query ) { |
| 132 | // is it sorted by post views or views_query is used? |
| 133 | if ( ( isset( $query->pvc_orderby ) && $query->pvc_orderby ) || ( isset( $query->pvc_query ) && $query->pvc_query ) || apply_filters( 'pvc_extend_post_object', false, $query ) === true ) { |
| 134 | global $wpdb; |
| 135 | |
| 136 | $groupby = trim( $groupby ); |
| 137 | |
| 138 | if ( strpos( $groupby, $wpdb->prefix . 'posts.ID' ) === false ) |
| 139 | $groupby = ( $groupby !== '' ? $groupby . ', ' : '') . $wpdb->prefix . 'posts.ID'; |
| 140 | |
| 141 | if ( ! isset( $query->query['views_query']['hide_empty'] ) || $query->query['views_query']['hide_empty'] === true ) |
| 142 | $groupby .= ' HAVING post_views > 0'; |
| 143 | } |
| 144 | |
| 145 | return $groupby; |
| 146 | } |
| 147 | |
| 148 | /** |
| 149 | * Order posts by post views. |
| 150 | * |
| 151 | * @global object $wpdb |
| 152 | * @param string $orderby |
| 153 | * @param object $query |
| 154 | * @return string |
| 155 | */ |
| 156 | public function posts_orderby( $orderby, $query ) { |
| 157 | // is it sorted by post views? |
| 158 | if ( ( isset( $query->pvc_orderby ) && $query->pvc_orderby ) ) { |
| 159 | global $wpdb; |
| 160 | |
| 161 | $order = $query->get( 'order' ); |
| 162 | $orderby = ( ! isset( $query->query['views_query']['hide_empty'] ) || $query->query['views_query']['hide_empty'] === true ? 'post_views' : 'pvc.count' ) . ' ' . $order . ', ' . $wpdb->prefix . 'posts.ID ' . $order; |
| 163 | } |
| 164 | |
| 165 | return $orderby; |
| 166 | } |
| 167 | |
| 168 | /** |
| 169 | * Return post views in queried post objects. |
| 170 | * |
| 171 | * @param string $fields |
| 172 | * @param object $query |
| 173 | * @return string |
| 174 | */ |
| 175 | public function posts_fields( $fields, $query ) { |
| 176 | if ( ( ! isset( $query->query['fields'] ) || $query->query['fields'] === '' ) && ( ( isset( $query->pvc_orderby ) && $query->pvc_orderby ) || ( isset( $query->pvc_query ) && $query->pvc_query ) || apply_filters( 'pvc_extend_post_object', false, $query ) === true ) ) |
| 177 | $fields = $fields . ', SUM( IFNULL( pvc.count, 0 ) ) AS post_views'; |
| 178 | |
| 179 | return $fields; |
| 180 | } |
| 181 | |
| 182 | /** |
| 183 | * Extend query object with total post views. |
| 184 | * |
| 185 | * @param array $posts |
| 186 | * @param object $query |
| 187 | * @return array |
| 188 | */ |
| 189 | public function the_posts( $posts, $query ) { |
| 190 | if ( ( isset( $query->pvc_orderby ) && $query->pvc_orderby ) || ( isset( $query->pvc_query ) && $query->pvc_query ) || apply_filters( 'pvc_extend_post_object', false, $query ) === true ) { |
| 191 | $sum = 0; |
| 192 | |
| 193 | // any posts found? |
| 194 | if ( ! empty( $posts ) ) { |
| 195 | foreach ( $posts as $post ) { |
| 196 | if ( ! empty( $post->post_views ) ) |
| 197 | $sum += (int) $post->post_views; |
| 198 | } |
| 199 | } |
| 200 | |
| 201 | // pass total views |
| 202 | $query->total_views = $sum; |
| 203 | } |
| 204 | |
| 205 | return $posts; |
| 206 | } |
| 207 | |
| 208 | /** |
| 209 | * Validate date helper function. |
| 210 | * |
| 211 | * @param string $type |
| 212 | * @param int $year |
| 213 | * @param int $month |
| 214 | * @param int $day |
| 215 | * @param int $week |
| 216 | * @return bool |
| 217 | */ |
| 218 | private function is_valid_date( $type, $year = 0, $month = 0, $day = 0, $week = 0 ) { |
| 219 | switch( $type ) { |
| 220 | case 'y': |
| 221 | $bool = ( $year >= 1 && $year <= 32767 ); |
| 222 | break; |
| 223 | |
| 224 | case 'yw': |
| 225 | $bool = ( $year >= 1 && $year <= 32767 && $week >= 0 && $week <= 53 ); |
| 226 | break; |
| 227 | |
| 228 | case 'ym': |
| 229 | $bool = ( $year >= 1 && $year <= 32767 && $month >= 1 && $month <= 12 ); |
| 230 | break; |
| 231 | |
| 232 | case 'ymd': |
| 233 | $bool = checkdate( $month, $day, $year ); |
| 234 | break; |
| 235 | |
| 236 | case 'm': |
| 237 | $bool = ( $month >= 1 && $month <= 12 ); |
| 238 | break; |
| 239 | |
| 240 | case 'md': |
| 241 | $bool = ( $month >= 1 && $month <= 12 && $day >= 1 && $day <= 31 ); |
| 242 | break; |
| 243 | |
| 244 | case 'w': |
| 245 | $bool = ( $week >= 0 && $week <= 53 ); |
| 246 | break; |
| 247 | |
| 248 | case 'd': |
| 249 | $bool = ( $day >= 1 && $day <= 31 ); |
| 250 | break; |
| 251 | } |
| 252 | |
| 253 | return $bool; |
| 254 | } |
| 255 | } |