Adds beta search engine to JCB.

master v3.1.10
parent f2ea22d0ad
commit f1cb398f7a
Signed by: Llewellyn
GPG Key ID: A9201372263741E7

@ -9,7 +9,7 @@ The Component Builder for [Joomla](https://extensions.joomla.org/extension/compo
Whether you're a seasoned [Joomla](https://extensions.joomla.org/extension/component-builder/) developer, or have just started, Component Builder will save you lots of time and money. A real must have!
You can install it quite easily and with no limitations. On [gitea](https://git.vdm.dev/joomla/Component-Builder/tags) is the latest release (3.1.9) with **ALL** its features and **ALL** concepts totally open-source and free!
You can install it quite easily and with no limitations. On [gitea](https://git.vdm.dev/joomla/Component-Builder/tags) is the latest release (3.1.10) with **ALL** its features and **ALL** concepts totally open-source and free!
> Watch Quick Build of a Hello World component in [JCB on Youtube](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45)
@ -140,11 +140,11 @@ TODO
+ *Author*: [Llewellyn van der Merwe](mailto:joomla@vdm.io)
+ *Name*: [Component Builder](https://git.vdm.dev/joomla/Component-Builder)
+ *First Build*: 30th April, 2015
+ *Last Build*: 30th October, 2022
+ *Version*: 3.1.9
+ *Last Build*: 2nd November, 2022
+ *Version*: 3.1.10
+ *Copyright*: Copyright (C) 2015 Vast Development Method. All rights reserved.
+ *License*: GNU General Public License version 2 or later; see LICENSE.txt
+ *Line count*: **333093**
+ *Line count*: **333951**
+ *Field count*: **2004**
+ *File count*: **2183**
+ *Folder count*: **381**

@ -9,7 +9,7 @@ The Component Builder for [Joomla](https://extensions.joomla.org/extension/compo
Whether you're a seasoned [Joomla](https://extensions.joomla.org/extension/component-builder/) developer, or have just started, Component Builder will save you lots of time and money. A real must have!
You can install it quite easily and with no limitations. On [gitea](https://git.vdm.dev/joomla/Component-Builder/tags) is the latest release (3.1.9) with **ALL** its features and **ALL** concepts totally open-source and free!
You can install it quite easily and with no limitations. On [gitea](https://git.vdm.dev/joomla/Component-Builder/tags) is the latest release (3.1.10) with **ALL** its features and **ALL** concepts totally open-source and free!
> Watch Quick Build of a Hello World component in [JCB on Youtube](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45)
@ -140,11 +140,11 @@ TODO
+ *Author*: [Llewellyn van der Merwe](mailto:joomla@vdm.io)
+ *Name*: [Component Builder](https://git.vdm.dev/joomla/Component-Builder)
+ *First Build*: 30th April, 2015
+ *Last Build*: 30th October, 2022
+ *Version*: 3.1.9
+ *Last Build*: 2nd November, 2022
+ *Version*: 3.1.10
+ *Copyright*: Copyright (C) 2015 Vast Development Method. All rights reserved.
+ *License*: GNU General Public License version 2 or later; see LICENSE.txt
+ *Line count*: **333093**
+ *Line count*: **333951**
+ *Field count*: **2004**
+ *File count*: **2183**
+ *Folder count*: **381**

@ -10,4 +10,28 @@
/* CSS Document */
.selected {
background-color:#d7d8db !important
}
tr.selected td {
background-color:#d7d8db !important
}
tr {
cursor:pointer
}
.found_code {
color: #46a546;
font-weight: bolder;
}
.search_details_title {
font-size: large;
font-weight: bolder;
}
.small_column {
padding: 2px;
text-align: center;
}
th.small_column {
padding: 2px !important;
text-align: center !important;
}

@ -20,24 +20,39 @@ const doSearch = async (signal, tables) => {
// load the result table
const resultsTable = new DataTable('#search_results_table');
// get the search mode
let typeSearch = modeObject.querySelector('input[type=\'radio\']:checked').value;
// set some search values
let searchValue = searchObject.value;
let replaceValue = replaceObject.value;
// add the form data
formData.append('table_name', '');
formData.append('type_search', typeSearch);
formData.append('search_value', searchValue);
formData.append('replace_value', replaceValue);
formData.append('match_case', matchObject.checked ? 1 : 0);
formData.append('whole_word', wholeObject.checked ? 1 : 0);
formData.append('regex_search', regexObject.checked ? 1 : 0);
let abort_this_search_value = false;
let abort_this_search_values = false;
// reset the progress bar
searchProgressBarObject.style.width = '0%';
searchProgressBarObject.innerHTML = '0%';
// show the progress bar
searchProgressObject.style.display = '';
// start search timer
startSearchTimer();
let total = 0;
let progress = tables.length;
let index;
for (index = 0; index < tables.length; index++) {
for (index = 0; index < progress; index++) {
let tableName = tables[index];
@ -50,19 +65,35 @@ const doSearch = async (signal, tables) => {
body: formData
}
if (abort_this_search_value) {
console.log('Aborting this searchValue:' + searchValue);
if (abort_this_search_values) {
break;
}
const response = await fetch(Url + 'doSearch', options).then(response => {
total++;
// calculate the percent
let percent = 100.0 * (total / progress);
// update the progress bar
searchProgressBarObject.style.width = percent.toFixed(2) + '%';
searchProgressBarObject.innerHTML = percent.toFixed(2) + '%';
// when complete hide the progress bar
if (progress == total) {
searchProgressBarObject.innerHTML = Joomla.JText._('COM_COMPONENTBUILDER_SEARCH_FINISHED_IN') + ' ' + getSearchLenght() + ' ' + Joomla.JText._('COM_COMPONENTBUILDER_SECONDS');
setTimeout(function () {
searchProgressObject.style.display = 'none';
}, 3000);
}
// return the json response
if (response.ok) {
return response.json();
}
}).then((data) => {
if (typeof data.success !== 'undefined') {
UIkit.notify(data.success, {pos:'top-right', timeout : 200, status:'success'});
//} else if (typeof data.not_found !== 'undefined') {
// UIkit.notify(data.not_found, {pos:'bottom-right', timeout : 200});
}
if (typeof data.items !== 'undefined') {
console.log('++ Fetched for ' + searchValue + ' [' + tableName + ']');
addTableItems(resultsTable, data.items);
addTableItems(resultsTable, data.items, typeSearch);
}
}).catch(error => {
console.log(error);
@ -75,6 +106,31 @@ const doSearch = async (signal, tables) => {
}
};
/**
* JS Function to start search timer
*/
const startSearchTimer = () => {
startSearchTime = new Date();
};
/**
* JS Function to get search lenght
*/
const getSearchLenght = () => {
// set ending time
endSearchTime = new Date();
// get diff in ms
var timeDiff = endSearchTime - startSearchTime;
// strip the ms
timeDiff /= 1000;
// get seconds
return Math.round(timeDiff);
}
/**
* JS Function to fetch selected item
*/
@ -86,27 +142,24 @@ const getSelectedItem = async (table, row, field, line) => {
// build form
const formData = new FormData();
formData.append('field_name', field);
formData.append('row_id', row);
formData.append('table_name', table);
formData.append('search_value', searchObject.value);
formData.append('replace_value', replaceObject.value);
formData.append('match_case', matchObject.checked ? 1 : 0);
formData.append('whole_word', wholeObject.checked ? 1 : 0);
formData.append('regex_search', regexObject.checked ? 1 : 0);
// get search value
if (mode == 1) {
formData.append('field_name', field);
formData.append('row_id', row);
formData.append('table_name', table);
// calling URL
getURL = Url + 'getSearchValue';
postURL = Url + 'getSearchValue';
} else {
formData.append('field_name', field);
formData.append('row_id', row);
// add the line value
formData.append('line_nr', line);
formData.append('table_name', table);
formData.append('search_value', searchObject.value);
formData.append('replace_value', replaceObject.value);
formData.append('match_case', matchObject.checked ? 1 : 0);
formData.append('whole_word', wholeObject.checked ? 1 : 0);
formData.append('regex_search', regexObject.checked ? 1 : 0);
// calling URL
getURL = Url + 'getReplaceValue';
postURL = Url + 'getReplaceValue';
}
let options = {
@ -114,11 +167,14 @@ const getSelectedItem = async (table, row, field, line) => {
body: formData
}
const response = await fetch(getURL, options).then(response => {
const response = await fetch(postURL, options).then(response => {
if (response.ok) {
return response.json();
}
}).then((data) => {
if (typeof data.success !== 'undefined') {
UIkit.notify(data.success, {pos:'top-right', status:'success'});
}
if (typeof data.value !== 'undefined') {
addSelectedItem(data.value, table, row, field, line);
}
@ -130,7 +186,166 @@ const getSelectedItem = async (table, row, field, line) => {
} finally {
// Executed regardless if we caught the error
}
}
};
/**
* JS Function to check if we should save/update the all current found items
*/
const replaceAllCheck = () => {
// load question
let question = Joomla.JText._('COM_COMPONENTBUILDER_YOUR_ARE_ABOUT_TO_REPLACE_BALLB_SEARCH_RESULTS') + '<br />' +
Joomla.JText._('COM_COMPONENTBUILDER_THIS_CAN_NOT_BE_UNDONE_BYOU_HAVE_BEEN_WARNEDB') + '<br /><br />' +
Joomla.JText._('COM_COMPONENTBUILDER_ARE_YOU_THEREFORE_ABSOLUTELY_SURE_YOU_WANT_TO_CONTINUE');
// do check
UIkit.modal.confirm(question, function () {
// we clear the table again
clearAll();
// show the search settings again
showSearch();
// clear search values
clearSearch();
// Create new controller and issue new request
controller = new AbortController();
// check if any specific table was set
let tables = [];
let table = tableObject.value;
if (table != -1) {
tables.push(table);
replaceAll(controller.signal, tables);
} else {
replaceAll(controller.signal, searchTables);
}
});
};
/**
* JS Function to execute the search
*/
const replaceAll = async (signal, tables) => {
try {
// build form
const formData = new FormData();
// load the result table
const resultsTable = new DataTable('#search_results_table');
// get the search mode
let typeSearch = modeObject.querySelector('input[type=\'radio\']:checked').value;
// set some search values
let searchValue = searchObject.value;
let replaceValue = replaceObject.value;
// add the form data
formData.append('table_name', '');
formData.append('type_search', typeSearch);
formData.append('search_value', searchValue);
formData.append('replace_value', replaceValue);
formData.append('match_case', matchObject.checked ? 1 : 0);
formData.append('whole_word', wholeObject.checked ? 1 : 0);
formData.append('regex_search', regexObject.checked ? 1 : 0);
let abort_this_replace_values = false;
let total = 0;
let index;
for (index = 0; index < tables.length; index++) {
let tableName = tables[index];
// add the table name
formData.set('table_name', tableName);
let options = {
signal: signal,
method: 'POST', // *GET, POST, PUT, DELETE, etc.
body: formData
}
if (abort_this_replace_values) {
break;
}
const response = await fetch(Url + 'replaceAll', options).then(response => {
total++;
if (response.ok) {
return response.json();
}
}).then((data) => {
if (typeof data.success !== 'undefined') {
UIkit.notify(data.success, {pos:'top-right', timeout : 200, status:'success'});
} else if (typeof data.error !== 'undefined') {
UIkit.notify(data.error, {pos:'bottom-right', timeout : 200});
}
}).catch(error => {
console.log(error);
});
}
} catch (error) {
console.log(error);
} finally {
// Executed regardless if we caught the error
}
};
/**
* JS Function to check if we should save/update the current selected item
*/
const setValueCheck = (row, field, table) => {
// load question
let question = Joomla.JText._('COM_COMPONENTBUILDER_YOUR_ARE_ABOUT_TO_UPDATE_ROW') + ' (' + row + ') -> (' + field + ') ' +
Joomla.JText._('COM_COMPONENTBUILDER_FIELD_IN_THE') + ' (' + table + ') ' + Joomla.JText._('COM_COMPONENTBUILDER_TABLE') + '.<br /><br />' +
Joomla.JText._('COM_COMPONENTBUILDER_THIS_CAN_NOT_BE_UNDONE_ARE_YOU_SURE_YOU_WANT_TO_CONTINUE');
// do check
UIkit.modal.confirm(question, function () {
setValue(row, field, table);
});
};
/**
* JS Function to set the current selected item
*/
const setValue = async (row, field, table) => {
try {
// get the value from the editor
let value = editorObject.getValue();
// build form
const formData = new FormData();
formData.append('value', value);
formData.append('row_id', row);
formData.append('field_name', field);
formData.append('table_name', table);
let options = {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
body: formData
}
const response = await fetch(Url + 'setValue', options).then(response => {
if (response.ok) {
return response.json();
}
}).then((data) => {
if (typeof data.success !== 'undefined') {
UIkit.notify(data.success, {pos:'top-right', status:'success'});
clearSelectedItem();
tableActiveObject.remove().draw();
}
}).catch(error => {
console.log(error);
});
} catch (error) {
console.log(error);
} finally {
// Executed regardless if we caught the error
}
};
/**
* JS Function to add item to the editor
@ -139,8 +354,33 @@ const addSelectedItem = async (value, table, row, field, line) => {
// display area
if (value.length > 1)
{
// add value to editor
editorObject.setValue(value);
editorNoticeObject.innerHTML = 'Table: <b>' + table + '</b>(id:<b>' + row + '</b>) | Field: <b>' + field + '</b>(line:<b>' + line + '</b>)';
// set item details notice area
itemNoticeObject.style.display = '';
itemEditButtonObject.innerHTML = editButtonSelected;
itemTableNameObject.innerHTML = table;
itemRowIdObject.innerHTML = row;
itemFieldNameObject.innerHTML = field;
itemLineNumberObject.innerHTML = line;
// set button and editor line if we have a line number
if (typeof line == 'number') {
// show and set the save button
buttonUpdateItemObject.style.display = '';
buttonUpdateItemObject.setAttribute('onclick',"setValueCheck(" + row + ", '" + field + "', '" + table + "');");
// get top of the code line
let top = editorObject.charCoords({line: line, ch: 0}, "local").top;
// scroll to the line
editorObject.scrollTo(null, top - 12);
// select the line
editorObject.setCursor(line - 1);
} else {
// no line so no data we can't save this data
buttonUpdateItemObject.setAttribute('onclick', "");
buttonUpdateItemObject.style.display = 'none';
}
}
}
@ -150,7 +390,15 @@ const addSelectedItem = async (value, table, row, field, line) => {
const clearSelectedItem = async () => {
// display area
editorObject.setValue('');
editorNoticeObject.innerHTML = '';
// clear notice area
itemNoticeObject.style.display = 'none';
itemEditButtonObject.innerHTML = '...';
itemTableNameObject.innerHTML = '...';
itemRowIdObject.innerHTML = '...';
itemFieldNameObject.innerHTML = '...';
itemLineNumberObject.innerHTML = '...';
// clear update button
buttonUpdateItemObject.setAttribute('onclick', '');
}
/**
@ -159,6 +407,9 @@ const clearSelectedItem = async () => {
const clearTableItems = async () => {
let table = new DataTable('#search_results_table');
table.clear().draw( true );
// hide the update all items
buttonUpdateAllObject.style.display = 'none';
}
/**
@ -168,19 +419,43 @@ const clearAll = async () => {
// clear all details
clearTableItems();
clearSelectedItem();
searchedObject.innerHTML = '....';
}
/**
* JS Function to clear the search and replace values
*/
const clearSearch = async () => {
// clear the search and replace values
searchObject.value = '';
replaceObject.value = '';
}
/**
* JS Function to add items to the table
*/
const addTableItems = async (table, items) => {
const addTableItems = async (table, items, typeSearch) => {
table.rows.add(items).draw( false );
if (typeSearch == 2) {
buttonUpdateAllObject.style.display = ''; // TODO should only show once all items are loaded
} else {
buttonUpdateAllObject.style.display = 'none'; // TODO should only show once all items are loaded
}
}
/**
* JS Function to execute (A) on search text change , (B) on search options changes
* JS Function to execute (A) on search/replace text change , (B) on search options changes
*/
const onChange = () => {
// get replace value if set
const replaceValue = replaceObject.value;
if (replaceValue.length > 0) {
// set the searched value
replacedObject.innerHTML = htmlentities(replaceValue);
} else {
replacedObject.innerHTML = '';
}
// get search value
const searchValue = searchObject.value;
if (searchValue.length > 2) {
// Cancel any ongoing requests
@ -189,6 +464,9 @@ const onChange = () => {
// we clear the table again
clearAll();
// set the searched value
searchedObject.innerHTML = htmlentities(searchValue);
// Create new controller and issue new request
controller = new AbortController();
@ -206,3 +484,241 @@ const onChange = () => {
clearAll();
}
};
/**
* JS Function to hide search settings and show table search
*/
const showSearch = () => {
searchSettingsObject.style.display = '';
searchDetailsObject.style.display = 'none';
replaceDetailsObject.style.display = 'none';
tableSearchObject.style.display = 'none';
tableLengthObject.style.display = 'none';
};
/**
* JS Function to show search settings and hide table search
*/
const hideSearch = () => {
searchSettingsObject.style.display = 'none';
searchDetailsObject.style.display = '';
tableSearchObject.style.display = '';
tableLengthObject.style.display = '';
// check if we are in replace mode
let mode = modeObject.querySelector('input[type=\'radio\']:checked').value;
if (mode == 2) {
replaceDetailsObject.style.display = '';
}
};
function htmlentities(string, quoteStyle, charset, doubleEncode) {
// discuss at: https://locutus.io/php/htmlentities/
// original by: Kevin van Zonneveld (https://kvz.io)
// revised by: Kevin van Zonneveld (https://kvz.io)
// revised by: Kevin van Zonneveld (https://kvz.io)
// improved by: nobbler
// improved by: Jack
// improved by: Rafał Kukawski (https://blog.kukawski.pl)
// improved by: Dj (https://locutus.io/php/htmlentities:425#comment_134018)
// bugfixed by: Onno Marsman (https://twitter.com/onnomarsman)
// bugfixed by: Brett Zamir (https://brett-zamir.me)
// input by: Ratheous
// note 1: function is compatible with PHP 5.2 and older
// example 1: htmlentities('Kevin & van Zonneveld')
// returns 1: 'Kevin &amp; van Zonneveld'
// example 2: htmlentities("foo'bar","ENT_QUOTES")
// returns 2: 'foo&#039;bar'
const hashMap = getHtmlTranslationTable('HTML_ENTITIES', quoteStyle)
string = string === null ? '' : string + ''
if (!hashMap) {
return false
}
if (quoteStyle && quoteStyle === 'ENT_QUOTES') {
hashMap["'"] = '&#039;'
}
doubleEncode = doubleEncode === null || !!doubleEncode
const regex = new RegExp('&(?:#\\d+|#x[\\da-f]+|[a-zA-Z][\\da-z]*);|[' +
Object.keys(hashMap)
.join('')
// replace regexp special chars
.replace(/([()[\]{}\-.*+?^$|/\\])/g, '\\$1') + ']',
'g')
return string.replace(regex, function (ent) {
if (ent.length > 1) {
return doubleEncode ? hashMap['&'] + ent.substr(1) : ent
}
return hashMap[ent]
})
}
function getHtmlTranslationTable(table, quoteStyle) { // eslint-disable-line camelcase
// discuss at: https://locutus.io/php/get_html_translation_table/
// original by: Philip Peterson
// revised by: Kevin van Zonneveld (https://kvz.io)
// bugfixed by: noname
// bugfixed by: Alex
// bugfixed by: Marco
// bugfixed by: madipta
// bugfixed by: Brett Zamir (https://brett-zamir.me)
// bugfixed by: T.Wild
// improved by: KELAN
// improved by: Brett Zamir (https://brett-zamir.me)
// input by: Frank Forte
// input by: Ratheous
// note 1: It has been decided that we're not going to add global
// note 1: dependencies to Locutus, meaning the constants are not
// note 1: real constants, but strings instead. Integers are also supported if someone
// note 1: chooses to create the constants themselves.
// example 1: get_html_translation_table('HTML_SPECIALCHARS')
// returns 1: {'"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;'}
const entities = {}
const hashMap = {}
let decimal
const constMappingTable = {}
const constMappingQuoteStyle = {}
let useTable = {}
let useQuoteStyle = {}
// Translate arguments
constMappingTable[0] = 'HTML_SPECIALCHARS'
constMappingTable[1] = 'HTML_ENTITIES'
constMappingQuoteStyle[0] = 'ENT_NOQUOTES'
constMappingQuoteStyle[2] = 'ENT_COMPAT'
constMappingQuoteStyle[3] = 'ENT_QUOTES'
useTable = !isNaN(table)
? constMappingTable[table]
: table
? table.toUpperCase()
: 'HTML_SPECIALCHARS'
useQuoteStyle = !isNaN(quoteStyle)
? constMappingQuoteStyle[quoteStyle]
: quoteStyle
? quoteStyle.toUpperCase()
: 'ENT_COMPAT'
if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') {
throw new Error('Table: ' + useTable + ' not supported')
}
entities['38'] = '&amp;'
if (useTable === 'HTML_ENTITIES') {
entities['160'] = '&nbsp;'
entities['161'] = '&iexcl;'
entities['162'] = '&cent;'
entities['163'] = '&pound;'
entities['164'] = '&curren;'
entities['165'] = '&yen;'
entities['166'] = '&brvbar;'
entities['167'] = '&sect;'
entities['168'] = '&uml;'
entities['169'] = '&copy;'
entities['170'] = '&ordf;'
entities['171'] = '&laquo;'
entities['172'] = '&not;'
entities['173'] = '&shy;'
entities['174'] = '&reg;'
entities['175'] = '&macr;'
entities['176'] = '&deg;'
entities['177'] = '&plusmn;'
entities['178'] = '&sup2;'
entities['179'] = '&sup3;'
entities['180'] = '&acute;'
entities['181'] = '&micro;'
entities['182'] = '&para;'
entities['183'] = '&middot;'
entities['184'] = '&cedil;'
entities['185'] = '&sup1;'
entities['186'] = '&ordm;'
entities['187'] = '&raquo;'
entities['188'] = '&frac14;'
entities['189'] = '&frac12;'
entities['190'] = '&frac34;'
entities['191'] = '&iquest;'
entities['192'] = '&Agrave;'
entities['193'] = '&Aacute;'
entities['194'] = '&Acirc;'
entities['195'] = '&Atilde;'
entities['196'] = '&Auml;'
entities['197'] = '&Aring;'
entities['198'] = '&AElig;'
entities['199'] = '&Ccedil;'
entities['200'] = '&Egrave;'
entities['201'] = '&Eacute;'
entities['202'] = '&Ecirc;'
entities['203'] = '&Euml;'
entities['204'] = '&Igrave;'
entities['205'] = '&Iacute;'
entities['206'] = '&Icirc;'
entities['207'] = '&Iuml;'
entities['208'] = '&ETH;'
entities['209'] = '&Ntilde;'
entities['210'] = '&Ograve;'
entities['211'] = '&Oacute;'
entities['212'] = '&Ocirc;'
entities['213'] = '&Otilde;'
entities['214'] = '&Ouml;'
entities['215'] = '&times;'
entities['216'] = '&Oslash;'
entities['217'] = '&Ugrave;'
entities['218'] = '&Uacute;'
entities['219'] = '&Ucirc;'
entities['220'] = '&Uuml;'
entities['221'] = '&Yacute;'
entities['222'] = '&THORN;'
entities['223'] = '&szlig;'
entities['224'] = '&agrave;'
entities['225'] = '&aacute;'
entities['226'] = '&acirc;'
entities['227'] = '&atilde;'
entities['228'] = '&auml;'
entities['229'] = '&aring;'
entities['230'] = '&aelig;'
entities['231'] = '&ccedil;'
entities['232'] = '&egrave;'
entities['233'] = '&eacute;'
entities['234'] = '&ecirc;'
entities['235'] = '&euml;'
entities['236'] = '&igrave;'
entities['237'] = '&iacute;'
entities['238'] = '&icirc;'
entities['239'] = '&iuml;'
entities['240'] = '&eth;'
entities['241'] = '&ntilde;'
entities['242'] = '&ograve;'
entities['243'] = '&oacute;'
entities['244'] = '&ocirc;'
entities['245'] = '&otilde;'
entities['246'] = '&ouml;'
entities['247'] = '&divide;'
entities['248'] = '&oslash;'
entities['249'] = '&ugrave;'
entities['250'] = '&uacute;'
entities['251'] = '&ucirc;'
entities['252'] = '&uuml;'
entities['253'] = '&yacute;'
entities['254'] = '&thorn;'
entities['255'] = '&yuml;'
}
if (useQuoteStyle !== 'ENT_NOQUOTES') {
entities['34'] = '&quot;'
}
if (useQuoteStyle === 'ENT_QUOTES') {
entities['39'] = '&#39;'
}
entities['60'] = '&lt;'
entities['62'] = '&gt;'
// ascii decimals to real symbols
for (decimal in entities) {
if (entities.hasOwnProperty(decimal)) {
hashMap[String.fromCharCode(decimal)] = entities[decimal]
}
}
return hashMap
}

@ -1640,14 +1640,15 @@ class ComponentbuilderControllerAjax extends BaseController
try
{
$table_nameValue = $jinput->get('table_name', NULL, 'WORD');
$type_searchValue = $jinput->get('type_search', 1, 'INT');
$search_valueValue = $jinput->get('search_value', NULL, 'RAW');
$match_caseValue = $jinput->get('match_case', 0, 'INT');
$whole_wordValue = $jinput->get('whole_word', 0, 'INT');
$regex_searchValue = $jinput->get('regex_search', 0, 'INT');
$component_idValue = $jinput->get('component_id', 0, 'INT');
if($table_nameValue && $user->id != 0 && $search_valueValue)
if($table_nameValue && $user->id != 0 && $type_searchValue && $search_valueValue)
{
$result = $this->getModel('ajax')->doSearch($table_nameValue, $search_valueValue, $match_caseValue, $whole_wordValue, $regex_searchValue, $component_idValue);
$result = $this->getModel('ajax')->doSearch($table_nameValue, $type_searchValue, $search_valueValue, $match_caseValue, $whole_wordValue, $regex_searchValue, $component_idValue);
}
else
{
@ -1735,9 +1736,14 @@ class ComponentbuilderControllerAjax extends BaseController
$field_nameValue = $jinput->get('field_name', NULL, 'WORD');
$row_idValue = $jinput->get('row_id', NULL, 'INT');
$table_nameValue = $jinput->get('table_name', NULL, 'WORD');
if($field_nameValue && $user->id != 0 && $row_idValue && $table_nameValue)
$search_valueValue = $jinput->get('search_value', NULL, 'RAW');
$replace_valueValue = $jinput->get('replace_value', NULL, 'RAW');
$match_caseValue = $jinput->get('match_case', 0, 'INT');
$whole_wordValue = $jinput->get('whole_word', 0, 'INT');
$regex_searchValue = $jinput->get('regex_search', 0, 'INT');
if($field_nameValue && $user->id != 0 && $row_idValue && $table_nameValue && $search_valueValue)
{
$result = $this->getModel('ajax')->getSearchValue($field_nameValue, $row_idValue, $table_nameValue);
$result = $this->getModel('ajax')->getSearchValue($field_nameValue, $row_idValue, $table_nameValue, $search_valueValue, $replace_valueValue, $match_caseValue, $whole_wordValue, $regex_searchValue);
}
else
{

@ -1312,6 +1312,7 @@ COM_COMPONENTBUILDER_ARE_YOU_SURE_YOU_WOULD_LIKE_TO_CONTINUE="Are you sure you w
COM_COMPONENTBUILDER_ARE_YOU_SURE_YOU_WOULD_LIKE_TO_REPLACE_YOUR_LOCAL_SNIPPET_WITH_THIS_JCB_COMMUNITY_SNIPPET="Are you sure you would like to replace your local snippet with this JCB community snippet?"
COM_COMPONENTBUILDER_ARE_YOU_SURE_YOU_WOULD_LIKE_TO_UPDATE_YOUR_LOCAL_SNIPPET_WITH_THIS_NEWER_JCB_COMMUNITY_SNIPPET="Are you sure you would like to update your local snippet with this newer JCB community snippet?"
COM_COMPONENTBUILDER_ARE_YOU_SURE_YOU_WOULD_LIKE_TO_UPDATE_YOUR_LOCAL_SNIPPET_WITH_THIS_OLDER_JCB_COMMUNITY_SNIPPET="Are you sure you would like to update your local snippet with this older JCB community snippet?"
COM_COMPONENTBUILDER_ARE_YOU_THEREFORE_ABSOLUTELY_SURE_YOU_WANT_TO_CONTINUE="Are you therefore absolutely sure you want to continue?"
COM_COMPONENTBUILDER_AUTHOR="Author"
COM_COMPONENTBUILDER_AUTHOR_EMAIL="Author Email"
COM_COMPONENTBUILDER_AUTHOR_NAME="Author Name"
@ -4706,6 +4707,7 @@ COM_COMPONENTBUILDER_EDIT_CREATED_DATE="Edit Created Date"
COM_COMPONENTBUILDER_EDIT_CREATED_DATE_DESC="Allows users in this group to edit created date."
COM_COMPONENTBUILDER_EDIT_S="Edit %s"
COM_COMPONENTBUILDER_EDIT_S_FOR_THIS_S="Edit %s for this %s"
COM_COMPONENTBUILDER_EDIT_S_S_DIRECTLY="Edit %s (%s) directly"
COM_COMPONENTBUILDER_EDIT_VERSIONS="Edit Version"
COM_COMPONENTBUILDER_EDIT_VERSIONS_DESC="Allows users in this group to edit versions."
COM_COMPONENTBUILDER_EDIT_VIEW="Edit View"
@ -5034,6 +5036,7 @@ $mediumkey = ComponentbuilderHelper::getCryptKey('medium');
$medium = new FOFEncryptAes($mediumkey);"
COM_COMPONENTBUILDER_FIELD_INITIATOR_ON_SAVE_MODEL_LABEL="Initiator<br /><small>on save model</small>"
COM_COMPONENTBUILDER_FIELD_INT="INT"
COM_COMPONENTBUILDER_FIELD_IN_THE="field in the"
COM_COMPONENTBUILDER_FIELD_JAVASCRIPT_VIEWS_FOOTER_DESCRIPTION="Add JavaScript for the list view that is loaded in the footer inside script tags. Do not add the script tags."
COM_COMPONENTBUILDER_FIELD_JAVASCRIPT_VIEWS_FOOTER_LABEL="Javascript (list view footer)"
COM_COMPONENTBUILDER_FIELD_JAVASCRIPT_VIEW_FOOTER_DESCRIPTION="Add JavaScript for the edit view that is loaded in the footer inside script tags. Do not add the script tags."
@ -5451,7 +5454,6 @@ COM_COMPONENTBUILDER_FORCE_THAT_THIS_JCB_PACKAGE_IMPORT_SEARCH_FOR_LOCAL_ITEMS_T
COM_COMPONENTBUILDER_FOUND="Found"
COM_COMPONENTBUILDER_FOUND_TEXT="Found Text"
COM_COMPONENTBUILDER_FREEOPEN="Free/Open"
COM_COMPONENTBUILDER_FULL_TEXT="Full Text"
COM_COMPONENTBUILDER_FULL_WIDTH_IN_TAB="Full Width in Tab"
COM_COMPONENTBUILDER_FUNCTION_NAME_ALREADY_TAKEN_PLEASE_TRY_AGAIN="Function name already taken, please try again."
COM_COMPONENTBUILDER_GENERAL_OVERVIEW_OF_HOW_THINGS_WORK_BSB="General overview of how things work: <b>%s</b>"
@ -5619,6 +5621,7 @@ COM_COMPONENTBUILDER_HTWOWE_COULD_NOT_OPEN_THE_PACKAGEHTWOTHIS_COULD_BE_DUE_TO_T
COM_COMPONENTBUILDER_IAUTHORI_BSB="<i>Author:</i> <b>%s</b>"
COM_COMPONENTBUILDER_ICOMPANYI_BSB="<i>Company:</i> <b>%s</b>"
COM_COMPONENTBUILDER_ICON="Icon"
COM_COMPONENTBUILDER_ID="id"
COM_COMPONENTBUILDER_ID_MISMATCH_WAS_DETECTED_WITH_THE_SSSS_GUI_CODE_FIELD_SO_THE_PLACEHOLDER_WAS_NOT_SET="ID mismatch was detected with the %s.%s.%s.%s GUI code field. So the placeholder was not set."
COM_COMPONENTBUILDER_IEMAILI_BSB="<i>Email:</i> <b>%s</b>"
COM_COMPONENTBUILDER_IMPORT_BY_GUID_ONLY="Import by GUID only!"
@ -5685,6 +5688,7 @@ COM_COMPONENTBUILDER_ISOLATE="Isolate"
COM_COMPONENTBUILDER_IS_BEING_COMPILED="is being compiled"
COM_COMPONENTBUILDER_IS_NOT_ONLY_FOUR_LISTRADIOCHECKBOXES="Is Not (only 4 list/radio/checkboxes)"
COM_COMPONENTBUILDER_IS_ONLY_FOUR_LISTRADIOCHECKBOXES="Is (only 4 list/radio/checkboxes)"
COM_COMPONENTBUILDER_ITEM_CODE="Item Code"
COM_COMPONENTBUILDER_IWEBSITEI_BSB="<i>Website:</i> <b>%s</b>"
COM_COMPONENTBUILDER_JCB_COMMUNITY="JCB Community"
COM_COMPONENTBUILDER_JCB_COMMUNITY_PACKAGES="JCB Community Packages"
@ -7748,7 +7752,7 @@ COM_COMPONENTBUILDER_LIBRARY_VERSION_DESC="A count of the number of times this L
COM_COMPONENTBUILDER_LIBRARY_VERSION_LABEL="Version"
COM_COMPONENTBUILDER_LICENSE="License"
COM_COMPONENTBUILDER_LICENSE_S="License: %s"
COM_COMPONENTBUILDER_LINE="Line"
COM_COMPONENTBUILDER_LINE="line"
COM_COMPONENTBUILDER_LINK="Link"
COM_COMPONENTBUILDER_LINK_LOCAL_DYNAMIC="Link & Local (dynamic)"
COM_COMPONENTBUILDER_LINK_TO_THE_CONTRIBUTOR="Link to the contributor"
@ -7803,7 +7807,7 @@ COM_COMPONENTBUILDER_NO_CRONJOB_PATH_FOUND_SINCE_INCORRECT_TYPE_REQUESTED="No cr
COM_COMPONENTBUILDER_NO_DESCRIPTION_FOUND="No description found."
COM_COMPONENTBUILDER_NO_FILES_LINKED="No Files Linked"
COM_COMPONENTBUILDER_NO_FOUND="No Found"
COM_COMPONENTBUILDER_NO_INSTANCES_WHERE_FOUND_S="No instances where found %s"
COM_COMPONENTBUILDER_NO_INSTANCES_WHERE_FOUND_IN_S="No instances where found in %s"
COM_COMPONENTBUILDER_NO_ITEM_FOUND="No Item Found"
COM_COMPONENTBUILDER_NO_KEYS_WERE_FOUND_TO_ADD_AN_EXPORT_KEY_SIMPLY_OPEN_THE_COMPONENT_GO_TO_THE_TAB_CALLED_SETTINGS_BOTTOM_RIGHT_THERE_IS_A_FIELD_CALLED_EXPORT_KEY="No keys were found. To add an export key simply open the component, go to the tab called settings, bottom right there is a field called Export Key."
COM_COMPONENTBUILDER_NO_LANGUAGES_FOUND="No Languages Found"
@ -8159,6 +8163,7 @@ COM_COMPONENTBUILDER_REMOVE="Remove"
COM_COMPONENTBUILDER_REMOVING_ALL_ZIP_PACKAGES_FROM_THE_TEMPORARY_FOLDER_OF_THE_JOOMLA_INSTALL="Removing all zip packages from the temporary folder of the Joomla install"
COM_COMPONENTBUILDER_RENAME="Rename"
COM_COMPONENTBUILDER_REPLACE="Replace"
COM_COMPONENTBUILDER_REPLACED_WITH="replaced with"
COM_COMPONENTBUILDER_REPORT_AN_ISSUE_BSB="Report an issue: <b>%s</b>"
COM_COMPONENTBUILDER_REQUIRES_THE_VALUE_ENTERED_BE_ONE_OF_THE_OPTIONS_IN_AN_ELEMENT_OF_TYPEQUOTLISTQUOT_THAT_IS_THAT_THE_ELEMENT_IS_A_SELECT_LIST="Requires the value entered be one of the options in an element of type=&quot;list&quot;: that is, that the element is a select list."
COM_COMPONENTBUILDER_REQUIRES_THE_VALUE_TO_BE_A_TELEPHONE_NUMBER_COMPLYING_WITH_THE_STANDARDS_OF_NANPA_ITUT_TRECEONE_HUNDRED_AND_SIXTY_FOUR_OR_IETF_RFCFOUR_THOUSAND_NINE_HUNDRED_AND_THIRTY_THREE="Requires the value to be a Telephone number complying with the standards of nanpa, ITU-T T-REC-E.164 or ietf rfc4933."
@ -8167,19 +8172,25 @@ COM_COMPONENTBUILDER_REVERT_ALL_AHEAD_SNIPPETS="Revert All Ahead Snippets"
COM_COMPONENTBUILDER_RIGHT_IN_TAB="Right in Tab"
COM_COMPONENTBUILDER_RIGHT_OF_TABS="Right of Tabs"
COM_COMPONENTBUILDER_RUN_EXPANSION="Run Expansion"
COM_COMPONENTBUILDER_SAVE_ALL_CHANGES_MADE_TO_THE_SELECTED_ITEM="Save all changes made to the selected item."
COM_COMPONENTBUILDER_SAVE_ITEM="Save Item"
COM_COMPONENTBUILDER_SAVE_SUCCESS="Great! Item successfully saved."
COM_COMPONENTBUILDER_SAVE_WARNING="The value already existed so please select another."
COM_COMPONENTBUILDER_SBR_YOU_CAN_ADD_A_BGITHUB_ACCESS_TOKENB_TO_COMPONENTBUILDER_GLOBAL_OPTIONS_TO_MAKE_AUTHENTICATED_REQUESTS_TO_GITHUB_AN_ACCESS_TOKEN_WITH_ONLY_PUBLIC_ACCESS_WILL_DO_TO_RETRIEVE_S="%s<br />You can add a <b>gitHub Access Token</b> to Componentbuilder global options to make authenticated requests to gitHub. An access token with only public access will do to retrieve %s."
COM_COMPONENTBUILDER_SEARCH="Search"
COM_COMPONENTBUILDER_SEARCHABLE="Searchable"
COM_COMPONENTBUILDER_SEARCHED_FOR="searched for"
COM_COMPONENTBUILDER_SEARCH_ACCESS="Search Access"
COM_COMPONENTBUILDER_SEARCH_ACCESS_DESC="Allows the users in this group to access search."
COM_COMPONENTBUILDER_SEARCH_COMPILER_BUTTON_ACCESS="Search Compiler Button Access"
COM_COMPONENTBUILDER_SEARCH_COMPILER_BUTTON_ACCESS_DESC="Allows the users in this group to access the compiler button."
COM_COMPONENTBUILDER_SEARCH_DATABASE_AGAIN="Search Database Again"
COM_COMPONENTBUILDER_SEARCH_DESC="JCB Search"
COM_COMPONENTBUILDER_SEARCH_FINISHED_IN="Search finished in"
COM_COMPONENTBUILDER_SEARCH_OR_SEARCH_AND_REPLACE="Search, or Search and Replace"
COM_COMPONENTBUILDER_SEARCH_SUBMENU="Search Submenu"
COM_COMPONENTBUILDER_SEARCH_SUBMENU_DESC="Allows the users in this group to submenu of Search"
COM_COMPONENTBUILDER_SECONDS="seconds"
COM_COMPONENTBUILDER_SEE_ALL_IMPORT_INFO="See All Import Info"
COM_COMPONENTBUILDER_SELECTION="selection"
COM_COMPONENTBUILDER_SELECT_ADMIN_VIEW="Select Admin View"
@ -9217,8 +9228,10 @@ COM_COMPONENTBUILDER_THE_URL_S_SET_TO_RETRIEVE_THE_PACKAGES_DOES_NOT_EXIST="The
COM_COMPONENTBUILDER_THE_URL_S_SET_TO_RETRIEVE_THE_PACKAGES_DOES_NOT_RETURN_ANY_DATA="The url (%s) set to retrieve the packages does not return any data!"
COM_COMPONENTBUILDER_THE_WIKI_CAN_ONLY_BE_LOADED_WHEN_YOUR_JCB_SYSTEM_HAS_INTERNET_CONNECTION="The wiki can only be loaded when your JCB system has internet connection."
COM_COMPONENTBUILDER_THE_WIKI_IS_LOADING="The wiki is loading"
COM_COMPONENTBUILDER_THIS_AREA_IS_STILL_UNDER_DEVELOPMENT_AND_DOES_NOT_WORK="This area is still under development and does not work."
COM_COMPONENTBUILDER_THIS_AREA_IS_STILL_UNDER_DEVELOPMENT_ALTHOUGH_IT_WORKS_IT_SHOULD_BE_USED_WITH_EXTREME_CAUTION_AS_ITS_NOT_STABLE="This area is still under development, although it works, it should be used with extreme caution as its not stable."
COM_COMPONENTBUILDER_THIS_BSB_IS_NOT_LINKED_TO_ANY_OTHER_AREAS_OF_JCB_AT_THIS_TIME="This <b>%s</b> is not linked to any other areas of JCB at this time!"
COM_COMPONENTBUILDER_THIS_CAN_NOT_BE_UNDONE_ARE_YOU_SURE_YOU_WANT_TO_CONTINUE="This can not be undone, are you sure you want to continue?"
COM_COMPONENTBUILDER_THIS_CAN_NOT_BE_UNDONE_BYOU_HAVE_BEEN_WARNEDB="This can not be undone, <b>you have been warned</b>!"
COM_COMPONENTBUILDER_THIS_MAY_TAKE_A_WHILE_DEPENDING_ON_THE_SIZE_OF_YOUR_PROJECT="This may take a while depending on the size of your project."
COM_COMPONENTBUILDER_THIS_PACKAGE_BPASSEDB_THE_CHECKSUM_VALIDATIONBR_BR_SMALLMANUALLY_ALSO_VALIDATE_THAT_THE_CORRECT_CHECKSUM_WAS_USEDSMALLBR_THIS_CHECKSUM_BSB_MUST_BE_THE_SAME_AS_THE_ONE_FOUND_A_S_SA="This package <b>PASSED</b> the checksum validation!<br /><br /><small>Manually also validate that the correct checksum was used.</small><br />This checksum: <b>%s</b> must be the same as the one found @ <a %s %s</a>"
COM_COMPONENTBUILDER_THIS_PACKAGE_HAS_NO_KEY="This package has no key."
@ -9294,7 +9307,9 @@ COM_COMPONENTBUILDER_TYPE_VALIDATION_RULE="Validation Rule"
COM_COMPONENTBUILDER_UNACTIVE_ONLY_FOUR_TEXT_FIELD="Unactive (only 4 text_field)"
COM_COMPONENTBUILDER_UNDERNEATH_TABS="Underneath Tabs"
COM_COMPONENTBUILDER_UPDATE="Update"
COM_COMPONENTBUILDER_UPDATE_ALL="Update All"
COM_COMPONENTBUILDER_UPDATE_ALL_DIVERGED_SNIPPETS="Update All Diverged Snippets"
COM_COMPONENTBUILDER_UPDATE_ALL_ITEMS_FOUND_WITH_THIS_DATABASE_SEARCH_WITH_THE_REPLACE_VALUE="Update all items found with this database search, with the replace value."
COM_COMPONENTBUILDER_UPDATE_ALL_OUT_DATED_SNIPPETS="Update All Out Dated Snippets"
COM_COMPONENTBUILDER_UP_TO_DATE="Up to date"
COM_COMPONENTBUILDER_USAGE="Usage"
@ -9413,6 +9428,8 @@ COM_COMPONENTBUILDER_WHILE_WE_DOWNLOAD_ALL_TWENTY_SIX_COMPILER_GIF_ANIMATIONS_RA
COM_COMPONENTBUILDER_WHOLE_WORD="Whole Word"
COM_COMPONENTBUILDER_WIKI="Wiki"
COM_COMPONENTBUILDER_YES="Yes"
COM_COMPONENTBUILDER_YOUR_ARE_ABOUT_TO_REPLACE_BALLB_SEARCH_RESULTS="Your are about to replace <b>ALL</b> search results."
COM_COMPONENTBUILDER_YOUR_ARE_ABOUT_TO_UPDATE_ROW="Your are about to update row"
COM_COMPONENTBUILDER_YOUR_DATA_IS_ENCRYPTED_WITH_A_AES_ONE_HUNDRED_AND_TWENTY_EIGHT_BIT_ENCRYPTION_USING_THE_ABOVE_THIRTY_TWO_CHARACTER_KEY="Your data is encrypted with a AES 128 bit encryption using the above 32 character key."
COM_COMPONENTBUILDER_YOUR_DATA_IS_ENCRYPTED_WITH_A_AES_ONE_HUNDRED_AND_TWENTY_EIGHT_BIT_ENCRYPTION_USING_THE_ABOVE_THIRTY_TWO_CHARACTER_KEY_WITHOUT_THIS_KEY_IT_WILL_TAKE_THE_CURRENT_TECHNOLOGY_WITH_A_BRUTE_FORCE_ATTACK_METHOD_MORE_THEN_A_HREFHTTPRANDOMIZECOMHOWLONGTOHACKPASS_TARGET_BLANK_TITLEHOW_LONG_TO_HACK_PASSSEVEN_HUNDRED_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZEROA_YEARS_TO_CRACK_THEORETICALLY_UNLESS_THEY_HAVE_THIS_KEY_ABOVE_SO_DO_KEEP_IT_SAFE="Your data is encrypted with a AES 128 bit encryption using the above 32 character key. Without this key it will take the current technology with a brute force attack method more then <a href="http://random-ize.com/how-long-to-hack-pass/" target="_blank" title="How long to hack pass">700 000 000 000 000 000 000 000 000 000 000</a> years to crack theoretically. Unless they have this key above, so do keep it safe."
COM_COMPONENTBUILDER_YOU_ARE_CURRENTLY_VIEWING_THE_TRASHED_ITEMS="You are currently viewing the trashed items."

@ -3610,6 +3610,7 @@ class ComponentbuilderModelAjax extends ListModel
* Search for value in a table
*
* @param string $tableName The main table to search
* @param int $typeSearch The type of search being done
* @param string $searchValue The value to search for
* @param int $matchCase The switch to control match case
* @param int $wholeWord The switch to control whole word
@ -3619,26 +3620,34 @@ class ComponentbuilderModelAjax extends ListModel
* @return array|null
* @since 3.2.0
**/
public function doSearch(string $tableName, string $searchValue,
public function doSearch(string $tableName, int $typeSearch, string $searchValue,
int $matchCase, int $wholeWord, int $regexSearch, int $componentId): ?array
{
// check if this is a valid table
if (SearchFactory::_('Table')->exist($tableName))
{
// load the configurations
SearchFactory::_('Config')->table_name = $tableName;
SearchFactory::_('Config')->search_value = $searchValue;
SearchFactory::_('Config')->match_case = $matchCase;
SearchFactory::_('Config')->whole_word = $wholeWord;
SearchFactory::_('Config')->regex_search = $regexSearch;
SearchFactory::_('Config')->component_id = $componentId;
try
{
// load the configurations
SearchFactory::_('Config')->table_name = $tableName;
SearchFactory::_('Config')->type_search = $typeSearch;
SearchFactory::_('Config')->search_value = $searchValue;
SearchFactory::_('Config')->match_case = $matchCase;
SearchFactory::_('Config')->whole_word = $wholeWord;
SearchFactory::_('Config')->regex_search = $regexSearch;
SearchFactory::_('Config')->component_id = $componentId;
if (($items = SearchFactory::_('Agent')->table($tableName)) !== null)
{
return ['success' => JText::sprintf('COM_COMPONENTBUILDER_WE_FOUND_SOME_INSTANCES_IN_S', $tableName), 'items' => $items];
}
if (($items = SearchFactory::_('Agent')->table($tableName)) !== null)
return ['not_found' => JText::sprintf('COM_COMPONENTBUILDER_NO_INSTANCES_WHERE_FOUND_IN_S', $tableName)];
}
catch(Exception $error)
{
return ['success' => JText::sprintf('COM_COMPONENTBUILDER_WE_FOUND_SOME_INSTANCES_IN_S', $tableName), 'items' => $items];
return ['error' => $error->getMessage()];
}
return ['success' => JText::sprintf('COM_COMPONENTBUILDER_NO_INSTANCES_WHERE_FOUND_S', $tableName)];
}
return ['error' => JText::_('COM_COMPONENTBUILDER_THERE_HAS_BEEN_AN_ERROR_PLEASE_TRY_AGAIN')];
@ -3664,18 +3673,27 @@ class ComponentbuilderModelAjax extends ListModel
// check if this is a valid table
if (SearchFactory::_('Table')->exist($tableName))
{
// load the configurations
SearchFactory::_('Config')->table_name = $tableName;
SearchFactory::_('Config')->search_value = $searchValue;
SearchFactory::_('Config')->replace_value = $replaceValue;
SearchFactory::_('Config')->match_case = $matchCase;
SearchFactory::_('Config')->whole_word = $wholeWord;
SearchFactory::_('Config')->regex_search = $regexSearch;
SearchFactory::_('Config')->component_id = $componentId;
// SearchFactory::_('Agent')->replace(); // TODO show danger message before allowing this!!!!!
try
{
// load the configurations
SearchFactory::_('Config')->table_name = $tableName;
SearchFactory::_('Config')->search_value = $searchValue;
SearchFactory::_('Config')->replace_value = $replaceValue;
SearchFactory::_('Config')->match_case = $matchCase;
SearchFactory::_('Config')->whole_word = $wholeWord;
SearchFactory::_('Config')->regex_search = $regexSearch;
SearchFactory::_('Config')->component_id = $componentId;
return ['success' => JText::sprintf('COM_COMPONENTBUILDER_ALL_FOUND_INSTANCES_IN_S_WHERE_REPLACED', $tableName)];
if (($number = SearchFactory::_('Agent')->replace()) !== 0)
{
return ['success' => JText::sprintf('COM_COMPONENTBUILDER_ALL_FOUND_INSTANCES_IN_S_WHERE_REPLACED', $tableName)];
}
return ['not_found' => JText::sprintf('COM_COMPONENTBUILDER_NO_INSTANCES_WHERE_FOUND_IN_S', $tableName)];
}
catch(Exception $error)
{
return ['error' => $error->getMessage()];
}
}
return ['error' => JText::_('COM_COMPONENTBUILDER_THERE_HAS_BEEN_AN_ERROR_PLEASE_TRY_AGAIN')];
}
@ -3686,28 +3704,41 @@ class ComponentbuilderModelAjax extends ListModel
* @param string $fieldName The field key
* @param int $rowId The item ID
* @param string $tableName The table
* @param string $searchValue The value to search for
* @param string|null $replaceValue The value to replace search value
* @param int $matchCase The switch to control match case
* @param int $wholeWord The switch to control whole word
* @param int $regexSearch The switch to control regex search
*
* @return array
* @since 3.2.0
**/
public function getSearchValue(string $fieldName, int $rowId, string $tableName): array
public function getSearchValue(string $fieldName, int $rowId, string $tableName,
string $searchValue, ?string $replaceValue = null, int $matchCase, int $wholeWord, int $regexSearch): array
{
// check if this is a valid table and field
if ($rowId > 0 && SearchFactory::_('Table')->exist($tableName, $fieldName))
{
// load the configurations
SearchFactory::_('Config')->table_name = $tableName;
// load dummy data... TODO this should not be needed!
SearchFactory::_('Config')->search_value = '';
SearchFactory::_('Config')->replace_value = '';
SearchFactory::_('Config')->match_case = 0;
SearchFactory::_('Config')->whole_word = 0;
SearchFactory::_('Config')->regex_search = 0;
try
{
// load the configurations
SearchFactory::_('Config')->table_name = $tableName;
SearchFactory::_('Config')->type_search = 1;
SearchFactory::_('Config')->search_value = $searchValue;
SearchFactory::_('Config')->replace_value = $replaceValue;
SearchFactory::_('Config')->match_case = $matchCase;
SearchFactory::_('Config')->whole_word = $wholeWord;
SearchFactory::_('Config')->regex_search = $regexSearch;
if (($value = SearchFactory::_('Agent')->getValue($rowId, $fieldName, 0, $tableName)) !== null)
if (($value = SearchFactory::_('Agent')->getValue($rowId, $fieldName, 0, $tableName)) !== null)
{
// load the value
return ['value' => $value];
}
}
catch(Exception $error)
{
// load the value
return ['value' => $value];
return ['error' => $error->getMessage()];
}
}
return ['error' => JText::_('COM_COMPONENTBUILDER_THERE_HAS_BEEN_AN_ERROR_PLEASE_TRY_AGAIN')];
@ -3735,18 +3766,26 @@ class ComponentbuilderModelAjax extends ListModel
// check if this is a valid table and field
if ($rowId > 0 && SearchFactory::_('Table')->exist($tableName, $fieldName))
{
// load the configurations
SearchFactory::_('Config')->table_name = $tableName;
SearchFactory::_('Config')->search_value = $searchValue;
SearchFactory::_('Config')->replace_value = $replaceValue;
SearchFactory::_('Config')->match_case = $matchCase;
SearchFactory::_('Config')->whole_word = $wholeWord;
SearchFactory::_('Config')->regex_search = $regexSearch;
try
{
// load the configurations
SearchFactory::_('Config')->table_name = $tableName;
SearchFactory::_('Config')->type_search = 2;
SearchFactory::_('Config')->search_value = $searchValue;
SearchFactory::_('Config')->replace_value = $replaceValue;
SearchFactory::_('Config')->match_case = $matchCase;
SearchFactory::_('Config')->whole_word = $wholeWord;
SearchFactory::_('Config')->regex_search = $regexSearch;
// load the value
if (($value = SearchFactory::_('Agent')->getValue($rowId, $fieldName, $line, $tableName, true)) !== null)
// load the value
if (($value = SearchFactory::_('Agent')->getValue($rowId, $fieldName, $line, $tableName, true)) !== null)
{
return ['value' => $value];
}
}
catch(Exception $error)
{
return ['value' => $value];
return ['error' => $error->getMessage()];
}
}
return ['error' => JText::_('COM_COMPONENTBUILDER_THERE_HAS_BEEN_AN_ERROR_PLEASE_TRY_AGAIN')];

@ -148,6 +148,50 @@ class ComponentbuilderModelSearch extends ItemModel
return $this->_item[$pk];
}
/**
* Custom Method
*
* @return mixed item data object on success, false on failure.
*
*/
public function getUrlValues()
{
if (!isset($this->initSet) || !$this->initSet)
{
$this->user = JFactory::getUser();
$this->userId = $this->user->get('id');
$this->guest = $this->user->get('guest');
$this->groups = $this->user->get('groups');
$this->authorisedGroups = $this->user->getAuthorisedGroups();
$this->levels = $this->user->getAuthorisedViewLevels();
$this->initSet = true;
}
// Get a db connection.
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
// Get data
$data = [
'type_search' => SearchFactory::_('Config')->get('type_search', 1),
'search_value' => SearchFactory::_('Config')->get('search_value', ''),
'replace_value' => SearchFactory::_('Config')->get('replace_value', ''),
'match_case' => SearchFactory::_('Config')->get('match_case', 0),
'whole_word' => SearchFactory::_('Config')->get('whole_word', 0),
'regex_search' => SearchFactory::_('Config')->get('regex_search', 0)
];
if (empty($data))
{
return false;
}
// return data object.
return $data;
}
/**
* Get the uikit needed components
*

@ -36,8 +36,8 @@ $selectNotice .= '<p>' . JText::_('COM_COMPONENTBUILDER_ENTER_YOUR_SEARCH_TEXT')
</script>
<?php $urlId = (isset($this->item->id)) ? '&id='. (int) $this->item->id : ''; ?>
<div class="alert alert-info" role="alert">
<?php echo JText::_('COM_COMPONENTBUILDER_THIS_AREA_IS_STILL_UNDER_DEVELOPMENT_AND_DOES_NOT_WORK'); ?>
<div class="alert alert-danger" role="alert">
<?php echo JText::_('COM_COMPONENTBUILDER_THIS_AREA_IS_STILL_UNDER_DEVELOPMENT_ALTHOUGH_IT_WORKS_IT_SHOULD_BE_USED_WITH_EXTREME_CAUTION_AS_ITS_NOT_STABLE'); ?>
</div>
<hr />
<?php if(!empty( $this->sidebar)): ?>
@ -52,7 +52,26 @@ $selectNotice .= '<p>' . JText::_('COM_COMPONENTBUILDER_ENTER_YOUR_SEARCH_TEXT')
<form action="<?php echo JRoute::_('index.php?option=com_componentbuilder&view=search'); ?>" method="post"
name="adminForm" id="adminForm" class="form-validate" enctype="multipart/form-data">
<div class="form-horizontal">
<div class="row-fluid">
<div class="row-fluid" id="search_progress_block" style="display: none">
<div class="uk-progress uk-progress-striped uk-active">
<div id="search_progress_bar" class="uk-progress-bar" style="width: 0%;">0%</div>
</div>
</div>
<div class="row-fluid" id="search_details_block" style="display: none">
<span id="search_details">
<span class="search_details_title"><?php echo JText::_('COM_COMPONENTBUILDER_SEARCHED_FOR'); ?></span>:
&nbsp;[<span id="searched" class="found_code">....</span>]&nbsp;&nbsp;&nbsp;&nbsp;
</span>
<span id="replace_details" style="display: none">
<span class="search_details_title"><?php echo JText::_('COM_COMPONENTBUILDER_REPLACED_WITH'); ?></span>:
&nbsp;[<span id="replaced" class="found_code">....</span>]
</span>
<button style="float: right;" type="button" onclick="showSearch();" class="btn button-new btn-success">
<span class="icon-search icon-white" aria-hidden="true"></span>
<?php echo JText::_('COM_COMPONENTBUILDER_SEARCH_DATABASE_AGAIN'); ?>
</button>
</div>
<div class="row-fluid" id="search_settings_block">
<div class="span7">
<?php echo $this->form->renderField('type_search'); ?>
<?php echo $this->form->renderField('search_value'); ?>
@ -62,16 +81,37 @@ $selectNotice .= '<p>' . JText::_('COM_COMPONENTBUILDER_ENTER_YOUR_SEARCH_TEXT')
<?php echo $this->form->renderFieldset('settings'); ?>
</div>
</div>
<div class="row-fluid" id="search_results_view">
<div class="row-fluid" id="search_results_block">
<hr>
<div id="search_results_table_box">
<div id="search_results_table_block">
<?php echo JLayoutHelper::render('table', ['id' => 'search_results_table', 'headers' => $this->table_headers, 'items' => 7, 'init' => false]); ?>
</div>
</div>
<div class="row-fluid" id="item_view_box">
<div class="row-fluid" id="item_view_block">
<hr>
<div id="item_notice"></div>
<?php echo $this->form->getInput('full_text'); ?>
<div>
<span id="item_notice_block" style="display: none">
<span id="item_edit_button"></span>&nbsp;
<?php echo JText::_('COM_COMPONENTBUILDER_TABLE'); ?>:&nbsp;<b><span id="item_table_name">
</span></b>(<?php echo JText::_('COM_COMPONENTBUILDER_ID'); ?>:<b><span id="item_row_id">
</span></b>)&nbsp;|&nbsp;
<?php echo JText::_('COM_COMPONENTBUILDER_FIELD'); ?>:&nbsp;<b><span id="item_field_name">
</span></b>(<?php echo JText::_('COM_COMPONENTBUILDER_LINE'); ?>:<b><span id="item_line_number">
</span></b>)&nbsp;&nbsp;&nbsp;
<button type="button" id="item_button_update" onclick="" class="hasTooltip btn btn-small button-new btn-success"
title="<?php echo JText::_('COM_COMPONENTBUILDER_SAVE_ALL_CHANGES_MADE_TO_THE_SELECTED_ITEM'); ?>">
<?php echo JText::_('COM_COMPONENTBUILDER_SAVE_ITEM'); ?>
</button>
</span>
<span id="update_all_block" style="display: none;">
<button style="float: right;" type="button" onclick="replaceAllCheck();" class="hasTooltip btn btn-small button-new btn-danger"
title="<?php echo JText::_('COM_COMPONENTBUILDER_UPDATE_ALL_ITEMS_FOUND_WITH_THIS_DATABASE_SEARCH_WITH_THE_REPLACE_VALUE'); ?>">
<?php echo JText::_('COM_COMPONENTBUILDER_UPDATE_ALL'); ?>
</button>
</span>
</div>
<hr>
<?php echo $this->form->getInput('item_code'); ?>
</div>
</div>
</form>
@ -79,115 +119,173 @@ $selectNotice .= '<p>' . JText::_('COM_COMPONENTBUILDER_ENTER_YOUR_SEARCH_TEXT')
</div>
<?php if (isset($this->item['tables']) && ComponentbuilderHelper::checkArray($this->item['tables'])) : ?>
<script>
const searchTables = <?php echo json_encode($this->item['tables']); ?>;
// To class="uk-autoload uk-progress" UIkit.notify
// get search table values
const searchTables = <?php echo json_encode($this->item['tables']); ?>;
// the search Ajax URLs
const Url = '<?php echo JUri::base(); ?>index.php?option=com_componentbuilder&format=json&raw=true&<?php echo JSession::getFormToken(); ?>=1&task=ajax.';
// make sure our controller is set
let controller = null;
// start search time keepers
var startSearchTime, endSearchTime;
// active edit button of row selected
var editButtonSelected;
// get search progress area
const searchProgressObject = document.getElementById("search_progress_block");
const searchProgressBarObject = document.getElementById("search_progress_bar");
// get search settings area
const searchSettingsObject = document.getElementById("search_settings_block");
const searchDetailsObject = document.getElementById("search_details_block");
const searchedObject = document.getElementById("searched");
// get replace settings area
const replaceDetailsObject = document.getElementById("replace_details");
const replacedObject = document.getElementById("replaced");
// set the search mode object
const modeObject = document.getElementById("type_search");
// the search Ajax URLs
const Url = '<?php echo JUri::base(); ?>index.php?option=com_componentbuilder&format=json&raw=true&<?php echo JSession::getFormToken(); ?>=1&task=ajax.';
// set the search settings objects
const searchObject = document.getElementById("search_value");
const replaceObject = document.getElementById("replace_value");
const matchObject = document.getElementById("search_behaviour0");
const wholeObject = document.getElementById("search_behaviour1");
const regexObject = document.getElementById("search_behaviour2");
const tableObject = document.getElementById("table_name");
// make sure our controller is set
let controller = null;
// Do the search on key up of search or replace input elements
searchObject.onkeyup = onChange;
// set the search mode object
const modeObject = document.getElementById("type_search");
// when the made changes and there is replace value do search
modeObject.onchange = onChange;
replaceObject.onkeyup = onChange;
// set the search settings objects
const searchObject = document.getElementById("search_value");
const replaceObject = document.getElementById("replace_value");
const matchObject = document.getElementById("search_behaviour0");
const wholeObject = document.getElementById("search_behaviour1");
const regexObject = document.getElementById("search_behaviour2");
const tableObject = document.getElementById("table_name");
// Do the search on key up of search input elements
matchObject.onchange = onChange;
wholeObject.onchange = onChange;
regexObject.onchange = onChange;
tableObject.onchange = onChange;
// Do the search on key up of search or replace input elements
searchObject.onkeyup = onChange;
replaceObject.onkeyup = onChange;
// set the item notice area
const itemNoticeObject = document.getElementById("item_notice_block");
const itemEditButtonObject = document.getElementById("item_edit_button");
const itemTableNameObject = document.getElementById("item_table_name");
const itemRowIdObject = document.getElementById("item_row_id");
const itemFieldNameObject = document.getElementById("item_field_name");
const itemLineNumberObject = document.getElementById("item_line_number");
// Do the search on key up of search input elements
matchObject.onchange = onChange;
wholeObject.onchange = onChange;
regexObject.onchange = onChange;
tableObject.onchange = onChange;
// set the update buttons
const buttonUpdateItemObject = document.getElementById("item_button_update");
const buttonUpdateAllObject = document.getElementById("update_all_block");
// get the editor
var editorObject;
// set some global objects
document.addEventListener('DOMContentLoaded', function () {
// get the editor
var editorObject;
var editorBoxObject;
var editorNoticeObject;
// set some global objects
document.addEventListener('DOMContentLoaded', function () {
// get the editor
editorObject = Joomla.editors.instances['full_text'];
editorBoxObject = document.getElementById("item_view_box");
editorNoticeObject = document.getElementById("item_notice");
editorObject = Joomla.editors.instances['item_code'];
});
// configurations of the table
const tableConfigObject = {
responsive: true,
order: [[ 2, "asc" ]],
select: true,
paging: true,
lengthMenu: [5, 10, 20 ,50, 80, 100, 150, 200, 500, 1000, 1500, 2000],
pageLength: 80,
scrollY: 170,
columnDefs: [
{ 'targets': [ 0 ], 'visible': false, 'searchable': false },
{ 'targets': [ 0, 1 ], type: 'html' },
{ responsivePriority: 1, targets: 1 },
{ responsivePriority: 2, targets: 2 },
{ responsivePriority: 3, targets: 3 }
],
columns: [
{
data: 'edit'
},
{
data: 'code'
},
{
data: 'table'
},
{
data: 'field'
},
{
data: 'id',
width: "15px",
className: "small_column"
},
{
data: 'line',
width: "15px",
className: "small_column"
}
]
};
// set some table object