AddonsController::Addons()   F
last analyzed

Complexity

Conditions 20
Paths 700

Size

Total Lines 102

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 102
rs 0.3333
c 0
b 0
f 0
cc 20
nc 700
nop 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
use Elastica\Query;
4
use Elastica\Query\Match;
5
use SilverStripe\Elastica\ElasticaService;
6
use SilverStripe\Elastica\ResultList;
7
8
/**
9
 * Lists and searches add-ons.
10
 */
11
class AddonsController extends SiteController
12
{
13
14
    public static $url_handlers = array(
15
        'rss'             => 'rss',
16
        '$Vendor!/$Name!' => 'addon',
17
        '$Vendor!'        => 'vendor',
18
    );
19
20
    public static $allowed_actions = array(
21
        'index',
22
        'addon',
23
        'vendor',
24
        'rss',
25
    );
26
27
    public static $dependencies = array(
28
        'ElasticaService' => '%$ElasticaService'
29
    );
30
31
    /**
32
     * @var \SilverStripe\Elastica\ElasticaService
33
     */
34
    private $elastica;
35
36
    public function index()
37
    {
38
        return $this->renderWith(array('Addons', 'Page'));
39
    }
40
41
    public function setElasticaService(ElasticaService $elastica)
42
    {
43
        $this->elastica = $elastica;
44
    }
45
46
    public function addon($request)
47
    {
48
        $vendor = $request->param('Vendor');
49
        $name = $request->param('Name');
50
        $addon = Addon::get()->filter('Name', "$vendor/$name")->first();
51
52
        if (!$addon) {
53
            $this->httpError(404);
54
        }
55
56
        return new AddonController($this, $addon);
57
    }
58
59
    public function vendor($request)
60
    {
61
        $name = $request->param('Vendor');
62
        $vendor = AddonVendor::get()->filter('Name', $name)->first();
63
64
        if (!$vendor) {
65
            $this->httpError(404);
66
        }
67
68
        return new VendorController($this, $vendor);
69
    }
70
71
    public function Title()
72
    {
73
        return 'Add-ons';
74
    }
75
76
    public function Link($slug = null)
77
    {
78
        if ($slug) {
79
            return Controller::join_links(Director::baseURL(), 'add-ons', $slug);
80
        } else {
81
            return Controller::join_links(Director::baseURL(), 'add-ons');
82
        }
83
    }
84
85
    public function ListView()
86
    {
87
        $view = $this->request->getVar('view');
88
        if ($view) {
89
            return $view;
90
        } else {
91
            return 'list';
92
        }
93
    }
94
95
    public function Addons()
96
    {
97
        $list = Addon::get();
98
99
        $search = $this->request->getVar('search');
100
        $type = $this->request->getVar('type');
101
        $compat = $this->request->getVar('compatibility');
102
        $tags = $this->request->getVar('tags');
103
        $sort = $this->request->getVar('sort');
104
105
        $useElasticOrderAsDefault = false;
106
107
        if (!in_array($sort, array('name', 'downloads', 'newest', 'relative'))) {
108
            $sort = null;
109
        }
110
111
        // Proxy out a search to elastic if any parameters are set.
112
        if ($search || $type || $compat || $tags) {
113
            $bool = new Query\BoolQuery();
114
115
            $query = new Query();
116
            $query->setQuery($bool);
117
            $query->setSize(count($list));
118
119
            if ($search) {
120
                $match = new Query\MultiMatch();
121
                $match->setQuery($search);
122
                $match->setFields([
123
                    'name^12',
124
                    'description^3',
125
                    'readme',
126
                ]);
127
                $match->setType('phrase_prefix');
128
129
                $bool->addMust($match);
130
                $useElasticOrderAsDefault = true;
131
            }
132
133
            if ($type) {
134
                $bool->addMust(new Query\Term(array('type' => $type)));
135
            }
136
137
            if ($compat) {
138
                $bool->addMust(new Query\Terms('compatibility', (array)$compat));
139
            }
140
141
            if ($tags) {
142
                $bool->addMust(new Query\Terms('tags', (array)$tags));
143
            }
144
145
            $list = new ResultList($this->elastica->getIndex(), $query);
146
147
            if ($sort) {
148
                $ids = $list->column('ID');
149
150
                if ($ids) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $ids of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
151
                    $list = Addon::get()->byIDs($ids);
152
                } else {
153
                    $list = new ArrayList();
154
                }
155
            } else {
156
                $list = $list->toArrayList();
157
            }
158
        } else {
159
            if (!$sort) {
160
                $sort = 'relative';
161
            }
162
        }
163
164
        switch ($sort) {
165
            case 'name':
166
                $list = $list->sort('Name');
167
                break;
168
            case 'newest':
169
                $list = $list->sort('Released', 'DESC');
170
                break;
171
            case 'downloads':
172
                $list = $list->sort('Downloads', 'DESC');
173
                break;
174
            case 'relative':
175
                if (!$list instanceof ArrayList) {
176
                    /** @var ArrayList|Addon[] $unsorted */
177
                    $unsorted = ArrayList::create($list->toArray());
178
                } else {
179
                    $unsorted = $list;
180
                }
181
                foreach ($unsorted as $item) {
182
                    $item->Score = $item->relativePopularityFormatted() . ' per day';
183
                }
184
                $list = $unsorted->sort('relativePopularity DESC');
185
                break;
186
            default:
187
                if (!$useElasticOrderAsDefault) {
188
                    $list = $list->sort('Downloads', 'DESC');
189
                }
190
        }
191
192
        $list = new PaginatedList($list, $this->request);
0 ignored issues
show
Documentation introduced by
$this->request is of type object<SS_HTTPRequest>, but the function expects a array.

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...
193
        $list->setPageLength(16);
194
195
        return $list;
196
    }
