AddonsController::Addons()   F
last analyzed

Complexity

Conditions 19
Paths 600

Size

Total Lines 91
Code Lines 60

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 91
rs 2.3386
c 0
b 0
f 0
cc 19
eloc 60
nc 600
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
        if (!in_array($sort, array('name', 'downloads', 'newest', 'relative'))) {
106
            $sort = null;
107
        }
108
109
        // Proxy out a search to elastic if any parameters are set.
110
        if ($search || $type || $compat || $tags) {
111
            $bool = new Query\BoolQuery();
112
113
            $query = new Query();
114
            $query->setQuery($bool);
115
            $query->setSize(count($list));
116
117
            if ($search) {
118
                $match = new Match();
119
                $match->setField('_all', $search);
120
121
                $bool->addMust($match);
122
            }
123
124
            if ($type) {
125
                $bool->addMust(new Query\Term(array('type' => $type)));
126
            }
127
128
            if ($compat) {
129
                $bool->addMust(new Query\Terms('compatibility', (array)$compat));
130
            }
131
132
            if ($tags) {
133
                $bool->addMust(new Query\Terms('tags', (array)$tags));
134
            }
135
136
            $list = new ResultList($this->elastica->getIndex(), $query);
137
138
            if ($sort) {
139
                $ids = $list->column('ID');
140
141
                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...
142
                    $list = Addon::get()->byIDs($ids);
143
                } else {
144
                    $list = new ArrayList();
145
                }
146
            } else {
147
                $list = $list->toArrayList();
148
            }
149
        } else {
150
            if (!$sort) {
151
                $sort = 'relative';
152
            }
153
        }
154
155
        switch ($sort) {
156
            case 'name':
157
                $list = $list->sort('Name');
158
                break;
159
            case 'newest':
160
                $list = $list->sort('Released', 'DESC');
161
                break;
162
            case 'downloads':
163
                $list = $list->sort('Downloads', 'DESC');
164
                break;
165
            case 'relative':
166
                if (!$list instanceof ArrayList) {
167
                    /** @var ArrayList|Addon[] $unsorted */
168
                    $unsorted = ArrayList::create($list->toArray());
169
                } else {
170
                    $unsorted = $list;
171
                }
172
                foreach ($unsorted as $item) {
173
                    $item->Score = $item->relativePopularityFormatted() . ' per day';
174
                }
175
                $list = $unsorted->sort('relativePopularity DESC');
176
                break;
177
            default:
178
                $list = $list->sort('Downloads', 'DESC');
179
        }
180
181
        $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...
182
        $list->setPageLength(16);
183
184
        return $list;
185
    }
186
187
    public function AddonsSearchForm()
188
    {
189
        $form = new Form(
190
            $this,
191
            'AddonsSearchForm',
192
            new FieldList(array(
193
                TextField::create('search', 'Search for')
194
                    ->setValue($this->request->getVar('search'))
195
                    ->addExtraClass('input-block-level'),
196
                DropdownField::create('sort', 'Sort by')
197
                    ->setSource(array(
198
                        'name'      => 'Name',
199
                        'downloads' => 'Most downloaded',
200
                        'relative'  => 'Average downloads per day',
201
                        'newest'    => 'Newest'
202
                    ))
203
                    ->setEmptyString('Best match')
204
                    ->setValue($this->request->getVar('sort'))
205
                    ->addExtraClass('input-block-level'),
206
                DropdownField::create('type', 'Add-on type')
207
                    ->setSource(array(
208
                        'module' => 'Modules',
209
                        'theme'  => 'Themes'
210
                    ))
211
                    ->setEmptyString('Modules and themes')
212
                    ->setValue($this->request->getVar('type'))
213
                    ->addExtraClass('input-block-level'),
214
                CheckboxSetField::create('compatibility', 'Compatible SilverStripe versions')
215
                    ->setSource(SilverStripeVersion::get()->map('Name', 'Name'))
216
                    ->setValue($this->request->getVar('compatibility'))
217
                    ->setTemplate('AddonsSearchCheckboxSetField')
218
            )),
219
            new FieldList()
220
        );
221
222
        return $form
223
            ->setFormMethod('GET')
224
            ->setFormAction($this->Link());
225
    }
226
227
    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...
228
    {
229
        $addons = Addon::get()
230
            ->sort('Released', 'DESC')
231
            ->limit($limit);
232
233
        $rss = new RSSFeed(
234
            $addons,
235
            $this->Link(),
236
            "Newest addons on addons.silverstripe.org",
237
            null,
238
            'RSSTitle'
239
        );
240
241
        return $rss->outputToBrowser();
242
    }
243
}
244