# Интеграция с тарифными планами Plesk

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

## Добавление и проверка персональных прав и ограничений

Используются два вида хуков:

- pm_Hook_Permissions — для управления правами.
- pm_Hook_Limits — для управления ограничениями.

Права и ограничения имеют идентификаторы строкового типа, такие как «manage_git» и «max_repos». Эти идентификаторы должны быть уникальны в пределах одного расширения, но один и тот же идентификатор можно использовать в разных расширениях. Идентификаторы хранятся с собственными правами, ограничениями и другими данными тарифных планов в базе данных Plesk в таблице `TmplData`. Чтобы предотвратить конфликты идентификаторов, мы добавляем имя расширения в качестве префикса к каждому идентификатору. Например, расширение «git» добавляет персональное ограничение с названием «max_repos», таким образом, в контексте Plesk оно называется «git_max_repos», но в коде расширения используется «max_repos».

Примечание

Идентификаторы могут содержать только цифры, буквы и символ подчеркивания. Никакие другие символы не допускаются.

Добавлена новая обертка класса для тарифных планов (pm_Plan). Объекты строятся согласно идентификатору тарифного плана. Используются следующие геттеры: getId() и getName().

Методы `hasPermission($name)` и `getLimit($name)` предоставляют доступ к персональным правам и ограничениям соответственно. Эти методы доступны для доменов (pm_Domain) и сервис-планов (pm_Plan).

Метод pm_Client::hasPermission($name, $domain) проверяет, имеет ли клиент доступ к функциям домена, ограниченным правами.

## Примеры

# Права

Чтобы настроить право, укажите следующие параметры:

- key — уникальный ключ доступа к праву (например, „manage_git“).
- default — значение права по умолчанию («true» или «false»).
- place — колонка, в которую будет помещено право. Может принимать либо значение `self::PLACE_MAIN` (левая колонка), либо `self::PLACE_ADDITIONAL` (правая/скрываемая колонка). Этот параметр необязателен, по умолчанию используется `PLACE_MAIN`.
- name — отображаемое имя права. Для имени рекомендуется использовать локализацию.
- description — краткое описание. Для описания рекомендуется использовать локализацию.
- master — ключ управляющего права (необязательно). Зависимое право может быть включено, только если включено управляющее право. Обратите внимание, что управляющее право также должно быть объявлено в расширении.

Добавьте хук (имя файла: `Permissions.php`), содержащий следующий код:

    class Modules_ServicePlanApi_Permissions extends pm_Hook_Permissions
    {
        public function getPermissions()
        {
            return [
                'manage_mypermission' => [
                    'default' => true,
                    'place' => self::PLACE_ADDITIONAL,
                    'name' => 'My Permission',
                    'description' => 'My Permission description.',
                ],
                'manage_mydependentpermission' => [
                    'default' => false,
                    'place' => self::PLACE_ADDITIONAL,
                    'name' => 'My Dependent Permission',
                    'description' => 'My Dependent Permission description.',
                    'master' => 'manage_mypermission',
                ],
            ];
        }
    }

Пример использования (проверка права):

    class IndexController extends pm_Controller_Action
    {
        public function init()
        {
            parent::init();

            /** @var pm_Domain */
            $domain = $this->_getDomain(); // get pm_Domain somehow
            if (!$domain->hasPermission('manage_something')) {
                throw new pm_Exception($this->lmsg('permissionDenied'));
            }

            if (!pm_Session::getClient()->hasPermission('manage_something', $domain)) {
                throw new pm_Exception($this->lmsg('permissionDenied'));
            }
        }

        // Some code here
    }

# Ограничения

Чтобы установить ограничение на использование ресурса, укажите следующие параметры:

- key — уникальный ключ доступа к ограничению (например, „max_repos“).
- default — значение ограничения по умолчанию (тип: целое число, установите -1 для значения «без ограничений»).
- place — колонка, в которую будет помещено ограничение. Может принимать либо значение `self::PLACE_MAIN` (левая колонка), либо `self::PLACE_ADDITIONAL` (правая/скрываемая колонка). Этот параметр необязателен, по умолчанию используется `PLACE_MAIN`.
- name — отображаемое имя ограничения. Для имени рекомендуется использовать локализацию.
- description — краткое описание. Для описания рекомендуется использовать локализацию.

Добавьте хук (имя файла: `Limits.php`), содержащий следующий код:

    class Modules_ServicePlanApi_Limits extends pm_Hook_Limits
    {
        public function getLimits()
        {
            return [
                'max_limit' => [
                    'default' => -1,
                    'place' => self::PLACE_MAIN,
                    'name' => 'My Limit',
                    'description' => 'My Limit description.',
                ],
            ];
        }
    }

Пример использования (проверка ограничения):

    class IndexController extends pm_Controller_Action
    {
        // Some code here

        public function addAction()
        {
            $repoCount = $this->_getRepoCount(); // get actual amount of limited entity
            /** @var pm_Domain */
            $domain = $this->_getDomain(); // get pm_Domain somehow
            $limit = $domain->getLimit('max_repos');
            if ($limit > -1 && $limit <= $repoCount) {
                throw new pm_Exception($this->lmsg('maxRepoCountCreated'));
            }
            // Some code here
        }

        // Some code here
    }

Вы можете найти пример расширения, иллюстрирующий этот подход, здесь.

## Регистрация тарифного плана, связанного с расширением, в Plesk

Вы можете создавать тарифные планы, ассоциированные с вашим расширением, и добавлять подписки, основанные на этих тарифных планах. Это может быть полезно для введения распределительных систем оплаты. Для регистрации тарифных планов ваше расширение должно содержать класс pm_Hook_PlanItems, назовите его `Modules_<Extension name>_PlanItems` и поместите в папку `plib/hooks/`. Помимо регистрации тарифных планов этот хук определяет, должны ли тарифные планы быть эксклюзивными (поведение по умолчанию) или можно использовать несколько тарифных планов в одной подписке.

Зарегистрированные тарифные планы должны быть созданы в Plesk при установке расширения и удалены из Plesk при удалении расширения. При обновлении расширения тарифные планы должны быть обновлены (новые тарифные планы должны быть добавлены, созданные ранее тарифные планы должны быть обновлены или удалены, если они больше не зарегистрированы в хуке).

Чтобы получить список тарифных планов расширения, которые включены в услугу или подписку Plesk, используйте следующие методы, которые возвращают массив ключей тарифных планов:

- `pm_Plan::getPlanItems()`
- `pm_Domain::getPlanItems()`

## Примеры

Пример регистрации тарифных планов (`PRODUCT_ROOT_D/admin/plib/modules/example/hooks/PlanItems.php`):

    class Modules_Example_PlanItems extends pm_Hook_PlanItems
    {
        public function getPlanItems()
        {
            return [
                'starter' => 'Starter',
                'lite' => 'Lite',
                'premium' => 'Premium'
            ];
        }
    }

Пример получения тарифных планов:

    $plan = new pm_Plan(3);
    $plan->getPlanItems(); // ['starter']
    $domain = new pm_Domain(1);
    $domain->getPlanItems(); // []

Вы можете найти пример расширения, иллюстрирующий этот подход, здесь.