Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.11.0
### Added
- Support for date-time format in type string

## 0.10.3
### Fixed
- IntegerValidator unnecessary casting to float causing overflow
- IntegerValidator unnecessary casting to float causing overflow
100 changes: 100 additions & 0 deletions src/Formats/DateTime.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?php

namespace Phramework\Validate\Formats;

use Phramework\Exceptions\IncorrectParametersException;
use Phramework\Validate\ValidateResult;

/**
* Class DateTime
*
* @author Alex Kalliontzis <alkallio@gmail.com>
* @internal Helper class for internal use
* @since 0.11.0
*/
class DateTime
{
const REGEX = '/^(?<year>\d{4})-(?<month>0[1-9]|1[0-2])-(?<day>0[1-9]|[12][0-9]|3[01])' .
'T([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)' .
'(Z|(\+|-)([01][0-9]|2[0-3]):([0-5][0-9]))$/i';

public function validateFormat(
string $data,
string $type,
\stdClass $formatProperties
): ValidateResult {
$matches = [];
if (!preg_match(self::REGEX, $data, $matches)) {
return new ValidateResult(
$data,
false,
new IncorrectParametersException([
[
'type' => $type,
'failure' => 'date-time',
],
])
);
}

//Check if date is valid. This is needed because DateTime
//will parse an invalid date like 2019-02-31
if (!checkdate((int)$matches ['month'], (int) $matches['day'], (int) $matches['year'])) {
return new ValidateResult(
$data,
false,
new IncorrectParametersException([
[
'type' => $type,
'failure' => 'date-time',
],
])
);
}

$date = (new \DateTime($data))->getTimestamp();

if ($formatProperties->formatMinimum !== null) {
$formatMinimum = (new \DateTime(
$formatProperties->formatMinimum
))->getTimestamp();

if ($date < $formatMinimum) {
return new ValidateResult(
$data,
false,
new IncorrectParametersException([
[
'type' => $type,
'failure' => 'formatMinimum',
]
])
);
}
}

if ($formatProperties->formatMaximum !== null) {
$formatMaximum = (new \DateTime(
$formatProperties->formatMaximum
))->getTimestamp();

if ($date > $formatMaximum) {
return new ValidateResult(
$data,
false,
new IncorrectParametersException([
[
'type' => $type,
'failure' => 'formatMaximum',
]
])
);
}
}

return new ValidateResult(
$data,
true
);
}
}
44 changes: 44 additions & 0 deletions src/Formats/StringFormatValidatorValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Phramework\Validate\Formats;

use Phramework\Validate\IFormatValidator;
use Phramework\Validate\ValidateResult;

/**
* Validates that a property of type 'string' and format
* 'date-time' is an RFC3339 formatted string
*
* @author Alex Kalliontzis <alkallio@gmail.com>
* @since 0.11.0
*/
class StringFormatValidatorValidator implements IFormatValidator
{
protected static $type = 'string';

public function validateFormat(
string $data,
string $format,
\stdClass $formatProperties = null
): ValidateResult {
$validateResult = new ValidateResult(
$data,
true
);

switch ($format) {
case 'date-time':
//Todo Create a TDO for formatProperties
$validateResult = (new DateTime())
->validateFormat(
$data,
self::$type,
$formatProperties
);

break;
}

return $validateResult;
}
}
18 changes: 18 additions & 0 deletions src/IFormatValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Phramework\Validate;

/**
* Interface IFormatValidator
*
* @author Alex Kalliontzis <alkallio@gmail.com>
* @since 0.11.0
*/
interface IFormatValidator
{
public function validateFormat(
string $data,
string $format,
\stdClass $formatProperties = null
): ValidateResult;
}
51 changes: 49 additions & 2 deletions src/StringValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
* @author Xenofon Spafaridis <nohponex@gmail.com>
* @since 0.0.0
* @see ECMA 262 regular expression dialect for regular expression pattern
* @version 0.11.0 Added support for date-time format
*/
class StringValidator extends \Phramework\Validate\BaseValidator
{
Expand All @@ -42,9 +43,30 @@ class StringValidator extends \Phramework\Validate\BaseValidator
'minLength',
'maxLength',
'pattern',
'raw' //non standard
'raw', //non standard,
'format',
'formatMaximum', //proposed
'formatMinimum' //proposed
];

/**
* @param string|null $formatMaximum
* Maximum allowed value for specified format
*/
public function setFormatMaximum(string $formatMaximum)
{
$this->formatMaximum = $formatMaximum;
}

/**
* @param string|null $formatMinimum
* Minimum allowed value for specified format
*/
public function setFormatMinimum(string $formatMinimum)
{
$this->formatMinimum = $formatMinimum;
}

/**
* @param integer $minLength *[Optional]*
* Minimum number of its characters, default is 0
Expand All @@ -54,13 +76,16 @@ class StringValidator extends \Phramework\Validate\BaseValidator
* Regular expression pattern for validating, default is null
* @param boolean $raw *[Optional]*
* Keep raw value, don't sanitize value after validation, default is false
* @param string $format *[Optional]*
* Validate if string is formatted according to specified format
* @throws \Exception
*/
public function __construct(
$minLength = 0,
$maxLength = null,
$pattern = null,
$raw = false
$raw = false,
$format = null
) {
parent::__construct();

Expand All @@ -76,6 +101,9 @@ public function __construct(
$this->maxLength = $maxLength;
$this->pattern = $pattern;
$this->raw = $raw;
$this->format = $format;
$this->formatMinimum = null;
$this->formatMaximum = null;
}

/**
Expand All @@ -90,6 +118,20 @@ public function validate($value)
{
$return = new ValidateResult($value, false);

$formatValidator = new Formats\StringFormatValidatorValidator();

if ($this->format !== null) {
$formatValidatorResult = $formatValidator
->validateFormat(
$value,
$this->format,
(object)[
'formatMinimum' => $this->formatMinimum,
'formatMaximum' => $this->formatMaximum,
]
);
}

if (!is_string($value)) {
//error
$return->errorObject = new IncorrectParametersException([
Expand Down Expand Up @@ -132,6 +174,11 @@ public function validate($value)
'failure' => 'pattern'
]
]);
} elseif ($this->format !== null
&& $formatValidatorResult->status === false
) {
$return->errorObject =
$formatValidatorResult->errorObject;
} else {
$return->errorObject = null;
//Set status to success
Expand Down
Loading