Количество просмотров записей WordPress без плагина

Самый простой способ вывести количество просмотров записей, это установить плагин Post Views Counter

snimok jekrana 2025 12 19 v 18.32.36
snimok jekrana 2025 10 23 v 23.26.53

Чтобы вывести на страницу записи, добавьте шорткод [ post-views ]

snimok jekrana 2025 10 24 v 12.02.04

Количество просмотров записей без плагина

snimok jekrana 2025 12 19 v 18.46.17

Или Вы можете сделать без плагина, добавьте сниппет код:

/* Defaults / configuration */
if ( ! defined( 'AVS_PV_COOKIE_TTL' ) ) define( 'AVS_PV_COOKIE_TTL', 12 * HOUR_IN_SECONDS );
if ( ! defined( 'AVS_PV_BUFFER_TTL' ) ) define( 'AVS_PV_BUFFER_TTL', HOUR_IN_SECONDS );
if ( ! defined( 'AVS_PV_BUFFER_THRESHOLD' ) ) define( 'AVS_PV_BUFFER_THRESHOLD', 10 );
if ( ! defined( 'AVS_PV_VISITOR_TTL' ) ) define( 'AVS_PV_VISITOR_TTL', AVS_PV_COOKIE_TTL );
if ( ! defined( 'AVS_PV_TABLE' ) ) define( 'AVS_PV_TABLE', 'avs_post_views' );
if ( ! defined( 'AVS_PV_DIRTY_KEY' ) ) define( 'AVS_PV_DIRTY_KEY', 'avs_pv_dirty_posts' );
if ( ! defined( 'AVS_PV_CRON_HOOK' ) ) define( 'AVS_PV_CRON_HOOK', 'avs_pv_flush_buffers_cron' );

function avs_pv_get_client_ip() {
	$keys = array( 'HTTP_CF_CONNECTING_IP', 'HTTP_X_REAL_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR' );
	foreach ( $keys as $key ) {
		if ( empty( $_SERVER[ $key ] ) ) continue;
		$value = (string) $_SERVER[ $key ];
		if ( 'HTTP_X_FORWARDED_FOR' === $key ) {
			$parts = array_map( 'trim', explode( ',', $value ) );
			$value = $parts[0] ?? $value;
		}
		if ( filter_var( trim( $value ), FILTER_VALIDATE_IP ) ) {
			return trim( $value );
		}
	}
	return '0.0.0.0';
}

function avs_pv_is_prefetch_request() {
	$headers = array(
		'HTTP_X_MOZ',
		'HTTP_PURPOSE',
		'HTTP_X_PURPOSE',
		'HTTP_SEC_PURPOSE',
		'HTTP_X_MIDDLETON_PREFETCH',
	);

	foreach ( $headers as $h ) {
		if ( empty( $_SERVER[ $h ] ) ) continue;
		$val = strtolower( trim( (string) $_SERVER[ $h ] ) );
		if ( strpos( $val, 'prefetch' ) !== false || strpos( $val, 'prerender' ) !== false ) {
			return true;
		}
	}

	if ( ! empty( $_SERVER['HTTP_SEC_FETCH_MODE'] ) ) {
		$mode = strtolower( trim( (string) $_SERVER['HTTP_SEC_FETCH_MODE'] ) );
		if ( in_array( $mode, array( 'prefetch', 'prerender' ), true ) ) {
			return true;
		}
	}

	return false;
}

function avs_pv_should_skip_current_user() {
	if ( ! is_user_logged_in() ) return false;
	$user = wp_get_current_user();
	if ( ! $user || empty( $user->roles ) ) return false;

	$excluded_roles = apply_filters( 'avs_pv_excluded_roles', array( 'administrator', 'editor', 'author', 'shop_manager' ) );
	if ( ! is_array( $excluded_roles ) ) $excluded_roles = array();

	return (bool) array_intersect( (array) $user->roles, $excluded_roles );
}

function avs_pv_cookie_name( $post_id ) {
	return 'avs_pv_' . (int) $post_id;
}

