Your IP : 18.116.200.95


Current Path : /home/bitrix/ext_www/easy-comfort.com.ua/local/php_interface/include/
Upload File :
Current File : /home/bitrix/ext_www/easy-comfort.com.ua/local/php_interface/include/events.php

<?
//Каноничная ссылка на товар
AddEventHandler("iblock", "OnIBlockPropertyBuildList", array("CIBlockPropertyLinkToSection", "GetUserTypeDescription"));

class CIBlockPropertyLinkToSection extends CIBlockPropertyElementList{

	public static function GetUserTypeDescription(){
		return array(
			'PROPERTY_TYPE' => 'S',
			'USER_TYPE' => 'wp_iblock_canonical_section',
			"DESCRIPTION" => "Web Profy: Привязка к разделу",
			"GetPropertyFieldHtml" => array(__CLASS__, "GetPropertyFieldHtml"),
		);
	}


	public static function createTree(&$ar, $parent){
		$tree = array();
		foreach($parent as $val){
			if(isset($ar[$val['ID']]) && $val['ID'] !== 0){
				$val['CHILDREN'] = self::createTree($ar, $ar[$val['ID']]);
			}
			$tree[] = $val;
		}
		return $tree;
	}

	public static function showTree($tree, $arValue, $level = 0){
		$return = '';
		foreach($tree as $category){
			if($category["ID"] === $arValue['VALUE']){
				$selected = ' selected="selected"';
			}else{
				$selected = '';
			}
			//Показываем название как во вкладке "Разделы", с точками.
			$return .= '<option'.$selected.' value="'.$category["ID"].'">'.str_repeat(" . ", $category["DEPTH_LEVEL"]).$category["NAME"].'</option>';
			$return .= self::showTree($category['CHILDREN'], $arValue, $level + 1);
		}
		return $return;
	}

	public static function GetPropertyFieldHtml($arProperty, $arValue, $strHTMLControlName){
		$arList = array();
		$options = '<option value="">(Не выбран)</option>';

		//Список разделов, к которым привязан элемент.
		$db_old_groups = CIBlockElement::GetElementGroups(intval($_REQUEST['ID']), false);
		while($ar_group = $db_old_groups->Fetch()){
			//Список всех родителей группы.
			$dbParents = CIBlockSection::GetNavChain(false, intval($ar_group["IBLOCK_SECTION_ID"]));
			while($arParents = $dbParents->Fetch()){
				//Для того, чтобы лишний раз не выбирать уникальные элементы, пишем их с ключом ID.
				$arList[$arParents["ID"]] = array(
					'ID' => $arParents["ID"],
					'PARENT' => intval($arParents["IBLOCK_SECTION_ID"]),
					'NAME' => $arParents["NAME"],
					'DEPTH_LEVEL' => $arParents["DEPTH_LEVEL"]
				);
			}
			$arList[$ar_group["ID"]] = array(
				'ID' => $ar_group["ID"],
				'PARENT' => intval($ar_group["IBLOCK_SECTION_ID"]),
				'NAME' => $ar_group["NAME"],
				'DEPTH_LEVEL' => $ar_group["DEPTH_LEVEL"]
			);
		}

		//Формируем массив для функции создания дерева.
		$new = array();
		foreach($arList as $val){
			$new[$val['PARENT']][] = $val;
		}

		//Это, конечно, стоит переосмыслить, но пока сойдёт. Да и функции полезные сами по себе.
		$tree = self::createTree($new, $new[0]);
		$options .= self::showTree($tree, $arValue);
		$html = str_replace('#OPTIONS#', $options, '
			<select name="'.$strHTMLControlName['VALUE'].'">
				#OPTIONS#
			</select>
		');

		return $html;
	}
}



//Обработчик для свойства boolean
AddEventHandler("iblock", "OnIBlockPropertyBuildList", array("CIBlockPropertyBoolean", "GetUserTypeDescription"));

/**
 * Свойство Web Profy: Boolean, используется для булевых значений Да/Нет
 *
 * Предпочтительно в использовании, потому что по умолчанию битрикс хранит свойства-чекбоксы
 * в отдельной таблице, что сказывается на производительности.
 *
 *
 * Для использования в фильтре необходимо передавать значение "true" (без кавычек), "1" (в кавычках или без кавычек)
 * Например,
 * $arFilter = array (
 *     '=PROPERTY_520' => true,
 *     'IBLOCK_ID' => 19,
 *     'IBLOCK_LID' => 's1',
 * );
 *
 * $arRes = CIBlockElement::GetList(array(), $arFilter);
 *
 * Для выборки всех элементов у которых свойство не заполнено
 * необходимо передавать значение "false" (без кавычек)
 * Например,
 * $arFilter = array('=PROPERTY_520' => false);
 *
 *
 * Class CIBlockPropertyBoolean
 *
 */
class CIBlockPropertyBoolean extends CIBlockPropertyElementList{

