Completed
Push — master ( 313f20...c23fe9 )
by Tim
9s
created

AbstractEavSubject::getAttributes()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 28
Code Lines 11

Duplication

Lines 28
Ratio 100 %

Code Coverage

Tests 11
CRAP Score 3

Importance

Changes 0
Metric Value
dl 28
loc 28
ccs 11
cts 11
cp 1
rs 8.8571
c 0
b 0
f 0
cc 3
eloc 11
nc 3
nop 0
crap 3
1
<?php
2
3
/**
4
 * TechDivision\Import\Subjects\AbstractSubject
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Tim Wagner <[email protected]>
15
 * @copyright 2016 TechDivision GmbH <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/techdivision/import
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Subjects;
22
23
use TechDivision\Import\Utils\MemberNames;
24
use TechDivision\Import\Utils\RegistryKeys;
25
use TechDivision\Import\Utils\BackendTypeKeys;
26
use TechDivision\Import\Utils\EntityTypeCodes;
27
28
/**
29
 * An abstract EAV subject implementation.
30
 *
31
 * @author    Tim Wagner <[email protected]>
32
 * @copyright 2016 TechDivision GmbH <[email protected]>
33
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
34
 * @link      https://github.com/techdivision/import
35
 * @link      http://www.techdivision.com
36
 */
