Your IP : 3.144.163.15


Current Path : /home/bitrix/ext_www/easy-comfort.com.ua/bitrix/components/bitrix/landing.pub/
Upload File :
Current File : /home/bitrix/ext_www/easy-comfort.com.ua/bitrix/components/bitrix/landing.pub/class.php

<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true)
{
	die();
}

use \Bitrix\Main\Entity;
use \Bitrix\Landing\Hook;
use \Bitrix\Landing\Manager;
use \Bitrix\Landing\Landing;
use \Bitrix\Landing\Site;
use \Bitrix\Landing\Syspage;
use \Bitrix\Landing\TemplateRef;
use \Bitrix\Main\Localization\Loc;
use \Bitrix\Main\EventManager;
use \Bitrix\Main\Config\Option;

Loc::loadMessages(__FILE__);

\CBitrixComponent::includeComponentClass('bitrix:landing.base');

class LandingPubComponent extends LandingBaseComponent
{
	/**
	 * Special page - robots.txt
	 * @var boolean
	 */
	protected $isRobotsTxt = false;

	/**
	 * Special page - sitemap.xml
	 * @var boolean
	 */
	protected $isSitemapXml = false;

	/**
	 * Is preview mode.
	 * @var boolean
	 */
	protected $isPreviewMode = false;

	/**
	 * SEF variables.
	 * @var array
	 */
	protected $sefVariables = array();

	/**
	 * Current zone.
	 * @var string
	 */
	protected $zone = '';

	/**
	 * Main instance of current page.
	 * @var array
	 */
	protected static $landingMain = null;

	/**
	 * Gets main instance of current page.
	 * @return array
	 */
	public static function getMainInstance()
	{
		return self::$landingMain;
	}

	/**
	 * Get base domain of service by lang.
	 * @return string
	 */
	protected function getParentDomain()
	{
		$domains = array(
			'ru' => 'bitrix24.ru',
			'ua' => 'bitrix24.ua',
			'by' => 'bitrix24.by',
			'kz' => 'bitrix24.kz',
			'pl' => 'bitrix24.pl',
			'en' => 'bitrix24.com',
			'de' => 'bitrix24.de',
			'es' => 'bitrix24.es',
			'la' => 'bitrix24.es',
			'br' => 'bitrix24.com.br',
			'fr' => 'bitrix24.fr',
			'cn' => 'bitrix24.cn',
			'in' => 'bitrix24.in',
			'eu' => 'bitrix24.eu',
			'tr' => 'bitrix24.com.tr'
		);

		if (isset($domains[$this->zone]))
		{
			return $domains[$this->zone];
		}
		else
		{
			return $domains['en'];
		}
	}

	/**
	 * Get adv campaign code.
	 * @return string
	 */
	protected function getAdvCode()
	{
		$codes = array(
			'ru' => 'utm_source=client_b24_site&utm_medium=referral&utm_campaign=b24_site',
			'ua' => 'utm_source=client_b24_site&utm_medium=referral&utm_campaign=b24ua_site',
			'pl' => 'utm_source=client_b24_site&utm_medium=referral&utm_campaign=b24pl_site',
			'en' => 'utm_medium=referral&utm_source=bitrix24.com&utm_campaign=SitesCom',
			'de' => 'utm_medium=referral&utm_source=bitrix24.de&utm_campaign=SitesDe',
			'es' => 'utm_medium=referral&utm_source=bitrix24.es&utm_campaign=SitesEs',
			'br' => 'utm_medium=referral&utm_source=bitrix24.com.br&utm_campaign=SitesBR',
			'fr' => 'utm_medium=referral&utm_source=bitrix24.fr&utm_campaign=SitesFr'
		);

		if (isset($codes[$this->zone]))
		{
			$return = $codes[$this->zone];
		}
		else
		{
			$return = $codes['en'];
		}

		$partnerId = Option::get('bitrix24', 'partner_id', 0);
		if ($partnerId)
		{
			$return .= '&p=' . $partnerId;
		}

		return \htmlspecialcharsbx($return);
	}

