From d4843d66963e77a7e733f9144f1b2c011582a26d Mon Sep 17 00:00:00 2001 From: Llewellyn van der Merwe Date: Thu, 20 Oct 2022 16:40:18 +0200 Subject: [PATCH] Improved the compiler power building class. Add the search form and the needed ajax functions. --- README.md | 6 +- admin/README.txt | 6 +- admin/assets/js/search.js | 312 ++++++++++++++++++ admin/controllers/ajax.json.php | 139 ++++++++ admin/controllers/compiler.php | 4 +- .../en-GB/en-GB.com_componentbuilder.ini | 21 ++ admin/models/ajax.php | 113 ++++++- admin/models/compiler.php | 151 +++++---- admin/models/search.php | 38 ++- admin/sql/install.mysql.utf8.sql | 7 +- admin/views/compiler/tmpl/default.php | 115 +++---- admin/views/compiler/view.html.php | 26 +- admin/views/search/tmpl/default.php | 79 +++-- admin/views/search/view.html.php | 224 ++++++++++++- componentbuilder.xml | 2 +- .../src/Componentbuilder/Compiler/Power.php | 20 +- .../Abstraction/{Type.php => Engine.php} | 4 +- .../src/Componentbuilder/Search/Agent.php | 70 +++- .../Componentbuilder/Search/Database/Get.php | 6 +- .../Search/{Type => Engine}/Basic.php | 6 +- .../Search/{Type => Engine}/Regex.php | 6 +- .../Search/{Type => Engine}/index.html | 0 .../Search/Service/Search.php | 4 +- .../src/Componentbuilder/Search/Table.php | 20 +- .../VDM.Joomla/src/Utilities/GetHelper.php | 75 +++-- 25 files changed, 1222 insertions(+), 232 deletions(-) create mode 100644 admin/assets/js/search.js rename libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Abstraction/{Type.php => Engine.php} (93%) rename libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/{Type => Engine}/Basic.php (92%) rename libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/{Type => Engine}/Regex.php (89%) rename libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/{Type => Engine}/index.html (100%) diff --git a/README.md b/README.md index 95a187961..3910a0eee 100644 --- a/README.md +++ b/README.md @@ -140,13 +140,13 @@ 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*: 6th October, 2022 ++ *Last Build*: 20th October, 2022 + *Version*: 3.1.8 + *Copyright*: Copyright (C) 2015 Vast Development Method. All rights reserved. + *License*: GNU General Public License version 2 or later; see LICENSE.txt -+ *Line count*: **331795** ++ *Line count*: **332785** + *Field count*: **2004** -+ *File count*: **2172** ++ *File count*: **2173** + *Folder count*: **378** > This **component** was build with a [Joomla](https://extensions.joomla.org/extension/component-builder/) [Automated Component Builder](http://joomlacomponentbuilder.com). diff --git a/admin/README.txt b/admin/README.txt index 95a187961..3910a0eee 100644 --- a/admin/README.txt +++ b/admin/README.txt @@ -140,13 +140,13 @@ 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*: 6th October, 2022 ++ *Last Build*: 20th October, 2022 + *Version*: 3.1.8 + *Copyright*: Copyright (C) 2015 Vast Development Method. All rights reserved. + *License*: GNU General Public License version 2 or later; see LICENSE.txt -+ *Line count*: **331795** ++ *Line count*: **332785** + *Field count*: **2004** -+ *File count*: **2172** ++ *File count*: **2173** + *Folder count*: **378** > This **component** was build with a [Joomla](https://extensions.joomla.org/extension/component-builder/) [Automated Component Builder](http://joomlacomponentbuilder.com). diff --git a/admin/assets/js/search.js b/admin/assets/js/search.js new file mode 100644 index 000000000..0b439743f --- /dev/null +++ b/admin/assets/js/search.js @@ -0,0 +1,312 @@ +/** + * @package Joomla.Component.Builder + * + * @created 30th April, 2015 + * @author Llewellyn van der Merwe + * @git Joomla Component Builder + * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +/* JS Document */ +/** + * JS Function to execute the search + */ +const doSearch = async (signal, tables) => { + try { + let searchValue = document.querySelector('input[name="search_value"]').value; + let replaceValue = document.querySelector('input[name="replace_value"]').value; + + // Display 'loading' message in search results message div + document.getElementById('search-mssg-box').innerHTML = + '' + + '
' + + ' 0% ' + + 'Loading for search text: ' + searchValue + '' + ; + // Clear results table + let search_loading_percent = document.getElementById('search-loading-percent'); + let tbl_obj_body = document.getElementById('search-results-tbl-tbody'); + tbl_obj_body.innerHTML = ''; + let abort_this_search_value = false; + + let total = 0; + let index; + + for (index = 0; index < searchTables.length; index++) { + const formData = new FormData(); + let tableName = searchTables[index]; + + formData.append('table_name', ''); + formData.append('search_value', searchValue); + formData.append('replace_value', replaceValue); + formData.append('match_case', document.querySelector('input[name="match_case"]').checked ? 1 : 0); + formData.append('whole_word', document.querySelector('input[name="whole_word"]').checked ? 1 : 0); + formData.append('regex_search', document.querySelector('input[name="regex_search"]').checked ? 1 : 0); + formData.append('table_name', tableName); + + let url = document.getElementById('adminForm').getAttribute('action') + '&layout=dosearch'; + let options = { + signal: signal, + method: 'POST', // *GET, POST, PUT, DELETE, etc. + body: formData + } + + if (abort_this_search_value) { + console.log('Aborting this searchValue:' + searchValue); + break; + } + console.log(total + ' -- SEARCHING: ' + searchValue + ' @[' + tableName + ']'); + const response = await fetch(url, options) + // Note: response.text() is a promise ... + .then(response => { + total++; + //console.log(total + ' ' + sTables.length); + if (sTables.length == total) setTimeout(function () { + document.getElementById('search-mssg-box').innerHTML = ''; + }, 200); + + response.text().then(data => { + console.log('++ Fetched for ' + searchValue + ' [' + tableName + ']'); + let percent = 100.0 * (total / sTables.length); + search_loading_percent.innerHTML = '' + percent.toFixed(2) + '%'; + document.getElementById('search-loading-progressbar').value = percent; + + let use_json = false, json_data = false, items = false; + if (use_json) { + try { + json_data = data ? JSON.parse(data) : false; + items = json_data ? json_data.items : false; + } catch (error) { + console.log(error); + } + } + + // Very fast and low memory display HTML table row prepared server-side via PHP instead of JS !! + if (!json_data) { + tbl_obj_body.innerHTML = tbl_obj_body.innerHTML + data; + } + + // Very slow fast and very high memory: Display HTML table rows by creating them now in browser (client-side) via JS instead of using PHP + if (json_data && items) { + let table_rows = ''; + for (const [row_num, row_field_vals] of Object.entries(items)) { + for (const [fname, fvals] of Object.entries(row_field_vals)) { + for (const [line, fval] of Object.entries(fvals)) { + let lnk = 'getFSText(this, \'' + tableName + '\', ' + row_num + ', \'' + fname + '\', line)'; + let val = fval; + val = val.replaceAll(marker_start, ''); + val = val.replaceAll(marker_end, ''); + table_rows = table_rows + '' + + '' + val + '' + + '' + tableName + '' + + '' + fname + '' + + '' + row_num + '' + + '' + line + '' + + ''; + } + } + } + tbl_obj_body.innerHTML = tbl_obj_body.innerHTML + table_rows; + } // END IF json_data && items + + }); + }) + .catch(error => { + total++; + if (sTables.length == total) document.getElementById('search-mssg-box').innerHTML = ''; + // Stop further searches for this search value + if (error.name === "AbortError") abort_this_search_value = true; + error.name === "AbortError" + ? console.log(" ... ABORTED fetch() for: " + searchValue) + : console.log(error.toString()); + }); + } + } catch (error) { + console.log(error); + } finally { + // Executed regardless if we caught the error + } +}; + +/** + * JS Function to execute the search + */ +const getFSText = async (el, table_name, row_id, field_name, line) => { + let sibling = el.parentNode.firstElementChild; + do { + sibling != el + ? sibling.classList.remove('active') + : sibling.classList.add('active'); + } while (sibling = sibling.nextElementSibling); + + try { + const formData = new FormData(); + + formData.append('table_name', table_name); + formData.append('get_full_search_text', 1); + formData.append('row_id', row_id); + formData.append('field_name', field_name); + + //let url = `https://jsonplaceholder.typicode.com/posts/${searchValue}`, + let url = document.getElementById('adminForm').getAttribute('action') + '&layout=dosearch'; + let options = { + method: 'POST', // *GET, POST, PUT, DELETE, etc. + mode: 'cors', // no-cors, *cors, same-origin + cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached + credentials: 'same-origin', // include, *same-origin, omit + /* + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json', //'application/x-www-form-urlencoded', + },*/ + redirect: 'follow', // manual, *follow, error + referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url + // body: JSON.stringify(formData) // body data type must match "Content-Type" header + body: formData + } + + // Clear full text box + document.getElementById('match-full-text-box').innerHTML = 'Loading ...'; + const response = await fetch(url, options) + // Note: response.text() is a promise ... + .then(response => { + response.text().then(data => { + console.log("Fetched full text for row: " + row_id + ' field name: ' + field_name + ' for Table: ' + table_name); + document.getElementById('match-full-text-box').innerHTML = '
' + + table_name + ' @ ' + field_name + ': ' + row_id + '
'; + document.getElementById('match-full-text-box').style.display = ''; + attachCodeMirror(jQuery('#match-full-text'), null); + cm_toggle_fully_searchable('match-full-text', 1); + cm_jumpToLine('match-full-text', line); + //cm_toggle_plain_textarea('match-full-text-box', 1); + }); + }) + .catch(error => { + // Stop further searches for this search value + if (error.name === "AbortError") abort_this_search_value = true; + error.name === "AbortError" + ? console.log(" ... ABORTED fetch() for: " + searchValue) + : console.log(error.toString()); + }); + } catch (error) { + console.log(error); + } finally { + // Executed regardless if we caught the error + } +}; + + +const cm_jumpToLine = function (tag_id, row) +{ + console.log('#' + tag_id); + let codeMirrorEl = jQuery('#' + tag_id).next('.CodeMirror'); + if (!codeMirrorEl.length) return; + let codeMirrorRef = jQuery('#' + tag_id).next('.CodeMirror').get(0).CodeMirror; + let t = codeMirrorRef.charCoords({line: row, ch: 0}, "local").top; + let middleHeight = codeMirrorRef.getScrollerElement().offsetHeight / 2; + codeMirrorRef.scrollTo(null, t - middleHeight - 5); +} + +/* Attach CodeMirror with optional settings */ +const cm_toggle_fully_searchable = function (el, toggle) +{ + if (typeof CodeMirror === 'undefined') {alert('CodeMirror not loaded'); return;} + + jQuery([el]).each(function(i, tag_id) { + let codeMirrorEl = jQuery('#' + tag_id).next('.CodeMirror'); + if (!codeMirrorEl.length) return; + let codeMirrorRef = jQuery('#' + tag_id).next('.CodeMirror').get(0).CodeMirror; + codeMirrorRef.setOption('viewportMargin', toggle ? '9999' : ''); + }); + +} + +const cm_toggle_plain_textarea = function (el, toggle) +{ + if (typeof CodeMirror === 'undefined') {alert('CodeMirror not loaded'); return;} + + jQuery([el]).each(function(i, tag_id) { + let codeMirrorEl = jQuery('#' + tag_id).next('.CodeMirror'); + if (toggle) { + let options = jQuery('#' + tag_id).data('options'); + options.viewportMargin = jQuery('#cm_toggle_fully_searchable_btn input').prop('checked') ? '9999' : ''; + jQuery('#' + tag_id).prev('p').show(); + attachCodeMirror(jQuery('#' + tag_id), options); + } + else if (codeMirrorEl.length) + { + let codeMirrorRef = codeMirrorEl.get(0).CodeMirror; + jQuery('#' + tag_id).prev('p').hide(); + jQuery('#' + tag_id).css({width: '100%', height: '400px'}); + codeMirrorRef.toTextArea(); + // Remove codemirror container in case that removing it failed + if (jQuery('#' + tag_id).next('.CodeMirror').length) { + jQuery('#' + tag_id).next('.CodeMirror').remove(); + } + } + }); + +} + +const attachCodeMirror = function (txtareas, CMoptions, mode) +{ + CMoptions = typeof CMoptions!=='undefined' && CMoptions ? CMoptions : { + mode: mode || 'application/x-httpd-php', + indentUnit: 2, + lineNumbers: true, + matchBrackets: true, + lineWrapping: true, + onCursorActivity: function(CM) + { + CM.setLineClass(hlLine, null); + hlLine = CM.setLineClass(CM.getCursor().line, 'activeline'); + } + }; + + var editor, theArea; + txtareas.each(function(i, txtarea) + { + theArea = jQuery(txtarea); + theArea.removeClass(); // Remove all classes from the textarea + editor = CodeMirror.fromTextArea(theArea.get(0), CMoptions); + editor.refresh(); + }); + + return txtareas.length==1 ? editor : true; +} + +/** + * JS Function to execute (A) on search text change , (B) on search options changes + */ +const onChange = () => { + const searchValue = searchValueInp.value; + if (searchValue.length > 2) { + // Cancel any ongoing requests + if (controller) controller.abort(); + + // Create new controller and issue new request + controller = new AbortController(); + doSearch(controller.signal, sTables); + } else { + // Clear any message in search results message div + //document.getElementById('search-mssg-box').innerHTML = ''; + } +}; + +const previewReplace = () => { + const replaceValue = replaceValueInp.value; + console.log(replaceValueInp); + if (replaceValue.length) { + document.getElementById('search-mssg-box').innerHTML = replaceValue; + } +} + +// Do the search on key up of search or replace input element +searchValueInp.onkeyup = onChange; +replaceValueInp.onkeyup = previewReplace; + +// Do the search on key up of search input element +caseSensitiveLbl.onchange = onChange; +completeWordLbl.onchange = onChange; +regexpSearchLbl.onchange = onChange; diff --git a/admin/controllers/ajax.json.php b/admin/controllers/ajax.json.php index a626d5936..3e31a059d 100644 --- a/admin/controllers/ajax.json.php +++ b/admin/controllers/ajax.json.php @@ -69,6 +69,9 @@ class ComponentbuilderControllerAjax extends BaseController $this->registerTask('getCodeGlueOptions', 'ajax'); $this->registerTask('searchTable', 'ajax'); $this->registerTask('updateTable', 'ajax'); + $this->registerTask('getSearchValue', 'ajax'); + $this->registerTask('getReplaceValue', 'ajax'); + $this->registerTask('setValue', 'ajax'); $this->registerTask('snippetDetails', 'ajax'); $this->registerTask('setSnippetGithub', 'ajax'); $this->registerTask('getSnippets', 'ajax'); @@ -1726,6 +1729,142 @@ class ComponentbuilderControllerAjax extends BaseController } } break; + case 'getSearchValue': + try + { + $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) + { + $result = $this->getModel('ajax')->getSearchValue($field_nameValue, $row_idValue, $table_nameValue); + } + else + { + $result = false; + } + if($callback) + { + echo $callback . "(".json_encode($result).");"; + } + elseif($returnRaw) + { + echo json_encode($result); + } + else + { + echo "(".json_encode($result).");"; + } + } + catch(Exception $e) + { + if($callback) + { + echo $callback."(".json_encode($e).");"; + } + elseif($returnRaw) + { + echo json_encode($e); + } + else + { + echo "(".json_encode($e).");"; + } + } + break; + case 'getReplaceValue': + try + { + $field_nameValue = $jinput->get('field_name', NULL, 'WORD'); + $row_idValue = $jinput->get('row_id', NULL, 'INT'); + $line_nrValue = $jinput->get('line_nr', 0, 'STRING'); + $table_nameValue = $jinput->get('table_name', NULL, 'WORD'); + $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')->getReplaceValue($field_nameValue, $row_idValue, $line_nrValue, $table_nameValue, $search_valueValue, $replace_valueValue, $match_caseValue, $whole_wordValue, $regex_searchValue); + } + else + { + $result = false; + } + if($callback) + { + echo $callback . "(".json_encode($result).");"; + } + elseif($returnRaw) + { + echo json_encode($result); + } + else + { + echo "(".json_encode($result).");"; + } + } + catch(Exception $e) + { + if($callback) + { + echo $callback."(".json_encode($e).");"; + } + elseif($returnRaw) + { + echo json_encode($e); + } + else + { + echo "(".json_encode($e).");"; + } + } + break; + case 'setValue': + try + { + $valueValue = $jinput->get('value', NULL, 'RAW'); + $row_idValue = $jinput->get('row_id', NULL, 'INT'); + $field_nameValue = $jinput->get('field_name', NULL, 'WORD'); + $table_nameValue = $jinput->get('table_name', NULL, 'WORD'); + if($valueValue && $user->id != 0 && $row_idValue && $field_nameValue && $table_nameValue) + { + $result = $this->getModel('ajax')->setValue($valueValue, $row_idValue, $field_nameValue, $table_nameValue); + } + else + { + $result = false; + } + if($callback) + { + echo $callback . "(".json_encode($result).");"; + } + elseif($returnRaw) + { + echo json_encode($result); + } + else + { + echo "(".json_encode($result).");"; + } + } + catch(Exception $e) + { + if($callback) + { + echo $callback."(".json_encode($e).");"; + } + elseif($returnRaw) + { + echo json_encode($e); + } + else + { + echo "(".json_encode($e).");"; + } + } + break; case 'snippetDetails': try { diff --git a/admin/controllers/compiler.php b/admin/controllers/compiler.php index e4411c370..2cde5d620 100644 --- a/admin/controllers/compiler.php +++ b/admin/controllers/compiler.php @@ -51,7 +51,7 @@ class ComponentbuilderControllerCompiler extends AdminController * * @return true on success */ - public function getCompilerAnimations() + public function getDynamicContent() { // Check for request forgeries JSession::checkToken() or jexit(JText::_('JINVALID_TOKEN')); @@ -65,7 +65,7 @@ class ComponentbuilderControllerCompiler extends AdminController { // get the model $model = $this->getModel('compiler'); - if ($model->getCompilerAnimations($message)) + if ($model->getDynamicContent($message)) { $message = JText::_('COM_COMPONENTBUILDER_BALL_THE_COMPILER_ANIMATIONS_WERE_SUCCESSFULLY_DOWNLOADED_TO_THIS_JOOMLA_INSTALLB'); $this->setRedirect($redirect_url, $message, 'message'); diff --git a/admin/language/en-GB/en-GB.com_componentbuilder.ini b/admin/language/en-GB/en-GB.com_componentbuilder.ini index e27fb16b5..19e0214b1 100644 --- a/admin/language/en-GB/en-GB.com_componentbuilder.ini +++ b/admin/language/en-GB/en-GB.com_componentbuilder.ini @@ -1331,6 +1331,7 @@ COM_COMPONENTBUILDER_BASIC_TUTORIAL_ON_GIT_BSB="Basic Tutorial on git: %s COM_COMPONENTBUILDER_BBEST_TO_NOT_CONTINUEBBR_WE_COULD_NOT_LOAD_THE_CHECKSUM_FOR_THIS_PACKAGE_AND_SO_NO_VALIDATION_WAS_POSSIBLE_THIS_MAY_BE_DUE_TO_YOUR_NETWORK_OR_A_CHANGE_TO_THAT_PACKAGE_NAME="Best to not continue!
We could not load the checksum for this package, and so no validation was possible. This may be due to your network, or a change to that package name." COM_COMPONENTBUILDER_BBEST_TO_NOT_CONTINUEBBR_YOU_CAN_REFRESH_AND_TRY_AGAINBR_BUT_NOTE_THAT_THIS_PACKAGE_BFAILEDB_CHECKSUM_VALIDATION_THIS_COULD_BE_A_SERIOUS_SECURITY_BREACH_DO_NOT_CONTINUE="Best to not continue!
You can Refresh and try again.
But note that this package FAILED checksum validation, this could be a serious security breach! DO NOT CONTINUE!!!" COM_COMPONENTBUILDER_BCUSTOM_FILESB_NOT_MOVED_TO_CORRECT_LOCATION="Custom files not moved to correct location!" +COM_COMPONENTBUILDER_BEHAVIOUR="Behaviour" COM_COMPONENTBUILDER_BEHIND="Behind" COM_COMPONENTBUILDER_BEHIND_MEANS_YOUR_BLOCAL_SNIPPETB_WITH_THE_SAME_NAME_LIBRARY_AND_TYPE_HAS_A_BOLDER_MODIFIED_DATEB_THEN_THE_COMMUNITY_SNIPPET_WITH_THE_SAME_NAME_LIBRARY_AND_TYPE="Behind means your local snippet (with the same name, library and type) has a older modified date then the community snippet (with the same name, library and type)." COM_COMPONENTBUILDER_BETA_RELEASE="Beta Release" @@ -1721,6 +1722,7 @@ COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_N_ITEMS_UNFEATURED="%s Components Ad COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_N_ITEMS_UNFEATURED_1="%s Component Admin Views unfeatured." COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_N_ITEMS_UNPUBLISHED="%s Components Admin Views unpublished." COM_COMPONENTBUILDER_COMPONENTS_ADMIN_VIEWS_N_ITEMS_UNPUBLISHED_1="%s Component Admin Views unpublished." +COM_COMPONENTBUILDER_COMPONENTS_BR_SMALLDISABLED_SOONSMALL="Components
(disabled... soon!)" COM_COMPONENTBUILDER_COMPONENTS_CONFIG="Components Config" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_ACCESS="Components Config Access" COM_COMPONENTBUILDER_COMPONENTS_CONFIG_ACCESS_DESC="Allows the users in this group to access access components config" @@ -4717,6 +4719,8 @@ COM_COMPONENTBUILDER_EMLICENSEEM_BSB="License: %s" COM_COMPONENTBUILDER_EMOWNEREM_BSB="Owner: %s" COM_COMPONENTBUILDER_EMPTY_TRASH="Empty trash" COM_COMPONENTBUILDER_EMWEBSITEEM_BSB="Website: %s" +COM_COMPONENTBUILDER_ENTER_YOUR_REPLACE_TEXT="Enter your replace text" +COM_COMPONENTBUILDER_ENTER_YOUR_SEARCH_TEXT="Enter your search text." COM_COMPONENTBUILDER_EQUAL="Equal" COM_COMPONENTBUILDER_EQUAL_MEANS_THAT_THE_COMMUNITY_SNIPPET_WITH_THE_SAME_NAME_LIBRARY_AND_TYPE_AND_YOUR_LOCAL_SNIPPET_WITH_THE_SAME_NAME_LIBRARY_AND_TYPE_HAS_THE_SAME_BCREATIONB_AND_BMODIFIED_DATEB="Equal means that the community snippet (with the same name, library and type) and your local snippet (with the same name, library and type) has the same creation and modified date." COM_COMPONENTBUILDER_ERROR="Error" @@ -5444,7 +5448,9 @@ COM_COMPONENTBUILDER_FOLDER_BSB_WAS_MOVED_TO_BSB="Folder %s was moved to COM_COMPONENTBUILDER_FOLDER_BSB_WAS_NOT_MOVED_TO_BSB="Folder %s was not moved to %s" COM_COMPONENTBUILDER_FORCE_LOCAL_UPDATE="Force Local Update" COM_COMPONENTBUILDER_FORCE_THAT_THIS_JCB_PACKAGE_IMPORT_SEARCH_FOR_LOCAL_ITEMS_TO_BE_DONE_WITH_GUID_VALUE_ONLY_IF_BMERGEB_IS_SET_TO_YES_ABOVE="Force that this JCB package import (search for local items) to be done with GUID value only, if Merge is set to yes above." +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: %s" @@ -5587,6 +5593,8 @@ COM_COMPONENTBUILDER_HELP_DOCUMENT_URL_MESSAGE="Error! Please add url here." COM_COMPONENTBUILDER_HELP_DOCUMENT_VERSION_DESC="A count of the number of times this Help Document has been revised." COM_COMPONENTBUILDER_HELP_DOCUMENT_VERSION_LABEL="Version" COM_COMPONENTBUILDER_HELP_MANAGER="Help" +COM_COMPONENTBUILDER_HERE_YOU_CAN_ENTER_THE_REPLACE_TEXT_THAT_YOU_WOULD_LIKE_TO_USE_AS_REPLACEMENT_FOR_THE_SEARCH_TEXT_FOUND="Here you can enter the replace text that you would like to use as replacement for the search text found." +COM_COMPONENTBUILDER_HERE_YOU_CAN_ENTER_YOUR_SEARCH_TEXT="Here you can enter your search text." COM_COMPONENTBUILDER_HFOUR_CLASSNAVHEADERCOPYRIGHTHFOURPSP="

