ImportTaskBasics   A
last analyzed

Complexity

Total Complexity 30

Size/Duplication

Total Lines 216
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 3

Importance

Changes 0
Metric Value
wmc 30
lcom 2
cbo 3
dl 0
loc 216
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getDescription() 0 4 1
A RunFromCode() 0 10 3
B run() 0 29 6
C readFile() 0 52 8
createRecords() 0 1 ?
deleteRecords() 0 1 ?
A outputToScreen() 0 8 1
C Link() 0 13 9
A DebugOutput() 0 15 2
1
<?php
2
3
4
/**
5
 * allows the creation of records from a CSV
6
 * data should be formatted in CSV like this:
7
 *
8
 * NAME (name of )
9
 * COUNTRY - New Zealand
10
 * COUNTRYCODE - e.g. NZ, AU, US
11
 * TYPE (retailler / agent)
12
 * CITY - e.g. Amsterdam
13
 * WEB - e.g. http://www.mysite.co.nz
14
 * EMAIL
15
 * PHONE e.g. +31 33323321
16
 * ADDRESS
17
 *
18
 * you can use ANY fields you like... this is just an example
19
 */
20
21
abstract class ImportTaskBasics extends BuildTask
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
22
{
23
    protected $title = "Extend this class";
24
25
    protected $description = "
26
        Extend this class ...
27
    ";
28
29
    /**
30
     * excluding base folder
31
     *
32
     * e.g. assets/files/mycsv.csv
33
     * @var String
34
     */
35
    protected $fileLocation;
36
37
    /**
38
     * excluding base folder
39
     *
40
     * e.g. assets/files/mycsv.csv
41
     * @var String
42
     */
43
    protected $csvSeparator = ",";
44
45
46
    /**
47
     * @var Boolean
48
     */
49
    protected $enabled = false;
50
51
52
    /**
53
     * @var Boolean
54
     */
55
    protected $debug = true;
56
57
    /**
58
     * @var array
59
     */
60
    protected static $characters_to_replace = array(
61
        '’' => '\''
62
    );
63
64
65
    /**
66
     * the original data from the CVS
67
     * @var Array
68
     */
69
    protected $csv = array();
70
71
    public function getDescription()
72
    {
73
        return $this->description .'<br /> The file to be used is: <strong>'.$this->fileLocation.'</strong>';
74
    }
75
76
    public function RunFromCode($reset, $run)
0 ignored issues
show
Coding Style introduced by
RunFromCode uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
77
    {
78
        if ($reset) {
79
            $_GET["reset"] = 1;
80
        }
81
        if ($run) {
82
            $_GET["run"] = 1;
83
        }
84
        $this->run(null);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a object<SS_HTTPRequest>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
85
    }
86
87
    /**
88
     *
89
     */
90
    public function run($request)
0 ignored issues
show
Coding Style introduced by
run uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
91
    {
92
        increase_time_limit_to(86400);
93
        set_time_limit(86400);
94
        increase_memory_limit_to('1024M');
95
        if (isset($_GET["resetonly"])) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
96
            //do nothing
97
        } else {
98
            $this->readFile();
99
        }
100
101
        if (isset($_GET["reset"]) && $_GET["reset"] == 1) {
102
            $this->deleteRecords();
103
        }
104
105
        if (isset($_GET["run"]) && $_GET["run"] == 1) {
106
            $this->createRecords();
107
        }
108
        $resetLink =  $this->Link(null, false, true);
109
        $runLink =  $this->Link(null, true, false);
110
        $allLink =  $this->Link(null, true, true);
111
        $this->outputToScreen("================================================");
112
        $this->outputToScreen($resetLink);
113
        $this->outputToScreen($runLink);
114
        $this->outputToScreen($allLink);
115
        $this->outputToScreen("================================================");
116
        $this->outputToScreen("================ THE END =======================");
117
        $this->outputToScreen("================================================");
118
    }
119
120
    protected function readFile()
