Skip to content

Instantly share code, notes, and snippets.

@Nessworthy
Created October 7, 2016 09:09
Show Gist options
  • Save Nessworthy/a794adcc52f2ad24caa2d5f5101000c3 to your computer and use it in GitHub Desktop.
Save Nessworthy/a794adcc52f2ad24caa2d5f5101000c3 to your computer and use it in GitHub Desktop.
<?php
namespace Parts\Restrictions;
interface MaxLength
{
/**
* Return the required minimum length of this type.
* @return int A positive integer.
*/
function getMaxLength();
}
<?php
namespace Parts\Restrictions;
interface MinLength
{
/**
* Return the required minimum length of this type.
* @return int A positive integer.
*/
function getMinLength();
}
<?php
namespace Parts\Restrictions;
interface Pattern
{
/**
* Return the regex pattern this data must match.
* @return string A regular expression.
*/
function getPattern();
}
<?php
namespace Parts\Content;
use Parts\Primitive\StringType;
use Parts\Restrictions\MaxLength;
use Parts\Restrictions\MinLength;
use Parts\Restrictions\Pattern;
/**
* Class PostcodeText
* Holds a UK postcode.
* @package Parts\Content
*/
class PostcodeText extends StringType implements MaxLength, MinLength, Pattern
{
/**
* @inheritDoc
*/
public function getMinLength()
{
return 1;
}
/**
* @inheritDoc
*/
public function getMaxLength()
{
return 8;
}
/**
* @inheritDoc
*/
public function getPattern()
{
return '#^[A-Z]{1,2}[0-9R][0-9A-Z]? [0-9][A-Z]{2}$#';
}
}
<?php
namespace Parts\Primitive;
use Parts\InvalidPrimitiveTypeException;
use Parts\Restrictions\Enumeration;
use Parts\Restrictions\MaxLength;
use Parts\Restrictions\MinLength;
use Parts\Restrictions\Pattern;
use Parts\ValidationRestrictionException;
/**
* The base type to represent a string.
* @package Parts\Primitive
*/
class StringType extends BaseSimpleType
{
/**
* Convert the data into a more suitable form.
* @param mixed $var
* @return string
*/
protected function convertType($var)
{
/**
* Possible php string conversions.
* Props to user mpen of StackOverflow
* @link http://stackoverflow.com/a/27368848/2274710
*/
if($var === null || is_scalar($var) || is_callable([$var, '__toString']))
{
return (string) $var;
}
throw new InvalidPrimitiveTypeException(sprintf(
'%s expected a string or type which can be converted to string, %s given.',
get_class($this),
gettype($var)
));
}
/**
* StringType constructor.
* @param string $string A text string.
*/
public function __construct($string) {
$className = get_class($this);
$string = $this->convertType($string);
if($this instanceof MinLength) {
$length = strlen($string);
$minLength = $this->getMinLength();
if($length < $minLength) {
throw new ValidationRestrictionException(sprintf(
'%s expected a string of at least %s character%s, %s given.',
$className,
$minLength,
$minLength === 1 ? '' : 's',
$length
));
}
}
if($this instanceof MaxLength) {
$length = strlen($string);
$maxLength = $this->getMaxLength();
if($length > $maxLength) {
throw new ValidationRestrictionException(sprintf(
'%s expected a string of at most %s character%s, %s given.',
$className,
$maxLength,
$maxLength === 1 ? '' : 's',
$length
));
}
}
if($this instanceof Pattern) {
$pattern = $this->getPattern();
if(preg_match($pattern, $string) !== 1) {
throw new ValidationRestrictionException(sprintf(
'%s expected a string matching the pattern ' . "\n" . '%s.',
$className,
$pattern
));
}
}
if($this instanceof Enumeration) {
$choices = $this->getEnumerableChoices();
if(!in_array($string, $choices, true)) {
throw new ValidationRestrictionException(sprintf(
'%s expected one of the following choices: %s, "%s" given',
$className,
implode(', ', $choices),
$string
));
}
}
return parent::__construct($string);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment