Completed
Pull Request — 2.0 (#506)
by Roman
18:39
created

ShopPeriodReport::query()   C

Complexity

Conditions 14
Paths 64

Size

Total Lines 50
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 39
CRAP Score 14.0713

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 50
ccs 39
cts 42
cp 0.9286
rs 5.3716
cc 14
eloc 36
nc 64
nop 1
crap 14.0713

How to fix   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
2
3
/**
4
 * Base class for creating reports that can be filtered to a specific range.
5
 * Record grouping is also supported.
6
 */
7
class ShopPeriodReport extends SS_Report implements i18nEntityProvider
8
{
9
    private static $display_uncategorised_data = false;
10
11
    protected      $dataClass                  = 'Order';
12
13
    protected      $periodfield                = "\"Order\".\"Created\"";
14
15
    protected      $grouping                   = false;
16
17
    protected      $pagesize                   = 30;
18
19
    private static $groupingdateformats        = array(
20
        "Year"  => "Y",
21
        "Month" => "Y - F",
22
        "Day"   => "d F Y - l",
23
    );
24
25
    public function title()
26
    {
27
        return _t($this->class . ".Title", $this->title);
28
    }
29
30
    public function description()
31
    {
32
        return _t($this->class . ".Description", $this->description);
33
    }
34
35 1
    public function parameterFields()
36
    {
37 1
        $member = Member::currentUserID() ? Member::currentUser() : Member::create();
38 1
        $dateformat = $member->getDateFormat();
39 1
        $fields = FieldList::create(
40 1
            $start = DateField::create("StartPeriod", "Start Date"),
41 1
            $end = DateField::create("EndPeriod", "End Date")
42 1
        );
43 1
        if ($this->grouping) {
44 1
            $fields->push(
45 1
                DropdownField::create(
46 1
                    "Grouping",
47 1
                    "Group By",
48
                    array(
49 1
                        "Year"  => "Year",
50 1
                        "Month" => "Month",
51 1
                        "Day"   => "Day",
52 1
                    ),
53
                    'Month'
54 1
                )
55 1
            );
56 1
            if (self::config()->display_uncategorised_data) {
57
                $fields->push(
58
                    CheckboxField::create("IncludeUncategorised", "Include Uncategorised Data")
59
                        ->setDescription("Display data that doesn't have a date.")
60
                );
61
            }
62 1
        }
63 1
        $start->setConfig("dateformat", $dateformat);
64 1
        $end->setConfig("dateformat", $dateformat);
65 1
        $start->setConfig("showcalendar", true);
66 1
        $end->setConfig("showcalendar", true);
67 1
        return $fields;
68
    }
69
70
    public function canView($member = null)
71
    {
72
        if (get_class($this) == "ShopPeriodReport") {
73
            return false;
74
        }
75
        return parent::canView($member);
76
    }
77
78
    public function getReportField()
79
    {
80
        $field = parent::getReportField();
81
        $config = $field->getConfig();
82
        $columns = $config->getComponentByType("GridFieldDataColumns")
83
            ->getDisplayFields($field);
84
        $config->getComponentByType('GridFieldExportButton')
85
            ->setExportColumns($columns);
86
        return $field;
87
    }
88
89 1
    public function sourceRecords($params)
90
    {
91 1
        isset($params['Grouping']) || $params['Grouping'] = "Month";
92 1
        $list = new SQLQueryList($this->query($params));
93 1
        $grouping = $params['Grouping'];
94 1
        $self = $this;
95 1
        $list->setOutputClosure(
96
            function ($row) use ($grouping, $self) {
97 1
                $row['FilterPeriod'] = $self->formatDateForGrouping($row['FilterPeriod'], $grouping);
98
99 1
                return new $self->dataClass($row);
100
            }
101 1
        );
102
103 1
        return $list;
104
    }
105
106 1
    public function formatDateForGrouping($date, $grouping)
107
    {
108 1
        if (!$date) {
109
            return $date;
110
        }
111 1
        $formats = self::config()->groupingdateformats;
112 1
        $dformat = $formats[$grouping];
113 1
        return date($dformat, strtotime($date));
114
    }
115
116 1
    public function query($params)
0 ignored issues
show
Complexity introduced by
This operation has 250 execution paths which exceeds the configured maximum of 200.

A high number of execution paths generally suggests many nested conditional statements and make the code less readible. This can usually be fixed by splitting the method into several smaller methods.

You can also find more information in the “Code” section of your repository.

Loading history...
117
    {
118
        //convert dates to correct format
119 1
        $fields = $this->parameterFields();
120 1
        $fields->setValues($params);
121 1
        $start = $fields->fieldByName("StartPeriod")->dataValue();
122 1
        $end = $fields->fieldByName("EndPeriod")->dataValue();
123
        //include the entire end day
124 1
        if ($end) {
125 1
            $end = date('Y-m-d', strtotime($end) + 86400);
126 1
        }
127 1
        $filterperiod = $this->periodfield;
128 1
        $query = new ShopReport_Query();
129 1
        $query->setSelect(array("FilterPeriod" => "MIN($filterperiod)"));
130
131 1
        $query->setFrom('"' . $this->dataClass . '"');
132
133 1
        if ($start && $end) {
134 1
            $query->addWhere("$filterperiod BETWEEN '$start' AND '$end'");
135 1
        } elseif ($start) {
136
            $query->addWhere("$filterperiod > '$start'");
137 1
        } elseif ($end) {
138
            $query->addWhere("$filterperiod <= '$end'");
139
        }
140 1
        if ($start || $end || !self::config()->display_uncategorised_data || !isset($params['IncludeUncategorised'])) {
141 1
            $query->addWhere("$filterperiod IS NOT NULL");
142 1
        }
143 1
        if ($this->grouping) {
144 1
            switch ($params['Grouping']) {
145 1
                case "Year":
146 1
                    $query->addGroupBy($this->fd($filterperiod, '%Y'));
147 1
                    break;
148 1
                case "Month":
149 1
                default:
150 1
                    $query->addGroupBy($this->fd($filterperiod, '%Y') . "," . $this->fd($filterperiod, '%m'));
151 1
                    break;
152 1
                case "Day":
0 ignored issues
show
Unused Code introduced by
case 'Day': $query->...iod, '%d')); break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
153 1
                    $query->addGroupBy(
154 1
                        $this->fd($filterperiod, '%Y') . "," . $this->fd($filterperiod, '%m') . "," . $this->fd(
155 1
                            $filterperiod,
156
                            '%d'
157 1
                        )
158 1
                    );
159 1
                    break;
160 1
            }
161 1
        }
162 1
        $query->setOrderBy("\"FilterPeriod\"", "ASC");
163
164 1
        return $query;
165
    }
166
167 1
    protected function fd($date, $format)
168
    {
169 1
        return DB::getConn()->formattedDatetimeClause($date, $format);
0 ignored issues
show
Deprecated Code introduced by
The method DB::getConn() has been deprecated with message: since version 4.0 Use DB::get_conn instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
170
    }
171
172
    /**
173
     * Provide translatable entities for this class and all subclasses
174
     *
175
     * @return array
176
     */
177
    public function provideI18nEntities()
178
    {
179
        return array(
180
            "{$this->class}.Title"       => array(
181
                $this->title,
182
                "Title for the {$this->class} report",
183
            ),
184
            "{$this->class}.Description" => array(
185
                $this->description,
186
                "Description for the {$this->class} report",
187
            ),
188
        );
189
    }
190
}
191
192
class ShopReport_Query extends SQLQuery
0 ignored issues
show
Deprecated Code introduced by
The class SQLQuery has been deprecated with message: since version 4.0

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
193
{
194
    public function canSortBy($fieldName)
195
    {
196
        return true;
197
    }
198
}
199