Integrate with Plesk Service Plans

Plesk SDK API gives you the ability to integrate with Plesk service plans by adding and checking custom permissions and limits to service plans, resellers and subscriptions, and also by registering extension-related plan items in Plesk.

Adding and checking custom permissions and limits

Two following hooks are used:

Permissions and limits have string IDs like “manage_git” and “max_repos”. These IDs must be unique for individual extensions, but the same ID name can be used in different extensions. IDs are stored with native permissions, limits, and other plan items’ data in the Plesk database, in the TmplData table. To prevent IDs from clashing, we add an extension name prefix to each ID. For example, the “git” extension adds custom limit named “max_repos”, so within the Plesk context it becomes “git_max_repos”, but in the extension code “max_repos” is used.

Note

ID names can contain only numbers, letters, and the underscore symbol. All other symbols are not allowed.

A new class Service Plan wrapper (pm_Plan) was added. Objects are constructed by service plan ID. There are getters: getId() and getName().

The methods hasPermission($name) and getLimit($name) provide access to custom permissions and limits, correspondingly. These methods are available for domains (pm_Domain) and service plans (pm_Plan).

The method pm_Client::hasPermission($name, $domain) checks if the client has access to the domain’s functionality restricted by permission.

Examples

Permissions

To set a permission, specify the following parameters:

  • key - a unique key to access the permission (for example, ‘manage_git’).
  • default - the permission’s default value (“true” or “false”).
  • place - the column in which the permission will be placed. Takes either self::PLACE_MAIN (the left column) or self::PLACE_ADDITIONAL (the right/hideable column). The parameter is optional, PLACE_MAIN is used by default.
  • name - the permission’s display name. It is recommended to use localization for the name.
  • description - a short description. It is recommended to use localization for the description.
  • master - a master permission key (optional). A dependent permission can be switched on only if the master permission is switched on. Note that the master permission must be also declared by the extension.

Add a hook (filename: Permissions.php) with the following code:

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',
            ],
        ];
    }
}

Usage example (checking permission):

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
}

Limits

To set a limit, specify the following parameters:

  • key - a unique key to access the limit (for example, ‘max_repos’).
  • default - the limit’s default value (type: integer, set -1 for “unlimited”).
  • place - the column in which the limit will be placed. Takes either self::PLACE_MAIN (the left column) or self::PLACE_ADDITIONAL (the right/hideable column). The parameter is optional, PLACE_MAIN is used by default.
  • name - the limit’s display name. It is recommended to use localization for the name.
  • description - a short description. It is recommended to use localization for the description.

Add a hook (filename: Limits.php) with the following code:

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.',
            ],
        ];
    }
}

Usage example (checking limit):

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
}

You can find a sample extension illustrating this concept here.

Examples

An example of plan items registry (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'
        ];
    }
}

An example of plan items being retrieved:

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

You can find a sample extension illustrating this concept here.