Skip to content

Commit 3f68cc5

Browse files
committed
spec compliance done!
1 parent 6e93f83 commit 3f68cc5

File tree

4 files changed

+72
-2
lines changed

4 files changed

+72
-2
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
"description": "PHP Schema",
44
"type": "library",
55
"require": {
6-
"php": ">=5.3"
6+
"php": ">=5.3",
7+
"phplang/scope-exit": "^1.0"
78
},
89
"require-dev": {
910
"phpunit/phpunit": "4.8.23",

src/Helper.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,34 @@ public static function toPregPattern($jsonPattern)
2828
return $pattern;
2929
}
3030

31+
public static function resolveURI($parent, $current)
32+
{
33+
if (false !== $pos = strpos($current, '://')) {
34+
if (strpos($current, '/') > $pos) {
35+
return $current;
36+
}
37+
}
38+
39+
if ($current === '') {
40+
return $parent;
41+
}
42+
43+
$result = $parent;
44+
if ($current[0] === '#') {
45+
if (false !== $pos = strpos($parent, '#')) {
46+
$result = substr($parent, 0, $pos) . $current;
47+
}
48+
} elseif ($current[0] === '/') {
49+
} else {
50+
if (false !== $pos = strrpos($parent, '/')) {
51+
$result = substr($parent, 0, $pos + 1) . $current;
52+
}
53+
}
54+
if (false === strpos($result, '#')) {
55+
$result .= '#';
56+
}
57+
return $result;
58+
}
59+
60+
3161
}

src/SchemaLoader.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22

33
namespace Yaoi\Schema;
44

5+
use PhpLang\ScopeExit;
56
use Yaoi\Schema\Constraint\Properties;
67
use Yaoi\Schema\Constraint\Ref;
78
use Yaoi\Schema\Constraint\Type;
89
use Yaoi\Schema\RemoteRef\BasicFetcher;
910

1011
class SchemaLoader extends Base
1112
{
13+
const ID = 'id';
14+
1215
const TYPE = 'type';
1316

1417
const PROPERTIES = 'properties';
@@ -77,6 +80,12 @@ public function readSchema($schemaData)
7780
return $this->readSchemaDeeper($schemaData);
7881
}
7982

83+
private $resolutionScope;
84+
85+
public function __construct()
86+
{
87+
$this->resolutionScope = new StackTraceStorage();
88+
}
8089

8190
protected function readSchemaDeeper($schemaArray, Schema $parentSchema = null)
8291
{
@@ -90,6 +99,14 @@ protected function readSchemaDeeper($schemaArray, Schema $parentSchema = null)
9099
$schemaArray = (array)$schemaArray;
91100
}
92101

102+
if (isset($schemaArray[self::ID])) {
103+
$parentScope = $this->resolutionScope;
104+
$this->resolutionScope = Helper::resolveURI($parentScope, $schemaArray[self::ID]);
105+
$defer = new ScopeExit(function () use ($parentScope) {
106+
$this->resolutionScope = $parentScope;
107+
});
108+
}
109+
93110
if (isset($schemaArray[self::TYPE])) {
94111
$schema->type = new Type($schemaArray[self::TYPE]);
95112
}
@@ -276,7 +293,8 @@ private function resolveReference($referencePath)
276293
}
277294
} else {
278295
$refParts = explode('#', $referencePath);
279-
$url = $refParts[0];
296+
$url = Helper::resolveURI($this->resolutionScope, $refParts[0]);
297+
$url = rtrim($url, '#');
280298
$refLocalPath = isset($refParts[1]) ? '#' . $refParts[1] : '#';
281299
$schemaLoader = &$this->remoteSchemaLoaders[$url];
282300
if (null === $schemaLoader) {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Yaoi\Schema\Tests\PHPUnit\Misc;
4+
5+
6+
use Yaoi\Schema\Helper;
7+
8+
class ResolveURITest extends \PHPUnit_Framework_TestCase
9+
{
10+
public function testResolve()
11+
{
12+
$root = 'http://x.y.z/rootschema.json#';
13+
$this->assertSame('http://x.y.z/rootschema.json#foo', Helper::resolveURI($root, "#foo"));
14+
$deeper = Helper::resolveURI($root, "otherschema.json");
15+
$this->assertSame('http://x.y.z/otherschema.json#', $deeper);
16+
$this->assertSame('http://x.y.z/otherschema.json#bar', Helper::resolveURI($deeper, "#bar"));
17+
$this->assertSame('http://x.y.z/t/inner.json#a', Helper::resolveURI($deeper, "t/inner.json#a"));
18+
$this->assertSame("some://where.else/completely#", Helper::resolveURI($root, "some://where.else/completely#"));
19+
}
20+
21+
}

0 commit comments

Comments
 (0)