Completed
Push — master ( cd3b2e...50c111 )
by Craig
07:10
created

SearchApi::computeSort()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 9
nc 4
nop 1
dl 0
loc 12
rs 9.2
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the Zikula package.
5
 *
6
 * Copyright Zikula Foundation - http://zikula.org/
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Zikula\SearchModule\Api;
13
14
use Symfony\Component\HttpFoundation\Session\SessionInterface;
15
use Zikula\ExtensionsModule\Api\VariableApi;
16
use Zikula\SearchModule\Api\ApiInterface\SearchApiInterface;
17
use Zikula\SearchModule\Collector\SearchableModuleCollector;
18
use Zikula\SearchModule\Entity\RepositoryInterface\SearchResultRepositoryInterface;
19
use Zikula\SearchModule\Entity\RepositoryInterface\SearchStatRepositoryInterface;
20
use Zikula\SearchModule\Entity\SearchStatEntity;
21
22
class SearchApi implements SearchApiInterface
23
{
24
    /**
25
     * @var VariableApi
26
     */
27
    protected $variableApi;
28
29
    /**
30
     * @var SearchResultRepositoryInterface
31
     */
32
    protected $searchResultRepository;
33
34
    /**
35
     * @var SearchStatRepositoryInterface
36
     */
37
    protected $searchStatRepository;
38
39
    /**
40
     * @var SessionInterface
41
     */
42
    protected $session;
43
44
    /**
45
     * @var SearchableModuleCollector
46
     */
47
    protected $searchableModuleCollector;
48
49
    /**
50
     * SearchApi constructor.
51
     * @param VariableApi $variableApi
52
     * @param SearchResultRepositoryInterface $searchResultRepository
53
     * @param SearchStatRepositoryInterface $searchStatRepository
54
     * @param SessionInterface $session
55
     * @param SearchableModuleCollector $searchableModuleCollector
56
     */
57
    public function __construct(
58
        VariableApi $variableApi,
59
        SearchResultRepositoryInterface $searchResultRepository,
60
        SearchStatRepositoryInterface $searchStatRepository,
61
        SessionInterface $session,
62
        SearchableModuleCollector $searchableModuleCollector
63
    ) {
64
        $this->variableApi = $variableApi;
65
        $this->searchResultRepository = $searchResultRepository;
66
        $this->searchStatRepository = $searchStatRepository;
67
        $this->session = $session;
68
        $this->searchableModuleCollector = $searchableModuleCollector;
69
    }
70
71
    /**
72
     * {@inheritdoc}
73
     */
74
    public function search($q, $firstPage = false, $searchType = 'AND', $searchOrder = 'newest', $limit = -1, $page = 1, array $moduleData = [])
75
    {
76
        $limit = isset($limit) && !empty($limit) ? $limit : $this->variableApi->get('ZikulaSearchModule', 'itemsperpage', 25);
77
        $offset = $limit > 0 ? (($page - 1) * $limit) : 0;
78
79
        // obtain and persist search results from searchableModules
80
        if ($firstPage) {
81
            // Clear current search result for current user - before showing the first page
82
            // Clear also older searches from other users.
83
            $this->searchResultRepository->clearOldResults($this->session->getId());
84
            // convert query string to an *array* of words
85
            $words = ($searchType == 'EXACT') ? [trim($q)] : preg_split('/ /', $q, -1, PREG_SPLIT_NO_EMPTY);
86
            $searchableModules = $this->searchableModuleCollector->getAll();
87
            foreach ($searchableModules as $moduleName => $searchableInstance) {
88
                if (isset($moduleData['active']) && !$moduleData['active']) {
89
                    continue;
90
                }
91
                $moduleFormData = isset($moduleData[$moduleName]) ? $moduleData[$moduleName] : null;
92
                $results = $searchableInstance->getResults($words, $searchType, $moduleFormData);
93
                foreach ($results as $searchResult) {
94
                    $this->searchResultRepository->persist($searchResult);
95
                }
96
            }
97
            $this->searchResultRepository->flush();
98
99
            $resultCount = $this->searchResultRepository->countResults($this->session->getId());
100
            $this->session->set('searchResultCount', $resultCount);
101
        } else {
102
            $resultCount = $this->session->get('searchResultCount');
103
        }
104
105
        $results = $this->searchResultRepository->getResults(['sesid' => $this->session->getId()], $this->computeSort($searchOrder), $limit, $offset);
106
107
        $result = [
108
            'count' => $resultCount,
109
            'results' => $results,
110
        ];
111
        if (isset($searchableInstance)) {
112
            $result['errors'] = $searchableInstance->getErrors();
113
        }
114
115
        return $result;
116
    }
117
118
    /**
119
     * {@inheritdoc}
120
     */
121
    public function log($q = null)
122
    {
123
        if (!isset($q)) {
124
            return;
125
        }
126
127
        $obj = $this->searchStatRepository->findOneBy(['search' => $q]);
128
        if (!$obj) {
129
            $obj = new SearchStatEntity();
130
        }
131
        $obj->incrementCount();
132
        $obj->setSearch($q);
133
        $obj->setDate(new \DateTime('now', new \DateTimeZone('UTC')));
134
        $this->searchStatRepository->persistAndFlush($obj);
135
    }
136
137
    private function computeSort($searchOrder)
138
    {
139
        switch ($searchOrder) {
140
            case 'oldest':
141
                return ['created' => 'ASC'];
142
            case 'newest':
143
                return ['created' => 'DESC'];
144
            case 'alphabetical':
145
            default:
146
                return ['title' => 'ASC'];
147
        }
148
    }
149
}
150