Skip to content

Commit

Permalink
Backports for 5.2.2 (Part 3) (#450)
Browse files Browse the repository at this point in the history
* Update php-csfixer rules to address problem in 2.7 & new multiline rule (#449)

* Update php-csfixer rules to address problem in 2.7 & new multiline rule

 * yoda_style in 2.7 is dangerous and may result in logic errors. In
 some cases, it also results in invalid syntax.

 * multiline comments prefixed with // now seem to be misaligned, and
 this cannot be disabled, so have changed the relevant comment.

* PHP-5.3 is not available on trusty, so explicitly specify precise for 5.3

* Add proper recursive handling for $ref resolution base (#448)

Fixes #447

Note that this patch does not check whether a given container is
actually a schema when recursing into it. In most cases this will
not matter, however it does mean that in some edge cases it will
attempt to resolve a `$ref` in a context where ref is actually not
part of the spec. Limiting resolution to schema-context containers
is outside the scope of this patch, but can be added later.
  • Loading branch information
erayd authored and bighappyface committed Oct 3, 2017
1 parent 36ed4d9 commit b80053b
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 15 deletions.
2 changes: 2 additions & 0 deletions .php_cs.dist
Expand Up @@ -11,6 +11,7 @@ $config
'@PSR2' => true,
'@Symfony' => true,
// additionally
'align_multiline_comment' => array('comment_type' => 'phpdocs_like'),
'array_syntax' => array('syntax' => 'long'),
'binary_operator_spaces' => false,
'concat_space' => array('spacing' => 'one'),
Expand All @@ -24,6 +25,7 @@ $config
'pre_increment' => false,
'trailing_comma_in_multiline_array' => false,
'simplified_null_return' => false,
'yoda_style' => null,
))
->setFinder($finder)
;
Expand Down
1 change: 1 addition & 0 deletions .travis.yml
Expand Up @@ -10,6 +10,7 @@ matrix:
fast_finish: true
include:
- php: 5.3
dist: precise
- php: 5.4
- php: 5.5
- php: 5.6
Expand Down
12 changes: 6 additions & 6 deletions src/JsonSchema/Constraints/CollectionConstraint.php
Expand Up @@ -85,8 +85,8 @@ protected function validateItems(&$value, $schema = null, JsonPointer $path = nu

$validator->check($v, $schema->items, $k_path, $i);
}
unset($v); // remove dangling reference to prevent any future bugs
// caused by accidentally using $v elsewhere
unset($v); /* remove dangling reference to prevent any future bugs
* caused by accidentally using $v elsewhere */
$this->addErrors($typeValidator->getErrors());
$this->addErrors($validator->getErrors());
} else {
Expand All @@ -109,8 +109,8 @@ protected function validateItems(&$value, $schema = null, JsonPointer $path = nu
$this->errors = $initErrors;
}
}
unset($v); // remove dangling reference to prevent any future bugs
// caused by accidentally using $v elsewhere
unset($v); /* remove dangling reference to prevent any future bugs
* caused by accidentally using $v elsewhere */
}
} else {
// Defined item type definitions
Expand All @@ -132,8 +132,8 @@ protected function validateItems(&$value, $schema = null, JsonPointer $path = nu
}
}
}
unset($v); // remove dangling reference to prevent any future bugs
// caused by accidentally using $v elsewhere
unset($v); /* remove dangling reference to prevent any future bugs
* caused by accidentally using $v elsewhere */

// Treat when we have more schema definitions than values, not for empty arrays
if (count($value) > 0) {
Expand Down
41 changes: 34 additions & 7 deletions src/JsonSchema/SchemaStorage.php
Expand Up @@ -5,7 +5,6 @@
use JsonSchema\Constraints\BaseConstraint;
use JsonSchema\Entity\JsonPointer;
use JsonSchema\Exception\UnresolvableJsonPointerException;
use JsonSchema\Iterator\ObjectIterator;
use JsonSchema\Uri\UriResolver;
use JsonSchema\Uri\UriRetriever;

Expand Down Expand Up @@ -69,14 +68,42 @@ public function addSchema($id, $schema = null)
}
}

