Completed
Push — master ( 54397a...1bfb0c )
by Dmitry
14:50
created

PricesCollection::dataToBeLoadedExistsInPostRequest()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
dl 0
loc 20
ccs 0
cts 18
cp 0
rs 8.9777
c 0
b 0
f 0
cc 6
nc 5
nop 0
crap 42
1
<?php
2
/**
3
 * Finance module for HiPanel
4
 *
5
 * @link      https://github.com/hiqdev/hipanel-module-finance
6
 * @package   hipanel-module-finance
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2015-2019, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hipanel\modules\finance\collections;
12
13
use hipanel\modules\finance\models\factories\PriceModelFactory;
14
use hipanel\modules\finance\models\Price;
15
use hiqdev\hiart\Collection;
16
use Yii;
17
18
/**
19
 * Class PricesCollection overrides loading behavior of parent class in order to:
20
 * make it possible to load all the models, specified in [[knownForms]] at once.
21
 *
22
 * @author Dmytro Naumenko <[email protected]>
23
 */
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()];
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_VARIABLE, expecting ',' or ')'
Loading history...
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
    }
117
}
118