Subversion Repositories oidplus

Rev

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