Разработка плагинов

Система поддерживает следующие типы плагинов:

Класс abstract PluginBase

PluginBase — класс, от которого должны наследоваться все index.php в плагинах. Все классы унаследованные от него, имеют возможность вызывать action%Method% через браузер напрямую, кроме зарезервированных. Например хочу сделать ссылку /plugins/%PluginName%/test — в коде надо обязательно прописать — actionTest

Свойства:

protected $actions = [] — Reference Action объектов плагина
protected $settings = []— Здесь все настройки плагина. В том числе с BD
protected $plugin_id = 0 — ID плагина после установки

После инициализации:

$this->DB — экземпляр класса Database

Методы:

String abstract public function getName()
Метод, который должен реализовать каждый плагин и вернуть (string) %plugin_name%

Void abstract public function actionIndex()
Метод, который должен реализовать каждый плагин. Используется для вывода Описания. Вызывается, когда кликаешь в plugin manager на описание

Array public function getManifest()
Возвращает ассоциативный массив манифеста или []

Bool public function checkActiveForm(string $formName)
Возвращает True/False если форма есть в ActiveForms

Void protected function eventInstall()
Вызывается после установки плагина и после сохранения параметров, если такие имеются

Void protected function eventChangeSettings()
Вызывается каждый раз, когда сохраняются новые параметра в plugin manager панели

Void protected function eventUninstall()
Вызывается перед удалением плагина

Void public function getData($configManifest = [])
Устанавливает $this->settings (Настройки плагина, в том числе по умолчанию) с базы данных.
Устанавливает $this->plugin_id
Если $configManifest не задан, то автоматом получает через $this->getManifest()

String public function getSettingsValue(string $key)
Получить опцию по ключу $this->settings[$key]. Если нет, то возвращает String.empty

(Exception)Void public function setSettingsValue(string $key, string $value)
Устанавливает в Database значение опции по ключу. Все ключи должны быть прописаны в mantifest.settings.

(Exception)Void public function deleteSettingsKey($key)
Удаляет в Database значение опции по ключу.

(Exception)Void protected final function installPlugin()
Устанавливает плагин и синхронизирует настройки manifest.settings c Database

(Exception)Void public final function deletePlugin()
Удаляет все настройка плагина и деинсталирует его

Bool public function isActive()
Проверяет — установлен или нет плагин в системе

String public function getRealName($nameAttr = «name»)
Получить имя с langpack. Если нет — берет $this->getName()

String public function getFullPath()
Полный физический путь к плагину

String public function getPath()
Относительный путь к плагину

Array protected function getLangPack($defLang = null)
Получает массив LangPack
Если $defLang не задан — то берется язык у системы

Bool public function existAction(string $actionName)
Проверяет — есть ли action у данного объекта

Array public function getListByType(PluginManager::PLUGIN_TYPE_* $type, bool $checkActive = false)
Получает Action объекта установленного плагина
$type — это тип Action:

  • Kernel\Plugins\PluginManager::PLUGIN_TYPE_PHONE — Телефония
  • Kernel\Plugins\PluginManager::PLUGIN_TYPE_SMS — СМС
  • Kernel\Plugins\PluginManager::PLUGIN_TYPE_CONTENT — Другие

Если checkActive = true — то будет проверятся плагин на isActive

PluginAction | NULL public function getAction(string $actionName)
Получить объект PluginAction
$actionName = PluginManager::PLUGIN_TYPE_*

Void public final function beforeDisplay()
Вызывается перед display или выводом информации. Устанавливает $this->page. Устанавливает отображение HTML.

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

Void public final function display(string $templateName)
Выводит шаблон $templateName который находится в папке html плагина

String public final function output($templateName, $isArray = false)
Тоже самое что и display, только не выводит, а возвращает результат рендера шаблона.

String public final function getApiKey()
Получить API_KEY

Die Xml/Json public function resultSuccess($array = [], $resultOnlyData = false)
Вернуть Json/Xml ответ
Если $resultOnlyData выставить в true, то будет результат массив $array, иначе полный заголовок result в системе со status и прочим.
Сбивает $this->page на XML/JSON

Die Xml/Json public function resultError($error = [], $resultOnlyData = false)
Вернуть Json/Xml Ошибку
resultOnlyData как и в resultSuccess