	/**
	 * Detect landing by path.
	 * @return int|false Detected landing id or false.
	 */
	protected function detectPage()
	{
		// preview mode for templates only
		$previewTemplate = $this->request('preview') == 'Y';

		// parse url
		$serverHost = $this->arParams['HTTP_HOST'];
		$requestedPage = '/' . $this->arParams['PATH'];
		$urlParts = parse_url($requestedPage);
		if (isset($urlParts['path']))
		{
			$requestedPage = $urlParts['path'];
		}
		$requestedPage = trim($requestedPage, '/');
		$requestedPageParts = explode('/', $requestedPage);
		if (Manager::isB24())
		{
			$siteUrl = array_shift($requestedPageParts);
			$siteId = $siteUrl;
		}
		// in smn detect site dir auto
		else
		{
			$siteUrl = '';
			$res = Site::getList(array(
				'select' => array(
					'ID', 'CODE'
				),
				'filter' => array(
					'=SMN_SITE_ID' => SITE_ID,
					'=TYPE' => 'SMN'
				),
				'order' => array(
					'ID' => 'desc'
				)
			));
			if ($row = $res->fetch())
			{
				$siteUrl = trim($row['CODE'], '/');
				$siteId = $row['ID'];
			}
		}

		// detect preview mode
		if (
			// for base work
			(
				$requestedPageParts[0] == 'preview' &&
				$requestedPageParts[1] == Site::getPublicHash($siteId)
			)
			||
			// for cloud version
			(
				$this->request('landing_mode') == 'preview' &&
				$this->request('hash') == Site::getPublicHash($siteId)
			)
		)
		{
			$this->isPreviewMode = true;
			if ($requestedPageParts[0] == 'preview')
			{
				array_shift($requestedPageParts);
				array_shift($requestedPageParts);
			}
		}

		$landingUrl = array_shift($requestedPageParts);
		$landingSubUrl = $requestedPageParts ? implode('/', $requestedPageParts) : '';

		if ($previewTemplate)
		{
			$site = $this->getSites(array(
				'select' => array(
					'ID', 'CODE'
				),
				'filter' => array(
					'=TYPE' => 'PREVIEW'
				),
				'limit' => 1
			));
			$site = array_shift($site);
			$siteUrl = trim($site['CODE'], '/');
		}

		$landingSubUrl = str_replace(
			array('/index.php', 'index.php'),
			'',
			$landingSubUrl
		);

		// system pages
		if ($landingUrl == 'robots.php')
		{
			$landingUrl = '';
			$this->isRobotsTxt = true;
		}
		elseif ($landingUrl == 'sitemap.php')
		{
			$landingUrl = '';
			$this->isSitemapXml = true;
		}
		elseif ($landingUrl == 'favicon' || $landingUrl == 'favicon.php')
		{
			Manager::getApplication()->restartBuffer();
			header('Content-type: image/x-icon');
			echo file_get_contents(Manager::getDocRoot() . '/bitrix/components/bitrix/landing.pub/favicon.ico');
			die();
		}

		$landingIdExec = false;
		$landingIdIndex = false;
		$landingId404 = false;

		// first detect site
		if (preg_match('#^([\d]+)$#', $siteUrl, $matches))
		{
			$filter = array(
				'ID' => $matches[1],
				'=DELETED' => ['Y', 'N']
			);
		}
		else
		{
			$filter = array(
				'=CODE' => '/' . $siteUrl . '/',//@todo fixme
				'=DELETED' => ['Y', 'N']
			);
		}
		if (
			$serverHost &&
			!$previewTemplate &&
			(!defined('LANDING_DISABLE_CLOUD') || LANDING_DISABLE_CLOUD !== true)
		)
		{
			if (strpos($serverHost, ':') !== false)
			{
				list($serverHost, ) = explode(':', $serverHost);
			}
			$filter['=DOMAIN.DOMAIN'] = $serverHost;
		}
		$res = Site::getList(array(
			'select' => array(
				'ID', 'ACTIVE', 'DELETED',
				'LANDING_ID_404', 'LANDING_ID_503',
				'LANDING_ID_INDEX'
			),
			'filter' => $filter
		));
		if (!($site = $res->fetch()))
		{
			return $landingIdExec;
		}

		// unactive site
		if (
			(
				!$this->isPreviewMode &&
				$site['ACTIVE'] == 'N'
			)
			||
			$site['DELETED'] == 'Y'
		)
		{
			if (Manager::isB24())
			{
				$this->setHttpStatusOnce($this::ERROR_STATUS_FORBIDDEN);
			}
			return $landingIdExec;
		}

		self::$landingMain['SITE_ID'] = $site['ID'];

		// site is down
		if ($site['LANDING_ID_503'])
		{
			$this->setHttpStatusOnce($this::ERROR_STATUS_UNAVAILABLE);
			return $site['LANDING_ID_503'];
		}

		/**
		 * Local function for iteration below,
		 * if record is un active, send 403 status.
		 * @param array $row Row array.
		 * @return int|bool
		 */
		$checkExecId = function(array $row)
		{
			if (
				(
					!$this->isPreviewMode &&
					$row['ACTIVE'] == 'N'
				)
				||
				$row['DELETED'] == 'Y'
			)
			{
				if (Manager::isB24())
				{
					$this->setHttpStatusOnce(
						$this::ERROR_STATUS_FORBIDDEN
					);
				}
				return false;
			}

			return $row['ID'];
		};

		// detect landing
		$res = Landing::getList(array(
			'select' => array(
				'ID', 'CODE', 'RULE',
				'FOLDER', 'ACTIVE', 'DELETED'
			),
			'filter' => array(
				'SITE_ID' => $site['ID'],
				'FOLDER_ID' => false,
				'=DELETED' => ['Y', 'N'],
				array(
					'LOGIC' => 'OR',
					'=CODE' => $landingUrl,
					'!=RULE' => false,
					array(
						'ID' => $site['LANDING_ID_404']
					),
					array(
						'ID' => $site['LANDING_ID_INDEX']
					)
				),
				$this->isPreviewMode
				? array()
				: array(
					'LOGIC' => 'OR',
					'=ACTIVE' => ['Y', 'N'],
					'ID' => $site['LANDING_ID_INDEX']
				)
			),
			'order' => array(
				'ID' => 'asc'
			)
		));
		while (($landing = $res->fetch()))
		{
			// if it's index and not active
			if (
				!$this->isPreviewMode &&
				$landing['ACTIVE'] != 'Y' &&
				$site['LANDING_ID_INDEX'] == $landing['ID']
			)
			{
				$landingIdIndex = -1 * $landing['ID'];
				continue;
			}
			// another checking
			if (strtolower($landing['CODE']) == strtolower($landingUrl))
			{
				if ($landingSubUrl)
				{
					if ($landing['FOLDER'] == 'Y')
					{
						// check landing in subfolder
						$resSub = Landing::getList(array(
							'select' => array(
								'ID', 'CODE', 'RULE', 'ACTIVE', 'DELETED'
							),
							'filter' => array(
								'SITE_ID' => $site['ID'],
								'=DELETED' => ['Y', 'N'],
								array(
									'LOGIC' => 'OR',
									'ID' => $landing['ID'],
									'FOLDER_ID' => $landing['ID']
								),
								array(
									'LOGIC' => 'OR',
									'CODE' => $landingSubUrl,
									'!=RULE' => false
								)
							),
							'order' => array(
								'ID' => 'asc'
							)
						));
						while ($row = $resSub->fetch())
						{
							if ($row['CODE'] == $landingSubUrl)
							{
								$landingIdExec = $checkExecId($row);
							}
							else if (
								$row['RULE'] &&
								preg_match('@^'. trim($row['RULE']) . '$@i', $landingSubUrl, $matches)
							)
							{
								$landingIdExec = $checkExecId($row);
								array_shift($matches);
								$this->sefVariables = $matches;
							}
						}
					}
				}
				else
				{
					$landingIdExec = $checkExecId($landing);
				}
			}
			else if (
				$landing['RULE'] && $landing['FOLDER'] != 'Y' &&
				preg_match('@^'. trim($landing['RULE']) . '$@i', $landingUrl, $matches)
			)
			{
				$landingIdExec = $checkExecId($landing);
				array_shift($matches);
				$this->sefVariables = $matches;
			}
			if ($site['LANDING_ID_INDEX'] == $landing['ID'])
			{
				$landingIdIndex = $landing['ID'];
			}
			if ($site['LANDING_ID_404'] == $landing['ID'])
			{
				$landingId404 = $landing['ID'];
			}
		}

		// disable direct access to include areas
		if ($landingIdExec)
		{
			if (TemplateRef::landingIsArea($landingIdExec))
			{
				$landingIdExec = false;
			}
		}

		// try load special landings if landing not found
		if (!$landingIdExec)
		{
			if (in_array($landingUrl, array('index.php', '')))
			{
				if ($landingIdIndex)
				{
					if ($landingIdIndex > 0)
					{
						$landingIdExec = $landingIdIndex;
					}
					else
					{
						$landingIdExec = $landingId404;
						$this->setHttpStatusOnce($this::ERROR_STATUS_NOT_FOUND);
					}
				}
				else
				{
					// if index page not set, gets first by asc
					$res = Landing::getList(array(
						'select' => array(
							'ID'
						),
						'filter' => array(
							'SITE_ID' => $site['ID'],
							'=ACTIVE' => 'Y',
							'!ID' => $landingId404
						),
						'order' => array(
							'ID' => 'asc'
						)
					));
					if ($row = $res->fetch())
					{
						$landingIdExec = $row['ID'];
					}
				}
			}
			else
			{
				$landingIdExec = $landingId404;
				$this->setHttpStatusOnce($this::ERROR_STATUS_NOT_FOUND);
			}
		}

		return $landingIdExec;
	}