$objectIterator = new ObjectIterator($schema);
foreach ($objectIterator as $toResolveSchema) {
if (property_exists($toResolveSchema, '$ref') && is_string($toResolveSchema->{'$ref'})) {
$jsonPointer = new JsonPointer($this->uriResolver->resolve($toResolveSchema->{'$ref'}, $id));
$toResolveSchema->{'$ref'} = (string) $jsonPointer;
// resolve references
$this->expandRefs($schema, $id);

$this->schemas[$id] = $schema;
}

/**
* Recursively resolve all references against the provided base
*
* @param mixed $schema
* @param string $base
*/
private function expandRefs(&$schema, $base = null)
{
if (!is_object($schema)) {
if (is_array($schema)) {
foreach ($schema as &$member) {
$this->expandRefs($member, $base);
}
}

return;
}

if (property_exists($schema, 'id') && is_string($schema->id)) {
$base = $this->uriResolver->resolve($schema->id, $base);
}

if (property_exists($schema, '$ref') && is_string($schema->{'$ref'})) {
$refPointer = new JsonPointer($this->uriResolver->resolve($schema->{'$ref'}, $base));
$schema->{'$ref'} = (string) $refPointer;
}

foreach ($schema as &$member) {
$this->expandRefs($member, $base);
}
$this->schemas[$id] = $schema;
}

/**
Expand Down
11 changes: 11 additions & 0 deletions src/JsonSchema/Uri/UriResolver.php
Expand Up @@ -76,6 +76,17 @@ public function generate(array $components)
*/
public function resolve($uri, $baseUri = null)
{
// treat non-uri base as local file path
if (!is_null($baseUri) && !filter_var($baseUri, \FILTER_VALIDATE_URL)) {
if (is_file($baseUri)) {
$baseUri = 'file://' . realpath($baseUri);
} elseif (is_dir($baseUri)) {
$baseUri = 'file://' . realpath($baseUri) . '/';
} else {
$baseUri = 'file://' . getcwd() . '/' . $baseUri;
}
}

if ($uri == '') {
return $baseUri;
}
Expand Down
9 changes: 7 additions & 2 deletions src/JsonSchema/Validator.php
Expand Up @@ -54,12 +54,17 @@ public function validate(&$value, $schema = null, $checkMode = null)
}

// add provided schema to SchemaStorage with internal URI to allow internal $ref resolution
$this->factory->getSchemaStorage()->addSchema(SchemaStorage::INTERNAL_PROVIDED_SCHEMA_URI, $schema);
if (is_object($schema) && property_exists($schema, 'id')) {
$schemaURI = $schema->id;
} else {
$schemaURI = SchemaStorage::INTERNAL_PROVIDED_SCHEMA_URI;
}
$this->factory->getSchemaStorage()->addSchema($schemaURI, $schema);

$validator = $this->factory->createInstanceFor('schema');
$validator->check(
$value,
$this->factory->getSchemaStorage()->getSchema(SchemaStorage::INTERNAL_PROVIDED_SCHEMA_URI)
$this->factory->getSchemaStorage()->getSchema($schemaURI)
);

$this->factory->setConfig($initialCheckMode);
Expand Down
33 changes: 33 additions & 0 deletions tests/Uri/UriResolverTest.php
Expand Up @@ -190,4 +190,37 @@ public function testReversable()
// check that the recombined URI matches the original input
$this->assertEquals($uri, $this->resolver->generate($split));
}

public function testRelativeFileAsRoot()
{
$this->assertEquals(
'file://' . getcwd() . '/src/JsonSchema/Validator.php',
$this->resolver->resolve(
'Validator.php',
'src/JsonSchema/SchemaStorage.php'
)
);
}

public function testRelativeDirectoryAsRoot()
{
$this->assertEquals(
'file://' . getcwd() . '/src/JsonSchema/Validator.php',
$this->resolver->resolve(
'Validator.php',
'src/JsonSchema'
)
);
}

public function testRelativeNonExistentFileAsRoot()
{
$this->assertEquals(
'file://' . getcwd() . '/resolved.file',
$this->resolver->resolve(
'resolved.file',
'test.file'
)
);
}
}

0 comments on commit b80053b

Please sign in to comment.