Completed
Push — master ( 306f62...27d0b1 )
by Dmitry
11:05 queued 07:55
created

loadDifferentModelsFromPostRequest()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 39

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
dl 0
loc 39
ccs 0
cts 30
cp 0
rs 8.6737
c 0
b 0
f 0
cc 6
nc 5
nop 0
crap 42
1
<?php
2
3
namespace hipanel\modules\finance\collections;
4
5
use hipanel\modules\finance\models\Price;
6
use hipanel\modules\finance\models\factories\PriceModelFactory;
7
use hiqdev\hiart\Collection;
8
use Yii;
9
10
/**
11
 * Class PricesCollection overrides loading behavior of parent class in order to:
12
 * make it possible to load all the models, specified in [[knownForms]] at once
13
 *
14
 * @author Dmytro Naumenko <[email protected]>
15
 */
16
class PricesCollection extends Collection
17
{
18
    /**
19
     * @var \hipanel\modules\finance\models\factories\PriceModelFactory
20
     */
21
    private $priceModelFactory;
22
23
    public function __construct(PriceModelFactory $priceModelFactory, array $config = [])
24
    {
25
        parent::__construct($config);
26
        $this->priceModelFactory = $priceModelFactory;
27
    }
28
29
    /**
30
     * {@inheritdoc}
31
     */
32
    public function load($data = null)
33
    {
34
        if ($data === null && $this->dataToBeLoadedExistsInPostRequest()) {
35
            $data = $this->loadDifferentModelsFromPostRequest();
36
            $this->checkConsistency = false;
37
38
            return $this->set($data);
39
        }
40
41
        return parent::load($data);
42
    }
43
44
    private function dataToBeLoadedExistsInPostRequest()
45
    {
46
        $request = Yii::$app->request->post();
47
48
        $map = $this->priceModelFactory->getMap();
49
        foreach ($map as $formName => $className) {
50
            if (is_array($map[$formName])) {
51
                foreach ($map[$formName] as $type => $class) {
52
                    $class = (new \ReflectionClass($class))->getShortName();
53
                    if (isset($request[$class])) {
54
                        return true;
55
                    }
56
                }
57
            } elseif (isset($request[$formName])) {
58
                return true;
59
            }
60
        }
61
62
        return false;
63
    }
64
65
    private function loadDifferentModelsFromPostRequest()
66
    {
67
        /** @var Price[] $result */
68
        $result = [];
69
        $request = Yii::$app->request->post();
70
        $usedClasses = [];
71
72
        $iter = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($this->priceModelFactory->getMap()));
73
        foreach ($iter as $className) {
74
            if (is_array($className) || isset($usedClasses[$className])) {
75
                continue;
76
            }
77
            $formName = (new \ReflectionClass($className))->getShortName();
78
            if (empty($request[$formName])) {
79
                continue;
80
            }
81
82
            $usedClasses[$className] = true;
83
            /** @var Price[] $models */
84
            $models = [];
85
            /** @var array $modelsData */
86
            $modelsData = [];
87
            /** @var Price $modelPrototype */
88
            $modelPrototype = $this->priceModelFactory->instantiate($className);
89
            $modelPrototype->setAttributes($this->modelOptions);
90
            $modelPrototype->scenario = $this->getScenario();
91
92
            $data = $request[$formName];
93
            foreach ($data as $key => $modelData) {
94
                $models[$key] = clone $modelPrototype;
95
                $modelsData[$modelPrototype->formName()][$key] = $modelData;
96
            }
97
98
            $modelPrototype->loadMultiple($models, $modelsData);
99
            $result = array_merge($result, $models);
100
        }
101
102
        return $result;
103
    }
104
}
105