diff --git a/src/JsonapiParse.php b/src/JsonapiParse.php index 88a57943653db2c4116827ff9dbc6a73bc378407..a111965bd7309843da48f66e1d806d04d92e7cd7 100644 --- a/src/JsonapiParse.php +++ b/src/JsonapiParse.php @@ -20,6 +20,13 @@ class JsonapiParse implements JsonapiParseInterface { */ protected $included; + /** + * Allowed includes. + * + * @var array + */ + protected $allowed; + /** * {@inheritdoc} */ @@ -97,7 +104,7 @@ class JsonapiParse implements JsonapiParseInterface { * @return array * The result. */ - protected function flattenIncluded($resource) { + protected function flattenIncluded($resource, $key) { if (isset($this->included[$resource['type']][$resource['id']])) { $object = $this->resolveAttributes($this->included[$resource['type']][$resource['id']]); if (isset($resource['meta'])) { @@ -107,7 +114,7 @@ class JsonapiParse implements JsonapiParseInterface { else { $object = $resource; } - $result = $this->resolveRelationships($object); + $result = $this->resolveRelationships($object, $key); return $result; } @@ -117,10 +124,17 @@ class JsonapiParse implements JsonapiParseInterface { * @param array|mixed $resource * The resource to verify. * + * @param string $key + * Relationship key. + * * @return bool * Check result. */ - protected function isIncluded($resource) { + protected function isIncluded($resource, $key) { + if (!in_array($key, $this->allowed) && count(preg_grep('/^' . preg_quote($key) . '\..*/', $this->allowed)) === 0) { + return FALSE; + } + return isset($resource['type']) && isset($this->included[$resource['type']]); } @@ -130,12 +144,15 @@ class JsonapiParse implements JsonapiParseInterface { * @param array|mixed $data * The data for resolve. * + * @param string $key + * Relationship key. + * * @return array * Result. */ - protected function resolveData($data) { - if ($this->isIncluded($data)) { - return $this->flattenIncluded($data); + protected function resolveData($data, $key) { + if ($this->isIncluded($data, $key)) { + return $this->flattenIncluded($data, $key); } else { return $data; @@ -148,21 +165,24 @@ class JsonapiParse implements JsonapiParseInterface { * @param array|mixed $links * The data for resolve. * + * @param string $key + * Relationship key. + * * @return array * Result. */ - protected function resolveRelationshipData($links) { + protected function resolveRelationshipData($links, $key) { if (empty($links['data'])) { return $links; } $output = []; if (!$this->isAssoc($links['data'])) { foreach ($links['data'] as $item) { - $output[] = $this->resolveData($item); + $output[] = $this->resolveData($item, $key); } } else { - $output = $this->resolveData($links['data']); + $output = $this->resolveData($links['data'], $key); } return $output; } @@ -173,16 +193,19 @@ class JsonapiParse implements JsonapiParseInterface { * @param array|mixed $resource * The data for resolve. * + * @param string $parent_key + * The parent key for relationship. + * * @return array * Result. */ - protected function resolveRelationships($resource) { + protected function resolveRelationships($resource, $parent_key) { if (empty($resource['relationships'])) { return $resource; } foreach ($resource['relationships'] as $key => $value) { - $resource[$key] = $this->resolveRelationshipData($value); + $resource[$key] = $this->resolveRelationshipData($value, trim("$parent_key.$key", '.')); } unset($resource['relationships']); return $resource; @@ -199,7 +222,7 @@ class JsonapiParse implements JsonapiParseInterface { */ protected function parseResource($item) { $attributes = $this->resolveAttributes($item); - return $this->resolveRelationships($attributes); + return $this->resolveRelationships($attributes, ''); } /** @@ -220,7 +243,7 @@ class JsonapiParse implements JsonapiParseInterface { $content = Json::decode($content); } } - // @todo Remove in the release 2.0 with removed the deprecated srings input. + // @todo Remove in the release 2.0 with removed the deprecated string input. elseif (is_array($response)) { $content = $response; } @@ -234,6 +257,8 @@ class JsonapiParse implements JsonapiParseInterface { return $response; } $this->included = $this->groupIncludes($content); + $include_parameter = \Drupal::request()->query->get('include'); + $this->allowed = array_map('trim', explode(',', $include_parameter ?? '')); $data = []; if (!$this->isAssoc($content['data'])) { foreach ($content['data'] as $item) {