Beispiel #1
0
 function testPathsValid()
 {
     $ctx = new Context();
     $ctx->push('a', 'a');
     $ctx->push('a', 'a');
     $ctx->push('a', 'a');
     $ctx->pop('a');
     $ctx->push('b', 'b');
     $ctx->getNode()->valid = false;
     $ctx->pop('b');
     $ctx->pop('a');
     $ctx->push('b', 'b');
     $ctx->getNode()->valid = false;
     $ctx->pop('b');
     $ctx->push('c', 'c');
     $ctx->pop('c');
     $ctx->push('d', 'd');
     $ctx->pop('d');
     $ctx->pop('a');
     $this->assertTrue($ctx->pathsValid([['a', 'c'], ['a', 'd']]));
     $this->assertFalse($ctx->pathsValid(['a', 'a', 'b'], ['a', 'c']));
     $this->assertFalse($ctx->pathsValid(['a', 'a', 'a'], ['a', 'a', 'b']));
     $this->assertFalse($ctx->pathsValid(['a', 'a', 'b'], ['a', 'b']));
 }
Beispiel #2
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;
 }