String protected function getCallbackLink(PluginManager::PLUGIN_TYPE_* $type, string $action = «», $joinParams = [])
Получить Ссылку на %Type%Action плагина с учетом API_KEY
Если $action установлен, то ссылку даст на actionMethod $Type%Action плагина
Параметр — $joinParams — это массив ключ=>значение. Добавляет get параметры к url, при этом не затирая apikey. Параметры автоматически экранируются urlencode.

echo getCallbackLink(Kernel\Plugins\PluginManager::PLUGIN_TYPE_PHONE, string $action = "") 
//Выведет http://xrm-dev-sp1/plugins/%pluginName%/%type%/%action%/?APIKEY=%API_KEY%
echo getCallbackLink(Kernel\Plugins\PluginManager::PLUGIN_TYPE_PHONE, string $action = "dopaction", ["a"=>"b"]) 
//Выведет http://xrm-dev-sp1/plugins/%pluginName%/phone/dopaction/?a=b&APIKEY=%API_KEY%

Void protected function printCallbackLink(PluginManager::PLUGIN_TYPE_* $type, string $action=»», string $link = «», string $BLOCK = «»)
Mapping Backlink в шаблон.
Если не установлен $link, то выполняется getBackLink
$BLOCK — в какой блок выполнить mapping. По умолчанию = «», в итоге = CALLBACK_LINK. Если задать BLOCK = «SUB_BLOCK», то выставиться «SUB_BLOCK.CALLBACK_LINK»

Void protected function printUsers($BLOCK = «»)
Используется для рендера списка пользователей. Например в телефонии, для привязки сотрудников к коротким номерам службы.

Пример использования в Телефония

Класс abstract PluginAction

PluginAction- класс, от которого наследуются все Action. Все классы унаследованные от него, имеют возможность вызывать action%Method% через браузер напрямую, кроме зарезервированных. Например хочу сделать ссылку /plugins/%PluginName%/%type%/test — в коде надо обязательно прописать — actionTest

Свойства:

После инициализации:

$this->DB — экземпляр класса Database
$this->User — экземпляр класса User
$this->Http — экземпляр класса Http

Методы:

String public function getDescription()
Получить описание. Проверяет есть ли оно в langPack, если нет то с манифеста берет

String public function getPluginName()
Получить имя плагина

Array public function getLangPack()
Получить lang pack

PluginManager::PLUGIN_TYPE_* public function getType()
Получить тип

String public function getVendor()
Получить vendor

String public function getVersion()
Получить версию

String public function getRating()
Получить рейтинг

PluginBase public function getPlugin()
Получить свой экземпляр класса PluginBase

String protected final function getFormatPhone(string $phone, string $append=»8″)
Конвертирует телефон например: +7 248 222-22-22 в 82482222222. Восьмерка вставляется с аргумента $append

String protected final function Transfer(string $url, array $postData = [], bool $ssl = null, bool $isGET = false)
Отправить запрос по CURL.
$url — ссылка куда
$postData — массив, который используется как для GET запроса так и для POST. Ассоциативный массив.
$ssl — Определяет включать ssl или нет. если установить null — то система автоматически определяет
$isGET — true/false GET или POST параметры в запросе.

String public function getFullPath()
Полный физический путь к плагину

String public function getPath()
Относительный путь к плагину

Void public final function beforeDisplay()
Вызывается перед display или выводом информации. Устанавливает $this->page. Устанавливает отображение HTML.

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

Void public final function display(string $templateName)
Выводит шаблон $templateName который находится в папке html плагина

String public final function output($templateName, $isArray = false)
Тоже самое что и display, только не выводит, а возвращает результат рендера шаблона.

Die Xml/Json public function resultSuccess($array = [], $resultOnlyData = false)
Вызывает getPlugin()->resultSuccess(…);

Die Xml/Json public function resultError($error = [], $resultOnlyData = false)
Вызывает getPlugin()->resultError(…);

Класс abstract class PluginPhoneBase extends PluginAction

PluginPhoneBase — расширение класса PluginAction.От PluginPhoneBase должны наследоваться все Phone Action

Константы:

для входящих звонков
const CALL_IN = 1;
для исходящих звонков
const CALL_OUT = 2;

Свойства:

Все свойства и методы PluginAction

Методы:

String Json abstract public function actionCall()
Метод, который должен реализовать каждый телефонный плагин. Этот метод вызывается системой для вызова.
На вход идут две переменные: $_POST[‘name’], $_POST[‘to’].
To — обязательно нужно обработать $to = $this->getFormatPhone($to)
From — от кого — $this->getShortNumber($this->User->getEmployeeId());
Функция должна вернуть Json массива:

[
'name'=>"NAME", 
'to'=>"PHONE TO", 
'from'=>"FROM", 
'status'=>'Connected', //or Disconnected
'pluginName' => $this->getPlugin()->getRealName()
]

String Json abstract public function actionInbound()
Метод, который должен реализовать каждый телефонный плагин. Этот метод вызывается внешней системой для callback.
На вход идут две переменные определенные системой.

Подробнее в примере плагина Телефония

String | Null public final function getShortNumber(integer $user_id)
Получить короткий номер пользователя в settings users текущего плагина

Array protected function findByPhone($phone)
Найти employees, companies, contacts по номеру телефона

Возвращает массив:

[
"id"=>0, 
"name"=>"", 
"url"=>"",
"responsible"=>"", 
"responsibleID"=>""
]

Void public function sendPopupPhone(integer | array $user_id, string $name, string $to, string $from, string $status, interger $command_id = 0, string $url = «», interger $responsible = 0, string $pluginName = »)
Отправка на websocket Popup телефонии
$user_id — id кому отсылать websocket
$name — Имя
$to — Телефон кому
$from — От кого
$status — «Connected» или «Disconnected»
$command_id — уникальный id — это некий параметр который уходит во внешнюю систему и приходит
$url — ссылка на найденного пользователя
$responsible — id Ответственного
$pluginName — Имя плагина — если не задать — выставиться автоматически

Entry public function createRelationship(integer $companyID, string $phone, String $type, bool $createCompany = false, integer $responsible = 0, String $call_unique_id = «»)
Создание контрагентов и контактов
$companyID — id Контрагента
$phone — Телефон
$type — Имя плагина в основном — $this->getPlugin()->getRealName()
$createCompany — Если true, то создает контрагента
$responsible — ID ответственного
$call_unique_id — уникальный номер звонка

Void public function createHistory(String $fromNumber, String $toNumber, Int $callId, int $direction = PluginPhoneBase::CALL_IN, Bool $createdContact = false)
Создание элемента Sound в historypanel
$fromNumber — Телефон от кого
$toNumber — Телефон кому
$callId — Уникальный идентификатор звонка
$direction — Входящий или исходящий звонок. Для этого нужно использовать константы PluginPhoneBase::CALL_IN и PluginPhoneBase::CALL_OUT. В PhoneAction можно писать как self::CALL_IN.
$createdContact — Создавать или нет у контакта в historypanel

$this->createHistory( "+7 (922) 222-11-13", "102", "2342342342", self::CALL_IN);

Класс abstract class PluginSmsBase extends PluginAction

PluginSmsBase — расширение класса PluginAction.От PluginSmsBase должны наследоваться все Sms Action

Свойства:

Все свойства и методы PluginAction

Методы:

String Json abstract public function actionSend()
Метод, который должен реализовать каждый sms плагин. Этот метод вызывается нашей системой для отправки SMS.
На вход идут две переменные.
text — сам текст
to — номер куда
Для результата необходимо использовать resultSuccess, resultError

Void abstract public function send(string $text, string $phoneTo);
Метод, который должен реализовать каждый sms плагин. Это метод самой отправки. Именно он должен вызываться в actionSend.
На вход идут две переменные.
text- сам текст
phoneTo- номер куда

Класс abstract class PluginContentBase extends PluginAction

PluginContentBase — расширение класса PluginAction.От PluginContentBase должны наследоваться все Content Action

Свойства:

Все свойства и методы PluginAction

Методы:

String abstract public function content()
Метод, который должен реализовать каждый sms плагин. Возвращает html|text который встраивается в контент

API Plugin

Есть система API для Javascript запросов и возвращает XML/JSON в зависимости от ACCEPT заголовка.
API работает по следующим ссылкам: /plugins/%PluginName%/api/%MethodApi%

Методы

  • getSettings — получить все настройки
  • setSettings — установить настройки
  • deletePlugin — удалить плагин
  • installPlugin — установить плагин

getSettings — Возвращает все сохраненные настройки плагина.

/plugins/%PluginName%/api/getSettings

setSettings — установить настройки плагина. Имена ключей должны соответствовать ключам настроек манифеста и добавляться для POST запроса префикс object_ — например ключ плагина — key, то в POST должен быть object_key

/plugins/%PluginName%/api/setSettings