function avs_pv_visitor_lock_key( $post_id ) {
	$post_id = (int) $post_id;
	$user_id = get_current_user_id();
	if ( $user_id > 0 ) {
		return 'avs_pv_v_' . $post_id . '_u_' . $user_id;
	}

	$ip = avs_pv_get_client_ip();
	$ua = ! empty( $_SERVER['HTTP_USER_AGENT'] ) ? strtolower( trim( (string) wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) ) : '';
	return 'avs_pv_v_' . $post_id . '_g_' . md5( $ip . '|' . $ua );
}

function avs_pv_has_recent_visitor_hit( $post_id ) {
	$post_id = (int) $post_id;
	if ( $post_id <= 0 ) return false;

	$cookie = avs_pv_cookie_name( $post_id );
	if ( ! empty( $_COOKIE[ $cookie ] ) ) {
		return true;
	}

	$lock_key = avs_pv_visitor_lock_key( $post_id );
	return (bool) get_transient( $lock_key );
}

function avs_pv_mark_visitor_hit( $post_id ) {
	$post_id = (int) $post_id;
	if ( $post_id <= 0 ) return;

	$ttl = (int) apply_filters( 'avs_pv_visitor_ttl', AVS_PV_VISITOR_TTL );
	if ( $ttl <= 0 ) $ttl = AVS_PV_VISITOR_TTL;

	$cookie = avs_pv_cookie_name( $post_id );
	$path   = defined( 'COOKIEPATH' ) ? COOKIEPATH : '/';
	$domain = defined( 'COOKIE_DOMAIN' ) ? COOKIE_DOMAIN : '';
	@setcookie( $cookie, '1', time() + $ttl, $path ?: '/', $domain ?: '', is_ssl(), true );
	$_COOKIE[ $cookie ] = '1';

	set_transient( avs_pv_visitor_lock_key( $post_id ), 1, $ttl );
}

/* Create DB table if missing */
add_action( 'init', 'avs_pv_maybe_create_table', 5 );
function avs_pv_maybe_create_table() {
	global $wpdb;
	$tbl = $wpdb->prefix . AVS_PV_TABLE;
	$exists = $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $tbl ) );
	if ( $exists === $tbl ) return;

	require_once ABSPATH . 'wp-admin/includes/upgrade.php';
	$charset_collate = $wpdb->get_charset_collate();

	$sql = "CREATE TABLE {$tbl} (
		post_id bigint unsigned NOT NULL,
		views bigint unsigned NOT NULL DEFAULT 0,
		last_updated datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
		PRIMARY KEY (post_id)
	) {$charset_collate};";

	dbDelta( $sql );
}

/* Server-side counting for uncached requests (single posts) */
add_action( 'template_redirect', 'avs_pv_maybe_count' );
function avs_pv_maybe_count() {
	if ( is_admin() ) return;
	if ( ! is_singular() ) return;
	if ( ! is_main_query() ) return;
	if ( 'GET' !== ( $_SERVER['REQUEST_METHOD'] ?? '' ) ) return;

	global $post;
	if ( empty( $post ) || empty( $post->ID ) ) return;
	$post_id = (int) $post->ID;

	if ( get_post_type( $post_id ) !== 'post' ) return;
	if ( is_preview() || wp_is_post_revision( $post_id ) ) return;
	if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) return;
	if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) return;
	if ( avs_pv_should_skip_current_user() ) return;
	if ( avs_pv_is_prefetch_request() ) return;

	if ( avs_pv_is_bot() ) return;
	if ( avs_pv_has_recent_visitor_hit( $post_id ) ) return;

	avs_pv_buffer_increment( $post_id );
	avs_pv_mark_visitor_hit( $post_id );
}

/* REST API: hit and views */
add_action( 'rest_api_init', function() {
	register_rest_route( 'avs/v1', '/post/(?P<id>\d+)/hit', array(
		'methods'  => 'POST',
		'callback' => 'avs_pv_rest_hit_callback',
		'permission_callback' => '__return_true',
	) );
	register_rest_route( 'avs/v1', '/post/(?P<id>\d+)/views', array(
		'methods'  => 'GET',
		'callback' => function( $request ) {
			$id = (int) $request['id'];
			if ( $id <= 0 ) return new WP_Error( 'invalid_id', 'Invalid post ID', array( 'status' => 400 ) );
			return rest_ensure_response( array( 'views' => avs_pv_get_views( $id ) ) );
		},
		'permission_callback' => '__return_true',
	) );
} );

