Your IP : 18.218.213.199


Current Path : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/landing/lib/hook/page/
Upload File :
Current File : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/landing/lib/hook/page/themefonts.php

<?php

namespace Bitrix\Landing\Hook\Page;

use Bitrix\Landing\Assets;
use Bitrix\Landing\Field;
use Bitrix\Landing\Hook;
use Bitrix\Landing\Internals\HookDataTable;
use Bitrix\Landing\Landing;
use Bitrix\Landing\Manager;
use Bitrix\Main\Loader;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\Entity\Query;
use Bitrix\Main\Page\Asset;
use Bitrix\Main\Page\AssetLocation;
use Bitrix\Main\Text\HtmlFilter;
use Bitrix\UI\Fonts;

/**
 * Typographic settings
 */
class ThemeFonts extends Hook\Page
{
	protected const BASE_HTML_SIZE = '14px';

	/**
	 * Map of the field.
	 * @return array
	 */
	protected function getMap(): array
	{
		return [
			'USE' => new Field\Checkbox('USE', [
				'title' => Loc::getMessage('LNDNGHOOK_THEMEFONTS_USE_2'),
			]),
			'CODE_H' => new Field\Text('CODE_H', [
				'title' => Loc::getMessage('LNDNGHOOK_THEMEFONTS_FONT_BASE_2'),
				'default' => 'Open Sans',
			]),
			'CODE' => new Field\Text('CODE', [
				'title' => Loc::getMessage('LNDNGHOOK_THEMEFONTS_FONT_BASE_2'),
				'default' => 'Open Sans',
			]),
			'SIZE' => new Field\Select('SIZE', [
				'title' => Loc::getMessage('LNDNGHOOK_THEMEFONTS_FONT_SIZE'),
				'default' => '1',
				'options' => [
					'0.92857' => Loc::getMessage('LNDNGHOOK_THEMEFONTS_FONT_12'),
					'1' => Loc::getMessage('LNDNGHOOK_THEMEFONTS_FONT_14'),
					'1.14286' => Loc::getMessage('LNDNGHOOK_THEMEFONTS_FONT_16'),
				],
			]),
			'COLOR' => new Field\Text('COLOR', [
				'title' => Loc::getMessage('LNDNGHOOK_THEMEFONTS_FONT_COLOR'),
				'help' => Loc::getMessage('LNDNGHOOK_THEMEFONTS_FONT_COLOR_HELP'),
			]),
			'COLOR_H' => new Field\Text('COLOR_H', [
				'title' => Loc::getMessage('LNDNGHOOK_THEMEFONTS_FONT_COLOR_H'),
				'help' => Loc::getMessage('LNDNGHOOK_THEMEFONTS_FONT_COLOR_HELP_H'),
			]),
			'LINE_HEIGHT' => new Field\Select('LINE_HEIGHT', [
				'title' => Loc::getMessage('LNDNGHOOK_THEMEFONTS_LINE_HEIGHT'),
				'default' => '1.6',
				'options' => self::getLineHeightOptions(),
			]),
			'FONT_WEIGHT' => new Field\Select('FONT_WEIGHT', [
				'title' => Loc::getMessage('LNDNGHOOK_THEMEFONTS_FONT_WEIGHT_2'),
				'default' => '400',
				'options' => self::getFontWeightOptions(),
				'help' => Loc::getMessage('LNDNGHOOK_THEMEFONTS_FONT_WEIGHT_HELP_2'),
			]),
			'FONT_WEIGHT_H' => new Field\Select('FONT_WEIGHT_H', [
				'title' => Loc::getMessage('LNDNGHOOK_THEMEFONTS_FONT_WEIGHT_H_2'),
				'default' => '400',
				'options' => self::getFontWeightOptions(),
				'help' => Loc::getMessage('LNDNGHOOK_THEMEFONTS_FONT_WEIGHT_HELP_H'),
			]),
		];
	}

	protected static function getLineHeightOptions(): array
	{
		return [
			'0.7' => '0.7',
			'0.8' => '0.8',
			'0.9' => '0.9',
			'1' => '1',
			'1.1' => '1.1',
			'1.2' => '1.2',
			'1.3' => '1.3',
			'1.4' => '1.4',
			'1.5' => '1.5',
			'1.6' => '1.6',
			'1.7' => '1.7',
			'1.8' => '1.8',
			'2' => '2',
		];
	}

	protected static function getFontWeightOptions(): array
	{
		return [
			'100' => '100',
			'200' => '200',
			'300' => '300',
			'400' => '400',
			'500' => '500',
			'600' => '600',
			'700' => '700',
			'800' => '800',
			'900' => '900',
		];
	}

	/**
	 * Enable or not the hook.
	 * @return boolean
	 */
	public function enabled(): bool
	{
		if ($this->issetCustomExec())
		{
			return true;
		}

		if ($this->isPage())
		{
			return $this->fields['USE']->getValue() === 'Y';
		}

		return true; //always enable on site to default value
	}

	/**
	 * Exec hook.
	 * @return void
	 */
	public function exec(): void
	{
		if ($this->execCustom())
		{
			return;
		}

		$this->setThemeFont();
		$this->setHFontTheme();
		$this->setSize();
		$this->setColors();
		$this->setTypo();
	}

	protected function getField(string $name): ?string
	{
		if ($field = $this->fields[$name]->getValue())
		{
			return HtmlFilter::encode(trim($field));
		}

		return self::getDefaultValues()[$name] ?? null;
	}

	protected static function getDefaultValues(): array
	{
		return [
			'CODE' => 'Open Sans',
			'CODE_H' => 'Open Sans',
			'SIZE' => '1',
			'LINE_HEIGHT' => '1.6',
			'FONT_WEIGHT' => '400',
			'FONT_WEIGHT_H' => '400',
		];
	}

	/**
	 * Set the main font to the page
	 */
	protected function setThemeFont(): void
	{
		$font = $this->getField('CODE');
		$font = self::convertFontName($font);

		$assets = Assets\Manager::getInstance();
		if ($this->fields['CODE']->getValue() !== null)
		{
			$assets->addString(
				"<style>
					body {
						--landing-font-family: {$font}
					}
				</style>"
			);
		}

		$assets->addString(self::getFontLink($font));
		$assets->addString(
			'<style>
				body {
					font-weight: 400;
					font-family: ' . $font . ';
					-webkit-font-smoothing: antialiased;
					-moz-osx-font-smoothing: grayscale;
					-moz-font-feature-settings: "liga", "kern";
					text-rendering: optimizelegibility;
				}
			</style>'
		);
	}

	/**
	 * Set fonts for headers, add style string
	 */
	protected function setHFontTheme(): void
	{
		$font = $this->getField('CODE_H');
		$font = self::convertFontName($font);

		$assets = Assets\Manager::getInstance();
		$assets->addString(self::getFontLink($font));
		$assets->addString(
			'<style>
				h1, h2, h3, h4, h5, h6 {
					font-family: ' . $font . ';
				}
			</style>'
		);
	}

	/**
	 * Convert to correct font name
	 * @param string $fontName
	 * @return string
	 */
	protected static function convertFontName(string $fontName): string
	{
		$fontName = str_replace(['g-font-', '-', 'ibm ', 'pt '], ['', ' ', 'IBM ', 'PT '], $fontName);

		$pattern = [
			'/sc(?:(?![a-z]))/i',
			'/jp(?:(?![a-z]))/i',
			'/kr(?:(?![a-z]))/i',
			'/tc(?:(?![a-z]))/i',
		];
		$replace = ['SC', 'JP', 'KR', 'TC'];
		$fontNameNew = preg_filter($pattern, $replace, $fontName);
		if ($fontNameNew)
		{
			$fontName = $fontNameNew;
		}

		$fontName = ucwords($fontName);

		return $fontName;
	}

	protected static function getFontLink(string $font): string
	{
		$domain = 'fonts.googleapis.com';
		if (Loader::includeModule('ui'))
		{
			$domain = Fonts\Proxy::resolveDomain(Manager::getZone());
		}

		$fontLink = "<link rel=\"stylesheet\" href=\"https://{$domain}/css2?family=";
		$fontLink .= str_replace(" ", "+", $font);
		$fontLink .= ':wght@100;200;300;400;500;600;700;800;900">';

		return $fontLink;
	}

	/**
	 * Set base font size for ALL text in body, add style string
	 */
	protected function setSize(): void
	{
		$size = $this->getField('SIZE');

		$assets = Assets\Manager::getInstance();
		$assets->addString(
			'<style>
			html {font-size: ' . self::BASE_HTML_SIZE . ';}
			body {font-size: ' . $size . 'rem;}
			.g-font-size-default {font-size: ' . $size . 'rem;}
		</style>'
		);
	}

	/**
	 * Set colors for text and headers
	 */
	protected function setColors(): void
	{
		$color = $this->getField('COLOR');
		$hColor = $this->getField('COLOR_H');
		$css = '';

		if ($color && Theme::isHex($color))
		{
			$css .= "--theme-color-main: {$color} !important;";
		}
		if ($hColor && Theme::isHex($hColor))
		{
			$css .= "--theme-color-title: {$hColor} !important;";
		}

		if (!empty($css))
		{
			Asset::getInstance()->addString(
				"<style>:root {{$css}}</style>",
				false,
				AssetLocation::BEFORE_CSS
			)
			;
		}
	}

	/**
	 * Set weight and line-height for text and headers
	 */
	protected function setTypo(): void
	{
		$lineHeight = $this->getField('LINE_HEIGHT');
		$fontWeight = $this->getField('FONT_WEIGHT');
		$hFontWeight = $this->getField('FONT_WEIGHT_H');

		$mainClass = Landing::getEditMode() ? '.landing-edit-mode' : '.landing-public-mode';
		$assets = Assets\Manager::getInstance();
		$assets->addString(
			"<style>
				main{$mainClass} {
					line-height: {$lineHeight};
					font-weight: {$fontWeight};
				}
				
				{$mainClass} .h1, {$mainClass} .h2, {$mainClass} .h3, {$mainClass} .h4, 
				{$mainClass} .h5, {$mainClass} .h6, {$mainClass} .h7,
				{$mainClass} h1, {$mainClass} h2, {$mainClass} h3, {$mainClass} h4, 
				{$mainClass} h5, {$mainClass} h6 {
					font-weight: {$hFontWeight};
				}
			</style>"
		);
	}

	/**
	 * Replace THEME_CODE_TYPO hook to THEMEFONTS hooks.
	 * @param int $lid Landing id.
	 * @param int $siteId Site id.
	 * @return void
	 * @throws \Bitrix\Main\ArgumentException
	 * @throws \Bitrix\Main\ObjectPropertyException
	 * @throws \Bitrix\Main\SystemException
	 */
	public static function migrateFromTypoThemes(int $lid, int $siteId): void
	{
		$migrations = [
			'1construction' => [
				'CODE' => 'Alegreya Sans',
				'CODE_H' => 'Alegreya Sans',
				'SIZE' => '1.14286',
			],
			'2business' => [
				'CODE' => 'Roboto',
				'CODE_H' => 'Roboto',
				'SIZE' => '1',
			],
			'3corporate' => [
				'CODE' => 'Roboto',
				'CODE_H' => 'Roboto',
				'SIZE' => '1',
			],
			'accounting' => [
				'CODE' => 'Open Sans',
				'CODE_H' => 'Open Sans',
				'SIZE' => '1',
			],
			'agency' => [
				'CODE' => 'Roboto',
				'CODE_H' => 'Roboto',
				'SIZE' => '1',
			],
			'app' => [
				'CODE' => 'Open Sans',
				'CODE_H' => 'Open Sans',
				'SIZE' => '1.14286',
			],
			'architecture' => [
				'CODE' => 'Open Sans',
				'CODE_H' => 'Open Sans',
				'SIZE' => '1',
			],
			'charity' => [
				'CODE' => 'Open Sans',
				'CODE_H' => 'Open Sans',
				'SIZE' => '0.92857',
			],
			'consulting' => [
				'CODE' => 'Open Sans',
				'CODE_H' => 'Open Sans',
				'SIZE' => '1',
			],
			'courses' => [
				'CODE' => 'Alegreya Sans',
				'CODE_H' => 'Alegreya Sans',
				'SIZE' => '1',
			],
			'event' => [
				'CODE' => 'Open Sans',
				'CODE_H' => 'Open Sans',
				'SIZE' => '1.14286',
			],
			'gym' => [
				'CODE' => 'Roboto',
				'CODE_H' => 'Roboto',
				'SIZE' => '1',
			],
			'lawyer' => [
				'CODE' => 'Roboto',
				'CODE_H' => 'Open Sans',
				'SIZE' => '1',
			],
			'music' => [
				'CODE' => 'Open Sans',
				'CODE_H' => 'Open Sans',
				'SIZE' => '0.92857',
			],
			'photography' => [
				'CODE' => 'Roboto',
				'CODE_H' => 'Roboto',
				'SIZE' => '0.92857',
			],
			'real-estate' => [
				'CODE' => 'Open Sans',
				'CODE_H' => 'Open Sans',
				'SIZE' => '1',
			],
			'restaurant' => [
				'CODE' => 'Montserrat',
				'CODE_H' => 'Montserrat',
				'SIZE' => '0.92857',
			],
			'shipping' => [
				'CODE' => 'Open Sans',
				'CODE_H' => 'Open Sans',
				'SIZE' => '1',
			],
			'spa' => [
				'CODE' => 'Open Sans',
				'CODE_H' => 'Open Sans',
				'SIZE' => '1',
			],
			'travel' => [
				'CODE' => 'Roboto',
				'CODE_H' => 'Roboto',
				'SIZE' => '1',
			],
			'wedding' => [
				'CODE' => 'Montserrat',
				'CODE_H' => 'Montserrat',
				'SIZE' => '1',
			],
		];

		$queryOld = HookDataTable::query()
			->addSelect('ID')
			->addSelect('VALUE')
			->addSelect('PUBLIC')
			->addSelect('ENTITY_ID')
			->addSelect('ENTITY_TYPE')
			->where('HOOK', 'THEME')
			->where('CODE', 'CODE_TYPO')
			->where(Query::filter()
				->logic('or')
				->where(Query::filter()
					->where('ENTITY_ID', $lid)
					->where('ENTITY_TYPE', Hook::ENTITY_TYPE_LANDING)
				)
				->where(Query::filter()
					->where('ENTITY_ID', $siteId)
					->where('ENTITY_TYPE', Hook::ENTITY_TYPE_SITE)
				)
			);

		while ($old = $queryOld->fetch())
		{
			// check exist
			$existing = HookDataTable::query()
				->addSelect('ID')
				->where('HOOK', 'THEMEFONTS')
				->where('ENTITY_ID', $old['ENTITY_ID'])
				->where('ENTITY_TYPE', $old['ENTITY_TYPE'])
				->where('PUBLIC', $old['PUBLIC'])
				->fetch();
			if (!$existing)
			{
				//process
				$migrations[$old['VALUE']]['USE'] = 'Y';
				foreach ($migrations[$old['VALUE']] as $code => $value)
				{
					HookDataTable::add(
						[
							'ENTITY_ID' => $old['ENTITY_ID'],
							'ENTITY_TYPE' => $old['ENTITY_TYPE'],
							'PUBLIC' => $old['PUBLIC'],
							'HOOK' => 'THEMEFONTS',
							'CODE' => $code,
							'VALUE' => $value,
						]
					);
				}
			}

			HookDataTable::delete($old['ID']);
		}
	}
}