deletePlugin — удаление установленного плагина. Никаких параметров не надо. Удаляет со всеми настройками.

/plugins/%PluginName%/api/deletePlugin

installPlugin — установка нового плагина. Имена ключей должны соответствовать ключам настроек манифеста и добавляться для POST запроса префикс object_ — например ключ плагина — key, то в POST должен быть object_key

/plugins/%PluginName%/api/installPlugin

Структура папок

Название папки/плагина — название компании или название выражающая суть плагина. Наименование должно быть уникально.

  • %plugin_name%
    • actions — размещаются все %Type%Action
    • css — для стилей
    • html — для html шаблонов
    • img — для всех изображений
      • logo_120.png — изображение в списке плагинов (120 x auto)
      • logo_200.png — изображение в описании плагина (200 x auto)
    • js — для различных скриптов
    • lang — содержатся все lang pack
      • ru.php — Возвращает ассоциативный массив.
    • index.php — Основной файл плагина унаследованный от PluginBase
    • manifest.php — Манифест. Описывает что за плагин, указывает какие Actions использует, настройки, и права

Манифест — manifest.php

Это первый файл, с которого должны начинать разработку плагина

<?php

/** Manifest plugin */


return [
    "name" => "%plugin_name%",
    "description" => "Plugin description ",
    "types" => [
        "phone"
        /*"content",*/ /*"sms",*/
    ],
    "vendor" => "vendor name",
    "version" => "1.0",
    "rating" => 0,
    "settings" => [
        "param1" => "",
        "param2",
    ],
    /*Для других плагинов*/
    "ActiveForms" => [
        "edit",
        "list",
    ],
]; 

Manifes.php возвращает ассоциативный массив.

  • name — имя плагина
  • description — описание (может быть пустым)
  • types — Массив в которм указываются какие типы Action есть в этом плагине
  • vendor — Разработчик или компания
  • version — Версия плагина
  • rating — Всегда 0. Система определяет
  • settings — Настройки по умолчанию. Они же сохраняются в базу в установке и настройки плагина. Это ассоциативный массив ключ=>значение. Здесь сразу же можно указать значение по умолчанию
  • ActiveForms — массив для Других плагинов(content).В массиве передается список типов форм для которых загружается

Класс Index(index.php) extends PluginBase

Это обязательный файл, без которого не может обойтись любой плагин. Всегда имеет имя Index и унаследован от PluginBase

Свойства:

Все свойства и методы PluginBase

Методы:

String public function getName()
Должен возвращать всегда %PluginName%

Void public function actionIndex()
Используется для вывода Описания. Вызывается, когда кликаешь в plugin manager на описание. Можно так же явно поучить контент по ссылке /plugins/%PluginName%/index

//print html/description.tpl file
public function actionIndex() {
     $this->display("description");
}

Void public function actionSettings()
Используется для вывода Настроек. Вызывается при установки плагина и изменения его настроек.

Например:

Ключ настройка например называется «key»

Файл index.php actionSettings()

public function actionSettings() {
    //Если нужно установить переменные в шаблон,обязательно нужно вызвать этот метод и установить $this->page
    $this->beforeDisplay();
    //Все настройки mapping page
    $this->page->set($this->settings);
 
    //Установить Label с Langpack
    $this->page->set([
        "title_key" => $this->getRealName("title_key"),
    ]);
    //вывод шаблона settings.tpl
    $this->display("settings");
}

Файл html/settings.tpl

<!-- Используется, если есть #include или [[css]] или [[js]] -->
{css static}
<link href="$app_path/css/#name.css" rel="stylesheet" media="all" />
{/css}
{js static}
<script type="text/javascript" src="$app_path/js/#name.js"></script>
{/js}
<!-- Подключаем эти файлы если хотим использовать [[field]] [[CONTAINER]] -->
#include <fields>
#include <container>
<!-- Подключает css/style.css -->
[[css | name: style]]
 
[[CONTAINER | h: hide]]
    [[field | name: key | type: input | parentClass: w-100 | addLabel: $title_key$ | required:required-mode | value: $key$]]
[[CONTAINER_END]]
 
<!-- Подключает js/main.js -->
[[js | name: main]]

Langpack

Файлы языковых пакетов

Создаются в папке lang под именем (ru, en…). Например lang/ru.php. Файл должен возвращать массив ключ/значение

<?php

return [
    "title_key" => "Какой-то ключ",
];


Плагин для телефонии

