/** * {@inheritdoc} */ public function bind(string $key, Data $data) : BindResult { if (!$data->hasKey($key)) { return BindResult::fromFormErrors(new FormError($key, 'error.required')); } return BindResult::fromValue($data->getValue($key)); }
public function testBindResultFromFormErrors() { $bindResult = BindResult::fromFormErrors(new FormError('foo', 'bar')); $this->assertFalse($bindResult->isSuccess()); FormErrorAssertion::assertErrorMessages($this, $bindResult->getFormErrorSequence(), ['foo' => 'bar']); $this->expectException(AssertionFailedException::class); $bindResult->getValue(); }
public function testBindReturnsFailureResult() { $data = Data::fromFlatArray(['foo' => 'bar']); $bindResult = BindResult::fromFormErrors(); $binder = $this->prophesize(FormatterInterface::class); $binder->bind('foo', $data)->willReturn($bindResult); $mapping = (new FieldMapping($binder->reveal()))->withPrefixAndRelativeKey('', 'foo'); $this->assertSame($bindResult, $mapping->bind($data)); }
public function testBindInvalidValue() { $data = Data::fromFlatArray(['foo' => 'bar']); $wrappedMapping = $this->prophesize(MappingInterface::class); $wrappedMapping->bind($data)->willReturn(BindResult::fromFormErrors(new FormError('foo', 'bar'))); $wrappedMapping->withPrefixAndRelativeKey('', 'foo')->willReturn($wrappedMapping->reveal()); $mapping = (new OptionalMapping($wrappedMapping->reveal()))->withPrefixAndRelativeKey('', 'foo'); $this->assertSame('bar', $mapping->bind($data)->getFormErrorSequence()->getIterator()->current()->getMessage()); }
/** * {@inheritdoc} */ public function bind(string $key, Data $data) : BindResult { switch ($data->getValue($key, 'false')) { case 'true': return BindResult::fromValue(true); case 'false': return BindResult::fromValue(false); } return BindResult::fromFormErrors(new FormError($key, 'error.boolean')); }
/** * {@inheritdoc} */ public function bind(string $key, Data $data) : BindResult { if (!$data->hasKey($key)) { return BindResult::fromFormErrors(new FormError($key, 'error.required')); } $dateTime = DateTimeImmutable::createFromFormat('!Y-m-d', $data->getValue($key), $this->timeZone); if (false === $dateTime) { return BindResult::fromFormErrors(new FormError($key, 'error.date')); } return BindResult::fromValue($dateTime); }
public function testBindInvalidData() { $data = Data::none(); $mapping = $this->prophesize(MappingInterface::class); $mapping->bind($data)->willReturn(BindResult::fromFormErrors(new FormError('', 'foo')))->shouldBeCalled(); $form = (new Form($mapping->reveal()))->bind($data); $this->assertTrue($form->hasErrors()); $this->assertSame('foo', iterator_to_array($form->getGlobalErrors())[0]->getMessage()); $this->expectException(AssertionFailedException::class); $form->getValue(); }
/** * {@inheritdoc} */ public function bind(string $key, Data $data) : BindResult { if (!$data->hasKey($key)) { return BindResult::fromFormErrors(new FormError($key, 'error.required')); } $value = $data->getValue($key); if (!preg_match('(^-?[1-9]*\\d+$)', $value)) { return BindResult::fromFormErrors(new FormError($key, 'error.integer')); } return BindResult::fromValue((int) $data->getValue($key)); }
/** * {@inheritdoc} */ public function bind(string $key, Data $data) : BindResult { if (!$data->hasKey($key)) { return BindResult::fromFormErrors(new FormError($key, 'error.required')); } $value = $data->getValue($key); if (!is_numeric($value)) { return BindResult::fromFormErrors(new FormError($key, 'error.float')); } return BindResult::fromValue((double) $data->getValue($key)); }
/** * {@inheritdoc} */ public function bind(string $key, Data $data) : BindResult { if (!$data->hasKey($key)) { return BindResult::fromFormErrors(new FormError($key, 'error.required')); } // Technically, seconds must always be present, according to the spec, but at least Chrome seems to ommit them. if (!preg_match('(^(?<hour>\\d{2}):(?<minute>\\d{2})(?::(?<second>\\d{2})(?:\\.(?<microsecond>\\d{1,6}))?)?$)', $data->getValue($key), $matches)) { return BindResult::fromFormErrors(new FormError($key, 'error.time')); } return BindResult::fromValue(DateTimeImmutable::createFromFormat('!H:i:s.u', sprintf('%s:%s:%s.%s', $matches['hour'], $matches['minute'], $matches['second'] ?? '00', $matches['microsecond'] ?? '0'), $this->timeZone)); }
public function testBindPartiallyValidArray() { $data = Data::fromNestedArray(['foo' => ['bar' => ['baz', 'bat']]]); $bazMapping = $this->prophesize(MappingInterface::class); $bazMapping->bind($data)->willReturn(BindResult::fromValue('baz')); $batMapping = $this->prophesize(MappingInterface::class); $batMapping->bind($data)->willReturn(BindResult::fromFormErrors(new FormError('', 'bar'))); $wrappedMapping = $this->prophesize(MappingInterface::class); $wrappedMapping->withPrefixAndRelativeKey('foo[bar]', '0')->willReturn($bazMapping->reveal()); $wrappedMapping->withPrefixAndRelativeKey('foo[bar]', '1')->willReturn($batMapping->reveal()); $mapping = (new RepeatedMapping($wrappedMapping->reveal()))->withPrefixAndRelativeKey('foo', 'bar'); $bindResult = $mapping->bind($data); $this->assertFalse($bindResult->isSuccess()); $this->assertSame('bar', $bindResult->getFormErrorSequence()->getIterator()->current()->getMessage()); }
/** * {@inheritdoc} */ public function bind(string $key, Data $data) : BindResult { if (!$data->hasKey($key)) { return BindResult::fromFormErrors(new FormError($key, 'error.required')); } // Technically, seconds must always be present, according to the spec, but at least Chrome seems to ommit them. if (!preg_match('(^ (?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})[Tt] (?<hour>\\d{2}):(?<minute>\\d{2})(?::(?<second>\\d{2})(?:\\.(?<microsecond>\\d{1,6}))?)? (?<timezone>[Zz]|[+-]\\d{2}:\\d{2})? $)x', $data->getValue($key), $matches)) { return BindResult::fromFormErrors(new FormError($key, 'error.date-time')); } return BindResult::fromValue(DateTimeImmutable::createFromFormat('!Y-m-d\\TH:i:s.u' . ($this->localTime ? '' : 'P'), sprintf('%s-%s-%sT%s:%s:%s.%s%s', $matches['year'], $matches['month'], $matches['day'], $matches['hour'], $matches['minute'], !empty($matches['second']) ? $matches['second'] : '00', !empty($matches['microsecond']) ? $matches['microsecond'] : '00', $matches['timezone'] ?? ''), $this->timeZone)->setTimezone($this->timeZone)); }
protected function applyConstraints($value, string $key) : BindResult { $validationResult = new ValidationResult(); foreach ($this->constraints as $constraint) { $validationResult = $validationResult->merge($constraint($value)); } if ($validationResult->isSuccess()) { return BindResult::fromValue($value); } return BindResult::fromFormErrors(...array_map(function (ValidationError $validationError) use($key) { if ('' === $key) { $finalKey = $validationError->getKeySuffix(); } elseif ('' === $validationError->getKeySuffix()) { $finalKey = $key; } else { $finalKey = $key . preg_replace('(^[^\\[]+)', '[\\0]', $validationError->getKeySuffix()); } return new FormError($finalKey, $validationError->getMessage(), $validationError->getArguments()); }, iterator_to_array($validationResult->getValidationErrors()))); }
private function getMockedMapping(string $key, string $value = null, Data $data = null, $success = true) : MappingInterface { $mapping = $this->prophesize(MappingInterface::class); if (null !== $value) { $mapping->unbind($value)->willReturn(Data::fromFlatArray([$key => $value])); } if (null !== $value && null !== $data) { $mapping->bind($data)->willReturn($success ? BindResult::fromValue($value) : BindResult::fromFormErrors(new FormError($key, $value))); } $mapping->withPrefixAndRelativeKey('', $key)->willReturn($mapping->reveal()); return $mapping->reveal(); }