ÿØÿà JFIF    ÿÛ „  ( %!1"%)+...383-7(-.+  -%%--------+------------/----------------------------ÿÀ  ¶" ÿÄ     ÿÄ @    !1AQaq‘¡"±ÁÑð2’BRráS‚ñ3b¢CT²Ò #cÿÄ    ÿÄ '   1!AQ2a"‘±#ÿÚ   ? ò(/p‘—–¢·,M|¯G»R£üešT. ôŸEoCFñ‡ 4ÔkåóxR|µÁ¨ÓDà!Ç´µ˜‡p ÍQ‹§!þž^õWsŒy  åÁ§$á«%ºq˜™JyyË0y«^Ϗ -3ÃÏËÈ£Æ\P’ä„s&•‹Üs üô'àWt¹pñCp$bÚF`·7.^)¾!)ÒÙ˜–ÅÏš^h¾ø³·ìe±ŒaeÖ—Í,e=B}Jéߦ$$½—šÙÜCC¯¶è8β–Åkèwx LÉngT±æ¹£Ócœ¿Í/©Éÿ ‰ÚCÒ­mq;Tt¶–}0"zÖPcd1š­¤tˆ„ÐÓâqú[™öUCŠ2޿د­É(¸ßúçšmW,Ò ºf‹Ån™ÄLêÁ8üÁkÁ€L¥ÍuJ1œôrÂSŒÓöt!7EUíïb)AËi¬â-ÙHk8òÁiXYwÅ)O^"ÇØriÛô{»wRUKÙÏÚlÓ¬€‚’שT ] ªb—ÊîKC^×M“xùäñz¬zJ× {4[¹M'IÆeH1LCWÕ]œûº WDæà°OÅ‚¹c²ÞuA–rL`HšpCez‡V’— Ž‚Ë„–ñ­'µR0ÕÖ=À:±G»C\nÆÉ5*¢ †3šhQ4ýÒi$Õ1"Ü]¢p-q3zcQ$ªö¨¥æf›‘»´ÝÚHá„e²JÇ–iÊ:·à¬Øc5Åk»Laª*wi [0Ówk ¦a¦0Õ²ÅÅ‚T¸’³q:Æ<¹ú Ò˜Æ}2VE•Ѐp¡Ô3Úº …h³^LJºçì¥Ánó|˜ÖˆÎˆ+« ¦dø‘Mº–d\ªDðÛ„Ì×LÝ——Ð9Ç|•FèçVm™¨€™3õS–9Äå¢<̉Ìm¢±`·º˜&Z²ž Ë®D«¶»6™‰©­HÈ Àá«h­i³04æ’hxœi3ï¨(ÓL·†‹¶ËpŒ ƒÜÒ? :õdsÀ –3æÓ·Üjâ¬9—]8n¼&]I F£¼…ì–—Œ0v°LǐÅfÛ2TÖ’aµ˜N@ÖBSÏ^à´4-±°b×nÈÈœÆD=KdŒø…ÄÈK,›ÖR§fjü$^ÔÎ!„6^ s:Üun\ôkCÞò÷<—Lúl Í›G¹ÀPá¼Nc¡šÒ…ÙWͳœ±vÊáЄ×9‹P‰cEØ‘™›µŸP<×g1 º©Ø¬wiÁ^l5× I/';Ë+´Z‡ÓÄFÕp[Èð’ HÄ ó 9¬Dl4“é±Ï”V=^Hð;žLädÉa‚°Ë,#/Ž~²BÔÛ QãñQtIeórVB,ÏÂf‹4#Μc‹É3ZIÖ Œ¢¥·üxa‡Ãçè„jŠ[5 Ä!U?,3žÎ×…ðdÓ÷háŠA‰ìÄ4÷ÃÜZÃE{‰®+W\ZÍE[‰»µk»MÝ­`¢©†˜ÃV‹-f¢¡†¢a«eŠ%«Y¨©q%jâd,Ôq`) ¤¦…šˆ ¦E>0Ùb²t–Ÿ  ÷jsςҒKÈcø(é›;k(’#ôŒQ ™C> õ³M9óºÆµ¤çâ;uÀ)5>RÔ¸fÓ~Ȧ—’-$fe«"FâUˆÊwµPÏu w+"åÉó¨6s™Û9(À¨ù©hE°½†n`m~“@©›p!Vkhµ Á1šbEqqÊ@ºèl›2 –Yã%‘‚hÛ{a¶‡ÅÞM²¬çL34®Çl]®‹ŽØŒm'RÜe35æöˆ­Á­ cP9šeÁköo´L³Ì=p8]”‡B¶,šº|ɏdzXˆØk*ÇÚ{#ñ‰pã(€¶‡9ý'šÜ³½¯kƒ†Â’ëSOƒ•Å®H6+a¢µˆ‹Y¨b˜b+XˆÖ!°u!¢"µˆˆn2ˆ Å0Ä`Å Ô®c(ÓÜGº•Ä»Œ âWî%q.áÐÄ÷î%umÍ£+ÜQ,Vn¦-GphU¸¢X­&,Gt ·K¢ÅÅ·¥RÄÊÉbKn N­R2g$VµÕó Qr#–ÓZUÏð0ÎtÙÀœz ëöo“Îk¯n„T°"SÞ+³/…€½"ižãO%Í%&Δâ‘ËØ´IˆÓ°Ë‰ÞM3.™yçÁzit›`4C`k¢¼á!álÄï sÂ[×!¤l¾æo"ƒIÔ'@ªu)3›ô®“@Z à¾] üœ'‡4¸PÞkÁ-qÄH‰ÓÍBd´ÿ —¹°ÄA&ÊUC„öz‚‚RæŠtf¬>˜ÑidšEçÑL÷áý¡V±h§­c¿¥¨ƒ@g¼…Ýö^ÞËc.ž„æ“I[ ª+·zÐÒÚ,½Ð»¶€C›7jk$๖€Ž¾ÅÙpp¶ÍþéΤ ½ØÎŒq ñpæžÅ¥#Øâ49ÃÂK^MYV“,¶Éz_òæ:…;Õ«¦I3âJ£¤û5$7Èxün\â]Êe¯(Ÿ&Ž‹¶2<6Ćf× æ¢ƱqWı[(ÙÂŽç‚T7¨@ÈÉÍß‚ïÙ"&3TYlGށ†)†#5ŠA©^T2ÆÁ†)©†©†¤yGXÁ†©"†)©¼ÅV WS†#©]R–r‹q5ÕbâWþBh¯u+ªÅÄ×ü„nÑ^êkªÁj‰jeœWˆÕÕ`µDµ2Ì+Ä µDµµ5Ô{¤Þ0RF’H÷AÛ<ÊÁ§ ƈæ0Ñ£ê4 öÚµ[¬/1²€â<-¬šö²r×0o×w ´xÐÒË„ g01¬„åEM蛇Ã\6µE›‘fÙO k÷CºnÓ1`iîÒ² áÂ!ÑLÄÿ ³¬\õ*:M=Ç»c‹2[‰ØsÕLò\ŒK L^™üÄN\¶#» Ç\……ßïIœÉ$¸ÎñÍ®ÔHÇ Ûí/´>Li”„†g^$ 7NÍÑÑ2M2ªNg=k½Ð}Ÿl6‡ —JWˆ”ÞéT·+µ¦üÂFè¢Vs6ýÆ4»2+2IÝ9ô9®ÇGÙÇ1+Ä8;*Õ§ž½D*îÑWÚçá3Ma¤·ˆ¥t}š²Ü…Q+Æüµ8HíS”üxGéÁˆ¦Ël„éÈ 5 µÄƒ6äÜ(kIš¯S†fÖ&¸®×v|Äyˆ*禌Éù@7-®Ä[]ÎÖ¿ê`º…=:…žJVnݳvðÖKE¼‚ »mà ÷f®:Ë ™–4rð¡4` ܹçž~‹C=œ…¾Ïj|VDtK.ƒ"9 Ï ­–éXá³6WÒïIL-Ї Ç PK\6mjRFCValidation.phpnu[parser = new EmailParser($emailLexer); try { $this->parser->parse((string)$email); } catch (InvalidEmail $invalid) { $this->error = $invalid; return false; } $this->warnings = $this->parser->getWarnings(); return true; } public function getError() { return $this->error; } public function getWarnings() { return $this->warnings; } } PK\7NoRFCWarningsValidation.phpnu[getWarnings())) { return true; } $this->error = new RFCWarnings(); return false; } /** * {@inheritdoc} */ public function getError() { return $this->error ?: parent::getError(); } } PK\v^Error/SpoofEmail.phpnu[setChecks(Spoofchecker::SINGLE_SCRIPT); if ($checker->isSuspicious($email)) { $this->error = new SpoofEmail(); } return $this->error === null; } /** * @return InvalidEmail|null */ public function getError() { return $this->error; } public function getWarnings() { return []; } } PK\P;__!Exception/EmptyValidationList.phpnu[error = new LocalOrReservedDomain(); return false; } return $this->checkDns($host); } public function getError() { return $this->error; } public function getWarnings() { return $this->warnings; } /** * @param string $host * * @return bool */ protected function checkDns($host) { $variant = INTL_IDNA_VARIANT_UTS46; $host = rtrim(idn_to_ascii($host, IDNA_DEFAULT, $variant), '.') . '.'; return $this->validateDnsRecords($host); } /** * Validate the DNS records for given host. * * @param string $host A set of DNS records in the format returned by dns_get_record. * * @return bool True on success. */ private function validateDnsRecords($host) { // Get all MX, A and AAAA DNS records for host // Using @ as workaround to fix https://bugs.php.net/bug.php?id=73149 $dnsRecords = @dns_get_record($host, DNS_MX + DNS_A + DNS_AAAA); // No MX, A or AAAA DNS records if (empty($dnsRecords)) { $this->error = new NoDNSRecord(); return false; } // For each DNS record foreach ($dnsRecords as $dnsRecord) { if (!$this->validateMXRecord($dnsRecord)) { return false; } } // No MX records (fallback to A or AAAA records) if (empty($this->mxRecords)) { $this->warnings[NoDNSMXRecord::CODE] = new NoDNSMXRecord(); } return true; } /** * Validate an MX record * * @param array $dnsRecord Given DNS record. * * @return bool True if valid. */ private function validateMxRecord($dnsRecord) { if ($dnsRecord['type'] !== 'MX') { return true; } // "Null MX" record indicates the domain accepts no mail (https://tools.ietf.org/html/rfc7505) if (empty($dnsRecord['target']) || $dnsRecord['target'] === '.') { $this->error = new DomainAcceptsNoMail(); return false; } $this->mxRecords[] = $dnsRecord; return true; } } PK\3av^^MultipleErrors.phpnu[errors = $errors; parent::__construct(); } /** * @return InvalidEmail[] */ public function getErrors() { return $this->errors; } } PK\fP߃ MultipleValidationWithAnd.phpnu[validations = $validations; $this->mode = $mode; } /** * {@inheritdoc} */ public function isValid($email, EmailLexer $emailLexer) { $result = true; $errors = []; foreach ($this->validations as $validation) { $emailLexer->reset(); $validationResult = $validation->isValid($email, $emailLexer); $result = $result && $validationResult; $this->warnings = array_merge($this->warnings, $validation->getWarnings()); $errors = $this->addNewError($validation->getError(), $errors); if ($this->shouldStop($result)) { break; } } if (!empty($errors)) { $this->error = new MultipleErrors($errors); } return $result; } /** * @param \Egulias\EmailValidator\Exception\InvalidEmail|null $possibleError * @param \Egulias\EmailValidator\Exception\InvalidEmail[] $errors * * @return \Egulias\EmailValidator\Exception\InvalidEmail[] */ private function addNewError($possibleError, array $errors) { if (null !== $possibleError) { $errors[] = $possibleError; } return $errors; } /** * @param bool $result * * @return bool */ private function shouldStop($result) { return !$result && $this->mode === self::STOP_ON_ERROR; } /** * Returns the validation errors. * * @return MultipleErrors|null */ public function getError() { return $this->error; } /** * {@inheritdoc} */ public function getWarnings() { return $this->warnings; } } PKf\RPValidatesWhenResolvedTrait.phpnu[prepareForValidation(); if (! $this->passesAuthorization()) { $this->failedAuthorization(); } $instance = $this->getValidatorInstance(); if ($instance->fails()) { $this->failedValidation($instance); } $this->passedValidation(); } /** * Prepare the data for validation. * * @return void */ protected function prepareForValidation() { // } /** * Get the validator instance for the request. * * @return \Illuminate\Validation\Validator */ protected function getValidatorInstance() { return $this->validator(); } /** * Handle a passed validation attempt. * * @return void */ protected function passedValidation() { // } /** * Handle a failed validation attempt. * * @param \Illuminate\Validation\Validator $validator * @return void * * @throws \Illuminate\Validation\ValidationException */ protected function failedValidation(Validator $validator) { throw new ValidationException($validator); } /** * Determine if the request passes the authorization check. * * @return bool */ protected function passesAuthorization() { if (method_exists($this, 'authorize')) { return $this->authorize(); } return true; } /** * Handle a failed authorization attempt. * * @return void * * @throws \Illuminate\Validation\UnauthorizedException */ protected function failedAuthorization() { throw new UnauthorizedException; } } PKf\C~-<%DatabasePresenceVerifierInterface.phpnu[flags = $flags; } /** * Create a new instance which allows any unicode characters in local-part. * * @return static */ public static function unicode() { return new static(FILTER_FLAG_EMAIL_UNICODE); } /** * Returns true if the given email is valid. * * @param string $email * @param \Egulias\EmailValidator\EmailLexer $emailLexer * @return bool */ public function isValid($email, EmailLexer $emailLexer) { return is_null($this->flags) ? filter_var($email, FILTER_VALIDATE_EMAIL) !== false : filter_var($email, FILTER_VALIDATE_EMAIL, $this->flags) !== false; } /** * Returns the validation error. * * @return \Egulias\EmailValidator\Exception\InvalidEmail|null */ public function getError() { // } /** * Returns the validation warnings. * * @return \Egulias\EmailValidator\Warning\Warning[] */ public function getWarnings() { return []; } } PKf\XG{5I5IConcerns/ReplacesAttributes.phpnu[getDisplayableValue($parameters[0], Arr::get($this->data, $parameters[0])); $parameters[0] = $this->getDisplayableAttribute($parameters[0]); return str_replace([':other', ':value'], $parameters, $message); } /** * Replace all place-holders for the declined_if rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceDeclinedIf($message, $attribute, $rule, $parameters) { $parameters[1] = $this->getDisplayableValue($parameters[0], Arr::get($this->data, $parameters[0])); $parameters[0] = $this->getDisplayableAttribute($parameters[0]); return str_replace([':other', ':value'], $parameters, $message); } /** * Replace all place-holders for the between rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceBetween($message, $attribute, $rule, $parameters) { return str_replace([':min', ':max'], $parameters, $message); } /** * Replace all place-holders for the date_format rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceDateFormat($message, $attribute, $rule, $parameters) { return str_replace(':format', $parameters[0], $message); } /** * Replace all place-holders for the different rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceDifferent($message, $attribute, $rule, $parameters) { return $this->replaceSame($message, $attribute, $rule, $parameters); } /** * Replace all place-holders for the digits rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceDigits($message, $attribute, $rule, $parameters) { return str_replace(':digits', $parameters[0], $message); } /** * Replace all place-holders for the digits (between) rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceDigitsBetween($message, $attribute, $rule, $parameters) { return $this->replaceBetween($message, $attribute, $rule, $parameters); } /** * Replace all place-holders for the min rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceMin($message, $attribute, $rule, $parameters) { return str_replace(':min', $parameters[0], $message); } /** * Replace all place-holders for the max rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceMax($message, $attribute, $rule, $parameters) { return str_replace(':max', $parameters[0], $message); } /** * Replace all place-holders for the multiple_of rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceMultipleOf($message, $attribute, $rule, $parameters) { return str_replace(':value', $parameters[0] ?? '', $message); } /** * Replace all place-holders for the in rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceIn($message, $attribute, $rule, $parameters) { foreach ($parameters as &$parameter) { $parameter = $this->getDisplayableValue($attribute, $parameter); } return str_replace(':values', implode(', ', $parameters), $message); } /** * Replace all place-holders for the not_in rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceNotIn($message, $attribute, $rule, $parameters) { return $this->replaceIn($message, $attribute, $rule, $parameters); } /** * Replace all place-holders for the in_array rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceInArray($message, $attribute, $rule, $parameters) { return str_replace(':other', $this->getDisplayableAttribute($parameters[0]), $message); } /** * Replace all place-holders for the required_array_keys rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceRequiredArrayKeys($message, $attribute, $rule, $parameters) { foreach ($parameters as &$parameter) { $parameter = $this->getDisplayableValue($attribute, $parameter); } return str_replace(':values', implode(', ', $parameters), $message); } /** * Replace all place-holders for the mimetypes rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceMimetypes($message, $attribute, $rule, $parameters) { return str_replace(':values', implode(', ', $parameters), $message); } /** * Replace all place-holders for the mimes rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceMimes($message, $attribute, $rule, $parameters) { return str_replace(':values', implode(', ', $parameters), $message); } /** * Replace all place-holders for the required_with rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceRequiredWith($message, $attribute, $rule, $parameters) { return str_replace(':values', implode(' / ', $this->getAttributeList($parameters)), $message); } /** * Replace all place-holders for the required_with_all rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceRequiredWithAll($message, $attribute, $rule, $parameters) { return $this->replaceRequiredWith($message, $attribute, $rule, $parameters); } /** * Replace all place-holders for the required_without rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceRequiredWithout($message, $attribute, $rule, $parameters) { return $this->replaceRequiredWith($message, $attribute, $rule, $parameters); } /** * Replace all place-holders for the required_without_all rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceRequiredWithoutAll($message, $attribute, $rule, $parameters) { return $this->replaceRequiredWith($message, $attribute, $rule, $parameters); } /** * Replace all place-holders for the size rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceSize($message, $attribute, $rule, $parameters) { return str_replace(':size', $parameters[0], $message); } /** * Replace all place-holders for the gt rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceGt($message, $attribute, $rule, $parameters) { if (is_null($value = $this->getValue($parameters[0]))) { return str_replace(':value', $this->getDisplayableAttribute($parameters[0]), $message); } return str_replace(':value', $this->getSize($attribute, $value), $message); } /** * Replace all place-holders for the lt rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceLt($message, $attribute, $rule, $parameters) { if (is_null($value = $this->getValue($parameters[0]))) { return str_replace(':value', $this->getDisplayableAttribute($parameters[0]), $message); } return str_replace(':value', $this->getSize($attribute, $value), $message); } /** * Replace all place-holders for the gte rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceGte($message, $attribute, $rule, $parameters) { if (is_null($value = $this->getValue($parameters[0]))) { return str_replace(':value', $this->getDisplayableAttribute($parameters[0]), $message); } return str_replace(':value', $this->getSize($attribute, $value), $message); } /** * Replace all place-holders for the lte rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceLte($message, $attribute, $rule, $parameters) { if (is_null($value = $this->getValue($parameters[0]))) { return str_replace(':value', $this->getDisplayableAttribute($parameters[0]), $message); } return str_replace(':value', $this->getSize($attribute, $value), $message); } /** * Replace all place-holders for the required_if rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceRequiredIf($message, $attribute, $rule, $parameters) { $parameters[1] = $this->getDisplayableValue($parameters[0], Arr::get($this->data, $parameters[0])); $parameters[0] = $this->getDisplayableAttribute($parameters[0]); return str_replace([':other', ':value'], $parameters, $message); } /** * Replace all place-holders for the required_unless rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceRequiredUnless($message, $attribute, $rule, $parameters) { $other = $this->getDisplayableAttribute($parameters[0]); $values = []; foreach (array_slice($parameters, 1) as $value) { $values[] = $this->getDisplayableValue($parameters[0], $value); } return str_replace([':other', ':values'], [$other, implode(', ', $values)], $message); } /** * Replace all place-holders for the prohibited_if rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceProhibitedIf($message, $attribute, $rule, $parameters) { $parameters[1] = $this->getDisplayableValue($parameters[0], Arr::get($this->data, $parameters[0])); $parameters[0] = $this->getDisplayableAttribute($parameters[0]); return str_replace([':other', ':value'], $parameters, $message); } /** * Replace all place-holders for the prohibited_unless rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceProhibitedUnless($message, $attribute, $rule, $parameters) { $other = $this->getDisplayableAttribute($parameters[0]); $values = []; foreach (array_slice($parameters, 1) as $value) { $values[] = $this->getDisplayableValue($parameters[0], $value); } return str_replace([':other', ':values'], [$other, implode(', ', $values)], $message); } /** * Replace all place-holders for the prohibited_with rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceProhibits($message, $attribute, $rule, $parameters) { return str_replace(':other', implode(' / ', $this->getAttributeList($parameters)), $message); } /** * Replace all place-holders for the same rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceSame($message, $attribute, $rule, $parameters) { return str_replace(':other', $this->getDisplayableAttribute($parameters[0]), $message); } /** * Replace all place-holders for the before rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceBefore($message, $attribute, $rule, $parameters) { if (! strtotime($parameters[0])) { return str_replace(':date', $this->getDisplayableAttribute($parameters[0]), $message); } return str_replace(':date', $this->getDisplayableValue($attribute, $parameters[0]), $message); } /** * Replace all place-holders for the before_or_equal rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceBeforeOrEqual($message, $attribute, $rule, $parameters) { return $this->replaceBefore($message, $attribute, $rule, $parameters); } /** * Replace all place-holders for the after rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceAfter($message, $attribute, $rule, $parameters) { return $this->replaceBefore($message, $attribute, $rule, $parameters); } /** * Replace all place-holders for the after_or_equal rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceAfterOrEqual($message, $attribute, $rule, $parameters) { return $this->replaceBefore($message, $attribute, $rule, $parameters); } /** * Replace all place-holders for the date_equals rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceDateEquals($message, $attribute, $rule, $parameters) { return $this->replaceBefore($message, $attribute, $rule, $parameters); } /** * Replace all place-holders for the dimensions rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceDimensions($message, $attribute, $rule, $parameters) { $parameters = $this->parseNamedParameters($parameters); if (is_array($parameters)) { foreach ($parameters as $key => $value) { $message = str_replace(':'.$key, $value, $message); } } return $message; } /** * Replace all place-holders for the ends_with rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceEndsWith($message, $attribute, $rule, $parameters) { foreach ($parameters as &$parameter) { $parameter = $this->getDisplayableValue($attribute, $parameter); } return str_replace(':values', implode(', ', $parameters), $message); } /** * Replace all place-holders for the starts_with rule. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ protected function replaceStartsWith($message, $attribute, $rule, $parameters) { foreach ($parameters as &$parameter) { $parameter = $this->getDisplayableValue($attribute, $parameter); } return str_replace(':values', implode(', ', $parameters), $message); } } PKf\zaa Concerns/ValidatesAttributes.phpnu[validateRequired($attribute, $value) && in_array($value, $acceptable, true); } /** * Validate that an attribute was "accepted" when another attribute has a given value. * * @param string $attribute * @param mixed $value * @param mixed $parameters * @return bool */ public function validateAcceptedIf($attribute, $value, $parameters) { $acceptable = ['yes', 'on', '1', 1, true, 'true']; $this->requireParameterCount(2, $parameters, 'accepted_if'); [$values, $other] = $this->parseDependentRuleParameters($parameters); if (in_array($other, $values, is_bool($other) || is_null($other))) { return $this->validateRequired($attribute, $value) && in_array($value, $acceptable, true); } return true; } /** * Validate that an attribute was "declined". * * This validation rule implies the attribute is "required". * * @param string $attribute * @param mixed $value * @return bool */ public function validateDeclined($attribute, $value) { $acceptable = ['no', 'off', '0', 0, false, 'false']; return $this->validateRequired($attribute, $value) && in_array($value, $acceptable, true); } /** * Validate that an attribute was "declined" when another attribute has a given value. * * @param string $attribute * @param mixed $value * @param mixed $parameters * @return bool */ public function validateDeclinedIf($attribute, $value, $parameters) { $acceptable = ['no', 'off', '0', 0, false, 'false']; $this->requireParameterCount(2, $parameters, 'declined_if'); [$values, $other] = $this->parseDependentRuleParameters($parameters); if (in_array($other, $values, is_bool($other) || is_null($other))) { return $this->validateRequired($attribute, $value) && in_array($value, $acceptable, true); } return true; } /** * Validate that an attribute is an active URL. * * @param string $attribute * @param mixed $value * @return bool */ public function validateActiveUrl($attribute, $value) { if (! is_string($value)) { return false; } if ($url = parse_url($value, PHP_URL_HOST)) { try { return count(dns_get_record($url.'.', DNS_A | DNS_AAAA)) > 0; } catch (Exception $e) { return false; } } return false; } /** * "Break" on first validation fail. * * Always returns true, just lets us put "bail" in rules. * * @return bool */ public function validateBail() { return true; } /** * Validate the date is before a given date. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateBefore($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'before'); return $this->compareDates($attribute, $value, $parameters, '<'); } /** * Validate the date is before or equal a given date. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateBeforeOrEqual($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'before_or_equal'); return $this->compareDates($attribute, $value, $parameters, '<='); } /** * Validate the date is after a given date. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateAfter($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'after'); return $this->compareDates($attribute, $value, $parameters, '>'); } /** * Validate the date is equal or after a given date. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateAfterOrEqual($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'after_or_equal'); return $this->compareDates($attribute, $value, $parameters, '>='); } /** * Compare a given date against another using an operator. * * @param string $attribute * @param mixed $value * @param array $parameters * @param string $operator * @return bool */ protected function compareDates($attribute, $value, $parameters, $operator) { if (! is_string($value) && ! is_numeric($value) && ! $value instanceof DateTimeInterface) { return false; } if ($format = $this->getDateFormat($attribute)) { return $this->checkDateTimeOrder($format, $value, $parameters[0], $operator); } if (! $date = $this->getDateTimestamp($parameters[0])) { $date = $this->getDateTimestamp($this->getValue($parameters[0])); } return $this->compare($this->getDateTimestamp($value), $date, $operator); } /** * Get the date format for an attribute if it has one. * * @param string $attribute * @return string|null */ protected function getDateFormat($attribute) { if ($result = $this->getRule($attribute, 'DateFormat')) { return $result[1][0]; } } /** * Get the date timestamp. * * @param mixed $value * @return int */ protected function getDateTimestamp($value) { $date = is_null($value) ? null : $this->getDateTime($value); return $date ? $date->getTimestamp() : null; } /** * Given two date/time strings, check that one is after the other. * * @param string $format * @param string $first * @param string $second * @param string $operator * @return bool */ protected function checkDateTimeOrder($format, $first, $second, $operator) { $firstDate = $this->getDateTimeWithOptionalFormat($format, $first); if (! $secondDate = $this->getDateTimeWithOptionalFormat($format, $second)) { if (is_null($second = $this->getValue($second))) { return true; } $secondDate = $this->getDateTimeWithOptionalFormat($format, $second); } return ($firstDate && $secondDate) && ($this->compare($firstDate, $secondDate, $operator)); } /** * Get a DateTime instance from a string. * * @param string $format * @param string $value * @return \DateTime|null */ protected function getDateTimeWithOptionalFormat($format, $value) { if ($date = DateTime::createFromFormat('!'.$format, $value)) { return $date; } return $this->getDateTime($value); } /** * Get a DateTime instance from a string with no format. * * @param string $value * @return \DateTime|null */ protected function getDateTime($value) { try { return @Date::parse($value) ?: null; } catch (Exception $e) { // } } /** * Validate that an attribute contains only alphabetic characters. * * @param string $attribute * @param mixed $value * @return bool */ public function validateAlpha($attribute, $value) { return is_string($value) && preg_match('/^[\pL\pM]+$/u', $value); } /** * Validate that an attribute contains only alpha-numeric characters, dashes, and underscores. * * @param string $attribute * @param mixed $value * @return bool */ public function validateAlphaDash($attribute, $value) { if (! is_string($value) && ! is_numeric($value)) { return false; } return preg_match('/^[\pL\pM\pN_-]+$/u', $value) > 0; } /** * Validate that an attribute contains only alpha-numeric characters. * * @param string $attribute * @param mixed $value * @return bool */ public function validateAlphaNum($attribute, $value) { if (! is_string($value) && ! is_numeric($value)) { return false; } return preg_match('/^[\pL\pM\pN]+$/u', $value) > 0; } /** * Validate that an attribute is an array. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateArray($attribute, $value, $parameters = []) { if (! is_array($value)) { return false; } if (empty($parameters)) { return true; } return empty(array_diff_key($value, array_fill_keys($parameters, ''))); } /** * Validate that an array has all of the given keys. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateRequiredArrayKeys($attribute, $value, $parameters) { if (! is_array($value)) { return false; } foreach ($parameters as $param) { if (! Arr::exists($value, $param)) { return false; } } return true; } /** * Validate the size of an attribute is between a set of values. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateBetween($attribute, $value, $parameters) { $this->requireParameterCount(2, $parameters, 'between'); $size = $this->getSize($attribute, $value); return $size >= $parameters[0] && $size <= $parameters[1]; } /** * Validate that an attribute is a boolean. * * @param string $attribute * @param mixed $value * @return bool */ public function validateBoolean($attribute, $value) { $acceptable = [true, false, 0, 1, '0', '1']; return in_array($value, $acceptable, true); } /** * Validate that an attribute has a matching confirmation. * * @param string $attribute * @param mixed $value * @return bool */ public function validateConfirmed($attribute, $value) { return $this->validateSame($attribute, $value, [$attribute.'_confirmation']); } /** * Validate that the password of the currently authenticated user matches the given value. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ protected function validateCurrentPassword($attribute, $value, $parameters) { $auth = $this->container->make('auth'); $hasher = $this->container->make('hash'); $guard = $auth->guard(Arr::first($parameters)); if ($guard->guest()) { return false; } return $hasher->check($value, $guard->user()->getAuthPassword()); } /** * Validate that an attribute is a valid date. * * @param string $attribute * @param mixed $value * @return bool */ public function validateDate($attribute, $value) { if ($value instanceof DateTimeInterface) { return true; } try { if ((! is_string($value) && ! is_numeric($value)) || strtotime($value) === false) { return false; } } catch (Exception $e) { return false; } $date = date_parse($value); return checkdate($date['month'], $date['day'], $date['year']); } /** * Validate that an attribute matches a date format. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateDateFormat($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'date_format'); if (! is_string($value) && ! is_numeric($value)) { return false; } foreach ($parameters as $format) { $date = DateTime::createFromFormat('!'.$format, $value); if ($date && $date->format($format) == $value) { return true; } } return false; } /** * Validate that an attribute is equal to another date. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateDateEquals($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'date_equals'); return $this->compareDates($attribute, $value, $parameters, '='); } /** * Validate that an attribute is different from another attribute. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateDifferent($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'different'); foreach ($parameters as $parameter) { if (Arr::has($this->data, $parameter)) { $other = Arr::get($this->data, $parameter); if ($value === $other) { return false; } } } return true; } /** * Validate that an attribute has a given number of digits. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateDigits($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'digits'); return ! preg_match('/[^0-9]/', $value) && strlen((string) $value) == $parameters[0]; } /** * Validate that an attribute is between a given number of digits. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateDigitsBetween($attribute, $value, $parameters) { $this->requireParameterCount(2, $parameters, 'digits_between'); $length = strlen((string) $value); return ! preg_match('/[^0-9]/', $value) && $length >= $parameters[0] && $length <= $parameters[1]; } /** * Validate the dimensions of an image matches the given values. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateDimensions($attribute, $value, $parameters) { if ($this->isValidFileInstance($value) && in_array($value->getMimeType(), ['image/svg+xml', 'image/svg'])) { return true; } if (! $this->isValidFileInstance($value) || ! $sizeDetails = @getimagesize($value->getRealPath())) { return false; } $this->requireParameterCount(1, $parameters, 'dimensions'); [$width, $height] = $sizeDetails; $parameters = $this->parseNamedParameters($parameters); if ($this->failsBasicDimensionChecks($parameters, $width, $height) || $this->failsRatioCheck($parameters, $width, $height)) { return false; } return true; } /** * Test if the given width and height fail any conditions. * * @param array $parameters * @param int $width * @param int $height * @return bool */ protected function failsBasicDimensionChecks($parameters, $width, $height) { return (isset($parameters['width']) && $parameters['width'] != $width) || (isset($parameters['min_width']) && $parameters['min_width'] > $width) || (isset($parameters['max_width']) && $parameters['max_width'] < $width) || (isset($parameters['height']) && $parameters['height'] != $height) || (isset($parameters['min_height']) && $parameters['min_height'] > $height) || (isset($parameters['max_height']) && $parameters['max_height'] < $height); } /** * Determine if the given parameters fail a dimension ratio check. * * @param array $parameters * @param int $width * @param int $height * @return bool */ protected function failsRatioCheck($parameters, $width, $height) { if (! isset($parameters['ratio'])) { return false; } [$numerator, $denominator] = array_replace( [1, 1], array_filter(sscanf($parameters['ratio'], '%f/%d')) ); $precision = 1 / (max($width, $height) + 1); return abs($numerator / $denominator - $width / $height) > $precision; } /** * Validate an attribute is unique among other values. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateDistinct($attribute, $value, $parameters) { $data = Arr::except($this->getDistinctValues($attribute), $attribute); if (in_array('ignore_case', $parameters)) { return empty(preg_grep('/^'.preg_quote($value, '/').'$/iu', $data)); } return ! in_array($value, array_values($data), in_array('strict', $parameters)); } /** * Get the values to distinct between. * * @param string $attribute * @return array */ protected function getDistinctValues($attribute) { $attributeName = $this->getPrimaryAttribute($attribute); if (! property_exists($this, 'distinctValues')) { return $this->extractDistinctValues($attributeName); } if (! array_key_exists($attributeName, $this->distinctValues)) { $this->distinctValues[$attributeName] = $this->extractDistinctValues($attributeName); } return $this->distinctValues[$attributeName]; } /** * Extract the distinct values from the data. * * @param string $attribute * @return array */ protected function extractDistinctValues($attribute) { $attributeData = ValidationData::extractDataFromPath( ValidationData::getLeadingExplicitAttributePath($attribute), $this->data ); $pattern = str_replace('\*', '[^.]+', preg_quote($attribute, '#')); return Arr::where(Arr::dot($attributeData), function ($value, $key) use ($pattern) { return (bool) preg_match('#^'.$pattern.'\z#u', $key); }); } /** * Validate that an attribute is a valid e-mail address. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateEmail($attribute, $value, $parameters) { if (! is_string($value) && ! (is_object($value) && method_exists($value, '__toString'))) { return false; } $validations = collect($parameters) ->unique() ->map(function ($validation) { if ($validation === 'rfc') { return new RFCValidation; } elseif ($validation === 'strict') { return new NoRFCWarningsValidation; } elseif ($validation === 'dns') { return new DNSCheckValidation; } elseif ($validation === 'spoof') { return new SpoofCheckValidation; } elseif ($validation === 'filter') { return new FilterEmailValidation; } elseif ($validation === 'filter_unicode') { return FilterEmailValidation::unicode(); } elseif (is_string($validation) && class_exists($validation)) { return $this->container->make($validation); } }) ->values() ->all() ?: [new RFCValidation]; return (new EmailValidator)->isValid($value, new MultipleValidationWithAnd($validations)); } /** * Validate the existence of an attribute value in a database table. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateExists($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'exists'); [$connection, $table] = $this->parseTable($parameters[0]); // The second parameter position holds the name of the column that should be // verified as existing. If this parameter is not specified we will guess // that the columns being "verified" shares the given attribute's name. $column = $this->getQueryColumn($parameters, $attribute); $expected = is_array($value) ? count(array_unique($value)) : 1; return $this->getExistCount( $connection, $table, $column, $value, $parameters ) >= $expected; } /** * Get the number of records that exist in storage. * * @param mixed $connection * @param string $table * @param string $column * @param mixed $value * @param array $parameters * @return int */ protected function getExistCount($connection, $table, $column, $value, $parameters) { $verifier = $this->getPresenceVerifier($connection); $extra = $this->getExtraConditions( array_values(array_slice($parameters, 2)) ); if ($this->currentRule instanceof Exists) { $extra = array_merge($extra, $this->currentRule->queryCallbacks()); } return is_array($value) ? $verifier->getMultiCount($table, $column, $value, $extra) : $verifier->getCount($table, $column, $value, null, null, $extra); } /** * Validate the uniqueness of an attribute value on a given database table. * * If a database column is not specified, the attribute will be used. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateUnique($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'unique'); [$connection, $table, $idColumn] = $this->parseTable($parameters[0]); // The second parameter position holds the name of the column that needs to // be verified as unique. If this parameter isn't specified we will just // assume that this column to be verified shares the attribute's name. $column = $this->getQueryColumn($parameters, $attribute); $id = null; if (isset($parameters[2])) { [$idColumn, $id] = $this->getUniqueIds($idColumn, $parameters); if (! is_null($id)) { $id = stripslashes($id); } } // The presence verifier is responsible for counting rows within this store // mechanism which might be a relational database or any other permanent // data store like Redis, etc. We will use it to determine uniqueness. $verifier = $this->getPresenceVerifier($connection); $extra = $this->getUniqueExtra($parameters); if ($this->currentRule instanceof Unique) { $extra = array_merge($extra, $this->currentRule->queryCallbacks()); } return $verifier->getCount( $table, $column, $value, $id, $idColumn, $extra ) == 0; } /** * Get the excluded ID column and value for the unique rule. * * @param string|null $idColumn * @param array $parameters * @return array */ protected function getUniqueIds($idColumn, $parameters) { $idColumn = $idColumn ?? $parameters[3] ?? 'id'; return [$idColumn, $this->prepareUniqueId($parameters[2])]; } /** * Prepare the given ID for querying. * * @param mixed $id * @return int */ protected function prepareUniqueId($id) { if (preg_match('/\[(.*)\]/', $id, $matches)) { $id = $this->getValue($matches[1]); } if (strtolower($id) === 'null') { $id = null; } if (filter_var($id, FILTER_VALIDATE_INT) !== false) { $id = (int) $id; } return $id; } /** * Get the extra conditions for a unique rule. * * @param array $parameters * @return array */ protected function getUniqueExtra($parameters) { if (isset($parameters[4])) { return $this->getExtraConditions(array_slice($parameters, 4)); } return []; } /** * Parse the connection / table for the unique / exists rules. * * @param string $table * @return array */ public function parseTable($table) { [$connection, $table] = Str::contains($table, '.') ? explode('.', $table, 2) : [null, $table]; if (Str::contains($table, '\\') && class_exists($table) && is_a($table, Model::class, true)) { $model = new $table; $table = $model->getTable(); $connection = $connection ?? $model->getConnectionName(); if (Str::contains($table, '.') && Str::startsWith($table, $connection)) { $connection = null; } $idColumn = $model->getKeyName(); } return [$connection, $table, $idColumn ?? null]; } /** * Get the column name for an exists / unique query. * * @param array $parameters * @param string $attribute * @return bool */ public function getQueryColumn($parameters, $attribute) { return isset($parameters[1]) && $parameters[1] !== 'NULL' ? $parameters[1] : $this->guessColumnForQuery($attribute); } /** * Guess the database column from the given attribute name. * * @param string $attribute * @return string */ public function guessColumnForQuery($attribute) { if (in_array($attribute, Arr::collapse($this->implicitAttributes)) && ! is_numeric($last = last(explode('.', $attribute)))) { return $last; } return $attribute; } /** * Get the extra conditions for a unique / exists rule. * * @param array $segments * @return array */ protected function getExtraConditions(array $segments) { $extra = []; $count = count($segments); for ($i = 0; $i < $count; $i += 2) { $extra[$segments[$i]] = $segments[$i + 1]; } return $extra; } /** * Validate the given value is a valid file. * * @param string $attribute * @param mixed $value * @return bool */ public function validateFile($attribute, $value) { return $this->isValidFileInstance($value); } /** * Validate the given attribute is filled if it is present. * * @param string $attribute * @param mixed $value * @return bool */ public function validateFilled($attribute, $value) { if (Arr::has($this->data, $attribute)) { return $this->validateRequired($attribute, $value); } return true; } /** * Validate that an attribute is greater than another attribute. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateGt($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'gt'); $comparedToValue = $this->getValue($parameters[0]); $this->shouldBeNumeric($attribute, 'Gt'); if (is_null($comparedToValue) && (is_numeric($value) && is_numeric($parameters[0]))) { return $this->getSize($attribute, $value) > $parameters[0]; } if (is_numeric($parameters[0])) { return false; } if ($this->hasRule($attribute, $this->numericRules) && is_numeric($value) && is_numeric($comparedToValue)) { return $value > $comparedToValue; } if (! $this->isSameType($value, $comparedToValue)) { return false; } return $this->getSize($attribute, $value) > $this->getSize($attribute, $comparedToValue); } /** * Validate that an attribute is less than another attribute. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateLt($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'lt'); $comparedToValue = $this->getValue($parameters[0]); $this->shouldBeNumeric($attribute, 'Lt'); if (is_null($comparedToValue) && (is_numeric($value) && is_numeric($parameters[0]))) { return $this->getSize($attribute, $value) < $parameters[0]; } if (is_numeric($parameters[0])) { return false; } if ($this->hasRule($attribute, $this->numericRules) && is_numeric($value) && is_numeric($comparedToValue)) { return $value < $comparedToValue; } if (! $this->isSameType($value, $comparedToValue)) { return false; } return $this->getSize($attribute, $value) < $this->getSize($attribute, $comparedToValue); } /** * Validate that an attribute is greater than or equal another attribute. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateGte($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'gte'); $comparedToValue = $this->getValue($parameters[0]); $this->shouldBeNumeric($attribute, 'Gte'); if (is_null($comparedToValue) && (is_numeric($value) && is_numeric($parameters[0]))) { return $this->getSize($attribute, $value) >= $parameters[0]; } if (is_numeric($parameters[0])) { return false; } if ($this->hasRule($attribute, $this->numericRules) && is_numeric($value) && is_numeric($comparedToValue)) { return $value >= $comparedToValue; } if (! $this->isSameType($value, $comparedToValue)) { return false; } return $this->getSize($attribute, $value) >= $this->getSize($attribute, $comparedToValue); } /** * Validate that an attribute is less than or equal another attribute. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateLte($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'lte'); $comparedToValue = $this->getValue($parameters[0]); $this->shouldBeNumeric($attribute, 'Lte'); if (is_null($comparedToValue) && (is_numeric($value) && is_numeric($parameters[0]))) { return $this->getSize($attribute, $value) <= $parameters[0]; } if (is_numeric($parameters[0])) { return false; } if ($this->hasRule($attribute, $this->numericRules) && is_numeric($value) && is_numeric($comparedToValue)) { return $value <= $comparedToValue; } if (! $this->isSameType($value, $comparedToValue)) { return false; } return $this->getSize($attribute, $value) <= $this->getSize($attribute, $comparedToValue); } /** * Validate the MIME type of a file is an image MIME type. * * @param string $attribute * @param mixed $value * @return bool */ public function validateImage($attribute, $value) { return $this->validateMimes($attribute, $value, ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp']); } /** * Validate an attribute is contained within a list of values. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateIn($attribute, $value, $parameters) { if (is_array($value) && $this->hasRule($attribute, 'Array')) { foreach ($value as $element) { if (is_array($element)) { return false; } } return count(array_diff($value, $parameters)) === 0; } return ! is_array($value) && in_array((string) $value, $parameters); } /** * Validate that the values of an attribute are in another attribute. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateInArray($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'in_array'); $explicitPath = ValidationData::getLeadingExplicitAttributePath($parameters[0]); $attributeData = ValidationData::extractDataFromPath($explicitPath, $this->data); $otherValues = Arr::where(Arr::dot($attributeData), function ($value, $key) use ($parameters) { return Str::is($parameters[0], $key); }); return in_array($value, $otherValues); } /** * Validate that an attribute is an integer. * * @param string $attribute * @param mixed $value * @return bool */ public function validateInteger($attribute, $value) { return filter_var($value, FILTER_VALIDATE_INT) !== false; } /** * Validate that an attribute is a valid IP. * * @param string $attribute * @param mixed $value * @return bool */ public function validateIp($attribute, $value) { return filter_var($value, FILTER_VALIDATE_IP) !== false; } /** * Validate that an attribute is a valid IPv4. * * @param string $attribute * @param mixed $value * @return bool */ public function validateIpv4($attribute, $value) { return filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false; } /** * Validate that an attribute is a valid IPv6. * * @param string $attribute * @param mixed $value * @return bool */ public function validateIpv6($attribute, $value) { return filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false; } /** * Validate that an attribute is a valid MAC address. * * @param string $attribute * @param mixed $value * @return bool */ public function validateMacAddress($attribute, $value) { return filter_var($value, FILTER_VALIDATE_MAC) !== false; } /** * Validate the attribute is a valid JSON string. * * @param string $attribute * @param mixed $value * @return bool */ public function validateJson($attribute, $value) { if (is_array($value)) { return false; } if (! is_scalar($value) && ! is_null($value) && ! method_exists($value, '__toString')) { return false; } json_decode($value); return json_last_error() === JSON_ERROR_NONE; } /** * Validate the size of an attribute is less than a maximum value. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateMax($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'max'); if ($value instanceof UploadedFile && ! $value->isValid()) { return false; } return $this->getSize($attribute, $value) <= $parameters[0]; } /** * Validate the guessed extension of a file upload is in a set of file extensions. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateMimes($attribute, $value, $parameters) { if (! $this->isValidFileInstance($value)) { return false; } if ($this->shouldBlockPhpUpload($value, $parameters)) { return false; } if (in_array('jpg', $parameters) || in_array('jpeg', $parameters)) { $parameters = array_unique(array_merge($parameters, ['jpg', 'jpeg'])); } return $value->getPath() !== '' && in_array($value->guessExtension(), $parameters); } /** * Validate the MIME type of a file upload attribute is in a set of MIME types. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateMimetypes($attribute, $value, $parameters) { if (! $this->isValidFileInstance($value)) { return false; } if ($this->shouldBlockPhpUpload($value, $parameters)) { return false; } return $value->getPath() !== '' && (in_array($value->getMimeType(), $parameters) || in_array(explode('/', $value->getMimeType())[0].'/*', $parameters)); } /** * Check if PHP uploads are explicitly allowed. * * @param mixed $value * @param array $parameters * @return bool */ protected function shouldBlockPhpUpload($value, $parameters) { if (in_array('php', $parameters)) { return false; } $phpExtensions = [ 'php', 'php3', 'php4', 'php5', 'phtml', 'phar', ]; return ($value instanceof UploadedFile) ? in_array(trim(strtolower($value->getClientOriginalExtension())), $phpExtensions) : in_array(trim(strtolower($value->getExtension())), $phpExtensions); } /** * Validate the size of an attribute is greater than a minimum value. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateMin($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'min'); return $this->getSize($attribute, $value) >= $parameters[0]; } /** * Validate the value of an attribute is a multiple of a given value. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateMultipleOf($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'multiple_of'); if (! $this->validateNumeric($attribute, $value) || ! $this->validateNumeric($attribute, $parameters[0])) { return false; } if ((float) $parameters[0] === 0.0) { return false; } return bcmod($value, $parameters[0], 16) === '0.0000000000000000'; } /** * "Indicate" validation should pass if value is null. * * Always returns true, just lets us put "nullable" in rules. * * @return bool */ public function validateNullable() { return true; } /** * Validate an attribute is not contained within a list of values. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateNotIn($attribute, $value, $parameters) { return ! $this->validateIn($attribute, $value, $parameters); } /** * Validate that an attribute is numeric. * * @param string $attribute * @param mixed $value * @return bool */ public function validateNumeric($attribute, $value) { return is_numeric($value); } /** * Validate that the password of the currently authenticated user matches the given value. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ protected function validatePassword($attribute, $value, $parameters) { return $this->validateCurrentPassword($attribute, $value, $parameters); } /** * Validate that an attribute exists even if not filled. * * @param string $attribute * @param mixed $value * @return bool */ public function validatePresent($attribute, $value) { return Arr::has($this->data, $attribute); } /** * Validate that an attribute passes a regular expression check. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateRegex($attribute, $value, $parameters) { if (! is_string($value) && ! is_numeric($value)) { return false; } $this->requireParameterCount(1, $parameters, 'regex'); return preg_match($parameters[0], $value) > 0; } /** * Validate that an attribute does not pass a regular expression check. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateNotRegex($attribute, $value, $parameters) { if (! is_string($value) && ! is_numeric($value)) { return false; } $this->requireParameterCount(1, $parameters, 'not_regex'); return preg_match($parameters[0], $value) < 1; } /** * Validate that a required attribute exists. * * @param string $attribute * @param mixed $value * @return bool */ public function validateRequired($attribute, $value) { if (is_null($value)) { return false; } elseif (is_string($value) && trim($value) === '') { return false; } elseif ((is_array($value) || $value instanceof Countable) && count($value) < 1) { return false; } elseif ($value instanceof File) { return (string) $value->getPath() !== ''; } return true; } /** * Validate that an attribute exists when another attribute has a given value. * * @param string $attribute * @param mixed $value * @param mixed $parameters * @return bool */ public function validateRequiredIf($attribute, $value, $parameters) { $this->requireParameterCount(2, $parameters, 'required_if'); if (! Arr::has($this->data, $parameters[0])) { return true; } [$values, $other] = $this->parseDependentRuleParameters($parameters); if (in_array($other, $values, is_bool($other) || is_null($other))) { return $this->validateRequired($attribute, $value); } return true; } /** * Validate that an attribute does not exist. * * @param string $attribute * @param mixed $value * @param mixed $parameters * @return bool */ public function validateProhibited($attribute, $value) { return false; } /** * Validate that an attribute does not exist when another attribute has a given value. * * @param string $attribute * @param mixed $value * @param mixed $parameters * @return bool */ public function validateProhibitedIf($attribute, $value, $parameters) { $this->requireParameterCount(2, $parameters, 'prohibited_if'); [$values, $other] = $this->parseDependentRuleParameters($parameters); if (in_array($other, $values, is_bool($other) || is_null($other))) { return ! $this->validateRequired($attribute, $value); } return true; } /** * Validate that an attribute does not exist unless another attribute has a given value. * * @param string $attribute * @param mixed $value * @param mixed $parameters * @return bool */ public function validateProhibitedUnless($attribute, $value, $parameters) { $this->requireParameterCount(2, $parameters, 'prohibited_unless'); [$values, $other] = $this->parseDependentRuleParameters($parameters); if (! in_array($other, $values, is_bool($other) || is_null($other))) { return ! $this->validateRequired($attribute, $value); } return true; } /** * Validate that other attributes do not exist when this attribute exists. * * @param string $attribute * @param mixed $value * @param mixed $parameters * @return bool */ public function validateProhibits($attribute, $value, $parameters) { return ! Arr::hasAny($this->data, $parameters); } /** * Indicate that an attribute is excluded. * * @return bool */ public function validateExclude() { return false; } /** * Indicate that an attribute should be excluded when another attribute has a given value. * * @param string $attribute * @param mixed $value * @param mixed $parameters * @return bool */ public function validateExcludeIf($attribute, $value, $parameters) { $this->requireParameterCount(2, $parameters, 'exclude_if'); if (! Arr::has($this->data, $parameters[0])) { return true; } [$values, $other] = $this->parseDependentRuleParameters($parameters); return ! in_array($other, $values, is_bool($other) || is_null($other)); } /** * Indicate that an attribute should be excluded when another attribute does not have a given value. * * @param string $attribute * @param mixed $value * @param mixed $parameters * @return bool */ public function validateExcludeUnless($attribute, $value, $parameters) { $this->requireParameterCount(2, $parameters, 'exclude_unless'); [$values, $other] = $this->parseDependentRuleParameters($parameters); return in_array($other, $values, is_bool($other) || is_null($other)); } /** * Validate that an attribute exists when another attribute does not have a given value. * * @param string $attribute * @param mixed $value * @param mixed $parameters * @return bool */ public function validateRequiredUnless($attribute, $value, $parameters) { $this->requireParameterCount(2, $parameters, 'required_unless'); [$values, $other] = $this->parseDependentRuleParameters($parameters); if (! in_array($other, $values, is_bool($other) || is_null($other))) { return $this->validateRequired($attribute, $value); } return true; } /** * Indicate that an attribute should be excluded when another attribute is missing. * * @param string $attribute * @param mixed $value * @param mixed $parameters * @return bool */ public function validateExcludeWithout($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'exclude_without'); if ($this->anyFailingRequired($parameters)) { return false; } return true; } /** * Prepare the values and the other value for validation. * * @param array $parameters * @return array */ public function parseDependentRuleParameters($parameters) { $other = Arr::get($this->data, $parameters[0]); $values = array_slice($parameters, 1); if ($this->shouldConvertToBoolean($parameters[0]) || is_bool($other)) { $values = $this->convertValuesToBoolean($values); } if (is_null($other)) { $values = $this->convertValuesToNull($values); } return [$values, $other]; } /** * Check if parameter should be converted to boolean. * * @param string $parameter * @return bool */ protected function shouldConvertToBoolean($parameter) { return in_array('boolean', Arr::get($this->rules, $parameter, [])); } /** * Convert the given values to boolean if they are string "true" / "false". * * @param array $values * @return array */ protected function convertValuesToBoolean($values) { return array_map(function ($value) { if ($value === 'true') { return true; } elseif ($value === 'false') { return false; } return $value; }, $values); } /** * Convert the given values to null if they are string "null". * * @param array $values * @return array */ protected function convertValuesToNull($values) { return array_map(function ($value) { return Str::lower($value) === 'null' ? null : $value; }, $values); } /** * Validate that an attribute exists when any other attribute exists. * * @param string $attribute * @param mixed $value * @param mixed $parameters * @return bool */ public function validateRequiredWith($attribute, $value, $parameters) { if (! $this->allFailingRequired($parameters)) { return $this->validateRequired($attribute, $value); } return true; } /** * Validate that an attribute exists when all other attributes exist. * * @param string $attribute * @param mixed $value * @param mixed $parameters * @return bool */ public function validateRequiredWithAll($attribute, $value, $parameters) { if (! $this->anyFailingRequired($parameters)) { return $this->validateRequired($attribute, $value); } return true; } /** * Validate that an attribute exists when another attribute does not. * * @param string $attribute * @param mixed $value * @param mixed $parameters * @return bool */ public function validateRequiredWithout($attribute, $value, $parameters) { if ($this->anyFailingRequired($parameters)) { return $this->validateRequired($attribute, $value); } return true; } /** * Validate that an attribute exists when all other attributes do not. * * @param string $attribute * @param mixed $value * @param mixed $parameters * @return bool */ public function validateRequiredWithoutAll($attribute, $value, $parameters) { if ($this->allFailingRequired($parameters)) { return $this->validateRequired($attribute, $value); } return true; } /** * Determine if any of the given attributes fail the required test. * * @param array $attributes * @return bool */ protected function anyFailingRequired(array $attributes) { foreach ($attributes as $key) { if (! $this->validateRequired($key, $this->getValue($key))) { return true; } } return false; } /** * Determine if all of the given attributes fail the required test. * * @param array $attributes * @return bool */ protected function allFailingRequired(array $attributes) { foreach ($attributes as $key) { if ($this->validateRequired($key, $this->getValue($key))) { return false; } } return true; } /** * Validate that two attributes match. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateSame($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'same'); $other = Arr::get($this->data, $parameters[0]); return $value === $other; } /** * Validate the size of an attribute. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateSize($attribute, $value, $parameters) { $this->requireParameterCount(1, $parameters, 'size'); return $this->getSize($attribute, $value) == $parameters[0]; } /** * "Validate" optional attributes. * * Always returns true, just lets us put sometimes in rules. * * @return bool */ public function validateSometimes() { return true; } /** * Validate the attribute starts with a given substring. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateStartsWith($attribute, $value, $parameters) { return Str::startsWith($value, $parameters); } /** * Validate the attribute ends with a given substring. * * @param string $attribute * @param mixed $value * @param array $parameters * @return bool */ public function validateEndsWith($attribute, $value, $parameters) { return Str::endsWith($value, $parameters); } /** * Validate that an attribute is a string. * * @param string $attribute * @param mixed $value * @return bool */ public function validateString($attribute, $value) { return is_string($value); } /** * Validate that an attribute is a valid timezone. * * @param string $attribute * @param mixed $value * @return bool */ public function validateTimezone($attribute, $value) { return in_array($value, timezone_identifiers_list(), true); } /** * Validate that an attribute is a valid URL. * * @param string $attribute * @param mixed $value * @return bool */ public function validateUrl($attribute, $value) { if (! is_string($value)) { return false; } /* * This pattern is derived from Symfony\Component\Validator\Constraints\UrlValidator (5.0.7). * * (c) Fabien Potencier http://symfony.com */ $pattern = '~^ (aaa|aaas|about|acap|acct|acd|acr|adiumxtra|adt|afp|afs|aim|amss|android|appdata|apt|ark|attachment|aw|barion|beshare|bitcoin|bitcoincash|blob|bolo|browserext|calculator|callto|cap|cast|casts|chrome|chrome-extension|cid|coap|coap\+tcp|coap\+ws|coaps|coaps\+tcp|coaps\+ws|com-eventbrite-attendee|content|conti|crid|cvs|dab|data|dav|diaspora|dict|did|dis|dlna-playcontainer|dlna-playsingle|dns|dntp|dpp|drm|drop|dtn|dvb|ed2k|elsi|example|facetime|fax|feed|feedready|file|filesystem|finger|first-run-pen-experience|fish|fm|ftp|fuchsia-pkg|geo|gg|git|gizmoproject|go|gopher|graph|gtalk|h323|ham|hcap|hcp|http|https|hxxp|hxxps|hydrazone|iax|icap|icon|im|imap|info|iotdisco|ipn|ipp|ipps|irc|irc6|ircs|iris|iris\.beep|iris\.lwz|iris\.xpc|iris\.xpcs|isostore|itms|jabber|jar|jms|keyparc|lastfm|ldap|ldaps|leaptofrogans|lorawan|lvlt|magnet|mailserver|mailto|maps|market|message|mid|mms|modem|mongodb|moz|ms-access|ms-browser-extension|ms-calculator|ms-drive-to|ms-enrollment|ms-excel|ms-eyecontrolspeech|ms-gamebarservices|ms-gamingoverlay|ms-getoffice|ms-help|ms-infopath|ms-inputapp|ms-lockscreencomponent-config|ms-media-stream-id|ms-mixedrealitycapture|ms-mobileplans|ms-officeapp|ms-people|ms-project|ms-powerpoint|ms-publisher|ms-restoretabcompanion|ms-screenclip|ms-screensketch|ms-search|ms-search-repair|ms-secondary-screen-controller|ms-secondary-screen-setup|ms-settings|ms-settings-airplanemode|ms-settings-bluetooth|ms-settings-camera|ms-settings-cellular|ms-settings-cloudstorage|ms-settings-connectabledevices|ms-settings-displays-topology|ms-settings-emailandaccounts|ms-settings-language|ms-settings-location|ms-settings-lock|ms-settings-nfctransactions|ms-settings-notifications|ms-settings-power|ms-settings-privacy|ms-settings-proximity|ms-settings-screenrotation|ms-settings-wifi|ms-settings-workplace|ms-spd|ms-sttoverlay|ms-transit-to|ms-useractivityset|ms-virtualtouchpad|ms-visio|ms-walk-to|ms-whiteboard|ms-whiteboard-cmd|ms-word|msnim|msrp|msrps|mss|mtqp|mumble|mupdate|mvn|news|nfs|ni|nih|nntp|notes|ocf|oid|onenote|onenote-cmd|opaquelocktoken|openpgp4fpr|pack|palm|paparazzi|payto|pkcs11|platform|pop|pres|prospero|proxy|pwid|psyc|pttp|qb|query|redis|rediss|reload|res|resource|rmi|rsync|rtmfp|rtmp|rtsp|rtsps|rtspu|s3|secondlife|service|session|sftp|sgn|shttp|sieve|simpleledger|sip|sips|skype|smb|sms|smtp|snews|snmp|soap\.beep|soap\.beeps|soldat|spiffe|spotify|ssh|steam|stun|stuns|submit|svn|tag|teamspeak|tel|teliaeid|telnet|tftp|tg|things|thismessage|tip|tn3270|tool|ts3server|turn|turns|tv|udp|unreal|urn|ut2004|v-event|vemmi|ventrilo|videotex|vnc|view-source|wais|webcal|wpid|ws|wss|wtai|wyciwyg|xcon|xcon-userid|xfire|xmlrpc\.beep|xmlrpc\.beeps|xmpp|xri|ymsgr|z39\.50|z39\.50r|z39\.50s):// # protocol (((?:[\_\.\pL\pN-]|%[0-9A-Fa-f]{2})+:)?((?:[\_\.\pL\pN-]|%[0-9A-Fa-f]{2})+)@)? # basic auth ( ([\pL\pN\pS\-\_\.])+(\.?([\pL\pN]|xn\-\-[\pL\pN-]+)+\.?) # a domain name | # or \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} # an IP address | # or \[ (?:(?:(?:(?:(?:(?:(?:[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})))?::)))) \] # an IPv6 address ) (:[0-9]+)? # a port (optional) (?:/ (?:[\pL\pN\-._\~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})* )* # a path (?:\? (?:[\pL\pN\-._\~!$&\'\[\]()*+,;=:@/?]|%[0-9A-Fa-f]{2})* )? # a query (optional) (?:\# (?:[\pL\pN\-._\~!$&\'()*+,;=:@/?]|%[0-9A-Fa-f]{2})* )? # a fragment (optional) $~ixu'; return preg_match($pattern, $value) > 0; } /** * Validate that an attribute is a valid UUID. * * @param string $attribute * @param mixed $value * @return bool */ public function validateUuid($attribute, $value) { return Str::isUuid($value); } /** * Get the size of an attribute. * * @param string $attribute * @param mixed $value * @return mixed */ protected function getSize($attribute, $value) { $hasNumeric = $this->hasRule($attribute, $this->numericRules); // This method will determine if the attribute is a number, string, or file and // return the proper size accordingly. If it is a number, then number itself // is the size. If it is a file, we take kilobytes, and for a string the // entire length of the string will be considered the attribute size. if (is_numeric($value) && $hasNumeric) { return $value; } elseif (is_array($value)) { return count($value); } elseif ($value instanceof File) { return $value->getSize() / 1024; } return mb_strlen($value ?? ''); } /** * Check that the given value is a valid file instance. * * @param mixed $value * @return bool */ public function isValidFileInstance($value) { if ($value instanceof UploadedFile && ! $value->isValid()) { return false; } return $value instanceof File; } /** * Determine if a comparison passes between the given values. * * @param mixed $first * @param mixed $second * @param string $operator * @return bool * * @throws \InvalidArgumentException */ protected function compare($first, $second, $operator) { switch ($operator) { case '<': return $first < $second; case '>': return $first > $second; case '<=': return $first <= $second; case '>=': return $first >= $second; case '=': return $first == $second; default: throw new InvalidArgumentException; } } /** * Parse named parameters to $key => $value items. * * @param array $parameters * @return array */ public function parseNamedParameters($parameters) { return array_reduce($parameters, function ($result, $item) { [$key, $value] = array_pad(explode('=', $item, 2), 2, null); $result[$key] = $value; return $result; }); } /** * Require a certain number of parameters to be present. * * @param int $count * @param array $parameters * @param string $rule * @return void * * @throws \InvalidArgumentException */ public function requireParameterCount($count, $parameters, $rule) { if (count($parameters) < $count) { throw new InvalidArgumentException("Validation rule $rule requires at least $count parameters."); } } /** * Check if the parameters are of the same type. * * @param mixed $first * @param mixed $second * @return bool */ protected function isSameType($first, $second) { return gettype($first) == gettype($second); } /** * Adds the existing rule to the numericRules array if the attribute's value is numeric. * * @param string $attribute * @param string $rule * @return void */ protected function shouldBeNumeric($attribute, $rule) { if (is_numeric($this->getValue($attribute))) { $this->numericRules[] = $rule; } } } PKf\44Concerns/FormatsMessages.phpnu[replacePlaceholderInString($attribute); $inlineMessage = $this->getInlineMessage($attribute, $rule); // First we will retrieve the custom message for the validation rule if one // exists. If a custom validation message is being used we'll return the // custom message, otherwise we'll keep searching for a valid message. if (! is_null($inlineMessage)) { return $inlineMessage; } $lowerRule = Str::snake($rule); $customMessage = $this->getCustomMessageFromTranslator( $customKey = "validation.custom.{$attribute}.{$lowerRule}" ); // First we check for a custom defined validation message for the attribute // and rule. This allows the developer to specify specific messages for // only some attributes and rules that need to get specially formed. if ($customMessage !== $customKey) { return $customMessage; } // If the rule being validated is a "size" rule, we will need to gather the // specific error message for the type of attribute being validated such // as a number, file or string which all have different message types. elseif (in_array($rule, $this->sizeRules)) { return $this->getSizeMessage($attributeWithPlaceholders, $rule); } // Finally, if no developer specified messages have been set, and no other // special messages apply for this rule, we will just pull the default // messages out of the translator service for this validation rule. $key = "validation.{$lowerRule}"; if ($key !== ($value = $this->translator->get($key))) { return $value; } return $this->getFromLocalArray( $attribute, $lowerRule, $this->fallbackMessages ) ?: $key; } /** * Get the proper inline error message for standard and size rules. * * @param string $attribute * @param string $rule * @return string|null */ protected function getInlineMessage($attribute, $rule) { $inlineEntry = $this->getFromLocalArray($attribute, Str::snake($rule)); return is_array($inlineEntry) && in_array($rule, $this->sizeRules) ? $inlineEntry[$this->getAttributeType($attribute)] : $inlineEntry; } /** * Get the inline message for a rule if it exists. * * @param string $attribute * @param string $lowerRule * @param array|null $source * @return string|null */ protected function getFromLocalArray($attribute, $lowerRule, $source = null) { $source = $source ?: $this->customMessages; $keys = ["{$attribute}.{$lowerRule}", $lowerRule]; // First we will check for a custom message for an attribute specific rule // message for the fields, then we will check for a general custom line // that is not attribute specific. If we find either we'll return it. foreach ($keys as $key) { foreach (array_keys($source) as $sourceKey) { if (strpos($sourceKey, '*') !== false) { $pattern = str_replace('\*', '([^.]*)', preg_quote($sourceKey, '#')); if (preg_match('#^'.$pattern.'\z#u', $key) === 1) { return $source[$sourceKey]; } continue; } if (Str::is($sourceKey, $key)) { return $source[$sourceKey]; } } } } /** * Get the custom error message from the translator. * * @param string $key * @return string */ protected function getCustomMessageFromTranslator($key) { if (($message = $this->translator->get($key)) !== $key) { return $message; } // If an exact match was not found for the key, we will collapse all of these // messages and loop through them and try to find a wildcard match for the // given key. Otherwise, we will simply return the key's value back out. $shortKey = preg_replace( '/^validation\.custom\./', '', $key ); return $this->getWildcardCustomMessages(Arr::dot( (array) $this->translator->get('validation.custom') ), $shortKey, $key); } /** * Check the given messages for a wildcard key. * * @param array $messages * @param string $search * @param string $default * @return string */ protected function getWildcardCustomMessages($messages, $search, $default) { foreach ($messages as $key => $message) { if ($search === $key || (Str::contains($key, ['*']) && Str::is($key, $search))) { return $message; } } return $default; } /** * Get the proper error message for an attribute and size rule. * * @param string $attribute * @param string $rule * @return string */ protected function getSizeMessage($attribute, $rule) { $lowerRule = Str::snake($rule); // There are three different types of size validations. The attribute may be // either a number, file, or string so we will check a few things to know // which type of value it is and return the correct line for that type. $type = $this->getAttributeType($attribute); $key = "validation.{$lowerRule}.{$type}"; return $this->translator->get($key); } /** * Get the data type of the given attribute. * * @param string $attribute * @return string */ protected function getAttributeType($attribute) { // We assume that the attributes present in the file array are files so that // means that if the attribute does not have a numeric rule and the files // list doesn't have it we'll just consider it a string by elimination. if ($this->hasRule($attribute, $this->numericRules)) { return 'numeric'; } elseif ($this->hasRule($attribute, ['Array'])) { return 'array'; } elseif ($this->getValue($attribute) instanceof UploadedFile) { return 'file'; } return 'string'; } /** * Replace all error message place-holders with actual values. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @return string */ public function makeReplacements($message, $attribute, $rule, $parameters) { $message = $this->replaceAttributePlaceholder( $message, $this->getDisplayableAttribute($attribute) ); $message = $this->replaceInputPlaceholder($message, $attribute); if (isset($this->replacers[Str::snake($rule)])) { return $this->callReplacer($message, $attribute, Str::snake($rule), $parameters, $this); } elseif (method_exists($this, $replacer = "replace{$rule}")) { return $this->$replacer($message, $attribute, $rule, $parameters); } return $message; } /** * Get the displayable name of the attribute. * * @param string $attribute * @return string */ public function getDisplayableAttribute($attribute) { $primaryAttribute = $this->getPrimaryAttribute($attribute); $expectedAttributes = $attribute != $primaryAttribute ? [$attribute, $primaryAttribute] : [$attribute]; foreach ($expectedAttributes as $name) { // The developer may dynamically specify the array of custom attributes on this // validator instance. If the attribute exists in this array it is used over // the other ways of pulling the attribute name for this given attributes. if (isset($this->customAttributes[$name])) { return $this->customAttributes[$name]; } // We allow for a developer to specify language lines for any attribute in this // application, which allows flexibility for displaying a unique displayable // version of the attribute name instead of the name used in an HTTP POST. if ($line = $this->getAttributeFromTranslations($name)) { return $line; } } // When no language line has been specified for the attribute and it is also // an implicit attribute we will display the raw attribute's name and not // modify it with any of these replacements before we display the name. if (isset($this->implicitAttributes[$primaryAttribute])) { return ($formatter = $this->implicitAttributesFormatter) ? $formatter($attribute) : $attribute; } return str_replace('_', ' ', Str::snake($attribute)); } /** * Get the given attribute from the attribute translations. * * @param string $name * @return string */ protected function getAttributeFromTranslations($name) { return Arr::get($this->translator->get('validation.attributes'), $name); } /** * Replace the :attribute placeholder in the given message. * * @param string $message * @param string $value * @return string */ protected function replaceAttributePlaceholder($message, $value) { return str_replace( [':attribute', ':ATTRIBUTE', ':Attribute'], [$value, Str::upper($value), Str::ucfirst($value)], $message ); } /** * Replace the :input placeholder in the given message. * * @param string $message * @param string $attribute * @return string */ protected function replaceInputPlaceholder($message, $attribute) { $actualValue = $this->getValue($attribute); if (is_scalar($actualValue) || is_null($actualValue)) { $message = str_replace(':input', $this->getDisplayableValue($attribute, $actualValue), $message); } return $message; } /** * Get the displayable name of the value. * * @param string $attribute * @param mixed $value * @return string */ public function getDisplayableValue($attribute, $value) { if (isset($this->customValues[$attribute][$value])) { return $this->customValues[$attribute][$value]; } $key = "validation.values.{$attribute}.{$value}"; if (($line = $this->translator->get($key)) !== $key) { return $line; } if (is_bool($value)) { return $value ? 'true' : 'false'; } if (is_null($value)) { return 'empty'; } return (string) $value; } /** * Transform an array of attributes to their displayable form. * * @param array $values * @return array */ protected function getAttributeList(array $values) { $attributes = []; // For each attribute in the list we will simply get its displayable form as // this is convenient when replacing lists of parameters like some of the // replacement functions do when formatting out the validation message. foreach ($values as $key => $value) { $attributes[$key] = $this->getDisplayableAttribute($value); } return $attributes; } /** * Call a custom validator message replacer. * * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @param \Illuminate\Validation\Validator $validator * @return string|null */ protected function callReplacer($message, $attribute, $rule, $parameters, $validator) { $callback = $this->replacers[$rule]; if ($callback instanceof Closure) { return $callback(...func_get_args()); } elseif (is_string($callback)) { return $this->callClassBasedReplacer($callback, $message, $attribute, $rule, $parameters, $validator); } } /** * Call a class based validator message replacer. * * @param string $callback * @param string $message * @param string $attribute * @param string $rule * @param array $parameters * @param \Illuminate\Validation\Validator $validator * @return string */ protected function callClassBasedReplacer($callback, $message, $attribute, $rule, $parameters, $validator) { [$class, $method] = Str::parseCallback($callback, 'replace'); return $this->container->make($class)->{$method}(...array_slice(func_get_args(), 1)); } } PKf\Rl ConditionalRules.phpnu[condition = $condition; $this->rules = $rules; $this->defaultRules = $defaultRules; } /** * Determine if the conditional rules should be added. * * @param array $data * @return bool */ public function passes(array $data = []) { return is_callable($this->condition) ? call_user_func($this->condition, new Fluent($data)) : $this->condition; } /** * Get the rules. * * @return array */ public function rules() { return is_string($this->rules) ? explode('|', $this->rules) : $this->rules; } /** * Get the default rules. * * @return array */ public function defaultRules() { return is_string($this->defaultRules) ? explode('|', $this->defaultRules) : $this->defaultRules; } } PKf\aValidationRuleParser.phpnu[data = $data; } /** * Parse the human-friendly rules into a full rules array for the validator. * * @param array $rules * @return \stdClass */ public function explode($rules) { $this->implicitAttributes = []; $rules = $this->explodeRules($rules); return (object) [ 'rules' => $rules, 'implicitAttributes' => $this->implicitAttributes, ]; } /** * Explode the rules into an array of explicit rules. * * @param array $rules * @return array */ protected function explodeRules($rules) { foreach ($rules as $key => $rule) { if (Str::contains($key, '*')) { $rules = $this->explodeWildcardRules($rules, $key, [$rule]); unset($rules[$key]); } else { $rules[$key] = $this->explodeExplicitRule($rule); } } return $rules; } /** * Explode the explicit rule into an array if necessary. * * @param mixed $rule * @return array */ protected function explodeExplicitRule($rule) { if (is_string($rule)) { return explode('|', $rule); } elseif (is_object($rule)) { return [$this->prepareRule($rule)]; } return array_map([$this, 'prepareRule'], $rule); } /** * Prepare the given rule for the Validator. * * @param mixed $rule * @return mixed */ protected function prepareRule($rule) { if ($rule instanceof Closure) { $rule = new ClosureValidationRule($rule); } if (! is_object($rule) || $rule instanceof RuleContract || ($rule instanceof Exists && $rule->queryCallbacks()) || ($rule instanceof Unique && $rule->queryCallbacks())) { return $rule; } return (string) $rule; } /** * Define a set of rules that apply to each element in an array attribute. * * @param array $results * @param string $attribute * @param string|array $rules * @return array */ protected function explodeWildcardRules($results, $attribute, $rules) { $pattern = str_replace('\*', '[^\.]*', preg_quote($attribute)); $data = ValidationData::initializeAndGatherData($attribute, $this->data); foreach ($data as $key => $value) { if (Str::startsWith($key, $attribute) || (bool) preg_match('/^'.$pattern.'\z/', $key)) { foreach ((array) $rules as $rule) { $this->implicitAttributes[$attribute][] = $key; $results = $this->mergeRules($results, $key, $rule); } } } return $results; } /** * Merge additional rules into a given attribute(s). * * @param array $results * @param string|array $attribute * @param string|array $rules * @return array */ public function mergeRules($results, $attribute, $rules = []) { if (is_array($attribute)) { foreach ((array) $attribute as $innerAttribute => $innerRules) { $results = $this->mergeRulesForAttribute($results, $innerAttribute, $innerRules); } return $results; } return $this->mergeRulesForAttribute( $results, $attribute, $rules ); } /** * Merge additional rules into a given attribute. * * @param array $results * @param string $attribute * @param string|array $rules * @return array */ protected function mergeRulesForAttribute($results, $attribute, $rules) { $merge = head($this->explodeRules([$rules])); $results[$attribute] = array_merge( isset($results[$attribute]) ? $this->explodeExplicitRule($results[$attribute]) : [], $merge ); return $results; } /** * Extract the rule name and parameters from a rule. * * @param array|string $rule * @return array */ public static function parse($rule) { if ($rule instanceof RuleContract) { return [$rule, []]; } if (is_array($rule)) { $rule = static::parseArrayRule($rule); } else { $rule = static::parseStringRule($rule); } $rule[0] = static::normalizeRule($rule[0]); return $rule; } /** * Parse an array based rule. * * @param array $rule * @return array */ protected static function parseArrayRule(array $rule) { return [Str::studly(trim(Arr::get($rule, 0, ''))), array_slice($rule, 1)]; } /** * Parse a string based rule. * * @param string $rule * @return array */ protected static function parseStringRule($rule) { $parameters = []; // The format for specifying validation rules and parameters follows an // easy {rule}:{parameters} formatting convention. For instance the // rule "Max:3" states that the value may only be three letters. if (strpos($rule, ':') !== false) { [$rule, $parameter] = explode(':', $rule, 2); $parameters = static::parseParameters($rule, $parameter); } return [Str::studly(trim($rule)), $parameters]; } /** * Parse a parameter list. * * @param string $rule * @param string $parameter * @return array */ protected static function parseParameters($rule, $parameter) { $rule = strtolower($rule); if (in_array($rule, ['regex', 'not_regex', 'notregex'], true)) { return [$parameter]; } return str_getcsv($parameter); } /** * Normalizes a rule so that we can accept short types. * * @param string $rule * @return string */ protected static function normalizeRule($rule) { switch ($rule) { case 'Int': return 'Integer'; case 'Bool': return 'Boolean'; default: return $rule; } } /** * Expand and conditional rules in the given array of rules. * * @param array $rules * @param array $data * @return array */ public static function filterConditionalRules($rules, array $data = []) { return collect($rules)->mapWithKeys(function ($attributeRules, $attribute) use ($data) { if (! is_array($attributeRules) && ! $attributeRules instanceof ConditionalRules) { return [$attribute => $attributeRules]; } if ($attributeRules instanceof ConditionalRules) { return [$attribute => $attributeRules->passes($data) ? array_filter($attributeRules->rules()) : array_filter($attributeRules->defaultRules()), ]; } return [$attribute => collect($attributeRules)->map(function ($rule) use ($data) { if (! $rule instanceof ConditionalRules) { return [$rule]; } return $rule->passes($data) ? $rule->rules() : $rule->defaultRules(); })->filter()->flatten(1)->values()->all()]; })->all(); } } PKf\sWDatabasePresenceVerifier.phpnu[db = $db; } /** * Count the number of objects in a collection having the given value. * * @param string $collection * @param string $column * @param string $value * @param int|null $excludeId * @param string|null $idColumn * @param array $extra * @return int */ public function getCount($collection, $column, $value, $excludeId = null, $idColumn = null, array $extra = []) { $query = $this->table($collection)->where($column, '=', $value); if (! is_null($excludeId) && $excludeId !== 'NULL') { $query->where($idColumn ?: 'id', '<>', $excludeId); } return $this->addConditions($query, $extra)->count(); } /** * Count the number of objects in a collection with the given values. * * @param string $collection * @param string $column * @param array $values * @param array $extra * @return int */ public function getMultiCount($collection, $column, array $values, array $extra = []) { $query = $this->table($collection)->whereIn($column, $values); return $this->addConditions($query, $extra)->distinct()->count($column); } /** * Add the given conditions to the query. * * @param \Illuminate\Database\Query\Builder $query * @param array $conditions * @return \Illuminate\Database\Query\Builder */ protected function addConditions($query, $conditions) { foreach ($conditions as $key => $value) { if ($value instanceof Closure) { $query->where(function ($query) use ($value) { $value($query); }); } else { $this->addWhere($query, $key, $value); } } return $query; } /** * Add a "where" clause to the given query. * * @param \Illuminate\Database\Query\Builder $query * @param string $key * @param string $extraValue * @return void */ protected function addWhere($query, $key, $extraValue) { if ($extraValue === 'NULL') { $query->whereNull($key); } elseif ($extraValue === 'NOT_NULL') { $query->whereNotNull($key); } elseif (Str::startsWith($extraValue, '!')) { $query->where($key, '!=', mb_substr($extraValue, 1)); } else { $query->where($key, $extraValue); } } /** * Get a query builder for the given table. * * @param string $table * @return \Illuminate\Database\Query\Builder */ protected function table($table) { return $this->db->connection($this->connection)->table($table)->useWritePdo(); } /** * Set the connection to be used. * * @param string $connection * @return void */ public function setConnection($connection) { $this->connection = $connection; } } PKf\ry00 composer.jsonnu[{ "name": "illuminate/validation", "description": "The Illuminate Validation package.", "license": "MIT", "homepage": "https://laravel.com", "support": { "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, "authors": [ { "name": "Taylor Otwell", "email": "taylor@laravel.com" } ], "require": { "php": "^7.3|^8.0", "ext-json": "*", "egulias/email-validator": "^2.1.10", "illuminate/collections": "^8.0", "illuminate/container": "^8.0", "illuminate/contracts": "^8.0", "illuminate/macroable": "^8.0", "illuminate/support": "^8.0", "illuminate/translation": "^8.0", "symfony/http-foundation": "^5.4", "symfony/mime": "^5.4" }, "autoload": { "psr-4": { "Illuminate\\Validation\\": "" } }, "extra": { "branch-alias": { "dev-master": "8.x-dev" } }, "suggest": { "ext-bcmath": "Required to use the multiple_of validation rule.", "illuminate/database": "Required to use the database presence verifier (^8.0)." }, "config": { "sort-packages": true }, "minimum-stability": "dev" } PKf\'* " " Factory.phpnu[container = $container; $this->translator = $translator; } /** * Create a new Validator instance. * * @param array $data * @param array $rules * @param array $messages * @param array $customAttributes * @return \Illuminate\Validation\Validator */ public function make(array $data, array $rules, array $messages = [], array $customAttributes = []) { $validator = $this->resolve( $data, $rules, $messages, $customAttributes ); // The presence verifier is responsible for checking the unique and exists data // for the validator. It is behind an interface so that multiple versions of // it may be written besides database. We'll inject it into the validator. if (! is_null($this->verifier)) { $validator->setPresenceVerifier($this->verifier); } // Next we'll set the IoC container instance of the validator, which is used to // resolve out class based validator extensions. If it is not set then these // types of extensions will not be possible on these validation instances. if (! is_null($this->container)) { $validator->setContainer($this->container); } $validator->excludeUnvalidatedArrayKeys = $this->excludeUnvalidatedArrayKeys; $this->addExtensions($validator); return $validator; } /** * Validate the given data against the provided rules. * * @param array $data * @param array $rules * @param array $messages * @param array $customAttributes * @return array * * @throws \Illuminate\Validation\ValidationException */ public function validate(array $data, array $rules, array $messages = [], array $customAttributes = []) { return $this->make($data, $rules, $messages, $customAttributes)->validate(); } /** * Resolve a new Validator instance. * * @param array $data * @param array $rules * @param array $messages * @param array $customAttributes * @return \Illuminate\Validation\Validator */ protected function resolve(array $data, array $rules, array $messages, array $customAttributes) { if (is_null($this->resolver)) { return new Validator($this->translator, $data, $rules, $messages, $customAttributes); } return call_user_func($this->resolver, $this->translator, $data, $rules, $messages, $customAttributes); } /** * Add the extensions to a validator instance. * * @param \Illuminate\Validation\Validator $validator * @return void */ protected function addExtensions(Validator $validator) { $validator->addExtensions($this->extensions); // Next, we will add the implicit extensions, which are similar to the required // and accepted rule in that they are run even if the attributes is not in a // array of data that is given to a validator instances via instantiation. $validator->addImplicitExtensions($this->implicitExtensions); $validator->addDependentExtensions($this->dependentExtensions); $validator->addReplacers($this->replacers); $validator->setFallbackMessages($this->fallbackMessages); } /** * Register a custom validator extension. * * @param string $rule * @param \Closure|string $extension * @param string|null $message * @return void */ public function extend($rule, $extension, $message = null) { $this->extensions[$rule] = $extension; if ($message) { $this->fallbackMessages[Str::snake($rule)] = $message; } } /** * Register a custom implicit validator extension. * * @param string $rule * @param \Closure|string $extension * @param string|null $message * @return void */ public function extendImplicit($rule, $extension, $message = null) { $this->implicitExtensions[$rule] = $extension; if ($message) { $this->fallbackMessages[Str::snake($rule)] = $message; } } /** * Register a custom dependent validator extension. * * @param string $rule * @param \Closure|string $extension * @param string|null $message * @return void */ public function extendDependent($rule, $extension, $message = null) { $this->dependentExtensions[$rule] = $extension; if ($message) { $this->fallbackMessages[Str::snake($rule)] = $message; } } /** * Register a custom validator message replacer. * * @param string $rule * @param \Closure|string $replacer * @return void */ public function replacer($rule, $replacer) { $this->replacers[$rule] = $replacer; } /** * Indicate that unvalidated array keys should be excluded, even if the parent array was validated. * * @return void */ public function excludeUnvalidatedArrayKeys() { $this->excludeUnvalidatedArrayKeys = true; } /** * Set the Validator instance resolver. * * @param \Closure $resolver * @return void */ public function resolver(Closure $resolver) { $this->resolver = $resolver; } /** * Get the Translator implementation. * * @return \Illuminate\Contracts\Translation\Translator */ public function getTranslator() { return $this->translator; } /** * Get the Presence Verifier implementation. * * @return \Illuminate\Validation\PresenceVerifierInterface */ public function getPresenceVerifier() { return $this->verifier; } /** * Set the Presence Verifier implementation. * * @param \Illuminate\Validation\PresenceVerifierInterface $presenceVerifier * @return void */ public function setPresenceVerifier(PresenceVerifierInterface $presenceVerifier) { $this->verifier = $presenceVerifier; } /** * Get the container instance used by the validation factory. * * @return \Illuminate\Contracts\Container\Container */ public function getContainer() { return $this->container; } /** * Set the container instance used by the validation factory. * * @param \Illuminate\Contracts\Container\Container $container * @return $this */ public function setContainer(Container $container) { $this->container = $container; return $this; } } PKf\#ȆValidationServiceProvider.phpnu[registerPresenceVerifier(); $this->registerUncompromisedVerifier(); $this->registerValidationFactory(); } /** * Register the validation factory. * * @return void */ protected function registerValidationFactory() { $this->app->singleton('validator', function ($app) { $validator = new Factory($app['translator'], $app); // The validation presence verifier is responsible for determining the existence of // values in a given data collection which is typically a relational database or // other persistent data stores. It is used to check for "uniqueness" as well. if (isset($app['db'], $app['validation.presence'])) { $validator->setPresenceVerifier($app['validation.presence']); } return $validator; }); } /** * Register the database presence verifier. * * @return void */ protected function registerPresenceVerifier() { $this->app->singleton('validation.presence', function ($app) { return new DatabasePresenceVerifier($app['db']); }); } /** * Register the uncompromised password verifier. * * @return void */ protected function registerUncompromisedVerifier() { $this->app->singleton(UncompromisedVerifier::class, function ($app) { return new NotPwnedVerifier($app[HttpFactory::class]); }); } /** * Get the services provided by the provider. * * @return array */ public function provides() { return [ 'validator', 'validation.presence', ]; } } PKf\k ValidationException.phpnu[response = $response; $this->errorBag = $errorBag; $this->validator = $validator; } /** * Create a new validation exception from a plain array of messages. * * @param array $messages * @return static */ public static function withMessages(array $messages) { return new static(tap(ValidatorFacade::make([], []), function ($validator) use ($messages) { foreach ($messages as $key => $value) { foreach (Arr::wrap($value) as $message) { $validator->errors()->add($key, $message); } } })); } /** * Get all of the validation error messages. * * @return array */ public function errors() { return $this->validator->errors()->messages(); } /** * Set the HTTP status code to be used for the response. * * @param int $status * @return $this */ public function status($status) { $this->status = $status; return $this; } /** * Set the error bag on the exception. * * @param string $errorBag * @return $this */ public function errorBag($errorBag) { $this->errorBag = $errorBag; return $this; } /** * Set the URL to redirect to on a validation error. * * @param string $url * @return $this */ public function redirectTo($url) { $this->redirectTo = $url; return $this; } /** * Get the underlying response instance. * * @return \Symfony\Component\HttpFoundation\Response|null */ public function getResponse() { return $this->response; } } PKf\#DSUnauthorizedException.phpnu[factory = $factory; $this->timeout = $timeout ?? 30; } /** * Verify that the given data has not been compromised in public breaches. * * @param array $data * @return bool */ public function verify($data) { $value = $data['value']; $threshold = $data['threshold']; if (empty($value = (string) $value)) { return false; } [$hash, $hashPrefix] = $this->getHash($value); return ! $this->search($hashPrefix) ->contains(function ($line) use ($hash, $hashPrefix, $threshold) { [$hashSuffix, $count] = explode(':', $line); return $hashPrefix.$hashSuffix == $hash && $count > $threshold; }); } /** * Get the hash and its first 5 chars. * * @param string $value * @return array */ protected function getHash($value) { $hash = strtoupper(sha1((string) $value)); $hashPrefix = substr($hash, 0, 5); return [$hash, $hashPrefix]; } /** * Search by the given hash prefix and returns all occurrences of leaked passwords. * * @param string $hashPrefix * @return \Illuminate\Support\Collection */ protected function search($hashPrefix) { try { $response = $this->factory->withHeaders([ 'Add-Padding' => true, ])->timeout($this->timeout)->get( 'https://api.pwnedpasswords.com/range/'.$hashPrefix ); } catch (Exception $e) { report($e); } $body = (isset($response) && $response->successful()) ? $response->body() : ''; return Str::of($body)->trim()->explode("\n")->filter(function ($line) { return Str::contains($line, ':'); }); } } PKf\α33 LICENSE.mdnu[The MIT License (MIT) Copyright (c) Taylor Otwell Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PKf\;_NNPresenceVerifierInterface.phpnu[toArray(); } return new In(is_array($values) ? $values : func_get_args()); } /** * Get a not_in constraint builder instance. * * @param \Illuminate\Contracts\Support\Arrayable|array|string $values * @return \Illuminate\Validation\Rules\NotIn */ public static function notIn($values) { if ($values instanceof Arrayable) { $values = $values->toArray(); } return new NotIn(is_array($values) ? $values : func_get_args()); } /** * Get a required_if constraint builder instance. * * @param callable|bool $callback * @return \Illuminate\Validation\Rules\RequiredIf */ public static function requiredIf($callback) { return new RequiredIf($callback); } /** * Get a unique constraint builder instance. * * @param string $table * @param string $column * @return \Illuminate\Validation\Rules\Unique */ public static function unique($table, $column = 'NULL') { return new Unique($table, $column); } } PKf\ ValidationData.phpnu[ $value) { if ((bool) preg_match('/^'.$pattern.'/', $key, $matches)) { $keys[] = $matches[0]; } } $keys = array_unique($keys); $data = []; foreach ($keys as $key) { $data[$key] = Arr::get($masterData, $key); } return $data; } /** * Extract data based on the given dot-notated path. * * Used to extract a sub-section of the data for faster iteration. * * @param string $attribute * @param array $masterData * @return array */ public static function extractDataFromPath($attribute, $masterData) { $results = []; $value = Arr::get($masterData, $attribute, '__missing__'); if ($value !== '__missing__') { Arr::set($results, $attribute, $value); } return $results; } /** * Get the explicit part of the attribute name. * * E.g. 'foo.bar.*.baz' -> 'foo.bar' * * Allows us to not spin through all of the flattened data for some operations. * * @param string $attribute * @return string */ public static function getLeadingExplicitAttributePath($attribute) { return rtrim(explode('*', $attribute)[0], '.') ?: null; } } PKf\6iX33 Validator.phpnu[dotPlaceholder = Str::random(); $this->initialRules = $rules; $this->translator = $translator; $this->customMessages = $messages; $this->data = $this->parseData($data); $this->customAttributes = $customAttributes; $this->setRules($rules); } /** * Parse the data array, converting dots and asterisks. * * @param array $data * @return array */ public function parseData(array $data) { $newData = []; foreach ($data as $key => $value) { if (is_array($value)) { $value = $this->parseData($value); } $key = str_replace( ['.', '*'], [$this->dotPlaceholder, '__asterisk__'], $key ); $newData[$key] = $value; } return $newData; } /** * Replace the placeholders used in data keys. * * @param array $data * @return array */ protected function replacePlaceholders($data) { $originalData = []; foreach ($data as $key => $value) { $originalData[$this->replacePlaceholderInString($key)] = is_array($value) ? $this->replacePlaceholders($value) : $value; } return $originalData; } /** * Replace the placeholders in the given string. * * @param string $value * @return string */ protected function replacePlaceholderInString(string $value) { return str_replace( [$this->dotPlaceholder, '__asterisk__'], ['.', '*'], $value ); } /** * Add an after validation callback. * * @param callable|string $callback * @return $this */ public function after($callback) { $this->after[] = function () use ($callback) { return $callback($this); }; return $this; } /** * Determine if the data passes the validation rules. * * @return bool */ public function passes() { $this->messages = new MessageBag; [$this->distinctValues, $this->failedRules] = [[], []]; // We'll spin through each rule, validating the attributes attached to that // rule. Any error messages will be added to the containers with each of // the other error messages, returning true if we don't have messages. foreach ($this->rules as $attribute => $rules) { if ($this->shouldBeExcluded($attribute)) { $this->removeAttribute($attribute); continue; } if ($this->stopOnFirstFailure && $this->messages->isNotEmpty()) { break; } foreach ($rules as $rule) { $this->validateAttribute($attribute, $rule); if ($this->shouldBeExcluded($attribute)) { $this->removeAttribute($attribute); break; } if ($this->shouldStopValidating($attribute)) { break; } } } // Here we will spin through all of the "after" hooks on this validator and // fire them off. This gives the callbacks a chance to perform all kinds // of other validation that needs to get wrapped up in this operation. foreach ($this->after as $after) { $after(); } return $this->messages->isEmpty(); } /** * Determine if the data fails the validation rules. * * @return bool */ public function fails() { return ! $this->passes(); } /** * Determine if the attribute should be excluded. * * @param string $attribute * @return bool */ protected function shouldBeExcluded($attribute) { foreach ($this->excludeAttributes as $excludeAttribute) { if ($attribute === $excludeAttribute || Str::startsWith($attribute, $excludeAttribute.'.')) { return true; } } return false; } /** * Remove the given attribute. * * @param string $attribute * @return void */ protected function removeAttribute($attribute) { Arr::forget($this->data, $attribute); Arr::forget($this->rules, $attribute); } /** * Run the validator's rules against its data. * * @return array * * @throws \Illuminate\Validation\ValidationException */ public function validate() { throw_if($this->fails(), $this->exception, $this); return $this->validated(); } /** * Run the validator's rules against its data. * * @param string $errorBag * @return array * * @throws \Illuminate\Validation\ValidationException */ public function validateWithBag(string $errorBag) { try { return $this->validate(); } catch (ValidationException $e) { $e->errorBag = $errorBag; throw $e; } } /** * Get a validated input container for the validated input. * * @param array|null $keys * @return \Illuminate\Support\ValidatedInput|array */ public function safe(array $keys = null) { return is_array($keys) ? (new ValidatedInput($this->validated()))->only($keys) : new ValidatedInput($this->validated()); } /** * Get the attributes and values that were validated. * * @return array * * @throws \Illuminate\Validation\ValidationException */ public function validated() { throw_if($this->invalid(), $this->exception, $this); $results = []; $missingValue = new stdClass; foreach ($this->getRules() as $key => $rules) { if ($this->excludeUnvalidatedArrayKeys && in_array('array', $rules) && ! empty(preg_grep('/^'.preg_quote($key, '/').'\.+/', array_keys($this->getRules())))) { continue; } $value = data_get($this->getData(), $key, $missingValue); if ($value !== $missingValue) { Arr::set($results, $key, $value); } } return $this->replacePlaceholders($results); } /** * Validate a given attribute against a rule. * * @param string $attribute * @param string $rule * @return void */ protected function validateAttribute($attribute, $rule) { $this->currentRule = $rule; [$rule, $parameters] = ValidationRuleParser::parse($rule); if ($rule === '') { return; } // First we will get the correct keys for the given attribute in case the field is nested in // an array. Then we determine if the given rule accepts other field names as parameters. // If so, we will replace any asterisks found in the parameters with the correct keys. if ($this->dependsOnOtherFields($rule)) { $parameters = $this->replaceDotInParameters($parameters); if ($keys = $this->getExplicitKeys($attribute)) { $parameters = $this->replaceAsterisksInParameters($parameters, $keys); } } $value = $this->getValue($attribute); // If the attribute is a file, we will verify that the file upload was actually successful // and if it wasn't we will add a failure for the attribute. Files may not successfully // upload if they are too large based on PHP's settings so we will bail in this case. if ($value instanceof UploadedFile && ! $value->isValid() && $this->hasRule($attribute, array_merge($this->fileRules, $this->implicitRules)) ) { return $this->addFailure($attribute, 'uploaded', []); } // If we have made it this far we will make sure the attribute is validatable and if it is // we will call the validation method with the attribute. If a method returns false the // attribute is invalid and we will add a failure message for this failing attribute. $validatable = $this->isValidatable($rule, $attribute, $value); if ($rule instanceof RuleContract) { return $validatable ? $this->validateUsingCustomRule($attribute, $value, $rule) : null; } $method = "validate{$rule}"; if ($validatable && ! $this->$method($attribute, $value, $parameters, $this)) { $this->addFailure($attribute, $rule, $parameters); } } /** * Determine if the given rule depends on other fields. * * @param string $rule * @return bool */ protected function dependsOnOtherFields($rule) { return in_array($rule, $this->dependentRules); } /** * Get the explicit keys from an attribute flattened with dot notation. * * E.g. 'foo.1.bar.spark.baz' -> [1, 'spark'] for 'foo.*.bar.*.baz' * * @param string $attribute * @return array */ protected function getExplicitKeys($attribute) { $pattern = str_replace('\*', '([^\.]+)', preg_quote($this->getPrimaryAttribute($attribute), '/')); if (preg_match('/^'.$pattern.'/', $attribute, $keys)) { array_shift($keys); return $keys; } return []; } /** * Get the primary attribute name. * * For example, if "name.0" is given, "name.*" will be returned. * * @param string $attribute * @return string */ protected function getPrimaryAttribute($attribute) { foreach ($this->implicitAttributes as $unparsed => $parsed) { if (in_array($attribute, $parsed, true)) { return $unparsed; } } return $attribute; } /** * Replace each field parameter which has an escaped dot with the dot placeholder. * * @param array $parameters * @param array $keys * @return array */ protected function replaceDotInParameters(array $parameters) { return array_map(function ($field) { return str_replace('\.', $this->dotPlaceholder, $field); }, $parameters); } /** * Replace each field parameter which has asterisks with the given keys. * * @param array $parameters * @param array $keys * @return array */ protected function replaceAsterisksInParameters(array $parameters, array $keys) { return array_map(function ($field) use ($keys) { return vsprintf(str_replace('*', '%s', $field), $keys); }, $parameters); } /** * Determine if the attribute is validatable. * * @param object|string $rule * @param string $attribute * @param mixed $value * @return bool */ protected function isValidatable($rule, $attribute, $value) { if (in_array($rule, $this->excludeRules)) { return true; } return $this->presentOrRuleIsImplicit($rule, $attribute, $value) && $this->passesOptionalCheck($attribute) && $this->isNotNullIfMarkedAsNullable($rule, $attribute) && $this->hasNotFailedPreviousRuleIfPresenceRule($rule, $attribute); } /** * Determine if the field is present, or the rule implies required. * * @param object|string $rule * @param string $attribute * @param mixed $value * @return bool */ protected function presentOrRuleIsImplicit($rule, $attribute, $value) { if (is_string($value) && trim($value) === '') { return $this->isImplicit($rule); } return $this->validatePresent($attribute, $value) || $this->isImplicit($rule); } /** * Determine if a given rule implies the attribute is required. * * @param object|string $rule * @return bool */ protected function isImplicit($rule) { return $rule instanceof ImplicitRule || in_array($rule, $this->implicitRules); } /** * Determine if the attribute passes any optional check. * * @param string $attribute * @return bool */ protected function passesOptionalCheck($attribute) { if (! $this->hasRule($attribute, ['Sometimes'])) { return true; } $data = ValidationData::initializeAndGatherData($attribute, $this->data); return array_key_exists($attribute, $data) || array_key_exists($attribute, $this->data); } /** * Determine if the attribute fails the nullable check. * * @param string $rule * @param string $attribute * @return bool */ protected function isNotNullIfMarkedAsNullable($rule, $attribute) { if ($this->isImplicit($rule) || ! $this->hasRule($attribute, ['Nullable'])) { return true; } return ! is_null(Arr::get($this->data, $attribute, 0)); } /** * Determine if it's a necessary presence validation. * * This is to avoid possible database type comparison errors. * * @param string $rule * @param string $attribute * @return bool */ protected function hasNotFailedPreviousRuleIfPresenceRule($rule, $attribute) { return in_array($rule, ['Unique', 'Exists']) ? ! $this->messages->has($attribute) : true; } /** * Validate an attribute using a custom rule object. * * @param string $attribute * @param mixed $value * @param \Illuminate\Contracts\Validation\Rule $rule * @return void */ protected function validateUsingCustomRule($attribute, $value, $rule) { $attribute = $this->replacePlaceholderInString($attribute); $value = is_array($value) ? $this->replacePlaceholders($value) : $value; if ($rule instanceof ValidatorAwareRule) { $rule->setValidator($this); } if ($rule instanceof DataAwareRule) { $rule->setData($this->data); } if (! $rule->passes($attribute, $value)) { $this->failedRules[$attribute][get_class($rule)] = []; $messages = $rule->message(); $messages = $messages ? (array) $messages : [get_class($rule)]; foreach ($messages as $message) { $this->messages->add($attribute, $this->makeReplacements( $message, $attribute, get_class($rule), [] )); } } } /** * Check if we should stop further validations on a given attribute. * * @param string $attribute * @return bool */ protected function shouldStopValidating($attribute) { $cleanedAttribute = $this->replacePlaceholderInString($attribute); if ($this->hasRule($attribute, ['Bail'])) { return $this->messages->has($cleanedAttribute); } if (isset($this->failedRules[$cleanedAttribute]) && array_key_exists('uploaded', $this->failedRules[$cleanedAttribute])) { return true; } // In case the attribute has any rule that indicates that the field is required // and that rule already failed then we should stop validation at this point // as now there is no point in calling other rules with this field empty. return $this->hasRule($attribute, $this->implicitRules) && isset($this->failedRules[$cleanedAttribute]) && array_intersect(array_keys($this->failedRules[$cleanedAttribute]), $this->implicitRules); } /** * Add a failed rule and error message to the collection. * * @param string $attribute * @param string $rule * @param array $parameters * @return void */ public function addFailure($attribute, $rule, $parameters = []) { if (! $this->messages) { $this->passes(); } $attributeWithPlaceholders = $attribute; $attribute = str_replace( [$this->dotPlaceholder, '__asterisk__'], ['.', '*'], $attribute ); if (in_array($rule, $this->excludeRules)) { return $this->excludeAttribute($attribute); } $this->messages->add($attribute, $this->makeReplacements( $this->getMessage($attributeWithPlaceholders, $rule), $attribute, $rule, $parameters )); $this->failedRules[$attribute][$rule] = $parameters; } /** * Add the given attribute to the list of excluded attributes. * * @param string $attribute * @return void */ protected function excludeAttribute(string $attribute) { $this->excludeAttributes[] = $attribute; $this->excludeAttributes = array_unique($this->excludeAttributes); } /** * Returns the data which was valid. * * @return array */ public function valid() { if (! $this->messages) { $this->passes(); } return array_diff_key( $this->data, $this->attributesThatHaveMessages() ); } /** * Returns the data which was invalid. * * @return array */ public function invalid() { if (! $this->messages) { $this->passes(); } $invalid = array_intersect_key( $this->data, $this->attributesThatHaveMessages() ); $result = []; $failed = Arr::only(Arr::dot($invalid), array_keys($this->failed())); foreach ($failed as $key => $failure) { Arr::set($result, $key, $failure); } return $result; } /** * Generate an array of all attributes that have messages. * * @return array */ protected function attributesThatHaveMessages() { return collect($this->messages()->toArray())->map(function ($message, $key) { return explode('.', $key)[0]; })->unique()->flip()->all(); } /** * Get the failed validation rules. * * @return array */ public function failed() { return $this->failedRules; } /** * Get the message container for the validator. * * @return \Illuminate\Support\MessageBag */ public function messages() { if (! $this->messages) { $this->passes(); } return $this->messages; } /** * An alternative more semantic shortcut to the message container. * * @return \Illuminate\Support\MessageBag */ public function errors() { return $this->messages(); } /** * Get the messages for the instance. * * @return \Illuminate\Support\MessageBag */ public function getMessageBag() { return $this->messages(); } /** * Determine if the given attribute has a rule in the given set. * * @param string $attribute * @param string|array $rules * @return bool */ public function hasRule($attribute, $rules) { return ! is_null($this->getRule($attribute, $rules)); } /** * Get a rule and its parameters for a given attribute. * * @param string $attribute * @param string|array $rules * @return array|null */ protected function getRule($attribute, $rules) { if (! array_key_exists($attribute, $this->rules)) { return; } $rules = (array) $rules; foreach ($this->rules[$attribute] as $rule) { [$rule, $parameters] = ValidationRuleParser::parse($rule); if (in_array($rule, $rules)) { return [$rule, $parameters]; } } } /** * Get the data under validation. * * @return array */ public function attributes() { return $this->getData(); } /** * Get the data under validation. * * @return array */ public function getData() { return $this->data; } /** * Set the data under validation. * * @param array $data * @return $this */ public function setData(array $data) { $this->data = $this->parseData($data); $this->setRules($this->initialRules); return $this; } /** * Get the value of a given attribute. * * @param string $attribute * @return mixed */ protected function getValue($attribute) { return Arr::get($this->data, $attribute); } /** * Get the validation rules. * * @return array */ public function getRules() { return $this->rules; } /** * Set the validation rules. * * @param array $rules * @return $this */ public function setRules(array $rules) { $rules = collect($rules)->mapWithKeys(function ($value, $key) { return [str_replace('\.', $this->dotPlaceholder, $key) => $value]; })->toArray(); $this->initialRules = $rules; $this->rules = []; $this->addRules($rules); return $this; } /** * Parse the given rules and merge them into current rules. * * @param array $rules * @return void */ public function addRules($rules) { // The primary purpose of this parser is to expand any "*" rules to the all // of the explicit rules needed for the given data. For example the rule // names.* would get expanded to names.0, names.1, etc. for this data. $response = (new ValidationRuleParser($this->data)) ->explode(ValidationRuleParser::filterConditionalRules($rules, $this->data)); $this->rules = array_merge_recursive( $this->rules, $response->rules ); $this->implicitAttributes = array_merge( $this->implicitAttributes, $response->implicitAttributes ); } /** * Add conditions to a given field based on a Closure. * * @param string|array $attribute * @param string|array $rules * @param callable $callback * @return $this */ public function sometimes($attribute, $rules, callable $callback) { $payload = new Fluent($this->data); foreach ((array) $attribute as $key) { $response = (new ValidationRuleParser($this->data))->explode([$key => $rules]); $this->implicitAttributes = array_merge($response->implicitAttributes, $this->implicitAttributes); foreach ($response->rules as $ruleKey => $ruleValue) { if ($callback($payload, $this->dataForSometimesIteration($ruleKey, ! Str::endsWith($key, '.*')))) { $this->addRules([$ruleKey => $ruleValue]); } } } return $this; } /** * Get the data that should be injected into the iteration of a wildcard "sometimes" callback. * * @param string $attribute * @return \Illuminate\Support\Fluent|array|mixed */ private function dataForSometimesIteration(string $attribute, $removeLastSegmentOfAttribute) { $lastSegmentOfAttribute = strrchr($attribute, '.'); $attribute = $lastSegmentOfAttribute && $removeLastSegmentOfAttribute ? Str::replaceLast($lastSegmentOfAttribute, '', $attribute) : $attribute; return is_array($data = data_get($this->data, $attribute)) ? new Fluent($data) : $data; } /** * Instruct the validator to stop validating after the first rule failure. * * @param bool $stopOnFirstFailure * @return $this */ public function stopOnFirstFailure($stopOnFirstFailure = true) { $this->stopOnFirstFailure = $stopOnFirstFailure; return $this; } /** * Register an array of custom validator extensions. * * @param array $extensions * @return void */ public function addExtensions(array $extensions) { if ($extensions) { $keys = array_map([Str::class, 'snake'], array_keys($extensions)); $extensions = array_combine($keys, array_values($extensions)); } $this->extensions = array_merge($this->extensions, $extensions); } /** * Register an array of custom implicit validator extensions. * * @param array $extensions * @return void */ public function addImplicitExtensions(array $extensions) { $this->addExtensions($extensions); foreach ($extensions as $rule => $extension) { $this->implicitRules[] = Str::studly($rule); } } /** * Register an array of custom dependent validator extensions. * * @param array $extensions * @return void */ public function addDependentExtensions(array $extensions) { $this->addExtensions($extensions); foreach ($extensions as $rule => $extension) { $this->dependentRules[] = Str::studly($rule); } } /** * Register a custom validator extension. * * @param string $rule * @param \Closure|string $extension * @return void */ public function addExtension($rule, $extension) { $this->extensions[Str::snake($rule)] = $extension; } /** * Register a custom implicit validator extension. * * @param string $rule * @param \Closure|string $extension * @return void */ public function addImplicitExtension($rule, $extension) { $this->addExtension($rule, $extension); $this->implicitRules[] = Str::studly($rule); } /** * Register a custom dependent validator extension. * * @param string $rule * @param \Closure|string $extension * @return void */ public function addDependentExtension($rule, $extension) { $this->addExtension($rule, $extension); $this->dependentRules[] = Str::studly($rule); } /** * Register an array of custom validator message replacers. * * @param array $replacers * @return void */ public function addReplacers(array $replacers) { if ($replacers) { $keys = array_map([Str::class, 'snake'], array_keys($replacers)); $replacers = array_combine($keys, array_values($replacers)); } $this->replacers = array_merge($this->replacers, $replacers); } /** * Register a custom validator message replacer. * * @param string $rule * @param \Closure|string $replacer * @return void */ public function addReplacer($rule, $replacer) { $this->replacers[Str::snake($rule)] = $replacer; } /** * Set the custom messages for the validator. * * @param array $messages * @return $this */ public function setCustomMessages(array $messages) { $this->customMessages = array_merge($this->customMessages, $messages); return $this; } /** * Set the custom attributes on the validator. * * @param array $attributes * @return $this */ public function setAttributeNames(array $attributes) { $this->customAttributes = $attributes; return $this; } /** * Add custom attributes to the validator. * * @param array $customAttributes * @return $this */ public function addCustomAttributes(array $customAttributes) { $this->customAttributes = array_merge($this->customAttributes, $customAttributes); return $this; } /** * Set the callback that used to format an implicit attribute. * * @param callable|null $formatter * @return $this */ public function setImplicitAttributesFormatter(callable $formatter = null) { $this->implicitAttributesFormatter = $formatter; return $this; } /** * Set the custom values on the validator. * * @param array $values * @return $this */ public function setValueNames(array $values) { $this->customValues = $values; return $this; } /** * Add the custom values for the validator. * * @param array $customValues * @return $this */ public function addCustomValues(array $customValues) { $this->customValues = array_merge($this->customValues, $customValues); return $this; } /** * Set the fallback messages for the validator. * * @param array $messages * @return void */ public function setFallbackMessages(array $messages) { $this->fallbackMessages = $messages; } /** * Get the Presence Verifier implementation. * * @param string|null $connection * @return \Illuminate\Validation\PresenceVerifierInterface * * @throws \RuntimeException */ public function getPresenceVerifier($connection = null) { if (! isset($this->presenceVerifier)) { throw new RuntimeException('Presence verifier has not been set.'); } if ($this->presenceVerifier instanceof DatabasePresenceVerifierInterface) { $this->presenceVerifier->setConnection($connection); } return $this->presenceVerifier; } /** * Set the Presence Verifier implementation. * * @param \Illuminate\Validation\PresenceVerifierInterface $presenceVerifier * @return void */ public function setPresenceVerifier(PresenceVerifierInterface $presenceVerifier) { $this->presenceVerifier = $presenceVerifier; } /** * Set the exception to throw upon failed validation. * * @param string $exception * @return $this * * @throws \InvalidArgumentException */ public function setException($exception) { if (! is_a($exception, ValidationException::class, true)) { throw new InvalidArgumentException( sprintf('Exception [%s] is invalid. It must extend [%s].', $exception, ValidationException::class) ); } $this->exception = $exception; return $this; } /** * Get the Translator implementation. * * @return \Illuminate\Contracts\Translation\Translator */ public function getTranslator() { return $this->translator; } /** * Set the Translator implementation. * * @param \Illuminate\Contracts\Translation\Translator $translator * @return void */ public function setTranslator(Translator $translator) { $this->translator = $translator; } /** * Set the IoC container instance. * * @param \Illuminate\Contracts\Container\Container $container * @return void */ public function setContainer(Container $container) { $this->container = $container; } /** * Call a custom validator extension. * * @param string $rule * @param array $parameters * @return bool|null */ protected function callExtension($rule, $parameters) { $callback = $this->extensions[$rule]; if (is_callable($callback)) { return $callback(...array_values($parameters)); } elseif (is_string($callback)) { return $this->callClassBasedExtension($callback, $parameters); } } /** * Call a class based validator extension. * * @param string $callback * @param array $parameters * @return bool */ protected function callClassBasedExtension($callback, $parameters) { [$class, $method] = Str::parseCallback($callback, 'validate'); return $this->container->make($class)->{$method}(...array_values($parameters)); } /** * Handle dynamic calls to class methods. * * @param string $method * @param array $parameters * @return mixed * * @throws \BadMethodCallException */ public function __call($method, $parameters) { $rule = Str::snake(substr($method, 8)); if (isset($this->extensions[$rule])) { return $this->callExtension($rule, $parameters); } throw new BadMethodCallException(sprintf( 'Method %s::%s does not exist.', static::class, $method )); } } PKf\3 O**ClosureValidationRule.phpnu[callback = $callback; } /** * Determine if the validation rule passes. * * @param string $attribute * @param mixed $value * @return bool */ public function passes($attribute, $value) { $this->failed = false; $this->callback->__invoke($attribute, $value, function ($message) { $this->failed = true; $this->message = $message; }); return ! $this->failed; } /** * Get the validation error message. * * @return string */ public function message() { return $this->message; } } PKf\~WRules/Enum.phpnu[type = $type; } /** * Determine if the validation rule passes. * * @param string $attribute * @param mixed $value * @return bool */ public function passes($attribute, $value) { if (is_null($value) || ! function_exists('enum_exists') || ! enum_exists($this->type) || ! method_exists($this->type, 'tryFrom')) { return false; } try { return ! is_null($this->type::tryFrom($value)); } catch (TypeError $e) { return false; } } /** * Get the validation error message. * * @return array */ public function message() { $message = trans('validation.enum'); return $message === 'validation.enum' ? ['The selected :attribute is invalid.'] : $message; } } PKf\IRules/Exists.phpnu[whereNull($deletedAtColumn); return $this; } /** * Convert the rule to a validation string. * * @return string */ public function __toString() { return rtrim(sprintf('exists:%s,%s,%s', $this->table, $this->column, $this->formatWheres() ), ','); } } PKf\/+FF Rules/In.phpnu[values = $values; } /** * Convert the rule to a validation string. * * @return string * * @see \Illuminate\Validation\ValidationRuleParser::parseParameters */ public function __toString() { $values = array_map(function ($value) { return '"'.str_replace('"', '""', $value).'"'; }, $this->values); return $this->rule.':'.implode(',', $values); } } PKf\OxxRules/Unique.phpnu[ignoreModel($id, $idColumn); } $this->ignore = $id; $this->idColumn = $idColumn ?? 'id'; return $this; } /** * Ignore the given model during the unique check. * * @param \Illuminate\Database\Eloquent\Model $model * @param string|null $idColumn * @return $this */ public function ignoreModel($model, $idColumn = null) { $this->idColumn = $idColumn ?? $model->getKeyName(); $this->ignore = $model->{$this->idColumn}; return $this; } /** * Ignore soft deleted models during the unique check. * * @param string $deletedAtColumn * @return $this */ public function withoutTrashed($deletedAtColumn = 'deleted_at') { $this->whereNull($deletedAtColumn); return $this; } /** * Convert the rule to a validation string. * * @return string */ public function __toString() { return rtrim(sprintf('unique:%s,%s,%s,%s,%s', $this->table, $this->column, $this->ignore ? '"'.addslashes($this->ignore).'"' : 'NULL', $this->idColumn, $this->formatWheres() ), ','); } } PKf\}zf " "Rules/Password.phpnu[min = max((int) $min, 1); } /** * Set the default callback to be used for determining a password's default rules. * * If no arguments are passed, the default password rule configuration will be returned. * * @param static|callable|null $callback * @return static|null */ public static function defaults($callback = null) { if (is_null($callback)) { return static::default(); } if (! is_callable($callback) && ! $callback instanceof static) { throw new InvalidArgumentException('The given callback should be callable or an instance of '.static::class); } static::$defaultCallback = $callback; } /** * Get the default configuration of the password rule. * * @return static */ public static function default() { $password = is_callable(static::$defaultCallback) ? call_user_func(static::$defaultCallback) : static::$defaultCallback; return $password instanceof Rule ? $password : static::min(8); } /** * Get the default configuration of the password rule and mark the field as required. * * @return array */ public static function required() { return ['required', static::default()]; } /** * Get the default configuration of the password rule and mark the field as sometimes being required. * * @return array */ public static function sometimes() { return ['sometimes', static::default()]; } /** * Set the performing validator. * * @param \Illuminate\Contracts\Validation\Validator $validator * @return $this */ public function setValidator($validator) { $this->validator = $validator; return $this; } /** * Set the data under validation. * * @param array $data * @return $this */ public function setData($data) { $this->data = $data; return $this; } /** * Sets the minimum size of the password. * * @param int $size * @return $this */ public static function min($size) { return new static($size); } /** * Ensures the password has not been compromised in data leaks. * * @param int $threshold * @return $this */ public function uncompromised($threshold = 0) { $this->uncompromised = true; $this->compromisedThreshold = $threshold; return $this; } /** * Makes the password require at least one uppercase and one lowercase letter. * * @return $this */ public function mixedCase() { $this->mixedCase = true; return $this; } /** * Makes the password require at least one letter. * * @return $this */ public function letters() { $this->letters = true; return $this; } /** * Makes the password require at least one number. * * @return $this */ public function numbers() { $this->numbers = true; return $this; } /** * Makes the password require at least one symbol. * * @return $this */ public function symbols() { $this->symbols = true; return $this; } /** * Specify additional validation rules that should be merged with the default rules during validation. * * @param string|array $rules * @return $this */ public function rules($rules) { $this->customRules = Arr::wrap($rules); return $this; } /** * Determine if the validation rule passes. * * @param string $attribute * @param mixed $value * @return bool */ public function passes($attribute, $value) { $this->messages = []; $validator = Validator::make( $this->data, [$attribute => array_merge(['string', 'min:'.$this->min], $this->customRules)], $this->validator->customMessages, $this->validator->customAttributes )->after(function ($validator) use ($attribute, $value) { if (! is_string($value)) { return; } $value = (string) $value; if ($this->mixedCase && ! preg_match('/(\p{Ll}+.*\p{Lu})|(\p{Lu}+.*\p{Ll})/u', $value)) { $validator->errors()->add($attribute, 'The :attribute must contain at least one uppercase and one lowercase letter.'); } if ($this->letters && ! preg_match('/\pL/u', $value)) { $validator->errors()->add($attribute, 'The :attribute must contain at least one letter.'); } if ($this->symbols && ! preg_match('/\p{Z}|\p{S}|\p{P}/u', $value)) { $validator->errors()->add($attribute, 'The :attribute must contain at least one symbol.'); } if ($this->numbers && ! preg_match('/\pN/u', $value)) { $validator->errors()->add($attribute, 'The :attribute must contain at least one number.'); } }); if ($validator->fails()) { return $this->fail($validator->messages()->all()); } if ($this->uncompromised && ! Container::getInstance()->make(UncompromisedVerifier::class)->verify([ 'value' => $value, 'threshold' => $this->compromisedThreshold, ])) { return $this->fail( 'The given :attribute has appeared in a data leak. Please choose a different :attribute.' ); } return true; } /** * Get the validation error message. * * @return array */ public function message() { return $this->messages; } /** * Adds the given failures, and return false. * * @param array|string $messages * @return bool */ protected function fail($messages) { $messages = collect(Arr::wrap($messages))->map(function ($message) { return $this->validator->getTranslator()->get($message); })->all(); $this->messages = array_merge($this->messages, $messages); return false; } } PKf\zbbRules/DatabaseRule.phpnu[column = $column; $this->table = $this->resolveTableName($table); } /** * Resolves the name of the table from the given string. * * @param string $table * @return string */ public function resolveTableName($table) { if (! Str::contains($table, '\\') || ! class_exists($table)) { return $table; } if (is_subclass_of($table, Model::class)) { $model = new $table; if (Str::contains($model->getTable(), '.')) { return $table; } return implode('.', array_map(function (string $part) { return trim($part, '.'); }, array_filter([$model->getConnectionName(), $model->getTable()]))); } return $table; } /** * Set a "where" constraint on the query. * * @param \Closure|string $column * @param array|string|int|null $value * @return $this */ public function where($column, $value = null) { if (is_array($value)) { return $this->whereIn($column, $value); } if ($column instanceof Closure) { return $this->using($column); } if (is_null($value)) { return $this->whereNull($column); } $this->wheres[] = compact('column', 'value'); return $this; } /** * Set a "where not" constraint on the query. * * @param string $column * @param array|string $value * @return $this */ public function whereNot($column, $value) { if (is_array($value)) { return $this->whereNotIn($column, $value); } return $this->where($column, '!'.$value); } /** * Set a "where null" constraint on the query. * * @param string $column * @return $this */ public function whereNull($column) { return $this->where($column, 'NULL'); } /** * Set a "where not null" constraint on the query. * * @param string $column * @return $this */ public function whereNotNull($column) { return $this->where($column, 'NOT_NULL'); } /** * Set a "where in" constraint on the query. * * @param string $column * @param array $values * @return $this */ public function whereIn($column, array $values) { return $this->where(function ($query) use ($column, $values) { $query->whereIn($column, $values); }); } /** * Set a "where not in" constraint on the query. * * @param string $column * @param array $values * @return $this */ public function whereNotIn($column, array $values) { return $this->where(function ($query) use ($column, $values) { $query->whereNotIn($column, $values); }); } /** * Register a custom query callback. * * @param \Closure $callback * @return $this */ public function using(Closure $callback) { $this->using[] = $callback; return $this; } /** * Get the custom query callbacks for the rule. * * @return array */ public function queryCallbacks() { return $this->using; } /** * Format the where clauses. * * @return string */ protected function formatWheres() { return collect($this->wheres)->map(function ($where) { return $where['column'].','.'"'.str_replace('"', '""', $where['value']).'"'; })->implode(','); } } PKf\pߚ| | Rules/Dimensions.phpnu[constraints = $constraints; } /** * Set the "width" constraint. * * @param int $value * @return $this */ public function width($value) { $this->constraints['width'] = $value; return $this; } /** * Set the "height" constraint. * * @param int $value * @return $this */ public function height($value) { $this->constraints['height'] = $value; return $this; } /** * Set the "min width" constraint. * * @param int $value * @return $this */ public function minWidth($value) { $this->constraints['min_width'] = $value; return $this; } /** * Set the "min height" constraint. * * @param int $value * @return $this */ public function minHeight($value) { $this->constraints['min_height'] = $value; return $this; } /** * Set the "max width" constraint. * * @param int $value * @return $this */ public function maxWidth($value) { $this->constraints['max_width'] = $value; return $this; } /** * Set the "max height" constraint. * * @param int $value * @return $this */ public function maxHeight($value) { $this->constraints['max_height'] = $value; return $this; } /** * Set the "ratio" constraint. * * @param float $value * @return $this */ public function ratio($value) { $this->constraints['ratio'] = $value; return $this; } /** * Convert the rule to a validation string. * * @return string */ public function __toString() { $result = ''; foreach ($this->constraints as $key => $value) { $result .= "$key=$value,"; } return 'dimensions:'.substr($result, 0, -1); } } PKf\Rules/NotIn.phpnu[values = $values; } /** * Convert the rule to a validation string. * * @return string */ public function __toString() { $values = array_map(function ($value) { return '"'.str_replace('"', '""', $value).'"'; }, $this->values); return $this->rule.':'.implode(',', $values); } } PKf\`%Rules/RequiredIf.phpnu[condition = $condition; } else { throw new InvalidArgumentException('The provided condition must be a callable or boolean.'); } } /** * Convert the rule to a validation string. * * @return string */ public function __toString() { if (is_callable($this->condition)) { return call_user_func($this->condition) ? 'required' : ''; } return $this->condition ? 'required' : ''; } } PK\6mjRFCValidation.phpnu[PK\7NoRFCWarningsValidation.phpnu[PK\v^rError/SpoofEmail.phpnu[PK\=fError/RFCWarnings.phpnu[PK\aLKK SpoofCheckValidation.phpnu[PK\P;__!kException/EmptyValidationList.phpnu[PK\3ޣEmailValidation.phpnu[PK\i39MDNSCheckValidation.phpnu[PK\3av^^$MultipleErrors.phpnu[PK\fP߃ 9'MultipleValidationWithAnd.phpnu[PKf\RP3ValidatesWhenResolvedTrait.phpnu[PKf\C~-<%0;DatabasePresenceVerifierInterface.phpnu[PKf\]z/,,"<Concerns/FilterEmailValidation.phpnu[PKf\XG{5I5I"CConcerns/ReplacesAttributes.phpnu[PKf\zaa Concerns/ValidatesAttributes.phpnu[PKf\44WConcerns/FormatsMessages.phpnu[PKf\Rl AConditionalRules.phpnu[PKf\a-ValidationRuleParser.phpnu[PKf\sW>DatabasePresenceVerifier.phpnu[PKf\ry00  composer.jsonnu[PKf\'* " " wFactory.phpnu[PKf\#Ȇ ValidationServiceProvider.phpnu[PKf\k )ValidationException.phpnu[PKf\#DS5UnauthorizedException.phpnu[PKf\g  j6NotPwnedVerifier.phpnu[PKf\α33 @LICENSE.mdnu[PKf\;_NN4EPresenceVerifierInterface.phpnu[PKf\]|@= HRule.phpnu[PKf\ SValidationData.phpnu[PKf\6iX33 _Validator.phpnu[PKf\3 O**0ClosureValidationRule.phpnu[PKf\~WRules/Enum.phpnu[PKf\IRules/Exists.phpnu[PKf\/+FF Rules/In.phpnu[PKf\Oxx_ Rules/Unique.phpnu[PKf\}zf " "Rules/Password.phpnu[PKf\zbby5Rules/DatabaseRule.phpnu[PKf\pߚ| | !GRules/Dimensions.phpnu[PKf\PRules/NotIn.phpnu[PKf\`%#TRules/RequiredIf.phpnu[PK((g (X