From b633a2acc587c59b498a98102ee8569cf08dcc42 Mon Sep 17 00:00:00 2001 From: Ener-Getick Date: Wed, 20 Jul 2016 15:44:24 +0200 Subject: [PATCH] Allow to merge models --- src/Contact.php | 12 ++++++++++ src/ExternalDocs.php | 9 +++++++ src/Header.php | 20 +++++++++++++--- src/parts/ConsumesPart.php | 5 ++++ src/parts/DescriptionPart.php | 13 ++++++---- src/parts/ExtensionPart.php | 7 +++++- src/parts/ExternalDocsPart.php | 8 +++++-- src/parts/ItemsPart.php | 11 ++++++++- src/parts/ParametersPart.php | 5 ++++ src/parts/ProducesPart.php | 5 ++++ src/parts/RefPart.php | 12 +++++----- src/parts/RequiredPart.php | 13 ++++++---- src/parts/ResponsesPart.php | 5 ++++ src/parts/SchemaPart.php | 5 ++++ src/parts/SchemesPart.php | 5 ++++ src/parts/TagsPart.php | 18 ++++++++++++++ src/parts/TypePart.php | 44 ++++++++++++++++++++++++---------- src/parts/UrlPart.php | 7 +++++- src/util/MergeHelper.php | 35 +++++++++++++++++++++++++++ 19 files changed, 205 insertions(+), 34 deletions(-) create mode 100644 src/util/MergeHelper.php diff --git a/src/Contact.php b/src/Contact.php index fd586a0..f49ed5e 100644 --- a/src/Contact.php +++ b/src/Contact.php @@ -2,6 +2,7 @@ namespace gossi\swagger; use gossi\swagger\parts\ExtensionPart; +use gossi\swagger\util\MergeHelper; use phootwork\collection\CollectionUtils; use phootwork\lang\Arrayable; @@ -33,6 +34,17 @@ private function parse($contents = []) { $this->parseExtensions($data); } + /** + * {@inheritdoc} + */ + public function merge(static $model, $overwrite = false) { + MergeHelper::mergeFields($this->name, $model->name, $overwrite); + MergeHelper::mergeFields($this->url, $model->url, $overwrite); + MergeHelper::mergeFields($this->email, $model->email, $overwrite); + + $this->mergeExtensions($model, $overwrite); + } + public function toArray() { return $this->export('name', 'url', 'email'); } diff --git a/src/ExternalDocs.php b/src/ExternalDocs.php index 5a77e38..f0857df 100644 --- a/src/ExternalDocs.php +++ b/src/ExternalDocs.php @@ -26,6 +26,15 @@ private function parse($contents = []) { $this->parseExtensions($data); } + /** + * {@inheritdoc} + */ + public function merge(static $model, $overwrite = false) { + $this->mergeDescription($model, $overwrite); + $this->mergeUrl($model, $overwrite); + $this->mergeExtensions($model, $overwrite); + } + public function toArray() { return $this->export('description', 'url'); } diff --git a/src/Header.php b/src/Header.php index 714e3d5..189859d 100644 --- a/src/Header.php +++ b/src/Header.php @@ -19,9 +19,9 @@ class Header extends AbstractModel implements Arrayable { /** @var string */ private $header; - public function __construct($header, $contents = null) { + public function __construct($header, $contents = []) { $this->header = $header; - $this->parse($contents === null ? new Map() : $contents); + $this->parse($contents); } private function parse($contents = []) { @@ -34,13 +34,27 @@ private function parse($contents = []) { $this->parseExtensions($data); } + /** + * {@inheritdoc} + */ + public function merge(static $model, $overwrite = false) { + if ($this->header !== $model->header) { + throw new \InvalidArgumentException(sprintf('You can\'t merge two different headers (provided "%s" and "%s").', $this->header, $model->header)); + } + + $this->mergeDescription($model, $overwrite); + $this->mergeType($model, $overwrite); + $this->mergeItems($model, $overwrite); + $this->mergeExtensions($model, $overwrite); + } + public function toArray() { return $this->export('description', $this->getTypeExportFields(), 'items'); } /** * Returns the header - * + * * @return string */ public function getHeader() { diff --git a/src/parts/ConsumesPart.php b/src/parts/ConsumesPart.php index f77c98d..7c29523 100644 --- a/src/parts/ConsumesPart.php +++ b/src/parts/ConsumesPart.php @@ -1,6 +1,7 @@ consumes = $data->get('consumes', new Set()); } + private function mergeConsumes(static $model, $overwrite = false) { + MergeHelper::mergeFields($this->consumes, $model->consumes, $overwrite); + } + /** * Return consumes * diff --git a/src/parts/DescriptionPart.php b/src/parts/DescriptionPart.php index 8b42fde..2e68a50 100644 --- a/src/parts/DescriptionPart.php +++ b/src/parts/DescriptionPart.php @@ -1,20 +1,25 @@ description = $data->get('description'); } + private function mergeDescription(static $model, $overwrite = false) { + MergeHelper::mergeFields($this->description, $model->description, $overwrite); + } + /** * - * @return string + * @return string|null */ public function getDescription() { return $this->description; @@ -22,7 +27,7 @@ public function getDescription() { /** * - * @param string $description + * @param string|null $description * @return $this */ public function setDescription($description) { diff --git a/src/parts/ExtensionPart.php b/src/parts/ExtensionPart.php index 2254c5c..514c956 100644 --- a/src/parts/ExtensionPart.php +++ b/src/parts/ExtensionPart.php @@ -1,6 +1,7 @@ extensions, $model->description, $overwrite); + } + /** * Returns extensions - * + * * @return Map */ public function getExtensions() { diff --git a/src/parts/ExternalDocsPart.php b/src/parts/ExternalDocsPart.php index 48b4365..1863cc5 100644 --- a/src/parts/ExternalDocsPart.php +++ b/src/parts/ExternalDocsPart.php @@ -12,6 +12,10 @@ private function parseExternalDocs(Map $data) { $this->externalDocs = new ExternalDocs($data->get('externalDocs', new Map())); } + private function mergeExternalDocs(static $model, $overwrite = false) { + $this->externalDocs->merge($model->externalDocs, $overwrite); + } + /** * * @return ExternalDocs @@ -22,8 +26,8 @@ public function getExternalDocs() { /** * - * @param ExternalDocs $externalDocs - * @return $this + * @param ExternalDocs $externalDocs + * @return $this */ public function setExternalDocs(ExternalDocs $externalDocs) { $this->externalDocs = $externalDocs; diff --git a/src/parts/ItemsPart.php b/src/parts/ItemsPart.php index f0a500e..c91e24f 100644 --- a/src/parts/ItemsPart.php +++ b/src/parts/ItemsPart.php @@ -3,6 +3,7 @@ namespace gossi\swagger\parts; use gossi\swagger\Items; +use gossi\swagger\util\MergeHelper; use phootwork\collection\Map; trait ItemsPart { @@ -16,9 +17,17 @@ private function parseItems(Map $data) { } } + private function mergeItems(static $model, $overwrite = false) { + if (null === $this->items) { + $this->items = clone $model->items; + } elseif (null !== $model->items) { + $this->items->merge($model->items, $overwrite); + } + } + /** * Returns the items - * + * * @return Items */ public function getItems() { diff --git a/src/parts/ParametersPart.php b/src/parts/ParametersPart.php index 566ac63..0a2577e 100644 --- a/src/parts/ParametersPart.php +++ b/src/parts/ParametersPart.php @@ -2,6 +2,7 @@ namespace gossi\swagger\parts; use gossi\swagger\collections\Parameters; +use gossi\swagger\util\MergeHelper; use phootwork\collection\Map; trait ParametersPart { @@ -13,6 +14,10 @@ private function parseParameters(Map $data) { $this->parameters = new Parameters($data->get('parameters', new Map())); } + private function mergeParameters(static $model, $overwrite = false) { + $this->parameters->merge($model, $overwrite); + } + /** * Return parameters * diff --git a/src/parts/ProducesPart.php b/src/parts/ProducesPart.php index 0a2383e..efed53c 100644 --- a/src/parts/ProducesPart.php +++ b/src/parts/ProducesPart.php @@ -1,6 +1,7 @@ produces = $data->get('produces', new Set()); } + private function mergeProduces(static $model, $overwrite = false) { + MergeHelper::mergeFields($this->produces, $model->produces, $overwrite); + } + /** * Return produces * diff --git a/src/parts/RefPart.php b/src/parts/RefPart.php index 675432a..be99d47 100644 --- a/src/parts/RefPart.php +++ b/src/parts/RefPart.php @@ -1,6 +1,7 @@ ref = $data->get('$ref'); - $this->hasRef = $data->has('$ref'); + } + + private function mergeRef(static $model, $overwrite = false) { + MergeHelper::mergeFields($this->ref, $model->ref, $overwrite); } /** @@ -31,12 +32,11 @@ public function getRef() { */ public function setRef($ref) { $this->ref = $ref; - $this->hasRef = $ref !== null; return $this; } public function hasRef() { - return $this->hasRef; + return null !== $this->ref; } } diff --git a/src/parts/RequiredPart.php b/src/parts/RequiredPart.php index 627e035..cccd259 100644 --- a/src/parts/RequiredPart.php +++ b/src/parts/RequiredPart.php @@ -1,15 +1,20 @@ required = $data->has('required') && $data->get('required'); + $this->required = $data->get('required'); + } + + private function mergeRequired(static $model, $overwrite = false) { + MergeHelper::mergeFields($this->required, $model->required, $overwrite); } /** @@ -17,12 +22,12 @@ private function parseRequired(Map $data) { * @return bool */ public function getRequired() { - return $this->required; + return null !== $this->required ? $this->required : false; } /** * - * @param bool $required + * @param bool|null $required * @return $this */ public function setRequired($required) { diff --git a/src/parts/ResponsesPart.php b/src/parts/ResponsesPart.php index 8ec965c..d25160a 100644 --- a/src/parts/ResponsesPart.php +++ b/src/parts/ResponsesPart.php @@ -2,6 +2,7 @@ namespace gossi\swagger\parts; use gossi\swagger\collections\Responses; +use gossi\swagger\util\MergeHelper; use phootwork\collection\Map; trait ResponsesPart { @@ -13,6 +14,10 @@ private function parseResponses(Map $data) { $this->responses = new Responses($data->get('responses', new Map())); } + private function mergeResponses(static $model, $overwrite = false) { + $this->responses->merge($model->responses, $overwrite); + } + /** * Return responses * diff --git a/src/parts/SchemaPart.php b/src/parts/SchemaPart.php index 095f79a..1522700 100644 --- a/src/parts/SchemaPart.php +++ b/src/parts/SchemaPart.php @@ -2,6 +2,7 @@ namespace gossi\swagger\parts; use gossi\swagger\Schema; +use gossi\swagger\util\MergeHelper; use phootwork\collection\Map; trait SchemaPart { @@ -13,6 +14,10 @@ private function parseSchema(Map $data) { $this->schema = new Schema($data->get('schema')); } + private function mergeSchema(static $model, $overwrite = false) { + $this->schema->merge($model->schema, $overwrite); + } + /** * * @return Schema diff --git a/src/parts/SchemesPart.php b/src/parts/SchemesPart.php index e435655..68c5d3a 100644 --- a/src/parts/SchemesPart.php +++ b/src/parts/SchemesPart.php @@ -1,6 +1,7 @@ schemes = $data->get('schemes', new ArrayList()); } + private function mergeSchemes(static $model, $overwrite = false) { + $this->schemes->addAll($model->schemes); + } + /** * Return schemes * diff --git a/src/parts/TagsPart.php b/src/parts/TagsPart.php index 5da31b0..5d0fe89 100644 --- a/src/parts/TagsPart.php +++ b/src/parts/TagsPart.php @@ -2,6 +2,7 @@ namespace gossi\swagger\parts; use gossi\swagger\Tag; +use gossi\swagger\util\MergeHelper; use phootwork\collection\ArrayList; use phootwork\collection\Map; @@ -16,6 +17,23 @@ private function parseTags(Map $data) { } } + private function mergeTags(static $model, $overwrite = false) { + $newTags = []; + foreach ($model->tags as $tag) { + $find = $this->tags->find(function(Tag $element) use ($tag) { + return $tag->getName() === $element->getName(); + }); + + if (null !== $find) { + $find->merge($tag, $overwrite); + } else { + $newTags[] = new Tag($tag->toArray()); + } + } + + $this->tags->addAll($newTags); + } + /** * Return tags * diff --git a/src/parts/TypePart.php b/src/parts/TypePart.php index e555d13..29e7ed5 100644 --- a/src/parts/TypePart.php +++ b/src/parts/TypePart.php @@ -1,6 +1,7 @@ collectionFormat = $data->get('collectionFormat'); $this->default = $data->get('default'); $this->maximum = $data->get('maximum'); - $this->exclusiveMaximum = $data->has('exclusiveMaximum') && $data->get('exclusiveMaximum'); + $this->exclusiveMaximum = $data->get('exclusiveMaximum'); $this->minimum = $data->get('minimum'); - $this->exclusiveMinimum = $data->has('exclusiveMinimum') && $data->get('exclusiveMinimum'); + $this->exclusiveMinimum = $data->get('exclusiveMinimum'); $this->maxLength = $data->get('maxLength'); $this->minLength = $data->get('minLength'); $this->pattern = $data->get('pattern'); $this->maxItems = $data->get('maxItems'); $this->minItems = $data->get('minItems'); - $this->uniqueItems = $data->has('uniqueItems') && $data->get('uniqueItems'); + $this->uniqueItems = $data->get('uniqueItems'); $this->enum = $data->get('enum'); $this->multipleOf = $data->get('multipleOf'); } + private function mergeType(static $model, $overwrite = false) { + MergeHelper::mergeFields($this->type, $model->type, $overwrite); + MergeHelper::mergeFields($this->format, $model->format, $overwrite); + MergeHelper::mergeFields($this->collectionFormat, $model->collectionFormat, $overwrite); + MergeHelper::mergeFields($this->default, $model->default, $overwrite); + MergeHelper::mergeFields($this->maximum, $model->maximum, $overwrite); + MergeHelper::mergeFields($this->exclusiveMaximum, $model->exclusiveMaximum, $overwrite); + MergeHelper::mergeFields($this->minimum, $model->minimum, $overwrite); + MergeHelper::mergeFields($this->exclusiveMinimum, $model->exclusiveMinimum, $overwrite); + MergeHelper::mergeFields($this->maxLength, $model->maxLength, $overwrite); + MergeHelper::mergeFields($this->minLength, $model->minLength, $overwrite); + MergeHelper::mergeFields($this->pattern, $model->pattern, $overwrite); + MergeHelper::mergeFields($this->maxItems, $model->maxItems, $overwrite); + MergeHelper::mergeFields($this->minItems, $model->minItems, $overwrite); + MergeHelper::mergeFields($this->uniqueItems, $model->uniqueItems, $overwrite); + MergeHelper::mergeFields($this->enum, $model->enum, $overwrite); + MergeHelper::mergeFields($this->multipleOf, $model->multipleOf, $overwrite); + } + private function getTypeExportFields() { return ['type', 'format', 'collectionFormat', 'default', 'maximum', 'exclusiveMaximum', 'minimum', 'exclusiveMinimum', 'maxLength', 'minLength', 'pattern', 'maxItems', @@ -126,17 +146,17 @@ public function getCollectionFormat() { /** * Determines the format of the array if type array is used. Possible values are: - * + * * - `csv` - comma separated values `foo,bar`. * - `ssv` - space separated values `foo bar`. * - `tsv` - tab separated values `foo\tbar`. * - `pipes` - pipe separated values `foo|bar`. - * - `multi` - corresponds to multiple parameter instances instead of multiple values for a + * - `multi` - corresponds to multiple parameter instances instead of multiple values for a * single instance `foo=bar&foo=baz`. This is valid only for parameters in "query" or "formData". - * + * * Default value is `csv`. - * - * + * + * * @param string $collectionFormat * @return $this */ @@ -186,7 +206,7 @@ public function setMaximum($maximum) { * @return bool */ public function isExclusiveMaximum() { - return $this->exclusiveMaximum; + return null !== $this->exclusiveMaximum ? $this->exclusiveMaximum : false; } /** @@ -222,7 +242,7 @@ public function setMinimum($minimum) { * @return bool */ public function isExclusiveMinimum() { - return $this->exclusiveMinimum; + return null !== $this->exclusiveMinimum ? $this->exclusiveMinimum : false; } /** diff --git a/src/parts/UrlPart.php b/src/parts/UrlPart.php index 6534e01..f2411b8 100644 --- a/src/parts/UrlPart.php +++ b/src/parts/UrlPart.php @@ -1,17 +1,22 @@ url = $data->get('url'); } + private function mergeUrl(static $model, $overwrite = false) { + MergeHelper::mergeFields($this->url, $model->url, $overwrite); + } + /** * * @return string diff --git a/src/util/MergeHelper.php b/src/util/MergeHelper.php new file mode 100644 index 0000000..7c8f8b9 --- /dev/null +++ b/src/util/MergeHelper.php @@ -0,0 +1,35 @@ + $value) { + if ($overwrite || !$original->has($key)) { + $original->set($key, $value); + } + } + } elseif ($original instanceof Set) { + foreach ($external as $value) { + $original->add($value); + } + } else { // if scalar + if ($overwrite) { + $original = null !== $external ? $external : $original; + } else { + $original = null === $original ? $external : $original; + } + } + } +}