<?php

require_once dirname(__FILE__).'/class.pleskserver.php';
require_once 'modules/admin/models/ServerPlugin.php';
/**
* @package Plugins
*/
class PluginPlesk extends ServerPlugin
{
    function getVariables()
    {
        /* Specification
              itemkey     - used to identify variable in your other functions
              type        - text,textarea,yesno,password,hidden ( type hidden are variables used by CE and are required )
              description - description of the variable, displayed in ClientExec
              encryptable - used to indicate the variable's value must be encrypted in the database
              template    - used to indicate the variable is in the domain template
        */

        $variables = array(
            /*T*/'Name'/*/T*/          => array(
                'type'          => 'hidden',
                'description'   => 'Used By CE to show plugin - must match how you call the action function names',
                'value'         => 'Plesk',
                               ),
            /*T*/'Description'/*/T*/   => array(
                'type'          => 'hidden',
                'description'   => /*T*/'Description viewable by admin in server settings'/*/T*/,
                'value'         => /*T*/'Plesk control panel integration'/*/T*/,
                               ),
            /*T*/'Username'/*/T*/      => array(
                'type'          => 'text',
                'description'   => /*T*/'If you\'ll provide reseller accounts, enter here the Plesk administrator credentials. Otherwise just enter a regular user\'s credentials, but be aware that such user has to have \'Domain creation\', \'Physical hosting management\', \'Hard disk quota assignment\', \'Domain limits adjustment\'  and \'Ability to use remote XML interface\' permissions. This user will also need to have all its personal data configured in Plesk (E-mail, phone, etc), even those fields that are not marked as required.'/*/T*/,
                'value'         => '',
                               ),
            /*T*/'Password'/*/T*/      => array(
                'type'          => 'password',
                'description'   => /*T*/'If you\'ll provide reseller accounts, enter here the Plesk administrator credentials. Otherwise just enter a regular user\'s credentials, but be aware that such user has to have \'Domain creation\', \'Physical hosting management\', \'Hard disk quota assignment\', \'Domain limits adjustment\'  and \'Ability to use remote XML interface\' permissions. This user will also need to have all its personal data configured in Plesk (E-mail, phone, etc), even those fields that are not marked as required.'/*/T*/,
                'value'         => '',
                'encryptable'   => true,
                               ),
            /*T*/'Non-Admin Username'/*/T*/ => array(
                'type'          => 'text',
                'description'   => /*T*/'If you\'ll provide both reseller and non-reseller accounts, use the Plesk administrator account to create a user under whom non-reseller accounts (domains) will be created and enter its credentials here. Otherwise leave this field empty. This user will also need to have all its personal data configured in Plesk (E-mail, phone, etc), even those fields that are not marked as required.'/*/T*/,
                'value'         => '',
                               ),
            /*T*/'Non-Admin Password'/*/T*/ => array(
                'type'          => 'password',
                'description'   => /*T*/'If you\'ll provide both reseller and non-reseller accounts, use the Plesk administrator account to create a user under whom non-reseller accounts (domains) will be created and enter its credentials here. Otherwise leave this field empty. This user will also need to have all its personal data configured in Plesk (E-mail, phone, etc), even those fields that are not marked as required.'/*/T*/,
                'value'         => '',
                'encryptable'   => true,
                               ),
            /*T*/'Actions'/*/T*/       => array(
                'type'          => 'hidden',
                'description'   => /*T*/'Current actions that are active for this plugin per server'/*/T*/,
                'value'         => 'Create,Delete,Update,Suspend,Unsuspend',
                               ),
            /*T*/'package_vars'/*/T*/  => array(
                'type'          => 'hidden',
                'description'   => /*T*/'Whether package settings are set'/*/T*/,
                'value'         => '0',
                               ),
            /*T*/'package_vars_values'/*/T*/ => array(
                'type'          => 'hidden',
                'description'   => /*T*/'Hosting account parameters'/*/T*/,
                'value'         => array(
                                        'reseller_account' => array(
                                                               'type'           => 'yesno',
                                                               'description'    => /*T*/'Reseller Account (you need Plesk Administrator access):<br>NOTE: The username for non-reseller accounts is the domain name'/*/T*/,
                                                               'value'          => '0',
                                                           ),
                                        'max_dom'       => array(
                                                               'type'           => 'text',
                                                               'description'    => /*T*/'Maximum number of domains (for resellers only, leave empty for unlimited)'/*/T*/,
                                                               'value'          => '',
                                                            ),
                                        'www'           => array(
                                                               'type'           => 'yesno',
                                                               'description'    => /*T*/'Use www prefix'/*/T*/,
                                                               'value'          => '1',
                                                            ),
                                        'max_subdom'    => array(
                                                               'type'           => 'text',
                                                               'description'    => /*T*/'Maximum number of subdomains (leave empty for unlimited)'/*/T*/,
                                                               'value'          => '',
                                                               'template'       => true,
                                                            ),
                                        'disk_space'    => array(
                                                               'type'           => 'text',
                                                               'description'    => /*T*/'Disk space (in bytes, leave empty for unlimited)'/*/T*/,
                                                               'value'          => '',
                                                               'template'       => true,
                                                            ),
                                        'max_traffic'   => array(
                                                               'type'           => 'text',
                                                               'description'    => /*T*/'Maximum amount of traffic (in bytes/month, leave empty for unlimited)'/*/T*/,
                                                               'value'          => '',
                                                               'template'       => true,
                                                            ),
                                        'max_wu'        => array(
                                                               'type'           => 'text',
                                                               'description'    => /*T*/'Maximum number of web users (leave empty for unlimited)'/*/T*/,
                                                               'value'          => '',
                                                               'template'       => true,
                                                            ),
                                        'max_db'        => array(
                                                               'type'           => 'text',
                                                               'description'    => /*T*/'Maximum number of databases (leave empty for unlimited)'/*/T*/,
                                                               'value'          => '',
                                                               'template'       => true,
                                                            ),
                                        'max_box'       => array(
                                                               'type'           => 'text',
                                                               'description'    => /*T*/'Maximum number of mailboxes (leave empty for unlimited)'/*/T*/,
                                                               'value'          => '',
                                                               'template'       => true,
                                                            ),
                                        'mbox_quota'    => array(
                                                               'type'           => 'text',
                                                               'description'    => /*T*/'Mailbox quota (in bytes, leave empty for unlimited)'/*/T*/,
                                                               'value'          => '',
                                                               'template'       => true,
                                                            ),
                                        'max_redir'     => array(
                                                               'type'           => 'text',
                                                               'description'    => /*T*/'Maximum number of mail redirects (leave empty for unlimited)'/*/T*/,
                                                               'value'          => '',
                                                               'template'       => true,
                                                            ),
                                        'max_mg'        => array(
                                                               'type'           => 'text',
                                                               'description'    => /*T*/'Maximum number of mail groups (leave empty for unlimited)'/*/T*/,
                                                               'value'          => '',
                                                               'template'       => true,
                                                            ),
                                        'max_resp'      => array(
                                                               'type'           => 'text',
                                                               'description'    => /*T*/'Maximum number of mail autoresponders (leave empty for unlimited)'/*/T*/,
                                                               'value'          => '',
                                                               'template'       => true,
                                                            ),
                                        'max_maillists' => array(
                                                               'type'           => 'text',
                                                               'description'    => /*T*/'Maximum number of mail lists (leave empty for unlimited)'/*/T*/,
                                                               'value'          => '',
                                                               'template'       => true,
                                                            ),
                                        'max_webapps'   => array(
                                                               'type'           => 'text',
                                                               'description'    => /*T*/'Maximum number of Java applications (leave empty for unlimited)'/*/T*/,
                                                               'value'          => '',
                                                               'template'       => true,
                                                            ),
                                        'ftp_quota'     => array(
                                                               'type'           => 'text',
                                                               'description'    => /*T*/'FTP quota (in bytes, leave empty for unlimited)'/*/T*/,
                                                               'value'          => '',
                                                               'template'       => true,
                                                            ),
                                        'fp'            => array(
                                                               'type'           => 'yesno',
                                                               'description'    => /*T*/'FrontPage support'/*/T*/,
                                                               'value'          => '0',
                                                               'template'       => true,
                                                            ),
                                        'fp_ssl'        => array(
                                                               'type'           => 'yesno',
                                                               'description'    => /*T*/'FrontPage over SSL support'/*/T*/,
                                                               'value'          => '0',
                                                               'template'       => true,
                                                            ),
                                        'fp_auth'       => array(
                                                               'type'           => 'yesno',
                                                               'description'    => /*T*/'Allow FrontPage Authorization'/*/T*/,
                                                               'value'          => '0',
                                                               'template'       => true,
                                                            ),
                                        'ssl'           => array(
                                                               'type'           => 'yesno',
                                                               'description'    => /*T*/'SSL support'/*/T*/,
                                                               'value'          => '0',
                                                               'template'       => true,
                                                            ),
                                        'shell'         => array(
                                                               'type'           => 'text',
                                                               'description'    => /*T*/'System shell (e.g. /bin/bash. Leave empty to disallow)'/*/T*/,
                                                               'value'          => '',
                                                               'template'       => true,
                                                            ),
                                        'php'           => array(
                                                               'type'           => 'yesno',
                                                               'description'    => /*T*/'PHP support'/*/T*/,
                                                               'value'          => '0',
                                                               'template'       => true,
                                                            ),
                                        'ssi'           => array(
                                                               'type'           => 'yesno',
                                                               'description'    => /*T*/'SSI support'/*/T*/,
                                                               'value'          => '0',
                                                               'template'       => true,
                                                            ),
                                        'cgi'           => array(
                                                               'type'           => 'yesno',
                                                               'description'    => /*T*/'CGI support'/*/T*/,
                                                               'value'          => '0',
                                                               'template'       => true,
                                                            ),
                                        'mod_perl'      => array(
                                                               'type'           => 'yesno',
                                                               'description'    => /*T*/'mod_perl support'/*/T*/,
                                                               'value'          => '0',
                                                               'template'       => true,
                                                            ),
                                        'mod_python'    => array(
                                                               'type'           => 'yesno',
                                                               'description'    => /*T*/'mod_python support'/*/T*/,
                                                               'value'          => '0',
                                                               'template'       => true,
                                                            ),
                                        'asp'           => array(
                                                               'type'           => 'yesno',
                                                               'description'    => /*T*/'Apache ASP support'/*/T*/,
                                                               'value'          => '0',
                                                               'template'       => true,
                                                            ),
                                        'asp_dot_net'   => array(
                                                               'type'           => 'yesno',
                                                               'description'    => /*T*/'ASP.NET support'/*/T*/,
                                                               'value'          => '0',
                                                               'template'       => true,
                                                            ),
                                        'max_mssql_db'   => array(
                                                               'type'           => 'text',
                                                               'description'    => /*T*/'Maximum number of Microsoft SQL Server databases'/*/T*/,
                                                               'value'          => '',
                                                               'template'       => true,
                                                            ),
                                        'coldfusion'    => array(
                                                               'type'           => 'yesno',
                                                               'description'    => /*T*/'Coldfusion support'/*/T*/,
                                                               'value'          => '0',
                                                               'template'       => true,
                                                            ),
                                        'webstat'       => array(
                                                               'type'           => 'text',
                                                               'description'    => /*T*/'Webserver statistics support (awstats, webalizer, smarterstats, urchin, none)'/*/T*/,
                                                               'value'          => 'none',
                                                               'template'       => true,
                                                            ),
                                        'errdocs'       => array(
                                                               'type'           => 'yesno',
                                                               'description'    => /*T*/'Custom error documents support'/*/T*/,
                                                               'value'          => '0',
                                                               'template'       => true,
                                                            ),
                                        'at_domains'    => array(
                                                               'type'           => 'yesno',
                                                               'description'    => /*T*/'@-domains support'/*/T*/,
                                                               'value'          => '0',
                                                            ),
                                    ),
                ),
            /*T*/'package_addons'/*/T*/ => array(
                'type'          => 'hidden',
                'description'   => /*T*/'Supported signup addons variables'/*/T*/,
                'value'         => array(
                    'DISKSPACE', 'BANDWIDTH', 'EMAIL_ACCOUNTS', 'EMAIL_QUOTA', 'SSH_ACCESS', 'SSL'
                ),
            ),
        );

        return $variables;
    }

