[php-nextgen] Use the API's configuration for the boolean format of query parameters

PA
1d ago
+438-204

Configuration::setBooleanFormatForQueryString() only takes effect on the default configuration. ObjectSerializer::toQueryValue(), ObjectSerializer::convertBoolToQueryStringFormat() and ObjectSerializer::buildQuery() always read the format from Configuration::getDefaultConfiguration(), so the setting is ignored on a configuration that is passed to an API:

$config = (new Configuration())
    ->setBooleanFormatForQueryString(Configuration::BOOLEAN_FORMAT_STRING);
$api = new SomeApi(null, $config);

$api->someOperation(archived: true); // sends ?archived=1 instead of ?archived=true

Changes

  • ObjectSerializer::toQueryValue(), ObjectSerializer::convertBoolToQueryStringFormat() and ObjectSerializer::buildQuery() take an optional ?Configuration $config as their last parameter. If it is null, they fall back to Configuration::getDefaultConfiguration(), so existing callers behave as before.
  • Generated APIs pass $this->config to toQueryValue() and buildQuery(), for both the query string and application/x-www-form-urlencoded bodies -> - application/x-www-form-urlencoded bodies are not affected: FormDataProcessor already converts booleans to true/false via ObjectSerializer::toString() (#2257), and the option only applies to query strings.
  • An API created without a configuration still uses the default configuration ($config ?: Configuration::getDefaultConfiguration()), so setting the format globally keeps working.
  • toQueryValue() now also converts booleans in non-exploded values (explode: false, e.g. ?flags=true,false) with the configured format before serializeCollection() joins them. Previously, implode() turned them into 1 and an empty string (?flags=1,), regardless of the configuration.

Tests

  • PhpNextgenClientCodegenTest::testQueryParametersUsesConfiguration checks that the generated API passes its configuration, and that ObjectSerializer no longer reads the format from the default configuration directly.
  • ObjectSerializerTest::testBooleanQueryValuesUseFormatOfGivenConfiguration checks that a given configuration overrides the default configuration, and that the default configuration is still used when none is given.
  • ObjectSerializerTest::testNonExplodedBooleanQueryValues covers non-exploded arrays and objects with both formats.

Notes

  • The option was introduced in #12385. int (1/0) became the default because guzzlehttp/psr7 encodes booleans in query strings as 1/0.
  • #18520 later extended the option to raw booleans in buildQuery().
  • No other client generator sends 1/0. They all send true/false. I'll propose making true/false the default for php-nextgen in a separate PR (#25312), keeping the int format as a deprecated fallback, and removing the option in 8.0.0.
  • Since guzzlehttp/psr7 2.7.0 Query::build() has a $treatBoolsAsInts parameter. Its default is still true.
  • This PR only changes php-nextgen. The php generator has the same behavior.

PR checklist

  • Read the contribution guidelines.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

@jebentier @dkarlovi @mandrean @jfastnacht @ybelenko @renepardon


Summary by cubic

Fixes the php-nextgen boolean query format so setBooleanFormatForQueryString() on an API's own configuration is respected, instead of always reading the format from the default configuration.

Previously, ObjectSerializer::toQueryValue(), convertBoolToQueryStringFormat(), and buildQuery() always read the boolean format from Configuration::getDefaultConfiguration(), ignoring the configuration passed to an API instance. These methods now accept an optional ?Configuration parameter and fall back to the default configuration when none is given, so existing callers keep working unchanged. Generated APIs pass $this->config for query strings. application/x-www-form-urlencoded bodies are unaffected: FormDataProcessor already converts booleans to true/false, and the option only applies to query strings.