Skip to content

Commit

Permalink
add writeOnly/readOnly keywords, nullable keyword
Browse files Browse the repository at this point in the history
  • Loading branch information
lezhnev74 committed May 1, 2019
1 parent c7e7ce2 commit be9e455
Show file tree
Hide file tree
Showing 27 changed files with 298 additions and 81 deletions.
2 changes: 1 addition & 1 deletion src/Schema/Keywords/AdditionalProperties.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
namespace OpenAPIValidation\Schema\Keywords;


class AdditionalProperties
class AdditionalProperties extends BaseKeyword
{
public function validate($data, bool $additionalProperties): void
{
Expand Down
2 changes: 1 addition & 1 deletion src/Schema/Keywords/AllOf.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
use OpenAPIValidation\Schema\Validator as SchemaValidator;
use Respect\Validation\Validator;

class AllOf
class AllOf extends BaseKeyword
{
/**
* This keyword's value MUST be an array. This array MUST have at least
Expand Down
2 changes: 1 addition & 1 deletion src/Schema/Keywords/AnyOf.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
use OpenAPIValidation\Schema\Validator as SchemaValidator;
use Respect\Validation\Validator;

class AnyOf
class AnyOf extends BaseKeyword
{
/**
* This keyword's value MUST be an array. This array MUST have at least
Expand Down
33 changes: 33 additions & 0 deletions src/Schema/Keywords/BaseKeyword.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php
/**
* @author Dmitry Lezhnev <[email protected]>
* Date: 01 May 2019
*/
declare(strict_types=1);


namespace OpenAPIValidation\Schema\Keywords;


use cebe\openapi\spec\Schema as CebeSchema;
use OpenAPIValidation\Schema\Validator;

abstract class BaseKeyword
{
/** @var CebeSchema */
protected $parentSchema;
/** @var Validator */
protected $parentSchemaValidator;

/**
* @param CebeSchema $parentSchema
* @param Validator $parentSchemaValidator
*/
public function __construct(CebeSchema $parentSchema, Validator $parentSchemaValidator)
{
$this->parentSchema = $parentSchema;
$this->parentSchemaValidator = $parentSchemaValidator;
}


}
43 changes: 43 additions & 0 deletions src/Schema/Keywords/Descriminator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
/**
* @author Dmitry Lezhnev <[email protected]>
* Date: 01 May 2019
*/
declare(strict_types=1);


namespace OpenAPIValidation\Schema\Keywords;


use OpenAPIValidation\Schema\Exception\ValidationKeywordFailed;
use Respect\Validation\Validator;

class Descriminator extends BaseKeyword
{
/**
* The value of this keyword MUST be an array. This array SHOULD have
* at least one element. Elements in the array SHOULD be unique.
*
* Elements in the array MAY be of any type, including null.
*
* An instance validates successfully against this keyword if its value
* is equal to one of the elements in this keyword's array value.
*
* @param $data
* @param array $enum
*/
public function validate($data, array $enum): void
{
try {
Validator::arrayType()->assert($enum);
Validator::trueVal()->assert(count($enum) >= 1);

if (!in_array($data, $enum, true)) {
throw new \Exception(sprintf("Value must be present in the enum"));
}

} catch (\Throwable $e) {
throw ValidationKeywordFailed::fromKeyword("enum", $data, $e->getMessage());
}
}
}
2 changes: 1 addition & 1 deletion src/Schema/Keywords/Enum.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use OpenAPIValidation\Schema\Exception\ValidationKeywordFailed;
use Respect\Validation\Validator;

class Enum
class Enum extends BaseKeyword
{
/**
* The value of this keyword MUST be an array. This array SHOULD have
Expand Down
14 changes: 1 addition & 13 deletions src/Schema/Keywords/Items.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,8 @@
use OpenAPIValidation\Schema\Validator as SchemaValidator;
use Respect\Validation\Validator;

class Items
class Items extends BaseKeyword
{
/** @var CebeSchema */
protected $parentSchema;

/**
* @param CebeSchema $parentSchema
*/
public function __construct(CebeSchema $parentSchema)
{
$this->parentSchema = $parentSchema;
}


/**
* Value MUST be an object and not an array.
* Inline or referenced schema MUST be of a Schema Object and not a standard JSON Schema.
Expand Down
2 changes: 1 addition & 1 deletion src/Schema/Keywords/MaxItems.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use OpenAPIValidation\Schema\Exception\ValidationKeywordFailed;
use Respect\Validation\Validator;

class MaxItems
class MaxItems extends BaseKeyword
{
/**
* The value of this keyword MUST be an integer. This integer MUST be
Expand Down
2 changes: 1 addition & 1 deletion src/Schema/Keywords/MaxLength.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use OpenAPIValidation\Schema\Exception\ValidationKeywordFailed;
use Respect\Validation\Validator;

class MaxLength
class MaxLength extends BaseKeyword
{
/**
* The value of this keyword MUST be a non-negative integer.
Expand Down
2 changes: 1 addition & 1 deletion src/Schema/Keywords/MaxProperties.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use OpenAPIValidation\Schema\Exception\ValidationKeywordFailed;
use Respect\Validation\Validator;

class MaxProperties
class MaxProperties extends BaseKeyword
{
/**
* The value of this keyword MUST be an integer. This integer MUST be
Expand Down
2 changes: 1 addition & 1 deletion src/Schema/Keywords/Maximum.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use OpenAPIValidation\Schema\Exception\ValidationKeywordFailed;
use Respect\Validation\Validator;

class Maximum
class Maximum extends BaseKeyword
{
/**
* The value of "maximum" MUST be a number, representing an upper limit
Expand Down
2 changes: 1 addition & 1 deletion src/Schema/Keywords/MinItems.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use OpenAPIValidation\Schema\Exception\ValidationKeywordFailed;
use Respect\Validation\Validator;

class MinItems
class MinItems extends BaseKeyword
{
/**
* The value of this keyword MUST be an integer. This integer MUST be
Expand Down
2 changes: 1 addition & 1 deletion src/Schema/Keywords/MinLength.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use OpenAPIValidation\Schema\Exception\ValidationKeywordFailed;
use Respect\Validation\Validator;

class MinLength
class MinLength extends BaseKeyword
{
/**
* A string instance is valid against this keyword if its length is
Expand Down
2 changes: 1 addition & 1 deletion src/Schema/Keywords/MinProperties.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use OpenAPIValidation\Schema\Exception\ValidationKeywordFailed;
use Respect\Validation\Validator;

class MinProperties
class MinProperties extends BaseKeyword
{
/**
* The value of this keyword MUST be an integer. This integer MUST be
Expand Down
2 changes: 1 addition & 1 deletion src/Schema/Keywords/Minimum.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use OpenAPIValidation\Schema\Exception\ValidationKeywordFailed;
use Respect\Validation\Validator;

class Minimum
class Minimum extends BaseKeyword
{
/**
* The value of "minimum" MUST be a number, representing a lower limit
Expand Down
2 changes: 1 addition & 1 deletion src/Schema/Keywords/MultipleOf.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use OpenAPIValidation\Schema\Exception\ValidationKeywordFailed;
use Respect\Validation\Validator;

class MultipleOf
class MultipleOf extends BaseKeyword
{
/**
* The value of "multipleOf" MUST be a number, strictly greater than 0.
Expand Down
2 changes: 1 addition & 1 deletion src/Schema/Keywords/Not.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
use OpenAPIValidation\Schema\Validator as SchemaValidator;
use Respect\Validation\Validator;

class Not
class Not extends BaseKeyword
{
/**
* This keyword's value MUST be an object.
Expand Down
34 changes: 34 additions & 0 deletions src/Schema/Keywords/Nullable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php
/**
* @author Dmitry Lezhnev <[email protected]>
* Date: 01 May 2019
*/
declare(strict_types=1);


namespace OpenAPIValidation\Schema\Keywords;


use OpenAPIValidation\Schema\Exception\ValidationKeywordFailed;

class Nullable extends BaseKeyword
{
/**
* Allows sending a null value for the defined schema. Default value is false.
*
* @param $data
* @param bool $nullable
*/
public function validate($data, bool $nullable): void
{
try {
if (!$nullable && ($data === null)) {
throw new \Exception("Value cannot be null");
}


} catch (\Throwable $e) {
throw ValidationKeywordFailed::fromKeyword("nullable", $data, $e->getMessage());
}
}
}
2 changes: 1 addition & 1 deletion src/Schema/Keywords/OneOf.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
use OpenAPIValidation\Schema\Validator as SchemaValidator;
use Respect\Validation\Validator;

class OneOf
class OneOf extends BaseKeyword
{
/**
* This keyword's value MUST be an array. This array MUST have at least
Expand Down
2 changes: 1 addition & 1 deletion src/Schema/Keywords/Pattern.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use OpenAPIValidation\Schema\Exception\ValidationKeywordFailed;
use Respect\Validation\Validator;

class Pattern
class Pattern extends BaseKeyword
{
/**
* The value of this keyword MUST be a string. This string SHOULD be a
Expand Down
18 changes: 3 additions & 15 deletions src/Schema/Keywords/Properties.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,8 @@
use Respect\Validation\Validator;


class Properties
class Properties extends BaseKeyword
{
/** @var CebeSchema */
protected $parentSchema;

/**
* @param CebeSchema $parentSchema
*/
public function __construct(CebeSchema $parentSchema)
{
$this->parentSchema = $parentSchema;
}


/**
* Property definitions MUST be a Schema Object and not a standard JSON Schema (inline or referenced).
* If absent, it can be considered the same as an empty object.
Expand Down Expand Up @@ -71,7 +59,7 @@ public function validate($data, $properties, $additionalProperties): void
// Validate against "properties"
foreach ($properties as $propName => $propSchema) {
if (property_exists($data, $propName)) {
$schemaValidator = new SchemaValidator($propSchema, $data->$propName);
$schemaValidator = new SchemaValidator($propSchema, $data->$propName, $this->parentSchemaValidator->dataType());
$schemaValidator->validate();
}
}
Expand All @@ -80,7 +68,7 @@ public function validate($data, $properties, $additionalProperties): void
if ($additionalProperties instanceof CebeSchema) {
foreach ($data as $propName => $propSchema) {
if (!isset($properties[$propName])) { # if not covered by "properties"
$schemaValidator = new SchemaValidator($additionalProperties, $data->$propName);
$schemaValidator = new SchemaValidator($additionalProperties, $data->$propName, $this->parentSchemaValidator->dataType());
$schemaValidator->validate();
}
}
Expand Down
22 changes: 21 additions & 1 deletion src/Schema/Keywords/Required.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use OpenAPIValidation\Schema\Exception\ValidationKeywordFailed;
use Respect\Validation\Validator;

class Required
class Required extends BaseKeyword
{
/**
* The value of this keyword MUST be an array. This array MUST have at
Expand All @@ -33,13 +33,33 @@ public function validate($data, $required): void
Validator::each(Validator::stringType())->assert($required);
Validator::trueVal()->assert(count(array_unique($required)) === count($required));

if ($this->parentSchema->type !== "object") {
throw new \Exception(sprintf("Required keyword only works with type=object, but %s found", $this->parentSchema->type));
}

foreach ($required as $reqProperty) {
$propertyFound = false;
foreach ($data as $property => $value) {
$propertyFound = $propertyFound || ($reqProperty === $property);
}

if (!$propertyFound) {

# respect writeOnly/readOnly keywords
if (
(
$this->parentSchema->properties[$reqProperty]->writeOnly &&
$this->parentSchemaValidator->dataType() == \OpenAPIValidation\Schema\Validator::VALIDATE_AS_RESPONSE
)
||
(
$this->parentSchema->properties[$reqProperty]->readOnly &&
$this->parentSchemaValidator->dataType() == \OpenAPIValidation\Schema\Validator::VALIDATE_AS_REQUEST
)
) {
continue;
}

throw new \Exception(sprintf("Required property %s must be present in the object", $reqProperty));
}
}
Expand Down
17 changes: 5 additions & 12 deletions src/Schema/Keywords/Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,8 @@
use OpenAPIValidation\Schema\Exception\ValidationKeywordFailed;
use Respect\Validation\Validator;

class Type
class Type extends BaseKeyword
{
/** @var CebeSchema */
protected $parentSchema;

/**
* @param CebeSchema $parentSchema
*/
public function __construct(CebeSchema $parentSchema)
{
$this->parentSchema = $parentSchema;
}

/**
* The value of this keyword MUST be either a string ONLY.
*
Expand All @@ -52,6 +41,10 @@ public function validate($data, $type, $format = null): void
# Note that there is no null type; instead, the nullable attribute is used as a modifier of the base type.
])->stringType()->assert($type);

if ($this->parentSchema->nullable && $data === null) {
return;
}

switch ($type) {
case "boolean":
if (!is_bool($data)) {
Expand Down
Loading

0 comments on commit be9e455

Please sign in to comment.