	/**
	 * Get sitemap.xml content.
	 * @param int $siteId Site Id.
	 * @return string
	 */
	protected function getSitemap($siteId)
	{
		$ids = array();

		$res = Landing::getList(array(
			'select' => array(
				'ID', 'DATE_PUBLIC_UNIX'
			),
			'filter' => array(
				'SITE_ID' => $siteId,
				'=SITEMAP' => 'Y'
			),
			'order' => array(
				'DATE_PUBLIC' => 'DESC'
			),
			'runtime' => array(
				new Entity\ExpressionField('DATE_PUBLIC_UNIX', 'UNIX_TIMESTAMP(DATE_PUBLIC)')
			)
		));
		while ($row = $res->fetch())
		{
			if ($row['DATE_PUBLIC_UNIX'])
			{
				$ids[$row['ID']] = $row['DATE_PUBLIC_UNIX'];
			}
		}

		if (empty($ids))
		{
			return '';
		}

		$urls = Landing::getPublicUrl(array_keys($ids));
		$sitemap = '<?xml version="1.0" encoding="' . SITE_CHARSET . '"?>';
		$sitemap .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
		foreach ($ids as $id => $date)
		{
			$sitemap .= '<url>';
			$sitemap .= '<loc>' . $urls[$id] . '</loc>';
			$sitemap .= '<lastmod>' . date('c', $date) . '</lastmod>';
			$sitemap .= '</url>';
		}
		$sitemap .= '</urlset>';

		return $sitemap;
	}

