Completed
Push — master ( 0f7b01...b73efb )
by Bukashk0zzz
02:11
created

Generator::addOffer()   D

Complexity

Conditions 10
Paths 40

Size

Total Lines 35
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 35
rs 4.8196
c 0
b 0
f 0
cc 10
eloc 20
nc 40
nop 1

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Offer\OfferInterface;
17
use Bukashk0zzz\YmlGenerator\Model\Offer\OfferParam;
18
use Bukashk0zzz\YmlGenerator\Model\ShopInfo;
19
20
/**
21
 * Class Generator
22
 *
23
 * @author Denis Golubovskiy <[email protected]>
24
 */
25
class Generator
26
{
27
    /**
28
     * @var string
29
     */
30
    private $tmpFile;
31
32
    /**
33
     * @var \XMLWriter
34
     */
35
    private $writer;
36
37
    /**
38
     * @var Settings
39
     */
40
    private $settings;
41
42
    /**
43
     * Generator constructor.
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
     *
66
     * @return bool
67
     *
68
     * @throws \RuntimeException
69
     */
70
    public function generate(ShopInfo $shopInfo, array $currencies, array $categories, array $offers)
71
    {
72
        try {
73
            $this->addHeader();
74
75
            $this->addShopInfo($shopInfo);
76
            $this->addCurrencies($currencies);
77
            $this->addCategories($categories);
78
            $this->addOffers($offers);
79
80
            $this->addFooter();
81
82
            if (null !== $this->settings->getOutputFile()) {
83
                rename($this->tmpFile, $this->settings->getOutputFile());
84
            }
85
86
            return true;
87
        } catch (\Exception $exception) {
88
            throw new \RuntimeException('Problem with generating YML file: '.$exception->getMessage(), 0, $exception);
89
        }
90
    }
91
92
    /**
93
     * Add document header
94
     */
95
    protected function addHeader()
96
    {
97
        $this->writer->startDocument('1.0', $this->settings->getEncoding());
98
        $this->writer->startElement('yml_catalog');
99
        $this->writer->writeAttribute('date', date('Y-m-d H:i'));
100
        $this->writer->startElement('shop');
101
    }
102
103
    /**
104
     * Add document footer
105
     */
106
    protected function addFooter()
107
    {
108
        $this->writer->fullEndElement();
109
        $this->writer->fullEndElement();
110
        $this->writer->endDocument();
111
    }
112
113
    /**
114
     * Adds shop element data. (See https://yandex.ru/support/webmaster/goods-prices/technical-requirements.xml#shop)
115
     * @param ShopInfo $shopInfo
116
     */
117
    protected function addShopInfo(ShopInfo $shopInfo)
118
    {
119
        foreach ($shopInfo->toArray() as $name => $value) {
120
            if ($value !== null) {
121
                $this->writer->writeElement($name, $value);
122
            }
123
        }
124
    }
125
126
    /**
127
     * @param Currency $currency
128
     */
129
    protected function addCurrency(Currency $currency)
130
    {
131
        $this->writer->startElement('currency');
132
        $this->writer->writeAttribute('id', $currency->getId());
133
        $this->writer->writeAttribute('rate', $currency->getRate());
134
        $this->writer->endElement();
135
    }
136
137
    /**
138
     * @param Category $category
139
     */
140
    protected function addCategory(Category $category)
141
    {
142
        $this->writer->startElement('category');
143
        $this->writer->writeAttribute('id', $category->getId());
144
145
        if ($category->getParentId() !== null) {
146
            $this->writer->writeAttribute('parentId', $category->getParentId());
147
        }
148
149
        $this->writer->text($category->getName());
150
        $this->writer->fullEndElement();
151
    }
152
153
    /**
154
     * @param OfferInterface $offer
155
     */
156
    protected function addOffer(OfferInterface $offer)
157
    {
158
        $this->writer->startElement('offer');
159
        $this->writer->writeAttribute('id', $offer->getId());
160
        $this->writer->writeAttribute('available', $offer->isAvailable() ? 'true' : 'false');
161
162
        if ($offer->getType() !== null) {
163
            $this->writer->writeAttribute('type', $offer->getType());
164
        }
165
166
        foreach ($offer->toArray() as $name => $value) {
167
            if ($value !== null) {
168
                if (is_bool($value)) {
169
                    $value = $value ? 'true' : 'false';
170
                }
171
                $this->writer->writeElement($name, $value);
172
            }
173
        }
174
175
        /** @var OfferParam $param */
176
        foreach ($offer->getParams() as $param) {
177
            if ($param instanceof OfferParam) {
178
                $this->writer->startElement('param');
179
180
                $this->writer->writeAttribute('name', $param->getName());
181
                if ($param->getUnit()) {
182
                    $this->writer->writeAttribute('unit', $param->getUnit());
183
                }
184
                $this->writer->text($param->getValue());
185
186
                $this->writer->endElement();
187
            }
188
        }
189
        $this->writer->fullEndElement();
190
    }
191
192
    /**
193
     * Adds <currencies> element. (See https://yandex.ru/support/webmaster/goods-prices/technical-requirements.xml#currencies)
194
     * @param array $currencies
195
     */
196
    private function addCurrencies(array $currencies)
197
    {
198
        $this->writer->startElement('currencies');
199
200
        /** @var Currency $currency */
201
        foreach ($currencies as $currency) {
202
            if ($currency instanceof Currency) {
203
                $this->addCurrency($currency);
204
            }
205
        }
206
207
        $this->writer->fullEndElement();
208
    }
209
210
    /**
211
     * Adds <categories> element. (See https://yandex.ru/support/webmaster/goods-prices/technical-requirements.xml#categories)
212
     * @param array $categories
213
     */
214
    private function addCategories(array $categories)
215
    {
216
        $this->writer->startElement('categories');
217
218
        /** @var Category $category */
219
        foreach ($categories as $category) {
220
            if ($category instanceof Category) {
221
                $this->addCategory($category);
222
            }
223
        }
224
225
        $this->writer->fullEndElement();
226
    }
227
228
    /**
229
     * Adds <offers> element. (See https://yandex.ru/support/webmaster/goods-prices/technical-requirements.xml#offers)
230
     * @param array $offers
231
     */
232
    private function addOffers(array $offers)
233
    {
234
        $this->writer->startElement('offers');
235
236
        /** @var OfferInterface $offer */
237
        foreach ($offers as $offer) {
238
            if ($offer instanceof OfferInterface) {
239
                $this->addOffer($offer);
240
            }
241
        }
242
243
        $this->writer->fullEndElement();
244
    }
245
}
246