    function validateCredentials($args)
    {
        $errors = array();
        if (!preg_match('/^[\w.-]+$/', $args['DomainUsername'])) {
            $errors[] = /*T*/'Domain username can only contain alphanumeric characters, dots, dashes and underscores'/*/T*/;
        }

        if (strpos($args['DomainPassword'], $args['DomainUsername']) !== false) {
            $errors[] = /*T*/'Domain password can\'t contain domain username'/*/T*/;
        }

        if (trim($args['DomainUsername']) == '') {
            $errors[] = /*T*/'Domain username can\'t be empty'/*/T*/;
        }

        if (strlen($args['DomainPassword']) > 14 && @$args['generateNewUsername']) {
            $args['DomainPassword'] = mb_substr($args['DomainPassword'], 0, 14);
        }

        if (strlen($args['DomainPassword']) < 5 || strlen($args['DomainPassword']) > 14) {
            $errors[] = /*T*/'Password length must be between 5 and 14 characters'/*/T*/;
        }

        if ($errors) {
            throw new Exception($errors[0]);
        }

        return $args['DomainUsername'];
    }

    function create($args, $server = false)
    {
        // package add-ons handling
        if (isset($args['package_addons']['DISKSPACE'])) {
            $args['package_vars']['disk_space'] += ((int)$args['package_addons']['DISKSPACE']) * 1048576; // 1 Meg in bytes
        }
        if (isset($args['package_addons']['BANDWIDTH'])) {
            $args['package_vars']['max_traffic'] += ((int)$args['package_addons']['BANDWIDTH']) * 1073741824; // 1 Gig in bytes
        }
        if (isset($args['package_addons']['EMAIL_ACCOUNTS'])) {
            $args['package_vars']['max_box'] += ((int)$args['package_addons']['EMAIL_ACCOUNTS']);
        }
        if (isset($args['package_addons']['EMAIL_QUOTA'])) {
            $args['package_vars']['mbox_quota'] += ((int)$args['package_addons']['EMAIL_QUOTA']) * 1048576;
        }
        if (isset($args['package_addons']['SSH_ACCESS']) && $args['package_addons']['SSH_ACCESS'] == 1) {
            $args['package_vars']['shell'] = '/bin/bash';
        }
        if (isset($args['package_addons']['SSL']) && $args['package_addons']['SSL'] == 1) {
            $args['package_vars']['ssl'] = '1';
        }

        if (isset($args['package_vars']['reseller_account']) && $args['package_vars']['reseller_account'] == 1) {
            // use $server to test with mock object
            if (!$server) {
                $server = new PleskServer($this->settings, $args['ServerHostName'], $args['plugin_plesk_Username'], $args['plugin_plesk_Password']);
            }

            // create user in Plesk
            $tUser = new User($args['CustomerID']);
            $userId = $server->addUser( $args['UserFirstName'] . ' ' . $args['UserLastName'] . ' (' . $args['PackageID'] . ')',
                                        $args['DomainUsername'],
                                        $args['DomainPassword'],
                                        $tUser);
            if (is_a($userId, 'NE_Error')) {
                return $userId;
            }
            $response = $server->addResellerPermissionsAndLimits($userId, @$args['package_vars']);
            if (is_a($response, 'NE_Error')) {
                return $response;
            }

            // add IP to user
            if (is_a($result = $server->addIpToUser($userId, $args['DomainIP']), 'NE_Error')) {
                return $result;
            }
        } else {
            if (!$server) {
                if ($args['plugin_plesk_Non-Admin_Username'] != '' && $args['plugin_plesk_Non-Admin_Password'] != '') {
                    $server = new PleskServer($this->settings, $args['ServerHostName'], $args['plugin_plesk_Non-Admin_Username'], $args['plugin_plesk_Non-Admin_Password']);
                } else {
                    $server = new PleskServer($this->settings, $args['ServerHostName'], $args['plugin_plesk_Username'], $args['plugin_plesk_Password']);
                }
            }
            $userId = false;
        }

        // add domain to user
        if($args['PackageNameOnServer']!=null && $args['PackageNameOnServer']!= ''){
            $args['package_vars']['PackageNameOnServer'] = $args['PackageNameOnServer'];
            $variables = $this->getVariables();
            foreach($variables['package_vars_values']['value'] AS $varName=>$attrs){
                if(isset($attrs['template']) && $attrs['template']){
                    $args['package_vars']['TemplateAttr'][] = $varName;
                }
            }
        }

        $dUser = new User($args['CustomerID']);
        $domainId = $server->addDomainToUser(    $userId,
                                                 $args['DomainUsername'],
                                                 $args['DomainPassword'],
                                                 $args['DomainName'],
                                                 $args['DomainIP'],
                                                 @$args['package_vars'],
                                                 @$dUser
                                                 );

        // Ignore error 2307: always raises even if operation was successful.
        if (is_a($domainId, 'NE_Error') && $domainId->getErrCode() != 2307) {
            $errormsg = 'There was an error creating the domain. ERROR CODE '.$domainId->getErrCode().'. '.$domainId->getMessage();
            $this->logger->log(4, "plugin_plesk::create::error: ".$errormsg);

            throw new Exception($errormsg, 200);
        }

        return array('userId' => $userId, 'domainId' => $domainId);

    }

