mirror of
				https://github.com/OpenAPITools/openapi-generator.git
				synced 2025-11-04 10:43:44 +00:00 
			
		
		
		
	[Feature][PHP] Update for ze-ph generator (#7472)
* update for ze-ph generator stub to support Zend Expressive 2.1 and Path Handler 0.3 * ze-ph: for each operation generator creates special DTO model from its query parameters * ze-ph: generation of extra TODO's for complex container type and update for samples
This commit is contained in:
		
							parent
							
								
									5a3a33b3c8
								
							
						
					
					
						commit
						60e3339aa6
					
				@ -1,8 +1,10 @@
 | 
			
		||||
package io.swagger.codegen.languages;
 | 
			
		||||
 | 
			
		||||
import io.swagger.codegen.*;
 | 
			
		||||
import io.swagger.models.Operation;
 | 
			
		||||
import org.apache.commons.lang3.StringUtils;
 | 
			
		||||
import io.swagger.models.*;
 | 
			
		||||
import io.swagger.models.parameters.Parameter;
 | 
			
		||||
import io.swagger.models.parameters.QueryParameter;
 | 
			
		||||
import io.swagger.models.properties.*;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
@ -12,6 +14,12 @@ import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
public class ZendExpressivePathHandlerServerCodegen extends AbstractPhpCodegen {
 | 
			
		||||
 | 
			
		||||
    public static final String VEN_FROM_QUERY = "internal.ze-ph.fromQuery";
 | 
			
		||||
    public static final String VEN_COLLECTION_FORMAT = "internal.ze-ph.collectionFormat";
 | 
			
		||||
    public static final String VEN_QUERY_DATA_TYPE = "internal.ze-ph.queryDataType";
 | 
			
		||||
    public static final String VEN_HAS_QUERY_DATA = "internal.ze-ph.hasQueryData";
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public CodegenType getTag() {
 | 
			
		||||
        return CodegenType.SERVER;
 | 
			
		||||
@ -29,6 +37,8 @@ public class ZendExpressivePathHandlerServerCodegen extends AbstractPhpCodegen {
 | 
			
		||||
 | 
			
		||||
    public ZendExpressivePathHandlerServerCodegen() {
 | 
			
		||||
        super();
 | 
			
		||||
        //no point to use double - http://php.net/manual/en/language.types.float.php , especially because of PHP 7+ float type declaration
 | 
			
		||||
        typeMapping.put("double", "float");
 | 
			
		||||
 | 
			
		||||
        embeddedTemplateDir = templateDir = "ze-ph";
 | 
			
		||||
        invokerPackage = "App";
 | 
			
		||||
@ -52,9 +62,14 @@ public class ZendExpressivePathHandlerServerCodegen extends AbstractPhpCodegen {
 | 
			
		||||
        supportingFiles.add(new SupportingFile("app.yml.mustache", packagePath + File.separator + "application" + File.separator + "config", "app.yml"));
 | 
			
		||||
        supportingFiles.add(new SupportingFile("path_handler.yml.mustache", packagePath + File.separator + "application" + File.separator + "config", "path_handler.yml"));
 | 
			
		||||
        supportingFiles.add(new SupportingFile("data_transfer.yml.mustache", packagePath + File.separator + "application" + File.separator + "config", "data_transfer.yml"));
 | 
			
		||||
        supportingFiles.add(new SupportingFile("ErrorMiddleware.php.mustache", packagePath + File.separator + srcBasePath, "ErrorMiddleware.php"));
 | 
			
		||||
        supportingFiles.add(new SupportingFile("Date.php.mustache", packagePath + File.separator + srcBasePath + File.separator + "Strategy", "Date.php"));
 | 
			
		||||
        supportingFiles.add(new SupportingFile("DateTime.php.mustache", packagePath + File.separator + srcBasePath + File.separator + "Strategy", "DateTime.php"));
 | 
			
		||||
        supportingFiles.add(new SupportingFile("QueryParameter.php.mustache", packagePath + File.separator + srcBasePath + File.separator + "Strategy", "QueryParameter.php"));
 | 
			
		||||
        supportingFiles.add(new SupportingFile("QueryParameterArray.php.mustache", packagePath + File.separator + srcBasePath + File.separator + "Strategy", "QueryParameterArray.php"));
 | 
			
		||||
        supportingFiles.add(new SupportingFile("Type.php.mustache", packagePath + File.separator + srcBasePath + File.separator + "Validator", "Type.php"));
 | 
			
		||||
        supportingFiles.add(new SupportingFile("QueryParameterType.php.mustache", packagePath + File.separator + srcBasePath + File.separator + "Validator", "QueryParameterType.php"));
 | 
			
		||||
        supportingFiles.add(new SupportingFile("QueryParameterArrayType.php.mustache", packagePath + File.separator + srcBasePath + File.separator + "Validator", "QueryParameterArrayType.php"));
 | 
			
		||||
 | 
			
		||||
        additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, "1.0.0");
 | 
			
		||||
    }
 | 
			
		||||
@ -115,6 +130,121 @@ public class ZendExpressivePathHandlerServerCodegen extends AbstractPhpCodegen {
 | 
			
		||||
        return super.toModelName(name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Generate additional model definitions from query parameters
 | 
			
		||||
     *
 | 
			
		||||
     * @param swagger
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public void preprocessSwagger(Swagger swagger) {
 | 
			
		||||
        super.preprocessSwagger(swagger);
 | 
			
		||||
        for (String pathKey : swagger.getPaths().keySet())
 | 
			
		||||
        {
 | 
			
		||||
            Path path = swagger.getPath(pathKey);
 | 
			
		||||
            Map<HttpMethod, Operation> operations = path.getOperationMap();
 | 
			
		||||
            for (HttpMethod method : operations.keySet())
 | 
			
		||||
            {
 | 
			
		||||
                Operation operation = operations.get(method);
 | 
			
		||||
                Map<String, Property> properties = new HashMap<>();
 | 
			
		||||
                for (Parameter parameter : operation.getParameters())
 | 
			
		||||
                {
 | 
			
		||||
                    Property property = convertParameterToProperty(parameter);
 | 
			
		||||
                    if (property != null)
 | 
			
		||||
                    {
 | 
			
		||||
                        properties.put(property.getName(), property);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (!properties.isEmpty())
 | 
			
		||||
                {
 | 
			
		||||
                    Model model = new ModelImpl();
 | 
			
		||||
                    String operationId = getOrGenerateOperationId(operation, pathKey, method.name());
 | 
			
		||||
                    model.setDescription("Query parameters for " + operationId);
 | 
			
		||||
                    model.setProperties(properties);
 | 
			
		||||
                    model.getVendorExtensions().put(VEN_FROM_QUERY, Boolean.TRUE);
 | 
			
		||||
                    String definitionName = generateUniqueDefinitionName(operationId + "QueryData", swagger);
 | 
			
		||||
                    swagger.addDefinition(definitionName, model);
 | 
			
		||||
                    String definitionModel = "\\" + modelPackage + "\\" + toModelName(definitionName);
 | 
			
		||||
                    operation.getVendorExtensions().put(VEN_QUERY_DATA_TYPE, definitionModel);
 | 
			
		||||
                    operation.getVendorExtensions().put(VEN_HAS_QUERY_DATA, Boolean.TRUE);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected Property convertParameterToProperty(Parameter parameter) {
 | 
			
		||||
        Property property = null;
 | 
			
		||||
        if (parameter instanceof QueryParameter)
 | 
			
		||||
        {
 | 
			
		||||
            QueryParameter queryParameter = (QueryParameter) parameter;
 | 
			
		||||
            switch (queryParameter.getType())
 | 
			
		||||
            {
 | 
			
		||||
                case "string":
 | 
			
		||||
                    StringProperty stringProperty = new StringProperty();
 | 
			
		||||
                    stringProperty.setMinLength(queryParameter.getMinLength());
 | 
			
		||||
                    stringProperty.setMaxLength(queryParameter.getMaxLength());
 | 
			
		||||
                    stringProperty.setPattern(queryParameter.getPattern());
 | 
			
		||||
                    stringProperty.setEnum(queryParameter.getEnum());
 | 
			
		||||
                    property = stringProperty;
 | 
			
		||||
                    break;
 | 
			
		||||
                case "integer":
 | 
			
		||||
                    IntegerProperty integerProperty = new IntegerProperty();
 | 
			
		||||
                    integerProperty.setMinimum(queryParameter.getMinimum());
 | 
			
		||||
                    integerProperty.setMaximum(queryParameter.getMaximum());
 | 
			
		||||
                    property = integerProperty;
 | 
			
		||||
                    break;
 | 
			
		||||
                case "number":
 | 
			
		||||
                    FloatProperty floatProperty = new FloatProperty();
 | 
			
		||||
                    floatProperty.setMinimum(queryParameter.getMinimum());
 | 
			
		||||
                    floatProperty.setMaximum(queryParameter.getMaximum());
 | 
			
		||||
                    property = floatProperty;
 | 
			
		||||
                    break;
 | 
			
		||||
                case "boolean":
 | 
			
		||||
                    property = new BooleanProperty();
 | 
			
		||||
                    break;
 | 
			
		||||
                case "array":
 | 
			
		||||
                    ArrayProperty arrayProperty = new ArrayProperty();
 | 
			
		||||
                    arrayProperty.setMinItems(queryParameter.getMinItems());
 | 
			
		||||
                    arrayProperty.setMaxItems(queryParameter.getMaxItems());
 | 
			
		||||
                    arrayProperty.setItems(queryParameter.getItems());
 | 
			
		||||
                    String collectionFormat = queryParameter.getCollectionFormat();
 | 
			
		||||
                    if (collectionFormat == null) {
 | 
			
		||||
                        collectionFormat = "csv";
 | 
			
		||||
                    }
 | 
			
		||||
                    arrayProperty.getVendorExtensions().put(VEN_COLLECTION_FORMAT, collectionFormat);
 | 
			
		||||
                    property = arrayProperty;
 | 
			
		||||
                    break;
 | 
			
		||||
                case "date":
 | 
			
		||||
                    property = new DateProperty();
 | 
			
		||||
                    break;
 | 
			
		||||
                case "date-time":
 | 
			
		||||
                    property = new DateTimeProperty();
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            if (property != null)
 | 
			
		||||
            {
 | 
			
		||||
                property.setName(queryParameter.getName());
 | 
			
		||||
                property.setDescription(queryParameter.getDescription());
 | 
			
		||||
                property.setRequired(queryParameter.getRequired());
 | 
			
		||||
                property.getVendorExtensions().put(VEN_FROM_QUERY, Boolean.TRUE);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return property;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected String generateUniqueDefinitionName(String name, Swagger swagger)
 | 
			
		||||
    {
 | 
			
		||||
        String result = name;
 | 
			
		||||
        if (swagger.getDefinitions() != null) {
 | 
			
		||||
            int count = 1;
 | 
			
		||||
            while (swagger.getDefinitions().containsKey(result))
 | 
			
		||||
            {
 | 
			
		||||
                result = name + "_" + count;
 | 
			
		||||
                count += 1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
 | 
			
		||||
        objs = super.postProcessOperations(objs);
 | 
			
		||||
@ -123,6 +253,7 @@ public class ZendExpressivePathHandlerServerCodegen extends AbstractPhpCodegen {
 | 
			
		||||
        String interfaceToImplement;
 | 
			
		||||
        StringBuilder interfacesToImplement = new StringBuilder();
 | 
			
		||||
        String classMethod;
 | 
			
		||||
        String pathPattern = null;
 | 
			
		||||
        for (CodegenOperation op : operationList) {
 | 
			
		||||
            switch (op.httpMethod) {
 | 
			
		||||
                case "GET":
 | 
			
		||||
@ -153,63 +284,41 @@ public class ZendExpressivePathHandlerServerCodegen extends AbstractPhpCodegen {
 | 
			
		||||
            }
 | 
			
		||||
            interfacesToImplement.append(interfaceToImplement);
 | 
			
		||||
            op.httpMethod = classMethod;
 | 
			
		||||
            //All operations have same path because of custom operation grouping, so path pattern can be calculated only once
 | 
			
		||||
            if (pathPattern == null) {
 | 
			
		||||
                pathPattern = generatePathPattern(op);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        operations.put("interfacesToImplement", interfacesToImplement.toString());
 | 
			
		||||
        operations.put("pathPattern", pathPattern);
 | 
			
		||||
 | 
			
		||||
        return objs;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Map<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
 | 
			
		||||
        objs = super.postProcessSupportingFileData(objs);
 | 
			
		||||
 | 
			
		||||
        Map<String, Object> apiInfo = (Map<String, Object>) objs.get("apiInfo");
 | 
			
		||||
        List<Map<String, Object>> apis = (List<Map<String, Object>>) apiInfo.get("apis");
 | 
			
		||||
 | 
			
		||||
        List<Map<String, Object>> routes = new ArrayList<Map<String, Object>>();
 | 
			
		||||
        for (Map<String, Object> api : apis) {
 | 
			
		||||
            String handler = (String) api.get("classname");
 | 
			
		||||
            String url = (String) api.get("baseName");
 | 
			
		||||
            if (url.charAt(0) == '/') {
 | 
			
		||||
                url = url.substring(1);
 | 
			
		||||
            }
 | 
			
		||||
            insertRoute(routes, url.split("/"), 0, handler);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        objs.put("routes", routes);
 | 
			
		||||
        return objs;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void insertRoute(List<Map<String, Object>> routes, String[] urlParts, int currentUrlPartIndex, String handler) {
 | 
			
		||||
        if (urlParts.length > currentUrlPartIndex) {
 | 
			
		||||
            String urlPart = urlParts[currentUrlPartIndex];
 | 
			
		||||
            //List<Map<String, Object>> subRoutes = null;
 | 
			
		||||
            Map<String, Object> currentRoute = null;
 | 
			
		||||
            for (Map<String, Object> route : routes) {
 | 
			
		||||
                if (urlPart.equals(route.get("name"))) {
 | 
			
		||||
                    currentRoute = route;
 | 
			
		||||
                    break;
 | 
			
		||||
    protected String generatePathPattern(CodegenOperation op) {
 | 
			
		||||
        String result = op.path;
 | 
			
		||||
        for (CodegenParameter pp : op.pathParams) {
 | 
			
		||||
            StringBuilder replacement = new StringBuilder( "{" + pp.paramName);
 | 
			
		||||
            if (pp.isEnum) {
 | 
			
		||||
                StringBuilder enumRegExp = new StringBuilder();
 | 
			
		||||
                for (String enumValue : pp._enum) {
 | 
			
		||||
                    if (enumRegExp.length() > 0) {
 | 
			
		||||
                        enumRegExp.append("|");
 | 
			
		||||
                    }
 | 
			
		||||
                    enumRegExp.append(enumValue.replaceAll("[\\Q<>()[]{}|^$-=!?*+.\\\\E]", "\\\\$0"));
 | 
			
		||||
                }
 | 
			
		||||
                replacement.append(":");
 | 
			
		||||
                replacement.append(enumRegExp);
 | 
			
		||||
            } else if (pp.isInteger) {
 | 
			
		||||
                replacement.append(":0|(?:-?[1-9][0-9]*)");
 | 
			
		||||
            } else if (pp.isString && (pp.pattern != null) && (!pp.pattern.isEmpty())) {
 | 
			
		||||
                replacement.append(":");
 | 
			
		||||
                replacement.append(pp.pattern);
 | 
			
		||||
            }
 | 
			
		||||
            if (currentRoute == null) {
 | 
			
		||||
                currentRoute = new HashMap<String, Object>();
 | 
			
		||||
 | 
			
		||||
                String routePart = urlPart.replaceAll("^\\{(\\w+)\\}$", ":$1");
 | 
			
		||||
                boolean isLastUrlPart = currentUrlPartIndex == urlParts.length - 1;
 | 
			
		||||
 | 
			
		||||
                currentRoute.put("name", urlPart);
 | 
			
		||||
                currentRoute.put("route", "/" + routePart);
 | 
			
		||||
                currentRoute.put("type", (urlPart == routePart) ? "Literal" : "Segment");
 | 
			
		||||
                currentRoute.put("handler", isLastUrlPart ? handler : null);
 | 
			
		||||
                currentRoute.put("hasChildren", false);
 | 
			
		||||
                currentRoute.put("children", new ArrayList<Map<String, Object>>());
 | 
			
		||||
                currentRoute.put("padding", StringUtils.repeat(' ', 4 * currentUrlPartIndex));
 | 
			
		||||
 | 
			
		||||
                routes.add(currentRoute);
 | 
			
		||||
            }
 | 
			
		||||
            List<Map<String, Object>> subRoutes = (List<Map<String, Object>>) currentRoute.get("children");
 | 
			
		||||
            insertRoute(subRoutes, urlParts, currentUrlPartIndex + 1, handler);
 | 
			
		||||
            currentRoute.put("hasChildren", !subRoutes.isEmpty());
 | 
			
		||||
            //TODO add regular expressions for other types if they are actually used for path parameters
 | 
			
		||||
            replacement.append("}");
 | 
			
		||||
            result = result.replace("{" + pp.paramName + "}", replacement);
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,34 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace {{invokerPackage}};
 | 
			
		||||
 | 
			
		||||
use Interop\Http\ServerMiddleware\DelegateInterface;
 | 
			
		||||
use Interop\Http\ServerMiddleware\MiddlewareInterface;
 | 
			
		||||
use Psr\Http\Message\ResponseInterface as Response;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface as Request;
 | 
			
		||||
use Zend\Stdlib\ErrorHandler;
 | 
			
		||||
 | 
			
		||||
class ErrorMiddleware implements MiddlewareInterface
 | 
			
		||||
{
 | 
			
		||||
    public function process(Request $request, DelegateInterface $delegate)
 | 
			
		||||
    {
 | 
			
		||||
        $result = null;
 | 
			
		||||
        try {
 | 
			
		||||
            ErrorHandler::start();
 | 
			
		||||
            $result = $delegate->process($request);
 | 
			
		||||
            ErrorHandler::stop(true);
 | 
			
		||||
            if (!($result instanceof Response)) {
 | 
			
		||||
                throw new \RuntimeException(sprintf(
 | 
			
		||||
                    'Invalid response: expecting %s, got %s',
 | 
			
		||||
                    Response::class,
 | 
			
		||||
                    is_object($result)? get_class($result) : gettype($result)
 | 
			
		||||
                ));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (\Exception $error) {
 | 
			
		||||
            $result = (new \Zend\Diactoros\Response())->withStatus(500, 'Internal server error');
 | 
			
		||||
            error_log((string)$error);
 | 
			
		||||
        }
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,76 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace {{invokerPackage}}\Strategy;
 | 
			
		||||
 | 
			
		||||
use Articus\DataTransfer\Strategy\StrategyInterface;
 | 
			
		||||
 | 
			
		||||
class QueryParameter implements StrategyInterface
 | 
			
		||||
{
 | 
			
		||||
    const TYPE_INT = 'int';
 | 
			
		||||
    const TYPE_FLOAT = 'float';
 | 
			
		||||
    const TYPE_BOOL = 'bool';
 | 
			
		||||
    const TYPE_STRING = 'string';
 | 
			
		||||
 | 
			
		||||
    const TYPE_MAP = [
 | 
			
		||||
        self::TYPE_INT => true,
 | 
			
		||||
        self::TYPE_FLOAT => true,
 | 
			
		||||
        self::TYPE_BOOL => true,
 | 
			
		||||
        self::TYPE_STRING => true,
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var string
 | 
			
		||||
     */
 | 
			
		||||
    protected $type;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * QueryParameterArray constructor.
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(array $options)
 | 
			
		||||
    {
 | 
			
		||||
        if (empty($options['type'])) {
 | 
			
		||||
            throw new \InvalidArgumentException('Option "type" is required.');
 | 
			
		||||
        } elseif (!isset(self::TYPE_MAP[$options['type']])) {
 | 
			
		||||
            throw new \InvalidArgumentException(sprintf('Unknown type "%s".', $options['type']));
 | 
			
		||||
        }
 | 
			
		||||
        $this->type = $options['type'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    public function extract($objectValue, $object = null)
 | 
			
		||||
    {
 | 
			
		||||
        $result = null;
 | 
			
		||||
        if ($objectValue !== null) {
 | 
			
		||||
            $result = (string)$objectValue;
 | 
			
		||||
        }
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    public function hydrate($arrayValue, $objectValue, array $array = null)
 | 
			
		||||
    {
 | 
			
		||||
        $result = null;
 | 
			
		||||
        if ($arrayValue !== null) {
 | 
			
		||||
            switch ($this->type) {
 | 
			
		||||
                case self::TYPE_INT:
 | 
			
		||||
                    $result = (int)$arrayValue;
 | 
			
		||||
                    break;
 | 
			
		||||
                case self::TYPE_FLOAT:
 | 
			
		||||
                    $result = (float)$arrayValue;
 | 
			
		||||
                    break;
 | 
			
		||||
                case self::TYPE_BOOL:
 | 
			
		||||
                    $result = ($arrayValue === 'true')? true : false;
 | 
			
		||||
                    break;
 | 
			
		||||
                case self::TYPE_STRING:
 | 
			
		||||
                    $result = (string)$arrayValue;
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,73 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace {{invokerPackage}}\Strategy;
 | 
			
		||||
 | 
			
		||||
class QueryParameterArray extends QueryParameter
 | 
			
		||||
{
 | 
			
		||||
    const FORMAT_CSV = 'csv'; //comma separated values foo,bar.
 | 
			
		||||
    const FORMAT_SSV = 'ssv'; //space separated values foo bar.
 | 
			
		||||
    const FORMAT_TSV = 'tsv'; //tab separated values foo\tbar.
 | 
			
		||||
    const FORMAT_PIPES = 'pipes'; //pipe separated values foo|bar.
 | 
			
		||||
    const FORMAT_MULTI = 'multi'; //corresponds to multiple parameter instances instead of multiple values for a single instance foo[]=bar&foo[]=baz.
 | 
			
		||||
 | 
			
		||||
    const DELIMITER_MAP = [
 | 
			
		||||
        self::FORMAT_CSV => ',',
 | 
			
		||||
        self::FORMAT_SSV => ' ',
 | 
			
		||||
        self::FORMAT_TSV => "\t",
 | 
			
		||||
        self::FORMAT_PIPES => '|',
 | 
			
		||||
        self::FORMAT_MULTI => null,
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var string|null
 | 
			
		||||
     */
 | 
			
		||||
    protected $delimiter;
 | 
			
		||||
 | 
			
		||||
    public function __construct(array $options)
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct($options);
 | 
			
		||||
        if (empty($options['format'])) {
 | 
			
		||||
            throw new \InvalidArgumentException('Option "format" is required.');
 | 
			
		||||
        } elseif (!array_key_exists($options['format'], self::DELIMITER_MAP)) {
 | 
			
		||||
            throw new \InvalidArgumentException(sprintf('Unknown format "%s".', $options['format']));
 | 
			
		||||
        }
 | 
			
		||||
        $this->delimiter = self::DELIMITER_MAP[$options['format']];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    public function extract($objectValue, $object = null)
 | 
			
		||||
    {
 | 
			
		||||
        $result = null;
 | 
			
		||||
        if (is_array($objectValue)) {
 | 
			
		||||
            if ($this->delimiter === null) {
 | 
			
		||||
                $result = $objectValue;
 | 
			
		||||
            } else {
 | 
			
		||||
                $result = implode($this->delimiter, $objectValue);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    public function hydrate($arrayValue, $objectValue, array $array = null)
 | 
			
		||||
    {
 | 
			
		||||
        $result = null;
 | 
			
		||||
        if ($arrayValue !== null) {
 | 
			
		||||
            $list = null;
 | 
			
		||||
            if ($this->delimiter === null) {
 | 
			
		||||
                $list = (is_array($arrayValue))? $arrayValue : [$arrayValue];
 | 
			
		||||
            } else {
 | 
			
		||||
                $list = explode($this->delimiter, $arrayValue);
 | 
			
		||||
            }
 | 
			
		||||
            $result = [];
 | 
			
		||||
            foreach ($list as $item) {
 | 
			
		||||
                $result[] = parent::hydrate($item, null);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,72 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace {{invokerPackage}}\Validator;
 | 
			
		||||
 | 
			
		||||
use App\Strategy\QueryParameterArray;
 | 
			
		||||
 | 
			
		||||
class QueryParameterArrayType extends QueryParameterType
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @var string
 | 
			
		||||
     */
 | 
			
		||||
    protected $format;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    public function getFormat()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->format;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string $format
 | 
			
		||||
     * @return self
 | 
			
		||||
     */
 | 
			
		||||
    public function setFormat($format)
 | 
			
		||||
    {
 | 
			
		||||
        $this->format = $format;
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function checkType($value)
 | 
			
		||||
    {
 | 
			
		||||
        $result = true;
 | 
			
		||||
        if (!array_key_exists($this->format, QueryParameterArray::DELIMITER_MAP)) {
 | 
			
		||||
            throw new \InvalidArgumentException(sprintf('Can not check for format %s.', $this->format));
 | 
			
		||||
        }
 | 
			
		||||
        $delimiter = QueryParameterArray::DELIMITER_MAP[$this->format];
 | 
			
		||||
        if ($delimiter === null) {
 | 
			
		||||
            if (is_array($value)) {
 | 
			
		||||
                foreach ($value as $item) {
 | 
			
		||||
                    $result = $result && parent::checkType($item);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                $result = false;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            switch ($this->type) {
 | 
			
		||||
                case QueryParameterArray::TYPE_INT:
 | 
			
		||||
                    $result = is_string($value) && preg_match(self::prepareRepeatingTypeRegExp(self::RE_INT, $delimiter), $value);
 | 
			
		||||
                    break;
 | 
			
		||||
                case QueryParameterArray::TYPE_BOOL:
 | 
			
		||||
                    $result = is_string($value) && preg_match(self::prepareRepeatingTypeRegExp(self::RE_BOOL, $delimiter), $value);
 | 
			
		||||
                    break;
 | 
			
		||||
                case QueryParameterArray::TYPE_FLOAT:
 | 
			
		||||
                    $result = is_string($value) && preg_match(self::prepareRepeatingTypeRegExp(self::RE_FLOAT, $delimiter), $value);
 | 
			
		||||
                    break;
 | 
			
		||||
                case QueryParameterArray::TYPE_STRING:
 | 
			
		||||
                    $result = is_string($value);
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    throw new \InvalidArgumentException(sprintf('Can not check for type %s.', $this->type));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected static function prepareRepeatingTypeRegExp($typeRegExp, $delimiter)
 | 
			
		||||
    {
 | 
			
		||||
        $escapedDelimiter = preg_quote($delimiter, '/');
 | 
			
		||||
        return '/^(' . $typeRegExp . ')(' . $escapedDelimiter . '('. $typeRegExp . '))*$/';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,27 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace {{invokerPackage}}\Validator;
 | 
			
		||||
 | 
			
		||||
use App\Strategy\QueryParameter;
 | 
			
		||||
 | 
			
		||||
class QueryParameterType extends Type
 | 
			
		||||
{
 | 
			
		||||
    const RE_INT = '0|-?[1-9]\d*';
 | 
			
		||||
    const RE_BOOL = 'true|false';
 | 
			
		||||
    const RE_FLOAT = '0(\.\d+)?|-?[1-9]\d*(\.\d+)?|-0\.\d+';
 | 
			
		||||
 | 
			
		||||
    protected function checkType($value)
 | 
			
		||||
    {
 | 
			
		||||
        switch ($this->type) {
 | 
			
		||||
            case QueryParameter::TYPE_INT:
 | 
			
		||||
                return is_string($value) && preg_match('/^(' . self::RE_INT . ')$/', $value);
 | 
			
		||||
            case QueryParameter::TYPE_BOOL:
 | 
			
		||||
                return is_string($value) && preg_match('/^(' . self::RE_BOOL . ')$/', $value);
 | 
			
		||||
            case QueryParameter::TYPE_FLOAT:
 | 
			
		||||
                return is_string($value) && preg_match('/^(' . self::RE_FLOAT . ')$/', $value);
 | 
			
		||||
            case QueryParameter::TYPE_STRING:
 | 
			
		||||
                return is_string($value);
 | 
			
		||||
            default:
 | 
			
		||||
                throw new \InvalidArgumentException(sprintf('Can not check for type %s.', $this->type));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,10 +1,34 @@
 | 
			
		||||
# Swagger generated server
 | 
			
		||||
 | 
			
		||||
Generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project.
 | 
			
		||||
 | 
			
		||||
## Overview
 | 
			
		||||
This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the
 | 
			
		||||
[OpenAPI-Spec](https://github.com/swagger-api/swagger-core/wiki) from a remote server, you can easily generate a server stub. This
 | 
			
		||||
is an example of building a PHP server.
 | 
			
		||||
This server stub aims to provide light, yet comprehensive structure for your API project using:
 | 
			
		||||
 | 
			
		||||
This example uses the [Zend Expressive](https://zendframework.github.io/zend-expressive) micro framework and [Path Handler](https://github.com/Articus/PathHandler) library. To see how to make this your own, please take a look at the template here:
 | 
			
		||||
- PHP: 5.6 or 7.*
 | 
			
		||||
- [Zend Expressive](https://zendframework.github.io/zend-expressive): 2.1
 | 
			
		||||
- [Path Handler](https://github.com/Articus/PathHandler): 0.3
 | 
			
		||||
 | 
			
		||||
[TEMPLATES](https://github.com/swagger-api/swagger-codegen/tree/master/modules/swagger-codegen/src/main/resources/ze-ph/)
 | 
			
		||||
## How to use
 | 
			
		||||
All you have to do to start development is:
 | 
			
		||||
 | 
			
		||||
- install dependencies via [Composer](https://getcomposer.org/)
 | 
			
		||||
- create cache folder: `mkdir -p ./data/cache/ZendCache` (you will need it later for configuration and metadata caches - check comments in `./application/conig.yml`)
 | 
			
		||||
- start PHP development server: `php -S 0.0.0.0:8080 -t ./public` (or any other SAPI you prefer, just make sure that you configure webroot to `./public` and rewrites to `./public/index.php`)
 | 
			
		||||
 | 
			
		||||
After that you should be able to call all methods from your API spec. Most of the negative scenarios should be handled:
 | 
			
		||||
 | 
			
		||||
- `404 Not found` for unknown routes
 | 
			
		||||
- `406 Not acceptable` for invalid `Accept` header
 | 
			
		||||
- `415 Unsupported media type` for invalid `Content-Type` header
 | 
			
		||||
- `400 Malformed JSON` for unparsable JSON body
 | 
			
		||||
- `422 Unprocessable entity` for parsable JSON body that fails validation
 | 
			
		||||
 | 
			
		||||
But for obvious reason you will not get any `200 OK`, only `500 Not implemented`. So your next steps are:
 | 
			
		||||
 | 
			
		||||
- check all TODOs left in the stub code where generator was not smart enough and could not guarantee correct implementation
 | 
			
		||||
- implement your API security mechanism (either special attribute or separate middleware) - generator does not do anything about it yet
 | 
			
		||||
- implement your handlers - the most tricky part :)
 | 
			
		||||
 | 
			
		||||
## Enjoy!
 | 
			
		||||
Hopefully this stub will reduce the amount of boilerplate code you have to write manually. If you have any suggestions or questions about `ze-ph` generator, feel free to create issue either in [Path Handler repository](https://github.com/Articus/PathHandler/issues) or in [Swagger Codegen repository](https://github.com/swagger-api/swagger-codegen/issues).
 | 
			
		||||
 | 
			
		||||
@ -11,11 +11,12 @@ use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
{{#operations}}
 | 
			
		||||
{{#description}}
 | 
			
		||||
/**
 | 
			
		||||
{{#description}}
 | 
			
		||||
 * {{&description}}
 | 
			
		||||
 */
 | 
			
		||||
{{/description}}
 | 
			
		||||
 * @PHA\Route(pattern="{{pathPattern}}")
 | 
			
		||||
 */
 | 
			
		||||
class {{classname}} implements {{interfacesToImplement}}
 | 
			
		||||
{
 | 
			
		||||
{{#operation}}
 | 
			
		||||
@ -26,13 +27,25 @@ class {{classname}} implements {{interfacesToImplement}}
 | 
			
		||||
{{#description}}
 | 
			
		||||
     * {{description}}
 | 
			
		||||
{{/description}}
 | 
			
		||||
{{#vendorExtensions}}
 | 
			
		||||
{{#internal.ze-ph.hasQueryData}}
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={
 | 
			
		||||
     *     "type":{{internal.ze-ph.queryDataType}}::class,
 | 
			
		||||
     *     "objectAttr":"queryData",
 | 
			
		||||
     *     "source": PHAttribute\Transfer::SOURCE_GET
 | 
			
		||||
     * })
 | 
			
		||||
{{/internal.ze-ph.hasQueryData}}
 | 
			
		||||
{{/vendorExtensions}}
 | 
			
		||||
{{#bodyParam}}
 | 
			
		||||
{{#consumes}}
 | 
			
		||||
     * TODO check if consumer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Consumer(name=PHConsumer\Json::class, mediaType="{{{mediaType}}}")
 | 
			
		||||
{{/consumes}}
 | 
			
		||||
{{^isPrimitiveType}}
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":{{dataType}}::class,"objectAttr":"{{paramName}}"})
 | 
			
		||||
{{#isContainer}}
 | 
			
		||||
     * TODO check if attribute is valid and can handle your container type
 | 
			
		||||
{{/isContainer}}
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":{{dataType}}::class,"objectAttr":"bodyData"})
 | 
			
		||||
{{/isPrimitiveType}}
 | 
			
		||||
{{/bodyParam}}
 | 
			
		||||
{{#produces}}
 | 
			
		||||
@ -50,10 +63,16 @@ class {{classname}} implements {{interfacesToImplement}}
 | 
			
		||||
    public function {{httpMethod}}(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO implement method
 | 
			
		||||
{{#vendorExtensions}}
 | 
			
		||||
{{#internal.ze-ph.hasQueryData}}
 | 
			
		||||
        /** @var {{internal.ze-ph.queryDataType}} $queryData */
 | 
			
		||||
        $queryData = $request->getAttribute("queryData");
 | 
			
		||||
{{/internal.ze-ph.hasQueryData}}
 | 
			
		||||
{{/vendorExtensions}}
 | 
			
		||||
{{#bodyParam}}
 | 
			
		||||
{{^isPrimitiveType}}
 | 
			
		||||
        /** @var {{dataType}} ${{paramName}} */
 | 
			
		||||
        ${{paramName}} = $request->getAttribute("{{paramName}}");
 | 
			
		||||
        /** @var {{dataType}} $bodyData */
 | 
			
		||||
        $bodyData = $request->getAttribute("bodyData");
 | 
			
		||||
{{/isPrimitiveType}}
 | 
			
		||||
{{/bodyParam}}
 | 
			
		||||
        throw new PHException\HttpCode(500, "Not implemented");
 | 
			
		||||
 | 
			
		||||
@ -1,26 +1,14 @@
 | 
			
		||||
dependencies:
 | 
			
		||||
  invokables:
 | 
			
		||||
    #Has to add this line because currently router is strict requirement for Zend\Expressive\Application even if only middleware_pipeline is used
 | 
			
		||||
    Zend\Expressive\Router\RouterInterface: Zend\Expressive\Router\ZendRouter
 | 
			
		||||
    Zend\Diactoros\Response\EmitterInterface: Zend\Diactoros\Response\SapiStreamEmitter
 | 
			
		||||
    App\ErrorMiddleware: App\ErrorMiddleware
 | 
			
		||||
  factories:
 | 
			
		||||
    Zend\Expressive\Application: Zend\Expressive\Container\ApplicationFactory
 | 
			
		||||
    Articus\PathHandler\Middleware: Articus\PathHandler\MiddlewareFactory
 | 
			
		||||
    Articus\DataTransfer\Service: Articus\DataTransfer\ServiceFactory
 | 
			
		||||
    Zend\Stratigility\Middleware\ErrorHandler: Zend\Expressive\Container\ErrorHandlerFactory
 | 
			
		||||
    Zend\Expressive\Middleware\ErrorResponseGenerator: Zend\Expressive\Container\WhoopsErrorResponseGeneratorFactory
 | 
			
		||||
    Zend\Expressive\Whoops: Zend\Expressive\Container\WhoopsFactory
 | 
			
		||||
    Zend\Expressive\WhoopsPageHandler: Zend\Expressive\Container\WhoopsPageHandlerFactory
 | 
			
		||||
 | 
			
		||||
middleware_pipeline:
 | 
			
		||||
  error:
 | 
			
		||||
    middleware: Zend\Stratigility\Middleware\ErrorHandler
 | 
			
		||||
    middleware: App\ErrorMiddleware
 | 
			
		||||
  api:
 | 
			
		||||
    middleware: Articus\PathHandler\Middleware
 | 
			
		||||
    path: {{basePathWithoutHost}}
 | 
			
		||||
 | 
			
		||||
whoops:
 | 
			
		||||
  json_exceptions:
 | 
			
		||||
    display: true
 | 
			
		||||
    show_trace: true
 | 
			
		||||
    ajax_only: true
 | 
			
		||||
 | 
			
		||||
@ -7,18 +7,17 @@
 | 
			
		||||
    "require": {
 | 
			
		||||
        "php": "^5.6 || ^7.0",
 | 
			
		||||
        "ext-yaml" : "^1.2 || ^2.0",
 | 
			
		||||
        "zendframework/zend-expressive": "^2.0",
 | 
			
		||||
        "zendframework/zend-expressive-router": "^2.1",
 | 
			
		||||
        "zendframework/zend-expressive-zendrouter": "^2.0",
 | 
			
		||||
        "articus/path-handler": "0.2.*",
 | 
			
		||||
        "articus/data-transfer": "*",
 | 
			
		||||
        "zendframework/zend-serializer": "*",
 | 
			
		||||
        "zendframework/zend-config": "*",
 | 
			
		||||
        "filp/whoops": "^2.1.7"
 | 
			
		||||
        "zendframework/zend-expressive": "^2.1",
 | 
			
		||||
        "articus/path-handler": "^0.3",
 | 
			
		||||
        "articus/data-transfer": "^0.1",
 | 
			
		||||
        "zendframework/zend-serializer": "^2.8",
 | 
			
		||||
        "zendframework/zend-config": "^3.1",
 | 
			
		||||
        "nikic/fast-route": "^1.2",
 | 
			
		||||
        "http-interop/http-middleware": "^0.4.1"
 | 
			
		||||
    },
 | 
			
		||||
    "autoload": {
 | 
			
		||||
        "psr-4": {
 | 
			
		||||
            "": "src/"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,3 +1,41 @@
 | 
			
		||||
#App
 | 
			
		||||
cache_configuration: false
 | 
			
		||||
debug: true
 | 
			
		||||
#Empty configuration placeholder, remove when you add any real configuration settings to this file
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
#Enable configuration cache
 | 
			
		||||
#cache_configuration: true
 | 
			
		||||
 | 
			
		||||
#Enable routing cache for handlers
 | 
			
		||||
#Articus\PathHandler\Router\FastRouteAnnotation:
 | 
			
		||||
#  metadata_cache:
 | 
			
		||||
#    adapter:
 | 
			
		||||
#      name: filesystem
 | 
			
		||||
#      options:
 | 
			
		||||
#        cache_dir: data/cache/ZendCache
 | 
			
		||||
#        namespace: fast-route
 | 
			
		||||
#    plugins:
 | 
			
		||||
#      serializer:
 | 
			
		||||
#        serializer: phpserialize
 | 
			
		||||
 | 
			
		||||
#Enable consumer, attribute and producer cache for handlers
 | 
			
		||||
#Articus\PathHandler\Middleware:
 | 
			
		||||
#  metadata_cache:
 | 
			
		||||
#    adapter:
 | 
			
		||||
#      name: filesystem
 | 
			
		||||
#      options:
 | 
			
		||||
#        cache_dir: data/cache/ZendCache
 | 
			
		||||
#        namespace: path-handler
 | 
			
		||||
#    plugins:
 | 
			
		||||
#      serializer:
 | 
			
		||||
#        serializer: phpserialize
 | 
			
		||||
 | 
			
		||||
#Enable data transfer metadata cache for DTOs
 | 
			
		||||
#data_transfer:
 | 
			
		||||
#  metadata_cache:
 | 
			
		||||
#    adapter:
 | 
			
		||||
#      name: filesystem
 | 
			
		||||
#      options:
 | 
			
		||||
#        cache_dir: data/cache/ZendCache
 | 
			
		||||
#        namespace: data-transfer
 | 
			
		||||
#    plugins:
 | 
			
		||||
#      serializer:
 | 
			
		||||
#        serializer: phpserialize
 | 
			
		||||
 | 
			
		||||
@ -1,24 +1,28 @@
 | 
			
		||||
dependencies:
 | 
			
		||||
  factories:
 | 
			
		||||
    Articus\DataTransfer\Service: Articus\DataTransfer\ServiceFactory
 | 
			
		||||
 | 
			
		||||
data_transfer:
 | 
			
		||||
  metadata_cache:
 | 
			
		||||
    adapter:
 | 
			
		||||
      name: blackhole
 | 
			
		||||
#    adapter:
 | 
			
		||||
#      name: filesystem
 | 
			
		||||
#      options:
 | 
			
		||||
#        cache_dir: data/cache/data_transfer
 | 
			
		||||
#        namespace: dt
 | 
			
		||||
 | 
			
		||||
  strategies:
 | 
			
		||||
    invokables:
 | 
			
		||||
      {{invokerPackage}}\Strategy\Date: {{invokerPackage}}\Strategy\Date
 | 
			
		||||
      {{invokerPackage}}\Strategy\DateTime: {{invokerPackage}}\Strategy\DateTime
 | 
			
		||||
      {{invokerPackage}}\Strategy\QueryParameter: {{invokerPackage}}\Strategy\QueryParameter
 | 
			
		||||
      {{invokerPackage}}\Strategy\QueryParameterArray: {{invokerPackage}}\Strategy\QueryParameterArray
 | 
			
		||||
#    factories:
 | 
			
		||||
    aliases:
 | 
			
		||||
      Date: {{invokerPackage}}\Strategy\Date
 | 
			
		||||
      DateTime: {{invokerPackage}}\Strategy\DateTime
 | 
			
		||||
      QueryParameter: {{invokerPackage}}\Strategy\QueryParameter
 | 
			
		||||
      QueryParameterArray: {{invokerPackage}}\Strategy\QueryParameterArray
 | 
			
		||||
  validators:
 | 
			
		||||
    invokables:
 | 
			
		||||
      {{invokerPackage}}\Validator\Type: {{invokerPackage}}\Validator\Type
 | 
			
		||||
      {{invokerPackage}}\Validator\QueryParameterType: {{invokerPackage}}\Validator\QueryParameterType
 | 
			
		||||
      {{invokerPackage}}\Validator\QueryParameterArrayType: {{invokerPackage}}\Validator\QueryParameterArrayType
 | 
			
		||||
    factories:
 | 
			
		||||
      Articus\DataTransfer\Validator\Dictionary: Articus\DataTransfer\Validator\Factory
 | 
			
		||||
      Articus\DataTransfer\Validator\Collection: Articus\DataTransfer\Validator\Factory
 | 
			
		||||
@ -26,3 +30,5 @@ data_transfer:
 | 
			
		||||
      Dictionary: Articus\DataTransfer\Validator\Dictionary
 | 
			
		||||
      Collection: Articus\DataTransfer\Validator\Collection
 | 
			
		||||
      Type: {{invokerPackage}}\Validator\Type
 | 
			
		||||
      QueryParameterType: {{invokerPackage}}\Validator\QueryParameterType
 | 
			
		||||
      QueryParameterArrayType: {{invokerPackage}}\Validator\QueryParameterArrayType
 | 
			
		||||
 | 
			
		||||
@ -16,114 +16,10 @@ class {{classname}}
 | 
			
		||||
{{#description}}
 | 
			
		||||
     * {{description}}
 | 
			
		||||
{{/description}}
 | 
			
		||||
     * @DTA\Data(field="{{baseName}}"{{^required}}, nullable=true{{/required}})
 | 
			
		||||
{{^isPrimitiveType}}
 | 
			
		||||
{{^isListContainer}}
 | 
			
		||||
{{^isDate}}
 | 
			
		||||
{{^isDateTime}}
 | 
			
		||||
     * @DTA\Strategy(name="Object", options={"type":{{datatype}}::class})
 | 
			
		||||
     * @DTA\Validator(name="Dictionary", options={"type":{{datatype}}::class})
 | 
			
		||||
{{/isDateTime}}
 | 
			
		||||
{{/isDate}}
 | 
			
		||||
{{#isDate}}
 | 
			
		||||
     * @DTA\Strategy(name="Date")
 | 
			
		||||
     * @DTA\Validator(name="Date")
 | 
			
		||||
{{/isDate}}
 | 
			
		||||
{{#isDateTime}}
 | 
			
		||||
     * @DTA\Strategy(name="DateTime")
 | 
			
		||||
     * @DTA\Validator(name="Date", options={"format": \DateTime::RFC3339})
 | 
			
		||||
{{/isDateTime}}
 | 
			
		||||
{{/isListContainer}}
 | 
			
		||||
{{#isListContainer}}
 | 
			
		||||
     * @DTA\Strategy(name="ObjectArray", options={"type":{{#items}}{{datatype}}{{/items}}::class})
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Dictionary", "options":{"type":{{#items}}{{datatype}}{{/items}}::class}}
 | 
			
		||||
     * }})
 | 
			
		||||
{{/isListContainer}}
 | 
			
		||||
{{/isPrimitiveType}}
 | 
			
		||||
{{#isPrimitiveType}}
 | 
			
		||||
{{#isListContainer}}
 | 
			
		||||
{{#items}}
 | 
			
		||||
{{#isString}}
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Type", "options":{"type":"string"}}
 | 
			
		||||
     * }})
 | 
			
		||||
{{/isString}}
 | 
			
		||||
{{#isInteger}}
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Type", "options":{"type":"int"}}
 | 
			
		||||
     * }})
 | 
			
		||||
{{/isInteger}}
 | 
			
		||||
{{#isLong}}
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Type", "options":{"type":"int"}}
 | 
			
		||||
     * }})
 | 
			
		||||
{{/isLong}}
 | 
			
		||||
{{#isBoolean}}
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Type", "options":{"type":"bool"}}
 | 
			
		||||
     * }})
 | 
			
		||||
{{/isBoolean}}
 | 
			
		||||
{{#isFloat}}
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Type", "options":{"type":"float"}}
 | 
			
		||||
     * }})
 | 
			
		||||
{{/isFloat}}
 | 
			
		||||
{{#isDouble}}
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Type", "options":{"type":"float"}}
 | 
			
		||||
     * }})
 | 
			
		||||
{{/isDouble}}
 | 
			
		||||
{{/items}}
 | 
			
		||||
{{/isListContainer}}
 | 
			
		||||
{{^isListContainer}}
 | 
			
		||||
{{#isString}}
 | 
			
		||||
     * @DTA\Validator(name="Type", options={"type":"string"})
 | 
			
		||||
{{/isString}}
 | 
			
		||||
{{#isInteger}}
 | 
			
		||||
     * @DTA\Validator(name="Type", options={"type":"int"})
 | 
			
		||||
{{/isInteger}}
 | 
			
		||||
{{#isLong}}
 | 
			
		||||
     * @DTA\Validator(name="Type", options={"type":"int"})
 | 
			
		||||
{{/isLong}}
 | 
			
		||||
{{#isBoolean}}
 | 
			
		||||
     * @DTA\Validator(name="Type", options={"type":"bool"})
 | 
			
		||||
{{/isBoolean}}
 | 
			
		||||
{{#isFloat}}
 | 
			
		||||
     * @DTA\Validator(name="Type", options={"type":"float"})
 | 
			
		||||
{{/isFloat}}
 | 
			
		||||
{{#isDouble}}
 | 
			
		||||
     * @DTA\Validator(name="Type", options={"type":"float"})
 | 
			
		||||
{{/isDouble}}
 | 
			
		||||
{{/isListContainer}}
 | 
			
		||||
{{/isPrimitiveType}}
 | 
			
		||||
{{#hasValidation}}
 | 
			
		||||
{{#minLength}}
 | 
			
		||||
{{#maxLength}}
 | 
			
		||||
     * @DTA\Validator(name="StringLength", options={"min":{{minLength}}, "max":{{maxLength}}})
 | 
			
		||||
{{/maxLength}}
 | 
			
		||||
{{/minLength}}
 | 
			
		||||
{{^minLength}}
 | 
			
		||||
{{#maxLength}}
 | 
			
		||||
     * @DTA\Validator(name="StringLength", options={"max":{{maxLength}}})
 | 
			
		||||
{{/maxLength}}
 | 
			
		||||
{{/minLength}}
 | 
			
		||||
{{#minLength}}
 | 
			
		||||
{{^maxLength}}
 | 
			
		||||
     * @DTA\Validator(name="StringLength", options={"min":{{minLength}}})
 | 
			
		||||
{{/maxLength}}
 | 
			
		||||
{{/minLength}}
 | 
			
		||||
{{#minimum}}
 | 
			
		||||
     * @DTA\Validator(name="GreaterThan", options={"min":{{minimum}}{{^exclusiveMinimum}}, "inclusive":true{{/exclusiveMinimum}}})
 | 
			
		||||
{{/minimum}}
 | 
			
		||||
{{#maximum}}
 | 
			
		||||
     * @DTA\Validator(name="LessThan", options={"max":{{maximum}}{{^exclusiveMaximum}}, "inclusive":true{{/exclusiveMaximum}}})
 | 
			
		||||
{{/maximum}}
 | 
			
		||||
{{#pattern}}
 | 
			
		||||
     * @DTA\Validator(name="Regex", options={"pattern":"{{{pattern}}}"})
 | 
			
		||||
{{/pattern}}
 | 
			
		||||
{{/hasValidation}}
 | 
			
		||||
     * @var {{datatype}}
 | 
			
		||||
     * @DTA\Data(field="{{baseName}}"{{^required}}, nullable=true{{/required}}){{#vendorExtensions}}{{#internal.ze-ph.fromQuery}}
 | 
			
		||||
{{>model_query_var}}{{/internal.ze-ph.fromQuery}}{{/vendorExtensions}}{{#vendorExtensions}}{{^internal.ze-ph.fromQuery}}
 | 
			
		||||
{{>model_normal_var}}{{/internal.ze-ph.fromQuery}}{{/vendorExtensions}}{{^vendorExtensions}}
 | 
			
		||||
{{>model_normal_var}}{{/vendorExtensions}}     * @var {{datatype}}
 | 
			
		||||
     */
 | 
			
		||||
    public ${{name}};
 | 
			
		||||
{{/vars}}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,64 @@
 | 
			
		||||
{{^isPrimitiveType}}
 | 
			
		||||
{{^isContainer}}
 | 
			
		||||
{{^isDate}}
 | 
			
		||||
{{^isDateTime}}
 | 
			
		||||
     * @DTA\Strategy(name="Object", options={"type":{{datatype}}::class})
 | 
			
		||||
     * @DTA\Validator(name="Dictionary", options={"type":{{datatype}}::class})
 | 
			
		||||
{{/isDateTime}}
 | 
			
		||||
{{/isDate}}
 | 
			
		||||
{{#isDate}}
 | 
			
		||||
     * @DTA\Strategy(name="Date")
 | 
			
		||||
     * @DTA\Validator(name="Date")
 | 
			
		||||
{{/isDate}}
 | 
			
		||||
{{#isDateTime}}
 | 
			
		||||
     * @DTA\Strategy(name="DateTime")
 | 
			
		||||
     * @DTA\Validator(name="Date", options={"format": \DateTime::RFC3339})
 | 
			
		||||
{{/isDateTime}}
 | 
			
		||||
{{/isContainer}}
 | 
			
		||||
{{#isContainer}}
 | 
			
		||||
     * TODO check validator and strategy are correct and can handle container item type
 | 
			
		||||
     * @DTA\Strategy(name="ObjectArray", options={"type":{{#items}}{{datatype}}{{/items}}::class})
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Dictionary", "options":{"type":{{#items}}{{datatype}}{{/items}}::class}}
 | 
			
		||||
     * }})
 | 
			
		||||
{{/isContainer}}
 | 
			
		||||
{{/isPrimitiveType}}
 | 
			
		||||
{{#isPrimitiveType}}
 | 
			
		||||
{{#isContainer}}
 | 
			
		||||
{{#items}}
 | 
			
		||||
     * TODO check validator and strategy are correct and can handle container item type
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Type", "options":{"type":"{{datatype}}"}}
 | 
			
		||||
     * }})
 | 
			
		||||
{{/items}}
 | 
			
		||||
{{/isContainer}}
 | 
			
		||||
{{^isContainer}}
 | 
			
		||||
     * @DTA\Validator(name="Type", options={"type":"{{datatype}}"})
 | 
			
		||||
{{/isContainer}}
 | 
			
		||||
{{/isPrimitiveType}}
 | 
			
		||||
{{#hasValidation}}
 | 
			
		||||
{{#minLength}}
 | 
			
		||||
{{#maxLength}}
 | 
			
		||||
     * @DTA\Validator(name="StringLength", options={"min":{{minLength}}, "max":{{maxLength}}})
 | 
			
		||||
{{/maxLength}}
 | 
			
		||||
{{/minLength}}
 | 
			
		||||
{{^minLength}}
 | 
			
		||||
{{#maxLength}}
 | 
			
		||||
     * @DTA\Validator(name="StringLength", options={"max":{{maxLength}}})
 | 
			
		||||
{{/maxLength}}
 | 
			
		||||
{{/minLength}}
 | 
			
		||||
{{#minLength}}
 | 
			
		||||
{{^maxLength}}
 | 
			
		||||
     * @DTA\Validator(name="StringLength", options={"min":{{minLength}}})
 | 
			
		||||
{{/maxLength}}
 | 
			
		||||
{{/minLength}}
 | 
			
		||||
{{#minimum}}
 | 
			
		||||
     * @DTA\Validator(name="GreaterThan", options={"min":{{minimum}}{{^exclusiveMinimum}}, "inclusive":true{{/exclusiveMinimum}}})
 | 
			
		||||
{{/minimum}}
 | 
			
		||||
{{#maximum}}
 | 
			
		||||
     * @DTA\Validator(name="LessThan", options={"max":{{maximum}}{{^exclusiveMaximum}}, "inclusive":true{{/exclusiveMaximum}}})
 | 
			
		||||
{{/maximum}}
 | 
			
		||||
{{#pattern}}
 | 
			
		||||
     * @DTA\Validator(name="Regex", options={"pattern":"{{{pattern}}}"})
 | 
			
		||||
{{/pattern}}
 | 
			
		||||
{{/hasValidation}}
 | 
			
		||||
@ -0,0 +1,54 @@
 | 
			
		||||
{{^isPrimitiveType}}
 | 
			
		||||
{{^isContainer}}
 | 
			
		||||
{{#isDate}}
 | 
			
		||||
     * @DTA\Strategy(name="Date")
 | 
			
		||||
     * @DTA\Validator(name="Date")
 | 
			
		||||
{{/isDate}}
 | 
			
		||||
{{#isDateTime}}
 | 
			
		||||
     * @DTA\Strategy(name="DateTime")
 | 
			
		||||
     * @DTA\Validator(name="Date", options={"format": \DateTime::RFC3339})
 | 
			
		||||
{{/isDateTime}}
 | 
			
		||||
{{/isContainer}}
 | 
			
		||||
{{#isContainer}}
 | 
			
		||||
     * TODO add validator(s) and strategy for {{datatype}} and collection format {{internal.ze-ph.collectionFormat}}
 | 
			
		||||
{{/isContainer}}
 | 
			
		||||
{{/isPrimitiveType}}
 | 
			
		||||
{{#isPrimitiveType}}
 | 
			
		||||
{{#isContainer}}
 | 
			
		||||
{{#items}}
 | 
			
		||||
     * TODO check validator and strategy are correct and can handle container item type
 | 
			
		||||
     * @DTA\Strategy(name="QueryParameterArray", options={"type":"{{datatype}}", "format":"{{internal.ze-ph.collectionFormat}}"})
 | 
			
		||||
     * @DTA\Validator(name="QueryParameterArrayType", options={"type":"{{datatype}}", "format":"{{internal.ze-ph.collectionFormat}}"})
 | 
			
		||||
{{/items}}
 | 
			
		||||
{{/isContainer}}
 | 
			
		||||
{{^isContainer}}
 | 
			
		||||
     * @DTA\Strategy(name="QueryParameter", options={"type":"{{datatype}}"})
 | 
			
		||||
     * @DTA\Validator(name="QueryParameterType", options={"type":"{{datatype}}"})
 | 
			
		||||
{{/isContainer}}
 | 
			
		||||
{{/isPrimitiveType}}
 | 
			
		||||
{{#hasValidation}}
 | 
			
		||||
{{#minLength}}
 | 
			
		||||
{{#maxLength}}
 | 
			
		||||
     * @DTA\Validator(name="StringLength", options={"min":{{minLength}}, "max":{{maxLength}}})
 | 
			
		||||
{{/maxLength}}
 | 
			
		||||
{{/minLength}}
 | 
			
		||||
{{^minLength}}
 | 
			
		||||
{{#maxLength}}
 | 
			
		||||
     * @DTA\Validator(name="StringLength", options={"max":{{maxLength}}})
 | 
			
		||||
{{/maxLength}}
 | 
			
		||||
{{/minLength}}
 | 
			
		||||
{{#minLength}}
 | 
			
		||||
{{^maxLength}}
 | 
			
		||||
     * @DTA\Validator(name="StringLength", options={"min":{{minLength}}})
 | 
			
		||||
{{/maxLength}}
 | 
			
		||||
{{/minLength}}
 | 
			
		||||
{{#minimum}}
 | 
			
		||||
     * @DTA\Validator(name="GreaterThan", options={"min":{{minimum}}{{^exclusiveMinimum}}, "inclusive":true{{/exclusiveMinimum}}})
 | 
			
		||||
{{/minimum}}
 | 
			
		||||
{{#maximum}}
 | 
			
		||||
     * @DTA\Validator(name="LessThan", options={"max":{{maximum}}{{^exclusiveMaximum}}, "inclusive":true{{/exclusiveMaximum}}})
 | 
			
		||||
{{/maximum}}
 | 
			
		||||
{{#pattern}}
 | 
			
		||||
     * @DTA\Validator(name="Regex", options={"pattern":"{{{pattern}}}"})
 | 
			
		||||
{{/pattern}}
 | 
			
		||||
{{/hasValidation}}
 | 
			
		||||
@ -1,27 +1,42 @@
 | 
			
		||||
path_handler:
 | 
			
		||||
  routes:
 | 
			
		||||
    routes:
 | 
			
		||||
{{#routes}}{{>route}}{{/routes}}
 | 
			
		||||
    default_params:
 | 
			
		||||
      middleware: ''
 | 
			
		||||
dependencies:
 | 
			
		||||
  factories:
 | 
			
		||||
    Zend\Expressive\Router\RouterInterface: Articus\PathHandler\Router\Factory\FastRouteAnnotation
 | 
			
		||||
 | 
			
		||||
Articus\PathHandler\Middleware:
 | 
			
		||||
  metadata_cache:
 | 
			
		||||
    adapter:
 | 
			
		||||
      name: blackhole
 | 
			
		||||
  handlers:
 | 
			
		||||
    abstract_factories:
 | 
			
		||||
      - Zend\ServiceManager\AbstractFactory\ConfigAbstractFactory
 | 
			
		||||
#  consumers:
 | 
			
		||||
#    factories:
 | 
			
		||||
#    invokables:
 | 
			
		||||
#  attributes:
 | 
			
		||||
#    factories:
 | 
			
		||||
#    invokables:
 | 
			
		||||
#  producers:
 | 
			
		||||
#    factories:
 | 
			
		||||
#    invokables:
 | 
			
		||||
 | 
			
		||||
Articus\PathHandler\Router\FastRouteAnnotation:
 | 
			
		||||
  metadata_cache:
 | 
			
		||||
    adapter:
 | 
			
		||||
      name: blackhole
 | 
			
		||||
#    adapter:
 | 
			
		||||
#      name: filesystem
 | 
			
		||||
#      options:
 | 
			
		||||
#        cache_dir: data/cache/path_handler
 | 
			
		||||
#        namespace: ph
 | 
			
		||||
 | 
			
		||||
  handlers:
 | 
			
		||||
    invokables:
 | 
			
		||||
{{#apiInfo}}
 | 
			
		||||
{{#apis}}
 | 
			
		||||
{{#operations}}
 | 
			
		||||
      {{classname}}: {{package}}\{{classname}}
 | 
			
		||||
    - {{package}}\{{classname}}
 | 
			
		||||
{{/operations}}
 | 
			
		||||
{{/apis}}
 | 
			
		||||
{{/apiInfo}}
 | 
			
		||||
 | 
			
		||||
Zend\ServiceManager\AbstractFactory\ConfigAbstractFactory:
 | 
			
		||||
{{#apiInfo}}
 | 
			
		||||
{{#apis}}
 | 
			
		||||
{{#operations}}
 | 
			
		||||
  {{package}}\{{classname}}: []
 | 
			
		||||
{{/operations}}
 | 
			
		||||
{{/apis}}
 | 
			
		||||
{{/apiInfo}}
 | 
			
		||||
#  consumers:
 | 
			
		||||
#  attributes:
 | 
			
		||||
#  producers:
 | 
			
		||||
 | 
			
		||||
@ -1,15 +0,0 @@
 | 
			
		||||
      {{padding}}'{{name}}':
 | 
			
		||||
      {{padding}}  type: {{type}}
 | 
			
		||||
      {{padding}}  options:
 | 
			
		||||
      {{padding}}    route: {{route}}
 | 
			
		||||
{{#handler}}
 | 
			
		||||
      {{padding}}    defaults:
 | 
			
		||||
      {{padding}}      handler: {{handler}}
 | 
			
		||||
{{/handler}}
 | 
			
		||||
{{#hasChildren}}
 | 
			
		||||
{{#handler}}
 | 
			
		||||
      {{padding}}  may_terminate: true
 | 
			
		||||
{{/handler}}
 | 
			
		||||
      {{padding}}  child_routes:
 | 
			
		||||
{{/hasChildren}}
 | 
			
		||||
{{#children}}{{>route}}{{/children}}
 | 
			
		||||
@ -1 +1 @@
 | 
			
		||||
2.3.0-SNAPSHOT
 | 
			
		||||
2.4.0-SNAPSHOT
 | 
			
		||||
@ -1,10 +1,34 @@
 | 
			
		||||
# Swagger generated server
 | 
			
		||||
 | 
			
		||||
Generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project.
 | 
			
		||||
 | 
			
		||||
## Overview
 | 
			
		||||
This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the
 | 
			
		||||
[OpenAPI-Spec](https://github.com/swagger-api/swagger-core/wiki) from a remote server, you can easily generate a server stub. This
 | 
			
		||||
is an example of building a PHP server.
 | 
			
		||||
This server stub aims to provide light, yet comprehensive structure for your API project using:
 | 
			
		||||
 | 
			
		||||
This example uses the [Zend Expressive](https://zendframework.github.io/zend-expressive) micro framework and [Path Handler](https://github.com/Articus/PathHandler) library. To see how to make this your own, please take a look at the template here:
 | 
			
		||||
- PHP: 5.6 or 7.*
 | 
			
		||||
- [Zend Expressive](https://zendframework.github.io/zend-expressive): 2.1
 | 
			
		||||
- [Path Handler](https://github.com/Articus/PathHandler): 0.3
 | 
			
		||||
 | 
			
		||||
[TEMPLATES](https://github.com/swagger-api/swagger-codegen/tree/master/modules/swagger-codegen/src/main/resources/ze-ph/)
 | 
			
		||||
## How to use
 | 
			
		||||
All you have to do to start development is:
 | 
			
		||||
 | 
			
		||||
- install dependencies via [Composer](https://getcomposer.org/)
 | 
			
		||||
- create cache folder: `mkdir -p ./data/cache/ZendCache` (you will need it later for configuration and metadata caches - check comments in `./application/conig.yml`)
 | 
			
		||||
- start PHP development server: `php -S 0.0.0.0:8080 -t ./public` (or any other SAPI you prefer, just make sure that you configure webroot to `./public` and rewrites to `./public/index.php`)
 | 
			
		||||
 | 
			
		||||
After that you should be able to call all methods from your API spec. Most of the negative scenarios should be handled:
 | 
			
		||||
 | 
			
		||||
- `404 Not found` for unknown routes
 | 
			
		||||
- `406 Not acceptable` for invalid `Accept` header
 | 
			
		||||
- `415 Unsupported media type` for invalid `Content-Type` header
 | 
			
		||||
- `400 Malformed JSON` for unparsable JSON body
 | 
			
		||||
- `422 Unprocessable entity` for parsable JSON body that fails validation
 | 
			
		||||
 | 
			
		||||
But for obvious reason you will not get any `200 OK`, only `500 Not implemented`. So your next steps are:
 | 
			
		||||
 | 
			
		||||
- check all TODOs left in the stub code where generator was not smart enough and could not guarantee correct implementation
 | 
			
		||||
- implement your API security mechanism (either special attribute or separate middleware) - generator does not do anything about it yet
 | 
			
		||||
- implement your handlers - the most tricky part :)
 | 
			
		||||
 | 
			
		||||
## Enjoy!
 | 
			
		||||
Hopefully this stub will reduce the amount of boilerplate code you have to write manually. If you have any suggestions or questions about `ze-ph` generator, feel free to create issue either in [Path Handler repository](https://github.com/Articus/PathHandler/issues) or in [Swagger Codegen repository](https://github.com/swagger-api/swagger-codegen/issues).
 | 
			
		||||
 | 
			
		||||
@ -1,3 +1,41 @@
 | 
			
		||||
#App
 | 
			
		||||
cache_configuration: false
 | 
			
		||||
debug: true
 | 
			
		||||
#Empty configuration placeholder, remove when you add any real configuration settings to this file
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
#Enable configuration cache
 | 
			
		||||
#cache_configuration: true
 | 
			
		||||
 | 
			
		||||
#Enable routing cache for handlers
 | 
			
		||||
#Articus\PathHandler\Router\FastRouteAnnotation:
 | 
			
		||||
#  metadata_cache:
 | 
			
		||||
#    adapter:
 | 
			
		||||
#      name: filesystem
 | 
			
		||||
#      options:
 | 
			
		||||
#        cache_dir: data/cache/ZendCache
 | 
			
		||||
#        namespace: fast-route
 | 
			
		||||
#    plugins:
 | 
			
		||||
#      serializer:
 | 
			
		||||
#        serializer: phpserialize
 | 
			
		||||
 | 
			
		||||
#Enable consumer, attribute and producer cache for handlers
 | 
			
		||||
#Articus\PathHandler\Middleware:
 | 
			
		||||
#  metadata_cache:
 | 
			
		||||
#    adapter:
 | 
			
		||||
#      name: filesystem
 | 
			
		||||
#      options:
 | 
			
		||||
#        cache_dir: data/cache/ZendCache
 | 
			
		||||
#        namespace: path-handler
 | 
			
		||||
#    plugins:
 | 
			
		||||
#      serializer:
 | 
			
		||||
#        serializer: phpserialize
 | 
			
		||||
 | 
			
		||||
#Enable data transfer metadata cache for DTOs
 | 
			
		||||
#data_transfer:
 | 
			
		||||
#  metadata_cache:
 | 
			
		||||
#    adapter:
 | 
			
		||||
#      name: filesystem
 | 
			
		||||
#      options:
 | 
			
		||||
#        cache_dir: data/cache/ZendCache
 | 
			
		||||
#        namespace: data-transfer
 | 
			
		||||
#    plugins:
 | 
			
		||||
#      serializer:
 | 
			
		||||
#        serializer: phpserialize
 | 
			
		||||
 | 
			
		||||
@ -1,26 +1,14 @@
 | 
			
		||||
dependencies:
 | 
			
		||||
  invokables:
 | 
			
		||||
    #Has to add this line because currently router is strict requirement for Zend\Expressive\Application even if only middleware_pipeline is used
 | 
			
		||||
    Zend\Expressive\Router\RouterInterface: Zend\Expressive\Router\ZendRouter
 | 
			
		||||
    Zend\Diactoros\Response\EmitterInterface: Zend\Diactoros\Response\SapiStreamEmitter
 | 
			
		||||
    App\ErrorMiddleware: App\ErrorMiddleware
 | 
			
		||||
  factories:
 | 
			
		||||
    Zend\Expressive\Application: Zend\Expressive\Container\ApplicationFactory
 | 
			
		||||
    Articus\PathHandler\Middleware: Articus\PathHandler\MiddlewareFactory
 | 
			
		||||
    Articus\DataTransfer\Service: Articus\DataTransfer\ServiceFactory
 | 
			
		||||
    Zend\Stratigility\Middleware\ErrorHandler: Zend\Expressive\Container\ErrorHandlerFactory
 | 
			
		||||
    Zend\Expressive\Middleware\ErrorResponseGenerator: Zend\Expressive\Container\WhoopsErrorResponseGeneratorFactory
 | 
			
		||||
    Zend\Expressive\Whoops: Zend\Expressive\Container\WhoopsFactory
 | 
			
		||||
    Zend\Expressive\WhoopsPageHandler: Zend\Expressive\Container\WhoopsPageHandlerFactory
 | 
			
		||||
 | 
			
		||||
middleware_pipeline:
 | 
			
		||||
  error:
 | 
			
		||||
    middleware: Zend\Stratigility\Middleware\ErrorHandler
 | 
			
		||||
    middleware: App\ErrorMiddleware
 | 
			
		||||
  api:
 | 
			
		||||
    middleware: Articus\PathHandler\Middleware
 | 
			
		||||
    path: /v2
 | 
			
		||||
 | 
			
		||||
whoops:
 | 
			
		||||
  json_exceptions:
 | 
			
		||||
    display: true
 | 
			
		||||
    show_trace: true
 | 
			
		||||
    ajax_only: true
 | 
			
		||||
 | 
			
		||||
@ -1,24 +1,28 @@
 | 
			
		||||
dependencies:
 | 
			
		||||
  factories:
 | 
			
		||||
    Articus\DataTransfer\Service: Articus\DataTransfer\ServiceFactory
 | 
			
		||||
 | 
			
		||||
data_transfer:
 | 
			
		||||
  metadata_cache:
 | 
			
		||||
    adapter:
 | 
			
		||||
      name: blackhole
 | 
			
		||||
#    adapter:
 | 
			
		||||
#      name: filesystem
 | 
			
		||||
#      options:
 | 
			
		||||
#        cache_dir: data/cache/data_transfer
 | 
			
		||||
#        namespace: dt
 | 
			
		||||
 | 
			
		||||
  strategies:
 | 
			
		||||
    invokables:
 | 
			
		||||
      App\Strategy\Date: App\Strategy\Date
 | 
			
		||||
      App\Strategy\DateTime: App\Strategy\DateTime
 | 
			
		||||
      App\Strategy\QueryParameter: App\Strategy\QueryParameter
 | 
			
		||||
      App\Strategy\QueryParameterArray: App\Strategy\QueryParameterArray
 | 
			
		||||
#    factories:
 | 
			
		||||
    aliases:
 | 
			
		||||
      Date: App\Strategy\Date
 | 
			
		||||
      DateTime: App\Strategy\DateTime
 | 
			
		||||
      QueryParameter: App\Strategy\QueryParameter
 | 
			
		||||
      QueryParameterArray: App\Strategy\QueryParameterArray
 | 
			
		||||
  validators:
 | 
			
		||||
    invokables:
 | 
			
		||||
      App\Validator\Type: App\Validator\Type
 | 
			
		||||
      App\Validator\QueryParameterType: App\Validator\QueryParameterType
 | 
			
		||||
      App\Validator\QueryParameterArrayType: App\Validator\QueryParameterArrayType
 | 
			
		||||
    factories:
 | 
			
		||||
      Articus\DataTransfer\Validator\Dictionary: Articus\DataTransfer\Validator\Factory
 | 
			
		||||
      Articus\DataTransfer\Validator\Collection: Articus\DataTransfer\Validator\Factory
 | 
			
		||||
@ -26,3 +30,5 @@ data_transfer:
 | 
			
		||||
      Dictionary: Articus\DataTransfer\Validator\Dictionary
 | 
			
		||||
      Collection: Articus\DataTransfer\Validator\Collection
 | 
			
		||||
      Type: App\Validator\Type
 | 
			
		||||
      QueryParameterType: App\Validator\QueryParameterType
 | 
			
		||||
      QueryParameterArrayType: App\Validator\QueryParameterArrayType
 | 
			
		||||
 | 
			
		||||
@ -1,187 +1,74 @@
 | 
			
		||||
path_handler:
 | 
			
		||||
  routes:
 | 
			
		||||
    routes:
 | 
			
		||||
      'fake':
 | 
			
		||||
        type: Literal
 | 
			
		||||
        options:
 | 
			
		||||
          route: /fake
 | 
			
		||||
          defaults:
 | 
			
		||||
            handler: Fake
 | 
			
		||||
        may_terminate: true
 | 
			
		||||
        child_routes:
 | 
			
		||||
          'jsonFormData':
 | 
			
		||||
            type: Literal
 | 
			
		||||
            options:
 | 
			
		||||
              route: /jsonFormData
 | 
			
		||||
              defaults:
 | 
			
		||||
                handler: FakeJsonFormData
 | 
			
		||||
          'outer':
 | 
			
		||||
            type: Literal
 | 
			
		||||
            options:
 | 
			
		||||
              route: /outer
 | 
			
		||||
            child_routes:
 | 
			
		||||
              'boolean':
 | 
			
		||||
                type: Literal
 | 
			
		||||
                options:
 | 
			
		||||
                  route: /boolean
 | 
			
		||||
                  defaults:
 | 
			
		||||
                    handler: FakeOuterBoolean
 | 
			
		||||
              'composite':
 | 
			
		||||
                type: Literal
 | 
			
		||||
                options:
 | 
			
		||||
                  route: /composite
 | 
			
		||||
                  defaults:
 | 
			
		||||
                    handler: FakeOuterComposite
 | 
			
		||||
              'number':
 | 
			
		||||
                type: Literal
 | 
			
		||||
                options:
 | 
			
		||||
                  route: /number
 | 
			
		||||
                  defaults:
 | 
			
		||||
                    handler: FakeOuterNumber
 | 
			
		||||
              'string':
 | 
			
		||||
                type: Literal
 | 
			
		||||
                options:
 | 
			
		||||
                  route: /string
 | 
			
		||||
                  defaults:
 | 
			
		||||
                    handler: FakeOuterString
 | 
			
		||||
      'fake_classname_test':
 | 
			
		||||
        type: Literal
 | 
			
		||||
        options:
 | 
			
		||||
          route: /fake_classname_test
 | 
			
		||||
          defaults:
 | 
			
		||||
            handler: FakeClassnameTest
 | 
			
		||||
      'pet':
 | 
			
		||||
        type: Literal
 | 
			
		||||
        options:
 | 
			
		||||
          route: /pet
 | 
			
		||||
          defaults:
 | 
			
		||||
            handler: Pet
 | 
			
		||||
        may_terminate: true
 | 
			
		||||
        child_routes:
 | 
			
		||||
          'findByStatus':
 | 
			
		||||
            type: Literal
 | 
			
		||||
            options:
 | 
			
		||||
              route: /findByStatus
 | 
			
		||||
              defaults:
 | 
			
		||||
                handler: PetFindByStatus
 | 
			
		||||
          'findByTags':
 | 
			
		||||
            type: Literal
 | 
			
		||||
            options:
 | 
			
		||||
              route: /findByTags
 | 
			
		||||
              defaults:
 | 
			
		||||
                handler: PetFindByTags
 | 
			
		||||
          '{petId}':
 | 
			
		||||
            type: Segment
 | 
			
		||||
            options:
 | 
			
		||||
              route: /:petId
 | 
			
		||||
              defaults:
 | 
			
		||||
                handler: PetPetId
 | 
			
		||||
            may_terminate: true
 | 
			
		||||
            child_routes:
 | 
			
		||||
              'uploadImage':
 | 
			
		||||
                type: Literal
 | 
			
		||||
                options:
 | 
			
		||||
                  route: /uploadImage
 | 
			
		||||
                  defaults:
 | 
			
		||||
                    handler: PetPetIdUploadImage
 | 
			
		||||
      'store':
 | 
			
		||||
        type: Literal
 | 
			
		||||
        options:
 | 
			
		||||
          route: /store
 | 
			
		||||
        child_routes:
 | 
			
		||||
          'inventory':
 | 
			
		||||
            type: Literal
 | 
			
		||||
            options:
 | 
			
		||||
              route: /inventory
 | 
			
		||||
              defaults:
 | 
			
		||||
                handler: StoreInventory
 | 
			
		||||
          'order':
 | 
			
		||||
            type: Literal
 | 
			
		||||
            options:
 | 
			
		||||
              route: /order
 | 
			
		||||
              defaults:
 | 
			
		||||
                handler: StoreOrder
 | 
			
		||||
            may_terminate: true
 | 
			
		||||
            child_routes:
 | 
			
		||||
              '{order_id}':
 | 
			
		||||
                type: Segment
 | 
			
		||||
                options:
 | 
			
		||||
                  route: /:order_id
 | 
			
		||||
                  defaults:
 | 
			
		||||
                    handler: StoreOrderOrderId
 | 
			
		||||
      'user':
 | 
			
		||||
        type: Literal
 | 
			
		||||
        options:
 | 
			
		||||
          route: /user
 | 
			
		||||
          defaults:
 | 
			
		||||
            handler: User
 | 
			
		||||
        may_terminate: true
 | 
			
		||||
        child_routes:
 | 
			
		||||
          'createWithArray':
 | 
			
		||||
            type: Literal
 | 
			
		||||
            options:
 | 
			
		||||
              route: /createWithArray
 | 
			
		||||
              defaults:
 | 
			
		||||
                handler: UserCreateWithArray
 | 
			
		||||
          'createWithList':
 | 
			
		||||
            type: Literal
 | 
			
		||||
            options:
 | 
			
		||||
              route: /createWithList
 | 
			
		||||
              defaults:
 | 
			
		||||
                handler: UserCreateWithList
 | 
			
		||||
          'login':
 | 
			
		||||
            type: Literal
 | 
			
		||||
            options:
 | 
			
		||||
              route: /login
 | 
			
		||||
              defaults:
 | 
			
		||||
                handler: UserLogin
 | 
			
		||||
          'logout':
 | 
			
		||||
            type: Literal
 | 
			
		||||
            options:
 | 
			
		||||
              route: /logout
 | 
			
		||||
              defaults:
 | 
			
		||||
                handler: UserLogout
 | 
			
		||||
          '{username}':
 | 
			
		||||
            type: Segment
 | 
			
		||||
            options:
 | 
			
		||||
              route: /:username
 | 
			
		||||
              defaults:
 | 
			
		||||
                handler: UserUsername
 | 
			
		||||
dependencies:
 | 
			
		||||
  factories:
 | 
			
		||||
    Zend\Expressive\Router\RouterInterface: Articus\PathHandler\Router\Factory\FastRouteAnnotation
 | 
			
		||||
 | 
			
		||||
    default_params:
 | 
			
		||||
      middleware: ''
 | 
			
		||||
Articus\PathHandler\Middleware:
 | 
			
		||||
  metadata_cache:
 | 
			
		||||
    adapter:
 | 
			
		||||
      name: blackhole
 | 
			
		||||
#    adapter:
 | 
			
		||||
#      name: filesystem
 | 
			
		||||
#      options:
 | 
			
		||||
#        cache_dir: data/cache/path_handler
 | 
			
		||||
#        namespace: ph
 | 
			
		||||
 | 
			
		||||
  handlers:
 | 
			
		||||
    invokables:
 | 
			
		||||
      Fake: App\Handler\Fake
 | 
			
		||||
      FakeJsonFormData: App\Handler\FakeJsonFormData
 | 
			
		||||
      FakeOuterBoolean: App\Handler\FakeOuterBoolean
 | 
			
		||||
      FakeOuterComposite: App\Handler\FakeOuterComposite
 | 
			
		||||
      FakeOuterNumber: App\Handler\FakeOuterNumber
 | 
			
		||||
      FakeOuterString: App\Handler\FakeOuterString
 | 
			
		||||
      FakeClassnameTest: App\Handler\FakeClassnameTest
 | 
			
		||||
      Pet: App\Handler\Pet
 | 
			
		||||
      PetFindByStatus: App\Handler\PetFindByStatus
 | 
			
		||||
      PetFindByTags: App\Handler\PetFindByTags
 | 
			
		||||
      PetPetId: App\Handler\PetPetId
 | 
			
		||||
      PetPetIdUploadImage: App\Handler\PetPetIdUploadImage
 | 
			
		||||
      StoreInventory: App\Handler\StoreInventory
 | 
			
		||||
      StoreOrder: App\Handler\StoreOrder
 | 
			
		||||
      StoreOrderOrderId: App\Handler\StoreOrderOrderId
 | 
			
		||||
      User: App\Handler\User
 | 
			
		||||
      UserCreateWithArray: App\Handler\UserCreateWithArray
 | 
			
		||||
      UserCreateWithList: App\Handler\UserCreateWithList
 | 
			
		||||
      UserLogin: App\Handler\UserLogin
 | 
			
		||||
      UserLogout: App\Handler\UserLogout
 | 
			
		||||
      UserUsername: App\Handler\UserUsername
 | 
			
		||||
    abstract_factories:
 | 
			
		||||
      - Zend\ServiceManager\AbstractFactory\ConfigAbstractFactory
 | 
			
		||||
#  consumers:
 | 
			
		||||
#    factories:
 | 
			
		||||
#    invokables:
 | 
			
		||||
#  attributes:
 | 
			
		||||
#    factories:
 | 
			
		||||
#    invokables:
 | 
			
		||||
#  producers:
 | 
			
		||||
#    factories:
 | 
			
		||||
#    invokables:
 | 
			
		||||
 | 
			
		||||
Articus\PathHandler\Router\FastRouteAnnotation:
 | 
			
		||||
  metadata_cache:
 | 
			
		||||
    adapter:
 | 
			
		||||
      name: blackhole
 | 
			
		||||
  handlers:
 | 
			
		||||
    - App\Handler\AnotherFakeDummy
 | 
			
		||||
    - App\Handler\Fake
 | 
			
		||||
    - App\Handler\FakeInlineAdditionalProperties
 | 
			
		||||
    - App\Handler\FakeJsonFormData
 | 
			
		||||
    - App\Handler\FakeOuterBoolean
 | 
			
		||||
    - App\Handler\FakeOuterComposite
 | 
			
		||||
    - App\Handler\FakeOuterNumber
 | 
			
		||||
    - App\Handler\FakeOuterString
 | 
			
		||||
    - App\Handler\FakeClassnameTest
 | 
			
		||||
    - App\Handler\Pet
 | 
			
		||||
    - App\Handler\PetFindByStatus
 | 
			
		||||
    - App\Handler\PetFindByTags
 | 
			
		||||
    - App\Handler\PetPetId
 | 
			
		||||
    - App\Handler\PetPetIdUploadImage
 | 
			
		||||
    - App\Handler\StoreInventory
 | 
			
		||||
    - App\Handler\StoreOrder
 | 
			
		||||
    - App\Handler\StoreOrderOrderId
 | 
			
		||||
    - App\Handler\User
 | 
			
		||||
    - App\Handler\UserCreateWithArray
 | 
			
		||||
    - App\Handler\UserCreateWithList
 | 
			
		||||
    - App\Handler\UserLogin
 | 
			
		||||
    - App\Handler\UserLogout
 | 
			
		||||
    - App\Handler\UserUsername
 | 
			
		||||
 | 
			
		||||
Zend\ServiceManager\AbstractFactory\ConfigAbstractFactory:
 | 
			
		||||
  App\Handler\AnotherFakeDummy: []
 | 
			
		||||
  App\Handler\Fake: []
 | 
			
		||||
  App\Handler\FakeInlineAdditionalProperties: []
 | 
			
		||||
  App\Handler\FakeJsonFormData: []
 | 
			
		||||
  App\Handler\FakeOuterBoolean: []
 | 
			
		||||
  App\Handler\FakeOuterComposite: []
 | 
			
		||||
  App\Handler\FakeOuterNumber: []
 | 
			
		||||
  App\Handler\FakeOuterString: []
 | 
			
		||||
  App\Handler\FakeClassnameTest: []
 | 
			
		||||
  App\Handler\Pet: []
 | 
			
		||||
  App\Handler\PetFindByStatus: []
 | 
			
		||||
  App\Handler\PetFindByTags: []
 | 
			
		||||
  App\Handler\PetPetId: []
 | 
			
		||||
  App\Handler\PetPetIdUploadImage: []
 | 
			
		||||
  App\Handler\StoreInventory: []
 | 
			
		||||
  App\Handler\StoreOrder: []
 | 
			
		||||
  App\Handler\StoreOrderOrderId: []
 | 
			
		||||
  App\Handler\User: []
 | 
			
		||||
  App\Handler\UserCreateWithArray: []
 | 
			
		||||
  App\Handler\UserCreateWithList: []
 | 
			
		||||
  App\Handler\UserLogin: []
 | 
			
		||||
  App\Handler\UserLogout: []
 | 
			
		||||
  App\Handler\UserUsername: []
 | 
			
		||||
 | 
			
		||||
@ -7,18 +7,17 @@
 | 
			
		||||
    "require": {
 | 
			
		||||
        "php": "^5.6 || ^7.0",
 | 
			
		||||
        "ext-yaml" : "^1.2 || ^2.0",
 | 
			
		||||
        "zendframework/zend-expressive": "^2.0",
 | 
			
		||||
        "zendframework/zend-expressive-router": "^2.1",
 | 
			
		||||
        "zendframework/zend-expressive-zendrouter": "^2.0",
 | 
			
		||||
        "articus/path-handler": "0.2.*",
 | 
			
		||||
        "articus/data-transfer": "*",
 | 
			
		||||
        "zendframework/zend-serializer": "*",
 | 
			
		||||
        "zendframework/zend-config": "*",
 | 
			
		||||
        "filp/whoops": "^2.1.7"
 | 
			
		||||
        "zendframework/zend-expressive": "^2.1",
 | 
			
		||||
        "articus/path-handler": "^0.3",
 | 
			
		||||
        "articus/data-transfer": "^0.1",
 | 
			
		||||
        "zendframework/zend-serializer": "^2.8",
 | 
			
		||||
        "zendframework/zend-config": "^3.1",
 | 
			
		||||
        "nikic/fast-route": "^1.2",
 | 
			
		||||
        "http-interop/http-middleware": "^0.4.1"
 | 
			
		||||
    },
 | 
			
		||||
    "autoload": {
 | 
			
		||||
        "psr-4": {
 | 
			
		||||
            "": "src/"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -10,13 +10,20 @@ class AdditionalPropertiesClass
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @DTA\Data(field="map_property", nullable=true)
 | 
			
		||||
     * TODO check validator and strategy are correct and can handle container item type
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Type", "options":{"type":"string"}}
 | 
			
		||||
     * }})
 | 
			
		||||
     * @var map[string,string]
 | 
			
		||||
     */
 | 
			
		||||
    public $map_property;
 | 
			
		||||
    /**
 | 
			
		||||
     * @DTA\Data(field="map_of_map_property", nullable=true)
 | 
			
		||||
     * @DTA\Strategy(name="Object", options={"type":map[string,map[string,string]]::class})
 | 
			
		||||
     * @DTA\Validator(name="Dictionary", options={"type":map[string,map[string,string]]::class})
 | 
			
		||||
     * TODO check validator and strategy are correct and can handle container item type
 | 
			
		||||
     * @DTA\Strategy(name="ObjectArray", options={"type":map[string,string]::class})
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Dictionary", "options":{"type":map[string,string]::class}}
 | 
			
		||||
     * }})
 | 
			
		||||
     * @var map[string,map[string,string]]
 | 
			
		||||
     */
 | 
			
		||||
    public $map_of_map_property;
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@ class ArrayOfArrayOfNumberOnly
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @DTA\Data(field="ArrayArrayNumber", nullable=true)
 | 
			
		||||
     * TODO check validator and strategy are correct and can handle container item type
 | 
			
		||||
     * @DTA\Strategy(name="ObjectArray", options={"type":float[]::class})
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Dictionary", "options":{"type":float[]::class}}
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@ class ArrayOfNumberOnly
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @DTA\Data(field="ArrayNumber", nullable=true)
 | 
			
		||||
     * TODO check validator and strategy are correct and can handle container item type
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Type", "options":{"type":"float"}}
 | 
			
		||||
     * }})
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@ class ArrayTest
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @DTA\Data(field="array_of_string", nullable=true)
 | 
			
		||||
     * TODO check validator and strategy are correct and can handle container item type
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Type", "options":{"type":"string"}}
 | 
			
		||||
     * }})
 | 
			
		||||
@ -18,6 +19,7 @@ class ArrayTest
 | 
			
		||||
    public $array_of_string;
 | 
			
		||||
    /**
 | 
			
		||||
     * @DTA\Data(field="array_array_of_integer", nullable=true)
 | 
			
		||||
     * TODO check validator and strategy are correct and can handle container item type
 | 
			
		||||
     * @DTA\Strategy(name="ObjectArray", options={"type":int[]::class})
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Dictionary", "options":{"type":int[]::class}}
 | 
			
		||||
@ -27,6 +29,7 @@ class ArrayTest
 | 
			
		||||
    public $array_array_of_integer;
 | 
			
		||||
    /**
 | 
			
		||||
     * @DTA\Data(field="array_array_of_model", nullable=true)
 | 
			
		||||
     * TODO check validator and strategy are correct and can handle container item type
 | 
			
		||||
     * @DTA\Strategy(name="ObjectArray", options={"type":\App\DTO\ReadOnlyFirst[]::class})
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Dictionary", "options":{"type":\App\DTO\ReadOnlyFirst[]::class}}
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@ class EnumArrays
 | 
			
		||||
    public $just_symbol;
 | 
			
		||||
    /**
 | 
			
		||||
     * @DTA\Data(field="array_enum", nullable=true)
 | 
			
		||||
     * TODO check validator and strategy are correct and can handle container item type
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Type", "options":{"type":"string"}}
 | 
			
		||||
     * }})
 | 
			
		||||
 | 
			
		||||
@ -23,7 +23,7 @@ class EnumTest
 | 
			
		||||
    /**
 | 
			
		||||
     * @DTA\Data(field="enum_number", nullable=true)
 | 
			
		||||
     * @DTA\Validator(name="Type", options={"type":"float"})
 | 
			
		||||
     * @var double
 | 
			
		||||
     * @var float
 | 
			
		||||
     */
 | 
			
		||||
    public $enum_number;
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,21 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\DTO;
 | 
			
		||||
 | 
			
		||||
use Articus\DataTransfer\Annotation as DTA;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Query parameters for findPetsByStatus
 | 
			
		||||
 */
 | 
			
		||||
class FindPetsByStatusQueryData
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Status values that need to be considered for filter
 | 
			
		||||
     * @DTA\Data(field="status")
 | 
			
		||||
     * TODO check validator and strategy are correct and can handle container item type
 | 
			
		||||
     * @DTA\Strategy(name="QueryParameterArray", options={"type":"string", "format":"csv"})
 | 
			
		||||
     * @DTA\Validator(name="QueryParameterArrayType", options={"type":"string", "format":"csv"})
 | 
			
		||||
     * @var string[]
 | 
			
		||||
     */
 | 
			
		||||
    public $status;
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,21 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\DTO;
 | 
			
		||||
 | 
			
		||||
use Articus\DataTransfer\Annotation as DTA;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Query parameters for findPetsByTags
 | 
			
		||||
 */
 | 
			
		||||
class FindPetsByTagsQueryData
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Tags to filter by
 | 
			
		||||
     * @DTA\Data(field="tags")
 | 
			
		||||
     * TODO check validator and strategy are correct and can handle container item type
 | 
			
		||||
     * @DTA\Strategy(name="QueryParameterArray", options={"type":"string", "format":"csv"})
 | 
			
		||||
     * @DTA\Validator(name="QueryParameterArrayType", options={"type":"string", "format":"csv"})
 | 
			
		||||
     * @var string[]
 | 
			
		||||
     */
 | 
			
		||||
    public $tags;
 | 
			
		||||
}
 | 
			
		||||
@ -51,7 +51,7 @@ class FormatTest
 | 
			
		||||
     * @DTA\Validator(name="Type", options={"type":"float"})
 | 
			
		||||
     * @DTA\Validator(name="GreaterThan", options={"min":67.8, "inclusive":true})
 | 
			
		||||
     * @DTA\Validator(name="LessThan", options={"max":123.4, "inclusive":true})
 | 
			
		||||
     * @var double
 | 
			
		||||
     * @var float
 | 
			
		||||
     */
 | 
			
		||||
    public $double;
 | 
			
		||||
    /**
 | 
			
		||||
@ -70,6 +70,7 @@ class FormatTest
 | 
			
		||||
    public $byte;
 | 
			
		||||
    /**
 | 
			
		||||
     * @DTA\Data(field="binary", nullable=true)
 | 
			
		||||
     * @DTA\Validator(name="Type", options={"type":"string"})
 | 
			
		||||
     * @var string
 | 
			
		||||
     */
 | 
			
		||||
    public $binary;
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,28 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\DTO;
 | 
			
		||||
 | 
			
		||||
use Articus\DataTransfer\Annotation as DTA;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Query parameters for loginUser
 | 
			
		||||
 */
 | 
			
		||||
class LoginUserQueryData
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * The password for login in clear text
 | 
			
		||||
     * @DTA\Data(field="password")
 | 
			
		||||
     * @DTA\Strategy(name="QueryParameter", options={"type":"string"})
 | 
			
		||||
     * @DTA\Validator(name="QueryParameterType", options={"type":"string"})
 | 
			
		||||
     * @var string
 | 
			
		||||
     */
 | 
			
		||||
    public $password;
 | 
			
		||||
    /**
 | 
			
		||||
     * The user name for login
 | 
			
		||||
     * @DTA\Data(field="username")
 | 
			
		||||
     * @DTA\Strategy(name="QueryParameter", options={"type":"string"})
 | 
			
		||||
     * @DTA\Validator(name="QueryParameterType", options={"type":"string"})
 | 
			
		||||
     * @var string
 | 
			
		||||
     */
 | 
			
		||||
    public $username;
 | 
			
		||||
}
 | 
			
		||||
@ -10,13 +10,20 @@ class MapTest
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @DTA\Data(field="map_map_of_string", nullable=true)
 | 
			
		||||
     * @DTA\Strategy(name="Object", options={"type":map[string,map[string,string]]::class})
 | 
			
		||||
     * @DTA\Validator(name="Dictionary", options={"type":map[string,map[string,string]]::class})
 | 
			
		||||
     * TODO check validator and strategy are correct and can handle container item type
 | 
			
		||||
     * @DTA\Strategy(name="ObjectArray", options={"type":map[string,string]::class})
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Dictionary", "options":{"type":map[string,string]::class}}
 | 
			
		||||
     * }})
 | 
			
		||||
     * @var map[string,map[string,string]]
 | 
			
		||||
     */
 | 
			
		||||
    public $map_map_of_string;
 | 
			
		||||
    /**
 | 
			
		||||
     * @DTA\Data(field="map_of_enum_string", nullable=true)
 | 
			
		||||
     * TODO check validator and strategy are correct and can handle container item type
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Type", "options":{"type":"string"}}
 | 
			
		||||
     * }})
 | 
			
		||||
     * @var map[string,string]
 | 
			
		||||
     */
 | 
			
		||||
    public $map_of_enum_string;
 | 
			
		||||
 | 
			
		||||
@ -23,8 +23,11 @@ class MixedPropertiesAndAdditionalPropertiesClass
 | 
			
		||||
    public $date_time;
 | 
			
		||||
    /**
 | 
			
		||||
     * @DTA\Data(field="map", nullable=true)
 | 
			
		||||
     * @DTA\Strategy(name="Object", options={"type":map[string,\App\DTO\Animal]::class})
 | 
			
		||||
     * @DTA\Validator(name="Dictionary", options={"type":map[string,\App\DTO\Animal]::class})
 | 
			
		||||
     * TODO check validator and strategy are correct and can handle container item type
 | 
			
		||||
     * @DTA\Strategy(name="ObjectArray", options={"type":\App\DTO\Animal::class})
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Dictionary", "options":{"type":\App\DTO\Animal::class}}
 | 
			
		||||
     * }})
 | 
			
		||||
     * @var map[string,\App\DTO\Animal]
 | 
			
		||||
     */
 | 
			
		||||
    public $map;
 | 
			
		||||
 | 
			
		||||
@ -29,6 +29,7 @@ class Pet
 | 
			
		||||
    public $name;
 | 
			
		||||
    /**
 | 
			
		||||
     * @DTA\Data(field="photoUrls")
 | 
			
		||||
     * TODO check validator and strategy are correct and can handle container item type
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Type", "options":{"type":"string"}}
 | 
			
		||||
     * }})
 | 
			
		||||
@ -37,6 +38,7 @@ class Pet
 | 
			
		||||
    public $photo_urls;
 | 
			
		||||
    /**
 | 
			
		||||
     * @DTA\Data(field="tags", nullable=true)
 | 
			
		||||
     * TODO check validator and strategy are correct and can handle container item type
 | 
			
		||||
     * @DTA\Strategy(name="ObjectArray", options={"type":\App\DTO\Tag::class})
 | 
			
		||||
     * @DTA\Validator(name="Collection", options={"validators":{
 | 
			
		||||
     *     {"name":"Dictionary", "options":{"type":\App\DTO\Tag::class}}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,37 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\DTO;
 | 
			
		||||
 | 
			
		||||
use Articus\DataTransfer\Annotation as DTA;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Query parameters for testEnumParameters
 | 
			
		||||
 */
 | 
			
		||||
class TestEnumParametersQueryData
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Query parameter enum test (string)
 | 
			
		||||
     * @DTA\Data(field="enum_query_string", nullable=true)
 | 
			
		||||
     * @DTA\Strategy(name="QueryParameter", options={"type":"string"})
 | 
			
		||||
     * @DTA\Validator(name="QueryParameterType", options={"type":"string"})
 | 
			
		||||
     * @var string
 | 
			
		||||
     */
 | 
			
		||||
    public $enum_query_string;
 | 
			
		||||
    /**
 | 
			
		||||
     * Query parameter enum test (double)
 | 
			
		||||
     * @DTA\Data(field="enum_query_integer", nullable=true)
 | 
			
		||||
     * @DTA\Strategy(name="QueryParameter", options={"type":"int"})
 | 
			
		||||
     * @DTA\Validator(name="QueryParameterType", options={"type":"int"})
 | 
			
		||||
     * @var int
 | 
			
		||||
     */
 | 
			
		||||
    public $enum_query_integer;
 | 
			
		||||
    /**
 | 
			
		||||
     * Query parameter enum test (string array)
 | 
			
		||||
     * @DTA\Data(field="enum_query_string_array", nullable=true)
 | 
			
		||||
     * TODO check validator and strategy are correct and can handle container item type
 | 
			
		||||
     * @DTA\Strategy(name="QueryParameterArray", options={"type":"string", "format":"csv"})
 | 
			
		||||
     * @DTA\Validator(name="QueryParameterArrayType", options={"type":"string", "format":"csv"})
 | 
			
		||||
     * @var string[]
 | 
			
		||||
     */
 | 
			
		||||
    public $enum_query_string_array;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										34
									
								
								samples/server/petstore/ze-ph/src/App/ErrorMiddleware.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								samples/server/petstore/ze-ph/src/App/ErrorMiddleware.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App;
 | 
			
		||||
 | 
			
		||||
use Interop\Http\ServerMiddleware\DelegateInterface;
 | 
			
		||||
use Interop\Http\ServerMiddleware\MiddlewareInterface;
 | 
			
		||||
use Psr\Http\Message\ResponseInterface as Response;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface as Request;
 | 
			
		||||
use Zend\Stdlib\ErrorHandler;
 | 
			
		||||
 | 
			
		||||
class ErrorMiddleware implements MiddlewareInterface
 | 
			
		||||
{
 | 
			
		||||
    public function process(Request $request, DelegateInterface $delegate)
 | 
			
		||||
    {
 | 
			
		||||
        $result = null;
 | 
			
		||||
        try {
 | 
			
		||||
            ErrorHandler::start();
 | 
			
		||||
            $result = $delegate->process($request);
 | 
			
		||||
            ErrorHandler::stop(true);
 | 
			
		||||
            if (!($result instanceof Response)) {
 | 
			
		||||
                throw new \RuntimeException(sprintf(
 | 
			
		||||
                    'Invalid response: expecting %s, got %s',
 | 
			
		||||
                    Response::class,
 | 
			
		||||
                    is_object($result)? get_class($result) : gettype($result)
 | 
			
		||||
                ));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (\Exception $error) {
 | 
			
		||||
            $result = (new \Zend\Diactoros\Response())->withStatus(500, 'Internal server error');
 | 
			
		||||
            error_log((string)$error);
 | 
			
		||||
        }
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,38 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\Handler;
 | 
			
		||||
 | 
			
		||||
use Articus\PathHandler\Operation;
 | 
			
		||||
use Articus\PathHandler\Annotation as PHA;
 | 
			
		||||
use Articus\PathHandler\Consumer as PHConsumer;
 | 
			
		||||
use Articus\PathHandler\Producer as PHProducer;
 | 
			
		||||
use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/another-fake/dummy")
 | 
			
		||||
 */
 | 
			
		||||
class AnotherFakeDummy implements Operation\PatchInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * To test special tags
 | 
			
		||||
     * TODO check if consumer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Consumer(name=PHConsumer\Json::class, mediaType="application/json")
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\Client::class,"objectAttr":"bodyData"})
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Producer(name=PHProducer\Transfer::class, mediaType="application/json")
 | 
			
		||||
     * @param ServerRequestInterface $request
 | 
			
		||||
     *
 | 
			
		||||
     * @throws PHException\HttpCode 500 if the method is not implemented
 | 
			
		||||
     *
 | 
			
		||||
     * @return \App\DTO\Client
 | 
			
		||||
     */
 | 
			
		||||
    public function handlePatch(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO implement method
 | 
			
		||||
        /** @var \App\DTO\Client $bodyData */
 | 
			
		||||
        $bodyData = $request->getAttribute("bodyData");
 | 
			
		||||
        throw new PHException\HttpCode(500, "Not implemented");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -10,13 +10,16 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/fake")
 | 
			
		||||
 */
 | 
			
		||||
class Fake implements Operation\PatchInterface, Operation\PostInterface, Operation\GetInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * To test \"client\" model
 | 
			
		||||
     * TODO check if consumer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Consumer(name=PHConsumer\Json::class, mediaType="application/json")
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\Client::class,"objectAttr":"body"})
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\Client::class,"objectAttr":"bodyData"})
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Producer(name=PHProducer\Transfer::class, mediaType="application/json")
 | 
			
		||||
     * @param ServerRequestInterface $request
 | 
			
		||||
@ -28,16 +31,16 @@ class Fake implements Operation\PatchInterface, Operation\PostInterface, Operati
 | 
			
		||||
    public function handlePatch(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO implement method
 | 
			
		||||
        /** @var \App\DTO\Client $body */
 | 
			
		||||
        $body = $request->getAttribute("body");
 | 
			
		||||
        /** @var \App\DTO\Client $bodyData */
 | 
			
		||||
        $bodyData = $request->getAttribute("bodyData");
 | 
			
		||||
        throw new PHException\HttpCode(500, "Not implemented");
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트 
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Producer(name=PHProducer\Transfer::class, mediaType="application/xml; charset=utf-8")
 | 
			
		||||
     * @PHA\Producer(name=PHProducer\Transfer::class, mediaType="application/xml; charset=utf-8")
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Producer(name=PHProducer\Transfer::class, mediaType="application/json; charset=utf-8")
 | 
			
		||||
     * @PHA\Producer(name=PHProducer\Transfer::class, mediaType="application/json; charset=utf-8")
 | 
			
		||||
     * @param ServerRequestInterface $request
 | 
			
		||||
     *
 | 
			
		||||
     * @throws PHException\HttpCode 500 if the method is not implemented
 | 
			
		||||
@ -49,6 +52,11 @@ class Fake implements Operation\PatchInterface, Operation\PostInterface, Operati
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * To test enum parameters
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={
 | 
			
		||||
     *     "type":\App\DTO\TestEnumParametersQueryData::class,
 | 
			
		||||
     *     "objectAttr":"queryData",
 | 
			
		||||
     *     "source": PHAttribute\Transfer::SOURCE_GET
 | 
			
		||||
     * })
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Producer(name=PHProducer\Transfer::class, mediaType="*/*")
 | 
			
		||||
     * @param ServerRequestInterface $request
 | 
			
		||||
@ -58,6 +66,8 @@ class Fake implements Operation\PatchInterface, Operation\PostInterface, Operati
 | 
			
		||||
    public function handleGet(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO implement method
 | 
			
		||||
        /** @var \App\DTO\TestEnumParametersQueryData $queryData */
 | 
			
		||||
        $queryData = $request->getAttribute("queryData");
 | 
			
		||||
        throw new PHException\HttpCode(500, "Not implemented");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,13 +10,16 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/fake_classname_test")
 | 
			
		||||
 */
 | 
			
		||||
class FakeClassnameTest implements Operation\PatchInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * To test class name in snake case
 | 
			
		||||
     * TODO check if consumer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Consumer(name=PHConsumer\Json::class, mediaType="application/json")
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\Client::class,"objectAttr":"body"})
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\Client::class,"objectAttr":"bodyData"})
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Producer(name=PHProducer\Transfer::class, mediaType="application/json")
 | 
			
		||||
     * @param ServerRequestInterface $request
 | 
			
		||||
@ -28,8 +31,8 @@ class FakeClassnameTest implements Operation\PatchInterface
 | 
			
		||||
    public function handlePatch(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO implement method
 | 
			
		||||
        /** @var \App\DTO\Client $body */
 | 
			
		||||
        $body = $request->getAttribute("body");
 | 
			
		||||
        /** @var \App\DTO\Client $bodyData */
 | 
			
		||||
        $bodyData = $request->getAttribute("bodyData");
 | 
			
		||||
        throw new PHException\HttpCode(500, "Not implemented");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,31 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\Handler;
 | 
			
		||||
 | 
			
		||||
use Articus\PathHandler\Operation;
 | 
			
		||||
use Articus\PathHandler\Annotation as PHA;
 | 
			
		||||
use Articus\PathHandler\Consumer as PHConsumer;
 | 
			
		||||
use Articus\PathHandler\Producer as PHProducer;
 | 
			
		||||
use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/fake/inline-additionalProperties")
 | 
			
		||||
 */
 | 
			
		||||
class FakeInlineAdditionalProperties implements Operation\PostInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * test inline additionalProperties
 | 
			
		||||
     * TODO check if consumer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Consumer(name=PHConsumer\Json::class, mediaType="application/json")
 | 
			
		||||
     * @param ServerRequestInterface $request
 | 
			
		||||
     *
 | 
			
		||||
     * @throws PHException\HttpCode 500 if the method is not implemented
 | 
			
		||||
     */
 | 
			
		||||
    public function handlePost(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO implement method
 | 
			
		||||
        throw new PHException\HttpCode(500, "Not implemented");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -10,6 +10,9 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/fake/jsonFormData")
 | 
			
		||||
 */
 | 
			
		||||
class FakeJsonFormData implements Operation\GetInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -10,10 +10,13 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/fake/outer/boolean")
 | 
			
		||||
 */
 | 
			
		||||
class FakeOuterBoolean implements Operation\PostInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\OuterBoolean::class,"objectAttr":"body"})
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\OuterBoolean::class,"objectAttr":"bodyData"})
 | 
			
		||||
     * @param ServerRequestInterface $request
 | 
			
		||||
     *
 | 
			
		||||
     * @throws PHException\HttpCode 500 if the method is not implemented
 | 
			
		||||
@ -23,8 +26,8 @@ class FakeOuterBoolean implements Operation\PostInterface
 | 
			
		||||
    public function handlePost(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO implement method
 | 
			
		||||
        /** @var \App\DTO\OuterBoolean $body */
 | 
			
		||||
        $body = $request->getAttribute("body");
 | 
			
		||||
        /** @var \App\DTO\OuterBoolean $bodyData */
 | 
			
		||||
        $bodyData = $request->getAttribute("bodyData");
 | 
			
		||||
        throw new PHException\HttpCode(500, "Not implemented");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,10 +10,13 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/fake/outer/composite")
 | 
			
		||||
 */
 | 
			
		||||
class FakeOuterComposite implements Operation\PostInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\OuterComposite::class,"objectAttr":"body"})
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\OuterComposite::class,"objectAttr":"bodyData"})
 | 
			
		||||
     * @param ServerRequestInterface $request
 | 
			
		||||
     *
 | 
			
		||||
     * @throws PHException\HttpCode 500 if the method is not implemented
 | 
			
		||||
@ -23,8 +26,8 @@ class FakeOuterComposite implements Operation\PostInterface
 | 
			
		||||
    public function handlePost(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO implement method
 | 
			
		||||
        /** @var \App\DTO\OuterComposite $body */
 | 
			
		||||
        $body = $request->getAttribute("body");
 | 
			
		||||
        /** @var \App\DTO\OuterComposite $bodyData */
 | 
			
		||||
        $bodyData = $request->getAttribute("bodyData");
 | 
			
		||||
        throw new PHException\HttpCode(500, "Not implemented");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,10 +10,13 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/fake/outer/number")
 | 
			
		||||
 */
 | 
			
		||||
class FakeOuterNumber implements Operation\PostInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\OuterNumber::class,"objectAttr":"body"})
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\OuterNumber::class,"objectAttr":"bodyData"})
 | 
			
		||||
     * @param ServerRequestInterface $request
 | 
			
		||||
     *
 | 
			
		||||
     * @throws PHException\HttpCode 500 if the method is not implemented
 | 
			
		||||
@ -23,8 +26,8 @@ class FakeOuterNumber implements Operation\PostInterface
 | 
			
		||||
    public function handlePost(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO implement method
 | 
			
		||||
        /** @var \App\DTO\OuterNumber $body */
 | 
			
		||||
        $body = $request->getAttribute("body");
 | 
			
		||||
        /** @var \App\DTO\OuterNumber $bodyData */
 | 
			
		||||
        $bodyData = $request->getAttribute("bodyData");
 | 
			
		||||
        throw new PHException\HttpCode(500, "Not implemented");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,10 +10,13 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/fake/outer/string")
 | 
			
		||||
 */
 | 
			
		||||
class FakeOuterString implements Operation\PostInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\OuterString::class,"objectAttr":"body"})
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\OuterString::class,"objectAttr":"bodyData"})
 | 
			
		||||
     * @param ServerRequestInterface $request
 | 
			
		||||
     *
 | 
			
		||||
     * @throws PHException\HttpCode 500 if the method is not implemented
 | 
			
		||||
@ -23,8 +26,8 @@ class FakeOuterString implements Operation\PostInterface
 | 
			
		||||
    public function handlePost(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO implement method
 | 
			
		||||
        /** @var \App\DTO\OuterString $body */
 | 
			
		||||
        $body = $request->getAttribute("body");
 | 
			
		||||
        /** @var \App\DTO\OuterString $bodyData */
 | 
			
		||||
        $bodyData = $request->getAttribute("bodyData");
 | 
			
		||||
        throw new PHException\HttpCode(500, "Not implemented");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,9 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/pet")
 | 
			
		||||
 */
 | 
			
		||||
class Pet implements Operation\PostInterface, Operation\PutInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
@ -18,7 +21,7 @@ class Pet implements Operation\PostInterface, Operation\PutInterface
 | 
			
		||||
     * @PHA\Consumer(name=PHConsumer\Json::class, mediaType="application/json")
 | 
			
		||||
     * TODO check if consumer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Consumer(name=PHConsumer\Json::class, mediaType="application/xml")
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\Pet::class,"objectAttr":"body"})
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\Pet::class,"objectAttr":"bodyData"})
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Producer(name=PHProducer\Transfer::class, mediaType="application/xml")
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
@ -30,8 +33,8 @@ class Pet implements Operation\PostInterface, Operation\PutInterface
 | 
			
		||||
    public function handlePost(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO implement method
 | 
			
		||||
        /** @var \App\DTO\Pet $body */
 | 
			
		||||
        $body = $request->getAttribute("body");
 | 
			
		||||
        /** @var \App\DTO\Pet $bodyData */
 | 
			
		||||
        $bodyData = $request->getAttribute("bodyData");
 | 
			
		||||
        throw new PHException\HttpCode(500, "Not implemented");
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
@ -40,7 +43,7 @@ class Pet implements Operation\PostInterface, Operation\PutInterface
 | 
			
		||||
     * @PHA\Consumer(name=PHConsumer\Json::class, mediaType="application/json")
 | 
			
		||||
     * TODO check if consumer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Consumer(name=PHConsumer\Json::class, mediaType="application/xml")
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\Pet::class,"objectAttr":"body"})
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\Pet::class,"objectAttr":"bodyData"})
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Producer(name=PHProducer\Transfer::class, mediaType="application/xml")
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
@ -52,8 +55,8 @@ class Pet implements Operation\PostInterface, Operation\PutInterface
 | 
			
		||||
    public function handlePut(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO implement method
 | 
			
		||||
        /** @var \App\DTO\Pet $body */
 | 
			
		||||
        $body = $request->getAttribute("body");
 | 
			
		||||
        /** @var \App\DTO\Pet $bodyData */
 | 
			
		||||
        $bodyData = $request->getAttribute("bodyData");
 | 
			
		||||
        throw new PHException\HttpCode(500, "Not implemented");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,10 +10,18 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/pet/findByStatus")
 | 
			
		||||
 */
 | 
			
		||||
class PetFindByStatus implements Operation\GetInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Finds Pets by status
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={
 | 
			
		||||
     *     "type":\App\DTO\FindPetsByStatusQueryData::class,
 | 
			
		||||
     *     "objectAttr":"queryData",
 | 
			
		||||
     *     "source": PHAttribute\Transfer::SOURCE_GET
 | 
			
		||||
     * })
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Producer(name=PHProducer\Transfer::class, mediaType="application/xml")
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
@ -27,6 +35,8 @@ class PetFindByStatus implements Operation\GetInterface
 | 
			
		||||
    public function handleGet(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO implement method
 | 
			
		||||
        /** @var \App\DTO\FindPetsByStatusQueryData $queryData */
 | 
			
		||||
        $queryData = $request->getAttribute("queryData");
 | 
			
		||||
        throw new PHException\HttpCode(500, "Not implemented");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,10 +10,18 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/pet/findByTags")
 | 
			
		||||
 */
 | 
			
		||||
class PetFindByTags implements Operation\GetInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Finds Pets by tags
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={
 | 
			
		||||
     *     "type":\App\DTO\FindPetsByTagsQueryData::class,
 | 
			
		||||
     *     "objectAttr":"queryData",
 | 
			
		||||
     *     "source": PHAttribute\Transfer::SOURCE_GET
 | 
			
		||||
     * })
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Producer(name=PHProducer\Transfer::class, mediaType="application/xml")
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
@ -27,6 +35,8 @@ class PetFindByTags implements Operation\GetInterface
 | 
			
		||||
    public function handleGet(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO implement method
 | 
			
		||||
        /** @var \App\DTO\FindPetsByTagsQueryData $queryData */
 | 
			
		||||
        $queryData = $request->getAttribute("queryData");
 | 
			
		||||
        throw new PHException\HttpCode(500, "Not implemented");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,9 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/pet/{petId}")
 | 
			
		||||
 */
 | 
			
		||||
class PetPetId implements Operation\DeleteInterface, Operation\GetInterface, Operation\PostInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,9 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/pet/{petId}/uploadImage")
 | 
			
		||||
 */
 | 
			
		||||
class PetPetIdUploadImage implements Operation\PostInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,9 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/store/inventory")
 | 
			
		||||
 */
 | 
			
		||||
class StoreInventory implements Operation\GetInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -10,11 +10,14 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/store/order")
 | 
			
		||||
 */
 | 
			
		||||
class StoreOrder implements Operation\PostInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Place an order for a pet
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\Order::class,"objectAttr":"body"})
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\Order::class,"objectAttr":"bodyData"})
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Producer(name=PHProducer\Transfer::class, mediaType="application/xml")
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
@ -28,8 +31,8 @@ class StoreOrder implements Operation\PostInterface
 | 
			
		||||
    public function handlePost(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO implement method
 | 
			
		||||
        /** @var \App\DTO\Order $body */
 | 
			
		||||
        $body = $request->getAttribute("body");
 | 
			
		||||
        /** @var \App\DTO\Order $bodyData */
 | 
			
		||||
        $bodyData = $request->getAttribute("bodyData");
 | 
			
		||||
        throw new PHException\HttpCode(500, "Not implemented");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,9 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/store/order/{order_id}")
 | 
			
		||||
 */
 | 
			
		||||
class StoreOrderOrderId implements Operation\DeleteInterface, Operation\GetInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -10,11 +10,14 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/user")
 | 
			
		||||
 */
 | 
			
		||||
class User implements Operation\PostInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Create user
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\User::class,"objectAttr":"body"})
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\User::class,"objectAttr":"bodyData"})
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Producer(name=PHProducer\Transfer::class, mediaType="application/xml")
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
@ -26,8 +29,8 @@ class User implements Operation\PostInterface
 | 
			
		||||
    public function handlePost(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO implement method
 | 
			
		||||
        /** @var \App\DTO\User $body */
 | 
			
		||||
        $body = $request->getAttribute("body");
 | 
			
		||||
        /** @var \App\DTO\User $bodyData */
 | 
			
		||||
        $bodyData = $request->getAttribute("bodyData");
 | 
			
		||||
        throw new PHException\HttpCode(500, "Not implemented");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,11 +10,15 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/user/createWithArray")
 | 
			
		||||
 */
 | 
			
		||||
class UserCreateWithArray implements Operation\PostInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates list of users with given input array
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\User[]::class,"objectAttr":"body"})
 | 
			
		||||
     * TODO check if attribute is valid and can handle your container type
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\User[]::class,"objectAttr":"bodyData"})
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Producer(name=PHProducer\Transfer::class, mediaType="application/xml")
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
@ -26,8 +30,8 @@ class UserCreateWithArray implements Operation\PostInterface
 | 
			
		||||
    public function handlePost(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO implement method
 | 
			
		||||
        /** @var \App\DTO\User[] $body */
 | 
			
		||||
        $body = $request->getAttribute("body");
 | 
			
		||||
        /** @var \App\DTO\User[] $bodyData */
 | 
			
		||||
        $bodyData = $request->getAttribute("bodyData");
 | 
			
		||||
        throw new PHException\HttpCode(500, "Not implemented");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,11 +10,15 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/user/createWithList")
 | 
			
		||||
 */
 | 
			
		||||
class UserCreateWithList implements Operation\PostInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates list of users with given input array
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\User[]::class,"objectAttr":"body"})
 | 
			
		||||
     * TODO check if attribute is valid and can handle your container type
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\User[]::class,"objectAttr":"bodyData"})
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Producer(name=PHProducer\Transfer::class, mediaType="application/xml")
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
@ -26,8 +30,8 @@ class UserCreateWithList implements Operation\PostInterface
 | 
			
		||||
    public function handlePost(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO implement method
 | 
			
		||||
        /** @var \App\DTO\User[] $body */
 | 
			
		||||
        $body = $request->getAttribute("body");
 | 
			
		||||
        /** @var \App\DTO\User[] $bodyData */
 | 
			
		||||
        $bodyData = $request->getAttribute("bodyData");
 | 
			
		||||
        throw new PHException\HttpCode(500, "Not implemented");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,10 +10,18 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/user/login")
 | 
			
		||||
 */
 | 
			
		||||
class UserLogin implements Operation\GetInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * Logs user into the system
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={
 | 
			
		||||
     *     "type":\App\DTO\LoginUserQueryData::class,
 | 
			
		||||
     *     "objectAttr":"queryData",
 | 
			
		||||
     *     "source": PHAttribute\Transfer::SOURCE_GET
 | 
			
		||||
     * })
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Producer(name=PHProducer\Transfer::class, mediaType="application/xml")
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
@ -27,6 +35,8 @@ class UserLogin implements Operation\GetInterface
 | 
			
		||||
    public function handleGet(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO implement method
 | 
			
		||||
        /** @var \App\DTO\LoginUserQueryData $queryData */
 | 
			
		||||
        $queryData = $request->getAttribute("queryData");
 | 
			
		||||
        throw new PHException\HttpCode(500, "Not implemented");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,9 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/user/logout")
 | 
			
		||||
 */
 | 
			
		||||
class UserLogout implements Operation\GetInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,9 @@ use Articus\PathHandler\Attribute as PHAttribute;
 | 
			
		||||
use Articus\PathHandler\Exception as PHException;
 | 
			
		||||
use Psr\Http\Message\ServerRequestInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @PHA\Route(pattern="/user/{username}")
 | 
			
		||||
 */
 | 
			
		||||
class UserUsername implements Operation\DeleteInterface, Operation\GetInterface, Operation\PutInterface
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
@ -46,7 +49,7 @@ class UserUsername implements Operation\DeleteInterface, Operation\GetInterface,
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Updated user
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\User::class,"objectAttr":"body"})
 | 
			
		||||
     * @PHA\Attribute(name=PHAttribute\Transfer::class, options={"type":\App\DTO\User::class,"objectAttr":"bodyData"})
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
     * @PHA\Producer(name=PHProducer\Transfer::class, mediaType="application/xml")
 | 
			
		||||
     * TODO check if producer is valid, if it has correct priority and if it can be moved to class annotation
 | 
			
		||||
@ -58,8 +61,8 @@ class UserUsername implements Operation\DeleteInterface, Operation\GetInterface,
 | 
			
		||||
    public function handlePut(ServerRequestInterface $request)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO implement method
 | 
			
		||||
        /** @var \App\DTO\User $body */
 | 
			
		||||
        $body = $request->getAttribute("body");
 | 
			
		||||
        /** @var \App\DTO\User $bodyData */
 | 
			
		||||
        $bodyData = $request->getAttribute("bodyData");
 | 
			
		||||
        throw new PHException\HttpCode(500, "Not implemented");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,76 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\Strategy;
 | 
			
		||||
 | 
			
		||||
use Articus\DataTransfer\Strategy\StrategyInterface;
 | 
			
		||||
 | 
			
		||||
class QueryParameter implements StrategyInterface
 | 
			
		||||
{
 | 
			
		||||
    const TYPE_INT = 'int';
 | 
			
		||||
    const TYPE_FLOAT = 'float';
 | 
			
		||||
    const TYPE_BOOL = 'bool';
 | 
			
		||||
    const TYPE_STRING = 'string';
 | 
			
		||||
 | 
			
		||||
    const TYPE_MAP = [
 | 
			
		||||
        self::TYPE_INT => true,
 | 
			
		||||
        self::TYPE_FLOAT => true,
 | 
			
		||||
        self::TYPE_BOOL => true,
 | 
			
		||||
        self::TYPE_STRING => true,
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var string
 | 
			
		||||
     */
 | 
			
		||||
    protected $type;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * QueryParameterArray constructor.
 | 
			
		||||
     */
 | 
			
		||||
    public function __construct(array $options)
 | 
			
		||||
    {
 | 
			
		||||
        if (empty($options['type'])) {
 | 
			
		||||
            throw new \InvalidArgumentException('Option "type" is required.');
 | 
			
		||||
        } elseif (!isset(self::TYPE_MAP[$options['type']])) {
 | 
			
		||||
            throw new \InvalidArgumentException(sprintf('Unknown type "%s".', $options['type']));
 | 
			
		||||
        }
 | 
			
		||||
        $this->type = $options['type'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    public function extract($objectValue, $object = null)
 | 
			
		||||
    {
 | 
			
		||||
        $result = null;
 | 
			
		||||
        if ($objectValue !== null) {
 | 
			
		||||
            $result = (string)$objectValue;
 | 
			
		||||
        }
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    public function hydrate($arrayValue, $objectValue, array $array = null)
 | 
			
		||||
    {
 | 
			
		||||
        $result = null;
 | 
			
		||||
        if ($arrayValue !== null) {
 | 
			
		||||
            switch ($this->type) {
 | 
			
		||||
                case self::TYPE_INT:
 | 
			
		||||
                    $result = (int)$arrayValue;
 | 
			
		||||
                    break;
 | 
			
		||||
                case self::TYPE_FLOAT:
 | 
			
		||||
                    $result = (float)$arrayValue;
 | 
			
		||||
                    break;
 | 
			
		||||
                case self::TYPE_BOOL:
 | 
			
		||||
                    $result = ($arrayValue === 'true')? true : false;
 | 
			
		||||
                    break;
 | 
			
		||||
                case self::TYPE_STRING:
 | 
			
		||||
                    $result = (string)$arrayValue;
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,73 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
namespace App\Strategy;
 | 
			
		||||
 | 
			
		||||
class QueryParameterArray extends QueryParameter
 | 
			
		||||
{
 | 
			
		||||
    const FORMAT_CSV = 'csv'; //comma separated values foo,bar.
 | 
			
		||||
    const FORMAT_SSV = 'ssv'; //space separated values foo bar.
 | 
			
		||||
    const FORMAT_TSV = 'tsv'; //tab separated values foo\tbar.
 | 
			
		||||
    const FORMAT_PIPES = 'pipes'; //pipe separated values foo|bar.
 | 
			
		||||
    const FORMAT_MULTI = 'multi'; //corresponds to multiple parameter instances instead of multiple values for a single instance foo[]=bar&foo[]=baz.
 | 
			
		||||
 | 
			
		||||
    const DELIMITER_MAP = [
 | 
			
		||||
        self::FORMAT_CSV => ',',
 | 
			
		||||
        self::FORMAT_SSV => ' ',
 | 
			
		||||
        self::FORMAT_TSV => "\t",
 | 
			
		||||
        self::FORMAT_PIPES => '|',
 | 
			
		||||
        self::FORMAT_MULTI => null,
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @var string|null
 | 
			
		||||
     */
 | 
			
		||||
    protected $delimiter;
 | 
			
		||||
 | 
			
		||||
    public function __construct(array $options)
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct($options);
 | 
			
		||||
        if (empty($options['format'])) {
 | 
			
		||||
            throw new \InvalidArgumentException('Option "format" is required.');
 | 
			
		||||
        } elseif (!array_key_exists($options['format'], self::DELIMITER_MAP)) {
 | 
			
		||||
            throw new \InvalidArgumentException(sprintf('Unknown format "%s".', $options['format']));
 | 
			
		||||
        }
 | 
			
		||||
        $this->delimiter = self::DELIMITER_MAP[$options['format']];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    public function extract($objectValue, $object = null)
 | 
			
		||||
    {
 | 
			
		||||
        $result = null;
 | 
			
		||||
        if (is_array($objectValue)) {
 | 
			
		||||
            if ($this->delimiter === null) {
 | 
			
		||||
                $result = $objectValue;
 | 
			
		||||
            } else {
 | 
			
		||||
                $result = implode($this->delimiter, $objectValue);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @inheritdoc
 | 
			
		||||
     */
 | 
			
		||||
    public function hydrate($arrayValue, $objectValue, array $array = null)
 | 
			
		||||
    {
 | 
			
		||||
        $result = null;
 | 
			
		||||
        if ($arrayValue !== null) {
 | 
			
		||||
            $list = null;
 | 
			
		||||
            if ($this->delimiter === null) {
 | 
			
		||||
                $list = (is_array($arrayValue))? $arrayValue : [$arrayValue];
 | 
			
		||||
            } else {
 | 
			
		||||
                $list = explode($this->delimiter, $arrayValue);
 | 
			
		||||
            }
 | 
			
		||||
            $result = [];
 | 
			
		||||
            foreach ($list as $item) {
 | 
			
		||||
                $result[] = parent::hydrate($item, null);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,72 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace App\Validator;
 | 
			
		||||
 | 
			
		||||
use App\Strategy\QueryParameterArray;
 | 
			
		||||
 | 
			
		||||
class QueryParameterArrayType extends QueryParameterType
 | 
			
		||||
{
 | 
			
		||||
    /**
 | 
			
		||||
     * @var string
 | 
			
		||||
     */
 | 
			
		||||
    protected $format;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return string
 | 
			
		||||
     */
 | 
			
		||||
    public function getFormat()
 | 
			
		||||
    {
 | 
			
		||||
        return $this->format;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param string $format
 | 
			
		||||
     * @return self
 | 
			
		||||
     */
 | 
			
		||||
    public function setFormat($format)
 | 
			
		||||
    {
 | 
			
		||||
        $this->format = $format;
 | 
			
		||||
        return $this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected function checkType($value)
 | 
			
		||||
    {
 | 
			
		||||
        $result = true;
 | 
			
		||||
        if (!array_key_exists($this->format, QueryParameterArray::DELIMITER_MAP)) {
 | 
			
		||||
            throw new \InvalidArgumentException(sprintf('Can not check for format %s.', $this->format));
 | 
			
		||||
        }
 | 
			
		||||
        $delimiter = QueryParameterArray::DELIMITER_MAP[$this->format];
 | 
			
		||||
        if ($delimiter === null) {
 | 
			
		||||
            if (is_array($value)) {
 | 
			
		||||
                foreach ($value as $item) {
 | 
			
		||||
                    $result = $result && parent::checkType($item);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                $result = false;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            switch ($this->type) {
 | 
			
		||||
                case QueryParameterArray::TYPE_INT:
 | 
			
		||||
                    $result = is_string($value) && preg_match(self::prepareRepeatingTypeRegExp(self::RE_INT, $delimiter), $value);
 | 
			
		||||
                    break;
 | 
			
		||||
                case QueryParameterArray::TYPE_BOOL:
 | 
			
		||||
                    $result = is_string($value) && preg_match(self::prepareRepeatingTypeRegExp(self::RE_BOOL, $delimiter), $value);
 | 
			
		||||
                    break;
 | 
			
		||||
                case QueryParameterArray::TYPE_FLOAT:
 | 
			
		||||
                    $result = is_string($value) && preg_match(self::prepareRepeatingTypeRegExp(self::RE_FLOAT, $delimiter), $value);
 | 
			
		||||
                    break;
 | 
			
		||||
                case QueryParameterArray::TYPE_STRING:
 | 
			
		||||
                    $result = is_string($value);
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    throw new \InvalidArgumentException(sprintf('Can not check for type %s.', $this->type));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected static function prepareRepeatingTypeRegExp($typeRegExp, $delimiter)
 | 
			
		||||
    {
 | 
			
		||||
        $escapedDelimiter = preg_quote($delimiter, '/');
 | 
			
		||||
        return '/^(' . $typeRegExp . ')(' . $escapedDelimiter . '('. $typeRegExp . '))*$/';
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,27 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace App\Validator;
 | 
			
		||||
 | 
			
		||||
use App\Strategy\QueryParameter;
 | 
			
		||||
 | 
			
		||||
class QueryParameterType extends Type
 | 
			
		||||
{
 | 
			
		||||
    const RE_INT = '0|-?[1-9]\d*';
 | 
			
		||||
    const RE_BOOL = 'true|false';
 | 
			
		||||
    const RE_FLOAT = '0(\.\d+)?|-?[1-9]\d*(\.\d+)?|-0\.\d+';
 | 
			
		||||
 | 
			
		||||
    protected function checkType($value)
 | 
			
		||||
    {
 | 
			
		||||
        switch ($this->type) {
 | 
			
		||||
            case QueryParameter::TYPE_INT:
 | 
			
		||||
                return is_string($value) && preg_match('/^(' . self::RE_INT . ')$/', $value);
 | 
			
		||||
            case QueryParameter::TYPE_BOOL:
 | 
			
		||||
                return is_string($value) && preg_match('/^(' . self::RE_BOOL . ')$/', $value);
 | 
			
		||||
            case QueryParameter::TYPE_FLOAT:
 | 
			
		||||
                return is_string($value) && preg_match('/^(' . self::RE_FLOAT . ')$/', $value);
 | 
			
		||||
            case QueryParameter::TYPE_STRING:
 | 
			
		||||
                return is_string($value);
 | 
			
		||||
            default:
 | 
			
		||||
                throw new \InvalidArgumentException(sprintf('Can not check for type %s.', $this->type));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user