121
    {
122
        $this->outputToScreen("
123
            ================================================
124
            READING FILE ".ini_get('max_execution_time')." seconds available. ".(ini_get('memory_limit'))."MB available
125
            ================================================");
126
        if (!$this->fileLocation) {
127
            $this->outputToScreen("There is no file to import", "deleted");
128
            return;
129
        }
130
        $rowCount = 1;
131
        $rows = array();
132
133
        if (strpos($this->fileLocation, Director::baseFolder()) === false) {
134
            $fileLocation = Director::baseFolder()."/".$this->fileLocation;
135
        } else {
136
            $fileLocation = $this->fileLocation;
137
        }
138
        $this->outputToScreen("reading file <strong>$fileLocation </strong>", "altered");
139
        $replaceFromChars = array_keys($this->Config()->get('characters_to_replace'));
140
        $replaceToChars = array_values($this->Config()->get('characters_to_replace'));
141
142
        if (($handle = fopen($fileLocation, "r")) !== false) {
143
            while (($data = fgetcsv($handle, 100000, $this->csvSeparator)) !== false) {
144
                $cleanArray = array();
145
                foreach ($data as $key => $value) {
146
                    $value = str_replace($replaceFromChars, $replaceToChars, $value);
147
                    $cleanArray[trim($key)] = trim($value);
148
                }
149
                $rows[] = $cleanArray;
150
                $rowCount++;
151
            }
152
            fclose($handle);
153
        }
154
        //$rows = str_getcsv(file_get_contents(, ",", '"');
0 ignored issues
show
Unused Code Comprehensibility introduced by
57% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
155
156
        $header = array_shift($rows);
157
158
        $this->csv = array();
159
        $rowCount = 1;
160
        foreach ($rows as $row) {
161
            if (count($header) != count($row)) {
162
                $this->outputToScreen("I am trying to merge ".implode(", ", $header)." with ".implode(", ", $row)." but the column count does not match!", "deleted");
163
                die("STOPPED");
0 ignored issues
show
Coding Style Compatibility introduced by
The method readFile() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
164
            }
165
            $this->csv[] = array_combine($header, $row);
166
            $rowCount++;
167
        }
168
        $this->outputToScreen("Imported ".count($this->csv)." rows with ".count($header)." cells each");
169
        $this->outputToScreen("Fields are: ".implode(", ", $header));
170
        $this->outputToScreen("================================================");
171
    }
172
173
174
    /**
175
     * created the records
176
     *
177
     */
178
    abstract protected function createRecords();
0 ignored issues
show
Documentation introduced by
For interfaces and abstract methods it is generally a good practice to add a @return annotation even if it is just @return void or @return null, so that implementors know what to do in the overridden method.

For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a @return doc comment to communicate to implementors of these methods what they are expected to return.

Loading history...
179
180
    /**
181
     * delete the records
182
     *
183
     */
184
    abstract protected function deleteRecords();
0 ignored issues
show
Documentation introduced by
For interfaces and abstract methods it is generally a good practice to add a @return annotation even if it is just @return void or @return null, so that implementors know what to do in the overridden method.

For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a @return doc comment to communicate to implementors of these methods what they are expected to return.

Loading history...
185
186
    /**
187
     *
188
     *
189
     * @param  string $message
190
     * @param  string $type
191
     */
192
    protected function outputToScreen($message, $type = "")
193
    {
194
        echo " ";
195
        flush();
196
        ob_end_flush();
197
        DB::alteration_message($message, $type);
198
        ob_start();
199
    }
200
201
    public function Link($action = null, $run = false, $reset = false)
202
    {
203
        $link =
204
            "/dev/tasks/".
205
            $this->class.'/'.
206
            ($action ?$action.'/' : '').
207
            "?run=".($run ? 1 : 0).
208
            "&reset=".($reset ? 1 : 0);
209
        return
210
            '<h3>'.$this->getTitle().': <a href="'.$link.'">'.
211
            ($reset ? 'reset' : '').' '.($reset && $run ? 'AND' : '').' '.($run ? 'run' : '').($action ? ' - '.$action : '').
212
            '</a></h3>';
213
    }
214
215
    /**
216
     *
217
     *
218
     * @param  string $message
219
     * @param  string $type
220
     */
221
    protected function DebugOutput($message, $type = "")
222
    {
223
        if (!$this->debug) {
224
            return;
225
        }
226
        echo " ";
227
        flush();
228
        ob_end_flush();
229
        DB::alteration_message($message, $type);
230
        ob_start();
231
        echo " ";
232
        flush();
233
        ob_end_flush();
234
        ob_start();
235
    }
236
}
237