blob: a299084563203a0a63b4414ef99bead910a9d2a4 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
<?php
namespace JsonApi\JsonApiIntegration;
use Closure;
use Neomerx\JsonApi\Contracts\Schema\SchemaInterface;
use Neomerx\JsonApi\Exceptions\InvalidArgumentException;
use function Neomerx\JsonApi\I18n\format as _;
use Neomerx\JsonApi\Schema\SchemaContainer as NeomerxSchemaContainer;
class SchemaContainer extends NeomerxSchemaContainer
{
/**
* The original SchemaContainer does not like mappings of interfaces to schemas.
* So this method now allows classes *and* interfaces.
*
* @inheritdoc
*/
public function register(string $type, $schema): void
{
if (true === empty($type) || (false === \class_exists($type) && false === \interface_exists($type))) {
throw new InvalidArgumentException(_(static::MSG_INVALID_MODEL_TYPE));
}
$isOk =
(true === \is_string($schema) &&
false === empty($schema) &&
true === \class_exists($schema) &&
true === \in_array(SchemaInterface::class, \class_implements($schema))) ||
\is_callable($schema) ||
$schema instanceof SchemaInterface;
if (false === $isOk) {
throw new InvalidArgumentException(_(static::MSG_INVALID_SCHEME, $type));
}
if (true === $this->hasProviderMapping($type)) {
throw new InvalidArgumentException(_(static::MSG_TYPE_REUSE_FORBIDDEN, $type));
}
if ($schema instanceof SchemaInterface) {
$this->setProviderMapping($type, \get_class($schema));
$this->setResourceToJsonTypeMapping($schema->getType(), $type);
$this->setCreatedProvider($type, $schema);
} else {
$this->setProviderMapping($type, $schema);
}
}
/**
* @param callable $callable
*
* @return SchemaInterface
*/
protected function createSchemaFromCallable(callable $callable): SchemaInterface
{
$schema = \call_user_func($callable, $this);
return $schema;
}
/**
* @param string $type
*
* @return bool
*/
protected function hasProviderMapping(string $type): bool
{
if (parent::hasProviderMapping($type)) {
return true;
}
foreach ($this->getParentClassesAndInterfaces($type) as $class) {
if (parent::hasProviderMapping($class)) {
return true;
}
}
return false;
}
/**
* @param string $type
*
* @return mixed
*/
protected function getProviderMapping(string $type)
{
if (parent::hasProviderMapping($type)) {
return parent::getProviderMapping($type);
}
foreach ($this->getParentClassesAndInterfaces($type) as $class) {
if (parent::hasProviderMapping($class)) {
return parent::getProviderMapping($class);
}
}
throw new InvalidArgumentException(_('Cannot find schema for type `%s`', $type));
}
private function getParentClassesAndInterfaces(string $type): array
{
return class_exists($type) ? @class_parents($type) + @class_implements($type) : [];
}
}
|