197
198
    public function AddonsSearchForm()
199
    {
200
        $form = new Form(
201
            $this,
202
            'AddonsSearchForm',
203
            new FieldList(array(
204
                TextField::create('search', 'Search for')
205
                    ->setValue($this->request->getVar('search'))
206
                    ->addExtraClass('input-block-level'),
207
                DropdownField::create('sort', 'Sort by')
208
                    ->setSource(array(
209
                        'name'      => 'Name',
210
                        'downloads' => 'Most downloaded',
211
                        'relative'  => 'Average downloads per day',
212
                        'newest'    => 'Newest'
213
                    ))
214
                    ->setEmptyString('Best match')
215
                    ->setValue($this->request->getVar('sort'))
216
                    ->addExtraClass('input-block-level'),
217
                DropdownField::create('type', 'Add-on type')
218
                    ->setSource(array(
219
                        'module' => 'Modules',
220
                        'theme'  => 'Themes'
221
                    ))
222
                    ->setEmptyString('Modules and themes')
223
                    ->setValue($this->request->getVar('type'))
224
                    ->addExtraClass('input-block-level'),
225
                CheckboxSetField::create('compatibility', 'Compatible SilverStripe versions')
226
                    ->setSource(SilverStripeVersion::get()->map('Name', 'Name'))
227
                    ->setValue($this->request->getVar('compatibility'))
228
                    ->setTemplate('AddonsSearchCheckboxSetField')
229
            )),
230
            new FieldList()
231
        );
232
233
        return $form
234
            ->setFormMethod('GET')
235
            ->setFormAction($this->Link());
236
    }
237
238
    public function rss($request, $limit = 10)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
239
    {
240
        $addons = Addon::get()
241
            ->sort('Released', 'DESC')
242
            ->limit($limit);
243
244
        $rss = new RSSFeed(
245
            $addons,
246
            $this->Link(),
247
            "Newest addons on addons.silverstripe.org",
248
            null,
249
            'RSSTitle'
250
        );
251
252
        return $rss->outputToBrowser();
253
    }
254
}
255