	/**
	 * Handler for localRedirect.
	 * @return void
	 */
	protected function onBeforeLocalRedirect()
	{
		$eventManager = EventManager::getInstance();
		$eventManager->addEventHandler('main', 'OnBeforeLocalRedirect',
			function(&$url, $skipCheck, &$bExternal)
			{
				$landing = $this->arResult['LANDING'];
				if (
					Manager::isB24() &&
					(
						!defined('LANDING_DISABLE_CLOUD') ||
						LANDING_DISABLE_CLOUD !== true
					)
				)
				{
					$pubPathMask = '@^' . Manager::getPublicationPath('[\d]+') . '@i';
					$url = preg_replace($pubPathMask, '/', $url);
					if (substr($url, 0, 1) == '/')
					{
						$url = Site::getPublicUrl(
								$landing->getSiteId()
							) . $url;
						$bExternal = true;
					}
				}
				if (strpos($url, '#system') === false)
				{
					return;
				}
				foreach (Syspage::get($landing->getSiteId()) as $code => $page)
				{
					if (strpos($url, '#system_' . $code) !== false)
					{
						$landing = Landing::createInstance($page['LANDING_ID']);
						if ($landing->exist())
						{
							$url = $landing->getPublicUrl(false, false);
							break;
						}
					}
				}
			}
		);
	}

	/**
	 * On search title.
	 * @return void
	 */
	protected function onSearchGetURL()
	{
		static $pageCatalog = null;

		if ($pageCatalog === null)
		{
			$syspages = Syspage::get($this->arResult['LANDING']->getSiteId());
			if (isset($syspages['catalog']))
			{
				$landing = Landing::createInstance(
					$syspages['catalog']['LANDING_ID']
				);
				if ($landing->exist())
				{
					$pageCatalog = $landing->getPublicUrl();
				}
			}
		}

		$eventManager = EventManager::getInstance();
		$eventManager->addEventHandler('search', 'onSearchGetURL',
			function($row) use($pageCatalog)
			{
				if (isset($row['URL']))
				{
					$urlType = 'detail';
					if (substr($row['ITEM_ID'], 0, 1) == 'S')
					{
						$row['ITEM_ID'] = substr($row['ITEM_ID'], 1);
						$urlType = 'section';
					}
					$row['URL'] = \Bitrix\Landing\Node\Component::getIblockURL(
						$row['ITEM_ID'],
						$urlType
					);
					$row['URL'] = str_replace(
						'#system_catalog',
						$pageCatalog,
						$row['URL']
					);
					return $row['URL'];
				}
			}
		);
	}

	/**
	 * Redefined basket item before save.
	 * @see Also called from landing/install/blocks/bitrix/store.cart/ajax.php:59
	 * @return void
	 */
	public function onSaleBasketItemBeforeSaved()
	{
		$eventManager = EventManager::getInstance();
		$eventManager->addEventHandler('sale', 'onSaleBasketItemBeforeSaved',
			function(\Bitrix\Main\Event $event)
			{
				$item = $event->getParameter('ENTITY');
				$productId = $item->getField('PRODUCT_ID');
				// by default without detail link
				$item->setField(
					'DETAIL_PAGE_URL',
					''
				);
				if (!Manager::isB24())
				{
					return;
				}
				// gets iblock id
				$res = \Bitrix\Iblock\ElementTable::getList(array(
					'select' => array(
						'IBLOCK_ID'
					),
					'filter' => array(
						'ID' => $productId
					)
				));
				if ($itemIblock = $res->fetch())
				{
					// gets prop with link to parent
					$res = \CIBlockElement::getProperty(
						$itemIblock['IBLOCK_ID'],
						$productId,
						array(),
						array(
							'CODE' => 'CML2_LINK'
						)
					);
					if ($itemProp = $res->fetch())
					{
						// gets parent's code
						$res = \Bitrix\Iblock\ElementTable::getList(array(
							'select' => array(
								'CODE'
							),
							'filter' => array(
								'ID' => $itemProp['VALUE']
							)
						));
						if ($itemParent = $res->fetch())
						{
							$item->setField(
								'DETAIL_PAGE_URL',
								'#system_catalogitem/' . $itemParent['CODE'] . '/'
							);
						}
					}
				}
			}
		);
	}