%s

" COM_COMPONENTBUILDER_HFOUR_CLASSNAVHEADERLICENSEHFOURPSP="

%s

" COM_COMPONENTBUILDER_HI="Hi" @@ -7738,6 +7746,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_LINK="Link" COM_COMPONENTBUILDER_LINK_LOCAL_DYNAMIC="Link & Local (dynamic)" COM_COMPONENTBUILDER_LINK_TO_THE_CONTRIBUTOR="Link to the contributor" @@ -7749,6 +7758,7 @@ COM_COMPONENTBUILDER_LOCAL_GET="Local (get)" COM_COMPONENTBUILDER_LOCAL_SNIPPET="Local snippet" COM_COMPONENTBUILDER_MAIN_MENU="Main Menu" COM_COMPONENTBUILDER_MATCH_BEHAVIOUR="Match Behaviour" +COM_COMPONENTBUILDER_MATCH_CASE="Match Case" COM_COMPONENTBUILDER_MATCH_FIELD="Match Field" COM_COMPONENTBUILDER_MATCH_OPTIONS="Match Options" COM_COMPONENTBUILDER_MAX_LENGTH_ONLY_FOUR_TEXT_FIELD="Max Length (only 4 text_field)" @@ -7756,6 +7766,7 @@ COM_COMPONENTBUILDER_MERGE="Merge" COM_COMPONENTBUILDER_METHODS="Methods" COM_COMPONENTBUILDER_MINIFY_JAVASCRIPT="Minify JavaScript" COM_COMPONENTBUILDER_MIN_LENGTH_ONLY_FOUR_TEXT_FIELD="Min Length (only 4 text_field)" +COM_COMPONENTBUILDER_MODE="Mode" COM_COMPONENTBUILDER_MODEL_AFTER_MODELLING="Model (after modelling)" COM_COMPONENTBUILDER_MODEL_BEFORE_MODELLING="Model (before modelling)" COM_COMPONENTBUILDER_MODULE="Module" @@ -8141,9 +8152,11 @@ COM_COMPONENTBUILDER_PUBLISHING="Publishing" COM_COMPONENTBUILDER_README="Readme" COM_COMPONENTBUILDER_READY_TO_COMPILE_A_COMPONENT="Ready to compile a component" COM_COMPONENTBUILDER_REFRESH="Refresh" +COM_COMPONENTBUILDER_REGEX_SEARCH="Regex Search" 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_REPORT_AN_ISSUE_BSB="Report an issue: %s" 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="list": 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." @@ -8162,6 +8175,7 @@ COM_COMPONENTBUILDER_SEARCH_ACCESS_DESC="Allows the users in this group to acces 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_DESC="JCB Search" +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_SEE_ALL_IMPORT_INFO="See All Import Info" @@ -8175,8 +8189,10 @@ COM_COMPONENTBUILDER_SELECT_A_SNIPPET="select a snippet" COM_COMPONENTBUILDER_SELECT_COMPONENT="Select Component" COM_COMPONENTBUILDER_SELECT_EXTENSION="Select Extension" COM_COMPONENTBUILDER_SELECT_THE_COMPONENT_TO_COMPILE="Select the component to compile" +COM_COMPONENTBUILDER_SELECT_THE_COMPONENT_TO_SEARCH="Select the component to search" COM_COMPONENTBUILDER_SELECT_THE_COMPONENT_YOUR_WOULD_LIKE_TO_IMPORT="Select the component your would like to import." COM_COMPONENTBUILDER_SELECT_THE_PACKAGE_TO_IMPORT="Select the package to import" +COM_COMPONENTBUILDER_SELECT_THE_TABLE_TO_SEARCH="Select the table to search" COM_COMPONENTBUILDER_SERVER="Server" COM_COMPONENTBUILDER_SERVERS="Servers" COM_COMPONENTBUILDER_SERVERS_ACCESS="Servers Access" @@ -8317,6 +8333,7 @@ COM_COMPONENTBUILDER_SERVER_VERSION_DESC="A count of the number of times this Se COM_COMPONENTBUILDER_SERVER_VERSION_LABEL="Version" COM_COMPONENTBUILDER_SET_A_CLASS_VALUE_FOR_THE_LIST_VIEW_OF_THIS_FIELD="Set a class value for the list view of this field." COM_COMPONENTBUILDER_SET_CUSTOM="Set Custom" +COM_COMPONENTBUILDER_SET_THE_SEARCH_BEHAVIOUR_HERE="Set the search behaviour here." COM_COMPONENTBUILDER_SHARE_SNIPPETS="Share Snippets" COM_COMPONENTBUILDER_SHOULD_JCB_ADD_ANY_POWERS_THAT_ARE_CONNECTED_TO_THIS_COMPONENT_THIS_MAY_BE_HELPFUL_IF_YOU_ARE_LOADING_POWERS_VIA_ANOTHER_COMPONENT_AND_WOULD_LIKE_TO_AVOID_ADDING_IT_TO_BOTH_JUST_REMEMBER_THAT_IN_THIS_CASE_YOU_NEED_TO_LOAD_THE_POWERS_VIA_A_PLUGIN="Should JCB add any powers that are connected to this component? This may be helpful if you are loading powers via another component, and would like to avoid adding it to both, just remember that in this case you need to load the powers via a plugin." COM_COMPONENTBUILDER_SHOULD_JCB_INSERT_THE_CUSTOM_CODE_PLACEHOLDERS_THIS_IS_ONLY_APPLICABLE_IF_THIS_COMPONENT_HAS_CUSTOM_CODE="Should JCB insert the custom code placeholders? This is only applicable if this component has custom code." @@ -9000,6 +9017,8 @@ COM_COMPONENTBUILDER_S_S_NUMBER_BSB_COULD_NOT_BE_DOWNLOADED_SUCCESSFULLY_TO_THIS COM_COMPONENTBUILDER_S_WE_DETECTED_A_CHANGE_IN_BEXTERNALCODEB_BUT_YOU_DO_NOT_HAVE_PERMISSION_TO_ALLOW_THIS_CHANGE_SO_BSB_WAS_REMOVED_FROM_THE_COMPILATION_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_INFOBR_SMALLADMIN_ACCESS_REQUIREDSMALL="%s, we detected a change in EXTERNALCODE, but you do not have permission to allow this change so %s was removed from the compilation. Please contact your system administrator for more info!
(admin access required)" COM_COMPONENTBUILDER_S_WE_DETECTED_BNEW_EXTERNALCODEB_BUT_YOU_DO_NOT_HAVE_PERMISSION_TO_ALLOW_THIS_NEW_CODESTRING_SO_BSB_WAS_REMOVED_FROM_THE_COMPILATION_PLEASE_CONTACT_YOU_SYSTEM_ADMINISTRATOR_FOR_MORE_INFOBR_SMALLADMIN_ACCESS_REQUIREDSMALL="%s, we detected NEW EXTERNALCODE, but you do not have permission to allow this new code/string so %s was removed from the compilation. Please contact you system administrator for more info!
(admin access required)" COM_COMPONENTBUILDER_TAB="Tab" +COM_COMPONENTBUILDER_TABLE="Table" +COM_COMPONENTBUILDER_TABLES="Tables" COM_COMPONENTBUILDER_TABLE_BSB_NOT_FOUND_IN_THE_LOCAL_DATABASE_SO_ITS_VALUES_COULD_NOT_BE_IMPORTED_PLEASE_UPDATE_YOUR_JCB_INSTALL_AND_TRY_AGAIN="Table %s not found in the local database so its values could not be imported, please update your JCB install and try again." COM_COMPONENTBUILDER_TABLE_BSB_NOT_FOUND_IN_THE_LOCAL_DATABASE_SO_ITS_VALUES_COULD_NOT_BE_IMPORTED_THE_WHOLE_POWERS_FEATURE_IS_ONLY_AVAILABLE_TO_A_HREFSPRO_MEMBERSA_AT_THIS_TIME="Table %s not found in the local database so its values could not be imported. The whole powers feature is only available to PRO Members at this time." COM_COMPONENTBUILDER_TARGET_BEHAVIOUR="Target Behaviour" @@ -9388,6 +9407,7 @@ COM_COMPONENTBUILDER_WE_FOUND_DYNAMIC_CODE_BALL_IN_ONE_LINEB_AND_IGNORED_IT_PLEA COM_COMPONENTBUILDER_WE_FOUND_SOME_INSTANCES_IN_S="We found some instances in %s" COM_COMPONENTBUILDER_WE_SUCCESSFULLY_MOVED_BSB="We successfully moved %s!" COM_COMPONENTBUILDER_WHILE_WE_DOWNLOAD_ALL_TWENTY_SIX_COMPILER_GIF_ANIMATIONS_RANDOMLY_USED_IN_THE_COMPILER_GUI_DURING_COMPILATION="While we download all 26 compiler GIF animations randomly used in the compiler GUI during compilation" +COM_COMPONENTBUILDER_WHOLE_WORD="Whole Word" COM_COMPONENTBUILDER_WIKI="Wiki" COM_COMPONENTBUILDER_YES="Yes" 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." @@ -9421,6 +9441,7 @@ COM_COMPONENTBUILDER_YOU_WILL_NEED_TO_KNOW_HOW_S_WORKS_BASIC_YOU_WILL_ALSO_NEED_ COM_COMPONENTBUILDER_ZIPPED_FILE_LOCATION="Zipped File Location" COM_COMPONENTBUILDER__ADD_YOUR_PHP_SCRIPT_HERE="// Add your php script here" COM_COMPONENTBUILDER__HAS_BEEN_CHECKED_OUT_BY_S="% has been checked out by %s" +COM_COMPONENTBUILDER__SEARCH_ALL_="- Search All -" COM_COMPONENTBUILDER__SELECT_COMPONENT_="- Select Component -" COM_COMPONENTBUILDER__SELECT_PACKAGE_="- Select Package -" COM_COMPONENTBUILDER__SINCE_YOU_DONT_HAVE_PERMISSION_TO_CREATE_S=", since you don't have permission to create %s!" diff --git a/admin/models/ajax.php b/admin/models/ajax.php index 16e97932d..39951a1ec 100644 --- a/admin/models/ajax.php +++ b/admin/models/ajax.php @@ -3649,11 +3649,11 @@ class ComponentbuilderModelAjax extends ListModel * * @param string $tableName The main table to search * @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 - * @param int $componentId The option to filter by component + * @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 + * @param int $componentId The option to filter by component * * @return array|null * @since 3.2.0 @@ -3662,23 +3662,108 @@ class ComponentbuilderModelAjax extends ListModel int $matchCase, int $wholeWord, int $regexSearch, int $componentId): ?array { // check if this is a valid table - if (SearchFactory('Table')->exist($tableName)) + 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::_('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(); + SearchFactory::_('Agent')->replace(); return ['success' => JText::sprintf('COM_COMPONENTBUILDER_ALL_FOUND_INSTANCES_IN_S_WHERE_REPLACED', $tableName)]; } return ['error' => JText::_('COM_COMPONENTBUILDER_THERE_HAS_BEEN_AN_ERROR_PLEASE_TRY_AGAIN')]; } + + /** + * Get a selected search value from a given table and row + * + * @param string $fieldName The field key + * @param int $rowId The item ID + * @param string $tableName The table + * + * @return array + * @since 3.2.0 + **/ + public function getSearchValue(string $fieldName, int $rowId, string $tableName): array + { + // check if this is a valid table and field + if ($rowId > 0 && SearchFactory('Table')->exist($tableName, $fieldName) && + ($value = SearchFactory('Agent')->getValue($fieldName, $rowId, 0, $tableName)) !== null) + { + // load the value + return ['value' => $value]; + } + return ['error' => JText::_('COM_COMPONENTBUILDER_THERE_HAS_BEEN_AN_ERROR_PLEASE_TRY_AGAIN')]; + } + + /** + * Get a replaced search value from a given table and row + * + * @param string $fieldName The field key + * @param int $rowId The item ID + * @param mixed $line The line line + * @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 getReplaceValue(string $fieldName, int $rowId, $line, 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; + 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($fieldName, $rowId, $line, $tableName, true)) !== null) + { + return ['value' => $value]; + } + } + return ['error' => JText::_('COM_COMPONENTBUILDER_THERE_HAS_BEEN_AN_ERROR_PLEASE_TRY_AGAIN')]; + } + + /** + * Set selected search value in a given table and row + * + * @param mixed $value The field value + * @param int $rowId The item ID + * @param string $fieldName The field key + * @param string $tableName The table + * + * @return array + * @since 3.2.0 + **/ + public function setValue($value, int $rowId, string $fieldName, string $tableName): array + { + // check if this is a valid table and field + if ($rowId > 0 && SearchFactory('Table')->exist($tableName, $fieldName) && + SearchFactory('Agent')->setValue($value, $rowId, $fieldName, $tableName)) + { + return ['success' => JText::sprintf( + '%s (%s:%s) was successfully updated!', + $tableName, $rowId, $fieldName)]; + } + return ['error' => JText::_('COM_COMPONENTBUILDER_THERE_HAS_BEEN_AN_ERROR_PLEASE_TRY_AGAIN')]; + } // Used in get_snippets diff --git a/admin/models/compiler.php b/admin/models/compiler.php index d8b405e61..456dd2fbf 100644 --- a/admin/models/compiler.php +++ b/admin/models/compiler.php @@ -139,69 +139,6 @@ class ComponentbuilderModelCompiler extends ListModel public $compiler; - public function getComponents() - { - // Get a db connection. - $db = JFactory::getDbo(); - // Create a new query object. - $query = $db->getQuery(true); - // Order it by the ordering field. - $query->select($db->quoteName(array('id', 'system_name'),array('id', 'name'))); - $query->from($db->quoteName('#__componentbuilder_joomla_component')); - $query->where($db->quoteName('published') . ' = 1'); - $query->order('modified DESC'); - $query->order('created DESC'); - // Reset the query using our newly populated query object. - $db->setQuery($query); - // return the result - return $db->loadObjectList(); - } - - public function getCompilerAnimations(&$errorMessage) - { - // convert error message to array - $errorMessage = array(); - $searchArray = array( - // add banners (width - height) - 'banner' => array( - '728-90', - '160-600' - ), - // The build-gif by size (width - height) - 'builder-gif' => array( - '480-540' - ) - ); - // start search, and get - foreach ($searchArray as $type => $sizes) - { - // per size - foreach ($sizes as $size) - { - // get size - if (($set_size = ComponentbuilderHelper::getDynamicContentSize($type, $size)) !== 0) - { - // we loop over all type size artwork - for ($target = 1; $target <= $set_size; $target++) - { - if (!ComponentbuilderHelper::getDynamicContent($type, $size, false, 0, $target)) - { - $errorMessage[] = JText::sprintf('COM_COMPONENTBUILDER_S_S_NUMBER_BSB_COULD_NOT_BE_DOWNLOADED_SUCCESSFULLY_TO_THIS_JOOMLA_INSTALL', $type, $size, $target); - } - } - } - } - } - // check if we had any errors - if (ComponentbuilderHelper::checkArray($errorMessage)) - { - // flatten the error message array - $errorMessage = implode('
', $errorMessage); - return false; - } - return true; - } - public function builder() { // run compiler @@ -359,5 +296,91 @@ class ComponentbuilderModelCompiler extends ListModel $this->cleanCache('mod_menu', 1); return $result; - } + } + + /** + * Get all components in the system + * + * @return array + * @since 3.2.0 + **/ + public function getComponents(): array + { + // Get a db connection. + $db = $this->getDbo(); + + // Create a new query object. + $query = $db->getQuery(true); + + // Select only id and system name + $query->select($db->quoteName(array('id', 'system_name'),array('id', 'name'))); + $query->from($db->quoteName('#__componentbuilder_joomla_component')); + + // only the active components + $query->where($db->quoteName('published') . ' = 1'); + + // Order it by the ordering field. + $query->order('modified DESC'); + $query->order('created DESC'); + + // Reset the query using our newly populated query object. + $db->setQuery($query); + + // return the result + return $db->loadObjectList(); + } + + + /** + * Get all dynamic content + * + * @return bool + * @since 3.2.0 + **/ + public function getDynamicContent(&$errorMessage): bool + { + // convert error message to array + $errorMessage = []; + $searchArray = [ + // add banners (width - height) + 'banner' => [ + '728-90', + '160-600' + ], + // The build-gif by size (width - height) + 'builder-gif' => [ + '480-540' + ] + ]; + // start search, and get + foreach ($searchArray as $type => $sizes) + { + // per size + foreach ($sizes as $size) + { + // get size + if (($set_size = ComponentbuilderHelper::getDynamicContentSize($type, $size)) !== 0) + { + // we loop over all type size artwork + for ($target = 1; $target <= $set_size; $target++) + { + if (!ComponentbuilderHelper::getDynamicContent($type, $size, false, 0, $target)) + { + $errorMessage[] = JText::sprintf('COM_COMPONENTBUILDER_S_S_NUMBER_BSB_COULD_NOT_BE_DOWNLOADED_SUCCESSFULLY_TO_THIS_JOOMLA_INSTALL', $type, $size, $target); + } + } + } + } + } + // check if we had any errors + if (ComponentbuilderHelper::checkArray($errorMessage)) + { + // flatten the error message array + $errorMessage = implode('
', $errorMessage); + + return false; + } + return true; + } + } diff --git a/admin/models/search.php b/admin/models/search.php index 560080af6..5479a986c 100644 --- a/admin/models/search.php +++ b/admin/models/search.php @@ -114,8 +114,8 @@ class ComponentbuilderModelSearch extends ItemModel $query = $db->getQuery(true); // Get data - // load the tables and components (soon) - $data = ['tables' => SearchFactory::_('Table')->tables(), 'components' => null]; + // load the tables and components + $data = ['tables' => SearchFactory::_('Table')->tables(), 'components' => $this->getComponents()]; if (empty($data)) @@ -162,4 +162,38 @@ class ComponentbuilderModelSearch extends ItemModel } return false; } + + + /** + * Get all components in the system + * + * @return array + * @since 3.2.0 + **/ + public function getComponents(): array + { + // Get a db connection. + $db = $this->getDbo(); + + // Create a new query object. + $query = $db->getQuery(true); + + // Select only id and system name + $query->select($db->quoteName(array('id', 'system_name'),array('id', 'name'))); + $query->from($db->quoteName('#__componentbuilder_joomla_component')); + + // only the active components + $query->where($db->quoteName('published') . ' = 1'); + + // Order it by the ordering field. + $query->order('modified DESC'); + $query->order('created DESC'); + + // Reset the query using our newly populated query object. + $db->setQuery($query); + + // return the result + return $db->loadObjectList(); + } + } diff --git a/admin/sql/install.mysql.utf8.sql b/admin/sql/install.mysql.utf8.sql index a8987270c..aa399d72b 100644 --- a/admin/sql/install.mysql.utf8.sql +++ b/admin/sql/install.mysql.utf8.sql @@ -1983,7 +1983,7 @@ INSERT INTO `#__componentbuilder_power` (`id`, `add_head`, `description`, `exten (14, '', 'Control the naming of a namespace helper\r\n\r\n@since 3.0.9', '', '', 'ce8cf834-6bac-44fb-941c-861f7e046cc0', '', '', '', '{}', 'CS8qKg0KCSAqIE1ha2luZyBuYW1lc3BhY2Ugc2FmZQ0KCSAqDQoJICogQGlucHV0CXN0cmluZyAgICAgICBUaGUgeW91IHdvdWxkIGxpa2UgdG8gbWFrZSBzYWZlDQoJICoNCgkgKiBAcmV0dXJucyBzdHJpbmcgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNhZmUoJHN0cmluZykNCgl7DQoJCS8vIDBubHkgY29udGludWUgaWYgd2UgaGF2ZSBhIHN0cmluZw0KCQlpZiAoU3RyaW5nSGVscGVyOjpjaGVjaygkc3RyaW5nKSkNCgkJew0KCQkJLy8gbWFrZSBzdXJlIGl0IGhhcyBub3QgbnVtYmVycw0KCQkJJHN0cmluZyA9IFN0cmluZ0hlbHBlcjo6bnVtYmVycygkc3RyaW5nKTsNCg0KCQkJLy8gVHJhbnNsaXRlcmF0ZSBzdHJpbmcgVE9ETzogbG9vayBhZ2FpbiBhcyB0aGlzIG1ha2UgaXQgbG93ZXJjYXNlDQoJCQkvLyAkc3RyaW5nID0gU3RyaW5nSGVscGVyOjp0cmFuc2xpdGVyYXRlKCRzdHJpbmcpOw0KDQoJCQkvLyBmaXJzdCByZW1vdmUgYWxsIFtcXSBiYWNrc2xhc2hlcw0KCQkJJHN0cmluZyA9IHN0cl9yZXBsYWNlKCdcXCcsICcxJywgJHN0cmluZyk7DQoNCgkJCS8vIHJlbW92ZSBhbGwgYW5kIGtlZXAgb25seSBjaGFyYWN0ZXJzIGFuZCBbXF0gYmFja3NsYXNoZXMgaW5zaWRlIG9mIHRoZSBzdHJpbmcNCgkJCSRzdHJpbmcgPSB0cmltKCBwcmVnX3JlcGxhY2UoIi9bXkEtWmEtejFdLyIsICcnLCAkc3RyaW5nKSwgJzEnKTsNCg0KCQkJLy8gcGxhY2UgdGhlIFtcXSBiYWNrc2xhc2hlcyBiYWNrDQoJCQlyZXR1cm4gdHJpbSggcHJlZ19yZXBsYWNlKCIvMSsvIiwgJ1xcJywgJHN0cmluZykpOw0KCQl9DQoJCS8vIG5vdCBhIHN0cmluZw0KCQlyZXR1cm4gJyc7DQoJfQ0K', '{}', 'NamespaceHelper', 'VDM\\Joomla\\Utilities.String.NamespaceHelper', '1.0.0', '{}', 'String Namespace Helper', 'abstract class', '{\"use_selection0\":{\"use\":\"1f28cb53-60d9-4db1-b517-3c7dc6b429ef\",\"as\":\"default\"}}', '', 1, '2022-03-08 23:27:57', '2022-09-20 10:09:58', 16, 5), (15, 1, 'Control the naming of a field type\r\n\r\n@since 3.0.9', '', '', 'a8935cbe-7701-40dc-bfd5-675f2d600954', 'dXNlIEpvb21sYVxDTVNcQ29tcG9uZW50XENvbXBvbmVudEhlbHBlcjs=', '', '', '{}', 'CS8qKg0KCSAqIFRoZSBmaWVsZCBidWlsZGVyIHN3aXRjaA0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwcm90ZWN0ZWQgc3RhdGljICRidWlsZGVyID0gZmFsc2U7DQoNCgkvKioNCgkgKiBNYWtpbmcgZmllbGQgdHlwZSBuYW1lIHNhZmUNCgkgKg0KCSAqIEBwYXJhbSAgIFN0cmluZyAgICAgICRzdHJpbmcgICAgIFRoZSB5b3Ugd291bGQgbGlrZSB0byBtYWtlIHNhZmUNCgkgKiBAcGFyYW0gICBTdHJpbmcgICAgICAkb3B0aW9uICAgIFRoZSBvcHRpb24gZm9yIHRoZSBjb21wb25lbnQuDQoJICoNCgkgKiBAcmV0dXJucyBzdHJpbmcgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNhZmUoJHN0cmluZywgJG9wdGlvbiA9IG51bGwpDQoJew0KCQkvLyBnZXQgZ2xvYmFsIHZhbHVlDQoJCWlmIChzZWxmOjokYnVpbGRlciA9PT0gZmFsc2UpDQoJCXsNCgkJCXNlbGY6OiRidWlsZGVyID0gSGVscGVyOjpnZXRQYXJhbXMoJG9wdGlvbiktPmdldCgndHlwZV9uYW1lX2J1aWxkZXInLCAxKTsNCgkJfQ0KDQoJCS8vIHVzZSB0aGUgbmV3IGNvbnZlbnRpb24NCgkJaWYgKDIgPT0gc2VsZjo6JGJ1aWxkZXIpDQoJCXsNCgkJCS8vIDBubHkgY29udGludWUgaWYgd2UgaGF2ZSBhIHN0cmluZw0KCQkJaWYgKFN0cmluZ0hlbHBlcjo6Y2hlY2soJHN0cmluZykpDQoJCQl7DQoJCQkJLy8gY2hlY2sgdGhhdCB0aGUgZmlyc3QgY2hhcmFjdGVyIGlzIG5vdCBhIG51bWJlcg0KCQkJCWlmIChpc19udW1lcmljKHN1YnN0cigkc3RyaW5nLCAwLCAxKSkpDQoJCQkJew0KCQkJCQkkc3RyaW5nID0gU3RyaW5nSGVscGVyOjpudW1iZXJzKCRzdHJpbmcpOw0KCQkJCX0NCg0KCQkJCS8vIFRyYW5zbGl0ZXJhdGUgc3RyaW5nDQoJCQkJJHN0cmluZyA9IFN0cmluZ0hlbHBlcjo6dHJhbnNsaXRlcmF0ZSgkc3RyaW5nKTsNCg0KCQkJCS8vIHJlbW92ZSBhbGwgYW5kIGtlZXAgb25seSBjaGFyYWN0ZXJzIGFuZCBudW1iZXJzIGFuZCBwb2ludCAoVE9ETyBqdXN0IG9uZSBwb2ludCkNCgkJCQkkc3RyaW5nID0gdHJpbShwcmVnX3JlcGxhY2UoIi9bXkEtWmEtejAtOVwuXS8iLCAnJywgJHN0cmluZykpOw0KDQoJCQkJLy8gYmVzdCBpcyB0byByZXR1cm4gbG93ZXIgKGZvciBhbGwgc3RyaW5nIGVxdWFsaXR5IGluIGNvbXBpbGVyKQ0KCQkJCXJldHVybiBzdHJ0b2xvd2VyKCRzdHJpbmcpOw0KCQkJfQ0KCQkJLy8gbm90IGEgc3RyaW5nDQoJCQlyZXR1cm4gJyc7DQoJCX0NCg0KCQkvLyB1c2UgdGhlIGRlZmF1bHQgKG9yaWdpbmFsIGJlaGF2aW91ci9jb252ZW50aW9uKQ0KCQlyZXR1cm4gU3RyaW5nSGVscGVyOjpzYWZlKCRzdHJpbmcpOw0KCX0NCg==', '{}', 'TypeHelper', 'VDM\\Joomla\\Utilities.String.TypeHelper', '1.0.0', '{}', 'String Type Helper', 'abstract class', '{\"use_selection0\":{\"use\":\"1f28cb53-60d9-4db1-b517-3c7dc6b429ef\",\"as\":\"default\"},\"use_selection1\":{\"use\":\"640b5352-fb09-425f-a26e-cd44eda03f15\",\"as\":\"default\"}}', '', 1, '2022-03-08 23:33:09', '2022-09-20 10:10:03', 15, 5), (16, '', 'Control the naming of a class and function\r\n\r\n@since 3.0.9', '', '', '30c5b4c2-f75f-4d15-869a-f8bfedd87358', '', '', '', '{}', 'CS8qKg0KCSAqIE1ha2luZyBjbGFzcyBvciBmdW5jdGlvbiBuYW1lIHNhZmUNCgkgKg0KCSAqIEBpbnB1dAlzdHJpbmcgICAgICAgVGhlIG5hbWUgeW91IHdvdWxkIGxpa2UgdG8gbWFrZSBzYWZlDQoJICoNCgkgKiBAcmV0dXJucyBzdHJpbmcgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNhZmUoJG5hbWUpDQoJew0KCQkvLyByZW1vdmUgbnVtYmVycyBpZiB0aGUgZmlyc3QgY2hhcmFjdGVyIGlzIGEgbnVtYmVyDQoJCWlmIChpc19udW1lcmljKHN1YnN0cigkbmFtZSwgMCwgMSkpKQ0KCQl7DQoJCQkkbmFtZSA9IFN0cmluZ0hlbHBlcjo6bnVtYmVycygkbmFtZSk7DQoJCX0NCg0KCQkvLyByZW1vdmUgYWxsIHNwYWNlcyBhbmQgc3RyYW5nZSBjaGFyYWN0ZXJzDQoJCXJldHVybiB0cmltKHByZWdfcmVwbGFjZSgiL1teQS1aYS16MC05Xy1dLyIsICcnLCAkbmFtZSkpOw0KCX0NCg==', '{}', 'ClassfunctionHelper', 'VDM\\Joomla\\Utilities.String.ClassfunctionHelper', '1.0.0', '{}', 'String Classfunction Helper', 'abstract class', '{\"use_selection0\":{\"use\":\"1f28cb53-60d9-4db1-b517-3c7dc6b429ef\",\"as\":\"default\"}}', '', 1, '2022-03-08 23:43:10', '2022-09-20 10:10:07', 15, 5), -(17, 1, 'Some easy get...\r\n\r\n@since 3.0.9', '', '', 'db87c339-5bb6-4291-a7ef-2c48ea1b06bc', 'dXNlIEpvb21sYVxDTVNcRmFjdG9yeTs=', '', '', '{\"load_selection0\":{\"load\":\"0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a\"},\"load_selection1\":{\"load\":\"1f28cb53-60d9-4db1-b517-3c7dc6b429ef\"}}', 'CS8qKg0KCSAqIEdldCBhIFZhcmlhYmxlIA0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nICAgJHRhYmxlICAgICAgICBUaGUgdGFibGUgZnJvbSB3aGljaCB0byBnZXQgdGhlIHZhcmlhYmxlDQoJICogQHBhcmFtICAgc3RyaW5nICAgJHdoZXJlICAgICAgICBUaGUgdmFsdWUgd2hlcmUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkd2hlcmVTdHJpbmcgIFRoZSB0YXJnZXQvZmllbGQgc3RyaW5nIHdoZXJlL25hbWUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkd2hhdCAgICAgICAgIFRoZSByZXR1cm4gZmllbGQNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkb3BlcmF0b3IgICAgIFRoZSBvcGVyYXRvciBiZXR3ZWVuICR3aGVyZVN0cmluZy9maWVsZCBhbmQgJHdoZXJlL3ZhbHVlDQoJICogQHBhcmFtICAgc3RyaW5nICAgJG1haW4gICAgICAgICBUaGUgY29tcG9uZW50IGluIHdoaWNoIHRoZSB0YWJsZSBpcyBmb3VuZA0KCSAqDQoJICogQHJldHVybiAgbWl4IHN0cmluZy9pbnQvZmxvYXQNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiB2YXIoJHRhYmxlLCAkd2hlcmUgPSBudWxsLCAkd2hlcmVTdHJpbmcgPSAndXNlcicsICR3aGF0ID0gJ2lkJywgJG9wZXJhdG9yID0gJz0nLCAkbWFpbiA9IG51bGwpDQoJew0KCQlpZihlbXB0eSgkd2hlcmUpKQ0KCQl7DQoJCQkkd2hlcmUgPSBGYWN0b3J5OjpnZXRVc2VyKCktPmlkOw0KCQl9DQoNCgkJaWYoZW1wdHkoJG1haW4pKQ0KCQl7DQoJCQkkbWFpbiA9IEhlbHBlcjo6Z2V0Q29kZSgpOw0KCQl9DQoNCgkJLy8gR2V0IGEgZGIgY29ubmVjdGlvbi4NCgkJJGRiID0gRmFjdG9yeTo6Z2V0RGJvKCk7DQoNCgkJLy8gQ3JlYXRlIGEgbmV3IHF1ZXJ5IG9iamVjdC4NCgkJJHF1ZXJ5ID0gJGRiLT5nZXRRdWVyeSh0cnVlKTsNCgkJJHF1ZXJ5LT5zZWxlY3QoJGRiLT5xdW90ZU5hbWUoYXJyYXkoJHdoYXQpKSk7DQoNCgkJaWYgKGVtcHR5KCR0YWJsZSkpDQoJCXsNCgkJCSRxdWVyeS0+ZnJvbSgkZGItPnF1b3RlTmFtZSgnI19fJyAuICRtYWluKSk7DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQkkcXVlcnktPmZyb20oJGRiLT5xdW90ZU5hbWUoJyNfXycgLiAkbWFpbiAuICdfJyAuICR0YWJsZSkpOw0KCQl9DQoNCgkJaWYgKGlzX251bWVyaWMoJHdoZXJlKSkNCgkJew0KCQkJJHF1ZXJ5LT53aGVyZSgkZGItPnF1b3RlTmFtZSgkd2hlcmVTdHJpbmcpIC4gJyAnIC4gJG9wZXJhdG9yIC4gJyAnIC4gKGludCkgJHdoZXJlKTsNCgkJfQ0KCQllbHNlaWYgKGlzX3N0cmluZygkd2hlcmUpKQ0KCQl7DQoJCQkkcXVlcnktPndoZXJlKCRkYi0+cXVvdGVOYW1lKCR3aGVyZVN0cmluZykgLiAnICcgLiAkb3BlcmF0b3IgLiAnICcgLiAkZGItPnF1b3RlKChzdHJpbmcpJHdoZXJlKSk7DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQlyZXR1cm4gZmFsc2U7DQoJCX0NCg0KCQkkZGItPnNldFF1ZXJ5KCRxdWVyeSk7DQoJCSRkYi0+ZXhlY3V0ZSgpOw0KDQoJCWlmICgkZGItPmdldE51bVJvd3MoKSkNCgkJew0KCQkJcmV0dXJuICRkYi0+bG9hZFJlc3VsdCgpOw0KCQl9DQoJCXJldHVybiBmYWxzZTsNCgl9DQoNCgkvKioNCgkgKiBHZXQgYXJyYXkgb2YgdmFyaWFibGVzDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkdGFibGUgICAgICAgIFRoZSB0YWJsZSBmcm9tIHdoaWNoIHRvIGdldCB0aGUgdmFyaWFibGVzDQoJICogQHBhcmFtICAgc3RyaW5nICAgJHdoZXJlICAgICAgICBUaGUgdmFsdWUgd2hlcmUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkd2hlcmVTdHJpbmcgIFRoZSB0YXJnZXQvZmllbGQgc3RyaW5nIHdoZXJlL25hbWUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkd2hhdCAgICAgICAgIFRoZSByZXR1cm4gZmllbGQNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkb3BlcmF0b3IgICAgIFRoZSBvcGVyYXRvciBiZXR3ZWVuICR3aGVyZVN0cmluZy9maWVsZCBhbmQgJHdoZXJlL3ZhbHVlDQoJICogQHBhcmFtICAgc3RyaW5nICAgJG1haW4gICAgICAgICBUaGUgY29tcG9uZW50IGluIHdoaWNoIHRoZSB0YWJsZSBpcyBmb3VuZA0KCSAqIEBwYXJhbSAgIGJvb2wgICAgICR1bmlxdWUgICAgICAgVGhlIHN3aXRjaCB0byByZXR1cm4gYSB1bmlxdWUgYXJyYXkNCgkgKg0KCSAqIEByZXR1cm4gIGFycmF5DQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdmFycygkdGFibGUsICR3aGVyZSA9IG51bGwsICR3aGVyZVN0cmluZyA9ICd1c2VyJywgJHdoYXQgPSAnaWQnLCAkb3BlcmF0b3IgPSAnSU4nLCAkbWFpbiA9IG51bGwsICR1bmlxdWUgPSB0cnVlKQ0KCXsNCgkJaWYoZW1wdHkoJHdoZXJlKSkNCgkJew0KCQkJJHdoZXJlID0gRmFjdG9yeTo6Z2V0VXNlcigpLT5pZDsNCgkJfQ0KDQoJCWlmKGlzX251bGwoJG1haW4pKQ0KCQl7DQoJCQkkbWFpbiA9IEhlbHBlcjo6Z2V0Q29kZSgpOw0KCQl9DQoNCgkJaWYgKCFBcnJheUhlbHBlcjo6Y2hlY2soJHdoZXJlKSAmJiAkd2hlcmUgPiAwKQ0KCQl7DQoJCQkkd2hlcmUgPSBhcnJheSgkd2hlcmUpOw0KCQl9DQoNCgkJaWYgKEFycmF5SGVscGVyOjpjaGVjaygkd2hlcmUpKQ0KCQl7DQoJCQkvLyBwcmVwIG1haW4gPC0tIHdoeT8gd2VsbCBpZiAkbWFpbj0nJyBpcyBlbXB0eSB0aGVuICR0YWJsZSBjYW4gYmUgY2F0ZWdvcmllcyBvciB1c2Vycw0KCQkJaWYgKFN0cmluZ0hlbHBlcjo6Y2hlY2soJG1haW4pKQ0KCQkJew0KCQkJCSRtYWluID0gJ18nIC4gbHRyaW0oJG1haW4sICdfJyk7DQoJCQl9DQoNCgkJCS8vIEdldCBhIGRiIGNvbm5lY3Rpb24uDQoJCQkkZGIgPSBGYWN0b3J5OjpnZXREYm8oKTsNCg0KCQkJLy8gQ3JlYXRlIGEgbmV3IHF1ZXJ5IG9iamVjdC4NCgkJCSRxdWVyeSA9ICRkYi0+Z2V0UXVlcnkodHJ1ZSk7DQoJCQkkcXVlcnktPnNlbGVjdCgkZGItPnF1b3RlTmFtZShhcnJheSgkd2hhdCkpKTsNCg0KCQkJaWYgKGVtcHR5KCR0YWJsZSkpDQoJCQl7DQoJCQkJJHF1ZXJ5LT5mcm9tKCRkYi0+cXVvdGVOYW1lKCcjX18nIC4gJG1haW4pKTsNCgkJCX0NCgkJCWVsc2UNCgkJCXsNCgkJCQkkcXVlcnktPmZyb20oJGRiLT5xdW90ZU5hbWUoJyNfJyAuICRtYWluIC4gJ18nIC4gJHRhYmxlKSk7DQoJCQl9DQoNCgkJCS8vIGFkZCBzdHJpbmdzIHRvIGFycmF5IHNlYXJjaA0KCQkJaWYgKCdJTl9TVFJJTkdTJyA9PT0gJG9wZXJhdG9yIHx8ICdOT1QgSU5fU1RSSU5HUycgPT09ICRvcGVyYXRvcikNCgkJCXsNCgkJCQkkcXVlcnktPndoZXJlKCRkYi0+cXVvdGVOYW1lKCR3aGVyZVN0cmluZykgLiAnICcgLiBzdHJfcmVwbGFjZSgnX1NUUklOR1MnLCAnJywgJG9wZXJhdG9yKSAuICcgKCInIC4gaW1wbG9kZSgnIiwiJywkd2hlcmUpIC4gJyIpJyk7DQoJCQl9DQoJCQllbHNlDQoJCQl7DQoJCQkJJHF1ZXJ5LT53aGVyZSgkZGItPnF1b3RlTmFtZSgkd2hlcmVTdHJpbmcpIC4gJyAnIC4gJG9wZXJhdG9yIC4gJyAoJyAuIGltcGxvZGUoJywnLCR3aGVyZSkgLiAnKScpOw0KCQkJfQ0KDQoJCQkkZGItPnNldFF1ZXJ5KCRxdWVyeSk7DQoJCQkkZGItPmV4ZWN1dGUoKTsNCg0KCQkJaWYgKCRkYi0+Z2V0TnVtUm93cygpKQ0KCQkJew0KCQkJCWlmICgkdW5pcXVlKQ0KCQkJCXsNCgkJCQkJcmV0dXJuIGFycmF5X3VuaXF1ZSgkZGItPmxvYWRDb2x1bW4oKSk7DQoJCQkJfQ0KCQkJCXJldHVybiAkZGItPmxvYWRDb2x1bW4oKTsNCgkJCX0NCgkJfQ0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0KDQoJLyoqDQoJICogZ2V0IGFsbCBzdHJpbmdzIGJldHdlZW4gdHdvIG90aGVyIHN0cmluZ3MNCgkgKiANCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAkY29udGVudCAgICBUaGUgY29udGVudCB0byBzZWFyY2gNCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAkc3RhcnQgICAgICAgIFRoZSBzdGFydGluZyB2YWx1ZQ0KCSAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICRlbmQgICAgICAgICBUaGUgZW5kaW5nIHZhbHVlDQoJICoNCgkgKiBAcmV0dXJuICBhcnJheSAgICAgICAgICBPbiBzdWNjZXNzDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gYWxsQmV0d2VlbigkY29udGVudCwgJHN0YXJ0LCAkZW5kKQ0KCXsNCgkJLy8gcmVzZXQgYnVja2V0DQoJCSRidWNrZXQgPSBhcnJheSgpOw0KCQlmb3IgKCRpID0gMDsgOyAkaSsrKQ0KCQl7DQoJCQkvLyBzZWFyY2ggZm9yIHN0cmluZw0KCQkJJGZvdW5kID0gc2VsZjo6YmV0d2VlbigkY29udGVudCwkc3RhcnQsJGVuZCk7DQoJCQlpZiAoU3RyaW5nSGVscGVyOjpjaGVjaygkZm91bmQpKQ0KCQkJew0KCQkJCS8vIGFkZCB0byBidWNrZXQNCgkJCQkkYnVja2V0W10gPSAkZm91bmQ7DQoJCQkJLy8gYnVpbGQgcmVtb3ZhbCBzdHJpbmcNCgkJCQkkcmVtb3ZlID0gJHN0YXJ0LiRmb3VuZC4kZW5kOw0KCQkJCS8vIHJlbW92ZSBmcm9tIGNvbnRlbnQNCgkJCQkkY29udGVudCA9IHN0cl9yZXBsYWNlKCRyZW1vdmUsJycsJGNvbnRlbnQpOw0KCQkJfQ0KCQkJZWxzZQ0KCQkJew0KCQkJCWJyZWFrOw0KCQkJfQ0KCQkJLy8gc2FmZXR5IGNhdGNoDQoJCQlpZiAoJGkgPT0gNTAwKQ0KCQkJew0KCQkJCWJyZWFrOw0KCQkJfQ0KCQl9DQoJCS8vIG9ubHkgcmV0dXJuIHVuaXF1ZSBhcnJheSBvZiB2YWx1ZXMNCgkJcmV0dXJuICBhcnJheV91bmlxdWUoJGJ1Y2tldCk7DQoJfQ0KDQoJLyoqDQoJICogZ2V0IGEgc3RyaW5nIGJldHdlZW4gdHdvIG90aGVyIHN0cmluZ3MNCgkgKiANCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAkY29udGVudCAgICBUaGUgY29udGVudCB0byBzZWFyY2gNCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAkc3RhcnQgICAgICAgIFRoZSBzdGFydGluZyB2YWx1ZQ0KCSAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICRlbmQgICAgICAgICBUaGUgZW5kaW5nIHZhbHVlDQoJICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgJGRlZmF1bHQgICAgIFRoZSBkZWZhdWx0IHZhbHVlIGlmIG5vbmUgZm91bmQNCgkgKg0KCSAqIEByZXR1cm4gIHN0cmluZyAgICAgICAgICBPbiBzdWNjZXNzIC8gZW1wdHkgc3RyaW5nIG9uIGZhaWx1cmUNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBiZXR3ZWVuKCRjb250ZW50LCAkc3RhcnQsICRlbmQsICRkZWZhdWx0ID0gJycpDQoJew0KCQkkciA9IGV4cGxvZGUoJHN0YXJ0LCAkY29udGVudCk7DQoJCWlmIChpc3NldCgkclsxXSkpDQoJCXsNCgkJCSRyID0gZXhwbG9kZSgkZW5kLCAkclsxXSk7DQoJCQlyZXR1cm4gJHJbMF07DQoJCX0NCgkJcmV0dXJuICRkZWZhdWx0Ow0KCX0NCg==', '{}', 'GetHelper', 'VDM\\Joomla\\Utilities.GetHelper', '1.0.0', '{}', 'Utilities GetHelper', 'abstract class', '{\"use_selection0\":{\"use\":\"640b5352-fb09-425f-a26e-cd44eda03f15\",\"as\":\"default\"}}', '', 1, '2022-03-09 00:21:06', '2022-09-20 09:51:35', 23, 9), +(17, 1, 'Some easy get...\r\n\r\n@since 3.0.9', '', '', 'db87c339-5bb6-4291-a7ef-2c48ea1b06bc', 'dXNlIEpvb21sYVxDTVNcRmFjdG9yeTs=', '', '', '{\"load_selection0\":{\"load\":\"0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a\"},\"load_selection1\":{\"load\":\"1f28cb53-60d9-4db1-b517-3c7dc6b429ef\"}}', 'CS8qKg0KCSAqIEdldCBhIFZhcmlhYmxlIA0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nICAgJHRhYmxlICAgICAgICBUaGUgdGFibGUgZnJvbSB3aGljaCB0byBnZXQgdGhlIHZhcmlhYmxlDQoJICogQHBhcmFtICAgc3RyaW5nICAgJHdoZXJlICAgICAgICBUaGUgdmFsdWUgd2hlcmUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkd2hlcmVTdHJpbmcgIFRoZSB0YXJnZXQvZmllbGQgc3RyaW5nIHdoZXJlL25hbWUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkd2hhdCAgICAgICAgIFRoZSByZXR1cm4gZmllbGQNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkb3BlcmF0b3IgICAgIFRoZSBvcGVyYXRvciBiZXR3ZWVuICR3aGVyZVN0cmluZy9maWVsZCBhbmQgJHdoZXJlL3ZhbHVlDQoJICogQHBhcmFtICAgc3RyaW5nICAgJG1haW4gICAgICAgICBUaGUgY29tcG9uZW50IGluIHdoaWNoIHRoZSB0YWJsZSBpcyBmb3VuZA0KCSAqDQoJICogQHJldHVybiAgbWl4ZWQgc3RyaW5nL2ludC9mbG9hdA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHZhcihzdHJpbmcgJHRhYmxlLCA/c3RyaW5nICR3aGVyZSA9IG51bGwsDQoJCXN0cmluZyAkd2hlcmVTdHJpbmcgPSAndXNlcicsIHN0cmluZyAkd2hhdCA9ICdpZCcsDQoJCXN0cmluZyAkb3BlcmF0b3IgPSAnPScsID9zdHJpbmcgJG1haW4gPSBudWxsKQ0KCXsNCgkJaWYoZW1wdHkoJHdoZXJlKSkNCgkJew0KCQkJJHdoZXJlID0gRmFjdG9yeTo6Z2V0VXNlcigpLT5pZDsNCgkJfQ0KDQoJCWlmKGVtcHR5KCRtYWluKSkNCgkJew0KCQkJJG1haW4gPSBIZWxwZXI6OmdldENvZGUoKTsNCgkJfQ0KDQoJCS8vIEdldCBhIGRiIGNvbm5lY3Rpb24uDQoJCSRkYiA9IEZhY3Rvcnk6OmdldERibygpOw0KDQoJCS8vIENyZWF0ZSBhIG5ldyBxdWVyeSBvYmplY3QuDQoJCSRxdWVyeSA9ICRkYi0+Z2V0UXVlcnkodHJ1ZSk7DQoJCSRxdWVyeS0+c2VsZWN0KCRkYi0+cXVvdGVOYW1lKGFycmF5KCR3aGF0KSkpOw0KDQoJCWlmIChlbXB0eSgkdGFibGUpKQ0KCQl7DQoJCQkkcXVlcnktPmZyb20oJGRiLT5xdW90ZU5hbWUoJyNfXycgLiAkbWFpbikpOw0KCQl9DQoJCWVsc2UNCgkJew0KCQkJJHF1ZXJ5LT5mcm9tKCRkYi0+cXVvdGVOYW1lKCcjX18nIC4gJG1haW4gLiAnXycgLiAkdGFibGUpKTsNCgkJfQ0KDQoJCWlmIChpc19udW1lcmljKCR3aGVyZSkpDQoJCXsNCgkJCSRxdWVyeS0+d2hlcmUoJGRiLT5xdW90ZU5hbWUoJHdoZXJlU3RyaW5nKSAuICcgJyAuICRvcGVyYXRvciAuICcgJyAuIChpbnQpICR3aGVyZSk7DQoJCX0NCgkJZWxzZWlmIChpc19zdHJpbmcoJHdoZXJlKSkNCgkJew0KCQkJJHF1ZXJ5LT53aGVyZSgkZGItPnF1b3RlTmFtZSgkd2hlcmVTdHJpbmcpIC4gJyAnIC4gJG9wZXJhdG9yIC4gJyAnIC4gJGRiLT5xdW90ZSgoc3RyaW5nKSR3aGVyZSkpOw0KCQl9DQoJCWVsc2UNCgkJew0KCQkJcmV0dXJuIGZhbHNlOw0KCQl9DQoNCgkJJGRiLT5zZXRRdWVyeSgkcXVlcnkpOw0KCQkkZGItPmV4ZWN1dGUoKTsNCg0KCQlpZiAoJGRiLT5nZXROdW1Sb3dzKCkpDQoJCXsNCgkJCXJldHVybiAkZGItPmxvYWRSZXN1bHQoKTsNCgkJfQ0KDQoJCXJldHVybiBmYWxzZTsNCgl9DQoNCgkvKioNCgkgKiBHZXQgYXJyYXkgb2YgdmFyaWFibGVzDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkdGFibGUgICAgICAgIFRoZSB0YWJsZSBmcm9tIHdoaWNoIHRvIGdldCB0aGUgdmFyaWFibGVzDQoJICogQHBhcmFtICAgc3RyaW5nICAgJHdoZXJlICAgICAgICBUaGUgdmFsdWUgd2hlcmUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkd2hlcmVTdHJpbmcgIFRoZSB0YXJnZXQvZmllbGQgc3RyaW5nIHdoZXJlL25hbWUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkd2hhdCAgICAgICAgIFRoZSByZXR1cm4gZmllbGQNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkb3BlcmF0b3IgICAgIFRoZSBvcGVyYXRvciBiZXR3ZWVuICR3aGVyZVN0cmluZy9maWVsZCBhbmQgJHdoZXJlL3ZhbHVlDQoJICogQHBhcmFtICAgc3RyaW5nICAgJG1haW4gICAgICAgICBUaGUgY29tcG9uZW50IGluIHdoaWNoIHRoZSB0YWJsZSBpcyBmb3VuZA0KCSAqIEBwYXJhbSAgIGJvb2wgICAgICR1bmlxdWUgICAgICAgVGhlIHN3aXRjaCB0byByZXR1cm4gYSB1bmlxdWUgYXJyYXkNCgkgKg0KCSAqIEByZXR1cm4gIGFycmF5fG51bGwNCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiB2YXJzKHN0cmluZyAkdGFibGUsID9zdHJpbmcgJHdoZXJlID0gbnVsbCwNCgkJc3RyaW5nICR3aGVyZVN0cmluZyA9ICd1c2VyJywgc3RyaW5nICR3aGF0ID0gJ2lkJywgc3RyaW5nICRvcGVyYXRvciA9ICdJTicsDQoJCT9zdHJpbmcgJG1haW4gPSBudWxsLCBib29sICR1bmlxdWUgPSB0cnVlKTogP2FycmF5DQoJew0KCQlpZihlbXB0eSgkd2hlcmUpKQ0KCQl7DQoJCQkkd2hlcmUgPSBGYWN0b3J5OjpnZXRVc2VyKCktPmlkOw0KCQl9DQoNCgkJaWYoaXNfbnVsbCgkbWFpbikpDQoJCXsNCgkJCSRtYWluID0gSGVscGVyOjpnZXRDb2RlKCk7DQoJCX0NCg0KCQlpZiAoIUFycmF5SGVscGVyOjpjaGVjaygkd2hlcmUpICYmICR3aGVyZSA+IDApDQoJCXsNCgkJCSR3aGVyZSA9IGFycmF5KCR3aGVyZSk7DQoJCX0NCg0KCQlpZiAoQXJyYXlIZWxwZXI6OmNoZWNrKCR3aGVyZSkpDQoJCXsNCgkJCS8vIHByZXAgbWFpbiA8LS0gd2h5PyB3ZWxsIGlmICRtYWluPScnIGlzIGVtcHR5IHRoZW4gJHRhYmxlIGNhbiBiZSBjYXRlZ29yaWVzIG9yIHVzZXJzDQoJCQlpZiAoU3RyaW5nSGVscGVyOjpjaGVjaygkbWFpbikpDQoJCQl7DQoJCQkJJG1haW4gPSAnXycgLiBsdHJpbSgkbWFpbiwgJ18nKTsNCgkJCX0NCg0KCQkJLy8gR2V0IGEgZGIgY29ubmVjdGlvbi4NCgkJCSRkYiA9IEZhY3Rvcnk6OmdldERibygpOw0KDQoJCQkvLyBDcmVhdGUgYSBuZXcgcXVlcnkgb2JqZWN0Lg0KCQkJJHF1ZXJ5ID0gJGRiLT5nZXRRdWVyeSh0cnVlKTsNCgkJCSRxdWVyeS0+c2VsZWN0KCRkYi0+cXVvdGVOYW1lKGFycmF5KCR3aGF0KSkpOw0KDQoJCQlpZiAoZW1wdHkoJHRhYmxlKSkNCgkJCXsNCgkJCQkkcXVlcnktPmZyb20oJGRiLT5xdW90ZU5hbWUoJyNfXycgLiAkbWFpbikpOw0KCQkJfQ0KCQkJZWxzZQ0KCQkJew0KCQkJCSRxdWVyeS0+ZnJvbSgkZGItPnF1b3RlTmFtZSgnI18nIC4gJG1haW4gLiAnXycgLiAkdGFibGUpKTsNCgkJCX0NCg0KCQkJLy8gYWRkIHN0cmluZ3MgdG8gYXJyYXkgc2VhcmNoDQoJCQlpZiAoJ0lOX1NUUklOR1MnID09PSAkb3BlcmF0b3IgfHwgJ05PVCBJTl9TVFJJTkdTJyA9PT0gJG9wZXJhdG9yKQ0KCQkJew0KCQkJCSRxdWVyeS0+d2hlcmUoJGRiLT5xdW90ZU5hbWUoJHdoZXJlU3RyaW5nKSAuICcgJyAuIHN0cl9yZXBsYWNlKCdfU1RSSU5HUycsICcnLCAkb3BlcmF0b3IpIC4gJyAoIicgLiBpbXBsb2RlKCciLCInLCAkd2hlcmUpIC4gJyIpJyk7DQoJCQl9DQoJCQllbHNlDQoJCQl7DQoJCQkJJHF1ZXJ5LT53aGVyZSgkZGItPnF1b3RlTmFtZSgkd2hlcmVTdHJpbmcpIC4gJyAnIC4gJG9wZXJhdG9yIC4gJyAoJyAuIGltcGxvZGUoJywnLCAkd2hlcmUpIC4gJyknKTsNCgkJCX0NCg0KCQkJJGRiLT5zZXRRdWVyeSgkcXVlcnkpOw0KCQkJJGRiLT5leGVjdXRlKCk7DQoNCgkJCWlmICgkZGItPmdldE51bVJvd3MoKSkNCgkJCXsNCgkJCQlpZiAoJHVuaXF1ZSkNCgkJCQl7DQoJCQkJCXJldHVybiBhcnJheV91bmlxdWUoJGRiLT5sb2FkQ29sdW1uKCkpOw0KCQkJCX0NCgkJCQlyZXR1cm4gJGRiLT5sb2FkQ29sdW1uKCk7DQoJCQl9DQoJCX0NCg0KCQlyZXR1cm4gbnVsbDsNCgl9DQoNCgkvKioNCgkgKiBnZXQgYWxsIHN0cmluZ3MgYmV0d2VlbiB0d28gb3RoZXIgc3RyaW5ncw0KCSAqIA0KCSAqIEBwYXJhbSAgc3RyaW5nICAgICAgICRjb250ZW50ICAgIFRoZSBjb250ZW50IHRvIHNlYXJjaA0KCSAqIEBwYXJhbSAgc3RyaW5nICAgICAgICRzdGFydCAgICAgIFRoZSBzdGFydGluZyB2YWx1ZQ0KCSAqIEBwYXJhbSAgc3RyaW5nICAgICAgICRlbmQgICAgICAgIFRoZSBlbmRpbmcgdmFsdWUNCgkgKg0KCSAqIEByZXR1cm4gIGFycmF5fG51bGwgICAgICAgICAgT24gc3VjY2Vzcw0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGFsbEJldHdlZW4oc3RyaW5nICRjb250ZW50LCBzdHJpbmcgJHN0YXJ0LCBzdHJpbmcgJGVuZCk6ID9hcnJheQ0KCXsNCgkJLy8gcmVzZXQgYnVja2V0DQoJCSRidWNrZXQgPSBbXTsNCgkJZm9yICgkaSA9IDA7IDsgJGkrKykNCgkJew0KCQkJLy8gc2VhcmNoIGZvciBzdHJpbmcNCgkJCSRmb3VuZCA9IHNlbGY6OmJldHdlZW4oJGNvbnRlbnQsICRzdGFydCwgJGVuZCk7DQoNCgkJCWlmIChTdHJpbmdIZWxwZXI6OmNoZWNrKCRmb3VuZCkpDQoJCQl7DQoJCQkJLy8gYWRkIHRvIGJ1Y2tldA0KCQkJCSRidWNrZXRbXSA9ICRmb3VuZDsNCg0KCQkJCS8vIGJ1aWxkIHJlbW92YWwgc3RyaW5nDQoJCQkJJHJlbW92ZSA9ICRzdGFydCAuICRmb3VuZCAuICRlbmQ7DQoNCgkJCQkvLyByZW1vdmUgZnJvbSBjb250ZW50DQoJCQkJJGNvbnRlbnQgPSBzdHJfcmVwbGFjZSgkcmVtb3ZlLCAnJywgJGNvbnRlbnQpOw0KCQkJfQ0KCQkJZWxzZQ0KCQkJew0KCQkJCWJyZWFrOw0KCQkJfQ0KDQoJCQkvLyBzYWZldHkgY2F0Y2gNCgkJCWlmICgkaSA9PSA1MDApDQoJCQl7DQoJCQkJYnJlYWs7DQoJCQl9DQoJCX0NCg0KCQkvLyBvbmx5IHJldHVybiB1bmlxdWUgYXJyYXkgb2YgdmFsdWVzDQoJCWlmIChBcnJheUhlbHBlcjo6Y2hlY2soJGJ1Y2tldCkpDQoJCXsNCgkJCXJldHVybiAgYXJyYXlfdW5pcXVlKCRidWNrZXQpOw0KCQl9DQoNCgkJcmV0dXJuIG51bGw7DQoJfQ0KDQoJLyoqDQoJICogZ2V0IGEgc3RyaW5nIGJldHdlZW4gdHdvIG90aGVyIHN0cmluZ3MNCgkgKiANCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAkY29udGVudCAgICBUaGUgY29udGVudCB0byBzZWFyY2gNCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAkc3RhcnQgICAgICBUaGUgc3RhcnRpbmcgdmFsdWUNCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAkZW5kICAgICAgICBUaGUgZW5kaW5nIHZhbHVlDQoJICogQHBhcmFtICBzdHJpbmcgICAgICAgJGRlZmF1bHQgICAgVGhlIGRlZmF1bHQgdmFsdWUgaWYgbm9uZSBmb3VuZA0KCSAqDQoJICogQHJldHVybiAgc3RyaW5nICAgICAgICAgIE9uIHN1Y2Nlc3MgLyBlbXB0eSBzdHJpbmcgb24gZmFpbHVyZQ0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGJldHdlZW4oc3RyaW5nICRjb250ZW50LCBzdHJpbmcgJHN0YXJ0LCBzdHJpbmcgJGVuZCwgc3RyaW5nICRkZWZhdWx0ID0gJycpOiBzdHJpbmcNCgl7DQoJCSRhcnJheSA9IGV4cGxvZGUoJHN0YXJ0LCAkY29udGVudCk7DQoJCWlmIChpc3NldCgkYXJyYXlbMV0pICYmIHN0cnBvcygkYXJyYXlbMV0sICRlbmQpICE9PSBmYWxzZSkNCgkJew0KCQkJJGFycmF5ID0gZXhwbG9kZSgkZW5kLCAkYXJyYXlbMV0pOw0KDQoJCQkvLyByZXR1cm4gc3RyaW5nIGZvdW5kIGJldHdlZW4NCgkJCXJldHVybiAkYXJyYXlbMF07DQoJCX0NCg0KCQlyZXR1cm4gJGRlZmF1bHQ7DQoJfQ0K', '{}', 'GetHelper', 'VDM\\Joomla\\Utilities.GetHelper', '1.0.0', '{}', 'Utilities GetHelper', 'abstract class', '{\"use_selection0\":{\"use\":\"640b5352-fb09-425f-a26e-cd44eda03f15\",\"as\":\"default\"}}', '', 1, '2022-03-09 00:21:06', '2022-10-20 14:18:47', 24, 9), (18, '', 'Some object tricks\r\n\r\n@since 3.0.9', '', '', '91004529-94a9-4590-b842-e7c6b624ecf5', '', '', '', '{}', 'CS8qKg0KCSAqIENoZWNrIGlmIGhhdmUgYW4gb2JqZWN0IHdpdGggYSBsZW5ndGgNCgkgKg0KCSAqIEBpbnB1dAlvYmplY3QgICBUaGUgb2JqZWN0IHRvIGNoZWNrDQoJICoNCgkgKiBAcmV0dXJucyBib29sIHRydWUgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNoZWNrKCRvYmplY3QpDQoJew0KCQlpZiAoaXNfb2JqZWN0KCRvYmplY3QpKQ0KCQl7DQoJCQlyZXR1cm4gY291bnQoKGFycmF5KSAkb2JqZWN0KSA+IDA7DQoJCX0NCg0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0K', '{}', 'ObjectHelper', 'VDM\\Joomla\\Utilities.ObjectHelper', '1.0.0', '{}', 'Utilities Object Helper', 'abstract class', '{}', '', 1, '2022-03-09 00:35:23', '2022-09-20 09:51:31', 15, 8), (19, '', 'Basic Math Helper\r\n\r\n@since 3.0.9', '', '', '152c8793-8b75-4715-996a-257b9f65451c', '', '', '', '{}', 'CS8qKg0KCSAqIGJjIG1hdGggd3JhcHBlciAodmVyeSBiYXNpYyBub3QgZm9yIGFjY291bnRpbmcpDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkdHlwZSAgICBUaGUgdHlwZSBiYyBtYXRoDQoJICogQHBhcmFtICAgaW50ICAgICAgJHZhbDEgICAgVGhlIGZpcnN0IHZhbHVlDQoJICogQHBhcmFtICAgaW50ICAgICAgJHZhbDIgICAgVGhlIHNlY29uZCB2YWx1ZQ0KCSAqIEBwYXJhbSAgIGludCAgICAgICRzY2FsZSAgIFRoZSBzY2FsZSB2YWx1ZQ0KCSAqDQoJICogQHJldHVybiBpbnQNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBiYygkdHlwZSwgJHZhbDEsICR2YWwyLCAkc2NhbGUgPSAwKQ0KCXsNCgkJLy8gYnVpbGQgZnVuY3Rpb24gbmFtZQ0KCQkkZnVuY3Rpb24gPSAnYmMnIC4gJHR5cGU7DQoJCS8vIHVzZSB0aGUgYmNtYXRoIGZ1bmN0aW9uIGlmIGF2YWlsYWJsZQ0KCQlpZiAoZnVuY3Rpb25fZXhpc3RzKCRmdW5jdGlvbikpDQoJCXsNCgkJCXJldHVybiAkZnVuY3Rpb24oJHZhbDEsICR2YWwyLCAkc2NhbGUpOw0KCQl9DQoJCS8vIGlmIGZ1bmN0aW9uIGRvZXMgbm90IGV4aXN0IHdlIHVzZSArLSovIG9wZXJhdG9ycyAoZmFsbGJhY2sgLSBub3QgaWRlYWwpDQoJCXN3aXRjaCAoJHR5cGUpDQoJCXsNCgkJCS8vIE11bHRpcGx5IHR3byBudW1iZXJzDQoJCQljYXNlICdtdWwnOg0KCQkJCXJldHVybiAoc3RyaW5nKSByb3VuZCgkdmFsMSAqICR2YWwyLCAkc2NhbGUpOw0KCQkJCWJyZWFrOw0KCQkJLy8gRGl2aWRlIG9mIHR3byBudW1iZXJzDQoJCQljYXNlICdkaXYnOg0KCQkJCXJldHVybiAoc3RyaW5nKSByb3VuZCgkdmFsMSAvICR2YWwyLCAkc2NhbGUpOw0KCQkJCWJyZWFrOw0KCQkJLy8gQWRkaW5nIHR3byBudW1iZXJzDQoJCQljYXNlICdhZGQnOg0KCQkJCXJldHVybiAoc3RyaW5nKSByb3VuZCgkdmFsMSArICR2YWwyLCAkc2NhbGUpOw0KCQkJCWJyZWFrOw0KCQkJLy8gU3VidHJhY3Qgb25lIG51bWJlciBmcm9tIHRoZSBvdGhlcg0KCQkJY2FzZSAnc3ViJzoNCgkJCQlyZXR1cm4gKHN0cmluZykgcm91bmQoJHZhbDEgLSAkdmFsMiwgJHNjYWxlKTsNCgkJCQlicmVhazsNCgkJCS8vIFJhaXNlIGFuIGFyYml0cmFyeSBwcmVjaXNpb24gbnVtYmVyIHRvIGFub3RoZXINCgkJCWNhc2UgJ3Bvdyc6DQoJCQkJcmV0dXJuIChzdHJpbmcpIHJvdW5kKHBvdygkdmFsMSwgJHZhbDIpLCAkc2NhbGUpOw0KCQkJCWJyZWFrOw0KCQkJLy8gQ29tcGFyZSB0d28gYXJiaXRyYXJ5IHByZWNpc2lvbiBudW1iZXJzDQoJCQljYXNlICdjb21wJzoNCgkJCQlyZXR1cm4gKHJvdW5kKCR2YWwxLDIpID09IHJvdW5kKCR2YWwyLDIpKTsNCgkJCQlicmVhazsNCgkJfQ0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0KDQoJLyoqDQoJICogQmFzaWMgc3VtIG9mIGFuIGFycmF5IHdpdGggbW9yZSBwcmVjaXNpb24NCgkgKg0KCSAqIEBwYXJhbSAgIGFycmF5ICAgJGFycmF5ICAgIFRoZSB2YWx1ZXMgdG8gc3VtDQoJICogQHBhcmFtICAgaW50ICAgICAgJHNjYWxlICAgVGhlIHNjYWxlIHZhbHVlDQoJICoNCgkgKiBAcmV0dXJuIGZsb2F0DQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc3VtKCRhcnJheSwgJHNjYWxlID0gNCkNCgl7DQoJCS8vIHVzZSB0aGUgYmNhZGQgZnVuY3Rpb24gaWYgYXZhaWxhYmxlDQoJCWlmIChmdW5jdGlvbl9leGlzdHMoJ2JjYWRkJykpDQoJCXsNCgkJCS8vIHNldCB0aGUgc3RhcnQgdmFsdWUNCgkJCSR2YWx1ZSA9IDAuMDsNCgkJCS8vIGxvb3AgdGhlIHZhbHVlcyBhbmQgcnVuIGJjYWRkDQoJCQlmb3JlYWNoKCRhcnJheSBhcyAkdmFsKQ0KCQkJew0KCQkJCSR2YWx1ZSA9IGJjYWRkKCR2YWx1ZSwgJHZhbCwgJHNjYWxlKTsNCgkJCX0NCgkJCXJldHVybiAkdmFsdWU7DQoJCX0NCgkJLy8gZmFsbCBiYWNrIG9uIGFycmF5IHN1bQ0KCQlyZXR1cm4gYXJyYXlfc3VtKCRhcnJheSk7DQoJfQ0K', '{}', 'MathHelper', 'VDM\\Joomla\\Utilities.MathHelper', '1.0.0', '{}', 'Utilities Math Helper', 'abstract class', '{}', '', 1, '2022-03-09 13:05:39', '2022-09-20 09:51:26', 11, 9), (20, '', 'Control the naming of a plugin\r\n\r\n@since 3.0.9', '', '', '3cf76fbf-fd95-4a33-878e-7aff6d36b7f6', '', '', '', '{}', 'CS8qKg0KCSAqIE1ha2luZyBwbHVnaW4gZm9sZGVyIG5hbWUgc2FmZQ0KCSAqDQoJICogQGlucHV0CXN0cmluZyAgICAkY29kZU5hbWUgICBUaGUgbmFtZQ0KCSAqIEBpbnB1dAlzdHJpbmcgICAgJGdyb3VwICAgVGhlIGdyb3VwIG5hbWUNCgkgKg0KCSAqIEByZXR1cm5zIHN0cmluZyBvbiBzdWNjZXNzDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc2FmZUZvbGRlck5hbWUoJGNvZGVOYW1lLCAkZ3JvdXApDQoJew0KCQkvLyBlZGl0b3JzLXh0ZCBncm91cCBwbHVnaW5zIG11c3QgaGF2ZSBhIGNsYXNzIHdpdGggcGxnQnV0dG9uPFBsdWdpbk5hbWU+IHN0cnVjdHVyZQ0KCQlpZiAoJGdyb3VwID09PSAnZWRpdG9ycy14dGQnKQ0KCQl7DQoJCQkkZ3JvdXAgPSAnQnV0dG9uJzsNCgkJfQ0KDQoJCXJldHVybiAncGxnXycgLiBzdHJ0b2xvd2VyKCRncm91cCkgLiAnXycgLiBzdHJ0b2xvd2VyKA0KCQkJJGNvZGVOYW1lDQoJCSk7DQoJfQ0KDQoJLyoqDQoJICogTWFraW5nIHBsdWdpbiBjbGFzcyBuYW1lIHNhZmUNCgkgKg0KCSAqIEBpbnB1dAlzdHJpbmcgICAgJGNvZGVOYW1lICAgVGhlIG5hbWUNCgkgKiBAaW5wdXQJc3RyaW5nICAgICRncm91cCAgIFRoZSBncm91cCBuYW1lDQoJICoNCgkgKiBAcmV0dXJucyBzdHJpbmcgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNhZmVDbGFzc05hbWUoJGNvZGVOYW1lLCAkZ3JvdXApDQoJew0KCQkvLyBlZGl0b3JzLXh0ZCBncm91cCBwbHVnaW5zIG11c3QgaGF2ZSBhIGNsYXNzIHdpdGggcGxnQnV0dG9uPFBsdWdpbk5hbWU+IHN0cnVjdHVyZQ0KCQlpZiAoJGdyb3VwID09PSAnZWRpdG9ycy14dGQnKQ0KCQl7DQoJCQkkZ3JvdXAgPSAnQnV0dG9uJzsNCgkJfQ0KDQoJCXJldHVybiAnUGxnJyAuIHVjZmlyc3QoJGdyb3VwKSAuIHVjZmlyc3QoDQoJCQkkY29kZU5hbWUNCgkJKTsNCgl9DQoNCgkvKioNCgkgKiBNYWtpbmcgcGx1Z2luIGluc3RhbGwgY2xhc3MgbmFtZSBzYWZlDQoJICoNCgkgKiBAaW5wdXQJc3RyaW5nICAgICRjb2RlTmFtZSAgIFRoZSBuYW1lDQoJICogQGlucHV0CXN0cmluZyAgICAkZ3JvdXAgICBUaGUgZ3JvdXAgbmFtZQ0KCSAqDQoJICogQHJldHVybnMgc3RyaW5nIG9uIHN1Y2Nlc3MNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzYWZlSW5zdGFsbENsYXNzTmFtZSgkY29kZU5hbWUsICRncm91cCkNCgl7DQoJCS8vIGVkaXRvcnMteHRkIGdyb3VwIHBsdWdpbnMgbXVzdCBoYXZlIGEgY2xhc3Mgd2l0aCBwbGdCdXR0b248UGx1Z2luTmFtZT4gc3RydWN0dXJlDQoJCWlmICgkZ3JvdXAgPT09ICdlZGl0b3JzLXh0ZCcpDQoJCXsNCgkJCSRncm91cCA9ICdCdXR0b24nOw0KCQl9DQoNCgkJcmV0dXJuICdwbGcnIC4gdWNmaXJzdCgkZ3JvdXApIC4gdWNmaXJzdCgNCgkJCSRjb2RlTmFtZQ0KCQkpIC4gJ0luc3RhbGxlclNjcmlwdCc7DQoJfQ0KDQoJLyoqDQoJICogTWFraW5nIGxhbmd1YWdlIHByZWZpeCBzYWZlDQoJICoNCgkgKiBAaW5wdXQJc3RyaW5nICAgICRjb2RlTmFtZSAgIFRoZSBuYW1lDQoJICogQGlucHV0CXN0cmluZyAgICAkZ3JvdXAgICBUaGUgZ3JvdXAgbmFtZQ0KCSAqDQoJICogQHJldHVybnMgc3RyaW5nIG9uIHN1Y2Nlc3MNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzYWZlTGFuZ1ByZWZpeCgkY29kZU5hbWUsICRncm91cCkNCgl7DQoJCS8vIGVkaXRvcnMteHRkIGdyb3VwIHBsdWdpbnMgbXVzdCBoYXZlIGEgY2xhc3Mgd2l0aCBwbGdCdXR0b248UGx1Z2luTmFtZT4gc3RydWN0dXJlDQoJCWlmICgkZ3JvdXAgPT09ICdlZGl0b3JzLXh0ZCcpDQoJCXsNCgkJCSRncm91cCA9ICdCdXR0b24nOw0KCQl9DQoNCgkJcmV0dXJuICdQTEdfJyAuIHN0cnRvdXBwZXIoJGdyb3VwKSAuICdfJyAuIHN0cnRvdXBwZXIoDQoJCQkkY29kZU5hbWUNCgkJKTsNCgl9DQo=', '{}', 'PluginHelper', 'VDM\\Joomla\\Utilities.String.PluginHelper', '1.0.0', '{}', 'String Plugin Helper', 'abstract class', '{}', '', 1, '2022-03-09 14:44:58', '2022-09-20 10:10:12', 14, 5), @@ -1993,7 +1993,7 @@ INSERT INTO `#__componentbuilder_power` (`id`, `add_head`, `description`, `exten (24, 1, 'Image helper\r\n\r\n@since 3.0.11', '', '', '962b15d8-915f-4cd7-aea6-7cf82afdc20b', 'dXNlIEpvb21sYVxDTVNcRmlsZXN5c3RlbVxGaWxlOw0KdXNlIEpvb21sYVxDTVNcRmlsZXN5c3RlbVxGb2xkZXI7DQp1c2UgSm9vbWxhXENNU1xVcmlcVXJpOw0KdXNlIEpvb21sYVxDTVNcSW1hZ2VcSW1hZ2U7', '', '', '{\"load_selection0\":{\"load\":\"91004529-94a9-4590-b842-e7c6b624ecf5\"},\"load_selection1\":{\"load\":\"f11dc790-713e-4706-9a85-a318ed3ad56e\"}}', 'CS8qKg0KCSAqIFJlc2l6ZSBhbiBpbWFnZQ0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nICAgICRmdWxsUGF0aCAgIFRoZSBmdWxsIHBhdGggdG8gdGhlIGltYWdlDQoJICogQHBhcmFtICAgc3RyaW5nICAgICR0eXBlICAgICAgICBUaGUgdHlwZSBvZiBpbWFnZQ0KCSAqDQoJICogQHJldHVybiBib29sDQoJICogQHNpbmNlIDMuMC4xMQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcmVzaXplKHN0cmluZyAkZnVsbFBhdGgsIHN0cmluZyAkdHlwZSkNCgl7DQoJCS8vIGZpcnN0IGNoZWNrIGlmIHdlIHNob3VsZCByZXNpemUgdGhpcyB0YXJnZXQNCgkJaWYgKDEgPT0gSGVscGVyOjpnZXRQYXJhbXMoKS0+Z2V0KCR0eXBlIC4gJ19yZXNpemUnLCAwKSkNCgkJew0KCQkJLy8gbG9hZCB0aGUgc2l6ZSB0byBiZSBzZXQNCgkJCSRoZWlnaHQgPSBIZWxwZXI6OmdldFBhcmFtcygpLT5nZXQoJHR5cGUgLiAnX2hlaWdodCcsICdub3Rfc2V0Jyk7DQoJCQkkd2lkdGggPSBIZWxwZXI6OmdldFBhcmFtcygpLT5nZXQoJHR5cGUgLiAnX3dpZHRoJywgJ25vdF9zZXQnKTsNCg0KCQkJLy8gR2V0IGZpbGUgZXh0ZW5zaW9uL2Zvcm1hdA0KCQkJJGZpbGVfZm9ybWF0ID0gTWltZUhlbHBlcjo6ZXh0ZW5zaW9uKCRmdWxsUGF0aCk7DQoNCgkJCS8vIGdldCBpbWFnZSBwcm9wZXJ0aWVzDQoJCQkkaW1hZ2UgPSBzZWxmOjpnZXRQcm9wZXJ0aWVzKCRmdWxsUGF0aCk7DQoNCgkJCS8vIG1ha2Ugc3VyZSB3ZSBoYXZlIGFuIG9iamVjdA0KCQkJaWYgKE9iamVjdEhlbHBlcjo6Y2hlY2soJGltYWdlKSAmJiBpc19zdHJpbmcoJGZpbGVfZm9ybWF0KSkNCgkJCXsNCgkJCQlpZiAoJHdpZHRoICE9PSAnbm90X3NldCcgJiYgJGhlaWdodCAhPT0gJ25vdF9zZXQnICYmICgkaW1hZ2UtPndpZHRoICE9ICR3aWR0aCB8fCAkaW1hZ2UtPmhlaWdodCAhPSAkaGVpZ2h0KSkNCgkJCQl7DQoJCQkJCS8vIGlmIGltYWdlIGlzIGh1Z2UgYW5kIHNob3VsZCBvbmx5IGJlIHNjYWxlZCwgcmVzaXplIGl0IG9uIHRoZSBmbHkNCgkJCQkJaWYoKCRpbWFnZS0+d2lkdGggPiA5MDAgfHwgJGltYWdlLT5oZWlnaHQgPiA3MDApICYmICgkaGVpZ2h0ID09IDAgfHwgJHdpZHRoID09IDApKQ0KCQkJCQl7DQoJCQkJCQkvLyBzZWxlY3QgdGhlIGltYWdlICJnZXR0ZXIiIGJhc2VkIG9uIGZvcm1hdA0KCQkJCQkJaWYoJGZpbGVfZm9ybWF0ID09ICJqcGciIHx8ICRmaWxlX2Zvcm1hdCA9PSAianBlZyIgKQ0KCQkJCQkJew0KCQkJCQkJCSRzcmMgPSBpbWFnZWNyZWF0ZWZyb21qcGVnKCRmdWxsUGF0aCk7DQoJCQkJCQl9DQoJCQkJCQllbHNlaWYoJGZpbGVfZm9ybWF0ID09ICJwbmciKQ0KCQkJCQkJew0KCQkJCQkJCSRzcmMgPSBpbWFnZWNyZWF0ZWZyb21wbmcoJGZ1bGxQYXRoKTsNCgkJCQkJCX0NCgkJCQkJCWVsc2VpZigkZmlsZV9mb3JtYXQgPT0gImdpZiIpDQoJCQkJCQl7DQoJCQkJCQkJJHNyYyA9IGltYWdlY3JlYXRlZnJvbWdpZigkZnVsbFBhdGgpOw0KCQkJCQkJfQ0KCQkJCQkJLy8gd2Ugb25seSBzdXBwb3J0IHRoZSBhYm92ZSB0aHJlZSBmb3JtYXRzIGZvciBub3cNCgkJCQkJCWVsc2UNCgkJCQkJCXsNCgkJCQkJCQlyZXR1cm4gZmFsc2U7DQoJCQkJCQl9DQoNCgkJCQkJCS8vIHdvcmtvdXQgdGhlIHJhdGlvIGlmIHdlIGhhdmUgaGVpZ2h0DQoJCQkJCQlpZiAoJGhlaWdodCAhPSAwKQ0KCQkJCQkJew0KCQkJCQkJCSRoZWlnaHRfcmF0aW8gPSAkaW1hZ2UtPmhlaWdodCAvICRoZWlnaHQ7DQoJCQkJCQl9DQoNCgkJCQkJCS8vIHdvcmtvdXQgdGhlIHJhdGlvIGlmIHdlIGhhdmUgd2lkdGgNCgkJCQkJCWlmICgkd2lkdGggIT0gMCkNCgkJCQkJCXsNCgkJCQkJCQkkd2lkdGhfcmF0aW8gPSAkaW1hZ2UtPndpZHRoIC8gJHdpZHRoOw0KCQkJCQkJfQ0KDQoJCQkJCQkvLyBzZXQgbWF4IHJhdGlvIGJhc2VkIG9uIGJvdGgNCgkJCQkJCWlmIChpc3NldCgkaGVpZ2h0X3JhdGlvKSAmJiBpc3NldCgkd2lkdGhfcmF0aW8pKQ0KCQkJCQkJew0KCQkJCQkJCSRtYXhfcmF0aW8JPSBtYXgoJHdpZHRoX3JhdGlvLCAkaGVpZ2h0X3JhdGlvKTsNCgkJCQkJCX0NCgkJCQkJCS8vIHNldCBtYXggcmF0aW8gYmFzZWQgb24gd2lkdGgNCgkJCQkJCWVsc2VpZiAoaXNzZXQoJHdpZHRoX3JhdGlvKSkNCgkJCQkJCXsNCgkJCQkJCQkkbWF4X3JhdGlvCT0gJHdpZHRoX3JhdGlvOw0KCQkJCQkJfQ0KCQkJCQkJLy8gc2V0IG1heCByYXRpbyBiYXNlZCBvbiBoZWlnaHQNCgkJCQkJCWVsc2VpZiAoaXNzZXQoJGhlaWdodF9yYXRpbykpDQoJCQkJCQl7DQoJCQkJCQkJJG1heF9yYXRpbwk9ICRoZWlnaHRfcmF0aW87DQoJCQkJCQl9DQoNCgkJCQkJCS8vIGlmIHdlIGhhdmUgcmF0aW8gZG8gdGhlIGNvbnZlcnNpb24NCgkJCQkJCWlmICgkbWF4X3JhdGlvID4gMSkNCgkJCQkJCXsNCgkJCQkJCQkkbmV3X3dpZHRoCT0gJGltYWdlLT53aWR0aCAvICRtYXhfcmF0aW87DQoJCQkJCQkJJG5ld19oZWlnaHQJPSAkaW1hZ2UtPmhlaWdodCAvICRtYXhfcmF0aW87DQoJCQkJCQl9DQoJCQkJCQllbHNlDQoJCQkJCQl7DQoJCQkJCQkJJG5ld193aWR0aAk9ICRpbWFnZS0+d2lkdGg7DQoJCQkJCQkJJG5ld19oZWlnaHQJPSAkaW1hZ2UtPmhlaWdodDsNCgkJCQkJCX0NCg0KCQkJCQkJJHRtcAkJCT0gaW1hZ2VjcmVhdGV0cnVlY29sb3IoJG5ld193aWR0aCwgJG5ld19oZWlnaHQpOw0KCQkJCQkJJGJhY2tncm91bmRfY29sb3IJPSBpbWFnZWNvbG9yYWxsb2NhdGUoJHRtcCwgMjU1LCAyNTUsIDI1NSk7DQoNCgkJCQkJCWltYWdlZmlsbCgkdG1wLCAwLCAwLCAkYmFja2dyb3VuZF9jb2xvcik7DQoJCQkJCQlpbWFnZWNvcHlyZXNhbXBsZWQoJHRtcCwgJHNyYywgMCwgMCwgMCwgMCwkbmV3X3dpZHRoLCAkbmV3X2hlaWdodCwgJGltYWdlLT53aWR0aCwgJGltYWdlLT5oZWlnaHQpOw0KCQkJCQkJaW1hZ2VqcGVnKCR0bXAsICRmdWxsUGF0aCwgMTAwKTsNCgkJCQkJCWltYWdlZGVzdHJveSgkc3JjKTsNCgkJCQkJCWltYWdlZGVzdHJveSgkdG1wKTsNCgkJCQkJfQ0KCQkJCQkvLyB3ZSBvbmx5IGNyb3AgaWYgYm90aCBoZWlnaHQgYW5kIHdpZHRoIGlzIHNldCB0byBjcm9wDQoJCQkJCWlmICgkaGVpZ2h0ICE9IDAgJiYgJHdpZHRoICE9IDApDQoJCQkJCXsNCgkJCQkJCS8vIGdldCB0aGUgY3VycmVudCBjb21wb25lbnQgY29kZSBuYW1lDQoJCQkJCQlpZiAoKCRjb21wb25lbnRfY29kZV9uYW1lID0gSGVscGVyOjpnZXRDb2RlKG51bGwsIGZhbHNlKSkgPT09IGZhbHNlKQ0KCQkJCQkJew0KCQkJCQkJCS8vIGlmIHdlIGNhbid0IGdldCB0aGUgY29tcG9uZW50IGNvZGUgbmFtZSB3ZSBzaG91bGQgYnJlYWsgcHV0IG5vdw0KCQkJCQkJCXJldHVybiBmYWxzZTsNCgkJCQkJCX0NCgkJCQkJCS8vIEluY2x1ZGUgd2lkZWltYWdlIC0gaHR0cDovL3dpZGVpbWFnZS5zb3VyY2Vmb3JnZS5uZXQgVE9ETzogaHR0cHM6Ly9naXRodWIuY29tL3Ntb3R0dC9XaWRlSW1hZ2UNCgkJCQkJCXJlcXVpcmVfb25jZShKUEFUSF9BRE1JTklTVFJBVE9SIC4gJy9jb21wb25lbnRzL2NvbV8nIC4gJGNvbXBvbmVudF9jb2RlX25hbWUgLiAnL2hlbHBlcnMvd2lkZWltYWdlL1dpZGVJbWFnZS5waHAnKTsNCgkJCQkJCS8vIGxvYWQgdGhlIGltYWdlIGludG8gdGhlIGJ1aWxkZXINCgkJCQkJCSRidWlsZGVyID0gXFdpZGVJbWFnZTo6bG9hZCgkZnVsbFBhdGgpOw0KCQkJCQkJLy8gcmVzaXplIHRoZSBpbWFnZQ0KCQkJCQkJJHJlc2l6ZWQgPSAkYnVpbGRlci0+cmVzaXplKCR3aWR0aCwgJGhlaWdodCwgJ291dHNpZGUnKS0+Y3JvcCgnY2VudGVyJywgJ21pZGRsZScsICR3aWR0aCwgJGhlaWdodCk7DQoJCQkJCQkvLyBzYXZlIHRoZSBuZXcgaW1hZ2UgdG8gZnVsbCBmaWxlIHBhdGgNCgkJCQkJCSRyZXNpemVkLT5zYXZlVG9GaWxlKCRmdWxsUGF0aCk7DQoJCQkJCX0NCgkJCQl9DQoJCQkJcmV0dXJuIHRydWU7DQoJCQl9DQoJCX0NCgkJcmV0dXJuIGZhbHNlOw0KCX0NCg0KCS8qKg0KCSAqIEdldCBJbWFnZSBQcm9wZXJ0aWVzDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAgJGZ1bGxQYXRoICAgVGhlIGZ1bGwgcGF0aCB0byB0aGUgaW1hZ2UNCgkgKg0KCSAqIEByZXR1cm4gYm9vbHxzdGRDbGFzcw0KCSAqIEBzaW5jZSAzLjAuMTENCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFByb3BlcnRpZXMoJGZ1bGxQYXRoKQ0KCXsNCgkJLy8gY2hlY2sgdGhhdCB0aGUgZmlsZSBleGlzdA0KCQlpZiAoRmlsZTo6ZXhpc3RzKCRmdWxsUGF0aCkpDQoJCXsNCgkJCSRwcm9wZXJ0aWVzID0gSW1hZ2U6OmdldEltYWdlRmlsZVByb3BlcnRpZXMoJGZ1bGxQYXRoKTsNCgkJCS8vIGNoZWNrIGlmIHdlIGhhdmUgcHJvcGVydGllcw0KCQkJaWYgKE9iamVjdEhlbHBlcjo6Y2hlY2soJHByb3BlcnRpZXMpKQ0KCQkJew0KCQkJCS8vIGdldCBpbWFnZSBmaWxlIG5hbWUNCgkJCQkkbmFtZSA9IGJhc2VuYW1lKCRmdWxsUGF0aCk7DQoJCQkJLy8gcmVtb3ZlIGZpbGUgbmFtZSBmcm9tIHBhdGgNCgkJCQkkZGlyX25hbWUgPSBwYXRoaW5mbygkZnVsbFBhdGgsIFBBVEhJTkZPX0RJUk5BTUUpOw0KCQkJCS8vIHJlbW92ZSB0aGUgc2VydmVyIHBhdGgNCgkJCQkkaW1hZ2VfcHVibGljX3BhdGggPSB0cmltKHN0cl9yZXBsYWNlKEpQQVRIX1NJVEUsICcnLCAkZGlyX25hbWUpLCAnLycpIC4gJy8nIC4gJG5hbWU7DQoJCQkJLy8gbm93IGFkZCB0aGUgc3JjIHBhdGggdG8gc2hvdyB0aGUgaW1hZ2UNCgkJCQkkcHJvcGVydGllcy0+c3JjID0gVXJpOjpyb290KCkgLiAkaW1hZ2VfcHVibGljX3BhdGg7DQoJCQkJLy8gcmV0dXJuIHRoZSBpbWFnZSBwcm9wZXJ0aWVzDQoJCQkJcmV0dXJuICRwcm9wZXJ0aWVzOw0KCQkJfQ0KCQl9DQoJCXJldHVybiBmYWxzZTsNCgl9DQo=', '{}', 'ImageHelper', 'VDM\\Joomla\\Utilities.ImageHelper', '1.0.0', '{}', 'Utilities ImageHelper', 'abstract class', '{\"use_selection0\":{\"use\":\"640b5352-fb09-425f-a26e-cd44eda03f15\",\"as\":\"default\"}}', '', 1, '2022-05-16 10:59:17', '2022-09-20 09:51:10', 21, 9), (25, 1, 'Upload Helper\r\n\r\n@since 3.0.11', '', '', 'd7600b43-771a-4747-9f5d-952765721799', 'dXNlIEpvb21sYVxDTVNcRmFjdG9yeTsNCnVzZSBKb29tbGFcQ01TXExhbmd1YWdlXFRleHQ7DQp1c2UgSm9vbWxhXENNU1xGaWxlc3lzdGVtXEZpbGU7DQp1c2UgSm9vbWxhXENNU1xGaWxlc3lzdGVtXEZvbGRlcjsNCnVzZSBKb29tbGFcQ01TXEZpbGVzeXN0ZW1cUGF0aDs=', '', '', '{\"load_selection0\":{\"load\":\"f11dc790-713e-4706-9a85-a318ed3ad56e\"},\"load_selection1\":{\"load\":\"1f28cb53-60d9-4db1-b517-3c7dc6b429ef\"}}', 'CS8qKg0KCSAqIFRydWUgdG8gdXNlIHN0cmVhbXMNCgkgKg0KCSAqIEB2YXIgICAgYm9vbA0KCSAqDQoJICogQHNpbmNlICAzLjAuMTENCgkgKi8NCglwdWJsaWMgc3RhdGljICR1c2VTdHJlYW1zID0gZmFsc2U7DQoNCgkvKioNCgkgKiBBbGxvdyB0aGUgdXBsb2FkIG9mIHVuc2FmZSBmaWxlcw0KCSAqDQoJICogQHZhciAgICBib29sDQoJICoNCgkgKiBAc2luY2UgIDMuMC4xMQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgJGFsbG93VW5zYWZlID0gZmFsc2U7DQoNCgkvKioNCgkgKiBPcHRpb25zIHRvIElucHV0RmlsdGVyOjppc1NhZmVGaWxlDQoJICoNCgkgKiBAdmFyICAgIGFycmF5DQoJICoNCgkgKiBAc2luY2UgIDMuMC4xMQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgJHNhZmVGaWxlT3B0aW9ucyA9IGFycmF5KCk7DQoNCgkvKioNCgkgKiBTZXQgdGhlIGVycm9yIGJlaGF2aW9yDQoJICoNCgkgKiBAdmFyICAgIGJvb2wNCgkgKg0KCSAqIEBzaW5jZSAgMy4wLjExDQoJICovDQoJcHVibGljIHN0YXRpYyAkZW5xdWV1ZUVycm9yID0gdHJ1ZTsNCg0KCS8qKg0KCSAqIEVycm9ycw0KCSAqDQoJICogQHZhciAgICBhcnJheQ0KCSAqDQoJICogQHNpbmNlICAzLjAuMTENCgkgKi8NCglwcm90ZWN0ZWQgc3RhdGljICRlcnJvcnMgPSBhcnJheSgpOw0KDQoJLyoqDQoJICogR2V0IGZpbGUvZmlsZXMgZnJvbSBhIEhUVFAgdXBsb2FkLg0KCSAqDQoJICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgJGZpZWxkICAgICAgICBUaGUgaW5wdXQgZmllbGQgbmFtZQ0KCSAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICR0eXBlICAgICAgICBUaGUgZmlsZSB0eXBlDQoJICogQHBhcmFtICBzdHJpbmd8bnVsbCAgICRmaWx0ZXIgICAgICAgIFRoZSBmaWx0ZXIgdG8gdXNlIHdoZW4gdXBsb2FkaW5nIHRoZSBmaWxlDQoJICogQHBhcmFtICBzdHJpbmd8bnVsbCAgICRwYXRoICAgICAgICBUaGUgcGF0aCB0byB0aGUgZGlyZWN0b3J5IHdoZXJlIHRoZSBpbWFnZSBtdXN0IGJlIHBsYWNlZA0KCSAqDQoJICogQHJldHVybiAgbWl4ZWQgICBGaWxlIGRldGFpbHMgb3IgZmFsc2Ugb24gZmFpbHVyZS4NCgkgKiBAc2luY2UgIDMuMC4xMQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0KHN0cmluZyAkZmllbGQsIHN0cmluZyAkdHlwZSwgc3RyaW5nICRmaWx0ZXIgPSBudWxsLCBzdHJpbmcgJHBhdGggPSBudWxsKQ0KCXsNCgkJLy8gR2V0IHRoZSB1cGxvYWRlZCBmaWxlIGluZm9ybWF0aW9uLg0KCQkkaW5wdXQgICAgPSBGYWN0b3J5OjpnZXRBcHBsaWNhdGlvbigpLT5pbnB1dDsNCg0KCQkvLyBzZXQgdGhlIGRlZmF1bHQgZmlsdGVyDQoJCWlmIChlbXB0eSgkZmlsdGVyKSkNCgkJew0KCQkJJGZpbHRlciA9ICdhcnJheSc7DQoJCX0NCgkJLy8gaWYgcmF3IHRoZW4gYWxzbyB1bnNhZmUNCgkJLy8gc2VlOiBodHRwczovL2dpdGh1Yi5jb20vam9vbWxhL2pvb21sYS1jbXMvYmxvYi80LjEtZGV2L2FkbWluaXN0cmF0b3IvY29tcG9uZW50cy9jb21faW5zdGFsbGVyL3NyYy9Nb2RlbC9JbnN0YWxsTW9kZWwucGhwI0wyNTkNCgkJZWxzZWlmICgkZmlsdGVyID09PSAncmF3JykNCgkJew0KCQkJc2VsZjo6JGFsbG93VW5zYWZlID0gdHJ1ZTsNCgkJfQ0KDQoJCS8vIGNoZWNrIGlmIHdlIGhhdmUgYSBmaWxlIGRlc3RpbmF0aW9uIG5hbWUgaW4gdGhlIGZpZWxkIG5hbWUNCgkJJG5hbWUgPSBudWxsOw0KCQlpZiAoc3RycG9zKCRmaWVsZCwgJzonKSAhPT0gZmFsc2UpDQoJCXsNCgkJCWxpc3QoJGZpZWxkLCAkbmFtZSkgPSBleHBsb2RlKCc6JywgJGZpZWxkKTsNCgkJfQ0KDQoJCS8vIFNlZSBKSW5wdXRGaWxlczo6Z2V0Lg0KCQkkdXNlcmZpbGUgPSAkaW5wdXQtPmZpbGVzLT5nZXQoJGZpZWxkLCBudWxsLCAkZmlsdGVyKTsNCg0KCQkvLyBNYWtlIHN1cmUgdGhhdCBmaWxlIHVwbG9hZHMgYXJlIGVuYWJsZWQgaW4gcGhwLg0KCQlpZiAoIShib29sKSBpbmlfZ2V0KCdmaWxlX3VwbG9hZHMnKSkNCgkJew0KCQkJc2VsZjo6c2V0RXJyb3IoVGV4dDo6XygnV2FybmluZywgdXBsb2FkIGVycm9yLicpKTsNCg0KCQkJcmV0dXJuIGZhbHNlOw0KCQl9DQoNCgkJLy8gSWYgdGhlcmUgaXMgbm8gdXBsb2FkZWQgZmlsZSwgd2UgaGF2ZSBhIHByb2JsZW0uLi4NCgkJaWYgKCFpc19hcnJheSgkdXNlcmZpbGUpKQ0KCQl7DQoJCQlzZWxmOjpzZXRFcnJvcihUZXh0OjpfKCdObyB1cGxvYWQgc2VsZWN0ZWQnKSk7DQoNCgkJCXJldHVybiBmYWxzZTsNCgkJfQ0KDQoJCS8vIElzIHRoZSBQSFAgdG1wIGRpcmVjdG9yeSBtaXNzaW5nPw0KCQlpZiAoJHVzZXJmaWxlWydlcnJvciddICYmICgkdXNlcmZpbGVbJ2Vycm9yJ10gPT0gVVBMT0FEX0VSUl9OT19UTVBfRElSKSkNCgkJew0KCQkJc2VsZjo6c2V0RXJyb3IoVGV4dDo6XygnVGhlcmUgd2FzIGFuIGVycm9yIHVwbG9hZGluZyB0byB0aGUgc2VydmVyLicpIC4gJzxicj4nIC4gVGV4dDo6XygnVGhlIFBIUCB0ZW1wb3JhcnkgZm9sZGVyIGlzIG5vdCBzZXQuJykpOw0KDQoJCQlyZXR1cm4gZmFsc2U7DQoJCX0NCg0KCQkvLyBJcyB0aGUgbWF4IHVwbG9hZCBzaXplIHRvbyBzbWFsbCBpbiBwaHAuaW5pPw0KCQlpZiAoJHVzZXJmaWxlWydlcnJvciddICYmICgkdXNlcmZpbGVbJ2Vycm9yJ10gPT0gVVBMT0FEX0VSUl9JTklfU0laRSkpDQoJCXsNCgkJCXNlbGY6OnNldEVycm9yKFRleHQ6Ol8oJ1RoZXJlIHdhcyBhbiBlcnJvciB1cGxvYWRpbmcgdG8gdGhlIHNlcnZlci4nKSAuICc8YnI+JyAuIFRleHQ6Ol8oJ1lvdXIgZmlsZSB3YXMgaXMgbGFyZ2VyIHRoYW4gdGhlIGFsbG93ZWQgc2l6ZS4nKSk7DQoNCgkJCXJldHVybiBmYWxzZTsNCgkJfQ0KDQoJCS8vIENoZWNrIGlmIHRoZXJlIHdhcyBhIGRpZmZlcmVudCBwcm9ibGVtIHVwbG9hZGluZyB0aGUgZmlsZS4NCgkJaWYgKCR1c2VyZmlsZVsnZXJyb3InXSB8fCAkdXNlcmZpbGVbJ3NpemUnXSA8IDEpDQoJCXsNCgkJCXNlbGY6OnNldEVycm9yKFRleHQ6Ol8oJ1RoZXJlIHdhcyBhbiBlcnJvciB1cGxvYWRpbmcgdG8gdGhlIHNlcnZlci4nKSk7DQoNCgkJCXJldHVybiBmYWxzZTsNCgkJfQ0KDQoJCS8vIGNoZWNrIGlmIGEgcGF0aCB3YXMgcGFzc2VkIGFuZCBleGlzdA0KCQlpZiAoaXNfc3RyaW5nKCRwYXRoKSAmJiBGb2xkZXI6OmNyZWF0ZSgkcGF0aCkpDQoJCXsNCgkJCS8vIHNldCB0aGUgcGF0aA0KCQkJJHVzZXJmaWxlWydwYXRoJ10gPSAkcGF0aDsNCgkJfQ0KCQllbHNlDQoJCXsNCgkJCS8vIGdldCB0aGUgSm9vbWxhIGNvbmZpZyBjbGFzcw0KCQkJJGNvbmZpZyA9IEZhY3Rvcnk6OmdldENvbmZpZygpOw0KCQkJLy8gc2V0IHRoZSBwYXRoDQoJCQkkdXNlcmZpbGVbJ3BhdGgnXSA9ICRjb25maWctPmdldCgndG1wX3BhdGgnKTsNCgkJfQ0KDQoJCS8vIHNldCB0aGUgcmFuZG9tIHBhcnQgb2YgdGhlIG5hbWUNCgkJJHVzZXJmaWxlWydyYW5kb20nXSA9IFN0cmluZ0hlbHBlcjo6cmFuZG9tKDEyKTsNCg0KCQkvLyBzZXQgdGhlIGZpbGUgbmFtZQ0KCQlpZiAoZW1wdHkoJG5hbWUpKQ0KCQl7DQoJCQkvLyBzZXQgdGhlIGZpbGUgbmFtZQ0KCQkJJHVzZXJmaWxlWydmaWxlX25hbWUnXSA9ICR1c2VyZmlsZVsncmFuZG9tJ10gLiAkdXNlcmZpbGVbJ25hbWUnXTsNCgkJfQ0KCQllbHNlDQoJCXsNCgkJCS8vIGNoZWNrIHRoYXQgaGlzIG5hbWUgaGFzIGZpbGUgZm9ybWF0DQoJCQlpZiAoaXNfc3RyaW5nKCRuYW1lKSAmJiBzdHJwb3MoJG5hbWUsICcuJykgPT09IGZhbHNlKQ0KCQkJew0KCQkJCSRuYW1lID0gJG5hbWUgLiAnLicgLiBNaW1lSGVscGVyOjpleHRlbnNpb24obnVsbCwgJHVzZXJmaWxlWyd0eXBlJ10pOw0KCQkJfQ0KCQkJJHVzZXJmaWxlWydmaWxlX25hbWUnXSA9ICRuYW1lOw0KCQl9DQoNCgkJLy8gc2V0IGZ1bGwgcGF0aA0KCQkkdXNlcmZpbGVbJ2Z1bGxfcGF0aCddID0gJHVzZXJmaWxlWydwYXRoJ10gLiAnLycgLiAkdXNlcmZpbGVbJ2ZpbGVfbmFtZSddOw0KDQoJCS8vIFVwbG9hZCB0aGUgZmlsZS4NCgkJaWYgKEZpbGU6OnVwbG9hZCgkdXNlcmZpbGVbJ3RtcF9uYW1lJ10sICR1c2VyZmlsZVsnZnVsbF9wYXRoJ10sIHNlbGY6OiR1c2VTdHJlYW1zLCBzZWxmOjokYWxsb3dVbnNhZmUpKQ0KCQl7DQoJCQkvLyBDaGVjayB0aGF0IHRoaXMgaXMgYSB2YWxpZCBmaWxlDQoJCQlyZXR1cm4gc2VsZjo6Y2hlY2soJHVzZXJmaWxlLCAkdHlwZSk7DQoJCX0NCgkJcmV0dXJuIGZhbHNlOw0KCX0NCg0KCS8qKg0KCSAqIEdldCB0aGUgZXJyb3JzDQoJICoNCgkgKiBAcGFyYW0gIGJvb2wgICAgICAgICAkdG9TdHJpbmcgICAgICBUaGUgb3B0aW9uIHRvIHJldHVybiBlcnJvcnMgYXMgYSBzdHJpbmcNCgkgKg0KCSAqIEByZXR1cm4gIGFycmF5DQoJICogQHNpbmNlICAzLjAuMTENCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEVycm9yKCR0b1N0cmluZyA9IGZhbHNlKQ0KCXsNCgkJaWYgKCR0b1N0cmluZykNCgkJew0KCQkJcmV0dXJuIGltcGxvZGUoJyAnIC4gUEhQX0VPTCwgc2VsZjo6JGVycm9ycyk7DQoJCX0NCgkJcmV0dXJuIHNlbGY6OiRlcnJvcnM7DQoJfQ0KDQoJLyoqDQoJICogQ2hlY2sgYSBmaWxlIGFuZCB2ZXJpZmllcyBpdCBhcyBhIGFsbG93ZWQgZmlsZSBmb3JtYXQgZmlsZQ0KCSAqDQoJICogQHBhcmFtICBhcnJheSAgICAgICAgICR1cGxvYWQgICAgICBUaGUgdXBsb2FkZWQgZGV0YWlscyBhcnJheQ0KCSAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAkdHlwZSAgICAgICAgICBUaGUgZmlsZSB0eXBlDQoJICoNCgkgKiBAcmV0dXJuICBhcnJheSAgb2YgZWxlbWVudHMNCgkgKg0KCSAqLw0KCXByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gY2hlY2soYXJyYXkgJHVwbG9hZCwgc3RyaW5nICR0eXBlKQ0KCXsNCgkJLy8gRGVmYXVsdCBmb3JtYXRzDQoJCSRmb3JtYXRzID0gTWltZUhlbHBlcjo6ZXh0ZW5zaW9ucygkdHlwZSk7DQoNCgkJLy8gQ2xlYW4gdGhlIHBhdGgNCgkJJHVwbG9hZF9wYXRoID0gUGF0aDo6Y2xlYW4oJHVwbG9hZFsnZnVsbF9wYXRoJ10pOw0KDQoJCS8vIEdldCBmaWxlIGV4dGVuc2lvbi9mb3JtYXQNCgkJJGZvcm1hdCA9IE1pbWVIZWxwZXI6OmV4dGVuc2lvbigkdXBsb2FkX3BhdGgpOw0KDQoJCS8vIExlZ2FsIGZpbGUgZm9ybWF0cw0KCQkkbGVnYWwgPSBhcnJheSgpOw0KDQoJCS8vIGNoZWNrIGlmIHRoZSBmaWxlIGZvcm1hdCBpcyBldmVuIGluIHRoZSBsaXN0DQoJCWlmIChpbl9hcnJheSgkZm9ybWF0LCAkZm9ybWF0cykpDQoJCXsNCgkJCS8vIGdldCBhbGxvd2VkIGZvcm1hdHMNCgkJCSRsZWdhbCA9IChhcnJheSkgSGVscGVyOjpnZXRQYXJhbXMoKS0+Z2V0KCR0eXBlIC4gJ19mb3JtYXRzJywgYXJyYXkoKSk7DQoJCX0NCg0KCQkvLyBjaGVjayB0aGUgZXh0ZW5zaW9uDQoJCWlmICghaW5fYXJyYXkoJGZvcm1hdCwgJGxlZ2FsKSkNCgkJew0KCQkJLy8gQ2xlYW51cCB0aGUgaW1wb3J0IGZpbGUNCgkJCXNlbGY6OnJlbW92ZSgkdXBsb2FkWydmdWxsX3BhdGgnXSk7DQoNCgkJCXNlbGY6OnNldEVycm9yKFRleHQ6Ol8oJ1VwbG9hZCBpcyBub3QgYSB2YWxpZCB0eXBlLicpKTsNCg0KCQkJcmV0dXJuIGZhbHNlOw0KCQl9DQoNCgkJcmV0dXJuICR1cGxvYWQ7DQoJfQ0KDQoJLyoqDQoJICogQ2xlYW4gdXAgdGVtcG9yYXJ5IHVwbG9hZGVkIGZpbGUNCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJGZ1bGxQYXRoICAgIFRoZSBmdWxsIHBhdGggb2YgdGhlIHVwbG9hZGVkIGZpbGUNCgkgKg0KCSAqIEByZXR1cm4gIGJvb2xlYW4gIFRydWUgb24gc3VjY2Vzcw0KCSAqDQoJICovDQoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiByZW1vdmUoJGZ1bGxQYXRoKQ0KCXsNCgkJLy8gSXMgdGhlIHBhY2thZ2UgZmlsZSBhIHZhbGlkIGZpbGU/DQoJCWlmIChpc19maWxlKCRmdWxsUGF0aCkpDQoJCXsNCgkJCUZpbGU6OmRlbGV0ZSgkZnVsbFBhdGgpOw0KCQl9DQoJCWVsc2VpZiAoaXNfZmlsZShQYXRoOjpjbGVhbigkZnVsbFBhdGgpKSkNCgkJew0KCQkJLy8gSXQgbWlnaHQgYWxzbyBiZSBqdXN0IGEgYmFzZSBmaWxlbmFtZQ0KCQkJRmlsZTo6ZGVsZXRlKFBhdGg6OmNsZWFuKCRmdWxsUGF0aCkpOw0KCQl9DQoJfQ0KDQoJLyoqDQoJICogU2V0IHRoZSBlcnJvcnMNCgkgKg0KCSAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAkbWVzc2FnZSAgIFRoZSBlcnJvciBtZXNzYWdlDQoJICoNCgkgKiBAcmV0dXJuICB2b2lkDQoJICogQHNpbmNlICAzLjAuMTENCgkgKi8NCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIHNldEVycm9yKCRtZXNzYWdlKQ0KCXsNCgkJaWYgKHNlbGY6OiRlbnF1ZXVlRXJyb3IpDQoJCXsNCgkJCUZhY3Rvcnk6OmdldEFwcGxpY2F0aW9uKCktPmVucXVldWVNZXNzYWdlKCRtZXNzYWdlLCAnZXJyb3InKTsNCgkJfQ0KCQllbHNlDQoJCXsNCgkJCXNlbGY6OiRlcnJvcnNbXSA9ICRtZXNzYWdlOw0KCQl9DQoJfQ0K', '{}', 'UploadHelper', 'VDM\\Joomla\\Utilities.UploadHelper', '1.0.0', '{}', 'Utilities UploadHelper', 'abstract class', '{\"use_selection0\":{\"use\":\"640b5352-fb09-425f-a26e-cd44eda03f15\",\"as\":\"default\"}}', '', 1, '2022-05-16 13:20:50', '2022-09-20 10:10:51', 37, 9), (26, '', 'Mime Helper\r\n\r\n@since 3.0.11', '', '', 'f11dc790-713e-4706-9a85-a318ed3ad56e', '', '', '', '{}', 'W0VYVEVSTkFMQ09ERT1odHRwczovL2dpc3QuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0xsZXdlbGx5bnZkbS83NGJlMzczMzU3ZTEzMWI4Nzc1YTc1ODJjM2RlNTA4Yi9yYXcvbWltZV90eXBlcy5waHBdDQoNCltFWFRFUk5BTENPREU9aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9MbGV3ZWxseW52ZG0vNzRiZTM3MzM1N2UxMzFiODc3NWE3NTgyYzNkZTUwOGIvcmF3L2dldC5waHBdDQoNCltFWFRFUk5BTENPREU9aHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9MbGV3ZWxseW52ZG0vNzRiZTM3MzM1N2UxMzFiODc3NWE3NTgyYzNkZTUwOGIvcmF3L2V4dGVuc2lvbnMucGhwXQ==', '{}', 'MimeHelper', 'VDM\\Joomla\\Utilities.MimeHelper', '1.0.0', '{}', 'Utilities MimeHelper', 'abstract class', '{}', '', 1, '2022-05-16 14:27:38', '2022-09-20 09:51:01', 6, 9), -(27, '', 'Just to link powers to the power updater component', '', '', '8025e71c-8e21-44cb-b23e-dce2fb5a1ab5', '', '', '', '{\"load_selection1\":{\"load\":\"79d765b3-7319-4988-9730-446c7f347020\"},\"load_selection2\":{\"load\":\"d7600b43-771a-4747-9f5d-952765721799\"},\"load_selection3\":{\"load\":\"962b15d8-915f-4cd7-aea6-7cf82afdc20b\"},\"load_selection4\":{\"load\":\"f11dc790-713e-4706-9a85-a318ed3ad56e\"},\"load_selection5\":{\"load\":\"0e6235bf-08ef-428a-bc0a-93957587e936\"}}', '', '{}', 'Updater', 'VDM\\Power\\Updater', '1.0.0', '{}', 'Power Updater', 'class', '{}', '', 1, '2022-05-21 13:15:55', '2022-09-20 11:54:29', 6, 13), +(27, '', 'Just to link powers to the power updater component', '', '', '8025e71c-8e21-44cb-b23e-dce2fb5a1ab5', '', '', '', '{\"load_selection0\":{\"load\":\"79d765b3-7319-4988-9730-446c7f347020\"},\"load_selection1\":{\"load\":\"d7600b43-771a-4747-9f5d-952765721799\"},\"load_selection2\":{\"load\":\"962b15d8-915f-4cd7-aea6-7cf82afdc20b\"},\"load_selection3\":{\"load\":\"f11dc790-713e-4706-9a85-a318ed3ad56e\"},\"load_selection4\":{\"load\":\"0e6235bf-08ef-428a-bc0a-93957587e936\"}}', '', '{}', 'Updater', 'VDM\\Power\\Updater', '1.0.0', '{}', 'Power Updater', 'class', '{}', '', 1, '2022-05-21 13:15:55', '2022-10-20 14:23:32', 7, 13), (28, 1, 'Start looking here:\r\nhttps://git.vdm.dev/api/swagger#/repository/repoGetContents', 'c65aaf1f-817c-49a2-8202-282e3904f5b1', '', 'ef011ee1-64f0-4048-b013-777473b727dd', 'dXNlIEpvb21sYVxDTVNcSHR0cFxIdHRwOw0KdXNlIEpvb21sYVxSZWdpc3RyeVxSZWdpc3RyeTs=', '', '', '{}', 'CS8qKg0KCSAqIEdldHMgdGhlIG1ldGFkYXRhIGFuZCBjb250ZW50cyAoaWYgYSBmaWxlKSBvZiBhbiBlbnRyeSBpbiBhIHJlcG9zaXRvcnksIG9yIGEgbGlzdCBvZiBlbnRyaWVzIGlmIGEgZGlyDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICRvd25lciAgICAgICBSZXBvc2l0b3J5IG93bmVyLg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJHJlcG8gICAgICAgICBSZXBvc2l0b3J5IG5hbWUuDQoJICogQHBhcmFtICAgc3RyaW5nICAkZmlsZXBhdGggICAgUmVwb3NpdG9yeSBmaWxlIHBhdGguDQoJICoNCgkgKiBAcmV0dXJuICBvYmplY3QNCgkgKg0KCSAqIEBzaW5jZSAgIDEuMA0KCSAqLw0KCXB1YmxpYyBmdW5jdGlvbiBnZXQoJG93bmVyLCAkcmVwbywgJGZpbGVwYXRoKQ0KCXsNCgkJLy8gQnVpbGQgdGhlIHJlcXVlc3QgcGF0aC4NCgkJJHBhdGggPSAnL3JlcG9zLycgLiAkb3duZXIgLiAnLycgLiAkcmVwbyAuICcvY29udGVudHMvJyAuICRmaWxlcGF0aDsNCg0KCQkvLyBTZW5kIHRoZSByZXF1ZXN0Lg0KCQlyZXR1cm4gJHRoaXMtPnByb2Nlc3NSZXNwb25zZSgNCgkJCSR0aGlzLT5jbGllbnQtPmdldCgkdGhpcy0+ZmV0Y2hVcmwoJHBhdGgpKQ0KCQkpOw0KCX0NCg==', '{}', 'File', 'VDM\\Gitea\\Package.Repo.File', '1.0.0', '{}', 'Gitea Repo File', 'class', '{}', '', 1, '2022-05-21 13:40:09', '2022-09-20 10:10:28', 11, 4), (29, 1, 'Start looking here:\r\nhttps://git.vdm.dev/api/swagger#/repository/repoCreateWikiPage', 'c65aaf1f-817c-49a2-8202-282e3904f5b1', '', 'c4a188de-ad78-4a6d-9d5b-01866846d701', 'dXNlIEpvb21sYVxDTVNcSHR0cFxIdHRwOw0KdXNlIEpvb21sYVxSZWdpc3RyeVxSZWdpc3RyeTs=', '', '', '{}', 'CS8qKg0KCSAqIEdldCBhIHJlcG9zaXRvcnkgd2lraSBwYWdlDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICRvd25lciAgICAgICAgICAgICAgIFRoZSByZXBvc2l0b3J5IG93bmVyDQoJICogQHBhcmFtICAgc3RyaW5nICAkcmVwbyAgICAgICAgICAgICAgICAgVGhlIHJlcG9zaXRvcnkgbmFtZQ0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJHBhZ2VOYW1lICAgICAgIFRoZSBwYWdlIG5hbWUNCgkgKg0KCSAqIEByZXR1cm4gIG9iamVjdA0KCSAqDQoJICogQHNpbmNlICAgMS4wDQoJICovDQoJcHVibGljIGZ1bmN0aW9uIGdldChzdHJpbmcgJG93bmVyLCBzdHJpbmcgJHJlcG8sIHN0cmluZyAkcGFnZU5hbWUpDQoJew0KCQkvLyBCdWlsZCB0aGUgcmVxdWVzdCBwYXRoLg0KCQkkcGF0aCA9ICcvcmVwb3MvJyAuICRvd25lciAuICcvJyAuICRyZXBvIC4gJy93aWtpL3BhZ2UvJyAuICRwYWdlTmFtZTsNCg0KCQkvLyBTZW5kIHRoZSByZXF1ZXN0Lg0KCQlyZXR1cm4gJHRoaXMtPnByb2Nlc3NSZXNwb25zZSgNCgkJCSR0aGlzLT5jbGllbnQtPmdldCgkdGhpcy0+ZmV0Y2hVcmwoJHBhdGgpKQ0KCQkpOw0KCX0NCg0KCS8qKg0KCSAqIEdldCBhIHJlcG9zaXRvcnkgd2lraSBodG1sIHBhZ2UNCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJG93bmVyICAgICAgICAgICAgICAgVGhlIHJlcG9zaXRvcnkgb3duZXINCgkgKiBAcGFyYW0gICBzdHJpbmcgICRyZXBvICAgICAgICAgICAgICAgICBUaGUgcmVwb3NpdG9yeSBuYW1lDQoJICogQHBhcmFtICAgc3RyaW5nICAkcGFnZU5hbWUgICAgICAgVGhlIHBhZ2UgbmFtZQ0KCSAqDQoJICogQHJldHVybiAgb2JqZWN0DQoJICoNCgkgKiBAc2luY2UgICAxLjANCgkgKi8NCglwdWJsaWMgZnVuY3Rpb24gZ2V0SHRtbChzdHJpbmcgJG93bmVyLCBzdHJpbmcgJHJlcG8sIHN0cmluZyAkcGFnZU5hbWUpDQoJew0KCQkvLyBnZXQgdGhlIGdpdGVhIHdpa2kgcGFnZQ0KCQkkcGFnZSA9ICR0aGlzLT5nZXQoJG93bmVyLCAkcmVwbywgJHBhZ2VOYW1lKTsNCg0KCQlpZiAoZW1wdHkoJHBhZ2UtPmNvbnRlbnQpKQ0KCQl7DQoJCQl0aHJvdyBuZXcgXEV4Y2VwdGlvbignV2lraSBwYWdlIGNvdWxkIG5vdCBiZSBmb3VuZC4nKTsNCgkJfQ0KDQoJCS8vIEJ1aWxkIHRoZSByZXF1ZXN0IHBhdGguDQoJCSRwYXRoID0gJy9tYXJrZG93bic7DQoNCgkJLy8gR2V0IGhlYWRlcnMNCgkJJGhlYWRlcnMgPSAkdGhpcy0+Y2xpZW50LT5nZXRPcHRpb24oJ2hlYWRlcnMnLCBhcnJheSgpKTsNCg0KCQkkaGVhZGVyc1snYWNjZXB0J10gPSAndGV4dC9odG1sJzsNCgkJJGhlYWRlcnNbJ0NvbnRlbnQtVHlwZSddID0gJ2FwcGxpY2F0aW9uL2pzb24nOw0KDQoJCS8vIGJ1aWxkIHRoZSBwb3N0IGJvZHkNCgkJJGRhdGEgPSBbDQoJCQknQ29udGV4dCcgPT4gJ3N0cmluZycsDQoJCQknTW9kZScgPT4gJ3N0cmluZycsDQoJCQknVGV4dCcgPT4gJHBhZ2UtPmNvbnRlbnQsDQoJCQknV2lraScgPT4gdHJ1ZQ0KCQldOw0KDQoJCS8vIFBvc3QgdGhlIHJlcXVlc3QuDQoJCXJldHVybiAkdGhpcy0+cHJvY2Vzc1Jlc3BvbnNlKA0KCQkJJHRoaXMtPmNsaWVudC0+cG9zdCgkdGhpcy0+ZmV0Y2hVcmwoJHBhdGgpLCBqc29uX2VuY29kZSgkZGF0YSksICRoZWFkZXJzKQ0KCQkpOw0KCX0NCg==', '{}', 'Wiki', 'VDM\\Gitea\\Package.Repo.Wiki', '1.0.0', '{}', 'Gitea Repo Wiki', 'class', '{}', '', 1, '2022-07-09 10:21:53', '2022-09-20 10:10:25', 10, 4); @@ -2511,7 +2511,8 @@ INSERT INTO `#__componentbuilder_library_files_folders_urls` (`id`, `addfiles`, (6, '{}', '{}', '{\"addurls0\":{\"url\":\"https:\\/\\/raw.githubusercontent.com\\/artf\\/grapesjs-preset-webpage\\/master\\/dist\\/grapesjs-preset-webpage.min.css\",\"type\":2},\"addurls1\":{\"url\":\"https:\\/\\/raw.githubusercontent.com\\/artf\\/grapesjs-preset-webpage\\/master\\/dist\\/grapesjs-preset-webpage.min.js\",\"type\":2},\"addurls2\":{\"url\":\"https:\\/\\/static.filestackapi.com\\/v3\\/filestack-0.1.10.js\",\"type\":2}}', 9, '', 1, '2020-02-18 21:13:16', '2020-02-18 21:14:11', 2, '', 5), (7, '{}', '{}', '{\"addurls0\":{\"url\":\"https:\\/\\/cdn.jsdelivr.net\\/npm\\/vue\",\"type\":3}}', 10, '', 1, '2020-06-05 13:11:54', '0000-00-00 00:00:00', 1, '', 6), (8, '{}', '{}', '{\"addurls2\":{\"url\":\"https:\\/\\/cdn.datatables.net\\/1.10.21\\/js\\/jquery.dataTables.min.js\",\"type\":2},\"addurls1\":{\"url\":\"https:\\/\\/cdn.datatables.net\\/1.10.21\\/css\\/dataTables.uikit.min.css\",\"type\":2}}', 11, '', 1, '2020-06-27 21:34:44', '0000-00-00 00:00:00', 1, '', 7), -(9, '{}', '{}', '{\"addurls3\":{\"url\":\"http:\\/\\/code.jquery.com\\/ui\\/1.11.1\\/themes\\/smoothness\\/jquery-ui.css\",\"type\":2},\"addurls0\":{\"url\":\"https:\\/\\/cdnjs.cloudflare.com\\/ajax\\/libs\\/jquery-ui-timepicker-addon\\/1.6.3\\/jquery-ui-timepicker-addon.min.css\",\"type\":2},\"addurls1\":{\"url\":\"http:\\/\\/code.jquery.com\\/ui\\/1.11.1\\/jquery-ui.min.js\",\"type\":2},\"addurls2\":{\"url\":\"https:\\/\\/cdnjs.cloudflare.com\\/ajax\\/libs\\/jquery-ui-timepicker-addon\\/1.6.3\\/jquery-ui-timepicker-addon.min.js\",\"type\":2}}', 12, '', 1, '2020-06-29 00:00:44', '2020-06-29 04:32:57', 4, '', 8); +(9, '{}', '{}', '{\"addurls3\":{\"url\":\"http:\\/\\/code.jquery.com\\/ui\\/1.11.1\\/themes\\/smoothness\\/jquery-ui.css\",\"type\":2},\"addurls0\":{\"url\":\"https:\\/\\/cdnjs.cloudflare.com\\/ajax\\/libs\\/jquery-ui-timepicker-addon\\/1.6.3\\/jquery-ui-timepicker-addon.min.css\",\"type\":2},\"addurls1\":{\"url\":\"http:\\/\\/code.jquery.com\\/ui\\/1.11.1\\/jquery-ui.min.js\",\"type\":2},\"addurls2\":{\"url\":\"https:\\/\\/cdnjs.cloudflare.com\\/ajax\\/libs\\/jquery-ui-timepicker-addon\\/1.6.3\\/jquery-ui-timepicker-addon.min.js\",\"type\":2}}', 12, '', 1, '2020-06-29 00:00:44', '2020-06-29 04:32:57', 4, '', 8), +(10, '{}', '{}', '{\"addurls0\":{\"url\":\"https:\\/\\/cdn.datatables.net\\/v\\/dt\\/jszip-2.5.0\\/dt-1.11.5\\/b-2.2.2\\/b-colvis-2.2.2\\/b-html5-2.2.2\\/b-print-2.2.2\\/cr-1.5.5\\/date-1.1.2\\/fc-4.0.2\\/fh-3.2.2\\/kt-2.6.4\\/r-2.2.9\\/rg-1.1.4\\/rr-1.2.8\\/sc-2.0.5\\/sb-1.3.2\\/sp-2.0.0\\/sl-1.3.4\\/sr-1.1.0\\/datatables.min.css\",\"type\":3},\"addurls1\":{\"url\":\"https:\\/\\/cdnjs.cloudflare.com\\/ajax\\/libs\\/pdfmake\\/0.1.36\\/pdfmake.min.js\",\"type\":3},\"addurls2\":{\"url\":\"https:\\/\\/cdnjs.cloudflare.com\\/ajax\\/libs\\/pdfmake\\/0.1.36\\/vfs_fonts.js\",\"type\":3},\"addurls3\":{\"url\":\"https:\\/\\/cdn.datatables.net\\/v\\/dt\\/jszip-2.5.0\\/dt-1.11.5\\/b-2.2.2\\/b-colvis-2.2.2\\/b-html5-2.2.2\\/b-print-2.2.2\\/cr-1.5.5\\/date-1.1.2\\/fc-4.0.2\\/fh-3.2.2\\/kt-2.6.4\\/r-2.2.9\\/rg-1.1.4\\/rr-1.2.8\\/sc-2.0.5\\/sb-1.3.2\\/sp-2.0.0\\/sl-1.3.4\\/sr-1.1.0\\/datatables.min.js\",\"type\":3}}', 13, '', 1, '2022-10-17 20:56:24', '0000-00-00 00:00:00', 1, '', 9); CREATE TABLE IF NOT EXISTS `#__componentbuilder_external_code` ( diff --git a/admin/views/compiler/tmpl/default.php b/admin/views/compiler/tmpl/default.php index 24a3811f9..87af7e0c7 100644 --- a/admin/views/compiler/tmpl/default.php +++ b/admin/views/compiler/tmpl/default.php @@ -25,7 +25,6 @@ $selectNotice .= '

' . JText::_('COM_COMPONENTBUILDER_PLEASE_SELECT_A_COMPONEN $noticeboardOptions = array('vdm', 'pro'); ?> canDo->get('compiler.access')): ?> -

