Completed
Push — search ( af3757...7ef0dc )
by Simon
03:28 queued 03:24
created

PageSearch::getCommentSearchResults()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 7
c 0
b 0
f 0
dl 0
loc 11
ccs 0
cts 9
cp 0
rs 10
cc 2
nc 2
nop 2
crap 6
1
<?php
2
/******************************************************************************
3
 * Wikipedia Account Creation Assistance tool                                 *
4
 *                                                                            *
5
 * All code in this file is released into the public domain by the ACC        *
6
 * Development Team. Please see team.json for a list of contributors.         *
7
 ******************************************************************************/
8
9
namespace Waca\Pages;
10
11
use Waca\DataObjects\Request;
12
use Waca\DataObjects\User;
13
use Waca\Exceptions\AccessDeniedException;
14
use Waca\Exceptions\ApplicationLogicException;
15
use Waca\Fragments\RequestListData;
16
use Waca\Helpers\SearchHelpers\RequestSearchHelper;
17
use Waca\Security\SecurityManager;
18
use Waca\SessionAlert;
19
use Waca\Tasks\PagedInternalPageBase;
20
use Waca\WebRequest;
21
22
class PageSearch extends PagedInternalPageBase
23
{
24
    use RequestListData;
25
26
    /**
27
     * Main function for this page, when no specific actions are called.
28
     */
29
    protected function main()
30
    {
31
        $this->setHtmlTitle('Search');
32
33
        $database = $this->getDatabase();
34
        $currentUser = User::getCurrent($database);
35
36
        $this->assign('canSearchByComment', $this->barrierTest('byComment', $currentUser));
37
        $this->assign('canSearchByEmail', $this->barrierTest('byEmail', $currentUser));
38
        $this->assign('canSearchByIp', $this->barrierTest('byIp', $currentUser));
39
        $this->assign('canSearchByName', $this->barrierTest('byName', $currentUser));
40
        $this->assign('canSeeNonConfirmed', $this->barrierTest('allowNonConfirmed', $currentUser));
41
42
        $this->setTemplate('search/main.tpl');
43
44
        // Dual-mode page
45
        if (WebRequest::getString('type') !== null) {
46
            $searchType = WebRequest::getString('type');
47
            $searchTerm = WebRequest::getString('term');
48
49
            $excludeNonConfirmed = true;
50
            if($this->barrierTest('allowNonConfirmed', $currentUser)) {
51
                $excludeNonConfirmed = WebRequest::getBoolean('excludeNonConfirmed');
52
            }
53
54
            $validationError = "";
55
            if (!$this->validateSearchParameters($searchType, $searchTerm, $validationError)) {
56
                SessionAlert::error($validationError, "Search error");
57
58
                $this->assign('term', $searchTerm);
59
                $this->assign('target', $searchType);
60
                $this->assign('excludeNonConfirmed', $excludeNonConfirmed);
61
                $this->assign('hasResultset', false);
62
                return;
63
            }
64
65
            // searchType known to be sane from the validate step above
66
            if (!$this->barrierTest('by' . ucfirst($searchType), User::getCurrent($this->getDatabase()))) {
67
                // only accessible by url munging, don't care about the UX
68
                throw new AccessDeniedException($this->getSecurityManager());
69
            }
70
71
            $requestSearch = RequestSearchHelper::get($database);
72
73
            $this->setSearchHelper($requestSearch);
74
            $this->setupLimits();
75
76
            if ($excludeNonConfirmed) {
77
                $requestSearch->withConfirmedEmail();
78
            }
79
80
            switch ($searchType) {
81
                case 'name':
82
                    $this->getNameSearchResults($requestSearch, $searchTerm);
83
                    break;
84
                case 'email':
85
                    $this->getEmailSearchResults($requestSearch, $searchTerm);
86
                    break;
87
                case 'ip':
88
                    $this->getIpSearchResults($requestSearch, $searchTerm);
89
                    break;
90
                case 'comment':
91
                    $this->getCommentSearchResults($requestSearch, $searchTerm);
92
                    break;
93
            }
94
95
            /** @var Request[] $results */
96
            $results = $requestSearch->getRecordCount($count)->fetch();
97
98
            $this->setupPageData($count, [
99
                'term'                => $searchTerm,
100
                'type'                => $searchType,
101
                'excludeNonConfirmed' => $excludeNonConfirmed,
102
            ]);
103
104
            // deal with results
105
            $this->assign('requests', $this->prepareRequestData($results));
106
            $this->assign('resultCount', count($results));
107
            $this->assign('hasResultset', true);
108
        }
109
        else {
110
            $this->assign('target', 'name');
111
            $this->assign('hasResultset', false);
112
            $this->assign('limit', 50);
113
            $this->assign('excludeNonConfirmed', true);
114
        }
115
    }
116
117
    /**
118
     * Gets search results by name
119
     *
120
     * @param RequestSearchHelper $searchHelper
121
     * @param string              $searchTerm
122
     */
123
    private function getNameSearchResults(RequestSearchHelper $searchHelper, $searchTerm)
124
    {
125
        $padded = '%' . $searchTerm . '%';
126
        $searchHelper->byName($padded);
127
    }
128
129
    /**
130
     * Gets search results by comment
131
     *
132
     * @param RequestSearchHelper $searchHelper
133
     * @param string              $searchTerm
134
     */
135
    private function getCommentSearchResults(RequestSearchHelper $searchHelper, $searchTerm)
136
    {
137
        $padded = '%' . $searchTerm . '%';
138
        $searchHelper->byComment($padded);
139
140
        $securityManager = $this->getSecurityManager();
141
        $currentUser = User::getCurrent($this->getDatabase());
142
        $securityResult = $securityManager->allows('RequestData', 'seeRestrictedComments', $currentUser);
143
144
        if ($securityResult !== SecurityManager::ALLOWED) {
145
            $searchHelper->byCommentSecurity(['requester', 'user']);
146
        }
147
    }
148
149
    /**
150
     * Gets search results by email
151
     *
152
     * @param        $searchHelper
153
     * @param string $searchTerm
154
     *
155
     * @throws ApplicationLogicException
156
     */
157
    private function getEmailSearchResults(RequestSearchHelper $searchHelper, $searchTerm)
158
    {
159
        if ($searchTerm === "@") {
160
            throw new ApplicationLogicException('The search term "@" is not valid for email address searches!');
161
        }
162
163
        $padded = '%' . $searchTerm . '%';
164
165
        $searchHelper->byEmailAddress($padded)->excludingPurgedData($this->getSiteConfiguration());
166
    }
167
168
    /**
169
     * Gets search results by IP address or XFF IP address
170
     *
171
     * @param RequestSearchHelper $searchHelper
172
     * @param string              $searchTerm
173
     */
174
    private function getIpSearchResults(RequestSearchHelper $searchHelper, $searchTerm)
175
    {
176
        $searchHelper
177
            ->byIp($searchTerm)
178
            ->excludingPurgedData($this->getSiteConfiguration());
179
    }
180
181
    /**
182
     * @param string $searchType
183
     * @param string $searchTerm
184
     *
185
     * @param string $errorMessage
186
     *
187
     * @return bool true if parameters are valid
188
     */
189
    protected function validateSearchParameters($searchType, $searchTerm, &$errorMessage)
190
    {
191
        if (!in_array($searchType, array('name', 'email', 'ip', 'comment'))) {
192
            $errorMessage = 'Unknown search type';
193
194
            return false;
195
        }
196
197
        if ($searchTerm === '%' || $searchTerm === '' || $searchTerm === null) {
198
            $errorMessage = 'No search term specified entered';
199
200
            return false;
201
        }
202
203
        $errorMessage = "";
204
205
        return true;
206
    }
207
}
208