Completed
Push — master ( e77248...65c04d )
by
unknown
04:36 queued 02:44
created

ExportableTrait   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 288
Duplicated Lines 17.01 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 86.57%

Importance

Changes 0
Metric Value
wmc 26
lcom 1
cbo 1
dl 49
loc 288
ccs 58
cts 67
cp 0.8657
rs 10
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A getArtefacts() 0 4 1
B addArtefacts() 23 23 6
A overrideArtefacts() 0 6 2
A appendArtefacts() 0 6 2
A hasArtefactsByTypeAndEntityId() 0 4 1
A newArtefact() 0 21 2
A setExportAdapter() 0 4 1
A getExportAdapter() 0 4 1
A setLastEntityId() 0 4 1
A getLastEntityId() 0 4 1
isDebugMode() 0 1 ?
mergeStatus() 0 1 ?
A resetArtefacts() 0 4 1
A getArtefactsByTypeAndEntityId() 0 29 5
A export() 26 26 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
/**
4
 * TechDivision\Import\Subjects\ExportableTrait
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\ColumnKeys;
24
use TechDivision\Import\Utils\RegistryKeys;
25
use TechDivision\Import\Adapter\ExportAdapterInterface;
26
27
/**
28
 * The trait implementation for the artefact export functionality.
29
 *
30
 * @author    Tim Wagner <[email protected]>
31
 * @copyright 2016 TechDivision GmbH <[email protected]>
32
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
33
 * @link      https://github.com/techdivision/import
34
 * @link      http://www.techdivision.com
35
 */
