diff --git a/README.md b/README.md index 294b864..199b0f2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,32 @@ -# whmcs-sdk -A simple PHP wrapper for WHMCS's API +# WHMCS SDK + +A simple wrapper around the WHMCS SDK. + +## Installation +This package is installed using Composer. You can use the following command to add it to a project. + +```bash +composer require hansadema/whmcs-sdk +composer update +``` + +## Usage +Create an API client: +```php +$api = new \HansAdema\WhmcsSdk\Client('https://example.com/whmcs/installation/url/', 'myusername', 'mypassword'); +``` + +Send an API request: +```php +try { + $result = $api->acceptOrder([ + 'orderid' => 123, + 'serverid' => 456, + //... + ]); +} catch (\HansAdema\WhmcsSdk\RequestException $e) { + echo "Error connecting to WHMCS: ".$e->getMessage(); +} catch (\HansAdema\WhmcsSdk\ResponseException $e) { + echo "There was an issue with your API call: ".$e->getMessage(); +} +``` \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..13a4c6e --- /dev/null +++ b/composer.json @@ -0,0 +1,20 @@ +{ + "name": "HansAdema/whmcs-sdk", + "description": "Simple OOP wrapper for the WHMCS API", + "minimum-stability": "stable", + "license": "MIT", + "authors": [ + { + "name": "Hans Adema", + "email": "hans@hansadema.nl" + } + ], + "autoload": { + "psr-4": { + "HansAdema\\WhmcsSdk\\" : "src/" + } + }, + "require": { + "guzzlehttp/guzzle": "~6.0" + } +} \ No newline at end of file diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..b0d022d --- /dev/null +++ b/composer.lock @@ -0,0 +1,247 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "a81678988b56f13b0ec5723f1f837880", + "content-hash": "572b9d5c4a904df644d09ebd125605c4", + "packages": [ + { + "name": "guzzlehttp/guzzle", + "version": "6.2.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/8d6c6cc55186db87b7dc5009827429ba4e9dc006", + "reference": "8d6c6cc55186db87b7dc5009827429ba4e9dc006", + "shasum": "" + }, + "require": { + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.4", + "php": ">=5.5" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.0", + "psr/log": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.2-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2017-02-28 22:50:30" + }, + { + "name": "guzzlehttp/promises", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2016-12-20 10:07:11" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "0d6c7ca039329247e4f0f8f8f6506810e8248855" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/0d6c7ca039329247e4f0f8f8f6506810e8248855", + "reference": "0d6c7ca039329247e4f0f8f8f6506810e8248855", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "request", + "response", + "stream", + "uri", + "url" + ], + "time": "2017-02-27 10:51:17" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06 14:39:51" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/src/Client.php b/src/Client.php new file mode 100644 index 0000000..0e27c80 --- /dev/null +++ b/src/Client.php @@ -0,0 +1,93 @@ +url = $url; + $this->username = $username; + $this->password = md5($password); + + $this->http = new Guzzle(['base_uri' => $url . 'includes/api.php']); + } + + /** + * Send a request to WHMCS + * + * @param string $action The API action name + * @param array $params The action parameters + * @return array The API response data + * @throws Exception + */ + public function sendRequest($action, $params = []) + { + try { + $response = $this->http->post('', [ + 'form_params' => array_merge($params, [ + 'username' => $this->username, + 'password' => $this->password, + 'action' => $action, + 'responsetype' => 'json', + ]), + ]); + } catch (ClientException $e) { + throw new RequestException($e->getResponse()); + } + + $data = json_decode($response->getBody(), true); + + if (isset($data['result']) && $data['result'] === 'success') { + return $data; + } else { + throw new ResponseException($response); + } + } + + /** + * Magic method to automagically build a sendRequest + * + * @param string $name + * @param array $arguments + * @return array + */ + public function __call($name, $arguments) + { + $params = isset($arguments[0]) && is_array($arguments[0]) ? $arguments[0] : []; + + return $this->sendRequest(ucfirst($name), $params); + } +} \ No newline at end of file diff --git a/src/Exceptions/Exception.php b/src/Exceptions/Exception.php new file mode 100644 index 0000000..a23b541 --- /dev/null +++ b/src/Exceptions/Exception.php @@ -0,0 +1,35 @@ +getBody(), true); + + parent::__construct($data['message'], $response->getStatusCode()); + + $this->response = $response; + } + + /** + * @return ResponseInterface + */ + public function getResponse() + { + return $this->response; + } +} \ No newline at end of file diff --git a/src/Exceptions/RequestException.php b/src/Exceptions/RequestException.php new file mode 100644 index 0000000..9f5dc82 --- /dev/null +++ b/src/Exceptions/RequestException.php @@ -0,0 +1,15 @@ +