Subversion Repositories oidplus

Rev

Rev 1050 | Rev 1116 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
635 daniel-mar 1
<?php
2
 
3
/*
4
 * OIDplus 2.0
1086 daniel-mar 5
 * Copyright 2019 - 2023 Daniel Marschall, ViaThinkSoft
635 daniel-mar 6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
 
1050 daniel-mar 20
namespace ViaThinkSoft\OIDplus;
635 daniel-mar 21
 
1086 daniel-mar 22
// phpcs:disable PSR1.Files.SideEffects
23
\defined('INSIDE_OIDPLUS') or die;
24
// phpcs:enable PSR1.Files.SideEffects
25
 
635 daniel-mar 26
class OIDplusPagePublicSearch extends OIDplusPagePluginPublic {
27
 
28
        public function init($html=true) {
29
                OIDplus::config()->prepareConfigKey('search_min_term_length', 'Minimum length of a search term', '3', OIDplusConfig::PROTECTION_EDITABLE, function($value) {
30
                        if (!is_numeric($value) || ($value < 0)) {
31
                                throw new OIDplusException(_L('Please enter a valid value.'));
32
                        }
33
                });
34
        }
35
 
36
        private function prepareSearchParams(&$params, $is_searching) {
37
                $params['term'] = isset($params['term']) ? trim($params['term']) : '';
38
                $params['namespace'] = isset($params['namespace']) ? trim($params['namespace']) : '';
39
 
40
                // Default criteria selection:
41
                if ($is_searching) {
42
                        $params['search_title'] = isset($params['search_title']) && $params['search_title'];
43
                        $params['search_description'] = isset($params['search_description']) && $params['search_description'];
44
                        $params['search_asn1id'] = isset($params['search_asn1id']) && $params['search_asn1id'];
45
                        $params['search_iri'] = isset($params['search_iri']) && $params['search_iri'];
46
                } else {
47
                        $params['search_title'] = true;
48
                        $params['search_description'] = false;
49
                        $params['search_asn1id'] = true;
50
                        $params['search_iri'] = true;
51
                }
52
        }
53
 
704 daniel-mar 54
        private function highlight_match($html, $term) {
55
                return str_replace(htmlentities($term), '<font color="red">'.htmlentities($term).'</font>', $html);
56
        }
57
 
635 daniel-mar 58
        private function doSearch($params) {
59
                $output = '';
60
 
61
                // Note: The SQL collation defines if search is case sensitive or case insensitive
62
 
63
                $min_length = OIDplus::config()->getValue('search_min_term_length');
64
 
65
                $this->prepareSearchParams($params, true);
66
 
67
                if (strlen($params['term']) == 0) {
68
                        $output .= '<p><font color="red">'._L('Error: You must enter a search term.').'</font></p>';
69
                } else if (strlen($params['term']) < $min_length) {
70
                        $output .= '<p><font color="red">'._L('Error: Search term minimum length is %1 characters.',$min_length).'</font></p>';
71
                } else {
72
                        // TODO: case insensitive comparison (or should we leave that to the DBMS?)
73
 
74
                        if ($params['namespace'] == 'oidplus:ra') {
704 daniel-mar 75
                                $output .= '<h2>'._L('Search results for RA %1','<font color="red">'.htmlentities($params['term']).'</font>').'</h2>';
635 daniel-mar 76
 
77
                                $sql_where = array(); $prep_where = array();
78
                                $sql_where[] = "email like ?";   $prep_where[] = '%'.$params['term'].'%';
79
                                $sql_where[] = "ra_name like ?"; $prep_where[] = '%'.$params['term'].'%';
80
 
81
                                if (count($sql_where) == 0) $sql_where[] = '1=0';
82
                                $res = OIDplus::db()->query("select * from ###ra where (".implode(' or ', $sql_where).")", $prep_where);
83
 
84
                                $count = 0;
85
                                while ($row = $res->fetch_object()) {
86
                                        $email = str_replace('@', '&', $row->email);
704 daniel-mar 87
                                        $output .= '<p><a '.OIDplus::gui()->link('oidplus:rainfo$'.str_replace('@','&',$email)).'>'.$this->highlight_match(htmlentities($email),$params['term']).'</a>: <b>'.$this->highlight_match(htmlentities($row->ra_name),$params['term']).'</b></p>';
635 daniel-mar 88
                                        $count++;
89
                                }
90
                                if ($count == 0) {
91
                                        $output .= '<p>'._L('Nothing found').'</p>';
92
                                }
93
                        } else {
704 daniel-mar 94
                                $output .= '<h2>'._L('Search results for %1 (%2)','<font color="red">'.htmlentities($params['term']).'</font>',htmlentities($params['namespace'])).'</h2>';
635 daniel-mar 95
 
96
                                $sql_where = array(); $prep_where = array();
97
                                $sql_where[] = "id like ?"; $prep_where[] = '%'.$params['term'].'%'; // TODO: should we rather do findFitting(), so we can e.g. find GUIDs with different notation?
98
                                if ($params["search_title"])       { $sql_where[] = "title like ?";       $prep_where[] = '%'.$params['term'].'%'; }
99
                                if ($params["search_description"]) { $sql_where[] = "description like ?"; $prep_where[] = '%'.$params['term'].'%'; }
100
 
101
                                if ($params["search_asn1id"]) {
102
                                        $res = OIDplus::db()->query("select * from ###asn1id where name like ?", array('%'.$params['term'].'%'));
103
                                        while ($row = $res->fetch_object()) {
104
                                                $sql_where[] = "id = ?"; $prep_where[] = $row->oid;
105
                                        }
106
                                }
107
 
108
                                if ($params["search_iri"]) {
109
                                        $res = OIDplus::db()->query("select * from ###iri where name like ?", array('%'.$params['term'].'%'));
110
                                        while ($row = $res->fetch_object()) {
111
                                                $sql_where[] = "id = ?"; $prep_where[] = $row->oid;
112
                                        }
113
                                }
114
 
115
                                if (count($sql_where) == 0) $sql_where[] = '1=0';
116
                                array_unshift($prep_where, $params['namespace'].':%');
117
 
118
                                $res = OIDplus::db()->query("select * from ###objects where id like ? and (".implode(' or ', $sql_where).")", $prep_where);
119
 
120
                                $count = 0;
121
                                while ($row = $res->fetch_object()) {
704 daniel-mar 122
                                        $output .= '<p><a '.OIDplus::gui()->link($row->id).'>'.$this->highlight_match(htmlentities($row->id),$params['term']).'</a>';
635 daniel-mar 123
 
124
                                        $asn1ids = array();
125
                                        $res2 = OIDplus::db()->query("select name from ###asn1id where oid = ?", array($row->id));
126
                                        while ($row2 = $res2->fetch_object()) {
127
                                                $asn1ids[] = $row2->name;
128
                                        }
129
                                        if (count($asn1ids) > 0) {
130
                                                $asn1ids = implode(', ', $asn1ids);
704 daniel-mar 131
                                                $output .= ' ('.$this->highlight_match(htmlentities($asn1ids),$params['term']).')';
635 daniel-mar 132
                                        }
133
 
704 daniel-mar 134
                                        if (htmlentities($row->title) != '') $output .= ': <b>'.$this->highlight_match(htmlentities($row->title),$params['term']).'</b></p>';
635 daniel-mar 135
                                        $count++;
136
                                }
137
                                if ($count == 0) {
138
                                        $output .= '<p>'._L('Nothing found').'</p>';
139
                                }
140
                        }
141
                }
142
 
143
                return $output;
144
        }
145
 
146
        public function action($actionID, $params) {
147
 
148
                if ($actionID == 'search') {
149
                        // Search with JavaScript/AJAX
150
                        $ret = $this->doSearch($params);
151
                        return array("status" => 0, "output" => $ret);
152
                }
153
 
154
        }
155
 
156
        public function gui($id, &$out, &$handled) {
157
                if (explode('$',$id)[0] == 'oidplus:search') {
158
                        $handled = true;
159
 
160
                        $out['title'] = _L('Search');
801 daniel-mar 161
                        $out['icon'] = file_exists(__DIR__.'/img/main_icon.png') ? OIDplus::webpath(__DIR__,OIDplus::PATH_RELATIVE).'img/main_icon.png' : '';
635 daniel-mar 162
 
163
                        $out['text'] = '';
164
 
165
                        try {
166
                                $params = $_POST;
167
 
168
                                $this->prepareSearchParams($params, isset($params['search']));
169
 
962 daniel-mar 170
                                $out['text'] .= '<form id="searchForm" action="?goto=oidplus%3Asearch" method="POST">
635 daniel-mar 171
                                                 <input type="hidden" name="search" value="1">
172
                                                 '._L('Search for').': <input type="text" id="term" name="term" value="'.htmlentities($params['term']).'"><br><br>
173
                                                 <script>
174
                                                 function searchNsSelect(ns) {
175
                                                     $("#search_options_oid")[0].style.display = (ns == "oid") ? "block" : "none";
176
                                                     $("#search_options_object")[0].style.display = (ns == "oidplus:ra") ? "none" : "block";
177
                                                     $("#search_options_ra")[0].style.display = (ns == "oidplus:ra") ? "block" : "none";
178
                                                 }
179
                                                 $( document ).ready(function() {
180
                                                     searchNsSelect($("#namespace")[0].value);
181
                                                 });
182
                                                 </script>
183
                                                 '._L('Search in').': <select name="namespace" id="namespace" onchange="searchNsSelect(this.value);"><br><br>';
184
 
185
                                foreach (OIDplus::getEnabledObjectTypes() as $ot) {
186
                                        $out['text'] .= '<option value="'.htmlentities($ot::ns()).'"'.(($params['namespace'] == $ot::ns()) ? ' selected' : '').'>'.htmlentities($ot::objectTypeTitle()).'</option>';
187
                                }
188
                                $out['text'] .= '<option value="oidplus:ra"'.(($params['namespace'] == 'oidplus:ra') ? ' selected' : '').'>'._L('Registration Authority').'</option>
189
                                                 </select><br><br>
190
                                <div id="search_options_ra">
191
                                <!-- TODO: RA specific selection criterias -->
192
                                </div>
193
                                <div id="search_options_object">
194
                                            <input type="checkbox" name="search_title" id="search_title" value="1"'.($params["search_title"] ? ' checked' : '').'> <label for="search_title">'._L('Search in field "Title"').'</label><br>
195
                                            <input type="checkbox" name="search_description" id="search_description" value="1"'.($params["search_description"] ? ' checked' : '').'> <label for="search_description">'._L('Search in field "Description"').'</label><br>
196
                                <div id="search_options_oid">
197
                                    <input type="checkbox" name="search_asn1id" id="search_asn1id" value="1"'.($params["search_asn1id"] ? ' checked' : '').'> <label for="search_asn1id">'._L('Search in field "ASN.1 identifier" (only OIDs)').'</label><br>
198
                                    <input type="checkbox" name="search_iri" id="search_iri" value="1"'.($params["search_iri"] ? ' checked' : '').'> <label for="search_iri">'._L('Search in field "Unicode label" (only OIDs)').'</label><br>
199
                                </div>
200
                                </div>
201
                                 <br>
202
 
203
                                <input type="submit" value="'._L('Search').'" onclick="return OIDplusPagePublicSearch.search_button_click()">
204
                                </form>';
205
 
206
                                $out['text'] .= '<div id="search_output">'; // will be filled with either AJAX or staticly (HTML form submit)
207
                                if (isset($params['search'])) {
208
                                        // Search with NoJS/HTML
209
                                        $out['text'] .= $this->doSearch($params);
210
                                }
211
                                $out['text'] .= '</div>';
1050 daniel-mar 212
                        } catch (\Exception $e) {
635 daniel-mar 213
                                $out['text'] = _L('Error: %1',$e->getMessage());
214
                        }
215
                }
216
        }
217
 
218
        public function publicSitemap(&$out) {
219
                $out[] = 'oidplus:search';
220
        }
221
 
222
        public function tree(&$json, $ra_email=null, $nonjs=false, $req_goto='') {
800 daniel-mar 223
                if (file_exists(__DIR__.'/img/main_icon16.png')) {
801 daniel-mar 224
                        $tree_icon = OIDplus::webpath(__DIR__,OIDplus::PATH_RELATIVE).'img/main_icon16.png';
635 daniel-mar 225
                } else {
226
                        $tree_icon = null; // default icon (folder)
227
                }
228
 
229
                $json[] = array(
230
                        'id' => 'oidplus:search',
231
                        'icon' => $tree_icon,
232
                        'text' => _L('Search')
233
                );
234
 
235
                return true;
236
        }
237
 
238
        public function tree_search($request) {
239
                return false;
240
        }
241
}