<?php
/**
 * Формирование иконок для устройств, favicon.
 *
 *
 * @name Meta icons builder 
 * @description Generates icons meta data
 *
 * @param void
 *
 * @author veselka.ua
 * @version 0.1
 *
 * @package veselka_ua/themes
 */

class ImgIcons {

	/**
	 * Список иконок.
	 * @type array
	 */
	private $ico;
	/**
	 * Регистр - флаги и данные необходимые для работы.
	 * @type array
	 */
	private $registry;
	/**
	 * Результат работы.
	 * @type string
	 */
	private $result_set;


	public function __construct() {
		// Флаг инициализации объекта
		$this->registry['instance'] = false;

		// Вывод элементов в хедере
		add_action( 'wp_head', [$this, 'get_icon_set'], 10 );
		// Хук получения иконки для Open Graph
		add_filter( 'open_graph_icon_construct', [$this, 'get_og_icon'] );
	}


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


	/**
	 * Обертка для получения разметки иконок.
	 *
	 * @param void
	 * @return string
	 */
	final public function get_icon_set() {
		if( $this->load() ) {
			$this->construct_icons_metadata();
			echo $this->result_set;
		}
	}


	/**
	 * Обертка для получения мета изображения.
	 *
	 * @param void
	 * @return string
	 */
	final public function get_og_icon() {
		if( $this->load() ) {
			$this->construct_og_icon();
			return $this->result_set;
		}
	}


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


	/**
	 * Инициализация.
	 * 
	 * @param void
	 * @return bool
	 */
	private function load() {
		// Обнуление переменной результата
		$this->result_set = '';
		// Если индикатор сущности ложь, объкт не вызывался
		if( $this->registry['instance'] ) {
			return true;
		}
		// Переменные и начальные установки.
		$this->set_variables();
		// Проверка существования файлов.
		$this->check_files();
		// Инициализация завершена
		$this->registry['instance'] = true;
		return true;
	}


	/**
	 * Переменные и начальные установки.
	 *
	 * @param void
	 * @return void
	 */
	private function set_variables() {
		// Путь к иконкам от корня сервера
		$this->registry['ico_path'] = TEMPLATEPATH . '/assets/img/ico/';
		// Путь к иконкам от URL
		$this->registry['ico_url'] = TEMPLATE_URL . '/assets/img/ico/';
		// Иконка для Open Graph
		$this->registry['og_320'] = 'icon-logo-320.png';
		$this->registry['og_1200'] = 'icon-logo-1200.png';
		// Манифест
		$this->ico['manifest'] = 'site.webmanifest';
		// Конфиг для браузеров
		$this->ico['browserconfig'] = 'browserconfig.xml';
		// Иконки для устройств Apple Touch
		$this->ico['apple'] = [
			'57'	=>	'apple-touch-icon-57x57.png',
			'60'	=>	'apple-touch-icon-60x60.png',
			'72'	=>	'apple-touch-icon-72x72.png',
			'76'	=>	'apple-touch-icon-76x76.png',
			'114'	=>	'apple-touch-icon-114x114.png',
			'120'	=>	'apple-touch-icon-120x120.png',
			'144'	=>	'apple-touch-icon-144x144.png',
			'152'	=>	'apple-touch-icon-152x152.png',
			'180'	=>	'apple-touch-icon-180x180.png',
		];
		// Chrome
		$this->ico['android'] = [
			//'36'	=>	'android-chrome-36x36.png',
			//'48'	=>	'android-chrome-48x48.png',
			//'72'	=>	'android-chrome-72x72.png',
			//'96'	=>	'android-chrome-96x96.png',
			//'144'	=>	'android-chrome-144x144.png',
			'192'	=>	'android-chrome-192x192.png',
			'256'	=>	'android-chrome-256x256.png',
			'384'	=>	'android-chrome-384x384.png',
			'512'	=>	'android-chrome-512x512.png',
		];
		// Иконки Favicon
		$this->ico['icons'] = [
			'16'	=>	'favicon-16x16.png',
			'32'	=>	'favicon-32x32.png',
			'48'	=>	'favicon-48x48.png',
			'96'	=>	'favicon-96x96.png',
			'194'	=>	'favicon-194x194.png',
		];
		// favicon.ico
		$this->ico['shortcut'] = 'favicon.ico';
		// Иконка для Safari
		$this->ico['safari'] = 'safari-pinned-tab.svg';
		// Иконка для Windows
		$this->ico['mstile'] = 'mstile-144x144.png';
	}


	/**
	 * Проверка существования файлов.
	 *
	 * @param void
	 * @return void
	 */
	private function check_files() {
		// Проверяет наличие файлов в каталоге иконок
		foreach( $this->ico as $set_key => $icons ) {
			if( !is_array($icons) ) {
				$icons = (array)$icons;
			}
			foreach( $icons as $key => $file ) {
				if( !is_file( $this->registry['ico_path'] . $file ) ) {
					if( is_array($this->ico[$set_key]) ) {
						unset($this->ico[$set_key][$key]);
					} else {
						$this->ico[$set_key] = '';
					}
				}
			}
			// Если весь набор пустой, удаляем набор
			if( empty($this->ico[$set_key]) ) {
				unset($this->ico[$set_key]);
			}
		}
		// Проверка наличия иконки для Open Graph
		if( is_file( $this->registry['ico_path'] . $this->registry['og_1200'] ) ) {
			$this->registry['og'] = $this->registry['og_1200'];
		} elseif( is_file( $this->registry['ico_path'] . $this->registry['og_320'] ) ) {
			$this->registry['og'] = $this->registry['og_320'];
		} else {
			$this->registry['og'] = false;
		}
	}


