Issues (3936)

Classes/Controller/AbstractSearchController.php (6 issues)

1
<?php
2
namespace EWW\Dpf\Controller;
3
4
/*
5
 * This file is part of the TYPO3 CMS project.
6
 *
7
 * It is free software; you can redistribute it and/or modify it under
8
 * the terms of the GNU General Public License, either version 2
9
 * of the License, or any later version.
10
 *
11
 * For the full copyright and license information, please read the
12
 * LICENSE.txt file that was distributed with this source code.
13
 *
14
 * The TYPO3 project - inspiring people to share!
15
 */
16
17
use TYPO3\CMS\Core\Utility\GeneralUtility;
18
use EWW\Dpf\Services\ElasticSearch\ElasticSearch;
19
20
/**
21
 * Class AbstractSearchController
22
 * @package EWW\Dpf\Controller
23
 * @deprecated since version 4.0
24
 */
25
abstract class AbstractSearchController extends \EWW\Dpf\Controller\AbstractController
26
{
27
    // search terms
28
    private static $terms   = ['_id', 'OWNER_ID', 'submitter', 'project'];
29
30
    // search matches
31
    private static $matches = ['title', 'abstract', 'author', 'language', 'tag', 'corporation', 'doctype', 'collections'];
32
33
34
    /**
35
     * get results from elastic search
36
     * @param  array $query elasticsearch search query
37
     * @return array        results
38
     */
39
    public function getResultList($query, $type)
40
    {
41
42
        $elasticSearch = $this->objectManager->get(ElasticSearch::class);
43
        $results = $elasticSearch->search($query, $type);
44
45
        return $results;
46
    }
47
48
    /**
49
     * prepare fulltext query
50
     * @param  string $searchString
51
     * @return array query
52
     */
53
    public function searchFulltext($searchString)
54
    {
55
        // don't return query if searchString is empty
56
        if (empty($searchString)) {
57
            return null;
58
        }
59
60
        $searchString = $this->escapeQuery(trim($searchString));
61
62
        $query['body']['query']['bool']['should'][0]['query_string']['query']                       = $searchString;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$query was never initialized. Although not strictly required by PHP, it is generally a good practice to add $query = array(); before regardless.
Loading history...
63
        //$query['body']['query']['bool']['should'][1]['has_child']['query']['query_string']['query'] = $searchString;
64
        $query['body']['query']['bool']['minimum_should_match'] = "1"; // 1
65
66
        // child_type is invalid in elasticsearch 7.5
67
        //$query['body']['query']['bool']['should'][1]['has_child']['type'] = "datastream"; // 1
68
69
        $query = $this->resultsFilter($query, false);
70
71
        return $query;
72
73
    }
74
75
    /**
76
     * build array for elasticsearch
77
     * @return array Elasticsearch query array
78
     */
79
    public function extendedSearch($searchArray = array())
80
    {
81
82
        $query  = array();
83
        $filter = array();
84
        foreach ($searchArray as $key => $qry) {
85
            $qry = trim($qry);
86
87
            if (!empty($qry) && in_array($key, self::$matches)) {
88
89
                $query['body']['query']['bool']['must'][] = array('match' => array($key => $qry));
90
91
            } elseif (!empty($qry) && in_array($key, self::$terms)) {
92
93
                $query['body']['query']['bool']['must'][] = array('term' => array($key => $qry));
94
95
            } elseif (!empty($qry) && $key == 'from') {
96
97
                if ($dateTime = $this->convertFormDate($qry, false)) {
98
                    $filter['gte'] = $dateTime->format('Y-m-d');
99
                }
100
101
            } elseif (!empty($qry) && $key == 'till') {
102
103
                if ($dateTime = $this->convertFormDate($qry, true)) {
104
                    $filter['lte'] = $dateTime->format('Y-m-d');
105
                }
106
107
            }
108
        }
109
110
        if (isset($filter['gte']) || isset($filter['lte'])) {
111
112
            $query['body']['query']['bool']['must'][] = array('range' => array('distribution_date' => $filter));
113
114
        }
115
116
        $showDeleted = ($searchArray['showDeleted'] == 'true') ? true : false;
117
        $query = $this->resultsFilter($query, $showDeleted);
118
        return $query;
119
120
    }
121
122
    /**
123
     * build array for elasticsearch resultfilter
124
     * @param array Elasticsearch query array
125
     * @return array Elasticsearch queryFilter array
126
     */
127
    public function resultsFilter($query, $showDeleted = false)
128
    {
129
130
        $queryFilter = array();
131
132
        // Frontend only
133
        $searchResultsFilter = $this->settings['searchResultsFilter'];
134
        if(!empty($searchResultsFilter)) {
135
136
            // add doctypes
137
            if($searchResultsFilter['doctype']) {
138
139
                $uids = GeneralUtility::trimExplode(',', $searchResultsFilter['doctype']);
140
                $documentTypeRepository = $this->documentTypeRepository;
141
                $documentTypes = array();
142
                foreach($uids as $uid) {
143
                    $documentType = $documentTypeRepository->findByUid($uid);
144
                    $documentTypes[] = $documentType->getName();
145
                };
146
                $searchResultsFilter['doctype'] = implode(',', $documentTypes);
147
            }
148
149
            // add date filter
150
            $dateFilter = array();
151
            if ($searchResultsFilter['from']) {
152
153
                $from     = date('d.m.Y', $searchResultsFilter['from']);
154
                $dateTime = $this->convertFormDate($from, false);
155
                $dateFilter['gte'] = $dateTime->format('Y-m-d');
156
                unset($searchResultsFilter['from']);
157
158
            }
159
160
            if ($searchResultsFilter['till']) {
161
162
                $till          = date('d.m.Y', $searchResultsFilter['till']);
163
                $dateTime = $this->convertFormDate($till, true);
164
                $dateFilter['lte'] = $dateTime->format('Y-m-d');
165
                unset($searchResultsFilter['till']);
166
167
            }
168
169
            if (isset($dateFilter['gte']) || isset($dateFilter['lte'])) {
170
171
                $queryFilter['body']['query']['bool']['must'][] = array('range' => array('distribution_date' => $dateFilter));
172
173
            }
174
175
            foreach ($searchResultsFilter as $key => $qry) {
176
177
                if(!empty($qry)) {
178
                    $queryFilter['body']['query']['bool']['must'][] = array('match' => array($key => $qry));
179
                }
180
181
            }
182
183
        }
184
185
        // document must be active
186
        if($showDeleted == false) {
187
188
            //  $queryFilter['body']['query']['bool']['must'][]['term']['STATE'] = 'A';
189
190
        };
191
192
        // add OWNER_ID if present
193
        $clients = $this->clientRepository->findAll();
194
        if ($clients) {
195
            $client = $clients->getFirst();
196
            if ($client) {
0 ignored issues
show
$client is of type object, thus it always evaluated to true.
Loading history...
197
                //    $queryFilter['body']['query']['bool']['must'][]['term']['OWNER_ID'] = $client->getOwnerId();
198
            }
199
        }
200
201
        $queryFilter = array_merge_recursive($queryFilter, $query);
202
        return $queryFilter;
203
    }
204
205
    /**
206
     * Convert date from form input into DateTime object.
207
     *
208
     * A 4 character string is taken for a year and the returning
209
     * DateTime object is supplemented with either the 01. Jan or 31. Dec
210
     * depending on the $intervalEnd parameter. This allows querying time
211
     * intervals like `2000 to 2003`.
212
     *
213
     * @param  string    $dateString  Date literal from form
214
     * @param  bool      $intervalEnd Fills missing values with the maximum possible date if true
215
     * @return DateTime               Determined date
0 ignored issues
show
The type EWW\Dpf\Controller\DateTime was not found. Did you mean DateTime? If so, make sure to prefix the type with \.
Loading history...
216
     */
217
    public function convertFormDate($dateString, $intervalEnd = false)
218
    {
219
        try {
220
            if (strlen($dateString) == 4) {
221
                // assuming year
222
                $year  = $dateString;
223
                $month = $intervalEnd ? "12" : "01";
224
                $day   = $intervalEnd ? "31" : "01";
225
                return new \DateTime("$year-$month-$day");
0 ignored issues
show
Bug Best Practice introduced by
The expression return new DateTime($year.'-'.$month.'-'.$day) returns the type DateTime which is incompatible with the documented return type EWW\Dpf\Controller\DateTime.
Loading history...
226
            } else {
227
                return new \DateTime($dateString);
0 ignored issues
show
Bug Best Practice introduced by
The expression return new DateTime($dateString) returns the type DateTime which is incompatible with the documented return type EWW\Dpf\Controller\DateTime.
Loading history...
228
            }
229
        } catch (\Exception $_) {
230
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type EWW\Dpf\Controller\DateTime.
Loading history...
231
        }
232
    }
233
234
    /**
235
     * escapes lucene reserved characters from string
236
     * @param $string
237
     * @return mixed
238
     */
239
    private function escapeQuery($string)
240
    {
241
        $luceneReservedCharacters = preg_quote('+-&|!(){}[]^"~?:\\');
242
        $string                   = preg_replace_callback(
243
            '/([' . $luceneReservedCharacters . '])/',
244
            function ($matches) {
245
                return '\\' . $matches[0];
246
            },
247
            $string
248
        );
249
250
        $string = str_replace("/", "\/", $string);
251
252
        return $string;
253
    }
254
255
    /**
256
     * converts a date from dd.mm.yy to yyyy-dd-mm
257
     * @param $date
258
     * @return string
259
     */
260
    public function formatDate($date)
261
    {
262
        // convert date from dd.mm.yyy to yyyy-dd-mm
263
        $date = explode(".", $date);
264
        return $date[2] . '-' . $date[1] . '-' . $date[0];
265
    }
266
}
267