Расширение логики модулей или Logic Hooks. Часть 3

Добрый день всем читателям блога.

После долго перерыва в работе блога, я снова возвращаюсь к написанию статей, и надеюсь, теперь уже буду радовать вас новой информацией намного чаще. Хоть я это обещаю уже не в первый раз :smile: .
И так сегодня мы поговорим опять о logic hooks (логических хуках) в SugarCRM. Если вы еще случайно не знакомы с тем, что это такое, для начала рекомендую ознакомиться с этой статьей: Расширение логики модулей или Logic Hooks

Как я понял из практики, многие достаточно быстро понимают, что это такое, и как им пользоваться. Но все время путаются в таких вопросах как: где надо создавать файл, как этот файл называть, где его и как подключать? Вот и новый наш стажер столкнулся с такими же трудностями. Чтобы помочь ему, а заодно и вам, я взял старенький модуль editLogicHooks от Marnus van Niekerk, модифицировал его для работы с SugarCRM 6, немного переписал код для корректной работы c php 5.3 (всякие eregi сейчас зло), добавил ссылку на описание хуков, ну и конечно русифицировал. При этом все авторство остается за Маркусом, мне чужого добра не надо )).

Хотя если честно модуль довольно простой и самому можно написать такой, а может и еще лучше, за пару часов.
Собственно сейчас я расскажу, что он из себя представляет, разберем конкретный пример, и если вас заинтересует, ссылка на закачку модуля размещена в конце статьи.

После инсталляции модуля через админку. В административном меню вы увидите новый пункт: Logic Hooks.Создание и редактирование Logic Hooks.

В этом модуле нам доступно создание новых хуков и редактирование ранее созданных хуков.
Для создания нового хука выбираем NEW, далее тип хука (для тех кто не знает или забыл, рядом ссылка в помощь с описанием). Так же выбираем модуль для которого будет работать данный хук и вводим имя (обязательно на английском языке, так как это имя будет участвовать при сохранении файла, и все русские символы будут заменены на _, и вы потом не разберетесь где какой хук).

Создание logic hooks

Отрывается новая страница, и вы можете редактировать код данного хука.
Код пишется между комментариями // Здесь начинается твой код для хука и // Здесь заканчивается твой код для хука.

Редактор Logic Hook

Для выбора ранее созданного хуку выбираем данный хук и нажимаем далее.
Разберем как всегда жизненный пример: необходимо в случае удаления контакта оповещать ответственное лицо за этот контакт, о произошедшем удалении и сообщать о том, кто такой нехороший его удалил.
Переходим в наш модуль редактирования хуков, выбираем тип before_delete, модуль контакты, и имя, например, BeforeDelete.
Наш код, который мы добавляем:

global $current_user;

 if ($event != 'before_delete') return;
 // Insert your custom logic between these comments
 $user = new User();
 $user->retrieve($bean->assigned_user_id);
 if (!empty($user->email1))
 {
 $this->sendSugarPHPMail(array($user->full_name => $user->email1),
 'Удален контакт',
 'Был удален контакт. Полное имя контакта: ' . $bean->full_name . '<br>' .
 'Контакт был удален: ' . $current_user->full_name );
 }
 // Insert your custom logic between these comments

Внимание, в данном коде для отправки сообщения я использую вызов метода sendSugarPHPMail. Это собственная функция, которую я добавил в данный класс. Вы можете воспользоваться ею, либо же написать свою. Полный код получившегося класса, со всеми функциями:

<?php
class BeforeDelete_class
{
	function BeforeDelete_method(&$bean, $event, $arguments=null)
	{
		global $current_user;

		if ($event != 'before_delete') return;
		// Insert your custom logic between these comments
        $user = new User();
        $user->retrieve($bean->assigned_user_id);

        if (!empty($user->email1))
        {
        	$this->sendSugarPHPMail(array($user->full_name => $user->email1),
        							'Удален контакт',
        							'Был удален контакт. Полное имя контакта: ' . $bean->full_name . '<br>' .
        							'Контакт был удален: ' . $current_user->full_name );
        }
        // Insert your custom logic between these comments
	}

