Вымышленный add message php. Вывод сообщений пользователю в веб-приложениях

В КП и БУС начиная с версии 11.5, в редакциях включающих в себя социальную сеть появился новый модуль " Веб-мессенджер ".
Перед тем как выпустить всем, модуль прошел боевое крещение на нашем " Социальном интранете ", собрав аж 8 обновлений


За шесть месяцев разработки, мы сделали многое

Мы полностью отказались от предыдущего интерфейса и создали новый, основываясь на опыте популярных мессенджеров.
Окно диалога стало открываться в рамках страницы, в нем появились лица, появилось цветовое кодирование сообщений, появилась возможность легко вести разговор с несколькими людьми одновременно.

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

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

И это все доступно на каждой странице вашего сайта!

К сожалению, реализовано далеко не все что планировалось

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

Второе , это реализация настоящей "мгновенной" связи. Сейчас в модуле используется обычный пулинг, раз в n-секунд опрос сервера, период опроса меняется в зависимости от активности общения.
Мы планируем написать отдельный сервис, который будет держать постоянные соединения и рассылать по мере надобности обновления данных (для мессенджера, для живой ленты и тд).

Третье , мы планируем немного изменить интерфейс, отказаться от раздельного контакт-листа и окна диалогов, объединить их в единое целое, что в перспективе позволит вынести мессенджер в мобильное приложение.

Документации пока нет и появится она не раньше осени, т.к. модуль активно развивается и мы хотим оставить возможность изменять API.
Тем не менее, я постараюсь публиковать примеры работы с той частью API над которой уже работы завершены и вы можете спокойно использовать их в своих модулях.

Работа с уведомлениями (актуально для IM начиная с версии 11.5.2)

Мы реализовали три типа уведомлений:
- персонализированное уведомление;
- уведомление от системы;
- уведомление требующее подтверждения (confirm);

П еред использованием API необходимо проверять установлен ли модуль в системе:

if (IsModuleInstalled("im") && CModule::IncludeModule("im")) { } ?>

Персонализированное уведомление


Если сообщениям задавать NOTIFY_TAG, то у пользователя они будут группироваться.

Уведомление от системы


