<?php
/**
 * Рейтинг 5 звезд
 * 
 * Формирует разметку рейтинга в соответствии с записанным в базе рейтингом текущего поста.
 * Создает нужные таблицы автоматически если их нет.
 * Может добавить фейковый рейтинг.
 * 
 * 
 * @param object $lib_construct
 * @param array $options
 *
 * @author veselka.ua
 * @version 0.12
 *
 * @package veselka_ua/themes
 */

class RatingStarPrint {

	use FileHandling, TemplatesLoad;

	/**
	 * Объект обработки библиотек.
	 * @type object
	 */
	private $lib_kit;
	/**
	 * Массив параметров.
	 * @type array
	 */
	private $options;
	/**
	 * Замены маркеров.
	 * @type array
	 */
	private $replacement;
	/**
	 * Результат работы.
	 * @type string
	 */
	private $result_set;


	public function __construct() {

		/**
		 * Хук для получение объекта с общими методами.
		 */
		add_action( 'wp_lib_construct_exchange', [$this, 'get_wp_lib_construct'], 20, 1 );


		// Инициализация
		$this->options['init'] = false;

		// В крючке вызывается метод обертка
		add_action( 'post_star_rating', [$this, 'get_post_star_rating'], 20, 0 );
		// В крючке вызывается метод обертка
		add_action( 'tax_star_rating', [$this, 'get_tax_star_rating'], 30, 0 );
	}


//////////////////// Публичные методы ////////////////////


	/**
	 * функция хука для получения общего объекта по ссылке.
	 *
	 * Сортировка.
	 *
	 * @param object $lib_construct
	 * @return void
	 */
	final public function get_wp_lib_construct( $lib_construct ){
		// Объект с общими методами в локальное свойство
		$this->lib_kit = $lib_construct;
	}


	/**
	 * Звездный рейтинг в записях
	 * Оберткка для получения результата работы
	 *
	 * @param void
	 * @return string
	 */
	public function get_post_star_rating() {
		// Режим работы ( post/tax )
		$this->options['mode'] = 'post';
		// Инициализация
		$this->load();
		// Вывод результата
		echo $this->result_set;
	}


	/**
	 * Звездный рейтинг в таксономиях
	 * Оберткка для получения результата работы
	 *
	 * @param void
	 * @return string
	 */
	public function get_tax_star_rating() {
		// Режим работы ( post/tax )
		$this->options['mode'] = 'tax';
		// Инициализация
		$this->load();
		// Вывод результата
		echo $this->result_set;
	}


//////////////////// Приватные методы ////////////////////


	/**
	 * Инициализация.
	 *
	 * @param void
	 * @return void
	 */
	private function load() {

		// Уже загружалось?
		if( !$this->options['init'] ) {
			// Параметры по умолчанию
			$this->options['post_votes_table_name'] = 'star_rating_post';
			$this->options['tax_votes_table_name'] = 'star_rating_tax';
			$this->options['files']['star_rating'] = 'star_rating.php';
			$this->options['on'] = true;
			$this->options['install'] = true;
			$this->options['debug'] = false; // Check DB tables anyway
			$this->options['fake_data'] = true;
			$this->options['lib'] = false;
			// Инициализация завершена
			$this->options['init'] = true;
		}
		// Загрузка библиотек
		if( !$this->options['lib'] ) {
			$this->lib_kit->set_new_lib('star_rating');
			$this->options['lib'] = true;
		}
		// Рейтинг текущего поста
		$this->set_rating_html();
	}


	/**
	 * Формирование разметки рейтинга.
	 *
	 * @param void
	 * @return void
	 */
	private function set_rating_html() {

		$this->result_set = true;

		if( $this->options['mode'] == 'post' ) {
			// Номер текущего поста
			$this->replacement['id'] = get_the_id();
			$this->replacement['item_reviewed'] = get_the_title();
		} elseif( $this->options['mode'] == 'tax' ) {
			// Номеер текущей таксономии
			$queried_object = get_queried_object();
			$this->replacement['id'] = $queried_object->term_id;
			$this->replacement['item_reviewed'] = $queried_object->name;
		} else {
			$this->result_set = false;
			return true;
		}

		// Получение данных из базы
		$this->{'check_'.$this->options['mode'].'_db'}();
	
		// Селекторы
		$this->replacement['class'] = '';
		// Data атрибуты
		$this->replacement['data'] = ' data-mode="'.$this->options['mode'].'" data-id="'.$this->replacement['id'].'"';

		// Текстовые даные рейтинга
		$this->replacement['rating_label'] = __( 'Rating: ', 'spiral' );
		$this->replacement['votes_label'] = __( 'Votes: ', 'spiral' );

		if( !$this->result_set ) {
			return true;
		}
		// Формирование значений для замены
		$total = floatval($this->replacement['total']);
		$total = round($total);
		for( $i = 1; $i <= 5; $i++ ) {
			if( $total >= $i ) {
				$this->replacement['empty-' . $i] = '';
			} else {
				$this->replacement['empty-' . $i] = '-o';
			}
		}
		// Замена маркеров значениями
		$this->result_set = $this->template_replacement( $this->replacement, 'star_rating', 'view' );
	}


	/**
	 * Установка рейтинга для записей.
	 * Создание таблицы в базе данных.
	 * Запись фекового рейтинга.
	 *
	 * @param void
	 * @return void
	 */
	private function check_post_db() {

		// Флаг проверки базы
		$check_db = false;

		// Получение рейтинга
		$total = get_post_meta( (int)$this->replacement['id'], 'rating_total', true );
		// Если еще нет, создаем
		if( $total == '' ) {
			$total = $this->randomize_timer('total');
			add_post_meta( (int)$this->replacement['id'], 'rating_total', $total, true );
			$check_db = true;
		}
		$this->replacement['total'] = round( $total, 1 );

		// Получение количества голосов
		$votes = get_post_meta( (int)$this->replacement['id'], 'rating_votes', true );
		// Если еще нет, создаем
		if( $votes == '' ) {
			$votes = $this->randomize_timer('votes');
			add_post_meta( (int)$this->replacement['id'], 'rating_votes', $votes, true );
			$check_db = true;
		}
		$this->replacement['votes'] = $votes;

		// Проверка наличия таблицы для детализации рейтинга
		if( $check_db || $this->options['debug'] ) {
			global $wpdb;
			$table_name = $wpdb->prefix . $this->options['post_votes_table_name'];
			if( $wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name && $this->options['install'] ) {
				$sql_create_table = "CREATE TABLE IF NOT EXISTS `". $table_name ."` (
					`id` INT(11) NOT NULL AUTO_INCREMENT,
					`id_post` INT(11) NOT NULL,
					`ip` VARCHAR(32) NOT NULL,
					`agent` VARCHAR(32) NOT NULL,
					PRIMARY KEY (`id`)
					) ENGINE=InnoDB";
				$wpdb->query($sql_create_table);
			}
		}
	}


	/**
	 * Установка рейтинга для таксономий.
	 * Создание таблицы в базе данных.
	 * Запись фекового рейтинга.
	 *
	 * @param void
	 * @return void
	 */
	private function check_tax_db() {

		$check_db = false;
		// Получение рейтинга
		$total = get_term_meta( (int)$this->replacement['id'], 'cat_rating_total', true );
		// Если еще нет, создаем
		if( !(bool)$total ) {
			$total = $this->randomize_timer('total');
			add_term_meta( (int)$this->replacement['id'], 'cat_rating_total', $total, true );
			$check_db = true;
		}
		$this->replacement['total'] = round( $total, 1 );
		// Получение Количества голосов
		$votes = get_term_meta( (int)$this->replacement['id'], 'cat_rating_votes', true );
		// Если еще нет, создаем
		if( !(bool)$votes ) {
			$votes = $this->randomize_timer('votes');
			add_term_meta( (int)$this->replacement['id'], 'cat_rating_votes', $votes, true );
			$check_db = true;
		}
		$this->replacement['votes'] = $votes;

		// Проверка наличия таблицы для детализации рейтинга
		if( $check_db || $this->options['debug'] ) {
			global $wpdb;
			$table_name = $wpdb->prefix . $this->options['tax_votes_table_name'];
			if( $wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name && $this->options['install'] ) {
				$sql_create_table = "CREATE TABLE IF NOT EXISTS `". $table_name ."` (
					`id` INT(11) NOT NULL AUTO_INCREMENT,
					`id_tax` INT(11) NOT NULL,
					`ip` VARCHAR(32) NOT NULL,
					`agent` VARCHAR(32) NOT NULL,
					PRIMARY KEY (`id`)
					) ENGINE=InnoDB";
				$wpdb->query($sql_create_table);
			}
		}
	}


	/**
	 * Генератор случайных значений.
	 *
	 * @param string $mode
	 * @return string $result_set
	 */
	private function randomize_timer($mode) {
		// Параметры генерации
		$min_total = 385000;
		$max_total = 500000;
		$min_votes = 30;
		$max_votes = 250;
		// Генерация
		if( $mode == 'total' ) {
			$result_set = mt_rand($min_total, $max_total)/100000;
		} elseif ( $mode == 'votes' ) {
			$result_set = mt_rand($min_votes, $max_votes);
		} else {
			$result_set = NULL;
		}
		return $result_set;
	}

} // end RatingStarPrint
?>