    // use $server to test with mock object
    function update($args, $server = false)
    {
        $userName       = $args['DomainUsername'];
        $password       = $args['DomainPassword'];
        $ip             = $args['DomainIP'];
        $packageVars    = false;

        foreach ($args as $change => $newValue) {
            switch($change) {
                case 'CHANGE_USERNAME':
                    $userName = $args['CHANGE_USERNAME'];
                    break;
                case 'CHANGE_PASSWORD':
                    $password = $args['CHANGE_PASSWORD'];
                    break;
                case 'CHANGE_PACKAGE':
                    $packageVars = $args['NewPackageVars'];
                    break;
                case 'CHANGE_IP':
                    // this actually does nothing since plesk won't let change a domains IP
                    $ip = $args['CHANGE_IP'];
                    break;
            }
        }

        if (isset($args['package_vars']['reseller_account'])) {
            if (!$server) {
                $server = new PleskServer($this->settings, $args['ServerHostName'], $args['plugin_plesk_Username'], $args['plugin_plesk_Password']);
            }

            // update reseller account if necessary
            if ($userName != $args['DomainUsername'] || $password != $args['DomainPassword']) {
                $tUser = new User($args['CustomerID']);
                $result = $server->updateAccount($tUser, $args['ServerAcctProperties']['userId'], $userName, $password);
                if (is_a($result, 'NE_Error')) {
                    return $result;
                }
            }
        } else {
            if (!$server) {
                if ($args['plugin_plesk_Non-Admin_Username'] != '' && $args['plugin_plesk_Non-Admin_Password'] != '') {
                    $server = new PleskServer($this->settings, $args['ServerHostName'], $args['plugin_plesk_Non-Admin_Username'], $args['plugin_plesk_Non-Admin_Password']);
                } else {
                    $server = new PleskServer($this->settings, $args['ServerHostName'], $args['plugin_plesk_Username'], $args['plugin_plesk_Password']);
                }
            }
        }

        // unset package attributes must be set to 0
        if ($packageVars) {
            $variables = $this->getVariables();
            $variables = array_keys($variables['package_vars_values']['value']);
            $attributes = array();
            foreach ($variables as $variable) {
                $attributes[$variable] = 0;
            }
            $packageVars = array_merge($attributes, $packageVars);
        }
        if($args['PackageNameOnServer']!=null && $args['PackageNameOnServer']!= ''){
            $packageVars['PackageNameOnServer'] = $args['PackageNameOnServer'];
            $variables = $this->getVariables();
            foreach($variables['package_vars_values']['value'] AS $varName=>$attrs){
                if(isset($attrs['template']) && $attrs['template']){
                    $packageVars['TemplateAttr'][] = $varName;
                }
            }
        }
        $isDomainIdMissing = false;
        if($args['ServerAcctProperties']['domainId'] == null || $args['ServerAcctProperties']['domainId'] == ""){
            $newDomainId = $server->getDomainId($args["domainName"]);
            $args['ServerAcctProperties']['domainId'] = $newDomainId;
            $isDomainIdMissing = true;
            $this->logger->log(4,"pluginplesk domain id = ".$newDomainId);
        }
        $result = $server->updateDomain($args['ServerAcctProperties']['domainId'], $userName, $password, $ip, $packageVars);

        if (is_a($result, 'NE_Error')) {
            $this->logger->log(4,"Error code = ".$result);
            return $result;
        }elseif($isDomainIdMissing){
            $this->logger->log(4,"pluginplesk domain id missing = ".$args['ServerAcctProperties']['domainId']);
            return array('domainId' => $newDomainId);
        }

        return true;
    }