	/**
	 * Функция, передающаяся в обработчик событий
	 * Регистрирует это свойство
	 * @return array
	 */
	public static function GetUserTypeDescription(){
		return array(
			'PROPERTY_TYPE' => 'S', // На самом деле — это строка
			'USER_TYPE' => 'wp_iblock_boolean',
			"DESCRIPTION" => "Web Profy: Boolean",
			"GetPropertyFieldHtml" => array(__CLASS__, "GetPropertyFieldHtml"),
			'GetAdminListViewHTML' => array(__CLASS__,'GetAdminListViewHTML'),
			'GetPublicViewHTML' => array(__CLASS__, 'GetPublicViewHTML'),
			'GetPublicEditHTML' => array(__CLASS__, 'GetPublicEditHTML'),
			'GetAdminFilterHTML' => array(__CLASS__,'GetAdminFilterHTML'),
			'GetPublicFilterHTML' => array(__CLASS__, 'GetPublicFilterHTML'),
			'ConvertToDB' => array(__CLASS__, 'ConvertToDB'),
			'ConvertFromDB' => array(__CLASS__, 'ConvertFromDB'),
			'AddFilterFields' => array(__CLASS__, 'AddFilterFields'), //Недокументированная функция, которая позволяет модифицировать фильтр в админке
		);
	}

	/**
	 * html для отображения свойства в админке при редактировании. Чекбокс.
	 *
	 * @param $arProperty
	 * @param $arValue
	 * @param $strHTMLControlName
	 * @return string
	 */
	public static function GetPropertyFieldHtml($arProperty, $arValue, $strHTMLControlName){
		if ($arValue['VALUE'] === null || $arValue['VALUE'] === false || $arValue['VALUE'] === '') {
			$newID = (!isset($_REQUEST['ID']) || (int)$_REQUEST['ID'] <= 0 || (isset($_REQUEST['action']) && $_REQUEST['action'] == 'copy'));
			if ($newID) {
				$arValue['VALUE'] = $arProperty['DEFAULT_VALUE'];
			}
		}
		$arValue['VALUE'] = (int)$arValue['VALUE'];
		if ($arValue['VALUE'] != 1) {
			$arValue['VALUE'] = 0;
		}
		$checked = '';
		if ($arValue['VALUE']==1) {
			$checked = 'checked="checked"';
		}

		$html = '<input type="hidden" name="'.htmlspecialcharsbx($strHTMLControlName['VALUE']).'" id="'.$strHTMLControlName['VALUE'].'_N" value="0" />' . 
				'<input type="checkbox" name="'.htmlspecialcharsbx($strHTMLControlName['VALUE']).'" id="'.$strHTMLControlName['VALUE'].'_Y" value="1" ' . $checked . '/>';

		return $html;
	}

	/**
	 * Возможные значения свойств. Ключи соответствуют значению.
	 * При необходимости — единственное место, требующее локализации
	 * @param $arFields
	 * @return array
	 */
	public static function PrepareSettings($arFields) {
		$arView = array(
			0 => 'Нет',
			1 => 'Да'
		);

		return array(
			'VIEW' => $arView,
			'EMPTY' => '(любой)'
		);
	}

	/**
	 * Вывод свойства для таблицы в админке. Просто строка.
	 *
	 * @param $arProperty
	 * @param $arValue
	 * @param $strHTMLControlName
	 * @return mixed
	 */
	public static function GetAdminListViewHTML($arProperty, $arValue, $strHTMLControlName) {
		$arSettings = static::PrepareSettings($arProperty);
		if ('|'.$arValue['VALUE'] != '|'.(int)$arValue['VALUE']) {
			return $arSettings['VIEW'][0];
		}
		if ($arValue['VALUE'] != 1 && $arValue['VALUE'] != 0) {
			return $arSettings['VIEW'][0];
		}
		return htmlspecialcharsEx($arSettings['VIEW'][$arValue['VALUE']]);
	}

	/**
	 * Вывод свойства для фильтра в админке. Селект, аналогичный селекту активности.
	 *
	 * @param $arProperty
	 * @param $strHTMLControlName
	 * @return string
	 */
	public static function GetAdminFilterHTML($arProperty, $strHTMLControlName) {
		$arSettings = static::PrepareSettings($arProperty);

		$strCurValue = '';
		if (array_key_exists($strHTMLControlName['VALUE'], $_REQUEST) && ($_REQUEST[$strHTMLControlName['VALUE']] == 1 || $_REQUEST[$strHTMLControlName['VALUE']] == 0)) {
			$strCurValue = $_REQUEST[$strHTMLControlName['VALUE']];
		} elseif (isset($GLOBALS[$strHTMLControlName['VALUE']]) && ($GLOBALS[$strHTMLControlName['VALUE']] == 1 || $GLOBALS[$strHTMLControlName['VALUE']] == 0)) {
			$strCurValue = $GLOBALS[$strHTMLControlName['VALUE']];
		}

		$strResult = '<select name="'.htmlspecialcharsbx($strHTMLControlName['VALUE']).'" id="filter_'.htmlspecialcharsbx($strHTMLControlName['VALUE']).'">';
		$strResult .= '<option value=""'.('' == $strCurValue ? ' selected="selected"' : '').'>'.$arSettings['EMPTY'].'</option>';
		foreach ($arSettings['VIEW'] as $key => $value) {
			$strResult .= '<option value="'.intval($key).'"'.($strCurValue != '' && $key == $strCurValue ? ' selected="selected"' : '').'>'.htmlspecialcharsEx($value).'</option>';
		}
		$strResult .= '</select>';

		return $strResult;
	}

