Refactoring

This commit is contained in:
René Preuß
2022-10-01 14:00:25 +02:00
parent 7ba3cdffb0
commit a2405875ad
26 changed files with 569 additions and 391 deletions

View File

@@ -0,0 +1,19 @@
<?php
namespace Bitinflow\Accounts\ApiOperations;
use Bitinflow\Accounts\Exceptions\RequestRequiresMissingParametersException;
use Illuminate\Support\Arr;
trait Validation
{
/**
* @throws RequestRequiresMissingParametersException
*/
public function validateRequired(array $parameters, array $required)
{
if (!Arr::has($parameters, $required)) {
throw RequestRequiresMissingParametersException::fromValidateRequired($parameters, $required);
}
}
}

View File

@@ -8,6 +8,7 @@ use Bitinflow\Accounts\Exceptions\RequestRequiresClientIdException;
use Bitinflow\Accounts\Exceptions\RequestRequiresRedirectUriException;
use Bitinflow\Accounts\Helpers\Paginator;
use Bitinflow\Accounts\Traits;
use Bitinflow\Support\Query;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Exception\RequestException;
@@ -18,13 +19,10 @@ use Illuminate\Contracts\Auth\Authenticatable;
*/
class BitinflowAccounts
{
use Traits\OauthTrait;
use Traits\SshKeysTrait;
use Traits\UsersTrait;
use Traits\HasBitinflowPaymentsWallet;
use ApiOperations\Delete;
use ApiOperations\Get;
use ApiOperations\Post;
@@ -35,61 +33,51 @@ class BitinflowAccounts
*
* @var string
*/
public static $cookie = 'bitinflow_token';
public static string $cookie = 'bitinflow_token';
/**
* Indicates if Bitinflow Accounts should ignore incoming CSRF tokens.
*
* @var bool
*/
public static $ignoreCsrfToken = false;
public static bool $ignoreCsrfToken = false;
/**
* Indicates if Bitinflow Accounts should unserializes cookies.
*
* @var bool
*/
public static $unserializesCookies = false;
private static $baseUrl = 'https://accounts.bitinflow.com/api/';
public static bool $unserializesCookies = false;
private static string $baseUrl = 'https://accounts.bitinflow.com/api/';
/**
* Guzzle is used to make http requests.
*
* @var Client
*/
protected $client;
protected Client $client;
/**
* Paginator object.
*
* @var Paginator
*/
protected $paginator;
protected Paginator $paginator;
/**
* bitinflow Accounts OAuth token.
*
* @var string|null
*/
protected $token = null;
protected ?string $token = null;
/**
* bitinflow Accounts client id.
*
* @var string|null
*/
protected $clientId = null;
protected ?string $clientId = null;
/**
* bitinflow Accounts client secret.
*
* @var string|null
*/
protected $clientSecret = null;
protected ?string $clientSecret = null;
/**
* bitinflow Accounts OAuth redirect url.
*
* @var string|null
*/
protected $redirectUri = null;
protected ?string $redirectUri = null;
/**
* Constructor.
@@ -129,7 +117,7 @@ class BitinflowAccounts
* @param string|null $cookie
* @return string|static
*/
public static function cookie($cookie = null)
public static function cookie(string $cookie = null)
{
if (is_null($cookie)) {
return static::$cookie;
@@ -268,7 +256,7 @@ class BitinflowAccounts
* @return string|null
* @throws RequestRequiresAuthenticationException
*/
public function getToken()
public function getToken(): ?string
{
if (!$this->token) {
throw new RequestRequiresAuthenticationException;
@@ -323,7 +311,7 @@ class BitinflowAccounts
* @param string $method HTTP method
* @param string $path Query path
* @param array $parameters Query parameters
* @param Paginator $paginator Paginator object
* @param Paginator|null $paginator Paginator object
* @param mixed|null $jsonBody JSON data
*
* @return Result Result object
@@ -332,13 +320,14 @@ class BitinflowAccounts
*/
public function query(string $method = 'GET', string $path = '', array $parameters = [], Paginator $paginator = null, $jsonBody = null): Result
{
/** @noinspection DuplicatedCode */
if ($paginator !== null) {
$parameters[$paginator->action] = $paginator->cursor();
}
try {
$response = $this->client->request($method, $path, [
'headers' => $this->buildHeaders($jsonBody ? true : false),
'query' => $this->buildQuery($parameters),
'headers' => $this->buildHeaders((bool)$jsonBody),
'query' => Query::build($parameters),
'json' => $jsonBody ?: null,
]);
$result = new Result($response, null, $paginator);
@@ -401,26 +390,6 @@ class BitinflowAccounts
$this->clientId = $clientId;
}
/**
* Build query with support for multiple smae first-dimension keys.
*
* @param array $query
*
* @return string
*/
public function buildQuery(array $query): string
{
$parts = [];
foreach ($query as $name => $value) {
$value = (array)$value;
array_walk_recursive($value, function ($value) use (&$parts, $name) {
$parts[] = urlencode($name) . '=' . urlencode($value);
});
}
return implode('&', $parts);
}
/**
* @param string $path
* @param array $parameters

View File

@@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
namespace Bitinflow\Accounts\Exceptions;
use Exception;
/**
* @author René Preuß <rene@preuss.io>
*/
class RequestRequiresMissingParametersException extends Exception
{
public function __construct($message = 'Request requires missing parameters', $code = 0, Exception $previous = null)
{
parent::__construct($message, $code, $previous);
}
public static function fromValidateRequired(array $given, array $required): RequestRequiresMissingParametersException
{
return new self(sprintf(
'Request requires missing parameters. Required: %s. Given: %s',
implode(', ', $required),
implode(', ', $given)
));
}
}

View File

@@ -5,14 +5,17 @@ declare(strict_types=1);
namespace Bitinflow\Accounts\Facades;
use Bitinflow\Accounts\BitinflowAccounts as BitinflowAccountsService;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Facades\Facade;
/**
* @author René Preuß <rene@preuss.io>
* @method static string|static cookie(string $cookie = null)
* @method static Authenticatable actingAs($user, $scopes = [], $guard = 'api')
* @method static static withClientId(string $clientId): self
* @method static string getClientSecret(): string
*/
class BitinflowAccounts extends Facade
{
protected static function getFacadeAccessor()
{
return BitinflowAccountsService::class;

View File

@@ -10,13 +10,13 @@ use Bitinflow\Accounts\BitinflowAccounts;
use Bitinflow\Accounts\Helpers\JwtParser;
use Bitinflow\Accounts\Contracts;
use Bitinflow\Accounts\Repository;
use Bitinflow\Payments\BitinflowPayments;
use Illuminate\Auth\RequestGuard;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\ServiceProvider;
class BitinflowAccountsServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
@@ -41,6 +41,9 @@ class BitinflowAccountsServiceProvider extends ServiceProvider
$this->app->singleton(BitinflowAccounts::class, function () {
return new BitinflowAccounts;
});
$this->app->singleton(BitinflowPayments::class, function () {
return new BitinflowPayments;
});
$this->registerGuard();
}
@@ -85,6 +88,9 @@ class BitinflowAccountsServiceProvider extends ServiceProvider
*/
public function provides()
{
return [BitinflowAccounts::class];
return [
BitinflowAccounts::class,
BitinflowPayments::class,
];
}
}

View File

@@ -262,4 +262,9 @@ class Result
{
return $this->response;
}
public function dump()
{
dump($this->data());
}
}

View File

@@ -1,57 +0,0 @@
<?php
namespace Bitinflow\Accounts\Traits\BitinflowPaymentsWallet;
use App\Models\User;
class Balance
{
public function __construct(protected User $user)
{
//
}
/**
* Get balance from user.
*
* @return float|null
*/
public function get(): ?float
{
return $this->user->getPaymentsUser()->data->balance;
}
/**
* Deposit given amount from bank to account.
*
* @param float $amount
* @param string $description
* @return bool
*/
public function deposit(float $amount, string $decription): bool
{
$this->user->asPaymentsUser('PUT', sprintf('wallet/deposit', [
'amount' => $amount,
'decription' => $decription,
]));
}
/**
* Charge given amount from account.
*
* @param float $amount
* @param string $decription
* @return bool
*/
public function charge(float $amount, string $decription): bool
{
$order = $this->user->orders()->create([
'name' => $decription,
'description' => 'one-time payment',
'amount' => 1,
'price' => $amount,
]);
return $this->user->orders()->checkout($order->id);
}
}

View File

@@ -1,33 +0,0 @@
<?php
namespace Bitinflow\Accounts\Traits\BitinflowPaymentsWallet;
use App\Models\User;
class CheckoutSessions
{
public function __construct(protected User $user)
{
//
}
public function create(array $payload)
{
return $this->user->asPaymentsUser('POST', 'checkout-sessions', $payload);
}
public function get(string $id)
{
return $this->user->asPaymentsUser('GET', sprintf('checkout-sessions/%s', $id));
}
public function checkout(string $id)
{
return $this->user->asPaymentsUser('PUT', sprintf('checkout-sessions/%s/checkout', $id));
}
public function revoke(string $id)
{
return $this->user->asPaymentsUser('PUT', sprintf('checkout-sessions/%s/revoke', $id));
}
}

View File

@@ -1,69 +0,0 @@
<?php
namespace Bitinflow\Accounts\Traits\BitinflowPaymentsWallet;
use App\Models\User;
class Orders
{
public function __construct(protected User $user)
{
//
}
/**
* Get orders from user.
*
* @return object|null
*/
public function all(): ?object
{
return $this->user->asPaymentsUser('GET', 'orders');
}
/**
* @param string $id
* @return object|null
*/
public function get(string $id): ?object
{
return $this->user->asPaymentsUser('GET', sprintf('orders/%s', $id));
}
/**
* Create a new order.
*
* @param array $attributes
* @return object|false
*/
public function create(array $attributes = []): object|false
{
return $this->user->asPaymentsUser('POST', 'orders', $attributes)->data;
}
/**
* Checkout given subscription.
*
* @param string $id
* @return bool
*/
public function checkout(string $id): bool
{
$this->user->asPaymentsUser('PUT', sprintf('orders/%s/checkout', $id));
return true;
}
/**
* Revoke a running subscription.
*
* @param string $id
* @return bool
*/
public function revoke(string $id): bool
{
$this->user->asPaymentsUser('PUT', sprintf('orders/%s/revoke', $id));
return true;
}
}

View File

@@ -1,97 +0,0 @@
<?php
namespace Bitinflow\Accounts\Traits\BitinflowPaymentsWallet;
use App\Models\User;
class Subscriptions
{
public function __construct(protected User $user)
{
//
}
/**
* Get subscriptions from user.
*
* @return object|null
*/
public function all(): ?object
{
return $this->user->asPaymentsUser('GET', 'subscriptions');
}
/**
* @param string $id
* @return object|null
*/
public function get(string $id): ?object
{
return $this->user->asPaymentsUser('GET', sprintf('subscriptions/%s', $id));
}
/**
* Create a new subscription.
*
* @param array $attributes array which requires following attributes:
* name, description, period, price
* and following attributes are optional:
* vat, payload, ends_at, webhook_url, webhook_secret
* @return object|false the subscription object
* @throws GuzzleException
*/
public function create(array $attributes): object|false
{
return $this->user->asPaymentsUser('POST', 'subscriptions', $attributes)->data;
}
/**
* @param string $name
* @return bool
*/
public function has(string $name = 'default'): bool
{
$subscription = $this->get($name);
return $subscription && $subscription->status === 'settled' || $subscription && $subscription->resumeable;
}
/**
* Checkout given subscription.
*
* @param string $id
* @return bool
*/
public function checkout(string $id): bool
{
$this->user->asPaymentsUser('PUT', sprintf('subscriptions/%s/checkout', $id));
return true;
}
/**
* Revoke a running subscription.
*
* @param string $id
* @return bool
*/
public function revoke(string $id): bool
{
$this->user->asPaymentsUser('PUT', sprintf('subscriptions/%s/revoke', $id));
return true;
}
/**
* Resume a running subscription.
*
* @param string $id
* @return bool
*/
public function resume(string $id): bool
{
$this->user->asPaymentsUser('PUT', sprintf('subscriptions/%s/resume', $id));
return true;
}
}

View File

@@ -1,23 +0,0 @@
<?php
namespace Bitinflow\Accounts\Traits\BitinflowPaymentsWallet;
use App\Models\User;
class Taxation
{
public function __construct(protected User $user)
{
//
}
/**
* Get vat from user.
*
* @return int|null
*/
public function get(): ?int
{
return $this->user->getPaymentsUser()->data->taxation->vat;
}
}

View File

@@ -1,54 +0,0 @@
<?php
namespace Bitinflow\Accounts\Traits\BitinflowPaymentsWallet;
use App\Models\User;
class Wallets
{
public function __construct(protected User $user)
{
//
}
/**
* Get all wallets that belongs to the user.
*
* @return array|null
*/
public function all(): ?array
{
return $this->user->getPaymentsUser()->data->wallets;
}
/**
* Check if user has an active wallet.
*
* @return bool
* @throws GuzzleException
*/
public function has(): ?bool
{
return $this->user->getPaymentsUser()->data->has_wallet;
}
/**
* Set default wallet to given wallet token.
*
* @param string $token default payment method token
* @return bool
*/
public function setDefault(string $token): bool
{
$this->user->asPaymentsUser('PUT', sprintf('wallets/default', [
'token' => $token
]));
return true;
}
public function setupIntent()
{
return sprintf('%swallet/?continue_url=%s', config('bitinflow-accounts.payments.dashboard_url'), urlencode(url()->to($success_path)));
}
}