From e76864b5c567856638387f4f6d98e17bb72f060a Mon Sep 17 00:00:00 2001 From: Mahmoud Ashraf <182176867+SNO7E-G@users.noreply.github.com> Date: Fri, 27 Mar 2026 07:37:11 +0500 Subject: [PATCH 1/2] refactor: use readonly classes with promoted constructors for DTOs --- src/ReCaptcha/RequestParameters.php | 35 +++--------- src/ReCaptcha/Response.php | 68 ++++++----------------- tests/ReCaptcha/RequestParametersTest.php | 6 ++ tests/ReCaptcha/ResponseTest.php | 6 ++ 4 files changed, 37 insertions(+), 78 deletions(-) diff --git a/src/ReCaptcha/RequestParameters.php b/src/ReCaptcha/RequestParameters.php index 2614b41..fd20b14 100644 --- a/src/ReCaptcha/RequestParameters.php +++ b/src/ReCaptcha/RequestParameters.php @@ -42,28 +42,8 @@ /** * Stores and formats the parameters for the request to the reCAPTCHA service. */ -class RequestParameters +readonly class RequestParameters { - /** - * The shared key between your site and reCAPTCHA. - */ - private string $secret; - - /** - * The user response token provided by reCAPTCHA, verifying the user on your site. - */ - private string $response; - - /** - * Remote user's IP address. - */ - private ?string $remoteIp; - - /** - * Client version. - */ - private ?string $version; - /** * Initialise parameters. * @@ -72,13 +52,12 @@ class RequestParameters * @param null|string $remoteIp user's IP address * @param null|string $version version of this client library */ - public function __construct(string $secret, string $response, ?string $remoteIp = null, ?string $version = null) - { - $this->secret = $secret; - $this->response = $response; - $this->remoteIp = $remoteIp; - $this->version = $version; - } + public function __construct( + private string $secret, + private string $response, + private ?string $remoteIp = null, + private ?string $version = null, + ) {} /** * Array representation. diff --git a/src/ReCaptcha/Response.php b/src/ReCaptcha/Response.php index 852439b..7cdf9e0 100644 --- a/src/ReCaptcha/Response.php +++ b/src/ReCaptcha/Response.php @@ -42,60 +42,28 @@ /** * The response returned from the service. */ -class Response +readonly class Response { - /** - * Success or failure. - */ - private bool $success = false; - - /** - * Error code strings. - * - * @var array - */ - private array $errorCodes = []; - - /** - * The hostname of the site where the reCAPTCHA was solved. - */ - private string $hostname; - - /** - * Timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ). - */ - private string $challengeTs; - - /** - * APK package name. - */ - private string $apkPackageName; - - /** - * Score assigned to the request. - */ - private ?float $score; - - /** - * Action as specified by the page. - */ - private string $action; - /** * Constructor. * - * @param array $errorCodes - */ - public function __construct(bool $success, array $errorCodes = [], string $hostname = '', string $challengeTs = '', string $apkPackageName = '', ?float $score = null, string $action = '') - { - $this->success = $success; - $this->hostname = $hostname; - $this->challengeTs = $challengeTs; - $this->apkPackageName = $apkPackageName; - $this->score = $score; - $this->action = $action; - $this->errorCodes = $errorCodes; - } + * @param bool $success success or failure + * @param array $errorCodes error code strings + * @param string $hostname the hostname of the site where the reCAPTCHA was solved + * @param string $challengeTs timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ) + * @param string $apkPackageName APK package name + * @param ?float $score score assigned to the request + * @param string $action action as specified by the page + */ + public function __construct( + private bool $success, + private array $errorCodes = [], + private string $hostname = '', + private string $challengeTs = '', + private string $apkPackageName = '', + private ?float $score = null, + private string $action = '', + ) {} /** * Build the response from the expected JSON returned by the service. diff --git a/tests/ReCaptcha/RequestParametersTest.php b/tests/ReCaptcha/RequestParametersTest.php index 8b5bcdc..8e9aca5 100644 --- a/tests/ReCaptcha/RequestParametersTest.php +++ b/tests/ReCaptcha/RequestParametersTest.php @@ -49,6 +49,12 @@ */ class RequestParametersTest extends TestCase { + public function testClassIsReadonly(): void + { + $reflection = new \ReflectionClass(RequestParameters::class); + $this->assertTrue($reflection->isReadOnly()); + } + /** * @param array $expectedArray */ diff --git a/tests/ReCaptcha/ResponseTest.php b/tests/ReCaptcha/ResponseTest.php index c18a8a4..a729e9b 100644 --- a/tests/ReCaptcha/ResponseTest.php +++ b/tests/ReCaptcha/ResponseTest.php @@ -49,6 +49,12 @@ */ class ResponseTest extends TestCase { + public function testClassIsReadonly(): void + { + $reflection = new \ReflectionClass(Response::class); + $this->assertTrue($reflection->isReadOnly()); + } + /** * @param array $errorCodes */ From 049637d4fd77daff29130eb29fd16057a6fc65bd Mon Sep 17 00:00:00 2001 From: Mahmoud Ashraf <182176867+SNO7E-G@users.noreply.github.com> Date: Mon, 30 Mar 2026 01:22:11 +0500 Subject: [PATCH 2/2] test: drop reflection-based readonly class checks per review --- tests/ReCaptcha/RequestParametersTest.php | 6 ------ tests/ReCaptcha/ResponseTest.php | 6 ------ 2 files changed, 12 deletions(-) diff --git a/tests/ReCaptcha/RequestParametersTest.php b/tests/ReCaptcha/RequestParametersTest.php index 8e9aca5..8b5bcdc 100644 --- a/tests/ReCaptcha/RequestParametersTest.php +++ b/tests/ReCaptcha/RequestParametersTest.php @@ -49,12 +49,6 @@ */ class RequestParametersTest extends TestCase { - public function testClassIsReadonly(): void - { - $reflection = new \ReflectionClass(RequestParameters::class); - $this->assertTrue($reflection->isReadOnly()); - } - /** * @param array $expectedArray */ diff --git a/tests/ReCaptcha/ResponseTest.php b/tests/ReCaptcha/ResponseTest.php index a729e9b..c18a8a4 100644 --- a/tests/ReCaptcha/ResponseTest.php +++ b/tests/ReCaptcha/ResponseTest.php @@ -49,12 +49,6 @@ */ class ResponseTest extends TestCase { - public function testClassIsReadonly(): void - { - $reflection = new \ReflectionClass(Response::class); - $this->assertTrue($reflection->isReadOnly()); - } - /** * @param array $errorCodes */