1<?php
2
3namespace FINDOLOGIC\Export\XML;
4
5use FINDOLOGIC\Export\Data\Attribute;
6use FINDOLOGIC\Export\Data\BaseImageMissingException;
7use FINDOLOGIC\Export\Data\Image;
8use FINDOLOGIC\Export\Data\ImagesWithoutUsergroupMissingException;
9use FINDOLOGIC\Export\Data\Item;
10use FINDOLOGIC\Export\Data\Usergroup;
11use FINDOLOGIC\Export\Helpers\XMLHelper;
12
13class XMLItem extends Item
14{
15    /**
16     * @inheritdoc
17     */
18    public function getCsvFragment()
19    {
20        throw new \BadMethodCallException('XMLItem does not implement CSV export.');
21    }
22
23    /**
24     * @SuppressWarnings(PHPMD.StaticAccess)
25     * @inheritdoc
26     */
27    public function getDomSubtree(\DOMDocument $document)
28    {
29        $itemElem = XMLHelper::createElement($document, 'item', ['id' => $this->id]);
30        $document->appendChild($itemElem);
31
32        $itemElem->appendChild($this->name->getDomSubtree($document));
33        $itemElem->appendChild($this->summary->getDomSubtree($document));
34        $itemElem->appendChild($this->description->getDomSubtree($document));
35        $itemElem->appendChild($this->price->getDomSubtree($document));
36        $itemElem->appendChild($this->url->getDomSubtree($document));
37        $itemElem->appendChild($this->bonus->getDomSubtree($document));
38        $itemElem->appendChild($this->salesFrequency->getDomSubtree($document));
39        $itemElem->appendChild($this->dateAdded->getDomSubtree($document));
40        $itemElem->appendChild($this->sort->getDomSubtree($document));
41        $itemElem->appendChild($this->keywords->getDomSubtree($document));
42        $itemElem->appendChild($this->ordernumbers->getDomSubtree($document));
43
44        $itemElem->appendChild($this->buildProperties($document));
45        $itemElem->appendChild($this->buildAttributes($document));
46        $itemElem->appendChild($this->buildImages($document));
47        $itemElem->appendChild($this->buildUsergroups($document));
48
49        return $itemElem;
50    }
51
52    /**
53     * @SuppressWarnings(PHPMD.StaticAccess)
54     */
55    private function buildProperties(\DOMDocument $document)
56    {
57        $allProps = XMLHelper::createElement($document, 'allProperties');
58
59        foreach ($this->properties as $usergroup => $usergroupSpecificProperties) {
60            $usergroupPropsElem = XMLHelper::createElement($document, 'properties');
61            if ($usergroup) {
62                $usergroupPropsElem->setAttribute('usergroup', $usergroup);
63            }
64            $allProps->appendChild($usergroupPropsElem);
65
66            foreach ($usergroupSpecificProperties as $key => $value) {
67                $propertyElem = XMLHelper::createElement($document, 'property');
68                $usergroupPropsElem->appendChild($propertyElem);
69
70                $keyElem = XMLHelper::createElementWithText($document, 'key', $key);
71                $propertyElem->appendChild($keyElem);
72
73                $valueElem = XMLHelper::createElementWithText($document, 'value', $value);
74                $propertyElem->appendChild($valueElem);
75            }
76        }
77
78        return $allProps;
79    }
80
81    /**
82     * @SuppressWarnings(PHPMD.StaticAccess)
83     */
84    private function buildAttributes(\DOMDocument $document)
85    {
86        $allAttributes = XMLHelper::createElement($document, 'allAttributes');
87
88        $attributes = XMLHelper::createElement($document, 'attributes');
89        $allAttributes->appendChild($attributes);
90
91        /**
92         * @var string $key
93         * @var Attribute $attribute
94         */
95        foreach ($this->attributes as $key => $attribute) {
96            $attributes->appendChild($attribute->getDomSubtree($document));
97        }
98
99        return $allAttributes;
100    }
101
102    /**
103     * @SuppressWarnings(PHPMD.StaticAccess)
104     */
105    private function buildImages(\DOMDocument $document)
106    {
107        $allImagesElem = XMLHelper::createElement($document, 'allImages');
108
109        if ($this->images) {
110            if (array_key_exists("", $this->images)) {
111                foreach ($this->images as $usergroup => $images) {
112                    $usergroupImagesElem = XMLHelper::createElement($document, 'images');
113                    if ($usergroup) {
114                        $usergroupImagesElem->setAttribute('usergroup', $usergroup);
115                    }
116
117                    $allImagesElem->appendChild($usergroupImagesElem);
118
119                    if ($this->validateImages($images)) {
120                        /** @var Image $image */
121                        foreach ($images as $image) {
122                            $usergroupImagesElem->appendChild($image->getDomSubtree($document));
123                        }
124                    }
125                }
126            } else {
127                throw new ImagesWithoutUsergroupMissingException();
128            }
129        }
130
131        return $allImagesElem;
132    }
133
134    /**
135     * @SuppressWarnings(PHPMD.StaticAccess)
136     */
137    private function buildUsergroups(\DOMDocument $document)
138    {
139        $usergroups = XMLHelper::createElement($document, 'usergroups');
140
141        /** @var Usergroup $usergroup */
142        foreach ($this->usergroups as $usergroup) {
143            $usergroups->appendChild($usergroup->getDomSubtree($document));
144        }
145
146        return $usergroups;
147    }
148
149    /**
150     * Checks if there is at least one image of type default
151     *
152     * @param array $images The images to validate.
153     * @return boolean Whether the images are valid or not.
154     */
155    private function validateImages(array $images)
156    {
157        $valid = false;
158
159        foreach ($images as $image) {
160            if ($image->getType() === Image::TYPE_DEFAULT) {
161                $valid = true;
162                break;
163            }
164        }
165
166        if (!$valid) {
167            throw new BaseImageMissingException();
168        }
169
170        return $valid;
171    }
172}
173