1 | <?php |
||
24 | class PricesCollection extends Collection |
||
25 | { |
||
26 | /** |
||
27 | * @var \hipanel\modules\finance\models\factories\PriceModelFactory |
||
28 | */ |
||
29 | private $priceModelFactory; |
||
30 | |||
31 | public function __construct(PriceModelFactory $priceModelFactory, array $config = []) |
||
32 | { |
||
33 | parent::__construct($config); |
||
34 | $this->priceModelFactory = $priceModelFactory; |
||
35 | // Prevent default behavior in Collection::collectData() in order to allow all attributes for different models |
||
36 | $this->dataCollector = fn(Price $model) => [$model->getPrimaryKey(), $model->toArray()]; |
||
|
|||
37 | } |
||
38 | |||
39 | /** |
||
40 | * {@inheritdoc} |
||
41 | */ |
||
42 | public function load($data = null) |
||
43 | { |
||
44 | if ($data === null && $this->dataToBeLoadedExistsInPostRequest()) { |
||
45 | $data = $this->loadDifferentModelsFromPostRequest(); |
||
46 | $this->checkConsistency = false; |
||
47 | |||
48 | return $this->set($data); |
||
49 | } |
||
50 | |||
51 | return parent::load($data); |
||
52 | } |
||
53 | |||
54 | private function dataToBeLoadedExistsInPostRequest() |
||
55 | { |
||
56 | $request = Yii::$app->request->post(); |
||
57 | |||
58 | $map = $this->priceModelFactory->getMap(); |
||
59 | foreach ($map as $formName => $className) { |
||
60 | if (is_array($map[$formName])) { |
||
61 | foreach ($map[$formName] as $type => $class) { |
||
62 | $class = (new \ReflectionClass($class))->getShortName(); |
||
63 | if (isset($request[$class])) { |
||
64 | return true; |
||
65 | } |
||
66 | } |
||
67 | } elseif (isset($request[$formName])) { |
||
68 | return true; |
||
69 | } |
||
70 | } |
||
71 | |||
72 | return false; |
||
73 | } |
||
74 | |||
75 | private function loadDifferentModelsFromPostRequest() |
||
76 | { |
||
77 | /** @var Price[] $result */ |
||
78 | $result = []; |
||
79 | $request = Yii::$app->request->post(); |
||
80 | $usedClasses = []; |
||
81 | |||
82 | $iter = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($this->priceModelFactory->getMap())); |
||
83 | foreach ($iter as $className) { |
||
84 | if (is_array($className) || isset($usedClasses[$className])) { |
||
85 | continue; |
||
86 | } |
||
87 | $formName = (new \ReflectionClass($className))->getShortName(); |
||
88 | if (empty($request[$formName])) { |
||
89 | continue; |
||
90 | } |
||
91 | |||
92 | $usedClasses[$className] = true; |
||
93 | /** @var Price[] $models */ |
||
94 | $models = []; |
||
95 | /** @var array $modelsData */ |
||
96 | $modelsData = []; |
||
97 | /** @var Price $modelPrototype */ |
||
98 | $modelPrototype = $this->priceModelFactory->instantiate($className); |
||
99 | $modelPrototype->setAttributes($this->modelOptions); |
||
100 | $modelPrototype->scenario = $this->getScenario(); |
||
101 | |||
102 | $data = $request[$formName]; |
||
103 | foreach ($data as $key => $modelData) { |
||
104 | if (empty(array_filter($modelData))) { |
||
105 | continue; |
||
106 | } |
||
107 | $models[$key] = clone $modelPrototype; |
||
108 | $modelsData[$modelPrototype->formName()][$key] = $modelData; |
||
109 | } |
||
110 | |||
111 | $modelPrototype->loadMultiple($models, $modelsData); |
||
112 | $result = array_merge($result, $models); |
||
113 | } |
||
114 | |||
115 | return $result; |
||
116 | } |
||
118 |