diff --git a/.gitignore b/.gitignore index cce9df3dcfd4..c31b8389c196 100644 --- a/.gitignore +++ b/.gitignore @@ -90,6 +90,11 @@ samples/client/petstore/silex/SwaggerServer/venodr/ **/vendor/ **/composer.lock +#PHP-Symfony +samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/cache/ +samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/logs/ + + # Perl samples/client/petstore/perl/deep_module_test/ diff --git a/bin/php-symfony-petstore.sh b/bin/php-symfony-petstore.sh new file mode 100755 index 000000000000..17d9418b3861 --- /dev/null +++ b/bin/php-symfony-petstore.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +SCRIPT="$0" + +while [ -h "$SCRIPT" ] ; do + ls=`ls -ld "$SCRIPT"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + SCRIPT="$link" + else + SCRIPT=`dirname "$SCRIPT"`/"$link" + fi +done + +# Make sure that the working directory is the root dir +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cd "${SCRIPT_DIR}/../" + +if [ ! -d "${APP_DIR}" ]; then + APP_DIR=`dirname "$SCRIPT"`/.. + APP_DIR=`cd "${APP_DIR}"; pwd` +fi + +# Make sure that we are regenerating the sample by removing any existing target directory +TARGET_DIR="$SCRIPT_DIR/../samples/server/petstore/php-symfony" +if [ -d "$TARGET_DIR" ]; then + rm -rf $TARGET_DIR +fi + +executable="$SCRIPT_DIR/../modules/swagger-codegen-cli/target/swagger-codegen-cli.jar" + +if [ ! -f "$executable" ] +then + mvn clean package +fi + +# if you've executed sbt assembly previously it will use that instead. +export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" +ags="generate -t $SCRIPT_DIR/../modules/swagger-codegen/src/main/resources/php-symfony -i $SCRIPT_DIR/../modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l php-symfony -o $TARGET_DIR $@" + +java $JAVA_OPTS -jar $executable $ags diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SymfonyServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SymfonyServerCodegen.java index 87ce66f16a70..ae9cbd81fdff 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SymfonyServerCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SymfonyServerCodegen.java @@ -32,7 +32,9 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC protected String bundleExtensionName; protected String bundleAlias; protected String controllerDirName = "Controller"; + protected String serviceDirName = "Service"; protected String controllerPackage; + protected String servicePackage; protected Boolean phpLegacySupport = Boolean.TRUE; protected HashSet typeHintable; @@ -74,7 +76,9 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC modelDocPath = docsBasePath + File.separator + modelDirName; outputFolder = "generated-code" + File.separator + "php"; apiTemplateFiles.put("api_controller.mustache", ".php"); - modelTestTemplateFiles.put("model_test.mustache", ".php"); + modelTestTemplateFiles.put("testing/model_test.mustache", ".php"); + apiTestTemplateFiles = new HashMap(); + apiTestTemplateFiles.put("testing/api_test.mustache", ".php"); embeddedTemplateDir = templateDir = "php-symfony"; setReservedWordsLowerCase( @@ -105,13 +109,10 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC ) ); - //instantiationTypes.put("array", "array"); - //instantiationTypes.put("map", "map"); - defaultIncludes = new HashSet( Arrays.asList( "\\DateTime", - "\\SplFileObject" + "UploadedFile" ) ); @@ -135,7 +136,7 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC typeMapping.put("boolean", "bool"); typeMapping.put("Date", "\\DateTime"); typeMapping.put("DateTime", "\\DateTime"); - typeMapping.put("file", "\\SplFileObject"); + typeMapping.put("file", "UploadedFile"); typeMapping.put("map", "array"); typeMapping.put("array", "array"); typeMapping.put("list", "array"); @@ -242,6 +243,7 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\")); additionalProperties.put("controllerPackage", controllerPackage); + additionalProperties.put("servicePackage", servicePackage); additionalProperties.put("apiTestsPackage", apiTestsPackage); additionalProperties.put("modelTestsPackage", modelTestsPackage); @@ -275,14 +277,28 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC supportingFiles.add(new SupportingFile("Extension.mustache", dependencyInjectionDir, bundleExtensionName + ".php")); supportingFiles.add(new SupportingFile("ApiPass.mustache", dependencyInjectionDir + File.separator + "Compiler", bundleName + "ApiPass.php")); supportingFiles.add(new SupportingFile("ApiServer.mustache", toPackagePath(apiPackage, srcBasePath), "ApiServer.php")); - supportingFiles.add(new SupportingFile("ModelSerializer.mustache", toPackagePath(modelPackage, srcBasePath), "ModelSerializer.php")); - supportingFiles.add(new SupportingFile("ModelInterface.mustache", toPackagePath(modelPackage, srcBasePath), "ModelInterface.php")); + + // Serialization components + supportingFiles.add(new SupportingFile("serialization/SerializerInterface.mustache", toPackagePath(servicePackage, srcBasePath), "SerializerInterface.php")); + supportingFiles.add(new SupportingFile("serialization/JmsSerializer.mustache", toPackagePath(servicePackage, srcBasePath), "JmsSerializer.php")); + supportingFiles.add(new SupportingFile("serialization/StrictJsonDeserializationVisitor.mustache", toPackagePath(servicePackage, srcBasePath), "StrictJsonDeserializationVisitor.php")); + supportingFiles.add(new SupportingFile("serialization/TypeMismatchException.mustache", toPackagePath(servicePackage, srcBasePath), "TypeMismatchException.php")); + // Validation components + supportingFiles.add(new SupportingFile("validation/ValidatorInterface.mustache", toPackagePath(servicePackage, srcBasePath), "ValidatorInterface.php")); + supportingFiles.add(new SupportingFile("validation/SymfonyValidator.mustache", toPackagePath(servicePackage, srcBasePath), "SymfonyValidator.php")); + + // Testing components + supportingFiles.add(new SupportingFile("testing/phpunit.xml.mustache", getPackagePath(), "phpunit.xml.dist")); + supportingFiles.add(new SupportingFile("testing/pom.xml", getPackagePath(), "pom.xml")); + supportingFiles.add(new SupportingFile("testing/AppKernel.php", toPackagePath(testsPackage, srcBasePath), "AppKernel.php")); + supportingFiles.add(new SupportingFile("testing/test_config.yml", toPackagePath(testsPackage, srcBasePath), "test_config.yml")); + supportingFiles.add(new SupportingFile("routing.mustache", configDir, "routing.yml")); supportingFiles.add(new SupportingFile("services.mustache", configDir, "services.yml")); supportingFiles.add(new SupportingFile("composer.mustache", getPackagePath(), "composer.json")); supportingFiles.add(new SupportingFile("autoload.mustache", getPackagePath(), "autoload.php")); supportingFiles.add(new SupportingFile("README.mustache", getPackagePath(), "README.md")); - supportingFiles.add(new SupportingFile("phpunit.xml.mustache", getPackagePath(), "phpunit.xml.dist")); + supportingFiles.add(new SupportingFile(".travis.yml", getPackagePath(), ".travis.yml")); supportingFiles.add(new SupportingFile(".php_cs", getPackagePath(), ".php_cs")); supportingFiles.add(new SupportingFile("git_push.sh.mustache", getPackagePath(), "git_push.sh")); @@ -329,6 +345,14 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC if (!typeHint.isEmpty()) { param.vendorExtensions.put("x-parameterType", typeHint); } + + // Quote default values for strings + // @todo: The default values for headers, forms and query params are handled + // in DefaultCodegen fromParameter with no real possibility to override + // the functionality. Thus we are handling quoting of string values here + if (param.dataType.equals("string") && param.defaultValue != null && !param.defaultValue.isEmpty()) { + param.defaultValue = "'"+param.defaultValue+"'"; + } } for (CodegenResponse response : op.responses) { @@ -340,9 +364,6 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC if (response.dataType != null) { final String dataType = extractSimpleName(response.dataType); response.vendorExtensions.put("x-simpleName", dataType); - // if (!typeMapping.containsValue(dataType)) { - // imports.add(response.dataType.replaceFirst("\\[\\]$", "")); - // } } } @@ -364,19 +385,15 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC ArrayList modelsArray = (ArrayList) objs.get("models"); Map models = (Map) modelsArray.get(0); CodegenModel model = (CodegenModel) models.get("model"); - HashSet imports = new HashSet<>(); // Simplify model var type for (CodegenProperty var : model.vars) { if (var.datatype != null) { - final String importType = var.datatype.replaceFirst("\\[\\]$", ""); - final String dataType = extractSimpleName(var.datatype); - final boolean isScalarType = typeMapping.containsValue(importType); - var.vendorExtensions.put("x-fullType", var.datatype); - if (!isScalarType) { - var.vendorExtensions.put("x-typeAnnotation", dataType.endsWith("[]") ? "array" : dataType); - imports.add(importType); - var.datatype = dataType; + // Determine if the paramter type is supported as a type hint and make it available + // to the templating engine + String typeHint = getTypeHint(var.datatype); + if (!typeHint.isEmpty()) { + var.vendorExtensions.put("x-parameterType", typeHint); } if (var.isBoolean) { @@ -385,8 +402,6 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC } } - objs.put("useStatements", new ArrayList<>(imports)); - return objs; } @@ -425,6 +440,7 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC apiTestsPackage = testsPackage + "\\" + apiDirName; modelTestsPackage = testsPackage + "\\" + modelDirName; controllerPackage = invokerPackage + "\\" + controllerDirName; + servicePackage = invokerPackage + "\\" + serviceDirName; } @Override @@ -485,6 +501,26 @@ public class SymfonyServerCodegen extends AbstractPhpCodegen implements CodegenC } } + @Override + public String toEnumValue(String value, String datatype) { + if ("int".equals(datatype) || "double".equals(datatype) || "float".equals(datatype)) { + return value; + } else { + return "\"" + escapeText(value) + "\""; + } + } + + /** + * Return the regular expression/JSON schema pattern (http://json-schema.org/latest/json-schema-validation.html#anchor33) + * + * @param pattern the pattern (regular expression) + * @return properly-escaped pattern + */ + @Override + public String toRegularExpression(String pattern) { + return escapeText(pattern); + } + public String toApiName(String name) { if (name.isEmpty()) { return "DefaultApiInterface"; diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/Controller.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/Controller.mustache index af937c7d99fe..c1adc2f64a40 100644 --- a/modules/swagger-codegen/src/main/resources/php-symfony/Controller.mustache +++ b/modules/swagger-codegen/src/main/resources/php-symfony/Controller.mustache @@ -19,9 +19,10 @@ namespace {{controllerPackage}}; -use Symfony\Bundle\FrameworkBundle\Controller\Controller as BaseController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\HttpException; +use {{servicePackage}}\SerializerInterface; +use {{servicePackage}}\ValidatorInterface; /** * Controller Class Doc Comment @@ -31,212 +32,141 @@ use Symfony\Component\HttpKernel\Exception\HttpException; * @author Swagger Codegen team * @link https://github.com/swagger-api/swagger-codegen */ -class Controller extends BaseController +class Controller { + protected $validator; + protected $serializer; + protected $apiServer; - /** - * This will return a response with code 400. Usage example: - * return $this->createBadRequestResponse('Unable to access this page!'); - * - * @param string $message A message - * - * @return Response - */ - public function createBadRequestResponse($message = 'Bad Request.') - { - return new Response($message, 400); - } + public function setValidator(ValidatorInterface $validator) + { + $this->validator = $validator; + } - /** - * This will return an error response. Usage example: - * return $this->createErrorResponse(new UnauthorizedHttpException()); - * - * @param HttpException $exception An HTTP exception - * - * @return Response - */ - public function createErrorResponse(HttpException $exception) - { - $statusCode = $exception->getStatusCode(); - $headers = array_merge($exception->getHeaders(), ['Content-Type' => 'application/json']); + public function setSerializer(SerializerInterface $serializer) + { + $this->serializer = $serializer; + } - $json = $this->exceptionToArray($exception); - $json['statusCode'] = $statusCode; + public function setApiServer($server) + { + $this->apiServer = $server; + } - return new Response(json_encode($json, 15, 512), $statusCode, $headers); - } + /** + * This will return a response with code 400. Usage example: + * return $this->createBadRequestResponse('Unable to access this page!'); + * + * @param string $message A message + * + * @return Response + */ + public function createBadRequestResponse($message = 'Bad Request.') + { + return new Response($message, 400); + } - /** - * Serializes data to a given type format. - * - * @param mixed $data The data to serialize. - * @param string $class The source data class. - * @param string $format The target serialization format. - * - * @return string A serialized data string. - */ - public function serialize($data, $format) - { - return $this->get('{{bundleAlias}}.model.model_serializer')->serialize($data, $format); - } + /** + * This will return an error response. Usage example: + * return $this->createErrorResponse(new UnauthorizedHttpException()); + * + * @param HttpException $exception An HTTP exception + * + * @return Response + */ + public function createErrorResponse(HttpException $exception) + { + $statusCode = $exception->getStatusCode(); + $headers = array_merge($exception->getHeaders(), ['Content-Type' => 'application/json']); - /** - * Deserializes data from a given type format. - * - * @param string $data The data to deserialize. - * @param string $class The target data class. - * @param string $format The source serialization format. - * - * @return mixed A deserialized data. - */ - public function deserialize($data, $class, $format) - { - return $this->get('{{bundleAlias}}.model.model_serializer')->deserialize($data, $class, $format); - } + $json = $this->exceptionToArray($exception); + $json['statusCode'] = $statusCode; - /** - * Decodes a string value. - * - * @param string $string The string value to decode. - * @param string $dataType The data type of the parameter. - * - * @return mixed The decoded value. - */ - public function fromString($string, $dataType) - { - if ($dataType === 'integer' || $dataType === 'number') { - return $this->toNumber($string); - } - if ($dataType === 'bool') { - return $this->toBoolean($string); - } - if ($dataType === '\DateTime') { - return $this->toDateTime($string); - } + return new Response(json_encode($json, 15, 512), $statusCode, $headers); + } - return $string; - } + /** + * Serializes data to a given type format. + * + * @param mixed $data The data to serialize. + * @param string $class The source data class. + * @param string $format The target serialization format. + * + * @return string A serialized data string. + */ + protected function serialize($data, $format) + { + return $this->serializer->serialize($data, $format); + } - /** - * Decodes a header value. - * - * @param string $header The header value to decode. - * @param string $dataType The data type of the parameter. - * - * @return mixed The decoded value. - */ - public function fromHeader($header, $dataType) - { - return $this->fromString($header, $dataType); - } + /** + * Deserializes data from a given type format. + * + * @param string $data The data to deserialize. + * @param string $class The target data class. + * @param string $format The source serialization format. + * + * @return mixed A deserialized data. + */ + protected function deserialize($data, $class, $format) + { + return $this->serializer->deserialize($data, $class, $format); + } - /** - * Decodes a query value. - * - * @param string $query The query value to decode. - * @param string $dataType The data type of the parameter. - * - * @return mixed The decoded value. - */ - public function fromQuery($query, $dataType) - { - return $this->fromString($query, $dataType); - } + protected function validate($data, $asserts = null) + { + $errors = $this->validator->validate($data, $asserts); - /** - * Decodes a path value. - * - * @param string $path The path value to decode. - * @param string $dataType The data type of the parameter. - * - * @return mixed The decoded value. - */ - public function fromPath($path, $dataType) - { - return $this->fromString($path, $dataType); - } + if (count($errors) > 0) { + $errorsString = (string)$errors; + return $this->createBadRequestResponse($errorsString); + } + } - /** - * Decodes a form value. - * - * @param string $form The form value to decode. - * @param string $dataType The data type of the parameter. - * - * @return mixed The decoded value. - */ - public function fromForm($form, $dataType) - { - return $this->fromString($form, $dataType); - } + /** + * Converts an exception to a serializable array. + * + * @param \Exception|null $exception + * + * @return array + */ + private function exceptionToArray(\Exception $exception = null) + { + if (null === $exception) { + return null; + } - /** - * Decoded a string to a number. - * - * @param string $string The string to decode. - * - * @return number|null A decoded number, or null, if not a valid string. - */ - private function toNumber($string) - { - if (is_numeric($string)) { - return $string + 0; - } + return [ + 'message' => $exception->getMessage(), + 'type' => get_class($exception), + 'previous' => $this->exceptionToArray($exception->getPrevious()), + ]; + } - return null; - } + protected function getOutputFormat($accept, array $produced) + { + // Figure out what the client accepts + $accept = preg_split("/[\s,]+/", $accept); + + if (in_array('*/*', $accept) || in_array('application/*', $accept)) { + // Prefer JSON if the client has no preference + if (in_array('application/json', $produced)) { + return 'application/json'; + } + if (in_array('application/xml', $produced)) { + return 'application/xml'; + } + } - /** - * Decoded a string to a boolean. - * - * @param string $string The string to decode. - * - * @return boolean|null A decoded boolean, or null, if not a valid string. - */ - private function toBoolean($string) - { - if ($string === 'true') { - return true; - } - if ($string === 'false') { - return false; - } + if (in_array('application/json', $accept) && in_array('application/json', $produced)) { + return 'application/json'; + } - return null; - } + if (in_array('application/xml', $accept) && in_array('application/xml', $produced)) { + return 'application/xml'; + } - /** - * Decoded a string to a date time. - * - * @param string $string The string to decode. - * - * @return \DateTime|null A decoded date time, or null, if not a valid string. - */ - private function toDateTime($string) - { - if ($dateTime = date_create($string)) { - return $dateTime; - } - - return null; - } - - /** - * Converts an exception to a serializable array. - * - * @param \Exception|null $exception - * - * @return array - */ - private function exceptionToArray(\Exception $exception = null) - { - if (null === $exception) { - return null; - } - - return [ - 'message' => $exception->getMessage(), - 'type' => get_class($exception), - 'previous' => $this->exceptionToArray($exception->getPrevious()), - ]; - } + // If we reach this point, we don't have a common ground between server and client + return null; + } } diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/ModelInterface.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/ModelInterface.mustache deleted file mode 100644 index a568374d6d38..000000000000 --- a/modules/swagger-codegen/src/main/resources/php-symfony/ModelInterface.mustache +++ /dev/null @@ -1,55 +0,0 @@ -partial_header}} -/** - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen - * Do not edit the class manually. - */ - -namespace {{modelPackage}}; - -/** - * Interface abstracting model access. - * - * @package {{modelPackage}} - * @author Swagger Codegen team - */ -interface ModelInterface -{ - - /** - * The original name of the model. - * - * @return string - */ - public function modelName(); - - /** - * Array of property to mappings. - * - * @return array[] - */ - public function modelAttributes(); - - /** - * Validate all the properties in the model - * - * Return true if all passed. - * - * @return bool True if all properties are valid - */ - public function isValid(); -} - - diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/ModelSerializer.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/ModelSerializer.mustache deleted file mode 100644 index c2064b60a8d2..000000000000 --- a/modules/swagger-codegen/src/main/resources/php-symfony/ModelSerializer.mustache +++ /dev/null @@ -1,174 +0,0 @@ -partial_header}} -/** - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen - * Do not edit the class manually. - */ - -namespace {{modelPackage}}; - -/** - * ModelSerializer Class Doc Comment - * - * @category Class - * @package {{modelPackage}} - * @author Swagger Codegen team - * @link https://github.com/swagger-api/swagger-codegen - */ -class ModelSerializer -{ - - /** - * Serializes data to a given type format. - * - * @param mixed $data The data to serialize. - * @param string $format The target serialization format. - * - * @return string A serialized data string. - * @throws \InvalidArgumentException When invalid serialization format was used. - */ - public function serialize($data, $format) - { - $normalized = $this->normalize($data); - if ($format === 'json') { - return json_encode($normalized, 15, 512); - } - - throw new \InvalidArgumentException('Unsupported serialization format: '.$format); - } - - /** - * Deserializes data from a given type format. - * - * @param string $data The data to deserialize. - * @param string $class The target class to deserialize to. - * @param string $format The source serialization format. - * - * @return mixed A deserialized value. - * @throws \InvalidArgumentException When invalid serialization format was used. - */ - public function deserialize($data, $class, $format) - { - switch ($format) { - case 'json': - $normalized = json_decode($data, true, 512, 15); - break; - default: - throw new \InvalidArgumentException('Unsupported serialization format: '.$format); - } - - return $this->denormalize($normalized, $class); - } - - public function normalize($data, $format = null) - { - if (is_scalar($data) || null === $data) { - return $data; - } - - if (is_array($data)) { - return array_map(function ($value) use ($format) { - return $this->normalize($value, $format); - }, $data); - } - - if ($data instanceof \DateTime) { - return ($format === 'date') ? $data->format('Y-m-d') : $data->format(\DateTime::ATOM); - } - - if ($data instanceof ModelInterface) { - $values = []; - foreach ($data->modelAttributes() as $name => $attribute) { - list($baseName, , $format, , $getter) = $attribute; - $value = $this->normalize($data->$getter(), $format); - if ($value !== null && method_exists($data, 'getAllowableEnumValues') - && !in_array($value, $data::getAllowableEnumValues())) { - $imploded = implode("', '", $data::getAllowableEnumValues()); - throw new \InvalidArgumentException("Invalid value for enum '$data', must be one of: '$imploded'"); - } - - if ($value !== null) { - $values[$baseName] = $value; - } - } - - return $values; - } - - return (string) $data; - } - - public function denormalize($data, $class, $format = null) - { - if ($data === null) { - return null; - } - - if (in_array($class, ['DateTime', 'bool', 'boolean', 'byte', 'double', 'float', 'int', 'integer', 'mixed', 'number', 'object', 'string', 'void'], true)) { - settype($data, $class); - return $data; - } - - // Denormalize array - if (substr($class, -2) === '[]') { - $innerClass = substr($class, 0, -2); - return array_map(function ($value) use ($format, $innerClass) { - return $this->denormalize($value, $innerClass, $format); - }, $data); - } - - if (!class_exists($class)) { - return $data; - } - - // Denormalize enum - if (method_exists($class, 'getAllowableEnumValues')) { - if (!in_array($data, $class::getAllowableEnumValues())) { - $imploded = implode("', '", $class::getAllowableEnumValues()); - throw new \InvalidArgumentException("Invalid value for enum '$class', must be one of: '$imploded'"); - } - - return $data; - } - - // If a discriminator is defined and points to a valid subclass, use it. - $discriminator = $class::DISCRIMINATOR; - if (!empty($discriminator) && isset($data[$discriminator]) && is_string($data[$discriminator])) { - $subclass = '{{modelPackage}}\\'.$data[$discriminator]; - if (is_subclass_of($subclass, $class)) { - $class = $subclass; - } - } - - // Denormalize another model - $values = new $class(); - if ($values instanceof ModelInterface) { - foreach ($values->modelAttributes() as $name => $attribute) { - list($baseName, $innerClass, $format, $setter) = $attribute; - - if (!isset($data[$baseName])) { - continue; - } - - $value = $this->denormalize($data[$baseName], $innerClass, $format); - $values->$setter($value); - } - - return $values; - } - - return $data; - } -} diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/README.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/README.mustache index d61acfa1c84d..0b72cf635fac 100644 --- a/modules/swagger-codegen/src/main/resources/php-symfony/README.mustache +++ b/modules/swagger-codegen/src/main/resources/php-symfony/README.mustache @@ -23,28 +23,28 @@ PHP 5.4.0 and later ## Installation & Usage -To install the bindings via [Composer](http://getcomposer.org/), add the following to `composer.json`: +To install the dependencies via [Composer](http://getcomposer.org/), add the following repository to `composer.json` of your Symfony project: -``` +```json { - "repositories": [ - { - "type": "git", - "url": "https://github.com/{{#composerVendorName}}{{.}}{{/composerVendorName}}{{^composerVendorName}}{{gitUserId}}{{/composerVendorName}}/{{#composerProjectName}}{{.}}{{/composerProjectName}}{{^composerProjectName}}{{gitRepoId}}{{/composerProjectName}}.git" - } - ], - "require": { - "{{#composerVendorName}}{{.}}{{/composerVendorName}}{{^composerVendorName}}{{gitUserId}}{{/composerVendorName}}/{{#composerProjectName}}{{.}}{{/composerProjectName}}{{^composerProjectName}}{{gitRepoId}}{{/composerProjectName}}": "*@dev" - } + "repositories": [{ + "type": "path", + "url": "//Path to your generated swagger bundle" + }], } ``` -Then run `composer install` +Then run: +``` +composer require {{#composerVendorName}}{{.}}{{/composerVendorName}}{{^composerVendorName}}{{gitUserId}}{{/composerVendorName}}/{{#composerProjectName}}{{.}}{{/composerProjectName}}{{^composerProjectName}}{{gitRepoId}}{{/composerProjectName}}:dev-master +``` + +to add the generated swagger bundle as a dependency. ## Tests -To run the unit tests: +To run the unit tests for the generated bundle, first navigate to the directory containing the code, then run the following commands: ``` composer install diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/api.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/api.mustache index b3985a9489ac..0e581a1b84de 100644 --- a/modules/swagger-codegen/src/main/resources/php-symfony/api.mustache +++ b/modules/swagger-codegen/src/main/resources/php-symfony/api.mustache @@ -18,6 +18,7 @@ namespace {{apiPackage}}; +use Symfony\Component\HttpFoundation\File\UploadedFile; {{#operations}}{{#imports}}use {{import}}; {{/imports}} @@ -58,18 +59,15 @@ interface {{classname}} {{#allParams}} * @param {{dataType}} ${{paramName}} {{description}} {{#required}}(required){{/required}}{{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}} {{/allParams}} + * @param integer $responseCode The HTTP response code to return + * @param array $responseHeaders Additional HTTP headers to return with the response () * - {{#responses}} - {{#vendorExtensions.x-symfonyExceptionSimple}} - * @throws {{vendorExtensions.x-symfonyExceptionSimple}} {{message}} - {{/vendorExtensions.x-symfonyExceptionSimple}} - {{^vendorExtensions.x-symfonyExceptionSimple}} - * @return {{^dataType}}void{{/dataType}}{{#dataType}}{{dataType}}{{/dataType}} {{message}} + {{#returnType}} + * @return {{{returnType}}} * - {{/vendorExtensions.x-symfonyExceptionSimple}} - {{/responses}} + {{/returnType}} */ - public function {{operationId}}({{#allParams}}{{#vendorExtensions.x-parameterType}}{{vendorExtensions.x-parameterType}} {{/vendorExtensions.x-parameterType}}${{paramName}}{{^required}} = {{#defaultValue}}'{{{.}}}'{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); + public function {{operationId}}({{#allParams}}{{#vendorExtensions.x-parameterType}}{{vendorExtensions.x-parameterType}} {{/vendorExtensions.x-parameterType}}${{paramName}}{{^required}} = {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}{{/required}}, {{/allParams}}&$responseCode, array &$responseHeaders); {{/operation}} } {{/operations}} diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/api_controller.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/api_controller.mustache index 8fb9efb5ed7c..6f21a082eb59 100644 --- a/modules/swagger-codegen/src/main/resources/php-symfony/api_controller.mustache +++ b/modules/swagger-codegen/src/main/resources/php-symfony/api_controller.mustache @@ -23,6 +23,7 @@ use \Exception; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\HttpException; +use Symfony\Component\Validator\Constraints as Assert; use {{apiPackage}}\{{classname}}; {{#imports}}use {{import}}; {{/imports}} @@ -53,8 +54,28 @@ class {{controllerName}} extends Controller * @param Request $request The Symfony request to handle. * @return Response The Symfony response. */ - public function {{operationId}}Action(Request $request) + public function {{operationId}}Action(Request $request{{#hasPathParams}}{{#pathParams}}, ${{paramName}}{{/pathParams}}{{/hasPathParams}}) { + {{#bodyParams}} + // Make sure that the client is providing something that we can consume + $consumes = [{{#consumes}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/consumes}}]; + $inputFormat = $request->headers->has('Content-Type')?$request->headers->get('Content-Type'):$consumes[0]; + if (!in_array($inputFormat, $consumes)) { + // We can't consume the content that the client is sending us + return new Response('', 415); + } + + {{/bodyParams}} + // Figure out what data format to return to the client + $produces = [{{#produces}}'{{mediaType}}'{{#hasMore}}, {{/hasMore}}{{/produces}}]; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication {{#authMethods}} // Authentication '{{name}}' required {{#isApiKey}} @@ -76,81 +97,58 @@ class {{controllerName}} extends Controller $security{{name}} = $request->headers->get('authorization'); {{/isOAuth}} {{/authMethods}} + + // Read out all input parameter values into variables + {{#allParams}} {{#queryParams}} - // Handle query params - ${{paramName}} = $this->fromQuery($request->query->get('{{paramName}}'), '{{dataType}}'); + ${{paramName}} = $request->query->get('{{paramName}}'); {{/queryParams}} {{#headerParams}} - // Handle header params - ${{paramName}} = $this->fromHeader($request->headers->get('{{paramName}}'), '{{dataType}}'); + ${{paramName}} = $request->headers->get('{{paramName}}'); {{/headerParams}} - {{#pathParams}} - // Handle path params - ${{paramName}} = $this->fromPath($request->attributes->get('{{paramName}}'), '{{dataType}}'); - {{/pathParams}} {{#formParams}} {{#isFile}} - // Handle file params ${{paramName}} = $request->files->get('{{paramName}}'); {{/isFile}} {{^isFile}} - // Handle form params - ${{paramName}} = $this->fromForm($request->request->get('{{paramName}}'), '{{dataType}}'); + ${{paramName}} = $request->request->get('{{paramName}}'); {{/isFile}} {{/formParams}} {{#bodyParams}} - // Handle body params - ${{paramName}} = $this->deserialize($request->getContent(), '{{{dataType}}}', 'json'); + ${{paramName}} = $request->getContent(); {{/bodyParams}} - // Parse incoming parameters - {{#allParams}} - {{#required}} - // Verify the required parameter '{{paramName}}' is set - if (${{paramName}} === null) { - return $this->createBadRequestResponse('Missing the required parameter ${{paramName}} when calling {{operationId}}'); - } + // Use the default value if no value was provided + {{^required}} + {{#isContainer}} + {{#items}} + {{#defaultValue}} + ${{paramName}} = ${{paramName}}?:[{{{defaultValue}}}]; + {{/defaultValue}} + {{/items}} + {{/isContainer}} + {{^isContainer}} + {{#defaultValue}} + ${{paramName}} = ${{paramName}}?:{{{defaultValue}}}; + {{/defaultValue}} + {{/isContainer}} {{/required}} - {{#hasValidation}} - {{#maxLength}} - if ({{^required}}!is_null(${{paramName}}) && {{/required}}(strlen(${{paramName}}) > {{maxLength}})) { - return $this->createBadRequestResponse('Invalid length for "${{paramName}}" when calling {{classname}}.{{operationId}}, must be smaller than or equal to {{maxLength}}.'); - } - {{/maxLength}} - {{#minLength}} - if ({{^required}}!is_null(${{paramName}}) && {{/required}}(strlen(${{paramName}}) < {{minLength}})) { - return $this->createBadRequestResponse('Invalid length for "${{paramName}}" when calling {{classname}}.{{operationId}}, must be bigger than or equal to {{minLength}}.'); - } - {{/minLength}} - {{#maximum}} - if ({{^required}}!is_null(${{paramName}}) && {{/required}}(${{paramName}} >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}})) { - return $this->createBadRequestResponse('Invalid value for "${{paramName}}" when calling {{classname}}.{{operationId}}, must be smaller than {{^exclusiveMaximum}}or equal to {{/exclusiveMaximum}}{{maximum}}.'); - } - {{/maximum}} - {{#minimum}} - if ({{^required}}!is_null(${{paramName}}) && {{/required}}(${{paramName}} <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}})) { - return $this->createBadRequestResponse('Invalid value for "${{paramName}}" when calling {{classname}}.{{operationId}}, must be bigger than {{^exclusiveMinimum}}or equal to {{/exclusiveMinimum}}{{minimum}}.'); - } - {{/minimum}} - {{#pattern}} - if ({{^required}}!is_null(${{paramName}}) && {{/required}}!preg_match("{{{pattern}}}", ${{paramName}})) { - return $this->createBadRequestResponse("Invalid value for \"{{paramName}}\" when calling {{classname}}.{{operationId}}, must conform to the pattern {{{pattern}}}."); - } - {{/pattern}} - {{#maxItems}} - if ({{^required}}!is_null(${{paramName}}) && {{/required}}(count(${{paramName}}) > {{maxItems}})) { - return $this->createBadRequestResponse('Invalid value for "${{paramName}}" when calling {{classname}}.{{operationId}}, number of items must be less than or equal to {{maxItems}}.'); - } - {{/maxItems}} - {{#minItems}} - if ({{^required}}!is_null(${{paramName}}) && {{/required}}(count(${{paramName}}) < {{minItems}})) { - return $this->createBadRequestResponse('Invalid value for "${{paramName}}" when calling {{classname}}.{{operationId}}, number of items must be greater than or equal to {{minItems}}.'); - } - {{/minItems}} - {{/hasValidation}} + + // Deserialize the input values that needs it + {{^isFile}} + {{#bodyParams}} + + ${{paramName}} = $this->deserialize(${{paramName}}, '{{{dataType}}}', $inputFormat); + {{/bodyParams}} + {{^bodyParams}} + ${{paramName}} = $this->deserialize(${{paramName}}, '{{#isContainer}}array<{{#collectionFormat}}{{collectionFormat}}{{/collectionFormat}}{{^collectionFormat}}csv{{/collectionFormat}}>{{/isContainer}}{{^isContainer}}{{dataType}}{{/isContainer}}', 'string'); + {{/bodyParams}} + {{/isFile}} {{/allParams}} - // Call the API interface + // Validate the input values +{{>api_input_validation}} + try { $handler = $this->getApiHandler(); @@ -158,31 +156,35 @@ class {{controllerName}} extends Controller // Set authentication method '{{name}}' $handler->set{{name}}($security{{name}}); {{/authMethods}} - {{#returnType}} - // Expecting a return value (exception otherwise) - $result = $handler->{{operationId}}({{#allParams}}${{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); + + // Make the call to the business logic + $responseCode = {{#returnType}}200{{/returnType}}{{^returnType}}204{{/returnType}}; + $responseHeaders = []; + $result = $handler->{{operationId}}({{#allParams}}${{paramName}}, {{/allParams}}$responseCode, $responseHeaders); + // Find default response message + $message = '{{#responses}}{{#isDefault}}{{message}}{{/isDefault}}{{/responses}}'; + + // Find a more specific message, if available + switch ($responseCode) { {{#responses}} - {{^vendorExtensions.x-symfonyExceptionSimple}} - // Handle {{code}} response: {{message}} - $content = $this->serialize($result, 'json'); - return new Response($content, {{code}}, [ - 'Content-Type' => 'application/json', - 'X-Swagger-Message' => '{{message}}', - ]); - {{/vendorExtensions.x-symfonyExceptionSimple}} + case {{code}}: + $message = '{{message}}'; + break; {{/responses}} - {{/returnType}} - {{^returnType}} - // No return type expected; return empty response - $handler->{{operationId}}({{#allParams}}${{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); - return new Response('', 204); - {{/returnType}} - {{#responses}} - } catch (HttpException $exception) { - // {{message}} - return $this->createErrorResponse($exception); - {{/responses}} + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); } catch (Exception $fallthrough) { return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); } @@ -195,7 +197,7 @@ class {{controllerName}} extends Controller */ public function getApiHandler() { - return $this->get('{{bundleAlias}}.api.api_server')->getApiHandler('{{pathPrefix}}'); + return $this->apiServer->getApiHandler('{{pathPrefix}}'); } } {{/operations}} diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/api_input_validation.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/api_input_validation.mustache new file mode 100644 index 000000000000..0bcd30534851 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/php-symfony/api_input_validation.mustache @@ -0,0 +1,88 @@ +{{#allParams}} + $asserts = []; +{{#required}} + $asserts[] = new Assert\NotNull(); +{{/required}} +{{#isEnum}} + {{#isContainer}} + $asserts[] = new Assert\All([ + {{#items}} + new Assert\Choice([ {{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}} ]) + {{/items}} + ]); + {{/isContainer}} + {{^isContainer}} + $asserts[] = new Assert\Choice([ {{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}} ]); + {{/isContainer}} +{{/isEnum}} +{{#isContainer}} + $asserts[] = new Assert\All([ + {{#items}} + new Assert\Type("{{datatype}}") + {{/items}} + ]); +{{/isContainer}} +{{^isContainer}} + {{#isDate}} + $asserts[] = new Assert\Date(); + {{/isDate}} + {{#isDateTime}} + $asserts[] = new Assert\DateTime(); + {{/isDateTime}} + {{^isDate}} + {{^isDateTime}} + {{#isFile}} + $asserts[] = new Assert\File(); + {{/isFile}} + {{^isFile}} + $asserts[] = new Assert\Type("{{dataType}}"); + {{/isFile}} + {{/isDateTime}} + {{/isDate}} +{{/isContainer}} +{{#hasValidation}} + {{#maxLength}} + $asserts[] = new Assert\Length([ + 'max' => {{maxLength}} + ]); + {{/maxLength}} + {{#minLength}} + $asserts[] = new Assert\Length([ + 'min' => {{minLength}} + ]); + {{/minLength}} + {{#minimum}} + {{#exclusiveMinimum}} + $asserts[] = new Assert\GreaterThan({{minimum}}); + {{/exclusiveMinimum}} + {{^exclusiveMinimum}} + $asserts[] = new Assert\GreaterThanOrEqual({{minimum}}); + {{/exclusiveMinimum}} + {{/minimum}} + {{#maximum}} + {{#exclusiveMaximum}} + $asserts[] = new Assert\LessThan({{minimum}}); + {{/exclusiveMaximum}} + {{^exclusiveMaximum}} + $asserts[] = new Assert\LessThanOrEqual({{minimum}}); + {{/exclusiveMaximum}} + {{/maximum}} + {{#pattern}} + $asserts[] = new Assert\Regex("/{{pattern}}/"); + {{/pattern}} + {{#maxItems}} + $asserts[] = new Assert\Count([ + 'max' => {{maxItems}} + ]); + {{/maxItems}} + {{#minItems}} + $asserts[] = new Assert\Count([ + 'min' => {{minItems}} + ]); + {{/minItems}} +{{/hasValidation}} + $response = $this->validate(${{paramName}}, $asserts); + if ($response instanceof Response) { + return $response; + } +{{/allParams}} diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/api_test.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/api_test.mustache deleted file mode 100644 index c1f16c70ceab..000000000000 --- a/modules/swagger-codegen/src/main/resources/php-symfony/api_test.mustache +++ /dev/null @@ -1,77 +0,0 @@ -partial_header}} -/** - * NOTE: This class is auto generated by the swagger code generator program. - * https://github.com/swagger-api/swagger-codegen - * Please update the test case below to test the endpoint. - */ - -namespace {{apiTestsPackage}}; - -use \{{invokerPackage}}\Configuration; -use \{{invokerPackage}}\ApiClient; -use \{{invokerPackage}}\ApiException; -use \{{invokerPackage}}\ObjectSerializer; - -/** - * {{classname}}Test Class Doc Comment - * - * @category Class - * @package {{apiTestsPackage}} - * @author Swagger Codegen team - * @link https://github.com/swagger-api/swagger-codegen - */ -{{#operations}}class {{classname}}Test extends \PHPUnit_Framework_TestCase -{ - - /** - * Setup before running any test cases - */ - public static function setUpBeforeClass() - { - } - - /** - * Setup before running each test case - */ - public function setUp() - { - } - - /** - * Clean up after running each test case - */ - public function tearDown() - { - } - - /** - * Clean up after running all test cases - */ - public static function tearDownAfterClass() - { - } - {{#operation}} - - /** - * Test case for {{{operationId}}} - * - * {{{summary}}}. - * - */ - public function test{{operationIdCamelCase}}() - { - } - {{/operation}} -} -{{/operations}} diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/composer.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/composer.mustache index eda7618bf65f..5d6156df5504 100644 --- a/modules/swagger-codegen/src/main/resources/php-symfony/composer.mustache +++ b/modules/swagger-codegen/src/main/resources/php-symfony/composer.mustache @@ -23,13 +23,17 @@ "ext-curl": "*", "ext-json": "*", "ext-mbstring": "*", + "symfony/validator": "*", + "jms/serializer-bundle": "*", "symfony/framework-bundle": "^2.3|^3.0" }, "require-dev": { "phpunit/phpunit": "~4.8", "satooshi/php-coveralls": "~1.0", "squizlabs/php_codesniffer": "~2.6", - "friendsofphp/php-cs-fixer": "~1.12" + "friendsofphp/php-cs-fixer": "~1.12", + "symfony/browser-kit": "*", + "hoa/regex": "~1.0" }, "autoload": { "psr-4": { "{{escapedInvokerPackage}}\\" : "{{srcBasePath}}/" } diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/model.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/model.mustache index 6e8655780757..02d96acb45fb 100644 --- a/modules/swagger-codegen/src/main/resources/php-symfony/model.mustache +++ b/modules/swagger-codegen/src/main/resources/php-symfony/model.mustache @@ -21,10 +21,9 @@ namespace {{modelPackage}}; -{{^isEnum}} -{{#useStatements}}use {{this}}; -{{/useStatements}} -{{/isEnum}} +use Symfony\Component\Validator\Constraints as Assert; +use JMS\Serializer\Annotation\Type; +use JMS\Serializer\Annotation\SerializedName; /** * Class representing the {{classname}} model. @@ -36,5 +35,5 @@ namespace {{modelPackage}}; * @package {{modelPackage}} * @author Swagger Codegen team */ -{{#isEnum}}{{>model_enum}}{{/isEnum}}{{^isEnum}}{{>model_generic}}{{/isEnum}} +{{>model_generic}} {{/model}}{{/models}} diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/model_generic.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/model_generic.mustache index 8e72f968406c..8106055c8548 100644 --- a/modules/swagger-codegen/src/main/resources/php-symfony/model_generic.mustache +++ b/modules/swagger-codegen/src/main/resources/php-symfony/model_generic.mustache @@ -1,49 +1,6 @@ -class {{classname}} {{#parentSchema}}extends {{{parent}}} {{/parentSchema}}implements ModelInterface, \ArrayAccess +class {{classname}} {{#parentSchema}}extends {{{parent}}} {{/parentSchema}} { - const DISCRIMINATOR = {{#discriminator}}'{{discriminator}}'{{/discriminator}}{{^discriminator}}null{{/discriminator}}; - - /** - * The original name of the model. - * @var string - */ - protected static $_name = '{{name}}'; - - /** - * Array of property to type mappings. Used for (de)serialization - * @var array[] - */ - protected static $_attributes = [{{#vars}} - '{{name}}' => ['{{baseName}}', '{{{vendorExtensions.x-fullType}}}', {{#dataFormat}}'{{{dataFormat}}}'{{/dataFormat}}{{^dataFormat}}null{{/dataFormat}}, '{{setter}}', '{{getter}}'],{{/vars}} - ]; - {{#vars}}{{#isEnum}} - - /** - * Allowed values of {{name}} - */{{#allowableValues}}{{#enumVars}} - const {{enumName}}_{{{name}}} = {{{value}}};{{/enumVars}}{{/allowableValues}}{{/isEnum}}{{/vars}} - - {{#vars}}{{#isEnum}} - /** - * Gets allowable values of the enum - * @return string[] - */ - public function {{getter}}AllowableValues() - { - return [ - {{#allowableValues}}{{#enumVars}}self::{{enumName}}_{{{name}}},{{^-last}} - {{/-last}}{{/enumVars}}{{/allowableValues}} - ]; - } - {{/isEnum}}{{/vars}} - {{#vars}} - /**{{#description}} - * {{description}} - * - {{/description}} - * @var {{{datatype}}}{{^required}}|null{{/required}} - */ - protected ${{name}}; - + {{#vars}}{{>model_variables}} {{/vars}} /** * Constructor @@ -58,187 +15,7 @@ class {{classname}} {{#parentSchema}}extends {{{parent}}} {{/parentSchema}}imple {{#vars}} $this->{{name}} = isset($data['{{name}}']) ? $data['{{name}}'] : {{#defaultValue}}{{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}; {{/vars}} - {{#discriminator}} - - // Initialize discriminator property with the model name. - foreach (self::$_attributes as $_name => $attribute) { - list($baseName) = $attribute; - if ('{{discriminator}}' === $baseName) { - $this->$_name = static::$_name; - } - } - {{/discriminator}} } - - /** - * show all the invalid properties with reasons. - * - * @return array invalid properties with reasons - */ - public function listInvalidProperties() - { - {{#parent}} - $invalid_properties = parent::listInvalidProperties(); - {{/parent}} - {{^parent}} - $invalid_properties = []; - {{/parent}} - - {{#vars}} - {{#required}} - if ($this->{{name}} === null) { - $invalid_properties[] = "'{{name}}' can't be null"; - } - {{/required}} - {{#isEnum}} - {{^isContainer}} - $allowedValues = $this->{{getter}}AllowableValues(); - if (!in_array($this->{{name}}, $allowedValues, true)) { - $invalid_properties[] = sprintf( - "invalid value for '{{name}}', must be one of '%s'", - implode("', '", $allowedValues) - ); - } - - {{/isContainer}} - {{/isEnum}} - {{#hasValidation}} - {{#maxLength}} - if ({{^required}}!is_null($this->{{name}}) && {{/required}}(strlen($this->{{name}}) > {{maxLength}})) { - $invalid_properties[] = "invalid value for '{{name}}', the character length must be smaller than or equal to {{{maxLength}}}."; - } - - {{/maxLength}} - {{#minLength}} - if ({{^required}}!is_null($this->{{name}}) && {{/required}}(strlen($this->{{name}}) < {{minLength}})) { - $invalid_properties[] = "invalid value for '{{name}}', the character length must be bigger than or equal to {{{minLength}}}."; - } - - {{/minLength}} - {{#maximum}} - if ({{^required}}!is_null($this->{{name}}) && {{/required}}($this->{{name}} >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}})) { - $invalid_properties[] = "invalid value for '{{name}}', must be smaller than {{^exclusiveMaximum}}or equal to {{/exclusiveMaximum}}{{maximum}}."; - } - - {{/maximum}} - {{#minimum}} - if ({{^required}}!is_null($this->{{name}}) && {{/required}}($this->{{name}} <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}})) { - $invalid_properties[] = "invalid value for '{{name}}', must be bigger than {{^exclusiveMinimum}}or equal to {{/exclusiveMinimum}}{{minimum}}."; - } - - {{/minimum}} - {{#pattern}} - if ({{^required}}!is_null($this->{{name}}) && {{/required}}!preg_match("{{{pattern}}}", $this->{{name}})) { - $invalid_properties[] = "invalid value for '{{name}}', must be conform to the pattern {{{pattern}}}."; - } - - {{/pattern}} - {{#maxItems}} - if ({{^required}}!is_null($this->{{name}}) && {{/required}}(count($this->{{name}}) > {{maxItems}})) { - $invalid_properties[] = "invalid value for '{{name}}', number of items must be less than or equal to {{{maxItems}}}."; - } - - {{/maxItems}} - {{#minItems}} - if ({{^required}}!is_null($this->{{name}}) && {{/required}}(count($this->{{name}}) < {{minItems}})) { - $invalid_properties[] = "invalid value for '{{name}}', number of items must be greater than or equal to {{{minItems}}}."; - } - - {{/minItems}} - {{/hasValidation}} - {{/vars}} - return $invalid_properties; - } - - /** - * The original name of the model. - * - * @return string - */ - public function modelName() { - return self::$_name; - } - - /** - * Array of property to mappings. - * - * @return array[] - */ - public function modelAttributes() { - {{#parentSchema}}return array_merge(parent::$_attributes, self::$_attributes);{{/parentSchema}} - {{^parentSchema}}return self::$_attributes;{{/parentSchema}} - } - - /** - * Validate all the properties in the model - * - * Return true if all passed. - * - * @return bool True if all properties are valid - */ - public function isValid() - { - {{#parent}} - if (!parent::isValid()) { - return false; - } - - {{/parent}} - {{#vars}} - {{#required}} - if ($this->{{name}} === null) { - return false; - } - {{/required}} - {{#isEnum}} - {{^isContainer}} - $allowedValues = $this->{{getter}}AllowableValues(); - if (!in_array($this->{{name}}, $allowedValues)) { - return false; - } - {{/isContainer}} - {{/isEnum}} - {{#hasValidation}} - {{#maxLength}} - if (strlen($this->{{name}}) > {{maxLength}}) { - return false; - } - {{/maxLength}} - {{#minLength}} - if (strlen($this->{{name}}) < {{minLength}}) { - return false; - } - {{/minLength}} - {{#maximum}} - if ($this->{{name}} >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}}) { - return false; - } - {{/maximum}} - {{#minimum}} - if ($this->{{name}} <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}}) { - return false; - } - {{/minimum}} - {{#pattern}} - if (!preg_match("{{{pattern}}}", $this->{{name}})) { - return false; - } - {{/pattern}} - {{#maxItems}} - if (count($this->{{name}}) > {{maxItems}}) { - return false; - } - {{/maxItems}} - {{#minItems}} - if (count($this->{{name}}) < {{minItems}}) { - return false; - } - {{/minItems}} - {{/hasValidation}} - {{/vars}} - return true; - } - {{#vars}} /** @@ -258,109 +35,11 @@ class {{classname}} {{#parentSchema}}extends {{{parent}}} {{/parentSchema}}imple * * @return $this */ - public function {{setter}}({{#vendorExtensions.x-typeAnnotation}}{{vendorExtensions.x-typeAnnotation}} {{/vendorExtensions.x-typeAnnotation}}${{name}}{{^required}} = null{{/required}}) + public function {{setter}}({{#vendorExtensions.x-parameterType}}{{vendorExtensions.x-parameterType}} {{/vendorExtensions.x-parameterType}}${{name}}{{^required}} = null{{/required}}) { - {{#isEnum}} - $allowedValues = $this->{{getter}}AllowableValues(); - {{^isContainer}} - if ({{^required}}${{name}} !== null && {{/required}}!in_array(${{{name}}}, $allowedValues, true)) { - throw new \InvalidArgumentException( - sprintf( - "Invalid value for '{{name}}', must be one of '%s'", - implode("', '", $allowedValues) - ) - ); - } - {{/isContainer}} - {{#isContainer}} - if ({{^required}}!is_null(${{name}}) && {{/required}}array_diff(${{{name}}}, $allowedValues)) { - throw new \InvalidArgumentException( - sprintf( - "Invalid value for '{{name}}', must be one of '%s'", - implode("', '", $allowedValues) - ) - ); - } - {{/isContainer}} - {{/isEnum}} - {{#hasValidation}} - {{#maxLength}} - if ({{^required}}!is_null(${{name}}) && {{/required}}(strlen(${{name}}) > {{maxLength}})) { - throw new \InvalidArgumentException('invalid length for ${{name}} when calling {{classname}}.{{operationId}}, must be smaller than or equal to {{maxLength}}.'); - }{{/maxLength}} - {{#minLength}} - if ({{^required}}!is_null(${{name}}) && {{/required}}(strlen(${{name}}) < {{minLength}})) { - throw new \InvalidArgumentException('invalid length for ${{name}} when calling {{classname}}.{{operationId}}, must be bigger than or equal to {{minLength}}.'); - } - {{/minLength}} - {{#maximum}} - if ({{^required}}!is_null(${{name}}) && {{/required}}(${{name}} >{{#exclusiveMaximum}}={{/exclusiveMaximum}} {{maximum}})) { - throw new \InvalidArgumentException('invalid value for ${{name}} when calling {{classname}}.{{operationId}}, must be smaller than {{^exclusiveMaximum}}or equal to {{/exclusiveMaximum}}{{maximum}}.'); - } - {{/maximum}} - {{#minimum}} - if ({{^required}}!is_null(${{name}}) && {{/required}}(${{name}} <{{#exclusiveMinimum}}={{/exclusiveMinimum}} {{minimum}})) { - throw new \InvalidArgumentException('invalid value for ${{name}} when calling {{classname}}.{{operationId}}, must be bigger than {{^exclusiveMinimum}}or equal to {{/exclusiveMinimum}}{{minimum}}.'); - } - {{/minimum}} - {{#pattern}} - if ({{^required}}!is_null(${{name}}) && {{/required}}(!preg_match("{{{pattern}}}", ${{name}}))) { - throw new \InvalidArgumentException("invalid value for ${{name}} when calling {{classname}}.{{operationId}}, must conform to the pattern {{{pattern}}}."); - } - {{/pattern}} - {{#maxItems}} - if ({{^required}}!is_null(${{name}}) && {{/required}}(count(${{name}}) > {{maxItems}})) { - throw new \InvalidArgumentException('invalid value for ${{name}} when calling {{classname}}.{{operationId}}, number of items must be less than or equal to {{maxItems}}.'); - }{{/maxItems}} - {{#minItems}} - if ({{^required}}!is_null(${{name}}) && {{/required}}(count(${{name}}) < {{minItems}})) { - throw new \InvalidArgumentException('invalid length for ${{name}} when calling {{classname}}.{{operationId}}, number of items must be greater than or equal to {{minItems}}.'); - } - {{/minItems}} - {{/hasValidation}} $this->{{name}} = ${{name}}; return $this; } {{/vars}} - /** - * Returns true if offset exists. False otherwise. - * @param integer $offset Offset - * @return boolean - */ - public function offsetExists($offset) - { - return isset($this->$offset); - } - - /** - * Gets offset. - * @param integer $offset Offset - * @return mixed - */ - public function offsetGet($offset) - { - return isset($this->$offset) ? $this->$offset : null; - } - - /** - * Sets value based on offset. - * @param string $offset Offset - * @param mixed $value Value to be set - * @return void - */ - public function offsetSet($offset, $value) - { - $this->$offset = $value; - } - - /** - * Unsets offset. - * @param integer $offset Offset - * @return void - */ - public function offsetUnset($offset) - { - $this->$offset = null; - } } diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/model_variables.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/model_variables.mustache new file mode 100644 index 000000000000..d0af5b8579e5 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/php-symfony/model_variables.mustache @@ -0,0 +1,91 @@ + /** + {{#description}} + * {{description}} + * + {{/description}} + * @var {{{datatype}}}{{^required}}|null{{/required}} + * @SerializedName("{{baseName}}") +{{#required}} + * @Assert\NotNull() +{{/required}} +{{#isEnum}} + {{#isContainer}} + * @Assert\All({ + {{#items}} + * @Assert\Choice({ {{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}} }) + {{/items}} + * }) + {{/isContainer}} + {{^isContainer}} + * @Assert\Choice({ {{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}} }) + {{/isContainer}} +{{/isEnum}} +{{#isContainer}} + * @Assert\All({ + {{#items}} + * @Assert\Type("{{datatype}}") + {{/items}} + * }) + {{#items}} + * @Type("array<{{datatype}}>") + {{/items}} +{{/isContainer}} +{{^isContainer}} + {{#isDate}} + * @Assert\Date() + * @Type("DateTime") + {{/isDate}} + {{#isDateTime}} + * @Assert\DateTime() + * @Type("DateTime") + {{/isDateTime}} + {{^isDate}} + {{^isDateTime}} + * @Assert\Type("{{datatype}}") + * @Type("{{datatype}}") + {{/isDateTime}} + {{/isDate}} +{{/isContainer}} +{{#hasValidation}} + {{#maxLength}} + * @Assert\Length( + * max = {{maxLength}} + * ) + {{/maxLength}} + {{#minLength}} + * @Assert\Length( + * min = {{minLength}} + * ) + {{/minLength}} + {{#minimum}} + {{#exclusiveMinimum}} + * @Assert\GreaterThan({{minimum}}) + {{/exclusiveMinimum}} + {{^exclusiveMinimum}} + * @Assert\GreaterThanOrEqual({{minimum}}) + {{/exclusiveMinimum}} + {{/minimum}} + {{#maximum}} + {{#exclusiveMaximum}} + * @Assert\LessThan({{minimum}}) + {{/exclusiveMaximum}} + {{^exclusiveMaximum}} + * @Assert\LessThanOrEqual({{minimum}}) + {{/exclusiveMaximum}} + {{/maximum}} + {{#pattern}} + * @Assert\Regex("/{{pattern}}/") + {{/pattern}} + {{#maxItems}} + * @Assert\Count( + * max = {{maxItems}} + * ) + {{/maxItems}} + {{#minItems}} + * @Assert\Count( + * min = {{minItems}} + * ) + {{/minItems}} +{{/hasValidation}} + */ + protected ${{name}}; diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/routing.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/routing.mustache index e91e9349c06e..e0294a956d17 100644 --- a/modules/swagger-codegen/src/main/resources/php-symfony/routing.mustache +++ b/modules/swagger-codegen/src/main/resources/php-symfony/routing.mustache @@ -11,7 +11,29 @@ path: {{path}} methods: [{{httpMethod}}] defaults: - _controller: {{bundleClassName}}:{{baseName}}:{{operationId}} + _controller: {{bundleAlias}}.controller.{{pathPrefix}}:{{operationId}}Action + {{#hasPathParams}} + requirements: + {{/hasPathParams}} + {{#pathParams}} + {{#pattern}} + {{paramName}}: '{{pattern}}' + {{/pattern}} + {{^pattern}} + {{#isLong}} + {{paramName}}: '\d+' + {{/isLong}} + {{#isInteger}} + {{paramName}}: '\d+' + {{/isInteger}} + {{#isString}} + {{paramName}}: '[a-z0-9]+' + {{/isString}} + {{#isBoolean}} + {{paramName}}: 'true|false' + {{/isBoolean}} + {{/pattern}} + {{/pathParams}} {{/operation}} {{/operations}} diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/serialization/JmsSerializer.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/serialization/JmsSerializer.mustache new file mode 100644 index 000000000000..995e71ba0235 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/php-symfony/serialization/JmsSerializer.mustache @@ -0,0 +1,91 @@ +serializer = SerializerBuilder::create() + ->setDeserializationVisitor('json', new StrictJsonDeserializationVisitor($naming_strategy)) + ->setDeserializationVisitor('xml', new XmlDeserializationVisitor($naming_strategy)) + ->build(); + } + + public function serialize($data, $format) + { + return SerializerBuilder::create()->build()->serialize($data, $this->convertFormat($format)); + } + + public function deserialize($data, $type, $format) + { + if ($format == 'string') { + return $this->deserializeString($data, $type); + } + + // If we end up here, let JMS serializer handle the deserialization + return $this->serializer->deserialize($data, $type, $this->convertFormat($format)); + } + + private function convertFormat($format) + { + switch ($format) { + case 'application/json': + return 'json'; + case 'application/xml': + return 'xml'; + } + + return null; + } + + private function deserializeString($data, $type) + { + switch ($type) { + case 'int': + case 'integer': + if (is_int($data)) { + return $data; + } + + if (is_numeric($data)) { + return $data + 0; + } + + break; + case 'string': + break; + case 'boolean': + case 'bool': + if (strtolower($data) === 'true') { + return true; + } + + if (strtolower($data) === 'false') { + return false; + } + + break; + case 'array': + return explode(',', $data); + case 'array': + return explode(' ', $data); + case 'array': + return explode("\t", $data); + case 'array': + return explode('|', $data); + } + + // If we end up here, just return data + return $data; + } +} diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/serialization/SerializerInterface.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/serialization/SerializerInterface.mustache new file mode 100644 index 000000000000..60ad87246487 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/php-symfony/serialization/SerializerInterface.mustache @@ -0,0 +1,27 @@ +getCurrentPath()) > 0) { + $property = sprintf('property "%s" to be ', implode('.', $context->getCurrentPath())); + } else { + $property = ''; + } + + return new static(sprintf( + 'Expected %s%s, but got %s: %s', + $property, + $expected_type, + gettype($actual_value), + json_encode($actual_value) + )); + } +} diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/services.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/services.mustache index 89e2bb8a96bc..f6aec0cc2e0a 100644 --- a/modules/swagger-codegen/src/main/resources/php-symfony/services.mustache +++ b/modules/swagger-codegen/src/main/resources/php-symfony/services.mustache @@ -2,9 +2,33 @@ # https://github.com/swagger-api/swagger-codegen # Do not edit the class manually. +parameters: + {{bundleAlias}}.serializer: '{{servicePackage}}\JmsSerializer' + {{bundleAlias}}.validator: '{{servicePackage}}\SymfonyValidator' + services: {{bundleAlias}}.api.api_server: class: {{apiPackage}}\ApiServer {{bundleAlias}}.model.model_serializer: class: {{modelPackage}}\ModelSerializer + + {{bundleAlias}}.service.serializer: + class: %{{bundleAlias}}.serializer% + + {{bundleAlias}}.service.validator: + class: %{{bundleAlias}}.validator% + +{{#apiInfo}} +{{#apis}} +{{#operations}} + {{bundleAlias}}.controller.{{pathPrefix}}: + class: {{controllerPackage}}\{{baseName}}Controller + calls: + - [setSerializer, ['@{{bundleAlias}}.service.serializer']] + - [setValidator, ['@{{bundleAlias}}.service.validator']] + - [setApiServer, ['@{{bundleAlias}}.api.api_server']] + +{{/operations}} +{{/apis}} +{{/apiInfo}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/testing/AppKernel.php b/modules/swagger-codegen/src/main/resources/php-symfony/testing/AppKernel.php new file mode 100644 index 000000000000..631690bc9786 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/php-symfony/testing/AppKernel.php @@ -0,0 +1,21 @@ +load(__DIR__.'/test_config.yml'); + } +} diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/testing/api_test.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/testing/api_test.mustache new file mode 100644 index 000000000000..d337c1e3df6a --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/php-symfony/testing/api_test.mustache @@ -0,0 +1,116 @@ +partial_header}} +/** + * NOTE: This class is auto generated by the swagger code generator program. + * https://github.com/swagger-api/swagger-codegen + * Please update the test case below to test the endpoint. + */ + +namespace {{apiTestsPackage}}; + +use {{invokerPackage}}\Configuration; +use {{invokerPackage}}\ApiClient; +use {{invokerPackage}}\ApiException; +use {{invokerPackage}}\ObjectSerializer; +use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; + +/** + * {{classname}}Test Class Doc Comment + * + * @category Class + * @package {{apiTestsPackage}} + * @author Swagger Codegen team + * @link https://github.com/swagger-api/swagger-codegen + */ +{{#operations}}class {{classname}}Test extends WebTestCase +{ + + /** + * Setup before running any test cases + */ + public static function setUpBeforeClass() + { + } + + /** + * Setup before running each test case + */ + public function setUp() + { + } + + /** + * Clean up after running each test case + */ + public function tearDown() + { + } + + /** + * Clean up after running all test cases + */ + public static function tearDownAfterClass() + { + } + {{#operation}} + + /** + * Test case for {{{operationId}}} + * + * {{{summary}}}. + * + */ + public function test{{operationIdCamelCase}}() + { + $client = static::createClient(); + + $path = '{{path}}'; + {{#pathParams}} + {{=<% %>=}} + $pattern = '{<%paramName%>}'; + <%={{ }}=%> + {{#pattern}} + $data = $this->genTestData('{{pattern}}'); + {{/pattern}} + {{^pattern}} + {{#isLong}} + $data = $this->genTestData('\d+'); + {{/isLong}} + {{#isInteger}} + $data = $this->genTestData('\d+'); + {{/isInteger}} + {{#isString}} + $data = $this->genTestData('[a-z0-9]+'); + {{/isString}} + {{#isBoolean}} + $data = $this->genTestData('true|false'); + {{/isBoolean}} + {{/pattern}} + $path = str_replace($pattern, $data, $path); + {{/pathParams}} + + $crawler = $client->request('{{httpMethod}}', $path); + } + {{/operation}} + + protected function genTestData($regexp) + { + $grammar = new \Hoa\File\Read('hoa://Library/Regex/Grammar.pp'); + $compiler = \Hoa\Compiler\Llk\Llk::load($grammar); + $ast = $compiler->parse($regexp); + $generator = new \Hoa\Regex\Visitor\Isotropic(new \Hoa\Math\Sampler\Random()); + + return $generator->visit($ast); + } +} +{{/operations}} diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/model_test.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/testing/model_test.mustache similarity index 95% rename from modules/swagger-codegen/src/main/resources/php-symfony/model_test.mustache rename to modules/swagger-codegen/src/main/resources/php-symfony/testing/model_test.mustache index 797f9a2af2a6..b4b9cf012a39 100644 --- a/modules/swagger-codegen/src/main/resources/php-symfony/model_test.mustache +++ b/modules/swagger-codegen/src/main/resources/php-symfony/testing/model_test.mustache @@ -19,7 +19,7 @@ * Please update the test case below to test the model. */ -namespace {{modelTestsPackage}}; +namespace {{modelPackage}}; /** * {{classname}}Test Class Doc Comment @@ -67,6 +67,7 @@ class {{classname}}Test extends \PHPUnit_Framework_TestCase */ public function test{{classname}}() { + $test{{classname}} = new {{classname}}(); } {{#vars}} diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/phpunit.xml.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/testing/phpunit.xml.mustache similarity index 90% rename from modules/swagger-codegen/src/main/resources/php-symfony/phpunit.xml.mustache rename to modules/swagger-codegen/src/main/resources/php-symfony/testing/phpunit.xml.mustache index 5de6fea575c0..bd5b2978ee04 100644 --- a/modules/swagger-codegen/src/main/resources/php-symfony/phpunit.xml.mustache +++ b/modules/swagger-codegen/src/main/resources/php-symfony/testing/phpunit.xml.mustache @@ -12,6 +12,10 @@ + + + + {{apiSrcPath}} diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/testing/pom.xml b/modules/swagger-codegen/src/main/resources/php-symfony/testing/pom.xml new file mode 100644 index 000000000000..614b3d33f98a --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/php-symfony/testing/pom.xml @@ -0,0 +1,57 @@ + + 4.0.0 + com.penneo + PhpSymfonyPetstoreServerTests + pom + 1.0-SNAPSHOT + PHP Symfony Swagger Petstore Server + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory} + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + bundle-install + pre-integration-test + + exec + + + composer + + install + + + + + bundle-test + integration-test + + exec + + + vendor/bin/phpunit + + + + + + + + diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/testing/test_config.yml b/modules/swagger-codegen/src/main/resources/php-symfony/testing/test_config.yml new file mode 100644 index 000000000000..10c88a274c97 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/php-symfony/testing/test_config.yml @@ -0,0 +1,8 @@ +imports: + - { resource: "../Resources/config/services.yml" } + +framework: + secret: "testsecret" + test: ~ + router: + resource: "%kernel.root_dir%/../Resources/config/routing.yml" diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/validation/SymfonyValidator.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/validation/SymfonyValidator.mustache new file mode 100644 index 000000000000..3b6c5dd0ef64 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/php-symfony/validation/SymfonyValidator.mustache @@ -0,0 +1,20 @@ +validator = Validation::createValidator(); + } + + public function validate($value, $constraints = null, $groups = null) + { + return $this->validator->validate($value, $constraints, $groups); + } +} diff --git a/modules/swagger-codegen/src/main/resources/php-symfony/validation/ValidatorInterface.mustache b/modules/swagger-codegen/src/main/resources/php-symfony/validation/ValidatorInterface.mustache new file mode 100644 index 000000000000..e2a0d9badc5d --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/php-symfony/validation/ValidatorInterface.mustache @@ -0,0 +1,25 @@ +level(Symfony\CS\FixerInterface::PSR2_LEVEL) + ->setUsingCache(true) + ->fixers( + [ + 'ordered_use', + 'phpdoc_order', + 'short_array_syntax', + 'strict', + 'strict_param' + ] + ) + ->finder( + Symfony\CS\Finder\DefaultFinder::create() + ->in(__DIR__) + ); diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/.travis.yml b/samples/server/petstore/php-symfony/SymfonyBundle-php/.travis.yml new file mode 100644 index 000000000000..d77f3825f6fe --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/.travis.yml @@ -0,0 +1,10 @@ +language: php +sudo: false +php: + - 5.4 + - 5.5 + - 5.6 + - 7.0 + - hhvm +before_install: "composer install" +script: "vendor/bin/phpunit" diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Api/ApiServer.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Api/ApiServer.php new file mode 100644 index 000000000000..d26918e624f0 --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Api/ApiServer.php @@ -0,0 +1,80 @@ +apis[$api])) { + throw new \InvalidArgumentException('API has already a handler: '.$api); + } + + $this->apis[$api] = $handler; + } + + /** + * Returns an API handler. + * + * @param string $api An API name of the handle + * @return mixed Returns a handler + * @throws \InvalidArgumentException When no such handler exists + */ + public function getApiHandler($api) + { + if (!isset($this->apis[$api])) { + throw new \InvalidArgumentException('No handler for '.$api.' implemented.'); + } + + return $this->apis[$api]; + } +} diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Api/PetApiInterface.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Api/PetApiInterface.php new file mode 100644 index 000000000000..587f6d813a31 --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Api/PetApiInterface.php @@ -0,0 +1,172 @@ +validator = $validator; + } + + public function setSerializer(SerializerInterface $serializer) + { + $this->serializer = $serializer; + } + + public function setApiServer($server) + { + $this->apiServer = $server; + } + + /** + * This will return a response with code 400. Usage example: + * return $this->createBadRequestResponse('Unable to access this page!'); + * + * @param string $message A message + * + * @return Response + */ + public function createBadRequestResponse($message = 'Bad Request.') + { + return new Response($message, 400); + } + + /** + * This will return an error response. Usage example: + * return $this->createErrorResponse(new UnauthorizedHttpException()); + * + * @param HttpException $exception An HTTP exception + * + * @return Response + */ + public function createErrorResponse(HttpException $exception) + { + $statusCode = $exception->getStatusCode(); + $headers = array_merge($exception->getHeaders(), ['Content-Type' => 'application/json']); + + $json = $this->exceptionToArray($exception); + $json['statusCode'] = $statusCode; + + return new Response(json_encode($json, 15, 512), $statusCode, $headers); + } + + /** + * Serializes data to a given type format. + * + * @param mixed $data The data to serialize. + * @param string $class The source data class. + * @param string $format The target serialization format. + * + * @return string A serialized data string. + */ + protected function serialize($data, $format) + { + return $this->serializer->serialize($data, $format); + } + + /** + * Deserializes data from a given type format. + * + * @param string $data The data to deserialize. + * @param string $class The target data class. + * @param string $format The source serialization format. + * + * @return mixed A deserialized data. + */ + protected function deserialize($data, $class, $format) + { + return $this->serializer->deserialize($data, $class, $format); + } + + protected function validate($data, $asserts = null) + { + $errors = $this->validator->validate($data, $asserts); + + if (count($errors) > 0) { + $errorsString = (string)$errors; + return $this->createBadRequestResponse($errorsString); + } + } + + /** + * Converts an exception to a serializable array. + * + * @param \Exception|null $exception + * + * @return array + */ + private function exceptionToArray(\Exception $exception = null) + { + if (null === $exception) { + return null; + } + + return [ + 'message' => $exception->getMessage(), + 'type' => get_class($exception), + 'previous' => $this->exceptionToArray($exception->getPrevious()), + ]; + } + + protected function getOutputFormat($accept, array $produced) + { + // Figure out what the client accepts + $accept = preg_split("/[\s,]+/", $accept); + + if (in_array('*/*', $accept) || in_array('application/*', $accept)) { + // Prefer JSON if the client has no preference + if (in_array('application/json', $produced)) { + return 'application/json'; + } + if (in_array('application/xml', $produced)) { + return 'application/xml'; + } + } + + if (in_array('application/json', $accept) && in_array('application/json', $produced)) { + return 'application/json'; + } + + if (in_array('application/xml', $accept) && in_array('application/xml', $produced)) { + return 'application/xml'; + } + + // If we reach this point, we don't have a common ground between server and client + return null; + } +} diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Controller/PetController.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Controller/PetController.php new file mode 100644 index 000000000000..9362b82b123c --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Controller/PetController.php @@ -0,0 +1,799 @@ +headers->has('Content-Type')?$request->headers->get('Content-Type'):$consumes[0]; + if (!in_array($inputFormat, $consumes)) { + // We can't consume the content that the client is sending us + return new Response('', 415); + } + + // Figure out what data format to return to the client + $produces = ['application/xml', 'application/json']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + // Authentication 'petstore_auth' required + // Oauth required + $securitypetstore_auth = $request->headers->get('authorization'); + + // Read out all input parameter values into variables + $body = $request->getContent(); + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + + $body = $this->deserialize($body, 'Swagger\Server\Model\Pet', $inputFormat); + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\Type("Swagger\Server\Model\Pet"); + $response = $this->validate($body, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + // Set authentication method 'petstore_auth' + $handler->setpetstore_auth($securitypetstore_auth); + + // Make the call to the business logic + $responseCode = 204; + $responseHeaders = []; + $result = $handler->addPet($body, $responseCode, $responseHeaders); + + // Find default response message + $message = ''; + + // Find a more specific message, if available + switch ($responseCode) { + case 405: + $message = 'Invalid input'; + break; + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); + } catch (Exception $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Operation deletePet + * + * Deletes a pet + * + * @param Request $request The Symfony request to handle. + * @return Response The Symfony response. + */ + public function deletePetAction(Request $request, $petId) + { + // Figure out what data format to return to the client + $produces = ['application/xml', 'application/json']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + // Authentication 'petstore_auth' required + // Oauth required + $securitypetstore_auth = $request->headers->get('authorization'); + + // Read out all input parameter values into variables + $apiKey = $request->headers->get('apiKey'); + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + $petId = $this->deserialize($petId, 'int', 'string'); + $apiKey = $request->headers->get('apiKey'); + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + $apiKey = $this->deserialize($apiKey, 'string', 'string'); + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\Type("int"); + $response = $this->validate($petId, $asserts); + if ($response instanceof Response) { + return $response; + } + $asserts = []; + $asserts[] = new Assert\Type("string"); + $response = $this->validate($apiKey, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + // Set authentication method 'petstore_auth' + $handler->setpetstore_auth($securitypetstore_auth); + + // Make the call to the business logic + $responseCode = 204; + $responseHeaders = []; + $result = $handler->deletePet($petId, $apiKey, $responseCode, $responseHeaders); + + // Find default response message + $message = ''; + + // Find a more specific message, if available + switch ($responseCode) { + case 400: + $message = 'Invalid pet value'; + break; + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); + } catch (Exception $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Operation findPetsByStatus + * + * Finds Pets by status + * + * @param Request $request The Symfony request to handle. + * @return Response The Symfony response. + */ + public function findPetsByStatusAction(Request $request) + { + // Figure out what data format to return to the client + $produces = ['application/xml', 'application/json']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + // Authentication 'petstore_auth' required + // Oauth required + $securitypetstore_auth = $request->headers->get('authorization'); + + // Read out all input parameter values into variables + $status = $request->query->get('status'); + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + $status = $this->deserialize($status, 'array', 'string'); + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\All([ + new Assert\Choice([ "available", "pending", "sold" ]) + ]); + $asserts[] = new Assert\All([ + new Assert\Type("string") + ]); + $response = $this->validate($status, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + // Set authentication method 'petstore_auth' + $handler->setpetstore_auth($securitypetstore_auth); + + // Make the call to the business logic + $responseCode = 200; + $responseHeaders = []; + $result = $handler->findPetsByStatus($status, $responseCode, $responseHeaders); + + // Find default response message + $message = 'successful operation'; + + // Find a more specific message, if available + switch ($responseCode) { + case 200: + $message = 'successful operation'; + break; + case 400: + $message = 'Invalid status value'; + break; + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); + } catch (Exception $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Operation findPetsByTags + * + * Finds Pets by tags + * + * @param Request $request The Symfony request to handle. + * @return Response The Symfony response. + */ + public function findPetsByTagsAction(Request $request) + { + // Figure out what data format to return to the client + $produces = ['application/xml', 'application/json']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + // Authentication 'petstore_auth' required + // Oauth required + $securitypetstore_auth = $request->headers->get('authorization'); + + // Read out all input parameter values into variables + $tags = $request->query->get('tags'); + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + $tags = $this->deserialize($tags, 'array', 'string'); + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\All([ + new Assert\Type("string") + ]); + $response = $this->validate($tags, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + // Set authentication method 'petstore_auth' + $handler->setpetstore_auth($securitypetstore_auth); + + // Make the call to the business logic + $responseCode = 200; + $responseHeaders = []; + $result = $handler->findPetsByTags($tags, $responseCode, $responseHeaders); + + // Find default response message + $message = 'successful operation'; + + // Find a more specific message, if available + switch ($responseCode) { + case 200: + $message = 'successful operation'; + break; + case 400: + $message = 'Invalid tag value'; + break; + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); + } catch (Exception $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Operation getPetById + * + * Find pet by ID + * + * @param Request $request The Symfony request to handle. + * @return Response The Symfony response. + */ + public function getPetByIdAction(Request $request, $petId) + { + // Figure out what data format to return to the client + $produces = ['application/xml', 'application/json']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + // Authentication 'api_key' required + // Set key with prefix in header + $securityapi_key = $request->headers->get('api_key'); + + // Read out all input parameter values into variables + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + $petId = $this->deserialize($petId, 'int', 'string'); + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\Type("int"); + $response = $this->validate($petId, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + // Set authentication method 'api_key' + $handler->setapi_key($securityapi_key); + + // Make the call to the business logic + $responseCode = 200; + $responseHeaders = []; + $result = $handler->getPetById($petId, $responseCode, $responseHeaders); + + // Find default response message + $message = 'successful operation'; + + // Find a more specific message, if available + switch ($responseCode) { + case 200: + $message = 'successful operation'; + break; + case 400: + $message = 'Invalid ID supplied'; + break; + case 404: + $message = 'Pet not found'; + break; + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); + } catch (Exception $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Operation updatePet + * + * Update an existing pet + * + * @param Request $request The Symfony request to handle. + * @return Response The Symfony response. + */ + public function updatePetAction(Request $request) + { + // Make sure that the client is providing something that we can consume + $consumes = ['application/json', 'application/xml']; + $inputFormat = $request->headers->has('Content-Type')?$request->headers->get('Content-Type'):$consumes[0]; + if (!in_array($inputFormat, $consumes)) { + // We can't consume the content that the client is sending us + return new Response('', 415); + } + + // Figure out what data format to return to the client + $produces = ['application/xml', 'application/json']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + // Authentication 'petstore_auth' required + // Oauth required + $securitypetstore_auth = $request->headers->get('authorization'); + + // Read out all input parameter values into variables + $body = $request->getContent(); + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + + $body = $this->deserialize($body, 'Swagger\Server\Model\Pet', $inputFormat); + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\Type("Swagger\Server\Model\Pet"); + $response = $this->validate($body, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + // Set authentication method 'petstore_auth' + $handler->setpetstore_auth($securitypetstore_auth); + + // Make the call to the business logic + $responseCode = 204; + $responseHeaders = []; + $result = $handler->updatePet($body, $responseCode, $responseHeaders); + + // Find default response message + $message = ''; + + // Find a more specific message, if available + switch ($responseCode) { + case 400: + $message = 'Invalid ID supplied'; + break; + case 404: + $message = 'Pet not found'; + break; + case 405: + $message = 'Validation exception'; + break; + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); + } catch (Exception $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Operation updatePetWithForm + * + * Updates a pet in the store with form data + * + * @param Request $request The Symfony request to handle. + * @return Response The Symfony response. + */ + public function updatePetWithFormAction(Request $request, $petId) + { + // Figure out what data format to return to the client + $produces = ['application/xml', 'application/json']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + // Authentication 'petstore_auth' required + // Oauth required + $securitypetstore_auth = $request->headers->get('authorization'); + + // Read out all input parameter values into variables + $name = $request->request->get('name'); + $status = $request->request->get('status'); + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + $petId = $this->deserialize($petId, 'int', 'string'); + $name = $request->request->get('name'); + $status = $request->request->get('status'); + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + $name = $this->deserialize($name, 'string', 'string'); + $name = $request->request->get('name'); + $status = $request->request->get('status'); + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + $status = $this->deserialize($status, 'string', 'string'); + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\Type("int"); + $response = $this->validate($petId, $asserts); + if ($response instanceof Response) { + return $response; + } + $asserts = []; + $asserts[] = new Assert\Type("string"); + $response = $this->validate($name, $asserts); + if ($response instanceof Response) { + return $response; + } + $asserts = []; + $asserts[] = new Assert\Type("string"); + $response = $this->validate($status, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + // Set authentication method 'petstore_auth' + $handler->setpetstore_auth($securitypetstore_auth); + + // Make the call to the business logic + $responseCode = 204; + $responseHeaders = []; + $result = $handler->updatePetWithForm($petId, $name, $status, $responseCode, $responseHeaders); + + // Find default response message + $message = ''; + + // Find a more specific message, if available + switch ($responseCode) { + case 405: + $message = 'Invalid input'; + break; + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); + } catch (Exception $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Operation uploadFile + * + * uploads an image + * + * @param Request $request The Symfony request to handle. + * @return Response The Symfony response. + */ + public function uploadFileAction(Request $request, $petId) + { + // Figure out what data format to return to the client + $produces = ['application/json']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + // Authentication 'petstore_auth' required + // Oauth required + $securitypetstore_auth = $request->headers->get('authorization'); + + // Read out all input parameter values into variables + $additionalMetadata = $request->request->get('additionalMetadata'); + $file = $request->files->get('file'); + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + $petId = $this->deserialize($petId, 'int', 'string'); + $additionalMetadata = $request->request->get('additionalMetadata'); + $file = $request->files->get('file'); + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + $additionalMetadata = $this->deserialize($additionalMetadata, 'string', 'string'); + $additionalMetadata = $request->request->get('additionalMetadata'); + $file = $request->files->get('file'); + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\Type("int"); + $response = $this->validate($petId, $asserts); + if ($response instanceof Response) { + return $response; + } + $asserts = []; + $asserts[] = new Assert\Type("string"); + $response = $this->validate($additionalMetadata, $asserts); + if ($response instanceof Response) { + return $response; + } + $asserts = []; + $asserts[] = new Assert\File(); + $response = $this->validate($file, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + // Set authentication method 'petstore_auth' + $handler->setpetstore_auth($securitypetstore_auth); + + // Make the call to the business logic + $responseCode = 200; + $responseHeaders = []; + $result = $handler->uploadFile($petId, $additionalMetadata, $file, $responseCode, $responseHeaders); + + // Find default response message + $message = 'successful operation'; + + // Find a more specific message, if available + switch ($responseCode) { + case 200: + $message = 'successful operation'; + break; + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); + } catch (Exception $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Returns the handler for this API controller. + * @return PetApiInterface + */ + public function getApiHandler() + { + return $this->apiServer->getApiHandler('pet'); + } +} diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Controller/StoreController.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Controller/StoreController.php new file mode 100644 index 000000000000..304a847c6eb8 --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Controller/StoreController.php @@ -0,0 +1,368 @@ +headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + + // Read out all input parameter values into variables + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + $orderId = $this->deserialize($orderId, 'string', 'string'); + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\Type("string"); + $response = $this->validate($orderId, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + + // Make the call to the business logic + $responseCode = 204; + $responseHeaders = []; + $result = $handler->deleteOrder($orderId, $responseCode, $responseHeaders); + + // Find default response message + $message = ''; + + // Find a more specific message, if available + switch ($responseCode) { + case 400: + $message = 'Invalid ID supplied'; + break; + case 404: + $message = 'Order not found'; + break; + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); + } catch (Exception $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Operation getInventory + * + * Returns pet inventories by status + * + * @param Request $request The Symfony request to handle. + * @return Response The Symfony response. + */ + public function getInventoryAction(Request $request) + { + // Figure out what data format to return to the client + $produces = ['application/json']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + // Authentication 'api_key' required + // Set key with prefix in header + $securityapi_key = $request->headers->get('api_key'); + + // Read out all input parameter values into variables + + // Validate the input values + + + try { + $handler = $this->getApiHandler(); + + // Set authentication method 'api_key' + $handler->setapi_key($securityapi_key); + + // Make the call to the business logic + $responseCode = 200; + $responseHeaders = []; + $result = $handler->getInventory($responseCode, $responseHeaders); + + // Find default response message + $message = 'successful operation'; + + // Find a more specific message, if available + switch ($responseCode) { + case 200: + $message = 'successful operation'; + break; + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); + } catch (Exception $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Operation getOrderById + * + * Find purchase order by ID + * + * @param Request $request The Symfony request to handle. + * @return Response The Symfony response. + */ + public function getOrderByIdAction(Request $request, $orderId) + { + // Figure out what data format to return to the client + $produces = ['application/xml', 'application/json']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + + // Read out all input parameter values into variables + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + $orderId = $this->deserialize($orderId, 'int', 'string'); + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\Type("int"); + $asserts[] = new Assert\GreaterThanOrEqual(1); + $asserts[] = new Assert\LessThanOrEqual(1); + $response = $this->validate($orderId, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + + // Make the call to the business logic + $responseCode = 200; + $responseHeaders = []; + $result = $handler->getOrderById($orderId, $responseCode, $responseHeaders); + + // Find default response message + $message = 'successful operation'; + + // Find a more specific message, if available + switch ($responseCode) { + case 200: + $message = 'successful operation'; + break; + case 400: + $message = 'Invalid ID supplied'; + break; + case 404: + $message = 'Order not found'; + break; + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); + } catch (Exception $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Operation placeOrder + * + * Place an order for a pet + * + * @param Request $request The Symfony request to handle. + * @return Response The Symfony response. + */ + public function placeOrderAction(Request $request) + { + // Make sure that the client is providing something that we can consume + $consumes = []; + $inputFormat = $request->headers->has('Content-Type')?$request->headers->get('Content-Type'):$consumes[0]; + if (!in_array($inputFormat, $consumes)) { + // We can't consume the content that the client is sending us + return new Response('', 415); + } + + // Figure out what data format to return to the client + $produces = ['application/xml', 'application/json']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + + // Read out all input parameter values into variables + $body = $request->getContent(); + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + + $body = $this->deserialize($body, 'Swagger\Server\Model\Order', $inputFormat); + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\Type("Swagger\Server\Model\Order"); + $response = $this->validate($body, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + + // Make the call to the business logic + $responseCode = 200; + $responseHeaders = []; + $result = $handler->placeOrder($body, $responseCode, $responseHeaders); + + // Find default response message + $message = 'successful operation'; + + // Find a more specific message, if available + switch ($responseCode) { + case 200: + $message = 'successful operation'; + break; + case 400: + $message = 'Invalid Order'; + break; + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); + } catch (Exception $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Returns the handler for this API controller. + * @return StoreApiInterface + */ + public function getApiHandler() + { + return $this->apiServer->getApiHandler('store'); + } +} diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Controller/UserController.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Controller/UserController.php new file mode 100644 index 000000000000..7f182bb1e61c --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Controller/UserController.php @@ -0,0 +1,720 @@ +headers->has('Content-Type')?$request->headers->get('Content-Type'):$consumes[0]; + if (!in_array($inputFormat, $consumes)) { + // We can't consume the content that the client is sending us + return new Response('', 415); + } + + // Figure out what data format to return to the client + $produces = ['application/xml', 'application/json']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + + // Read out all input parameter values into variables + $body = $request->getContent(); + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + + $body = $this->deserialize($body, 'Swagger\Server\Model\User', $inputFormat); + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\Type("Swagger\Server\Model\User"); + $response = $this->validate($body, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + + // Make the call to the business logic + $responseCode = 204; + $responseHeaders = []; + $result = $handler->createUser($body, $responseCode, $responseHeaders); + + // Find default response message + $message = 'successful operation'; + + // Find a more specific message, if available + switch ($responseCode) { + case 0: + $message = 'successful operation'; + break; + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); + } catch (Exception $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Operation createUsersWithArrayInput + * + * Creates list of users with given input array + * + * @param Request $request The Symfony request to handle. + * @return Response The Symfony response. + */ + public function createUsersWithArrayInputAction(Request $request) + { + // Make sure that the client is providing something that we can consume + $consumes = []; + $inputFormat = $request->headers->has('Content-Type')?$request->headers->get('Content-Type'):$consumes[0]; + if (!in_array($inputFormat, $consumes)) { + // We can't consume the content that the client is sending us + return new Response('', 415); + } + + // Figure out what data format to return to the client + $produces = ['application/xml', 'application/json']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + + // Read out all input parameter values into variables + $body = $request->getContent(); + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + + $body = $this->deserialize($body, 'Swagger\Server\Model\User[]', $inputFormat); + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\All([ + new Assert\Type("Swagger\Server\Model\User[]") + ]); + $response = $this->validate($body, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + + // Make the call to the business logic + $responseCode = 204; + $responseHeaders = []; + $result = $handler->createUsersWithArrayInput($body, $responseCode, $responseHeaders); + + // Find default response message + $message = 'successful operation'; + + // Find a more specific message, if available + switch ($responseCode) { + case 0: + $message = 'successful operation'; + break; + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); + } catch (Exception $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Operation createUsersWithListInput + * + * Creates list of users with given input array + * + * @param Request $request The Symfony request to handle. + * @return Response The Symfony response. + */ + public function createUsersWithListInputAction(Request $request) + { + // Make sure that the client is providing something that we can consume + $consumes = []; + $inputFormat = $request->headers->has('Content-Type')?$request->headers->get('Content-Type'):$consumes[0]; + if (!in_array($inputFormat, $consumes)) { + // We can't consume the content that the client is sending us + return new Response('', 415); + } + + // Figure out what data format to return to the client + $produces = ['application/xml', 'application/json']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + + // Read out all input parameter values into variables + $body = $request->getContent(); + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + + $body = $this->deserialize($body, 'Swagger\Server\Model\User[]', $inputFormat); + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\All([ + new Assert\Type("Swagger\Server\Model\User[]") + ]); + $response = $this->validate($body, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + + // Make the call to the business logic + $responseCode = 204; + $responseHeaders = []; + $result = $handler->createUsersWithListInput($body, $responseCode, $responseHeaders); + + // Find default response message + $message = 'successful operation'; + + // Find a more specific message, if available + switch ($responseCode) { + case 0: + $message = 'successful operation'; + break; + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); + } catch (Exception $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Operation deleteUser + * + * Delete user + * + * @param Request $request The Symfony request to handle. + * @return Response The Symfony response. + */ + public function deleteUserAction(Request $request, $username) + { + // Figure out what data format to return to the client + $produces = ['application/xml', 'application/json']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + + // Read out all input parameter values into variables + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + $username = $this->deserialize($username, 'string', 'string'); + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\Type("string"); + $response = $this->validate($username, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + + // Make the call to the business logic + $responseCode = 204; + $responseHeaders = []; + $result = $handler->deleteUser($username, $responseCode, $responseHeaders); + + // Find default response message + $message = ''; + + // Find a more specific message, if available + switch ($responseCode) { + case 400: + $message = 'Invalid username supplied'; + break; + case 404: + $message = 'User not found'; + break; + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); + } catch (Exception $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Operation getUserByName + * + * Get user by user name + * + * @param Request $request The Symfony request to handle. + * @return Response The Symfony response. + */ + public function getUserByNameAction(Request $request, $username) + { + // Figure out what data format to return to the client + $produces = ['application/xml', 'application/json']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + + // Read out all input parameter values into variables + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + $username = $this->deserialize($username, 'string', 'string'); + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\Type("string"); + $response = $this->validate($username, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + + // Make the call to the business logic + $responseCode = 200; + $responseHeaders = []; + $result = $handler->getUserByName($username, $responseCode, $responseHeaders); + + // Find default response message + $message = 'successful operation'; + + // Find a more specific message, if available + switch ($responseCode) { + case 200: + $message = 'successful operation'; + break; + case 400: + $message = 'Invalid username supplied'; + break; + case 404: + $message = 'User not found'; + break; + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); + } catch (Exception $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Operation loginUser + * + * Logs user into the system + * + * @param Request $request The Symfony request to handle. + * @return Response The Symfony response. + */ + public function loginUserAction(Request $request) + { + // Figure out what data format to return to the client + $produces = ['application/xml', 'application/json']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + + // Read out all input parameter values into variables + $username = $request->query->get('username'); + $password = $request->query->get('password'); + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + $username = $this->deserialize($username, 'string', 'string'); + $username = $request->query->get('username'); + $password = $request->query->get('password'); + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + $password = $this->deserialize($password, 'string', 'string'); + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\Type("string"); + $response = $this->validate($username, $asserts); + if ($response instanceof Response) { + return $response; + } + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\Type("string"); + $response = $this->validate($password, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + + // Make the call to the business logic + $responseCode = 200; + $responseHeaders = []; + $result = $handler->loginUser($username, $password, $responseCode, $responseHeaders); + + // Find default response message + $message = 'successful operation'; + + // Find a more specific message, if available + switch ($responseCode) { + case 200: + $message = 'successful operation'; + break; + case 400: + $message = 'Invalid username/password supplied'; + break; + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); + } catch (Exception $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Operation logoutUser + * + * Logs out current logged in user session + * + * @param Request $request The Symfony request to handle. + * @return Response The Symfony response. + */ + public function logoutUserAction(Request $request) + { + // Figure out what data format to return to the client + $produces = ['application/xml', 'application/json']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + + // Read out all input parameter values into variables + + // Validate the input values + + + try { + $handler = $this->getApiHandler(); + + + // Make the call to the business logic + $responseCode = 204; + $responseHeaders = []; + $result = $handler->logoutUser($responseCode, $responseHeaders); + + // Find default response message + $message = 'successful operation'; + + // Find a more specific message, if available + switch ($responseCode) { + case 0: + $message = 'successful operation'; + break; + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); + } catch (Exception $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Operation updateUser + * + * Updated user + * + * @param Request $request The Symfony request to handle. + * @return Response The Symfony response. + */ + public function updateUserAction(Request $request, $username) + { + // Make sure that the client is providing something that we can consume + $consumes = []; + $inputFormat = $request->headers->has('Content-Type')?$request->headers->get('Content-Type'):$consumes[0]; + if (!in_array($inputFormat, $consumes)) { + // We can't consume the content that the client is sending us + return new Response('', 415); + } + + // Figure out what data format to return to the client + $produces = ['application/xml', 'application/json']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + + // Read out all input parameter values into variables + $body = $request->getContent(); + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + + $body = $this->deserialize($body, 'Swagger\Server\Model\User', $inputFormat); + $body = $request->getContent(); + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + + $body = $this->deserialize($body, 'Swagger\Server\Model\User', $inputFormat); + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\Type("string"); + $response = $this->validate($username, $asserts); + if ($response instanceof Response) { + return $response; + } + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\Type("Swagger\Server\Model\User"); + $response = $this->validate($body, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + + // Make the call to the business logic + $responseCode = 204; + $responseHeaders = []; + $result = $handler->updateUser($username, $body, $responseCode, $responseHeaders); + + // Find default response message + $message = ''; + + // Find a more specific message, if available + switch ($responseCode) { + case 400: + $message = 'Invalid user supplied'; + break; + case 404: + $message = 'User not found'; + break; + } + + return new Response( + $result?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-Swagger-Message' => $message + ] + ) + ); + } catch (Exception $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Returns the handler for this API controller. + * @return UserApiInterface + */ + public function getApiHandler() + { + return $this->apiServer->getApiHandler('user'); + } +} diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/DependencyInjection/Compiler/SwaggerServerApiPass.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/DependencyInjection/Compiler/SwaggerServerApiPass.php new file mode 100644 index 000000000000..7ac5898d1432 --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/DependencyInjection/Compiler/SwaggerServerApiPass.php @@ -0,0 +1,70 @@ +has('swagger_server.api.api_server')) { + return; + } + + $definition = $container->findDefinition('swagger_server.api.api_server'); + + // find all service IDs with the swagger_server.api tag + $taggedServices = $container->findTaggedServiceIds('swagger_server.api'); + + foreach ($taggedServices as $id => $tags) { + foreach ($tags as $tag) { + // add the transport service to the ChainTransport service + $definition->addMethodCall('addApiHandler', [$tag['api'], new Reference($id)]); + } + } + } +} diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/DependencyInjection/SwaggerServerExtension.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/DependencyInjection/SwaggerServerExtension.php new file mode 100644 index 000000000000..2f12f034cce2 --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/DependencyInjection/SwaggerServerExtension.php @@ -0,0 +1,57 @@ +load('services.yml'); + } + + public function getAlias() + { + return 'swagger_server'; + } +} diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Model/ApiResponse.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Model/ApiResponse.php new file mode 100644 index 000000000000..5a00e41be2d5 --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Model/ApiResponse.php @@ -0,0 +1,154 @@ +code = isset($data['code']) ? $data['code'] : null; + $this->type = isset($data['type']) ? $data['type'] : null; + $this->message = isset($data['message']) ? $data['message'] : null; + } + + /** + * Gets code. + * + * @return int|null + */ + public function getCode() + { + return $this->code; + } + + /** + * Sets code. + * + * @param int|null $code + * + * @return $this + */ + public function setCode($code = null) + { + $this->code = $code; + + return $this; + } + + /** + * Gets type. + * + * @return string|null + */ + public function getType() + { + return $this->type; + } + + /** + * Sets type. + * + * @param string|null $type + * + * @return $this + */ + public function setType($type = null) + { + $this->type = $type; + + return $this; + } + + /** + * Gets message. + * + * @return string|null + */ + public function getMessage() + { + return $this->message; + } + + /** + * Sets message. + * + * @param string|null $message + * + * @return $this + */ + public function setMessage($message = null) + { + $this->message = $message; + + return $this; + } +} + + diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Model/Category.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Model/Category.php new file mode 100644 index 000000000000..e59ecdbe7c4d --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Model/Category.php @@ -0,0 +1,121 @@ +id = isset($data['id']) ? $data['id'] : null; + $this->name = isset($data['name']) ? $data['name'] : null; + } + + /** + * Gets id. + * + * @return int|null + */ + public function getId() + { + return $this->id; + } + + /** + * Sets id. + * + * @param int|null $id + * + * @return $this + */ + public function setId($id = null) + { + $this->id = $id; + + return $this; + } + + /** + * Gets name. + * + * @return string|null + */ + public function getName() + { + return $this->name; + } + + /** + * Sets name. + * + * @param string|null $name + * + * @return $this + */ + public function setName($name = null) + { + $this->name = $name; + + return $this; + } +} + + diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Model/Order.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Model/Order.php new file mode 100644 index 000000000000..65a7ead3cf28 --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Model/Order.php @@ -0,0 +1,256 @@ +id = isset($data['id']) ? $data['id'] : null; + $this->petId = isset($data['petId']) ? $data['petId'] : null; + $this->quantity = isset($data['quantity']) ? $data['quantity'] : null; + $this->shipDate = isset($data['shipDate']) ? $data['shipDate'] : null; + $this->status = isset($data['status']) ? $data['status'] : null; + $this->complete = isset($data['complete']) ? $data['complete'] : false; + } + + /** + * Gets id. + * + * @return int|null + */ + public function getId() + { + return $this->id; + } + + /** + * Sets id. + * + * @param int|null $id + * + * @return $this + */ + public function setId($id = null) + { + $this->id = $id; + + return $this; + } + + /** + * Gets petId. + * + * @return int|null + */ + public function getPetId() + { + return $this->petId; + } + + /** + * Sets petId. + * + * @param int|null $petId + * + * @return $this + */ + public function setPetId($petId = null) + { + $this->petId = $petId; + + return $this; + } + + /** + * Gets quantity. + * + * @return int|null + */ + public function getQuantity() + { + return $this->quantity; + } + + /** + * Sets quantity. + * + * @param int|null $quantity + * + * @return $this + */ + public function setQuantity($quantity = null) + { + $this->quantity = $quantity; + + return $this; + } + + /** + * Gets shipDate. + * + * @return \DateTime|null + */ + public function getShipDate() + { + return $this->shipDate; + } + + /** + * Sets shipDate. + * + * @param \DateTime|null $shipDate + * + * @return $this + */ + public function setShipDate(\DateTime $shipDate = null) + { + $this->shipDate = $shipDate; + + return $this; + } + + /** + * Gets status. + * + * @return string|null + */ + public function getStatus() + { + return $this->status; + } + + /** + * Sets status. + * + * @param string|null $status Order Status + * + * @return $this + */ + public function setStatus($status = null) + { + $this->status = $status; + + return $this; + } + + /** + * Gets complete. + * + * @return bool|null + */ + public function isComplete() + { + return $this->complete; + } + + /** + * Sets complete. + * + * @param bool|null $complete + * + * @return $this + */ + public function setComplete($complete = null) + { + $this->complete = $complete; + + return $this; + } +} + + diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Model/Pet.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Model/Pet.php new file mode 100644 index 000000000000..ac3fba47a7d1 --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Model/Pet.php @@ -0,0 +1,262 @@ +") + */ + protected $photoUrls; + + /** + * @var Swagger\Server\Model\Tag[]|null + * @SerializedName("tags") + * @Assert\All({ + * @Assert\Type("Swagger\Server\Model\Tag") + * }) + * @Type("array") + */ + protected $tags; + + /** + * pet status in the store + * + * @var string|null + * @SerializedName("status") + * @Assert\Choice({ "available", "pending", "sold" }) + * @Assert\Type("string") + * @Type("string") + */ + protected $status; + + /** + * Constructor + * @param mixed[] $data Associated array of property values initializing the model + */ + public function __construct(array $data = null) + { + $this->id = isset($data['id']) ? $data['id'] : null; + $this->category = isset($data['category']) ? $data['category'] : null; + $this->name = isset($data['name']) ? $data['name'] : null; + $this->photoUrls = isset($data['photoUrls']) ? $data['photoUrls'] : null; + $this->tags = isset($data['tags']) ? $data['tags'] : null; + $this->status = isset($data['status']) ? $data['status'] : null; + } + + /** + * Gets id. + * + * @return int|null + */ + public function getId() + { + return $this->id; + } + + /** + * Sets id. + * + * @param int|null $id + * + * @return $this + */ + public function setId($id = null) + { + $this->id = $id; + + return $this; + } + + /** + * Gets category. + * + * @return Swagger\Server\Model\Category|null + */ + public function getCategory() + { + return $this->category; + } + + /** + * Sets category. + * + * @param Swagger\Server\Model\Category|null $category + * + * @return $this + */ + public function setCategory(Category $category = null) + { + $this->category = $category; + + return $this; + } + + /** + * Gets name. + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Sets name. + * + * @param string $name + * + * @return $this + */ + public function setName($name) + { + $this->name = $name; + + return $this; + } + + /** + * Gets photoUrls. + * + * @return string[] + */ + public function getPhotoUrls() + { + return $this->photoUrls; + } + + /** + * Sets photoUrls. + * + * @param string[] $photoUrls + * + * @return $this + */ + public function setPhotoUrls(array $photoUrls) + { + $this->photoUrls = $photoUrls; + + return $this; + } + + /** + * Gets tags. + * + * @return Swagger\Server\Model\Tag[]|null + */ + public function getTags() + { + return $this->tags; + } + + /** + * Sets tags. + * + * @param Swagger\Server\Model\Tag[]|null $tags + * + * @return $this + */ + public function setTags(array $tags = null) + { + $this->tags = $tags; + + return $this; + } + + /** + * Gets status. + * + * @return string|null + */ + public function getStatus() + { + return $this->status; + } + + /** + * Sets status. + * + * @param string|null $status pet status in the store + * + * @return $this + */ + public function setStatus($status = null) + { + $this->status = $status; + + return $this; + } +} + + diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Model/Tag.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Model/Tag.php new file mode 100644 index 000000000000..ffe2ef4fb4f4 --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Model/Tag.php @@ -0,0 +1,121 @@ +id = isset($data['id']) ? $data['id'] : null; + $this->name = isset($data['name']) ? $data['name'] : null; + } + + /** + * Gets id. + * + * @return int|null + */ + public function getId() + { + return $this->id; + } + + /** + * Sets id. + * + * @param int|null $id + * + * @return $this + */ + public function setId($id = null) + { + $this->id = $id; + + return $this; + } + + /** + * Gets name. + * + * @return string|null + */ + public function getName() + { + return $this->name; + } + + /** + * Sets name. + * + * @param string|null $name + * + * @return $this + */ + public function setName($name = null) + { + $this->name = $name; + + return $this; + } +} + + diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Model/User.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Model/User.php new file mode 100644 index 000000000000..5f69763a5253 --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Model/User.php @@ -0,0 +1,321 @@ +id = isset($data['id']) ? $data['id'] : null; + $this->username = isset($data['username']) ? $data['username'] : null; + $this->firstName = isset($data['firstName']) ? $data['firstName'] : null; + $this->lastName = isset($data['lastName']) ? $data['lastName'] : null; + $this->email = isset($data['email']) ? $data['email'] : null; + $this->password = isset($data['password']) ? $data['password'] : null; + $this->phone = isset($data['phone']) ? $data['phone'] : null; + $this->userStatus = isset($data['userStatus']) ? $data['userStatus'] : null; + } + + /** + * Gets id. + * + * @return int|null + */ + public function getId() + { + return $this->id; + } + + /** + * Sets id. + * + * @param int|null $id + * + * @return $this + */ + public function setId($id = null) + { + $this->id = $id; + + return $this; + } + + /** + * Gets username. + * + * @return string|null + */ + public function getUsername() + { + return $this->username; + } + + /** + * Sets username. + * + * @param string|null $username + * + * @return $this + */ + public function setUsername($username = null) + { + $this->username = $username; + + return $this; + } + + /** + * Gets firstName. + * + * @return string|null + */ + public function getFirstName() + { + return $this->firstName; + } + + /** + * Sets firstName. + * + * @param string|null $firstName + * + * @return $this + */ + public function setFirstName($firstName = null) + { + $this->firstName = $firstName; + + return $this; + } + + /** + * Gets lastName. + * + * @return string|null + */ + public function getLastName() + { + return $this->lastName; + } + + /** + * Sets lastName. + * + * @param string|null $lastName + * + * @return $this + */ + public function setLastName($lastName = null) + { + $this->lastName = $lastName; + + return $this; + } + + /** + * Gets email. + * + * @return string|null + */ + public function getEmail() + { + return $this->email; + } + + /** + * Sets email. + * + * @param string|null $email + * + * @return $this + */ + public function setEmail($email = null) + { + $this->email = $email; + + return $this; + } + + /** + * Gets password. + * + * @return string|null + */ + public function getPassword() + { + return $this->password; + } + + /** + * Sets password. + * + * @param string|null $password + * + * @return $this + */ + public function setPassword($password = null) + { + $this->password = $password; + + return $this; + } + + /** + * Gets phone. + * + * @return string|null + */ + public function getPhone() + { + return $this->phone; + } + + /** + * Sets phone. + * + * @param string|null $phone + * + * @return $this + */ + public function setPhone($phone = null) + { + $this->phone = $phone; + + return $this; + } + + /** + * Gets userStatus. + * + * @return int|null + */ + public function getUserStatus() + { + return $this->userStatus; + } + + /** + * Sets userStatus. + * + * @param int|null $userStatus User Status + * + * @return $this + */ + public function setUserStatus($userStatus = null) + { + $this->userStatus = $userStatus; + + return $this; + } +} + + diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/README.md b/samples/server/petstore/php-symfony/SymfonyBundle-php/README.md new file mode 100644 index 000000000000..d4375c06941f --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/README.md @@ -0,0 +1,182 @@ +# SwaggerServer +This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + +This [Symfony](https://symfony.com/) bundle is automatically generated by the [Swagger Codegen](https://github.com/swagger-api/swagger-codegen) project: + +- API version: 1.0.0 +- Build package: io.swagger.codegen.languages.SymfonyServerCodegen + +## Requirements + +PHP 5.4.0 and later + +## Installation & Usage + +To install the dependencies via [Composer](http://getcomposer.org/), add the following repository to `composer.json` of your Symfony project: + +```json +{ + "repositories": [{ + "type": "path", + "url": "//Path to your generated swagger bundle" + }], +} +``` + +Then run: + +``` +composer require swagger/server-bundle:dev-master +``` + +to add the generated swagger bundle as a dependency. + +## Tests + +To run the unit tests for the generated bundle, first navigate to the directory containing the code, then run the following commands: + +``` +composer install +./vendor/bin/phpunit +``` + + +## Getting Started + +Step 1: Please follow the [installation procedure](#installation--usage) first. + +Step 2: Enable the bundle in the kernel: + +```php + addPet($body) + +Add a new pet to the store + + + +### Example Implementation +```php + deletePet($petId, $apiKey) + +Deletes a pet + + + +### Example Implementation +```php + Swagger\Server\Model\Pet[] findPetsByStatus($status) + +Finds Pets by status + +Multiple status values can be provided with comma separated strings + +### Example Implementation +```php + Swagger\Server\Model\Pet[] findPetsByTags($tags) + +Finds Pets by tags + +Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. + +### Example Implementation +```php + Swagger\Server\Model\Pet getPetById($petId) + +Find pet by ID + +Returns a single pet + +### Example Implementation +```php + updatePet($body) + +Update an existing pet + + + +### Example Implementation +```php + updatePetWithForm($petId, $name, $status) + +Updates a pet in the store with form data + + + +### Example Implementation +```php + Swagger\Server\Model\ApiResponse uploadFile($petId, $additionalMetadata, $file) + +uploads an image + + + +### Example Implementation +```php + deleteOrder($orderId) + +Delete purchase order by ID + +For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + +### Example Implementation +```php + int[] getInventory() + +Returns pet inventories by status + +Returns a map of status codes to quantities + +### Example Implementation +```php + Swagger\Server\Model\Order getOrderById($orderId) + +Find purchase order by ID + +For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions + +### Example Implementation +```php + Swagger\Server\Model\Order placeOrder($body) + +Place an order for a pet + + + +### Example Implementation +```php + createUser($body) + +Create user + +This can only be done by the logged in user. + +### Example Implementation +```php + createUsersWithArrayInput($body) + +Creates list of users with given input array + + + +### Example Implementation +```php + createUsersWithListInput($body) + +Creates list of users with given input array + + + +### Example Implementation +```php + deleteUser($username) + +Delete user + +This can only be done by the logged in user. + +### Example Implementation +```php + Swagger\Server\Model\User getUserByName($username) + +Get user by user name + + + +### Example Implementation +```php + string loginUser($username, $password) + +Logs user into the system + + + +### Example Implementation +```php + logoutUser() + +Logs out current logged in user session + + + +### Example Implementation +```php + updateUser($username, $body) + +Updated user + +This can only be done by the logged in user. + +### Example Implementation +```php +serializer = SerializerBuilder::create() + ->setDeserializationVisitor('json', new StrictJsonDeserializationVisitor($naming_strategy)) + ->setDeserializationVisitor('xml', new XmlDeserializationVisitor($naming_strategy)) + ->build(); + } + + public function serialize($data, $format) + { + return SerializerBuilder::create()->build()->serialize($data, $this->convertFormat($format)); + } + + public function deserialize($data, $type, $format) + { + if ($format == 'string') { + return $this->deserializeString($data, $type); + } + + // If we end up here, let JMS serializer handle the deserialization + return $this->serializer->deserialize($data, $type, $this->convertFormat($format)); + } + + private function convertFormat($format) + { + switch ($format) { + case 'application/json': + return 'json'; + case 'application/xml': + return 'xml'; + } + + return null; + } + + private function deserializeString($data, $type) + { + switch ($type) { + case 'int': + case 'integer': + if (is_int($data)) { + return $data; + } + + if (is_numeric($data)) { + return $data + 0; + } + + break; + case 'string': + break; + case 'boolean': + case 'bool': + if (strtolower($data) === 'true') { + return true; + } + + if (strtolower($data) === 'false') { + return false; + } + + break; + case 'array': + return explode(',', $data); + case 'array': + return explode(' ', $data); + case 'array': + return explode("\t", $data); + case 'array': + return explode('|', $data); + } + + // If we end up here, just return data + return $data; + } +} diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Service/SerializerInterface.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Service/SerializerInterface.php new file mode 100644 index 000000000000..bf8bc1896f66 --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Service/SerializerInterface.php @@ -0,0 +1,27 @@ +validator = Validation::createValidator(); + } + + public function validate($value, $constraints = null, $groups = null) + { + return $this->validator->validate($value, $constraints, $groups); + } +} diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Service/TypeMismatchException.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Service/TypeMismatchException.php new file mode 100644 index 000000000000..97a8f2e31975 --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Service/TypeMismatchException.php @@ -0,0 +1,52 @@ +getCurrentPath()) > 0) { + $property = sprintf('property "%s" to be ', implode('.', $context->getCurrentPath())); + } else { + $property = ''; + } + + return new static(sprintf( + 'Expected %s%s, but got %s: %s', + $property, + $expected_type, + gettype($actual_value), + json_encode($actual_value) + )); + } +} diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Service/ValidatorInterface.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Service/ValidatorInterface.php new file mode 100644 index 000000000000..a85241e81f65 --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Service/ValidatorInterface.php @@ -0,0 +1,25 @@ +addCompilerPass(new SwaggerServerApiPass()); + } +} diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/Api/PetApiInterfaceTest.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/Api/PetApiInterfaceTest.php new file mode 100644 index 000000000000..ca0c3b8ec263 --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/Api/PetApiInterfaceTest.php @@ -0,0 +1,217 @@ +request('POST', $path); + } + + /** + * Test case for deletePet + * + * Deletes a pet. + * + */ + public function testDeletePet() + { + $client = static::createClient(); + + $path = '/pet/{petId}'; + $pattern = '{petId}'; + $data = $this->genTestData('\d+'); + $path = str_replace($pattern, $data, $path); + + $crawler = $client->request('DELETE', $path); + } + + /** + * Test case for findPetsByStatus + * + * Finds Pets by status. + * + */ + public function testFindPetsByStatus() + { + $client = static::createClient(); + + $path = '/pet/findByStatus'; + + $crawler = $client->request('GET', $path); + } + + /** + * Test case for findPetsByTags + * + * Finds Pets by tags. + * + */ + public function testFindPetsByTags() + { + $client = static::createClient(); + + $path = '/pet/findByTags'; + + $crawler = $client->request('GET', $path); + } + + /** + * Test case for getPetById + * + * Find pet by ID. + * + */ + public function testGetPetById() + { + $client = static::createClient(); + + $path = '/pet/{petId}'; + $pattern = '{petId}'; + $data = $this->genTestData('\d+'); + $path = str_replace($pattern, $data, $path); + + $crawler = $client->request('GET', $path); + } + + /** + * Test case for updatePet + * + * Update an existing pet. + * + */ + public function testUpdatePet() + { + $client = static::createClient(); + + $path = '/pet'; + + $crawler = $client->request('PUT', $path); + } + + /** + * Test case for updatePetWithForm + * + * Updates a pet in the store with form data. + * + */ + public function testUpdatePetWithForm() + { + $client = static::createClient(); + + $path = '/pet/{petId}'; + $pattern = '{petId}'; + $data = $this->genTestData('\d+'); + $path = str_replace($pattern, $data, $path); + + $crawler = $client->request('POST', $path); + } + + /** + * Test case for uploadFile + * + * uploads an image. + * + */ + public function testUploadFile() + { + $client = static::createClient(); + + $path = '/pet/{petId}/uploadImage'; + $pattern = '{petId}'; + $data = $this->genTestData('\d+'); + $path = str_replace($pattern, $data, $path); + + $crawler = $client->request('POST', $path); + } + + protected function genTestData($regexp) + { + $grammar = new \Hoa\File\Read('hoa://Library/Regex/Grammar.pp'); + $compiler = \Hoa\Compiler\Llk\Llk::load($grammar); + $ast = $compiler->parse($regexp); + $generator = new \Hoa\Regex\Visitor\Isotropic(new \Hoa\Math\Sampler\Random()); + + return $generator->visit($ast); + } +} diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/Api/StoreApiInterfaceTest.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/Api/StoreApiInterfaceTest.php new file mode 100644 index 000000000000..2162289d8dde --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/Api/StoreApiInterfaceTest.php @@ -0,0 +1,151 @@ +genTestData('[a-z0-9]+'); + $path = str_replace($pattern, $data, $path); + + $crawler = $client->request('DELETE', $path); + } + + /** + * Test case for getInventory + * + * Returns pet inventories by status. + * + */ + public function testGetInventory() + { + $client = static::createClient(); + + $path = '/store/inventory'; + + $crawler = $client->request('GET', $path); + } + + /** + * Test case for getOrderById + * + * Find purchase order by ID. + * + */ + public function testGetOrderById() + { + $client = static::createClient(); + + $path = '/store/order/{orderId}'; + $pattern = '{orderId}'; + $data = $this->genTestData('\d+'); + $path = str_replace($pattern, $data, $path); + + $crawler = $client->request('GET', $path); + } + + /** + * Test case for placeOrder + * + * Place an order for a pet. + * + */ + public function testPlaceOrder() + { + $client = static::createClient(); + + $path = '/store/order'; + + $crawler = $client->request('POST', $path); + } + + protected function genTestData($regexp) + { + $grammar = new \Hoa\File\Read('hoa://Library/Regex/Grammar.pp'); + $compiler = \Hoa\Compiler\Llk\Llk::load($grammar); + $ast = $compiler->parse($regexp); + $generator = new \Hoa\Regex\Visitor\Isotropic(new \Hoa\Math\Sampler\Random()); + + return $generator->visit($ast); + } +} diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/Api/UserApiInterfaceTest.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/Api/UserApiInterfaceTest.php new file mode 100644 index 000000000000..9074d020f308 --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/Api/UserApiInterfaceTest.php @@ -0,0 +1,214 @@ +request('POST', $path); + } + + /** + * Test case for createUsersWithArrayInput + * + * Creates list of users with given input array. + * + */ + public function testCreateUsersWithArrayInput() + { + $client = static::createClient(); + + $path = '/user/createWithArray'; + + $crawler = $client->request('POST', $path); + } + + /** + * Test case for createUsersWithListInput + * + * Creates list of users with given input array. + * + */ + public function testCreateUsersWithListInput() + { + $client = static::createClient(); + + $path = '/user/createWithList'; + + $crawler = $client->request('POST', $path); + } + + /** + * Test case for deleteUser + * + * Delete user. + * + */ + public function testDeleteUser() + { + $client = static::createClient(); + + $path = '/user/{username}'; + $pattern = '{username}'; + $data = $this->genTestData('[a-z0-9]+'); + $path = str_replace($pattern, $data, $path); + + $crawler = $client->request('DELETE', $path); + } + + /** + * Test case for getUserByName + * + * Get user by user name. + * + */ + public function testGetUserByName() + { + $client = static::createClient(); + + $path = '/user/{username}'; + $pattern = '{username}'; + $data = $this->genTestData('[a-z0-9]+'); + $path = str_replace($pattern, $data, $path); + + $crawler = $client->request('GET', $path); + } + + /** + * Test case for loginUser + * + * Logs user into the system. + * + */ + public function testLoginUser() + { + $client = static::createClient(); + + $path = '/user/login'; + + $crawler = $client->request('GET', $path); + } + + /** + * Test case for logoutUser + * + * Logs out current logged in user session. + * + */ + public function testLogoutUser() + { + $client = static::createClient(); + + $path = '/user/logout'; + + $crawler = $client->request('GET', $path); + } + + /** + * Test case for updateUser + * + * Updated user. + * + */ + public function testUpdateUser() + { + $client = static::createClient(); + + $path = '/user/{username}'; + $pattern = '{username}'; + $data = $this->genTestData('[a-z0-9]+'); + $path = str_replace($pattern, $data, $path); + + $crawler = $client->request('PUT', $path); + } + + protected function genTestData($regexp) + { + $grammar = new \Hoa\File\Read('hoa://Library/Regex/Grammar.pp'); + $compiler = \Hoa\Compiler\Llk\Llk::load($grammar); + $ast = $compiler->parse($regexp); + $generator = new \Hoa\Regex\Visitor\Isotropic(new \Hoa\Math\Sampler\Random()); + + return $generator->visit($ast); + } +} diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/AppKernel.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/AppKernel.php new file mode 100644 index 000000000000..631690bc9786 --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/AppKernel.php @@ -0,0 +1,21 @@ +load(__DIR__.'/test_config.yml'); + } +} diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/Model/ApiResponseTest.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/Model/ApiResponseTest.php new file mode 100644 index 000000000000..47970cb5c0bb --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Tests/Model/ApiResponseTest.php @@ -0,0 +1,101 @@ +=5.4", + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "symfony/validator": "*", + "jms/serializer-bundle": "*", + "symfony/framework-bundle": "^2.3|^3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8", + "satooshi/php-coveralls": "~1.0", + "squizlabs/php_codesniffer": "~2.6", + "friendsofphp/php-cs-fixer": "~1.12", + "symfony/browser-kit": "*", + "hoa/regex": "~1.0" + }, + "autoload": { + "psr-4": { "Swagger\\Server\\" : "./" } + } +} diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/git_push.sh b/samples/server/petstore/php-symfony/SymfonyBundle-php/git_push.sh new file mode 100644 index 000000000000..792320114fbe --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/git_push.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 swagger-petstore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=`git remote` +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git crediential in your environment." + git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' + diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/phpunit.xml.dist b/samples/server/petstore/php-symfony/SymfonyBundle-php/phpunit.xml.dist new file mode 100644 index 000000000000..ec07d2081c9e --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/phpunit.xml.dist @@ -0,0 +1,25 @@ + + + + + ./Tests/Api + ./Tests/Model + + + + + + + + + + ././Api + ././Model + + + diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/pom.xml b/samples/server/petstore/php-symfony/SymfonyBundle-php/pom.xml new file mode 100644 index 000000000000..614b3d33f98a --- /dev/null +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/pom.xml @@ -0,0 +1,57 @@ + + 4.0.0 + com.penneo + PhpSymfonyPetstoreServerTests + pom + 1.0-SNAPSHOT + PHP Symfony Swagger Petstore Server + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory} + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + bundle-install + pre-integration-test + + exec + + + composer + + install + + + + + bundle-test + integration-test + + exec + + + vendor/bin/phpunit + + + + + + + +