SearchablePaymentReport::getExportFields()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 8
nc 1
nop 0
1
<?php
2
/**
3
 *
4
 * @package ecommercextras
5
 * @author nicolaas[at]sunnysideup.co.nz
6
 */
7
class SearchablePaymentReport extends PaymentsReport
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...
8
{
9
    protected $title = 'Searchable Payments';
10
11
    protected $description = 'Search all payments';
12
13
    protected static $default_from_time = "11:00 am";
14
    public static function set_default_from_time($v)
15
    {
16
        self::$default_from_time = $v;
17
    }
18
    public static function get_default_from_time()
19
    {
20
        return self::$default_from_time;
21
    }
22
    public static function get_default_from_time_as_full_date_time()
23
    {
24
        return date("Y-m-d", time()) . " " . date("H:i", strtotime(self::get_default_from_time()));
25
    }
26
    protected static $default_until_time = "10:00 pm";
27
    public static function set_default_until_time($v)
28
    {
29
        self::$default_until_time = $v;
30
    }
31
    public static function get_default_until_time()
32
    {
33
        return self::$default_until_time;
34
    }
35
    public static function get_default_until_time_as_full_date_time()
36
    {
37
        return date("Y-m-d", time()) . " " . date("H:i", strtotime(self::get_default_until_time()));
38
    }
39
40
    public function getCMSFields()
41
    {
42
        $fields = parent::getCMSFields();
43
        $stats[] = "Count: ".$this->statistic("count");
0 ignored issues
show
Coding Style Comprehensibility introduced by
$stats was never initialized. Although not strictly required by PHP, it is generally a good practice to add $stats = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
44
        $stats[] = "Sum: ".$this->currencyFormat($this->statistic("sum"));
45
        $stats[] = "Avg: ".$this->currencyFormat($this->statistic("avg"));
46
        $stats[] = "Min: ".$this->currencyFormat($this->statistic("min"));
47
        $stats[] = "Max: ".$this->currencyFormat($this->statistic("max"));
48
        if ($this->statistic("count") > 3) {
49
            $fields->addFieldToTab("Root.Report", new LiteralField("stats", '<h2>Payment Statistics</h2><ul><li>'.implode('</li><li>', $stats).'</li></ul>'));
50
        }
51 View Code Duplication
        if ($humanWhere = Session::get("SearchablePaymentReport.humanWhere")) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
52
            $fields->addFieldToTab("Root.Report", new LiteralField("humanWhere", "<p>Current Search: ".$humanWhere."</p>"), "ReportDescription");
53
            $fields->removeByName("ReportDescription");
54
            $fields->addFieldToTab("Root.Search", new FormAction('clearSearch', 'Clear Search'));
0 ignored issues
show
Documentation introduced by
'clearSearch' is of type string, but the function expects a object<The>.

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...
55
        }
56
        $paymentStatusList = singleton('Payment')->dbObject('Status')->enumValues();
57
        $dropDownValues = array();
58
        foreach ($paymentStatusList as $paymentStatus) {
59
            $dropDownValues[$paymentStatus] = $paymentStatus;
60
        }
61
        $fields->addFieldToTab("Root.Search", new CheckboxSetField("Status", "Payment Status", $dropDownValues));
0 ignored issues
show
Documentation introduced by
'Status' is of type string, but the function expects a object<The>.

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...
62
        $fields->addFieldToTab("Root.Search", new NumericField("OrderID", "Order ID"));
63
        $fields->addFieldToTab("Root.Search", new DateField("From", "From..."));
64
        $fields->addFieldToTab("Root.Search", new DropdownTimeField("FromTime", "Start time...", self::get_default_from_time_as_full_date_time(), "H:i a"));
65
        $fields->addFieldToTab("Root.Search", new DateField("Until", "Until..."));
66
        $fields->addFieldToTab("Root.Search", new DropdownTimeField("UntilTime", "End time...", self::get_default_until_time_as_full_date_time(), "H:i a"));
67
        $fields->addFieldToTab("Root.Search", new NumericField("HasMinimumPayment", "Amout at least..."));
68
        $fields->addFieldToTab("Root.Search", new NumericField("HasMaximumPayment", "Amount no more than ..."));
69
        $fields->addFieldToTab("Root.Search", new FormAction('doSearch', 'Apply Search'));
0 ignored issues
show
Documentation introduced by
'doSearch' is of type string, but the function expects a object<The>.

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...
70
71
        return $fields;
72
    }
73
74
    public function processform()
0 ignored issues
show
Coding Style introduced by
processform uses the super-global variable $_REQUEST 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...
75
    {
76
        $bt = defined('DB::USE_ANSI_SQL') ? "\"" : "`";
0 ignored issues
show
Unused Code introduced by
$bt is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
77
        $where = array();
78
        $having = array();
79
        $humanWhere = array();
80
        foreach ($_REQUEST as $key => $value) {
81
            $value = Convert::raw2sql($value);
82
            if ($value) {
83
                switch ($key) {
84
                    case "OrderID":
85
                        $where[] = ' {$bt}Order{$bt}.{$bt}ID{$bt} = '.intval($value);
86
                        $humanWhere[] = ' OrderID equals '.intval($value);
87
                        break;
88 View Code Duplication
                    case "From":
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
89
                        $d = new Date("date");
90
                        $d->setValue($value);
91
                        $t = new Time("time");
92
                        $cleanTime = trim(preg_replace('/([ap]m)/', "", Convert::raw2sql($_REQUEST["FromTime"])));
93
                        $t->setValue($cleanTime); //
94
                        $exactTime = strtotime($d->format("Y-m-d")." ".$t->Nice24());
95
                        $where[] = ' UNIX_TIMESTAMP({$bt}Payment{$bt}.{$bt}Created{$bt}) >= "'.$exactTime.'"';
96
                        $humanWhere[] = ' Order on or after '.Date("r", $exactTime);//r = Example: Thu, 21 Dec 2000 16:01:07 +0200 // also consider: l jS \of F Y H:i Z(e)
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% 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...
97
                        break;
98 View Code Duplication
                    case "Until":
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
99
                        $d = new Date("date");
100
                        $d->setValue($value);
101
                        $t = new Time("time");
102
                        $cleanTime = trim(preg_replace('/([ap]m)/', "", Convert::raw2sql($_REQUEST["FromTime"])));
103
                        $t->setValue($cleanTime); //
104
                        $exactTime = strtotime($d->format("Y-m-d")." ".$t->Nice24());
105
                        $where[] = ' UNIX_TIMESTAMP({$bt}Payment{$bt}.{$bt}Created{$bt}) <= "'.$exactTime.'"';
106
                        $humanWhere[] = ' Order before or on '.Date("r", $exactTime);//r = Example: Thu, 21 Dec 2000 16:01:07 +0200 // also consider: l jS \of F Y H:i Z(e)
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% 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...
107
108
                        break;
109
                    case "Status":
110
                        $subWhere = array();
111
                        foreach ($value as $item) {
112
                            $subWhere[] = ' {$bt}Payment{$bt}.{$bt}Status{$bt} = "'.$item.'"';
113
                            $humanWhere[] = ' Payment Status equals "'.$item.'"';
114
                        }
115
                        if (count($subWhere)) {
116
                            $where[] = implode(" OR ", $subWhere);
117
                        }
118
                        break;
119 View Code Duplication
                    case "HasMinimumPayment":
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
120
                        $having[] = ' Amount > '.intval($value);
121
                        $humanWhere[] = ' Payment of at least '.$this->currencyFormat($value);
122
                        break;
123 View Code Duplication
                    case "HasMaximumPayment":
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
124
                        $having[] = ' Amount < '.intval($value);
125
                        $humanWhere[] = ' Payment of no more than '.$this->currencyFormat($value);
126
                        break;
127
                    default:
128
                     break;
129
                }
130
            }
131
        }
132
        Session::set("SearchablePaymentReport.having", implode(" AND ", $having));
133
        Session::set("SearchablePaymentReport.where", implode(" AND", $where));
134
        Session::set("SearchablePaymentReport.humanWhere", implode(", ", $humanWhere));
135
        return "ok";
136
    }
137
138
    public function getCustomQuery()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
139
    {
140
        $bt = defined('DB::USE_ANSI_SQL') ? "\"" : "`";
141
            //buildSQL($filter = "", $sort = "", $limit = "", $join = "", $restrictClasses = true, $having = "")
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% 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...
142
        $where = Session::get("SearchablePaymentReport.where");
143
        if (trim($where)) {
144
            $where = " ( $where ) AND ";
145
        }
146
        $where .= " 1 = 1";
147
        $query = singleton('Payment')->buildSQL(
148
            $where,
149
            $sort = "{$bt}Payment{$bt}.{$bt}Created{$bt} DESC",
150
            $limit = "",
151
            $join = " INNER JOIN {$bt}Order{$bt} on {$bt}Order{$bt}.{$bt}ID{$bt} = {$bt}Payment{$bt}.{$bt}OrderID{$bt}"
152
        );
153
        if ($having = Session::get("SearchablePaymentReport.having")) {
154
            $query->having($having);
155
        }
156
        return $query;
157
    }
158
159
160
    public function getReportField()
161
    {
162
        $report = parent::getReportField();
163
        $report->setCustomCsvQuery($this->getExportQuery());
164
        return $report;
165
    }
166
167
168
    public function getExportFields()
169
    {
170
        return array(
171
            "OrderSummary" => "Order Details",
172
            'Amount' => 'Amount',
173
            'Currency' => 'Currency',
174
            'Message' => 'Message',
175
            'IP' => 'Varchar',
176
            'ProxyIP' => 'Varchar'
177
        );
178
    }
179
180
    public function getExportQuery()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
181
    {
182
        $bt = defined('DB::USE_ANSI_SQL') ? "\"" : "`";
183
        //buildSQL($filter = "", $sort = "", $limit = "", $join = "", $restrictClasses = true, $having = "")
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% 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...
184
        $where = Session::get("SearchablePaymentReport.where");
185
        if (trim($where)) {
186
            $where = " ( $where ) AND ";
187
        }
188
        $query = singleton('Payment')->buildSQL(
189
            $where,
190
            $sort = "{$bt}Payment{$bt}.{$bt}Created{$bt} DESC",
191
            $limit = "",
192
            $join = " INNER JOIN {$bt}Order{$bt} on {$bt}Order{$bt}.{$bt}ID{$bt} = {$bt}Payment{$bt}.{$bt}OrderID{$bt}"
193
        );
194
        $fieldArray = $this->getExportFields();
195 View Code Duplication
        if (is_array($fieldArray)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
196
            if (count($fieldArray)) {
197
                foreach ($fieldArray as $key => $field) {
198
                    $query->select[] = $key;
199
                }
200
            }
201
        }
202 View Code Duplication
        foreach ($query->select as $key=>$value) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
203
            if ($value == "OrderSummary") {
204
                $query->select[$key] = "CONCAT({$bt}Order{$bt}.{$bt}ID{$bt}, ' :: ', {$bt}Order{$bt}.{$bt}Created{$bt}, ' :: ', {$bt}Order{$bt}.{$bt}Status{$bt}) AS OrderSummary";
205
            }
206
        }
207
        if ($having = Session::get("SearchableOrderReport.having")) {
208
            $query->having($having);
209
        }
210
        return $query;
211
    }
212
}
213