From bea01badb7c0f9151493198de5859dee2e299d78 Mon Sep 17 00:00:00 2001
From: Dave Mc Nicoll <dave.mcnicoll@cslsj.qc.ca>
Date: Mon, 13 Nov 2023 14:21:39 -0500
Subject: [PATCH] - Work done to allow more flexibility on based on whatever
 custom attributes were provided.

---
 src/Adapter/Rest.php                |  4 ++--
 src/ApiRepository.php               | 14 +++++++++++---
 src/Attribute/Obj/Api/ApiAction.php |  1 +
 src/Transport/CurlClient.php        |  1 -
 src/Transport/CurlTransport.php     |  9 +++++++--
 5 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/src/Adapter/Rest.php b/src/Adapter/Rest.php
index e06978c..d819884 100644
--- a/src/Adapter/Rest.php
+++ b/src/Adapter/Rest.php
@@ -29,7 +29,7 @@ class Rest implements AdapterInterface
 
     public function connect(): object
     {
-        return new CurlClient($this->headers, $this->options, ( new CurlAuthorization())->fromAuthenticationEnum($this->auth, $this->username ?? false, $this->password ?? false, $this->token ?? false) );
+        return new CurlClient($this->headers, $this->options, ( new CurlAuthorization() )->fromAuthenticationEnum($this->auth, $this->username ?? false, $this->password ?? false, $this->token ?? false) );
     }
 
     public function buildDataSourceName(): string
@@ -39,7 +39,7 @@ class Rest implements AdapterInterface
 
     public function setup(array $configuration): void
     {
-        $this->auth = AuthenticationEnum::from($configuration['auth'] ?: AuthenticationEnum::Basic->value);
+        $this->auth = AuthenticationEnum::from($configuration['auth'] ?? AuthenticationEnum::Basic->value);
         $this->url = rtrim($configuration['url'], '/');
 
         foreach([ 'username', 'password', 'token', 'headers', 'options' ] as $conf) {
diff --git a/src/ApiRepository.php b/src/ApiRepository.php
index b766683..0221b0c 100644
--- a/src/ApiRepository.php
+++ b/src/ApiRepository.php
@@ -31,7 +31,7 @@ class ApiRepository extends \Ulmus\Repository
         parent::__construct($entity, $alias, $adapter);
     }
 
-    public function loadOne(): ?object
+    public function loadOne(): ? object
     {
         $response = $this->executeRequest(Attribute\Obj\Api\Read::class);
 
@@ -58,11 +58,19 @@ class ApiRepository extends \Ulmus\Repository
     {
         $attribute = $this->getApiAttribute($attributeClass);
 
+        if ($attribute === null) {
+            throw new \RuntimeException(sprintf("Could not find attribute class '%s' for class '%s'", $attributeClass, $this->entityClass));
+        }
+
         $request = $this->prepareRequest($this->buildRequestUrl($attribute->url), $attribute->method, $data);
 
         $request = $this->callApiRequestCallback($request, $attribute);
 
-        $this->lastResponse = $response = $this->adapter->adapter()->connect()->fromRequest($request);
+        $rest = $this->adapter->adapter()->connect();
+
+        $rest->timeout = $attribute->timeout;
+
+        $this->lastResponse = $response = $rest->fromRequest($request);
 
         $response = $this->callApiResponseCallback($response, $attribute);
 
@@ -126,7 +134,7 @@ class ApiRepository extends \Ulmus\Repository
         return new JsonRequest($uri, $method, $body === null ? Stream::fromTemp() : JsonStream::fromContent($body), $headers);
     }
 
-    public function getApiAttribute(string $type) : object
+    public function getApiAttribute(string $type) : ? object
     {
         return $this->entityClass::resolveEntity()->getAttributeImplementing($type);
     }
diff --git a/src/Attribute/Obj/Api/ApiAction.php b/src/Attribute/Obj/Api/ApiAction.php
index 16d6609..abf9a22 100644
--- a/src/Attribute/Obj/Api/ApiAction.php
+++ b/src/Attribute/Obj/Api/ApiAction.php
@@ -10,5 +10,6 @@ abstract class ApiAction
     public function __construct(
         public string $url,
         public MethodEnum $method,
+        public int $timeout = 5,
     ) {}
 }
\ No newline at end of file
diff --git a/src/Transport/CurlClient.php b/src/Transport/CurlClient.php
index 43ed462..3e13852 100644
--- a/src/Transport/CurlClient.php
+++ b/src/Transport/CurlClient.php
@@ -9,6 +9,5 @@ class CurlClient extends CurlTransport
 {
 
     # Handle file uploading here
-    
 
 }
\ No newline at end of file
diff --git a/src/Transport/CurlTransport.php b/src/Transport/CurlTransport.php
index d117527..0c6806e 100644
--- a/src/Transport/CurlTransport.php
+++ b/src/Transport/CurlTransport.php
@@ -10,7 +10,11 @@ use Ulmus\Api\Response\{ Response, JsonResponse };
 
 abstract class CurlTransport {
 
-    public int $timeout = 5;
+    # Seconds
+    public int $timeout = 30;
+
+    # Seconds
+    public int $connectTimeout = 300;
 
     public int $maximumRedirections = 10;
 
@@ -81,7 +85,8 @@ abstract class CurlTransport {
             CURLOPT_URL => $url,
             CURLOPT_HTTPHEADER => HttpHeaderEnum::compileHeaders($headers),
             CURLOPT_MAXREDIRS => $this->maximumRedirections,
-            CURLOPT_TIMEOUT_MS => $this->timeout * 1000,
+            CURLOPT_TIMEOUT => $this->timeout * 1000,
+            CURLOPT_CONNECTTIMEOUT => $this->connectTimeout,
             CURLOPT_SSL_VERIFYPEER => false,
             CURLOPT_SSL_VERIFYHOST => false,
             CURLOPT_RETURNTRANSFER => true,