	/**
	 * Вывод свойства элемента в публичке. Строка.
	 *
	 *
	 * @param $arProperty
	 * @param $arValue
	 * @param $strHTMLControlName
	 * @return mixed
	 */
	public static function GetPublicViewHTML($arProperty, $arValue, $strHTMLControlName) {
		$arSettings = static::PrepareSettings($arProperty);
		if ('|'.$arValue['VALUE'] != '|'.(int)$arValue['VALUE']) {
			$arValue['VALUE'] = 0;
		}
		if ($arValue['VALUE'] != 1 && $arValue['VALUE'] != 0) {
			$arValue['VALUE'] = 0;
		}
		return htmlspecialcharsex($arSettings['VIEW'][$arValue['VALUE']]);
	}

	/**
	 * Вывод свойства для изменения элемента в публичке. Чекбокс.
	 *
	 * @param $arProperty
	 * @param $arValue
	 * @param $strHTMLControlName
	 * @return string
	 */
	public static function GetPublicEditHtml($arProperty, $arValue, $strHTMLControlName) {
		if ($arValue['VALUE'] === null || $arValue['VALUE'] === false || $arValue['VALUE'] === '') {
			$arValue['VALUE'] = $arProperty['DEFAULT_VALUE'];
		}

		$arValue['VALUE'] = (int)$arValue['VALUE'];
		if ($arValue['VALUE'] != 1) {
			$arValue['VALUE'] = 0;
		}

		$checked = '';
		if ($arValue['VALUE']==1) {
			$checked = 'checked="checked"';
		}

		$strResult = '<input type="hidden" name="'.htmlspecialcharsbx($strHTMLControlName['VALUE']).'" id="'.$strHTMLControlName['VALUE'].'_N" value="0" />' . 
					 '<input type="checkbox" name="'.htmlspecialcharsbx($strHTMLControlName['VALUE']).'" id="'.$strHTMLControlName['VALUE'].'_Y" value="1" ' . $checked . '/>';
		return $strResult;
	}

	/**
	 * Вывод свойства для фильтра в публичке. Селект, аналогичный селекту активности.
	 *
	 * @param $arProperty
	 * @param $strHTMLControlName
	 * @return string
	 */
	public static function GetPublicFilterHTML($arProperty, $strHTMLControlName) {

		$arSettings = static::PrepareSettings($arProperty);

		$strCurValue = '';
		if (isset($_REQUEST[$strHTMLControlName['VALUE']]) && ($_REQUEST[$strHTMLControlName['VALUE']] == 1 || $_REQUEST[$strHTMLControlName['VALUE']] == 0)) {
			$strCurValue = $_REQUEST[$strHTMLControlName['VALUE']];
		}

		$strResult = '<select name="'.htmlspecialcharsbx($strHTMLControlName['VALUE']).'" id="filter_'.htmlspecialcharsbx($strHTMLControlName['VALUE']).'">';
		$strResult .= '<option value=""'.('' == $strCurValue ? ' selected="selected"' : '').'>'.$arSettings['EMPTY'].'</option>';
		foreach ($arSettings['VIEW'] as $key => $value) {
			$strResult .= '<option value="'.intval($key).'"'.($strCurValue != '' && $key == $strCurValue ? ' selected="selected"' : '').'>'.htmlspecialcharsEx($value).'</option>';
		}
		$strResult .= '</select>';

		return $strResult;
	}

	/**
	 * Функция, приводящая все значения к 1 при сохранении.
	 *
	 * @param $arProperty
	 * @param $value
	 * @return mixed
	 */
	public static function ConvertToDB($arProperty, $value) {
		$value['VALUE'] = intval($value['VALUE']);
		if ($value['VALUE'] != 1) {
			$value['VALUE'] = null;
		}
		return $value;
	}

	/**
	 * Функция, приводящая все значения к 1 при получении свойства.
	 *
	 * @param $arProperty
	 * @param $value
	 * @return mixed
	 */
	public static function ConvertFromDB($arProperty, $value){
		if ($value['VALUE'] != '') {
			$value['VALUE'] = intval($value['VALUE']);
			if ($value['VALUE'] != 1) {
				$value['VALUE'] = null;
			}
		}
		return $value;
	}

