Passed
Push — master ( 02af32...8da1a0 )
by Nicolaas
03:41
created

SearchAdmin::search()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 2
dl 0
loc 15
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Sunnysideup\SiteWideSearch\Admin;
4
5
use SilverStripe\Admin\LeftAndMain;
6
use SilverStripe\Control\HTTPResponse;
7
use SilverStripe\Core\Injector\Injector;
8
9
use SilverStripe\Core\Environment;
10
use SilverStripe\Forms\CheckboxField;
11
use SilverStripe\Forms\Form;
12
use SilverStripe\Forms\FormAction;
13
use SilverStripe\Forms\HTMLReadonlyField;
14
use SilverStripe\Forms\LiteralField;
15
use SilverStripe\Forms\TextField;
16
use SilverStripe\ORM\ArrayList;
17
use SilverStripe\ORM\DataObject;
18
use SilverStripe\ORM\FieldType\DBField;
19
use SilverStripe\Security\PermissionProvider;
20
use Sunnysideup\SiteWideSearch\Api\SearchApi;
21
22
class SearchAdmin extends LeftAndMain implements PermissionProvider
23
{
24
    protected $listHTML = '';
25
26
    protected $keywords = '';
27
28
    protected $replace = '';
29
30
    protected $applyReplace = false;
31
32
    protected $isQuickSearch = false;
33
34
    protected $searchWholePhrase = false;
35
36
    protected $rawData;
37
38
    private static $url_segment = 'find';
39
40
    private static $menu_title = 'Search';
41
42
    private static $menu_icon_class = 'font-icon-p-search';
43
44
    private static $menu_priority = 99999;
45
46
    private static $required_permission_codes = [
47
        'CMS_ACCESS_SITE_WIDE_SEARCH',
48
    ];
49
50
    public function getEditForm($id = null, $fields = null)
51
    {
52
        $form = parent::getEditForm($id, $fields);
53
54
        // if ($form instanceof HTTPResponse) {
55
        //     return $form;
56
        // }
57
        // $form->Fields()->removeByName('LastVisited');
58
        $form->Fields()->push(
59
            (new TextField('Keywords', 'Keyword(s)', $this->keywords ?? ''))
60
                ->setAttribute('placeholder', 'e.g. agreement')
61
        );
62
        $form->Fields()->push(
63
            (new TextField('ReplaceWith', 'Replace (optional - careful!)', $this->replace ?? ''))
64
                ->setAttribute('placeholder', 'e.g. contract - make sure to also tick checkbox below')
65
        );
66
        $form->Fields()->push(
67
            (new CheckboxField('ApplyReplace', 'Run replace (please make sure to make a backup first!)', $this->applyReplace))
68
                ->setDescription('Check this to replace the searched value set above with its replacement value. Note that searches ignore uppercase / lowercase, but replace actions will only search and replace values with the same upper / lowercase.')
69
        );
70
        $form->Fields()->push(
71
            (new CheckboxField('QuickSearch', 'Search Main Fields Only', $this->isQuickSearch))
72
                ->setDescription('This is faster but only searches a limited number of fields')
73
        );
74
        $form->Fields()->push(
75
            (new CheckboxField('SearchWholePhrase', 'Search exact phrase', $this->searchWholePhrase))
76
                ->setDescription('If ticked, any item will be included that includes the whole phrase (e.g. New Zealand, rather than New OR Zealand)')
77
        );
78
        if (! $this->getRequest()->requestVar('Keywords')) {
79
            $resultsTitle = 'Recently Edited';
80
            $this->listHTML = $this->renderWith(self::class . '_Results');
81
        } else {
82
            $resultsTitle = 'Search Results';
83
        }
84
85
        $form->Fields()->push(
86
            (new HTMLReadonlyField('List', $resultsTitle, DBField::create_field('HTMLText', $this->listHTML)))
87
        );
88
        $form->Fields()->push(
89
            (new LiteralField('Styling', $this->renderWith(self::class . '_Styling')))
90
        );
91
        $form->Actions()->push(
92
            FormAction::create('search', 'Find')
93
                ->addExtraClass('btn-primary')
94
                ->setUseButtonTag(true)
95
        );
96
        $form->addExtraClass('root-form cms-edit-form center fill-height');
97
        // $form->disableSecurityToken();
98
        // $form->setFormMethod('get');
99
100
        return $form;
101
    }
102
103
    public function search(array $data, Form $form): HTTPResponse
104
    {
105
        if (empty($data['Keywords'])) {
106
            $form->sessionMessage('Please enter one or more keywords', 'bad');
107
108
            return $this->redirectBack();
109
        }
110
111
        $request = $this->getRequest();
112
113
        $this->rawData = $data;
114
        $this->listHTML = $this->renderWith(self::class . '_Results');
115
        // Existing or new record?
116
117
        return $this->getResponseNegotiator()->respond($request);
118
    }
119
120
    /**
121
     * Only show first element, as the profile form is limited to editing
122
     * the current member it doesn't make much sense to show the member name
123
     * in the breadcrumbs.
124
     *
125
     * @param bool $unlinked
126
     *
127
     * @return ArrayList
128
     */
129
    public function Breadcrumbs($unlinked = false)
130
    {
131
        $items = parent::Breadcrumbs($unlinked);
132
133
        return new ArrayList([$items[0]]);
134
    }
135
136
    public function SearchResults(): ?ArrayList
137
    {
138
        Environment::increaseTimeLimitTo(300);
139
        Environment::setMemoryLimitMax(-1);
140
        Environment::increaseMemoryLimitTo(-1);
141
        $this->isQuickSearch = ! empty($this->rawData['QuickSearch']);
142
        $this->searchWholePhrase = ! empty($this->rawData['SearchWholePhrase']);
143
        $this->applyReplace = ! empty($this->rawData['ApplyReplace']);
144
        $this->keywords = trim($this->rawData['Keywords'] ?? '');
145
        $this->replace = trim($this->rawData['ReplaceWith'] ?? '');
146
        if ($this->applyReplace) {
147
            Injector::inst()->get(SearchApi::class)
148
                ->setBaseClass(DataObject::class)
149
                ->setIsQuickSearch($this->isQuickSearch)
150
                ->setSearchWholePhrase(true)
151
                ->setWordsAsString($this->keywords)
152
                ->buildCache()
153
                ->doReplacement($this->keywords, $this->replace)
154
            ;
155
            $this->applyReplace = false;
156
        }
157
158
        return Injector::inst()->get(SearchApi::class)
159
            ->setBaseClass(DataObject::class)
160
            ->setIsQuickSearch($this->isQuickSearch)
161
            ->setSearchWholePhrase($this->searchWholePhrase)
162
            ->setWordsAsString($this->keywords)
163
            ->getLinks()
164
        ;
165
    }
166
167
    public function providePermissions()
168
    {
169
        return [
170
            'CMS_ACCESS_SITE_WIDE_SEARCH' => [
171
                'name' => 'Access to Search Website in the CMS',
172
                'category' => _t('SilverStripe\\Security\\Permission.CMS_ACCESS_CATEGORY', 'CMS Access'),
173
                'help' => 'Allow users to search for documents (all documents will also be checked to see if they are allowed to be viewed)',
174
            ],
175
        ];
176
    }
177
}
178