[PHP] New client generator php-dt (#10041)

* - new PHP client generator php-dt

* - samples regen after rebase

* - README update

* - fix missing options for php-dt-modern config

* - use another workaround to prevent special treatment of form media types in DefaultGenerator - GlobalSettings usage mangled behaviour of other generators
- fix of missing spaces in generated docs

* - samples update after rebase
This commit is contained in:
Arthur Mogliev 2021-08-15 18:15:44 +04:00 committed by GitHub
parent fce10c7284
commit 2210c9f016
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
170 changed files with 7621 additions and 2 deletions

3
.gitignore vendored
View File

@ -176,12 +176,15 @@ samples/client/petstore/python-tornado/.venv/
# PHP
samples/client/petstore/php/OpenAPIClient-php/composer.lock
samples/client/petstore/php-dt/composer.lock
samples/client/petstore/php-dt-modern/composer.lock
samples/openapi3/server/petstore/php-symfony/SymfonyBundle-php/composer.lock
samples/server/petstore/php-laravel/lib/composer.lock
samples/server/petstore/php-lumen/lib/composer.lock
samples/server/petstore/php-slim4/composer.lock
samples/server/petstore/php-symfony/SymfonyBundle-php/composer.lock
samples/server/petstore/php-mezzio-ph/composer.lock
samples/server/petstore/php-mezzio-ph-modern/composer.lock
# ts
samples/client/petstore/typescript-angular2/npm/npm-debug.log

View File

@ -76,7 +76,7 @@ OpenAPI Generator allows generation of API client libraries (SDK generation), se
| | Languages/Frameworks |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **API clients** | **ActionScript**, **Ada**, **Apex**, **Bash**, **C**, **C#** (.net 2.0, 3.5 or later, .NET Standard 1.3 - 2.0, .NET Core 2.0, .NET 5.0. Libraries: RestSharp, HttpClient), **C++** (Arduino, cpp-restsdk, Qt5, Tizen, Unreal Engine 4), **Clojure**, **Crystal**, **Dart**, **Elixir**, **Elm**, **Eiffel**, **Erlang**, **Go**, **Groovy**, **Haskell** (http-client, Servant), **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign, RestTemplate, RESTEasy, Vertx, Google API Client Library for Java, Rest-assured, Spring 5 Web Client, MicroProfile Rest Client), **k6**, **Kotlin**, **Lua**, **Nim**, **Node.js/JavaScript** (ES5, ES6, AngularJS with Google Closure Compiler annotations, Flow types, Apollo GraphQL DataStore), **Objective-C**, **OCaml**, **Perl**, **PHP**, **PowerShell**, **Python**, **R**, **Ruby**, **Rust** (hyper, reqwest, rust-server), **Scala** (akka, http4s, scalaz, sttp, swagger-async-httpclient), **Swift** (2.x, 3.x, 4.x, 5.x), **Typescript** (AngularJS, Angular (2.x - 11.x), Aurelia, Axios, Fetch, Inversify, jQuery, Nestjs, Node, redux-query, Rxjs) |
| **Server stubs** | **Ada**, **C#** (ASP.NET Core, NancyFx), **C++** (Pistache, Restbed, Qt5 QHTTPEngine), **Erlang**, **F#** (Giraffe), **Go** (net/http, Gin, Echo), **Haskell** (Servant), **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, Jersey, RestEasy, Play Framework, [PKMST](https://github.com/ProKarma-Inc/pkmst-getting-started-examples), [Vert.x](https://vertx.io/)), **Kotlin** (Spring Boot, Ktor, Vertx), **PHP** (Laravel, Lumen, Slim, Silex, [Symfony](https://symfony.com/), [Zend Expressive](https://github.com/zendframework/zend-expressive)), **Python** (FastAPI, Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Rust** (rust-server), **Scala** (Akka, [Finch](https://github.com/finagle/finch), [Lagom](https://github.com/lagom/lagom), [Play](https://www.playframework.com/), Scalatra) |
| **Server stubs** | **Ada**, **C#** (ASP.NET Core, NancyFx), **C++** (Pistache, Restbed, Qt5 QHTTPEngine), **Erlang**, **F#** (Giraffe), **Go** (net/http, Gin, Echo), **Haskell** (Servant), **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, Jersey, RestEasy, Play Framework, [PKMST](https://github.com/ProKarma-Inc/pkmst-getting-started-examples), [Vert.x](https://vertx.io/)), **Kotlin** (Spring Boot, Ktor, Vertx), **PHP** (Laravel, Lumen, [Mezzio (fka Zend Expressive)](https://github.com/mezzio/mezzio), Slim, Silex, [Symfony](https://symfony.com/)), **Python** (FastAPI, Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Rust** (rust-server), **Scala** (Akka, [Finch](https://github.com/finagle/finch), [Lagom](https://github.com/lagom/lagom), [Play](https://www.playframework.com/), Scalatra) |
| **API documentation generators** | **HTML**, **Confluence Wiki**, **Asciidoc**, **Markdown**, **PlantUML** |
| **Configuration files** | [**Apache2**](https://httpd.apache.org/) |
| **Others** | **GraphQL**, **JMeter**, **Ktorm**, **MySQL Schema**, **Protocol Buffer**, **WSDL** |
@ -905,6 +905,7 @@ Here is a list of template creators:
* OCaml: @cgensoul
* Perl: @wing328 [:heart:](https://www.patreon.com/wing328)
* PHP (Guzzle): @baartosz
* PHP (with Data Transfer): @Articus
* PowerShell: @beatcracker
* PowerShell (refactored in 5.0.0): @wing328
* Python: @spacether
@ -963,10 +964,10 @@ Here is a list of template creators:
* NodeJS Express: @YishTish
* PHP Laravel: @renepardon
* PHP Lumen: @abcsun
* PHP Mezzio (with Path Handler): @Articus
* PHP Slim: @jfastnacht
* PHP Slim4: @ybelenko
* PHP Symfony: @ksm2
* PHP Zend Expressive (with Path Handler): @Articus
* Python FastAPI: @krjakbrjak
* Python AIOHTTP: @Jyhess
* Ruby on Rails 5: @zlx

View File

@ -0,0 +1,6 @@
generatorName: php-dt
outputDir: samples/client/petstore/php-dt-modern
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/php-dt-modern
additionalProperties:
modern: "true"

4
bin/configs/php-dt.yaml Normal file
View File

@ -0,0 +1,4 @@
generatorName: php-dt
outputDir: samples/client/petstore/php-dt
inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
templateDir: modules/openapi-generator/src/main/resources/php-dt

View File

@ -50,6 +50,7 @@ The following generators are available:
* [ocaml](generators/ocaml.md)
* [perl](generators/perl.md)
* [php](generators/php.md)
* [php-dt](generators/php-dt.md)
* [powershell (beta)](generators/powershell.md)
* [python (experimental)](generators/python.md)
* [python-legacy](generators/python-legacy.md)

View File

@ -39,6 +39,7 @@ The following generators are available:
* [ocaml](ocaml.md)
* [perl](perl.md)
* [php](php.md)
* [php-dt](php-dt.md)
* [powershell](powershell.md)
* [python](python.md)
* [python-legacy](python-legacy.md)

242
docs/generators/php-dt.md Normal file
View File

@ -0,0 +1,242 @@
---
title: Config Options for php-dt
sidebar_label: php-dt
---
These options may be applied as additional-properties (cli) or configOptions (plugins). Refer to [configuration docs](https://openapi-generator.tech/docs/configuration) for more details.
| Option | Description | Values | Default |
| ------ | ----------- | ------ | ------- |
|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false|
|apiPackage|package for generated api classes| |null|
|artifactVersion|The version to use in the composer package version field. e.g. 1.2.3| |null|
|disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|<dl><dt>**false**</dt><dd>The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.</dd><dt>**true**</dt><dd>Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.</dd></dl>|true|
|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
|invokerPackage|The main namespace to use for all classes. e.g. Yay\Pets| |null|
|legacyDiscriminatorBehavior|Set to false for generators with better support for discriminators. (Python, Java, Go, PowerShell, C#have this enabled by default).|<dl><dt>**true**</dt><dd>The mapping in the discriminator includes descendent schemas that allOf inherit from self and the discriminator mapping schemas in the OAS document.</dd><dt>**false**</dt><dd>The mapping in the discriminator includes any descendent schemas that allOf inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values, and the discriminator mapping schemas in the OAS document AND Codegen validates that oneOf and anyOf schemas contain the required discriminator and throws an error if the discriminator is missing.</dd></dl>|true|
|modelPackage|package for generated models| |null|
|modern|use modern language features (generated code will require PHP 8.0)| |false|
|packageName|The main package name for classes. e.g. GeneratedPetstore| |null|
|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
|srcBasePath|The directory to serve as source root.| |null|
|variableNamingConvention|naming convention of variable name, e.g. camelCase.| |snake_case|
## IMPORT MAPPING
| Type/Alias | Imports |
| ---------- | ------- |
## INSTANTIATION TYPES
| Type/Alias | Instantiated By |
| ---------- | --------------- |
|array|array|
|map|array|
## LANGUAGE PRIMITIVES
<ul class="column-ul">
<li>DateTime</li>
<li>bool</li>
<li>boolean</li>
<li>byte</li>
<li>double</li>
<li>float</li>
<li>int</li>
<li>integer</li>
<li>mixed</li>
<li>number</li>
<li>object</li>
<li>string</li>
<li>void</li>
</ul>
## RESERVED WORDS
<ul class="column-ul">
<li>__halt_compiler</li>
<li>_header_accept</li>
<li>_tempbody</li>
<li>abstract</li>
<li>and</li>
<li>array</li>
<li>as</li>
<li>break</li>
<li>callable</li>
<li>case</li>
<li>catch</li>
<li>class</li>
<li>clone</li>
<li>const</li>
<li>continue</li>
<li>declare</li>
<li>default</li>
<li>die</li>
<li>do</li>
<li>echo</li>
<li>else</li>
<li>elseif</li>
<li>empty</li>
<li>enddeclare</li>
<li>endfor</li>
<li>endforeach</li>
<li>endif</li>
<li>endswitch</li>
<li>endwhile</li>
<li>eval</li>
<li>exit</li>
<li>extends</li>
<li>final</li>
<li>for</li>
<li>foreach</li>
<li>formparams</li>
<li>function</li>
<li>global</li>
<li>goto</li>
<li>headerparams</li>
<li>httpbody</li>
<li>if</li>
<li>implements</li>
<li>include</li>
<li>include_once</li>
<li>instanceof</li>
<li>insteadof</li>
<li>interface</li>
<li>isset</li>
<li>list</li>
<li>namespace</li>
<li>new</li>
<li>or</li>
<li>print</li>
<li>private</li>
<li>protected</li>
<li>public</li>
<li>queryparams</li>
<li>require</li>
<li>require_once</li>
<li>resourcepath</li>
<li>return</li>
<li>static</li>
<li>switch</li>
<li>throw</li>
<li>trait</li>
<li>try</li>
<li>unset</li>
<li>use</li>
<li>var</li>
<li>while</li>
<li>xor</li>
</ul>
## FEATURE SET
### Client Modification Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasePath|✗|ToolingExtension
|Authorizations|✗|ToolingExtension
|UserAgent|✗|ToolingExtension
|MockServer|✗|ToolingExtension
### Data Type Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Custom|✗|OAS2,OAS3
|Int32|✓|OAS2,OAS3
|Int64|✓|OAS2,OAS3
|Float|✓|OAS2,OAS3
|Double|✓|OAS2,OAS3
|Decimal|✓|ToolingExtension
|String|✓|OAS2,OAS3
|Byte|✓|OAS2,OAS3
|Binary|✓|OAS2,OAS3
|Boolean|✓|OAS2,OAS3
|Date|✓|OAS2,OAS3
|DateTime|✓|OAS2,OAS3
|Password|✓|OAS2,OAS3
|File|✓|OAS2
|Array|✓|OAS2,OAS3
|Maps|✓|ToolingExtension
|CollectionFormat|✓|OAS2
|CollectionFormatMulti|✓|OAS2
|Enum|✓|OAS2,OAS3
|ArrayOfEnum|✓|ToolingExtension
|ArrayOfModel|✓|ToolingExtension
|ArrayOfCollectionOfPrimitives|✓|ToolingExtension
|ArrayOfCollectionOfModel|✓|ToolingExtension
|ArrayOfCollectionOfEnum|✓|ToolingExtension
|MapOfEnum|✓|ToolingExtension
|MapOfModel|✓|ToolingExtension
|MapOfCollectionOfPrimitives|✓|ToolingExtension
|MapOfCollectionOfModel|✓|ToolingExtension
|MapOfCollectionOfEnum|✓|ToolingExtension
### Documentation Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Readme|✓|ToolingExtension
|Model|✓|ToolingExtension
|Api|✓|ToolingExtension
### Global Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Host|✓|OAS2,OAS3
|BasePath|✓|OAS2,OAS3
|Info|✓|OAS2,OAS3
|Schemes|✗|OAS2,OAS3
|PartialSchemes|✓|OAS2,OAS3
|Consumes|✓|OAS2
|Produces|✓|OAS2
|ExternalDocumentation|✓|OAS2,OAS3
|Examples|✓|OAS2,OAS3
|XMLStructureDefinitions|✗|OAS2,OAS3
|MultiServer|✗|OAS3
|ParameterizedServer|✗|OAS3
|ParameterStyling|✗|OAS3
|Callbacks|✗|OAS3
|LinkObjects|✗|OAS3
### Parameter Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Path|✓|OAS2,OAS3
|Query|✓|OAS2,OAS3
|Header|✓|OAS2,OAS3
|Body|✓|OAS2
|FormUnencoded|✓|OAS2
|FormMultipart|✓|OAS2
|Cookie|✓|OAS3
### Schema Support Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|Simple|✓|OAS2,OAS3
|Composite|✓|OAS2,OAS3
|Polymorphism|✗|OAS2,OAS3
|Union|✗|OAS3
### Security Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|BasicAuth|✗|OAS2,OAS3
|ApiKey|✗|OAS2,OAS3
|OpenIDConnect|✗|OAS3
|BearerToken|✗|OAS3
|OAuth2_Implicit|✗|OAS2,OAS3
|OAuth2_Password|✗|OAS2,OAS3
|OAuth2_ClientCredentials|✗|OAS2,OAS3
|OAuth2_AuthorizationCode|✗|OAS2,OAS3
### Wire Format Feature
| Name | Supported | Defined By |
| ---- | --------- | ---------- |
|JSON|✓|OAS2,OAS3
|XML|✗|OAS2,OAS3
|PROTOBUF|✗|ToolingExtension
|Custom|✗|OAS2,OAS3

View File

@ -0,0 +1,444 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
* Copyright 2018 SmartBear Software
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.PathItem.HttpMethod;
import io.swagger.v3.oas.models.Paths;
import io.swagger.v3.oas.models.media.*;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.responses.ApiResponses;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.features.*;
import org.openapitools.codegen.utils.ModelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.*;
public class PhpDataTransferClientCodegen extends AbstractPhpCodegen {
private final Logger LOGGER = LoggerFactory.getLogger(PhpDataTransferClientCodegen.class);
// Custom generator option names
public static final String OPT_MODERN = "modern";
// Internal vendor extension names for extra template data that should not be set in specification
public static final String VEN_PARAMETER_LOCATION = "internal.parameterLocation";
public static final String VEN_FROM_PARAMETERS = "internal.fromParameters";
public static final String VEN_COLLECTION_FORMAT = "internal.collectionFormat";
public static final String VEN_PARAMETER_DATA_TYPE = "internal.parameterDataType";
public static final String VEN_HAS_PARAMETER_DATA = "internal.hasParameterData";
public static final String VEN_FROM_CONTAINER = "internal.fromContainer";
public static final String VEN_CONTAINER_DATA_TYPE = "internal.containerDataType";
private boolean useModernSyntax = false;
@Override
public CodegenType getTag() {
return CodegenType.CLIENT;
}
@Override
public String getName() {
return "php-dt";
}
@Override
public String getHelp() {
return "Generates PHP client relying on Data Transfer ( https://github.com/Articus/DataTransfer ) and compliant with PSR-7, PSR-11, PSR-17 and PSR-18.";
}
public PhpDataTransferClientCodegen() {
super();
modifyFeatureSet(features -> features
.includeDocumentationFeatures(DocumentationFeature.Readme)
.wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON))
.securityFeatures(EnumSet.noneOf(SecurityFeature.class))
.excludeGlobalFeatures(
GlobalFeature.XMLStructureDefinitions,
GlobalFeature.Callbacks,
GlobalFeature.LinkObjects,
GlobalFeature.ParameterStyling
)
.excludeSchemaSupportFeatures(
SchemaSupportFeature.Polymorphism
)
);
//no point to use double - http://php.net/manual/en/language.types.float.php , especially because of PHP 7+ float type declaration
typeMapping.put("double", "float");
apiTemplateFiles.clear();
apiTestTemplateFiles.clear();
apiDocTemplateFiles.clear();
modelTestTemplateFiles.clear();
modelDocTemplateFiles.clear();
additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, "1.0.0");
//Register custom CLI options
addSwitch(OPT_MODERN, "use modern language features (generated code will require PHP 8.0)", useModernSyntax);
}
@Override
public void processOpts() {
setSrcBasePath("src");
//Preserve and process options mangled in parent class
String rootNamespace = "App";
if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
rootNamespace = (String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE);
}
String modelNamespace = rootNamespace + "\\DTO";
if (additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) {
modelNamespace = (String) additionalProperties.get(CodegenConstants.MODEL_PACKAGE);
}
super.processOpts();
//Restore mangled options
setInvokerPackage(rootNamespace);
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, rootNamespace);
setModelPackage(modelNamespace);
additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelNamespace);
//Process custom options
if (additionalProperties.containsKey(OPT_MODERN)) {
embeddedTemplateDir = templateDir = "php-dt-modern";
useModernSyntax = true;
} else {
embeddedTemplateDir = templateDir = "php-dt";
}
supportingFiles.add(new SupportingFile("composer.json.mustache", "", "composer.json"));
supportingFiles.add(new SupportingFile("ApiClient.php.mustache", toSrcPath(invokerPackage, srcBasePath), "ApiClient.php"));
supportingFiles.add(new SupportingFile("ApiClientFactory.php.mustache", toSrcPath(invokerPackage, srcBasePath), "ApiClientFactory.php"));
supportingFiles.add(new SupportingFile("README.md.mustache", "", "README.md"));
}
@Override
public String toSrcPath(String packageName, String basePath) {
return basePath + File.separator + packageName.replace("\\", File.separator);
}
@Override
public String toApiName(String name) {
return super.toApiName(toModelName(name));
}
@Override
public String getTypeDeclaration(Schema p) {
String result;
Map<String, Object> extensions = p.getExtensions();
if ((extensions != null) && extensions.containsKey(VEN_CONTAINER_DATA_TYPE)) {
result = (String) extensions.get(VEN_CONTAINER_DATA_TYPE);
} else if (useModernSyntax && (ModelUtils.isArraySchema(p) || ModelUtils.isMapSchema(p))) {
result = "array";
} else {
result = super.getTypeDeclaration(p);
}
return result;
}
@Override
public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) {
//Do not use tags for operation grouping
super.addOperationToGroup("", resourcePath, operation, co, operations);
}
@Override
protected String getContentType(RequestBody requestBody) {
//Awfully nasty workaround to skip formParams generation
return null;
}
@Override
public void preprocessOpenAPI(OpenAPI openAPI) {
super.preprocessOpenAPI(openAPI);
generateParameterSchemas(openAPI);
generateContainerSchemas(openAPI);
}
@Override
public void processOpenAPI(OpenAPI openAPI) {
super.processOpenAPI(openAPI);
quoteMediaTypes(openAPI);
}
/**
* Generate additional model definitions from query parameters
*
* @param openAPI OpenAPI object
*/
protected void generateParameterSchemas(OpenAPI openAPI) {
Map<String, PathItem> paths = openAPI.getPaths();
if (paths != null) {
for (String pathname : paths.keySet()) {
PathItem path = paths.get(pathname);
Map<HttpMethod, Operation> operationMap = path.readOperationsMap();
if (operationMap != null) {
for (HttpMethod method : operationMap.keySet()) {
Operation operation = operationMap.get(method);
Map<String, Schema> propertySchemas = new HashMap<>();
if (operation == null || operation.getParameters() == null) {
continue;
}
List<String> requiredProperties = new ArrayList<>();
for (Parameter parameter : operation.getParameters()) {
Parameter referencedParameter = ModelUtils.getReferencedParameter(openAPI, parameter);
Schema propertySchema = convertParameterToSchema(openAPI, referencedParameter);
if (propertySchema != null) {
propertySchemas.put(propertySchema.getName(), propertySchema);
if (Boolean.TRUE.equals(referencedParameter.getRequired())) {
requiredProperties.add(propertySchema.getName());
}
}
}
if (!propertySchemas.isEmpty()) {
ObjectSchema schema = new ObjectSchema();
String operationId = getOrGenerateOperationId(operation, pathname, method.name());
schema.setDescription("Parameters for " + operationId);
schema.setProperties(propertySchemas);
schema.setRequired(requiredProperties);
addInternalExtensionToSchema(schema, VEN_FROM_PARAMETERS, Boolean.TRUE);
String schemaName = generateUniqueSchemaName(openAPI, operationId + "ParameterData");
openAPI.getComponents().addSchemas(schemaName, schema);
String schemaDataType = getTypeDeclaration(toModelName(schemaName));
addInternalExtensionToOperation(operation, VEN_PARAMETER_DATA_TYPE, schemaDataType);
addInternalExtensionToOperation(operation, VEN_HAS_PARAMETER_DATA, Boolean.TRUE);
}
}
}
}
}
}
protected Schema convertParameterToSchema(OpenAPI openAPI, Parameter parameter) {
Schema property = null;
Schema parameterSchema = ModelUtils.getReferencedSchema(openAPI, parameter.getSchema());
// array
if (ModelUtils.isArraySchema(parameterSchema)) {
Schema itemSchema = ((ArraySchema) parameterSchema).getItems();
ArraySchema arraySchema = new ArraySchema();
arraySchema.setMinItems(parameterSchema.getMinItems());
arraySchema.setMaxItems(parameterSchema.getMaxItems());
arraySchema.setItems(itemSchema);
String collectionFormat = getCollectionFormat(parameter);
if (collectionFormat == null) {
collectionFormat = "csv";
}
addInternalExtensionToSchema(arraySchema, VEN_COLLECTION_FORMAT, collectionFormat);
property = arraySchema;
} else { // non-array e.g. string, integer
switch (parameterSchema.getType()) {
case "string":
StringSchema stringSchema = new StringSchema();
stringSchema.setMinLength(parameterSchema.getMinLength());
stringSchema.setMaxLength(parameterSchema.getMaxLength());
stringSchema.setPattern(parameterSchema.getPattern());
stringSchema.setEnum(parameterSchema.getEnum());
property = stringSchema;
break;
case "integer":
IntegerSchema integerSchema = new IntegerSchema();
integerSchema.setMinimum(parameterSchema.getMinimum());
integerSchema.setMaximum(parameterSchema.getMaximum());
property = integerSchema;
break;
case "number":
NumberSchema floatSchema = new NumberSchema();
floatSchema.setMinimum(parameterSchema.getMinimum());
floatSchema.setMaximum(parameterSchema.getMaximum());
property = floatSchema;
break;
case "boolean":
property = new BooleanSchema();
break;
case "date":
property = new DateSchema();
break;
case "date-time":
property = new DateTimeSchema();
break;
}
}
if (property != null) {
property.setName(parameter.getName());
property.setDescription(parameter.getDescription());
addInternalExtensionToSchema(property, VEN_PARAMETER_LOCATION, parameter.getIn());
}
return property;
}
protected void addInternalExtensionToSchema(Schema schema, String name, Object value) {
//Add internal extension directly, because addExtension filters extension names
if (schema.getExtensions() == null) {
schema.setExtensions(new HashMap<>());
}
schema.getExtensions().put(name, value);
}
protected void addInternalExtensionToOperation(Operation operation, String name, Object value) {
//Add internal extension directly, because addExtension filters extension names
if (operation.getExtensions() == null) {
operation.setExtensions(new HashMap<>());
}
operation.getExtensions().put(name, value);
}
protected String generateUniqueSchemaName(OpenAPI openAPI, String name) {
String result = name;
if (openAPI.getComponents().getSchemas() != null) {
int count = 1;
while (openAPI.getComponents().getSchemas().containsKey(result)) {
result = name + "_" + count;
count += 1;
}
}
return result;
}
/**
* Generate additional model definitions for containers in whole specification
*
* @param openAPI OpenAPI object
*/
protected void generateContainerSchemas(OpenAPI openAPI) {
Paths paths = openAPI.getPaths();
for (String pathName : paths.keySet()) {
for (Operation operation : paths.get(pathName).readOperations()) {
List<Parameter> parameters = operation.getParameters();
if (parameters != null) {
for (Parameter parameter : parameters) {
generateContainerSchemas(openAPI, ModelUtils.getReferencedParameter(openAPI, parameter).getSchema());
}
}
RequestBody requestBody = ModelUtils.getReferencedRequestBody(openAPI, operation.getRequestBody());
if (requestBody != null) {
Content requestBodyContent = requestBody.getContent();
if (requestBodyContent != null) {
for (String mediaTypeName : requestBodyContent.keySet()) {
generateContainerSchemas(openAPI, requestBodyContent.get(mediaTypeName).getSchema());
}
}
}
ApiResponses responses = operation.getResponses();
for (String responseCode : responses.keySet()) {
ApiResponse response = ModelUtils.getReferencedApiResponse(openAPI, responses.get(responseCode));
Content responseContent = response.getContent();
if (responseContent != null) {
for (String mediaTypeName : responseContent.keySet()) {
generateContainerSchemas(openAPI, responseContent.get(mediaTypeName).getSchema());
}
}
}
}
}
}
/**
* Generate additional model definitions for containers in specified schema
*
* @param openAPI OpenAPI object
* @param schema OAS schema to process
*/
protected void generateContainerSchemas(OpenAPI openAPI, Schema schema) {
if (schema != null) {
//Dereference schema
schema = ModelUtils.getReferencedSchema(openAPI, schema);
Boolean isContainer = Boolean.FALSE;
if (ModelUtils.isObjectSchema(schema)) {
//Recursively process all schemas of object properties
Map<String, Schema> properties = schema.getProperties();
if (properties != null) {
for (String propertyName: properties.keySet()) {
generateContainerSchemas(openAPI, properties.get(propertyName));
}
}
} else if (ModelUtils.isArraySchema(schema)) {
//Recursively process schema of array items
generateContainerSchemas(openAPI, ((ArraySchema) schema).getItems());
isContainer = Boolean.TRUE;
} else if (ModelUtils.isMapSchema(schema)) {
//Recursively process schema of map items
Object itemSchema = schema.getAdditionalProperties();
if (itemSchema instanceof Schema) {
generateContainerSchemas(openAPI, (Schema) itemSchema);
}
isContainer = Boolean.TRUE;
}
if (isContainer) {
//Generate special component schema for container
String containerSchemaName = generateUniqueSchemaName(openAPI, "Collection");
Schema containerSchema = new ObjectSchema();
containerSchema.addProperties("inner", schema);
addInternalExtensionToSchema(containerSchema, VEN_FROM_CONTAINER, Boolean.TRUE);
openAPI.getComponents().addSchemas(containerSchemaName, containerSchema);
String containerDataType = getTypeDeclaration(toModelName(containerSchemaName));
addInternalExtensionToSchema(schema, VEN_CONTAINER_DATA_TYPE, containerDataType);
}
}
}
/**
* Awfully nasty workaround - add quotation marks for all media types to prevent special treatment of form media types
* in org/openapitools/codegen/DefaultGenerator.java:873
* TODO find a better way to prevent special form media type treatment
*
* @param openAPI OpenAPI object
*/
protected void quoteMediaTypes(OpenAPI openAPI) {
Map<String, PathItem> paths = openAPI.getPaths();
if (paths != null) {
for (String pathname : paths.keySet()) {
PathItem path = paths.get(pathname);
List<Operation> operations = path.readOperations();
if (operations != null) {
for (Operation operation: operations) {
RequestBody requestBody = ModelUtils.getReferencedRequestBody(openAPI, operation.getRequestBody());
if (requestBody != null) {
requestBody.setContent(copyWithQuotedMediaTypes(requestBody.getContent()));
}
ApiResponses responses = operation.getResponses();
for (String responseCode : responses.keySet()) {
ApiResponse response = ModelUtils.getReferencedApiResponse(openAPI, responses.get(responseCode));
response.setContent(copyWithQuotedMediaTypes(response.getContent()));
}
}
}
}
}
}
protected Content copyWithQuotedMediaTypes(Content content) {
Content result = null;
if (content != null) {
result = new Content();
for (String mediaType: content.keySet()) {
result.addMediaType("'" + mediaType + "'", content.get(mediaType));
}
}
return result;
}
}