Пример плагина для телефонии с именем test. Скачать пример можно по ссылке

  • test
    • actions
      • phone_action.php
    • css
      • style.css
    • html
      • description.tpl
      • settings.tpl
    • img
      • description.png — необязательная картинка для описания
      • logo_120.png
      • logo_200.png
    • js
      • main.js
    • lang
      • ru.php
    • index.php
    • manifest.php

manifest.php

<?php
/** Manifest plugin */
 
 
return [
    "name" => "test",
    "description" => "Test phone description",
    "types" => [
        "phone",
    ],
    "vendor" => "Test vendor",
    "version" => "1.0",
    "settings" => [
        "key" => "",
        "salt" => "",
        "url" => "",
    ]
];

index.php

<?php
namespace Kernel\Plugins\Test;
 
 
 
class Index extends \Kernel\Plugins\PluginBase {
 
    /** get system name */
    public function getName()
    {
        return "test";
    }
 
 
    /**
     * Render description install
     */
    public function actionIndex() {
        $this->display("description");
    }
 
 
 
    /**
     * Render settings form
     */
    public function actionSettings() {
        $this->beforeDisplay();
        $this->page->set($this->settings);
 
        $this->page->set([
            "api_key" => $this->getRealName("api_key"),
            "api_salt" => $this->getRealName("api_salt"),
            "urlName" => $this->getRealName("url")
        ]);
 
        $this->printCallbackLink(\Kernel\Plugins\PluginManager::PLUGIN_TYPE_PHONE);
        $this->printUsers();
        $this->display("settings");
    }
 
}

lang/ru.php

<?php
return [
    "name" => "Тест",
    "description" => "Система телефонии Test",
    "url" => "Адрес API Виртуальной АТС (call-back)",
    "api_key" => "Уникальный код вашей АТС ",
    "api_salt" => "Ключ для создания подписи "
];

actions/phone_action.php

<?php
 
namespace Kernel\Plugins\Test\Actions;
use Kernel\Actions\Notifications;
use Kernel\Framework\SocketMessage;
use Kernel\Framework\Websocket;
use Kernel\Database\Database as DB;
use Kernel\Kernel;
 
class PhoneAction extends \Kernel\Plugins\PluginPhoneBase {
 
   // use Notifications;
 
    public function actionCall(){
        $post = $_POST['name'];
        $to = $_POST['to'];
        $from = $this->getShortNumber($this->User->getEmployeeId());
        $company_id = time();
        echo $toRelease = $this->getFormatPhone($to, 7);
 
 
 
        $usersSet = $this->getPlugin()->getSettingsValue("users");
        if($usersSet){
            $decodedList = json_decode($usersSet, true);
            if($decodedList){
                foreach($decodedList as $dItem){
                    if($this->User->getEmployeeId() == $dItem['employee']){
                        $from = $dItem['ext'];
                        break;
                    }
                }
            }
        }
 
 
        $json       = '{"command_id":"'.$company_id.'","from":{"extension":"'.$from.'", "number":""},"to_number":"'.$to.'"}';
        $vpbx_api_key   = $this->getPlugin()->getSettingsValue("key");
        $vpbx_api_salt  = $this->getPlugin()->getSettingsValue("salt");
        $url = $this->getPlugin()->getSettingsValue("url");
 
 
        if(!$vpbx_api_key){
             $this->resultError ("api_key not set");
        }
        if(!$vpbx_api_salt){
             $this->resultError ("api_salt not set");
        }
        $sign       =  hash("sha256", $vpbx_api_key.$json.$vpbx_api_salt);
 
        $postData = [
            "vpbx_api_key" => $vpbx_api_key,
            "sign" => $sign,
            "from" => [
                "extension" => $from
            ],
            "to_number" => $to
        ];
 
        $response = $this->Transfer($url, $postData, false);
        return json_encode(['unique_id'=>$company_id, 'name'=>$post, 'to'=>$to, 'from'=>$from, 'status'=>'Connected', 'toRelease'=>$toRelease, 'pluginName' => $this->getPlugin()->getRealName()]);
 
    }
 
 
 
