@Nentra

Почему не запускается функция при наступлении события?

В " /local/php_interface/init.php"

написал

<?
	//добавить пользователя в нужные групповые чаты
AddEventHandler("main", "OnAfterUserAdd", Array("AddUserToGroupChatsClass", "AddUserToGroupChats"), $_SERVER["DOCUMENT_ROOT"] . "/local/php_interface/event_handlers/add_user_to_group_chats_class.php");
?>


Почему у меня обработчик не запускается?
тут написано
https://dev.1c-bitrix.ru/api_help/main/functions/m...
что в функции "AddEventHandler" последним аргументом указывается путь, но событие у меня так и не наступает.

<?
	//добавить нвого пользователя в нужные групповые чаты
	class AddUserToGroupChatsClass
	{
		// создаем обработчик события "OnAfterUserAdd"
		function AddUserToGroupChats(&$arFields)
		{		 
			use Bitrix\Main\Diag;
			Diag\Debug::writeToFile("Событие наступило", $varName = "", $fileName = "logText.php");
			
		
		}
	}
	
?>
  • Вопрос задан
  • 2087 просмотров
Решения вопроса 1
gromdron
@gromdron Куратор тега Битрикс24
Работаю с Bitrix24
Да, вы почти все правильно сделали, но не так как нужно.
Прежде чем копировать бездумно прочитайте до конца, я попытался развернуть мысль, чтобы не просто дать ответ на вопрос, но и пояснить некоторые действия.

Давайте разберемся что у вас получлось правильно:
- Вы решили использовать механизм событий
- Вы правильно определили событие
- Вы использовали local-папку для разработки
- Вы попытались разделить ответственность между подпиской на событием и непосредственно ее обработчиком.

Теперь что у вас НЕ получилось.

Для начала это сама подписка на событие.
- Вы не правильно поняли ее аргументы
- Вы использовали устаревшую надстройку для подписки.

Начнем с обратного порядка: AddEventHandler это лишь обертка над \Bitrix\Main\EventManager::addEventHandlerCompatible поэтому мы будем использовать его.

Для начала перепишем ваш код дословно на "новый лад":

$eventManager = \Bitrix\Main\EventManager::getInstance();
$eventManager->addEventHandlerCompatible(
	'main',
	'OnAfterUserAdd',
	[
		'AddUserToGroupChatsClass',
		'AddUserToGroupChats'
	],
	$_SERVER["DOCUMENT_ROOT"] . "/local/php_interface/event_handlers/add_user_to_group_chats_class.php"
);


Оно выглядит лучше но по-прежнему не работает.

Порядок аргументов addEventHandlerCompatible и AddEventHandler одинаковый и состоит из:

- FROM_MODULE_ID - на какой модуль подписываемся
- MESSAGE_ID - на какое событие подписываемся
- CALLBACK - callback обработчик (будет вызван для )
- SORT - порядок выполнения относительно других событий
- FULL_PATH - путь к файлу

Т.е. получается что у тебя нарушен порядок аргументов. Корректнее было бы так:
$eventManager = \Bitrix\Main\EventManager::getInstance();
$eventManager->addEventHandlerCompatible(
	'main',
	'OnAfterUserAdd',
	[
		'AddUserToGroupChatsClass',
		'AddUserToGroupChats'
	],
	100,
	$_SERVER["DOCUMENT_ROOT"] . "/local/php_interface/event_handlers/add_user_to_group_chats_class.php"
);


Теперь разберемся с самой подписной моделью: вы хотите использовать свой класс и выделить его в отдельный файл для удобства.
Не будем поднимать вопросы по поводу нейминга, но совершенно не обязательно подключать дополнительный файл для события. Рекомендую почитать про spl_autoload и composer.
Давайте воспользуемся нашей готовой разработкой init.php и разместим в init.php маленький автолоадер.

Предположим что за добавление будет отвечать ваш класс AddUserToGroupChatsClass

Ваш init.php:
/**
 * - /local/php_interface/classes/{Path|raw}/{*|raw}.php
 * - /local/php_interface/classes/{Path|ucfirst,lowercase}/{*|ucfirst,lowercase}.php
 */