	function sendSugarPHPMail($tos, $subject, $body)
	{

	  require_once('include/SugarPHPMailer.php');
	  require_once('modules/Administration/Administration.php');

	  $mail = new SugarPHPMailer();
	  $admin = new Administration();
	  $admin->retrieveSettings();

	  if ($admin->settings['mail_sendtype'] == "SMTP") {
		  $mail->Host = $admin->settings['mail_smtpserver'];
		  $mail->Port = $admin->settings['mail_smtpport'];

		  if ($admin->settings['mail_smtpauth_req']) {
			  $mail->SMTPAuth = TRUE;
			  $mail->Username = $admin->settings['mail_smtpuser'];
			  $mail->Password = $admin->settings['mail_smtppass'];
		  }

		  $mail->Mailer   = "smtp";
		  $mail->SMTPKeepAlive = true;

	  }else{
		  $mail->mailer = 'sendmail';
	  }

	  $mail->IsSMTP(); // send via SMTP
	  if ($admin->settings['mail_smtpssl'] == '2') $mail->SMTPSecure = "tls";
	  elseif ($admin->settings['mail_smtpssl'] == '1') $mail->SMTPSecure = "ssl";
	  $mail->CharSet='UTF-8';

	  $mail->From     = $admin->settings['notify_fromaddress'];
	  $mail->FromName = $admin->settings['notify_fromname'];
	  $mail->ContentType = "text/html"; //"text/plain"
	  $mail->IsHTML(true);

	  $mail->Subject = $subject;
	  $mail->Body = $body;

	  foreach ($tos as $name => $address){
		  $mail->AddAddress("{$address}", "{$name}");
	  }

	  if (!$mail->send()) {
		  $GLOBALS['log']->info("sendSugarPHPMail - Mailer error: " . $mail->ErrorInfo);
		  return false;
	  }else{
		  return true;
	  }
	}
}
?>

Один из минусов модуля заключается в том, что нельзя удалить созданный хук, через администрирование. Удалять необходимо вручную из папки custom/modules /папка_модуля/название_вашего_хука.php и плюс удалить его подключение из файла logic_hooks.php в этой же папке.
Если вас заинтересовал данный модуль для SugarCRM, скачать его можно по данной ссылке: editLogicHooks-1.0.6.zip (379) или же со страницы загрузок.

P.S. Если вдруг данный модуль будет вас интересовать, могу прикрутить визуальный php редактор (а то в обычной textarea редактировать код неудобно) + сделать удаление хуков из админки. Вашу заинтересованность я узнаю из количества скачек модуля и комментариев к данной теме :mrgreen:

P.P.S Добавил редактор с подсветкой php кода editarea. Модуль по ссылке обновлен. Теперь редактор выглядит следующим образом:

SugarCRM редактор

Высказать своё мнение о статье Вы можете в комментариях, если Вас интересуют какие либо вопросы или дополнения, то обсуждение по данной теме доступно на нашем форуме.

