1class PostsQuery { 2 3 // Init the PostQUery with the website url, the API endpoint 4 // and the params of the Query 5 6 constructor() { 7 this._siteUrl = globalThis.origin 8 this._APIRoute = '' 9 this._mode = this.apiParams() 10 11 12 this.URLQuery = '' 13 this.URLArgs = {} 14 this.nextPage = false 15 } 16 17 // Function enlevant les accents d'une chaine 18 pregReplace(array_pattern, array_pattern_replace, my_string) { 19 let new_string = String(my_string); 20 for (let i = 0; i < array_pattern.length; i++) { 21 let reg_exp = RegExp(array_pattern[i], "gi"); 22 let val_to_replace = array_pattern_replace[i]; 23 new_string = new_string.replace(reg_exp, val_to_replace); 24 } 25 return new_string; 26 } 27 28 29 removeAccent(my_string) { 30 let new_string = ""; 31 let pattern_accent = ["é", "è", "ê", "ë", "ç", "à ", "â", "ä", "î", "ï", "ù", "ô", "ó", "ö"]; 32 let pattern_replace_accent = ["e", "e", "e", "e", "c", "a", "a", "a", "i", "i", "u", "o", "o", "o"]; 33 if (my_string && my_string !== "") { 34 new_string = this.pregReplace(pattern_accent, pattern_replace_accent, my_string); 35 } 36 return new_string; 37 } 38 39 fetchArgs(searchedWords) { 40 searchedWords = this.removeAccent(searchedWords) 41 return { 42 bool: { 43 must: [ 44 { 45 multi_match: { 46 query: searchedWords, 47 type: "best_fields", 48 fields: [ 49 'post_title^5', 50 'post_name^5', 51 'meta.top_post_group_top_post_introduction.value^3', 52 'meta.top_post_group_top_post_introduction.raw^3', 53 'meta.*_title.value^2', 54 'meta.*_title.raw^2', 55 'meta.*_text.value^2', 56 'meta.*_text.raw^2', 57 'meta.*_question.value^2', 58 'meta.*_question.raw^2', 59 'meta.*_answer.value^2', 60 'meta.*_answer.raw^2', 61 'meta.*_procedure_type_group_procedure_*.value', 62 'meta.*_procedure_type_group_procedure_*.raw', 63 'meta.restriction_group_authorized_groups.value', 64 'meta.restriction_group_authorized_groups.raw', 65 ], 66 fuzziness: 'AUTO', 67 }, 68 } 69 ], 70 } 71 } 72 } 73 74 /************** 75 * Prepare the URL to send to the front 76 * @params array 77 * @return 78 ***************/ 79 apiParams(params = []) { 80 81 let paramsToURL = '' 82 for (let [index, data] of Object.entries(params)) { 83 paramsToURL += index + '=' + data + '&' 84 } 85 return paramsToURL 86 } 87 88 /************** 89 * Sends the URL to the front 90 * @params array 91 * @use this.apiParams 92 ***************/ 93 getURL(paramsToURL) { 94 let apiURL = `/wp-json/creasit/${(this._APIRoute)}?` 95 return this._siteUrl + apiURL + this.apiParams(paramsToURL) 96 } 97 98 /************** 99 * Sends the URL to the front 100 * @pagination_infos array 101 * @PostsPerPage int 102 ***************/ 103 getCount(postCount, PostsPerPage, append) { 104 if (append === true) { 105 PostsPerPage += postCount 106 } else { 107 PostsPerPage = postCount 108 } 109 return PostsPerPage 110 } 111 112 /************** 113 * Add GET data in the URL field 114 * @paged string 115 * @return string 116 ***************/ 117 pushArgsInUrl(paged, category) { 118 119 if (paged) { 120 paged = '?page=' + Number(paged) ? '?page=' + Number(paged) : '' 121 } 122 123 if (category > 0) { 124 category = '&category=' + Number(category) 125 } else { 126 category = '' 127 } 128 129 window.history.pushState( 130 '', '', paged + category 131 ) 132 133 } 134 135 /************** 136 * Add GET data in the URL field 137 * @paged string 138 * @return string 139 ***************/ 140 pushSearchArgsInUrl() { 141 142 let query = this.URLQuery 143 let argsObject = this.URLArgs 144 let url = query 145 146 Object.keys(argsObject).forEach(function (parameterName) { 147 let valueObject = argsObject[parameterName] 148 let parameterValue = valueObject.parameterValue 149 if (parameterValue === undefined) { 150 return 151 } 152 if (parameterValue.length !== 0) { 153 url += `&${parameterName}=` 154 url += parameterValue 155 } 156 }); 157 158 window.history.pushState( 159 '', '', url 160 ) 161 162 } 163 164 /************** 165 * Add GET data in the URL field 166 * @postsPerPage int
167 * @foundPosts int 168 * @paged int 169 ***************/ 170 canPaginate(postsPerPage, foundPosts, paged) { 171 return (postsPerPage * paged) < foundPosts 172 } 173 174 /************** 175 * Sends the URL to the front 176 * @params array 177 * @use this.apiParams 178 ***************/ 179 async fetchAPI(URL, method) { 180 let response = await fetch(URL, { 181 method: method, 182 credentials: 'same-origin', 183 headers: { 184 'Content-Type': 'application/json; charset=utf-8' 185 }, 186 }) 187 return await response.json() 188 } 189 190 getCookie(name) { 191 let v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)'); 192 return v ? v[2] : null; 193 } 194 195 /************** 196 * Sends the URL to the front 197 * @params array 198 * @use this.apiParams 199 ***************/ 200 async secureFetchAPI(URL, method) { 201 let cookie = this.getCookie('bearer_token') 202 let headers = new Headers({ 203 'Accept': 'application/json', 204 'Content-Type': 'application/json; charset=utf-8', 205 'Authorization': 'Bearer ' + cookie, 206 'Access-Control-Allow-Origin': '*', 207 'Access-Control-Allow-Methods': 'OPTIONS, GET' 208 }); 209 let response = await fetch(URL, { 210 mode: 'cors', 211 method: 'GET', 212 headers: headers, 213 redirect: 'follow' 214 }) 215 return await response.json() 216 } 217 218 /************** 219 * Fetch & Get the result from the ElasticSearch APIw 220 * @params array 221 * @use this.apiParams' 222 ***************/ 223 async fetchES(URL, fetchArgs, offset = 0, postsPerPage = 5) { 224 let body = { 225 from: offset, 226 size: postsPerPage, 227 query: fetchArgs, 228 } 229 let cookie = this.getCookie('bearer_token') 230 let response = await fetch(URL, { 231 mode: 'cors', 232 method: 'POST', 233 headers: { 234 'Content-Type': 'application/json', 235 'Authorization': 'Bearer ' + cookie, 236 'Access-Control-Allow-Origin': '*', 237 'Access-Control-Allow-Methods': 'OPTIONS, GET' 238 }, 239 body: JSON.stringify(body) 240 }) 241 return await response.json() 242 } 243 244 /************** 245 * Handle the fetch API result 246 * @params $sampleContainer 247 * @params $resultContainer 248 * @params hits 249 * @params cpt 250 * @use this.apiParams 251 ***************/ 252 appendSearchResult($sampleContainer, $resultContainer, hits, cpt) { 253 let postArray = [] 254 hits.forEach((hit) => { 255 let $container = $sampleContainer.cloneNode(true) 256 let ID = hit._id 257 let score = hit._score 258 let title = hit._source.post_title 259 let titleLink = 'Consulter la page ' + hit._source.post_title + ' (même onglet)' 260 let post_type = hit._source.post_type 261 let link = hit._source.permalink 262 let introduction = '' 263 if (hit._source.meta.top_post_group_top_post_introduction) { 264 introduction = hit._source.meta.top_post_group_top_post_introduction[0].value 265 } 266 267 $container.dataset.score = score 268 269 // The article HTML tag 270 let $article = $container.querySelector('.card') 271 $article.dataset.id = ID 272 $article.dataset.cpt = post_type 273 274 // The a HTML tag 275 let $link = $container.querySelector('.card__link') 276 $link.setAttribute('href', link) 277 $link.setAttribute('title', titleLink) 278 279 // The h2 HTML tag 280 let $title = $container.querySelector('.card__title') 281 $title.innerHTML = title 282 283 // The span HTML tag inside the h2 284 let $cpt = $container.querySelector('.card__cpt') 285 let entries = Object.entries(cpt); 286 // We remove the "Transitions" & "Pages système" to avoid misleading for the visitors. 287 // CF Christophe. 288 entries.forEach(([name, label]) => { 289 if (name === post_type) { 290 $cpt.innerHTML = String(label) 291 } 292 }) 293 294 // The p HTML tag 295 let $postIntro = $container.querySelector('.card__description p') 296 if (introduction) { 297 $postIntro.innerHTML = this.truncate(introduction, 60, '...') 298 } 299 300 $container.classList.remove('hide') 301 302 postArray.push($container) 303 304 }) 305 if (this.nextPage === false) {
306 $resultContainer.innerHTML = $sampleContainer.outerHTML 307 } 308 for (let postKey in postArray) { 309 $resultContainer.innerHTML += postArray[postKey].outerHTML 310 } 311 } 312 313 /************** 314 * Map to object function 315 * @posts array 316 * @selector html 317 * @append bool 318 ***************/ 319 mapToObject(m) { 320 let object = {} 321 for (let [k, v] of m) { 322 object[k] = v 323 } 324 return object 325 } 326 327 formatDate(date, format) { 328 const map = { 329 dd: date.getMonth() + 1, 330 mm: date.getDate(), 331 yyyy: date.getFullYear(), 332 hh: date.getHours(), 333 ii: date.getMinutes(), 334 ss: date.getSeconds(), 335 } 336 337 return format.replace(/mm|dd|yyy|hh|ii|ss/gi, matched => map[matched]) 338 } 339 340 /************** 341 * Append the post after the last diplayed post 342 * @posts array 343 * @selector html 344 * @append bool 345 ***************/ 346 appendPosts(posts, container, append) { 347 if (append === false) { 348 container.innerHTML = '' 349 } 350 posts.forEach((post) => { 351 container.innerHTML += post 352 this.fadeIn(container) 353 }) 354 } 355 356 /************** 357 * Get the selected button category 358 * @posts array 359 * @selector html 360 * @append bool 361 ***************/ 362 currentCategory(categoryButtons) { 363 let currentCategoryID = '' 364 let currentCategory 365 366 Array.prototype.forEach.call(categoryButtons, function (el, i) { 367 currentCategory = el.classList.contains('is-active') 368 if (currentCategory) { 369 currentCategoryID = el.dataset.id 370 } 371 }) 372 return currentCategoryID 373 } 374 375 /************** 376 * Apply a fadOut effect on selector with CSS help. 377 * @selector html 378 ***************/ 379 fadeOut(selector) { 380 selector.classList.add('hideX') 381 selector.classList.add('hide') 382 selector.classList.remove('showX') 383 } 384 385 /************** 386 * Apply a fadIn effect on selector with CSS help. 387 * @selector html 388 ***************/ 389 fadeIn(selector) { 390 selector.classList.add('showX') 391 selector.classList.remove('hideX') 392 selector.classList.remove('hide') 393 } 394 395 truncate(elem, limit, after, separator = ' ') { 396 // Make sure an element and number of items to truncate is provided 397 if (!elem || !limit) return 398 // Get the inner content of the element 399 400 let content = elem.trim() 401 402 // Convert the content into an array of words 403 // Remove any words above the limit 404 content = content.split(separator) 405 406 if (content.length < 60) { 407 return elem 408 } 409 content = content.slice(0, limit) 410 // Convert the array of words back into a string 411 // If there's content to add after it, add it 412 content = content.join(separator) + (after ? after : '') 413 414 return content 415 }; 416 417 418} 419 420// Execute the script only when the DOM is ready. 421ready = (callback) => { 422 if (document.readyState !== 'loading') { 423 callback() 424 } else { 425 document.addEventListener('DOMContentLoaded', callback) 426 } 427}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.