1 | <?php |
||
7 | class ModelSerialiser |
||
8 | { |
||
9 | // take a supplied Eloquent model with metadata trait and serialise it in bulk. |
||
10 | // Upstream POData implementation has an N+1 lookup problem that interacts badly with how |
||
11 | // Eloquent handles property accesses |
||
12 | |||
13 | private static $mutatorCache = []; |
||
14 | private static $metadataCache = []; |
||
15 | |||
16 | public function __construct() |
||
19 | |||
20 | /** |
||
21 | * Serialise needed bits of supplied model, taking fast path where possible |
||
22 | * |
||
23 | * @param $model |
||
24 | * @return mixed |
||
25 | */ |
||
26 | public function bulkSerialise($model) |
||
27 | { |
||
28 | $class = get_class($model); |
||
29 | assert($model instanceof Model, $class); |
||
30 | // dig up metadata |
||
31 | if (!isset(self::$metadataCache[$class])) { |
||
32 | self::$metadataCache[$class] = $model->metadata(); |
||
33 | } |
||
34 | $meta = self::$metadataCache[$class]; |
||
35 | $keys = array_keys($meta); |
||
36 | // dig up getter list - we only care about the mutators that end up in metadata |
||
37 | if (!isset(self::$mutatorCache[$class])) { |
||
38 | $getterz = []; |
||
39 | $datez = $model->getDates(); |
||
40 | $castz = method_exists($model, 'getCasts') ? $model->getCasts() : []; |
||
41 | foreach ($keys as $key) { |
||
42 | if ($model->hasGetMutator($key) || in_array($key, $datez) || array_key_exists($key, $castz)) { |
||
43 | $getterz[] = $key; |
||
44 | } |
||
45 | } |
||
46 | self::$mutatorCache[$class] = $getterz; |
||
47 | } |
||
48 | $getterz = self::$mutatorCache[$class]; |
||
49 | $result = array_intersect_key($model->getAttributes(), $meta); |
||
50 | foreach ($keys as $key) { |
||
51 | if (!isset($result[$key])) { |
||
52 | $result[$key] = null; |
||
53 | } |
||
54 | } |
||
55 | foreach ($getterz as $getter) { |
||
56 | $result[$getter] = $model->$getter; |
||
57 | } |
||
58 | |||
59 | return $result; |
||
60 | } |
||
61 | |||
62 | public function reset() |
||
67 | } |
||
68 |