Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
41 / 41
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
InsertSchema
100.00% covered (success)
100.00%
41 / 41
100.00% covered (success)
100.00%
2 / 2
13
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 create
100.00% covered (success)
100.00%
40 / 40
100.00% covered (success)
100.00%
1 / 1
12
1<?php
2
3/**
4 * @license MIT
5 * @author hazuki3417<hazuki3417@gmail.com>
6 * @copyright 2022 hazuki3417 all rights reserved.
7 */
8
9namespace Selen\MongoDB\Builder;
10
11use ReflectionClass;
12use Selen\MongoDB\Attribute\SchemaLoader;
13use Selen\MongoDB\Attributes\Nest;
14use Selen\MongoDB\Builder\Attributes\Build;
15
16class InsertSchema implements SchemaBuilderInterface
17{
18    /** @var SchemaLoader */
19    private $schemaLoader;
20
21    public function __construct(SchemaLoader $schemaLoader)
22    {
23        $this->schemaLoader = $schemaLoader;
24    }
25
26    /**
27     * @param array<mixed,mixed> $input insertする値を渡します
28     *
29     * @return array<mixed,mixed> insertする値を返します
30     */
31    public function create(array $input): array
32    {
33        $schema = [];
34
35        foreach ($this->schemaLoader->fieldLoaders as $fieldLoader) {
36            $attributeNest  = $fieldLoader->attributeNest;
37            $attributeBuild = $fieldLoader->fetchAttribute(Build::class);
38
39            $isNestedValueBuild = $attributeNest !== null && $attributeBuild !== null;
40
41            if (!$isNestedValueBuild) {
42                // ネストされていない定義のときの処理
43                $key          = $fieldLoader->reflectionProperty->getName();
44                $value        = $fieldLoader->reflectionProperty->getDefaultValue();
45                $schema[$key] = $value;
46
47                if (!\array_key_exists($key, $input)) {
48                    // input側に上書きする値がないときの処理
49                    continue;
50                }
51
52                // input側の値で上書きする値があるときの処理
53                $schema[$key] = $input[$key];
54                continue;
55            }
56
57            // ネストされた定義のときの処理
58
59            /** @var Nest */
60            $nestInstance = $attributeNest->newInstance();
61            $insertSchema = new self(new SchemaLoader(new ReflectionClass($nestInstance->schemaClassName)));
62
63            if ($nestInstance->type === Nest::TYPE_OBJECT) {
64                /**
65                 * ネストされた値の形式がObject
66                 * 上書きする値がリテラル値の場合、定義の形式に合わないため上書き処理をしない。
67                 * ネストした定義の値を上書きするには1次元配列で指定する必要がある。
68                 */
69                $passInput = [];
70
71                if (\array_key_exists($fieldLoader->reflectionProperty->getName(), $input)) {
72                    $passInput = $input[$fieldLoader->reflectionProperty->getName()];
73                }
74
75                if (!\is_array($passInput)) {
76                    $passInput = [];
77                }
78
79                $key          = $fieldLoader->reflectionProperty->getName();
80                $value        = $insertSchema->create($passInput);
81                $schema[$key] = $value;
82                continue;
83            }
84
85            /**
86             * ネストされた値の形式がArrayObject
87             * 上書きする値がリテラル値の場合、定義の形式に合わないため上書き処理をしない。
88             * ネストした定義の値を上書きするには2次元配列で指定する必要がある。
89             * (1次はObjectを持つ要素, 2次はObjectのフィールドを持つ要素)
90             */
91            $key          = $fieldLoader->reflectionProperty->getName();
92            $value        = [];
93            $schema[$key] = $value;
94
95            if (!\array_key_exists($key, $input)) {
96                // input側に上書きする値がないときの処理
97                continue;
98            }
99
100            // input側に上書きする値があるときの処理
101
102            $inputObjectItems = $input[$key];
103
104            // ObjectItemsを想定した値かどうか確認
105            if (!\is_array($inputObjectItems)) {
106                // ObjectItemsを想定した値がリテラル値のときは処理しない
107                continue;
108            }
109
110            $writeObjectItems = [];
111
112            foreach ($inputObjectItems as $inputObjectItem) {
113                // ObjectItemを想定した値かどうか確認
114                if (!\is_array($inputObjectItem)) {
115                    // ObjectItemを想定した値がリテラル値のときは処理しない
116                    continue;
117                }
118                $writeObjectItems[] = $insertSchema->create($inputObjectItem);
119            }
120            $schema[$key] = $writeObjectItems;
121        }
122        return $schema;
123    }
124}