	/**
	 * Base executable method.
	 * @return void
	 */
	public function executeComponent()
	{
		$init = $this->init();
		$this->zone = Manager::getZone();

		if ($init)
		{
			if (
				!isset($this->arParams['PATH']) ||
				!$this->arParams['PATH']
			)
			{
				$context = \Bitrix\Main\Context::getCurrent();
				$requestURL = $context->getRequest()->getRequestedPage();
				$realFilePath = $context->getServer()->get('REAL_FILE_PATH');
				if (!$realFilePath)
				{
					$realFilePath = $context->getServer()->get('SCRIPT_NAME');
				}
				$requestURL = str_replace('/index.php', '/', $requestURL);
				$realFilePath = str_replace('/' . basename($realFilePath), '/', $realFilePath);
				$this->arParams['PATH'] = substr($requestURL, strlen($realFilePath));
			}

			$this->checkParam('LID', 0);
			$this->checkParam('HTTP_HOST', '');

			if (
				($lid = $this->arParams['LID']) ||
				($lid = $this->detectPage())
			)
			{
				if (Manager::isB24())
				{
					$asset = \Bitrix\Main\Page\Asset::getInstance();
					if (
						method_exists($asset, 'disableOptimizeCss') &&
						method_exists($asset, 'disableOptimizeJs')
					)
					{
						$asset->disableOptimizeCss();
						$asset->disableOptimizeJs();
					}
				}

				if (isset($this->sefVariables))
				{
					Landing::setVariables(array(
						'sef' => $this->sefVariables
					));
				}

				if ($this->isPreviewMode)
				{
					Landing::setPreviewMode(true);
				}

				self::$landingMain['LANDING_ID'] = $lid;
				$landing = Landing::createInstance($lid);
				$this->arResult['LANDING'] = $landing;
				$this->arResult['DOMAIN'] = $this->getParentDomain();
				$this->arResult['ADV_CODE'] = $this->getAdvCode();

				if ($landing->exist())
				{
					// exec Hook Robots
					if ($this->isRobotsTxt)
					{
						$hooksSite = Hook::getForSite($landing->getSiteId());
						if (isset($hooksSite['ROBOTS']))
						{
							Manager::getApplication()->restartBuffer();
							$robotsContent = trim($hooksSite['ROBOTS']->exec());
							// check sitemaps url
							$sitemap = Landing::getList(array(
								'select' => array(
									'ID'
								),
								'filter' => array(
									'SITE_ID' => $landing->getSiteId(),
									'=SITEMAP' => 'Y'
								),
								'limit' => 1
							));
							if ($sitemap->fetch())
							{
								$robotsContent .= ($robotsContent ? PHP_EOL : '');
								$robotsContent .= 'Sitemap: ' .
												  Site::getPublicUrl($landing->getSiteId()) .
												  '/sitemap.xml';
							}
							// out
							if ($robotsContent)
							{
								header('content-type: text/plain');
								echo $robotsContent;
							}
							else
							{
								$this->setHttpStatusOnce($this::ERROR_STATUS_NOT_FOUND);
							}
							die();
						}
					}
					// build sitemap
					elseif ($this->isSitemapXml)
					{
						Manager::getApplication()->restartBuffer();
						header('content-type: text/xml');
						$sitemap = $this->getSitemap($landing->getSiteId());
						if ($sitemap)
						{
							echo $sitemap;
						}
						else
						{
							$this->setHttpStatusOnce($this::ERROR_STATUS_NOT_FOUND);
						}
						die();
					}
				}

				$this->setErrors(
					$landing->getError()->getErrors()
				);

				// events
				$this->onBeforeLocalRedirect();
				$this->onSearchGetURL();
				$this->onSaleBasketItemBeforeSaved();

				// change view
				Manager::setPageView(
					'MainClass',
					'landing-public-mode'
				);
				if (
					\Bitrix\Main\Loader::includeModule('crm') &&
					method_exists(
						'\Bitrix\Crm\UI\Webpack\CallTracker',
						'getEmbeddedScript'
					)
				)
				{
					Manager::setPageView(
						'FooterJS',
						\Bitrix\Crm\UI\Webpack\CallTracker::instance()->getEmbeddedScript()
					);
				}
				
				// set og url
				Manager::setPageView(
					'MetaOG',
					'<meta name="og:url" content="' . $landing->getPublicUrl() . '" />'
				);
			}
			else
			{
				$this->setHttpStatusOnce($this::ERROR_STATUS_NOT_FOUND);
				$this->addError(
					'LANDING_CMP_SITE_NOT_FOUND',
					Loc::getMessage('LANDING_CMP_SITE_NOT_FOUND')
				);
			}
		}

		parent::executeComponent();
	}
}