function avs_pv_rest_hit_callback( $request ) {
	$id = (int) $request['id'];
	if ( $id <= 0 ) return new WP_Error( 'invalid_id', 'Invalid post ID', array( 'status' => 400 ) );
	if ( get_post_type( $id ) !== 'post' ) return new WP_Error( 'wrong_type', 'Not a standard post', array( 'status' => 400 ) );

	$site_host = parse_url( home_url(), PHP_URL_HOST );
	$allowed = false;
	if ( ! empty( $_SERVER['HTTP_ORIGIN'] ) ) {
		$origin_host = parse_url( wp_unslash( $_SERVER['HTTP_ORIGIN'] ), PHP_URL_HOST );
		if ( $origin_host === $site_host ) $allowed = true;
	}
	if ( ! $allowed && ! empty( $_SERVER['HTTP_REFERER'] ) ) {
		$ref_host = parse_url( wp_unslash( $_SERVER['HTTP_REFERER'] ), PHP_URL_HOST );
		if ( $ref_host === $site_host ) $allowed = true;
	}
	if ( ! $allowed ) {
		return new WP_Error( 'forbidden_origin', 'Forbidden', array( 'status' => 403 ) );
	}

	if ( avs_pv_should_skip_current_user() || avs_pv_is_prefetch_request() ) {
		return rest_ensure_response( array( 'ok' => false, 'skipped' => true ) );
	}

	if ( avs_pv_is_bot() ) {
		return rest_ensure_response( array( 'ok' => false, 'bot' => true ) );
	}
	if ( avs_pv_has_recent_visitor_hit( $id ) ) {
		return rest_ensure_response( array( 'ok' => true, 'message' => 'already' ) );
	}

	avs_pv_buffer_increment( $id );
	avs_pv_mark_visitor_hit( $id );

	return rest_ensure_response( array( 'ok' => true ) );
}

