Completed
Push — master ( 8cd536...c19902 )
by Tim
9s
created

FileMerger::merge()   C

Complexity

Conditions 14
Paths 39

Size

Total Lines 70
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 210

Importance

Changes 0
Metric Value
dl 0
loc 70
ccs 0
cts 40
cp 0
rs 5.6188
c 0
b 0
f 0
cc 14
eloc 29
nc 39
nop 2
crap 210

How to fix   Long Method    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
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 36 and the first side effect is on line 155.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
3
/**
4
 * TechDivision\Import\Cli\FileMerger
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-cli-simple
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Cli;
22
23
/**
24
 * Prototype for a class that merges multiple CSV files.
25
 *
26
 * This class SHOULD only be used for testing purposes, as it reads the content of all files
27
 * into the memory and merges them. This results in huge memory consumption and has to be
28
 * refactored.
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-cli-simple
34
 * @link      http://www.techdivision.com
35
 */
36
class FileMerger
37
{
38
39
    /**
40
     * The columns that has to be ignored when merging the files
41
     *
42
     * @var array
43
     */
44
    protected $ignoreColumns = array(
45
        'base_image',
46
        'base_image_label',
47
        'small_image',
48
        'small_image_label',
49
        'thumbnail_image',
50
        'thumbnail_image_label',
51
        'swatch_image',
52
        'swatch_image_label',
53
        'additional_images',
54
        'additional_image_label'
55
    );
56
57
    /**
58
     * The array with the headers.
59
     *
60
     * @var array
61
     */
62
    protected $headers = array();
63
64
    /**
65
     * The array with the rows.
66
     *
67
     * @var array
68
     */
69
    protected $rows = array();
70
71
    /**
72
     * Initialize the the merger instance.
73
     *
74
     * @param string $srcDir       The source directory
75
     * @param string $destFilename The target filename
76
     *
77
     * @return void
78
     */
79
    public function merge($srcDir, $destFilename)
80
    {
81
82
        // load the CSV files from the source directory
83
        $srcFilenames = glob(sprintf('%s/*.csv', $srcDir));
84
85
        // iterate over all found CSV files
86
        foreach ($srcFilenames as $srcFilename) {
87
            // open the CSV file
88
            if ($fh = fopen($srcFilename, 'r')) {
89
                // log a message
90
                error_log(sprintf('Now open file "%s"', $srcFilename));
91
                // initialize the row counter
92
                $rowCounter = 0;
93
94
                // read the lines
95
                while (($data = fgetcsv($fh, 0, ",")) !== false) {
96
                    // raise the row counter
97
                    $rowCounter++;
98
99
                    // initialize the headers, if we're on the first line
100
                    if ($rowCounter === 1) {
101
                        $this->headers = array_flip($data);
102
                        continue;
103
                    }
104
105
                    // iterate over the headers
106
                    foreach ($this->headers as $headerName => $headerValue) {
107
                        // set a default price of 1, if the column has NO price
108
                        if ($headerName === 'price' && $data[$headerValue] !== '') {
109
                            $data[$headerValue] = 1;
110
                        }
111
112
                        // query whether or not the field has to be ignored
113
                        if (in_array($headerName, $this->ignoreColumns)) {
114
                            $this->rows[$data[$this->headers['sku']]][$data[$this->headers['store_view_code']]][$headerValue] = null;
115
                        } elseif ($data[$headerValue] !== '') {
116
                            $this->rows[$data[$this->headers['sku']]][$data[$this->headers['store_view_code']]][$headerValue] = $data[$headerValue];
117
                        } elseif ($data[$headerValue] === '' && !isset($this->rows[$data[$this->headers['sku']]][$data[$this->headers['store_view_code']]][$headerValue])) {
118
                            $this->rows[$data[$this->headers['sku']]][$data[$this->headers['store_view_code']]][$headerValue] = $data[$headerValue];
119
                        } else {
120
                            // do not override with empty value
121
                        }
122
                    }
123
124
                    // log a message with the number of rows processed
125
                    error_log(sprintf('Successfully processed line "%s", "%d"', $srcFilename, $rowCounter));
126
                }
127
128
                // close the file finally
129
                fclose($fh);
130
            }
131
        }
132
133
        // open the destination file
134
        $fh = fopen(sprintf('%s/%s', $srcDir, $destFilename, 'w'));
135
136
        // write the headers
137
        fputcsv($fh, array_keys($this->headers));
138
139
        // write the rows to the target file
140
        foreach ($this->rows as $skus) {
141
            foreach ($skus as $storeViewCode) {
142
                fputcsv($fh, $storeViewCode);
143
            }
144
        }
145
146
        // close the destination file
147
        fclose($fh);
148
    }
149
}
150
151
// Example how to invoke the file merger:
152
// php -f src/FileMerger.php projects/sample-data/data/products/add-update import-products_20171220-1234_01.csv
153
154
// initialize the source directory
155
$srcDir = __DIR__;
156
157
// query whether or not a source directoy has been passed
158
if (isset($argv[1]) && is_dir($argv[1])) {
159
    $srcDir = $argv[1];
160
} else {
161
    throw new \Exception(sprintf('Please specify a source directory as first argument'));
162
}
163
164
// query whether or not a target filename has been passed
165
if (!isset($argv[2])) {
166
    throw new \Exception(sprintf('Please specify a target filename as second argument'));
167
}
168
169
// intialize the instance and merge the files
170
$merger = new FileMerger();
171
$merger->merge($srcDir, argv[2]);
172