Completed
Pull Request — master (#39)
by
unknown
04:01
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
         * @var mixed
165 9
         */
166 9
        $findParams = [];
167
        if (is_array($modelClass)) {
168 9
            if (array_key_exists('findParams', $modelClass)) {
169 6
                $findParams = $modelClass['findParams'];
170
                unset($modelClass['findParams']);
171 9
            }
172 9
173 6
            $modelClass = $modelClass['class'];
174 4
        }
175 9
176 6
        $interfaces = class_implements($modelClass);
177 4
        if (!isset($interfaces[ActiveRecordInterface::class])) {
178
            return $this->writeModel($this->getNewModel($modelClass), \Yii::createObject($modelClass));
179 9
        }
180 9
181 9
        /* @var \yii\db\ActiveQuery $query */
182 6
        $query = $modelClass::findYml($findParams);
183 3
184
        $newModel = $this->getNewModel($modelClass);
185 6
        foreach ($query->batch(100) as $models) {
186 9
//
0 ignored issues
show
Unused Code Comprehensibility introduced by
44% 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...
187
//        /**
188 9
//         * @var ActiveQuery
189
//         */
190 9
//        $query = null;
191
//
192
//        /**
193
//         * @var ActiveDataProvider
194
//         */
195 9
//        $dataProvider = null;
196
//
197 9
//        if (is_array($modelClass)) {
198 9
//            foreach (['findParams', 'query', 'dataProvider'] as $name) {
199
//                if (array_key_exists($name, $modelClass)) {
200 9
//                    $$name = $modelClass[$name];
201
//                    unset($modelClass[$name]);
202
//                }
203 9
//            }
204
//        }
205 9
//
206 9
//        /**
207 9
//         * @var BaseFindYmlInterface $class
208 6
//         */
209 6
//        $class = \Yii::createObject($modelClass);
210 9
//
211
//        /**
212
//         * @var ReaderInterface
213
//         */
214
//        $reader = ReaderFactory::build(
215
//            $class,
216
//            $dataProvider,
217 9
//            $query,
218
//            $findParams
219 9
//        );
220
//
221 9
//        $newModel = $this->getNewModel($class);
222 9
//
223 6
//        foreach ($reader as $models) {
224 9
            foreach ($models as $model) {
225 9
                $this->writeModel($newModel, $model);
226 3
            }
227 3
            $this->gc();
228 6
        }
229 6
    }
230 4
231
    /**
232
     * @param $modelClass
233
     * @return Category|Currency|SimpleOffer
234 9
     * @throws Exception
235
     */
236
    protected function getNewModel($modelClass)
237
    {
238
        $factory = new ModelsFactory([
239
            'modelClass' => $modelClass,
240
        ]);
241
242
        return $factory->create();
243
    }
244
    
245
    /**
246
     * Performs PHP memory garbage collection.
247
     */
248
    protected function gc()
249
    {
250
        if (!gc_enabled()) {
251
            gc_enable();
252
        }
253
        gc_collect_cycles();
254
    }
255
}
256