    public function actionInbound(){
        $json         = $_POST['json'];
        $obj          = json_decode($json, true);
 
        $ext = [];
        $extArray = [];
        $usersSet = $this->getPlugin()->getSettingsValue("users");
        $transfer = $this->getPlugin()->getSettingsValue("transfer");
 
 
        $aviableStates = ["Appeared", "Disconnected"];
 
        if(!isset($obj['call_state']))
            $obj['call_state'] = "";
 
        if(in_array($obj['call_state'], $aviableStates)/* && isset($obj['to']['extension']) && $obj['to']['extension']*/){
            if(isset($obj['to']['extension']))
                $ext[] = $obj['to']['extension'];
            if(!isset($obj['command_id']))
                $obj['command_id'] = $obj['from']['number'];
 
            if(mb_strlen($obj['from']['number']) == 10){
                if($obj['from']['number'][0] == "7")
                    $obj['from']['number'][0] = "8";
            }
 
 
            $search = $this->findByPhone($obj['from']['number']);
 
            // если перевод звонка включен и у нашелся контрагент звонящий
            if($transfer && $search['responsibleID'])
            {
                $extArray[] = $search['responsibleID'];
            }
            elseif($usersSet)
            {
                $decodedList = json_decode($usersSet, true);
                foreach ($decodedList as $item) {
                    // если от манго не пришел параметр ext
                    if(!count($ext))
                    {
                        $extArray[] = $item["employee"];
                        continue;
                    }
                    else if(is_array($ext) && in_array($item["ext"], $ext))
                    {
                        $extArray[] = $item["employee"];
                    }
                }
            }
 
            if($createRelationship)
            {
                if($search['id'])
                {
                    echo $search["id"];
                    $this->createRelationship($search['id'], $obj['from']['number'], $this->getPlugin()->getRealName(), false, $search['responsibleID']);
                }
                else
                {
                    $company = $this->createRelationship(0, $obj['from']['number'], $this->getPlugin()->getRealName(), true, $search['responsibleID']);
 
                    $search['name'] = $company->name;
                    $search['url'] = "/companies/" . $company->id . "/";
                }
            }
 
            //find user by ext
            $this->sendPopupPhone($extArray, $search['name'], $obj['to']['number'], $obj['from']['number'],  'Connected', 12, $search['url'], $search['responsible'], $this->getPlugin()->getRealName());
 
 
        }
        var_dump("OK");
    }
}

css/style.css

.assign-user{
    display:flex;
    flex-wrap:nowrap;
    align-items: flex-end;
}
 
.assign-user.prototype {
    display:none;
}
.assign-user > div:first-child {
    width:100%;
}
.assign-user > div:not(:first-child){
    margin-left:10px;
}
 
.assign-user > div:nth-child(2){
    max-width:80px;
}
 
.assign-user > div:last-child{
    align-self: center;
}
.actions-add-users {
    margin-top:10px;
}
.actions-add-users a {
    color:#6fa92e;
}
 
.actions-add-users a > span {
    display:inline-block;
    border-bottom:1px solid #6fa92e;
}

html/description.tpl

<link href="$app_path/css/style.css" type="text/css" rel="stylesheet" />
<h3>Описание</h3>
<p>«Text» — description</p>
 
<div class="descr-img">
   <img src="$app_path/img/description.png">
</div>

html/settings.tpl

{css static}
<link href="$app_path/css/#name.css" rel="stylesheet" media="all" />
{/css}
{js static}
<script type="text/javascript" src="$app_path/js/#name.js"></script>
{/js}
#include <fields>
#include <container>
 
[[css | name: style]]
 
 
{CALLBACK_LINK}
<div class="ui green message font-rel">
  <div class="header font-rel">
      Адрес внешней системы для callback:
  </div>
    <br>
  $link
</div>
{/CALLBACK_LINK}
 
[[CONTAINER | h: hide]]
    [[field | name: key | type: input | parentClass: w-100 | addLabel: $api_key$ | required:required-mode | value: $key$]]
    [[field | name: salt | type: input | parentClass: w-100 | addLabel: $api_salt$ | required:required-mode | value: $salt$]]
    [[field | name: url | type: hidden | parentClass: w-100 | addLabel: $urlName$ | required:required-mode | value: $url$]]
[[CONTAINER_END]]
 
<script>
    window.pluginTestSettings = "settings";
</script>
 
#include <plugin_users>
[[js | name: main]]


Плагин для SMS

Пример плагина для SMS с именем test. Скачать пример можно по ссылке

  • test
    • actions
      • sms_action.php
    • css
      • style.css
    • html
      • description.tpl
      • settings.tpl
    • img
      • description.png — необязательная картинка для описания
      • logo_120.png
      • logo_200.png
    • js
      • main.js
    • lang
      • ru.php
    • index.php
    • manifest.php

manifest.php

<?php
/** Manifest plugin */
 
 
return [
    "name" => "test",
    "description" => "Test sms description",
    "types" => [
        "sms",
    ],
    "vendor" => "Test vendor",
    "version" => "1.0",
    "settings" => [
        "key" => "",
        "salt" => "",
        "url" => "",
    ]
];

index.php

<?php
namespace Kernel\Plugins\Test;
 
class Index extends \Kernel\Plugins\PluginBase {
 
    /** get system name */
    public function getName()
    {
        return "test";
    }
 
    public function actionIndex() {
       $this->display("description");
    }
 
 
     /**
     * Render settings form
     */
    public function actionSettings() {
        $this->beforeDisplay();
        $this->printCallbackLink(\Kernel\Plugins\PluginManager::PLUGIN_TYPE_SMS);
        $this->page->set($this->settings);
        $this->page->set([
           "Login" => $this->getRealName("Login"),
           "Password" => $this->getRealName("Password"),
           "Sender" => $this->getRealName("Sender"),
           "URL" => $this->getRealName("URL"),
           "urlPirName" => $this->getRealName("urlPir"),
        ]);
        $this->display("settings");
    }
 
}

lang/ru.php

<?php
return [
    "name" => "Test",
    "fname" => "Test",
    "description" => "Отправка SMS-сообщений",
    "Login" => "Логин ",
    "Password" => "Пароль",
    "Sender" => "Отправитель",
    "URL" => "URL для исходящих запросов",
    "urlPir" => "Создать аккаунт",
];

actions/sms_action.php

<?php
namespace Kernel\Plugins\Test\Actions;
use Kernel\Actions\Notifications;
use Kernel\Framework\SocketMessage;
use Kernel\Framework\Websocket;
use Kernel\Database\Database as DB;
use Kernel\Kernel;
 
class SmsAction extends \Kernel\Plugins\PluginSmsBase {
 
   public function actionSend($argsData = []){
        $text    = trim($this->Http->Post->request("text", "Text", ""));
        $phoneTo = trim($this->Http->Post->request("to", "Varchar", ""));
 
        try {
            $this->send($text, $phoneTo);
            $this->resultSuccess("Ваше сообщение отправлено");
        } catch (\Exception $ex) {
            $this->resultError($ex->getMessage());
        }
    }
 
 
    /**
     *  SELF SEND
     * @param type $argsData
     */
    public function send($text, $phoneTo){
        if (!$phoneTo || !$text)
            throw new \Exception ("Variables not found");
 
        $phoneTo   = $this->getFormatPhone($phoneTo, "7");
       // $phoneTo   = "79169464837";
        $sLogin    = $this->getPlugin()->getSettingsValue("login");
        $sPassword = $this->getPlugin()->getSettingsValue("password");
        $sadr      = $this->getPlugin()->getSettingsValue("sadr");
        $url       = $this->getPlugin()->getSettingsValue("url");
 
 
        $result = $this->Transfer("https://".$url, [
            "user"=>$sLogin,
            "pwd" => $sPassword,
            "sadr"=>$sadr,
            "dadr"=>$phoneTo,
            "text"=>$text
        ], true, true);
 
        if(!is_numeric($result))
            throw new \Exception ($result);
    }
}

html/description.tpl

<link href="$app_path/css/style.css" type="text/css" rel="stylesheet" />
<h3>Описание</h3>
<p>«Text» — description</p>
 
<div class="descr-img">
   <img src="$app_path/img/description.png">
</div>

html/settings.tpl

{css static}
<link href="$app_path/css/#name.css" rel="stylesheet" media="all" />
{/css}
{js static}
<script type="text/javascript" src="$app_path/js/#name.js"></script>
{/js}
#include <fields>
#include <container>
 
[[css | name: style]]
 
 
{CALLBACK_LINK}
<div class="ui green message font-rel">
  <div class="header font-rel">
    Базовый адрес для принятия уведомлений:
  </div>
    <br>
  $link
</div>
{/CALLBACK_LINK}
 
[[CONTAINER | h: hide]]
    [[field | name: login | type: input| parentClass: w-100 | addLabel: $Login$ | required:required-mode | value: $login$]]
    [[field | name: password | type: input | ftype: password | parentClass: w-100 | addLabel: $Password$ | required:required-mode | value: $password$]]
    [[field | name: sadr | type: input| parentClass: w-100 | addLabel: $Sender$ | required:required-mode | value: $sadr$]]
    [[field | name: url | type: input| parentClass: w-100 | addLabel: $URL$ | required:required-mode | value: $url$]]
