1
|
|
|
<?php |
2
|
|
|
namespace gossi\swagger; |
3
|
|
|
|
4
|
|
|
use phootwork\collection\Collection; |
5
|
|
|
use phootwork\collection\CollectionUtils; |
6
|
|
|
|
7
|
|
|
abstract class AbstractModel { |
8
|
|
|
/** |
9
|
|
|
* Prefers the original model when merging two models. |
10
|
|
|
*/ |
11
|
|
|
const PREFER_ORIGINAL = 0; |
12
|
|
|
/** |
13
|
|
|
* Prefers the external model when merging two models. |
14
|
|
|
*/ |
15
|
|
|
const PREFER_EXTERNAL = 1; |
16
|
|
|
|
17
|
10 |
|
protected function export() { |
18
|
10 |
|
$cols = func_get_args(); |
19
|
|
|
|
20
|
|
|
// add cols |
21
|
10 |
|
if (method_exists($this, 'hasRef') && $this->hasRef()) { |
|
|
|
|
22
|
6 |
|
$cols = array_merge(['$ref'], $cols); |
23
|
6 |
|
} |
24
|
|
|
|
25
|
|
|
// flatten array |
26
|
10 |
|
$fields = []; |
27
|
|
|
array_walk_recursive($cols, function ($a) use (&$fields) { $fields[] = $a; }); |
|
|
|
|
28
|
|
|
|
29
|
10 |
|
$out = []; |
30
|
10 |
|
$refl = new \ReflectionClass(get_class($this)); |
31
|
|
|
|
32
|
10 |
|
foreach ($fields as $field) { |
33
|
10 |
|
if ($field == 'tags') { |
34
|
7 |
|
$val = $this->exportTags(); |
|
|
|
|
35
|
7 |
|
} else { |
36
|
10 |
|
$prop = $refl->getProperty($field == '$ref' ? 'ref' : $field); |
37
|
10 |
|
$prop->setAccessible(true); |
38
|
10 |
|
$val = $prop->getValue($this); |
39
|
|
|
|
40
|
10 |
|
if ($val instanceof Collection) { |
41
|
10 |
|
$val = CollectionUtils::toArrayRecursive($val); |
42
|
10 |
|
} else if (method_exists($val, 'toArray')) { |
43
|
10 |
|
$val = $val->toArray(); |
44
|
10 |
|
} |
45
|
|
|
} |
46
|
|
|
|
47
|
10 |
|
if ($field == 'required' && is_bool($val) || !empty($val)) { |
48
|
8 |
|
$out[$field] = $val; |
49
|
8 |
|
} |
50
|
10 |
|
} |
51
|
|
|
|
52
|
10 |
|
if (method_exists($this, 'getExtensions')) { |
53
|
10 |
|
$out = array_merge($out, $this->getExtensions()->toArray()); |
|
|
|
|
54
|
10 |
|
} |
55
|
|
|
|
56
|
10 |
|
return $out; |
57
|
|
|
} |
58
|
|
|
|
59
|
10 |
|
protected function mergeFields(&$original, $external, $strategy) |
60
|
|
|
{ |
61
|
10 |
|
if ($original instanceof self && method_exists($original, 'merge')) { |
62
|
10 |
|
$original->merge($external, $strategy); |
|
|
|
|
63
|
|
|
|
64
|
10 |
|
return; |
65
|
|
|
} |
66
|
|
|
|
67
|
10 |
|
if (self::PREFER_ORIGINAL === $strategy) { |
68
|
10 |
|
if (null === $original) { |
69
|
10 |
|
$original = $external; |
70
|
10 |
|
} |
71
|
10 |
|
} else { |
72
|
|
|
if (null !== $external) { |
73
|
|
|
$original = $external; |
74
|
|
|
} |
75
|
|
|
} |
76
|
10 |
|
} |
77
|
|
|
} |
78
|
|
|
|
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the parent class: