Skip to content

Commit d70b55f

Browse files
authored
Merge branch 'master' into phpstan
2 parents 013541d + de7f6c4 commit d70b55f

4 files changed

Lines changed: 158 additions & 118 deletions

File tree

src/Supporting/CommunicationProvider.php

Lines changed: 108 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace INTERMediator\FileMakerServer\RESTAPI\Supporting;
44

55
use Exception;
6+
use CurlHandle;
67

78
/**
89
* Class CommunicationProvider is for internal use to communicate with FileMaker Server.
@@ -258,31 +259,27 @@ public function __construct(string $solution, string $user, string $password, ?
258259

259260
/**
260261
* @param array $params Array to build the API path. Ex: `["layouts" => null]` or `["sessions" => $this->accessToken]`.
261-
* @param null|array $request The query parameters as `"key" => "value"`.
262+
* @param array|null $request The query parameters as `"key" => "value"`.
262263
* @param string $methodLower The method in lowercase. Ex: `"get"`, `"delete"`, etc.
263264
* @param bool $isSystem If the query is for the system (sessions, databases, etc) or for a database.
264-
* @param false|string $directPath If we don't want to build the path with the other parameters, you can provide the direct path.
265+
* @param string|null|false $directPath If we don't want to build the path with the other parameters, you can provide the direct path.
265266
* @return string
266267
* @ignore
267268
*/
268-
public function getURL(array $params, string|array|null $request, string $methodLower,
269-
bool $isSystem = false, bool $directPath = false): string
269+
public function getURL(array $params, ?array $request, string $methodLower,
270+
bool $isSystem = false, string|null|false $directPath = null): string
270271
{
271272
$vStr = $this->vNum < 1 ? 'Latest' : strval($this->vNum);
272273
$url = "$this->protocol://$this->host:$this->port";
273-
if ($directPath) {
274+
if (!empty($directPath)) {
274275
$url .= $directPath;
275276
} else {
276277
$url .= "/fmi/data/v$vStr" . ((!$isSystem) ? "/databases/$this->solution" : "");
277278
}
278279
foreach ($params as $key => $value) {
279280
$url .= "/$key" . (is_null($value) ? "" : "/$value");
280281
}
281-
if (!is_string($request) &&
282-
in_array($methodLower, array('get', 'delete')) &&
283-
!is_null($request) &&
284-
(count($request) > 0)
285-
) {
282+
if (!empty($request) && in_array($methodLower, array('get', 'delete'))) {
286283
$url .= '?';
287284
foreach ($request as $key => $value) {
288285
if (key($request) !== $key) {
@@ -293,7 +290,7 @@ public function getURL(array $params, string|array|null $request, string $method
293290
if ($sortParam !== '[]') {
294291
$url .= '_' . $key . '=' . $sortParam;
295292
}
296-
} else if ($key === 'limit' || $key === 'offset') {
293+
} elseif ($key === 'limit' || $key === 'offset') {
297294
$url .= '_' . $key . '=' . (is_array($value) ? json_encode($value) : $value);
298295
} else {
299296
// handling portal object name etc.
@@ -361,7 +358,7 @@ public function justifyRequest(?array $request): array
361358

362359
if (isset($result['sort'])) {
363360
$sort = [];
364-
foreach ($result['sort'] as $sortKey => $sortCondition) {
361+
foreach ($result['sort'] as $sortCondition) {
365362
if (isset($sortCondition[0])) {
366363
$sortOrder = 'ascend';
367364
if (isset($sortCondition[1])) {
@@ -490,14 +487,12 @@ public function getScriptNames(): null|array
490487

491488
/**
492489
* @throws Exception In case of any error, an exception arises.
490+
* @return bool
493491
* @ignore
494492
*/
495-
public function login()
493+
public function login(): bool
496494
{
497-
if ($this->keepAuth) {
498-
return true;
499-
}
500-
if (!is_null($this->accessToken)) {
495+
if ($this->keepAuth || !is_null($this->accessToken)) {
501496
return true;
502497
}
503498

@@ -509,7 +504,10 @@ public function login()
509504
];
510505
} else {
511506
$value = "Basic " . base64_encode("{$this->user}:{$this->password}");
512-
$headers = ["Content-Type" => "application/json", "Authorization" => $value];
507+
$headers = [
508+
"Content-Type" => "application/json",
509+
"Authorization" => $value
510+
];
513511
}
514512
$params = ["sessions" => null];
515513
$request = [];
@@ -531,6 +529,7 @@ public function login()
531529
/**
532530
*
533531
* @throws Exception In case of any error, an exception arises.
532+
* @return void
534533
* @ignore
535534
*/
536535
public function logout()
@@ -564,16 +563,21 @@ private function getSupportingProviders()
564563
private function getOAuthIdentifier($provider)
565564
{
566565
try {
567-
$this->callRestAPI([], [
568-
"trackingID" => rand(10000000, 99999999),
569-
"provider" => $provider,
570-
"address" => "127.0.0.1",
571-
"X-FMS-OAuth-AuthType" => 2
572-
], 'GET', [], [
573-
"X-FMS-Application-Type" => 9,
574-
"X-FMS-Application-Version" => 15,
575-
"X-FMS-Return-URL" => "http://127.0.0.1/",
576-
], false, "/oauth/getoauthurl");
566+
$this->callRestAPI(
567+
[], false, 'GET',
568+
[
569+
"trackingID" => rand(10000000, 99999999),
570+
"provider" => $provider,
571+
"address" => "127.0.0.1",
572+
"X-FMS-OAuth-AuthType" => 2
573+
],
574+
[
575+
"X-FMS-Application-Type" => 9,
576+
"X-FMS-Application-Version" => 15,
577+
"X-FMS-Return-URL" => "http://127.0.0.1/",
578+
],
579+
false, "/oauth/getoauthurl"
580+
);
577581
$result = [];
578582
foreach ($this->responseBody as $key => $item) {
579583

@@ -585,55 +589,38 @@ private function getOAuthIdentifier($provider)
585589
}
586590

587591
/**
588-
* @param $params
589-
* @param $layout
590-
* @param boolean $isAddToken
592+
* @param array $params
593+
* @param bool $isAddToken
591594
* @param string $method
592-
* @param array $request
593-
* @param array $addHeader
594-
* @param boolean $isSystem for Metadata
595+
* @param array|null $request
596+
* @param array|null $addHeader
597+
* @param bool $isSystem for Metadata
598+
* @param string|null|false $directPath
599+
* @return void
595600
* @throws Exception In case of any error, an exception arises.
596601
* @ignore
597602
*/
598-
public function callRestAPI($params, $isAddToken, $method = 'GET', $request = null, $addHeader = null, $isSystem = false, $directPath = false)
603+
public function callRestAPI(array $params, bool $isAddToken, string $method = 'GET', $request = null,
604+
$addHeader = null, $isSystem = false, string|null|false $directPath = null)
599605
{
600606
$methodLower = strtolower($method);
601607
$url = $this->getURL($params, $request, $methodLower, $isSystem, $directPath);
602608
$header = $this->getHeaders($isAddToken, $addHeader);
603609
$jsonEncoding = true;
604610
if (is_string($request)) {
605611
$jsonEncoding = false;
606-
} else if ($methodLower !== 'get' && !is_null($request)) {
612+
} elseif ($methodLower !== 'get' && !is_null($request)) {
607613
$request = $this->justifyRequest($request);
608614
}
609-
$ch = curl_init();
610-
curl_setopt($ch, CURLOPT_URL, $url);
615+
$ch = $this->_createCurlHandle($url);
611616
curl_setopt($ch, CURLOPT_VERBOSE, 0);
612617
curl_setopt($ch, CURLOPT_HEADER, 1);
613-
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_DEFAULT);
614618
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
615619
if ($methodLower == 'post') {
616620
curl_setopt($ch, CURLOPT_POST, 1);
617621
} elseif (in_array($methodLower, ['put', 'patch', 'delete', 'get'], true)) {
618622
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, strtoupper($methodLower));
619623
}
620-
if ($this->isCertValidating) {
621-
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
622-
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
623-
// Use the OS native certificate authorities, if possible.
624-
// This fixes SSL validation errors if `php.ini` doesn't have
625-
// [curl] `curl.cainfo` set properly of if this PEM file isn't
626-
// up to date. Better rely on the OS certificate authorities, which
627-
// is maintained automatically.
628-
if (defined('CURLSSLOPT_NATIVE_CA')
629-
&& version_compare(curl_version()['version'], '7.71', '>=')) {
630-
curl_setopt($ch, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA);
631-
}
632-
} else {
633-
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
634-
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
635-
}
636-
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
637624
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
638625
if ($methodLower != 'get') {
639626
if ($jsonEncoding) {
@@ -648,9 +635,6 @@ public function callRestAPI($params, $isAddToken, $method = 'GET', $request = nu
648635
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
649636
}
650637
}
651-
if (!is_null($this->timeout)) {
652-
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
653-
}
654638
$response = curl_exec($ch);
655639
$this->curlInfo = curl_getinfo($ch);
656640
$this->curlErrorNumber = curl_errno($ch);
@@ -699,55 +683,37 @@ public function callRestAPI($params, $isAddToken, $method = 'GET', $request = nu
699683
/**
700684
* Return the base64 encoded data in container field.
701685
* Thanks to 'base64bits' as https://github.com/msyk/FMDataAPI/issues/18.
702-
* @param string $name The container field name.
703-
* The table occurrence name of the portal can be the portal name, and also the object name of the portal.
704-
* @param string $toName The table occurrence name of the portal as the prefix of the field name.
686+
* @param string $url
705687
* @return string The base64 encoded data in container field.
706688
* @ignore
707689
*/
708-
public function accessToContainer($url)
690+
public function accessToContainer(string $url): string
709691
{
710-
$cookieFile = tempnam(sys_get_temp_dir(), "CURLCOOKIE"); //create a cookie file
692+
$cookieFile = tempnam(sys_get_temp_dir(), "CURLCOOKIE"); // Create a cookie file.
711693

712-
$ch = curl_init($url); //visit the container URL to set the cookie
694+
// Visit the container URL to set the cookie.
695+
$ch = $this->_createCurlHandle($url);
713696
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile);
714-
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
715-
if ($this->isCertValidating) {
716-
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
717-
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
718-
} else {
719-
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
720-
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
721-
}
722-
if (!is_null($this->timeout)) {
723-
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
724-
}
725697
curl_exec($ch);
726698
if (curl_errno($ch) !== 0) {
727699
$errMsg = curl_error($ch);
700+
curl_close($ch);
728701
throw new Exception("Error in creating cookie file. {$errMsg}");
729702
}
703+
curl_close($ch);
730704

731-
$ch = curl_init($url); //visit container URL again
705+
// Visit the container URL again.
706+
$ch = $this->_createCurlHandle($url);
732707
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile);
733-
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
734-
if ($this->isCertValidating) {
735-
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
736-
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
737-
} else {
738-
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
739-
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
740-
}
741-
if (!is_null($this->timeout)) {
742-
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
743-
}
744708
$output = curl_exec($ch);
745709
if (curl_errno($ch) !== 0) {
746710
$errMsg = curl_error($ch);
711+
curl_close($ch);
747712
throw new Exception("Error in downloading content of file. {$errMsg}");
748713
}
714+
curl_close($ch);
749715

750-
return base64_encode($output); //process the image data as need it
716+
return base64_encode($output); // Process the data as needed.
751717
}
752718

753719
/**
@@ -811,11 +777,11 @@ public function storeToProperties()
811777
* @return string
812778
* @ignore
813779
*/
814-
public function adjustSortDirection($direction)
780+
public function adjustSortDirection($direction): string
815781
{
816782
if (strtoupper($direction) == 'ASC') {
817783
$direction = 'ascend';
818-
} else if (strtoupper($direction) == 'DESC') {
784+
} elseif (strtoupper($direction) == 'DESC') {
819785
$direction = 'descend';
820786
}
821787

@@ -837,7 +803,7 @@ public function getCurlInfo($key)
837803
* @return string
838804
* @ignore
839805
*/
840-
public function debugOutput($isReturnValue = false)
806+
public function debugOutput(bool $isReturnValue = false): string
841807
{
842808
$str = "<div style='background-color: #DDDDDD'>URL: ";
843809
$str .= $this->method . ' ' . htmlspecialchars($this->url);
@@ -872,7 +838,7 @@ public function debugOutput($isReturnValue = false)
872838
* @return string
873839
* @ignore
874840
*/
875-
private function _buildSortParameters($value)
841+
private function _buildSortParameters(array $value): string
876842
{
877843
$param = '[';
878844
foreach ($value as $sortCondition) {
@@ -899,7 +865,7 @@ private function _buildSortParameters($value)
899865
* @return string
900866
* @ignore
901867
*/
902-
private function _json_urlencode($value)
868+
private function _json_urlencode(array $value): string
903869
{
904870
$str = '[';
905871
if (count($value) > 0) {
@@ -914,4 +880,52 @@ private function _json_urlencode($value)
914880

915881
return $str;
916882
}
883+
884+
/**
885+
* To create and configure cURL at a single place, avoiding code redundancy.
886+
* If later we need some specific settings for some cases, then add new
887+
* parameters to this function.
888+
*
889+
* @param string|null $url The URL you want to access.
890+
* @param bool $returnTransfer By default, sets CURLOPT_RETURNTRANSFER to `true`.
891+
* But it can be set to false if needed.
892+
* @return CurlHandle
893+
*/
894+
private function _createCurlHandle(string|null $url = null, bool $returnTransfer = true): CurlHandle
895+
{
896+
$ch = curl_init();
897+
898+
if (!is_null($url)) {
899+
curl_setopt($ch, CURLOPT_URL, $url);
900+
}
901+
902+
if ($returnTransfer) {
903+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
904+
}
905+
906+
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_DEFAULT);
907+
908+
if ($this->isCertValidating) {
909+
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
910+
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
911+
// Use the OS native certificate authorities, if possible.
912+
// This fixes SSL validation errors if `php.ini` doesn't have
913+
// [curl] `curl.cainfo` set properly of if this PEM file isn't
914+
// up to date. Better rely on the OS certificate authorities, which
915+
// is maintained automatically.
916+
if (defined('CURLSSLOPT_NATIVE_CA')
917+
&& version_compare(curl_version()['version'], '7.71', '>=')) {
918+
curl_setopt($ch, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA);
919+
}
920+
} else {
921+
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
922+
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
923+
}
924+
925+
if (!is_null($this->timeout)) {
926+
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
927+
}
928+
929+
return $ch;
930+
}
917931
}

0 commit comments

Comments
 (0)