/* Simple bot detection (filterable) */
function avs_pv_is_bot() {
	$forced = apply_filters( 'avs_pv_is_bot', null );
	if ( $forced !== null ) return (bool) $forced;

	$ua = ! empty( $_SERVER['HTTP_USER_AGENT'] ) ? strtolower( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : '';
	if ( $ua === '' ) return true;

	$bots = apply_filters( 'avs_pv_bot_useragents', array(
		'bot','crawl','slurp','googlebot','bingbot','yandex','facebookexternalhit','facebot',
		'ahrefs','semrush','curl','wget','python-requests','php','libwww-perl'
	) );

	foreach ( $bots as $b ) {
		$b = trim( strtolower( $b ) );
		if ( $b === '' ) continue;
		if ( strpos( $ua, $b ) !== false ) return true;
	}

	if ( ! empty( $_SERVER['HTTP_ACCEPT'] ) ) {
		$accept = strtolower( $_SERVER['HTTP_ACCEPT'] );
		if ( strpos( $accept, 'text/html' ) === false && strpos( $accept, '*/*' ) === false ) return true;
	}

	return false;
}

/* Buffer increment (object cache preferred) + dirty tracking */
function avs_pv_buffer_increment( $post_id ) {
	$post_id = (int) $post_id;
	if ( $post_id <= 0 ) return false;

	$key = "avs_pv_buffer_{$post_id}";
	$use_cache = wp_using_ext_object_cache();
	$ttl = (int) apply_filters( 'avs_pv_buffer_ttl', AVS_PV_BUFFER_TTL );
	$threshold = (int) apply_filters( 'avs_pv_buffer_threshold', AVS_PV_BUFFER_THRESHOLD );

	if ( $use_cache ) {
		$buf = (int) wp_cache_get( $key, 'avs_pv' );
		$buf++;
		wp_cache_set( $key, $buf, 'avs_pv', $ttl );
	} else {
		$buf = (int) get_transient( $key );
		$buf++;
		set_transient( $key, $buf, $ttl );
	}

	$dirty_key = AVS_PV_DIRTY_KEY;
	$dirty = get_transient( $dirty_key );
	if ( ! is_array( $dirty ) ) $dirty = array();
	if ( ! in_array( $post_id, $dirty, true ) ) {
		$dirty[] = $post_id;
		set_transient( $dirty_key, $dirty, DAY_IN_SECONDS );
	}

	if ( $buf >= $threshold ) {
		if ( function_exists( 'as_enqueue_async_action' ) ) {
			as_enqueue_async_action( 'avs_pv_flush_single_action', array( 'post_id' => $post_id ), 'avs-pv' );
		} elseif ( function_exists( 'as_schedule_single_action' ) ) {
			as_schedule_single_action( time() + 1, 'avs_pv_flush_single_action', array( 'post_id' => $post_id ), 'avs-pv' );
		} else {
			avs_pv_flush_post_buffer( $post_id );
		}
	}

	return true;
}

/* Action Scheduler handler */
add_action( 'avs_pv_flush_single_action', 'avs_pv_as_single_flush_handler', 10, 1 );
function avs_pv_as_single_flush_handler( $args ) {
	if ( empty( $args['post_id'] ) ) return;
	avs_pv_flush_post_buffer( (int) $args['post_id'] );
}

/* Flush buffer to DB */
function avs_pv_flush_post_buffer( $post_id ) {
	global $wpdb;
	$post_id = (int) $post_id;
	if ( $post_id <= 0 ) return false;

	$key = "avs_pv_buffer_{$post_id}";
	$use_cache = wp_using_ext_object_cache();

	$buffer = $use_cache ? (int) wp_cache_get( $key, 'avs_pv' ) : (int) get_transient( $key );
	if ( $buffer <= 0 ) {
		avs_pv_remove_dirty( $post_id );
		return false;
	}

	$table = $wpdb->prefix . AVS_PV_TABLE;
	$now   = current_time( 'mysql', 1 );

	$sql = $wpdb->prepare(
		"INSERT INTO {$table} (post_id, views, last_updated) VALUES (%d, %d, %s)
		 ON DUPLICATE KEY UPDATE views = views + %d, last_updated = %s",
		$post_id, $buffer, $now, $buffer, $now
	);

	$wpdb->query( $sql );

	if ( $use_cache ) wp_cache_delete( $key, 'avs_pv' );
	else delete_transient( $key );

	avs_pv_remove_dirty( $post_id );
	return true;
}

function avs_pv_remove_dirty( $post_id ) {
	$dirty_key = AVS_PV_DIRTY_KEY;
	$dirty = get_transient( $dirty_key );
	if ( ! is_array( $dirty ) ) return;
	$idx = array_search( $post_id, $dirty, true );
	if ( $idx !== false ) {
		array_splice( $dirty, $idx, 1 );
		set_transient( $dirty_key, $dirty, DAY_IN_SECONDS );
	}
}

/* Periodic flush runner: Action Scheduler preferred, WP-Cron fallback (5 minutes) */
add_action( 'wp_loaded', 'avs_pv_schedule_flush_runner' );
function avs_pv_schedule_flush_runner() {
	$hook = AVS_PV_CRON_HOOK;

	if ( function_exists( 'as_schedule_recurring_action' ) && function_exists( 'as_next_scheduled_action' ) ) {
		if ( ! as_next_scheduled_action( 'avs_pv_as_cron' ) ) {
			as_schedule_recurring_action( time() + 60, 5 * MINUTE_IN_SECONDS, 'avs_pv_as_cron', array(), 'avs-pv' );
		}
		add_action( 'avs_pv_as_cron', 'avs_pv_cron_flush' );
		return;
	}

	if ( ! wp_next_scheduled( $hook ) ) {
		wp_schedule_event( time() + 60, 'avs_pv_5min', $hook );
	}
	add_action( $hook, 'avs_pv_cron_flush' );
}

add_filter( 'cron_schedules', function( $schedules ) {
	if ( empty( $schedules['avs_pv_5min'] ) ) {
		$schedules['avs_pv_5min'] = array(
			'interval' => 5 * MINUTE_IN_SECONDS,
			'display'  => 'AVS every 5 minutes'
		);
	}
	return $schedules;
} );

function avs_pv_cron_flush() {
	$dirty_key = AVS_PV_DIRTY_KEY;
	$dirty = get_transient( $dirty_key );
	if ( ! is_array( $dirty ) || empty( $dirty ) ) return;

	set_transient( $dirty_key, array(), DAY_IN_SECONDS );

	foreach ( $dirty as $post_id ) {
		avs_pv_flush_post_buffer( (int) $post_id );
	}
}

/* Read helper: DB + buffered */
function avs_pv_get_views( $post_id = 0 ) {
	global $wpdb;
	$post_id = (int) $post_id;
	if ( $post_id <= 0 ) $post_id = get_the_ID();
	if ( $post_id <= 0 ) return 0;
	if ( get_post_type( $post_id ) !== 'post' ) return 0;

	$table = $wpdb->prefix . AVS_PV_TABLE;
	$row = $wpdb->get_row( $wpdb->prepare( "SELECT views FROM {$table} WHERE post_id = %d LIMIT 1", $post_id ), ARRAY_A );
	$db_views = ( $row && isset( $row['views'] ) ) ? (int) $row['views'] : 0;

	$key = "avs_pv_buffer_{$post_id}";
	$use_cache = wp_using_ext_object_cache();
	$buffer = $use_cache ? (int) wp_cache_get( $key, 'avs_pv' ) : (int) get_transient( $key );

	return $db_views + max(0, $buffer);
}

/* Cached read helper */
function avs_pv_get_views_cached( $post_id = 0, $ttl = 60 ) {
	$post_id = (int) $post_id;
	if ( $post_id <= 0 ) $post_id = get_the_ID();
	if ( $post_id <= 0 ) return 0;
	if ( get_post_type( $post_id ) !== 'post' ) return 0;

	$cache_key = "avs_pv_views_{$post_id}";
	$cached = wp_cache_get( $cache_key, 'avs_pv' );
	if ( $cached !== false ) {
		return (int) $cached;
	}

	$views = avs_pv_get_views( $post_id );
	wp_cache_set( $cache_key, (int) $views, 'avs_pv', $ttl );
	return (int) $views;
}

/* Shortcode: server-side rendering to avoid flicker */
add_shortcode( 'avs_post_views_container', function( $atts ) {
	$atts = shortcode_atts( array( 'id' => 0, 'cache_ttl' => 60 ), $atts, 'avs_post_views_container' );
	$post_id = (int) $atts['id'];
	if ( $post_id <= 0 ) $post_id = get_the_ID();
	if ( ! $post_id ) return '<span class="avs-post-views" data-post-id="">0</span>';

	$ttl = (int) $atts['cache_ttl'];
	if ( $ttl < 0 ) $ttl = 0;

	$views = $ttl > 0 ? avs_pv_get_views_cached( $post_id, $ttl ) : avs_pv_get_views( $post_id );

	return '<span class="avs-post-views" data-post-id="' . esc_attr( $post_id ) . '">' . intval( $views ) . '</span>';
} );

/* Admin: add "Просмотры" column (appended last) and make it sortable */
add_filter( 'manage_edit-post_columns', 'avs_admin_add_views_column' );
function avs_admin_add_views_column( $columns ) {
	$columns['avs_views'] = __( 'Просмотры', 'avs' );
	return $columns;
}

add_action( 'manage_post_posts_custom_column', 'avs_admin_render_views_column', 10, 2 );
function avs_admin_render_views_column( $column, $post_id ) {
	if ( 'avs_views' !== $column ) return;

	if ( function_exists( 'avs_pv_get_views_cached' ) ) {
		$views = avs_pv_get_views_cached( $post_id, 30 );
	} else {
		$views = function_exists( 'avs_pv_get_views' ) ? avs_pv_get_views( $post_id ) : 0;
	}

	echo '<span class="avs-views-count">' . intval( $views ) . '</span>';
}

add_filter( 'manage_edit-post_sortable_columns', 'avs_admin_make_views_sortable' );
function avs_admin_make_views_sortable( $sortable ) {
	$sortable['avs_views'] = 'avs_views';
	return $sortable;
}

add_filter( 'posts_join', 'avs_admin_posts_join_for_views', 10, 2 );
function avs_admin_posts_join_for_views( $join, $query ) {
	if ( ! is_admin() || ! $query->is_main_query() ) return $join;
	$orderby = $query->get( 'orderby' );
	$post_type = $query->get( 'post_type' );
	if ( 'avs_views' === $orderby && ( ! $post_type || 'post' === $post_type ) ) {
		global $wpdb;
		$tbl = $wpdb->prefix . ( defined( 'AVS_PV_TABLE' ) ? AVS_PV_TABLE : 'avs_post_views' );
		$join .= " LEFT JOIN {$tbl} AS avs_views_table ON avs_views_table.post_id = {$wpdb->posts}.ID ";
	}
	return $join;
}

add_filter( 'posts_orderby', 'avs_admin_posts_orderby_for_views', 10, 2 );
function avs_admin_posts_orderby_for_views( $orderby_sql, $query ) {
	if ( ! is_admin() || ! $query->is_main_query() ) return $orderby_sql;
	$orderby = $query->get( 'orderby' );
	$post_type = $query->get( 'post_type' );
	if ( 'avs_views' === $orderby && ( ! $post_type || 'post' === $post_type ) ) {
		$order = strtoupper( $query->get( 'order' ) ) === 'ASC' ? 'ASC' : 'DESC';
		$orderby_sql = " COALESCE(avs_views_table.views,0) {$order} ";
	}
	return $orderby_sql;
}

/* Optional admin CSS */
add_action( 'admin_head-edit.php', 'avs_admin_column_css' );
function avs_admin_column_css() {
	?>
	<style>
		.wp-list-table .column-avs_views { width: 8%; text-align: left; }
		.avs-views-count { display: inline-block; min-width: 30px; text-align: left; }
	</style>
	<?php
}

/**
 * Шорткод [avs_post_views] — число просмотров из основного AVS-счетчика
 */
add_shortcode( 'avs_post_views', function( $atts ) {
	$atts = shortcode_atts( array( 'id' => 0, 'cache_ttl' => 60 ), $atts, 'avs_post_views' );

	$post_id = (int) $atts['id'];
	if ( $post_id <= 0 ) {
		$post_id = get_the_ID();
	}
	if ( $post_id <= 0 ) {
		return '0';
	}

	$ttl = max( 0, (int) $atts['cache_ttl'] );
	$views = $ttl > 0 ? avs_pv_get_views_cached( $post_id, $ttl ) : avs_pv_get_views( $post_id );

	return (string) number_format_i18n( (int) $views );
} );

Вывести количество просмотров шоркодом [ avs_post_views ]


Админке также появится сортируемый столбец с количеством просмотров.
Количество просмотров считается только для стандартных записей WordPress, чтобы вывести кол-во просмотров для CCT и CPT, то необходимо изменить php.

Picture of Автор: Александра

Автор: Александра

@avsalexandra
Занимаюсь натуральным питанием собак и кошек BARF. Wordpress для души ☺️

Crocoblock
Elementor
Gutenberg
Jetengine
Jetformbuilder
profile builder
Woocommerce
Wordpress
WYSIWYG
Лейка
#публикация постов
#видео
#доменная почта
#рассылка
#бейдж
#благотворительность
#заказ ожидает
#подарок
#подчёркивание
#vk
#автосохранение
#пожертвования
#мультивыбор
#роли
#drag and drop
#изображения товаров
#подписки
#цена
#отменить заказ
#самозанятый
#чеки
#мой налог
#alt text
#галерея товара
#возврат
#видео товара
Комментарии:

Добавить комментарий