HEX
Server: LiteSpeed
System: Linux dal1.hostclusters.com 5.14.0-687.26.1.el9_8.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Jul 14 16:32:02 EDT 2026 x86_64
User: vslw (1496)
PHP: 8.0.30
Disabled: NONE
Upload Files
File: /home/vslw/public_html/wp-content/themes/soledad/inc/live_visitor.php
<?php

class penci_live_visitor_update {

	public function __construct() {
		// Register REST route early.
		add_action( 'rest_api_init', [ $this, 'register_routes' ] );
	
		// Skip if the feature is disabled.
		if ( ! get_theme_mod( 'penci_live_viewer_enable' ) ) {
			return;
		}
	
		// Delay other actions until WP query is ready.
		add_action( 'wp', [ $this, 'init_later' ] );
	}
	
	public function init_later() {
		if ( ! is_singular() ) {
			return;
		}
	
		$post_type = get_post_type();
		if ( get_theme_mod( 'penci_live_viewer_disable_' . $post_type ) ) {
			return;
		}
	
		add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
		add_action( 'wp_footer', [ $this, 'view_content' ] );
		add_action( 'soledad_theme/custom_css', [ $this, 'popup_style' ] );
	}

	public function view_content() {
		$pos = get_theme_mod( 'penci_live_viewer_position', 'bottom-left' );
		echo '<div id="visitor-count" class="penci-visitor-count ' . esc_attr( $pos ) . '"></div>';
	}

	// Register REST routes
	public function register_routes() {
		register_rest_route( 'livevisitor/v1', '/update/(?P<post_id>\d+)', [
			'methods'             => 'POST',
			'callback'            => [ $this, 'update_visitor' ],
			'permission_callback' => '__return_true',
		] );

		register_rest_route( 'livevisitor/v1', '/count/(?P<post_id>\d+)', [
			'methods'             => 'GET',
			'callback'            => [ $this, 'count_visitor' ],
			'permission_callback' => '__return_true',
		] );
	}

	// Update visitor count
	public function update_visitor( $request ) {
		$post_id = (int) $request['post_id'];

		// Get visitor's IP address
		$visitor_ip = $_SERVER['REMOTE_ADDR'];

		// Fetch the current list of visitor IPs (or initialize an empty array)
		$visitors = get_transient( 'livevisitor_ips_' . $post_id ) ?: [];

		// Add visitor IP if it's not already in the list
		if ( ! in_array( $visitor_ip, $visitors ) ) {
			$visitors[] = $visitor_ip;
		}

		// Save the updated list of visitor IPs back to transient with expiration of 30 seconds
		set_transient( 'livevisitor_ips_' . $post_id, $visitors, 30 );

		return [ 'status' => 'ok' ];
	}

	// Get current visitor count based on IP addresses
	public function count_visitor( $request ) {
		$post_id = (int) $request['post_id'];

		// Get the list of visitor IPs for this post
		$visitors = get_transient( 'livevisitor_ips_' . $post_id ) ?: [];

		// Return the number of unique visitors (IP count)
		return [ 'count' => count( $visitors ) ];
	}

	// Enqueue JS file
	public function enqueue_scripts() {
		if ( is_singular() ) {
			// Enqueue JS file
			wp_enqueue_script(
				'penci-live-visitor-counter',
				PENCI_SOLEDAD_URL . '/js/live-visitor.js',
				[],
				null,
				true
			);

			$post_id = get_the_ID();
        	$post_type_object = get_post_type_object( get_post_type( $post_id ) );
        	$object_label = $post_type_object ? strtolower( $post_type_object->labels->singular_name ) : 'post';


			// Localize the post ID to JavaScript
			wp_localize_script( 'penci-live-visitor-counter', 'penci_live_visitor', [
				'post_id'        => $post_id,
				'object_label'   => $object_label,
				'singular_text'  => get_theme_mod('penci_live_viewer_singular_text', '1 viewer reading this {object}'),
				'plural_text'    => get_theme_mod('penci_live_viewer_plural_text', '{view} viewers are reading this {object}')
			] );
		}
	}

	public function popup_style() {
		$color = get_theme_mod( 'penci_live_viewer_color' );
		$bgcolor = get_theme_mod( 'penci_live_viewer_bgcolor' );
		if ( $color ) {
			echo '.penci-visitor-count{
				color: ' . esc_attr( $color ) . ';
			}';
		}
		if ( $bgcolor ) {
			echo '.penci-visitor-count{
				background: ' . esc_attr( $bgcolor ) . ';
			}';
		}
	}
}

// Initialize the class
new penci_live_visitor_update();