- - -

diff --git a/admin/views/compiler/view.html.php b/admin/views/compiler/view.html.php index 970ebbf4c..1a6cc9be3 100644 --- a/admin/views/compiler/view.html.php +++ b/admin/views/compiler/view.html.php @@ -40,11 +40,18 @@ class ComponentbuilderViewCompiler extends HtmlView JHtmlSidebar::setAction('index.php?option=com_componentbuilder&view=compiler'); $this->sidebar = JHtmlSidebar::render(); } + // get the success message if set $this->SuccessMessage = $this->app->getUserState('com_componentbuilder.success_message', false); + + // get active components $this->Components = $this->get('Components'); - $this->form = $this->setForm(); + + // get the needed form fields + $this->Form = $this->getDynamicForm(); + // set the compiler artwork from global settings $this->builder_gif_size = $this->params->get('builder_gif_size', '480-272'); + // only run these checks if he has access if ($this->canDo->get('compiler.compiler_animations')) { @@ -96,7 +103,14 @@ class ComponentbuilderViewCompiler extends HtmlView // JLayoutHelper::render('sectionjcb', [?]); // added to ensure the layout are loaded // JLayoutHelper::render('repeatablejcb', [?]); // added to ensure the layout are loaded - public function setForm() + /** + * Get the dynamic build form fields needed on the page + * + * @return array|null The array of form fields + * + * @since 3.2.0 + */ + public function getDynamicForm(): ?array { if(ComponentbuilderHelper::checkArray($this->Components)) { @@ -209,8 +223,10 @@ class ComponentbuilderViewCompiler extends HtmlView // return the form array return $form; } - return false; - } + + return null; + } + /** * Prepares the document @@ -396,7 +412,7 @@ class ComponentbuilderViewCompiler extends HtmlView if ($this->canDo->get('compiler.compiler_animations')) { // add Compiler Animations button. - JToolBarHelper::custom('compiler.getCompilerAnimations', 'download custom-button-getcompileranimations', '', 'COM_COMPONENTBUILDER_COMPILER_ANIMATIONS', false); + JToolBarHelper::custom('compiler.getDynamicContent', 'download custom-button-getdynamiccontent', '', 'COM_COMPONENTBUILDER_COMPILER_ANIMATIONS', false); } if ($this->canDo->get('compiler.clear_tmp')) { diff --git a/admin/views/search/tmpl/default.php b/admin/views/search/tmpl/default.php index 3b6806e03..a19313068 100644 --- a/admin/views/search/tmpl/default.php +++ b/admin/views/search/tmpl/default.php @@ -17,6 +17,10 @@ JHtml::_('behavior.formvalidator'); JHtml::_('formbehavior.chosen', 'select'); JHtml::_('behavior.keepalive'); use VDM\Joomla\Componentbuilder\Search\Factory as SearchFactory; + +$this->app->input->set('hidemainmenu', false); +$selectNotice = '

