Completed
Push — master ( 4a8227...2407ef )
by Bukashk0zzz
01:29
created

Generator::addDelivery()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 10
Ratio 100 %

Importance

Changes 0
Metric Value
dl 10
loc 10
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 2
nop 1
1
<?php
2
3
/*
4
 * This file is part of the Bukashk0zzzYmlGenerator
5
 *
6
 * (c) Denis Golubovskiy <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Bukashk0zzz\YmlGenerator;
13
14
use Bukashk0zzz\YmlGenerator\Model\Category;
15
use Bukashk0zzz\YmlGenerator\Model\Currency;
16
use Bukashk0zzz\YmlGenerator\Model\Delivery;
17
use Bukashk0zzz\YmlGenerator\Model\Offer\OfferInterface;
18
use Bukashk0zzz\YmlGenerator\Model\Offer\OfferParam;
19
use Bukashk0zzz\YmlGenerator\Model\ShopInfo;
20
21
/**
22
 * Class Generator
23
 */
24
class Generator
25
{
26
    /**
27
     * @var string
28
     */
29
    private $tmpFile;
30
31
    /**
32
     * @var \XMLWriter
33
     */
34
    private $writer;
35
36
    /**
37
     * @var Settings
38
     */
39
    private $settings;
40
41
    /**
42
     * Generator constructor.
43
     *
44
     * @param Settings $settings
45
     */
46
    public function __construct($settings = null)
47
    {
48
        $this->settings = $settings instanceof Settings ? $settings : new Settings();
49
        $this->tmpFile = $this->settings->getOutputFile() !== null ? \tempnam(\sys_get_temp_dir(), 'YMLGenerator') : 'php://output';
50
51
        $this->writer = new \XMLWriter();
52
        $this->writer->openURI($this->tmpFile);
53
54
        if ($this->settings->getIndentString()) {
55
            $this->writer->setIndentString($this->settings->getIndentString());
56
            $this->writer->setIndent(true);
57
        }
58
    }
59
60
    /**
61
     * @param ShopInfo $shopInfo
62
     * @param array    $currencies
63
     * @param array    $categories
64
     * @param array    $offers
65
     * @param array    $deliveries
66
     *
67
     * @return bool
68
     */
69
    public function generate(ShopInfo $shopInfo, array $currencies, array $categories, array $offers, array $deliveries = [])
70
    {
71
        try {
72
            $this->addHeader();
73
74
            $this->addShopInfo($shopInfo);
75
            $this->addCurrencies($currencies);
76
            $this->addCategories($categories);
77
78
            if (\count($deliveries) !== 0) {
79
                $this->addDeliveries($deliveries);
80
            }
81
82
            $this->addOffers($offers);
83
            $this->addFooter();
84
85
            if (null !== $this->settings->getOutputFile()) {
86
                \copy($this->tmpFile, $this->settings->getOutputFile());
87
                @\unlink($this->tmpFile);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
88
            }
89
90
            return true;
91
        } catch (\Exception $exception) {
92
            throw new \RuntimeException(\sprintf('Problem with generating YML file: %s', $exception->getMessage()), 0, $exception);
93
        }
94
    }
95
96
    /**
97
     * Add document header
98
     */
99
    protected function addHeader()
100
    {
101
        $this->writer->startDocument('1.0', $this->settings->getEncoding());
102
        $this->writer->startDTD('yml_catalog', null, 'shops.dtd');
103
        $this->writer->endDTD();
104
        $this->writer->startElement('yml_catalog');
105
        $this->writer->writeAttribute('date', \date('Y-m-d H:i'));
106
        $this->writer->startElement('shop');
107
    }
108
109
    /**
110
     * Add document footer
111
     */
112
    protected function addFooter()
113
    {
114
        $this->writer->fullEndElement();
115
        $this->writer->fullEndElement();
116
        $this->writer->endDocument();
117
    }
118
119
    /**
120
     * Adds shop element data. (See https://yandex.ru/support/webmaster/goods-prices/technical-requirements.xml#shop)
121
     *
122
     * @param ShopInfo $shopInfo
123
     */
124
    protected function addShopInfo(ShopInfo $shopInfo)
125
    {
126
        foreach ($shopInfo->toArray() as $name => $value) {
127
            if ($value !== null) {
128
                $this->writer->writeElement($name, $value);
129
            }
130
        }
131
    }
132
133
    /**
134
     * @param Currency $currency
135
     */
136
    protected function addCurrency(Currency $currency)
137
    {
138
        $this->writer->startElement('currency');
139
        $this->writer->writeAttribute('id', $currency->getId());
140
        $this->writer->writeAttribute('rate', $currency->getRate());
141
        $this->writer->endElement();
142
    }
143
144
    /**
145
     * @param Category $category
146
     */
147 View Code Duplication
    protected function addCategory(Category $category)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
148
    {
149
        $this->writer->startElement('category');
150
        $this->writer->writeAttribute('id', $category->getId());
151
152
        if ($category->getParentId() !== null) {
153
            $this->writer->writeAttribute('parentId', $category->getParentId());
154
        }
155
156
        $this->writer->text($category->getName());
157
        $this->writer->fullEndElement();
158
    }
159
160
    /**
161
     * @param Delivery $delivery
162
     */
163 View Code Duplication
    protected function addDelivery(Delivery $delivery)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
164
    {
165
        $this->writer->startElement('option');
166
        $this->writer->writeAttribute('cost', $delivery->getCost());
167
        $this->writer->writeAttribute('days', $delivery->getDays());
168
        if ($delivery->getOrderBefore() !== null) {
169
            $this->writer->writeAttribute('order-before', $delivery->getOrderBefore());
170
        }
171
        $this->writer->endElement();
172
    }
173
174
    /**
175
     * @param OfferInterface $offer
176
     */
177
    protected function addOffer(OfferInterface $offer)
178
    {
179
        $this->writer->startElement('offer');
180
        $this->writer->writeAttribute('id', $offer->getId());
181
        $this->writer->writeAttribute('available', $offer->isAvailable() ? 'true' : 'false');
182
183
        if ($offer->getType() !== null) {
184
            $this->writer->writeAttribute('type', $offer->getType());
185
        }
186
187
        foreach ($offer->toArray() as $name => $value) {
188
            if (\is_array($value)) {
189
                foreach ($value as $itemValue) {
190
                    $this->addOfferElement($name, $itemValue);
191
                }
192
            } else {
193
                $this->addOfferElement($name, $value);
194
            }
195
        }
196
        $this->addOfferParams($offer);
197
198
        $this->writer->fullEndElement();
199
    }
200
201
    /**
202
     * Adds <currencies> element. (See https://yandex.ru/support/webmaster/goods-prices/technical-requirements.xml#currencies)
203
     *
204
     * @param array $currencies
205
     */
206
    private function addCurrencies(array $currencies)
207
    {
208
        $this->writer->startElement('currencies');
209
210
        /** @var Currency $currency */
211
        foreach ($currencies as $currency) {
212
            if ($currency instanceof Currency) {
213
                $this->addCurrency($currency);
214
            }
215
        }
216
217
        $this->writer->fullEndElement();
218
    }
219
220
    /**
221
     * Adds <categories> element. (See https://yandex.ru/support/webmaster/goods-prices/technical-requirements.xml#categories)
222
     *
223
     * @param array $categories
224
     */
225
    private function addCategories(array $categories)
226
    {
227
        $this->writer->startElement('categories');
228
229
        /** @var Category $category */
230
        foreach ($categories as $category) {
231
            if ($category instanceof Category) {
232
                $this->addCategory($category);
233
            }
234
        }
235
236
        $this->writer->fullEndElement();
237
    }
238
239
    /**
240
     * Adds <delivery-option> element. (See https://yandex.ru/support/partnermarket/elements/delivery-options.xml)
241
     *
242
     * @param array $deliveries
243
     */
244
    private function addDeliveries(array $deliveries)
245
    {
246
        $this->writer->startElement('delivery-options');
247
248
        /** @var Delivery $delivery */
249
        foreach ($deliveries as $delivery) {
250
            if ($delivery instanceof Delivery) {
251
                $this->addDelivery($delivery);
252
            }
253
        }
254
255
        $this->writer->fullEndElement();
256
    }
257
258
    /**
259
     * Adds <offers> element. (See https://yandex.ru/support/webmaster/goods-prices/technical-requirements.xml#offers)
260
     *
261
     * @param array $offers
262
     */
263
    private function addOffers(array $offers)
264
    {
265
        $this->writer->startElement('offers');
266
267
        /** @var OfferInterface $offer */
268
        foreach ($offers as $offer) {
269
            if ($offer instanceof OfferInterface) {
270
                $this->addOffer($offer);
271
            }
272
        }
273
274
        $this->writer->fullEndElement();
275
    }
276
277
    /**
278
     * @param OfferInterface $offer
279
     */
280
    private function addOfferParams(OfferInterface $offer)
281
    {
282
        /** @var OfferParam $param */
283
        foreach ($offer->getParams() as $param) {
284
            if ($param instanceof OfferParam) {
285
                $this->writer->startElement('param');
286
287
                $this->writer->writeAttribute('name', $param->getName());
288
                if ($param->getUnit()) {
289
                    $this->writer->writeAttribute('unit', $param->getUnit());
290
                }
291
                $this->writer->text($param->getValue());
292
293
                $this->writer->endElement();
294
            }
295
        }
296
    }
297
298
    /**
299
     * @param string $name
300
     * @param mixed  $value
301
     *
302
     * @return bool
303
     */
304
    private function addOfferElement($name, $value)
305
    {
306
        if ($value === null) {
307
            return false;
308
        }
309
310
        if (\is_bool($value)) {
311
            $value = $value ? 'true' : 'false';
312
        }
313
        $this->writer->writeElement($name, $value);
314
315
        return true;
316
    }
317
}
318