• Каким событием ядра D7 PHP Битрикс24 можно отловить входящее письмо?

    @sevnet Автор вопроса
    Системный аналитик, бизнес-консультант
    Плохо искал((
    событие на получение почты onMailMessageNew
    
    <?php
    
    use Bitrix\Main\Diag\Debug;
    use Bitrix\Mail\Helper\Message;
    use \Bitrix\Main\Entity\Event;
    
    CModule::IncludeModule('mail');
    $eventManager = \Bitrix\Main\EventManager::getInstance();
    
    $eventManager->addEventHandler('mail', 'onMailMessageNew', 'onMailMessageNew');
    function onMailMessageNew($event)
    {
       $message = $event->getParameter('message');
       Debug::dumpToFile( $message);
    }
    Ответ написан
    Комментировать
  • Реализован ли в VS Code поиск по выделенному фрагменту кода?

    Balya
    @Balya
    Люди и технологии
    В плашке поиска (Ctrl+F) есть кнопка, похожая на выравнивание текста по левому краю (Alt+L). Она то как раз указывает на поиск по фрагменту.

    5c3a7fff1fa90932732932.png
    Ответ написан
    1 комментарий
  • Не выводит значение, а выводит какие-то иероглифы?

    @animof
    в settings.json

    {
      "code-runner.executorMap": {
            "javascript": "node",
            "php": "C:\\Users\\enten\\.vscode\\php\\php.exe", //путь до php, его надо скачать
            "go": "go run",
            "html": "\"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe\"",
        },
    }

    В настройки переходим, там иконка в правом верхнем углу будет, для перехода в settings.json
    Ответ написан
    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

    Надеюсь помог.
    Ответ написан
    Комментировать
  • Как преобразовать двумерный массив в одномерный PHP?

    GM_pAnda
    @GM_pAnda
    Бездельник
    Точно такой массив какой вы хотите
    $arrOne = Array(
      0 => Array(
        0 => 'name 0',
        1 => 'name 1',
        2 => 'name 2'
      ),
      1 => Array(
        0 => 100,
        1 => 200,
        2 => 300
      )
    );
    $arrTwo = array();
    
    foreach ($arrOne as $keys => $names) { 
    	foreach ($names as $key => $name) {
    		$arrTwo[$key][] = $name;
    		continue;
    	}
    	
    
    }
    
    var_dump($arrTwo);
    Ответ написан
    Комментировать