	/**
	 * Формирование разметки иконок в <head>.
	 *
	 * @param void
	 * @return void
	 */
	private function construct_icons_metadata() {
		// Иконки для устройств Apple Touch
		if( isset($this->ico['apple']) ) {
			foreach($this->ico['apple'] as $num => $file) {
				$this->result_set .= "\t" . '<link rel="apple-touch-icon" sizes="' . $num . 'x' . $num . '" href="' . $this->registry['ico_url'] . $file . '">' . PHP_EOL;
			}
		}
		// Иконки Android
		if( isset($this->ico['android']) ) {
			foreach($this->ico['android'] as $num => $file) {
				$this->result_set .= "\t" . '<link rel="icon" type="image/png" sizes="' . $num . 'x' . $num . '" href="' . $this->registry['ico_url'] . $file . '">' . PHP_EOL;
			}
		}
		// Иконки Favicon
		if( isset($this->ico['icons']) ) {
			foreach($this->ico['icons'] as $num => $file) {
				$this->result_set .= "\t" . '<link rel="icon" type="image/png" sizes="' . $num . 'x' . $num . '" href="' . $this->registry['ico_url'] . $file . '">' . PHP_EOL;
			}
		}
		// Список иконок для Google Chrome
		if( isset($this->ico['manifest']) ) {
			$this->result_set .= "\t" . '<link rel="manifest" href="' . $this->registry['ico_url'] . 'site.webmanifest">' . PHP_EOL;
			// Разбор манифеста
			$file_path = $this->registry['ico_path'] . $this->ico['manifest'];
			$file_path = $manifest_obj = json_decode( file_get_contents($file_path) );
			$manifest['theme_color'] = $manifest_obj->theme_color;
			$manifest['name'] = $manifest_obj->name;
		} else {
			$manifest['theme_color'] = '#ffffff';
			$manifest['name'] = get_bloginfo( 'name' );
		}
		// Поиск цвета
		if( isset($this->ico['browserconfig']) ) {
			// Разбор манифеста
			$file_path = $this->registry['ico_path'] . $this->ico['browserconfig'];
			$file_string = file_get_contents($file_path);
			$xml = simplexml_load_string( $file_string, "SimpleXMLElement", LIBXML_NOCDATA);
			$manifest['color'] = $xml->msapplication->tile->TileColor;
		}
		if( !isset($manifest['color']) || !$manifest['color'] ) {
			$manifest['color'] = '#003399';
		}
		// favicon.ico
		if( isset($this->ico['shortcut']) ) {
			$this->result_set .= "\t" . '<link rel="shortcut icon" type="image/x-icon" href="' . $this->registry['ico_url'] . $this->ico['shortcut'] . '">' . PHP_EOL;
		}
		// Иконка для Safari
		if( isset($this->ico['safari']) ) {
			$this->result_set .= "\t" . '<link rel="mask-icon" href="' . $this->registry['ico_url'] . $this->ico['safari'] . '" color="' . $manifest['color'] . '">' . PHP_EOL;
		}
		// Название
		$this->result_set .= "\t" . '<meta name="apple-mobile-web-app-title" content="' . $manifest['name'] . '">' . PHP_EOL;
		$this->result_set .= "\t" . '<meta name="application-name" content="' . $manifest['name'] . '">' . PHP_EOL;
		// Иконка для Windows
		if( isset($this->ico['mstile']) ) {
			$this->result_set .= "\t" . '<meta name="theme-color" content="' . $manifest['theme_color'] . '">' . PHP_EOL;
			$this->result_set .= "\t" . '<meta name="msapplication-TileColor" content="' . $manifest['color'] . '">' . PHP_EOL;
			$this->result_set .= "\t" . '<meta name="msapplication-TileImage" content="' . $this->registry['ico_url'] . $this->ico['mstile'] . '">' . PHP_EOL;
			if( isset($this->ico['browserconfig']) ) {
				$this->result_set .= "\t" . '<meta name="msapplication-config" content="' . $this->registry['ico_url'] . $this->ico['browserconfig'] . '">' . PHP_EOL;
			}
		}
		// Комментарий
		if( (bool)$this->result_set ) {
			$this->result_set =  PHP_EOL . "\t" . '<!-- ICO -->' . PHP_EOL . $this->result_set;
		}
	}


	/**
	 * Получение адреса картинки для Open Graph.
	 *
	 * @param void
	 * @return bool
	 */
	private function construct_og_icon() {
		// Подготовленное изображение
		if( $this->registry['og'] ) {
			$this->result_set = $this->registry['ico_url'] . $this->registry['og'];
			return true;
		}
		// Иконка для андроид
		foreach( ['512','384','256'] as $size ) {
			$android_chrome = 'android-chrome-' . $size . 'x' . $size . '.png';
			if( is_file( $this->registry['ico_path'] . $android_chrome ) ) {
				$this->result_set = $this->registry['ico_url'] . $android_chrome;
				return true;
			}
		}
		if( isset($this->ico['icons']) ) {
			$this->result_set = $this->registry['ico_url'] . end($this->ico['icons']);
			return true;
		}
		// Иконка из мета данных
		if( isset($this->ico['icons']) ) {
			$this->result_set = $this->registry['ico_url'] . end($this->ico['icons']);
			return true;
		}
		// Логотип на худой конец
		if( is_file( $this->registry['ico_path'] . 'logo.png' ) ) {
			$this->result_set = $this->registry['ico_url'] . 'logo.png';
			return true;
		}
		return false;
	}


} //end ImgIcons
?>