<?php
/**
* @version	$Id: skin_helper.php 16568 2017-07-16 17:59:04Z alex $
* @package	In-Portal
* @copyright	Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license      GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/

	defined('FULL_PATH') or die('restricted access!');

	class SkinHelper extends kHelper {

		/**
		 * Allows to read some skin fields and build link to admin skin file.
		 * Will automatically compile skin file, when missing.
		 *
		 * @param array $params Tag params.
		 *
		 * @return string
		 */
		public function AdminSkinTag(array $params)
		{
			// Returns given field of skin.
			if ( array_key_exists('type', $params) ) {
				return $this->_getStyleField($params['type']);
			}

			if ( file_exists($this->getSkinPath()) ) {
				$ret = $this->getSkinPath(true);
			}
			else {
				/** @var kDBItem $skin */
				$skin = $this->Application->recallObject('skin.-item', null, array('skip_autoload' => true));

				$skin->Load(1, 'IsPrimary');
				$ret = $this->compile($skin) ? $this->getSkinPath(true) : '';
			}

			if ( array_key_exists('file_only', $params) && $params['file_only'] ) {
				return $ret;
			}

			$ret .= '?ts=' . adodb_date('Y-m-d_H:i:s', filemtime($this->getSkinPath()));

			return '<link rel="stylesheet" rev="stylesheet" href="' . $ret . '" type="text/css" media="screen"/>';
		}

		/**
		 * Compiles given skin object
		 *
		 * @param kDBItem $object Skin.
		 *
		 * @return integer
		 */
		public function compile(kDBItem $object)
		{
			$ret = $object->GetDBField('CSS');
			$options = $object->GetDBField('Options');
			$options = unserialize($options);
			$options['base_url'] = array('Value' => rtrim(BASE_PATH, '/'));

			foreach ( $options as $key => $row ) {
				$ret = str_replace('@@' . $key . '@@', $row['Value'], $ret);
			}

			$compile_ts = adodb_mktime();
			$style_name = $this->getSkinFilename($object->GetDBField('Name'));
			$css_file = $this->_getStylesheetPath() . DIRECTORY_SEPARATOR . $style_name;

			if ( file_put_contents($css_file, $ret) === false ) {
				return false;
			}

			$sql = 'UPDATE ' . $object->TableName . '
					SET LastCompiled = ' . $compile_ts . '
					WHERE ' . $object->IDField . ' = ' . $object->GetID();
			$this->Conn->Query($sql);

			$this->Application->incrementCacheSerial('skin');
			$this->Application->incrementCacheSerial('skin', $object->GetID());

			return $compile_ts;
		}

		/**
		 * Returns fields of primary admin skin
		 *
		 * @return array
		 */
		protected function _getStyleInfo()
		{
			$cache_key = 'primary_skin_info[%SkinSerial%]';
			$ret = $this->Application->getCache($cache_key);

			if ( $ret === false ) {
				$this->Conn->nextQueryCachable = true;
				$sql = 'SELECT *
						FROM ' . TABLE_PREFIX . 'AdminSkins
						WHERE IsPrimary = 1';
				$ret = $this->Conn->GetRow($sql);

				$this->Application->setCache($cache_key, $ret);
			}

			return $ret;
		}

		/**
		 * Returns requested field value of primary admin skin
		 *
		 * @param string $field Field.
		 *
		 * @return string
		 */
		protected function _getStyleField($field)
		{
			// Old style method of calling.
			if ( $field == 'logo' ) {
				$field = 'Logo';
			}

			$style_info = $this->_getStyleInfo();

			if ( !$style_info[$field] ) {
				return '';
			}

			$image_fields = array('Logo', 'LogoBottom', 'LogoLogin');

			if ( in_array($field, $image_fields) ) {
				return $this->_getStylesheetPath(true) . '/' . $style_info[$field];
			}

			return $style_info[$field];
		}

		/**
		 * Returns path, where compiled skin and it's image files are stored
		 *
		 * @param boolean $url Return url or path.
		 *
		 * @return string
		 */
		protected function _getStylesheetPath($url = false)
		{
			if ( $url ) {
				$sub_folder = str_replace(DIRECTORY_SEPARATOR, '/', WRITEBALE_BASE) . '/user_files';

				return $this->Application->BaseURL() . ltrim($sub_folder, '/');
			}

			return WRITEABLE . DIRECTORY_SEPARATOR . 'user_files';
		}

		/**
		 * Returns full path to primary admin skin using given or last compiled date
		 *
		 * @param boolean $url Return url or path..
		 *
		 * @return string
		 */
		public function getSkinPath($url = false)
		{
			$style_info = $this->_getStyleInfo();
			$style_name = $this->getSkinFilename($style_info['Name']);

			return $this->_getStylesheetPath($url) . ($url ? '/' : DIRECTORY_SEPARATOR) . $style_name;
		}

		/**
		 * Returns skin filename without path.
		 *
		 * @param string $skin_name Skin name.
		 *
		 * @return string
		 */
		protected function getSkinFilename($skin_name)
		{
			return 'admin-' . mb_strtolower($skin_name) . '.css';
		}

		/**
		 * Deletes all compiled versions of all skins
		 *
		 * @return void
		 */
		public function deleteCompiled()
		{
			$files = glob($this->_getStylesheetPath() . DIRECTORY_SEPARATOR . 'admin-*.css');

			if ( $files ) {
				array_map('unlink', $files);
			}
		}

	}