Есть 30 коммент. к “Расширение логики модулей или Logic Hooks. Часть 3”

  1. Булат:

    отлично что появляются новые статьи!

    удаление надо сделать конечно

    еще статей разных и вкусных!

    например интересует тема Team как оно работает в шугаре, роли и прочее... если есть примеры из реализации и разграничения доступов к объектам

    • Шуга Админ:

      Конечно, есть примеры реализации разграничений, как простых по отделам и группам, так и разграничений по отделам с условиями.

      Но это довольно сложная тема, может как в раз в следующих статьях рассмотреть основы. Для начала можно рассмотреть, например, работу CETeams. Помогал автору в адаптации под 6 версию и в нормальной русификации, правда смотрю он все равно забросил проект и даже не последняя версии на sugarforge лежит. Постараюсь у себя найти нормальную версию.

  2. Вадим:

    Да, было бы полезно сделать хотя бы подсветку синтаксиса этому модулю.

    Кстати, кто хочет в целях обучения посмотреть на профессиональную версию sugarcrm 5.5.0, то она, похоже случайно, доступна на google code www.google.ru/codesearch/...p;cd=2&ct=rc

    Там реализован WorkFlow который базируется на LogicHook'ах, есть разделение прав по командам и назначение прав доступа к полям по ролям. Ну и в мелочах тоже много красивого и полезного (отображение воронки продаж, вкладки на главной странице и т.д).

    • Шуга Админ:

      Спасибо за случайную :-P ссылку. У меня такая есть ))

      Делал модуль WorkFlow для CE, так и не доделал из-за нехватки времени. А в стандартном Workflow довольно скудный функционал действий, разве что оповещениями пользоваться, хотел сделать более универсальным, но видимо не судьба.

      Правда стандартный WorkFlow можно еще расширять плагинами, но нормальной документации по этому делу нет, да и пользователей Pro версий на порядок меньше, поэтому данные плагины и не пишутся.

      • Вадим:

        Да, WorkFlow в pro версии не очень пригоден для практического использования, например, там нет контроля срока исполнения заданий по дате/времени хранящемися в поле записи. Нет возможности исполнения произвольного PHP-кода. Это конечно про визуал речь — руками, то все можно доделать, но это и в CE можно сделать.

  3. Юлия:

    А можно ли и как с помощью хуков реализовать просмотр списка в модуле (listview) в виде дерева? с двумя — тремя уровнями хотя бы?

    • Булат:

      Нет это не хуки

      это надо менять у модуля его контролер отображения listview

      плюс надо еще как-то вложенность, кто кому там подчиняется?

  4. Юлия:

    Я уже весь интернет перерыла, но ничего полезного так и не нашла. Неужели придется писать свой модуль? :( :(

  5. Статья полезная, спасибо. Передо мной сейчас стоит похожая задача, собираюсь сам вспомнить былое и стать на время кодером, но вдруг уже что-то подобное существует? Собственно, интересует возможность уведомления того, кто поставил кому-то задачу, об изменении статуса задачи или внесении каких-либо комментариев. А также уведомление владельца задачи о том, что время исполнения подходит к концу, ну и постановщика задачи о том, что задача в срок не выполнена. Почти ТЗ )) Как бы то ни было — может следующий пример с хуком организуете на эту тему? Думаю, всем было бы интересно.

    • Юлия:

      Уведомления о назначении задач, изменении статуса задачи уже реализованы в версии 6.0.х.

      • У нас стоит 6.1 и там реализовано уведомление только о назначениях задач (тому, кому назначено), а также уведомления о приближении времени встречи или звонка. Все. Я же писал немного о другом наборе уведомлений.

  6. Шуга Админ:

    Андрей, а в чем собственно проблема? Данная вещь реализуется очень просто хуками:

    Пример функции хука (обязательно для того чтобы увидеть изменения в полях необходимо добавить в after save хук):

    function checkAndSendMail(&$focus, $event, $arguments) 
    {
                
      if ($focus->fetched_row['STATUS_TASK'] != $focus->STATUS_TASK ) //Поле STATUS_TASK - поле статуса задачи, оно изменилось
      {
         $created_by = new User();
         $created_by->retrieve($bean->created_by); //получаем юзера который создал задачу
         /*
         * В $created_by->email1 - email человека создавшего задачу,
         * отсылаем ему письмо, как пример можно взять функцию отправки почты из статьи
         */
      }
    }
    

    Остальные задачи реализуются точно так же однотипно.

    P.S. пишу из головы возможны небольшие недочеты :wink: Удачи.

    • )) ну, «очень просто» — это если знать, что в $focus->fetched_row['STATUS_TASK'] хранится предыдущее значение статуса и т.п. Я понимаю, что если детально изучить всю объектную модель шуги, решение подобных задач будет проще простого. Но я активно программировал достаточно давно и сейчас моей основной деятельностью является управление компанией, в связи с чем изучать модель мне бы не очень хотелось. Но, так или иначе, спасибо за идею — будем пробовать решать.

  7. VanVo:

    Существует ли способ выводить сообщения после выполнения хука?

    • Шуга Админ:

      Не понятна ваша задача: где, кому, как?

      Если просто интересует валидация формы перед сохранением, для этого есть java script, если необходима не стандартная валидация значений формы воспользуйтесь ajax и напишите еще серверный скрипт для этой валидации.

      Если вас интересует вывод сообщения на экран в каких то других ситуациях, то «прямого» метода нет.

      Если универсально, то обычно такая задача решается в два этапа, первый это сохраняем само сообщения в сессию, в нужном вам хуке, например, before_save.

      Второе на хуке after_ui_frame проверяем есть ли сообщения для этого юзера в ссесси, и если есть выводим их с помощью js.

      Еще раз повторюсь задача не сложная, но прямого метода типа $current_user->set_message, в SugarCRM не существует, поэтому решается немного обходными путями. Есть так же $_SESSION['administrator_error'], но данные сообщения предназначены только для администраторов.

    • spry:

      прямого пути нет, т.к. например при обработке soap запросов... непонятно куда это вообще выводить.

      хотя в SalesForce например, у любого поля есть метод setError ('текст ошибки') и оно отобразится под этим полем красным, или в случае soap вернет ошибку в с нужным комментарием, к сожалению Шуге еще далеко до этого :(

  8. VanVo:

    //Не понятна ваша задача: где, кому, как? //

    Под меню (шапкой), над основным гридом и формой поиска.

    Скорее всего подойдет вариант с after_ui_frame

    А где должен находится файл logic_hooks.php?

    В папке модуля? Это ведь хук уровня приложения.

    Нужно ли создавать класс для хука?

    И еще after_ui_frame сработает после формирования шапки или поле?

    Заранее спасибо

    • Шуга Админ:

      logic_hooks.php если это не хук модуля, должен находиться в корне папки custom/modules.

      Класс для хука необходимо создавать в любом случае.

      after_ui_frame срабатывает уже после формирования. Тут проще всего конечно применить alert. Но если вам необходимо обязательно добавить после шапки, придется на js динамически формировать элемент и «цеплять» его под шапку.

  9. kolya27:

    The uploaded file is not compatible with this version of Sugar: 6.2.0

    не выходит подгрузить модуль редакции хуков в версию 6.2.0. (profession)

  10. Шуга Админ:

    В файле manifest.php

    Замените

    	'acceptable_sugar_versions' => array(
    		'regex_matches' => array('6\.[0-1]\.*'),
    	),

    На

    	'acceptable_sugar_versions' => array(
    		'regex_matches' => array('6\.[0-2]\.*'),
    	),

    Но учтите что он не тестировался на версии 6.2.

    Хотя работать должен )

    • kolya27:

      все равно облако не пропускает. допустим у нас я права поставлю, но у заказчика — точно не пустят.

      Installation failed!

      The package you are attempting to install does not conform to the policies established within the Sugar Open Cloud or by your system administrator.

      Sugar Open Cloud customers must obtain a new package from the package provider that addresses the issues described below.

      If you are running Sugar locally, you can relax your Module Loader restrictions to allow the package to be installed.

      The Sugar Open Cloud package loading policies are detailed in the SugarCRM Knowledge Base.

      The available restrictions and exceptions are detailed in the SugarCRM Developer Zone.

      File Issues
      custom/include/edit_area/edit_area_compressor.php
      Invalid usage of a function filemtime()
      Invalid usage of a function filemtime()
      Invalid usage of a function filemtime()
      Invalid usage of a function filemtime()
      Invalid usage of a function fopen()
      Invalid usage of a function file_put_contents()
      Invalid usage of a function fopen()
      Invalid usage of a function touch()
      custom/include/edit_area/plugins/test/images/Thumbs.db
      Invalid file extension
      custom/modules/Administration/editLogicHooks.php
      Invalid usage of a function file_put_contents()
      

      • Шуга Админ:

        Правильно, политика безопасности)

        Так зачем вам для PRO версии данный модуль? у вас же есть WorkFlow.

        Или правьте ручками что надо ))

        • kolya27:

          вообщем задача такая: нужно добавить кнопки слева от кнопок топ меню в модуле контакты, правее edit, duplicate, delete и т.д. Вот делаем экспорт модуля, добавляем кнопки в файле (detailviewdefs.php) через прописывание в массив. Заливаем файл обратно через модуль лоадер в шугу, и ничего не отображает, хотя нормально делает инстоляцию. Понятно что нужно добавить еще прописывание кнопок в include/DetailView/header.tpl но к нему шуга не пускает ввиду политики безопасности. Что нужно делать, чтобы кнопки появились?

        • Шуга Админ:

          include/DetailView/header.tpl — не надо изменять, это шаблон для формирования кнопок.

          Все можно сделать через метадата файлы, для просмотра как вы и писали это файл detailviewdefs.php.

          Дело в том что если вы через студию редактировали данный модуль то метада файл находится в custom/modules/[MODULE_NAME]/metadata, вы если меняете файл в modules/[MODULE_NAME]/metadata, то он не повлияет на изменения.

          Так же не забывайте делать repair после того как меняете метада файл, так как в кеше лежит старый.

          Пожалуйста, не задавайте вопросы в комментариях :)

          На днях прикручу наконец то форум, потому что данная статья, не для обсуждения какого то модуля :wink:

Написать комментарий

Вы должны войти чтобы комментировать.