From 97691be7ad9a048ee0cb7896311808faccdbadce Mon Sep 17 00:00:00 2001 From: Kevin Krummnacker Date: Fri, 7 Jan 2022 23:54:38 +0100 Subject: [PATCH 1/8] feat: boilerplate --- config/whmcs.php | 53 ++++++++--------- src/Adapter/ConnectorInterface.php | 11 ---- src/Adapter/GuzzleHttpAdapter.php | 95 ------------------------------ src/Auth/AuthenticatorFactory.php | 14 +++++ src/Facades/Whmcs.php | 2 + src/WhmcsFactory.php | 10 ++++ src/WhmcsManager.php | 85 ++------------------------ src/WhmcsServiceProvider.php | 1 - 8 files changed, 53 insertions(+), 218 deletions(-) delete mode 100644 src/Adapter/ConnectorInterface.php delete mode 100644 src/Adapter/GuzzleHttpAdapter.php create mode 100644 src/Auth/AuthenticatorFactory.php create mode 100644 src/WhmcsFactory.php diff --git a/config/whmcs.php b/config/whmcs.php index 1c2fe4a..3cb03cc 100644 --- a/config/whmcs.php +++ b/config/whmcs.php @@ -4,47 +4,40 @@ /* |-------------------------------------------------------------------------- - | HTTP Driver + | Default Connection |-------------------------------------------------------------------------- | - | Supported: "guzzlehttp" - */ - - 'driver' => 'guzzlehttp', - - /* - |-------------------------------------------------------------------------- - | API Credentials - |-------------------------------------------------------------------------- - | - | Enter the unhashed variant of your password if you use 'password' as 'auth_type' - | - | Supported auth types': "api", "password" + | Define your default whmcs connection | */ - 'auth_type' => env('WHMCS_AUTH_TYPE', 'password'), - - 'apiurl' => env('WHMCS_API_URL', 'https://url.to.whmcs.tld/whmcs/includes/api.php'), - - 'api' => [ - 'identifier' => env('WHMCS_API_IDENTIFIER', 'YOUR_API_IDENTIFIER'), - 'secret' => env('WHMCS_API_SECRET', 'YOUR_API_SECRET'), - ], - - 'password' => [ - 'username' => env('WHMCS_USERNAME', 'YOUR_USERNAME'), - 'password' => env('WHMCS_PASSWORD', 'YOUR_PASSWORD'), - ], + 'default' => 'primary', /* |-------------------------------------------------------------------------- - | ResponseType + | WHMCS Connections |-------------------------------------------------------------------------- | - | Supported auth types': "json", "xml" + | Define your whmcs connections here. + | + | Methods: "password", "token" | */ - 'responsetype' => env('WHMCS_RESPONSE_TYPE', 'json'), + 'connections' => [ + + 'main' => [ + 'method' => env('WHMCS_AUTH_TYPE', 'password'), + 'url' => env('WHMCS_API_URL', 'https://url.to.whmcs.tld/whmcs'), + 'username' => env('WHMCS_USERNAME', 'YOUR_USERNAME'), + 'password' => env('WHMCS_PASSWORD', 'YOUR_PASSWORD'), + ], + + 'secondary' => [ + 'method' => env('WHMCS_AUTH_TYPE', 'token'), + 'url' => env('WHMCS_API_URL', 'https://url.to.whmcs.tld/whmcs'), + 'identifier' => env('WHMCS_API_IDENTIFIER', 'YOUR_API_IDENTIFIER'), + 'secret' => env('WHMCS_API_SECRET', 'YOUR_API_SECRET'), + ] + ] ]; diff --git a/src/Adapter/ConnectorInterface.php b/src/Adapter/ConnectorInterface.php deleted file mode 100644 index 02f0aaa..0000000 --- a/src/Adapter/ConnectorInterface.php +++ /dev/null @@ -1,11 +0,0 @@ -config = $this->getConfig($config); - - return $this->getAdapter(); - } - - /** - * @param $config - * @return array|null - * @throws \InvalidArgumentException - */ - private function getConfig($config) - { - if ('api' === $config['auth_type']) { - $credentials = Arr::get($config, $config['auth_type']); - - if (! array_key_exists('identifier', $credentials) || empty($credentials['identifier'])) { - throw new InvalidArgumentException('The guzzlehttp connector requires configuration.'); - } - - if (! array_key_exists('secret', $credentials) || empty($credentials['secret'])) { - throw new InvalidArgumentException('The guzzlehttp connector requires configuration.'); - } - - return $config; - } - - if ('password' === $config['auth_type']) { - $credentials = Arr::get($config, $config['auth_type']); - - if (! array_key_exists('username', $credentials) || empty($credentials['username'])) { - throw new InvalidArgumentException('The guzzlehttp connector requires configuration.'); - } - - if (! array_key_exists('password', $credentials) || empty($credentials['password'])) { - throw new InvalidArgumentException('The guzzlehttp connector requires configuration.'); - } - - $credentials['password'] = md5($credentials['password']); - Arr::set($config, $config['auth_type'], $credentials); - - return $config; - } - - throw new InvalidArgumentException('Unsupported whmcs auth type'); - } - - /** - * @return Client - */ - private function getAdapter() - { - return new Client([ - 'timeout' => 30, - 'form_params' => array_merge( - Arr::get($this->config, $this->config['auth_type']), - [ - 'responsetype' => Arr::get($this->config, 'responsetype', 'json'), - ] - ), - 'headers' => [ - 'User-Agent' => 'Laravel WHMCS API Interface', - ], - ]); - } -} diff --git a/src/Auth/AuthenticatorFactory.php b/src/Auth/AuthenticatorFactory.php new file mode 100644 index 0000000..4cd9e31 --- /dev/null +++ b/src/Auth/AuthenticatorFactory.php @@ -0,0 +1,14 @@ +config = $config; - $this->client = $client; - } - - /** - * @return ConnectorInterface - */ - public function connection() - { - return $this->client->connect($this->getConfig()); - } - - /** - * @param $method - * @param $parameters - * @return mixed - */ - protected function execute(string $method, $parameters = []) + public function make(string $method) { - $parameters['action'] = $method; - try { - $url = $this->getConfig()['apiurl'].'/api.php'; - $response = $this->connection()->post($url, [ - 'form_params' => array_merge($parameters, $this->connection()->getConfig()['form_params']), - ]); - - if ($this->getConfig()['responsetype'] === 'xml') { - return simplexml_load_string($response->getBody()->getContents()); - } - - return json_decode($response->getBody()->getContents(), true); - } catch (ClientException $ex) { - $response = json_decode($ex->getResponse()->getBody()->getContents(), true); - - return $response; - } - } - - /** - * Get the config array. - * - * @return array - */ - public function getConfig() - { - return $this->config->get('whmcs'); - } - - /** - * Dynamically pass methods to the default connection. - * - * @param string $method - * @param array $parameters - * @return mixed - */ - public function __call(string $method, $parameters) - { - return $this->execute($method, ...$parameters); + throw new \InvalidArgumentException("Unsupported authentication method [$method]."); } } diff --git a/src/WhmcsServiceProvider.php b/src/WhmcsServiceProvider.php index 5abc702..8d85517 100644 --- a/src/WhmcsServiceProvider.php +++ b/src/WhmcsServiceProvider.php @@ -4,7 +4,6 @@ namespace DarthSoup\Whmcs; -use DarthSoup\Whmcs\Adapter\GuzzleHttpAdapter; use Illuminate\Container\Container; use Illuminate\Foundation\Application as LaravelApplication; use Illuminate\Support\ServiceProvider; From 26fcd89a8cee6e908323357805395a6672112c4a Mon Sep 17 00:00:00 2001 From: Kevin Krummnacker Date: Thu, 20 Jan 2022 01:15:20 +0100 Subject: [PATCH 2/8] wip --- config/whmcs.php | 5 +- src/Auth/AbstractAuth.php | 19 ++++ src/Auth/AuthFactory.php | 22 +++++ src/Auth/AuthInterface.php | 14 +++ src/Auth/AuthenticatorFactory.php | 14 --- src/Auth/Method/PasswordAuth.php | 34 ++++++++ src/Auth/Method/TokenAuth.php | 34 ++++++++ src/WhmcsFactory.php | 45 ++++++++++ src/WhmcsManager.php | 139 +++++++++++++++++++++++++++++- 9 files changed, 309 insertions(+), 17 deletions(-) create mode 100644 src/Auth/AbstractAuth.php create mode 100644 src/Auth/AuthFactory.php create mode 100644 src/Auth/AuthInterface.php delete mode 100644 src/Auth/AuthenticatorFactory.php create mode 100644 src/Auth/Method/PasswordAuth.php create mode 100644 src/Auth/Method/TokenAuth.php diff --git a/config/whmcs.php b/config/whmcs.php index 3cb03cc..bd7c147 100644 --- a/config/whmcs.php +++ b/config/whmcs.php @@ -1,5 +1,7 @@ [ - 'main' => [ + 'primary' => [ 'method' => env('WHMCS_AUTH_TYPE', 'password'), 'url' => env('WHMCS_API_URL', 'https://url.to.whmcs.tld/whmcs'), 'username' => env('WHMCS_USERNAME', 'YOUR_USERNAME'), diff --git a/src/Auth/AbstractAuth.php b/src/Auth/AbstractAuth.php new file mode 100644 index 0000000..f8624a6 --- /dev/null +++ b/src/Auth/AbstractAuth.php @@ -0,0 +1,19 @@ +client = $client; + + return $this; + } +} diff --git a/src/Auth/AuthFactory.php b/src/Auth/AuthFactory.php new file mode 100644 index 0000000..33a3d50 --- /dev/null +++ b/src/Auth/AuthFactory.php @@ -0,0 +1,22 @@ +client) { + throw new InvalidArgumentException('The client instance was not given to the auth process.'); + } + + if (!array_key_exists('username', $config)) { + throw new InvalidArgumentException('The token authenticator requires a username.'); + } + if (!array_key_exists('password', $config)) { + throw new InvalidArgumentException('The token authenticator requires a password.'); + } + + $this->client->authenticate( + $config['username'], + $config['password'], + Client::AUTH_LOGIN_CREDENTIALS + ); + + return $this->client; + } +} diff --git a/src/Auth/Method/TokenAuth.php b/src/Auth/Method/TokenAuth.php new file mode 100644 index 0000000..441414f --- /dev/null +++ b/src/Auth/Method/TokenAuth.php @@ -0,0 +1,34 @@ +client) { + throw new InvalidArgumentException('The client instance was not given to the auth process.'); + } + + if (!array_key_exists('identifier', $config)) { + throw new InvalidArgumentException('The token authenticator requires a identifier.'); + } + if (!array_key_exists('secret', $config)) { + throw new InvalidArgumentException('The token authenticator requires a secret.'); + } + + $this->client->authenticate( + $config['identifer'], + $config['secret'], + Client::AUTH_API_CREDENTIALS + ); + + return $this->client; + } +} diff --git a/src/WhmcsFactory.php b/src/WhmcsFactory.php index 72fdf61..b3c9543 100644 --- a/src/WhmcsFactory.php +++ b/src/WhmcsFactory.php @@ -4,7 +4,52 @@ namespace DarthSoup\Whmcs; +use DarthSoup\Whmcs\Auth\AuthFactory; +use DarthSoup\WhmcsApi\Client; +use DarthSoup\WhmcsApi\HttpClient\Builder; +use Http\Client\Common\Plugin\RetryPlugin; +use Illuminate\Support\Arr; +use InvalidArgumentException; + class WhmcsFactory { + protected AuthFactory $auth; + + public function __construct(AuthFactory $auth) + { + $this->auth = $auth; + } + + public function make(array $config): Client + { + $client = new Client($this->getBuilder($config)); + + if (!array_key_exists('method', $config)) { + throw new InvalidArgumentException('The whmcs factory requires an auth method.'); + } + + if ($url = Arr::get($config, 'url')) { + $client->url($url); + } + + if ($config['method'] === 'none') { + return $client; + } + + return $this->auth->make($config['method'])->with($client)->authenticate($config); + } + + protected function getBuilder(array $config): Builder + { + $builder = new Builder(); + + if ($backoff = Arr::get($config, 'backoff')) { + $builder->addPlugin( + new RetryPlugin(['retries' => $backoff === true ? 2 : $backoff]) + ); + } + + return $builder; + } } diff --git a/src/WhmcsManager.php b/src/WhmcsManager.php index 2ed2c84..6d27108 100644 --- a/src/WhmcsManager.php +++ b/src/WhmcsManager.php @@ -4,11 +4,146 @@ namespace DarthSoup\Whmcs; +use Closure; +use DarthSoup\WhmcsApi\Client; +use Illuminate\Contracts\Config\Repository; +use InvalidArgumentException; + class WhmcsManager { - public function make(string $method) + protected WhmcsFactory $factory; + + protected Repository $config; + + /** + * @var array + */ + protected $connections = []; + + /** + * @var array + */ + protected $extensions = []; + + public function __construct(Repository $config, WhmcsFactory $factory) + { + $this->config = $config; + $this->factory = $factory; + } + + protected function createConnection(array $config): Client { + return $this->factory->make($config); + } + + public function getFactory(): WhmcsFactory + { + return $this->factory; + } - throw new \InvalidArgumentException("Unsupported authentication method [$method]."); + public function connection(string $name = null) + { + $name = $name ?: $this->getDefaultConnection(); + + if (!isset($this->connections[$name])) { + $this->connections[$name] = $this->makeConnection($name); + } + + return $this->connections[$name]; + } + + public function reconnect(string $name = null) + { + $name = $name ?: $this->getDefaultConnection(); + + $this->disconnect($name); + + return $this->connection($name); + } + + public function disconnect(string $name = null): void + { + $name = $name ?: $this->getDefaultConnection(); + + unset($this->connections[$name]); + } + + protected function makeConnection(string $name): Client + { + $config = $this->getConnectionConfig($name); + + if (isset($this->extensions[$name])) { + return $this->extensions[$name]($config); + } + + if ($driver = Arr::get($config, 'driver')) { + if (isset($this->extensions[$driver])) { + return $this->extensions[$driver]($config); + } + } + + return $this->createConnection($config); + } + + public function getConnectionConfig(string $name = null): array + { + $name = $name ?: $this->getDefaultConnection(); + + return $this->getNamedConfig('connections', 'Connection', $name); + } + + protected function getNamedConfig(string $type, string $desc, string $name): array + { + $data = $this->config->get($this->getConfigName().'.'.$type); + + if (!is_array($config = Arr::get($data, $name)) && !$config) { + throw new InvalidArgumentException("$desc [$name] not configured."); + } + + $config['name'] = $name; + + return $config; + } + + public function getDefaultConnection(): string + { + return $this->config->get($this->getConfigName().'.default'); + } + + public function setDefaultConnection(string $name): void + { + $this->config->set($this->getConfigName().'.default', $name); + } + + public function extend(string $name, callable $resolver): void + { + if ($resolver instanceof Closure) { + $this->extensions[$name] = $resolver->bindTo($this, $this); + } else { + $this->extensions[$name] = $resolver; + } + } + + /** + * @return array + */ + public function getConnections(): array + { + return $this->connections; + } + + public function getConfig(): Repository + { + return $this->config; + } + + protected function getConfigName(): string + { + return 'whmcs'; + } + + public function __call(string $method, array $parameters) + { + return $this->connection()->$method(...$parameters); } } From 3b127bc0d26f91b8a5553ea914e26f54505629c6 Mon Sep 17 00:00:00 2001 From: Kevin Krummnacker Date: Thu, 20 Jan 2022 01:28:54 +0100 Subject: [PATCH 3/8] feat: set serviceprovider --- src/WhmcsServiceProvider.php | 43 +++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/src/WhmcsServiceProvider.php b/src/WhmcsServiceProvider.php index 8d85517..d449d72 100644 --- a/src/WhmcsServiceProvider.php +++ b/src/WhmcsServiceProvider.php @@ -4,6 +4,8 @@ namespace DarthSoup\Whmcs; +use DarthSoup\Whmcs\Auth\AuthFactory; +use DarthSoup\Whmcs\Facades\Whmcs; use Illuminate\Container\Container; use Illuminate\Foundation\Application as LaravelApplication; use Illuminate\Support\ServiceProvider; @@ -36,33 +38,47 @@ public function boot() */ public function register() { - $this->registerClient(); - + $this->registerAuthFactory(); + $this->registerWhmcsFactroy(); $this->registerManager(); } /** - * Register HttpClient. + * Register the auth factory class. */ - public function registerClient() + protected function registerAuthFactory(): void { - $this->app->singleton('whmcs.client', function () { - return new GuzzleHttpAdapter(); + $this->app->singleton('whmcs.authfactory', function () { + return new AuthFactory(); + }); + + $this->app->alias('whmcs.authfactory', AuthFactory::class); + } + + /** + * Register the whmcs factory class. + */ + public function registerWhmcsFactroy(): void + { + $this->app->singleton('whmcs.factory', function (Container $app) { + $auth = $app['whmcs.authfactory']; + + return new WhmcsFactory($auth); }); - $this->app->alias('whmcs.client', GuzzleHttpAdapter::class); + $this->app->alias('whmcs.factory', WhmcsFactory::class); } /** - * Register Manager. + * Register the whmcs factory class. */ - public function registerManager() + public function registerManager(): void { $this->app->singleton('whmcs', function (Container $app) { $config = $app['config']; - $client = $app['whmcs.client']; + $factory = $app['whmcs.factory']; - return new WhmcsManager($config, $client); + return new WhmcsManager($config, $factory); }); $this->app->alias('whmcs', WhmcsManager::class); @@ -71,10 +87,11 @@ public function registerManager() /** * @return array */ - public function provides() + public function provides(): array { return [ - 'whmcs.client', + 'whmcs.authfactory', + 'whmcs.factory', 'whmcs', ]; } From 6cd453374a956537e878065f4ad940d403d70c51 Mon Sep 17 00:00:00 2001 From: Kevin Krummnacker Date: Thu, 20 Jan 2022 01:45:29 +0100 Subject: [PATCH 4/8] fix: abstract auth class and wrong parameter in tokenauth --- src/Auth/AbstractAuth.php | 2 +- src/Auth/Method/TokenAuth.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Auth/AbstractAuth.php b/src/Auth/AbstractAuth.php index f8624a6..6c9da00 100644 --- a/src/Auth/AbstractAuth.php +++ b/src/Auth/AbstractAuth.php @@ -6,7 +6,7 @@ use DarthSoup\WhmcsApi\Client; -class AbstractAuth implements AuthInterface +abstract class AbstractAuth implements AuthInterface { protected Client $client; diff --git a/src/Auth/Method/TokenAuth.php b/src/Auth/Method/TokenAuth.php index 441414f..c62de65 100644 --- a/src/Auth/Method/TokenAuth.php +++ b/src/Auth/Method/TokenAuth.php @@ -24,7 +24,7 @@ public function authenticate(array $config): Client } $this->client->authenticate( - $config['identifer'], + $config['identifier'], $config['secret'], Client::AUTH_API_CREDENTIALS ); From 2de1216f741a15e29759c64d4f32a5b5beef0b0f Mon Sep 17 00:00:00 2001 From: Kevin Krummnacker Date: Thu, 20 Jan 2022 01:54:14 +0100 Subject: [PATCH 5/8] feat: replace connection methods with AbstractManager from GrahamCampbell --- composer.json | 3 +- src/WhmcsManager.php | 131 ++++++------------------------------------- 2 files changed, 18 insertions(+), 116 deletions(-) diff --git a/composer.json b/composer.json index efd60a5..ecf74e1 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,8 @@ "illuminate/support": "~7.0|~8.0", "illuminate/session": "~7.0|~8.0", "illuminate/events": "~7.0|~8.0", - "darthsoup/php-whmcs-api": "~1.0" + "darthsoup/php-whmcs-api": "~1.0", + "graham-campbell/manager": "^4.6" }, "require-dev": { "guzzlehttp/guzzle": "^7.0", diff --git a/src/WhmcsManager.php b/src/WhmcsManager.php index 6d27108..1425d30 100644 --- a/src/WhmcsManager.php +++ b/src/WhmcsManager.php @@ -6,28 +6,30 @@ use Closure; use DarthSoup\WhmcsApi\Client; +use GrahamCampbell\Manager\AbstractManager; use Illuminate\Contracts\Config\Repository; +use Illuminate\Support\Arr; use InvalidArgumentException; -class WhmcsManager +/** + * @method array getConnections() + * @method \DarthSoup\WhmcsApi\Api\Authentication authentication() + * @method \DarthSoup\WhmcsApi\Api\Billing billing() + * @method \DarthSoup\WhmcsApi\Api\Client client() + * @method \DarthSoup\WhmcsApi\Api\Custom custom() + * @method \DarthSoup\WhmcsApi\Api\Domains domains() + * @method \DarthSoup\WhmcsApi\Api\Orders orders() + * @method \DarthSoup\WhmcsApi\Api\Servers servers() + * @method \DarthSoup\WhmcsApi\Api\System system() + * @method \DarthSoup\WhmcsApi\Api\Users users() + */ +class WhmcsManager extends AbstractManager { protected WhmcsFactory $factory; - protected Repository $config; - - /** - * @var array - */ - protected $connections = []; - - /** - * @var array - */ - protected $extensions = []; - public function __construct(Repository $config, WhmcsFactory $factory) { - $this->config = $config; + parent::__construct($config); $this->factory = $factory; } @@ -41,109 +43,8 @@ public function getFactory(): WhmcsFactory return $this->factory; } - public function connection(string $name = null) - { - $name = $name ?: $this->getDefaultConnection(); - - if (!isset($this->connections[$name])) { - $this->connections[$name] = $this->makeConnection($name); - } - - return $this->connections[$name]; - } - - public function reconnect(string $name = null) - { - $name = $name ?: $this->getDefaultConnection(); - - $this->disconnect($name); - - return $this->connection($name); - } - - public function disconnect(string $name = null): void - { - $name = $name ?: $this->getDefaultConnection(); - - unset($this->connections[$name]); - } - - protected function makeConnection(string $name): Client - { - $config = $this->getConnectionConfig($name); - - if (isset($this->extensions[$name])) { - return $this->extensions[$name]($config); - } - - if ($driver = Arr::get($config, 'driver')) { - if (isset($this->extensions[$driver])) { - return $this->extensions[$driver]($config); - } - } - - return $this->createConnection($config); - } - - public function getConnectionConfig(string $name = null): array - { - $name = $name ?: $this->getDefaultConnection(); - - return $this->getNamedConfig('connections', 'Connection', $name); - } - - protected function getNamedConfig(string $type, string $desc, string $name): array - { - $data = $this->config->get($this->getConfigName().'.'.$type); - - if (!is_array($config = Arr::get($data, $name)) && !$config) { - throw new InvalidArgumentException("$desc [$name] not configured."); - } - - $config['name'] = $name; - - return $config; - } - - public function getDefaultConnection(): string - { - return $this->config->get($this->getConfigName().'.default'); - } - - public function setDefaultConnection(string $name): void - { - $this->config->set($this->getConfigName().'.default', $name); - } - - public function extend(string $name, callable $resolver): void - { - if ($resolver instanceof Closure) { - $this->extensions[$name] = $resolver->bindTo($this, $this); - } else { - $this->extensions[$name] = $resolver; - } - } - - /** - * @return array - */ - public function getConnections(): array - { - return $this->connections; - } - - public function getConfig(): Repository - { - return $this->config; - } - protected function getConfigName(): string { return 'whmcs'; } - - public function __call(string $method, array $parameters) - { - return $this->connection()->$method(...$parameters); - } } From d7d8c6d849509d9f3ac74176b3a1743f463093cd Mon Sep 17 00:00:00 2001 From: Kevin Krummnacker Date: Thu, 20 Jan 2022 02:52:34 +0100 Subject: [PATCH 6/8] chore: code cleanup --- src/Auth/AbstractAuth.php | 2 +- src/WhmcsFactory.php | 1 - src/WhmcsManager.php | 5 +---- src/WhmcsServiceProvider.php | 1 - 4 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Auth/AbstractAuth.php b/src/Auth/AbstractAuth.php index 6c9da00..0cc246f 100644 --- a/src/Auth/AbstractAuth.php +++ b/src/Auth/AbstractAuth.php @@ -8,7 +8,7 @@ abstract class AbstractAuth implements AuthInterface { - protected Client $client; + protected ?Client $client; public function with(Client $client): AuthInterface { diff --git a/src/WhmcsFactory.php b/src/WhmcsFactory.php index b3c9543..ab56e58 100644 --- a/src/WhmcsFactory.php +++ b/src/WhmcsFactory.php @@ -51,5 +51,4 @@ protected function getBuilder(array $config): Builder return $builder; } - } diff --git a/src/WhmcsManager.php b/src/WhmcsManager.php index 1425d30..6d095ab 100644 --- a/src/WhmcsManager.php +++ b/src/WhmcsManager.php @@ -4,15 +4,12 @@ namespace DarthSoup\Whmcs; -use Closure; use DarthSoup\WhmcsApi\Client; use GrahamCampbell\Manager\AbstractManager; use Illuminate\Contracts\Config\Repository; -use Illuminate\Support\Arr; -use InvalidArgumentException; /** - * @method array getConnections() + * @method array getConnections() * @method \DarthSoup\WhmcsApi\Api\Authentication authentication() * @method \DarthSoup\WhmcsApi\Api\Billing billing() * @method \DarthSoup\WhmcsApi\Api\Client client() diff --git a/src/WhmcsServiceProvider.php b/src/WhmcsServiceProvider.php index d449d72..ee16d06 100644 --- a/src/WhmcsServiceProvider.php +++ b/src/WhmcsServiceProvider.php @@ -5,7 +5,6 @@ namespace DarthSoup\Whmcs; use DarthSoup\Whmcs\Auth\AuthFactory; -use DarthSoup\Whmcs\Facades\Whmcs; use Illuminate\Container\Container; use Illuminate\Foundation\Application as LaravelApplication; use Illuminate\Support\ServiceProvider; From cdf5adff4667e39890ca3ff38bde4c5dc6d06321 Mon Sep 17 00:00:00 2001 From: Kevin Krummnacker Date: Thu, 20 Jan 2022 02:52:53 +0100 Subject: [PATCH 7/8] fix: test workflow php version --- .github/workflows/tests.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ddff2d0..1bfda9a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,6 +1,8 @@ name: tests -on: [push, pull_request] +on: + push: + pull_request: jobs: @@ -10,12 +12,11 @@ jobs: strategy: matrix: operating-system: - - 'ubuntu-latest' + - 'ubuntu-20.04' php-version: - - '7.2' - - '7.3' - '7.4' - '8.0' + - '8.1' runs-on: ${{ matrix.operating-system }} From e23e0646b0f1c5d43ab214aa2011aba43367ece9 Mon Sep 17 00:00:00 2001 From: Kevin Krummnacker Date: Thu, 20 Jan 2022 03:27:30 +0100 Subject: [PATCH 8/8] docs: changed readme --- README.md | 73 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 010a64b..61d70b7 100644 --- a/README.md +++ b/README.md @@ -6,23 +6,26 @@ Laravel WHMCS [![License](https://poser.pugx.org/darthsoup/laravel-whmcs/license)](https://packagist.org/packages/darthsoup/laravel-whmcs) An interface for interaction with the WHMCS API in Laravel. +This Package is heavily inspired by [Laravel GitLab](https://github.com/GrahamCampbell/Laravel-GitLab) created by [Graham Campbell](https://github.com/GrahamCampbell/). > **Notice:** > -> The working legacy branch can be found [here](https://github.com/darthsoup/laravel-whmcs/tree/legacy) +> The legacy version 0.3 can be found [here](https://github.com/darthsoup/laravel-whmcs/tree/legacy) ## Installation +Laravel WHMCS requires PHP ^7.4 | ^8.0 with at least Laravel version 6. + Install the package through [Composer](http://getcomposer.org/). Run the Composer require command from the Terminal: ```bash composer require darthsoup/laravel-whmcs ``` -Package will be installed automaticlly through composer package discovery. If not, then you need to register -the `DarthSoup\Whmcs\WhmcsService` service provider in your config/app.php. +Package will be installed automatically through composer package discovery. If not, then you need to register +the `DarthSoup\Whmcs\WhmcsService` service provider in your `config/app.php`. -Optionally, you can add the alias if you prefer to use the Facade +Optionally, you can add the alias if you prefer to use the Facade: ```php 'Whmcs' => DarthSoup\Whmcs\Facades\Whmcs::class @@ -30,47 +33,36 @@ Optionally, you can add the alias if you prefer to use the Facade ## Configuration -To get started, you'll need to publish all vendor assets. +To get started, you'll need to publish vendor assets for Laravel-Whmcs. ```bash php artisan vendor:publish --provider=DarthSoup\Whmcs\WhmcsServiceProvider ``` -Then open `config\whmcs.php` to fill your WHMCS api credentials in - -Now you can use the WHMCS API in your Laravel project. - -### Lumen +This will create the `config/whmcs.php` file in your app, modify it to set your configuration. -Copy the config file from the package to your projects config directory: +#### Default Connection -```bash -cp vendor/darthsoup/laravel-whmcs/config/whmcs.php config/whmcs.php -``` +The option `default` is where you specify the default connection. -Then open `config\whmcs.php` to fill your WHMCS api credentials in. - -To finish this, register the config file and the service provider in `bootstrap/app.php`: - -```php -$app->configure('whmcs'); -$app->register(DarthSoup\Whmcs\WhmcsServiceProvider::class); -``` +#### Whmcs Connections -Now you can use the WHMCS API in your Lumen project. +The option `connections` is where you can add multiple connections to your whmcs instances. +You can choose between both API connection types from whmcs. These methods are `password` and `token`. +Example connections has been included, but you can add as many connections you would like. -## Basic Usage +## Usage -You can call your WHMCS API directly by calling the `\WHMCS::{WHMCSAPIFUNCTION}` facade. +#### via dependency injection -If you prefer dependency injection, you can inject the manager like this: +If you prefer to use Dependency Injection, you can easily add it to your controller as below: ```php use DarthSoup\Whmcs\WhmcsManager; class WhmcsController extends Controller { - private $whmcsManager; + private WhmcsManager $whmcsManager; public function __construct(WhmcsManager $whmcsManager) { @@ -79,19 +71,34 @@ class WhmcsController extends Controller public function index() { - $this->whmcsManager->execute('GetInvoice', ['invoiceid' => '1337']); + $result = $this->whmcsManager->client()->getClients(); + dd($result); } } ``` -**Hint**: The execute command will also support your self-created WHMCS api commands. +#### Via Facade -### Examples +If you prefer the classic Laravel facade style, this might be the way to go: + +```php +use \DarthSoup\Whmcs\Facades\Whmcs; +# or +use \Whmcs; + +\Whmcs::Client()->getClientsDomains([ + 'clientid' => '1' +]); +``` + +#### API Examples Obtain a list of client purchased products: ```php -\Whmcs::GetClientsProducts([ +use \DarthSoup\Whmcs\Facades\Whmcs; + +\Whmcs::Client()->getClientsProducts([ 'clientid' => '12345' ]); ``` @@ -99,11 +106,13 @@ Obtain a list of client purchased products: Retrieve a specific invoice: ```php -\Whmcs::GetInvoice([ +\Whmcs::Billing()->getInvoice([ 'invoiceid' => '1337' ]); ``` +For more information on how to use the WhmcsApi Client `DarthSoup\WhmcsApi\Client` class, check out the documentation at https://github.com/darthsoup/php-whmcs-api + ## Support [Please open an issue in github](https://github.com/darthsoup/laravel-whmcs/issues)