protected function applyValue($input, \Fulfil\Context $ctx) { if ($input === null) { goto done; } if (!$input instanceof $this->class) { $found = Func::getType($input); $ctx->addReason($this, ['id' => 'instance.invalidType', 'params' => ['expected' => $this->class, 'found' => $found]]); } elseif ($input instanceof \Fulfil\Lang\SelfChecker) { $input->check($ctx); } done: return $input; }
protected function applyValue($input, Context $ctx) { if ($input === null) { goto done; } $isArray = is_array($input); $len = null; type: if (!$isArray && !$input instanceof \Traversable && !$input instanceof \Countable) { $ctx->addReason($this, ['id' => 'array.invalidType', 'params' => ['type' => Func::getType($input)]]); goto done; } $len = $this->length !== null || $this->lengthMax !== null || $this->lengthMin !== null || $this->unique !== null ? count($input) : null; length: if ($this->length) { if ($len != $this->length) { $ctx->addReason($this, ['id' => 'array.length', 'params' => ['len' => $len, 'expected' => $this->length]]); } } elseif ($this->lengthMin !== null && $this->lengthMax !== null) { if ($len < $this->lengthMin || $len > $this->lengthMax) { $ctx->addReason($this, ['id' => 'array.lengthBetween', 'params' => ['len' => $len, 'min' => $this->lengthMin, 'max' => $this->lengthMax]]); } } elseif ($this->lengthMin !== null) { if ($len < $this->lengthMin) { $ctx->addReason($this, ['id' => 'array.lengthAtLeast', 'params' => ['len' => $len, 'min' => $this->lengthMin]]); } } elseif ($this->lengthMax !== null) { if ($len > $this->lengthMax) { $ctx->addReason($this, ['id' => 'array.lengthAtMost', 'params' => ['len' => $len, 'max' => $this->lengthMax]]); } } unique: if ($this->unique !== null && $this->unique) { if ($len === null) { $len = count($input); } if (count(array_unique($input, SORT_REGULAR)) != $len) { $ctx->addReason($this, ['id' => 'array.unique']); } } done: return $input; }
protected function applyValue($input, Context $ctx) { if ($input === null) { return $input; } $properties = null; $isMapped = false; $modifiedProps = []; $unknown = []; list_properties: if (is_object($input)) { if ($this->mapper) { $properties = (array) $this->mapper->mapObjectToProperties($input); $isMapped = $properties !== null; } if ($properties === null) { $properties = []; foreach ($input as $k => &$v) { $properties[$k] =& $v; } } } elseif (is_array($input)) { $properties =& $input; } input_checks: if (!is_array($properties)) { $ctx->addReason($this, ['id' => 'schema.invalidType']); goto done; } prop_checks: $checkedProps = []; foreach ($this->props as $propId => $checks) { $name = null; $checkedProps[$propId] = true; if ($checks === true) { goto next_prop; } if ($checks instanceof \Fulfil\CheckInterface) { $checks = [$checks]; } foreach ($checks as $check) { if ($check->name()) { $name = $check->name(); break; } } $ctx->push($propId, $name); try { $value = array_key_exists($propId, $properties) ? $properties[$propId] : null; $modified = false; foreach ($checks as $check) { $value = $check->apply($value, $ctx); $modified |= $ctx->getChange() == true; } if ($modified) { $properties[$propId] = $value; $modifiedProps[$propId] = $value; } } finally { $ctx->pop($propId); } next_prop: } $unknown = array_keys(array_diff_key($properties, $checkedProps)); foreach ($unknown as $up) { foreach ($this->ignore as $pattern) { if (Func::userPatternMatch($pattern, $up)) { goto next_unknown; } } if ($this->filterUnknownProps) { // important: without this, if you attempt to repopulate an object with // the result later, you can run into errors. unset($properties[$up]); $ctx->setChange(Change::Internal); } $ctx->addReason($this, ['id' => 'schema.propUnknown', 'params' => ['prop' => $up]]); next_unknown: } rules: foreach ($this->rules as $rule) { $ruleProps = []; foreach ($rule->listProps() as $k => $p) { $ruleProps[$k] = isset($properties[$p]) ? $properties[$p] : null; } $rule->validate($ruleProps, $ctx); } done: if ($modifiedProps && $isMapped) { $this->mapper->populateObject($input, (object) $modifiedProps); } return $input; }
protected function applyPattern($input, $ctx) { $pattern = $this->getPattern(); if ($pattern !== null) { if (!Helper\Func::userPatternMatch($pattern, $input)) { $ctx->addReason($this, ['id' => 'string.pattern']); } } }