Completed
Push — master ( 770316...74fc07 )
by Jeroen
09:08 queued 02:44
created

NodeSearchBundle/Services/SearchService.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Kunstmaan\NodeSearchBundle\Services;
4
5
use Elastica\Aggregation\Terms;
6
use Kunstmaan\NodeBundle\Helper\RenderContext;
7
use Kunstmaan\NodeSearchBundle\PagerFanta\Adapter\SearcherRequestAdapter;
8
use Kunstmaan\NodeSearchBundle\Search\AbstractElasticaSearcher;
9
use Pagerfanta\Exception\NotValidCurrentPageException;
10
use Pagerfanta\Pagerfanta;
11
use Symfony\Component\DependencyInjection\Container;
12
use Symfony\Component\DependencyInjection\ContainerInterface;
13
use Symfony\Component\HttpFoundation\Request;
14
use Symfony\Component\HttpFoundation\RequestStack;
15
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
16
17
/**
18
 * Class SearchService
19
 */
20
class SearchService
21
{
22
    /**
23
     * @var RenderContext
24
     */
25
    protected $renderContext;
26
27
    /**
28
     * @var Container
29
     */
30
    protected $container;
31
32
    /**
33
     * @var RequestStack
34
     */
35
    protected $requestStack;
36
37
    /**
38
     * @var int
39
     */
40
    protected $defaultPerPage;
41
42
    /**
43
     * @var array
44
     */
45
    private $searchers;
46
47
    /**
48
     * @param ContainerInterface $container
49
     * @param RequestStack       $requestStack
50
     * @param int                $defaultPerPage
51
     * @param array              $searchers
52
     */
53 2
    public function __construct(ContainerInterface $container, RequestStack $requestStack, $defaultPerPage = 10, array $searchers = [])
54
    {
55 2
        $this->container = $container;
0 ignored issues
show
Documentation Bug introduced by
$container is of type object<Symfony\Component...ion\ContainerInterface>, but the property $container was declared to be of type object<Symfony\Component...ncyInjection\Container>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
56 2
        $this->requestStack = $requestStack;
57 2
        $this->defaultPerPage = $defaultPerPage;
58 2
        $this->renderContext = new RenderContext();
59 2
        $this->searchers = $searchers;
60 2
    }
61
62
    /**
63
     * @param int $defaultPerPage
64
     */
65
    public function setDefaultPerPage($defaultPerPage)
66
    {
67
        $this->defaultPerPage = $defaultPerPage;
68
    }
69
70
    /**
71
     * @return RenderContext
72
     */
73
    public function getRenderContext()
74
    {
75
        return $this->renderContext;
76
    }
77
78
    /**
79
     * @param RenderContext $renderContext
80
     */
81
    public function setRenderContext($renderContext)
82
    {
83
        $this->renderContext = $renderContext;
84
    }
85
86
    /**
87
     * @return int
88
     */
89 1
    public function getDefaultPerPage()
90
    {
91 1
        return $this->defaultPerPage;
92
    }
93
94
    /**
95
     * @return Container
96
     */
97
    public function getContainer()
98
    {
99
        return $this->container;
100
    }
101
102
    /**
103
     * @param Container $container
104
     */
105
    public function setContainer($container)
106
    {
107
        $this->container = $container;
108
    }
109
110
    /**
111
     * @return Request
112
     */
113
    public function getRequest()
114
    {
115
        return $this->requestStack->getCurrentRequest();
116
    }
117
118
    /**
119
     * @return Pagerfanta
120
     */
121 2
    public function search()
122
    {
123 2
        $request = $this->requestStack->getCurrentRequest();
124
125
        // Retrieve the current page number from the URL, if not present of lower than 1, set it to 1
126 2
        $entity = $request->attributes->get('_entity');
127
128 2
        $pageNumber = $this->getRequestedPage($request);
129
130 2
        $searcher = $this->searchers[$entity->getSearcher()] ?? null;
131 2
        if (null === $searcher) {
132 2
            @trigger_error(
133 2
                sprintf(
134 2
                    'Getting the node searcher "%s" from the container is deprecated in KunstmaanNodeSearchBundle 5.2 and will be removed in KunstmaanNodeSearchBundle 6.0. Tag your searcher service with the "kunstmaan_node_search.node_searcher" tag to add a searcher.',
135 2
                    $entity->getSearcher()
136
                ),
137 2
                E_USER_DEPRECATED
138
            );
139
140 2
            $searcher = $this->container->get($entity->getSearcher());
141
        }
142
143 1
        $this->applySearchParams($searcher, $request, $this->renderContext);
144
145 1
        $adapter = new SearcherRequestAdapter($searcher);
146 1
        $pagerfanta = new Pagerfanta($adapter);
147
148
        try {
149
            $pagerfanta
150 1
                ->setMaxPerPage($this->getDefaultPerPage())
151 1
                ->setCurrentPage($pageNumber);
152
        } catch (NotValidCurrentPageException $e) {
153
            throw new NotFoundHttpException();
154
        }
155
156 1
        return $pagerfanta;
157
    }
158
159
    /**
160
     * @param AbstractElasticaSearcher $searcher
161
     * @param Request                  $request
162
     * @param RenderContext            $context
163
     */
164 1
    protected function applySearchParams(AbstractElasticaSearcher $searcher, Request $request, RenderContext $context)
165
    {
166
        // Retrieve the search parameters
167 1
        $queryString = trim($request->query->get('query'));
168 1
        $queryType = $request->query->get('type');
169 1
        $lang = $request->getLocale();
170
171 1
        $context['q_query'] = $queryString;
172 1
        $context['q_type'] = $queryType;
173
174
        $searcher
175 1
            ->setData($this->sanitizeSearchQuery($queryString))
176 1
            ->setContentType($queryType)
177 1
            ->setLanguage($lang);
178
179 1
        $query = $searcher->getQuery();
180
181
        // Aggregations
182 1
        $termsAggregation = new Terms('type');
183 1
        $termsAggregation->setField('type');
184
185 1
        $query->addAggregation($termsAggregation);
186 1
    }
187
188
    /**
189
     * Currently we just search for a complete match...
190
     *
191
     * @param string $query
192
     *
193
     * @return string
194
     */
195 1
    protected function sanitizeSearchQuery($query)
196
    {
197 1
        return '"' . $query . '"';
198
    }
199
200
    /**
201
     * @param Request $request
202
     *
203
     * @return int
204
     */
205 2
    private function getRequestedPage(Request $request)
206
    {
207 2
        $pageNumber = $request->query->getInt('page', 1);
208 2
        if (!$pageNumber || $pageNumber < 1) {
209
            $pageNumber = 1;
210
        }
211
212 2
        return $pageNumber;
213
    }
214
}
215