From 1d96f3adb924ae4531df37860f7475692715a246 Mon Sep 17 00:00:00 2001 From: "Abdulmhsen B. A. A" Date: Wed, 13 Dec 2023 14:10:12 +0300 Subject: [PATCH] Updated Backends.Common docs. --- src/Backends/Common/Cache.php | 64 +++++++++++ src/Backends/Common/ClientInterface.php | 140 +++++++++++++----------- src/Backends/Common/CommonTrait.php | 15 ++- src/Backends/Common/Context.php | 14 +-- src/Backends/Common/Error.php | 22 ++-- src/Backends/Common/GuidInterface.php | 32 +++--- src/Backends/Common/ManageInterface.php | 8 +- src/Backends/Common/Response.php | 20 ++-- 8 files changed, 205 insertions(+), 110 deletions(-) diff --git a/src/Backends/Common/Cache.php b/src/Backends/Common/Cache.php index 3d0c600e..c41be929 100644 --- a/src/Backends/Common/Cache.php +++ b/src/Backends/Common/Cache.php @@ -11,10 +11,25 @@ use Psr\Log\LoggerInterface; use Psr\SimpleCache\CacheInterface; use Psr\SimpleCache\InvalidArgumentException; +/** + * Class Cache + * + * Class to handle backend cache. + */ final class Cache implements Countable { + /** + * @var array The data to be cached. + */ private array $data = []; + /** + * @var string|null The key to identify the data in the cache. + */ private string|null $key = null; + + /** + * @var array The options for retrieving the data. + */ private array $options = []; /** @@ -27,6 +42,14 @@ final class Cache implements Countable { } + /** + * Clone the object with the data retrieved from the cache based on the key. + * + * @param string $key The key to identify the data in the cache. + * @param array $options options for retrieving the data. + * + * @return Cache The cloned object with the data. + */ public function withData(string $key, array $options = []): self { $cloned = clone $this; @@ -46,16 +69,39 @@ final class Cache implements Countable return $cloned; } + /** + * Checks if the given key exists in the cache. + * + * @param string $key The key to check. + * + * @return bool Returns true if the key exists, false otherwise. + */ public function has(string $key): bool { return ag_exists($this->data, $key); } + /** + * Retrieves a value from the cache based on the given key. + * + * @param string $key The key used to retrieve the value from the cache. + * @param mixed $default Default value to return if the key is not found in the cache. + * + * @return mixed The value associated with the given key in the cache, or the default value if the key is not found. + */ public function get(string $key, mixed $default = null): mixed { return ag($this->data, $key, $default); } + /** + * Sets a value in the cache based on the given key. + * + * @param string $key The key used to set the value in the cache. + * @param mixed $value The value to set in the cache. + * + * @return Cache Returns the current object. + */ public function set(string $key, mixed $value): self { $this->data = ag_set($this->data, $key, $value); @@ -63,6 +109,13 @@ final class Cache implements Countable return $this; } + /** + * Removes a value from the cache based on the given key. + * + * @param string $key The key used to remove the value from the cache. + * + * @return bool True if the value was successfully removed from the cache, false otherwise. + */ public function remove(string $key): bool { if (false === ag_exists($this->data, $key)) { @@ -73,6 +126,12 @@ final class Cache implements Countable return true; } + /** + * If key is set and there is a data within the data array and the dry run option is not set, + * then the data is flushed to the cache backend. + * + * @return void + */ public function __destruct() { if (null === $this->key || $this->count() < 1 || true === (bool)ag($this->options, Options::DRY_RUN)) { @@ -85,6 +144,11 @@ final class Cache implements Countable } } + /** + * Counts the number of elements in the data array. + * + * @return int The number of elements in the data array. + */ public function count(): int { return count($this->data); diff --git a/src/Backends/Common/ClientInterface.php b/src/Backends/Common/ClientInterface.php index e70f5ca1..e7050cca 100644 --- a/src/Backends/Common/ClientInterface.php +++ b/src/Backends/Common/ClientInterface.php @@ -18,147 +18,155 @@ use Symfony\Contracts\HttpClient\ResponseInterface; interface ClientInterface { /** - * Initiate Client with context. It **MUST** return new instance. + * Initiate client with context. It **MUST** return new instance. * - * @param Context $context + * @param Context $context client context. * - * @return ClientInterface + * @return ClientInterface new instance. */ public function withContext(Context $context): ClientInterface; /** * Return client context. * - * @return Context + * @return Context client context. */ public function getContext(): Context; /** - * Get Backend name. + * Get backend name. * - * @return string + * @return string backend name. */ public function getName(): string; /** * Inject logger. * - * @param LoggerInterface $logger + * @param LoggerInterface $logger logger instance. * - * @return ClientInterface + * @return ClientInterface Returns same instance. */ public function setLogger(LoggerInterface $logger): ClientInterface; /** - * Process The request For attributes extraction. + * Process the request for attributes extraction. * - * @param ServerRequestInterface $request - * @param array $opts + * @param ServerRequestInterface $request request to process. + * @param array $opts options for processing the request. * - * @return ServerRequestInterface + * @return ServerRequestInterface processed request. */ public function processRequest(ServerRequestInterface $request, array $opts = []): ServerRequestInterface; /** * Parse backend webhook event. * - * @param ServerRequestInterface $request - * @return StateInterface + * @param ServerRequestInterface $request request to process. + * + * @return StateInterface state object. */ public function parseWebhook(ServerRequestInterface $request): StateInterface; /** - * Import metadata & play state. + * Import play state and metadata from backend. * - * @param iImport $mapper - * @param iDate|null $after + * @param iImport $mapper mapper to use. + * @param iDate|null $after only import items after this date. * - * @return array + * @return array responses. */ public function pull(iImport $mapper, iDate|null $after = null): array; /** - * Backup play state. + * Backup play state from backend. * - * @param iImport $mapper - * @param SplFileObject|null $writer - * @param array $opts + * @param iImport $mapper mapper to use. + * @param SplFileObject|null $writer writer to use. + * @param array $opts options for backup. * - * @return array + * @return array responses. */ public function backup(iImport $mapper, SplFileObject|null $writer = null, array $opts = []): array; /** - * Compare play state and export. + * Export play state back to backend. * - * @param iImport $mapper - * @param QueueRequests $queue - * @param iDate|null $after + * @param iImport $mapper mapper to use. + * @param QueueRequests $queue queue to use. + * @param iDate|null $after only export items after this date. * - * @return array + * @return array responses. */ public function export(iImport $mapper, QueueRequests $queue, iDate|null $after = null): array; /** - * Compare webhook queued events and push. + * Compare webhook queued events and push them to backend. * - * @param array $entities - * @param QueueRequests $queue - * @param iDate|null $after + * @param array $entities entities to push. + * @param QueueRequests $queue queue to use. + * @param iDate|null $after only push items after this date. * - * @return array + * @return array empty array. The data is pushed to the queue. */ public function push(array $entities, QueueRequests $queue, iDate|null $after = null): array; /** * Compare watch progress and push to backend. * - * @param array $entities - * @param QueueRequests $queue - * @param iDate|null $after + * @param array $entities entities to push. + * @param QueueRequests $queue queue to use. + * @param iDate|null $after only push items after this date. * - * @return array + * @return array empty array. The data is pushed to the queue. */ public function progress(array $entities, QueueRequests $queue, iDate|null $after = null): array; /** * Search backend libraries. * - * @param string $query - * @param int $limit - * @param array $opts + * @param string $query search query. + * @param int $limit limit results. + * @param array $opts options. * - * @return array + * @return array. */ public function search(string $query, int $limit = 25, array $opts = []): array; /** * Search backend for item id. * - * @param string|int $id - * @param array $opts + * @param string|int $id item id. + * @param array $opts options. * - * @return array + * @return array empty array if not found. */ public function searchId(string|int $id, array $opts = []): array; /** - * Get Specific item metadata. + * Search backend for specific item metadata. * - * @param string|int $id - * @param array $opts + * @param string|int $id item id. + * @param array $opts options. * - * @return array + * @return array empty array if not found. */ public function getMetadata(string|int $id, array $opts = []): array; /** * Get Library content. * - * @param string|int $id - * @param array $opts + * @param string|int $id library id. + * @param array $opts options. * - * @return array + * @return array empty array if no items found. */ public function getLibrary(string|int $id, array $opts = []): array; @@ -167,16 +175,16 @@ interface ClientInterface * * @param bool $forceRefresh force reload from backend. * - * @return int|string|null + * @return int|string|null return backend unique id or null if not supported. */ public function getIdentifier(bool $forceRefresh = false): int|string|null; /** * Return list of backend users. * - * @param array $opts + * @param array $opts options. * - * @return array empty error if not supported. + * @return array empty array if not supported. * * @throws JsonException May throw if json decoding fails. * @throws ExceptionInterface May be thrown if there is HTTP request errors. @@ -186,7 +194,7 @@ interface ClientInterface /** * Return list of backend libraries. * - * @param array $opts + * @param array $opts options. * * @return array */ @@ -195,38 +203,38 @@ interface ClientInterface /** * Add/Edit Backend. * - * @param array $backend - * @param array $opts + * @param array $backend backend data. + * @param array $opts options. * - * @return array + * @return array Returns backend with appended backend specific data. */ public static function manage(array $backend, array $opts = []): array; /** * Return user access token. * - * @param int|string $userId - * @param string $username + * @param int|string $userId user id. + * @param string $username username. * - * @return string|bool return user token as string or bool(FALSE) if not supported. + * @return string|bool return user token as string or bool(false) if not supported. */ public function getUserToken(int|string $userId, string $username): string|bool; /** - * Get Backend Info. + * Get backend info. * - * @param array $opts + * @param array $opts options. * * @return array */ public function getInfo(array $opts = []): array; /** - * Get Backend Version. + * Get backend version. * - * @param array $opts + * @param array $opts options. * - * @return string + * @return string backend version. */ public function getVersion(array $opts = []): string; diff --git a/src/Backends/Common/CommonTrait.php b/src/Backends/Common/CommonTrait.php index a71ad26d..9e4533af 100644 --- a/src/Backends/Common/CommonTrait.php +++ b/src/Backends/Common/CommonTrait.php @@ -11,13 +11,15 @@ use Throwable; trait CommonTrait { /** - * Wrap Closure into try catch response. + * Wrap closure into try catch response. * * @param Context $context Context to associate the call with. * @param callable():Response $fn Closure - * @param string|null $action the action name to personalize the message. + * @param string|null $action the action name to make error message more clear. * - * @return Response We should Expand the catch to include common http errors. json decode failing. + * @return Response Response object. + * @todo Expand the catch to include common http errors. json decode failing. + * @todo raise the log level to error instead of warning as it's currently doing, warning imply it's ok to ignore. */ protected function tryResponse(Context $context, callable $fn, string|null $action = null): Response { @@ -35,7 +37,7 @@ trait CommonTrait error: new Error( message: 'Exception [{error.kind}] was thrown unhandled in [{client}: {backend}] {action}. Error [{error.message} @ {error.file}:{error.line}].', context: [ - 'action' => $action ?? 'context', + 'action' => $action ?? 'not_set', 'backend' => $context->backendName, 'client' => $context->clientName, 'message' => $e->getMessage(), @@ -60,6 +62,11 @@ trait CommonTrait } } + /** + * Get Logger. + * + * @return LoggerInterface Return the logger. + */ protected function getLogger(): LoggerInterface { return Container::get(LoggerInterface::class); diff --git a/src/Backends/Common/Context.php b/src/Backends/Common/Context.php index 801a4250..0ab8ee47 100644 --- a/src/Backends/Common/Context.php +++ b/src/Backends/Common/Context.php @@ -9,16 +9,16 @@ use Psr\Http\Message\UriInterface; class Context { /** - * Make Context for classes to work with. + * Make backend context for classes to work with. * - * @param string $clientName Backend Client Name - * @param string $backendName Backend Name - * @param UriInterface $backendUrl Backend Url - * @param Cache $cache A Global Cache for backend. - * @param string|int|null $backendId Backend Id. + * @param string $clientName Backend client name. + * @param string $backendName Backend name. + * @param UriInterface $backendUrl Backend URL. + * @param Cache $cache A global cache for backend. + * @param string|int|null $backendId Backend id. * @param string|int|null $backendToken Backend access token * @param string|int|null $backendUser Backend user id. - * @param array $backendHeaders Headers to pass for backend. + * @param array $backendHeaders Headers to pass for backend requests. * @param bool $trace Enable debug tracing mode. * @param array $options optional options. */ diff --git a/src/Backends/Common/Error.php b/src/Backends/Common/Error.php index bcd60b43..28f0a9c5 100644 --- a/src/Backends/Common/Error.php +++ b/src/Backends/Common/Error.php @@ -4,12 +4,13 @@ declare(strict_types=1); namespace App\Backends\Common; +use Stringable; use Throwable; -final class Error implements \Stringable +final class Error implements Stringable { /** - * Wrap Error in easy to consume way. + * Wrap error in easy to consume way. * * @param string $message Error message. * @param array $context Error message context. @@ -66,16 +67,21 @@ final class Error implements \Stringable return $this->message; } - return r($this->message, $this->context, [ - 'log_behavior' => true - ]); + return r($this->message, $this->context, ['log_behavior' => true]); } public function __toString(): string { - return r('{ERROR}: {message}', [ - 'ERROR' => $this->level->value, + $params = [ + 'level' => $this->level->value, 'message' => $this->format(), - ]); + ]; + + if ($this->hasException()) { + $params['line'] = $this->previous->getLine(); + $params['file'] = after($this->previous->getFile(), ROOT_PATH); + } + + return r('{level}: {message}' . ($this->hasException() ? '. In [{file}:{line}].' : ''), $params); } } diff --git a/src/Backends/Common/GuidInterface.php b/src/Backends/Common/GuidInterface.php index b3e34ea1..708db81a 100644 --- a/src/Backends/Common/GuidInterface.php +++ b/src/Backends/Common/GuidInterface.php @@ -9,48 +9,52 @@ interface GuidInterface /** * Set working context. * - * @param Context $context + * @param Context $context Context to associate this object with. * - * @return $this Mutated version of the implementation shall be returned. + * @return $this A new instance will be returned. */ public function withContext(Context $context): self; /** * Parse external ids from given list in safe way. * - * *DO NOT THROW OR LOG ANYTHING.* + * @note this method is **NOT allowed** to log and throw exceptions. * - * @param array $guids - * @param array $context + * @param array $guids List of external ids to parse. + * @param array $context Context to associate this call with. * - * @return array + * @return array List of parsed external ids. */ public function parse(array $guids, array $context = []): array; /** * Parse supported external ids from given list. * - * @param array $guids - * @param array $context - * @return array + * @note this method is allowed to log and throw exceptions. + * + * @param array $guids List of external ids to parse. + * @param array $context Context to associate this call with. + * + * @return array List of parsed and supported external ids. */ public function get(array $guids, array $context = []): array; /** * Does the given list contain supported external ids? * - * @param array $guids - * @param array $context - * @return bool + * @param array $guids List of external ids to check. + * @param array $context Context to associate this call with. + * + * @return bool True if the list contain supported external ids. */ public function has(array $guids, array $context = []): bool; /** * Is the given identifier a local id? * - * @param string $guid + * @param string $guid External id to check. * - * @return bool + * @return bool True if the given id is a local id. */ public function isLocal(string $guid): bool; } diff --git a/src/Backends/Common/ManageInterface.php b/src/Backends/Common/ManageInterface.php index 905b8ffe..fd7f3157 100644 --- a/src/Backends/Common/ManageInterface.php +++ b/src/Backends/Common/ManageInterface.php @@ -7,12 +7,12 @@ namespace App\Backends\Common; interface ManageInterface { /** - * Add/Edit Backend. + * Add or edit backend. * - * @param array $backend - * @param array $opts + * @param array $backend Backend data. + * @param array $opts options. * - * @return array + * @return array return modified $backend data. */ public function manage(array $backend, array $opts = []): array; } diff --git a/src/Backends/Common/Response.php b/src/Backends/Common/Response.php index 293362e4..0218011e 100644 --- a/src/Backends/Common/Response.php +++ b/src/Backends/Common/Response.php @@ -7,12 +7,12 @@ namespace App\Backends\Common; final class Response { /** - * Wrap Clients responses into easy to consume object. + * Wrap clients responses into easy to consume object. * - * @param bool $status Whether the operation is Successful. - * @param mixed $response the actual response. - * @param Error|null $error If the response has an error, populate it using {@see Error} object. - * @param mixed $extra an array that can contain anything. + * @param bool $status Whether the operation is successful. + * @param mixed $response The actual response. + * @param Error|null $error If the response has an error. + * @param mixed $extra An array that can contain anything. Should be rarely used. */ public function __construct( public readonly bool $status, @@ -24,6 +24,8 @@ final class Response /** * Does the response contain an error object? + * + * @return bool True if the response has an error. */ public function hasError(): bool { @@ -31,7 +33,9 @@ final class Response } /** - * Return Error response. + * Return error response. + * + * @return Error the error object if exists otherwise dummy error object is returned. */ public function getError(): Error { @@ -39,7 +43,9 @@ final class Response } /** - * Is the Operation Successful? + * Is the operation successful? + * + * @return bool true if the operation is successful. */ public function isSuccessful(): bool {