spl_autoload_register(function($sClassName)
{
	$sClassFile = __DIR__.'/classes';

	if ( file_exists($sClassFile.'/'.str_replace('\\', '/', $sClassName).'.php') )
	{
		require_once($sClassFile.'/'.str_replace('\\', '/', $sClassName).'.php');
		return;
	}

	$arClass = explode('\\', strtolower($sClassName));
	foreach($arClass as $sPath )
	{
	    $sClassFile .= '/'.ucfirst($sPath);
	}
	$sClassFile .= '.php';
	if (file_exists($sClassFile))
	{
		require_once($sClassFile);
	}
});

$eventManager = \Bitrix\Main\EventManager::getInstance();
$eventManager->addEventHandlerCompatible(

	'main',
	'OnAfterUserAdd',
	[
		'AddUserToGroupChatsClass',
		'AddUserToGroupChats'
	]
);


Теперь нужно разметить ваш класс в файле: /local/php_interface/classes/AddUserToGroupChatsClass.php
Заметьте - мы удалили сортировку (вам не важем порядок) и подключение файла - за это теперь отвечает автолоадер.

Теперь поработаем с содержимым этого файла.
Произведем косметические изменения:
- уберем лишние отступы
- добавим phpdoc

Произведем функциональные изменения:
- приведем файл к виду opentag -> namespace -> use -> class
- добавим описание метода необходимые для вызова его в call_user_func_array
- Пропишем корректные праметры к Debug::writeToFile методу

<?php

use \Bitrix\Main\Diag;

class AddUserToGroupChatsClass
{
	/**
	 * Handle main::OnAfterUserAdd event
	 *     after add user to groups
	 * @param array &$arFields User data
	 * @return void
	 */
	public static function AddUserToGroupChats( &$arFields )
	{		 
		Diag\Debug::writeToFile(
			[
				'text'   => "Событие наступило",
				'fields' => $arFields
			],
			date('d.m.Y'),
			"AddUserToGroupChatsClass.log"
		); 
	}
}


В результате проделанной работы будет создан файл `AddUserToGroupChatsClass.log` (у меня bitrix env и $_SERVER['DOCUMENT_ROOT'] указывает на /home/bitrix/www, соответственно файл располагается по пути: /home/bitrix/www/AddUserToGroupChatsClass.log)

С примерно таким содержимым:

28.09.2021:
Array
(
    [text] => Событие наступило
    [fields] => Array
        (
            [TITLE] => 
            [NAME] => test1
            [LAST_NAME] => test1
            [SECOND_NAME] => test1
            [EMAIL] => test1@test1.test1
            [LOGIN] => test1@test1.test1
            [PERSONAL_PROFESSION] => 
            [PERSONAL_WWW] => 
            [PERSONAL_ICQ] => 
            [PERSONAL_GENDER] => 
            [PERSONAL_BIRTHDAY] => 
            [PERSONAL_PHONE] => 
            [PERSONAL_FAX] => 
            [PERSONAL_MOBILE] => 
            [PERSONAL_PAGER] => 
            [PERSONAL_STREET] => 
            [PERSONAL_MAILBOX] => 
            [PERSONAL_CITY] => 
            [PERSONAL_STATE] => 
            [PERSONAL_ZIP] => 
            [PERSONAL_COUNTRY] => 0
            [PERSONAL_NOTES] => 
            [WORK_COMPANY] => 
            [WORK_DEPARTMENT] => 
            [WORK_POSITION] => 
            [WORK_WWW] => 
            [WORK_PHONE] => 
            [WORK_FAX] => 
            [WORK_PAGER] => 
            [WORK_STREET] => 
            [WORK_MAILBOX] => 
            [WORK_CITY] => 
            [WORK_STATE] => 
            [WORK_ZIP] => 
            [WORK_COUNTRY] => 0
            [WORK_PROFILE] => 
            [WORK_NOTES] => 
            [AUTO_TIME_ZONE] => 
            [XML_ID] => 
            [PHONE_NUMBER] => 
            [PASSWORD_EXPIRED] => N
            [TIME_ZONE] => 
            [LID] => s1
            [LANGUAGE_ID] => 
            [ACTIVE] => Y
            [BLOCKED] => N
            [GROUP_ID] => Array
                (
                    [0] => Array
                        (
                            [GROUP_ID] => 3
                            [DATE_ACTIVE_FROM] => 
                            [DATE_ACTIVE_TO] => 
                        )

                    [1] => Array
                        (
                            [GROUP_ID] => 12
                            [DATE_ACTIVE_FROM] => 
                            [DATE_ACTIVE_TO] => 
                        )

                    [2] => Array
                        (
                            [GROUP_ID] => 4
                            [DATE_ACTIVE_FROM] => 
                            [DATE_ACTIVE_TO] => 
                        )

                )

            [ADMIN_NOTES] => 
            [PASSWORD] => $5$hjIX0a5X2ps0X6kFG1h5xXAt4elIW.typcRgt23xwX97xU.GgGt0i3HG1a2hwZtcYXwIR3Whg6sXwV.
            [CONFIRM_PASSWORD] => test1@test1.test1
            [UF_DEPARTMENT] => Array
                (
                    [0] => 2
                )

            [UF_PHONE_INNER] => 
            [UF_USER_CRM_ENTITY] => 
            [UF_INN] => 
            [UF_DISTRICT] => 
            [UF_SKYPE] => 
            [UF_TWITTER] => 
            [UF_FACEBOOK] => 
            [UF_LINKEDIN] => 
            [UF_XING] => 
            [UF_WEB_SITES] => 
            [UF_SKILLS] => 
            [UF_INTERESTS] => 
            [UF_EMPLOYMENT_DATE] => 
            [UF_SKYPE_LINK] => 
            [UF_ZOOM] => 
            [UF_TIMEMAN] => 
            [UF_TM_MAX_START] => 00:00
            [UF_TM_MIN_FINISH] => 00:00
            [UF_TM_MIN_DURATION] => 00:00
            [UF_TM_REPORT_REQ] => 
            [UF_TM_REPORT_TPL] => Array
                (
                    [0] => 
                )

            [UF_TM_FREE] => 
            [UF_TM_TIME] => 
            [UF_TM_DAY] => 
            [UF_TM_REPORT_DATE] => 
            [UF_REPORT_PERIOD] => 
            [UF_DELAY_TIME] => 
            [UF_LAST_REPORT_DATE] => 
            [UF_SETTING_DATE] => 
            [UF_TM_ALLOWED_DELTA] => 
            [CHECKWORD] => 433ddaf3c8a14fe75431252a2709b8
            [~CHECKWORD_TIME] => now()
            [ID] => 5
            [RESULT] => 5
        )
)


Итого на выходе у нас:
- Подписка на событие (работает)
- Автолоадер, который позволит подключать классы по мере использования (без необходимости прописывать явно)
- Разделение логики между подпиской и обработчиком.

Хорошо было бы углубиться в:
- php классы (namespace, static, public, protected, private)
- composer

Надеюсь помог.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@Nentra Автор вопроса
Вот это у меня не работает, хотя должно работать

$eventManager = \Bitrix\Main\EventManager::getInstance();
$eventManager->addEventHandlerCompatible(
  'main',
  'OnAfterUserAdd',
  [
    'AddUserToGroupChatsClass',
    'AddUserToGroupChats'
  ],
  100,
  $_SERVER["DOCUMENT_ROOT"] . "/local/php_interface/event_handlers/add_user_to_group_chats_class.php"
);


Работает вот это:
AddEventHandler("main", "OnAfterUserAdd", Array("AddUserToGroupChatsClass", "AddUserToGroupChats") );
require_once($_SERVER['DOCUMENT_ROOT'] . "/local/php_interface/event_handlers/add_user_to_group_chats_class.php");


но получается у меня файл
add_user_to_group_chats_class.php
вообще каждый раз загружается, а мне бы хотелось сделать чтобы он загружался только при срабатывании события.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы