Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recursion Update for php-json-schema #167

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -308,7 +308,7 @@ User::export($user); // Exception: Required property missing: id at #->propertie

#### Nested structures

Nested structures allow you to make composition: flatten several objects in one and separate back.
Nested structures allow you to make composition: flatten several objects in one and separate back. For nested structures that exceed a depth of the default 200 recursion limit, submit a Context maxNestLevel of an appropriate amount.

```php
$user = new User();
@@ -462,14 +462,16 @@ $this->assertSame(4, $res->one);
#### Overriding mapping classes

If you want to map data to a different class you can register mapping at top level of your importer structure.

Additionally, you can use the option property, maxNestLevel to increase your depth beyond the default 200 which may be
useful for certain complex Schema's.
```php
class CustomSwaggerSchema extends SwaggerSchema
{
public static function import($data, ?Context $options = null)
{
if ($options === null) {
$options = new Context();
$options->maxNestLevel = 500;
}
$options->objectItemClassMapping[Schema::className()] = CustomSchema::className();
return parent::import($data, $options);
7 changes: 6 additions & 1 deletion src/Context.php
Original file line number Diff line number Diff line change
@@ -4,6 +4,8 @@

class Context extends MagicMap
{
const DEFAULT_MAX_NEST = 200;

public $import = true;

/** @var DataPreProcessor */
@@ -51,6 +53,9 @@ class Context extends MagicMap

public $isRef = false;

/** @var int property max recursive nesting depth */
public $maxNestLevel = self::DEFAULT_MAX_NEST;

/**
* Dereference $ref unless there is a $ref property defined with format not equal to `uri-reference`.
* Default JSON Schema behavior is to dereference only if there is a $ref property defined with format
@@ -134,4 +139,4 @@ public function withDefault()
}


}
}
10 changes: 6 additions & 4 deletions src/RefResolver.php
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ class RefResolver
public $url;
/** @var null|RefResolver */
private $rootResolver;
private int $maxNestLevel = 200; //Change this via options submitted to ::import if needed

/**
* @param mixed $resolutionScope
@@ -102,9 +103,10 @@ public function setupResolutionScope($id, $data)
* RefResolver constructor.
* @param JsonSchema $rootData
*/
public function __construct($rootData = null)
public function __construct($rootData = null, int $maxNestLevel = 200)
{
$this->rootData = $rootData;
$this->maxNestLevel = $max_nest_level;
}

public function setRootData($rootData)
@@ -224,8 +226,8 @@ public function resolveReference($referencePath)
*/
public function preProcessReferences($data, Context $options, $nestingLevel = 0)
{
if ($nestingLevel > 200) {
throw new Exception('Too deep nesting level', Exception::DEEP_NESTING);
if ($nestingLevel > $this->maxNestLevel) { //Updated due to specific recursion depth from Amazon product JSON Schemas - yep 200 was not enough
throw new Exception('Too deep nesting level. Nesting / Recursion level (' . $nestingLevel . ') exceeds ' . $this->maxNestLevel , Exception::DEEP_NESTING);
}
if (is_array($data)) {
foreach ($data as $key => $item) {
@@ -264,4 +266,4 @@ public function preProcessReferences($data, Context $options, $nestingLevel = 0)
}


}
}
2 changes: 1 addition & 1 deletion src/Schema.php
Original file line number Diff line number Diff line change
@@ -165,7 +165,7 @@ public function in($data, ?Context $options = null)
$options->import = true;

if ($options->refResolver === null) {
$options->refResolver = new RefResolver($data);
$options->refResolver = new RefResolver($data, $options->maxNestLevel ?? Context::DEFAULT_MAX_NEST);
} else {
$options->refResolver->setRootData($data);
}