$arMessageFields = array(// получатель "TO_USER_ID" => $USER->GetId(), // отправитель (может быть >0) "FROM_USER_ID" => 0, // тип уведомления "NOTIFY_TYPE" => IM_NOTIFY_SYSTEM, // модуль запросивший отправку уведомления "NOTIFY_MODULE" => "im", // символьный тэг для группировки (будет выведено только одно сообщение), если это не требуется - не задаем параметр "NOTIFY_TAG" => "IM_CONFIG_NOTICE", // текст уведомления на сайте (доступен html и бб-коды) "NOTIFY_MESSAGE" => "[b]Внимание: необходимо проверить и указать корректный путь до социальной сети в настройках модуля “Мгновенные сообщения и уведомления”", // текст уведомления для отправки на почту (или XMPP), если различий нет - не задаем параметр //"NOTIFY_MESSAGE_OUT" => ""); CIMNotify::Add($arMessageFields); ?>

Уведомление требующее подтверждения (confirm)


$arMessageFields = array(// получатель "TO_USER_ID" => $USER->GetId(), // отправитель "FROM_USER_ID" => 2, // тип уведомления "NOTIFY_TYPE" => IM_NOTIFY_CONFIRM, // модуль запросивший отправку уведомления "NOTIFY_MODULE" => "calendar", // символьный тэг для группировки (будет выведено только одно сообщение), если это не требуется - не задаем параметр "NOTIFY_TAG" => "CALENDAR|INVITE|123|".$USER->GetId(), // текст уведомления на сайте (доступен html и бб-коды) "NOTIFY_MESSAGE" => "Приглашаю вас принять участие во встрече “Мгновенные сообщения и уведомления” которая состоится 15.03.2012 в 14:00", // текст уведомления для отправки на почту (или XMPP), если различий нет - не задаем параметр "NOTIFY_MESSAGE_OUT" => "Пользователь Евгений Шеленков приглашает вас принять участие во встрече “Мгновенные сообщения и уведомления” #BR# которая состоится 15.03.2012 в 14:00.#BR# #BR# Принять: http://test.ru/calend.php?CONFIRM=Y&CID=123 #BR# Отказаться: http://test.ru/calend.php?CONFIRM=N&CID=123", // массив описывающий кнопки уведомления "NOTIFY_BUTTONS" => Array(// 1. название кнопки, 2. значение, 3. шаблон кнопки, 4. переход по адресу после нажатия (не обязательный параметр) Array("TITLE" => "Принять", "VALUE" => "Y", "TYPE" => "accept" /*, "URL" => "http://test.ru/?confirm=Y" */), Array("TITLE" => "Отказаться", "VALUE" => "N", "TYPE" => "cancel" /*, "URL" => "http://test.ru/?confirm=N" */),), // символьный код шаблона отправки письма, если не задавать отправляется шаблоном уведомлений "NOTIFY_EMAIL_TEMPLATE" => "CALENDAR_INVITATION",); CIMNotify::Add($arMessageFields); ?>

Для работы с этим типом уведомлений, недостаточно просто отправить сообщение, требуется еще и обслуживать его.

Обслуживание
Есть два варианта, самый простой, переход по ссылке (если задать 4 параметр в NOTIFY_BUTTONS).
После перехода по ссылке, в вашем коде нужно вызвать следующий код:
Внимание: внимательно следите за названием тэгов, при вызове удаления будут удалены все сообщения с таким тэгом.
При множественной рассылке необходимо это учитывать, что бы выполнение действия одним пользователем случайно не удалило уведомление всем (кроме мест где такая логика нужна).

Второй вариант, на событиях.
1. нужно зарегистрировать зависимость

Не забудьте внутри ваших функций ConfirmRequest и RejectRequest вызвать удаление уведомления CIMNotify:: DeleteByTag()

На этом пока все, жду ваших предложений в комментариях, удачных внедрений!
Если вы хотите попробовать API до выхода 11.5.2 в массив с параметрами необходимо дополнительно указывать "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM, так же у уведомлений confirm не будет работать вариант с ссылкой в кнопках. Но лучше подождать, обновление 11.5.2 должно выйти 23 мая.

3.3K

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

Очень часто создание и вывод сообщений разнесены по разным HTTP-запросам. Как правило, удобно бывает использовать редирект после обработки форм (чтобы избежать проблем с кнопками Back и Refresh), но в то же время естественный момент для создания сообщения - это именно момент обработки форм и совершения действий, ему сопутствующих. Почему? Представьте, что текст сообщения должен выглядеть примерно так: "Количество заказываемых единиц товара ‘Коврик для мыши’ успешно изменено с 7 до 12". После редиректа, возможно, на совершенно другую с точки зрения функциональности страницу, это будет лишняя головная - определить, что же было совершено до этого.

Чаще всего сообщения выводят именно в POST-запросе, который занимается обработкой формы - это нехорошо, надписи "эта страница устарела" портят жизнь (когда пользователю вздумается попробовать кнопку Back).

Кто-то использует редирект, махнув рукой на дружелюбные сообщения.

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

Итак, имеем проблему - сообщение должно "жить" в разных запросах. Нам нужен механизм передачи текста сообщения на страницу, которая должна его выводить. Вы уже, наверное, вспомнили про сессии.

Да, вобщем-то вы правы. Прочие способы, например через глобальную переменную, не позволяют сохранить данные в случае, когда используется редирект (замечание Максима Науменко). Плюс еще я обычно делаю так, чтобы каждый экран в приложении имел возможность, наряду с прочей информацией, выводить сообщения, которые были сформированы на предыдущих экранах. Это удобно, потому что не потребуется готовить отдельные экраны для вывода сообщений, а пользователю не придется лишний раз щелкать мышью. Но, правда, здесь надо подумать дизайнеру - выделить область, в которой бы появлялись сообщения.

Идея очень простая, и ее можно реализовать с помощью пары классов.

Первое, что приходит в голову - создать класс Message, который бы, собственно, и представлял собой сообщение на нашей нехитрой схеме классов. Сообщение должно уметь сохранять себя в сессии, а также выводить себя на экран.

class Message { /** * Содержание сообщения. */ var $content; /** * Конструктор для инициализации текста сообщения. * * @param content содержание сообщения */ function Message($content) { $this->content = $content; } /** * Запись сообщения в сессию. */ function send() { $_SESSION["session_messages"] = $this->content; } /** * Вывод сообщения на страницу. */ function toPage() { echo " - " . $this->content . "
"; } }

Для доступа к сессии используется переменная $_SESSION.

Замечу, что $_SESSION - это массив, мы используем всего лишь один элемент этого массива с индексом ‘session_message’.

В данном случае имеем дело с "массивом массивов" - то, что мы храним в элементе ‘session_message’, представляет собой массив, это и есть список передаваемых сообщений (их, конечно, может быть несколько).

Если вы не смогли нащупать нить, самое время освежить в памяти разделы мануала, посвященные сессиям и массивам.

У вас может возникнуть вопрос. А зачем здесь нужны классы? Вполне можно было бы обойтись двумя функциями. Но давайте заглянем дальше. Нам может понадобиться создавать сообщения с различными типами (info, error, warning), определять адресатов сообщений.

Заметьте, что в данный момент в сессию кладется не сам объект, а только текст сообщения. ООП позволяет нам в дальнейшем поменять поведение метода send(), не меняя клиенский код, который обращается к этому методу (например, в будущем в сессию можно записывать полностью объект Message, если в нем будет много полей).

Представим, что мы бы это делали с помощью функций. Наверное, у нас была бы функция message_send($txt), еще была бы функция message_to_page($txt). Теперь надо добавить возможность различного поведения для различных видов сообщений. Вызовы функций меняются: message_send($txt, $kind), message_to_page($txt, $kind). Придется прочесать весь код приложения в поисках таких функций, делая исправления.

Этого можно избежать, заранее предвидя ситуацию, представив сообщение в виде ассоциативного массива: $msg[‘txt’], $msg[‘kind’], тогда в вызовах функций будет только один параметр. Чувствуете, как это стремится превратиться в класс?

Так вот, ООП дает возможность позволить себе роскошь не продумывать все заранее.

Следующий класс - Inbox - как раз для этого и предназначен.

class Inbox { /** * Массив поступивших сообщений. */ var $messages = array(); /** * В конструкторе получаем все поступившие сообщения * и удаляем их из сессии. */ function Inbox() { if (is_array($_SESSION["session_messages"])) { $messages = $_SESSION["session_messages"]; $co = sizeof($messages); for ($i = 0; $i < $co; $i++) { $this->messages = new Message($messages[$i]); } } /* очищаем массив сообщений */ $_SESSION["session_messages"] = array(); } /** * Выводим на страницу содержимое Inbox. */ function toPage() { $co = sizeof($this->messages); if ($co > 0) { echo "Сообщение от системы:
"; } for ($i = 0; $i < $co; $i++) { $this->messages[$i]->ToPage(); } } }

Давайте испытаем нашу систему сообщений.

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

Всю работу с массивами и сессиями мы спрятали внутри классов, и конечный код выглядит просто и красиво.

Создайте каталог на веб-сервере, затем создайте в нем эти три файла и попробуйте скрипт в работе. Заметьте, проблем с кнопками Back и Refresh не возникает.

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

Здесь мы встречаем два затруднения:

* Хотелось бы, чтобы список сообщений появлялся в определенной части страницы, и вы уже подобрали хорошее местечко для этого.
Проблема в том, что надо запустить команду $inbox->toPage() именно в тот момент, который бы соответствовал положению списка сообщений на странице. Если мы захотим поменять положение этого списка, придется лезть в код, но нехорошо постоянно для этого изменять каркас портала. Наилучшим решением было бы сделать вывод сообщений в виде отдельного модуля, о котором известно лишь только, что его надо подключить к каркасу.
То есть освободиться от строгой последовательности запуска модулей. Действительно, раз результат работы вывода Inbox не зависит от работы системы (на данном шаге - все данные у нас уже есть в сессии), то зачем лишние сложности?
* Чтобы поддерживать внешний вид (дизайн) списка сообщений надо заботиться об HTML-коде, который у нас зашит в методах toPage() классов Message и Inbox. Как правило, придется изменять PHP-код для того, чтобы изменить дизайн.

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

Возможно, у нас еще будет несколько похожих (на Inbox) вещей, и надо создать систему буферов. Для того, чтобы не перепутать где чей вывод, мы, наверное придем к именованию буферов. У нас будет где-то храниться последовательность, в соответствии с которой должен происходить вывод буферов - желательно во внешнем файле, чтобы легче было вносить изменения.

Уже эта попытка решения дает нам идею использовать XML как средство хранения промежуточных данных. А использование стилей XSLT поможет справиться и со втором проблемой.

Я не буду останавливаться на том, что такое XML, и что такое XSLT. Если вы не знакомы с этими вещами, zvon.org станет хорошей отправной точкой для изучения.

Идея в том, чтобы в методах toPage() формировать не HTML-код, а XML структуру. Документ страницы будет создаваться в виде стринга с XML-кодом (он будет служить в качестве "буфера"), а на последней стадии работы скрипта мы будем использовать XSL-трансформацию.

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

minute 57 second: 45

Что это такое - догадаться довольно просто - два сообщения и форма. Заметьте, PHP-скрипт должен подготовить только такой стринг - он очень простой. Причем порядок следования основных тегов неважен - можно поставить вначале, например, как будет удобно программисту. Как это реализовать. Можно, почти ничего не меняя, использовать output buffering, вместо HTML-кода выводить XML, а в конце просто захватить вывод в стринг. Но тогда мы потеряем в гибкости - например, хочется иногда выводить отладочную информацию прямо на страницу (с помощью echo). В то же время, разработчики PHP работают над DOM-модулем, который предлагает более продвинутый способ создания и передачи древовидных документов. Если мы захотим внедрить DOM, то придется перекраивать все приложение, изменяя вывод стрингов на создание DOM-элементов. Поэтому я предпочитаю хранить XML-представление объектов внутри самих объектов, последовательно собирая общий XML-документ. Это не так сложно, нужна всего лишь небольшая модификация. Вы увидите, что такой прием не привязан жестко к конкретному способу хранения XML-данных, и это позволит совершить переход к использованию DOM "малой кровью". Прежде всего заметим, что у каждого нашего объекта есть метод toPage(). Эта похожесть должна нас заставить задуматься о том, чтобы ввести новый общий родительский класс. Пусть каждый класс, который способен создавать кусочки XML-документа для страницы, будет наследоваться от класса, который будет заботиться об XML-представлении объекта. Назовем его Outputable.

class Outputable { /** * XML контейнер (стринг). */ var $output = ""; /** * Отдать содержимое контейнера и очистить контейнер. * * @return стринг с XML-данными */ function getOutput() { $out = $this->output; $this->output = ""; return $out; } /** * Добавить порцию к содержимому контейнера. * * @param string добавляемый стринг */ function appendOutput($string) { $this->output .= $string . "n"; } /** * "Абстрактный" метод. */ function toPage() { } }

Метод toPage() сделан пустым - в данном случае он нужен как индикатор того, как должны внешние "матрешки"-классы общаться с внутренним классом. Впрочем, здесь можно было бы предложить реализацию по умолчанию, если бы мы заметили, что есть много объектов, которые одинаково выводят себя на страницу.

Классы Message и Inbox несколько изменятся - теперь оба они должны наследоваться от Outputable, а также изменятся и методы toPage()
Message.php

class Message extends Outputable { /** * Содержание сообщения. */ var $content; /** * Конструктор для инициализации текста сообщения. * * @param content содержание сообщения */ function Message($content) { $this->content = $content; } /** * Запись сообщения в сессию. */ function send() { $_SESSION["session_messages"] = $this->content; } /** * Вывод сообщения на страницу. */ function toPage() { $this->appendOutput("".$this->content.""); } }

class Inbox extends Outputable { /** * Массив поступивших сообщений. */ var $messages = array(); /** * В конструкторе получаем все поступившие сообщения * и удаляем их из сессии. */ function Inbox() { if (is_array($_SESSION["session_messages"])) { $messages = $_SESSION["session_messages"]; $co = sizeof($messages); for ($i = 0; $i < $co; $i++) { $this->messages = new Message($messages[$i]); } } /* очищаем массив сообщений */ $_SESSION["session_messages"] = array(); } /** * Выводим на страницу содержимое Inbox. */ function toPage() { $co = sizeof($this->messages); $this->appendOutput(""); for ($i = 0; $i < $co; $i++) { $this->messages[$i]->toPage(); $this->appendOutput($this->messages[$i]->getOutput()); } $this->appendOutput(""); } }

Изменился способ вывода - теперь вместо непосредственного вывода на страницу внешнее представление до поры до времени хранится в Outputable, который "сидит" в каждом из объектов. Метод appendOutput() служит некоторой заменой конструкции echo(). Чтобы забрать вывод объекта, используется метод getOutput().

Теперь посмотрим, что собой представляет клиентская часть кода, которая будет решать ту же задачу, что и раньше.
index.php

Главное новшество - в объекте $global_content, название которого говорит само за себя. В данном случае он принадлежит классу Outputable, в реальных задачах вы, наверное, создадите отдельный класс для контента страницы.

Если внимательно присмотреться, то содержательная часть скрипта практически не изменилась - тот же inbox, тот же toPage(). Добавлена инструкция, которая содержимое списка сообщений выводит в контент страницы. Для разнообразия теперь генерируется два сообщения.

Для того, чтобы посмотреть на результат, осталось только подготовить XSL-шаблон.
style.xsl

XSLT Example

message

Чего же мы добились?

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

Любой модуль, который генерирует XML-данные в качестве результата своей работы, может быть использован в проекте. Кстати, это одно из преимуществ перед template-движками, в которых создание данных заключается в последовательности вызова методов (assign и т.п.) конкретного движка, на которых нет общего стандарта.

Еще одно преимущество - легкость отладки. Если вы запустите скрипт, то заметите, что на каждой странице присутствует debug-вывод - XML-прообраз, который здорово упрощает отладку приложений.

Над чем надо еще подумать - как создавать объекты-сообщения. Не всегда удобно использовать new непосредственно в клиентском коде. Но, пожалуй, это тема для отдельной статьи.

Напоследок, галопом о перспективах:

* всплывающие окна для списка важных сообщений
* "страницы-отправители" и "страницы-адресаты" в сообщениях
* ведение лога сообщений в базе данных
* кнопка "показать историю моих действий"
* статистический анализ действий пользователей в пределах сессий
* "интеллектуальные помощники" в веб-приложениях

Лучше черная полоса, чем белая горячка...

PHP AJAX CRUD: создание, удаление, редактирование записей в БД MySQL

В этой статье мы узнаем о том, как добавлять, редактировать и удалять записи в базе данных MySQL, используя PHP. Мы использовали обработчик JQuery, который посылает AJAX запрос к серверному скрипту. Обработчик обновляет список записей.

AJAX форма для отправки запросов на создание, удаление, редактирование

При добавлении записи форма отправляет данные PHP скрипту через AJAX запрос. В случае успешного добавления список записей перезагружается.

JQuery AJAX функции для запроса к базе данных CRUD

В функции JQuery AJAX у нас есть переключатель случаи добавить редактировать и удалять. Эти случаи генерирует различные строки запроса и ответа-данные в зависимости от действий базы данных.

function showEditBox(id) { $("#frmAdd").hide(); var currentMessage = $("#message_" + id + " .message-content").html(); var editMarkUp = ""+currentMessage+"SaveCancel"; $("#message_" + id + " .message-content").html(editMarkUp); } function cancelEdit(message,id) { $("#message_" + id + " .message-content").html(message); $("#frmAdd").show(); } function callCrudAction(action,id) { $("#loaderIcon").show(); var queryString; switch(action) { case "add": queryString = "action="+action+"&txtmessage="+ $("#txtmessage").val(); break; case "edit": queryString = "action="+action+"&message_id="+ id + "&txtmessage="+ $("#txtmessage_"+id).val(); break; case "delete": queryString = "action="+action+"&message_id="+ id; break; } jQuery.ajax({ url: "crud_action.php", data:queryString, type: "POST", success:function(data){ switch(action) { case "add": $("#comment-list-box").append(data); break; case "edit": $("#message_" + id + " .message-content").html(data); $("#frmAdd").show(); break; case "delete": $("#message_"+id).fadeOut(); break; } $("#txtmessage").val(""); $("#loaderIcon").hide(); }, error:function (){} }); }

PHP скрипт для операций CRUD

Следующий код выполняет запросы к базе данных. Этот скрипт PHP после выполнения CRUD действия обновляет записи в результате ответа AJAX.

require_once("dbcontroller.php"); $db_handle = new DBController(); $action = $_POST["action"]; if(!empty($action)) { switch($action) { case "add": $result = mysql_query("INSERT INTO comment(message) VALUES("".$_POST["txtmessage"]."")"); if($result){$insert_id = mysql_insert_id(); echo " Edit Delete " . $_POST["txtmessage"] . " "; } break; case "edit": $result = mysql_query("UPDATE comment set message = "".$_POST["txtmessage"]."" WHERE id=".$_POST["message_id"]); if($result) echo $_POST["txtmessage"]; break; case "delete": if(!empty($_POST["message_id"])) { mysql_query("DELETE FROM comment WHERE id=".$_POST["message_id"]); } break; } }

Overview

The built in notification system, first ever in Joomla, allows your app to keep the user (or group of users) informed about various different events. Think of notifications as important alerts that user would be interested to read and keep track of it.
Notifications can be generated everywhere. In your component or plugins and later displayed inside JomSocial notification system.
This tutorial will show you how, but since we do not have idea of any third-party component we could use:) the examples will be done on a community plugin which will be triggered at onAfterProfileUpdate event
If you don"t know how to create plugin which will be triggered on this event, we suggest you to check this guide

Implementing it in your component anyway

As stated in overview of this tutorial, we will generate notifications using community plugin.
You will most likely want to create notifications inside your component, or your plugin. The following tutorial will work in any of this cases. You only need to determine at what point in your code the notification will be created and just load the JomSocial Core Libraries file.

require_once JPATH_ROOT . "/components/com_community/libraries/core.php" ;

Following the tutorial explained bellow will work just fine for your extension too

Preparing the Development Environment

1. We will assume that you"re already created community type example plugin which will be triggered when user changes its profile
If not, you can download empty example plugin from , install it in Joomla and enable the plugin. It is named Community - Notifications Example
2. Navigate to your database and empty these two tables, so they dont have any records at all

A) prefix_community_notification
b) prefix_community_mailq

3. Have at least two (2) users at your test sites and know their ID"s

In earlier versions of Joomla, user ID"s have always started from specified number (62, 42) In Joomla 3, this number will be random, hence, the picture of our testing environment because it will definitely be different at your end.

The First Notification

Open the plugin php file which will be located in ROOT/plugins/community/example
Within the function onAfterProfileUpdate() replace the

CNotificationLibrary:: add ( $cmd , $actor , $target , $subject , $body , $template , $params ) ;

As shown on the example, notification add api have 7 parameters

  • $cmd - is the notification type. You can see all notifications types in this file. ROOT/components/com_community/libraries/notificationtypes.php starting from, or around line 53. We recommend using system_messaging notification type.
  • $actor - is the person who carry out the action
  • $target - is the person, or group of people that will receive notification
  • $subject - is the notification subject, in both, notification popup window and the email title
  • $body - is the body of email notification message
  • $template - if you need specific template to use, you can define it here. Otherwise, this parameter can be empty
  • $params - custom defined parameters
  • Knowing all this, lets define the variables we will use
    Change your plugin code to:

    $user = CFactory:: getUser () ; $cmd = "system_messaging" ; // first param, type of activity $actor = $user -> id ; //second param - get the id of $actor $target = "965" ; // third param. Who receive notification? In our dev environment, its admin user with id 965. At your environment, you will most likely want to get the ID from your object or from array of users. $subject = "Notification Subject" ; // Subject of both, email and popup notifications $body = ; //Body message in emails. $template = "" ; // If you need to use specific jomsocial template file, you can define it here. $params = new CParameter("" ) ; // We want to create an additional params object, and assign data to it, without having to formally define a class CNotificationLibrary:: add ( $cmd , $actor , $target , $subject , $body , $template , $params ) ;

    Now login with any user and change the profile information. Lets go to database to see what happened.
    Navigate to prefix_community_notifications table and observe the new record

    Navigate to prefix_community_mailq table, and see the new record

    Congratulations! - You have successfully created your first very own notification which has been dispatched via email and internal JomSocial notification system


    Potential Code Bloat

    Above example is fine, and it works, but generally it is not recommended to use it like that. Instead, it could be written like this

    $actor = CFactory:: getUser () ; $params = new CParameter("" ) ; CNotificationLibrary:: add ( "system_messaging" , $actor -> "This is the notification body message" , "" , $params ) ;

    This is much cleaner and easier to follow while basically doing absolutely same thing as a code shown above.

    Custom Notification Parameters

    A notification API can be extended with any param you would like to add.
    These params can be passed to either email template, notification, and of course, language file.

    $actor = CFactory:: getUser () ; $link = "http://www.google.com" ; $params = new CParameter("" ) ; $params -> set ("actor" , $actor -> getDisplayName () ) ; // can be used as {actor} tag $params -> set ("actor_url" , "index.php?option=com_community&view=profile&userid=" . $actor -> id ) ; // Link for the {actor} tag $params -> set ("url" , $link ) ; //url of the whole activity. Used when hovering over avatar in notification window. Can be used as {url} tag in outgoing emails too. Make sure that you have defined $link variable:) CNotificationLibrary:: add ( "system_messaging" , $actor -> id , "965" , "Notification Subject" , "This is the notification body message" , "" , $params ) ;

    • $params = new CParameter(); - We want to create a new params object, and assign data to it, without having to formally define a class.
    • $params->set("actor", $actor->getDisplayName()); - Your notification should always have an actor. This param can be passed to template as {actor} tag. In notification window, it defines the user that carries an action.
    • $params->set("actor_url", "index.php?option=com_community&view=profile&userid=" . $actor->id); - Actor URL is usually the url of an actor. In notification popup, it adds the link to the {actor) element
    • $params->set("url", $link); - This is most important paramater you must always set properly. In notification window, this param is used over the avatar image. In email notification, it echoes the location where activity occurred.

    For this example, we will set variable $link to lands on www.google.com so you can see how it works

    Adding Language String and Use Params

    Having the params we just set are available to be used in our language files as well.
    Lets define the language keys by altering the "CNotificationLibrary::add() API

    CNotificationLibrary:: add ( "system_messaging" , $actor -> id , "965" , JText:: sprintf ("PLG_COMMUNITY_EXAMPLE_SUBJECT" ) , JText:: sprintf ("PLG_COMMUNITY_EXAMPLE_BODY" ) , "" , $params ) ;

    The language file should look like this

    PLG_COMMUNITY_EXAMPLE_SUBJECT = "{actor} updated profile" PLG_COMMUNITY_EXAMPLE_BODY = "Hi Admin \n This is the mail to inform you that {actor} updated profile \n\n If you want to go to Google, click here \n a href=" _QQ_"{url}" _QQ_">{url}"

    In this example, we have used the tag {actor) and {url} to pass the data to both, notification, and email templates. Lets see how does that look.
    In notification window when hovering over avatar, notice the {url} param kicked in and adds the link to google over avatar. It is intentional , because we made it that way:)


    ]

    In the same window, when hovering over actor link. This is the part where {actor} echoed the user that carries an action, while {actor_url}" taken care that object is linked properly


    Lets see what happens in the email queue


    And finally, the actual email that is sent to end user


    Success
    Till now, we created three (3) parameters that are successfully used in notification window, and emails.

  • (actor) - Returns the username of the user which carries the action
  • {actor_url} - Gives the attribute to the {actor}
  • {url} - Is not mandatory, but you should always have it in your notification. It is the main url where action that we are notified about happened.
  • Similarly, you can define "

    • {target} - if you need it
    • {target_url} if you need it in your notification.
    • (title) - Commonly used to refer to an object that generated notification. Example: "User X posted new photo in Album Y ." Album Y is title here
    • {title_url} - As with previous ones, the url of an object that generated notification.
    • {message} - This param can be used to set (and echo) the message in the body of JomSocial email.

    К этому моменту в данном курсе заложена основа нашего плагина, определён пользовательский hook и привязано постоянное сообщение, чтобы показать, как этот hook работает.

    То, что мы не сделали, это не реализовали типы сообщений и их отображение согласно введённым пользователем данным.

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

    Готовы начать?

    Я с нетерпением жду продолжения урока, но есть несколько вещей, которые нам необходимо рассмотреть перед тем, как с головой окунуться в исходный код. Убедитесь, что в вашей системе установлено следующее программное обеспечение:

    • PHP 5.6.25 и MySQL 5.6.28
    • Apache или Nginx
    • WordPress 4.6.1
    • Предпочитаемый вами IDE или редактор

    И если вы ищете решение "все-в-одном", не забудьте попробовать MAMP .

    Мы продвинулись до

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

  • В первом уроке , мы сосредоточились на минимальной основе для создания нашего плагина и на том, что необходимо иметь на старте.
  • В второй части , мы продвинулись с плагином дальше, немного дополнив базовую страницу администрации в WordPress. Ещё мы назначили пользовательский hook, который используем и провели его на стороне сервера. Также мы задали основные параметры для нашего Settings Messenger.
  • И вот что мы рассмотрим на заключительном этапе обучения:

  • Мы свяжем все это вместе, посмотрим в действии и сделаем плагин публично доступным для скачивания.
  • В настоящее время у нас есть иные задачи, на них мы и сосредоточимся.

    Вернёмся к работе

    Поскольку мы обратились к работе (и, как было сказано в предыдущих уроках), мы стремимся к дальнейшей реализации задач в этой части:

    В этом уроке мы продолжим развитие нашего Settings Messenger путём добавления поддержки для успешных и ошибочных сообщений, а также затронем вопросы безопасности.

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

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

    Кроме того, мы собираемся внести ещё одно изменение, которое добавит поддержку для отклонения уведомлений по усмотрению пользователя.

    Это весь план необходимой работы на этот урок. Давайте начнем.

    Расширение Settings Messenger

    Помните, что вся суть Settings Messenger состоит в определении для нас своего способа работы с пользовательскими сообщениями, пользовательскими hooks и родной WordPress API для отображения сообщений в контексте WordPress панели администрации.

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

    Успешные сообщения

    Поскольку мы начали с успешных сообщений в предыдущем уроке, давайте с ними и продолжим. Теперь у нас есть жестко-кодированный метод, который отображает единственный приём:

    • Сергей Савенков

      какой то “куцый” обзор… как будто спешили куда то