Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
/**
4
 * This file is part of the Nette Framework (https://nette.org)
5
 * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6
 */
7
 
8
declare(strict_types=1);
9
 
10
namespace Nette\Schema\Elements;
11
 
12
use Nette;
13
use Nette\Schema\Context;
14
 
15
 
16
/**
17
 * @internal
18
 */
19
trait Base
20
{
21
	/** @var bool */
22
	private $required = false;
23
 
24
	/** @var mixed */
25
	private $default;
26
 
27
	/** @var callable|null */
28
	private $before;
29
 
30
	/** @var array[] */
31
	private $asserts = [];
32
 
33
	/** @var string|null */
34
	private $castTo;
35
 
36
	/** @var string|null */
37
	private $deprecated;
38
 
39
 
40
	public function default($value): self
41
	{
42
		$this->default = $value;
43
		return $this;
44
	}
45
 
46
 
47
	public function required(bool $state = true): self
48
	{
49
		$this->required = $state;
50
		return $this;
51
	}
52
 
53
 
54
	public function before(callable $handler): self
55
	{
56
		$this->before = $handler;
57
		return $this;
58
	}
59
 
60
 
61
	public function castTo(string $type): self
62
	{
63
		$this->castTo = $type;
64
		return $this;
65
	}
66
 
67
 
68
	public function assert(callable $handler, ?string $description = null): self
69
	{
70
		$this->asserts[] = [$handler, $description];
71
		return $this;
72
	}
73
 
74
 
75
	/** Marks as deprecated */
76
	public function deprecated(string $message = 'The item %path% is deprecated.'): self
77
	{
78
		$this->deprecated = $message;
79
		return $this;
80
	}
81
 
82
 
83
	public function completeDefault(Context $context)
84
	{
85
		if ($this->required) {
86
			$context->addError(
87
				'The mandatory item %path% is missing.',
88
				Nette\Schema\Message::MISSING_ITEM
89
			);
90
			return null;
91
		}
92
 
93
		return $this->default;
94
	}
95
 
96
 
97
	public function doNormalize($value, Context $context)
98
	{
99
		if ($this->before) {
100
			$value = ($this->before)($value);
101
		}
102
 
103
		return $value;
104
	}
105
 
106
 
107
	private function doDeprecation(Context $context): void
108
	{
109
		if ($this->deprecated !== null) {
110
			$context->addWarning(
111
				$this->deprecated,
112
				Nette\Schema\Message::DEPRECATED
113
			);
114
		}
115
	}
116
 
117
 
118
	private function doValidate($value, string $expected, Context $context): bool
119
	{
120
		if (!Nette\Utils\Validators::is($value, $expected)) {
121
			$expected = str_replace(['|', ':'], [' or ', ' in range '], $expected);
122
			$context->addError(
123
				'The %label% %path% expects to be %expected%, %value% given.',
124
				Nette\Schema\Message::TYPE_MISMATCH,
125
				['value' => $value, 'expected' => $expected]
126
			);
127
			return false;
128
		}
129
 
130
		return true;
131
	}
132
 
133
 
134
	private function doValidateRange($value, array $range, Context $context, string $types = ''): bool
135
	{
136
		if (is_array($value) || is_string($value)) {
137
			[$length, $label] = is_array($value)
138
				? [count($value), 'items']
139
				: (in_array('unicode', explode('|', $types), true)
140
					? [Nette\Utils\Strings::length($value), 'characters']
141
					: [strlen($value), 'bytes']);
142
 
143
			if (!self::isInRange($length, $range)) {
144
				$context->addError(
145
					"The length of %label% %path% expects to be in range %expected%, %length% $label given.",
146
					Nette\Schema\Message::LENGTH_OUT_OF_RANGE,
147
					['value' => $value, 'length' => $length, 'expected' => implode('..', $range)]
148
				);
149
				return false;
150
			}
151
		} elseif ((is_int($value) || is_float($value)) && !self::isInRange($value, $range)) {
152
			$context->addError(
153
				'The %label% %path% expects to be in range %expected%, %value% given.',
154
				Nette\Schema\Message::VALUE_OUT_OF_RANGE,
155
				['value' => $value, 'expected' => implode('..', $range)]
156
			);
157
			return false;
158
		}
159
 
160
		return true;
161
	}
162
 
163
 
164
	private function isInRange($value, array $range): bool
165
	{
166
		return ($range[0] === null || $value >= $range[0])
167
			&& ($range[1] === null || $value <= $range[1]);
168
	}
169
 
170
 
171
	private function doFinalize($value, Context $context)
172
	{
173
		if ($this->castTo) {
174
			if (Nette\Utils\Reflection::isBuiltinType($this->castTo)) {
175
				settype($value, $this->castTo);
176
			} else {
177
				$object = new $this->castTo;
178
				foreach ($value as $k => $v) {
179
					$object->$k = $v;
180
				}
181
 
182
				$value = $object;
183
			}
184
		}
185
 
186
		foreach ($this->asserts as $i => [$handler, $description]) {
187
			if (!$handler($value)) {
188
				$expected = $description ?: (is_string($handler) ? "$handler()" : "#$i");
189
				$context->addError(
190
					'Failed assertion ' . ($description ? "'%assertion%'" : '%assertion%') . ' for %label% %path% with value %value%.',
191
					Nette\Schema\Message::FAILED_ASSERTION,
192
					['value' => $value, 'assertion' => $expected]
193
				);
194
				return;
195
			}
196
		}
197
 
198
		return $value;
199
	}
200
}