	/**
	 * Функция, переопределяющяя фильтр по умолчанию в административной части
	 * Если в фильтр передаётся 1, то ищем 1. Если что-нибудь другое (например 0), то ищем всё, кроме 1.
	 * @param $arProperty
	 * @param $strHTMLControlName
	 * @param $arFilter
	 * @param $filtered
	 */
	public static function AddFilterFields( $arProperty, $strHTMLControlName, &$arFilter, &$filtered ){
		if( isset( $_REQUEST[$strHTMLControlName['VALUE']] ) ){
			$prefix = $_REQUEST[$strHTMLControlName['VALUE']] == '1' ? '=' : '!=';
			$arFilter[$prefix.'PROPERTY_'.$arProperty['ID']] = '1';
			$filtered = TRUE;

		}
	}
}






//Чиним службу доставки по умолчанию.
AddEventHandler("sale", "OnSaleComponentOrderOneStepOrderProps", "fixOrderDefaultLocation");
 
function fixOrderDefaultLocation(&$arResult, &$arUserResult, &$arParams){
   foreach ($arResult['ORDER_PROP']['USER_PROPS_Y'] as $key => &$arProp) {
      if($arProp['TYPE'] == 'LOCATION'){
         if(!$arProp['VALUE']){
            $arProp['VALUE'] = $arProp['DEFAULT_VALUE'];
            if(!$arUserResult["DELIVERY_LOCATION"]){
               $arUserResult["DELIVERY_LOCATION"] = $arProp['DEFAULT_VALUE'];
            }
         }
      }
   }
   unset($arProp);
}

function webFormAntiSpamBeforeResultAdd($WEB_FORM_ID, $arFields, $arrVALUES)
{
	global $APPLICATION;
	if($_REQUEST['confirm'] == '1')
		$APPLICATION->ThrowException('Отправка формы автоматическими средствами запрещена');
}
AddEventHandler('form', 'onBeforeResultAdd', 'webFormAntiSpamBeforeResultAdd');

function webFormTopicEmails(&$event, &$lid, &$arFields)
{
	//AddMessage2Log('Event Add -- '.print_r($event, true). ' -- '.print_r($arFields, true));
	if($arFields['RS_FORM_SID'] == 'FEEDBACK'){
		$matches = array();
		preg_match('/(.*) \((.*)\) \[(\d+)\]$/', $arFields['theme'], $matches);
		$arFields['topic_email'] = $matches[2];
	}
}
AddEventHandler('main', 'OnBeforeEventAdd', 'webFormTopicEmails');
//Убираем авторизацию по Basic Auth
//AddEventHandler("main", "onBeforeUserLoginByHttpAuth", array("CAreYouSerious", "NoJustNoThisIsStupid"));

class CAreYouSerious{
	function NoJustNoThisIsStupid(&$arAuth){
		unset($arAuth["basic"]);
		return null;
	}
}

////Привязываем к псевдоразделам
//AddEventHandler("iblock", "OnAfterIBlockElementUpdate", "autoPseudoSection");
//AddEventHandler("iblock", "OnAfterIBlockElementAdd", "autoPseudoSection");
//function autoPseudoSection(&$arFields)
//{
//	if ($arFields["ID"]) {
//		setPseudoSectionsToElement($arFields["ID"]);
//	}
//}

/** Ловим письмо о заказе и вставляем туда список товаров в виде HTML */

AddEventHandler("sale", "OnOrderNewSendEmail", "bxModifySaleMails");
function bxModifySaleMails($orderID, &$eventName, &$arFields)
{
	global $APPLICATION;
	global $CUSTOM_SELECT_PROPS;

	// Дополняем список полей свойствами заказа для использования их значений в почтовых шаблонах
	$resProps = CSaleOrderPropsValue::GetList(
	    array("SORT" => "ASC"),
	    array(
	        "ORDER_ID" => $orderID
	    )
    );
	while($arProp = $resProps->Fetch()) {
	    $arFields['ORDER_PROP_'.$arProp['CODE']] = $arProp['VALUE'];
	}
	
	if(!trim($arFields['ORDER_PROP_CITY_EMAIL']))
		$arFields['ORDER_PROP_CITY_EMAIL'] = 'orders@easy-comfort.ru';
	
	$arFields['ORDER_PROP_CITY'] = explode(", ", $arFields['ORDER_PROP_CITY'])[1];

	//Контент для пользователя
	ob_start();
	$APPLICATION->IncludeComponent("bitrix:sale.personal.order.detail","mail",Array(
			"PATH_TO_LIST" => "/personal/order/",
			"PATH_TO_CANCEL" => "/personal/order/cancel/",
			"PATH_TO_PAYMENT" => "payment.php",
			"PATH_TO_PERSONAL" => "/personal/",
			"ID" => $orderID,
			"CACHE_TYPE" => "N",
			"CACHE_TIME" => "0",
			"CACHE_GROUPS" => "Y",
			"SET_TITLE" => "N",
			"ACTIVE_DATE_FORMAT" => "d.m.Y",
			"PREVIEW_PICTURE_WIDTH" => "110",
			"PREVIEW_PICTURE_HEIGHT" => "110",
			"RESAMPLE_TYPE" => "1",
			"CUSTOM_SELECT_PROPS" => ($CUSTOM_SELECT_PROPS)? $CUSTOM_SELECT_PROPS : array() ,
			"PROP_1" => "",
			"PROP_2" => "",	// Не показывать свойства для типа плательщика "Юридическое лицо" (s1),
			'AUTH_FORM_IN_TEMPLATE' => 'Y'
		)
	);

	$arFields["HTML_CONTENT"] =  ob_get_clean();


	//Контент для администратора
	ob_start();
	$APPLICATION->IncludeComponent("bitrix:sale.personal.order.detail","mail_admin",Array(
			"PATH_TO_LIST" => "/personal/order/",
			"PATH_TO_CANCEL" => "/personal/order/cancel/",
			"PATH_TO_PAYMENT" => "payment.php",
			"PATH_TO_PERSONAL" => "/personal/",
			"ID" => $orderID,
			"CACHE_TYPE" => "N",
			"CACHE_TIME" => "0",
			"CACHE_GROUPS" => "Y",
			"SET_TITLE" => "N",
			"ACTIVE_DATE_FORMAT" => "d.m.Y",
			"PREVIEW_PICTURE_WIDTH" => "110",
			"PREVIEW_PICTURE_HEIGHT" => "110",
			"RESAMPLE_TYPE" => "1",
			"CUSTOM_SELECT_PROPS" => ($CUSTOM_SELECT_PROPS)? $CUSTOM_SELECT_PROPS : array() ,
			"PROP_1" => "",
			"PROP_2" => "",	// Не показывать свойства для типа плательщика "Юридическое лицо" (s1),
			'AUTH_FORM_IN_TEMPLATE' => 'Y',
			'USER_FIELDS' => array(
				'ID',
				'LOGIN',
				'LAST_NAME',
				'NAME',
				'EMAIL',
				'PERSONAL_PHONE'
			)
		)
	);
	$adminContent =  ob_get_clean();
	$arFields['ADMIN_HTML_CONTENT'] = $adminContent;
}

/**
 * Отправка писем оповещения администратору после запалнения форм  FAQ и Отзывы
 **/

AddEventHandler("iblock", "OnAfterIBlockElementAdd", "sendPostOnNewQuestion");
function sendPostOnNewQuestion(&$arFields) {

	if($arFields["IBLOCK_ID"] == FAQ_IBLOCK_ID) {

		$property = array();
		foreach ($arFields["PROPERTY_VALUES"] as $key => $item) {
			$prop = CIBlockProperty::GetByID($key);
			$prop = $prop->GetNext();

			if(is_array($item)) {
				$property[$prop["CODE"]]["VALUE"] = $item["VALUE"]["TEXT"];
			} else {
				$property[$prop["CODE"]]["VALUE"] = $item;
			}
		}

		$arEventFields = array(
			"NAME" => $arFields["NAME"],
			"QUASTION" => $property["FAQ_QUESTION"]["VALUE"]
		);

		CEvent::Send("WP_NEW_FOR_FAQ", 's1', $arEventFields);
	}elseif ( $arFields['IBLOCK_ID'] == REVIEWS_IBLOCK_ID ) {
		$PARAMS = array(
			'U_NAME'=>$arFields['NAME'],
			'U_TOWN'=>($arFields['PROPERTY_VALUES']['TOWN'])? $arFields['PROPERTY_VALUES']['TOWN']: $arFields['PROPERTY_VALUES'][58],
			'DATE_ACTIVE'=>($arFields['DATE_ACTIVE_FROM'])?$arFields['DATE_ACTIVE_FROM']: date("m.d.Y") ,
			'REVIEW_TEXT'=>$arFields['PREVIEW_TEXT'],
			'IBLOCK_ID'=>$arFields['IBLOCK_ID'],
			'ID'=>$arFields['ID'],
		);
		CEvent::Send("WEBPROFY_NEW_REVIEW", 's1', $PARAMS);
	}

}

/**
 * Всегда отсылаем письмо новому пользователю
 * (нужно в основном для авторегистрации пользователя при заказе)
 */

AddEventHandler("main", "OnAfterUserAdd", "OnSendAfterUserAddHandler");
function OnSendAfterUserAddHandler(&$arFields){
	CEvent::Send(
		"USER_INFO",
		"s1",
		Array(
			"NAME" => $arFields["NAME"],
			"LAST_NAME" => $arFields["LAST_NAME"],
			"EMAIL" => $arFields['EMAIL'],
			"MESSAGE" => GetMessage("SUCCESSFULLY_REGISTE"),
			"LOGIN" => $arFields['EMAIL'],
			"SERVER_NAME" => $_SERVER['SERVER_NAME'].LANG_URL,
			"PASSWORD" =>  $arFields["CONFIRM_PASSWORD"],
			"CHECKWORD" =>  $arFields["CHECKWORD"],
			"URL_LOGIN" =>  $arFields["LOGIN"],
		),
		"N",
		""
	);
	return $arFields;
}

//AddEventHandler("main", "OnEndBufferContent", "deleteKernelJs");
//AddEventHandler("main", "OnEndBufferContent", "deleteKernelCss");

function deleteKernelJs(&$content) {
	global $USER, $APPLICATION;
	if((is_object($USER) && $USER->IsAuthorized()) || strpos($APPLICATION->GetCurDir(), "/bitrix/")!==false) return;
	if($APPLICATION->GetProperty("save_kernel") == "Y") return;

	$arPatternsToRemove = Array(
		'/<script.+?src=".+?kernel_main\/kernel_main\.js\?\d+"><\/script\>/',
		'/<script.+?src=".+?bitrix\/js\/main\/core\/core[^"]+"><\/script\>/',
		'/<script.+?>BX\.(setCSSList|setJSList)\(\[.+?\]\).*?<\/script>/',
		'/<script.+?>if\(\!window\.BX\)window\.BX.+?<\/script>/',
		'/<script[^>]+?>\(window\.BX\|\|top\.BX\)\.message[^<]+<\/script>/',
	);

	$content = preg_replace($arPatternsToRemove, "", $content);
	$content = preg_replace("/\n{2,}/", "\n\n", $content);
}

function deleteKernelCss(&$content) {
	global $USER, $APPLICATION;
	if((is_object($USER) && $USER->IsAuthorized()) || strpos($APPLICATION->GetCurDir(), "/bitrix/")!==false) return;
	if($APPLICATION->GetProperty("save_kernel") == "Y") return;

	$arPatternsToRemove = Array(
		'/<link.+?href=".+?kernel_main\/kernel_main\.css\?\d+"[^>]+>/',
		'/<link.+?href=".+?bitrix\/js\/main\/core\/css\/core[^"]+"[^>]+>/',
		'/<link.+?href=".+?bitrix\/templates\/[\w\d_-]+\/styles.css[^"]+"[^>]+>/',
		'/<link.+?href=".+?bitrix\/templates\/[\w\d_-]+\/template_styles.css[^"]+"[^>]+>/',
	);

	$content = preg_replace($arPatternsToRemove, "", $content);
	$content = preg_replace("/\n{2,}/", "\n\n", $content);
}


//AddEventHandler("main", "OnEndBufferContent", Array("Webprofy\\UnCache", "OnEndBufferContentHandler"));

$eventManager = \Bitrix\Main\EventManager::getInstance();
$eventManager->addEventHandler(
	"sale",
	'OnSaleComponentOrderOneStepFinal',
	Array("Webprofy\\FileStorage", "OnSaleComponentOrderOneStepFinal")
);

//$eventManager->addEventHandler(
//	"form",
//	"onAfterResultAdd",
//	Array("Webprofy\\FormEvent", "OnAfterResultAdd")
//);

/**
 * Обработчик для проверки заказа перед сохранением
 */
$eventManager->addEventHandler(
	"sale",
	"OnSaleOrderBeforeSaved",
	Array("Webprofy\\OrderCheck", "onSaleOrderBeforeSaved")
);


/**
 * Замена заголовков и хлебных крошек в теле страницы
 * Ищет вхождения значений констант BREADCRUMBS, CONDITIONAL_BREADCRUMBS, H1, CONDITIONAL_H1
 * Подставляет вместо них корректные значения
 */
AddEventHandler('main', 'OnEndBufferContent', 'ReplaceBreadCrumbsAndH1');
function ReplaceBreadCrumbsAndH1(&$buffer) {
	global $APPLICATION;


	$templatePath = $APPLICATION->GetTemplatePath('components/bitrix/breadcrumb/.default/template.php');
	$breadcrumbs = $APPLICATION->GetNavChain(false, 0, $templatePath, true);

	// Обычные хлебные крошки
	if (strpos($buffer, BREADCRUMBS) !== false) {
		$buffer = str_replace(BREADCRUMBS, $breadcrumbs, $buffer);
	}

	// Хлебные крошки по условию показа
	if (strpos($buffer, CONDITIONAL_BREADCRUMBS) !== false) {
		if($APPLICATION->GetProperty('DONOTSHOWBREADCRUMBS') == 'Y'){
			$buffer = str_replace(CONDITIONAL_BREADCRUMBS, '', $buffer);
		}else{
			$buffer = str_replace(CONDITIONAL_BREADCRUMBS, $breadcrumbs, $buffer);
		}
	}


	$h1 = '<h1>'.$APPLICATION->GetTitle().'</h1>';

	// Обычные заголовки
	if (strpos($buffer, H1) !== false) {
		$buffer = str_replace(H1, $h1, $buffer);
	}

	// Заголовки по условию показа
	if (strpos($buffer, CONDITIONAL_H1) !== false) {
		if ($APPLICATION->GetProperty('DONOTSHOWTITLE') == 'Y') {
			$buffer = str_replace(CONDITIONAL_H1, '', $buffer);
		}else{
			$buffer = str_replace(CONDITIONAL_H1, $h1, $buffer);
		}
	}
}

// Дополнительные функции для формирования метатегов в админке

require_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/iblock/lib/template/functions/fabric.php');
use Bitrix\Main;
$eventManager = Main\EventManager::getInstance();
$eventManager->addEventHandler("iblock", "OnTemplateGetFunctionClass", "myOnTemplateGetFunctionClass");

/**
 * @param Main\Event $event
 * @return Main\EventResult
 *
 * Добавляет дополнительные функции для оформления метатегов инфоблоков в вдминке
 */
function myOnTemplateGetFunctionClass(Bitrix\Main\Event $event) {
    $arParam = $event->getParameters();
    $functionClass = $arParam[0];
    if (is_string($functionClass) && class_exists($functionClass) && (
            $functionClass=='sitename'
        )){
        $result = new Bitrix\Main\EventResult(1,$functionClass);
        return $result;
    }
}

/**
 * Class sitename
 *
 * Класс реализует функцию sitename для вывода имени сайта в CEO-настройках
 *
 * Пример:
 *
 * {=sitename}
 */
class sitename extends Bitrix\Iblock\Template\Functions\FunctionBase
{
    public function onPrepareParameters(\Bitrix\Iblock\Template\Entity\Base $entity, $parameters)
    {
        $arguments = array();
        /** @var \Bitrix\Iblock\Template\NodeBase $parameter */
        foreach ($parameters as $parameter){
            $arguments[] = $parameter->process($entity);
        }
        return $arguments;
    }

