Completed
Pull Request — master (#39)
by
unknown
05:32
created

YmlCatalog::generate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 23
ccs 16
cts 16
cp 1
rs 9.0856
cc 1
eloc 14
nc 1
nop 0
crap 1
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
//    /**
0 ignored issues
show
Unused Code Comprehensibility introduced by
39% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
220
//     * @param string|array $modelClass class name or yii configuration array. You can also set params:
221 9
//     *      `findParams`:   array of additional find params;
222 9
//     *      `query`:        ActiveQuery object to generate yml use already created object;
223 6
//     *      `dataProvider`: ActiveDataProvider or true to generate yml with pagination;
224 9
//     */
225 9
//    protected function writeEachModel($modelClass)
226 3
//    {
227 3
//        /**
228 6
//         * @var mixed
229 6
//         */
230 4
//        $findParams = [];
231
//        if (is_array($modelClass)) {
232
//            if (array_key_exists('findParams', $modelClass)) {
233
//                $findParams = $modelClass['findParams'];
234 9
//                unset($modelClass['findParams']);
235
//            }
236
//
237
//            $modelClass = $modelClass['class'];
238
//        }
239
//
240
//        $interfaces = class_implements($modelClass);
241
//        if (!isset($interfaces[ActiveRecordInterface::class])) {
242
//            return $this->writeModel($this->getNewModel($modelClass), \Yii::createObject($modelClass));
243
//        }
244
//
245
//        /* @var \yii\db\ActiveQuery $query */
246
//        $query = $modelClass::findYml($findParams);
247
//
248
//        $newModel = $this->getNewModel($modelClass);
249
//        foreach ($query->batch(100) as $models) {
250
////
251
////        /**
252
////         * @var ActiveQuery
253
////         */
254
////        $query = null;
255
////
256
////        /**
257
////         * @var ActiveDataProvider
258
////         */
259
////        $dataProvider = null;
260
////
261
////        if (is_array($modelClass)) {
262
////            foreach (['findParams', 'query', 'dataProvider'] as $name) {
263
////                if (array_key_exists($name, $modelClass)) {
264
////                    $$name = $modelClass[$name];
265
////                    unset($modelClass[$name]);
266
////                }
267
////            }
268
////        }
269
////
270
////        /**
271
////         * @var BaseFindYmlInterface $class
272
////         */
273
////        $class = \Yii::createObject($modelClass);
274
////
275
////        /**
276
////         * @var ReaderInterface
277
////         */
278
////        $reader = ReaderFactory::build(
279
////            $class,
280
////            $dataProvider,
281
////            $query,
282
////            $findParams
283
////        );
284
////
285
////        $newModel = $this->getNewModel($class);
286
////
287
////        foreach ($reader as $models) {
288
//            foreach ($models as $model) {
289
//                $this->writeModel($newModel, $model);
290
//            }
291
//            $this->gc();
292
//        }
293
//    }
294
295
    /**
296
     * @param $modelClass
297
     * @return Category|Currency|SimpleOffer
298
     * @throws Exception
299
     */
300
    protected function getNewModel($modelClass)
301
    {
302
        $factory = new ModelsFactory([
303
            'modelClass' => $modelClass,
304
        ]);
305
306
        return $factory->create();
307
    }
308
    
309
    /**
310
     * Performs PHP memory garbage collection.
311
     */
312
    protected function gc()
313
    {
314
        if (!gc_enabled()) {
315
            gc_enable();
316
        }
317
        gc_collect_cycles();
318
    }
319
}
320