Assertion.php 111 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603
  1. <?php
  2. /**
  3. * Assert
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the MIT license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * If you did not receive a copy of the license and are unable to
  10. * obtain it through the world-wide-web, please send an email
  11. * to kontakt@beberlei.de so I can send you a copy immediately.
  12. */
  13. namespace Assert;
  14. use BadMethodCallException;
  15. /**
  16. * Assert library.
  17. *
  18. * @author Benjamin Eberlei <kontakt@beberlei.de>
  19. *
  20. * @method static bool allAlnum(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is alphanumeric for all values.
  21. * @method static bool allBase64(string $value, string|callable $message = null, string $propertyPath = null) Assert that a constant is defined for all values.
  22. * @method static bool allBetween(mixed $value, mixed $lowerLimit, mixed $upperLimit, string $message = null, string $propertyPath = null) Assert that a value is greater or equal than a lower limit, and less than or equal to an upper limit for all values.
  23. * @method static bool allBetweenExclusive(mixed $value, mixed $lowerLimit, mixed $upperLimit, string $message = null, string $propertyPath = null) Assert that a value is greater than a lower limit, and less than an upper limit for all values.
  24. * @method static bool allBetweenLength(mixed $value, int $minLength, int $maxLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string length is between min,max lengths for all values.
  25. * @method static bool allBoolean(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is php boolean for all values.
  26. * @method static bool allChoice(mixed $value, array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is in array of choices for all values.
  27. * @method static bool allChoicesNotEmpty(array $values, array $choices, string|callable $message = null, string $propertyPath = null) Determines if the values array has every choice as key and that this choice has content for all values.
  28. * @method static bool allClassExists(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that the class exists for all values.
  29. * @method static bool allContains(mixed $string, string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string contains a sequence of chars for all values.
  30. * @method static bool allCount(array|\Countable $countable, int $count, string $message = null, string $propertyPath = null) Assert that the count of countable is equal to count for all values.
  31. * @method static bool allDate(string $value, string $format, string|callable $message = null, string $propertyPath = null) Assert that date is valid and corresponds to the given format for all values.
  32. * @method static bool allDefined(mixed $constant, string|callable $message = null, string $propertyPath = null) Assert that a constant is defined for all values.
  33. * @method static bool allDigit(mixed $value, string|callable $message = null, string $propertyPath = null) Validates if an integer or integerish is a digit for all values.
  34. * @method static bool allDirectory(string $value, string|callable $message = null, string $propertyPath = null) Assert that a directory exists for all values.
  35. * @method static bool allE164(string $value, string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid E164 Phone Number for all values.
  36. * @method static bool allEmail(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is an email address (using input_filter/FILTER_VALIDATE_EMAIL) for all values.
  37. * @method static bool allEndsWith(mixed $string, string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string ends with a sequence of chars for all values.
  38. * @method static bool allEq(mixed $value, mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are equal (using == ) for all values.
  39. * @method static bool allExtensionLoaded(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that extension is loaded for all values.
  40. * @method static bool allExtensionVersion(string $extension, string $operator, mixed $version, string|callable $message = null, string $propertyPath = null) Assert that extension is loaded and a specific version is installed for all values.
  41. * @method static bool allFalse(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that the value is boolean False for all values.
  42. * @method static bool allFile(string $value, string|callable $message = null, string $propertyPath = null) Assert that a file exists for all values.
  43. * @method static bool allFloat(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is a php float for all values.
  44. * @method static bool allGreaterOrEqualThan(mixed $value, mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is greater or equal than given limit for all values.
  45. * @method static bool allGreaterThan(mixed $value, mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is greater than given limit for all values.
  46. * @method static bool allImplementsInterface(mixed $class, string $interfaceName, string|callable $message = null, string $propertyPath = null) Assert that the class implements the interface for all values.
  47. * @method static bool allInArray(mixed $value, array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is in array of choices. This is an alias of Assertion::choice() for all values.
  48. * @method static bool allInteger(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is a php integer for all values.
  49. * @method static bool allIntegerish(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is a php integer'ish for all values.
  50. * @method static bool allInterfaceExists(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that the interface exists for all values.
  51. * @method static bool allIp(string $value, int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv4 or IPv6 address for all values.
  52. * @method static bool allIpv4(string $value, int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv4 address for all values.
  53. * @method static bool allIpv6(string $value, int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv6 address for all values.
  54. * @method static bool allIsArray(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is an array for all values.
  55. * @method static bool allIsArrayAccessible(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is an array or an array-accessible object for all values.
  56. * @method static bool allIsCallable(mixed $value, string|callable $message = null, string $propertyPath = null) Determines that the provided value is callable for all values.
  57. * @method static bool allIsInstanceOf(mixed $value, string $className, string|callable $message = null, string $propertyPath = null) Assert that value is instance of given class-name for all values.
  58. * @method static bool allIsJsonString(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid json string for all values.
  59. * @method static bool allIsObject(mixed $value, string|callable $message = null, string $propertyPath = null) Determines that the provided value is an object for all values.
  60. * @method static bool allIsResource(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is a resource for all values.
  61. * @method static bool allIsTraversable(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is an array or a traversable object for all values.
  62. * @method static bool allKeyExists(mixed $value, string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array for all values.
  63. * @method static bool allKeyIsset(mixed $value, string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array/array-accessible object using isset() for all values.
  64. * @method static bool allKeyNotExists(mixed $value, string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key does not exist in an array for all values.
  65. * @method static bool allLength(mixed $value, int $length, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string has a given length for all values.
  66. * @method static bool allLessOrEqualThan(mixed $value, mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is less or equal than given limit for all values.
  67. * @method static bool allLessThan(mixed $value, mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is less than given limit for all values.
  68. * @method static bool allMax(mixed $value, mixed $maxValue, string|callable $message = null, string $propertyPath = null) Assert that a number is smaller as a given limit for all values.
  69. * @method static bool allMaxLength(mixed $value, int $maxLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string value is not longer than $maxLength chars for all values.
  70. * @method static bool allMethodExists(string $value, mixed $object, string|callable $message = null, string $propertyPath = null) Determines that the named method is defined in the provided object for all values.
  71. * @method static bool allMin(mixed $value, mixed $minValue, string|callable $message = null, string $propertyPath = null) Assert that a value is at least as big as a given limit for all values.
  72. * @method static bool allMinLength(mixed $value, int $minLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that a string is at least $minLength chars long for all values.
  73. * @method static bool allNoContent(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is empty for all values.
  74. * @method static bool allNotBlank(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is not blank for all values.
  75. * @method static bool allNotEmpty(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is not empty for all values.
  76. * @method static bool allNotEmptyKey(mixed $value, string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array/array-accessible object and its value is not empty for all values.
  77. * @method static bool allNotEq(mixed $value1, mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are not equal (using == ) for all values.
  78. * @method static bool allNotInArray(mixed $value, array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is not in array of choices for all values.
  79. * @method static bool allNotIsInstanceOf(mixed $value, string $className, string|callable $message = null, string $propertyPath = null) Assert that value is not instance of given class-name for all values.
  80. * @method static bool allNotNull(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is not null for all values.
  81. * @method static bool allNotSame(mixed $value1, mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are not the same (using === ) for all values.
  82. * @method static bool allNull(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is null for all values.
  83. * @method static bool allNumeric(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is numeric for all values.
  84. * @method static bool allObjectOrClass(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that the value is an object, or a class that exists for all values.
  85. * @method static bool allPhpVersion(string $operator, mixed $version, string|callable $message = null, string $propertyPath = null) Assert on PHP version for all values.
  86. * @method static bool allPropertiesExist(mixed $value, array $properties, string|callable $message = null, string $propertyPath = null) Assert that the value is an object or class, and that the properties all exist for all values.
  87. * @method static bool allPropertyExists(mixed $value, string $property, string|callable $message = null, string $propertyPath = null) Assert that the value is an object or class, and that the property exists for all values.
  88. * @method static bool allRange(mixed $value, mixed $minValue, mixed $maxValue, string|callable $message = null, string $propertyPath = null) Assert that value is in range of numbers for all values.
  89. * @method static bool allReadable(string $value, string|callable $message = null, string $propertyPath = null) Assert that the value is something readable for all values.
  90. * @method static bool allRegex(mixed $value, string $pattern, string|callable $message = null, string $propertyPath = null) Assert that value matches a regex for all values.
  91. * @method static bool allSame(mixed $value, mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are the same (using ===) for all values.
  92. * @method static bool allSatisfy(mixed $value, callable $callback, string|callable $message = null, string $propertyPath = null) Assert that the provided value is valid according to a callback for all values.
  93. * @method static bool allScalar(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is a PHP scalar for all values.
  94. * @method static bool allStartsWith(mixed $string, string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string starts with a sequence of chars for all values.
  95. * @method static bool allString(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is a string for all values.
  96. * @method static bool allSubclassOf(mixed $value, string $className, string|callable $message = null, string $propertyPath = null) Assert that value is subclass of given class-name for all values.
  97. * @method static bool allTrue(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that the value is boolean True for all values.
  98. * @method static bool allUrl(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is an URL for all values.
  99. * @method static bool allUuid(string $value, string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid UUID for all values.
  100. * @method static bool allVersion(string $version1, string $operator, string $version2, string|callable $message = null, string $propertyPath = null) Assert comparison of two versions for all values.
  101. * @method static bool allWriteable(string $value, string|callable $message = null, string $propertyPath = null) Assert that the value is something writeable for all values.
  102. * @method static bool nullOrAlnum(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is alphanumeric or that the value is null.
  103. * @method static bool nullOrBase64(string $value, string|callable $message = null, string $propertyPath = null) Assert that a constant is defined or that the value is null.
  104. * @method static bool nullOrBetween(mixed $value, mixed $lowerLimit, mixed $upperLimit, string $message = null, string $propertyPath = null) Assert that a value is greater or equal than a lower limit, and less than or equal to an upper limit or that the value is null.
  105. * @method static bool nullOrBetweenExclusive(mixed $value, mixed $lowerLimit, mixed $upperLimit, string $message = null, string $propertyPath = null) Assert that a value is greater than a lower limit, and less than an upper limit or that the value is null.
  106. * @method static bool nullOrBetweenLength(mixed $value, int $minLength, int $maxLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string length is between min,max lengths or that the value is null.
  107. * @method static bool nullOrBoolean(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is php boolean or that the value is null.
  108. * @method static bool nullOrChoice(mixed $value, array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is in array of choices or that the value is null.
  109. * @method static bool nullOrChoicesNotEmpty(array $values, array $choices, string|callable $message = null, string $propertyPath = null) Determines if the values array has every choice as key and that this choice has content or that the value is null.
  110. * @method static bool nullOrClassExists(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that the class exists or that the value is null.
  111. * @method static bool nullOrContains(mixed $string, string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string contains a sequence of chars or that the value is null.
  112. * @method static bool nullOrCount(array|\Countable $countable, int $count, string $message = null, string $propertyPath = null) Assert that the count of countable is equal to count or that the value is null.
  113. * @method static bool nullOrDate(string $value, string $format, string|callable $message = null, string $propertyPath = null) Assert that date is valid and corresponds to the given format or that the value is null.
  114. * @method static bool nullOrDefined(mixed $constant, string|callable $message = null, string $propertyPath = null) Assert that a constant is defined or that the value is null.
  115. * @method static bool nullOrDigit(mixed $value, string|callable $message = null, string $propertyPath = null) Validates if an integer or integerish is a digit or that the value is null.
  116. * @method static bool nullOrDirectory(string $value, string|callable $message = null, string $propertyPath = null) Assert that a directory exists or that the value is null.
  117. * @method static bool nullOrE164(string $value, string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid E164 Phone Number or that the value is null.
  118. * @method static bool nullOrEmail(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is an email address (using input_filter/FILTER_VALIDATE_EMAIL) or that the value is null.
  119. * @method static bool nullOrEndsWith(mixed $string, string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string ends with a sequence of chars or that the value is null.
  120. * @method static bool nullOrEq(mixed $value, mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are equal (using == ) or that the value is null.
  121. * @method static bool nullOrExtensionLoaded(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that extension is loaded or that the value is null.
  122. * @method static bool nullOrExtensionVersion(string $extension, string $operator, mixed $version, string|callable $message = null, string $propertyPath = null) Assert that extension is loaded and a specific version is installed or that the value is null.
  123. * @method static bool nullOrFalse(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that the value is boolean False or that the value is null.
  124. * @method static bool nullOrFile(string $value, string|callable $message = null, string $propertyPath = null) Assert that a file exists or that the value is null.
  125. * @method static bool nullOrFloat(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is a php float or that the value is null.
  126. * @method static bool nullOrGreaterOrEqualThan(mixed $value, mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is greater or equal than given limit or that the value is null.
  127. * @method static bool nullOrGreaterThan(mixed $value, mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is greater than given limit or that the value is null.
  128. * @method static bool nullOrImplementsInterface(mixed $class, string $interfaceName, string|callable $message = null, string $propertyPath = null) Assert that the class implements the interface or that the value is null.
  129. * @method static bool nullOrInArray(mixed $value, array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is in array of choices. This is an alias of Assertion::choice() or that the value is null.
  130. * @method static bool nullOrInteger(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is a php integer or that the value is null.
  131. * @method static bool nullOrIntegerish(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is a php integer'ish or that the value is null.
  132. * @method static bool nullOrInterfaceExists(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that the interface exists or that the value is null.
  133. * @method static bool nullOrIp(string $value, int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv4 or IPv6 address or that the value is null.
  134. * @method static bool nullOrIpv4(string $value, int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv4 address or that the value is null.
  135. * @method static bool nullOrIpv6(string $value, int $flag = null, string|callable $message = null, string $propertyPath = null) Assert that value is an IPv6 address or that the value is null.
  136. * @method static bool nullOrIsArray(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is an array or that the value is null.
  137. * @method static bool nullOrIsArrayAccessible(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is an array or an array-accessible object or that the value is null.
  138. * @method static bool nullOrIsCallable(mixed $value, string|callable $message = null, string $propertyPath = null) Determines that the provided value is callable or that the value is null.
  139. * @method static bool nullOrIsInstanceOf(mixed $value, string $className, string|callable $message = null, string $propertyPath = null) Assert that value is instance of given class-name or that the value is null.
  140. * @method static bool nullOrIsJsonString(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid json string or that the value is null.
  141. * @method static bool nullOrIsObject(mixed $value, string|callable $message = null, string $propertyPath = null) Determines that the provided value is an object or that the value is null.
  142. * @method static bool nullOrIsResource(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is a resource or that the value is null.
  143. * @method static bool nullOrIsTraversable(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is an array or a traversable object or that the value is null.
  144. * @method static bool nullOrKeyExists(mixed $value, string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array or that the value is null.
  145. * @method static bool nullOrKeyIsset(mixed $value, string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array/array-accessible object using isset() or that the value is null.
  146. * @method static bool nullOrKeyNotExists(mixed $value, string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key does not exist in an array or that the value is null.
  147. * @method static bool nullOrLength(mixed $value, int $length, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string has a given length or that the value is null.
  148. * @method static bool nullOrLessOrEqualThan(mixed $value, mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is less or equal than given limit or that the value is null.
  149. * @method static bool nullOrLessThan(mixed $value, mixed $limit, string|callable $message = null, string $propertyPath = null) Determines if the value is less than given limit or that the value is null.
  150. * @method static bool nullOrMax(mixed $value, mixed $maxValue, string|callable $message = null, string $propertyPath = null) Assert that a number is smaller as a given limit or that the value is null.
  151. * @method static bool nullOrMaxLength(mixed $value, int $maxLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string value is not longer than $maxLength chars or that the value is null.
  152. * @method static bool nullOrMethodExists(string $value, mixed $object, string|callable $message = null, string $propertyPath = null) Determines that the named method is defined in the provided object or that the value is null.
  153. * @method static bool nullOrMin(mixed $value, mixed $minValue, string|callable $message = null, string $propertyPath = null) Assert that a value is at least as big as a given limit or that the value is null.
  154. * @method static bool nullOrMinLength(mixed $value, int $minLength, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that a string is at least $minLength chars long or that the value is null.
  155. * @method static bool nullOrNoContent(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is empty or that the value is null.
  156. * @method static bool nullOrNotBlank(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is not blank or that the value is null.
  157. * @method static bool nullOrNotEmpty(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is not empty or that the value is null.
  158. * @method static bool nullOrNotEmptyKey(mixed $value, string|int $key, string|callable $message = null, string $propertyPath = null) Assert that key exists in an array/array-accessible object and its value is not empty or that the value is null.
  159. * @method static bool nullOrNotEq(mixed $value1, mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are not equal (using == ) or that the value is null.
  160. * @method static bool nullOrNotInArray(mixed $value, array $choices, string|callable $message = null, string $propertyPath = null) Assert that value is not in array of choices or that the value is null.
  161. * @method static bool nullOrNotIsInstanceOf(mixed $value, string $className, string|callable $message = null, string $propertyPath = null) Assert that value is not instance of given class-name or that the value is null.
  162. * @method static bool nullOrNotNull(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is not null or that the value is null.
  163. * @method static bool nullOrNotSame(mixed $value1, mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are not the same (using === ) or that the value is null.
  164. * @method static bool nullOrNull(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is null or that the value is null.
  165. * @method static bool nullOrNumeric(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is numeric or that the value is null.
  166. * @method static bool nullOrObjectOrClass(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that the value is an object, or a class that exists or that the value is null.
  167. * @method static bool nullOrPhpVersion(string $operator, mixed $version, string|callable $message = null, string $propertyPath = null) Assert on PHP version or that the value is null.
  168. * @method static bool nullOrPropertiesExist(mixed $value, array $properties, string|callable $message = null, string $propertyPath = null) Assert that the value is an object or class, and that the properties all exist or that the value is null.
  169. * @method static bool nullOrPropertyExists(mixed $value, string $property, string|callable $message = null, string $propertyPath = null) Assert that the value is an object or class, and that the property exists or that the value is null.
  170. * @method static bool nullOrRange(mixed $value, mixed $minValue, mixed $maxValue, string|callable $message = null, string $propertyPath = null) Assert that value is in range of numbers or that the value is null.
  171. * @method static bool nullOrReadable(string $value, string|callable $message = null, string $propertyPath = null) Assert that the value is something readable or that the value is null.
  172. * @method static bool nullOrRegex(mixed $value, string $pattern, string|callable $message = null, string $propertyPath = null) Assert that value matches a regex or that the value is null.
  173. * @method static bool nullOrSame(mixed $value, mixed $value2, string|callable $message = null, string $propertyPath = null) Assert that two values are the same (using ===) or that the value is null.
  174. * @method static bool nullOrSatisfy(mixed $value, callable $callback, string|callable $message = null, string $propertyPath = null) Assert that the provided value is valid according to a callback or that the value is null.
  175. * @method static bool nullOrScalar(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is a PHP scalar or that the value is null.
  176. * @method static bool nullOrStartsWith(mixed $string, string $needle, string|callable $message = null, string $propertyPath = null, string $encoding = 'utf8') Assert that string starts with a sequence of chars or that the value is null.
  177. * @method static bool nullOrString(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is a string or that the value is null.
  178. * @method static bool nullOrSubclassOf(mixed $value, string $className, string|callable $message = null, string $propertyPath = null) Assert that value is subclass of given class-name or that the value is null.
  179. * @method static bool nullOrTrue(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that the value is boolean True or that the value is null.
  180. * @method static bool nullOrUrl(mixed $value, string|callable $message = null, string $propertyPath = null) Assert that value is an URL or that the value is null.
  181. * @method static bool nullOrUuid(string $value, string|callable $message = null, string $propertyPath = null) Assert that the given string is a valid UUID or that the value is null.
  182. * @method static bool nullOrVersion(string $version1, string $operator, string $version2, string|callable $message = null, string $propertyPath = null) Assert comparison of two versions or that the value is null.
  183. * @method static bool nullOrWriteable(string $value, string|callable $message = null, string $propertyPath = null) Assert that the value is something writeable or that the value is null.
  184. */
  185. class Assertion
  186. {
  187. const INVALID_FLOAT = 9;
  188. const INVALID_INTEGER = 10;
  189. const INVALID_DIGIT = 11;
  190. const INVALID_INTEGERISH = 12;
  191. const INVALID_BOOLEAN = 13;
  192. const VALUE_EMPTY = 14;
  193. const VALUE_NULL = 15;
  194. const VALUE_NOT_NULL = 25;
  195. const INVALID_STRING = 16;
  196. const INVALID_REGEX = 17;
  197. const INVALID_MIN_LENGTH = 18;
  198. const INVALID_MAX_LENGTH = 19;
  199. const INVALID_STRING_START = 20;
  200. const INVALID_STRING_CONTAINS = 21;
  201. const INVALID_CHOICE = 22;
  202. const INVALID_NUMERIC = 23;
  203. const INVALID_ARRAY = 24;
  204. const INVALID_KEY_EXISTS = 26;
  205. const INVALID_NOT_BLANK = 27;
  206. const INVALID_INSTANCE_OF = 28;
  207. const INVALID_SUBCLASS_OF = 29;
  208. const INVALID_RANGE = 30;
  209. const INVALID_ALNUM = 31;
  210. const INVALID_TRUE = 32;
  211. const INVALID_EQ = 33;
  212. const INVALID_SAME = 34;
  213. const INVALID_MIN = 35;
  214. const INVALID_MAX = 36;
  215. const INVALID_LENGTH = 37;
  216. const INVALID_FALSE = 38;
  217. const INVALID_STRING_END = 39;
  218. const INVALID_UUID = 40;
  219. const INVALID_COUNT = 41;
  220. const INVALID_NOT_EQ = 42;
  221. const INVALID_NOT_SAME = 43;
  222. const INVALID_TRAVERSABLE = 44;
  223. const INVALID_ARRAY_ACCESSIBLE = 45;
  224. const INVALID_KEY_ISSET = 46;
  225. const INVALID_VALUE_IN_ARRAY = 47;
  226. const INVALID_E164 = 48;
  227. const INVALID_BASE64 = 49;
  228. const INVALID_DIRECTORY = 101;
  229. const INVALID_FILE = 102;
  230. const INVALID_READABLE = 103;
  231. const INVALID_WRITEABLE = 104;
  232. const INVALID_CLASS = 105;
  233. const INVALID_INTERFACE = 106;
  234. const INVALID_EMAIL = 201;
  235. const INTERFACE_NOT_IMPLEMENTED = 202;
  236. const INVALID_URL = 203;
  237. const INVALID_NOT_INSTANCE_OF = 204;
  238. const VALUE_NOT_EMPTY = 205;
  239. const INVALID_JSON_STRING = 206;
  240. const INVALID_OBJECT = 207;
  241. const INVALID_METHOD = 208;
  242. const INVALID_SCALAR = 209;
  243. const INVALID_LESS = 210;
  244. const INVALID_LESS_OR_EQUAL = 211;
  245. const INVALID_GREATER = 212;
  246. const INVALID_GREATER_OR_EQUAL = 213;
  247. const INVALID_DATE = 214;
  248. const INVALID_CALLABLE = 215;
  249. const INVALID_KEY_NOT_EXISTS = 216;
  250. const INVALID_SATISFY = 217;
  251. const INVALID_IP = 218;
  252. const INVALID_BETWEEN = 219;
  253. const INVALID_BETWEEN_EXCLUSIVE = 220;
  254. const INVALID_EXTENSION = 222;
  255. const INVALID_CONSTANT = 221;
  256. const INVALID_VERSION = 223;
  257. const INVALID_PROPERTY = 224;
  258. const INVALID_RESOURCE = 225;
  259. /**
  260. * Exception to throw when an assertion failed.
  261. *
  262. * @var string
  263. */
  264. protected static $exceptionClass = 'Assert\InvalidArgumentException';
  265. /**
  266. * Helper method that handles building the assertion failure exceptions.
  267. * They are returned from this method so that the stack trace still shows
  268. * the assertions method.
  269. *
  270. * @param mixed $value
  271. * @param string|callable $message
  272. * @param int $code
  273. * @param string|null $propertyPath
  274. * @param array $constraints
  275. *
  276. * @return mixed
  277. */
  278. protected static function createException($value, $message, $code, $propertyPath = null, array $constraints = array())
  279. {
  280. $exceptionClass = static::$exceptionClass;
  281. return new $exceptionClass($message, $code, $propertyPath, $value, $constraints);
  282. }
  283. /**
  284. * Assert that two values are equal (using == ).
  285. *
  286. * @param mixed $value
  287. * @param mixed $value2
  288. * @param string|callable|null $message
  289. * @param string|null $propertyPath
  290. *
  291. * @return bool
  292. *
  293. * @throws \Assert\AssertionFailedException
  294. */
  295. public static function eq($value, $value2, $message = null, $propertyPath = null)
  296. {
  297. if ($value != $value2) {
  298. $message = \sprintf(
  299. static::generateMessage($message ?: 'Value "%s" does not equal expected value "%s".'),
  300. static::stringify($value),
  301. static::stringify($value2)
  302. );
  303. throw static::createException($value, $message, static::INVALID_EQ, $propertyPath, array('expected' => $value2));
  304. }
  305. return true;
  306. }
  307. /**
  308. * Assert that two values are the same (using ===).
  309. *
  310. * @param mixed $value
  311. * @param mixed $value2
  312. * @param string|callable|null $message
  313. * @param string|null $propertyPath
  314. *
  315. * @return bool
  316. *
  317. * @throws \Assert\AssertionFailedException
  318. */
  319. public static function same($value, $value2, $message = null, $propertyPath = null)
  320. {
  321. if ($value !== $value2) {
  322. $message = \sprintf(
  323. static::generateMessage($message ?: 'Value "%s" is not the same as expected value "%s".'),
  324. static::stringify($value),
  325. static::stringify($value2)
  326. );
  327. throw static::createException($value, $message, static::INVALID_SAME, $propertyPath, array('expected' => $value2));
  328. }
  329. return true;
  330. }
  331. /**
  332. * Assert that two values are not equal (using == ).
  333. *
  334. * @param mixed $value1
  335. * @param mixed $value2
  336. * @param string|callable|null $message
  337. * @param string|null $propertyPath
  338. *
  339. * @return bool
  340. *
  341. * @throws \Assert\AssertionFailedException
  342. */
  343. public static function notEq($value1, $value2, $message = null, $propertyPath = null)
  344. {
  345. if ($value1 == $value2) {
  346. $message = \sprintf(
  347. static::generateMessage($message ?: 'Value "%s" is equal to expected value "%s".'),
  348. static::stringify($value1),
  349. static::stringify($value2)
  350. );
  351. throw static::createException($value1, $message, static::INVALID_NOT_EQ, $propertyPath, array('expected' => $value2));
  352. }
  353. return true;
  354. }
  355. /**
  356. * Assert that two values are not the same (using === ).
  357. *
  358. * @param mixed $value1
  359. * @param mixed $value2
  360. * @param string|callable|null $message
  361. * @param string|null $propertyPath
  362. *
  363. * @return bool
  364. *
  365. * @throws \Assert\AssertionFailedException
  366. */
  367. public static function notSame($value1, $value2, $message = null, $propertyPath = null)
  368. {
  369. if ($value1 === $value2) {
  370. $message = \sprintf(
  371. static::generateMessage($message ?: 'Value "%s" is the same as expected value "%s".'),
  372. static::stringify($value1),
  373. static::stringify($value2)
  374. );
  375. throw static::createException($value1, $message, static::INVALID_NOT_SAME, $propertyPath, array('expected' => $value2));
  376. }
  377. return true;
  378. }
  379. /**
  380. * Assert that value is not in array of choices.
  381. *
  382. * @param mixed $value
  383. * @param array $choices
  384. * @param string|callable|null $message
  385. * @param string|null $propertyPath
  386. *
  387. * @return bool
  388. *
  389. * @throws \Assert\AssertionFailedException
  390. */
  391. public static function notInArray($value, array $choices, $message = null, $propertyPath = null)
  392. {
  393. if (true === \in_array($value, $choices)) {
  394. $message = \sprintf(
  395. static::generateMessage($message ?: 'Value "%s" is in given "%s".'),
  396. static::stringify($value),
  397. static::stringify($choices)
  398. );
  399. throw static::createException($value, $message, static::INVALID_VALUE_IN_ARRAY, $propertyPath, array('choices' => $choices));
  400. }
  401. return true;
  402. }
  403. /**
  404. * Assert that value is a php integer.
  405. *
  406. * @param mixed $value
  407. * @param string|callable|null $message
  408. * @param string|null $propertyPath
  409. *
  410. * @return bool
  411. *
  412. * @throws \Assert\AssertionFailedException
  413. */
  414. public static function integer($value, $message = null, $propertyPath = null)
  415. {
  416. if (!\is_int($value)) {
  417. $message = \sprintf(
  418. static::generateMessage($message ?: 'Value "%s" is not an integer.'),
  419. static::stringify($value)
  420. );
  421. throw static::createException($value, $message, static::INVALID_INTEGER, $propertyPath);
  422. }
  423. return true;
  424. }
  425. /**
  426. * Assert that value is a php float.
  427. *
  428. * @param mixed $value
  429. * @param string|callable|null $message
  430. * @param string|null $propertyPath
  431. *
  432. * @return bool
  433. *
  434. * @throws \Assert\AssertionFailedException
  435. */
  436. public static function float($value, $message = null, $propertyPath = null)
  437. {
  438. if (!\is_float($value)) {
  439. $message = \sprintf(
  440. static::generateMessage($message ?: 'Value "%s" is not a float.'),
  441. static::stringify($value)
  442. );
  443. throw static::createException($value, $message, static::INVALID_FLOAT, $propertyPath);
  444. }
  445. return true;
  446. }
  447. /**
  448. * Validates if an integer or integerish is a digit.
  449. *
  450. * @param mixed $value
  451. * @param string|callable|null $message
  452. * @param string|null $propertyPath
  453. *
  454. * @return bool
  455. *
  456. * @throws \Assert\AssertionFailedException
  457. */
  458. public static function digit($value, $message = null, $propertyPath = null)
  459. {
  460. if (!\ctype_digit((string) $value)) {
  461. $message = \sprintf(
  462. static::generateMessage($message ?: 'Value "%s" is not a digit.'),
  463. static::stringify($value)
  464. );
  465. throw static::createException($value, $message, static::INVALID_DIGIT, $propertyPath);
  466. }
  467. return true;
  468. }
  469. /**
  470. * Assert that value is a php integer'ish.
  471. *
  472. * @param mixed $value
  473. * @param string|callable|null $message
  474. * @param string|null $propertyPath
  475. *
  476. * @return bool
  477. *
  478. * @throws \Assert\AssertionFailedException
  479. */
  480. public static function integerish($value, $message = null, $propertyPath = null)
  481. {
  482. if (
  483. \is_resource($value) ||
  484. \is_object($value) ||
  485. \is_bool($value) ||
  486. \is_null($value) ||
  487. \is_array($value) ||
  488. (\is_string($value) && '' == $value) ||
  489. (
  490. \strval(\intval($value)) !== \strval($value) &&
  491. \strval(\intval($value)) !== \strval(\ltrim($value, '0')) &&
  492. '' !== \strval(\intval($value)) &&
  493. '' !== \strval(\ltrim($value, '0'))
  494. )
  495. ) {
  496. $message = \sprintf(
  497. static::generateMessage($message ?: 'Value "%s" is not an integer or a number castable to integer.'),
  498. static::stringify($value)
  499. );
  500. throw static::createException($value, $message, static::INVALID_INTEGERISH, $propertyPath);
  501. }
  502. return true;
  503. }
  504. /**
  505. * Assert that value is php boolean.
  506. *
  507. * @param mixed $value
  508. * @param string|callable|null $message
  509. * @param string|null $propertyPath
  510. *
  511. * @return bool
  512. *
  513. * @throws \Assert\AssertionFailedException
  514. */
  515. public static function boolean($value, $message = null, $propertyPath = null)
  516. {
  517. if (!\is_bool($value)) {
  518. $message = \sprintf(
  519. static::generateMessage($message ?: 'Value "%s" is not a boolean.'),
  520. static::stringify($value)
  521. );
  522. throw static::createException($value, $message, static::INVALID_BOOLEAN, $propertyPath);
  523. }
  524. return true;
  525. }
  526. /**
  527. * Assert that value is a PHP scalar.
  528. *
  529. * @param mixed $value
  530. * @param string|callable|null $message
  531. * @param string|null $propertyPath
  532. *
  533. * @return bool
  534. *
  535. * @throws \Assert\AssertionFailedException
  536. */
  537. public static function scalar($value, $message = null, $propertyPath = null)
  538. {
  539. if (!\is_scalar($value)) {
  540. $message = \sprintf(
  541. static::generateMessage($message ?: 'Value "%s" is not a scalar.'),
  542. static::stringify($value)
  543. );
  544. throw static::createException($value, $message, static::INVALID_SCALAR, $propertyPath);
  545. }
  546. return true;
  547. }
  548. /**
  549. * Assert that value is not empty.
  550. *
  551. * @param mixed $value
  552. * @param string|callable|null $message
  553. * @param string|null $propertyPath
  554. *
  555. * @return bool
  556. *
  557. * @throws \Assert\AssertionFailedException
  558. */
  559. public static function notEmpty($value, $message = null, $propertyPath = null)
  560. {
  561. if (empty($value)) {
  562. $message = \sprintf(
  563. static::generateMessage($message ?: 'Value "%s" is empty, but non empty value was expected.'),
  564. static::stringify($value)
  565. );
  566. throw static::createException($value, $message, static::VALUE_EMPTY, $propertyPath);
  567. }
  568. return true;
  569. }
  570. /**
  571. * Assert that value is empty.
  572. *
  573. * @param mixed $value
  574. * @param string|callable|null $message
  575. * @param string|null $propertyPath
  576. *
  577. * @return bool
  578. *
  579. * @throws \Assert\AssertionFailedException
  580. */
  581. public static function noContent($value, $message = null, $propertyPath = null)
  582. {
  583. if (!empty($value)) {
  584. $message = \sprintf(
  585. static::generateMessage($message ?: 'Value "%s" is not empty, but empty value was expected.'),
  586. static::stringify($value)
  587. );
  588. throw static::createException($value, $message, static::VALUE_NOT_EMPTY, $propertyPath);
  589. }
  590. return true;
  591. }
  592. /**
  593. * Assert that value is null.
  594. *
  595. * @param mixed $value
  596. * @param string|callable|null $message
  597. * @param string|null $propertyPath
  598. *
  599. * @return bool
  600. *
  601. * @throws \Assert\AssertionFailedException
  602. */
  603. public static function null($value, $message = null, $propertyPath = null)
  604. {
  605. if (null !== $value) {
  606. $message = \sprintf(
  607. static::generateMessage($message ?: 'Value "%s" is not null, but null value was expected.'),
  608. static::stringify($value)
  609. );
  610. throw static::createException($value, $message, static::VALUE_NOT_NULL, $propertyPath);
  611. }
  612. return true;
  613. }
  614. /**
  615. * Assert that value is not null.
  616. *
  617. * @param mixed $value
  618. * @param string|callable|null $message
  619. * @param string|null $propertyPath
  620. *
  621. * @return bool
  622. *
  623. * @throws \Assert\AssertionFailedException
  624. */
  625. public static function notNull($value, $message = null, $propertyPath = null)
  626. {
  627. if (null === $value) {
  628. $message = \sprintf(
  629. static::generateMessage($message ?: 'Value "%s" is null, but non null value was expected.'),
  630. static::stringify($value)
  631. );
  632. throw static::createException($value, $message, static::VALUE_NULL, $propertyPath);
  633. }
  634. return true;
  635. }
  636. /**
  637. * Assert that value is a string.
  638. *
  639. * @param mixed $value
  640. * @param string|callable|null $message
  641. * @param string|null $propertyPath
  642. *
  643. * @return bool
  644. *
  645. * @throws \Assert\AssertionFailedException
  646. */
  647. public static function string($value, $message = null, $propertyPath = null)
  648. {
  649. if (!\is_string($value)) {
  650. $message = \sprintf(
  651. static::generateMessage($message ?: 'Value "%s" expected to be string, type %s given.'),
  652. static::stringify($value),
  653. \gettype($value)
  654. );
  655. throw static::createException($value, $message, static::INVALID_STRING, $propertyPath);
  656. }
  657. return true;
  658. }
  659. /**
  660. * Assert that value matches a regex.
  661. *
  662. * @param mixed $value
  663. * @param string $pattern
  664. * @param string|callable|null $message
  665. * @param string|null $propertyPath
  666. *
  667. * @return bool
  668. *
  669. * @throws \Assert\AssertionFailedException
  670. */
  671. public static function regex($value, $pattern, $message = null, $propertyPath = null)
  672. {
  673. static::string($value, $message, $propertyPath);
  674. if (!\preg_match($pattern, $value)) {
  675. $message = \sprintf(
  676. static::generateMessage($message ?: 'Value "%s" does not match expression.'),
  677. static::stringify($value)
  678. );
  679. throw static::createException($value, $message, static::INVALID_REGEX, $propertyPath, array('pattern' => $pattern));
  680. }
  681. return true;
  682. }
  683. /**
  684. * Assert that string has a given length.
  685. *
  686. * @param mixed $value
  687. * @param int $length
  688. * @param string|callable|null $message
  689. * @param string|null $propertyPath
  690. * @param string $encoding
  691. *
  692. * @return bool
  693. *
  694. * @throws \Assert\AssertionFailedException
  695. */
  696. public static function length($value, $length, $message = null, $propertyPath = null, $encoding = 'utf8')
  697. {
  698. static::string($value, $message, $propertyPath);
  699. if (\mb_strlen($value, $encoding) !== $length) {
  700. $message = \sprintf(
  701. static::generateMessage($message ?: 'Value "%s" has to be %d exactly characters long, but length is %d.'),
  702. static::stringify($value),
  703. $length,
  704. \mb_strlen($value, $encoding)
  705. );
  706. throw static::createException($value, $message, static::INVALID_LENGTH, $propertyPath, array('length' => $length, 'encoding' => $encoding));
  707. }
  708. return true;
  709. }
  710. /**
  711. * Assert that a string is at least $minLength chars long.
  712. *
  713. * @param mixed $value
  714. * @param int $minLength
  715. * @param string|callable|null $message
  716. * @param string|null $propertyPath
  717. * @param string $encoding
  718. *
  719. * @return bool
  720. *
  721. * @throws \Assert\AssertionFailedException
  722. */
  723. public static function minLength($value, $minLength, $message = null, $propertyPath = null, $encoding = 'utf8')
  724. {
  725. static::string($value, $message, $propertyPath);
  726. if (\mb_strlen($value, $encoding) < $minLength) {
  727. $message = \sprintf(
  728. static::generateMessage($message ?: 'Value "%s" is too short, it should have at least %d characters, but only has %d characters.'),
  729. static::stringify($value),
  730. $minLength,
  731. \mb_strlen($value, $encoding)
  732. );
  733. throw static::createException($value, $message, static::INVALID_MIN_LENGTH, $propertyPath, array('min_length' => $minLength, 'encoding' => $encoding));
  734. }
  735. return true;
  736. }
  737. /**
  738. * Assert that string value is not longer than $maxLength chars.
  739. *
  740. * @param mixed $value
  741. * @param int $maxLength
  742. * @param string|callable|null $message
  743. * @param string|null $propertyPath
  744. * @param string $encoding
  745. *
  746. * @return bool
  747. *
  748. * @throws \Assert\AssertionFailedException
  749. */
  750. public static function maxLength($value, $maxLength, $message = null, $propertyPath = null, $encoding = 'utf8')
  751. {
  752. static::string($value, $message, $propertyPath);
  753. if (\mb_strlen($value, $encoding) > $maxLength) {
  754. $message = \sprintf(
  755. static::generateMessage($message ?: 'Value "%s" is too long, it should have no more than %d characters, but has %d characters.'),
  756. static::stringify($value),
  757. $maxLength,
  758. \mb_strlen($value, $encoding)
  759. );
  760. throw static::createException($value, $message, static::INVALID_MAX_LENGTH, $propertyPath, array('max_length' => $maxLength, 'encoding' => $encoding));
  761. }
  762. return true;
  763. }
  764. /**
  765. * Assert that string length is between min,max lengths.
  766. *
  767. * @param mixed $value
  768. * @param int $minLength
  769. * @param int $maxLength
  770. * @param string|callable|null $message
  771. * @param string|null $propertyPath
  772. * @param string $encoding
  773. *
  774. * @return bool
  775. *
  776. * @throws \Assert\AssertionFailedException
  777. */
  778. public static function betweenLength($value, $minLength, $maxLength, $message = null, $propertyPath = null, $encoding = 'utf8')
  779. {
  780. static::string($value, $message, $propertyPath);
  781. static::minLength($value, $minLength, $message, $propertyPath, $encoding);
  782. static::maxLength($value, $maxLength, $message, $propertyPath, $encoding);
  783. return true;
  784. }
  785. /**
  786. * Assert that string starts with a sequence of chars.
  787. *
  788. * @param mixed $string
  789. * @param string $needle
  790. * @param string|callable|null $message
  791. * @param string|null $propertyPath
  792. * @param string $encoding
  793. *
  794. * @return bool
  795. *
  796. * @throws \Assert\AssertionFailedException
  797. */
  798. public static function startsWith($string, $needle, $message = null, $propertyPath = null, $encoding = 'utf8')
  799. {
  800. static::string($string, $message, $propertyPath);
  801. if (0 !== \mb_strpos($string, $needle, null, $encoding)) {
  802. $message = \sprintf(
  803. static::generateMessage($message ?: 'Value "%s" does not start with "%s".'),
  804. static::stringify($string),
  805. static::stringify($needle)
  806. );
  807. throw static::createException($string, $message, static::INVALID_STRING_START, $propertyPath, array('needle' => $needle, 'encoding' => $encoding));
  808. }
  809. return true;
  810. }
  811. /**
  812. * Assert that string ends with a sequence of chars.
  813. *
  814. * @param mixed $string
  815. * @param string $needle
  816. * @param string|callable|null $message
  817. * @param string|null $propertyPath
  818. * @param string $encoding
  819. *
  820. * @return bool
  821. *
  822. * @throws \Assert\AssertionFailedException
  823. */
  824. public static function endsWith($string, $needle, $message = null, $propertyPath = null, $encoding = 'utf8')
  825. {
  826. static::string($string, $message, $propertyPath);
  827. $stringPosition = \mb_strlen($string, $encoding) - \mb_strlen($needle, $encoding);
  828. if (\mb_strripos($string, $needle, null, $encoding) !== $stringPosition) {
  829. $message = \sprintf(
  830. static::generateMessage($message ?: 'Value "%s" does not end with "%s".'),
  831. static::stringify($string),
  832. static::stringify($needle)
  833. );
  834. throw static::createException($string, $message, static::INVALID_STRING_END, $propertyPath, array('needle' => $needle, 'encoding' => $encoding));
  835. }
  836. return true;
  837. }
  838. /**
  839. * Assert that string contains a sequence of chars.
  840. *
  841. * @param mixed $string
  842. * @param string $needle
  843. * @param string|callable|null $message
  844. * @param string|null $propertyPath
  845. * @param string $encoding
  846. *
  847. * @return bool
  848. *
  849. * @throws \Assert\AssertionFailedException
  850. */
  851. public static function contains($string, $needle, $message = null, $propertyPath = null, $encoding = 'utf8')
  852. {
  853. static::string($string, $message, $propertyPath);
  854. if (false === \mb_strpos($string, $needle, null, $encoding)) {
  855. $message = \sprintf(
  856. static::generateMessage($message ?: 'Value "%s" does not contain "%s".'),
  857. static::stringify($string),
  858. static::stringify($needle)
  859. );
  860. throw static::createException($string, $message, static::INVALID_STRING_CONTAINS, $propertyPath, array('needle' => $needle, 'encoding' => $encoding));
  861. }
  862. return true;
  863. }
  864. /**
  865. * Assert that value is in array of choices.
  866. *
  867. * @param mixed $value
  868. * @param array $choices
  869. * @param string|callable|null $message
  870. * @param string|null $propertyPath
  871. *
  872. * @return bool
  873. *
  874. * @throws \Assert\AssertionFailedException
  875. */
  876. public static function choice($value, array $choices, $message = null, $propertyPath = null)
  877. {
  878. if (!\in_array($value, $choices, true)) {
  879. $message = \sprintf(
  880. static::generateMessage($message ?: 'Value "%s" is not an element of the valid values: %s'),
  881. static::stringify($value),
  882. \implode(', ', \array_map(array(\get_called_class(), 'stringify'), $choices))
  883. );
  884. throw static::createException($value, $message, static::INVALID_CHOICE, $propertyPath, array('choices' => $choices));
  885. }
  886. return true;
  887. }
  888. /**
  889. * Assert that value is in array of choices.
  890. *
  891. * This is an alias of {@see choice()}.
  892. *
  893. * @param mixed $value
  894. * @param array $choices
  895. * @param string|callable|null $message
  896. * @param string|null $propertyPath
  897. *
  898. * @return bool
  899. */
  900. public static function inArray($value, array $choices, $message = null, $propertyPath = null)
  901. {
  902. return static::choice($value, $choices, $message, $propertyPath);
  903. }
  904. /**
  905. * Assert that value is numeric.
  906. *
  907. * @param mixed $value
  908. * @param string|callable|null $message
  909. * @param string|null $propertyPath
  910. *
  911. * @return bool
  912. *
  913. * @throws \Assert\AssertionFailedException
  914. */
  915. public static function numeric($value, $message = null, $propertyPath = null)
  916. {
  917. if (!\is_numeric($value)) {
  918. $message = \sprintf(
  919. static::generateMessage($message ?: 'Value "%s" is not numeric.'),
  920. static::stringify($value)
  921. );
  922. throw static::createException($value, $message, static::INVALID_NUMERIC, $propertyPath);
  923. }
  924. return true;
  925. }
  926. /**
  927. * Assert that value is a resource.
  928. *
  929. * @param mixed $value
  930. * @param string|callable|null $message
  931. * @param string|null $propertyPath
  932. *
  933. * @return bool
  934. *
  935. * @throws \Assert\AssertionFailedException
  936. */
  937. public static function isResource($value, $message = null, $propertyPath = null)
  938. {
  939. if (!\is_resource($value)) {
  940. $message = \sprintf(
  941. static::generateMessage($message ?: 'Value "%s" is not a resource.'),
  942. static::stringify($value)
  943. );
  944. throw static::createException($value, $message, static::INVALID_RESOURCE, $propertyPath);
  945. }
  946. return true;
  947. }
  948. /**
  949. * Assert that value is an array.
  950. *
  951. * @param mixed $value
  952. * @param string|callable|null $message
  953. * @param string|null $propertyPath
  954. *
  955. * @return bool
  956. *
  957. * @throws \Assert\AssertionFailedException
  958. */
  959. public static function isArray($value, $message = null, $propertyPath = null)
  960. {
  961. if (!\is_array($value)) {
  962. $message = \sprintf(
  963. static::generateMessage($message ?: 'Value "%s" is not an array.'),
  964. static::stringify($value)
  965. );
  966. throw static::createException($value, $message, static::INVALID_ARRAY, $propertyPath);
  967. }
  968. return true;
  969. }
  970. /**
  971. * Assert that value is an array or a traversable object.
  972. *
  973. * @param mixed $value
  974. * @param string|callable|null $message
  975. * @param string|null $propertyPath
  976. *
  977. * @return bool
  978. *
  979. * @throws \Assert\AssertionFailedException
  980. */
  981. public static function isTraversable($value, $message = null, $propertyPath = null)
  982. {
  983. if (!\is_array($value) && !$value instanceof \Traversable) {
  984. $message = \sprintf(
  985. static::generateMessage($message ?: 'Value "%s" is not an array and does not implement Traversable.'),
  986. static::stringify($value)
  987. );
  988. throw static::createException($value, $message, static::INVALID_TRAVERSABLE, $propertyPath);
  989. }
  990. return true;
  991. }
  992. /**
  993. * Assert that value is an array or an array-accessible object.
  994. *
  995. * @param mixed $value
  996. * @param string|callable|null $message
  997. * @param string|null $propertyPath
  998. *
  999. * @return bool
  1000. *
  1001. * @throws \Assert\AssertionFailedException
  1002. */
  1003. public static function isArrayAccessible($value, $message = null, $propertyPath = null)
  1004. {
  1005. if (!\is_array($value) && !$value instanceof \ArrayAccess) {
  1006. $message = \sprintf(
  1007. static::generateMessage($message ?: 'Value "%s" is not an array and does not implement ArrayAccess.'),
  1008. static::stringify($value)
  1009. );
  1010. throw static::createException($value, $message, static::INVALID_ARRAY_ACCESSIBLE, $propertyPath);
  1011. }
  1012. return true;
  1013. }
  1014. /**
  1015. * Assert that key exists in an array.
  1016. *
  1017. * @param mixed $value
  1018. * @param string|int $key
  1019. * @param string|callable|null $message
  1020. * @param string|null $propertyPath
  1021. *
  1022. * @return bool
  1023. *
  1024. * @throws \Assert\AssertionFailedException
  1025. */
  1026. public static function keyExists($value, $key, $message = null, $propertyPath = null)
  1027. {
  1028. static::isArray($value, $message, $propertyPath);
  1029. if (!\array_key_exists($key, $value)) {
  1030. $message = \sprintf(
  1031. static::generateMessage($message ?: 'Array does not contain an element with key "%s"'),
  1032. static::stringify($key)
  1033. );
  1034. throw static::createException($value, $message, static::INVALID_KEY_EXISTS, $propertyPath, array('key' => $key));
  1035. }
  1036. return true;
  1037. }
  1038. /**
  1039. * Assert that key does not exist in an array.
  1040. *
  1041. * @param mixed $value
  1042. * @param string|int $key
  1043. * @param string|callable|null $message
  1044. * @param string|null $propertyPath
  1045. *
  1046. * @return bool
  1047. *
  1048. * @throws \Assert\AssertionFailedException
  1049. */
  1050. public static function keyNotExists($value, $key, $message = null, $propertyPath = null)
  1051. {
  1052. static::isArray($value, $message, $propertyPath);
  1053. if (\array_key_exists($key, $value)) {
  1054. $message = \sprintf(
  1055. static::generateMessage($message ?: 'Array contains an element with key "%s"'),
  1056. static::stringify($key)
  1057. );
  1058. throw static::createException($value, $message, static::INVALID_KEY_NOT_EXISTS, $propertyPath, array('key' => $key));
  1059. }
  1060. return true;
  1061. }
  1062. /**
  1063. * Assert that key exists in an array/array-accessible object using isset().
  1064. *
  1065. * @param mixed $value
  1066. * @param string|int $key
  1067. * @param string|callable|null $message
  1068. * @param string|null $propertyPath
  1069. *
  1070. * @return bool
  1071. *
  1072. * @throws \Assert\AssertionFailedException
  1073. */
  1074. public static function keyIsset($value, $key, $message = null, $propertyPath = null)
  1075. {
  1076. static::isArrayAccessible($value, $message, $propertyPath);
  1077. if (!isset($value[$key])) {
  1078. $message = \sprintf(
  1079. static::generateMessage($message ?: 'The element with key "%s" was not found'),
  1080. static::stringify($key)
  1081. );
  1082. throw static::createException($value, $message, static::INVALID_KEY_ISSET, $propertyPath, array('key' => $key));
  1083. }
  1084. return true;
  1085. }
  1086. /**
  1087. * Assert that key exists in an array/array-accessible object and its value is not empty.
  1088. *
  1089. * @param mixed $value
  1090. * @param string|int $key
  1091. * @param string|callable|null $message
  1092. * @param string|null $propertyPath
  1093. *
  1094. * @return bool
  1095. *
  1096. * @throws \Assert\AssertionFailedException
  1097. */
  1098. public static function notEmptyKey($value, $key, $message = null, $propertyPath = null)
  1099. {
  1100. static::keyIsset($value, $key, $message, $propertyPath);
  1101. static::notEmpty($value[$key], $message, $propertyPath);
  1102. return true;
  1103. }
  1104. /**
  1105. * Assert that value is not blank.
  1106. *
  1107. * @param mixed $value
  1108. * @param string|callable|null $message
  1109. * @param string|null $propertyPath
  1110. *
  1111. * @return bool
  1112. *
  1113. * @throws \Assert\AssertionFailedException
  1114. */
  1115. public static function notBlank($value, $message = null, $propertyPath = null)
  1116. {
  1117. if (false === $value || (empty($value) && '0' != $value) || (\is_string($value) && '' === \trim($value))) {
  1118. $message = \sprintf(
  1119. static::generateMessage($message ?: 'Value "%s" is blank, but was expected to contain a value.'),
  1120. static::stringify($value)
  1121. );
  1122. throw static::createException($value, $message, static::INVALID_NOT_BLANK, $propertyPath);
  1123. }
  1124. return true;
  1125. }
  1126. /**
  1127. * Assert that value is instance of given class-name.
  1128. *
  1129. * @param mixed $value
  1130. * @param string $className
  1131. * @param string|callable|null $message
  1132. * @param string|null $propertyPath
  1133. *
  1134. * @return bool
  1135. *
  1136. * @throws \Assert\AssertionFailedException
  1137. */
  1138. public static function isInstanceOf($value, $className, $message = null, $propertyPath = null)
  1139. {
  1140. if (!($value instanceof $className)) {
  1141. $message = \sprintf(
  1142. static::generateMessage($message ?: 'Class "%s" was expected to be instanceof of "%s" but is not.'),
  1143. static::stringify($value),
  1144. $className
  1145. );
  1146. throw static::createException($value, $message, static::INVALID_INSTANCE_OF, $propertyPath, array('class' => $className));
  1147. }
  1148. return true;
  1149. }
  1150. /**
  1151. * Assert that value is not instance of given class-name.
  1152. *
  1153. * @param mixed $value
  1154. * @param string $className
  1155. * @param string|callable|null $message
  1156. * @param string|null $propertyPath
  1157. *
  1158. * @return bool
  1159. *
  1160. * @throws \Assert\AssertionFailedException
  1161. */
  1162. public static function notIsInstanceOf($value, $className, $message = null, $propertyPath = null)
  1163. {
  1164. if ($value instanceof $className) {
  1165. $message = \sprintf(
  1166. static::generateMessage($message ?: 'Class "%s" was not expected to be instanceof of "%s".'),
  1167. static::stringify($value),
  1168. $className
  1169. );
  1170. throw static::createException($value, $message, static::INVALID_NOT_INSTANCE_OF, $propertyPath, array('class' => $className));
  1171. }
  1172. return true;
  1173. }
  1174. /**
  1175. * Assert that value is subclass of given class-name.
  1176. *
  1177. * @param mixed $value
  1178. * @param string $className
  1179. * @param string|callable|null $message
  1180. * @param string|null $propertyPath
  1181. *
  1182. * @return bool
  1183. *
  1184. * @throws \Assert\AssertionFailedException
  1185. */
  1186. public static function subclassOf($value, $className, $message = null, $propertyPath = null)
  1187. {
  1188. if (!\is_subclass_of($value, $className)) {
  1189. $message = \sprintf(
  1190. static::generateMessage($message ?: 'Class "%s" was expected to be subclass of "%s".'),
  1191. static::stringify($value),
  1192. $className
  1193. );
  1194. throw static::createException($value, $message, static::INVALID_SUBCLASS_OF, $propertyPath, array('class' => $className));
  1195. }
  1196. return true;
  1197. }
  1198. /**
  1199. * Assert that value is in range of numbers.
  1200. *
  1201. * @param mixed $value
  1202. * @param mixed $minValue
  1203. * @param mixed $maxValue
  1204. * @param string|callable|null $message
  1205. * @param string|null $propertyPath
  1206. *
  1207. * @return bool
  1208. *
  1209. * @throws \Assert\AssertionFailedException
  1210. */
  1211. public static function range($value, $minValue, $maxValue, $message = null, $propertyPath = null)
  1212. {
  1213. static::numeric($value, $message, $propertyPath);
  1214. if ($value < $minValue || $value > $maxValue) {
  1215. $message = \sprintf(
  1216. static::generateMessage($message ?: 'Number "%s" was expected to be at least "%d" and at most "%d".'),
  1217. static::stringify($value),
  1218. static::stringify($minValue),
  1219. static::stringify($maxValue)
  1220. );
  1221. throw static::createException($value, $message, static::INVALID_RANGE, $propertyPath, array('min' => $minValue, 'max' => $maxValue));
  1222. }
  1223. return true;
  1224. }
  1225. /**
  1226. * Assert that a value is at least as big as a given limit.
  1227. *
  1228. * @param mixed $value
  1229. * @param mixed $minValue
  1230. * @param string|callable|null $message
  1231. * @param string|null $propertyPath
  1232. *
  1233. * @return bool
  1234. *
  1235. * @throws \Assert\AssertionFailedException
  1236. */
  1237. public static function min($value, $minValue, $message = null, $propertyPath = null)
  1238. {
  1239. static::numeric($value, $message, $propertyPath);
  1240. if ($value < $minValue) {
  1241. $message = \sprintf(
  1242. static::generateMessage($message ?: 'Number "%s" was expected to be at least "%s".'),
  1243. static::stringify($value),
  1244. static::stringify($minValue)
  1245. );
  1246. throw static::createException($value, $message, static::INVALID_MIN, $propertyPath, array('min' => $minValue));
  1247. }
  1248. return true;
  1249. }
  1250. /**
  1251. * Assert that a number is smaller as a given limit.
  1252. *
  1253. * @param mixed $value
  1254. * @param mixed $maxValue
  1255. * @param string|callable|null $message
  1256. * @param string|null $propertyPath
  1257. *
  1258. * @return bool
  1259. *
  1260. * @throws \Assert\AssertionFailedException
  1261. */
  1262. public static function max($value, $maxValue, $message = null, $propertyPath = null)
  1263. {
  1264. static::numeric($value, $message, $propertyPath);
  1265. if ($value > $maxValue) {
  1266. $message = \sprintf(
  1267. static::generateMessage($message ?: 'Number "%s" was expected to be at most "%s".'),
  1268. static::stringify($value),
  1269. static::stringify($maxValue)
  1270. );
  1271. throw static::createException($value, $message, static::INVALID_MAX, $propertyPath, array('max' => $maxValue));
  1272. }
  1273. return true;
  1274. }
  1275. /**
  1276. * Assert that a file exists.
  1277. *
  1278. * @param string $value
  1279. * @param string|callable|null $message
  1280. * @param string|null $propertyPath
  1281. *
  1282. * @return bool
  1283. *
  1284. * @throws \Assert\AssertionFailedException
  1285. */
  1286. public static function file($value, $message = null, $propertyPath = null)
  1287. {
  1288. static::string($value, $message, $propertyPath);
  1289. static::notEmpty($value, $message, $propertyPath);
  1290. if (!\is_file($value)) {
  1291. $message = \sprintf(
  1292. static::generateMessage($message ?: 'File "%s" was expected to exist.'),
  1293. static::stringify($value)
  1294. );
  1295. throw static::createException($value, $message, static::INVALID_FILE, $propertyPath);
  1296. }
  1297. return true;
  1298. }
  1299. /**
  1300. * Assert that a directory exists.
  1301. *
  1302. * @param string $value
  1303. * @param string|callable|null $message
  1304. * @param string|null $propertyPath
  1305. *
  1306. * @return bool
  1307. *
  1308. * @throws \Assert\AssertionFailedException
  1309. */
  1310. public static function directory($value, $message = null, $propertyPath = null)
  1311. {
  1312. static::string($value, $message, $propertyPath);
  1313. if (!\is_dir($value)) {
  1314. $message = \sprintf(
  1315. static::generateMessage($message ?: 'Path "%s" was expected to be a directory.'),
  1316. static::stringify($value)
  1317. );
  1318. throw static::createException($value, $message, static::INVALID_DIRECTORY, $propertyPath);
  1319. }
  1320. return true;
  1321. }
  1322. /**
  1323. * Assert that the value is something readable.
  1324. *
  1325. * @param string $value
  1326. * @param string|callable|null $message
  1327. * @param string|null $propertyPath
  1328. *
  1329. * @return bool
  1330. *
  1331. * @throws \Assert\AssertionFailedException
  1332. */
  1333. public static function readable($value, $message = null, $propertyPath = null)
  1334. {
  1335. static::string($value, $message, $propertyPath);
  1336. if (!\is_readable($value)) {
  1337. $message = \sprintf(
  1338. static::generateMessage($message ?: 'Path "%s" was expected to be readable.'),
  1339. static::stringify($value)
  1340. );
  1341. throw static::createException($value, $message, static::INVALID_READABLE, $propertyPath);
  1342. }
  1343. return true;
  1344. }
  1345. /**
  1346. * Assert that the value is something writeable.
  1347. *
  1348. * @param string $value
  1349. * @param string|callable|null $message
  1350. * @param string|null $propertyPath
  1351. *
  1352. * @return bool
  1353. *
  1354. * @throws \Assert\AssertionFailedException
  1355. */
  1356. public static function writeable($value, $message = null, $propertyPath = null)
  1357. {
  1358. static::string($value, $message, $propertyPath);
  1359. if (!\is_writable($value)) {
  1360. $message = \sprintf(
  1361. static::generateMessage($message ?: 'Path "%s" was expected to be writeable.'),
  1362. static::stringify($value)
  1363. );
  1364. throw static::createException($value, $message, static::INVALID_WRITEABLE, $propertyPath);
  1365. }
  1366. return true;
  1367. }
  1368. /**
  1369. * Assert that value is an email address (using input_filter/FILTER_VALIDATE_EMAIL).
  1370. *
  1371. * @param mixed $value
  1372. * @param string|callable|null $message
  1373. * @param string|null $propertyPath
  1374. *
  1375. * @return bool
  1376. *
  1377. * @throws \Assert\AssertionFailedException
  1378. */
  1379. public static function email($value, $message = null, $propertyPath = null)
  1380. {
  1381. static::string($value, $message, $propertyPath);
  1382. if (!\filter_var($value, FILTER_VALIDATE_EMAIL)) {
  1383. $message = \sprintf(
  1384. static::generateMessage($message ?: 'Value "%s" was expected to be a valid e-mail address.'),
  1385. static::stringify($value)
  1386. );
  1387. throw static::createException($value, $message, static::INVALID_EMAIL, $propertyPath);
  1388. } else {
  1389. $host = \substr($value, \strpos($value, '@') + 1);
  1390. // Likely not a FQDN, bug in PHP FILTER_VALIDATE_EMAIL prior to PHP 5.3.3
  1391. if (\version_compare(PHP_VERSION, '5.3.3', '<') && false === \strpos($host, '.')) {
  1392. $message = \sprintf(
  1393. static::generateMessage($message ?: 'Value "%s" was expected to be a valid e-mail address.'),
  1394. static::stringify($value)
  1395. );
  1396. throw static::createException($value, $message, static::INVALID_EMAIL, $propertyPath);
  1397. }
  1398. }
  1399. return true;
  1400. }
  1401. /**
  1402. * Assert that value is an URL.
  1403. *
  1404. * This code snipped was taken from the Symfony project and modified to the special demands of this method.
  1405. *
  1406. * @param mixed $value
  1407. * @param string|callable|null $message
  1408. * @param string|null $propertyPath
  1409. *
  1410. * @return bool
  1411. *
  1412. * @throws \Assert\AssertionFailedException
  1413. *
  1414. * @see https://github.com/symfony/Validator/blob/master/Constraints/UrlValidator.php
  1415. * @see https://github.com/symfony/Validator/blob/master/Constraints/Url.php
  1416. */
  1417. public static function url($value, $message = null, $propertyPath = null)
  1418. {
  1419. static::string($value, $message, $propertyPath);
  1420. $protocols = array('http', 'https');
  1421. $pattern = '~^
  1422. (%s):// # protocol
  1423. (([\.\pL\pN-]+:)?([\.\pL\pN-]+)@)? # basic auth
  1424. (
  1425. ([\pL\pN\pS\-\.])+(\.?([\pL\pN]|xn\-\-[\pL\pN-]+)+\.?) # a domain name
  1426. | # or
  1427. \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} # an IP address
  1428. | # or
  1429. \[
  1430. (?:(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-f]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,1}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,2}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,3}(?:(?:[0-9a-f]{1,4})))?::(?:(?:[0-9a-f]{1,4})):)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,4}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,5}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,6}(?:(?:[0-9a-f]{1,4})))?::))))
  1431. \] # an IPv6 address
  1432. )
  1433. (:[0-9]+)? # a port (optional)
  1434. (?:/ (?:[\pL\pN\-._\~!$&\'()*+,;=:@]|%%[0-9A-Fa-f]{2})* )* # a path
  1435. (?:\? (?:[\pL\pN\-._\~!$&\'\[\]()*+,;=:@/?]|%%[0-9A-Fa-f]{2})* )? # a query (optional)
  1436. (?:\# (?:[\pL\pN\-._\~!$&\'()*+,;=:@/?]|%%[0-9A-Fa-f]{2})* )? # a fragment (optional)
  1437. $~ixu';
  1438. $pattern = \sprintf($pattern, \implode('|', $protocols));
  1439. if (!\preg_match($pattern, $value)) {
  1440. $message = \sprintf(
  1441. static::generateMessage($message ?: 'Value "%s" was expected to be a valid URL starting with http or https'),
  1442. static::stringify($value)
  1443. );
  1444. throw static::createException($value, $message, static::INVALID_URL, $propertyPath);
  1445. }
  1446. return true;
  1447. }
  1448. /**
  1449. * Assert that value is alphanumeric.
  1450. *
  1451. * @param mixed $value
  1452. * @param string|callable|null $message
  1453. * @param string|null $propertyPath
  1454. *
  1455. * @return bool
  1456. *
  1457. * @throws \Assert\AssertionFailedException
  1458. */
  1459. public static function alnum($value, $message = null, $propertyPath = null)
  1460. {
  1461. try {
  1462. static::regex($value, '(^([a-zA-Z]{1}[a-zA-Z0-9]*)$)', $message, $propertyPath);
  1463. } catch (AssertionFailedException $e) {
  1464. $message = \sprintf(
  1465. static::generateMessage($message ?: 'Value "%s" is not alphanumeric, starting with letters and containing only letters and numbers.'),
  1466. static::stringify($value)
  1467. );
  1468. throw static::createException($value, $message, static::INVALID_ALNUM, $propertyPath);
  1469. }
  1470. return true;
  1471. }
  1472. /**
  1473. * Assert that the value is boolean True.
  1474. *
  1475. * @param mixed $value
  1476. * @param string|callable|null $message
  1477. * @param string|null $propertyPath
  1478. *
  1479. * @return bool
  1480. *
  1481. * @throws \Assert\AssertionFailedException
  1482. */
  1483. public static function true($value, $message = null, $propertyPath = null)
  1484. {
  1485. if (true !== $value) {
  1486. $message = \sprintf(
  1487. static::generateMessage($message ?: 'Value "%s" is not TRUE.'),
  1488. static::stringify($value)
  1489. );
  1490. throw static::createException($value, $message, static::INVALID_TRUE, $propertyPath);
  1491. }
  1492. return true;
  1493. }
  1494. /**
  1495. * Assert that the value is boolean False.
  1496. *
  1497. * @param mixed $value
  1498. * @param string|callable|null $message
  1499. * @param string|null $propertyPath
  1500. *
  1501. * @return bool
  1502. *
  1503. * @throws \Assert\AssertionFailedException
  1504. */
  1505. public static function false($value, $message = null, $propertyPath = null)
  1506. {
  1507. if (false !== $value) {
  1508. $message = \sprintf(
  1509. static::generateMessage($message ?: 'Value "%s" is not FALSE.'),
  1510. static::stringify($value)
  1511. );
  1512. throw static::createException($value, $message, static::INVALID_FALSE, $propertyPath);
  1513. }
  1514. return true;
  1515. }
  1516. /**
  1517. * Assert that the class exists.
  1518. *
  1519. * @param mixed $value
  1520. * @param string|callable|null $message
  1521. * @param string|null $propertyPath
  1522. *
  1523. * @return bool
  1524. *
  1525. * @throws \Assert\AssertionFailedException
  1526. */
  1527. public static function classExists($value, $message = null, $propertyPath = null)
  1528. {
  1529. if (!\class_exists($value)) {
  1530. $message = \sprintf(
  1531. static::generateMessage($message ?: 'Class "%s" does not exist.'),
  1532. static::stringify($value)
  1533. );
  1534. throw static::createException($value, $message, static::INVALID_CLASS, $propertyPath);
  1535. }
  1536. return true;
  1537. }
  1538. /**
  1539. * Assert that the interface exists.
  1540. *
  1541. * @param mixed $value
  1542. * @param string|callable|null $message
  1543. * @param string|null $propertyPath
  1544. *
  1545. * @return bool
  1546. *
  1547. * @throws \Assert\AssertionFailedException
  1548. */
  1549. public static function interfaceExists($value, $message = null, $propertyPath = null)
  1550. {
  1551. if (!\interface_exists($value)) {
  1552. $message = \sprintf(
  1553. static::generateMessage($message ?: 'Interface "%s" does not exist.'),
  1554. static::stringify($value)
  1555. );
  1556. throw static::createException($value, $message, static::INVALID_INTERFACE, $propertyPath);
  1557. }
  1558. return true;
  1559. }
  1560. /**
  1561. * Assert that the class implements the interface.
  1562. *
  1563. * @param mixed $class
  1564. * @param string $interfaceName
  1565. * @param string|callable|null $message
  1566. * @param string|null $propertyPath
  1567. *
  1568. * @return bool
  1569. *
  1570. * @throws \Assert\AssertionFailedException
  1571. */
  1572. public static function implementsInterface($class, $interfaceName, $message = null, $propertyPath = null)
  1573. {
  1574. $reflection = new \ReflectionClass($class);
  1575. if (!$reflection->implementsInterface($interfaceName)) {
  1576. $message = \sprintf(
  1577. static::generateMessage($message ?: 'Class "%s" does not implement interface "%s".'),
  1578. static::stringify($class),
  1579. static::stringify($interfaceName)
  1580. );
  1581. throw static::createException($class, $message, static::INTERFACE_NOT_IMPLEMENTED, $propertyPath, array('interface' => $interfaceName));
  1582. }
  1583. return true;
  1584. }
  1585. /**
  1586. * Assert that the given string is a valid json string.
  1587. *
  1588. * NOTICE:
  1589. * Since this does a json_decode to determine its validity
  1590. * you probably should consider, when using the variable
  1591. * content afterwards, just to decode and check for yourself instead
  1592. * of using this assertion.
  1593. *
  1594. * @param mixed $value
  1595. * @param string|callable|null $message
  1596. * @param string|null $propertyPath
  1597. *
  1598. * @return bool
  1599. *
  1600. * @throws \Assert\AssertionFailedException
  1601. */
  1602. public static function isJsonString($value, $message = null, $propertyPath = null)
  1603. {
  1604. if (null === \json_decode($value) && JSON_ERROR_NONE !== \json_last_error()) {
  1605. $message = \sprintf(
  1606. static::generateMessage($message ?: 'Value "%s" is not a valid JSON string.'),
  1607. static::stringify($value)
  1608. );
  1609. throw static::createException($value, $message, static::INVALID_JSON_STRING, $propertyPath);
  1610. }
  1611. return true;
  1612. }
  1613. /**
  1614. * Assert that the given string is a valid UUID.
  1615. *
  1616. * Uses code from {@link https://github.com/ramsey/uuid} that is MIT licensed.
  1617. *
  1618. * @param string $value
  1619. * @param string|callable|null $message
  1620. * @param string|null $propertyPath
  1621. *
  1622. * @return bool
  1623. *
  1624. * @throws \Assert\AssertionFailedException
  1625. */
  1626. public static function uuid($value, $message = null, $propertyPath = null)
  1627. {
  1628. $value = \str_replace(array('urn:', 'uuid:', '{', '}'), '', $value);
  1629. if ('00000000-0000-0000-0000-000000000000' === $value) {
  1630. return true;
  1631. }
  1632. if (!\preg_match('/^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$/', $value)) {
  1633. $message = \sprintf(
  1634. static::generateMessage($message ?: 'Value "%s" is not a valid UUID.'),
  1635. static::stringify($value)
  1636. );
  1637. throw static::createException($value, $message, static::INVALID_UUID, $propertyPath);
  1638. }
  1639. return true;
  1640. }
  1641. /**
  1642. * Assert that the given string is a valid E164 Phone Number.
  1643. *
  1644. * @see https://en.wikipedia.org/wiki/E.164
  1645. *
  1646. * @param string $value
  1647. * @param string|callable|null $message
  1648. * @param string|null $propertyPath
  1649. *
  1650. * @return bool
  1651. *
  1652. * @throws \Assert\AssertionFailedException
  1653. */
  1654. public static function e164($value, $message = null, $propertyPath = null)
  1655. {
  1656. if (!\preg_match('/^\+?[1-9]\d{1,14}$/', $value)) {
  1657. $message = \sprintf(
  1658. static::generateMessage($message ?: 'Value "%s" is not a valid E164.'),
  1659. static::stringify($value)
  1660. );
  1661. throw static::createException($value, $message, static::INVALID_E164, $propertyPath);
  1662. }
  1663. return true;
  1664. }
  1665. /**
  1666. * Assert that the count of countable is equal to count.
  1667. *
  1668. * @param array|\Countable $countable
  1669. * @param int $count
  1670. * @param string|null $message
  1671. * @param string|null $propertyPath
  1672. *
  1673. * @return bool
  1674. *
  1675. * @throws \Assert\AssertionFailedException
  1676. */
  1677. public static function count($countable, $count, $message = null, $propertyPath = null)
  1678. {
  1679. if ($count !== \count($countable)) {
  1680. $message = \sprintf(
  1681. static::generateMessage($message ?: 'List does not contain exactly %d elements (%d given).'),
  1682. static::stringify($count),
  1683. static::stringify(\count($countable))
  1684. );
  1685. throw static::createException($countable, $message, static::INVALID_COUNT, $propertyPath, array('count' => $count));
  1686. }
  1687. return true;
  1688. }
  1689. /**
  1690. * static call handler to implement:
  1691. * - "null or assertion" delegation
  1692. * - "all" delegation.
  1693. *
  1694. * @param string $method
  1695. * @param array $args
  1696. *
  1697. * @return bool|mixed
  1698. */
  1699. public static function __callStatic($method, $args)
  1700. {
  1701. if (0 === \strpos($method, 'nullOr')) {
  1702. if (!\array_key_exists(0, $args)) {
  1703. throw new BadMethodCallException('Missing the first argument.');
  1704. }
  1705. if (null === $args[0]) {
  1706. return true;
  1707. }
  1708. $method = \substr($method, 6);
  1709. return \call_user_func_array(array(\get_called_class(), $method), $args);
  1710. }
  1711. if (0 === \strpos($method, 'all')) {
  1712. if (!\array_key_exists(0, $args)) {
  1713. throw new BadMethodCallException('Missing the first argument.');
  1714. }
  1715. static::isTraversable($args[0]);
  1716. $method = \substr($method, 3);
  1717. $values = \array_shift($args);
  1718. $calledClass = \get_called_class();
  1719. foreach ($values as $value) {
  1720. \call_user_func_array(array($calledClass, $method), \array_merge(array($value), $args));
  1721. }
  1722. return true;
  1723. }
  1724. throw new BadMethodCallException('No assertion Assertion#' . $method . ' exists.');
  1725. }
  1726. /**
  1727. * Determines if the values array has every choice as key and that this choice has content.
  1728. *
  1729. * @param array $values
  1730. * @param array $choices
  1731. * @param string|callable|null $message
  1732. * @param string|null $propertyPath
  1733. *
  1734. * @return bool
  1735. */
  1736. public static function choicesNotEmpty(array $values, array $choices, $message = null, $propertyPath = null)
  1737. {
  1738. static::notEmpty($values, $message, $propertyPath);
  1739. foreach ($choices as $choice) {
  1740. static::notEmptyKey($values, $choice, $message, $propertyPath);
  1741. }
  1742. return true;
  1743. }
  1744. /**
  1745. * Determines that the named method is defined in the provided object.
  1746. *
  1747. * @param string $value
  1748. * @param mixed $object
  1749. * @param string|callable|null $message
  1750. * @param string|null $propertyPath
  1751. *
  1752. * @return bool
  1753. */
  1754. public static function methodExists($value, $object, $message = null, $propertyPath = null)
  1755. {
  1756. static::isObject($object, $message, $propertyPath);
  1757. if (!\method_exists($object, $value)) {
  1758. $message = \sprintf(
  1759. static::generateMessage($message ?: 'Expected "%s" does not exist in provided object.'),
  1760. static::stringify($value)
  1761. );
  1762. throw static::createException($value, $message, static::INVALID_METHOD, $propertyPath, array('object' => \get_class($object)));
  1763. }
  1764. return true;
  1765. }
  1766. /**
  1767. * Determines that the provided value is an object.
  1768. *
  1769. * @param mixed $value
  1770. * @param string|callable|null $message
  1771. * @param string|null $propertyPath
  1772. *
  1773. * @return bool
  1774. */
  1775. public static function isObject($value, $message = null, $propertyPath = null)
  1776. {
  1777. if (!\is_object($value)) {
  1778. $message = \sprintf(
  1779. static::generateMessage($message ?: 'Provided "%s" is not a valid object.'),
  1780. static::stringify($value)
  1781. );
  1782. throw static::createException($value, $message, static::INVALID_OBJECT, $propertyPath);
  1783. }
  1784. return true;
  1785. }
  1786. /**
  1787. * Determines if the value is less than given limit.
  1788. *
  1789. * @param mixed $value
  1790. * @param mixed $limit
  1791. * @param string|callable|null $message
  1792. * @param string|null $propertyPath
  1793. *
  1794. * @return bool
  1795. */
  1796. public static function lessThan($value, $limit, $message = null, $propertyPath = null)
  1797. {
  1798. if ($value >= $limit) {
  1799. $message = \sprintf(
  1800. static::generateMessage($message ?: 'Provided "%s" is not less than "%s".'),
  1801. static::stringify($value),
  1802. static::stringify($limit)
  1803. );
  1804. throw static::createException($value, $message, static::INVALID_LESS, $propertyPath, array('limit' => $limit));
  1805. }
  1806. return true;
  1807. }
  1808. /**
  1809. * Determines if the value is less or equal than given limit.
  1810. *
  1811. * @param mixed $value
  1812. * @param mixed $limit
  1813. * @param string|callable|null $message
  1814. * @param string|null $propertyPath
  1815. *
  1816. * @return bool
  1817. */
  1818. public static function lessOrEqualThan($value, $limit, $message = null, $propertyPath = null)
  1819. {
  1820. if ($value > $limit) {
  1821. $message = \sprintf(
  1822. static::generateMessage($message ?: 'Provided "%s" is not less or equal than "%s".'),
  1823. static::stringify($value),
  1824. static::stringify($limit)
  1825. );
  1826. throw static::createException($value, $message, static::INVALID_LESS_OR_EQUAL, $propertyPath, array('limit' => $limit));
  1827. }
  1828. return true;
  1829. }
  1830. /**
  1831. * Determines if the value is greater than given limit.
  1832. *
  1833. * @param mixed $value
  1834. * @param mixed $limit
  1835. * @param string|callable|null $message
  1836. * @param string|null $propertyPath
  1837. *
  1838. * @return bool
  1839. */
  1840. public static function greaterThan($value, $limit, $message = null, $propertyPath = null)
  1841. {
  1842. if ($value <= $limit) {
  1843. $message = \sprintf(
  1844. static::generateMessage($message ?: 'Provided "%s" is not greater than "%s".'),
  1845. static::stringify($value),
  1846. static::stringify($limit)
  1847. );
  1848. throw static::createException($value, $message, static::INVALID_GREATER, $propertyPath, array('limit' => $limit));
  1849. }
  1850. return true;
  1851. }
  1852. /**
  1853. * Determines if the value is greater or equal than given limit.
  1854. *
  1855. * @param mixed $value
  1856. * @param mixed $limit
  1857. * @param string|callable|null $message
  1858. * @param string|null $propertyPath
  1859. *
  1860. * @return bool
  1861. */
  1862. public static function greaterOrEqualThan($value, $limit, $message = null, $propertyPath = null)
  1863. {
  1864. if ($value < $limit) {
  1865. $message = \sprintf(
  1866. static::generateMessage($message ?: 'Provided "%s" is not greater or equal than "%s".'),
  1867. static::stringify($value),
  1868. static::stringify($limit)
  1869. );
  1870. throw static::createException($value, $message, static::INVALID_GREATER_OR_EQUAL, $propertyPath, array('limit' => $limit));
  1871. }
  1872. return true;
  1873. }
  1874. /**
  1875. * Assert that a value is greater or equal than a lower limit, and less than or equal to an upper limit.
  1876. *
  1877. * @param mixed $value
  1878. * @param mixed $lowerLimit
  1879. * @param mixed $upperLimit
  1880. * @param string $message
  1881. * @param string $propertyPath
  1882. *
  1883. * @return bool
  1884. */
  1885. public static function between($value, $lowerLimit, $upperLimit, $message = null, $propertyPath = null)
  1886. {
  1887. if ($lowerLimit > $value || $value > $upperLimit) {
  1888. $message = \sprintf(
  1889. static::generateMessage($message ?: 'Provided "%s" is neither greater than or equal to "%s" nor less than or equal to "%s".'),
  1890. static::stringify($value),
  1891. static::stringify($lowerLimit),
  1892. static::stringify($upperLimit)
  1893. );
  1894. throw static::createException($value, $message, static::INVALID_BETWEEN, $propertyPath, array('lower' => $lowerLimit, 'upper' => $upperLimit));
  1895. }
  1896. return true;
  1897. }
  1898. /**
  1899. * Assert that a value is greater than a lower limit, and less than an upper limit.
  1900. *
  1901. * @param mixed $value
  1902. * @param mixed $lowerLimit
  1903. * @param mixed $upperLimit
  1904. * @param string $message
  1905. * @param string $propertyPath
  1906. *
  1907. * @return bool
  1908. */
  1909. public static function betweenExclusive($value, $lowerLimit, $upperLimit, $message = null, $propertyPath = null)
  1910. {
  1911. if ($lowerLimit >= $value || $value >= $upperLimit) {
  1912. $message = \sprintf(
  1913. static::generateMessage($message ?: 'Provided "%s" is neither greater than "%s" nor less than "%s".'),
  1914. static::stringify($value),
  1915. static::stringify($lowerLimit),
  1916. static::stringify($upperLimit)
  1917. );
  1918. throw static::createException($value, $message, static::INVALID_BETWEEN_EXCLUSIVE, $propertyPath, array('lower' => $lowerLimit, 'upper' => $upperLimit));
  1919. }
  1920. return true;
  1921. }
  1922. /**
  1923. * Assert that extension is loaded.
  1924. *
  1925. * @param mixed $value
  1926. * @param string|callable|null $message
  1927. * @param string|null $propertyPath
  1928. *
  1929. * @return bool
  1930. *
  1931. * @throws \Assert\AssertionFailedException
  1932. */
  1933. public static function extensionLoaded($value, $message = null, $propertyPath = null)
  1934. {
  1935. if (!\extension_loaded($value)) {
  1936. $message = \sprintf(
  1937. static::generateMessage($message ?: 'Extension "%s" is required.'),
  1938. static::stringify($value)
  1939. );
  1940. throw static::createException($value, $message, static::INVALID_EXTENSION, $propertyPath);
  1941. }
  1942. return true;
  1943. }
  1944. /**
  1945. * Assert that date is valid and corresponds to the given format.
  1946. *
  1947. * @param string $value
  1948. * @param string $format supports all of the options date(), except for the following:
  1949. * N, w, W, t, L, o, B, a, A, g, h, I, O, P, Z, c, r
  1950. * @param string|callable|null $message
  1951. * @param string|null $propertyPath
  1952. *
  1953. * @return bool
  1954. *
  1955. * @see http://php.net/manual/function.date.php#refsect1-function.date-parameters
  1956. */
  1957. public static function date($value, $format, $message = null, $propertyPath = null)
  1958. {
  1959. static::string($value, $message, $propertyPath);
  1960. static::string($format, $message, $propertyPath);
  1961. $dateTime = \DateTime::createFromFormat('!' . $format, $value);
  1962. if (false === $dateTime || $value !== $dateTime->format($format)) {
  1963. $message = \sprintf(
  1964. static::generateMessage($message ?: 'Date "%s" is invalid or does not match format "%s".'),
  1965. static::stringify($value),
  1966. static::stringify($format)
  1967. );
  1968. throw static::createException($value, $message, static::INVALID_DATE, $propertyPath, array('format' => $format));
  1969. }
  1970. return true;
  1971. }
  1972. /**
  1973. * Assert that the value is an object, or a class that exists.
  1974. *
  1975. * @param mixed $value
  1976. * @param string|callable|null $message
  1977. * @param string|null $propertyPath
  1978. *
  1979. * @return bool
  1980. *
  1981. * @throws \Assert\AssertionFailedException
  1982. */
  1983. public static function objectOrClass($value, $message = null, $propertyPath = null)
  1984. {
  1985. if (!\is_object($value)) {
  1986. static::classExists($value, $message, $propertyPath);
  1987. }
  1988. return true;
  1989. }
  1990. /**
  1991. * Assert that the value is an object or class, and that the property exists.
  1992. *
  1993. * @param mixed $value
  1994. * @param string $property
  1995. * @param string|callable|null $message
  1996. * @param string|null $propertyPath
  1997. *
  1998. * @return bool
  1999. *
  2000. * @throws \Assert\AssertionFailedException
  2001. */
  2002. public static function propertyExists($value, $property, $message = null, $propertyPath = null)
  2003. {
  2004. static::objectOrClass($value);
  2005. if (!\property_exists($value, $property)) {
  2006. $message = \sprintf(
  2007. static::generateMessage($message ?: 'Class "%s" does not have property "%s".'),
  2008. static::stringify($value),
  2009. static::stringify($property)
  2010. );
  2011. throw static::createException($value, $message, static::INVALID_PROPERTY, $propertyPath, array('property' => $property));
  2012. }
  2013. return true;
  2014. }
  2015. /**
  2016. * Assert that the value is an object or class, and that the properties all exist.
  2017. *
  2018. * @param mixed $value
  2019. * @param array $properties
  2020. * @param string|callable|null $message
  2021. * @param string|null $propertyPath
  2022. *
  2023. * @return bool
  2024. *
  2025. * @throws \Assert\AssertionFailedException
  2026. */
  2027. public static function propertiesExist($value, array $properties, $message = null, $propertyPath = null)
  2028. {
  2029. static::objectOrClass($value);
  2030. static::allString($properties, $message, $propertyPath);
  2031. $invalidProperties = array();
  2032. foreach ($properties as $property) {
  2033. if (!\property_exists($value, $property)) {
  2034. $invalidProperties[] = $property;
  2035. }
  2036. }
  2037. if ($invalidProperties) {
  2038. $message = \sprintf(
  2039. static::generateMessage($message ?: 'Class "%s" does not have these properties: %s.'),
  2040. static::stringify($value),
  2041. static::stringify(\implode(', ', $invalidProperties))
  2042. );
  2043. throw static::createException($value, $message, static::INVALID_PROPERTY, $propertyPath, array('properties' => $properties));
  2044. }
  2045. return true;
  2046. }
  2047. /**
  2048. * Assert comparison of two versions.
  2049. *
  2050. * @param string $version1
  2051. * @param string $operator
  2052. * @param string $version2
  2053. * @param string|callable|null $message
  2054. * @param string|null $propertyPath
  2055. *
  2056. * @return bool
  2057. *
  2058. * @throws \Assert\AssertionFailedException
  2059. */
  2060. public static function version($version1, $operator, $version2, $message = null, $propertyPath = null)
  2061. {
  2062. static::notEmpty($operator, 'versionCompare operator is required and cannot be empty.');
  2063. if (true !== \version_compare($version1, $version2, $operator)) {
  2064. $message = \sprintf(
  2065. static::generateMessage($message ?: 'Version "%s" is not "%s" version "%s".'),
  2066. static::stringify($version1),
  2067. static::stringify($operator),
  2068. static::stringify($version2)
  2069. );
  2070. throw static::createException($version1, $message, static::INVALID_VERSION, $propertyPath, array('operator' => $operator, 'version' => $version2));
  2071. }
  2072. return true;
  2073. }
  2074. /**
  2075. * Assert on PHP version.
  2076. *
  2077. * @param string $operator
  2078. * @param mixed $version
  2079. * @param string|callable|null $message
  2080. * @param string|null $propertyPath
  2081. *
  2082. * @return bool
  2083. *
  2084. * @throws \Assert\AssertionFailedException
  2085. */
  2086. public static function phpVersion($operator, $version, $message = null, $propertyPath = null)
  2087. {
  2088. static::defined('PHP_VERSION');
  2089. return static::version(PHP_VERSION, $operator, $version, $message, $propertyPath);
  2090. }
  2091. /**
  2092. * Assert that extension is loaded and a specific version is installed.
  2093. *
  2094. * @param string $extension
  2095. * @param string $operator
  2096. * @param mixed $version
  2097. * @param string|callable|null $message
  2098. * @param string|null $propertyPath
  2099. *
  2100. * @return bool
  2101. *
  2102. * @throws \Assert\AssertionFailedException
  2103. */
  2104. public static function extensionVersion($extension, $operator, $version, $message = null, $propertyPath = null)
  2105. {
  2106. static::extensionLoaded($extension, $message, $propertyPath);
  2107. return static::version(\phpversion($extension), $operator, $version, $message, $propertyPath);
  2108. }
  2109. /**
  2110. * Determines that the provided value is callable.
  2111. *
  2112. * @param mixed $value
  2113. * @param string|callable|null $message
  2114. * @param string|null $propertyPath
  2115. *
  2116. * @return bool
  2117. */
  2118. public static function isCallable($value, $message = null, $propertyPath = null)
  2119. {
  2120. if (!\is_callable($value)) {
  2121. $message = \sprintf(
  2122. static::generateMessage($message ?: 'Provided "%s" is not a callable.'),
  2123. static::stringify($value)
  2124. );
  2125. throw static::createException($value, $message, static::INVALID_CALLABLE, $propertyPath);
  2126. }
  2127. return true;
  2128. }
  2129. /**
  2130. * Assert that the provided value is valid according to a callback.
  2131. *
  2132. * If the callback returns `false` the assertion will fail.
  2133. *
  2134. * @param mixed $value
  2135. * @param callable $callback
  2136. * @param string|callable|null $message
  2137. * @param string|null $propertyPath
  2138. *
  2139. * @return bool
  2140. */
  2141. public static function satisfy($value, $callback, $message = null, $propertyPath = null)
  2142. {
  2143. static::isCallable($callback);
  2144. if (false === \call_user_func($callback, $value)) {
  2145. $message = \sprintf(
  2146. static::generateMessage($message ?: 'Provided "%s" is invalid according to custom rule.'),
  2147. static::stringify($value)
  2148. );
  2149. throw static::createException($value, $message, static::INVALID_SATISFY, $propertyPath);
  2150. }
  2151. return true;
  2152. }
  2153. /**
  2154. * Assert that value is an IPv4 or IPv6 address
  2155. * (using input_filter/FILTER_VALIDATE_IP).
  2156. *
  2157. * @param string $value
  2158. * @param int|null $flag
  2159. * @param string|callable|null $message
  2160. * @param string|null $propertyPath
  2161. *
  2162. * @return bool
  2163. *
  2164. * @see http://php.net/manual/filter.filters.flags.php
  2165. */
  2166. public static function ip($value, $flag = null, $message = null, $propertyPath = null)
  2167. {
  2168. static::string($value, $message, $propertyPath);
  2169. if (!\filter_var($value, FILTER_VALIDATE_IP, $flag)) {
  2170. $message = \sprintf(
  2171. static::generateMessage($message ?: 'Value "%s" was expected to be a valid IP address.'),
  2172. static::stringify($value)
  2173. );
  2174. throw static::createException($value, $message, static::INVALID_IP, $propertyPath, array('flag' => $flag));
  2175. }
  2176. return true;
  2177. }
  2178. /**
  2179. * Assert that value is an IPv4 address
  2180. * (using input_filter/FILTER_VALIDATE_IP).
  2181. *
  2182. * @param string $value
  2183. * @param int|null $flag
  2184. * @param string|callable|null $message
  2185. * @param string|null $propertyPath
  2186. *
  2187. * @return bool
  2188. *
  2189. * @see http://php.net/manual/filter.filters.flags.php
  2190. */
  2191. public static function ipv4($value, $flag = null, $message = null, $propertyPath = null)
  2192. {
  2193. static::ip($value, $flag | FILTER_FLAG_IPV4, static::generateMessage($message ?: 'Value "%s" was expected to be a valid IPv4 address.'), $propertyPath);
  2194. return true;
  2195. }
  2196. /**
  2197. * Assert that value is an IPv6 address
  2198. * (using input_filter/FILTER_VALIDATE_IP).
  2199. *
  2200. * @param string $value
  2201. * @param int|null $flag
  2202. * @param string|callable|null $message
  2203. * @param string|null $propertyPath
  2204. *
  2205. * @return bool
  2206. *
  2207. * @see http://php.net/manual/filter.filters.flags.php
  2208. */
  2209. public static function ipv6($value, $flag = null, $message = null, $propertyPath = null)
  2210. {
  2211. static::ip($value, $flag | FILTER_FLAG_IPV6, static::generateMessage($message ?: 'Value "%s" was expected to be a valid IPv6 address.'), $propertyPath);
  2212. return true;
  2213. }
  2214. /**
  2215. * Make a string version of a value.
  2216. *
  2217. * @param mixed $value
  2218. *
  2219. * @return string
  2220. */
  2221. protected static function stringify($value)
  2222. {
  2223. $result = \gettype($value);
  2224. if (\is_bool($value)) {
  2225. $result = $value ? '<TRUE>' : '<FALSE>';
  2226. } elseif (\is_scalar($value)) {
  2227. $val = (string) $value;
  2228. if (\strlen($val) > 100) {
  2229. $val = \substr($val, 0, 97) . '...';
  2230. }
  2231. $result = $val;
  2232. } elseif (\is_array($value)) {
  2233. $result = '<ARRAY>';
  2234. } elseif (\is_object($value)) {
  2235. $result = \get_class($value);
  2236. } elseif (\is_resource($value)) {
  2237. $result = \get_resource_type($value);
  2238. } elseif (null === $value) {
  2239. $result = '<NULL>';
  2240. }
  2241. return $result;
  2242. }
  2243. /**
  2244. * Assert that a constant is defined.
  2245. *
  2246. * @param mixed $constant
  2247. * @param string|callable|null $message
  2248. * @param string|null $propertyPath
  2249. *
  2250. * @return bool
  2251. *
  2252. * @throws \Assert\AssertionFailedException
  2253. */
  2254. public static function defined($constant, $message = null, $propertyPath = null)
  2255. {
  2256. if (!\defined($constant)) {
  2257. $message = \sprintf(static::generateMessage($message ?: 'Value "%s" expected to be a defined constant.'), $constant);
  2258. throw static::createException($constant, $message, static::INVALID_CONSTANT, $propertyPath);
  2259. }
  2260. return true;
  2261. }
  2262. /**
  2263. * Assert that a constant is defined.
  2264. *
  2265. * @param string $value
  2266. * @param string|callable|null $message
  2267. * @param string|null $propertyPath
  2268. *
  2269. * @return bool
  2270. *
  2271. * @throws \Assert\AssertionFailedException
  2272. */
  2273. public static function base64($value, $message = null, $propertyPath = null)
  2274. {
  2275. if (false === \base64_decode($value, true)) {
  2276. $message = \sprintf(static::generateMessage($message ?: 'Value "%s" is not a valid base64 string.'), $value);
  2277. throw static::createException($value, $message, static::INVALID_BASE64, $propertyPath);
  2278. }
  2279. return true;
  2280. }
  2281. /**
  2282. * Generate the message.
  2283. *
  2284. * @param string|callable|null $message
  2285. *
  2286. * @return string|null
  2287. */
  2288. protected static function generateMessage($message = null)
  2289. {
  2290. if (\is_callable($message)) {
  2291. $traces = \debug_backtrace(0);
  2292. $parameters = array();
  2293. $reflection = new \ReflectionClass($traces[1]['class']);
  2294. $method = $reflection->getMethod($traces[1]['function']);
  2295. foreach ($method->getParameters() as $index => $parameter) {
  2296. if ('message' !== $parameter->getName()) {
  2297. $parameters[$parameter->getName()] = \array_key_exists($index, $traces[1]['args'])
  2298. ? $traces[1]['args'][$index]
  2299. : $parameter->getDefaultValue();
  2300. }
  2301. }
  2302. $parameters['::assertion'] = \sprintf('%s%s%s', $traces[1]['class'], $traces[1]['type'], $traces[1]['function']);
  2303. $message = \call_user_func_array($message, array($parameters));
  2304. }
  2305. return \is_null($message) ? null : (string) $message;
  2306. }
  2307. }