    /**
     * @param array $parameters
     * @return mixed
     */
    public function calculate(array $parameters)
    {
        $rsSites = CSite::GetList($by="sort", $order="desc", array('ID' => SITE_ID));

        if ($arSite = $rsSites->Fetch()) {
            return $arSite['NAME'];
        }

        return '';
    }
}

define("PREFIX_PATH_404", "/404.php");
 
AddEventHandler("main", "OnAfterEpilog", "checkForError404");
 
function checkForError404() {
    global $APPLICATION;
 
    if(CHTTP::GetLastStatus() == "404 Not Found")
	define("ERROR_404", "Y"); // Стандартные news и catalog ставят статус, но не определяют константу 404
 
    // Check if we need to show the content of the 404 page
    if (!defined('ERROR_404') || ERROR_404 != 'Y') {
        return;
    }
 
    // Display the 404 page unless it is already being displayed
    if ($APPLICATION->GetCurPage() != PREFIX_PATH_404) {
        header('X-Accel-Redirect: '.PREFIX_PATH_404);
        exit();
    }
}

/**
 * Класс заменяет контент перед выводом его в браузер. Singleton.
 * Замены регистрируются через функцию register
 * Например: $CR = ContentReplacer::getInstance(); CR->register('Мама', 'Папа');
 * Также есть ob_start-вариант:
 *    CR->registerStart('#MY_FORM#');
 *    (подключение компонента или любой другой вывод);
 *    CR->registerEnd();
 */
AddEventHandler('main', 'OnEndBufferContent', array('ContentReplacer', 'replace'));
class ContentReplacer {
	private static $instance = null;
    private $tmpCode;

	public static function getInstance() {
		if (null === self::$instance) {
			self::$instance = new self();
		}
		return self::$instance;
	}
	private function __clone() {}
	private function __construct() {
		$this->arSearch = array();
		$this->arReplace = array();
        $this->isAjax = isset($_POST['ajax']) || isset($_GET['formresult']);
	}

    public function register($code, $val) {
        if($index = array_search($code, $this->arSearch) === false){
            $this->arSearch[] = $code;
            $this->arReplace[] = $val;
        } else {
            $this->arReplace[$index] = $val;
        }
    }
    public function registerStart($code) {
        if($this->isAjax)
            return;
        $this->tmpCode = $code;
        ob_start();
    }
    public function registerEnd() {
        if($this->isAjax)
            return;
        $content = ob_get_clean();
        $this->register($this->tmpCode, $content);
        unset($this->tmpCode);
    }
    public static function replace(&$buffer) {
        $CR = self::getInstance();
        $buffer = str_replace($CR->arSearch, $CR->arReplace, $buffer);
    }
}

// set email as user login on update
AddEventHandler("main", "OnBeforeUserUpdate", "OnBeforeUserUpdateHandler");
function OnBeforeUserUpdateHandler(&$arFields) {
	if ($arFields['EMAIL']) {
		if($arFields['LOGIN'] == 'admin'){
			return;
		}
		$arFields['LOGIN'] = $arFields['EMAIL'];
	}
}

AddEventHandler("search", "BeforeIndex", "BeforeIndexHandler");
//обработчик события "BeforeIndex", убирает из индексации разделы, у которых активна галочка "скрывать в подразделах", Задается константой HIDE_IN_SEARCH_PROPERTY_NAME
function BeforeIndexHandler($arFields)
{
	if(!CModule::IncludeModule("iblock")){
		return $arFields;
	}

	//Обработка только для инфоблока с типом каталог
	if(($arFields["MODULE_ID"] == "iblock") && ($arFields['PARAM1'] == 'catalog_zanussi'))
	{
		//Дальнейшая обработка только для разделов
		if(substr($arFields['ITEM_ID'], 0,1) == 'S'){
			$sectionId = substr($arFields['ITEM_ID'], 1);


			$arFilter = array(
				"IBLOCK_ID" => $arFields['PARAM2'],
				"ID" => $sectionId,
				HIDE_IN_SEARCH_PROPERTY_NAME => 1
			);
			$dbRes = CIBlockSection::GetList([], $arFilter, false, []);
			if($res = $dbRes->GetNext()){
				$arFields["BODY"]='';
				$arFields["TITLE"]='';
			}
		}
		/*
		 * Исключаем все элементы каталога, которые привязаны только к разделу "ZZZ"
		 */
		if($arFields['PARAM2'] == CATALOG_IBLOCK_ID) {
		    $rsSections = CIBlockElement::GetElementGroups($arFields['ITEM_ID'], true);
		    while($arSection = $rsSections->Fetch()) {
                if($rsSections->selectedRowsCount() == 1 && strtolower(trim($arSection['NAME'])) == "zzz") {
                    $arFields["BODY"]='';
                    $arFields["TITLE"]='';
                }
		    }		    
		}
	}
	return $arFields; // вернём изменения
}

/**
 * Создание заказа из формы
 */
AddEventHandler('form', 'onAfterResultAdd', 'MakeOrderFromFormResult');
function MakeOrderFromFormResult($WEB_FORM_ID, $RESULT_ID) {

	global $USER;

	if(CModule::IncludeModule('catalog') && CModule::IncludeModule('iblock') && CModule::IncludeModule('sale')) {

		// Форма "Товар под заказ"
		if ($WEB_FORM_ID == CUSTOM_ORDER_WEB_FORM_ID) { // Константа определяется в ./constants.php

			// Получаем ответы по форме
			$arFormAnswer = CFormResult::GetDataByID($RESULT_ID);

			$arFields = Array(
				'NAME' => $arFormAnswer['name'][0]['USER_TEXT'],
				'EMAIL' => $arFormAnswer['email'][0]['USER_TEXT'],
				'PHONE' => $arFormAnswer['phone'][0]['USER_TEXT'],
				'PRODUCT_ID' => intVal($arFormAnswer['product_id'][0]['USER_TEXT']),
				'PRODUCT' => Array()
			);

			$res = CIBlockElement::GetList(
				Array(),
				Array("ID" => $arFields['PRODUCT_ID']),
				false,
				false,
				Array("ID", "IBLOCK_ID", "NAME", "CATALOG_1_PRICE")
			);
			if($ob = $res->GetNextElement()){
				$arFields['PRODUCT'] = $ob->GetFields();
				$arFields['PRODUCT']['PRICE'] = CPrice::GetBasePrice($arFields['PRODUCT_ID']);
			}

			if($arFields['EMAIL'] && $arFields['PRODUCT']['ID']) {

				// Создаем или получаем существующего пользователя
				$userId = 0;
				$obUser = new CUser;
				$arUser = CUser::GetByLogin($arFields['EMAIL'])->Fetch();
				if($arUser) { // Пользователь существует
					$userId = $arUser['ID'];
					$obUser->Update($userId, array("PERSONAL_PHONE" => $arFields['PHONE'], 'NAME' => $arFields['NAME']));
				} else { // Создаем пользователя

					$userPassword = "cl_pss!".time();

					$arUserFields = Array(
						"EMAIL" => $arFields['EMAIL'],
						"LOGIN" => $arFields['EMAIL'],
						"NAME" => $arFields['NAME'],
						"PERSONAL_PHONE" => $arFields['PHONE'],
						"LID" => 'ru',
						"ACTIVE" => "Y",
						"PASSWORD" => $userPassword,
						"CONFIRM_PASSWORD" => $userPassword
					);
					$userId = $obUser->Add($arUserFields);
				}

				if($userId) {

					$USER->Authorize($userId);

					// Константы определяются в ./constants.php
					$personalType = CUSTOM_ORDER_PERSONAL_TYPE_ID; // ID типа плательщика
					$deliveryId = CUSTOM_ORDER_DELIVERY_ID; // ID службы доставки
					$paySystemId = CUSTOM_ORDER_PAY_SYSTEM_ID; // ID способа оплаты

					// Корзина
					$basket = Bitrix\Sale\Basket::create('s1');
					$item = $basket->createItem("catalog", $arFields['PRODUCT']['ID']);
					$item->setFields(Array(
						'NAME' => $arFields['PRODUCT']['NAME'],
						'PRICE' => $arFields['PRODUCT']['PRICE']["PRICE"],
						'CURRENCY' => $arFields['PRODUCT']['PRICE']["CURRENCY"],
						'QUANTITY' => 1
					));

					// Заказ
					$order = Bitrix\Sale\Order::create('s1', $userId);
					$order->setPersonTypeId($personalType);
					$order->setBasket($basket);

					// Отгрузка
					$shipmentCollection = $order->getShipmentCollection();
					$shipment = $shipmentCollection->createItem(
						Bitrix\Sale\Delivery\Services\Manager::getObjectById($deliveryId)
					);

					// Кладем товары в отгрузку
					$shipmentItemCollection = $shipment->getShipmentItemCollection();
					foreach($basket as $basketItem) {
						$item = $shipmentItemCollection->createItem($basketItem);
						$item->setQuantity($basketItem->getQuantity());
					}

					// Оплата
					$paymentCollection = $order->getPaymentCollection();
					$payment = $paymentCollection->createItem(
						Bitrix\Sale\PaySystem\Manager::getObjectById($paySystemId)
					);

					$payment->setField("SUM", $order->getPrice());
					$payment->setField("CURRENCY", $order->getCurrency());

					// Сохраняем заказ
					$order->save();
					$USER->Logout();
				}

			}

		}

	}

}


AddEventHandler("iblock", "OnBeforeIBlockSectionAdd", "DisableZSection");
AddEventHandler("iblock", "OnBeforeIBlockSectionUpdate", "DisableZSection");

function DisableZSection(&$arFields) {
	if(strtolower(trim($arFields['NAME'])) == "zzz") {
		$arFields['ACTIVE'] = 'N';
		$arFields['UF_HIDE_IN_SEARCH'] = 1;
	}
}