diff --git a/lib/Assert/Assertion.php b/lib/Assert/Assertion.php index 472f1928..38159e6f 100644 --- a/lib/Assert/Assertion.php +++ b/lib/Assert/Assertion.php @@ -28,6 +28,7 @@ * @method static void nullOrInteger($value, $message = null, $propertyPath = null) * @method static void nullOrFloat($value, $message = null, $propertyPath = null) * @method static void nullOrDigit($value, $message = null, $propertyPath = null) + * @method static void nullOrDate($value, $message = null, $propertyPath = null) * @method static void nullOrIntegerish($value, $message = null, $propertyPath = null) * @method static void nullOrBoolean($value, $message = null, $propertyPath = null) * @method static void nullOrScalar($value, $message = null, $propertyPath = null) @@ -50,9 +51,13 @@ * @method static void nullOrIsTraversable($value, $message = null, $propertyPath = null) * @method static void nullOrIsArrayAccessible($value, $message = null, $propertyPath = null) * @method static void nullOrKeyExists($value, $key, $message = null, $propertyPath = null) + * @method static void nullOrKeysExist($value, $keys, $message = null, $propertyPath = null) * @method static void nullOrKeyIsset($value, $key, $message = null, $propertyPath = null) + * @method static void nullOrPropertyExists($value, $key, $message = null, $propertyPath = null) + * @method static void nullOrPropertiesExist($value, $keys, $message = null, $propertyPath = null) * @method static void nullOrNotEmptyKey($value, $key, $message = null, $propertyPath = null) * @method static void nullOrNotBlank($value, $message = null, $propertyPath = null) + * @method static void nullOrIsCallable($value, $message = null, $propertyPath = null) * @method static void nullOrIsInstanceOf($value, $className, $message = null, $propertyPath = null) * @method static void nullOrNotIsInstanceOf($value, $className, $message = null, $propertyPath = null) * @method static void nullOrSubclassOf($value, $className, $message = null, $propertyPath = null) @@ -76,6 +81,7 @@ * @method static void nullOrChoicesNotEmpty($values, $choices, $message = null, $propertyPath = null) * @method static void nullOrMethodExists($value, $object, $message = null, $propertyPath = null) * @method static void nullOrIsObject($value, $message = null, $propertyPath = null) + * @method static void nullOrUtf8($value, $message = null, $propertyPath = null) * @method static void allEq($value, $value2, $message = null, $propertyPath = null) * @method static void allSame($value, $value2, $message = null, $propertyPath = null) * @method static void allNotEq($value1, $value2, $message = null, $propertyPath = null) @@ -83,6 +89,7 @@ * @method static void allInteger($value, $message = null, $propertyPath = null) * @method static void allFloat($value, $message = null, $propertyPath = null) * @method static void allDigit($value, $message = null, $propertyPath = null) + * @method static void allDate($value, $message = null, $propertyPath = null) * @method static void allIntegerish($value, $message = null, $propertyPath = null) * @method static void allBoolean($value, $message = null, $propertyPath = null) * @method static void allScalar($value, $message = null, $propertyPath = null) @@ -105,9 +112,13 @@ * @method static void allIsTraversable($value, $message = null, $propertyPath = null) * @method static void allIsArrayAccessible($value, $message = null, $propertyPath = null) * @method static void allKeyExists($value, $key, $message = null, $propertyPath = null) + * @method static void allKeysExist($value, $keys, $message = null, $propertyPath = null) * @method static void allKeyIsset($value, $key, $message = null, $propertyPath = null) + * @method static void allPropertyExists($value, $key, $message = null, $propertyPath = null) + * @method static void allPropertiesExist($value, $keys, $message = null, $propertyPath = null) * @method static void allNotEmptyKey($value, $key, $message = null, $propertyPath = null) * @method static void allNotBlank($value, $message = null, $propertyPath = null) + * @method static void allIsCallable($value, $message = null, $propertyPath = null) * @method static void allIsInstanceOf($value, $className, $message = null, $propertyPath = null) * @method static void allNotIsInstanceOf($value, $className, $message = null, $propertyPath = null) * @method static void allSubclassOf($value, $className, $message = null, $propertyPath = null) @@ -131,6 +142,7 @@ * @method static void allChoicesNotEmpty($values, $choices, $message = null, $propertyPath = null) * @method static void allMethodExists($value, $object, $message = null, $propertyPath = null) * @method static void allIsObject($value, $message = null, $propertyPath = null) + * @method static void allUtf8($value, $message = null, $propertyPath = null) * METHODEND */ class Assertion @@ -186,7 +198,12 @@ class Assertion const INVALID_OBJECT = 207; const INVALID_METHOD = 208; const INVALID_SCALAR = 209; - + const INVALID_DATE = 210; + const INVALID_CALLABLE = 211; + const INVALID_KEYS_EXIST = 300; + const INVALID_PROPERTY_EXISTS = 301; + const INVALID_PROPERTIES_EXIST = 302; + const INVALID_UTF8 = 303; /** * Exception to throw when an assertion failed. * @@ -205,6 +222,11 @@ protected static function createException($value, $message, $code, $propertyPath return new $exceptionClass($message, $code, $propertyPath, $value, $constraints); } + public static function setExceptionClass($exceptionClass) + { + static::$exceptionClass = $exceptionClass; + } + /** * Assert that two values are equal (using == ). * @@ -358,6 +380,27 @@ public static function digit($value, $message = null, $propertyPath = null) } } + /** + * Validates if an string is a date . + * + * @param string $value + * @param string|null $message + * @param string|null $propertyPath + * @return void + * @throws \Assert\AssertionFailedException + */ + public static function date($value, $message=null, $propertyPath=null) + { + if ( strtotime($value) === false ) + { + $message = sprintf( + $message ?: 'Value "%s" is not a date.', + self::stringify($value) + ); + throw static::createException($value, $message, static::INVALID_DATE, $propertyPath); + } + } + /** * Assert that value is a php integer'ish. * @param mixed $value @@ -878,6 +921,110 @@ public static function keyExists($value, $key, $message = null, $propertyPath = } } + /** + * Assert that keys exist in array + * + * @param mixed $value + * @param string|integer $key + * @param string|null $message + * @param string|null $propertyPath + * @return void + * @throws \Assert\AssertionFailedException + */ + public static function keysExist($value, $keys, $message = null, $propertyPath = null) + { + static::isArray($value, $message, $propertyPath); + + foreach ( $keys as $key ) { + + if ( ! array_key_exists($key, $value)) { + $message = $message ?: sprintf( + 'Array does not contain an element with key "%s"', + self::stringify($key) + ); + + throw static::createException($value, $message, static::INVALID_KEYS_EXIST, $propertyPath, array('key' => $key)); + } + } + + } + + /** + * Assert that property exists in array + * + * @param mixed $value + * @param string|integer $key + * @param string|null $message + * @param string|null $propertyPath + * @return void + * @throws \Assert\AssertionFailedException + */ + public static function propertyExists($value, $key, $message = null, $propertyPath = null) + { + static::isObject($value); + + if ( ! property_exists($value, $key) && ! isset($value->$key) ) { + $message = $message ?: sprintf( + 'Object does not contain an property with key "%s"', + self::stringify($key) + ); + + throw static::createException($value, $message, static::INVALID_PROPERTY_EXISTS, $propertyPath, array('key' => $key)); + + } + } + + /** + * Assert that properties exists in array + * + * @param mixed $value + * @param array $keys + * @param string|null $message + * @param string|null $propertyPath + * @return void + * @throws \Assert\AssertionFailedException + */ + public static function propertiesExist($value, array $keys, $message = null, $propertyPath = null) + { + static::isObject($value); + foreach ($keys as $key ) + { + // Using isset to allow resolution of magically defined properties + if ( ! property_exists($value, $key) && ! isset($value->$key) ) + { + $message = $message ?: sprintf( + 'Object does not contain an property with key "%s"', + self::stringify($key) + ); + throw static::createException($value, $message, static::INVALID_PROPERTIES_EXIST, $propertyPath, array('key' => $key)); + } + } + } + + /** + * Assert that string is valid utf8 + * + * @param mixed $value + * @param string|null $message + * @param string|null $propertyPath + * @return void + * @throws \Assert\AssertionFailedException + */ + public static function utf8($value, $message = null, $propertyPath = null) + { + static::string($value, $message, $propertyPath); + + if ( mb_detect_encoding($value, 'UTF-8', true) !== 'UTF-8' ) { + $message = $message ?: sprintf( + 'Value "%s" was expected to be a valid UTF8 string', + self::stringify($value) + ); + + throw static::createException($value, $message, static::INVALID_UTF8, $propertyPath); + } + + } + /** * Assert that key exists in an array/array-accessible object using isset() * diff --git a/lib/Assert/AssertionChain.php b/lib/Assert/AssertionChain.php index 7689558a..37e04592 100644 --- a/lib/Assert/AssertionChain.php +++ b/lib/Assert/AssertionChain.php @@ -29,6 +29,7 @@ * @method \Assert\AssertionChain integer($message = null, $propertyPath = null) * @method \Assert\AssertionChain float($message = null, $propertyPath = null) * @method \Assert\AssertionChain digit($message = null, $propertyPath = null) + * @method \Assert\AssertionChain date($message = null, $propertyPath = null) * @method \Assert\AssertionChain integerish($message = null, $propertyPath = null) * @method \Assert\AssertionChain boolean($message = null, $propertyPath = null) * @method \Assert\AssertionChain scalar($message = null, $propertyPath = null) @@ -49,8 +50,12 @@ * @method \Assert\AssertionChain numeric($message = null, $propertyPath = null) * @method \Assert\AssertionChain isArray($message = null, $propertyPath = null) * @method \Assert\AssertionChain keyExists($key, $message = null, $propertyPath = null) + * @method \Assert\AssertionChain keysExist($keys, $message = null, $propertyPath = null) + * @method \Assert\AssertionChain propertyExists($key, $message = null, $propertyPath = null) + * @method \Assert\AssertionChain propertiesExist($keys, $message = null, $propertyPath = null) * @method \Assert\AssertionChain notEmptyKey($key, $message = null, $propertyPath = null) * @method \Assert\AssertionChain notBlank($message = null, $propertyPath = null) + * @method \Assert\AssertionChain isCallable($message = null, $propertyPath = null) * @method \Assert\AssertionChain isInstanceOf($className, $message = null, $propertyPath = null) * @method \Assert\AssertionChain notIsInstanceOf($className, $message = null, $propertyPath = null) * @method \Assert\AssertionChain subclassOf($className, $message = null, $propertyPath = null) @@ -74,6 +79,7 @@ * @method \Assert\AssertionChain choicesNotEmpty($choices, $message = null, $propertyPath = null) * @method \Assert\AssertionChain methodExists($object, $message = null, $propertyPath = null) * @method \Assert\AssertionChain isObject($message = null, $propertyPath = null) + * @method \Assert\AssertionChain utf8($message = null, $propertyPath = null) * METHODEND */ class AssertionChain diff --git a/lib/Assert/LazyAssertion.php b/lib/Assert/LazyAssertion.php index a6352b3a..90f305f6 100644 --- a/lib/Assert/LazyAssertion.php +++ b/lib/Assert/LazyAssertion.php @@ -26,6 +26,7 @@ * @method \Assert\LazyAssertion integer($message = null, $propertyPath = null) * @method \Assert\LazyAssertion float($message = null, $propertyPath = null) * @method \Assert\LazyAssertion digit($message = null, $propertyPath = null) + * @method \Assert\LazyAssertion date($message = null, $propertyPath = null) * @method \Assert\LazyAssertion integerish($message = null, $propertyPath = null) * @method \Assert\LazyAssertion boolean($message = null, $propertyPath = null) * @method \Assert\LazyAssertion scalar($message = null, $propertyPath = null) @@ -46,8 +47,12 @@ * @method \Assert\LazyAssertion numeric($message = null, $propertyPath = null) * @method \Assert\LazyAssertion isArray($message = null, $propertyPath = null) * @method \Assert\LazyAssertion keyExists($key, $message = null, $propertyPath = null) + * @method \Assert\LazyAssertion keysExist($keys, $message = null, $propertyPath = null) + * @method \Assert\LazyAssertion propertyExists($key, $message = null, $propertyPath = null) + * @method \Assert\LazyAssertion propertiesExist($keys, $message = null, $propertyPath = null) * @method \Assert\LazyAssertion notEmptyKey($key, $message = null, $propertyPath = null) * @method \Assert\LazyAssertion notBlank($message = null, $propertyPath = null) + * @method \Assert\LazyAssertion isCallable($message = null, $propertyPath = null) * @method \Assert\LazyAssertion isInstanceOf($className, $message = null, $propertyPath = null) * @method \Assert\LazyAssertion notIsInstanceOf($className, $message = null, $propertyPath = null) * @method \Assert\LazyAssertion subclassOf($className, $message = null, $propertyPath = null) @@ -71,6 +76,7 @@ * @method \Assert\LazyAssertion choicesNotEmpty($choices, $message = null, $propertyPath = null) * @method \Assert\LazyAssertion methodExists($object, $message = null, $propertyPath = null) * @method \Assert\LazyAssertion isObject($message = null, $propertyPath = null) + * @method \Assert\LazyAssertion utf8($message = null, $propertyPath = null) * @method \Assert\LazyAssertion all() * @method \Assert\LazyAssertion nullOr() * METHODEND diff --git a/tests/Assert/Tests/AssertTest.php b/tests/Assert/Tests/AssertTest.php index 4c973d1a..dbb46c92 100644 --- a/tests/Assert/Tests/AssertTest.php +++ b/tests/Assert/Tests/AssertTest.php @@ -358,6 +358,15 @@ public function testValidNumeric() Assertion::numeric(1.23); } + public function testValidUtf8() + { + $text = 'Française señor café 0123 කොහොමද ශ්‍රී ලංකා hello Žluťoučký kůň ' + . 'ÀÁÂ,ÃÄÅ,Æ,ÇÈ,ÉÊË,ÌÍÎ,ÏÐÑ,ÒÓÔ,ÕÖØ,ÙÚÛ,ÜÝ,Þ,' + . 'ß,àáâ,ãäå,æ,çèé,êëì,íîï,ðñò,óôõ,öøù,úûýý,þ,ÿŔŕ ' + . 'YA(亚) HE(何) Tra Mỹ'; + Assertion::utf8($text); + } + public static function dataInvalidArray() { return array(