Completed
Pull Request — master (#39)
by
unknown
05:19 queued 02:35
created

YmlCatalog::writeModel()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 9.4285
cc 2
eloc 4
nc 2
nop 2
crap 2
1
<?php
2
namespace pastuhov\ymlcatalog;
3
4
use pastuhov\ymlcatalog\models\BaseModel;
5
use pastuhov\ymlcatalog\models\Category;
6
use pastuhov\ymlcatalog\models\Currency;
7
use pastuhov\ymlcatalog\models\CustomOffer;
8
use pastuhov\ymlcatalog\models\Shop;
9
use pastuhov\ymlcatalog\models\SimpleOffer;
10
use pastuhov\ymlcatalog\models\DeliveryOption;
11
use Yii;
12
use pastuhov\FileStream\BaseFileStream;
13
use yii\base\Exception;
14
use yii\base\Object;
15
use yii\db\ActiveRecordInterface;
16
use yii\data\ActiveDataProvider;
17
use yii\db\ActiveQuery;
18
19
/**
20
 * Yml генератор каталога.
21
 *
22
 * @package pastuhov\ymlcatalog
23
 */
24
class YmlCatalog extends Object
25
{
26
    /**
27
     * @var BaseFileStream
28
     */
29
    public $handle;
30
    /**
31
     * @var string
32
     */
33
    public $shopClass;
34
    /**
35
     * @var string
36
     */
37
    public $currencyClass;
38
    /**
39
     * @var string
40
     */
41
    public $categoryClass;
42
    /**
43
     * @var string
44
     */
45
    public $offerClass;
46
    /**
47
     * @var null|string
48
     */
49
    public $date;
50
51
    /**
52
     * @var null|callable
53
     */
54
    public $onValidationError;
55
56
    /**
57
     * @var null|string
58
     */
59
    public $customOfferClass;
60
61
    /**
62
     * @var null|string
63
     */
64
    public $deliveryOptionClass;
65
66
    /**
67
     * @return null|string
68
     */
69
    protected function getFormattedDate()
70
    {
71 9
        $date = $this->date;
72
73
        if ($date === null) {
74 2
            $date = Yii::$app->formatter->asDatetime(new \DateTime(), 'php:Y-m-d H:i');
75
        }
76
77
        return $date;
78
    }
79
80
    /**
81
     * @throws Exception
82 9
     */
83 9
    public function generate()
84 9
    {
85 9
        $date = $this->getFormattedDate();
86 9
87 9
        $this->write(
88 9
            '<?xml version="1.0" encoding="utf-8"?>' . PHP_EOL .
89 9
            '<yml_catalog date="' . $date . '">' . PHP_EOL
90 9
        );
91 9
92
        $tags = [
93
            'shop' => [
94
                $this->shopClass,
95
                'currencies' => $this->currencyClass,
96 9
                'categories' => $this->categoryClass,
97
                'delivery-options' => $this->deliveryOptionClass,
98 9
                'offers' => $this->offerClass,
99
            ],
100 9
        ];
101 9
102 9
        $this->writeTags($tags);
103 9
104 6
        $this->write('</yml_catalog>');
105
    }
106 9
107 9
    /**
108 9
     * @param string $string
109 9
     * @throws \Exception
110 9
     */
111 9
    protected function write($string)
112 9
    {
113 9
        $this->handle->write($string);
114 9
    }
115 9
116 9
    /**
117 9
     * @param string $string tag name
118 4
     */
119 6
    protected function writeTag($string)
120 8
    {
121
        $this->write('<' . $string . '>' . PHP_EOL);
122 6
    }
123 6
124
    /**
125
     * @param BaseModel $model
126
     * @param $valuesModel
127
     * @throws Exception
128 9
     */
129
    protected function writeModel(BaseModel $model, $valuesModel)
130 9
    {
131
        if($model->loadModel($valuesModel, $this->onValidationError)) {
0 ignored issues
show
Bug introduced by
It seems like $this->onValidationError can also be of type callable; however, pastuhov\ymlcatalog\models\BaseModel::loadModel() does only seem to accept null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
132 9
            $string = $model->getYml();
133 3
            $this->write($string);
134 2
        }
135
    }
136 9
137
    protected function writeTags($tags)
138
    {
139
        foreach ($tags as $tagName => $tagParams) {
140
            if (is_string($tagName)) {
141
                $this->writeTag($tagName);
142
                if (is_string($tagParams) || isset($tagParams['class'])) {
143 9
                    $this->writeEachModel($tagParams);
144 6
                } else {
145 9
                    $this->writeTags($tagParams);
146 9
                }
147
148
                $this->writeTag('/' . $tagName);
149
            } else if (!is_null($tagParams)) {
150
                $this->writeEachModel($tagParams);
151 9
            }
152 6
        }
153 9
    }
154 9
155
    /**
156
     * @param string|array $modelClass class name or yii configuration array. You can also set params:
157
     *      `findParams`:   array of additional find params;
158
     *      `query`:        ActiveQuery object to generate yml use already created object;
159
     *      `dataProvider`: ActiveDataProvider or true to generate yml with pagination;
160
     */
161 9
    protected function writeEachModel($modelClass)
162
    {
163 9
164 9
        /**
165 9
         * @var ActiveQuery
166 9
         */
167
        $query = null;
168 9
169 6
        /**
170
         * @var ActiveDataProvider
171 9
         */
172 9
        $dataProvider = null;
173 6
174 4
        /**
175 9
         * @var mixed
176 6
         */
177 4
        $findParams = [];
178
        if (is_array($modelClass)) {
179 9
            foreach (['findParams', 'query', 'dataProvider'] as $name) {
180 9
                if (array_key_exists($name, $modelClass)) {
181 9
                    $$name = $modelClass[$name];
182 6
                    unset($modelClass[$name]);
183 3
                }
184
            }
185 6
186 9
            $modelClass = $modelClass['class'];
187
        }
188 9
189
        $interfaces = class_implements($modelClass);
190 9
        if (!isset($interfaces[BaseFindYmlInterface::class])) {
191
            return $this->writeModel($this->getNewModel($modelClass), \Yii::createObject($modelClass));
192
        }
193
194
        /**
195 9
         * @var BaseFindYmlInterface $class
196
         */
197 9
        $class = \Yii::createObject($modelClass);
198 9
199
        /**
200 9
         * @var ReaderInterface
201
         */
202
        $reader = ReaderFactory::build(
203 9
            $class,
204
            $dataProvider,
205 9
            $query,
206 9
            $findParams
207 9
        );
208 6
209 6
        $newModel = $this->getNewModel($class);
210 9
211
        foreach ($reader as $models) {
212
            foreach ($models as $model) {
213
                $this->writeModel($newModel, $model);
214
            }
215
            $this->gc();
216
        }
217 9
    }
218
219 9
    /**
220
     * @param $modelClass
221 9
     * @return Category|Currency|SimpleOffer
222 9
     * @throws Exception
223 6
     */
224 9
    protected function getNewModel($modelClass)
225 9
    {
226 3
        $factory = new ModelsFactory([
227 3
            'modelClass' => $modelClass,
228 6
        ]);
229 6
230 4
        return $factory->create();
231
    }
232
    
233
    /**
234 9
     * Performs PHP memory garbage collection.
235
     */
236
    protected function gc()
237
    {
238
        if (!gc_enabled()) {
239
            gc_enable();
240
        }
241
        gc_collect_cycles();
242
    }
243
}
244