View File

@ -93,6 +93,7 @@ org.openapitools.codegen.languages.PhpSlim4ServerCodegen
org.openapitools.codegen.languages.PhpSilexServerCodegen
org.openapitools.codegen.languages.PhpSymfonyServerCodegen
org.openapitools.codegen.languages.PhpMezzioPathHandlerServerCodegen
org.openapitools.codegen.languages.PhpDataTransferClientCodegen
org.openapitools.codegen.languages.PowerShellClientCodegen
org.openapitools.codegen.languages.ProtobufSchemaCodegen
org.openapitools.codegen.languages.PythonLegacyClientCodegen

View File

@ -0,0 +1,123 @@
<?php
declare(strict_types=1);
namespace {{invokerPackage}};
{{#apiInfo}}
{{#apis}}
{{#operations}}
use Articus\DataTransfer as DT;
use OpenAPIGenerator\APIClient as OAGAC;
use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Message\ResponseInterface;
/**
{{#appName}}
* {{&appName}}
{{/appName}}
{{#appDescription}}
* {{&appDescription}}
{{/appDescription}}
{{#version}}
* The version of the OpenAPI document: {{version}}
{{/version}}
*/
class ApiClient extends OAGAC\AbstractApiClient
{
{{#operation}}
//region {{operationId}}
/**
{{>api_arg_doc
}} * @return ResponseInterface
* @throws ClientExceptionInterface
* @throws DT\Exception\InvalidData
*/
public function {{operationId}}Raw(
{{>api_arg_declaration
}} ): ResponseInterface
{
$request = $this->createRequest('{{httpMethod}}', '{{path}}', {{#pathParams.0}}$this->getPathParameters($parameters){{/pathParams.0}}{{^pathParams.0}}[]{{/pathParams.0}}, {{#queryParams.0}}$this->getQueryParameters($parameters){{/queryParams.0}}{{^queryParams.0}}[]{{/queryParams.0}});
{{#headerParams.0}}
$request = $this->addCustomHeaders($request, $parameters);
{{/headerParams.0}}
{{#cookieParams.0}}
$request = $this->addCookies($request, $parameters);
{{/cookieParams.0}}
{{#bodyParam}}
$request = $this->addBody($request, $requestMediaType, $requestContent);
{{/bodyParam}}
{{#hasProduces}}
$request = $this->addAcceptHeader($request, $responseMediaType);
{{/hasProduces}}
{{#hasAuthMethods}}
$request = $this->addSecurity($request, $security);
{{/hasAuthMethods}}
return $this->httpClient->sendRequest($request);
}
/**
{{>api_arg_doc
}} * @return array
* @throws ClientExceptionInterface
* @throws DT\Exception\InvalidData
* @throws OAGAC\Exception\InvalidResponseBodySchema
*/
public function {{operationId}}(
{{>api_arg_declaration
}} ): array
{
$response = $this->{{operationId}}Raw({{>api_arg_call}});
$responseContent = null;
switch ($response->getStatusCode())
{
{{#responses}}
{{#isDefault}}default{{/isDefault}}{{^isDefault}}case {{code}}{{/isDefault}}:
{{#message}}
/* {{&message}} */
{{/message}}
{{#isModel}}
$responseContent = new {{dataType}}();
{{/isModel}}
{{^isModel}}
{{#isArray}}
$responseContent = new {{dataType}}();
{{/isArray}}
{{/isModel}}
{{^isModel}}
{{^isArray}}
{{#isMap}}
$responseContent = new {{dataType}}();
{{/isMap}}
{{/isArray}}
{{/isModel}}
break;
{{/responses}}
}
$this->parseBody($response, $responseContent);
return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
}
/**
{{>api_arg_doc
}} * @return {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}mixed{{/returnType}}
* @throws ClientExceptionInterface
* @throws DT\Exception\InvalidData
* @throws OAGAC\Exception\InvalidResponseBodySchema
* @throws OAGAC\Exception\UnsuccessfulResponse
*/
public function {{operationId}}Result(
{{>api_arg_declaration
}} ): {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}mixed{{/returnType}}
{
return $this->getSuccessfulContent(...$this->{{operationId}}({{>api_arg_call}}));
}
//endregion
{{^-last}}
{{/-last}}
{{/operation}}
}
{{/operations}}
{{/apis}}
{{/apiInfo}}

View File

@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace {{invokerPackage}};
use Articus\DataTransfer as DT;
use Interop\Container\ContainerInterface;
use OpenAPIGenerator\APIClient as OAGAC;
class ApiClientFactory extends DT\ConfigAwareFactory
{
public function __construct(string $configKey = ApiClient::class)
{
parent::__construct($configKey);
}
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$config = new OAGAC\ApiClientOptions(\array_merge($this->getServiceConfig($container), $options ?? []));
return new ApiClient(
$config->serverUrl,
$container->get($config->dataTransferServiceName),
$container->get($config->requestFactoryServiceName),
$container->get($config->httpClientServiceName),
$container->get($config->securityProviderFactoryServiceName),
$container->get($config->bodyCoderFactoryServiceName),
$container->get($config->bodyCoderFactoryServiceName)
);
}
}

View File

@ -0,0 +1,135 @@
# Client library for {{appName}}
Generated by the [OpenAPI Generator](https://openapi-generator.tech) project.
## Overview
This lightweight extensible client library is [PSR-7](https://www.php-fig.org/psr/psr-7), [PSR-11](https://www.php-fig.org/psr/psr-11), [PSR-17](https://www.php-fig.org/psr/psr-17) and [PSR-18](https://www.php-fig.org/psr/psr-18) complaint and relies on:
- PHP: >=8.0
- [Data Transfer](https://github.com/Articus/DataTransfer): >=0.5
## How to use
This library can be used either as a separate package (just deploy generated files to your package repository and add dependency `"{{#lambda.lowercase}}{{gitUserId}}/{{gitRepoId}}{{/lambda.lowercase}}":"{{artifactVersion}}"` to your project `composer.json`) or as a part of your project (just copy generated code from `{{srcBasePath}}` and merge generated `composer.json` into your project `composer.json`).
First you need an implementation for [PSR-7](https://packagist.org/packages/psr/http-message) and [PSR-17](https://packagist.org/packages/psr/http-factory) interfaces. Usually it is a single package, and your project might already have one among its dependencies (for example if it is some web service). Otherwise, https://packagist.org/providers/psr/http-message-implementation and https://packagist.org/providers/psr/http-factory-implementation may help to find some suitable options.
Next choose an implementation for [PSR-18 interfaces](https://packagist.org/packages/psr/http-client). https://packagist.org/providers/psr/http-client-implementation may help to find some suitable options.
Then check content types for API requests you intend to send and API responses you intend to receive. For each unique content type you will need an implementation of [`OpenAPIGenerator\APIClient\BodyCoderInterface`](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/BodyCoderInterface.php) to encode request bodies and decode response bodies. Currently, only [`application/json` body coder](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/BodyCoder/Json.php) is provided out-of-the-box.
After that review security requirements for API operations you intend to use. For each unique security scheme you will need an implementation of [OpenAPIGenerator\APIClient\SecurityProviderInterface](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/SecurityProviderInterface.php). Currently, only [HTTP Bearer authentication](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/SecurityProvider/HttpBearer.php) is supported out-of-the-box.
The last step is to configure and wire all services together. It is highly advisable to use [PSR-11 container](https://packagist.org/packages/psr/container) for that. If you have not selected one for your project yet, https://packagist.org/providers/psr/container-implementation may help to find some suitable options. Here is a sample wiring configuration for `"laminas/laminas-servicemanager"`, `"laminas/laminas-diactoros"` and `"symfony/http-client"` (consult generated `composer.json` for the exact versions of used packages):
```PHP
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
$dependencies = [
'invokables' => [
Psr\Http\Message\RequestFactoryInterface::class => Laminas\Diactoros\RequestFactory::class,
Psr\Http\Message\ResponseFactoryInterface::class => Laminas\Diactoros\ResponseFactory::class,
Psr\Http\Message\StreamFactoryInterface::class => Laminas\Diactoros\StreamFactory::class,
],
'factories' => [
{{invokerPackage}}\ApiClient::class => {{invokerPackage}}\ApiClientFactory::class,
Articus\DataTransfer\Service::class => Articus\DataTransfer\Factory::class,
Articus\DataTransfer\MetadataProvider\PhpAttribute::class => Articus\DataTransfer\MetadataProvider\Factory\PhpAttribute::class,
Articus\DataTransfer\Strategy\PluginManager::class => Articus\DataTransfer\Strategy\Factory\PluginManager::class,
Articus\DataTransfer\Validator\PluginManager::class => Articus\DataTransfer\Validator\Factory\PluginManager::class,
Laminas\Validator\ValidatorPluginManager::class => Laminas\Validator\ValidatorPluginManagerFactory::class,
OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class => OpenAPIGenerator\APIClient\SecurityProvider\Factory\PluginManager::class,
OpenAPIGenerator\APIClient\BodyCoder\PluginManager::class => OpenAPIGenerator\APIClient\BodyCoder\Factory\PluginManager::class,
Psr\Http\Client\ClientInterface::class => function (Psr\Container\ContainerInterface $container)
{
return new Symfony\Component\HttpClient\Psr18Client(
new Symfony\Component\HttpClient\NativeHttpClient(),
$container->get(Psr\Http\Message\ResponseFactoryInterface::class),
$container->get(Psr\Http\Message\StreamFactoryInterface::class)
);
},
],
'aliases' => [
Articus\DataTransfer\ClassMetadataProviderInterface::class => Articus\DataTransfer\MetadataProvider\PhpAttribute::class,
Articus\DataTransfer\FieldMetadataProviderInterface::class => Articus\DataTransfer\MetadataProvider\PhpAttribute::class,
],
];
$config = [
'dependencies' => $dependencies,
//Configure DataTransfer library
Articus\DataTransfer\Strategy\PluginManager::class => [
'invokables' => [
'QueryStringScalar' => OpenAPIGenerator\Common\Strategy\QueryStringScalar::class,
'QueryStringScalarArray' => OpenAPIGenerator\Common\Strategy\QueryStringScalarArray::class,
],
'factories' => [
'Date' => OpenAPIGenerator\Common\Strategy\Factory\ImmutableDate::class,
'DateTime' => OpenAPIGenerator\Common\Strategy\Factory\ImmutableDateTime::class,
'ObjectList' => OpenAPIGenerator\Common\Strategy\Factory\NoArgObjectList::class,
'ObjectMap' => OpenAPIGenerator\Common\Strategy\Factory\NoArgObjectMap::class,
'ScalarList' => OpenAPIGenerator\Common\Strategy\Factory\ScalarList::class,
'ScalarMap' => OpenAPIGenerator\Common\Strategy\Factory\ScalarMap::class,
]
],
Articus\DataTransfer\Validator\PluginManager::class => [
'invokables' => [
'Scalar' => OpenAPIGenerator\Common\Validator\Scalar::class,
'QueryStringScalar' => OpenAPIGenerator\Common\Validator\QueryStringScalar::class,
'QueryStringScalarArray' => OpenAPIGenerator\Common\Validator\QueryStringScalarArray::class,
],
'abstract_factories' => [
Articus\DataTransfer\Validator\Factory\Laminas::class,
],
],
'validators' => [
'invokables' => [
'Count' => Laminas\Validator\IsCountable::class,
],
],
//Set API server URL here
{{invokerPackage}}\ApiClient::class => [
//'server_url' => 'https://api.url',
],
//Register body coders for used content types here
OpenAPIGenerator\APIClient\BodyCoder\PluginManager::class => [
'factories' => [
//'another/mime-type' => AnotherMimeTypeBodyCoder::class
],
],
//Register security providers for used security schemes here
OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class => [
'factories' => [
//'another-security-scheme' => AnotherSecuritySchemeProvider::class,
],
'aliases' => [
//'custom-name-for-htt-bearer' => OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer::class,
],
],
];
$container = new Laminas\ServiceManager\ServiceManager($dependencies);
$container->setService('config', $config);
$container->setAlias('Config', 'config');
/** @var {{invokerPackage}}\ApiClient $client */
$client = $container->get({{invokerPackage}}\ApiClient::class);
//... and now you can use client methods to call API operations :)
//And one more sample: how to set token for HTTP Bearer authentication
/** @var OpenAPIGenerator\APIClient\SecurityProvider\PluginManager $securityProviders */
$securityProviders = $container->get(OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class);
/** @var OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer $httpBearer */
$httpBearer = $securityProviders->get(OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer::class);
$httpBearer->setToken('some-token');
```

View File

@ -0,0 +1,13 @@
{{#vendorExtensions}}{{#internal.hasParameterData
}}$parameters{{#bodyParam}}, {{/bodyParam}}{{^bodyParam}}{{#hasAuthMethods}}, {{/hasAuthMethods}}{{^hasAuthMethods}}{{#hasConsumes}}, {{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}}, {{/hasProduces}}{{/hasConsumes}}{{/hasAuthMethods}}{{/bodyParam
}}{{/internal.hasParameterData}}{{/vendorExtensions
}}{{#bodyParam
}}$requestContent{{#hasAuthMethods}}, {{/hasAuthMethods}}{{^hasAuthMethods}}{{#hasConsumes}}, {{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}}, {{/hasProduces}}{{/hasConsumes}}{{/hasAuthMethods
}}{{/bodyParam
}}{{#hasAuthMethods
}}$security{{#hasConsumes}}, {{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}}, {{/hasProduces}}{{/hasConsumes
}}{{/hasAuthMethods
}}{{#hasConsumes
}}$requestMediaType{{#hasProduces}}, {{/hasProduces
}}{{/hasConsumes
}}{{#hasProduces}}$responseMediaType{{/hasProduces}}

View File

@ -0,0 +1,17 @@
{{#vendorExtensions}}
{{#internal.hasParameterData}}
{{internal.parameterDataType}} $parameters{{#bodyParam}},{{/bodyParam}}{{^bodyParam}}{{#hasAuthMethods}},{{/hasAuthMethods}}{{^hasAuthMethods}}{{#hasConsumes}},{{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}},{{/hasProduces}}{{/hasConsumes}}{{/hasAuthMethods}}{{/bodyParam}}
{{/internal.hasParameterData}}
{{/vendorExtensions}}
{{#bodyParam}}
{{dataType}} $requestContent{{#hasAuthMethods}},{{/hasAuthMethods}}{{^hasAuthMethods}}{{#hasConsumes}},{{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}},{{/hasProduces}}{{/hasConsumes}}{{/hasAuthMethods}}
{{/bodyParam}}
{{#hasAuthMethods}}
iterable $security = ['{{authMethods.0.name}}' => [{{#authMethods.0.scopes}}'{{scope}}', {{/authMethods.0.scopes}}]]{{#hasConsumes}},{{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}},{{/hasProduces}}{{/hasConsumes}}
{{/hasAuthMethods}}
{{#hasConsumes}}
string $requestMediaType = '{{consumes.0.mediaType}}'{{#hasProduces}},{{/hasProduces}}
{{/hasConsumes}}
{{#hasProduces}}
string $responseMediaType = '{{produces.0.mediaType}}'
{{/hasProduces}}

View File

@ -0,0 +1,23 @@
{{#summary}}
* {{&summary}}
{{/summary}}
{{#description}}
* {{&description}}
{{/description}}
{{#vendorExtensions}}
{{#internal.hasParameterData}}
* @param {{internal.parameterDataType}} $parameters
{{/internal.hasParameterData}}
{{/vendorExtensions}}
{{#bodyParam}}
* @param {{dataType}} $requestContent
{{/bodyParam}}
{{#hasAuthMethods}}
* @param iterable|string[][] $security
{{/hasAuthMethods}}
{{#hasConsumes}}
* @param string $requestMediaType
{{/hasConsumes}}
{{#hasProduces}}
* @param string $responseMediaType
{{/hasProduces}}

View File

@ -0,0 +1,26 @@
{
"name": "{{#lambda.lowercase}}{{gitUserId}}/{{gitRepoId}}{{/lambda.lowercase}}",
"description": "{{description}}",
"license": "unlicense",
"version": "{{artifactVersion}}",
"type": "library",
"require": {
"php": "^8.0",
"articus/data-transfer": "^0.5",
"articus/openapi-generator-common": "^0.2",
"articus/openapi-generator-apiclient": "^0.1",
"psr/simple-cache": "^1.0",
"laminas/laminas-stdlib": "^3.2",
"laminas/laminas-validator": "^2.13"
},
"autoload": {
"psr-4": {
"": "{{srcBasePath}}/"
}
},
"require-dev": {
"laminas/laminas-servicemanager": "^3.6",
"laminas/laminas-diactoros": "^2.6",
"symfony/http-client": "^5.3"
}
}

View File

@ -0,0 +1,6 @@
#based on .gitignore generated by https://github.com/zendframework/zend-expressive-skeleton
.idea
# Composer files
composer.phar
vendor/

View File

@ -0,0 +1,8 @@
{{#items
}}{{^isContainer
}}{{#isPrimitiveType}}"{{dataType}}"{{/isPrimitiveType
}}{{^isPrimitiveType}}{{dataType}}::class{{/isPrimitiveType
}}{{/isContainer
}}{{#isContainer
}}{{dataType}}::class{{/isContainer
}}{{/items}}

View File

@ -0,0 +1,8 @@
{{#additionalProperties
}}{{^isContainer
}}{{#isPrimitiveType}}"{{dataType}}"{{/isPrimitiveType
}}{{^isPrimitiveType}}{{dataType}}::class{{/isPrimitiveType
}}{{/isContainer
}}{{#isContainer
}}{{dataType}}::class{{/isContainer
}}{{/additionalProperties}}

View File

@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
{{#models}}{{#model}}
namespace {{package}};
use Articus\DataTransfer\PhpAttribute as DTA;
{{#vendorExtensions
}}{{#internal.fromContainer}}{{>model_container}}{{/internal.fromContainer
}}{{^internal.fromContainer}}{{>model_object}}{{/internal.fromContainer
}}{{/vendorExtensions
}}{{^vendorExtensions}}{{>model_object}}{{/vendorExtensions
}}{{/model}}{{/models}}

View File

@ -0,0 +1,57 @@
{{#vars
}}{{#isArray
}}#[DTA\Strategy("{{#isPrimitiveType}}ScalarList{{/isPrimitiveType}}{{^isPrimitiveType}}ObjectList{{/isPrimitiveType}}", ["type" => {{>list_item_type}}])]
{{#minItems}}{{^maxItems
}}#[DTA\Validator("Count", ["min" => {{minItems}}], blocker: true)]
{{/maxItems}}{{/minItems
}}{{^minItems}}{{#maxItems
}}#[DTA\Validator("Count", ["max" => {{maxItems}}], blocker: true)]
{{/maxItems}}{{/minItems
}}{{#minItems}}{{#maxItems
}}#[DTA\Validator("Count", ["min" => {{minItems}}, "max" => {{maxItems}}], blocker: true)]
{{/maxItems}}{{/minItems
}}#[DTA\Validator("Collection", ["validators" => [
{{#isPrimitiveType
}} ["name" => "Scalar", "options" => ["type" => {{>list_item_type}}]]
{{/isPrimitiveType
}}{{#isDate
}} ["name" => "Date"]
{{/isDate
}}{{#isDateTime
}} ["name" => "Date", "options" => ["format" => \DateTime::RFC3339]]
{{/isDateTime
}}{{^isPrimitiveType}}{{^isDate}}{{^isDateTime
}} ["name" => "TypeCompliant", "options" => ["type" => {{>list_item_type}}]]
{{/isDateTime}}{{/isDate}}{{/isPrimitiveType
}}]])]
{{/isArray
}}{{#isMap
}}#[DTA\Strategy("{{#isPrimitiveType}}ScalarMap{{/isPrimitiveType}}{{^isPrimitiveType}}ObjectMap{{/isPrimitiveType}}", ["type" => {{>map_item_type}}])]
{{#minProperties}}{{^maxProperties
}}#[DTA\Validator("Count", ["min" => {{minProperties}}], blocker: true)]
{{/maxProperties}}{{/minProperties
}}{{^minProperties}}{{#maxProperties
}}#[DTA\Validator("Count", ["max" => {{maxProperties}}], blocker: true)]
{{/maxProperties}}{{/minProperties
}}{{#minProperties}}{{#maxProperties
}}#[DTA\Validator("Count", ["min" => {{minProperties}}, "max" => {{maxProperties}}], blocker: true)]
{{/maxProperties}}{{/minProperties
}}#[DTA\Validator("Collection", ["validators" => [
{{#isPrimitiveType
}} ["name" => "Scalar", "options" => ["type" => {{>map_item_type}}]]
{{/isPrimitiveType
}}{{#isDate
}} ["name" => "Date"]
{{/isDate
}}{{#isDateTime
}} ["name" => "Date", "options" => ["format" => \DateTime::RFC3339]]
{{/isDateTime
}}{{^isPrimitiveType}}{{^isDate}}{{^isDateTime
}} ["name" => "TypeCompliant", "options" => ["type" => {{>map_item_type}}]]
{{/isDateTime}}{{/isDate}}{{/isPrimitiveType
}}]])]
{{/isMap
}}{{/vars
}}class {{classname}} extends \ArrayObject
{
}

View File

@ -0,0 +1,45 @@
{{#isContainer
}} #[DTA\Strategy("Object", ["type" => {{internal.containerDataType}}::class])]
#[DTA\Validator("TypeCompliant", ["type" => {{internal.containerDataType}}::class])]
{{/isContainer
}}{{^isContainer
}}{{#isPrimitiveType
}} #[DTA\Validator("Scalar", ["type" => "{{dataType}}"])]
{{/isPrimitiveType
}}{{#isDate
}} #[DTA\Strategy("Date")]
#[DTA\Validator("Date")]
{{/isDate
}}{{#isDateTime
}} #[DTA\Strategy("DateTime")]
#[DTA\Validator("Date", ["format" => \DateTime::RFC3339])]
{{/isDateTime
}}{{^isPrimitiveType
}}{{^isDate
}}{{^isDateTime
}} #[DTA\Strategy("Object", ["type" => {{dataType}}::class])]
#[DTA\Validator("TypeCompliant", ["type" => {{dataType}}::class])]
{{/isDateTime
}}{{/isDate
}}{{/isPrimitiveType
}}{{/isContainer
}}{{#hasValidation
}}{{#minLength}}{{#maxLength
}} #[DTA\Validator("StringLength", ["min" => {{minLength}}, "max" => {{maxLength}}])]
{{/maxLength}}{{/minLength
}}{{^minLength}}{{#maxLength
}} #[DTA\Validator("StringLength", ["max" => {{maxLength}}])]
{{/maxLength}}{{/minLength
}}{{#minLength}}{{^maxLength
}} #[DTA\Validator("StringLength", ["min" => {{minLength}}])]
{{/maxLength}}{{/minLength
}}{{#minimum
}} #[DTA\Validator("GreaterThan", ["min" => {{minimum}}{{^exclusiveMinimum}}, "inclusive" => true{{/exclusiveMinimum}}])]
{{/minimum
}}{{#maximum
}} #[DTA\Validator("LessThan", ["max" => {{maximum}}{{^exclusiveMaximum}}, "inclusive" => true{{/exclusiveMaximum}}])]
{{/maximum
}}{{#pattern
}} #[DTA\Validator("Regex", ["pattern" => "{{{pattern}}}"])]
{{/pattern
}}{{/hasValidation}}

View File

@ -0,0 +1,23 @@
{{#description
}}/**
* {{description}}
*/
{{/description
}}class {{classname}}
{
{{#vars
}}{{#description
}} /**
* {{description}}
*/
{{/description
}} #[DTA\Data({{#vendorExtensions}}{{#internal.fromParameters}}subset: "{{internal.parameterLocation}}", {{/internal.fromParameters}}{{/vendorExtensions}}field: "{{baseName}}"{{^required}}, nullable: true{{/required}})]
{{#vendorExtensions
}}{{#internal.fromParameters}}{{>model_query_var}}{{/internal.fromParameters
}}{{^internal.fromParameters}}{{>model_normal_var}}{{/internal.fromParameters
}}{{/vendorExtensions
}}{{^vendorExtensions}}{{>model_normal_var}}{{/vendorExtensions
}} public {{dataType}}|null ${{name}} = null;
{{/vars
}}}

View File

@ -0,0 +1,51 @@
{{#isArray
}}{{#isPrimitiveType
}} #[DTA\Strategy("QueryStringScalarArray", ["type" => {{>list_item_type}}, "format" => "{{internal.collectionFormat}}"], "{{internal.parameterLocation}}")]
#[DTA\Validator("QueryStringScalarArray", ["type" => {{>list_item_type}}, "format" => "{{internal.collectionFormat}}"{{#minItems}}, "min_items" => {{minItems}}{{/minItems}}{{#maxItems}}, "max_items" => {{maxItems}}{{/maxItems}}], subset: "{{internal.parameterLocation}}")]
{{/isPrimitiveType
}}{{^isPrimitiveType
}} // TODO add validator(s) and strategy for list of {{>list_item_type}} and collection format {{internal.collectionFormat}} inside query string
{{/isPrimitiveType
}}{{/isArray
}}{{#isMap
}} // TODO add validator(s) and strategy for map of {{>map_item_type}} and collection format {{internal.collectionFormat}} inside query string
{{/isMap
}}{{^isContainer
}}{{#isPrimitiveType
}} #[DTA\Strategy("QueryStringScalar", ["type" => "{{dataType}}"], "{{internal.parameterLocation}}")]
#[DTA\Validator("QueryStringScalar", ["type" => "{{dataType}}"], subset: "{{internal.parameterLocation}}")]
{{/isPrimitiveType
}}{{#isDate
}} #[DTA\Strategy("Date", subset: "{{internal.parameterLocation}}")]
#[DTA\Validator("Date", subset: "{{internal.parameterLocation}}")]
{{/isDate
}}{{#isDateTime
}} #[DTA\Strategy("DateTime", subset: "{{internal.parameterLocation}}")]
#[DTA\Validator("Date", ["format" => \DateTime::RFC3339], subset: "{{internal.parameterLocation}}")]
{{/isDateTime
}}{{^isPrimitiveType
}}{{^isDate}}{{^isDateTime
}} // TODO add validator(s) and strategy for {{dataType}} inside query string
{{/isDateTime}}{{/isDate
}}{{/isPrimitiveType
}}{{/isContainer
}}{{#hasValidation
}}{{#minLength}}{{#maxLength
}} #[DTA\Validator("StringLength", ["min" => {{minLength}}, "max" => {{maxLength}}], subset: "{{internal.parameterLocation}}")]
{{/maxLength}}{{/minLength
}}{{^minLength}}{{#maxLength
}} #[DTA\Validator("StringLength", ["max" => {{maxLength}}], subset: "{{internal.parameterLocation}}")]
{{/maxLength}}{{/minLength
}}{{#minLength}}{{^maxLength
}} #[DTA\Validator("StringLength", ["min" => {{minLength}}], subset: "{{internal.parameterLocation}}")]
{{/maxLength}}{{/minLength
}}{{#minimum
}} #[DTA\Validator("GreaterThan", ["min" => {{minimum}}{{^exclusiveMinimum}}, "inclusive" => true{{/exclusiveMinimum}}], subset: "{{internal.parameterLocation}}")]
{{/minimum
}}{{#maximum
}} #[DTA\Validator("LessThan", ["max" => {{maximum}}{{^exclusiveMaximum}}, "inclusive" => true{{/exclusiveMaximum}}], subset: "{{internal.parameterLocation}}")]
{{/maximum
}}{{#pattern
}} #[DTA\Validator("Regex", ["pattern" => "{{{pattern}}}"], subset: "{{internal.parameterLocation}}")]
{{/pattern
}}{{/hasValidation}}

View File

@ -0,0 +1,123 @@
<?php
declare(strict_types=1);
namespace {{invokerPackage}};
{{#apiInfo}}
{{#apis}}
{{#operations}}
use Articus\DataTransfer as DT;
use OpenAPIGenerator\APIClient as OAGAC;
use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Message\ResponseInterface;
/**
{{#appName}}
* {{&appName}}
{{/appName}}
{{#appDescription}}
* {{&appDescription}}
{{/appDescription}}
{{#version}}
* The version of the OpenAPI document: {{version}}
{{/version}}
*/
class ApiClient extends OAGAC\AbstractApiClient
{
{{#operation}}
//region {{operationId}}
/**
{{>api_arg_doc
}} * @return ResponseInterface
* @throws ClientExceptionInterface
* @throws DT\Exception\InvalidData
*/
public function {{operationId}}Raw(
{{>api_arg_declaration
}} ): ResponseInterface
{
$request = $this->createRequest('{{httpMethod}}', '{{path}}', {{#pathParams.0}}$this->getPathParameters($parameters){{/pathParams.0}}{{^pathParams.0}}[]{{/pathParams.0}}, {{#queryParams.0}}$this->getQueryParameters($parameters){{/queryParams.0}}{{^queryParams.0}}[]{{/queryParams.0}});
{{#headerParams.0}}
$request = $this->addCustomHeaders($request, $parameters);
{{/headerParams.0}}
{{#cookieParams.0}}
$request = $this->addCookies($request, $parameters);
{{/cookieParams.0}}
{{#bodyParam}}
$request = $this->addBody($request, $requestMediaType, $requestContent);
{{/bodyParam}}
{{#hasProduces}}
$request = $this->addAcceptHeader($request, $responseMediaType);
{{/hasProduces}}
{{#hasAuthMethods}}
$request = $this->addSecurity($request, $security);
{{/hasAuthMethods}}
return $this->httpClient->sendRequest($request);
}
/**
{{>api_arg_doc
}} * @return array
* @throws ClientExceptionInterface
* @throws DT\Exception\InvalidData
* @throws OAGAC\Exception\InvalidResponseBodySchema
*/
public function {{operationId}}(
{{>api_arg_declaration
}} ): array
{
$response = $this->{{operationId}}Raw({{>api_arg_call}});
$responseContent = null;
switch ($response->getStatusCode())
{
{{#responses}}
{{#isDefault}}default{{/isDefault}}{{^isDefault}}case {{code}}{{/isDefault}}:
{{#message}}
/* {{&message}} */
{{/message}}
{{#isModel}}
$responseContent = new {{dataType}}();
{{/isModel}}
{{^isModel}}
{{#isArray}}
$responseContent = new {{dataType}}();
{{/isArray}}
{{/isModel}}
{{^isModel}}
{{^isArray}}
{{#isMap}}
$responseContent = new {{dataType}}();
{{/isMap}}
{{/isArray}}
{{/isModel}}
break;
{{/responses}}
}
$this->parseBody($response, $responseContent);
return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
}
/**
{{>api_arg_doc
}} * @return {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}mixed{{/returnType}}
* @throws ClientExceptionInterface
* @throws DT\Exception\InvalidData
* @throws OAGAC\Exception\InvalidResponseBodySchema
* @throws OAGAC\Exception\UnsuccessfulResponse
*/
public function {{operationId}}Result(
{{>api_arg_declaration
}} ){{#returnType}}: {{returnType}}{{/returnType}}
{
return $this->getSuccessfulContent(...$this->{{operationId}}({{>api_arg_call}}));
}
//endregion
{{^-last}}
{{/-last}}
{{/operation}}
}
{{/operations}}
{{/apis}}
{{/apiInfo}}

View File

@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace {{invokerPackage}};
use Articus\DataTransfer as DT;
use Interop\Container\ContainerInterface;
use OpenAPIGenerator\APIClient as OAGAC;
class ApiClientFactory extends DT\ConfigAwareFactory
{
public function __construct(string $configKey = ApiClient::class)
{
parent::__construct($configKey);
}
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$config = new OAGAC\ApiClientOptions(\array_merge($this->getServiceConfig($container), $options ?? []));
return new ApiClient(
$config->serverUrl,
$container->get($config->dataTransferServiceName),
$container->get($config->requestFactoryServiceName),
$container->get($config->httpClientServiceName),
$container->get($config->securityProviderFactoryServiceName),
$container->get($config->bodyCoderFactoryServiceName),
$container->get($config->bodyCoderFactoryServiceName)
);
}
}

View File

@ -0,0 +1,135 @@
# Client library for {{appName}}
Generated by the [OpenAPI Generator](https://openapi-generator.tech) project.
## Overview
This lightweight extensible client library is [PSR-7](https://www.php-fig.org/psr/psr-7), [PSR-11](https://www.php-fig.org/psr/psr-11), [PSR-17](https://www.php-fig.org/psr/psr-17) and [PSR-18](https://www.php-fig.org/psr/psr-18) complaint and relies on:
- PHP: >=7.3
- [Data Transfer](https://github.com/Articus/DataTransfer): >=0.5
## How to use
This library can be used either as a separate package (just deploy generated files to your package repository and add dependency `"{{#lambda.lowercase}}{{gitUserId}}/{{gitRepoId}}{{/lambda.lowercase}}":"{{artifactVersion}}"` to your project `composer.json`) or as a part of your project (just copy generated code from `{{srcBasePath}}` and merge generated `composer.json` into your project `composer.json`).
First you need an implementation for [PSR-7](https://packagist.org/packages/psr/http-message) and [PSR-17](https://packagist.org/packages/psr/http-factory) interfaces. Usually it is a single package, and your project might already have one among its dependencies (for example if it is some web service). Otherwise, https://packagist.org/providers/psr/http-message-implementation and https://packagist.org/providers/psr/http-factory-implementation may help to find some suitable options.
Next choose an implementation for [PSR-18 interfaces](https://packagist.org/packages/psr/http-client). https://packagist.org/providers/psr/http-client-implementation may help to find some suitable options.
Then check content types for API requests you intend to send and API responses you intend to receive. For each unique content type you will need an implementation of [`OpenAPIGenerator\APIClient\BodyCoderInterface`](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/BodyCoderInterface.php) to encode request bodies and decode response bodies. Currently, only [`application/json` body coder](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/BodyCoder/Json.php) is provided out-of-the-box.
After that review security requirements for API operations you intend to use. For each unique security scheme you will need an implementation of [OpenAPIGenerator\APIClient\SecurityProviderInterface](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/SecurityProviderInterface.php). Currently, only [HTTP Bearer authentication](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/SecurityProvider/HttpBearer.php) is supported out-of-the-box.
The last step is to configure and wire all services together. It is highly advisable to use [PSR-11 container](https://packagist.org/packages/psr/container) for that. If you have not selected one for your project yet, https://packagist.org/providers/psr/container-implementation may help to find some suitable options. Here is a sample wiring configuration for `"laminas/laminas-servicemanager"`, `"laminas/laminas-diactoros"` and `"symfony/http-client"` (consult generated `composer.json` for the exact versions of used packages):
```PHP
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
$dependencies = [
'invokables' => [
Psr\Http\Message\RequestFactoryInterface::class => Laminas\Diactoros\RequestFactory::class,
Psr\Http\Message\ResponseFactoryInterface::class => Laminas\Diactoros\ResponseFactory::class,
Psr\Http\Message\StreamFactoryInterface::class => Laminas\Diactoros\StreamFactory::class,
],
'factories' => [
{{invokerPackage}}\ApiClient::class => {{invokerPackage}}\ApiClientFactory::class,
Articus\DataTransfer\Service::class => Articus\DataTransfer\Factory::class,
Articus\DataTransfer\MetadataProvider\Annotation::class => Articus\DataTransfer\MetadataProvider\Factory\Annotation::class,
Articus\DataTransfer\Strategy\PluginManager::class => Articus\DataTransfer\Strategy\Factory\PluginManager::class,
Articus\DataTransfer\Validator\PluginManager::class => Articus\DataTransfer\Validator\Factory\PluginManager::class,
Laminas\Validator\ValidatorPluginManager::class => Laminas\Validator\ValidatorPluginManagerFactory::class,
OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class => OpenAPIGenerator\APIClient\SecurityProvider\Factory\PluginManager::class,
OpenAPIGenerator\APIClient\BodyCoder\PluginManager::class => OpenAPIGenerator\APIClient\BodyCoder\Factory\PluginManager::class,
Psr\Http\Client\ClientInterface::class => function (Psr\Container\ContainerInterface $container)
{
return new Symfony\Component\HttpClient\Psr18Client(
new Symfony\Component\HttpClient\NativeHttpClient(),
$container->get(Psr\Http\Message\ResponseFactoryInterface::class),
$container->get(Psr\Http\Message\StreamFactoryInterface::class)
);
},
],
'aliases' => [
Articus\DataTransfer\ClassMetadataProviderInterface::class => Articus\DataTransfer\MetadataProvider\Annotation::class,
Articus\DataTransfer\FieldMetadataProviderInterface::class => Articus\DataTransfer\MetadataProvider\Annotation::class,
],
];
$config = [
'dependencies' => $dependencies,
//Configure DataTransfer library
Articus\DataTransfer\Strategy\PluginManager::class => [
'invokables' => [
'QueryStringScalar' => OpenAPIGenerator\Common\Strategy\QueryStringScalar::class,
'QueryStringScalarArray' => OpenAPIGenerator\Common\Strategy\QueryStringScalarArray::class,
],
'factories' => [
'Date' => OpenAPIGenerator\Common\Strategy\Factory\ImmutableDate::class,
'DateTime' => OpenAPIGenerator\Common\Strategy\Factory\ImmutableDateTime::class,
'ObjectList' => OpenAPIGenerator\Common\Strategy\Factory\NoArgObjectList::class,
'ObjectMap' => OpenAPIGenerator\Common\Strategy\Factory\NoArgObjectMap::class,
'ScalarList' => OpenAPIGenerator\Common\Strategy\Factory\ScalarList::class,
'ScalarMap' => OpenAPIGenerator\Common\Strategy\Factory\ScalarMap::class,
]
],
Articus\DataTransfer\Validator\PluginManager::class => [
'invokables' => [
'Scalar' => OpenAPIGenerator\Common\Validator\Scalar::class,
'QueryStringScalar' => OpenAPIGenerator\Common\Validator\QueryStringScalar::class,
'QueryStringScalarArray' => OpenAPIGenerator\Common\Validator\QueryStringScalarArray::class,
],
'abstract_factories' => [
Articus\DataTransfer\Validator\Factory\Laminas::class,
],
],
'validators' => [
'invokables' => [
'Count' => Laminas\Validator\IsCountable::class,
],
],
//Set API server URL here
{{invokerPackage}}\ApiClient::class => [
//'server_url' => 'https://api.url',
],
//Register body coders for used content types here
OpenAPIGenerator\APIClient\BodyCoder\PluginManager::class => [
'factories' => [
//'another/mime-type' => AnotherMimeTypeBodyCoder::class
],
],
//Register security providers for used security schemes here
OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class => [
'factories' => [
//'another-security-scheme' => AnotherSecuritySchemeProvider::class,
],
'aliases' => [
//'custom-name-for-htt-bearer' => OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer::class,
],
],
];
$container = new Laminas\ServiceManager\ServiceManager($dependencies);
$container->setService('config', $config);
$container->setAlias('Config', 'config');
/** @var {{invokerPackage}}\ApiClient $client */
$client = $container->get({{invokerPackage}}\ApiClient::class);
//... and now you can use client methods to call API operations :)
//And one more sample: how to set token for HTTP Bearer authentication
/** @var OpenAPIGenerator\APIClient\SecurityProvider\PluginManager $securityProviders */
$securityProviders = $container->get(OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class);
/** @var OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer $httpBearer */
$httpBearer = $securityProviders->get(OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer::class);
$httpBearer->setToken('some-token');
```

View File

@ -0,0 +1,13 @@
{{#vendorExtensions}}{{#internal.hasParameterData
}}$parameters{{#bodyParam}}, {{/bodyParam}}{{^bodyParam}}{{#hasAuthMethods}}, {{/hasAuthMethods}}{{^hasAuthMethods}}{{#hasConsumes}}, {{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}}, {{/hasProduces}}{{/hasConsumes}}{{/hasAuthMethods}}{{/bodyParam
}}{{/internal.hasParameterData}}{{/vendorExtensions
}}{{#bodyParam
}}$requestContent{{#hasAuthMethods}}, {{/hasAuthMethods}}{{^hasAuthMethods}}{{#hasConsumes}}, {{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}}, {{/hasProduces}}{{/hasConsumes}}{{/hasAuthMethods
}}{{/bodyParam
}}{{#hasAuthMethods
}}$security{{#hasConsumes}}, {{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}}, {{/hasProduces}}{{/hasConsumes
}}{{/hasAuthMethods
}}{{#hasConsumes
}}$requestMediaType{{#hasProduces}}, {{/hasProduces
}}{{/hasConsumes
}}{{#hasProduces}}$responseMediaType{{/hasProduces}}

View File

@ -0,0 +1,17 @@
{{#vendorExtensions}}
{{#internal.hasParameterData}}
{{internal.parameterDataType}} $parameters{{#bodyParam}},{{/bodyParam}}{{^bodyParam}}{{#hasAuthMethods}},{{/hasAuthMethods}}{{^hasAuthMethods}}{{#hasConsumes}},{{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}},{{/hasProduces}}{{/hasConsumes}}{{/hasAuthMethods}}{{/bodyParam}}
{{/internal.hasParameterData}}
{{/vendorExtensions}}
{{#bodyParam}}
{{dataType}} $requestContent{{#hasAuthMethods}},{{/hasAuthMethods}}{{^hasAuthMethods}}{{#hasConsumes}},{{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}},{{/hasProduces}}{{/hasConsumes}}{{/hasAuthMethods}}
{{/bodyParam}}
{{#hasAuthMethods}}
iterable $security = ['{{authMethods.0.name}}' => [{{#authMethods.0.scopes}}'{{scope}}', {{/authMethods.0.scopes}}]]{{#hasConsumes}},{{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}},{{/hasProduces}}{{/hasConsumes}}
{{/hasAuthMethods}}
{{#hasConsumes}}
string $requestMediaType = '{{consumes.0.mediaType}}'{{#hasProduces}},{{/hasProduces}}
{{/hasConsumes}}
{{#hasProduces}}
string $responseMediaType = '{{produces.0.mediaType}}'
{{/hasProduces}}

View File

@ -0,0 +1,23 @@
{{#summary}}
* {{&summary}}
{{/summary}}
{{#description}}
* {{&description}}
{{/description}}
{{#vendorExtensions}}
{{#internal.hasParameterData}}
* @param {{internal.parameterDataType}} $parameters
{{/internal.hasParameterData}}
{{/vendorExtensions}}
{{#bodyParam}}
* @param {{dataType}} $requestContent
{{/bodyParam}}
{{#hasAuthMethods}}
* @param iterable|string[][] $security
{{/hasAuthMethods}}
{{#hasConsumes}}
* @param string $requestMediaType
{{/hasConsumes}}
{{#hasProduces}}
* @param string $responseMediaType
{{/hasProduces}}

View File

@ -0,0 +1,27 @@
{
"name": "{{#lambda.lowercase}}{{gitUserId}}/{{gitRepoId}}{{/lambda.lowercase}}",
"description": "{{description}}",
"license": "unlicense",
"version": "{{artifactVersion}}",
"type": "library",
"require": {
"php": "^7.3 || ^8.0",
"articus/data-transfer": "^0.5",
"articus/openapi-generator-common": "^0.2",
"articus/openapi-generator-apiclient": "^0.1",
"doctrine/annotations": "^1.10",
"psr/simple-cache": "^1.0",
"laminas/laminas-stdlib": "^3.2",
"laminas/laminas-validator": "^2.13"
},
"autoload": {
"psr-4": {
"": "{{srcBasePath}}/"
}
},
"require-dev": {
"laminas/laminas-servicemanager": "^3.6",
"laminas/laminas-diactoros": "^2.6",
"symfony/http-client": "^5.3"
}
}

View File

@ -0,0 +1,6 @@
#based on .gitignore generated by https://github.com/zendframework/zend-expressive-skeleton
.idea
# Composer files
composer.phar
vendor/

View File

@ -0,0 +1,8 @@
{{#items
}}{{^isContainer
}}{{#isPrimitiveType}}"{{dataType}}"{{/isPrimitiveType
}}{{^isPrimitiveType}}{{dataType}}::class{{/isPrimitiveType
}}{{/isContainer
}}{{#isContainer
}}{{dataType}}::class{{/isContainer
}}{{/items}}

View File

@ -0,0 +1,8 @@
{{#additionalProperties
}}{{^isContainer
}}{{#isPrimitiveType}}"{{dataType}}"{{/isPrimitiveType
}}{{^isPrimitiveType}}{{dataType}}::class{{/isPrimitiveType
}}{{/isContainer
}}{{#isContainer
}}{{dataType}}::class{{/isContainer
}}{{/additionalProperties}}

View File

@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
{{#models}}{{#model}}
namespace {{package}};
use Articus\DataTransfer\Annotation as DTA;
{{#vendorExtensions
}}{{#internal.fromContainer}}{{>model_container}}{{/internal.fromContainer
}}{{^internal.fromContainer}}{{>model_object}}{{/internal.fromContainer
}}{{/vendorExtensions
}}{{^vendorExtensions}}{{>model_object}}{{/vendorExtensions
}}{{/model}}{{/models}}

View File

@ -0,0 +1,59 @@
/**
{{#vars
}}{{#isArray
}} * @DTA\Strategy(name="{{#isPrimitiveType}}ScalarList{{/isPrimitiveType}}{{^isPrimitiveType}}ObjectList{{/isPrimitiveType}}", options={"type":{{>list_item_type}}})
{{#minItems}}{{^maxItems
}} * @DTA\Validator(name="Count", options={"min":{{minItems}}}, blocker=true)
{{/maxItems}}{{/minItems
}}{{^minItems}}{{#maxItems
}} * @DTA\Validator(name="Count", options={"max":{{maxItems}}}, blocker=true)
{{/maxItems}}{{/minItems
}}{{#minItems}}{{#maxItems
}} * @DTA\Validator(name="Count", options={"min":{{minItems}},"max":{{maxItems}}}, blocker=true)
{{/maxItems}}{{/minItems
}} * @DTA\Validator(name="Collection", options={"validators":{
{{#isPrimitiveType
}} * {"name":"Scalar", "options":{"type":{{>list_item_type}}}}
{{/isPrimitiveType
}}{{#isDate
}} * {"name":"Date"}
{{/isDate
}}{{#isDateTime
}} * {"name":"Date", "options":{"format": \DateTime::RFC3339}}
{{/isDateTime
}}{{^isPrimitiveType}}{{^isDate}}{{^isDateTime
}} * {"name":"TypeCompliant", "options":{"type":{{>list_item_type}}}}
{{/isDateTime}}{{/isDate}}{{/isPrimitiveType
}} * }})
{{/isArray
}}{{#isMap
}} * @DTA\Strategy(name="{{#isPrimitiveType}}ScalarMap{{/isPrimitiveType}}{{^isPrimitiveType}}ObjectMap{{/isPrimitiveType}}", options={"type":{{>map_item_type}}})
{{#minProperties}}{{^maxProperties
}} * @DTA\Validator(name="Count", options={"min":{{minProperties}}}, blocker=true)
{{/maxProperties}}{{/minProperties
}}{{^minProperties}}{{#maxProperties
}} * @DTA\Validator(name="Count", options={"max":{{maxProperties}}}, blocker=true)
{{/maxProperties}}{{/minProperties
}}{{#minProperties}}{{#maxProperties
}} * @DTA\Validator(name="Count", options={"min":{{minProperties}},"max":{{maxProperties}}}, blocker=true)
{{/maxProperties}}{{/minProperties
}} * @DTA\Validator(name="Collection", options={"validators":{
{{#isPrimitiveType
}} * {"name":"Scalar", "options":{"type":{{>map_item_type}}}}
{{/isPrimitiveType
}}{{#isDate
}} * {"name":"Date"}
{{/isDate
}}{{#isDateTime
}} * {"name":"Date", "options":{"format": \DateTime::RFC3339}}
{{/isDateTime
}}{{^isPrimitiveType}}{{^isDate}}{{^isDateTime
}} * {"name":"TypeCompliant", "options":{"type":{{>map_item_type}}}}
{{/isDateTime}}{{/isDate}}{{/isPrimitiveType
}} * }})
{{/isMap
}}{{/vars
}} */
class {{classname}} extends \ArrayObject
{
}

View File

@ -0,0 +1,45 @@
{{#isContainer
}} * @DTA\Strategy(name="Object", options={"type":{{internal.containerDataType}}::class})
* @DTA\Validator(name="TypeCompliant", options={"type":{{internal.containerDataType}}::class})
{{/isContainer
}}{{^isContainer
}}{{#isPrimitiveType
}} * @DTA\Validator(name="Scalar", options={"type":"{{dataType}}"})
{{/isPrimitiveType
}}{{#isDate
}} * @DTA\Strategy(name="Date")
* @DTA\Validator(name="Date")
{{/isDate
}}{{#isDateTime
}} * @DTA\Strategy(name="DateTime")
* @DTA\Validator(name="Date", options={"format": \DateTime::RFC3339})
{{/isDateTime
}}{{^isPrimitiveType
}}{{^isDate
}}{{^isDateTime
}} * @DTA\Strategy(name="Object", options={"type":{{dataType}}::class})
* @DTA\Validator(name="TypeCompliant", options={"type":{{dataType}}::class})
{{/isDateTime
}}{{/isDate
}}{{/isPrimitiveType
}}{{/isContainer
}}{{#hasValidation
}}{{#minLength}}{{#maxLength
}} * @DTA\Validator(name="StringLength", options={"min":{{minLength}}, "max":{{maxLength}}})
{{/maxLength}}{{/minLength
}}{{^minLength}}{{#maxLength
}} * @DTA\Validator(name="StringLength", options={"max":{{maxLength}}})
{{/maxLength}}{{/minLength
}}{{#minLength}}{{^maxLength
}} * @DTA\Validator(name="StringLength", options={"min":{{minLength}}})
{{/maxLength}}{{/minLength
}}{{#minimum
}} * @DTA\Validator(name="GreaterThan", options={"min":{{minimum}}{{^exclusiveMinimum}}, "inclusive":true{{/exclusiveMinimum}}})
{{/minimum
}}{{#maximum
}} * @DTA\Validator(name="LessThan", options={"max":{{maximum}}{{^exclusiveMaximum}}, "inclusive":true{{/exclusiveMaximum}}})
{{/maximum
}}{{#pattern
}} * @DTA\Validator(name="Regex", options={"pattern":"{{{pattern}}}"})
{{/pattern
}}{{/hasValidation}}

View File

@ -0,0 +1,24 @@
/**
{{#description
}} * {{description}}
{{/description
}} */
class {{classname}}
{
{{#vars
}} /**
{{#description
}} * {{description}}
{{/description
}} * @DTA\Data({{#vendorExtensions}}{{#internal.fromParameters}}subset="{{internal.parameterLocation}}", {{/internal.fromParameters}}{{/vendorExtensions}}field="{{baseName}}"{{^required}}, nullable=true{{/required}})
{{#vendorExtensions
}}{{#internal.fromParameters}}{{>model_query_var}}{{/internal.fromParameters
}}{{^internal.fromParameters}}{{>model_normal_var}}{{/internal.fromParameters
}}{{/vendorExtensions
}}{{^vendorExtensions}}{{>model_normal_var}}{{/vendorExtensions
}} * @var {{dataType}}|null
*/
public ${{name}};
{{/vars
}}}

View File

@ -0,0 +1,51 @@
{{#isArray
}}{{#isPrimitiveType
}} * @DTA\Strategy(subset="{{internal.parameterLocation}}", name="QueryStringScalarArray", options={"type":{{>list_item_type}}, "format":"{{internal.collectionFormat}}"})
* @DTA\Validator(subset="{{internal.parameterLocation}}", name="QueryStringScalarArray", options={"type":{{>list_item_type}}, "format":"{{internal.collectionFormat}}"{{#minItems}}, "min_items":{{minItems}}{{/minItems}}{{#maxItems}}, "max_items":{{maxItems}}{{/maxItems}}})
{{/isPrimitiveType
}}{{^isPrimitiveType
}} * TODO add validator(s) and strategy for list of {{>list_item_type}} and collection format {{internal.collectionFormat}} inside query string
{{/isPrimitiveType
}}{{/isArray
}}{{#isMap
}} * TODO add validator(s) and strategy for map of {{>map_item_type}} and collection format {{internal.collectionFormat}} inside query string
{{/isMap
}}{{^isContainer
}}{{#isPrimitiveType
}} * @DTA\Strategy(subset="{{internal.parameterLocation}}", name="QueryStringScalar", options={"type":"{{dataType}}"})
* @DTA\Validator(subset="{{internal.parameterLocation}}", name="QueryStringScalar", options={"type":"{{dataType}}"})
{{/isPrimitiveType
}}{{#isDate
}} * @DTA\Strategy(subset="{{internal.parameterLocation}}", name="Date")
* @DTA\Validator(subset="{{internal.parameterLocation}}", name="Date")
{{/isDate
}}{{#isDateTime
}} * @DTA\Strategy(subset="{{internal.parameterLocation}}", name="DateTime")
* @DTA\Validator(subset="{{internal.parameterLocation}}", name="Date", options={"format": \DateTime::RFC3339})
{{/isDateTime
}}{{^isPrimitiveType
}}{{^isDate}}{{^isDateTime
}} * TODO add validator(s) and strategy for {{dataType}} inside query string
{{/isDateTime}}{{/isDate
}}{{/isPrimitiveType
}}{{/isContainer
}}{{#hasValidation
}}{{#minLength}}{{#maxLength
}} * @DTA\Validator(subset="{{internal.parameterLocation}}", name="StringLength", options={"min":{{minLength}}, "max":{{maxLength}}})
{{/maxLength}}{{/minLength
}}{{^minLength}}{{#maxLength
}} * @DTA\Validator(subset="{{internal.parameterLocation}}", name="StringLength", options={"max":{{maxLength}}})
{{/maxLength}}{{/minLength
}}{{#minLength}}{{^maxLength
}} * @DTA\Validator(subset="{{internal.parameterLocation}}", name="StringLength", options={"min":{{minLength}}})
{{/maxLength}}{{/minLength
}}{{#minimum
}} * @DTA\Validator(subset="{{internal.parameterLocation}}", name="GreaterThan", options={"min":{{minimum}}{{^exclusiveMinimum}}, "inclusive":true{{/exclusiveMinimum}}})
{{/minimum
}}{{#maximum
}} * @DTA\Validator(subset="{{internal.parameterLocation}}", name="LessThan", options={"max":{{maximum}}{{^exclusiveMaximum}}, "inclusive":true{{/exclusiveMaximum}}})
{{/maximum
}}{{#pattern
}} * @DTA\Validator(subset="{{internal.parameterLocation}}", name="Regex", options={"pattern":"{{{pattern}}}"})
{{/pattern
}}{{/hasValidation}}

View File

@ -0,0 +1,6 @@
#based on .gitignore generated by https://github.com/zendframework/zend-expressive-skeleton
.idea
# Composer files
composer.phar
vendor/

View File

@ -0,0 +1,23 @@
# OpenAPI Generator Ignore
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.
# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
#ApiClient.cs
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md

View File

@ -0,0 +1,62 @@
.gitignore
README.md
composer.json
src/App/ApiClient.php
src/App/ApiClientFactory.php
src/App/DTO/ApiResponse.php
src/App/DTO/Category.php
src/App/DTO/Collection.php
src/App/DTO/Collection1.php
src/App/DTO/Collection10.php
src/App/DTO/Collection11.php
src/App/DTO/Collection12.php
src/App/DTO/Collection13.php
src/App/DTO/Collection14.php
src/App/DTO/Collection15.php
src/App/DTO/Collection16.php
src/App/DTO/Collection17.php
src/App/DTO/Collection18.php
src/App/DTO/Collection19.php
src/App/DTO/Collection2.php
src/App/DTO/Collection20.php
src/App/DTO/Collection21.php
src/App/DTO/Collection22.php
src/App/DTO/Collection23.php
src/App/DTO/Collection24.php
src/App/DTO/Collection25.php
src/App/DTO/Collection26.php
src/App/DTO/Collection27.php
src/App/DTO/Collection28.php
src/App/DTO/Collection29.php
src/App/DTO/Collection3.php
src/App/DTO/Collection30.php
src/App/DTO/Collection31.php
src/App/DTO/Collection32.php
src/App/DTO/Collection33.php
src/App/DTO/Collection34.php
src/App/DTO/Collection35.php
src/App/DTO/Collection36.php
src/App/DTO/Collection4.php
src/App/DTO/Collection5.php
src/App/DTO/Collection6.php
src/App/DTO/Collection7.php
src/App/DTO/Collection8.php
src/App/DTO/Collection9.php
src/App/DTO/DeleteOrderParameterData.php
src/App/DTO/DeletePetParameterData.php
src/App/DTO/DeleteUserParameterData.php
src/App/DTO/FindPetsByStatusParameterData.php
src/App/DTO/FindPetsByTagsParameterData.php
src/App/DTO/GetOrderByIdParameterData.php
src/App/DTO/GetPetByIdParameterData.php
src/App/DTO/GetUserByNameParameterData.php
src/App/DTO/InlineObject.php
src/App/DTO/InlineObject1.php
src/App/DTO/LoginUserParameterData.php
src/App/DTO/Order.php
src/App/DTO/Pet.php
src/App/DTO/Tag.php
src/App/DTO/UpdatePetWithFormParameterData.php
src/App/DTO/UpdateUserParameterData.php
src/App/DTO/UploadFileParameterData.php
src/App/DTO/User.php

View File

@ -0,0 +1 @@
5.2.1-SNAPSHOT

View File

@ -0,0 +1,135 @@
# Client library for OpenAPI Petstore
Generated by the [OpenAPI Generator](https://openapi-generator.tech) project.
## Overview
This lightweight extensible client library is [PSR-7](https://www.php-fig.org/psr/psr-7), [PSR-11](https://www.php-fig.org/psr/psr-11), [PSR-17](https://www.php-fig.org/psr/psr-17) and [PSR-18](https://www.php-fig.org/psr/psr-18) complaint and relies on:
- PHP: >=8.0
- [Data Transfer](https://github.com/Articus/DataTransfer): >=0.5
## How to use
This library can be used either as a separate package (just deploy generated files to your package repository and add dependency `"git_user_id/git_repo_id":"1.0.0"` to your project `composer.json`) or as a part of your project (just copy generated code from `src` and merge generated `composer.json` into your project `composer.json`).
First you need an implementation for [PSR-7](https://packagist.org/packages/psr/http-message) and [PSR-17](https://packagist.org/packages/psr/http-factory) interfaces. Usually it is a single package, and your project might already have one among its dependencies (for example if it is some web service). Otherwise, https://packagist.org/providers/psr/http-message-implementation and https://packagist.org/providers/psr/http-factory-implementation may help to find some suitable options.
Next choose an implementation for [PSR-18 interfaces](https://packagist.org/packages/psr/http-client). https://packagist.org/providers/psr/http-client-implementation may help to find some suitable options.
Then check content types for API requests you intend to send and API responses you intend to receive. For each unique content type you will need an implementation of [`OpenAPIGenerator\APIClient\BodyCoderInterface`](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/BodyCoderInterface.php) to encode request bodies and decode response bodies. Currently, only [`application/json` body coder](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/BodyCoder/Json.php) is provided out-of-the-box.
After that review security requirements for API operations you intend to use. For each unique security scheme you will need an implementation of [OpenAPIGenerator\APIClient\SecurityProviderInterface](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/SecurityProviderInterface.php). Currently, only [HTTP Bearer authentication](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/SecurityProvider/HttpBearer.php) is supported out-of-the-box.
The last step is to configure and wire all services together. It is highly advisable to use [PSR-11 container](https://packagist.org/packages/psr/container) for that. If you have not selected one for your project yet, https://packagist.org/providers/psr/container-implementation may help to find some suitable options. Here is a sample wiring configuration for `"laminas/laminas-servicemanager"`, `"laminas/laminas-diactoros"` and `"symfony/http-client"` (consult generated `composer.json` for the exact versions of used packages):
```PHP
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
$dependencies = [
'invokables' => [
Psr\Http\Message\RequestFactoryInterface::class => Laminas\Diactoros\RequestFactory::class,
Psr\Http\Message\ResponseFactoryInterface::class => Laminas\Diactoros\ResponseFactory::class,
Psr\Http\Message\StreamFactoryInterface::class => Laminas\Diactoros\StreamFactory::class,
],
'factories' => [
App\ApiClient::class => App\ApiClientFactory::class,
Articus\DataTransfer\Service::class => Articus\DataTransfer\Factory::class,
Articus\DataTransfer\MetadataProvider\PhpAttribute::class => Articus\DataTransfer\MetadataProvider\Factory\PhpAttribute::class,
Articus\DataTransfer\Strategy\PluginManager::class => Articus\DataTransfer\Strategy\Factory\PluginManager::class,
Articus\DataTransfer\Validator\PluginManager::class => Articus\DataTransfer\Validator\Factory\PluginManager::class,
Laminas\Validator\ValidatorPluginManager::class => Laminas\Validator\ValidatorPluginManagerFactory::class,
OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class => OpenAPIGenerator\APIClient\SecurityProvider\Factory\PluginManager::class,
OpenAPIGenerator\APIClient\BodyCoder\PluginManager::class => OpenAPIGenerator\APIClient\BodyCoder\Factory\PluginManager::class,
Psr\Http\Client\ClientInterface::class => function (Psr\Container\ContainerInterface $container)
{
return new Symfony\Component\HttpClient\Psr18Client(
new Symfony\Component\HttpClient\NativeHttpClient(),
$container->get(Psr\Http\Message\ResponseFactoryInterface::class),
$container->get(Psr\Http\Message\StreamFactoryInterface::class)
);
},
],
'aliases' => [
Articus\DataTransfer\ClassMetadataProviderInterface::class => Articus\DataTransfer\MetadataProvider\PhpAttribute::class,
Articus\DataTransfer\FieldMetadataProviderInterface::class => Articus\DataTransfer\MetadataProvider\PhpAttribute::class,
],
];
$config = [
'dependencies' => $dependencies,
//Configure DataTransfer library
Articus\DataTransfer\Strategy\PluginManager::class => [
'invokables' => [
'QueryStringScalar' => OpenAPIGenerator\Common\Strategy\QueryStringScalar::class,
'QueryStringScalarArray' => OpenAPIGenerator\Common\Strategy\QueryStringScalarArray::class,
],
'factories' => [
'Date' => OpenAPIGenerator\Common\Strategy\Factory\ImmutableDate::class,
'DateTime' => OpenAPIGenerator\Common\Strategy\Factory\ImmutableDateTime::class,
'ObjectList' => OpenAPIGenerator\Common\Strategy\Factory\NoArgObjectList::class,
'ObjectMap' => OpenAPIGenerator\Common\Strategy\Factory\NoArgObjectMap::class,
'ScalarList' => OpenAPIGenerator\Common\Strategy\Factory\ScalarList::class,
'ScalarMap' => OpenAPIGenerator\Common\Strategy\Factory\ScalarMap::class,
]
],
Articus\DataTransfer\Validator\PluginManager::class => [
'invokables' => [
'Scalar' => OpenAPIGenerator\Common\Validator\Scalar::class,
'QueryStringScalar' => OpenAPIGenerator\Common\Validator\QueryStringScalar::class,
'QueryStringScalarArray' => OpenAPIGenerator\Common\Validator\QueryStringScalarArray::class,
],
'abstract_factories' => [
Articus\DataTransfer\Validator\Factory\Laminas::class,
],
],
'validators' => [
'invokables' => [
'Count' => Laminas\Validator\IsCountable::class,
],
],
//Set API server URL here
App\ApiClient::class => [
//'server_url' => 'https://api.url',
],
//Register body coders for used content types here
OpenAPIGenerator\APIClient\BodyCoder\PluginManager::class => [
'factories' => [
//'another/mime-type' => AnotherMimeTypeBodyCoder::class
],
],
//Register security providers for used security schemes here
OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class => [
'factories' => [
//'another-security-scheme' => AnotherSecuritySchemeProvider::class,
],
'aliases' => [
//'custom-name-for-htt-bearer' => OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer::class,
],
],
];
$container = new Laminas\ServiceManager\ServiceManager($dependencies);
$container->setService('config', $config);
$container->setAlias('Config', 'config');
/** @var App\ApiClient $client */
$client = $container->get(App\ApiClient::class);
//... and now you can use client methods to call API operations :)
//And one more sample: how to set token for HTTP Bearer authentication
/** @var OpenAPIGenerator\APIClient\SecurityProvider\PluginManager $securityProviders */
$securityProviders = $container->get(OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class);
/** @var OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer $httpBearer */
$httpBearer = $securityProviders->get(OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer::class);
$httpBearer->setToken('some-token');
```

View File

@ -0,0 +1,26 @@
{
"name": "git_user_id/git_repo_id",
"description": "",
"license": "unlicense",
"version": "1.0.0",
"type": "library",
"require": {
"php": "^8.0",
"articus/data-transfer": "^0.5",
"articus/openapi-generator-common": "^0.2",
"articus/openapi-generator-apiclient": "^0.1",
"psr/simple-cache": "^1.0",
"laminas/laminas-stdlib": "^3.2",
"laminas/laminas-validator": "^2.13"
},
"autoload": {
"psr-4": {
"": "src/"
}
},
"require-dev": {
"laminas/laminas-servicemanager": "^3.6",
"laminas/laminas-diactoros": "^2.6",
"symfony/http-client": "^5.3"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace App;
use Articus\DataTransfer as DT;
use Interop\Container\ContainerInterface;
use OpenAPIGenerator\APIClient as OAGAC;
class ApiClientFactory extends DT\ConfigAwareFactory
{
public function __construct(string $configKey = ApiClient::class)
{
parent::__construct($configKey);
}
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$config = new OAGAC\ApiClientOptions(\array_merge($this->getServiceConfig($container), $options ?? []));
return new ApiClient(
$config->serverUrl,
$container->get($config->dataTransferServiceName),
$container->get($config->requestFactoryServiceName),
$container->get($config->httpClientServiceName),
$container->get($config->securityProviderFactoryServiceName),
$container->get($config->bodyCoderFactoryServiceName),
$container->get($config->bodyCoderFactoryServiceName)
);
}
}

View File

@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
/**
* Describes the result of uploading an image resource
*/
class ApiResponse
{
#[DTA\Data(field: "code", nullable: true)]
#[DTA\Validator("Scalar", ["type" => "int"])]
public int|null $code = null;
#[DTA\Data(field: "type", nullable: true)]
#[DTA\Validator("Scalar", ["type" => "string"])]
public string|null $type = null;
#[DTA\Data(field: "message", nullable: true)]
#[DTA\Validator("Scalar", ["type" => "string"])]
public string|null $message = null;
}

View File

@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
/**
* A category for a pet
*/
class Category
{
#[DTA\Data(field: "id", nullable: true)]
#[DTA\Validator("Scalar", ["type" => "int"])]
public int|null $id = null;
#[DTA\Data(field: "name", nullable: true)]
#[DTA\Validator("Scalar", ["type" => "string"])]
#[DTA\Validator("Regex", ["pattern" => "/^[a-zA-Z0-9]+[a-zA-Z0-9\\.\\-_]*[a-zA-Z0-9]+$/"])]
public string|null $name = null;
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ScalarList", ["type" => "string"])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "Scalar", "options" => ["type" => "string"]]
]])]
class Collection extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
]])]
class Collection1 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ScalarList", ["type" => "string"])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "Scalar", "options" => ["type" => "string"]]
]])]
class Collection10 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
]])]
class Collection11 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ScalarList", ["type" => "string"])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "Scalar", "options" => ["type" => "string"]]
]])]
class Collection12 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
]])]
class Collection13 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ScalarList", ["type" => "string"])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "Scalar", "options" => ["type" => "string"]]
]])]
class Collection14 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
]])]
class Collection15 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ScalarList", ["type" => "string"])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "Scalar", "options" => ["type" => "string"]]
]])]
class Collection16 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ScalarList", ["type" => "string"])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "Scalar", "options" => ["type" => "string"]]
]])]
class Collection17 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
]])]
class Collection18 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Pet::class])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Pet::class]]
]])]
class Collection19 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ScalarList", ["type" => "string"])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "Scalar", "options" => ["type" => "string"]]
]])]
class Collection2 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ScalarList", ["type" => "string"])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "Scalar", "options" => ["type" => "string"]]
]])]
class Collection20 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
]])]
class Collection21 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Pet::class])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Pet::class]]
]])]
class Collection22 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ScalarList", ["type" => "string"])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "Scalar", "options" => ["type" => "string"]]
]])]
class Collection23 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ScalarList", ["type" => "string"])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "Scalar", "options" => ["type" => "string"]]
]])]
class Collection24 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
]])]
class Collection25 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Pet::class])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Pet::class]]
]])]
class Collection26 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ScalarList", ["type" => "string"])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "Scalar", "options" => ["type" => "string"]]
]])]
class Collection27 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
]])]
class Collection28 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Pet::class])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Pet::class]]
]])]
class Collection29 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
]])]
class Collection3 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ScalarList", ["type" => "string"])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "Scalar", "options" => ["type" => "string"]]
]])]
class Collection30 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
]])]
class Collection31 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ScalarList", ["type" => "string"])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "Scalar", "options" => ["type" => "string"]]
]])]
class Collection32 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
]])]
class Collection33 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ScalarMap", ["type" => "int"])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "Scalar", "options" => ["type" => "int"]]
]])]
class Collection34 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ObjectList", ["type" => \App\DTO\User::class])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "TypeCompliant", "options" => ["type" => \App\DTO\User::class]]
]])]
class Collection35 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ObjectList", ["type" => \App\DTO\User::class])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "TypeCompliant", "options" => ["type" => \App\DTO\User::class]]
]])]
class Collection36 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ScalarList", ["type" => "string"])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "Scalar", "options" => ["type" => "string"]]
]])]
class Collection4 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
]])]
class Collection5 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ScalarList", ["type" => "string"])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "Scalar", "options" => ["type" => "string"]]
]])]
class Collection6 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
]])]
class Collection7 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ScalarList", ["type" => "string"])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "Scalar", "options" => ["type" => "string"]]
]])]
class Collection8 extends \ArrayObject
{
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
#[DTA\Validator("Collection", ["validators" => [
["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
]])]
class Collection9 extends \ArrayObject
{
}

View File

@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
/**
* Parameters for deleteOrder
*/
class DeleteOrderParameterData
{
/**
* ID of the order that needs to be deleted
*/
#[DTA\Data(subset: "path", field: "orderId")]
#[DTA\Strategy("QueryStringScalar", ["type" => "string"], "path")]
#[DTA\Validator("QueryStringScalar", ["type" => "string"], subset: "path")]
public string|null $order_id = null;
}

View File

@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
/**
* Parameters for deletePet
*/
class DeletePetParameterData
{
/**
* Pet id to delete
*/
#[DTA\Data(subset: "path", field: "petId")]
#[DTA\Strategy("QueryStringScalar", ["type" => "int"], "path")]
#[DTA\Validator("QueryStringScalar", ["type" => "int"], subset: "path")]
public int|null $pet_id = null;
#[DTA\Data(subset: "header", field: "api_key", nullable: true)]
#[DTA\Strategy("QueryStringScalar", ["type" => "string"], "header")]
#[DTA\Validator("QueryStringScalar", ["type" => "string"], subset: "header")]
public string|null $api_key = null;
}

View File

@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
/**
* Parameters for deleteUser
*/
class DeleteUserParameterData
{
/**
* The name that needs to be deleted
*/
#[DTA\Data(subset: "path", field: "username")]
#[DTA\Strategy("QueryStringScalar", ["type" => "string"], "path")]
#[DTA\Validator("QueryStringScalar", ["type" => "string"], subset: "path")]
public string|null $username = null;
}

View File

@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
/**
* Parameters for findPetsByStatus
*/
class FindPetsByStatusParameterData
{
/**
* Status values that need to be considered for filter
*/
#[DTA\Data(subset: "query", field: "status")]
#[DTA\Strategy("QueryStringScalarArray", ["type" => "string", "format" => "csv"], "query")]
#[DTA\Validator("QueryStringScalarArray", ["type" => "string", "format" => "csv"], subset: "query")]
public array|null $status = null;
}

View File

@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
/**
* Parameters for findPetsByTags
*/
class FindPetsByTagsParameterData
{
/**
* Tags to filter by
*/
#[DTA\Data(subset: "query", field: "tags")]
#[DTA\Strategy("QueryStringScalarArray", ["type" => "string", "format" => "csv"], "query")]
#[DTA\Validator("QueryStringScalarArray", ["type" => "string", "format" => "csv"], subset: "query")]
public array|null $tags = null;
}

View File

@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
/**
* Parameters for getOrderById
*/
class GetOrderByIdParameterData
{
/**
* ID of pet that needs to be fetched
*/
#[DTA\Data(subset: "path", field: "orderId")]
#[DTA\Strategy("QueryStringScalar", ["type" => "int"], "path")]
#[DTA\Validator("QueryStringScalar", ["type" => "int"], subset: "path")]
#[DTA\Validator("GreaterThan", ["min" => 1, "inclusive" => true], subset: "path")]
#[DTA\Validator("LessThan", ["max" => 5, "inclusive" => true], subset: "path")]
public int|null $order_id = null;
}

View File

@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
/**
* Parameters for getPetById
*/
class GetPetByIdParameterData
{
/**
* ID of pet to return
*/
#[DTA\Data(subset: "path", field: "petId")]
#[DTA\Strategy("QueryStringScalar", ["type" => "int"], "path")]
#[DTA\Validator("QueryStringScalar", ["type" => "int"], subset: "path")]
public int|null $pet_id = null;
}

View File

@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
/**
* Parameters for getUserByName
*/
class GetUserByNameParameterData
{
/**
* The name that needs to be fetched. Use user1 for testing.
*/
#[DTA\Data(subset: "path", field: "username")]
#[DTA\Strategy("QueryStringScalar", ["type" => "string"], "path")]
#[DTA\Validator("QueryStringScalar", ["type" => "string"], subset: "path")]
public string|null $username = null;
}

View File

@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
class InlineObject
{
/**
* Updated name of the pet
*/
#[DTA\Data(field: "name", nullable: true)]
#[DTA\Validator("Scalar", ["type" => "string"])]
public string|null $name = null;
/**
* Updated status of the pet
*/
#[DTA\Data(field: "status", nullable: true)]
#[DTA\Validator("Scalar", ["type" => "string"])]
public string|null $status = null;
}

View File

@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
class InlineObject1
{
/**
* Additional data to pass to server
*/
#[DTA\Data(field: "additionalMetadata", nullable: true)]
#[DTA\Validator("Scalar", ["type" => "string"])]
public string|null $additional_metadata = null;
/**
* file to upload
*/
#[DTA\Data(field: "file", nullable: true)]
#[DTA\Strategy("Object", ["type" => \SplFileObject::class])]
#[DTA\Validator("TypeCompliant", ["type" => \SplFileObject::class])]
public \SplFileObject|null $file = null;
}

View File

@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
/**
* Parameters for loginUser
*/
class LoginUserParameterData
{
/**
* The password for login in clear text
*/
#[DTA\Data(subset: "query", field: "password")]
#[DTA\Strategy("QueryStringScalar", ["type" => "string"], "query")]
#[DTA\Validator("QueryStringScalar", ["type" => "string"], subset: "query")]
public string|null $password = null;
/**
* The user name for login
*/
#[DTA\Data(subset: "query", field: "username")]
#[DTA\Strategy("QueryStringScalar", ["type" => "string"], "query")]
#[DTA\Validator("QueryStringScalar", ["type" => "string"], subset: "query")]
#[DTA\Validator("Regex", ["pattern" => "/^[a-zA-Z0-9]+[a-zA-Z0-9\\.\\-_]*[a-zA-Z0-9]+$/"], subset: "query")]
public string|null $username = null;
}

View File

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
/**
* An order for a pets from the pet store
*/
class Order
{
#[DTA\Data(field: "id", nullable: true)]
#[DTA\Validator("Scalar", ["type" => "int"])]
public int|null $id = null;
#[DTA\Data(field: "petId", nullable: true)]
#[DTA\Validator("Scalar", ["type" => "int"])]
public int|null $pet_id = null;
#[DTA\Data(field: "quantity", nullable: true)]
#[DTA\Validator("Scalar", ["type" => "int"])]
public int|null $quantity = null;
#[DTA\Data(field: "shipDate", nullable: true)]
#[DTA\Strategy("DateTime")]
#[DTA\Validator("Date", ["format" => \DateTime::RFC3339])]
public \DateTime|null $ship_date = null;
/**
* Order Status
*/
#[DTA\Data(field: "status", nullable: true)]
#[DTA\Validator("Scalar", ["type" => "string"])]
public string|null $status = null;
#[DTA\Data(field: "complete", nullable: true)]
#[DTA\Validator("Scalar", ["type" => "bool"])]
public bool|null $complete = null;
}

View File

@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
/**
* A pet for sale in the pet store
*/
class Pet
{
#[DTA\Data(field: "id", nullable: true)]
#[DTA\Validator("Scalar", ["type" => "int"])]
public int|null $id = null;
#[DTA\Data(field: "category", nullable: true)]
#[DTA\Strategy("Object", ["type" => \App\DTO\Category::class])]
#[DTA\Validator("TypeCompliant", ["type" => \App\DTO\Category::class])]
public \App\DTO\Category|null $category = null;
#[DTA\Data(field: "name")]
#[DTA\Validator("Scalar", ["type" => "string"])]
public string|null $name = null;
#[DTA\Data(field: "photoUrls")]
#[DTA\Strategy("Object", ["type" => \App\DTO\Collection32::class])]
#[DTA\Validator("TypeCompliant", ["type" => \App\DTO\Collection32::class])]
public \App\DTO\Collection32|null $photo_urls = null;
#[DTA\Data(field: "tags", nullable: true)]
#[DTA\Strategy("Object", ["type" => \App\DTO\Collection33::class])]
#[DTA\Validator("TypeCompliant", ["type" => \App\DTO\Collection33::class])]
public \App\DTO\Collection33|null $tags = null;
/**
* pet status in the store
*/
#[DTA\Data(field: "status", nullable: true)]
#[DTA\Validator("Scalar", ["type" => "string"])]
public string|null $status = null;
}

View File

@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace App\DTO;
use Articus\DataTransfer\PhpAttribute as DTA;
/**
* A tag for a pet
*/
class Tag
{
#[DTA\Data(field: "id", nullable: true)]
#[DTA\Validator("Scalar", ["type" => "int"])]
public int|null $id = null;
#[DTA\Data(field: "name", nullable: true)]
#[DTA\Validator("Scalar", ["type" => "string"])]
public string|null $name = null;
}

Some files were not shown because too many files have changed in this diff Show More