Example #1
0
 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;
 }
Example #2
0
 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;
 }
Example #3
0
 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;
 }
Example #4
0
 protected function applyPattern($input, $ctx)
 {
     $pattern = $this->getPattern();
     if ($pattern !== null) {
         if (!Helper\Func::userPatternMatch($pattern, $input)) {
             $ctx->addReason($this, ['id' => 'string.pattern']);
         }
     }
 }