Repository: auth0/auth0-PHP (php)

Issue:
Cannot empty  initiate_login_uri with API
### Checklist

- [X] This can be reproduced in [the quickstart sample application](https://github.com/auth0-samples/auth0-php-web-app).
- [X] I have reviewed [the README.md](https://github.com/auth0/auth0-PHP/blob/main/README.md) and have not found a solution.
- [X] I have reviewed [the EXAMPLES.md](https://github.com/auth0/auth0-PHP/blob/main/EXAMPLES.md) and have not found a solution.
- [X] I have searched [previous issues](https://github.com/auth0/auth0-PHP/issues) and have not found a solution.
- [X] I have searched [the Auth0 Community](https://community.auth0.com/tag/auth0-php) and have not found a solution.
- [X] I agree to adhere to the [Auth0 General Contribution Guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md).
- [X] I agree to uphold the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md).

### SDK Version

8.7

### PHP Version

PHP 8.2

### Description

When performing a call to update a client with the call https://auth0.com/docs/api/management/v2/clients/patch-clients-by-id, we get an error when me make the field initiate_login_uri empty.

Failed to update Auth0 client(s) {"integration_id":"89826f96-ed00-4110-8fca-5a909cb6442c","exception":"[object] (App\\Auth0\\Auth0SDKException(code: 400): Auth0 responded with status code 400 instead of 201. Response body: {\"statusCode\":400,\"error\":\"Bad Request\",\"message\":\"Payload validation error: 'Expected type string but found type null' on property initiate_login_uri (Initiate login uri, must be https).\",\"errorCode\":\"invalid_body\"} at /var/www/html/app/Auth0/Auth0SDKException.php:17)

Problem is the class vendor/auth0/auth0-php/src/Utility/Toolkit/Filter/StringFilter.php, line 40, it changes all empty string '' values to a NULL, but the API cannot handle this.

We need a change so this field is not set to NULL when empty.

Currently, I have fixed it in the  \Auth0\SDK\API\Management\Clients::update class, to add an extra check and restore the empty value.
This code fixes it:

```
public function update(
        string $id,
        ?array $body = null,
        ?RequestOptions $options = null,
    ): ResponseInterface {
        [$id] = Toolkit::filter([$id])->string()->trim();
        [$body] = Toolkit::filter([$body])->array()->trim();

        if(isset($body['initiate_login_uri']) && $body['initiate_login_uri'] === null) {
            $body['initiate_login_uri'] = '';
        }

        Toolkit::assert([
            [$id, \Auth0\SDK\Exception\ArgumentException::missing('id')],
        ])->isString();

        return $this->getHttpClient()
            ->method('patch')->addPath(['clients', $id])
            ->withBody($body ?? [])
            ->withOptions($options)
            ->call();
    }
```

### How can we reproduce this issue?

Do a call with \Auth0\SDK\API\Management\Clients::update with an empty initiate_login_uri.

Pull request:
[SDK-4665] Support `initiate_login_uri` property being an empty string for PATCH /api/v2/clients/:id requests.
### Changes

This PR adds support for `initiate_login_uri` to be supplied as an empty string to the `/api/v2/clients/:id` endpoint for `PATCH` requests.

### References

Resolves #731 

### Testing

This PR adds a regression testing for the change.

### Contributor Checklist

- [x] I agree to adhere to the [Auth0 General Contribution Guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md).
- [x] I agree to uphold the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md).


Patch:
diff --git a/src/API/Management/Clients.php b/src/API/Management/Clients.php
index e94ec30..52bacb0 100644
--- a/src/API/Management/Clients.php
+++ b/src/API/Management/Clients.php
@@ -9,6 +9,9 @@ use Auth0\SDK\Utility\Request\RequestOptions;
 use Auth0\SDK\Utility\Toolkit;
 use Psr\Http\Message\ResponseInterface;
 
+use function array_key_exists;
+use function is_array;
+
 /**
  * Handles requests to the Clients endpoint of the v2 Management API.
  *
@@ -180,6 +183,10 @@ final class Clients extends ManagementEndpoint implements ClientsInterface
             [$id, \Auth0\SDK\Exception\ArgumentException::missing('id')],
         ])->isString();
 
+        if (is_array($body) && array_key_exists('initiate_login_uri', $body) && null === $body['initiate_login_uri']) {
+            $body['initiate_login_uri'] = '';
+        }
+
         return $this->getHttpClient()
             ->method('patch')->addPath(['clients', $id])
             ->withBody($body ?? [])


Test patch:
diff --git a/tests/Unit/API/Management/ClientsTest.php b/tests/Unit/API/Management/ClientsTest.php
index 2f518e9..bc5fd17 100644
--- a/tests/Unit/API/Management/ClientsTest.php
+++ b/tests/Unit/API/Management/ClientsTest.php
@@ -68,6 +68,18 @@ test('update() issues an appropriate request', function(): void {
     expect($body['name'])->toEqual('__test_new_name__');
 });
 
+test('update() does NOT nullify empty `initiate_login_uri` values', function(): void {
+    $this->endpoint->update('__test_id__', ['name' => '__test_new_name__', 'initiate_login_uri' => '']);
+
+    expect($this->api->getRequestMethod())->toEqual('PATCH');
+    expect($this->api->getRequestUrl())->toEndWith('/api/v2/clients/__test_id__');
+
+    $body = $this->api->getRequestBody();
+    $this->assertArrayHasKey('name', $body);
+    expect($body['name'])->toEqual('__test_new_name__');
+    expect($body['initiate_login_uri'])->toEqual('');
+});
+
 test('getCredentials() issues an appropriate request', function(): void {
     $mockClientId = uniqid();
     $this->endpoint->getCredentials($mockClientId, ['client_id' => '__test_client_id__', 'app_type' => '__test_app_type__']);