' . JText::_('COM_COMPONENTBUILDER_HI') . ' ' . $this->user->name . '

'; +$selectNotice .= '

' . JText::_('COM_COMPONENTBUILDER_ENTER_YOUR_SEARCH_TEXT') . '

'; ?> canDo->get('search.access')): ?> item->id)) ? '&id='. (int) $this->item->id : ''; ?> -
sidebar)): ?>
@@ -42,33 +45,55 @@ use VDM\Joomla\Componentbuilder\Search\Factory as SearchFactory;
- table_name = $tableName; - SearchFactory::_('Config')->search_value = $searchValue; - SearchFactory::_('Config')->match_case = 1; - SearchFactory::_('Config')->whole_word = 0; - SearchFactory::_('Config')->regex_search = 1; - SearchFactory::_('Config')->component_id = 0; + form): ?> + +
+
+
+ form->renderField('type_search'); ?> + form->renderField('search_value'); ?> + form->renderField('replace_value'); ?> +
+
+ form->renderFieldset('settings'); ?> +
+
+
+
+ + + + + + + + + + + +
+
+
+ +
+ + +
+item['tables']) && ComponentbuilderHelper::checkArray($this->item['tables'])) : ?> + +

diff --git a/admin/views/search/view.html.php b/admin/views/search/view.html.php index 551d3d701..423db2bde 100644 --- a/admin/views/search/view.html.php +++ b/admin/views/search/view.html.php @@ -13,6 +13,9 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\View\HtmlView; +use Joomla\CMS\Filesystem\File; +use Joomla\CMS\Form\Form; +use VDM\Joomla\Componentbuilder\Search\Factory as SearchFactory; /** * Componentbuilder Html View class for the Search @@ -38,7 +41,11 @@ class ComponentbuilderViewSearch extends HtmlView ComponentbuilderHelper::addSubmenu('search'); JHtmlSidebar::setAction('index.php?option=com_componentbuilder&view=search'); $this->sidebar = JHtmlSidebar::render(); - } + } + + // get the needed form fields + $this->form = $this->getDynamicForm(); + // We don't need toolbar in the modal window. if ($this->getLayout() !== 'modal') @@ -59,6 +66,184 @@ class ComponentbuilderViewSearch extends HtmlView parent::display($tpl); } + /** + * Get the dynamic build form fields needed on the page + * + * @return Form|null The array of form fields + * + * @since 3.2.0 + */ + public function getDynamicForm(): ?Form + { + if(ComponentbuilderHelper::checkArray($this->item) && + ComponentbuilderHelper::checkArray($this->item['tables']) && + ComponentbuilderHelper::checkArray($this->item['components'])) + { + // start the form + $form = new Form('Search'); + + $form->load('
+
+
+
+
'); + + // Search Mode + $attributes = [ + 'type' => 'radio', + 'name' => 'type_search', + 'label' => 'COM_COMPONENTBUILDER_MODE', + 'class' => 'btn-group', + 'description' => 'COM_COMPONENTBUILDER_SEARCH_OR_SEARCH_AND_REPLACE', + 'default' => '1']; + // set the mode options + $options = [ + 1 => 'COM_COMPONENTBUILDER_SEARCH', + 2 => 'COM_COMPONENTBUILDER_REPLACE']; + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'search'); + } + + // search text attributes + $attributes = [ + 'type' => 'text', + 'name' => 'search_value', + 'label' => 'COM_COMPONENTBUILDER_SEARCH', + 'size' => 150, + 'maxlength' => 200, + 'description' => 'COM_COMPONENTBUILDER_HERE_YOU_CAN_ENTER_YOUR_SEARCH_TEXT', + 'filter' => 'RAW', + 'class' => 'search-value span12', + 'hint' => 'COM_COMPONENTBUILDER_ENTER_YOUR_SEARCH_TEXT', + 'autocomplete' => true]; + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'search'); + } + + // replace text attributes + $attributes = [ + 'type' => 'text', + 'name' => 'replace_value', + 'label' => 'COM_COMPONENTBUILDER_REPLACE', + 'size' => 150, + 'maxlength' => 200, + 'description' => 'COM_COMPONENTBUILDER_HERE_YOU_CAN_ENTER_THE_REPLACE_TEXT_THAT_YOU_WOULD_LIKE_TO_USE_AS_REPLACEMENT_FOR_THE_SEARCH_TEXT_FOUND', + 'filter' => 'RAW', + 'class' => 'replace-value span12', + 'hint' => 'COM_COMPONENTBUILDER_ENTER_YOUR_REPLACE_TEXT', + 'autocomplete' => true, + 'showon' => 'type_search:2']; + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'search'); + } + + // Search Behaviour + $attributes = [ + 'type' => 'checkboxes', + 'name' => 'search_behaviour', + 'label' => 'COM_COMPONENTBUILDER_BEHAVIOUR', + 'class' => 'btn-group', + 'description' => 'COM_COMPONENTBUILDER_SET_THE_SEARCH_BEHAVIOUR_HERE']; + // set the mode options + $options = [ + 'match_case' => 'COM_COMPONENTBUILDER_MATCH_CASE', + 'whole_word' => 'COM_COMPONENTBUILDER_WHOLE_WORD', + 'regex_search' => 'COM_COMPONENTBUILDER_REGEX_SEARCH']; + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'settings'); + } + + // component attributes + $attributes = [ + 'type' => 'list', + 'name' => 'component_id', + 'label' => 'COM_COMPONENTBUILDER_COMPONENTS_BR_SMALLDISABLED_SOONSMALL', + 'class' => 'list_class', + 'description' => 'COM_COMPONENTBUILDER_SELECT_THE_COMPONENT_TO_SEARCH', + 'required' => 'true', + 'disable' => 'true', + 'readonly' => 'true', + 'default' => -1]; + // start the component options + $options = []; + $options['-1'] = 'COM_COMPONENTBUILDER__SEARCH_ALL_'; + // load component options from array + foreach($this->item['components'] as $component) + { + $options[(int) $component->id] = $this->escape($component->name); + } + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'settings'); + } + + // table attributes + $attributes = [ + 'type' => 'list', + 'name' => 'table_name', + 'label' => 'COM_COMPONENTBUILDER_TABLES', + 'class' => 'list_class', + 'description' => 'COM_COMPONENTBUILDER_SELECT_THE_TABLE_TO_SEARCH', + 'required' => 'true', + 'default' => -1]; + // start the component options + $options = []; + $options['-1'] = 'COM_COMPONENTBUILDER__SEARCH_ALL_'; + // load table options from array + foreach($this->item['tables'] as $table) + { + $options[$table] = $this->escape($table); + } + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'settings'); + } + + // editor attributes + $attributes = [ + 'type' => 'editor', + 'name' => 'full_text', + 'label' => 'COM_COMPONENTBUILDER_FULL_TEXT', + 'width' => '100%', + 'height' => '450px', + 'class' => 'full_text_editor', + 'syntax' => 'php', + 'buttons' => 'false', + 'filter' => 'raw', + 'editor' => 'codemirror|none']; + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'view'); + } + + // return the form array + return $form; + } + + return null; + } + + /** * Prepares the document */ @@ -72,6 +257,9 @@ class ComponentbuilderViewSearch extends HtmlView // Initialize the header checker. $HeaderCheck = new componentbuilderHeaderCheck; + // Add View JavaScript File + $this->document->addScript(JURI::root(true) . "/administrator/components/com_componentbuilder/assets/js/search.js", (ComponentbuilderHelper::jVersion()->isCompatible("3.8.0")) ? array("version" => "auto") : "text/javascript"); + // Load uikit options. $uikit = $this->params->get('uikit_load'); // Set script size. @@ -89,6 +277,40 @@ class ComponentbuilderViewSearch extends HtmlView { JHtml::_('script', 'media/com_componentbuilder/uikit-v2/js/uikit'.$size.'.js', ['version' => 'auto']); } + + // Load the script to find all uikit components needed. + if ($uikit != 2) + { + // Set the default uikit components in this view. + $uikitComp = array(); + $uikitComp[] = 'uk-progress'; + } + + // Load the needed uikit components in this view. + if ($uikit != 2 && isset($uikitComp) && ComponentbuilderHelper::checkArray($uikitComp)) + { + // load just in case. + jimport('joomla.filesystem.file'); + // loading... + foreach ($uikitComp as $class) + { + foreach (ComponentbuilderHelper::$uk_components[$class] as $name) + { + // check if the CSS file exists. + if (File::exists(JPATH_ROOT.'/media/com_componentbuilder/uikit-v2/css/components/'.$name.$style.$size.'.css')) + { + // load the css. + JHtml::_('stylesheet', 'media/com_componentbuilder/uikit-v2/css/components/'.$name.$style.$size.'.css', ['version' => 'auto']); + } + // check if the JavaScript file exists. + if (File::exists(JPATH_ROOT.'/media/com_componentbuilder/uikit-v2/js/components/'.$name.$size.'.js')) + { + // load the js. + JHtml::_('script', 'media/com_componentbuilder/uikit-v2/js/components/'.$name.$size.'.js', ['version' => 'auto'], ['type' => 'text/javascript', 'async' => 'async']); + } + } + } + } // add the document default css file $this->document->addStyleSheet(JURI::root(true) .'/administrator/components/com_componentbuilder/assets/css/search.css', (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/css'); } diff --git a/componentbuilder.xml b/componentbuilder.xml index a5bd7a14d..840ddb7db 100644 --- a/componentbuilder.xml +++ b/componentbuilder.xml @@ -1,7 +1,7 @@ COM_COMPONENTBUILDER - 6th October, 2022 + 20th October, 2022 Llewellyn van der Merwe joomla@vdm.io https://dev.vdm.io diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power.php index dfa6ba645..eba3a4a89 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power.php @@ -175,7 +175,7 @@ class Power implements PowerInterface * * @param string $guid The global unique id of the power * - * @return bool + * @return bool true on successful setting of a power * @since 3.2.0 */ protected function set(string $guid): bool @@ -190,39 +190,52 @@ class Power implements PowerInterface // Create a new query object. $query = $this->db->getQuery(true); + // select all values $query->select('a.*'); - // from these tables + + // from this table $query->from('#__componentbuilder_power AS a'); $query->where($this->db->quoteName('a.guid') . ' = ' . $this->db->quote($guid)); + $this->db->setQuery($query); $this->db->execute(); + if ($this->db->getNumRows()) { // make sure that in recursion we // don't try to load this power again + // since during the load of a power we also load + // all powers linked to it $this->state[$guid] = true; + // get the power data $this->active[$guid] = $this->db->loadObject(); + // make sure to add any language strings found to all language files // since we can't know where this is used at this point $tmp_lang_target = $this->config->lang_target; $this->config->lang_target = 'both'; + // we set the fix usr if needed $this->fixUrl = '"index.php?option=com_componentbuilder&view=powers&task=power.edit&id=' . $this->active[$guid]->id . '" target="_blank"'; + // set some keys $this->active[$guid]->target_type = 'P0m3R!'; $this->active[$guid]->key = $this->active[$guid]->id . '_' . $this->active[$guid]->target_type; + // now set the name $this->active[$guid]->name = $this->placeholder->update( $this->customcode->update($this->active[$guid]->name), $this->placeholder->active ); + // now set the code_name and class name $this->active[$guid]->code_name = $this->active[$guid]->class_name = ClassfunctionHelper::safe( $this->active[$guid]->name ); + // set official name $this->active[$guid]->official_name = StringHelper::safe( $this->active[$guid]->name, 'W' @@ -287,6 +300,7 @@ class Power implements PowerInterface { // set GUI mapper field $guiMapper['field'] = 'head'; + // base64 Decode code $this->active[$guid]->head = $this->gui->set( $this->placeholder->update( @@ -333,6 +347,7 @@ class Power implements PowerInterface return true; } } + // we failed to get the power, // so we raise an error message // only if guid is valid @@ -343,6 +358,7 @@ class Power implements PowerInterface 'Error' ); } + // let's not try again $this->state[$guid] = false; diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Abstraction/Type.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Abstraction/Engine.php similarity index 93% rename from libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Abstraction/Type.php rename to libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Abstraction/Engine.php index fcb902a80..0199a81ae 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Abstraction/Type.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Abstraction/Engine.php @@ -17,11 +17,11 @@ use VDM\Joomla\Componentbuilder\Search\Config; /** - * Search Type Regex + * Search Engine * * @since 3.2.0 */ -abstract class Type +abstract class Engine { /** * Search Config diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent.php index 79e0b057e..08cdaee10 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Agent.php @@ -19,6 +19,7 @@ use VDM\Joomla\Componentbuilder\Search\Database\Set; use VDM\Joomla\Componentbuilder\Search\Agent\Find; use VDM\Joomla\Componentbuilder\Search\Agent\Replace; use VDM\Joomla\Componentbuilder\Search\Agent\Search; +use VDM\Joomla\Componentbuilder\Search\Agent\Update; /** @@ -76,6 +77,14 @@ class Agent */ protected Search $search; + /** + * Update + * + * @var Update + * @since 3.2.0 + */ + protected Update $update; + /** * Constructor * @@ -90,7 +99,7 @@ class Agent */ public function __construct(?Config $config = null, ?Get $get = null, ?Set$set = null, ?Find $find = null, ?Replace $replace = null, - ?Search $search = null) + ?Search $search = null, ?Update $update = null) { $this->config = $config ?: Factory::_('Config'); $this->get = $get ?: Factory::_('Get.Database'); @@ -98,6 +107,65 @@ class Agent $this->find = $find ?: Factory::_('Agent.Find'); $this->replace = $replace ?: Factory::_('Agent.Replace'); $this->search = $search ?: Factory::_('Agent.Search'); + $this->update = $update ?: Factory::_('Agent.Update'); + } + + /** + * Get the value of a field in a row and table + * + * @param mixed $value The field value + * @param int $id The item ID + * @param string $field The field key + * @param mixed $line The field line + * @param string|null $table The table + * @param bool $update The switch to triger an update (default is false) + * + * @return mixed + * @since 3.2.0 + */ + public function getValue(int $id, string $field, $line = null, + ?string $table = null, bool $update = false) + { + // set the table name + if (empty($table)) + { + $table = $this->config->table_name; + } + + if (($value = $this->get->value($id, $field, $table)) !== null) + { + // try to update the value if required + if ($update && ($updated_value = $this->update->value($value, $line)) !== null) + { + return $updated_value; + } + + return $value; + } + + return null; + } + + /** + * Set the value of a field in a row and table + * + * @param mixed $value The field value + * @param int $id The item ID + * @param string $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + public function setValue($value, int $id, string $field, ?string $table = null): bool + { + // set the table name + if (empty($table)) + { + $table = $this->config->table_name; + } + + return $this->set->value($value, $id, $field, $table); } /** diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Database/Get.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Database/Get.php index 70bdc5f7e..e1e52e892 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Database/Get.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Database/Get.php @@ -87,17 +87,17 @@ class Get implements GetInterface } /** - * Get values from a given table + * Get a value from a given table * Example: $this->value(23, 'value_key', 'table_name'); * - * @param string $field The field key * @param int $id The item ID + * @param string $field The field key * @param string|null $table The table * * @return mixed * @since 3.2.0 */ - public function value(string $field, int $id, string $table = null) + public function value(int $id, string $field, string $table = null) { // load the table if (empty($table)) diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Type/Basic.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Engine/Basic.php similarity index 92% rename from libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Type/Basic.php rename to libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Engine/Basic.php index a2959ad30..c7d19a988 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Type/Basic.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Engine/Basic.php @@ -9,14 +9,14 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt */ -namespace VDM\Joomla\Componentbuilder\Search\Type; +namespace VDM\Joomla\Componentbuilder\Search\Engine; use VDM\Joomla\Componentbuilder\Search\Config; use VDM\Joomla\Utilities\StringHelper; use VDM\Joomla\Utilities\ArrayHelper; use VDM\Joomla\Componentbuilder\Search\Interfaces\SearchTypeInterface; -use VDM\Joomla\Componentbuilder\Search\Abstraction\Type; +use VDM\Joomla\Componentbuilder\Search\Abstraction\Engine; /** @@ -24,7 +24,7 @@ use VDM\Joomla\Componentbuilder\Search\Abstraction\Type; * * @since 3.2.0 */ -class Basic extends Type implements SearchTypeInterface +class Basic extends Engine implements SearchTypeInterface { /** * Regex Search Value diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Type/Regex.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Engine/Regex.php similarity index 89% rename from libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Type/Regex.php rename to libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Engine/Regex.php index 19bd68a69..c2a89b872 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Type/Regex.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Engine/Regex.php @@ -9,14 +9,14 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt */ -namespace VDM\Joomla\Componentbuilder\Search\Type; +namespace VDM\Joomla\Componentbuilder\Search\Engine; use VDM\Joomla\Componentbuilder\Search\Config; use VDM\Joomla\Utilities\StringHelper; use VDM\Joomla\Utilities\ArrayHelper; use VDM\Joomla\Componentbuilder\Search\Interfaces\SearchTypeInterface; -use VDM\Joomla\Componentbuilder\Search\Abstraction\Type; +use VDM\Joomla\Componentbuilder\Search\Abstraction\Engine; /** @@ -24,7 +24,7 @@ use VDM\Joomla\Componentbuilder\Search\Abstraction\Type; * * @since 3.2.0 */ -class Regex extends Type implements SearchTypeInterface +class Regex extends Engine implements SearchTypeInterface { /** * Regex Search Value diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Type/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Engine/index.html similarity index 100% rename from libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Type/index.html rename to libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Engine/index.html diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Service/Search.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Service/Search.php index 9085109e8..0ad634810 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Service/Search.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Service/Search.php @@ -17,8 +17,8 @@ use Joomla\DI\ServiceProviderInterface; use VDM\Joomla\Componentbuilder\Search\Config; use VDM\Joomla\Componentbuilder\Search\Table; use VDM\Joomla\Componentbuilder\Search\Interfaces\SearchTypeInterface as SearchEngine; -use VDM\Joomla\Componentbuilder\Search\Type\Regex; -use VDM\Joomla\Componentbuilder\Search\Type\Basic; +use VDM\Joomla\Componentbuilder\Search\Engine\Regex; +use VDM\Joomla\Componentbuilder\Search\Engine\Basic; /** diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Table.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Table.php index d9c3fa440..f30bb7c26 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Table.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Table.php @@ -2981,14 +2981,15 @@ class Table } /** - * Check if a table exist + * Check if a table (and field) exist * * @param string|null $table The area + * @param string|null $field The area * * @return bool * @since 3.2.0 */ - public function exist(?string $table = null): bool + public function exist(?string $table = null, ?string $field = null): bool { // load the table if (empty($table)) @@ -2996,9 +2997,20 @@ class Table $table = $this->config->table_name; } - if (isset($table) && isset($this->tables[$table])) + if (is_string($table) && isset($this->tables[$table])) { - return true; + // if we have a field + if (is_string($field)) + { + if (isset($this->tables[$table][$field])) + { + return true; + } + } + else + { + return true; + } } return false; diff --git a/libraries/jcb_powers/VDM.Joomla/src/Utilities/GetHelper.php b/libraries/jcb_powers/VDM.Joomla/src/Utilities/GetHelper.php index baa6c42b1..91a3a61a5 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Utilities/GetHelper.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Utilities/GetHelper.php @@ -33,11 +33,12 @@ abstract class GetHelper * @param string $operator The operator between $whereString/field and $where/value * @param string $main The component in which the table is found * - * @return mix string/int/float - * + * @return mixed string/int/float * @since 3.0.9 */ - public static function var($table, $where = null, $whereString = 'user', $what = 'id', $operator = '=', $main = null) + public static function var(string $table, ?string $where = null, + string $whereString = 'user', string $what = 'id', + string $operator = '=', ?string $main = null) { if(empty($where)) { @@ -85,6 +86,7 @@ abstract class GetHelper { return $db->loadResult(); } + return false; } @@ -99,11 +101,12 @@ abstract class GetHelper * @param string $main The component in which the table is found * @param bool $unique The switch to return a unique array * - * @return array - * + * @return array|null * @since 3.0.9 */ - public static function vars($table, $where = null, $whereString = 'user', $what = 'id', $operator = 'IN', $main = null, $unique = true) + public static function vars(string $table, ?string $where = null, + string $whereString = 'user', string $what = 'id', string $operator = 'IN', + ?string $main = null, bool $unique = true): ?array { if(empty($where)) { @@ -147,11 +150,11 @@ abstract class GetHelper // add strings to array search if ('IN_STRINGS' === $operator || 'NOT IN_STRINGS' === $operator) { - $query->where($db->quoteName($whereString) . ' ' . str_replace('_STRINGS', '', $operator) . ' ("' . implode('","',$where) . '")'); + $query->where($db->quoteName($whereString) . ' ' . str_replace('_STRINGS', '', $operator) . ' ("' . implode('","', $where) . '")'); } else { - $query->where($db->quoteName($whereString) . ' ' . $operator . ' (' . implode(',',$where) . ')'); + $query->where($db->quoteName($whereString) . ' ' . $operator . ' (' . implode(',', $where) . ')'); } $db->setQuery($query); @@ -166,71 +169,83 @@ abstract class GetHelper return $db->loadColumn(); } } - return false; + + return null; } /** * get all strings between two other strings * - * @param string $content The content to search - * @param string $start The starting value - * @param string $end The ending value + * @param string $content The content to search + * @param string $start The starting value + * @param string $end The ending value * - * @return array On success - * + * @return array|null On success * @since 3.0.9 */ - public static function allBetween($content, $start, $end) + public static function allBetween(string $content, string $start, string $end): ?array { // reset bucket - $bucket = array(); + $bucket = []; for ($i = 0; ; $i++) { // search for string - $found = self::between($content,$start,$end); + $found = self::between($content, $start, $end); + if (StringHelper::check($found)) { // add to bucket $bucket[] = $found; + // build removal string - $remove = $start.$found.$end; + $remove = $start . $found . $end; + // remove from content - $content = str_replace($remove,'',$content); + $content = str_replace($remove, '', $content); } else { break; } + // safety catch if ($i == 500) { break; } } + // only return unique array of values - return array_unique($bucket); + if (ArrayHelper::check($bucket)) + { + return array_unique($bucket); + } + + return null; } /** * get a string between two other strings * - * @param string $content The content to search - * @param string $start The starting value - * @param string $end The ending value - * @param string $default The default value if none found + * @param string $content The content to search + * @param string $start The starting value + * @param string $end The ending value + * @param string $default The default value if none found * * @return string On success / empty string on failure - * * @since 3.0.9 */ - public static function between($content, $start, $end, $default = '') + public static function between(string $content, string $start, string $end, string $default = ''): string { - $r = explode($start, $content); - if (isset($r[1])) + $array = explode($start, $content); + if (isset($array[1]) && strpos($array[1], $end) !== false) { - $r = explode($end, $r[1]); - return $r[0]; + $array = explode($end, $array[1]); + + // return string found between + return $array[0]; } + return $default; }