EcommerceSearchHistoryFormField::Field()   D
last analyzed

Complexity

Conditions 15
Paths 192

Size

Total Lines 105

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 15
nc 192
nop 1
dl 0
loc 105
rs 4.12
c 0
b 0
f 0

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
2
3
class EcommerceSearchHistoryFormField extends LiteralField
4
{
5
    /**
6
     * total number days to search back.
7
     *
8
     * @var int
9
     */
10
    protected $numberOfDays = 100;
11
12
    /**
13
     * how many days ago the data-analysis should end.
14
     *
15
     * @var int
16
     */
17
    protected $endingDaysBack = 0;
18
19
    /**
20
     * minimum number of searches for the data to show up.
21
     *
22
     * @var int
23
     */
24
    protected $minimumCount = 30;
25
26
    /**
27
     * maximum number of searches for the data to show up.
28
     *
29
     * @var int
30
     */
31
    protected $maxRows = 20;
32
33
    /**
34
     *
35
     * @var bool
36
     */
37
    protected $addTitle = true;
38
39
    /**
40
     *
41
     * @var bool
42
     */
43
    protected $addAtoZ = true;
44
45
    /**
46
     * minimum number of searches for the data to show up.
47
     *
48
     * @var bool
49
     */
50
    protected $showMoreLink = false;
51
52
    public function __construct($name, $title = '')
53
    {
54
        return parent::__construct($name, $title);
0 ignored issues
show
Bug introduced by
Constructors do not have meaningful return values, anything that is returned from here is discarded. Are you sure this is correct?
Loading history...
55
    }
56
57
    /**
58
     * @param int
59
     *
60
     * @return EcommerceSearchHistoryFormField
61
     */
62
    public function setNumberOfDays($days)
63
    {
64
        $this->numberOfDays = intval($days);
65
66
        return $this;
67
    }
68
69
    /**
70
     * @param int
71
     *
72
     * @return EcommerceSearchHistoryFormField
73
     */
74
    public function setMinimumCount($count)
75
    {
76
        $this->minimumCount = intval($count);
77
78
        return $this;
79
    }
80
81
    /**
82
     * @param int
83
     *
84
     * @return EcommerceSearchHistoryFormField
85
     */
86
    public function setShowMoreLink($b)
87
    {
88
        $this->showMoreLink = $b;
89
90
        return $this;
91
    }
92
93
    /**
94
     * @param int
95
     *
96
     * @return EcommerceSearchHistoryFormField
97
     */
98
    public function setEndingDaysBack($count)
99
    {
100
        $this->endingDaysBack = intval($count);
101
102
        return $this;
103
    }
104
105
    /**
106
     * @param int
107
     *
108
     * @return EcommerceSearchHistoryFormField
109
     */
110
    public function setMaxRows($number)
111
    {
112
        $this->maxRows = $number;
113
114
        return $this;
115
    }
116
117
    /**
118
     * @param bool
119
     *
120
     * @return EcommerceSearchHistoryFormField
121
     */
122
    public function setAddTitle($b)
123
    {
124
        $this->addTitle = $b;
125
126
        return $this;
127
    }
128
129
    /**
130
     * @param bool
131
     *
132
     * @return EcommerceSearchHistoryFormField
133
     */
134
    public function setAddAtoZ($b)
135
    {
136
        $this->addAtoZ = $b;
137
138
        return $this;
139
    }
140
141
142
    public function FieldHolder($properties = array())
143
    {
144
        return $this->Field($properties);
145
    }
146
147
    public function Field($properties = array())
148
    {
149
        $redirectToPage = DataObject::get_one('ProductGroupSearchPage');
150
        $title = $this->getContent();
151
        $totalNumberOfDaysBack = $this->numberOfDays + $this->endingDaysBack;
152
        $data = DB::query('
153
            SELECT COUNT(ID) myCount, "Title"
154
            FROM "SearchHistory"
155
            WHERE Created > ( NOW() - INTERVAL '.$totalNumberOfDaysBack.' DAY )
156
                AND Created < ( NOW() - INTERVAL '.$this->endingDaysBack." DAY )
157
            GROUP BY \"Title\"
158
            HAVING COUNT(\"ID\") >= $this->minimumCount
159
            ORDER BY myCount DESC
160
            LIMIT ".$this->maxRows."
161
        ");
162
        if (!$this->minimumCount) {
163
            ++$this->minimumCount;
164
        }
165
        $content = '';
166
        $tableContent = '';
167
        if ($title && $this->addTitle) {
168
            $content .= '<h3>'.$title.'</h3>';
169
        }
170
        $content .= '
171
        <div id="SearchHistoryTableForCMS">
172
            <h3>
173
                Search Phrases'
174
                .($this->minimumCount > 1 ? ', entered at least '.$this->minimumCount.' times' : '')
175
                .($this->maxRows < 1000 ? ', limited to '.$this->maxRows.' entries, ' : '')
176
                .' between '.date('j-M-Y', strtotime('-'.$totalNumberOfDaysBack.' days')).' and '.date('j-M-Y', strtotime('-'.$this->endingDaysBack.' days')).'
177
            </h3>';
178
        $count = 0;
179
        if ($data && count($data)) {
180
            $tableContent .= '
181
                <table class="highToLow" style="widht: 100%">';
182
            $list = array();
183
            foreach ($data as $key => $row) {
184
                $count++;
185
                //for the highest count, we work out a max-width
186
                if (!$key) {
187
                    $maxWidth = $row['myCount'];
188
                }
189
                $multipliedWidthInPercentage = floor(($row['myCount'] / $maxWidth) * 100);
0 ignored issues
show
Bug introduced by
The variable $maxWidth does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
190
                $list[$row['myCount'].'-'.$key] = $row['Title'];
191
                $link = $redirectToPage->Link('ProductSearchForm').'?Keyword='.urlencode($row['Title']).'&action_doProductSearchForm=Search';
192
                $debugLink = $link .'&DebugSearch=1';
193
                $tableContent .= '
194
                    <tr>
195
                        <td style="text-align: right; width: 30%; padding: 5px;">
196
                            <a href="'.$link.'">'.$row['Title'].'</a>
197
                        </td>
198
                        <td style="background-color: silver;  padding: 5px; width: 70%;">
199
                            <div style="width: '.$multipliedWidthInPercentage.'%; background-color: #C51162; color: #fff;">'.$row['myCount'].'</div>
200
                        </td>
201
                        <td style="background-color: silver; width: 20px">
202
                            <a href="'.$debugLink.'">☕</a>
203
                        </td>
204
                    </tr>';
205
            }
206
            $tableContent .= '
207
                </table>';
208
            if ($count && $this->addAtoZ) {
209
                asort($list);
210
                $tableContent .= '
211
                    <h3>A - Z</h3>
212
                    <table class="aToz" style="widht: 100%">';
213
                foreach ($list as $key => $title) {
214
                    $link = $redirectToPage->Link('ProductSearchForm').'?Keyword='.urlencode($row['Title']).'&action_doProductSearchForm=Search';
0 ignored issues
show
Bug introduced by
The variable $row seems to be defined by a foreach iteration on line 183. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
215
                    $debugLink = $link .'&DebugSearch=1';
216
                    $array = explode('-', $key);
217
                    $multipliedWidthInPercentage = floor(($array[0] / $maxWidth) * 100);
218
                    $tableContent .= '
219
                        <tr>
220
                            <td style="text-align: right; width: 30%; padding: 5px;">
221
                                <a href="'.$link.'">'.$title.'</a>
222
                            </td>
223
                            <td style="background-color: silver;  padding: 5px; width: 70%">
224
                                <div style="width: '.$multipliedWidthInPercentage.'%; background-color: #004D40; color: #fff;">'.trim($array[0]).'</div>
225
                            </td>
226
                            <td style="background-color: silver; width: 20px">
227
                                <a href="'.$debugLink.'">☕</a>
228
                            </td>
229
                        </tr>';
230
                }
231
                $tableContent .= '
232
                    </table>';
233
            }
234
        }
235
        if ($count === 0) {
236
            //we replace table content here...
237
            $tableContent = '<p class="warning message">No searches found.</p>';
238
        }
239
        $content .= $tableContent;
240
        if ($this->showMoreLink) {
241
            $content .= '
242
            <p>
243
                <a href="/dev/tasks/EcommerceTaskReviewSearches/">Query more resuts</a>
244
            </p>';
245
        } else {
246
        }
247
        $content .= '
248
        </div>';
249
250
        return $content;
251
    }
252
}
253