37
abstract class AbstractEavSubject extends AbstractSubject implements EavSubjectInterface
38
{
39
40
    /**
41
     * The available EAV attributes, grouped by their attribute set and the attribute set name as keys.
42
     *
43
     * @var array
44
     */
45
    protected $attributes = array();
46
47
    /**
48
     * The available user defined EAV attributes, grouped by their entity type.
49
     *
50
     * @var array
51
     */
52
    protected $userDefinedAttributes = array();
53
54
    /**
55
     * The attribute set of the entity that has to be created.
56
     *
57
     * @var array
58
     */
59
    protected $attributeSet = array();
60
61
    /**
62
     * The available EAV attribute sets.
63
     *
64
     * @var array
65
     */
66
    protected $attributeSets = array();
67
68
    /**
69
     * The mapping for the supported backend types (for the EAV entity) => persist methods.
70
     *
71
     * @var array
72
     */
73
    protected $backendTypes = array(
74
        BackendTypeKeys::BACKEND_TYPE_DATETIME => array('persistDatetimeAttribute', 'loadDatetimeAttribute', 'deleteDatetimeAttribute'),
75
        BackendTypeKeys::BACKEND_TYPE_DECIMAL  => array('persistDecimalAttribute', 'loadDecimalAttribute', 'deleteDecimalAttribute'),
76
        BackendTypeKeys::BACKEND_TYPE_INT      => array('persistIntAttribute', 'loadIntAttribute', 'deleteIntAttribute'),
77
        BackendTypeKeys::BACKEND_TYPE_TEXT     => array('persistTextAttribute', 'loadTextAttribute', 'deleteTextAttribute'),
78
        BackendTypeKeys::BACKEND_TYPE_VARCHAR  => array('persistVarcharAttribute', 'loadVarcharAttribute', 'deleteVarcharAttribute')
79
    );
80
81
    /**
82
     * The mappings for the entity type code to attribute set.
83
     *
84
     * @var array
85
     */
86
    protected $entityTypeCodeToAttributeSetMappings = array(
87
        EntityTypeCodes::CATALOG_PRODUCT           => EntityTypeCodes::CATALOG_PRODUCT,
88
        EntityTypeCodes::CATALOG_PRODUCT_PRICE     => EntityTypeCodes::CATALOG_PRODUCT,
89
        EntityTypeCodes::CATALOG_PRODUCT_INVENTORY => EntityTypeCodes::CATALOG_PRODUCT,
90
        EntityTypeCodes::CATALOG_CATEGORY          => EntityTypeCodes::CATALOG_CATEGORY,
91
        EntityTypeCodes::EAV_ATTRIBUTE             => EntityTypeCodes::EAV_ATTRIBUTE,
92
        EntityTypeCodes::NONE                      => EntityTypeCodes::NONE
93
    );
94
95
    /**
96
     * The default mappings for the user defined attributes, based on the attributes frontend input type.
97
     *
98
     * @var array
99
     */
100
    protected $defaultFrontendInputCallbackMappings = array();
101
102
    /**
103
     * Return's the default callback frontend input mappings for the user defined attributes.
104
     *
105
     * @return array The default frontend input callback mappings
106
     */
107 22
    public function getDefaultFrontendInputCallbackMappings()
108
    {
109 22
        return $this->defaultFrontendInputCallbackMappings;
110
    }
111
112
    /**
113
     * Intializes the previously loaded global data for exactly one bunch.
114
     *
115
     * @param string $serial The serial of the actual import
116
     *
117
     * @return void
118
     */
119 22
    public function setUp($serial)
120
    {
121
122
        // load the status of the actual import
123 22
        $status = $this->getRegistryProcessor()->getAttribute($serial);
124
125
        // load the global data we've prepared initially
126 22
        $this->attributes = $status[RegistryKeys::GLOBAL_DATA][RegistryKeys::EAV_ATTRIBUTES];
127 22
        $this->attributeSets = $status[RegistryKeys::GLOBAL_DATA][RegistryKeys::ATTRIBUTE_SETS];
128 22
        $this->userDefinedAttributes = $status[RegistryKeys::GLOBAL_DATA][RegistryKeys::EAV_USER_DEFINED_ATTRIBUTES];
129
130
        // load the default frontend callback mappings from the child instance and merge with the one from the configuration
131 22
        $defaultFrontendInputCallbackMappings = $this->getDefaultFrontendInputCallbackMappings();
132
133
        // merge the default mappings with the one's found in the configuration
134 22
        foreach ($this->getConfiguration()->getFrontendInputCallbacks() as $frontendInputCallbackMappings) {
135
            foreach ($frontendInputCallbackMappings as $frontendInput => $frontentInputMappings) {
136
                $defaultFrontendInputCallbackMappings[$frontendInput] = $frontentInputMappings;
137
            }
138
        }
139
140
        // load the user defined attributes and add the callback mappings
141 22
        foreach ($this->getEavUserDefinedAttributes() as $eavAttribute) {
142
            // load attribute code and frontend input type
143 1
            $attributeCode = $eavAttribute[MemberNames::ATTRIBUTE_CODE];
144 1
            $frontendInput = $eavAttribute[MemberNames::FRONTEND_INPUT];
145
146
            // query whether or not the array for the mappings has been initialized
147 1
            if (!isset($this->callbackMappings[$attributeCode])) {
148 1
                $this->callbackMappings[$attributeCode] = array();
149
            }
150
151
            // set the appropriate callback mapping for the attributes input type
152 1
            if (isset($defaultFrontendInputCallbackMappings[$frontendInput])) {
153 1
                foreach ($defaultFrontendInputCallbackMappings[$frontendInput] as $defaultFrontendInputCallbackMapping) {
154 1
                    $this->callbackMappings[$attributeCode][] = $defaultFrontendInputCallbackMapping;
155
                }
156
            }
157
        }
158
159
        // prepare the callbacks
160 22
        parent::setUp($serial);
161 22
    }
162
163
    /**
164
     * Return's mapping for the supported backend types (for the product entity) => persist methods.
165
     *
166
     * @return array The mapping for the supported backend types
167
     */
168 1
    public function getBackendTypes()
169
    {
170 1
        return $this->backendTypes;
171
    }
172
173
    /**
174
     * Set's the attribute set of the product that has to be created.
175
     *
176
     * @param array $attributeSet The attribute set
177
     *
178
     * @return void
179
     */
180 5
    public function setAttributeSet(array $attributeSet)
181
    {
182 5
        $this->attributeSet = $attributeSet;
183 5
    }
184
185
    /**
186
     * Return's the attribute set of the product that has to be created.
187
     *
188
     * @return array The attribute set
189
     */
190 1
    public function getAttributeSet()
191
    {
192 1
        return $this->attributeSet;
193
    }
194
195
    /**
196
     * Cast's the passed value based on the backend type information.
197
     *
198
     * @param string $backendType The backend type to cast to
199
     * @param mixed  $value       The value to be casted
200
     *
201
     * @return mixed The casted value
202
     */
203 9
    public function castValueByBackendType($backendType, $value)
204
    {
205
206
        // cast the value to a valid timestamp
207 9
        if ($backendType === BackendTypeKeys::BACKEND_TYPE_DATETIME) {
208 2
            return \DateTime::createFromFormat($this->getSourceDateFormat(), $value)->format('Y-m-d H:i:s');
209
        }
210
211
        // cast the value to a float value
212 7
        if ($backendType === BackendTypeKeys::BACKEND_TYPE_FLOAT) {
213 2
            return (float) $value;
214
        }
215
216
        // cast the value to an integer
217 5
        if ($backendType === BackendTypeKeys::BACKEND_TYPE_INT) {
218 3
            return (int) $value;
219
        }
220
221
        // we don't need to cast strings
222 2
        return $value;
223
    }
224
225
    /**
226
     * Return's the entity type code to be used.
227
     *
228
     * @return string The entity type code to be used
229
     */
230 22
    public function getEntityTypeCode()
231
    {
232
233
        // load the entity type code from the configuration
234 22
        $entityTypeCode = $this->getConfiguration()->getConfiguration()->getEntityTypeCode();
235
236
        // try to map the entity type code
237 22
        if (isset($this->entityTypeCodeToAttributeSetMappings[$entityTypeCode])) {
238 8
            $entityTypeCode = $this->entityTypeCodeToAttributeSetMappings[$entityTypeCode];
239
        }
240
241
        // return the (mapped) entity type code
242 22
        return $entityTypeCode;
243
    }
244
245
    /**
246
     * Return's the attribute set with the passed attribute set name.
247
     *
248
     * @param string $attributeSetName The name of the requested attribute set
249
     *
250
     * @return array The attribute set data
251
     * @throws \Exception Is thrown, if the attribute set or the given entity type with the passed name is not available
252
     */
253 3 View Code Duplication
    public function getAttributeSetByAttributeSetName($attributeSetName)
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...
254
    {
255
256
        // query whether or not attribute sets for the actualy entity type code are available
257 3
        if (isset($this->attributeSets[$entityTypeCode = $this->getEntityTypeCode()])) {
258
            // load the attribute sets for the actualy entity type code
259 2
            $attributSets = $this->attributeSets[$entityTypeCode];
260
261
            // query whether or not, the requested attribute set is available
262 2
            if (isset($attributSets[$attributeSetName])) {
263 1
                return $attributSets[$attributeSetName];
264
            }
265
266
            // throw an exception, if not
267 1
            throw new \Exception(
268 1
                $this->appendExceptionSuffix(
269 1
                    sprintf('Found invalid attribute set name "%s"', $attributeSetName)
270
                )
271
            );
272
        }
273
274
        // throw an exception, if not
275 1
        throw new \Exception(
276 1
            $this->appendExceptionSuffix(
277 1
                sprintf('Found invalid entity type code "%s"', $entityTypeCode)
278
            )
279
        );
280
    }
281
282
    /**
283
     * Return's the attributes for the attribute set of the product that has to be created.
284
     *
285
     * @return array The attributes
286
     * @throws \Exception Is thrown, if the attribute set or the given entity type with the passed name is not available
287
     */
288 5 View Code Duplication
    public function getAttributes()
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...
289
    {
290
291
        // query whether or not, the requested EAV attributes are available
292 5
        if (isset($this->attributes[$entityTypeCode = $this->getEntityTypeCode()])) {
293
            // load the attributes for the entity type code
294 4
            $attributes = $this->attributes[$entityTypeCode];
295
296
            // query whether or not attributes for the actual attribute set name
297 4
            if (isset($attributes[$attributeSetName = $this->attributeSet[MemberNames::ATTRIBUTE_SET_NAME]])) {
298 3
                return $attributes[$attributeSetName];
299
            }
300
301
            // throw an exception, if not
302 1
            throw new \Exception(
303 1
                $this->appendExceptionSuffix(
304 1
                    sprintf('Found invalid attribute set name "%s"', $attributeSetName)
305
                )
306
            );
307
        }
308
309
        // throw an exception, if not
310 1
        throw new \Exception(
311 1
            $this->appendExceptionSuffix(
312 1
                sprintf('Found invalid entity type code "%s"', $entityTypeCode)
313
            )
314
        );
315
    }
316
317
    /**
318
     * Return's an array with the available user defined EAV attributes for the actual entity type.
319
     *
320
     * @return array The array with the user defined EAV attributes
321
     */
322 22
    public function getEavUserDefinedAttributes()
323
    {
324
325
        // initialize the array with the user defined EAV attributes
326 22
        $eavUserDefinedAttributes = array();
327
328
        // query whether or not user defined EAV attributes for the actualy entity type are available
329 22
        if (isset($this->userDefinedAttributes[$entityTypeCode = $this->getEntityTypeCode()])) {
330 2
            $eavUserDefinedAttributes = $this->userDefinedAttributes[$entityTypeCode];
331
        }
332
333
        // return the array with the user defined EAV attributes
334 22
        return $eavUserDefinedAttributes;
335
    }
336
337
    /**
338
     * Return's the EAV attribute with the passed attribute code.
339
     *
340
     * @param string $attributeCode The attribute code
341
     *
342
     * @return array The array with the EAV attribute
343
     * @throws \Exception Is thrown if the attribute with the passed code is not available
344
     */
345 2
    public function getEavAttributeByAttributeCode($attributeCode)
346
    {
347
348
        // load the attributes
349 2
        $attributes = $this->getAttributes();
350
351
        // query whether or not the attribute exists
352 2
        if (isset($attributes[$attributeCode])) {
353 1
            return $attributes[$attributeCode];
354
        }
355
356
        // throw an exception if the requested attribute is not available
357 1
        throw new \Exception(
358 1
            $this->appendExceptionSuffix(
359 1
                sprintf('Can\'t load attribute with code "%s"', $attributeCode)
360
            )
361
        );
362
    }
363
}
364