    function delete($args, $server = false)
    {
        if (isset($args['package_vars']['reseller_account'])) {
            if (!$server) {
                $server = new PleskServer($this->settings, $args['ServerHostName'], $args['plugin_plesk_Username'], $args['plugin_plesk_Password']);
            }

            // delete user account
            $response = $server->deleteUser($args['ServerAcctProperties']['userId']);
            if (is_a($response, 'NE_Error')) {
                return $response;
            }

        } else {
            if (!$server) {
                if ($args['plugin_plesk_Non-Admin_Username'] != '' && $args['plugin_plesk_Non-Admin_Password'] != '') {
                    $server = new PleskServer($this->settings, $args['ServerHostName'], $args['plugin_plesk_Non-Admin_Username'], $args['plugin_plesk_Non-Admin_Password']);
                } else {
                    $server = new PleskServer($this->settings, $args['ServerHostName'], $args['plugin_plesk_Username'], $args['plugin_plesk_Password']);
                }
            }

            // delete domain
            // Plesk is not responding well to this command
            /*$response = $server->deleteDomain($args['ServerAcctProperties']['domainId']);
            if (is_error($response)) {
                return $response;
            }*/

            throw new Exception('For the moment Plesk doesn\'t support the DELETE event for domains', 107);
        }

        return true;
    }

