From 66a9641c48c3b68fef52e461f21729f37dbb36a6 Mon Sep 17 00:00:00 2001 From: Giorgio Consorti Date: Fri, 7 Feb 2020 17:08:20 +0100 Subject: [PATCH 1/6] add CSRF token support for OpenRefine 3.3 onwards --- src/Keboola/OpenRefine/Client.php | 128 ++++++++++++++++++++++++++++-- 1 file changed, 122 insertions(+), 6 deletions(-) diff --git a/src/Keboola/OpenRefine/Client.php b/src/Keboola/OpenRefine/Client.php index f0fe377..025f495 100644 --- a/src/Keboola/OpenRefine/Client.php +++ b/src/Keboola/OpenRefine/Client.php @@ -21,6 +21,25 @@ class Client */ protected $temp; + /** + * the CSRF token + * + * @var string + */ + protected $csrfToken; + + /** + * OpenRefine server version + * + * @var null|string + */ + static private $version = null; + + /** + * Minimum version of OpenRefine for which the CSRF token must be used + */ + const MIN_VERSION_FOR_CSRF = '3.3'; + /** * Client constructor. * @@ -46,8 +65,7 @@ public function createProject(CsvFile $file, string $name): string } try { - $response = $this->client->request( - "POST", + $response = $this->post( "create-project-from-upload", [ "multipart" => [ @@ -87,8 +105,7 @@ public function createProject(CsvFile $file, string $name): string public function applyOperations(string $projectId, array $operations): void { try { - $response = $this->client->request( - "POST", + $response = $this->post( "apply-operations", [ "form_params" => [ @@ -116,7 +133,7 @@ public function applyOperations(string $projectId, array $operations): void public function exportRowsToCsv(string $projectId): CsvFile { - $response = $this->client->request("POST", "export-rows", [ + $response = $this->post("export-rows", [ "form_params" => [ "project" => $projectId, "format" => "csv", @@ -157,7 +174,7 @@ public function getProjectMetadata(string $projectId) public function deleteProject(string $projectId): void { - $response = $this->client->request("POST", "delete-project", [ + $response = $this->post("delete-project", [ "form_params" => [ "project" => $projectId, ], @@ -197,4 +214,103 @@ protected function getResponseError(Response $response) return $decodedResponse["code"]; } } + + /** + * Sets the OpenRefine version calling the get-version endpoint + * + * @return void + */ + private function setVersion(): void + { + if (is_null(self::$version)) { + self::$version = "0.0"; + $response = $this->client->request("GET", "get-version"); + if (!$this->isResponseError($response)) { + $decodedResponse = json_decode($response->getBody()->__toString(), true); + if (array_key_exists("version", $decodedResponse)) { + self::$version = $decodedResponse["version"]; + } + } + } + } + + /** + * Gets the OpenRefine version + * + * @return string + */ + protected function getVersion(): string + { + if (is_null(self::$version)) $this->setVersion(); + return self::$version; + } + + /** + * Gets the CSRF token + * + * @return string + */ + protected function getCsrfToken(): string + { + try { + $this->setCsrfToken(); + } catch (Exception $e) { + $this->csrfToken = ""; + } + return $this->csrfToken; + } + + /** + * Sets the CSRF token calling the get-csrf-token endpoint + * + * @return void + */ + protected function setCsrfToken(): void + { + $token = ""; + $error = false; + if (is_null($this->csrfToken) && version_compare(self::getVersion(), self::MIN_VERSION_FOR_CSRF, '>=')) { + $response = $this->client->request("GET", "get-csrf-token"); + if (!$this->isResponseError($response)) { + $decodedResponse = json_decode($response->getBody()->__toString(), true); + if (array_key_exists("token", $decodedResponse)) $token = $decodedResponse["token"]; + else $error = true; + } else $error = true; + } + if ($error) { + throw new Exception("Cannot GET the CSRF token"); + } + $this->csrfToken = $token; + } + + /** + * Does the post request using the client and setting the CSRF token if needed + * + * @param string $endpoint + * @param array $params + * @return \Psr\Http\Message\ResponseInterface + */ + protected function post(string $endpoint, array $params = []): \Psr\Http\Message\ResponseInterface + { + if (version_compare(self::getVersion(), self::MIN_VERSION_FOR_CSRF, '>=')) { + $this->csrfToken = $this->getCsrfToken(); + if ($this->csrfToken !== "") { + if (stristr($endpoint,"create") !== false) { + $endpoint .= '?csrf_token='.$this->csrfToken; + } else if (array_key_exists('multipart', $params)) { + array_push($params['multipart'],[ + 'name' => "csrf_token", + 'contents' => $this->csrfToken + ]); + } else if (array_key_exists('form_params', $params)) { + $params['form_params']['csrf_token'] = $this->csrfToken; + } else { + $params["csrf_token"] = $this->csrfToken; + } + } + // The CSRF token is a one timer, forget it to get a new one + $this->csrfToken = null; + } + return $this->client->request("POST", $endpoint, $params); + } } From 13b7197c727c36c7b4adbb90e53ac86b39bcd0c3 Mon Sep 17 00:00:00 2001 From: Giorgio Consorti Date: Mon, 10 Feb 2020 10:59:50 +0100 Subject: [PATCH 2/6] fix phpcs errors --- src/Keboola/OpenRefine/Client.php | 126 +++++++++--------- .../OpenRefine/ApplyOperationsTest.php | 10 +- .../Keboola/OpenRefine/CreateProjectTest.php | 26 ++-- .../Keboola/OpenRefine/DeleteProjectTest.php | 10 +- .../OpenRefine/ExportProjectToCsvTest.php | 10 +- 5 files changed, 93 insertions(+), 89 deletions(-) diff --git a/src/Keboola/OpenRefine/Client.php b/src/Keboola/OpenRefine/Client.php index 025f495..b0142e5 100644 --- a/src/Keboola/OpenRefine/Client.php +++ b/src/Keboola/OpenRefine/Client.php @@ -33,12 +33,12 @@ class Client * * @var null|string */ - static private $version = null; + private static $version = null; /** * Minimum version of OpenRefine for which the CSRF token must be used */ - const MIN_VERSION_FOR_CSRF = '3.3'; + protected const MIN_VERSION_FOR_CSRF = '3.3'; /** * Client constructor. @@ -47,10 +47,10 @@ class Client * @param string $port * @param Temp|null $temp */ - public function __construct(string $host = "localhost", string $port = "3333", ?Temp $temp = null) + public function __construct(string $host = 'localhost', string $port = '3333', ?Temp $temp = null) { $this->client = new \GuzzleHttp\Client([ - "base_uri" => "http://" . $host . ":" . $port . "/command/core/", + 'base_uri' => 'http://' . $host . ':' . $port . '/command/core/', ]); if (!$temp) { $temp = new Temp(); @@ -61,39 +61,39 @@ public function __construct(string $host = "localhost", string $port = "3333", ? public function createProject(CsvFile $file, string $name): string { if ($file->getColumnsCount() === 0) { - throw new Exception("Empty file"); + throw new Exception('Empty file'); } try { $response = $this->post( - "create-project-from-upload", + 'create-project-from-upload', [ - "multipart" => [ + 'multipart' => [ [ - "name" => "project-file", - "contents" => fopen($file->getPathname(), "r"), + 'name' => 'project-file', + 'contents' => fopen($file->getPathname(), 'r'), ], [ - "name" => "project-name", - "contents" => $name, + 'name' => 'project-name', + 'contents' => $name, ], ], - "allow_redirects" => false, + 'allow_redirects' => false, ] ); } catch (ServerException $e) { $response = $e->getResponse(); if ($response && $response->getReasonPhrase() === 'GC overhead limit exceeded') { - throw new Exception("OpenRefine is out of memory. Data set too large."); + throw new Exception('OpenRefine is out of memory. Data set too large.'); } throw $e; } if ($response->getStatusCode() !== 302) { - throw new Exception("Cannot create project: {$response->getStatusCode()}"); + throw new Exception('Cannot create project: {$response->getStatusCode()}'); } - $url = $response->getHeader("Location")[0]; - $projectId = substr($url, strrpos($url, "=") + 1); + $url = $response->getHeader('Location')[0]; + $projectId = substr($url, strrpos($url, '=') + 1); return $projectId; } @@ -106,47 +106,47 @@ public function applyOperations(string $projectId, array $operations): void { try { $response = $this->post( - "apply-operations", + 'apply-operations', [ - "form_params" => [ - "project" => $projectId, - "operations" => json_encode($operations), + 'form_params' => [ + 'project' => $projectId, + 'operations' => json_encode($operations), ], ] ); } catch (ServerException $e) { $response = $e->getResponse(); if ($response && $response->getReasonPhrase() === 'GC overhead limit exceeded') { - throw new Exception("OpenRefine is out of memory. Data set too large."); + throw new Exception('OpenRefine is out of memory. Data set too large.'); } throw $e; } if ($response->getStatusCode() !== 200) { // Actually never managed to get here - throw new Exception("Cannot apply operations: ({$response->getStatusCode()}) {$response->getBody()}"); + throw new Exception('Cannot apply operations: ({$response->getStatusCode()}) {$response->getBody()}'); } if ($this->isResponseError($response)) { - throw new Exception("Cannot apply operations: {$this->getResponseError($response)}"); + throw new Exception('Cannot apply operations: {$this->getResponseError($response)}'); } } public function exportRowsToCsv(string $projectId): CsvFile { - $response = $this->post("export-rows", [ - "form_params" => [ - "project" => $projectId, - "format" => "csv", + $response = $this->post('export-rows', [ + 'form_params' => [ + 'project' => $projectId, + 'format' => 'csv', ], ]); if ($response->getStatusCode() !== 200) { - throw new Exception("Cannot export rows: ({$response->getStatusCode()}) {$response->getBody()}"); + throw new Exception('Cannot export rows: ({$response->getStatusCode()}) {$response->getBody()}'); } - $fileName = $this->temp->createFile("data.csv", true)->getPathname(); - $handle = fopen($fileName, "w"); + $fileName = $this->temp->createFile('data.csv', true)->getPathname(); + $handle = fopen($fileName, 'w'); if (!$handle) { - throw new Exception("Cannot open file " . $fileName . " for writing."); + throw new Exception('Cannot open file ' . $fileName . ' for writing.'); } $buffer = $response->getBody()->read(1000); while ($buffer !== '') { @@ -164,9 +164,9 @@ public function exportRowsToCsv(string $projectId): CsvFile */ public function getProjectMetadata(string $projectId) { - $response = $this->client->request("GET", "get-project-metadata?project={$projectId}"); + $response = $this->client->request('GET', 'get-project-metadata?project={$projectId}'); if ($this->isResponseError($response)) { - throw new Exception("Project not found: {$this->getResponseError($response)}"); + throw new Exception('Project not found: {$this->getResponseError($response)}'); } $decodedResponse = json_decode($response->getBody()->__toString(), true); return $decodedResponse; @@ -174,26 +174,26 @@ public function getProjectMetadata(string $projectId) public function deleteProject(string $projectId): void { - $response = $this->post("delete-project", [ - "form_params" => [ - "project" => $projectId, + $response = $this->post('delete-project', [ + 'form_params' => [ + 'project' => $projectId, ], ]); if ($response->getStatusCode() !== 200) { // Actually never managed to get here - throw new Exception("Cannot delete project: ({$response->getStatusCode()}) {$response->getBody()}"); + throw new Exception('Cannot delete project: ({$response->getStatusCode()}) {$response->getBody()}'); } if ($this->isResponseError($response)) { - throw new Exception("Cannot delete project: {$this->getResponseError($response)}"); + throw new Exception('Cannot delete project: {$this->getResponseError($response)}'); } } protected function isResponseError(Response $response): bool { $decodedResponse = json_decode($response->getBody()->__toString(), true); - if (isset($decodedResponse["status"]) && $decodedResponse["status"] === "error" || - isset($decodedResponse["code"]) && $decodedResponse["code"] === "error" + if (isset($decodedResponse['status']) && $decodedResponse['status'] === 'error' || + isset($decodedResponse['code']) && $decodedResponse['code'] === 'error' ) { return true; } @@ -207,11 +207,11 @@ protected function isResponseError(Response $response): bool protected function getResponseError(Response $response) { $decodedResponse = json_decode($response->getBody()->__toString(), true); - if (isset($decodedResponse["status"])) { - return $decodedResponse["status"]; + if (isset($decodedResponse['status'])) { + return $decodedResponse['status']; } - if (isset($decodedResponse["code"])) { - return $decodedResponse["code"]; + if (isset($decodedResponse['code'])) { + return $decodedResponse['code']; } } @@ -223,12 +223,12 @@ protected function getResponseError(Response $response) private function setVersion(): void { if (is_null(self::$version)) { - self::$version = "0.0"; - $response = $this->client->request("GET", "get-version"); + self::$version = '0.0'; + $response = $this->client->request('GET', 'get-version'); if (!$this->isResponseError($response)) { $decodedResponse = json_decode($response->getBody()->__toString(), true); - if (array_key_exists("version", $decodedResponse)) { - self::$version = $decodedResponse["version"]; + if (array_key_exists('version', $decodedResponse)) { + self::$version = $decodedResponse['version']; } } } @@ -241,7 +241,9 @@ private function setVersion(): void */ protected function getVersion(): string { - if (is_null(self::$version)) $this->setVersion(); + if (is_null(self::$version)) { + $this->setVersion(); + } return self::$version; } @@ -255,7 +257,7 @@ protected function getCsrfToken(): string try { $this->setCsrfToken(); } catch (Exception $e) { - $this->csrfToken = ""; + $this->csrfToken = ''; } return $this->csrfToken; } @@ -267,18 +269,20 @@ protected function getCsrfToken(): string */ protected function setCsrfToken(): void { - $token = ""; + $token = ''; $error = false; if (is_null($this->csrfToken) && version_compare(self::getVersion(), self::MIN_VERSION_FOR_CSRF, '>=')) { - $response = $this->client->request("GET", "get-csrf-token"); + $response = $this->client->request('GET', 'get-csrf-token'); if (!$this->isResponseError($response)) { $decodedResponse = json_decode($response->getBody()->__toString(), true); - if (array_key_exists("token", $decodedResponse)) $token = $decodedResponse["token"]; + if (array_key_exists('token', $decodedResponse)) { + $token = $decodedResponse['token']; + } else $error = true; } else $error = true; } if ($error) { - throw new Exception("Cannot GET the CSRF token"); + throw new Exception('Cannot GET the CSRF token'); } $this->csrfToken = $token; } @@ -294,23 +298,23 @@ protected function post(string $endpoint, array $params = []): \Psr\Http\Message { if (version_compare(self::getVersion(), self::MIN_VERSION_FOR_CSRF, '>=')) { $this->csrfToken = $this->getCsrfToken(); - if ($this->csrfToken !== "") { - if (stristr($endpoint,"create") !== false) { + if ($this->csrfToken !== '') { + if (stristr($endpoint, 'create') !== false) { $endpoint .= '?csrf_token='.$this->csrfToken; } else if (array_key_exists('multipart', $params)) { - array_push($params['multipart'],[ - 'name' => "csrf_token", - 'contents' => $this->csrfToken + array_push($params['multipart'], [ + 'name' => 'csrf_token', + 'contents' => $this->csrfToken, ]); } else if (array_key_exists('form_params', $params)) { $params['form_params']['csrf_token'] = $this->csrfToken; } else { - $params["csrf_token"] = $this->csrfToken; + $params['csrf_token'] = $this->csrfToken; } } // The CSRF token is a one timer, forget it to get a new one $this->csrfToken = null; } - return $this->client->request("POST", $endpoint, $params); + return $this->client->request('POST', $endpoint, $params); } } diff --git a/tests/Keboola/OpenRefine/ApplyOperationsTest.php b/tests/Keboola/OpenRefine/ApplyOperationsTest.php index 8d1d20a..9f6e76a 100644 --- a/tests/Keboola/OpenRefine/ApplyOperationsTest.php +++ b/tests/Keboola/OpenRefine/ApplyOperationsTest.php @@ -11,13 +11,13 @@ class ApplyOperationsTest extends \PHPUnit_Framework_TestCase { public function testApplyOperationsSuccess(): void { - $client = new Client(getenv("OPENREFINE_HOST"), getenv("OPENREFINE_PORT")); + $client = new Client(getenv('OPENREFINE_HOST'), getenv('OPENREFINE_PORT')); $temp = new Temp(); - $fileInfo = $temp->createFile("file.csv"); + $fileInfo = $temp->createFile('file.csv'); $csv = new CsvFile($fileInfo->getPathname()); - $csv->writeRow(["col1", "col2"]); - $csv->writeRow(["A", "B"]); - $projectId = $client->createProject($csv, "test"); + $csv->writeRow(['col1', 'col2']); + $csv->writeRow(['A', 'B']); + $projectId = $client->createProject($csv, 'test'); $operationsJSON = <<createFile("file.csv"); + $fileInfo = $temp->createFile('file.csv'); $csv = new CsvFile($fileInfo->getPathname()); - $csv->writeRow(["col1", "col2"]); - $csv->writeRow(["A", "B"]); - $projectId = $client->createProject($csv, "test"); - $this->assertNotNull($projectId, "Did not return project id"); - $this->assertRegExp("/^[0-9]*$/", $projectId); + $csv->writeRow(['col1', 'col2']); + $csv->writeRow(['A', 'B']); + $projectId = $client->createProject($csv, 'test'); + $this->assertNotNull($projectId, 'Did not return project id'); + $this->assertRegExp('/^[0-9]*$/', $projectId); $this->assertGreaterThan(0, $projectId); - $this->assertEquals("test", $client->getProjectMetadata($projectId)["name"]); + $this->assertEquals('test', $client->getProjectMetadata($projectId)['name']); $outCsv = $client->exportRowsToCsv($projectId); - $this->assertEquals("col1,col2\nA,B\n", file_get_contents($outCsv->getPathname())); + $this->assertEquals('col1,col2\nA,B\n', file_get_contents($outCsv->getPathname())); } public function testsCreateProjectEmptyFile(): void { $this->expectException(Exception::class); - $this->expectExceptionMessage("Empty file"); - $client = new Client(getenv("OPENREFINE_HOST"), getenv("OPENREFINE_PORT")); + $this->expectExceptionMessage('Empty file'); + $client = new Client(getenv('OPENREFINE_HOST'), getenv('OPENREFINE_PORT')); $temp = new Temp(); - $fileInfo = $temp->createFile("empty_file.csv"); + $fileInfo = $temp->createFile('empty_file.csv'); $csv = new CsvFile($fileInfo->getPathname()); - $client->createProject($csv, "test"); + $client->createProject($csv, 'test'); } } diff --git a/tests/Keboola/OpenRefine/DeleteProjectTest.php b/tests/Keboola/OpenRefine/DeleteProjectTest.php index 2c03082..ff870f2 100644 --- a/tests/Keboola/OpenRefine/DeleteProjectTest.php +++ b/tests/Keboola/OpenRefine/DeleteProjectTest.php @@ -11,13 +11,13 @@ class DeleteProjectTest extends \PHPUnit_Framework_TestCase { public function testDeleteProjectSuccess(): void { - $client = new Client(getenv("OPENREFINE_HOST"), getenv("OPENREFINE_PORT")); + $client = new Client(getenv('OPENREFINE_HOST'), getenv('OPENREFINE_PORT')); $temp = new Temp(); - $fileInfo = $temp->createFile("file.csv"); + $fileInfo = $temp->createFile('file.csv'); $csv = new CsvFile($fileInfo->getPathname()); - $csv->writeRow(["col1", "col2"]); - $csv->writeRow(["A", "B"]); - $projectId = $client->createProject($csv, "test"); + $csv->writeRow(['col1', 'col2']); + $csv->writeRow(['A', 'B']); + $projectId = $client->createProject($csv, 'test'); $client->deleteProject($projectId); } } diff --git a/tests/Keboola/OpenRefine/ExportProjectToCsvTest.php b/tests/Keboola/OpenRefine/ExportProjectToCsvTest.php index 9799bdb..07bdee7 100644 --- a/tests/Keboola/OpenRefine/ExportProjectToCsvTest.php +++ b/tests/Keboola/OpenRefine/ExportProjectToCsvTest.php @@ -11,13 +11,13 @@ class ExportProjecetToCsvTest extends \PHPUnit_Framework_TestCase { public function testCreateProjectSuccess(): void { - $client = new Client(getenv("OPENREFINE_HOST"), getenv("OPENREFINE_PORT")); + $client = new Client(getenv('OPENREFINE_HOST'), getenv('OPENREFINE_PORT')); $temp = new Temp(); - $fileInfo = $temp->createFile("file.csv"); + $fileInfo = $temp->createFile('file.csv'); $csv = new CsvFile($fileInfo->getPathname()); - $csv->writeRow(["col1", "col2"]); - $csv->writeRow(["A", "B"]); - $projectId = $client->createProject($csv, "test"); + $csv->writeRow(['col1', 'col2']); + $csv->writeRow(['A', 'B']); + $projectId = $client->createProject($csv, 'test'); $file = $client->exportRowsToCsv($projectId); $this->assertInstanceOf(CsvFile::class, $file); } From e3671079fd62d3c25b506b0f43c0f52af309a565 Mon Sep 17 00:00:00 2001 From: Giorgio Consorti Date: Mon, 10 Feb 2020 11:05:20 +0100 Subject: [PATCH 3/6] fix phpcs errors --- src/Keboola/OpenRefine/Client.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Keboola/OpenRefine/Client.php b/src/Keboola/OpenRefine/Client.php index b0142e5..b9172f9 100644 --- a/src/Keboola/OpenRefine/Client.php +++ b/src/Keboola/OpenRefine/Client.php @@ -277,9 +277,12 @@ protected function setCsrfToken(): void $decodedResponse = json_decode($response->getBody()->__toString(), true); if (array_key_exists('token', $decodedResponse)) { $token = $decodedResponse['token']; + } else { + $error = true; } - else $error = true; - } else $error = true; + } else { + $error = true; + } } if ($error) { throw new Exception('Cannot GET the CSRF token'); From 1c9567ce0dcab9bb89e861701d2e8dea2c11da0a Mon Sep 17 00:00:00 2001 From: Giorgio Consorti Date: Mon, 10 Feb 2020 11:49:49 +0100 Subject: [PATCH 4/6] fix phpstan errors --- src/Keboola/OpenRefine/Client.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Keboola/OpenRefine/Client.php b/src/Keboola/OpenRefine/Client.php index b9172f9..54cb824 100644 --- a/src/Keboola/OpenRefine/Client.php +++ b/src/Keboola/OpenRefine/Client.php @@ -24,7 +24,7 @@ class Client /** * the CSRF token * - * @var string + * @var null|string */ protected $csrfToken; @@ -239,7 +239,7 @@ private function setVersion(): void * * @return string */ - protected function getVersion(): string + protected function getVersion(): ?string { if (is_null(self::$version)) { $this->setVersion(); @@ -295,9 +295,9 @@ protected function setCsrfToken(): void * * @param string $endpoint * @param array $params - * @return \Psr\Http\Message\ResponseInterface + * @return \GuzzleHttp\Psr7\Response */ - protected function post(string $endpoint, array $params = []): \Psr\Http\Message\ResponseInterface + protected function post(string $endpoint, array $params = []): \GuzzleHttp\Psr7\Response { if (version_compare(self::getVersion(), self::MIN_VERSION_FOR_CSRF, '>=')) { $this->csrfToken = $this->getCsrfToken(); From ec618d73fb070d73b28fe3ac862f86be72e48ba1 Mon Sep 17 00:00:00 2001 From: Giorgio Consorti Date: Mon, 10 Feb 2020 12:16:03 +0100 Subject: [PATCH 5/6] fix phpstan errors --- src/Keboola/OpenRefine/Client.php | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/Keboola/OpenRefine/Client.php b/src/Keboola/OpenRefine/Client.php index 54cb824..6598243 100644 --- a/src/Keboola/OpenRefine/Client.php +++ b/src/Keboola/OpenRefine/Client.php @@ -8,6 +8,7 @@ use GuzzleHttp\Psr7\Response; use Keboola\Csv\CsvFile; use Keboola\Temp\Temp; +use Psr\Http\Message\ResponseInterface; class Client { @@ -189,7 +190,7 @@ public function deleteProject(string $projectId): void } } - protected function isResponseError(Response $response): bool + protected function isResponseError(ResponseInterface $response): bool { $decodedResponse = json_decode($response->getBody()->__toString(), true); if (isset($decodedResponse['status']) && $decodedResponse['status'] === 'error' || @@ -237,7 +238,7 @@ private function setVersion(): void /** * Gets the OpenRefine version * - * @return string + * @return string|null */ protected function getVersion(): ?string { @@ -250,9 +251,9 @@ protected function getVersion(): ?string /** * Gets the CSRF token * - * @return string + * @return string|null */ - protected function getCsrfToken(): string + protected function getCsrfToken(): ?string { try { $this->setCsrfToken(); @@ -271,7 +272,8 @@ protected function setCsrfToken(): void { $token = ''; $error = false; - if (is_null($this->csrfToken) && version_compare(self::getVersion(), self::MIN_VERSION_FOR_CSRF, '>=')) { + $version = is_null(self::getVersion()) ? '0.0' : self::getVersion(); + if (is_null($this->csrfToken) && version_compare($version, self::MIN_VERSION_FOR_CSRF, '>=')) { $response = $this->client->request('GET', 'get-csrf-token'); if (!$this->isResponseError($response)) { $decodedResponse = json_decode($response->getBody()->__toString(), true); @@ -295,11 +297,12 @@ protected function setCsrfToken(): void * * @param string $endpoint * @param array $params - * @return \GuzzleHttp\Psr7\Response + * @return ResponseInterface */ - protected function post(string $endpoint, array $params = []): \GuzzleHttp\Psr7\Response + protected function post(string $endpoint, array $params = []): ResponseInterface { - if (version_compare(self::getVersion(), self::MIN_VERSION_FOR_CSRF, '>=')) { + $version = is_null(self::getVersion()) ? '0.0' : self::getVersion(); + if (version_compare($version, self::MIN_VERSION_FOR_CSRF, '>=')) { $this->csrfToken = $this->getCsrfToken(); if ($this->csrfToken !== '') { if (stristr($endpoint, 'create') !== false) { From e07f62643face9bfd0e7774ab35363b87e07d026 Mon Sep 17 00:00:00 2001 From: Giorgio Consorti Date: Tue, 3 Mar 2020 18:11:38 +0100 Subject: [PATCH 6/6] substitute single with double quotes where needed --- src/Keboola/OpenRefine/Client.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Keboola/OpenRefine/Client.php b/src/Keboola/OpenRefine/Client.php index 6598243..863d8e9 100644 --- a/src/Keboola/OpenRefine/Client.php +++ b/src/Keboola/OpenRefine/Client.php @@ -91,7 +91,7 @@ public function createProject(CsvFile $file, string $name): string } if ($response->getStatusCode() !== 302) { - throw new Exception('Cannot create project: {$response->getStatusCode()}'); + throw new Exception("Cannot create project: {$response->getStatusCode()}"); } $url = $response->getHeader('Location')[0]; $projectId = substr($url, strrpos($url, '=') + 1); @@ -125,10 +125,10 @@ public function applyOperations(string $projectId, array $operations): void if ($response->getStatusCode() !== 200) { // Actually never managed to get here - throw new Exception('Cannot apply operations: ({$response->getStatusCode()}) {$response->getBody()}'); + throw new Exception("Cannot apply operations: ({$response->getStatusCode()}) {$response->getBody()}"); } if ($this->isResponseError($response)) { - throw new Exception('Cannot apply operations: {$this->getResponseError($response)}'); + throw new Exception("Cannot apply operations: {$this->getResponseError($response)}"); } } @@ -141,7 +141,7 @@ public function exportRowsToCsv(string $projectId): CsvFile ], ]); if ($response->getStatusCode() !== 200) { - throw new Exception('Cannot export rows: ({$response->getStatusCode()}) {$response->getBody()}'); + throw new Exception("Cannot export rows: ({$response->getStatusCode()}) {$response->getBody()}"); } $fileName = $this->temp->createFile('data.csv', true)->getPathname(); @@ -165,9 +165,9 @@ public function exportRowsToCsv(string $projectId): CsvFile */ public function getProjectMetadata(string $projectId) { - $response = $this->client->request('GET', 'get-project-metadata?project={$projectId}'); + $response = $this->client->request('GET', "get-project-metadata?project={$projectId}"); if ($this->isResponseError($response)) { - throw new Exception('Project not found: {$this->getResponseError($response)}'); + throw new Exception("Project not found: {$this->getResponseError($response)}"); } $decodedResponse = json_decode($response->getBody()->__toString(), true); return $decodedResponse; @@ -183,10 +183,10 @@ public function deleteProject(string $projectId): void if ($response->getStatusCode() !== 200) { // Actually never managed to get here - throw new Exception('Cannot delete project: ({$response->getStatusCode()}) {$response->getBody()}'); + throw new Exception("Cannot delete project: ({$response->getStatusCode()}) {$response->getBody()}"); } if ($this->isResponseError($response)) { - throw new Exception('Cannot delete project: {$this->getResponseError($response)}'); + throw new Exception("Cannot delete project: {$this->getResponseError($response)}"); } }