36
trait ExportableTrait
37
{
38
39
    /**
40
     * The array containing the data for product type configuration (configurables, bundles, etc).
41
     *
42
     * @var array
43
     */
44
    protected $artefacts = array();
45
46
    /**
47
     * The export adapter instance.
48
     *
49
     * @var \TechDivision\Import\Adapter\ExportAdapterInterface
50
     */
51
    protected $exportAdapter;
52
53
    /**
54
     * The ID of the product that has been created recently.
55
     *
56
     * @var string
57
     */
58
    protected $lastEntityId;
59
60
    /**
61
     * Return's the artefacts for post-processing.
62
     *
63
     * @return array The artefacts
64
     */
65 4
    public function getArtefacts()
66
    {
67 4
        return $this->artefacts;
68
    }
69
70
    /**
71
     * Reset the array with the artefacts to free the memory.
72
     *
73
     * @return void
74
     */
75 1
    protected function resetArtefacts()
76
    {
77 1
        $this->artefacts = array();
78 1
    }
79
80
    /**
81
     * Add the passed product type artefacts to the product with the
82
     * last entity ID.
83
     *
84
     * @param string  $type      The artefact type, e. g. configurable
85
     * @param array   $artefacts The product type artefacts
86
     * @param boolean $override  Whether or not the artefacts for the actual entity ID has to be overwritten
87
     *
88
     * @return void
89
     * @uses \TechDivision\Import\Product\Subjects\BunchSubject::getLastEntityId()
90
     */
91 5 View Code Duplication
    public function addArtefacts($type, array $artefacts, $override = true)
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...
92
    {
93
94
        // query whether or not, any artefacts are available
95 5
        if (sizeof($artefacts) === 0) {
96 1
            return;
97
        }
98
99
        // serialize the original data, if we're in debug mode
100 4
        $keys = array_keys($artefacts);
101 4
        foreach ($keys as $key) {
102 4
            if (isset($artefacts[$key][ColumnKeys::ORIGINAL_DATA])) {
103 2
                $artefacts[$key][ColumnKeys::ORIGINAL_DATA] = $this->isDebugMode() ? serialize($artefacts[$key][ColumnKeys::ORIGINAL_DATA]) : null;
104
            }
105
        }
106
107
        // query whether or not, existing artefacts has to be overwritten
108 4
        if ($override === true) {
109 4
            $this->overrideArtefacts($type, $artefacts);
110
        } else {
111
            $this->appendArtefacts($type, $artefacts);
112
        }
113 4
    }
114
115
    /**
116
     * Add the passed product type artefacts to the product with the
117
     * last entity ID and overrides existing ones with the same key.
118
     *
119
     * @param string $type      The artefact type, e. g. configurable
120
     * @param array  $artefacts The product type artefacts
121
     *
122
     * @return void
123
     */
124 4
    protected function overrideArtefacts($type, array $artefacts)
125
    {
126 4
        foreach ($artefacts as $key => $artefact) {
127 4
            $this->artefacts[$type][$this->getLastEntityId()][$key] = $artefact;
128
        }
129 4
    }
130
131
    /**
132
     * Append's the passed product type artefacts to the product with the
133
     * last entity ID.
134
     *
135
     * @param string $type      The artefact type, e. g. configurable
136
     * @param array  $artefacts The product type artefacts
137
     *
138
     * @return void
139
     */
140
    protected function appendArtefacts($type, array $artefacts)
141
    {
142
        foreach ($artefacts as $artefact) {
143
            $this->artefacts[$type][$this->getLastEntityId()][] = $artefact;
144
        }
145
    }
146
147
    /**
148
     * Return the artefacts for the passed type and entity ID.
149
     *
150
     * @param string $type     The artefact type, e. g. configurable
151
     * @param string $entityId The entity ID to return the artefacts for
152
     *
153
     * @return array The array with the artefacts
154
     * @throws \Exception Is thrown, if no artefacts are available
155
     */
156 2
    public function getArtefactsByTypeAndEntityId($type, $entityId)
157
    {
158
159
        // query whether or not, artefacts for the passed params are available
160 2
        if (isset($this->artefacts[$type][$entityId])) {
161
            // load the artefacts
162 1
            $artefacts = $this->artefacts[$type][$entityId];
163
164
            // unserialize the original data, if we're in debug mode
165 1
            $keys = array_keys($artefacts);
166 1
            foreach ($keys as $key) {
167 1
                if (isset($artefacts[$key][ColumnKeys::ORIGINAL_DATA])) {
168
                    $artefacts[$key][ColumnKeys::ORIGINAL_DATA] = $this->isDebugMode() ? unserialize($artefacts[$key][ColumnKeys::ORIGINAL_DATA]) : null;
169
                }
170
            }
171
172
            // return the artefacts
173 1
            return $artefacts;
174
        }
175
176
        // throw an exception if not
177 1
        throw new \Exception(
178 1
            sprintf(
179 1
                'Cant\'t load artefacts for type %s and entity ID %d',
180 1
                $type,
181 1
                $entityId
182
            )
183
        );
184
    }
185
186
    /**
187
     * Queries whether or not artefacts for the passed type and entity ID are available.
188
     *
189
     * @param string $type     The artefact type, e. g. configurable
190
     * @param string $entityId The entity ID to return the artefacts for
191
     *
192
     * @return boolean TRUE if artefacts are available, else FALSE
193
     */
194
    public function hasArtefactsByTypeAndEntityId($type, $entityId)
195
    {
196
        return isset($this->artefacts[$type][$entityId]);
197
    }
198
199
    /**
200
     * Create's and return's a new empty artefact entity.
201
     *
202
     * @param array $columns             The array with the column data
203
     * @param array $originalColumnNames The array with a mapping from the old to the new column names
204
     *
205
     * @return array The new artefact entity
206
     */
207 1
    public function newArtefact(array $columns, array $originalColumnNames = array())
208
    {
209
210
        // initialize the original data and the artefact
211 1
        $artefact = array();
212 1
        $originalData = array();
213
214
        // query whether or not, we've original columns
215 1
        if (sizeof($originalColumnNames) > 0) {
216
            // prepare the original column data
217 1
            $originalData[ColumnKeys::ORIGINAL_FILENAME] = $this->getFilename();
0 ignored issues
show
Bug introduced by
It seems like getFilename() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
218 1
            $originalData[ColumnKeys::ORIGINAL_LINE_NUMBER] = $this->getLineNumber();
0 ignored issues
show
Bug introduced by
It seems like getLineNumber() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
219 1
            $originalData[ColumnKeys::ORIGINAL_COLUMN_NAMES] =  $originalColumnNames;
220
221
            // add the original column data to the new artefact
222 1
            $artefact = array(ColumnKeys::ORIGINAL_DATA => $originalData);
223
        }
224
225
        // merge the columns into the artefact entity and return it
226 1
        return array_merge($artefact, $columns);
227
    }
228
229
    /**
230
     * Export's the artefacts to CSV files and resets the array with the artefacts to free the memory.
231
     *
232
     * @param integer $timestamp The timestamp part of the original import file
233
     * @param string  $counter   The counter part of the origin import file
234
     *
235
     * @return void
236
     */
237 1 View Code Duplication
    public function export($timestamp, $counter)
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...
238
    {
239
240
        // export the artefacts
241 1
        $this->getExportAdapter()->export($this->getArtefacts(), $this->getTargetDir(), $timestamp, $counter);
0 ignored issues
show
Bug introduced by
It seems like getTargetDir() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
242
243
        // initialize the array with the status
244 1
        $status = array();
245
246
        // add the exported artefacts to the status
247 1
        foreach ($this->getExportAdapter()->getExportedFilenames() as $filename) {
248
            $status[$filename] = array();
249
        }
250
251
        // merge the status
252 1
        $this->mergeStatus(
253
            array(
254
                RegistryKeys::STATUS => array(
255 1
                    RegistryKeys::FILES => $status
256
                )
257
            )
258
        );
259
260
        // reset the artefacts
261 1
        $this->resetArtefacts();
262 1
    }
263
264
    /**
265
     * Set's the exporter adapter instance.
266
     *
267
     * @param \TechDivision\Import\Adapter\ExportAdapterInterface $exportAdapter The exporter adapter instance
268
     *
269
     * @return void
270
     */
271 2
    public function setExportAdapter(ExportAdapterInterface $exportAdapter)
272
    {
273 2
        $this->exportAdapter = $exportAdapter;
274 2
    }
275
276
    /**
277
     * Return's the exporter adapter instance.
278
     *
279
     * @return \TechDivision\Import\Adapter\ExportAdapterInterface The exporter adapter instance
280
     */
281 2
    public function getExportAdapter()
282
    {
283 2
        return $this->exportAdapter;
284
    }
285
286
    /**
287
     * Set's the ID of the product that has been created recently.
288
     *
289
     * @param string $lastEntityId The entity ID
290
     *
291
     * @return void
292
     */
293 4
    public function setLastEntityId($lastEntityId)
294
    {
295 4
        $this->lastEntityId = $lastEntityId;
296 4
    }
297
298
    /**
299
     * Return's the ID of the product that has been created recently.
300
     *
301
     * @return string The entity Id
302
     */
303 4
    public function getLastEntityId()
304
    {
305 4
        return $this->lastEntityId;
306
    }
307
308
    /**
309
     * Queries whether or not debug mode is enabled or not, default is TRUE.
310
     *
311
     * @return boolean TRUE if debug mode is enabled, else FALSE
312
     */
313
    abstract public function isDebugMode();
314
315
    /**
316
     * Merge's the passed status into the actual one.
317
     *
318
     * @param array $status The status to MergeBuilder
319
     *
320
     * @return void
321
     */
322
    abstract public function mergeStatus(array $status);
323
}
324