__( 'popular_post', 'top-10' ), // Singular name of the listed records. 'plural' => __( 'popular_posts', 'top-10' ), // plural name of the listed records. ) ); $this->all_post_type = array( 'all' => __( 'All post types', 'top-10' ), ); $this->network_wide = $network_wide; } /** * Retrieve the Top 10 posts * * @param int $per_page Posts per page. * @param int $page_number Page number. * @param array $args Array of arguments. * * @return array Array of popular posts */ public function get_popular_posts( $per_page = 20, $page_number = 1, $args = null ) { global $wpdb; // Initialise some variables. $fields = array(); $where = ''; $join = ''; $groupby = ''; $orderby = ''; $limits = ''; $sql = ''; $blog_id = get_current_blog_id(); $from_date = isset( $args['post-date-filter-from'] ) ? $args['post-date-filter-from'] : current_time( 'd M Y' ); $from_date = gmdate( 'Y-m-d', strtotime( $from_date ) ); $to_date = isset( $args['post-date-filter-to'] ) ? $args['post-date-filter-to'] : current_time( 'd M Y' ); $to_date = gmdate( 'Y-m-d', strtotime( $to_date ) ); /* Start creating the SQL */ $table_name_daily = $wpdb->base_prefix . 'top_ten_daily AS ttd'; $table_name = $wpdb->base_prefix . 'top_ten AS ttt'; // Fields to return. if ( ! $this->network_wide ) { $fields[] = "{$wpdb->posts}.post_title as title"; $fields[] = "{$wpdb->posts}.post_type"; $fields[] = "{$wpdb->posts}.post_date"; $fields[] = "{$wpdb->posts}.post_author"; } $fields[] = 'ttt.postnumber as ID'; $fields[] = 'ttt.cntaccess as total_count'; $fields[] = 'SUM(ttd.cntaccess) as daily_count'; $fields[] = 'ttt.blog_id as blog_id'; $fields = implode( ', ', $fields ); // Create the JOIN clause. if ( ! $this->network_wide ) { $join .= " LEFT JOIN {$wpdb->posts} ON ttt.postnumber={$wpdb->posts}.ID "; } $join .= $wpdb->prepare( " LEFT JOIN ( SELECT * FROM {$table_name_daily} " . // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared 'WHERE DATE(ttd.dp_date) >= DATE(%s) AND DATE(ttd.dp_date) <= DATE(%s) ) AS ttd ON ttt.postnumber=ttd.postnumber AND ttt.blog_id=ttd.blog_id ', $from_date, $to_date ); // Create the base WHERE clause. if ( ! $this->network_wide ) { $where .= $wpdb->prepare( ' AND ttt.blog_id = %d ', $blog_id ); // Posts need to be from the current blog only. $where .= " AND ($wpdb->posts.post_status = 'publish' OR $wpdb->posts.post_status = 'inherit') "; // Show published posts and attachments. // If search argument is set, do a search for it. if ( ! empty( $args['search'] ) ) { $where .= $wpdb->prepare( " AND $wpdb->posts.post_title LIKE %s ", '%' . $wpdb->esc_like( $args['search'] ) . '%' ); } // If post filter argument is set, do a search for it. if ( isset( $args['post-type-filter'] ) && $this->all_post_type['all'] !== $args['post-type-filter'] ) { $where .= $wpdb->prepare( " AND $wpdb->posts.post_type = %s ", $args['post-type-filter'] ); } else { $post_types = get_post_types( array( 'public' => true, ) ); $where .= " AND $wpdb->posts.post_type IN ('" . join( "', '", $post_types ) . "') "; } } // Create the base GROUP BY clause. $groupby = ' ttt.postnumber, ttt.blog_id '; // Create the ORDER BY clause. $orderby = ''; if ( ! empty( $_REQUEST['orderby'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended $orderby = sanitize_text_field( wp_unslash( $_REQUEST['orderby'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended } elseif ( ! empty( $args['orderby'] ) ) { $orderby = $args['orderby']; } if ( $orderby ) { if ( ! in_array( $orderby, array( 'title', 'daily_count', 'total_count' ) ) ) { //phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict $orderby = ' total_count '; } $order = ''; if ( ! empty( $_REQUEST['order'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended $order = sanitize_text_field( wp_unslash( $_REQUEST['order'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended } elseif ( ! empty( $args['order'] ) ) { $order = $args['order']; } if ( $order && in_array( $order, array( 'asc', 'ASC', 'desc', 'DESC' ), true ) ) { $orderby .= " {$order}"; } else { $orderby .= ' DESC'; } } else { $orderby = ' total_count DESC '; } // Create the base LIMITS clause. $limits = $wpdb->prepare( ' LIMIT %d, %d ', ( $page_number - 1 ) * $per_page, $per_page ); $groupby = " GROUP BY {$groupby} "; $orderby = " ORDER BY {$orderby} "; $sql = "SELECT $fields FROM {$table_name} $join WHERE 1=1 $where $groupby $orderby $limits"; $result = $wpdb->get_results( $sql, 'ARRAY_A' ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared return $result; } /** * Returns the count of records in the database. * * @param array $args Array of arguments. * @return null|string null|string */ public function record_count( $args = null ) { global $wpdb; $where = ''; $join = ''; $sql = "SELECT COUNT(*) FROM {$wpdb->base_prefix}top_ten as ttt"; if ( ! $this->network_wide ) { $join = "INNER JOIN {$wpdb->posts} ON ttt.postnumber=ID"; $where .= $wpdb->prepare( ' AND blog_id = %d ', get_current_blog_id() ); if ( ! empty( $args['search'] ) ) { $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_title LIKE %s ", '%' . $wpdb->esc_like( $args['search'] ) . '%' ); } if ( isset( $args['post-type-filter'] ) && $this->all_post_type['all'] !== $args['post-type-filter'] ) { $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_type = %s ", $args['post-type-filter'] ); } else { $post_types = get_post_types( array( 'public' => true, ) ); $where .= " AND $wpdb->posts.post_type IN ('" . join( "', '", $post_types ) . "') "; } } return $wpdb->get_var( "$sql $join WHERE 1=1 $where" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQL.InterpolatedNotPrepared } /** * Delete the post count for this post. * * @param int $id Post ID. * @param int $blog_id Blog ID. */ public static function delete_post_count( $id, $blog_id ) { \WebberZone\Top_Ten\Counter::delete_count( $id, $blog_id, false ); \WebberZone\Top_Ten\Counter::delete_count( $id, $blog_id, true ); } /** * Text displayed when no post data is available */ public function no_items() { esc_html_e( 'No popular posts available.', 'top-10' ); } /** * Render a column when no column specific method exist. * * @param array $item Current item. * @param string $column_name Column name. * * @return mixed */ public function column_default( $item, $column_name ) { switch ( $column_name ) { case 'daily_count': return \WebberZone\Top_Ten\Util\Helpers::number_format_i18n( absint( $item[ $column_name ] ) ); default: // Show the whole array for troubleshooting purposes. return ''; } } /** * Render the checkbox column. * * @param array $item Current item. * @return string */ public function column_cb( $item ) { return sprintf( '', 'bulk-delete', $item['ID'], $item['blog_id'] ); } /** * Render the title column. * * @param array $item Current item. * @return string */ public function column_title( $item ) { $delete_nonce = wp_create_nonce( 'tptn_delete_entry' ); $page = isset( $_REQUEST['page'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $post = $this->network_wide ? get_blog_post( $item['blog_id'], $item['ID'] ) : get_post( $item['ID'] ); if ( null === $post ) { return sprintf( '%s (id:%2$s)', __( 'Invalid post ID. This post might have been deleted.', 'top-10' ), $item['ID'] ); } $actions = array( 'view' => sprintf( '' . __( 'View', 'top-10' ) . '', get_permalink( $item['ID'] ) ), 'edit' => sprintf( '' . __( 'Edit', 'top-10' ) . '', get_edit_post_link( $item['ID'] ) ), 'delete' => sprintf( '' . __( 'Delete', 'top-10' ) . '', esc_attr( $page ), 'delete', absint( $item['ID'] ), absint( $item['blog_id'] ), $delete_nonce ), ); // Return the title contents. return sprintf( '%1$s (id:%2$s)%3$s', $post->post_title, $item['ID'], $this->network_wide ? '' : $this->row_actions( $actions ), is_multisite() ? get_blog_permalink( $item['blog_id'], $item['ID'] ) : get_permalink( $item['ID'] ) ); } /** * Handles the post date column output. * * @param array $item Current item. * @return string Post date. */ public function column_date( $item ) { $post = is_multisite() ? get_blog_post( $item['blog_id'], $item['ID'] ) : get_post( $item['ID'] ); if ( $post ) { $m_time = strtotime( $post->post_date ); $h_time = wp_date( get_option( 'date_format' ), $m_time ); return sprintf( '%1$s', esc_attr( $h_time ) ); } return ''; } /** * Handles the post_type column output. * * @param array $item Current item. * @return string Post Type. */ public function column_post_type( $item ) { $post = is_multisite() ? get_blog_post( $item['blog_id'], $item['ID'] ) : get_post( $item['ID'] ); if ( $post ) { $pt = get_post_type_object( $post->post_type ); if ( empty( $pt ) ) { return $post->post_type; } $name = isset( $pt->labels->singular_name ) ? $pt->labels->singular_name : $pt->labels->name; return $name; } return ''; } /** * Handles the post author column output. * * @param array $item Current item. * @return string Post Author. */ public function column_author( $item ) { $post = is_multisite() ? get_blog_post( $item['blog_id'], $item['ID'] ) : get_post( $item['ID'] ); if ( ! $post ) { return ''; } $author_info = get_userdata( (int) $post->post_author ); $author_name = ( false === $author_info ) ? '' : ucwords( trim( stripslashes( $author_info->display_name ) ) ); return sprintf( '%s', esc_url( add_query_arg( array( 'post_type' => $post->post_type, 'author' => ( false === $author_info ) ? 0 : $author_info->ID, ), get_admin_url( $item['blog_id'], 'edit.php' ) ) ), esc_html( $author_name ) ); } /** * Render the Total Count column. * * @param array $item Current item. * @return string */ public function column_total_count( $item ) { return sprintf( '