[[CONTAINER_END]]
 
[[js | name: main]]


Другие плагины


Другие плагины в системе называются content

Пример плагина для Content с именем test. Скачать пример можно по ссылке

  • test
    • actions
      • content_action.php
    • css
      • style.css
    • html
      • content.tpl
      • description.tpl
      • settings.tpl
    • img
      • description.png — необязательная картинка для описания
      • logo_120.png
      • logo_200.png
    • js
      • main.js
    • lang
      • ru.php
    • index.php
    • manifest.php

manifest.php

<?php
/** Manifest plugin */
 
 
return [
    "name" => "Test",
    "description" => "Test description",
    "types" => [
        "content",
    ],
    "ActiveForms" => [
        "edit",
        "list",
    ],
    "vendor" => "Test vendor",
    "version" => "1.1",
    "settings" => [
 
    ]
];

index.php

<?php
namespace Kernel\Plugins\Test;
 
 
 
class Index extends \Kernel\Plugins\PluginBase {
 
    /** get system name */
    public function getName()
    {
        return "test";
    }
 
 
    /**
     * Render description install
     */
    public function actionIndex() {
        $this->display("description");
    }
 
 
 
    /**
     * Render settings form
     */
    public function actionSettings() {
        $this->beforeDisplay();
        $this->page->set($this->settings);
        $this->printCallbackLink(\Kernel\Plugins\PluginManager::PLUGIN_TYPE_CONTENT);
        $this->display("settings");
    }
 
}

lang/ru.php

<?php
return [
    "name" => "Test",
    "fname" => "Test",
    "description" => "Test описание",
];

actions/content_action.php

<?php
namespace Kernel\Plugins\Test\Actions;
 
class ContentAction extends \Kernel\Plugins\PluginContentBase {
 
 
    /**
     * Requered function for render content result
     */
    public function content() {   
        $this->beforeDisplay();
        $this->page->set(['var'=>'test']);
        return $this->output("content");
    }
 
}

html/description.tpl

<link href="$app_path/css/style.css" type="text/css" rel="stylesheet" />
<h3>Описание</h3>
<p>«Text» — description</p>
 
<div class="descr-img">
   <img src="$app_path/img/description.png">
</div>

html/settings.tpl

{css static}
<link href="$app_path/css/#name.css" rel="stylesheet" media="all" />
{/css}
{js static}
<script type="text/javascript" src="$app_path/js/#name.js"></script>
{/js}
#include <fields>
#include <container>
 
[[css | name: style]]
 
 
{CALLBACK_LINK}
<div class="ui green message font-rel">
  $link
</div>
{/CALLBACK_LINK}
 
[[js | name: main]]

html/content.tpl

Файл может назваться как угодно. Контент который здесь, будет вставляться в CRM

Для плагинов, которые работают с чатом, нужно что бы метод был метод public function sendMessage($text, $user_id, $chat_id = null) в content_action.php. Для того что бы можно было вызвать в sendNotification

//plugin:viber content_action.php
public function sendMessage($text, $user_id, $chat_id = null)
{
    if(!$chat_id && $user_id)
        $chat_id = $this->getChatUser($user_id);
    if(!$chat_id)
        return;
    $token 	= $this->getPlugin()->getSettingsValue("auth_token");
    if(!$token)
        return;
 
   //send code here....
}
 
 
 
private function getChatUser($user_id){
    $resultUsers = [];
    $paramUsers =  $this->getPlugin()->getSettingsValue("users");
    if($paramUsers){
        try {
            $resultUsers = json_decode($paramUsers, true);
        } catch (\Exception $ex) {
 
        }
    }
    if($resultUsers){
        foreach($resultUsers as $usr){
            if(!isset($usr['employee']))
                continue;
            if(!isset($usr['ext']))
                continue;
            if($usr['employee'] == $user_id){
                if($usr['ext']){
                    return $usr['ext'];
                    break;
                }
            }
        }
    }
    return null;
}

Тогда вызвать в системе можно в любом месте следующим образом:

//Подключить trait
use \Kernel\Actions\Notifications;
//to user 2 and 22
$this->sendNotification([2,22], ["viber","telegram"], "message text");
Последние правки: 14.12.2018 11:43:46