├── .gitignore ├── LICENSE ├── README.md ├── composer.json ├── composer.lock ├── samples ├── AddUser.php ├── DeleteUser.php └── settings.dist.php └── src └── VestaCP ├── Client.php ├── Command ├── AbstractCommand.php ├── CommandInterface.php ├── Exception.php ├── Map │ ├── AbstractMap.php │ └── User.php └── User │ ├── AddUserCommand.php │ └── DeleteUserCommand.php ├── ErrorCodes.php ├── Exception.php └── HTTP ├── Client.php └── Exception.php /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | vendor 3 | samples/settings.php -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Phalcon Hosting 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VestaCP API wrapper for PHP 2 | ----- 3 | 4 | ## Description 5 | This library acts as a API wrapper for the VestaCP (http://vestacp.com) Control Panel. 6 | 7 | ## Usage 8 | 9 | To use this library first run `composer update` or `composer install`. 10 | 11 | ## Samples 12 | Samples of usage can be found in samples/ 13 | 14 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phalcon-hosting/vestacp-api", 3 | "description": "API Wrapper for the VestaCP Control Panel", 4 | "keywords": ["vesta","vestacp","api wrapper","phalcon","phalcon hosting"], 5 | "homepage": "http://www.phalconhosting.com", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Stephen Hoogendijk", 10 | "email": "stephen@tca0.nl", 11 | "homepage": "http://stephen.tca0.nl", 12 | "role": "Developer" 13 | } 14 | ], 15 | "autoload": { 16 | "psr-0": { "VestaCP\\": "src/" } 17 | }, 18 | "require": { 19 | "php": ">=5.3.0" 20 | }, 21 | "minimum-stability": "dev" 22 | } -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "hash": "15995dd07edd2fc5655b518c02d6a055", 8 | "packages": [], 9 | "packages-dev": [], 10 | "aliases": [], 11 | "minimum-stability": "dev", 12 | "stability-flags": [], 13 | "prefer-stable": false, 14 | "prefer-lowest": false, 15 | "platform": { 16 | "php": ">=5.3.0" 17 | }, 18 | "platform-dev": [] 19 | } 20 | -------------------------------------------------------------------------------- /samples/AddUser.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | use VestaCP\Client; 6 | 7 | require __DIR__ . '/../vendor/autoload.php'; 8 | $settings = require __DIR__ . '/settings.php'; 9 | 10 | 11 | $host = 'server01.phalconhosting.com'; 12 | $port = '8083'; 13 | $username = $settings['username']; 14 | $password = $settings['password']; 15 | 16 | $client = new Client($host, $port, $username, $password); 17 | 18 | $result = $client->user->add('johndoe', 'testtest', 'test@phalconhosting.com', 'default', 'John', 'Doe'); 19 | 20 | if ($result) { 21 | echo 'User created successfully.'.PHP_EOL; 22 | } else { 23 | echo 'User could not be created.'.PHP_EOL; 24 | } -------------------------------------------------------------------------------- /samples/DeleteUser.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | use VestaCP\Client; 6 | 7 | require __DIR__ . '/../vendor/autoload.php'; 8 | $settings = require __DIR__ . '/settings.php'; 9 | 10 | 11 | $host = 'server01.phalconhosting.com'; 12 | $port = '8083'; 13 | $username = $settings['username']; 14 | $password = $settings['password']; 15 | 16 | $client = new Client($host, $port, $username, $password); 17 | 18 | $result = $client->user->delete('johndoe'); 19 | 20 | if ($result) { 21 | echo 'User deleted successfully.'.PHP_EOL; 22 | } else { 23 | echo 'User could not be deleted.'.PHP_EOL; 24 | } -------------------------------------------------------------------------------- /samples/settings.dist.php: -------------------------------------------------------------------------------- 1 | '', 'password' => ''); -------------------------------------------------------------------------------- /src/VestaCP/Client.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | 6 | namespace VestaCP; 7 | 8 | use VestaCP\Command\AddUserCommand; 9 | use VestaCP\Command\CommandInterface; 10 | use VestaCP\Command\Map\User; 11 | use VestaCP\HTTP\Client as httpClient; 12 | use VestaCP\Command\Exception as CommandException; 13 | 14 | class Client 15 | { 16 | 17 | const RESULT_OK = '0'; 18 | const RESULT_E_ARGS = '1'; 19 | const RESULT_E_INVALID = '2'; 20 | const RESULT_E_NOTEXIST = '3'; 21 | const RESULT_E_EXISTS = '4'; 22 | const RESULT_E_SUSPENDED = '5'; 23 | const RESULT_E_UNSUSPENDED = '6'; 24 | const RESULT_E_INUSE = '7'; 25 | const RESULT_E_LIMIT = '8'; 26 | const RESULT_E_PASSWORD = '9'; 27 | const RESULT_E_FORBIDDEN = '10'; 28 | const RESULT_E_DISABLED = '11'; 29 | const RESULT_E_PARSING = '12'; 30 | const RESULT_E_DISK = '13'; 31 | const RESULT_E_LA = '14'; 32 | const RESULT_E_CONNECT = '15'; 33 | const RESULT_E_FTP = '16'; 34 | const RESULT_E_DB = '17'; 35 | const RESULT_E_RRD = '18'; 36 | const RESULT_E_UPDATE = '19'; 37 | const RESULT_E_RESTART = '20'; 38 | 39 | /** 40 | * @var 41 | */ 42 | protected $hostIp; 43 | 44 | /** 45 | * @var int 46 | */ 47 | protected $hostPort; 48 | 49 | /** 50 | * @var string 51 | */ 52 | protected $adminUsername; 53 | 54 | /** 55 | * @var string 56 | */ 57 | protected $adminPassword; 58 | 59 | /** 60 | * @var httpClient 61 | */ 62 | protected $http; 63 | 64 | /** 65 | * Command maps below 66 | */ 67 | 68 | /** 69 | * User command map 70 | * 71 | * @var User 72 | */ 73 | public $user; 74 | 75 | /** 76 | * Create the client object 77 | * 78 | * @param string $hostIp 79 | * @param int $hostPort 80 | * @param string $adminUsername 81 | * @param string $adminPassword 82 | * 83 | * @throws Exception 84 | */ 85 | public function __construct($hostIp, $hostPort, $adminUsername, $adminPassword) 86 | { 87 | if (!extension_loaded('curl')) { 88 | throw new Exception('Curl module not found', ErrorCodes::ERROR_CURL_NOT_FOUND); 89 | } 90 | 91 | $hostPort = (int) $hostPort; 92 | $this->http = new httpClient(sprintf('https://%s:%d/api/', $hostIp, $hostPort)); 93 | 94 | $this->adminUsername = $adminUsername; 95 | $this->adminPassword = $adminPassword; 96 | 97 | // register command maps 98 | $this->user = new User($this); 99 | } 100 | 101 | /** 102 | * @param CommandInterface $command 103 | * @param array|string $args 104 | * 105 | * @throws CommandException 106 | * @throws Exception 107 | * @return mixed 108 | */ 109 | public function execute(CommandInterface $command, $args) 110 | { 111 | $return = false; 112 | 113 | if ($result = $command->run($args)) { 114 | 115 | $general = array( 116 | 'user' => $this->adminUsername, 117 | 'password'=> $this->adminPassword, 118 | 'returncode' => $command->getReturnCode(), 119 | 'cmd' => $command->getCommand() 120 | ); 121 | 122 | $argumentArray = array(); 123 | ; 124 | for($i=0; $i < count($args); $i++) { 125 | $argumentArray['arg'.($i+1)] = $args[$i]; 126 | } 127 | 128 | $postVars = array_merge($general, $argumentArray); 129 | $commandResult = $this->http->send($postVars); 130 | 131 | if ($commandResult == self::RESULT_E_PASSWORD) { 132 | throw new CommandException('Invalid password', self::RESULT_E_PASSWORD); 133 | } elseif ($commandResult == self::RESULT_E_DISK) { 134 | throw new CommandException('Not enough free diskspace to perform the request', self::RESULT_E_DISK); 135 | } elseif ($commandResult == self::RESULT_E_ARGS) { 136 | throw new CommandException('Incorrect usage; invalid or missing arguments',self::RESULT_E_ARGS); 137 | } elseif ($commandResult == self::RESULT_E_LIMIT) { 138 | throw new CommandException('Hosting package limits reached', self::RESULT_E_LIMIT); 139 | } elseif ($commandResult == self::RESULT_E_EXISTS) { 140 | throw new CommandException('Given object already exists', self::RESULT_E_EXISTS); 141 | } 142 | 143 | $result = $command->check($commandResult); 144 | 145 | if ($result == null) { 146 | throw new Exception('Command should either return true or false in the check() method', ErrorCodes::ERROR_INVALID_COMMAND); 147 | } 148 | 149 | // return true if the command executed successfully 150 | $return = ($result && $commandResult == self::RESULT_OK); 151 | } 152 | 153 | if ($result == null) { 154 | throw new Exception('Command should either return true or false in the run() method', ErrorCodes::ERROR_INVALID_COMMAND); 155 | } 156 | 157 | return $return; 158 | } 159 | 160 | } -------------------------------------------------------------------------------- /src/VestaCP/Command/AbstractCommand.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | 6 | namespace VestaCP\Command; 7 | 8 | use VestaCP\Client; 9 | 10 | /** 11 | * Class AbstractCommand 12 | * 13 | * @package VestaCP\Command\User 14 | */ 15 | abstract class AbstractCommand implements CommandInterface 16 | { 17 | 18 | protected $arguments = array(); 19 | 20 | /** 21 | * @var Client 22 | */ 23 | protected $client; 24 | 25 | /** 26 | * @param Client $client 27 | * 28 | * @return mixed|void 29 | */ 30 | public function setClient(Client $client) 31 | { 32 | $this->client = $client; 33 | } 34 | 35 | /** 36 | * @return Client 37 | */ 38 | public function getClient() 39 | { 40 | return $this->client; 41 | } 42 | 43 | /** 44 | * @return array 45 | */ 46 | public function getArguments() 47 | { 48 | return $this->arguments; 49 | } 50 | 51 | /** 52 | * @param array $arguments 53 | */ 54 | public function setArguments(array $arguments) 55 | { 56 | $this->arguments = $arguments; 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /src/VestaCP/Command/CommandInterface.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | 6 | namespace VestaCP\Command; 7 | 8 | use VestaCP\Client; 9 | 10 | /** 11 | * Interface MethodInterface 12 | * 13 | * @package VestaCP\Methods 14 | */ 15 | interface CommandInterface 16 | { 17 | 18 | /** 19 | * @param Client $client 20 | * 21 | * @return mixed 22 | */ 23 | public function setClient(Client $client); 24 | 25 | /** 26 | * @return Client 27 | */ 28 | public function getClient(); 29 | 30 | /** 31 | * @return string 32 | */ 33 | public function getCommand(); 34 | 35 | /** 36 | * @return string 37 | */ 38 | public function getReturnCode(); 39 | 40 | /** 41 | * Run should contain the running logic (check for errors etc) and should simply return true 42 | * in order to be executed properly. If the method returns false, the command is considered to be have failed. 43 | * 44 | * @param array $arguments 45 | * 46 | * @return mixed 47 | */ 48 | public function run(array $arguments); 49 | 50 | /** 51 | * 52 | * Method to run a check that executes after the command has returned a value 53 | * 54 | * @param string $returnCode 55 | * 56 | * @return mixed 57 | */ 58 | public function check($returnCode); 59 | 60 | /** 61 | * @param array $arguments 62 | * 63 | * @return mixed 64 | */ 65 | public function setArguments(array $arguments); 66 | } 67 | -------------------------------------------------------------------------------- /src/VestaCP/Command/Exception.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | 6 | namespace VestaCP\Command; 7 | 8 | /** 9 | * Class Exception 10 | * 11 | * @package VestaCP\Command 12 | */ 13 | class Exception extends \Exception 14 | { 15 | /** 16 | * @param string $message 17 | * @param int $code 18 | * @param Exception $previous 19 | */ 20 | public function __construct($message, $code, Exception $previous = null) { 21 | parent::__construct($message, $code, $previous); 22 | } 23 | } -------------------------------------------------------------------------------- /src/VestaCP/Command/Map/AbstractMap.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | 6 | namespace VestaCP\Command\Map; 7 | 8 | 9 | use VestaCP\Client; 10 | use VestaCP\Command\CommandInterface; 11 | 12 | /** 13 | * Class AbstractMap 14 | * 15 | * @package VestaCP\Command\Map 16 | */ 17 | abstract class AbstractMap 18 | { 19 | /** 20 | * @var Client 21 | */ 22 | protected $client; 23 | 24 | /** 25 | * @var CommandInterface 26 | */ 27 | protected $command; 28 | 29 | /** 30 | * @param Client $client 31 | */ 32 | public function __construct(Client $client) 33 | { 34 | $this->client = $client; 35 | } 36 | 37 | /** 38 | * @param CommandInterface $command 39 | */ 40 | public function setCommand(CommandInterface $command) 41 | { 42 | $this->command = $command; 43 | } 44 | 45 | /** 46 | * @param array $arguments 47 | * 48 | * @return mixed 49 | * @throws \VestaCP\Command\Exception 50 | * @throws \VestaCP\Exception 51 | */ 52 | public function executeCommand(array $arguments) 53 | { 54 | $this->command->setArguments($arguments); 55 | 56 | return $this->client->execute($this->command, $arguments); 57 | } 58 | } -------------------------------------------------------------------------------- /src/VestaCP/Command/Map/User.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | 6 | namespace VestaCP\Command\Map; 7 | 8 | use VestaCP\Command\User\AddUserCommand; 9 | use VestaCP\Command\User\DeleteUserCommand; 10 | 11 | class User extends AbstractMap 12 | { 13 | 14 | /** 15 | * @param string $userName 16 | * @param string $password 17 | * @param string $email 18 | * @param string $package 19 | * @param string $firstName 20 | * @param string $lastName 21 | * 22 | * @return mixed 23 | * @throws \VestaCP\Exception 24 | */ 25 | public function add($userName, $password, $email, $package = 'default', $firstName = '', $lastName = '') 26 | { 27 | $this->command = new AddUserCommand(); 28 | return $this->executeCommand(func_get_args()); 29 | } 30 | 31 | public function delete($userName) 32 | { 33 | $this->command = new DeleteUserCommand(); 34 | return $this->executeCommand(func_get_args()); 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /src/VestaCP/Command/User/AddUserCommand.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | 6 | namespace VestaCP\Command\User; 7 | 8 | use VestaCP\Command\AbstractCommand; 9 | use VestaCP\Command\Exception; 10 | use VestaCP\ErrorCodes; 11 | 12 | /** 13 | * Class AddUserCommand 14 | * 15 | * @package VestaCP\Command 16 | */ 17 | class AddUserCommand extends AbstractCommand 18 | { 19 | 20 | /** 21 | * @param array $arguments 22 | * 23 | * @return mixed|void 24 | * @throws Exception 25 | */ 26 | public function run(array $arguments) 27 | { 28 | if (!filter_var($arguments[2], FILTER_VALIDATE_EMAIL)) { 29 | throw new Exception('Invalid email given', ErrorCodes::ERROR_ADD_USER); 30 | } 31 | 32 | return true; 33 | } 34 | 35 | /** 36 | * @param string $returnCode 37 | * 38 | * @return bool 39 | */ 40 | public function check($returnCode) 41 | { 42 | return true; 43 | } 44 | 45 | /** 46 | * @return string 47 | */ 48 | public function getCommand() 49 | { 50 | return 'v-add-user'; 51 | } 52 | 53 | /** 54 | * @return string 55 | */ 56 | public function getReturnCode() 57 | { 58 | return 'yes'; 59 | } 60 | } -------------------------------------------------------------------------------- /src/VestaCP/Command/User/DeleteUserCommand.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | 6 | namespace VestaCP\Command\User; 7 | 8 | use VestaCP\Client; 9 | use VestaCP\Command\AbstractCommand; 10 | use VestaCP\Command\CommandInterface; 11 | use VestaCP\Command\Exception; 12 | use VestaCP\ErrorCodes; 13 | 14 | /** 15 | * Class DeleteUserCommand 16 | * 17 | * @package VestaCP\Command 18 | */ 19 | class DeleteUserCommand extends AbstractCommand 20 | { 21 | 22 | /** 23 | * @param array $arguments 24 | * 25 | * @return mixed|void 26 | * @throws Exception 27 | */ 28 | public function run(array $arguments) 29 | { 30 | return true; 31 | } 32 | 33 | /** 34 | * @param $returnCode 35 | * 36 | * @return bool|mixed 37 | * @throws Exception 38 | */ 39 | public function check($returnCode) 40 | { 41 | if ($returnCode == Client::RESULT_E_INUSE) { 42 | throw new Exception(sprintf('User \'%s\' is in use and cannot be deleted', $this->arguments[0]), Client::RESULT_E_INUSE); 43 | } elseif($returnCode == Client::RESULT_E_NOTEXIST) { 44 | throw new Exception(sprintf('User \'%s\' does not exist', $this->arguments[0]), Client::RESULT_E_NOTEXIST); 45 | } 46 | 47 | return true; 48 | } 49 | 50 | /** 51 | * @return string 52 | */ 53 | public function getCommand() 54 | { 55 | return 'v-delete-user'; 56 | } 57 | 58 | /** 59 | * @return string 60 | */ 61 | public function getReturnCode() 62 | { 63 | return 'yes'; 64 | } 65 | } -------------------------------------------------------------------------------- /src/VestaCP/ErrorCodes.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | 6 | namespace VestaCP; 7 | 8 | /** 9 | * Class ErrorCodes 10 | * 11 | * @package VestaCP 12 | */ 13 | class ErrorCodes 14 | { 15 | const ERROR_CANNOT_CONNECT_TO_HOST = 1000; 16 | const ERROR_CURL_NOT_FOUND = 1001; 17 | const ERROR_INVALID_HOST = 1002; 18 | const ERROR_INVALID_COMMAND = 1003; 19 | const ERROR_ADD_USER = 1004; 20 | const ERROR_HOST = 1005; 21 | const ERROR_LIMITS_REACHED = 1006; 22 | } -------------------------------------------------------------------------------- /src/VestaCP/Exception.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | 6 | namespace VestaCP; 7 | 8 | 9 | class Exception extends \Exception 10 | { 11 | /** 12 | * @param string $message 13 | * @param int $code 14 | * @param Exception $previous 15 | */ 16 | public function __construct($message, $code, Exception $previous = null) { 17 | parent::__construct($message, $code, $previous); 18 | } 19 | } -------------------------------------------------------------------------------- /src/VestaCP/HTTP/Client.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | 6 | namespace VestaCP\HTTP; 7 | 8 | 9 | use VestaCP\ErrorCodes; 10 | 11 | class Client 12 | { 13 | 14 | /** 15 | * @var string 16 | */ 17 | protected $host; 18 | 19 | public function __construct($host) 20 | { 21 | $this->host = $host; 22 | 23 | // test the connection to the host 24 | if ($this->send() === false) { 25 | throw new Exception(sprintf('Cannot connect to host %s', $host), ErrorCodes::ERROR_CANNOT_CONNECT_TO_HOST); 26 | } 27 | } 28 | 29 | public function send(array $postVars = array()) 30 | { 31 | $curl = curl_init(); 32 | curl_setopt($curl, CURLOPT_URL, $this->host); 33 | curl_setopt($curl, CURLOPT_RETURNTRANSFER,true); 34 | curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); 35 | curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); 36 | curl_setopt($curl, CURLOPT_POST, true); 37 | curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postVars)); 38 | 39 | return curl_exec($curl); 40 | } 41 | } -------------------------------------------------------------------------------- /src/VestaCP/HTTP/Exception.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | 6 | namespace VestaCP\HTTP; 7 | 8 | 9 | class Exception extends \Exception 10 | { 11 | /** 12 | * @param string $message 13 | * @param int $code 14 | * @param Exception $previous 15 | */ 16 | public function __construct($message, $code = 0, Exception $previous = null) { 17 | parent::__construct($message, $code, $previous); 18 | } 19 | } --------------------------------------------------------------------------------