    function suspend($args, $server = false)
    {
        if (!$server) {
            $server = new PleskServer($this->settings, $args['ServerHostName'], $args['plugin_plesk_Username'], $args['plugin_plesk_Password']);
        }

        if (isset($args['package_vars']['reseller_account'])) {
            // suspend user account
            // Plesk is not responding well to this command
            /*$response = $server->setUserStatus($args['ServerAcctProperties']['userId'], 16);
            if (is_a($response, 'NE_Error')) {
                return $response;
            }*/

            // Erase this block of code when Plesk respond well to the above block
            // ---------------------------------------------------------------------------------
            $response = $server->setDomainStatus($args['ServerAcctProperties']['domainId'], 16);
        	if (is_a($response, 'NE_Error')) {
                    return $response;
            }
            // ---------------------------------------------------------------------------------

            throw new Exception('For the moment Plesk doesn\'t support the SUSPEND event for clients, only the domain was suspended', 108);

        }else{
            // suspend domain
            $response = $server->setDomainStatus($args['ServerAcctProperties']['domainId'], 16);
        	if (is_a($response, 'NE_Error')) {
                    return $response;
            }
        }
    }

    function unsuspend($args, $server = false)
    {
        if (!$server) {
            $server = new PleskServer($this->settings, $args['ServerHostName'], $args['plugin_plesk_Username'], $args['plugin_plesk_Password']);
        }

        /*if (isset($args['package_vars']['reseller_account'])) {
            // unsuspend user account
            // Plesk is not responding well to this command
            $response = $server->setUserStatus($args['ServerAcctProperties']['userId'], 0);
            if (is_a($response, 'NE_Error')) {
                return $response;
            }
        }*/

        // unsuspend domain
    	$response = $server->setDomainStatus($args['ServerAcctProperties']['domainId'], 0);
    	if (is_a($response, 'NE_Error')) {
                return $response;
        }
    }
}
?>
