diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c81a1580..657c62ca5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,4 +9,19 @@ - We fixed the server class to load new client if server details changed. - We fixed the readme placeholder issue #978. - We fixed the empty server url issue #978. -- Fixed Package import to now use the phplibsec version 3 \ No newline at end of file +- Fixed Package import to now use the phplibsec version 3 + +# v3.1.24 + +- Fix the update server #978 issue. +- Fixed the change log to load all entries, not just the last one. +- Fixed #983 so that database updates are created when adding a new adminview +- Moved a few builder arrays to the Compiler Registry +- Adds super powers to JCB +- Adds Gitea API library +- Improves Power filters +- Fix #991 to add the Utilities service class +- Adds Superpower Key (SPK) replacement feature +- Adds Superpower search (GREP) feature +- Adds Power Insert/Update Classes +- Fix #995 that all update sites are using the correct URL \ No newline at end of file diff --git a/README.md b/README.md index 50b01a839..c39b78dae 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ The Component Builder for [Joomla](https://extensions.joomla.org/extension/compo Whether you're a seasoned [Joomla](https://extensions.joomla.org/extension/component-builder/) developer, or have just started, Component Builder will save you lots of time and money. A real must have! -You can install it quite easily and with no limitations. On [gitea](https://git.vdm.dev/joomla/Component-Builder/tags) is the latest release (3.1.19) with **ALL** its features and **ALL** concepts totally open-source and free! +You can install it quite easily and with no limitations. On [gitea](https://git.vdm.dev/joomla/Component-Builder/tags) is the latest release (3.1.24) with **ALL** its features and **ALL** concepts totally open-source and free! > Watch Quick Build of a Hello World component in [JCB on Youtube](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45) @@ -106,8 +106,8 @@ Where can you get support and help? - [Hello World](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45). - [Discussions](https://github.com/vdm-io/Joomla-Component-Builder/discussions). - [Wiki](https://git.vdm.dev/joomla/Component-Builder/wiki). -- [Issues](https://git.vdm.dev/joomla/Component-Builder/issues). -- [Issues Stream](https://t.me/jcb_issues). ^^ +- [Issues](https://git.vdm.dev/joomla/Component-Builder/issues). ^^ +- [Issues Stream](https://t.me/jcb_issues). - [Updates](https://t.me/jcb_updates). - [User Group](https://t.me/jcb_group). - [Announcement](https://t.me/Joomla_component_builder). @@ -144,14 +144,14 @@ 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*: 27th February, 2023 -+ *Version*: 3.1.19 ++ *Last Build*: 2nd May, 2023 ++ *Version*: 3.1.24 + *Copyright*: Copyright (C) 2015 Vast Development Method. All rights reserved. + *License*: GNU General Public License version 2 or later; see LICENSE.txt -+ *Line count*: **366135** -+ *Field count*: **2021** -+ *File count*: **2339** -+ *Folder count*: **411** ++ *Line count*: **557762** ++ *Field count*: **2041** ++ *File count*: **3930** ++ *Folder count*: **432** > This **component** was build with a [Joomla](https://extensions.joomla.org/extension/component-builder/) [Automated Component Builder](https://www.joomlacomponentbuilder.com). > Developed by [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) diff --git a/admin/README.txt b/admin/README.txt index 50b01a839..c39b78dae 100644 --- a/admin/README.txt +++ b/admin/README.txt @@ -9,7 +9,7 @@ The Component Builder for [Joomla](https://extensions.joomla.org/extension/compo Whether you're a seasoned [Joomla](https://extensions.joomla.org/extension/component-builder/) developer, or have just started, Component Builder will save you lots of time and money. A real must have! -You can install it quite easily and with no limitations. On [gitea](https://git.vdm.dev/joomla/Component-Builder/tags) is the latest release (3.1.19) with **ALL** its features and **ALL** concepts totally open-source and free! +You can install it quite easily and with no limitations. On [gitea](https://git.vdm.dev/joomla/Component-Builder/tags) is the latest release (3.1.24) with **ALL** its features and **ALL** concepts totally open-source and free! > Watch Quick Build of a Hello World component in [JCB on Youtube](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45) @@ -106,8 +106,8 @@ Where can you get support and help? - [Hello World](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45). - [Discussions](https://github.com/vdm-io/Joomla-Component-Builder/discussions). - [Wiki](https://git.vdm.dev/joomla/Component-Builder/wiki). -- [Issues](https://git.vdm.dev/joomla/Component-Builder/issues). -- [Issues Stream](https://t.me/jcb_issues). ^^ +- [Issues](https://git.vdm.dev/joomla/Component-Builder/issues). ^^ +- [Issues Stream](https://t.me/jcb_issues). - [Updates](https://t.me/jcb_updates). - [User Group](https://t.me/jcb_group). - [Announcement](https://t.me/Joomla_component_builder). @@ -144,14 +144,14 @@ 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*: 27th February, 2023 -+ *Version*: 3.1.19 ++ *Last Build*: 2nd May, 2023 ++ *Version*: 3.1.24 + *Copyright*: Copyright (C) 2015 Vast Development Method. All rights reserved. + *License*: GNU General Public License version 2 or later; see LICENSE.txt -+ *Line count*: **366135** -+ *Field count*: **2021** -+ *File count*: **2339** -+ *Folder count*: **411** ++ *Line count*: **557762** ++ *Field count*: **2041** ++ *File count*: **3930** ++ *Folder count*: **432** > This **component** was build with a [Joomla](https://extensions.joomla.org/extension/component-builder/) [Automated Component Builder](https://www.joomlacomponentbuilder.com). > Developed by [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) diff --git a/admin/access.xml b/admin/access.xml index 374fb60f0..64689b109 100644 --- a/admin/access.xml +++ b/admin/access.xml @@ -483,7 +483,10 @@ + + + diff --git a/admin/config.xml b/admin/config.xml index ea930586a..e17ac9ea0 100644 --- a/admin/config.xml +++ b/admin/config.xml @@ -679,6 +679,202 @@ default="" /> +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/admin/controllers/power.php b/admin/controllers/power.php index 6124827f7..65d257c0b 100644 --- a/admin/controllers/power.php +++ b/admin/controllers/power.php @@ -42,6 +42,94 @@ class ComponentbuilderControllerPower extends FormController parent::__construct($config); } + public function syncPowers() + { + // Check for request forgeries + JSession::checkToken() or die(JText::_('JINVALID_TOKEN')); + + // get IDS of the selected powers + $item = $this->input->post->get('jform', array(), 'array'); + + // check if there is any selections + if (empty($item['id'])) + { + // set error message + $message = '

'.JText::_('COM_COMPONENTBUILDER_NOT_SAVED').'

'; + $message .= '

'.JText::_('COM_COMPONENTBUILDER_YOU_MUST_FIRST_SAVE_THE_POWER_BEFORE_YOU_CAN_USE_THIS_FEATURE').'

'; + // set redirect + $redirect_url = \JRoute::_( + 'index.php?option=com_componentbuilder&view=power' + . $this->getRedirectToItemAppend(), false + ); + $this->setRedirect($redirect_url, $message, 'error'); + return false; + } + + // check if user has the right + $user = JFactory::getUser(); + if($user->authorise('power.sync', 'com_componentbuilder')) + { + // set success message + $message = '

'.JText::_('COM_COMPONENTBUILDER_THIS_SYNC_FEATURE_IS_STILL_UNDER_DEVELOPMENT').'

'; + $message .= '

'.JText::sprintf('COM_COMPONENTBUILDER_PLEASE_CHECK_AGAIN_SOON_ANDOR_FOLLOW_THE_PROGRESS_ON_SGITVDMDEVA', '').'

'; + // set redirect + $redirect_url = \JRoute::_( + 'index.php?option=com_componentbuilder&view=power' + . $this->getRedirectToItemAppend($item['id']), false + ); + $this->setRedirect($redirect_url, $message); + return true; + } + // set redirect + $redirect_url = JRoute::_('index.php?option=com_componentbuilder&view=powers', false); + $this->setRedirect($redirect_url); + return false; + } + + public function resetPowers() + { + // Check for request forgeries + JSession::checkToken() or die(JText::_('JINVALID_TOKEN')); + + // get IDS of the selected powers + $item = $this->input->post->get('jform', array(), 'array'); + + // check if there is any selections + if (empty($item['id'])) + { + // set error message + $message = '

'.JText::_('COM_COMPONENTBUILDER_NOT_SAVED').'

'; + $message .= '

'.JText::_('COM_COMPONENTBUILDER_YOU_MUST_FIRST_SAVE_THE_POWER_BEFORE_YOU_CAN_USE_THIS_FEATURE').'

'; + // set redirect + $redirect_url = \JRoute::_( + 'index.php?option=com_componentbuilder&view=power' + . $this->getRedirectToItemAppend(), false + ); + $this->setRedirect($redirect_url, $message, 'error'); + return false; + } + + // check if user has the right + $user = JFactory::getUser(); + if($user->authorise('power.reset', 'com_componentbuilder')) + { + // set success message + $message = '

'.JText::_('COM_COMPONENTBUILDER_THIS_RESET_FEATURE_IS_STILL_UNDER_DEVELOPMENT').'

'; + $message .= '

'.JText::sprintf('COM_COMPONENTBUILDER_PLEASE_CHECK_AGAIN_SOON_ANDOR_FOLLOW_THE_PROGRESS_ON_SGITVDMDEVA', '').'

'; + // set redirect + $redirect_url = \JRoute::_( + 'index.php?option=com_componentbuilder&view=power' + . $this->getRedirectToItemAppend($item['id']), false + ); + $this->setRedirect($redirect_url, $message); + return true; + } + // set redirect + $redirect_url = JRoute::_('index.php?option=com_componentbuilder&view=powers', false); + $this->setRedirect($redirect_url); + return false; + } + /** * Method override to check if you can add a new record. * diff --git a/admin/controllers/powers.php b/admin/controllers/powers.php index a5d82dee5..290e7d949 100644 --- a/admin/controllers/powers.php +++ b/admin/controllers/powers.php @@ -83,5 +83,109 @@ class ComponentbuilderControllerPowers extends AdminController $this->setRedirect($redirect_url, $message, 'error'); return false; } + + public function initPowers() + { + // Check for request forgeries + JSession::checkToken() or die(JText::_('JINVALID_TOKEN')); + // check if user has the right + $user = JFactory::getUser(); + if($user->authorise('power.init', 'com_componentbuilder')) + { + // set success message + $message = '

'.JText::_('COM_COMPONENTBUILDER_THIS_INIT_FEATURE_IS_STILL_UNDER_DEVELOPMENT').'

'; + $message .= '

'.JText::sprintf('COM_COMPONENTBUILDER_PLEASE_CHECK_AGAIN_SOON_ANDOR_FOLLOW_THE_PROGRESS_ON_SGITVDMDEVA', '').'

'; + // set redirect + $redirect_url = JRoute::_('index.php?option=com_componentbuilder&view=powers', false); + $this->setRedirect($redirect_url, $message); + return true; + } + // set redirect + $redirect_url = JRoute::_('index.php?option=com_componentbuilder&view=powers', false); + $this->setRedirect($redirect_url); + return false; + } + + public function syncPowers() + { + // Check for request forgeries + JSession::checkToken() or die(JText::_('JINVALID_TOKEN')); + + // get IDS of the selected powers + $pks = $this->input->post->get('cid', [], 'array'); + + // Sanitize the input + JArrayHelper::toInteger($pks); + + // check if there is any selections + if ($pks == []) + { + // set error message + $message = '

'.JText::_('COM_COMPONENTBUILDER_NO_SELECTION_DETECTED').'

'; + $message .= '

'.JText::_('COM_COMPONENTBUILDER_PLEASE_FIRST_MAKE_A_SELECTION_FROM_THE_LIST').'

'; + // set redirect + $redirect_url = JRoute::_('index.php?option=com_componentbuilder&view=powers', false); + $this->setRedirect($redirect_url, $message, 'error'); + return false; + } + + // check if user has the right + $user = JFactory::getUser(); + if($user->authorise('power.sync', 'com_componentbuilder')) + { + // set success message + $message = '

'.JText::_('COM_COMPONENTBUILDER_THIS_SYNC_FEATURE_IS_STILL_UNDER_DEVELOPMENT').'

'; + $message .= '

'.JText::sprintf('COM_COMPONENTBUILDER_PLEASE_CHECK_AGAIN_SOON_ANDOR_FOLLOW_THE_PROGRESS_ON_SGITVDMDEVA', '').'

'; + // set redirect + $redirect_url = JRoute::_('index.php?option=com_componentbuilder&view=powers', false); + $this->setRedirect($redirect_url, $message); + return true; + } + // set redirect + $redirect_url = JRoute::_('index.php?option=com_componentbuilder&view=powers', false); + $this->setRedirect($redirect_url); + return false; + } + + public function resetPowers() + { + // Check for request forgeries + JSession::checkToken() or die(JText::_('JINVALID_TOKEN')); + + // get IDS of the selected powers + $pks = $this->input->post->get('cid', [], 'array'); + + // Sanitize the input + JArrayHelper::toInteger($pks); + + // check if there is any selections + if ($pks == []) + { + // set error message + $message = '

'.JText::_('COM_COMPONENTBUILDER_NO_SELECTION_DETECTED').'

'; + $message .= '

'.JText::_('COM_COMPONENTBUILDER_PLEASE_FIRST_MAKE_A_SELECTION_FROM_THE_LIST').'

'; + // set redirect + $redirect_url = JRoute::_('index.php?option=com_componentbuilder&view=powers', false); + $this->setRedirect($redirect_url, $message, 'error'); + return false; + } + + // check if user has the right + $user = JFactory::getUser(); + if($user->authorise('power.reset', 'com_componentbuilder')) + { + // set success message + $message = '

'.JText::_('COM_COMPONENTBUILDER_THIS_RESET_FEATURE_IS_STILL_UNDER_DEVELOPMENT').'

'; + $message .= '

'.JText::sprintf('COM_COMPONENTBUILDER_PLEASE_CHECK_AGAIN_SOON_ANDOR_FOLLOW_THE_PROGRESS_ON_SGITVDMDEVA', '').'

'; + // set redirect + $redirect_url = JRoute::_('index.php?option=com_componentbuilder&view=powers', false); + $this->setRedirect($redirect_url, $message); + return true; + } + // set redirect + $redirect_url = JRoute::_('index.php?option=com_componentbuilder&view=powers', false); + $this->setRedirect($redirect_url); + return false; + } } diff --git a/admin/helpers/compiler.php b/admin/helpers/compiler.php index c0af9a1b9..e36e9f9a4 100644 --- a/admin/helpers/compiler.php +++ b/admin/helpers/compiler.php @@ -603,6 +603,31 @@ class Compiler extends Infusion } } } + // do super powers details if found + if (ArrayHelper::check(CFactory::_('Power')->superpowers)) + { + foreach (CFactory::_('Power')->superpowers as $path => $powers) + { + $key = StringHelper::safe($path); + if (CFactory::_('Utilities.Files')->exists($key)) + { + // update the power files + foreach (CFactory::_('Utilities.Files')->get($key) as $power_file) + { + if (File::exists($power_file['path'])) + { + $this->setFileContent( + $power_file['name'], $power_file['path'], + $bom, $key + ); + } + } + // free up some memory + CFactory::_('Utilities.Files')->remove($key); + CFactory::_('Content')->remove_($key); + } + } + } return true; } @@ -680,6 +705,9 @@ class Compiler extends Infusion &$view) ); + // inject any super powers found + $answer = CFactory::_('Power.Injector')->power($answer); + // add answer back to file CFactory::_('Utilities.File')->write($path, $answer); @@ -1384,7 +1412,7 @@ class Compiler extends Infusion if ($found && !$foundEnd) { $replace[] = (int) $lineBites[$lineNumber]; - // we musk keep last three lines to dynamic find target entry + // we must keep last three lines to dynamic find target entry $fingerPrint[$lineNumber] = trim($lineContent); // check lines each time if it fits our target if (count((array) $fingerPrint) === $sizeEnd @@ -1413,7 +1441,7 @@ class Compiler extends Infusion { $replace[] = (int) $lineBites[$lineNumber]; } - // we musk keep last three lines to dynamic find target entry + // we must keep last three lines to dynamic find target entry $fingerPrint[$lineNumber] = trim($lineContent); // check lines each time if it fits our target if (count((array) $fingerPrint) === $size && !$found) @@ -1535,7 +1563,7 @@ class Compiler extends Infusion $code = PHP_EOL . $commentType . implode( $_commentType . PHP_EOL . $commentType, $code ) . $_commentType . PHP_EOL; - // get place holders + // get placeholders $placeholder = CFactory::_('Placeholder')->keys( (int) $target['comment_type'] . $target['type'], $target['id'] ); @@ -1554,37 +1582,55 @@ class Compiler extends Infusion $this->addDataToFile($file, $data, (int) array_sum($bitBucket)); } - // Thanks to http://stackoverflow.com/a/16813550/1429677 - protected function addDataToFile($file, $data, $position, $replace = null) + /** + * Inserts or replaces data in a file at a specific position. + * Thanks to http://stackoverflow.com/a/16813550/1429677 + * + * @param string $file The path of the file to modify + * @param string $data The data to insert or replace + * @param int $position The position in the file where the data should be inserted or replaced + * @param int|null $replace The number of bytes to replace; if null, data will be inserted + * + * @return void + * @throws RuntimeException if unable to open the file + */ + protected function addDataToFile(string $file, string $data, int $position, ?int $replace = null) { - // start the process - $fpFile = fopen($file, "rw+"); - $fpTemp = fopen('php://temp', "rw+"); - // make a copy of the file - stream_copy_to_stream($fpFile, $fpTemp); - // move to the position where we should add the data - fseek($fpFile, $position); - // Add the data - fwrite($fpFile, (string) $data); - // truncate file at the end of the data that was added - $remove = MathHelper::bc( - 'add', $position, mb_strlen((string) $data, '8bit') - ); - ftruncate($fpFile, $remove); - // check if this was a replacement of data - if ($replace) + // Open the file and a temporary stream + $actual_file = fopen($file, "rw+"); + if ($actual_file === false) { - $position = MathHelper::bc( - 'add', $position, $replace - ); + throw new RuntimeException("Unable to open the file: {$file}"); } - // move to the position of the data that should remain below the new data - fseek($fpTemp, $position); - // copy that remaining data to the file - stream_copy_to_stream($fpTemp, $fpFile); // @Jack - // done close both files - fclose($fpFile); - fclose($fpTemp); + + $temp_file = fopen('php://temp', "rw+"); + + // Make a copy of the file in the temporary stream + stream_copy_to_stream($actual_file, $temp_file); + + // Move to the position where the data should be added + fseek($actual_file, $position); + + // Add the data + fwrite($actual_file, $data); + + // Truncate the file at the end of the added data if replacing + $data_length = mb_strlen($data, '8bit'); + $remove = MathHelper::bc('add', $position, $data_length); + ftruncate($actual_file, $remove); + + // check if this was a replacement of data + $position = MathHelper::bc('add', $position, $replace ?: 0); + + // Move to the position of the remaining data in the temporary stream + fseek($temp_file, $position); + + // Copy the remaining data from the temporary stream to the file + stream_copy_to_stream($temp_file, $actual_file); + + // Close both file handles + fclose($actual_file); + fclose($temp_file); // any help to improve this is welcome... } diff --git a/admin/helpers/compiler/a_Get.php b/admin/helpers/compiler/a_Get.php index 2d1b75162..5c43fe637 100644 --- a/admin/helpers/compiler/a_Get.php +++ b/admin/helpers/compiler/a_Get.php @@ -1144,8 +1144,13 @@ class Get )); } - // get powers *+*+*+*+*+*+*+*PRO + // load powers *+*+*+*+*+*+*+* CFactory::_('Power')->load($this->linkedPowers); + // load any other super powers that was found + if (($super_powers = CFactory::_('Power.Extractor')->get_()) !== null) + { + CFactory::_('Power')->load($super_powers); + } // set the percentage when a language can be added $this->percentageLanguageAdd = (int) $this->params->get( 'percentagelanguageadd', 50 diff --git a/admin/helpers/compiler/c_Fields.php b/admin/helpers/compiler/c_Fields.php index 4c785f487..f45880893 100644 --- a/admin/helpers/compiler/c_Fields.php +++ b/admin/helpers/compiler/c_Fields.php @@ -34,6 +34,7 @@ class Fields extends Structure * Metadate Switch * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->get('builder.meta_data'); */ public $metadataBuilder = array(); @@ -41,6 +42,7 @@ class Fields extends Structure * View access Switch * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->get('builder.access_switch'); */ public $accessBuilder = array(); @@ -48,6 +50,7 @@ class Fields extends Structure * edit view tabs counter * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->get('builder.tab_counter'); */ public $tabCounter = array(); @@ -55,6 +58,7 @@ class Fields extends Structure * layout builder * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->get('builder.layout'); */ public $layoutBuilder = array(); @@ -62,6 +66,7 @@ class Fields extends Structure * permissions builder * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->get('builder.has_permissions'); */ public $hasPermissions = array(); @@ -83,6 +88,7 @@ class Fields extends Structure * list of fields that are not being escaped * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->get('builder.do_not_escape'); */ public $doNotEscape = array(); @@ -90,6 +96,7 @@ class Fields extends Structure * list of classes used in the list view for the fields * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->set('builder.list_field_class'); */ public $listFieldClass = array(); @@ -97,6 +104,7 @@ class Fields extends Structure * tags builder * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->get('builder.tags'); */ public $tagsBuilder = array(); @@ -104,6 +112,7 @@ class Fields extends Structure * query builder * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->get('builder.database_tables'); */ public $queryBuilder = array(); @@ -111,6 +120,7 @@ class Fields extends Structure * unique keys for database field * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->get('builder.database_unique_keys'); */ public $dbUniqueKeys = array(); @@ -118,6 +128,7 @@ class Fields extends Structure * unique guid swtich * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->get('builder.database_unique_guid'); */ public $dbUniqueGuid = array(); @@ -125,6 +136,7 @@ class Fields extends Structure * keys for database field * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->get('builder.database_keys'); */ public $dbKeys = array(); @@ -132,6 +144,7 @@ class Fields extends Structure * history builder * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->get('builder.history'); */ public $historyBuilder = array(); @@ -139,6 +152,7 @@ class Fields extends Structure * alias builder * * @var array + * @deprecated 3.3 CFactory::_('Registry')->get('builder.alias'); */ public $aliasBuilder = array(); @@ -146,6 +160,7 @@ class Fields extends Structure * title builder * * @var array + * @deprecated 3.3 CFactory::_('Registry')->get('builder.title'); */ public $titleBuilder = array(); @@ -161,6 +176,7 @@ class Fields extends Structure * custom Builder List * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->get('builder.custom_list'); */ public $customBuilderList = array(); @@ -168,6 +184,7 @@ class Fields extends Structure * Hidden Fields Builder * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->get('builder.hidden_fields'); */ public $hiddenFieldsBuilder = array(); @@ -175,6 +192,7 @@ class Fields extends Structure * INT Field Builder * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->get('builder.integer_fields'); */ public $intFieldsBuilder = array(); @@ -182,6 +200,7 @@ class Fields extends Structure * Dynamic Fields Builder * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->get('builder.dynamic_fields'); */ public $dynamicfieldsBuilder = array(); @@ -189,6 +208,7 @@ class Fields extends Structure * Main text Builder * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->get('builder.main_text_field'); */ public $maintextBuilder = array(); @@ -203,6 +223,7 @@ class Fields extends Structure * Custom Field Links Builder * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->get('builder.custom_field_links'); */ public $customFieldLinksBuilder = array(); @@ -357,6 +378,7 @@ class Fields extends Structure * Set Field Names * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->get('builder.field_names'); */ public $fieldsNames = array(); @@ -364,6 +386,7 @@ class Fields extends Structure * Default Fields set to publishing * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->set('builder.new_publishing_fields'); */ public $newPublishingFields = array(); @@ -371,6 +394,7 @@ class Fields extends Structure * Default Fields set to publishing * * @var array + * @deprecated 3.3 Use CFactory::_('Registry')->get('builder.moved_publishing_fields'); */ public $movedPublishingFields = array(); @@ -386,7 +410,7 @@ class Fields extends Structure * */ public function setFieldSet($view, $component, $nameSingleCode, - $nameListCode + $nameListCode ) { // setup the fieldset of this view if (isset($view['settings']->fields) @@ -395,12 +419,13 @@ class Fields extends Structure // add metadata to the view if (isset($view['metadata']) && $view['metadata']) { - $this->metadataBuilder[$nameSingleCode] = $nameListCode; + CFactory::_('Registry')->set('builder.meta_data.' . $nameSingleCode, $nameListCode); } // add access to the view if (isset($view['access']) && $view['access']) { - $this->accessBuilder[$nameSingleCode] = $nameListCode; + CFactory::_('Registry')->set('builder.access_switch.' . $nameSingleCode, true); + CFactory::_('Registry')->set('builder.access_switch_list.' . $nameListCode, true); } // main lang prefix $langView = CFactory::_('Config')->lang_prefix . '_' @@ -593,7 +618,7 @@ class Fields extends Structure * */ protected function stringFieldSet($view, $component, $nameSingleCode, - $nameListCode, $langView, $langViews + $nameListCode, $langView, $langViews ) { // set the read only $readOnly = false; @@ -614,9 +639,9 @@ class Fields extends Structure CFactory::_('Event')->trigger( 'jcb_ce_onBeforeBuildFields', array(&$component_context, &$dynamicFields, &$readOnly, - &$dbkey, &$view, &$component, &$nameSingleCode, - &$nameListCode, &$placeholders, &$langView, - &$langViews) + &$dbkey, &$view, &$component, &$nameSingleCode, + &$nameListCode, &$placeholders, &$langView, + &$langViews) ); unset($placeholders); // TODO we should add the global and local view switch if field for front end @@ -634,9 +659,9 @@ class Fields extends Structure CFactory::_('Event')->trigger( 'jcb_ce_onAfterBuildFields', array(&$component_context, &$dynamicFields, &$readOnly, - &$dbkey, &$view, &$component, &$nameSingleCode, - &$nameListCode, &$placeholders, &$langView, - &$langViews) + &$dbkey, &$view, &$component, &$nameSingleCode, + &$nameListCode, &$placeholders, &$langView, + &$langViews) ); unset($placeholders); // set the default fields @@ -647,7 +672,7 @@ class Fields extends Structure $fieldSet[] = Indent::_(2) . ""; // if id is not set - if (!isset($this->fieldsNames[$nameSingleCode]['id'])) + if (!CFactory::_('Registry')->isString('builder.field_names.' . $nameSingleCode . '.id')) { $fieldSet[] = Indent::_(2) . "field++; } // if created is not set - if (!isset($this->fieldsNames[$nameSingleCode]['created'])) + if (!CFactory::_('Registry')->isString('builder.field_names.' . $nameSingleCode . '.created')) { $fieldSet[] = Indent::_(2) . ""; @@ -684,7 +709,7 @@ class Fields extends Structure CFactory::_('Utilities.Counter')->field++; } // if created_by is not set - if (!isset($this->fieldsNames[$nameSingleCode]['created_by'])) + if (!CFactory::_('Registry')->isString('builder.field_names.' . $nameSingleCode . '.created_by')) { $fieldSet[] = Indent::_(2) . ""; @@ -704,7 +729,7 @@ class Fields extends Structure CFactory::_('Utilities.Counter')->field++; } // if published is not set - if (!isset($this->fieldsNames[$nameSingleCode]['published'])) + if (!CFactory::_('Registry')->isString('builder.field_names.' . $nameSingleCode . '.published')) { $fieldSet[] = Indent::_(2) . ""; @@ -731,7 +756,7 @@ class Fields extends Structure CFactory::_('Utilities.Counter')->field++; } // if modified is not set - if (!isset($this->fieldsNames[$nameSingleCode]['modified'])) + if (!CFactory::_('Registry')->isString('builder.field_names.' . $nameSingleCode . '.modified')) { $fieldSet[] = Indent::_(2) . ""; @@ -746,7 +771,7 @@ class Fields extends Structure CFactory::_('Utilities.Counter')->field++; } // if modified_by is not set - if (!isset($this->fieldsNames[$nameSingleCode]['modified_by'])) + if (!CFactory::_('Registry')->isString('builder.field_names.' . $nameSingleCode . '.modified_by')) { $fieldSet[] = Indent::_(2) . ""; @@ -764,11 +789,8 @@ class Fields extends Structure CFactory::_('Utilities.Counter')->field++; } // check if view has access - if (isset($this->accessBuilder[$nameSingleCode]) - && StringHelper::check( - $this->accessBuilder[$nameSingleCode] - ) - && !isset($this->fieldsNames[$nameSingleCode]['access'])) + if (CFactory::_('Registry')->exists('builder.access_switch.' . $nameSingleCode) + && !CFactory::_('Registry')->isString('builder.field_names.' . $nameSingleCode . '.access')) { $fieldSet[] = Indent::_(2) . ""; @@ -787,7 +809,7 @@ class Fields extends Structure CFactory::_('Utilities.Counter')->field++; } // if ordering is not set - if (!isset($this->fieldsNames[$nameSingleCode]['ordering'])) + if (!CFactory::_('Registry')->isString('builder.field_names.' . $nameSingleCode . '.ordering')) { $fieldSet[] = Indent::_(2) . ""; @@ -810,7 +832,7 @@ class Fields extends Structure CFactory::_('Utilities.Counter')->field++; } // if version is not set - if (!isset($this->fieldsNames[$nameSingleCode]['version'])) + if (!CFactory::_('Registry')->isString('builder.field_names.' . $nameSingleCode . '.version')) { $fieldSet[] = Indent::_(2) . ""; @@ -830,13 +852,10 @@ class Fields extends Structure CFactory::_('Utilities.Counter')->field++; } // check if metadata is added to this view - if (isset($this->metadataBuilder[$nameSingleCode]) - && StringHelper::check( - $this->metadataBuilder[$nameSingleCode] - )) + if (CFactory::_('Registry')->isString('builder.meta_data.' . $nameSingleCode)) { // metakey - if (!isset($this->fieldsNames[$nameSingleCode]['metakey'])) + if (!CFactory::_('Registry')->isString('builder.field_names.' . $nameSingleCode . '.metakey')) { $fieldSet[] = Indent::_(2) . ""; @@ -854,7 +873,7 @@ class Fields extends Structure CFactory::_('Utilities.Counter')->field++; } // metadesc - if (!isset($this->fieldsNames[$nameSingleCode]['metadesc'])) + if (!CFactory::_('Registry')->isString('builder.field_names.' . $nameSingleCode . '.metadesc')) { $fieldSet[] = Indent::_(2) . ""; @@ -874,7 +893,7 @@ class Fields extends Structure } // fix the permissions field "title" issue gh-629 // check if the the title is not already set - if (!isset($this->fieldsNames[$nameSingleCode]['title']) + if (!CFactory::_('Registry')->isString('builder.field_names.' . $nameSingleCode . '.title') && $this->hasPermissionsSet($view, $nameSingleCode)) { // set the field/tab name @@ -916,14 +935,11 @@ class Fields extends Structure // close fieldset $fieldSet[] = Indent::_(1) . "
"; // check if metadata is added to this view - if (isset($this->metadataBuilder[$nameSingleCode]) - && StringHelper::check( - $this->metadataBuilder[$nameSingleCode] - )) + if (CFactory::_('Registry')->isString('builder.meta_data.' . $nameSingleCode)) { - if (!isset($this->fieldsNames[$nameSingleCode]['robots']) - || !isset($this->fieldsNames[$nameSingleCode]['rights']) - || !isset($this->fieldsNames[$nameSingleCode]['author'])) + if (!CFactory::_('Registry')->isString('builder.field_names.' . $nameSingleCode . '.robots') + || !CFactory::_('Registry')->isString('builder.field_names.' . $nameSingleCode . '.rights') + || !CFactory::_('Registry')->isString('builder.field_names.' . $nameSingleCode . '.author')) { $fieldSet[] = PHP_EOL . Indent::_(1) . " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The available values for the filter attribute are:
FilterDescription
INTAn integer
UINTAn unsigned integer
FLOATA floating point number
BOOLEANA boolean value
WORDA string containing A-Z or underscores only (not case sensitive)
ALNUMA string containing A-Z or 0-9 only (not case sensitive)
CMDA string containing A-Z, 0-9, underscores, periods or hyphens (not case sensitive)
BASE64A string containing A-Z, 0-9, forward slashes, plus or equals (not case sensitive)
STRINGA fully decoded and sanitized string (default)
HTMLA sanitized string
ARRAYAn array
PATHA sanitized file path
USERNAMEDo not use (use an application specific filter)
RAWThe raw string is returned with no filtering
unknownAn unknown filter will act like STRING. If the input is an array it will return an array of fully decoded and sanitized strings.
- -
-

Validation Rules

- -
Searching the system.
-
-
-

Linked To

- -
Searching the database.
-
-" +COM_COMPONENTBUILDER_FIELD_NOTE_FILTER_INFORMATION_DESCRIPTION="

Filter Information

The available values for the filter attribute are:
Filter Description
INT An integer
UINT An unsigned integer
FLOAT A floating point number
BOOLEAN A boolean value
WORD A string containing A-Z or underscores only (not case sensitive)
ALNUM A string containing A-Z or 0-9 only (not case sensitive)
CMD A string containing A-Z, 0-9, underscores, periods or hyphens (not case sensitive)
BASE64 A string containing A-Z, 0-9, forward slashes, plus or equals (not case sensitive)
STRING A fully decoded and sanitized string (default)
HTML A sanitized string
ARRAY An array
PATH A sanitized file path
USERNAME Do not use (use an application specific filter)
RAW The raw string is returned with no filtering
unknown An unknown filter will act like STRING. If the input is an array it will return an array of fully decoded and sanitized strings.

Validation Rules

Searching the system.

Linked To

Searching the database.
" COM_COMPONENTBUILDER_FIELD_NOTE_NO_DATABASE_SETTINGS_NEEDED_DESCRIPTION="This field does not require any database settings to function correctly." COM_COMPONENTBUILDER_FIELD_NOTE_NO_DATABASE_SETTINGS_NEEDED_LABEL="No Database Require" COM_COMPONENTBUILDER_FIELD_NOTE_SELECT_FIELD_TYPE_DESCRIPTION="Please select a field type that you would like to build." COM_COMPONENTBUILDER_FIELD_NOTE_SELECT_FIELD_TYPE_LABEL="Building a field" -COM_COMPONENTBUILDER_FIELD_NOTE_WHMCS_ENCRYPTION_DESCRIPTION="

When using the WHMCS encryption you need to get a WHMCS key from:
https://www.vdm.io, or your own WHMCS install.

Please note that you will need to enable the add-on in the Joomla Component area (Add WHMCS)->Yes.

You can get more info about the WHMCS licensing add-on at the following links.

Helpful Links:
-https://www.whmcs.com/software-licensing/
-http://docs.whmcs.com/Licensing_Addon/

Support JCB and use our affiliate link (https://www.whmcs.com/members/aff.php?aff=37513) to sign-up with WHMCS.

" +COM_COMPONENTBUILDER_FIELD_NOTE_WHMCS_ENCRYPTION_DESCRIPTION="

When using the WHMCS encryption you need to get a WHMCS key from:
https://www.vdm.io, or your own WHMCS install.

Please note that you will need to enable the add-on in the Joomla Component area (Add WHMCS)->Yes.

You can get more info about the WHMCS licensing add-on at the following links.

Helpful Links:
https://www.whmcs.com/software-licensing/
http://docs.whmcs.com/Licensing_Addon/

Support JCB and use our affiliate link (https://www.whmcs.com/members/aff.php?aff=37513) to sign-up with WHMCS.

" COM_COMPONENTBUILDER_FIELD_NOTE_WHMCS_ENCRYPTION_LABEL="The WHMCS Encryption" COM_COMPONENTBUILDER_FIELD_NOT_NULL="NOT NULL" COM_COMPONENTBUILDER_FIELD_NOT_REQUIRED="Not Required" @@ -5177,11 +4814,7 @@ COM_COMPONENTBUILDER_FIELD_ONE="1" COM_COMPONENTBUILDER_FIELD_ONE_HUNDRED="100" COM_COMPONENTBUILDER_FIELD_ONE_THOUSAND_AND_TWENTY_FOUR="1024" COM_COMPONENTBUILDER_FIELD_ON_GET_MODEL_FIELD_DESCRIPTION="To on get model the field value" -COM_COMPONENTBUILDER_FIELD_ON_GET_MODEL_FIELD_HINT="if (!empty([[[field]]]) && $mediumkey && !is_numeric([[[field]]]) && [[[field]]] === base64_encode(base64_decode([[[field]]], true))) -{ - // medium decrypt field - [[[field]]] = rtrim($medium->decryptString([[[field]]]), "\0"); -}" +COM_COMPONENTBUILDER_FIELD_ON_GET_MODEL_FIELD_HINT="if (!empty([[[field]]]) && $mediumkey && !is_numeric([[[field]]]) && [[[field]]] === base64_encode(base64_decode([[[field]]], true))){ // medium decrypt field [[[field]]] = rtrim($medium->decryptString([[[field]]]), "\0");}" COM_COMPONENTBUILDER_FIELD_ON_GET_MODEL_FIELD_LABEL="On Get Model" COM_COMPONENTBUILDER_FIELD_ON_SAVE_MODEL_FIELD_DESCRIPTION="To on save model the field value" COM_COMPONENTBUILDER_FIELD_ON_SAVE_MODEL_FIELD_HINT="[[[field]]] = $medium->encryptString([[[field]]]);" @@ -5277,14 +4910,10 @@ COM_COMPONENTBUILDER_FILTER_NAMESPACE_ASCENDING="Namespace ascending" COM_COMPONENTBUILDER_FILTER_NAMESPACE_DESCENDING="Namespace descending" COM_COMPONENTBUILDER_FILTER_NAME_ASCENDING="Name ascending" COM_COMPONENTBUILDER_FILTER_NAME_DESCENDING="Name descending" -COM_COMPONENTBUILDER_FILTER_NAME_IN_CODE_NAMING_CONVENTIONS_ASCENDING="Name in Code -Naming Conventions ascending" -COM_COMPONENTBUILDER_FILTER_NAME_IN_CODE_NAMING_CONVENTIONS_DESCENDING="Name in Code -Naming Conventions descending" -COM_COMPONENTBUILDER_FILTER_NAME_SINGLE_RECORD_NAMING_CONVENTIONS_ASCENDING="Name (single record) -Naming Conventions ascending" -COM_COMPONENTBUILDER_FILTER_NAME_SINGLE_RECORD_NAMING_CONVENTIONS_DESCENDING="Name (single record) -Naming Conventions descending" +COM_COMPONENTBUILDER_FILTER_NAME_IN_CODENAMING_CONVENTIONS_ASCENDING="Name in CodeNaming Conventions ascending" +COM_COMPONENTBUILDER_FILTER_NAME_IN_CODENAMING_CONVENTIONS_DESCENDING="Name in CodeNaming Conventions descending" +COM_COMPONENTBUILDER_FILTER_NAME_SINGLE_RECORDNAMING_CONVENTIONS_ASCENDING="Name (single record)Naming Conventions ascending" +COM_COMPONENTBUILDER_FILTER_NAME_SINGLE_RECORDNAMING_CONVENTIONS_DESCENDING="Name (single record)Naming Conventions descending" COM_COMPONENTBUILDER_FILTER_NULL_SWITCH_ASCENDING="Null Switch ascending" COM_COMPONENTBUILDER_FILTER_NULL_SWITCH_DESCENDING="Null Switch descending" COM_COMPONENTBUILDER_FILTER_PROTOCOL_ASCENDING="Protocol ascending" @@ -5417,13 +5046,13 @@ COM_COMPONENTBUILDER_FILTER_SELECT_NAME="Select Name" COM_COMPONENTBUILDER_FILTER_SELECT_NULL_SWITCH="Select Null Switch" COM_COMPONENTBUILDER_FILTER_SELECT_PROTOCOL="Select Protocol" COM_COMPONENTBUILDER_FILTER_SELECT_SITE_VIEWS="Select Site Views" +COM_COMPONENTBUILDER_FILTER_SELECT_SUPER_POWER="Select Super Power" COM_COMPONENTBUILDER_FILTER_SELECT_TARGET="Select Target" COM_COMPONENTBUILDER_FILTER_SELECT_TARGET_AREA="Select Target Area" COM_COMPONENTBUILDER_FILTER_SELECT_TARGET_FOLDER="Select Target Folder" COM_COMPONENTBUILDER_FILTER_SELECT_TYPE="Select Type" COM_COMPONENTBUILDER_FILTER_SELECT_TYPE_BEHAVIOR="Select Type Behavior" COM_COMPONENTBUILDER_FILTER_SELECT_TYPE_OF_POWER="Select Type of Power" -COM_COMPONENTBUILDER_FILTER_SELECT_VERSION="Select Version" COM_COMPONENTBUILDER_FILTER_SELECT_VISIBILITY="Select Visibility" COM_COMPONENTBUILDER_FILTER_SET_STRING_VALUE_ASCENDING="Set String Value ascending" COM_COMPONENTBUILDER_FILTER_SET_STRING_VALUE_DESCENDING="Set String Value descending" @@ -5611,6 +5240,7 @@ COM_COMPONENTBUILDER_HELP_JCB_GROW="Help JCB Grow" 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_HERE_YOU_CAN_SET_THE_PATH_TO_THE_SUPER_POWERS_LOCAL_REPOSITORY_FOLDER_WHERE_BLAYERCOREB_AND_ALL_TARGETED_BLAYEROWNB_SUB_PATHS_WILL_BE_PLACED_WITH_THEIR_SELECTIVE_BSWITCHAPPROVEDB_POWERS="Here you can set the path to the super powers local repository folder, where [layer:core] and all targeted [layer:own] sub paths will be placed with their selective [switch:approved] powers." COM_COMPONENTBUILDER_HFOUR_CLASSNAVHEADERCOPYRIGHTHFOURPSP="

%s

" COM_COMPONENTBUILDER_HFOUR_CLASSNAVHEADERLICENSEHFOURPSP="

%s

" COM_COMPONENTBUILDER_HI="Hi" @@ -5634,7 +5264,7 @@ COM_COMPONENTBUILDER_HTHREES_NAMESPACE_ERROR_SHTHREEPYOU_MUST_ATLEAST_HAVE_TWO_S COM_COMPONENTBUILDER_HTWOCURL_NOT_FOUNDHTWOPPLEASE_SETUP_CURL_ON_YOUR_SYSTEM_OR_BCOMPONENTBUILDERB_WILL_NOT_FUNCTION_CORRECTLYP="

Curl Not Found!

Please setup curl on your system, or componentbuilder will not function correctly!

" COM_COMPONENTBUILDER_HTWODATA_IS_CORRUPTHTWOTHIS_COULD_BE_DUE_TO_BKEY_ERRORB_OR_BROKEN_PACKAGE="

Data is corrupt!

This could be due to key error, or broken package!" COM_COMPONENTBUILDER_HTWODATA_IS_CORRUPTHTWOTHIS_COULD_BE_DUE_TO_BROKEN_PACKAGE="

Data is corrupt!

This could be due to broken package!" -COM_COMPONENTBUILDER_HTWOWE_COULD_NOT_OPEN_THE_ENCRYPT_DATAHTWO_THIS_COULD_BE_DUE_TO_THE_FOFENCRYPTION_THAT_IS_NO_LONGER_SUPPORTED_IN_JOOMLABR_PLEASE_EXPORT_YOUR_PACKAGES_WITH_JCB_VTHREEONEONENINE_OR_HIGHER_TO_BE_ABLE_TO_IMPORT_IT_INTO_THIS_VERSION_OF_JCB="

We could not open the encrypt data!

This could be due to the FOFEncryption that is no longer supported in Joomla.
Please export your packages with JCB v3.1.19 or higher to be able to import it into this version of JCB." +COM_COMPONENTBUILDER_HTWOWE_COULD_NOT_OPEN_THE_ENCRYPT_DATAHTWO_THIS_COULD_BE_DUE_TO_THE_FOFENCRYPTION_THAT_IS_NO_LONGER_SUPPORTED_IN_JOOMLABR_PLEASE_EXPORT_YOUR_PACKAGES_WITH_JCB_VTHREEONEONEEIGHT_OR_HIGHER_TO_BE_ABLE_TO_IMPORT_IT_INTO_THIS_VERSION_OF_JCB="

We could not open the encrypt data!

This could be due to the FOFEncryption that is no longer supported in Joomla.
Please export your packages with JCB v3.1.18 or higher to be able to import it into this version of JCB." COM_COMPONENTBUILDER_HTWOWE_COULD_NOT_OPEN_THE_PACKAGEHTWOTHIS_COULD_BE_DUE_TO_THE_FOFENCRYPTION_THAT_IS_NO_LONGER_SUPPORTED_IN_JOOMLA_PLEASE_EXPORT_YOUR_PACKAGES_WITH_JCB_VTHREEZEROELEVENPRO_OR_VTWOONETWOSEVENTEENPUBLIC_OR_HIGHER_TO_BE_ABLE_TO_IMPORT_IT_INTO_THIS_VERSION_OF_JCB="

We could not open the package!

This could be due to the FOFEncryption that is no longer supported in Joomla. Please export your packages with JCB v3.0.11(pro) or v2.12.17(public) or higher to be able to import it into this version of JCB." COM_COMPONENTBUILDER_IAUTHORI_BSB="Author: %s" COM_COMPONENTBUILDER_ICOMPANYI_BSB="Company: %s" @@ -5702,6 +5332,7 @@ COM_COMPONENTBUILDER_IMPORT_UPDATE_DATA="Import Data" COM_COMPONENTBUILDER_IMPORT_UPLOAD_BOTTON="Upload File" COM_COMPONENTBUILDER_INACTIVE="Inactive" COM_COMPONENTBUILDER_INDENTATION_OPTIONS="Indentation Options" +COM_COMPONENTBUILDER_INIT="Init" COM_COMPONENTBUILDER_INVEST_IN_JCB="Invest in JCB" COM_COMPONENTBUILDER_INVEST_IN_THE_FUTURE_OF_JOOMLA_COMPONENT_BUILDER_JCB_BY_MAKING_A_BFINANCIAL_CONTRIBUTIONB_NO_MATTER_HOW_SMALL_THE_CONTINUAL_SUPPORT_OF_ALL_THOSE_USING_THE_TOOL_WILL_BE_MORE_THAN_ENOUGH_TO_ENSURE_ITS_CONTINUED_GROWTH_AND_RELEVANCE_BY_INVESTING_IN_THIS_OPENSOURCE_PROJECT_YOU_ARE_SECURING_ITS_FUTURE_AS_A_VITAL_TOOL_FOR_PHP_PROGRAMMERS="Invest in the future of Joomla Component Builder (JCB) by making a financial contribution, no matter how small. The continual support of all those using the tool will be more than enough to ensure its continued growth and relevance. By investing in this open-source project, you are securing its future as a vital tool for PHP programmers." COM_COMPONENTBUILDER_INVEST_IN_THE_FUTURE_OF_JOOMLA_COMPONENT_BUILDER_JCB_BY_MAKING_A_BFINANCIAL_DONATIONB_SUPPORT_THE_NECESSARY_DEVELOPMENT_AND_MAINTENANCE_OF_THIS_OPENSOURCE_PROJECT_ENSURING_ITS_CONTINUED_GROWTH_AND_RELEVANCE_FOR_THE_COMMUNITY_YOUR_CONTRIBUTION_WILL_HELP_SECURE_THE_FUTURE_OF_THIS_VITAL_TOOL_FOR_PHP_PROGRAMMERS="Invest in the future of Joomla Component Builder (JCB) by making a financial donation. Support the necessary development and maintenance of this open-source project, ensuring its continued growth and relevance for the community. Your contribution will help secure the future of this vital tool for PHP programmers." @@ -5862,9 +5493,7 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_UIKIT_V2="Add Uikit v2" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_UIKIT_V3="Add Uikit v3" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADD_UPDATE_SERVER_LABEL="Add Update Server" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ADMIN_VIEWS="Admin Views" -COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ASSETS_TABLE_FIX_DESCRIPTION="How to apply the assets table fix in JCB.
-SQL (add&remove) this is the default which adds the SQL fix and removes it once the component is uninstalled.
-Intelligent (add&remove+if) same as default, but on uninstall will only remove this fix if no other component needs it. Note that this option will only work with other components that also use the intelligent path." +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ASSETS_TABLE_FIX_DESCRIPTION="How to apply the assets table fix in JCB.
SQL (add&remove) this is the default which adds the SQL fix and removes it once the component is uninstalled.
Intelligent (add&remove+if) same as default, but on uninstall will only remove this fix if no other component needs it. Note that this option will only work with other components that also use the intelligent path." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ASSETS_TABLE_FIX_LABEL="Assets Table Fix" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_AUTHOR_DESCRIPTION="The Author's Name & Surname." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_AUTHOR_HINT="Author Name & Surname Here" @@ -5986,10 +5615,7 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_LICENSE_TYPE_LABEL="Implementation" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_LOCK_DOWN_USE_USED_TO_VERIFY_OWNERSHIP="Lock Down Use (used to verify ownership)" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MENU_PREFIX_DESCRIPTION="Add the prefix you would like to use. Make sure that it is HTML Character Entities since it is being used in XML." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MENU_PREFIX_HINT="»" -COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MENU_PREFIX_LABEL="Prefix
-Check out these lists:
-Char-ref or -Emoji
" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MENU_PREFIX_LABEL="Prefix
Check out these lists:
Char-ref or Emoji
" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MENU_PREFIX_MESSAGE="Error! Please add some text here." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MODIFIED_BY_DESC="The last user that modified this Joomla Component." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MODIFIED_BY_LABEL="Modified By" @@ -6002,8 +5628,7 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MVC_VERSIONDATE_LABEL="Version Options" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_MYSQL="MySQL" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NAME_CODE_DESCRIPTION="Add Name in Code Here" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NAME_CODE_HINT="codename" -COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NAME_CODE_LABEL="Name in Code
-Naming Conventions" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NAME_CODE_LABEL="Name in Code
Naming Conventions" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NAME_CODE_MESSAGE="Error! Please add name in code here." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NAME_DESCRIPTION="Enter Name Here" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NAME_HINT="Name Here" @@ -6022,22 +5647,7 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_BUILDCOMP_DYNAMIC_MYSQL_DESCRIPTION=" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_BUILDCOMP_DYNAMIC_MYSQL_LABEL="Dynamic Builder (mySql) Option" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_COMPONENT_FILES_FOLDERS_DESCRIPTION="You can add custom files and folders to the component, simply add the files to the administrator/components/com_componentbuilder/custom folder and then select them here." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_COMPONENT_FILES_FOLDERS_LABEL="Adding Custom Files & Folder" -COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_CROWDIN_DESCRIPTION="
-

Feature not ready?

-

We are still working on this integration, so it is not fully ready.

-
-
-
-

How to use Crowdin with JCB?

-

You will need an account with Crowdin https://crowdin.com/, then setup a project following these steps https://support.crowdin.com/creating-project/
-Once your project is created get the project API key following these steps https://support.crowdin.com/api/api-integration-setup/
-Then add the Project API key and identifier details below, and your done! Next time you compile this component JCB will automatically sync your project with Crowdin.

-
-
-
-
-
-
" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_CROWDIN_DESCRIPTION="

Feature not ready?

We are still working on this integration, so it is not fully ready.

How to use Crowdin with JCB?

You will need an account with Crowdin https://crowdin.com/, then setup a project following these steps https://support.crowdin.com/creating-project/
Once your project is created get the project API key following these steps https://support.crowdin.com/api/api-integration-setup/
Then add the Project API key and identifier details below, and your done! Next time you compile this component JCB will automatically sync your project with Crowdin.

" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_CROWDIN_LABEL="Crowdin" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_DISPLAY_COMPONENT_ADMIN_VIEWS_DESCRIPTION="

Linked Admin Views

Display of the admin views will load here!
" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_DISPLAY_COMPONENT_CUSTOM_ADMIN_VIEWS_DESCRIPTION="

Linked Custom Admin Views

Display of the custom admin views will load here!
" @@ -6056,61 +5666,7 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_ON_CUSTOM_ADMIN_VIEWS_DESCRIPTION="Do COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_ON_CUSTOM_ADMIN_VIEWS_LABEL="Setting Custom Admin Views" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_ON_SITE_VIEWS_DESCRIPTION="Do not add the same view twice it will not work. Please watch this tutorial for more help." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_ON_SITE_VIEWS_LABEL="Setting Site Views" -COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_README_DESCRIPTION="

Need help, visit Markdown-Cheatsheet

- -# ###Component_name### (###VERSION###)
-
-###DESCRIPTION###
-
-# Build Details
-
-+ *Company*: [###COMPANYNAME###](###AUTHORWEBSITE###)
-+ *Author*: [###AUTHOR###](mailto:###AUTHOREMAIL###)
-+ *Name*: [###Component_name###](###AUTHORWEBSITE###)
-+ *First Build*: ###CREATIONDATE###
-+ *Last Build*: ###BUILDDATE###
-+ *Version*: ###VERSION###
-+ *Copyright*: ###COPYRIGHT###
-+ *License*: ###LICENSE###
-
-## Build Time
-
-**###totalHours### Hours** or **###totalDays### Eight Hour Days** (actual time the author saved -
-due to [Automated Component Builder](https://www.joomlacomponentbuilder.com))
-
-> (if creating a folder and file took **5 seconds** and writing one line of code took **10 seconds**,
-> never making one mistake or taking any coffee break.)
-
-+ *Line count*: **###LINE_COUNT###**
-+ *File count*: **###FILE_COUNT###**
-+ *Folder count*: **###FOLDER_COUNT###**
-
-**###actualHoursSpent### Hours** or **###actualDaysSpent### Eight Hour Days** (the actual time the author spent)
-
-> (with the following break down:
-> **debugging @###debuggingHours###hours** = codingtime / 4;
-> **planning @###planningHours###hours** = codingtime / 7;
-> **mapping @###mappingHours###hours** = codingtime / 10;
-> **office @###officeHours###hours** = codingtime / 6;)
-
-**###actualTotalHours### Hours** or **###actualTotalDays### Eight Hour Days**
-(a total of the realistic time frame for this project)
-
-> (if creating a folder and file took **5 seconds** and writing one line of code took **10 seconds**,
-> with the normal everyday realities at the office, that includes the component planning, mapping & debugging.)
-
-Project duration: **###projectWeekTime### weeks** or **###projectMonthTime### months**
-
-> This **component** was build with a Joomla [Automated Component Builder](https://www.joomlacomponentbuilder.com).
-> Developed by [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com)
-
-## Donations
-
- If you want to support this project, please consider donating:
- * PayPal: [paypal.me/donationgeek](https://www.paypal.me/donationgeek)
- * Bitcoin: 18vURxYpPFjvNk8BnUy1ovCAyQmY3MzkSf
- * Ethereum: 0x9548144662b47327c954f3e214edb96662d51218 -
" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_README_DESCRIPTION="

Need help, visit Markdown-Cheatsheet

# ###Component_name### (###VERSION###)

###DESCRIPTION###

# Build Details

+ *Company*: [###COMPANYNAME###](###AUTHORWEBSITE###)
+ *Author*: [###AUTHOR###](mailto:###AUTHOREMAIL###)
+ *Name*: [###Component_name###](###AUTHORWEBSITE###)
+ *First Build*: ###CREATIONDATE###
+ *Last Build*: ###BUILDDATE###
+ *Version*: ###VERSION###
+ *Copyright*: ###COPYRIGHT###
+ *License*: ###LICENSE###

## Build Time

**###totalHours### Hours** or **###totalDays### Eight Hour Days** (actual time the author saved -
due to [Automated Component Builder](https://www.joomlacomponentbuilder.com))

> (if creating a folder and file took **5 seconds** and writing one line of code took **10 seconds**,
> never making one mistake or taking any coffee break.)

+ *Line count*: **###LINE_COUNT###**
+ *File count*: **###FILE_COUNT###**
+ *Folder count*: **###FOLDER_COUNT###**

**###actualHoursSpent### Hours** or **###actualDaysSpent### Eight Hour Days** (the actual time the author spent)

> (with the following break down:
> **debugging @###debuggingHours###hours** = codingtime / 4;
> **planning @###planningHours###hours** = codingtime / 7;
> **mapping @###mappingHours###hours** = codingtime / 10;
> **office @###officeHours###hours** = codingtime / 6;)

**###actualTotalHours### Hours** or **###actualTotalDays### Eight Hour Days**
(a total of the realistic time frame for this project)

> (if creating a folder and file took **5 seconds** and writing one line of code took **10 seconds**,
> with the normal everyday realities at the office, that includes the component planning, mapping & debugging.)

Project duration: **###projectWeekTime### weeks** or **###projectMonthTime### months**

> This **component** was build with a Joomla [Automated Component Builder](https://www.joomlacomponentbuilder.com).
> Developed by [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com)

## Donations

If you want to support this project, please consider donating:
* PayPal: [paypal.me/donationgeek](https://www.paypal.me/donationgeek)
* Bitcoin: 18vURxYpPFjvNk8BnUy1ovCAyQmY3MzkSf
* Ethereum: 0x9548144662b47327c954f3e214edb96662d51218
" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_README_LABEL="Demo README (with all place-holders)" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_UPDATE_SERVER_NOTE_FTP_DESCRIPTION="During compilation the file will be moved to the server. You still need to point the above update server url to the xml file location on your server for it to work correctly." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_NOTE_UPDATE_SERVER_NOTE_FTP_LABEL="Select the server used for your update server." @@ -6476,42 +6032,7 @@ COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_NOTE_ADD_FOLDERS_FULLPATH_ COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_NOTE_ADD_FOLDERS_LABEL="Adding Custom Folders" COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_NOTE_ADD_URLS_DESCRIPTION="You can add urls here, and it can be used in three ways. As a direct link (default) or to get the file content and add it to the component (get) or as both local and link (dynamic)" COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_NOTE_ADD_URLS_LABEL="Adding Urls" -COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_NOTE_CONSTANT_PATHS_DESCRIPTION="

// The path to the administrator folder.
-JPATH_ADMINISTRATOR
-// The path to the installed Joomla! site, or JPATH_ROOT/administrator if executed from the backend.
-JPATH_BASE
-// The path to the cache folder.
-JPATH_CACHE
-// The path to the administration folder of JCB component.
-JPATH_COMPONENT_ADMINISTRATOR no ideal to use
-// The path to the site folder of JCB component.
-JPATH_COMPONENT_SITE no ideal to use
-// The path to the JCB component.
-JPATH_COMPONENT no ideal to use
-// The path to folder containing the configuration.php file.
-JPATH_CONFIGURATION
-// The path to the installation folder.
-JPATH_INSTALLATION
-// The path to the libraries folder.
-JPATH_LIBRARIES
-// The path to the plugins folder.
-JPATH_PLUGINS
-// The path to the installed Joomla! site.
-JPATH_ROOT
-// The path to the installed Joomla! site.
-JPATH_SITE
-// The path to the templates folder.
-JPATH_THEMES

- -

JPATH_SITE is meant to represent the root path of the JSite application,
-just as JPATH_ADMINISTRATOR is mean to represent the root path of the JAdministrator application.
-JPATH_BASE is the root path for the current requested application.... so if you are in the administrator application:
-JPATH_BASE == JPATH_ADMINISTRATOR
-If you are in the site application:
-JPATH_BASE == JPATH_SITE
-If you are in the installation application:
-JPATH_BASE == JPATH_INSTALLATION.
-JPATH_ROOT is the root path for the Joomla install and does not depend upon any application.

" +COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_NOTE_CONSTANT_PATHS_DESCRIPTION="

// The path to the administrator folder.
JPATH_ADMINISTRATOR
// The path to the installed Joomla! site, or JPATH_ROOT/administrator if executed from the backend.
JPATH_BASE
// The path to the cache folder.
JPATH_CACHE
// The path to the administration folder of JCB component.
JPATH_COMPONENT_ADMINISTRATOR no ideal to use
// The path to the site folder of JCB component.
JPATH_COMPONENT_SITE no ideal to use
// The path to the JCB component.
JPATH_COMPONENT no ideal to use
// The path to folder containing the configuration.php file.
JPATH_CONFIGURATION
// The path to the installation folder.
JPATH_INSTALLATION
// The path to the libraries folder.
JPATH_LIBRARIES
// The path to the plugins folder.
JPATH_PLUGINS
// The path to the installed Joomla! site.
JPATH_ROOT
// The path to the installed Joomla! site.
JPATH_SITE
// The path to the templates folder.
JPATH_THEMES

JPATH_SITE is meant to represent the root path of the JSite application,
just as JPATH_ADMINISTRATOR is mean to represent the root path of the JAdministrator application.
JPATH_BASE is the root path for the current requested application.... so if you are in the administrator application:
JPATH_BASE == JPATH_ADMINISTRATOR
If you are in the site application:
JPATH_BASE == JPATH_SITE
If you are in the installation application:
JPATH_BASE == JPATH_INSTALLATION.
JPATH_ROOT is the root path for the Joomla install and does not depend upon any application.

" COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_NOTE_CONSTANT_PATHS_LABEL="Constant Paths" COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_NOTNEW_DESCRIPTION="Should file be updated." COM_COMPONENTBUILDER_JOOMLA_MODULE_FILES_FOLDERS_URLS_NOTNEW_LABEL="Update" @@ -6571,13 +6092,9 @@ COM_COMPONENTBUILDER_JOOMLA_MODULE_NAME_MESSAGE="Error! Please add name here." COM_COMPONENTBUILDER_JOOMLA_MODULE_NEW="A New Joomla Module" COM_COMPONENTBUILDER_JOOMLA_MODULE_NO="No" COM_COMPONENTBUILDER_JOOMLA_MODULE_NONE="None" -COM_COMPONENTBUILDER_JOOMLA_MODULE_NOTE_ADD_PHP_LANGUAGE_STRING_DESCRIPTION="<?php echo JText::_('Text'); ?>
-<?php echo JText::sprintf('Hello %s', $this->user->name); ?>
-Just get UPPERCASE language string:
-<?php echo JustTEXT::_('Text'); ?>" +COM_COMPONENTBUILDER_JOOMLA_MODULE_NOTE_ADD_PHP_LANGUAGE_STRING_DESCRIPTION="<?php echo JText::_('Text'); ?>
<?php echo JText::sprintf('Hello %s', $this->user->name); ?>
Just get UPPERCASE language string:
<?php echo JustTEXT::_('Text'); ?>" COM_COMPONENTBUILDER_JOOMLA_MODULE_NOTE_ADD_PHP_LANGUAGE_STRING_LABEL="Add PHP Language String" -COM_COMPONENTBUILDER_JOOMLA_MODULE_NOTE_LIBRARIES_OPTIONS_DESCRIPTION="

All libraries added to modules are added to the component media folder for now

-

So over here you are able to manually add HTML code to your model default tmpl.

" +COM_COMPONENTBUILDER_JOOMLA_MODULE_NOTE_LIBRARIES_OPTIONS_DESCRIPTION="

All libraries added to modules are added to the component media folder for now

So over here you are able to manually add HTML code to your model default tmpl.

" COM_COMPONENTBUILDER_JOOMLA_MODULE_NOTE_LIBRARIES_OPTIONS_LABEL="Libraries Options" COM_COMPONENTBUILDER_JOOMLA_MODULE_NOTE_LINKED_TO_NOTICE_DESCRIPTION="
Searching the database.
" COM_COMPONENTBUILDER_JOOMLA_MODULE_NOTE_LINKED_TO_NOTICE_LABEL="Linked To" @@ -6914,42 +6431,7 @@ COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_NOTE_ADD_FOLDERS_FULLPATH_ COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_NOTE_ADD_FOLDERS_LABEL="Adding Custom Folders" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_NOTE_ADD_URLS_DESCRIPTION="You can add urls here, and it can be used in three ways. As a direct link (default) or to get the file content and add it to the component (get) or as both local and link (dynamic)" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_NOTE_ADD_URLS_LABEL="Adding Urls" -COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_NOTE_CONSTANT_PATHS_DESCRIPTION="

// The path to the administrator folder.
-JPATH_ADMINISTRATOR
-// The path to the installed Joomla! site, or JPATH_ROOT/administrator if executed from the backend.
-JPATH_BASE
-// The path to the cache folder.
-JPATH_CACHE
-// The path to the administration folder of JCB component.
-JPATH_COMPONENT_ADMINISTRATOR no ideal to use
-// The path to the site folder of JCB component.
-JPATH_COMPONENT_SITE no ideal to use
-// The path to the JCB component.
-JPATH_COMPONENT no ideal to use
-// The path to folder containing the configuration.php file.
-JPATH_CONFIGURATION
-// The path to the installation folder.
-JPATH_INSTALLATION
-// The path to the libraries folder.
-JPATH_LIBRARIES
-// The path to the plugins folder.
-JPATH_PLUGINS
-// The path to the installed Joomla! site.
-JPATH_ROOT
-// The path to the installed Joomla! site.
-JPATH_SITE
-// The path to the templates folder.
-JPATH_THEMES

- -

JPATH_SITE is meant to represent the root path of the JSite application,
-just as JPATH_ADMINISTRATOR is mean to represent the root path of the JAdministrator application.
-JPATH_BASE is the root path for the current requested application.... so if you are in the administrator application:
-JPATH_BASE == JPATH_ADMINISTRATOR
-If you are in the site application:
-JPATH_BASE == JPATH_SITE
-If you are in the installation application:
-JPATH_BASE == JPATH_INSTALLATION.
-JPATH_ROOT is the root path for the Joomla install and does not depend upon any application.

" +COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_NOTE_CONSTANT_PATHS_DESCRIPTION="

// The path to the administrator folder.
JPATH_ADMINISTRATOR
// The path to the installed Joomla! site, or JPATH_ROOT/administrator if executed from the backend.
JPATH_BASE
// The path to the cache folder.
JPATH_CACHE
// The path to the administration folder of JCB component.
JPATH_COMPONENT_ADMINISTRATOR no ideal to use
// The path to the site folder of JCB component.
JPATH_COMPONENT_SITE no ideal to use
// The path to the JCB component.
JPATH_COMPONENT no ideal to use
// The path to folder containing the configuration.php file.
JPATH_CONFIGURATION
// The path to the installation folder.
JPATH_INSTALLATION
// The path to the libraries folder.
JPATH_LIBRARIES
// The path to the plugins folder.
JPATH_PLUGINS
// The path to the installed Joomla! site.
JPATH_ROOT
// The path to the installed Joomla! site.
JPATH_SITE
// The path to the templates folder.
JPATH_THEMES

JPATH_SITE is meant to represent the root path of the JSite application,
just as JPATH_ADMINISTRATOR is mean to represent the root path of the JAdministrator application.
JPATH_BASE is the root path for the current requested application.... so if you are in the administrator application:
JPATH_BASE == JPATH_ADMINISTRATOR
If you are in the site application:
JPATH_BASE == JPATH_SITE
If you are in the installation application:
JPATH_BASE == JPATH_INSTALLATION.
JPATH_ROOT is the root path for the Joomla install and does not depend upon any application.

" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_NOTE_CONSTANT_PATHS_LABEL="Constant Paths" COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_NOTNEW_DESCRIPTION="Should file be updated." COM_COMPONENTBUILDER_JOOMLA_PLUGIN_FILES_FOLDERS_URLS_NOTNEW_LABEL="Update" @@ -7425,10 +6907,7 @@ COM_COMPONENTBUILDER_LAYOUT_NAME_LABEL="Name" COM_COMPONENTBUILDER_LAYOUT_NAME_MESSAGE="Error! Please add name here." COM_COMPONENTBUILDER_LAYOUT_NEW="A New Layout" COM_COMPONENTBUILDER_LAYOUT_NO="No" -COM_COMPONENTBUILDER_LAYOUT_NOTE_ADD_PHP_LANGUAGE_STRING_DESCRIPTION="<?php echo JText::_('Text'); ?>
-<?php echo JText::sprintf('Hello %s', $this->user->name); ?>
-Just get UPPERCASE language string:
-<?php echo JustTEXT::_('Text'); ?>" +COM_COMPONENTBUILDER_LAYOUT_NOTE_ADD_PHP_LANGUAGE_STRING_DESCRIPTION="<?php echo JText::_('Text'); ?>
<?php echo JText::sprintf('Hello %s', $this->user->name); ?>
Just get UPPERCASE language string:
<?php echo JustTEXT::_('Text'); ?>" COM_COMPONENTBUILDER_LAYOUT_NOTE_ADD_PHP_LANGUAGE_STRING_LABEL="Add PHP Language String" COM_COMPONENTBUILDER_LAYOUT_NOTE_LIBRARIES_SELECTION_DESCRIPTION="All libraries you select will dynamically be added to the header of the page according to the settings of the selected library. Each library will also get its respective buttons added to the component global options if it has any set. Please take a look at the libraries for more details." COM_COMPONENTBUILDER_LAYOUT_NOTE_LIBRARIES_SELECTION_LABEL="Select libraries you would like to use in your code" @@ -7687,42 +7166,7 @@ COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_NOTE_ADD_FOLDERS_FULLPATH_LABEL= COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_NOTE_ADD_FOLDERS_LABEL="Adding Custom Folders" COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_NOTE_ADD_URLS_DESCRIPTION="You can add urls here, and it can be used in three ways. As a direct link (default) or to get the file content and add it to the component (get) or as both local and link (dynamic)" COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_NOTE_ADD_URLS_LABEL="Adding Urls" -COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_NOTE_CONSTANT_PATHS_DESCRIPTION="

// The path to the administrator folder.
-JPATH_ADMINISTRATOR
-// The path to the installed Joomla! site, or JPATH_ROOT/administrator if executed from the backend.
-JPATH_BASE
-// The path to the cache folder.
-JPATH_CACHE
-// The path to the administration folder of JCB component.
-JPATH_COMPONENT_ADMINISTRATOR no ideal to use
-// The path to the site folder of JCB component.
-JPATH_COMPONENT_SITE no ideal to use
-// The path to the JCB component.
-JPATH_COMPONENT no ideal to use
-// The path to folder containing the configuration.php file.
-JPATH_CONFIGURATION
-// The path to the installation folder.
-JPATH_INSTALLATION
-// The path to the libraries folder.
-JPATH_LIBRARIES
-// The path to the plugins folder.
-JPATH_PLUGINS
-// The path to the installed Joomla! site.
-JPATH_ROOT
-// The path to the installed Joomla! site.
-JPATH_SITE
-// The path to the templates folder.
-JPATH_THEMES

- -

JPATH_SITE is meant to represent the root path of the JSite application,
-just as JPATH_ADMINISTRATOR is mean to represent the root path of the JAdministrator application.
-JPATH_BASE is the root path for the current requested application.... so if you are in the administrator application:
-JPATH_BASE == JPATH_ADMINISTRATOR
-If you are in the site application:
-JPATH_BASE == JPATH_SITE
-If you are in the installation application:
-JPATH_BASE == JPATH_INSTALLATION.
-JPATH_ROOT is the root path for the Joomla install and does not depend upon any application.

" +COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_NOTE_CONSTANT_PATHS_DESCRIPTION="

// The path to the administrator folder.
JPATH_ADMINISTRATOR
// The path to the installed Joomla! site, or JPATH_ROOT/administrator if executed from the backend.
JPATH_BASE
// The path to the cache folder.
JPATH_CACHE
// The path to the administration folder of JCB component.
JPATH_COMPONENT_ADMINISTRATOR no ideal to use
// The path to the site folder of JCB component.
JPATH_COMPONENT_SITE no ideal to use
// The path to the JCB component.
JPATH_COMPONENT no ideal to use
// The path to folder containing the configuration.php file.
JPATH_CONFIGURATION
// The path to the installation folder.
JPATH_INSTALLATION
// The path to the libraries folder.
JPATH_LIBRARIES
// The path to the plugins folder.
JPATH_PLUGINS
// The path to the installed Joomla! site.
JPATH_ROOT
// The path to the installed Joomla! site.
JPATH_SITE
// The path to the templates folder.
JPATH_THEMES

JPATH_SITE is meant to represent the root path of the JSite application,
just as JPATH_ADMINISTRATOR is mean to represent the root path of the JAdministrator application.
JPATH_BASE is the root path for the current requested application.... so if you are in the administrator application:
JPATH_BASE == JPATH_ADMINISTRATOR
If you are in the site application:
JPATH_BASE == JPATH_SITE
If you are in the installation application:
JPATH_BASE == JPATH_INSTALLATION.
JPATH_ROOT is the root path for the Joomla install and does not depend upon any application.

" COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_NOTE_CONSTANT_PATHS_LABEL="Constant Paths" COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_NOTNEW_DESCRIPTION="Should file be updated." COM_COMPONENTBUILDER_LIBRARY_FILES_FOLDERS_URLS_NOTNEW_LABEL="Update" @@ -7840,6 +7284,7 @@ COM_COMPONENTBUILDER_LIST_VIEW="List View" COM_COMPONENTBUILDER_LOADING="loading" COM_COMPONENTBUILDER_LOCAL="Local" COM_COMPONENTBUILDER_LOCAL_GET="Local (get)" +COM_COMPONENTBUILDER_LOCAL_POWERS_REPOSITORY_PATH="Local Powers Repository Path" COM_COMPONENTBUILDER_LOCAL_SNIPPET="Local snippet" COM_COMPONENTBUILDER_MAIN_MENU="Main Menu" COM_COMPONENTBUILDER_MAKE_A_DIFFERENCE_WITH_JCB="Make a Difference with JCB" @@ -7875,6 +7320,7 @@ COM_COMPONENTBUILDER_NONE_SELECTED="None selected" COM_COMPONENTBUILDER_NOTICE_BOARD="Notice Board" COM_COMPONENTBUILDER_NOTRANSLATION="no-translation" COM_COMPONENTBUILDER_NOT_FOUND_OR_ACCESS_DENIED="Not found, or access denied." +COM_COMPONENTBUILDER_NOT_SAVED="Not saved!" COM_COMPONENTBUILDER_NOT_SET="not set" COM_COMPONENTBUILDER_NOT_TRANSLATED_IN="Not translated in" COM_COMPONENTBUILDER_NO_ACCESS_GRANTED="No Access Granted!" @@ -7893,8 +7339,11 @@ COM_COMPONENTBUILDER_NO_ITEM_FOUND="No Item Found" COM_COMPONENTBUILDER_NO_KEYS_WERE_FOUND_TO_ADD_AN_EXPORT_KEY_SIMPLY_OPEN_THE_COMPONENT_GO_TO_THE_TAB_CALLED_SETTINGS_BOTTOM_RIGHT_THERE_IS_A_FIELD_CALLED_EXPORT_KEY="No keys were found. To add an export key simply open the component, go to the tab called settings, bottom right there is a field called Export Key." COM_COMPONENTBUILDER_NO_LANGUAGES_FOUND="No Languages Found" COM_COMPONENTBUILDER_NO_LANGUAGES_UPDATE_SERVER_FOUND="No Languages Update server found." +COM_COMPONENTBUILDER_NO_NAMESPACE_FOUND="No Namespace Found" COM_COMPONENTBUILDER_NO_NEED_TO_GET_IT_SINCE_IT_IS_ALREADY_IN_SYNC_WITH_YOUR_LOCAL_VERSION="No need to get it since it is already in sync with your local version" +COM_COMPONENTBUILDER_NO_PATHS_FOUND="No Paths Found" COM_COMPONENTBUILDER_NO_RESULTS_MATCH="No results match" +COM_COMPONENTBUILDER_NO_SELECTION_DETECTED="No selection detected" COM_COMPONENTBUILDER_NO_SNIPPETS_WERE_SELECTED_PLEASE_MAKE_A_SELECTION_AND_TRY_AGAIN="No snippets were selected, please make a selection and try again!" COM_COMPONENTBUILDER_NO_S_FOUND="No %s Found" COM_COMPONENTBUILDER_NO_S_HAVE_BEEN_LINKED_TO_THIS_VIEW_SOON_AS_THIS_IS_DONE_IT_WILL_BE_DISPLAYED_HERE="No %s have been linked to this view. Soon as this is done it will be displayed here." @@ -7925,6 +7374,7 @@ COM_COMPONENTBUILDER_PAIDLOCKED="Paid/Locked" COM_COMPONENTBUILDER_PATH_CODESCODE="Path: %s" COM_COMPONENTBUILDER_PATH_TO_THE_ZIPPED_PACKAGE_IS_CODESCODE_BR_S_S="Path to the zipped package is: %s
%s %s" COM_COMPONENTBUILDER_PERMISSIONS="Permissions" +COM_COMPONENTBUILDER_PFILE_AT_BGITEAREMOTESB_GAVE_THE_FOLLOWING_ERRORBR_SP="

File at gitea.remote/%s gave the following error!
%s

" COM_COMPONENTBUILDER_PLACEHOLDER="Placeholder" COM_COMPONENTBUILDER_PLACEHOLDERS="Placeholders" COM_COMPONENTBUILDER_PLACEHOLDERS_ACCESS="Placeholders Access" @@ -7987,36 +7437,7 @@ COM_COMPONENTBUILDER_PLACEHOLDER_MODIFIED_BY_LABEL="Modified By" COM_COMPONENTBUILDER_PLACEHOLDER_MODIFIED_DATE_DESC="The date this Placeholder was modified." COM_COMPONENTBUILDER_PLACEHOLDER_MODIFIED_DATE_LABEL="Modified Date" COM_COMPONENTBUILDER_PLACEHOLDER_NEW="A New Placeholder" -COM_COMPONENTBUILDER_PLACEHOLDER_NOTE_PLACEHOLDERS_PLACEDIN_DESCRIPTION="" +COM_COMPONENTBUILDER_PLACEHOLDER_NOTE_PLACEHOLDERS_PLACEDIN_DESCRIPTION="" COM_COMPONENTBUILDER_PLACEHOLDER_ORDERING_LABEL="Ordering" COM_COMPONENTBUILDER_PLACEHOLDER_PERMISSION="Permissions" COM_COMPONENTBUILDER_PLACEHOLDER_PUBLISHING="Publishing" @@ -8037,6 +7458,8 @@ COM_COMPONENTBUILDER_PLACES_ACROSS_JCB_WHERE_THIS_S_IS_LINKED="Places across JCB COM_COMPONENTBUILDER_PLEASE_ADD_FILES_TO_S="Please add files to (%s)" COM_COMPONENTBUILDER_PLEASE_ADD_FOLDERS_TO_S="Please add folders to (%s)" COM_COMPONENTBUILDER_PLEASE_CHECK_AGAIN_LATTER="Please check again latter." +COM_COMPONENTBUILDER_PLEASE_CHECK_AGAIN_SOON_ANDOR_FOLLOW_THE_PROGRESS_ON_SGITVDMDEVA="Please check again soon! and/or follow the progress on %sgit.vdm.dev." +COM_COMPONENTBUILDER_PLEASE_FIRST_MAKE_A_SELECTION_FROM_THE_LIST="Please first make a selection from the list." COM_COMPONENTBUILDER_PLEASE_NOTE_THAT_THIS_PACKAGE_BHAS_NOB_CHECKSUM_VALIDATION="Please note that this package has no checksum validation!" COM_COMPONENTBUILDER_PLEASE_SELECT_A_COMPONENT_THAT_YOU_WOULD_LIKE_TO_COMPILE="Please select a component that you would like to compile." COM_COMPONENTBUILDER_PLEASE_TRY_AGAIN_LATER="Please try again later" @@ -8103,16 +7526,13 @@ COM_COMPONENTBUILDER_POWER_ADD_HEAD_DESCRIPTION="You can add your own custom hea COM_COMPONENTBUILDER_POWER_ADD_HEAD_LABEL="Add Custom Class Header" COM_COMPONENTBUILDER_POWER_ADD_LICENSING_TEMPLATE_DESCRIPTION="The option to override the licensing template." COM_COMPONENTBUILDER_POWER_ADD_LICENSING_TEMPLATE_LABEL="Add Licensing Template" +COM_COMPONENTBUILDER_POWER_APPROVED="Approved" +COM_COMPONENTBUILDER_POWER_APPROVED_DESCRIPTION="When you approve a power, it will be added to your local powers folder once linked to a component, and this super power feature is activated. There are two ways to activate this feature, one is in the advanced options on the compiler page, and the other is in the global options of JCB." +COM_COMPONENTBUILDER_POWER_APPROVED_LABEL="Super Power" +COM_COMPONENTBUILDER_POWER_APPROVED_PATHS_DESCRIPTION="Select the paths this power should be added to." +COM_COMPONENTBUILDER_POWER_APPROVED_PATHS_LABEL="Approved Paths" COM_COMPONENTBUILDER_POWER_AS_LABEL="as" -COM_COMPONENTBUILDER_POWER_AUTOLOAD_COMPOSER_NOTE_DESCRIPTION="

Once you have manually pulled composer classes into your own custom folder in libraries area (via composer), you can link it here.

- -

So this feature gives you the ability to add your own custom composer set of classes to your project. Yes, you will still have to manually pull them into your own custom and unique folder into the libraries area of Joomla (on this JCB development system). But you can link it here and JCB will take care of adding it to your component.

- -

First and most importantly (due to obvious risk of collusion), avoid pulling classes into your custom set of composer classes that are already included in the Joomla vendor folder. Those classes that Joomla loads are already available to you. To use them, just add the use Namespace; of that class to the header of this power, and the PHP auto linker will take care of the rest.

- -

So all composer projects =>(vendor folders) has an autoload.php file that is located in the root of the vendor folder. We call this the access point to that cluster of classes. This means you will have one access point for multiple namespaces.

- -

Due the continued risk of collusion we allow only one access point per/power. But for even more peace of mind, it is best to have only one access point per/project. Which means you should try to consolidate your custom composer additional classes (outside of the Joomla vendor folder) into one vendor folder. This will result in one access point, that you will use multiple times for various powers.

" +COM_COMPONENTBUILDER_POWER_AUTOLOAD_COMPOSER_NOTE_DESCRIPTION="

Once you have manually pulled composer classes into your own custom folder in libraries area (via composer), you can link it here.

So this feature gives you the ability to add your own custom composer set of classes to your project. Yes, you will still have to manually pull them into your own custom and unique folder into the libraries area of Joomla (on this JCB development system). But you can link it here and JCB will take care of adding it to your component.

First and most importantly (due to obvious risk of collusion), avoid pulling classes into your custom set of composer classes that are already included in the Joomla vendor folder. Those classes that Joomla loads are already available to you. To use them, just add the use Namespace; of that class to the header of this power, and the PHP auto linker will take care of the rest.

So all composer projects =>(vendor folders) has an autoload.php file that is located in the root of the vendor folder. We call this the access point to that cluster of classes. This means you will have one access point for multiple namespaces.

Due the continued risk of collusion we allow only one access point per/power. But for even more peace of mind, it is best to have only one access point per/project. Which means you should try to consolidate your custom composer additional classes (outside of the Joomla vendor folder) into one vendor folder. This will result in one access point, that you will use multiple times for various powers.

Should you want JCB to load the composer classes to your component, you will have to manually link it to the Component Files & Folders area. This is the best option for now (and will always work), but we will soon improve the Library area in JCB to also take care of PHP libraries. Once this option becomes available we will give notice of the change here.

" COM_COMPONENTBUILDER_POWER_AUTOLOAD_COMPOSER_NOTE_LABEL="When to use Autoloader Composer Powers?" COM_COMPONENTBUILDER_POWER_CLASS="class" COM_COMPONENTBUILDER_POWER_CODE="Code" @@ -8144,22 +7564,16 @@ COM_COMPONENTBUILDER_POWER_IMPLEMENTS_CUSTOM_LABEL="Implements interface(s) - Cu COM_COMPONENTBUILDER_POWER_IMPLEMENTS_CUSTOM_MESSAGE="Error! Please add the custom interface(s) this class must implement." COM_COMPONENTBUILDER_POWER_IMPLEMENTS_DESCRIPTION="The interface(s), this class should implement." COM_COMPONENTBUILDER_POWER_IMPLEMENTS_LABEL="Implements interface(s)" +COM_COMPONENTBUILDER_POWER_INIT_BUTTON_ACCESS="Power Init Button Access" +COM_COMPONENTBUILDER_POWER_INIT_BUTTON_ACCESS_DESC="Allows the users in this group to access the init button." COM_COMPONENTBUILDER_POWER_INTERFACE="interface" +COM_COMPONENTBUILDER_POWER_JOOMLASUPERPOWERS="joomla/super-powers" COM_COMPONENTBUILDER_POWER_LICENSING="Licensing" -COM_COMPONENTBUILDER_POWER_LICENSING_TEMPLATE_HINT="/** - * @package Joomla.Component.Builder - * - * @created 4th September, 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 - */" +COM_COMPONENTBUILDER_POWER_LICENSING_TEMPLATE_HINT="/** * @package Joomla.Component.Builder * * @created 4th September, 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 */" COM_COMPONENTBUILDER_POWER_LICENSING_TEMPLATE_LABEL="Licensing Template" COM_COMPONENTBUILDER_POWER_LOAD="Load" COM_COMPONENTBUILDER_POWER_LOAD_LABEL="load" -COM_COMPONENTBUILDER_POWER_LOAD_POWERS_NOTE_DESCRIPTION="

When you would like to load a power to the project, but you do not want that power to be part of the use namespace declarations in the header of this power.

-

You do not need to again select any power that is already selected in the Extends, Implements, or Use Selection fields, since they are already being loaded.

" +COM_COMPONENTBUILDER_POWER_LOAD_POWERS_NOTE_DESCRIPTION="

When you would like to load a power to the project, but you do not want that power to be part of the use namespace declarations in the header of this power.

You do not need to again select any power that is already selected in the Extends, Implements, or Use Selection fields, since they are already being loaded.

" COM_COMPONENTBUILDER_POWER_LOAD_POWERS_NOTE_LABEL="When to Load Powers Here?" COM_COMPONENTBUILDER_POWER_LOAD_SELECTION_DESCRIPTION="Select powers that you want to make sure also load when this power is loaded." COM_COMPONENTBUILDER_POWER_LOAD_SELECTION_LABEL="Load Powers" @@ -8174,29 +7588,7 @@ COM_COMPONENTBUILDER_POWER_MODIFIED_BY_LABEL="Modified By" COM_COMPONENTBUILDER_POWER_MODIFIED_DATE_DESC="The date this Power was modified." COM_COMPONENTBUILDER_POWER_MODIFIED_DATE_LABEL="Modified Date" COM_COMPONENTBUILDER_POWER_NAMESPACE_DESCRIPTION="Add the namespace of this class." -COM_COMPONENTBUILDER_POWER_NAMESPACE_DETAILS_DESCRIPTION="
-

We will use the namespace value to build the folder structure and filename. This namespace will also directly be used as the use declaration wherever you link this power. Therefore the namespace declared here must end with the filename, and this file name must match the case of the terminating class name.
-Example (namespace): ComponentName\Sub\ClassName
-JCB will build the following file path
-Example (filepath): root/libraries/jcb_powers/ComponentName.Sub/src/ClassName.php
-With a four section namespace
-Example (namespace): ComponentName\Sub\Type\ClassName
-JCB will build the following file path
-Example (filepath): root/libraries/jcb_powers/ComponentName.Sub.Type/src/ClassName.php
-To add a folder inside the src folder use [.] in class name
-Example (namespace): ComponentName\Sub\Util.ClassName
-Example (JCB builds this namespace): ComponentName\Sub\Util\ClassName
-JCB will build the following file path
-Example (filepath): root/libraries/jcb_powers/ComponentName.Sub/src/Util/ClassName.php

- -

The component placeholder also works in namespacing, as well as normal placeholders:
-Example: [[[Component]]]\SubNamespaceNames\ClassName

- -

We will also use the namespacing for auto loading in your project wherever you link this power.

-

The jcb_powers can be changed globally and per/component (soon).
Make your powers load system wide with a plugin (soon).

- -

For more info on how all this works: https://www.php-fig.org/psr/psr-4/

-
" +COM_COMPONENTBUILDER_POWER_NAMESPACE_DETAILS_DESCRIPTION="

We will use the namespace value to build the folder structure and filename. This namespace will also directly be used as the use declaration wherever you link this power. Therefore the namespace declared here must end with the filename, and this file name must match the case of the terminating class name.
Example (namespace): ComponentName\Sub\ClassName
JCB will build the following file path
Example (filepath): root/libraries/jcb_powers/ComponentName.Sub/src/ClassName.php
With a four section namespace
Example (namespace): ComponentName\Sub\Type\ClassName
JCB will build the following file path
Example (filepath): root/libraries/jcb_powers/ComponentName.Sub.Type/src/ClassName.php
To add a folder inside the src folder use [.] in class name
Example (namespace): ComponentName\Sub\Util.ClassName
Example (JCB builds this namespace): ComponentName\Sub\Util\ClassName
JCB will build the following file path
Example (filepath): root/libraries/jcb_powers/ComponentName.Sub/src/Util/ClassName.php

The component placeholder also works in namespacing, as well as normal placeholders:
Example: [[[Component]]]\SubNamespaceNames\ClassName

We will also use the namespacing for auto loading in your project wherever you link this power.

The jcb_powers can be changed globally and per/component (soon).
Make your powers load system wide with a plugin (soon).

For more info on how all this works: https://www.php-fig.org/psr/psr-4/

" COM_COMPONENTBUILDER_POWER_NAMESPACE_DETAILS_LABEL="Namespacing in JCB" COM_COMPONENTBUILDER_POWER_NAMESPACE_HINT="ComponentName\Powers\ClassName" COM_COMPONENTBUILDER_POWER_NAMESPACE_LABEL="Namespace" @@ -8207,8 +7599,11 @@ COM_COMPONENTBUILDER_POWER_NAME_LABEL="Name" COM_COMPONENTBUILDER_POWER_NAME_MESSAGE="Error! Please add name here." COM_COMPONENTBUILDER_POWER_NEW="A New Power" COM_COMPONENTBUILDER_POWER_NO="No" +COM_COMPONENTBUILDER_POWER_NOTE_APPROVED_PATHS_DESCRIPTION="

Select the sub paths inside the local path where you would like to add this power. The default is the core JCB path which is joomla/super-powers (this can be changed in the global options)

To set the local path, and to add more sub paths, open the JCB global options, and look for the super power tab, there you will find all the instructions needed.

" +COM_COMPONENTBUILDER_POWER_NOTE_APPROVED_PATHS_LABEL="Super Powers Repositories" COM_COMPONENTBUILDER_POWER_NOTE_LINKED_TO_NOTICE_DESCRIPTION="
Searching the database.
" COM_COMPONENTBUILDER_POWER_NOTE_LINKED_TO_NOTICE_LABEL="Linked To" +COM_COMPONENTBUILDER_POWER_NOT_APPROVED="Not Approved" COM_COMPONENTBUILDER_POWER_NOT_REQUIRED="Not Required" COM_COMPONENTBUILDER_POWER_ORDERING_LABEL="Ordering" COM_COMPONENTBUILDER_POWER_OVERRIDE="Override" @@ -8222,10 +7617,15 @@ COM_COMPONENTBUILDER_POWER_PROPERTY_LABEL="Properties" COM_COMPONENTBUILDER_POWER_PROPERTY_SELECTION_DESCRIPTION="Select properties you want to use in your power." COM_COMPONENTBUILDER_POWER_PROPERTY_SELECTION_LABEL="Property Selection" COM_COMPONENTBUILDER_POWER_PUBLISHING="Publishing" +COM_COMPONENTBUILDER_POWER_RESET_BUTTON_ACCESS="Power Reset Button Access" +COM_COMPONENTBUILDER_POWER_RESET_BUTTON_ACCESS_DESC="Allows the users in this group to access the reset button." COM_COMPONENTBUILDER_POWER_RUN_EXPANSION_BUTTON_ACCESS="Power Run Expansion Button Access" COM_COMPONENTBUILDER_POWER_RUN_EXPANSION_BUTTON_ACCESS_DESC="Allows the users in this group to access the run expansion button." COM_COMPONENTBUILDER_POWER_SAVE_WARNING="Alias already existed so a number was added at the end. You can re-edit the Power to customise the alias." COM_COMPONENTBUILDER_POWER_STATUS="Status" +COM_COMPONENTBUILDER_POWER_SUPER_POWER="Super Power" +COM_COMPONENTBUILDER_POWER_SYNC_BUTTON_ACCESS="Power Sync Button Access" +COM_COMPONENTBUILDER_POWER_SYNC_BUTTON_ACCESS_DESC="Allows the users in this group to access the sync button." COM_COMPONENTBUILDER_POWER_SYSTEM_NAME_DESCRIPTION="Used only in the system." COM_COMPONENTBUILDER_POWER_SYSTEM_NAME_HINT="The System Name Here" COM_COMPONENTBUILDER_POWER_SYSTEM_NAME_LABEL="System Name" @@ -8250,6 +7650,7 @@ COM_COMPONENTBUILDER_PROPERTY="Property" COM_COMPONENTBUILDER_PROPERTY_ALREADY_SELECTED_TRY_ANOTHER="Property already selected, try another." COM_COMPONENTBUILDER_PROPERTY_NAME="Property Name" COM_COMPONENTBUILDER_PROPERTY_VALUE="Property Value" +COM_COMPONENTBUILDER_PSUPER_POWERB_REPOSITORY_AT_BGITVDMDEVSB_GAVE_THE_FOLLOWING_ERRORBR_SP="

Super Power repository at git.vdm.dev/%s gave the following error!
%s

" COM_COMPONENTBUILDER_PS_NAMING_MISMATCH_ERROR_SPPTHE_S_NAME_IS_BSB_AND_THE_ENDING_FILE_NAME_IN_THE_NAMESPACE_IS_BSB_THIS_IS_BAD_CONVENTION_PLEASE_SEE_A_HREFS_PSRFOURA_FOR_MORE_INFOPPA_HREFSCLICK_HEREA_TO_FIX_THIS_ISSUEP="

%s naming mismatch error (%s)

The %s name is %s and the ending file name in the namespace is %s. This is bad convention, please see psr-4 for more info.

Click here to fix this issue.

" COM_COMPONENTBUILDER_PUBLIC_ACCESS="Public Access" COM_COMPONENTBUILDER_PUBLISHED="Published" @@ -8268,6 +7669,7 @@ 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." COM_COMPONENTBUILDER_REQUIRES_THE_VALUE_TO_BE_THE_SAME_AS_THAT_HELD_IN_THE_FIELD_NAMED_QUOTFIELDQUOT_EGS="Requires the value to be the same as that held in the field named "field", eg:%s" +COM_COMPONENTBUILDER_RESET="Reset" COM_COMPONENTBUILDER_REVERT_ALL_AHEAD_SNIPPETS="Revert All Ahead Snippets" COM_COMPONENTBUILDER_RIGHT_IN_TAB="Right in Tab" COM_COMPONENTBUILDER_RIGHT_OF_TABS="Right of Tabs" @@ -8298,6 +7700,8 @@ COM_COMPONENTBUILDER_SELECTION="selection" COM_COMPONENTBUILDER_SELECT_ADMIN_VIEW="Select Admin View" COM_COMPONENTBUILDER_SELECT_AN_ADMIN_VIEW="Select an admin view" COM_COMPONENTBUILDER_SELECT_AN_OPTION="Select an option" +COM_COMPONENTBUILDER_SELECT_APPROVED_PATH="Select Approved Path" +COM_COMPONENTBUILDER_SELECT_A_NAMESPACE="Select a Namespace" COM_COMPONENTBUILDER_SELECT_A_PROPERTY="Select a property" COM_COMPONENTBUILDER_SELECT_A_SITE_VIEW="Select a site view" COM_COMPONENTBUILDER_SELECT_A_SNIPPET="select a snippet" @@ -8409,21 +7813,7 @@ COM_COMPONENTBUILDER_SERVER_PRIVATE_DESCRIPTION="Set the path to the private key COM_COMPONENTBUILDER_SERVER_PRIVATE_HINT="/home/username/.ssh/id_rsa" COM_COMPONENTBUILDER_SERVER_PRIVATE_KEY_DESCRIPTION="Add your private key here! Yes this field is encrypted in the DB, but if your DB gets compromised this key must also be considered compromised! The system path option is considered more secure and seen as best practice." COM_COMPONENTBUILDER_SERVER_PRIVATE_KEY_FILE_PATH="Private Key - File Path" -COM_COMPONENTBUILDER_SERVER_PRIVATE_KEY_HINT="-----BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQDPF9uyDuHtD+sCYBaEIV34uAc+eRa62souVUcmsVwKUUBbk7sY -bnO6ixjouEbhis1L4m854895tJ99SSPu5cXxYTFimCJDjp47fjro4x8js9em10kK -VCP2fP60/jO+mTruGc25C1SksMtRj5XlsGW3avoOV2RjsqAwKxhk6AUF6QIDAQAB -AoGAYGGlMOB2S2NeJ7PaptH0rz3OuUeXyYzsDdZIj/x5bp/UCQrfR4aYO9hi1mR1 -MKDt3QRcaZ/ZvrXOiHuSyquLjG0R1tVVR+OZE+haBSunUUq05ZFT7zUJRPHVKoSK -QOV/c831tCA5gCUupXiaak/vYMZRf+xs9wHDyuZstEoU8tUCQQD/GGV/8cuiYQK4 -MlpXgvOeYEYayhbQ80qe2aVolQIlRXyY6N9dV1lfbUO8rlTJ2EDVOFc8NDkPHf2f -xzbplDCDAkEAz9PhT8ji8fJgKuDAhWDXF0TuwVWk2hjtYCVGsksE3w16lv9OCwoK -UuWOY2b7wEYh0y8Z9AKBDHM1xhS8Bl7MIwJBANAkNd1Zi5Aom7Fz1GcHQIR/hXQi -ZM+FU+OdLuvQeXmz4uBZUre0qAXG/7gafrBbNTtEx1kmO1BsZh9Syyl3csUCQQDF -MD4pm2tpMRV52YIRi07J70ex/PbLULd5cCTh6jgXAwz71AVSiBY/jTtKqV3YkzJo -09oGIZIcI/wzk1zLloqNAkB8qHxAtmUZFdo5sssaUDTOB82QAPfiHUqIFPaYuc0f -4NqtXZm+fv4liR3QJEo8zkiBs3NjBnm7Hh3BMSqGh3d+ ------END RSA PRIVATE KEY-----" +COM_COMPONENTBUILDER_SERVER_PRIVATE_KEY_HINT="-----BEGIN RSA PRIVATE KEY-----MIICXQIBAAKBgQDPF9uyDuHtD+sCYBaEIV34uAc+eRa62souVUcmsVwKUUBbk7sYbnO6ixjouEbhis1L4m854895tJ99SSPu5cXxYTFimCJDjp47fjro4x8js9em10kKVCP2fP60/jO+mTruGc25C1SksMtRj5XlsGW3avoOV2RjsqAwKxhk6AUF6QIDAQABAoGAYGGlMOB2S2NeJ7PaptH0rz3OuUeXyYzsDdZIj/x5bp/UCQrfR4aYO9hi1mR1MKDt3QRcaZ/ZvrXOiHuSyquLjG0R1tVVR+OZE+haBSunUUq05ZFT7zUJRPHVKoSKQOV/c831tCA5gCUupXiaak/vYMZRf+xs9wHDyuZstEoU8tUCQQD/GGV/8cuiYQK4MlpXgvOeYEYayhbQ80qe2aVolQIlRXyY6N9dV1lfbUO8rlTJ2EDVOFc8NDkPHf2fxzbplDCDAkEAz9PhT8ji8fJgKuDAhWDXF0TuwVWk2hjtYCVGsksE3w16lv9OCwoKUuWOY2b7wEYh0y8Z9AKBDHM1xhS8Bl7MIwJBANAkNd1Zi5Aom7Fz1GcHQIR/hXQiZM+FU+OdLuvQeXmz4uBZUre0qAXG/7gafrBbNTtEx1kmO1BsZh9Syyl3csUCQQDFMD4pm2tpMRV52YIRi07J70ex/PbLULd5cCTh6jgXAwz71AVSiBY/jTtKqV3YkzJo09oGIZIcI/wzk1zLloqNAkB8qHxAtmUZFdo5sssaUDTOB82QAPfiHUqIFPaYuc0f4NqtXZm+fv4liR3QJEo8zkiBs3NjBnm7Hh3BMSqGh3d+-----END RSA PRIVATE KEY-----" COM_COMPONENTBUILDER_SERVER_PRIVATE_KEY_LABEL="PRIVATE KEY
(encrypted field)" COM_COMPONENTBUILDER_SERVER_PRIVATE_KEY_TEXT_FIELD="Private Key - Text Field" COM_COMPONENTBUILDER_SERVER_PRIVATE_LABEL="Private Key Path
(encrypted field)" @@ -8589,8 +7979,7 @@ COM_COMPONENTBUILDER_SITE_VIEW_CLOCK="Clock" COM_COMPONENTBUILDER_SITE_VIEW_CMD="CMD" COM_COMPONENTBUILDER_SITE_VIEW_CODENAME_DESCRIPTION="Add Name in Code Here" COM_COMPONENTBUILDER_SITE_VIEW_CODENAME_HINT="codename" -COM_COMPONENTBUILDER_SITE_VIEW_CODENAME_LABEL="Name in Code
-Naming Conventions" +COM_COMPONENTBUILDER_SITE_VIEW_CODENAME_LABEL="Name in Code
Naming Conventions" COM_COMPONENTBUILDER_SITE_VIEW_CODENAME_MESSAGE="Error! Please add name in code here." COM_COMPONENTBUILDER_SITE_VIEW_COG="Cog" COM_COMPONENTBUILDER_SITE_VIEW_COGS="Cogs" @@ -8748,10 +8137,7 @@ COM_COMPONENTBUILDER_SITE_VIEW_NEW_TAB_2="New Tab 2" COM_COMPONENTBUILDER_SITE_VIEW_NEXT="Next" COM_COMPONENTBUILDER_SITE_VIEW_NO="No" COM_COMPONENTBUILDER_SITE_VIEW_NONE="None" -COM_COMPONENTBUILDER_SITE_VIEW_NOTE_ADD_PHP_LANGUAGE_STRING_DESCRIPTION="<?php echo JText::_('Text'); ?>
-<?php echo JText::sprintf('Hello %s', $this->user->name); ?>
-Just get UPPERCASE language string:
-<?php echo JustTEXT::_('Text'); ?>" +COM_COMPONENTBUILDER_SITE_VIEW_NOTE_ADD_PHP_LANGUAGE_STRING_DESCRIPTION="<?php echo JText::_('Text'); ?>
<?php echo JText::sprintf('Hello %s', $this->user->name); ?>
Just get UPPERCASE language string:
<?php echo JustTEXT::_('Text'); ?>" COM_COMPONENTBUILDER_SITE_VIEW_NOTE_ADD_PHP_LANGUAGE_STRING_LABEL="Add PHP Language String" COM_COMPONENTBUILDER_SITE_VIEW_NOTE_CUSTOM_TOOLBAR_PLACEHOLDER_DESCRIPTION="Use this placeholder in the body [[[SITE_TOOLBAR]]] to add the custom position of the toolbar." COM_COMPONENTBUILDER_SITE_VIEW_NOTE_LIBRARIES_SELECTION_DESCRIPTION="All libraries you select will dynamically be added to the header of the page according to the settings of the selected library. Each library will also get its respective buttons added to the component global options if it has any set. Please take a look at the libraries for more details." @@ -9126,8 +8512,10 @@ COM_COMPONENTBUILDER_SUBMENU_TEMPLATES="Templates" COM_COMPONENTBUILDER_SUBMENU_VALIDATION_RULES="Validation Rules" COM_COMPONENTBUILDER_SUCCESS_THE_SNIPPET_WAS_SAVED="Success! The snippet was saved." COM_COMPONENTBUILDER_SUCCESS_THE_SNIPPET_WAS_SAVED_BUT_THE_MODIFIED_DATE_COULD_NOT_BE_ADJUSTED_BR_BR_BTHIS_MEANS_THE_SNIPPETS_WILL_CONTINUE_TO_APPEAR_OUT_OF_DATEB="Success! The snippet was saved. But the modified date could not be adjusted.

This means the snippets will continue to appear out of date." +COM_COMPONENTBUILDER_SUPER_POWER="Super Power" COM_COMPONENTBUILDER_SUPPORT_JCB_TODAY="Support JCB Today" COM_COMPONENTBUILDER_SUPPORT_JOOMLA_COMPONENT_BUILDER_JCB_WITH_A_BFINANCIAL_DONATIONB_TO_SHOW_GRATITUDE_FOR_THE_TIME_AND_EFFORT_SAVED_IN_YOUR_DEVELOPMENT_PROCESS_YOUR_CONTRIBUTION_NO_MATTER_THE_SIZE_WILL_BE_APPRECIATED_BY_THE_PROJECTS_TEAM_AND_THE_WIDER_COMMUNITY_HELP_ENSURE_THE_GROWTH_AND_RELEVANCE_OF_THIS_ESSENTIAL_TOOL="Support Joomla Component Builder (JCB) with a financial donation to show gratitude for the time and effort saved in your development process. Your contribution, no matter the size, will be appreciated by the project's team and the wider community. Help ensure the growth and relevance of this essential tool." +COM_COMPONENTBUILDER_SYNC="Sync" COM_COMPONENTBUILDER_SZIP_COULD_NOT_BE_INSTALLED="%s.zip could not be installed!" COM_COMPONENTBUILDER_SZIP_WAS_REMOVED_THE_FROM_TMP_FOLDER_DURING_INSTALLATION="%s.zip was removed the from tmp folder during installation!" COM_COMPONENTBUILDER_S_BEING_IMPORTED="%s Being Imported" @@ -9234,10 +8622,7 @@ COM_COMPONENTBUILDER_TEMPLATE_NAME_LABEL="Name" COM_COMPONENTBUILDER_TEMPLATE_NAME_MESSAGE="Error! Please add name here." COM_COMPONENTBUILDER_TEMPLATE_NEW="A New Template" COM_COMPONENTBUILDER_TEMPLATE_NO="No" -COM_COMPONENTBUILDER_TEMPLATE_NOTE_ADD_PHP_LANGUAGE_STRING_DESCRIPTION="<?php echo JText::_('Text'); ?>
-<?php echo JText::sprintf('Hello %s', $this->user->name); ?>
-Just get UPPERCASE language string:
-<?php echo JustTEXT::_('Text'); ?>" +COM_COMPONENTBUILDER_TEMPLATE_NOTE_ADD_PHP_LANGUAGE_STRING_DESCRIPTION="<?php echo JText::_('Text'); ?>
<?php echo JText::sprintf('Hello %s', $this->user->name); ?>
Just get UPPERCASE language string:
<?php echo JustTEXT::_('Text'); ?>" COM_COMPONENTBUILDER_TEMPLATE_NOTE_ADD_PHP_LANGUAGE_STRING_LABEL="Add PHP Language String" COM_COMPONENTBUILDER_TEMPLATE_NOTE_LIBRARIES_SELECTION_DESCRIPTION="All libraries you select will dynamically be added to the header of the page according to the settings of the selected library. Each library will also get its respective buttons added to the component global options if it has any set. Please take a look at the libraries for more details." COM_COMPONENTBUILDER_TEMPLATE_NOTE_LIBRARIES_SELECTION_LABEL="Select libraries you would like to use in your code" @@ -9344,12 +8729,16 @@ COM_COMPONENTBUILDER_THE_URL_S_SET_TO_RETRIEVE_THE_PACKAGES_DOES_NOT_EXIST="The COM_COMPONENTBUILDER_THE_URL_S_SET_TO_RETRIEVE_THE_PACKAGES_DOES_NOT_RETURN_ANY_DATA="The url (%s) set to retrieve the packages does not return any data!" COM_COMPONENTBUILDER_THE_WIKI_CAN_ONLY_BE_LOADED_WHEN_YOUR_JCB_SYSTEM_HAS_INTERNET_CONNECTION="The wiki can only be loaded when your JCB system has internet connection." COM_COMPONENTBUILDER_THE_WIKI_IS_LOADING="The wiki is loading" +COM_COMPONENTBUILDER_THIS_ADDS_POWERS_TO_A_LOCAL_REPOSITORY_FOLDER_ALL_BAPPROVEDB_POWERS_LINKED_TO_THIS_COMPONENT_WILL_BE_MOVED_TO_YOUR_BLOCALB_POWERS_REPOSITORY_FOLDER_INTO_THEIR_SELECTIVE_TARGET_PATHS_THIS_LOCAL_FOLDER_PATH_MUST_BE_SET_IN_THE_GLOBAL_OPTIONS_OF_JCB_UNDER_THE_BSUPER_POWERB_TAB="This adds powers to a local repository folder. All approved powers, linked to this component, will be moved to your local powers repository folder into their selective target paths. This local folder path must be set in the global options of JCB under the super power tab." COM_COMPONENTBUILDER_THIS_BSB_IS_NOT_LINKED_TO_ANY_OTHER_AREAS_OF_JCB_AT_THIS_TIME="This %s is not linked to any other areas of JCB at this time!" COM_COMPONENTBUILDER_THIS_CAN_NOT_BE_UNDONE_ARE_YOU_SURE_YOU_WANT_TO_CONTINUE="This can not be undone, are you sure you want to continue?" COM_COMPONENTBUILDER_THIS_CAN_NOT_BE_UNDONE_BYOU_HAVE_BEEN_WARNEDB="This can not be undone, you have been warned!" +COM_COMPONENTBUILDER_THIS_INIT_FEATURE_IS_STILL_UNDER_DEVELOPMENT="This (init) feature is still under development!" COM_COMPONENTBUILDER_THIS_MAY_TAKE_A_WHILE_DEPENDING_ON_THE_SIZE_OF_YOUR_PROJECT="This may take a while depending on the size of your project." COM_COMPONENTBUILDER_THIS_PACKAGE_BPASSEDB_THE_CHECKSUM_VALIDATIONBR_BR_SMALLMANUALLY_ALSO_VALIDATE_THAT_THE_CORRECT_CHECKSUM_WAS_USEDSMALLBR_THIS_CHECKSUM_BSB_MUST_BE_THE_SAME_AS_THE_ONE_FOUND_A_S_SA="This package PASSED the checksum validation!

Manually also validate that the correct checksum was used.
This checksum: %s must be the same as the one found @ " COM_COMPONENTBUILDER_THIS_PACKAGE_HAS_NO_KEY="This package has no key." +COM_COMPONENTBUILDER_THIS_RESET_FEATURE_IS_STILL_UNDER_DEVELOPMENT="This (reset) feature is still under development!" +COM_COMPONENTBUILDER_THIS_SYNC_FEATURE_IS_STILL_UNDER_DEVELOPMENT="This (sync) feature is still under development!" COM_COMPONENTBUILDER_TITLE="Title" COM_COMPONENTBUILDER_TO_ADD_SIMPLY_COPY_AND_PAST_THE_SNIPPET_INTO_YOUR_CODE="To add simply copy and past the snippet into your code." COM_COMPONENTBUILDER_TO_ADD_VALIDATION_TO_A_FIELD_IF_VALIDATION_IS_NOT_PART_OF_FIELD_TYPE_PROPERTIES_LOADED_ABOVE_SO_IF_YOU_HAVE_VALIDATION_SET_AS_A_FIELD_PROPERTY_THIS_EXTRA_PROPERTY_WILL_NOT_BE_NEEDED="To add validation to a field if validation is not part of field type properties loaded above. So if you have validation set as a field property this extra property will not be needed." @@ -9582,6 +8971,7 @@ COM_COMPONENTBUILDER_YOU_MUST_ADD_AN_UNIQUE_FUNCTION_NAME="You must add an uniqu COM_COMPONENTBUILDER_YOU_MUST_ADD_AN_UNIQUE_PLACEHOLDER="You must add an unique placeholder." COM_COMPONENTBUILDER_YOU_MUST_ADD_AN_UNIQUE_VALIDATION_RULE_NAME="You must add an unique validation rule name." COM_COMPONENTBUILDER_YOU_MUST_FIRST_LINK_AN_ADMIN_OR_A_CUSTOM_ADMIN_VIEW_TO_THIS_COMPONENT_THEN_YOU_CAN_SELECT_IT_HERE="You must first link an admin or a custom admin view to this component, then you can select it here" +COM_COMPONENTBUILDER_YOU_MUST_FIRST_SAVE_THE_POWER_BEFORE_YOU_CAN_USE_THIS_FEATURE="You must first save the power, before you can use this feature." COM_COMPONENTBUILDER_YOU_MUST_SELECT_A_COMPONENT="You must select a component!" COM_COMPONENTBUILDER_YOU_SHOULD_ADD_THE_CORRECT_OWNER_DETAILS="You should add the correct owner details." COM_COMPONENTBUILDER_YOU_SHOULD_ONLY_CONTINUE_THIS_IMPORT_IF_YOU_HAVE_BACKUP_YOUR_COMPONENTS_AND_INSURED_THAT_THE_PACKAGE_OWNER_IS_REPUTABLE="You should only continue this import if you have backup your components, and insured that the package owner is reputable." diff --git a/admin/language/en-GB/en-GB.com_componentbuilder.sys.ini b/admin/language/en-GB/en-GB.com_componentbuilder.sys.ini index 67be6ab55..d846592bc 100644 --- a/admin/language/en-GB/en-GB.com_componentbuilder.sys.ini +++ b/admin/language/en-GB/en-GB.com_componentbuilder.sys.ini @@ -1012,8 +1012,14 @@ COM_COMPONENTBUILDER_POWERS_EDIT_VERSION="Powers Edit Version" COM_COMPONENTBUILDER_POWERS_EDIT_VERSION_DESC="Allows users in this group to edit versions of version powers" COM_COMPONENTBUILDER_POWERS_SUBMENU="Powers Submenu" COM_COMPONENTBUILDER_POWERS_SUBMENU_DESC="Allows the users in this group to submenu of power" +COM_COMPONENTBUILDER_POWER_INIT_BUTTON_ACCESS="Power Init Button Access" +COM_COMPONENTBUILDER_POWER_INIT_BUTTON_ACCESS_DESC="Allows the users in this group to access the init button." +COM_COMPONENTBUILDER_POWER_RESET_BUTTON_ACCESS="Power Reset Button Access" +COM_COMPONENTBUILDER_POWER_RESET_BUTTON_ACCESS_DESC="Allows the users in this group to access the reset button." COM_COMPONENTBUILDER_POWER_RUN_EXPANSION_BUTTON_ACCESS="Power Run Expansion Button Access" COM_COMPONENTBUILDER_POWER_RUN_EXPANSION_BUTTON_ACCESS_DESC="Allows the users in this group to access the run expansion button." +COM_COMPONENTBUILDER_POWER_SYNC_BUTTON_ACCESS="Power Sync Button Access" +COM_COMPONENTBUILDER_POWER_SYNC_BUTTON_ACCESS_DESC="Allows the users in this group to access the sync button." COM_COMPONENTBUILDER_SEARCH_ACCESS="Search Access" COM_COMPONENTBUILDER_SEARCH_ACCESS_DESC="Allows the users in this group to access search." COM_COMPONENTBUILDER_SEARCH_COMPILER_BUTTON_ACCESS="Search Compiler Button Access" diff --git a/admin/layouts/jcbsupportmessage.php b/admin/layouts/jcbsupportmessage.php index 4b78bce9e..1aaa5a707 100644 --- a/admin/layouts/jcbsupportmessage.php +++ b/admin/layouts/jcbsupportmessage.php @@ -12,7 +12,7 @@ // No direct access to this file defined('JPATH_BASE') or die('Restricted access'); -// Different support requests/appreciation +// Different support requests/appreciation $support = [ JText::_("COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BUILDER_JCB_IS_A_CRUCIAL_TOOL_FOR_PHP_PROGRAMMERS_WHO_USE_JOOMLA_TO_EARN_A_LIVING_BY_MAKING_A_BFINANCIAL_DONATIONB_YOU_CAN_SUPPORT_THE_GROWTH_AND_CONTINUITY_OF_THIS_VITAL_RESOURCE_AND_ENSURE_ITS_RELEVANCE_FOR_YEARS_TO_COME_YOUR_CONTRIBUTION_NO_MATTER_HOW_BIG_OR_SMALL_WILL_BE_DEEPLY_APPRECIATED_BY_THE_PROJECTS_TEAM_AND_THE_WIDER_COMMUNITY"), JText::_("COM_COMPONENTBUILDER_THE_CONTINUED_SUPPORT_OF_INDIVIDUALS_LIKE_YOU_HAS_ALLOWED_JOOMLA_COMPONENT_BUILDER_JCB_TO_THRIVE_FOR_SEVEN_YEARS_SINCE_GOING_PUBLIC_YOUR_CONTRIBUTIONS_HAVE_BEEN_CRUCIAL_IN_ENSURING_THE_GROWTH_AND_RELEVANCE_OF_THIS_VITAL_TOOL_FOR_PHP_PROGRAMMERS_THANK_YOU_FOR_YOUR_SUPPORT_AND_FOR_BEING_A_PART_OF_JCBS_JOURNEY"), diff --git a/admin/layouts/power/super_power_left.php b/admin/layouts/power/super_power_left.php new file mode 100644 index 000000000..8b1e5cc6c --- /dev/null +++ b/admin/layouts/power/super_power_left.php @@ -0,0 +1,43 @@ + + * @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 + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +// get the form +$form = $displayData->getForm(); + +// get the layout fields override method name (from layout path/ID) +$layout_path_array = explode('.', $this->getLayoutId()); +// Since we cannot pass the layout and tab names as parameters to the model method +// this name combination of tab and layout in the method name is the only work around +// seeing that JCB uses those two values (tab_name & layout_name) as the layout file name. +// example of layout name: details_left.php +// example of method name: getFields_details_left() +$fields_tab_layout = 'fields_' . $layout_path_array[1]; + +// get the fields +$fields = $displayData->get($fields_tab_layout) ?: array( + 'approved', + 'approved_paths' +); + +$hiddenFields = $displayData->get('hidden_fields') ?: array(); + +?> + + + + setFieldAttribute($field, 'type', 'hidden'); ?> + + renderField($field, null, null, array('class' => 'control-wrapper-' . $field)); ?> + + diff --git a/admin/layouts/power/super_power_right.php b/admin/layouts/power/super_power_right.php new file mode 100644 index 000000000..e0dac78ab --- /dev/null +++ b/admin/layouts/power/super_power_right.php @@ -0,0 +1,42 @@ + + * @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 + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +// get the form +$form = $displayData->getForm(); + +// get the layout fields override method name (from layout path/ID) +$layout_path_array = explode('.', $this->getLayoutId()); +// Since we cannot pass the layout and tab names as parameters to the model method +// this name combination of tab and layout in the method name is the only work around +// seeing that JCB uses those two values (tab_name & layout_name) as the layout file name. +// example of layout name: details_left.php +// example of method name: getFields_details_left() +$fields_tab_layout = 'fields_' . $layout_path_array[1]; + +// get the fields +$fields = $displayData->get($fields_tab_layout) ?: array( + 'note_approved_paths' +); + +$hiddenFields = $displayData->get('hidden_fields') ?: array(); + +?> + + + + setFieldAttribute($field, 'type', 'hidden'); ?> + + renderField($field, null, null, array('class' => 'control-wrapper-' . $field)); ?> + + diff --git a/admin/models/admin_views.php b/admin/models/admin_views.php index 6c5fee144..769b01965 100644 --- a/admin/models/admin_views.php +++ b/admin/models/admin_views.php @@ -14,6 +14,8 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Utilities\FilterHelper as JCBFilterHelper; +use VDM\Joomla\Componentbuilder\Utilities\FormHelper as JCBFormHelper; /** * Admin_views List Model @@ -70,7 +72,7 @@ class ComponentbuilderModelAdmin_views extends ListModel '' => '- ' . JText::_('COM_COMPONENTBUILDER_NO_COMPONENTS_FOUND') . ' -' ); // check if we have joomla components - if (($joomla_components = ComponentbuilderHelper::getByTypeTheIdsSystemNames('joomla_component')) !== false) + if (($joomla_components = JCBFilterHelper::names('joomla_component')) !== null) { $options = array( '' => '- ' . JText::_('COM_COMPONENTBUILDER_SELECT_COMPONENT') . ' -' @@ -79,7 +81,7 @@ class ComponentbuilderModelAdmin_views extends ListModel $options = $options + $joomla_components; } - $form->setField(ComponentbuilderHelper::getFieldXML($attributes, $options),'filter'); + $form->setField(JCBFormHelper::xml($attributes, $options),'filter'); $form->setValue( 'joomla_component', 'filter', @@ -88,7 +90,8 @@ class ComponentbuilderModelAdmin_views extends ListModel array_push($this->filter_fields, 'joomla_component'); return $form; - } + } + /** * Method to auto-populate the model state. @@ -354,7 +357,7 @@ class ComponentbuilderModelAdmin_views extends ListModel $filter_joomla_component = $this->state->get("filter.joomla_component"); if ($filter_joomla_component !== null && !empty($filter_joomla_component)) { - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($filter_joomla_component, 'joomla_component_admin_views')) !== false) + if (($ids = JCBFilterHelper::linked((int) $filter_joomla_component, 'joomla_component_admin_views')) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); } @@ -589,7 +592,7 @@ class ComponentbuilderModelAdmin_views extends ListModel $filter_joomla_component = $this->state->get("filter.joomla_component"); if ($filter_joomla_component !== null && !empty($filter_joomla_component)) { - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($filter_joomla_component, 'joomla_component_admin_views')) !== false) + if (($ids = JCBFilterHelper::linked((int) $filter_joomla_component, 'joomla_component_admin_views')) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); } diff --git a/admin/models/ajax.php b/admin/models/ajax.php index 5f53d5e5b..55d0ff96a 100644 --- a/admin/models/ajax.php +++ b/admin/models/ajax.php @@ -14,7 +14,7 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; -use VDM\Gitea\Gitea; +use VDM\Joomla\Gitea\Factory as GiteaFactory; use VDM\Joomla\Componentbuilder\Package\Factory as PackageFactory; use VDM\Joomla\Utilities\FileHelper; use VDM\Joomla\Utilities\JsonHelper; @@ -175,11 +175,18 @@ class ComponentbuilderModelAjax extends ListModel // check if url exist if ($info = FileHelper::getContent($url, false)) { - if ((($info_ = PackageFactory::_('Crypt')->decrypt($info, 'local')) !== null && JsonHelper::check($info_)) || - (($info_ = PackageFactory::_('Crypt')->decrypt($info, 'local.legacy')) !== null && JsonHelper::check($info_)) || - (($info_ = PackageFactory::_('Crypt')->decrypt($info, 'local.fof')) !== null && JsonHelper::check($info_))) + $_info = PackageFactory::_('Crypt')->decrypt($info, 'local.legacy'); + + // check if we had success + if (!JsonHelper::check($_info)) { - $info = json_decode($info_, true); + $_info = PackageFactory::_('Crypt')->decrypt($info, 'local.fof'); + } + + // check if we have json + if (JsonHelper::check($_info)) + { + $info = json_decode($_info, true); return [ 'owner' => PackageFactory::_('Display.Details')->owner($info, true), @@ -268,25 +275,16 @@ class ComponentbuilderModelAjax extends ListModel public function getWiki($name = 'Home') { - // get the token if set - $token = JComponentHelper::getParams('com_componentbuilder')->get('gitea_token', false); - - // setup a registry - $options = new Registry; - - // only add if token is set - if ($token) - { - $options->set('access.token', $token); - } - try { - // get gitea object - $gitea = new Gitea($options); + // load the API details + GiteaFactory::_('Gitea.Repository.Wiki')->load_('https://git.vdm.dev', ''); - // get the gitea wiki page TODO: we hard coded the page name - $page = $gitea->repo->wiki->getHtml('joomla', 'Component-Builder', 'Home'); + // get the gitea wiki page im markdown + $wiki = GiteaFactory::_('Gitea.Repository.Wiki')->get('joomla', 'Component-Builder', 'Home'); + + // now render the page in HTML + $page = GiteaFactory::_('Gitea.Miscellaneous.Markdown')->render($wiki->content, true); } catch (DomainException $e) { @@ -323,20 +321,18 @@ class ComponentbuilderModelAjax extends ListModel public function getVersion($version = null) { // get the token if set - $token = JComponentHelper::getParams('com_componentbuilder')->get('gitea_token', false); + $token = $this->app_params->get('gitea_token', false); + // only add if token is set if ($token) { - // setup a registry - $options = new Registry; - $options->set('access.token', $token); - // get the gitea http try { - // get gitea object - $gitea = new Gitea($options); - // get a list of all the repos tags - $tags = $gitea->repo->getListTags('joomla', 'Component-Builder'); + // load the API details + GiteaFactory::_('Gitea.Repository.Tags')->load_('https://git.vdm.dev', $token); + + // get the repository tags + $tags = GiteaFactory::_('Gitea.Repository.Tags')->list('joomla', 'Component-Builder'); } catch (DomainException $e) { diff --git a/admin/models/componentbuilder.php b/admin/models/componentbuilder.php index ff134f1e4..5dc5edac9 100644 --- a/admin/models/componentbuilder.php +++ b/admin/models/componentbuilder.php @@ -14,7 +14,6 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; -use VDM\Gitea\Gitea; use Joomla\Registry\Registry; /** diff --git a/admin/models/custom_admin_views.php b/admin/models/custom_admin_views.php index 59ad7188a..858694392 100644 --- a/admin/models/custom_admin_views.php +++ b/admin/models/custom_admin_views.php @@ -14,6 +14,8 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Utilities\FormHelper as JCBFormHelper; +use VDM\Joomla\Componentbuilder\Utilities\FilterHelper as JCBFilterHelper; /** * Custom_admin_views List Model @@ -68,7 +70,7 @@ class ComponentbuilderModelCustom_admin_views extends ListModel '' => '- ' . JText::_('COM_COMPONENTBUILDER_NO_COMPONENTS_FOUND') . ' -' ); // check if we have joomla components - if (($joomla_components = ComponentbuilderHelper::getByTypeTheIdsSystemNames('joomla_component')) !== false) + if (($joomla_components = JCBFilterHelper::names('joomla_component')) !== null) { $options = array( '' => '- ' . JText::_('COM_COMPONENTBUILDER_SELECT_COMPONENT') . ' -' @@ -77,7 +79,7 @@ class ComponentbuilderModelCustom_admin_views extends ListModel $options = $options + $joomla_components; } - $form->setField(ComponentbuilderHelper::getFieldXML($attributes, $options),'filter'); + $form->setField(JCBFormHelper::xml($attributes, $options),'filter'); $form->setValue( 'joomla_component', 'filter', @@ -293,7 +295,7 @@ class ComponentbuilderModelCustom_admin_views extends ListModel $filter_joomla_component = $this->state->get("filter.joomla_component"); if ($filter_joomla_component !== null && !empty($filter_joomla_component)) { - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($filter_joomla_component, 'joomla_component_custom_admin_views')) !== false) + if (($ids = JCBFilterHelper::linked((int) $filter_joomla_component, 'joomla_component_custom_admin_views')) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); } @@ -498,7 +500,7 @@ class ComponentbuilderModelCustom_admin_views extends ListModel $filter_joomla_component = $this->state->get("filter.joomla_component"); if ($filter_joomla_component !== null && !empty($filter_joomla_component)) { - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($filter_joomla_component, 'joomla_component_custom_admin_views')) !== false) + if (($ids = JCBFilterHelper::linked((int) $filter_joomla_component, 'joomla_component_custom_admin_views')) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); } diff --git a/admin/models/fields.php b/admin/models/fields.php index 36c670a60..b0b693373 100644 --- a/admin/models/fields.php +++ b/admin/models/fields.php @@ -14,6 +14,8 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Utilities\FormHelper as JCBFormHelper; +use VDM\Joomla\Componentbuilder\Utilities\FilterHelper as JCBFilterHelper; /** * Fields List Model @@ -63,7 +65,7 @@ class ComponentbuilderModelFields extends ListModel // Create the "extension" filter $form->setField(new SimpleXMLElement( - ComponentbuilderHelper::getExtensionGroupedListXml() + JCBFilterHelper::extensions() ),'filter'); $form->setValue( 'extension', @@ -82,7 +84,7 @@ class ComponentbuilderModelFields extends ListModel '' => '- ' . JText::_('COM_COMPONENTBUILDER_NO_ADMIN_VIEWS_FOUND') . ' -' ); // check if we have admin views (and limit to an extension if it is set) - if (($admin_views = ComponentbuilderHelper::getByTypeTheIdsSystemNames('admin_view', $this->state->get("filter.extension"))) !== false) + if (($admin_views = JCBFilterHelper::names('admin_view', $this->state->get("filter.extension"))) !== null) { $options = array( '' => '- ' . JText::_('COM_COMPONENTBUILDER_SELECT_ADMIN_VIEW') . ' -' @@ -91,7 +93,7 @@ class ComponentbuilderModelFields extends ListModel $options = $options + $admin_views; } - $form->setField(ComponentbuilderHelper::getFieldXML($attributes, $options),'filter'); + $form->setField(JCBFormHelper::xml($attributes, $options),'filter'); $form->setValue( 'admin_view', 'filter', @@ -100,7 +102,8 @@ class ComponentbuilderModelFields extends ListModel array_push($this->filter_fields, 'admin_view'); return $form; - } + } + /** * Method to auto-populate the model state. @@ -379,7 +382,7 @@ class ComponentbuilderModelFields extends ListModel { // column name, and id $type_extension = explode('__', $filter_extension); - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($type_extension[1], $type_extension[0])) !== false) + if (($ids = JCBFilterHelper::linked((int) $type_extension[1], (string) $type_extension[0])) !== null) { $field_ids = $ids; } @@ -395,7 +398,7 @@ class ComponentbuilderModelFields extends ListModel $filter_admin_view = $this->state->get("filter.admin_view"); if ($get_ids && $filter_admin_view !== null && !empty($filter_admin_view)) { - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($filter_admin_view, 'admin_view')) !== false) + if (($ids = JCBFilterHelper::linked((int) $filter_admin_view, 'admin_view')) !== null) { // view will return less fields, so we ignore the component $field_ids = $ids; @@ -644,7 +647,7 @@ class ComponentbuilderModelFields extends ListModel { // column name, and id $type_extension = explode('__', $filter_extension); - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($type_extension[1], $type_extension[0])) !== false) + if (($ids = JCBFilterHelper::linked((int) $type_extension[1], (string) $type_extension[0])) !== null) { $field_ids = $ids; } @@ -660,7 +663,7 @@ class ComponentbuilderModelFields extends ListModel $filter_admin_view = $this->state->get("filter.admin_view"); if ($get_ids && $filter_admin_view !== null && !empty($filter_admin_view)) { - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($filter_admin_view, 'admin_view')) !== false) + if (($ids = JCBFilterHelper::linked((int) $filter_admin_view, 'admin_view')) !== null) { // view will return less fields, so we ignore the component $field_ids = $ids; diff --git a/admin/models/fields/powersfilterpowerversion.php b/admin/models/fields/powersfilterapproved.php similarity index 63% rename from admin/models/fields/powersfilterpowerversion.php rename to admin/models/fields/powersfilterapproved.php index e594e102d..0cafe0ce7 100644 --- a/admin/models/fields/powersfilterpowerversion.php +++ b/admin/models/fields/powersfilterapproved.php @@ -17,16 +17,16 @@ jimport('joomla.form.helper'); JFormHelper::loadFieldClass('list'); /** - * Powersfilterpowerversion Form Field class for the Componentbuilder component + * Powersfilterapproved Form Field class for the Componentbuilder component */ -class JFormFieldPowersfilterpowerversion extends JFormFieldList +class JFormFieldPowersfilterapproved extends JFormFieldList { /** - * The powersfilterpowerversion field type. + * The powersfilterapproved field type. * * @var string */ - public $type = 'powersfilterpowerversion'; + public $type = 'powersfilterapproved'; /** * Method to get a list of options for a list input. @@ -42,24 +42,28 @@ class JFormFieldPowersfilterpowerversion extends JFormFieldList $query = $db->getQuery(true); // Select the text. - $query->select($db->quoteName('power_version')); + $query->select($db->quoteName('approved')); $query->from($db->quoteName('#__componentbuilder_power')); - $query->order($db->quoteName('power_version') . ' ASC'); + $query->order($db->quoteName('approved') . ' ASC'); // Reset the query using our newly populated query object. $db->setQuery($query); $results = $db->loadColumn(); $_filter = array(); - $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_VERSION') . ' -'); + $_filter[] = JHtml::_('select.option', '', '- ' . JText::_('COM_COMPONENTBUILDER_FILTER_SELECT_SUPER_POWER') . ' -'); if ($results) { + // get powersmodel + $model = ComponentbuilderHelper::getModel('powers'); $results = array_unique($results); - foreach ($results as $power_version) + foreach ($results as $approved) { - // Now add the power_version and its text to the options array - $_filter[] = JHtml::_('select.option', $power_version, $power_version); + // Translate the approved selection + $text = $model->selectionTranslation($approved,'approved'); + // Now add the approved and its text to the options array + $_filter[] = JHtml::_('select.option', $approved, JText::_($text)); } } return $_filter; diff --git a/admin/models/fields/superpowerpaths.php b/admin/models/fields/superpowerpaths.php new file mode 100644 index 000000000..4f44dfe94 --- /dev/null +++ b/admin/models/fields/superpowerpaths.php @@ -0,0 +1,100 @@ + + * @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 + */ + +// No direct access to this file +defined('_JEXEC') or die('Restricted access'); + +// Import the checkboxes field type classes needed + +JFormHelper::loadFieldClass('checkboxes'); +use VDM\Joomla\Utilities\Component\Helper; + +/** + * Superpowerpaths Form Field class for the Componentbuilder component + */ +class JFormFieldSuperpowerpaths extends JFormFieldCheckboxes +{ + /** + * The superpowerpaths field type. + * + * @var string + */ + public $type = 'superpowerpaths'; + + // A DynamicCheckboxes@ Field + + /** + * Method to get the data to be passed to the layout for rendering. + * + * @return array + * + * @since 3.5 + */ + protected function getLayoutData() + { + $data = parent::getLayoutData(); + + // True if the field has 'value' set. In other words, it has been stored, don't use the default values. + $hasValue = (isset($this->value) && !empty($this->value)); + + // If a value has been stored, use it. Otherwise, use the defaults. + $checkedOptions = $hasValue ? $this->value : $this->checkedOptions; + + // get the form options + $options = []; + + // get the component params + $params = Helper::getParams(); + $activate = $params->get('super_powers_repositories', 0); + + // set the default + $default = $params->get('super_powers_core', 'joomla/super-powers'); + + // must have one / in the path + if (strpos($default, '/') !== false) + { + $tmp = new stdClass; + $tmp->text = $tmp->value = trim($default); + $tmp->checked = false; + $options[$tmp->value] = $tmp; + } + + if ($activate == 1) + { + $subform = $params->get($this->fieldname); + + // add the paths found in global settings + if (is_object($subform)) + { + foreach ($subform as $value) + { + if (isset($value->owner) && strlen($value->owner) > 1 && + isset($value->repo) && strlen($value->repo) > 1) + { + $tmp = new stdClass; + $tmp->text = $tmp->value = trim($value->owner) . '/' . trim($value->repo); + $tmp->checked = false; + + $options[$tmp->value] = $tmp; + } + } + } + } + + $extraData = array( + 'checkedOptions' => is_array($checkedOptions) ? $checkedOptions : explode(',', (string) $checkedOptions), + 'hasValue' => $hasValue, + 'options' => array_values($options) + ); + + return array_merge($data, $extraData); + } +} diff --git a/admin/models/fieldtype.php b/admin/models/fieldtype.php index e10d23415..b33b2c2a3 100644 --- a/admin/models/fieldtype.php +++ b/admin/models/fieldtype.php @@ -271,7 +271,7 @@ class ComponentbuilderModelFieldtype extends AdminModel { // column name, and id $type_extension = explode('__', $filter_extension); - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($type_extension[1], $type_extension[0])) !== false) + if (($ids = JCBFilterHelper::linked((int) $type_extension[1], (string) $type_extension[0])) !== null) { $field_ids = $ids; } @@ -287,7 +287,7 @@ class ComponentbuilderModelFieldtype extends AdminModel $filter_admin_view = $this->state->get("filter.admin_view"); if ($get_ids && $filter_admin_view !== null && !empty($filter_admin_view)) { - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($filter_admin_view, 'admin_view')) !== false) + if (($ids = JCBFilterHelper::linked((int) $filter_admin_view, 'admin_view')) !== null) { // view will return less fields, so we ignore the component $field_ids = $ids; diff --git a/admin/models/forms/filter_admin_views.xml b/admin/models/forms/filter_admin_views.xml index 57794b43e..b188dcca1 100644 --- a/admin/models/forms/filter_admin_views.xml +++ b/admin/models/forms/filter_admin_views.xml @@ -86,8 +86,8 @@ - - + + diff --git a/admin/models/forms/filter_joomla_components.xml b/admin/models/forms/filter_joomla_components.xml index 74fd0fc2d..e1d29ea4b 100644 --- a/admin/models/forms/filter_joomla_components.xml +++ b/admin/models/forms/filter_joomla_components.xml @@ -66,8 +66,8 @@ - - + + diff --git a/admin/models/forms/filter_powers.xml b/admin/models/forms/filter_powers.xml index 6571e0783..173808595 100644 --- a/admin/models/forms/filter_powers.xml +++ b/admin/models/forms/filter_powers.xml @@ -39,16 +39,9 @@ onchange="this.form.submit();" /> - diff --git a/admin/models/forms/power.xml b/admin/models/forms/power.xml index f8a8058d1..d553af000 100644 --- a/admin/models/forms/power.xml +++ b/admin/models/forms/power.xml @@ -159,6 +159,38 @@ message="COM_COMPONENTBUILDER_POWER_POWER_VERSION_MESSAGE" hint="COM_COMPONENTBUILDER_POWER_POWER_VERSION_HINT" /> + + + + + - - - - + + + + + + + + + + + + + + COM_COMPONENTBUILDER_POWER_NO + + - - - - - - - - - - - @@ -413,8 +428,18 @@ required="false" validate="code" /> - - + + + + + - - - - - - + + + + + + + + + + app->enqueueMessage(Text::_('COM_COMPONENTBUILDER_HTWOWE_COULD_NOT_OPEN_THE_ENCRYPT_DATAHTWO_THIS_COULD_BE_DUE_TO_THE_FOFENCRYPTION_THAT_IS_NO_LONGER_SUPPORTED_IN_JOOMLABR_PLEASE_EXPORT_YOUR_PACKAGES_WITH_JCB_VTHREEONEONENINE_OR_HIGHER_TO_BE_ABLE_TO_IMPORT_IT_INTO_THIS_VERSION_OF_JCB'), 'error'); + $this->app->enqueueMessage(Text::_('COM_COMPONENTBUILDER_HTWOWE_COULD_NOT_OPEN_THE_ENCRYPT_DATAHTWO_THIS_COULD_BE_DUE_TO_THE_FOFENCRYPTION_THAT_IS_NO_LONGER_SUPPORTED_IN_JOOMLABR_PLEASE_EXPORT_YOUR_PACKAGES_WITH_JCB_VTHREEONEONEEIGHT_OR_HIGHER_TO_BE_ABLE_TO_IMPORT_IT_INTO_THIS_VERSION_OF_JCB'), 'error'); } else { diff --git a/admin/models/language_translations.php b/admin/models/language_translations.php index 13bdfcc66..b4aceafdd 100644 --- a/admin/models/language_translations.php +++ b/admin/models/language_translations.php @@ -14,6 +14,8 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Utilities\FormHelper as JCBFormHelper; +use VDM\Joomla\Componentbuilder\Utilities\FilterHelper as JCBFilterHelper; /** * Language_translations List Model @@ -55,7 +57,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel // Create the "extension" filter $form->setField(new SimpleXMLElement( - ComponentbuilderHelper::getExtensionGroupedListXml() + JCBFilterHelper::extensions() ),'filter'); $form->setValue( 'extension', @@ -75,7 +77,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel '' => '- ' . JText::_('COM_COMPONENTBUILDER_NO_LANGUAGES_FOUND') . ' -' ); // check if we have languages set - if (($languages = ComponentbuilderHelper::getAvailableLanguages()) !== false) + if (($languages = JCBFilterHelper::languages()) !== null) { $options = array( '' => '- ' . JText::_('COM_COMPONENTBUILDER_TRANSLATED_IN') . ' -', @@ -85,7 +87,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel $options = array_merge($options, $languages); } - $form->setField(ComponentbuilderHelper::getFieldXML($attributes, $options),'filter'); + $form->setField(JCBFormHelper::xml($attributes, $options),'filter'); $form->setValue( 'translated', 'filter', @@ -114,7 +116,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel $options = array_merge($options, $languages); } - $form->setField(ComponentbuilderHelper::getFieldXML($attributes, $options),'filter'); + $form->setField(JCBFormHelper::xml($attributes, $options),'filter'); $form->setValue( 'not_translated', 'filter', @@ -300,7 +302,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel $filter_translated = $this->state->get("filter.translated"); if ($filter_translated !== null && !empty($filter_translated)) { - if (($ids = ComponentbuilderHelper::getTranslationIds($filter_translated)) !== false) + if (($ids = JCBFilterHelper::translations($filter_translated)) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); } @@ -315,7 +317,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel $filter_not_translated = $this->state->get("filter.not_translated"); if ($filter_not_translated !== null && !empty($filter_not_translated)) { - if (($ids = ComponentbuilderHelper::getTranslationIds($filter_not_translated, false)) !== false) + if (($ids = JCBFilterHelper::translations($filter_not_translated, false)) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',',$ids) . ')'); } @@ -332,7 +334,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel { // column name, and id $type_extension = explode('__', $filter_extension); - if (($ids = ComponentbuilderHelper::getTranslationExtensionsIds($type_extension[1], $type_extension[0])) !== false) + if (($ids = JCBFilterHelper::translation((int) $type_extension[1], $type_extension[0])) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); } @@ -459,7 +461,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel $filter_translated = $this->state->get("filter.translated"); if ($filter_translated !== null && !empty($filter_translated)) { - if (($ids = ComponentbuilderHelper::getTranslationIds($filter_translated)) !== false) + if (($ids = JCBFilterHelper::translations($filter_translated)) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); } @@ -474,7 +476,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel $filter_not_translated = $this->state->get("filter.not_translated"); if ($filter_not_translated !== null && !empty($filter_not_translated)) { - if (($ids = ComponentbuilderHelper::getTranslationIds($filter_not_translated, false)) !== false) + if (($ids = JCBFilterHelper::translations($filter_not_translated, false)) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',',$ids) . ')'); } @@ -491,7 +493,7 @@ class ComponentbuilderModelLanguage_translations extends ListModel { // column name, and id $type_extension = explode('__', $filter_extension); - if (($ids = ComponentbuilderHelper::getTranslationExtensionsIds($type_extension[1], $type_extension[0])) !== false) + if (($ids = JCBFilterHelper::translation((int) $type_extension[1], $type_extension[0])) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); } diff --git a/admin/models/power.php b/admin/models/power.php index 9a1942045..d005d0f8b 100644 --- a/admin/models/power.php +++ b/admin/models/power.php @@ -16,6 +16,9 @@ use Joomla\CMS\MVC\Model\AdminModel; use Joomla\Registry\Registry; use Joomla\String\StringHelper; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\String\ClassfunctionHelper; +use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper; +use VDM\Joomla\Utilities\GetHelper; /** * Componentbuilder Power Admin Model @@ -65,6 +68,15 @@ class ComponentbuilderModelPower extends AdminModel 'licensing_template' ) ), + 'super_power' => array( + 'left' => array( + 'approved', + 'approved_paths' + ), + 'right' => array( + 'note_approved_paths' + ) + ), 'composer' => array( 'fullwidth' => array( 'autoload_composer_note', @@ -202,6 +214,14 @@ class ComponentbuilderModelPower extends AdminModel $item->main_class_code = base64_decode($item->main_class_code); } + if (!empty($item->method_selection)) + { + // Convert the method_selection field to an array. + $method_selection = new Registry; + $method_selection->loadString($item->method_selection); + $item->method_selection = $method_selection->toArray(); + } + if (!empty($item->load_selection)) { // Convert the load_selection field to an array. @@ -234,14 +254,6 @@ class ComponentbuilderModelPower extends AdminModel $item->implements = $implements->toArray(); } - if (!empty($item->method_selection)) - { - // Convert the method_selection field to an array. - $method_selection = new Registry; - $method_selection->loadString($item->method_selection); - $item->method_selection = $method_selection->toArray(); - } - if (!empty($item->use_selection)) { // Convert the use_selection field to an array. @@ -250,6 +262,12 @@ class ComponentbuilderModelPower extends AdminModel $item->use_selection = $use_selection->toArray(); } + if (!empty($item->approved_paths)) + { + // JSON Decode approved_paths. + $item->approved_paths = json_decode($item->approved_paths); + } + if (empty($item->id)) { @@ -1003,24 +1021,30 @@ class ComponentbuilderModelPower extends AdminModel $data['metadata'] = (string) $metadata; } + // Set the empty approved_paths item to data + if (!isset($data['approved_paths'])) + { + $data['approved_paths'] = ''; + } + // check if the name has placeholder if (strpos($data['name'], '[[[') === false && strpos($data['name'], '###') === false) { // make sure the name is safe to be used as a function name - $data['name'] = ComponentbuilderHelper::safeClassFunctionName($data['name']); + $data['name'] = ClassfunctionHelper::safe($data['name']); } // if system name is empty create from name - if (empty($data['system_name']) || !ComponentbuilderHelper::checkString($data['system_name'])) + if (empty($data['system_name']) || !UtilitiesStringHelper::check($data['system_name'])) { $data['system_name'] = $data['name']; } // must set the version if empty - if (empty($data['power_version']) && $data['id'] > 0 && ($power_version = ComponentbuilderHelper::getVar('power', $data['id'], 'id', 'power_version')) !== false) + if (empty($data['power_version']) && $data['id'] > 0 && ($power_version = GetHelper::var('power', $data['id'], 'id', 'power_version')) !== false) { $data['power_version'] = $power_version; } // we must preserve versions (so that a change to the version number must result in save as copy) - elseif ($data['id'] > 0 && ($old_version = ComponentbuilderHelper::getVar('power', $data['id'], 'id', 'power_version')) && $data['power_version'] != $old_version) + elseif ($data['id'] > 0 && ($old_version = GetHelper::var('power', $data['id'], 'id', 'power_version')) && $data['power_version'] != $old_version) { // lets check if we already have this version if (($existing_id = ComponentbuilderHelper::checkExist('power', ['power_version' => $data['power_version'], 'name' => $data['name'], 'namespace' => $data['namespace']])) !== false) @@ -1051,6 +1075,19 @@ class ComponentbuilderModelPower extends AdminModel } + // Set the method_selection items to data. + if (isset($data['method_selection']) && is_array($data['method_selection'])) + { + $method_selection = new JRegistry; + $method_selection->loadArray($data['method_selection']); + $data['method_selection'] = (string) $method_selection; + } + elseif (!isset($data['method_selection'])) + { + // Set the empty method_selection to data + $data['method_selection'] = ''; + } + // Set the load_selection items to data. if (isset($data['load_selection']) && is_array($data['load_selection'])) { @@ -1103,19 +1140,6 @@ class ComponentbuilderModelPower extends AdminModel $data['implements'] = ''; } - // Set the method_selection items to data. - if (isset($data['method_selection']) && is_array($data['method_selection'])) - { - $method_selection = new JRegistry; - $method_selection->loadArray($data['method_selection']); - $data['method_selection'] = (string) $method_selection; - } - elseif (!isset($data['method_selection'])) - { - // Set the empty method_selection to data - $data['method_selection'] = ''; - } - // Set the use_selection items to data. if (isset($data['use_selection']) && is_array($data['use_selection'])) { @@ -1129,6 +1153,12 @@ class ComponentbuilderModelPower extends AdminModel $data['use_selection'] = ''; } + // Set the approved_paths string to JSON string. + if (isset($data['approved_paths'])) + { + $data['approved_paths'] = (string) json_encode($data['approved_paths']); + } + // Set the licensing_template string to base64 string. if (isset($data['licensing_template'])) { diff --git a/admin/models/powers.php b/admin/models/powers.php index ddeb3149d..03ec428ea 100644 --- a/admin/models/powers.php +++ b/admin/models/powers.php @@ -14,6 +14,9 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\Component\Helper as JCBHelper; +use VDM\Joomla\Componentbuilder\Utilities\FilterHelper as JCBFilterHelper; +use VDM\Joomla\Componentbuilder\Utilities\FormHelper as JCBFormHelper; /** * Powers List Model @@ -32,16 +35,123 @@ class ComponentbuilderModelPowers extends ListModel 'a.created_by','created_by', 'a.modified_by','modified_by', 'a.type','type', - 'a.power_version','power_version', - 'h.name','extends', + 'a.approved','approved', 'a.system_name','system_name', - 'a.namespace','namespace' + 'a.namespace','namespace', + 'a.power_version','power_version' ); } parent::__construct($config); } + /** + * Get the filter form - Override the parent method + * + * @param array $data data + * @param boolean $loadData load current data + * + * @return \JForm|boolean The \JForm object or false on error + * + * @since JCB 2.12.5 + */ + public function getFilterForm($data = array(), $loadData = true) + { + // load form from the parent class + $form = parent::getFilterForm($data, $loadData); + + // Create the "admin_view" filter + $attributes = array( + 'name' => 'namegroup', + 'type' => 'list', + 'onchange' => 'this.form.submit();', + ); + $options = array( + '' => '- ' . JText::_('COM_COMPONENTBUILDER_NO_NAMESPACE_FOUND') . ' -' + ); + // check if we have namespace (and limit to an extension if it is set) + if (($namespaces = JCBFilterHelper::namespaces()) !== null) + { + $options = array( + '' => '- ' . JText::_('COM_COMPONENTBUILDER_SELECT_A_NAMESPACE') . ' -' + ); + // make sure we do not lose the key values in normal merge + $options = $options + $namespaces; + } + + $form->setField(JCBFormHelper::xml($attributes, $options),'filter'); + $form->setValue( + 'namegroup', + 'filter', + $this->state->get("filter.namegroup") + ); + array_push($this->filter_fields, 'namegroup'); + + // get the component params + $params = JCBHelper::getParams(); + $activate = $params->get('super_powers_repositories', 0); + if ($activate == 1) + { + $subform = $params->get('approved_paths', null); + + // create approved paths filter + $attributes = array( + 'name' => 'approved_paths', + 'type' => 'list', + 'onchange' => 'this.form.submit();', + ); + $options = array( + '' => '- ' . JText::_('COM_COMPONENTBUILDER_NO_PATHS_FOUND') . ' -' + ); + + // add the paths found in global settings + if (is_object($subform)) + { + $core = $params->get('super_powers_core', 'joomla/super-powers'); + + $options = array( + '' => '- ' . JText::_('COM_COMPONENTBUILDER_SELECT_APPROVED_PATH') . ' -', + $core => $core + ); + + foreach ($subform as $value) + { + if (isset($value->owner) && strlen($value->owner) > 1 && + isset($value->repo) && strlen($value->repo) > 1) + { + $value = trim($value->owner) . '/' . trim($value->repo); + + $options[$value] = $value; + } + } + } + + $form->setField(JCBFormHelper::xml($attributes, $options), 'filter'); + $form->setValue( + 'approved_paths', + 'filter', + $this->state->get("filter.approved_paths") + ); + array_push($this->filter_fields, 'approved_paths'); + } + + return $form; + } + + /** + * Check if a power can be used in linking + * + * @param string $type the type of power + * + * @return bool + * @since JCB 3.1.23 + */ + protected function isSuperPower(string $type): bool + { + return in_array($type, ['class', 'abstract class', 'final class', 'trait']); + } + + /** * Method to auto-populate the model state. * @@ -95,18 +205,11 @@ class ComponentbuilderModelPowers extends ListModel $this->setState('filter.type', $type); } - $power_version = $this->getUserStateFromRequest($this->context . '.filter.power_version', 'filter_power_version'); + $approved = $this->getUserStateFromRequest($this->context . '.filter.approved', 'filter_approved'); if ($formSubmited) { - $power_version = $app->input->post->get('power_version'); - $this->setState('filter.power_version', $power_version); - } - - $extends = $this->getUserStateFromRequest($this->context . '.filter.extends', 'filter_extends'); - if ($formSubmited) - { - $extends = $app->input->post->get('extends'); - $this->setState('filter.extends', $extends); + $approved = $app->input->post->get('approved'); + $this->setState('filter.approved', $approved); } $system_name = $this->getUserStateFromRequest($this->context . '.filter.system_name', 'filter_system_name'); @@ -123,6 +226,13 @@ class ComponentbuilderModelPowers extends ListModel $this->setState('filter.namespace', $namespace); } + $power_version = $this->getUserStateFromRequest($this->context . '.filter.power_version', 'filter_power_version'); + if ($formSubmited) + { + $power_version = $app->input->post->get('power_version'); + $this->setState('filter.power_version', $power_version); + } + // List state information. parent::populateState($ordering, $direction); } @@ -158,6 +268,11 @@ class ComponentbuilderModelPowers extends ListModel continue; } + // create the GUID placeholder key + if ($this->isSuperPower($item->type)) + { + $item->super_power_key = 'Super_'.'_'.'_' . str_replace('-', '_', $item->guid) . '_'.'_'.'_Power'; + } // remove dots $item->namespace = str_replace('.','\\', $item->namespace); } @@ -170,6 +285,8 @@ class ComponentbuilderModelPowers extends ListModel { // convert type $item->type = $this->selectionTranslation($item->type, 'type'); + // convert approved + $item->approved = $this->selectionTranslation($item->approved, 'approved'); } } @@ -201,6 +318,19 @@ class ComponentbuilderModelPowers extends ListModel return $typeArray[$value]; } } + // Array of approved language strings + if ($name === 'approved') + { + $approvedArray = array( + 0 => 'COM_COMPONENTBUILDER_POWER_NOT_APPROVED', + 1 => 'COM_COMPONENTBUILDER_POWER_APPROVED' + ); + // Now check if value is found in this array + if (isset($approvedArray[$value]) && ComponentbuilderHelper::checkString($approvedArray[$value])) + { + return $approvedArray[$value]; + } + } return $value; } @@ -223,9 +353,43 @@ class ComponentbuilderModelPowers extends ListModel // From the componentbuilder_item table $query->from($db->quoteName('#__componentbuilder_power', 'a')); + // do not use these filters in the export method + if (!isset($_export) || !$_export) + { + // Filtering "namegroup" + $filter_namegroup = $this->state->get("filter.namegroup"); + if ($filter_namegroup !== null && !empty($filter_namegroup)) + { + if (($ids = JCBFilterHelper::namegroup($filter_namegroup)) !== null) + { + $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); + } + else + { + // there is none + $query->where($db->quoteName('a.id') . ' = ' . 0); + } + } + + // Filtering "approved paths" + $filter_approved_paths = $this->state->get("filter.approved_paths"); + if ($filter_approved_paths !== null && !empty($filter_approved_paths)) + { + if (($ids = JCBFilterHelper::paths($filter_approved_paths)) !== null) + { + $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); + } + else + { + // there is none + $query->where($db->quoteName('a.id') . ' = ' . 0); + } + } + } + // From the componentbuilder_power table. - $query->select($db->quoteName(['h.name','h.id'],['extends_name','extends_id'])); - $query->join('LEFT', $db->quoteName('#__componentbuilder_power', 'h') . ' ON (' . $db->quoteName('a.extends') . ' = ' . $db->quoteName('h.guid') . ')'); + $query->select($db->quoteName(['g.name','g.id'],['extends_name','extends_id'])); + $query->join('LEFT', $db->quoteName('#__componentbuilder_power', 'g') . ' ON (' . $db->quoteName('a.extends') . ' = ' . $db->quoteName('g.guid') . ')'); // Filter by published state $published = $this->getState('filter.published'); @@ -271,7 +435,7 @@ class ComponentbuilderModelPowers extends ListModel else { $search = $db->quote('%' . $db->escape($search) . '%'); - $query->where('(a.system_name LIKE '.$search.' OR a.type LIKE '.$search.' OR a.description LIKE '.$search.' OR a.extends_custom LIKE '.$search.' OR a.extends LIKE '.$search.' OR a.guid LIKE '.$search.' OR a.name LIKE '.$search.')'); + $query->where('(a.system_name LIKE '.$search.' OR a.type LIKE '.$search.' OR a.description LIKE '.$search.' OR a.extends LIKE '.$search.' OR a.extends_custom LIKE '.$search.' OR a.approved_paths LIKE '.$search.' OR a.guid LIKE '.$search.' OR a.name LIKE '.$search.')'); } } @@ -315,39 +479,22 @@ class ComponentbuilderModelPowers extends ListModel // Filter by the Type Array. $query->where('a.type IN (' . implode(',', $_type) . ')'); } - // Filter by Power_version. - $_power_version = $this->getState('filter.power_version'); - if (is_numeric($_power_version)) + // Filter by Approved. + $_approved = $this->getState('filter.approved'); + if (is_numeric($_approved)) { - if (is_float($_power_version)) + if (is_float($_approved)) { - $query->where('a.power_version = ' . (float) $_power_version); + $query->where('a.approved = ' . (float) $_approved); } else { - $query->where('a.power_version = ' . (int) $_power_version); + $query->where('a.approved = ' . (int) $_approved); } } - elseif (ComponentbuilderHelper::checkString($_power_version)) + elseif (ComponentbuilderHelper::checkString($_approved)) { - $query->where('a.power_version = ' . $db->quote($db->escape($_power_version))); - } - // Filter by Extends. - $_extends = $this->getState('filter.extends'); - if (is_numeric($_extends)) - { - if (is_float($_extends)) - { - $query->where('a.extends = ' . (float) $_extends); - } - else - { - $query->where('a.extends = ' . (int) $_extends); - } - } - elseif (ComponentbuilderHelper::checkString($_extends)) - { - $query->where('a.extends = ' . $db->quote($db->escape($_extends))); + $query->where('a.approved = ' . $db->quote($db->escape($_approved))); } // Add the list ordering clause. @@ -400,10 +547,10 @@ class ComponentbuilderModelPowers extends ListModel { $id .= ':' . $_type; } - $id .= ':' . $this->getState('filter.power_version'); - $id .= ':' . $this->getState('filter.extends'); + $id .= ':' . $this->getState('filter.approved'); $id .= ':' . $this->getState('filter.system_name'); $id .= ':' . $this->getState('filter.namespace'); + $id .= ':' . $this->getState('filter.power_version'); return parent::getStoreId($id); } diff --git a/admin/models/site_views.php b/admin/models/site_views.php index 5294f6603..1f636d217 100644 --- a/admin/models/site_views.php +++ b/admin/models/site_views.php @@ -14,6 +14,8 @@ defined('_JEXEC') or die('Restricted access'); use Joomla\CMS\MVC\Model\ListModel; use Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Componentbuilder\Utilities\FormHelper as JCBFormHelper; +use VDM\Joomla\Componentbuilder\Utilities\FilterHelper as JCBFilterHelper; /** * Site_views List Model @@ -69,7 +71,7 @@ class ComponentbuilderModelSite_views extends ListModel '' => '- ' . JText::_('COM_COMPONENTBUILDER_NO_COMPONENTS_FOUND') . ' -' ); // check if we have joomla components - if (($joomla_components = ComponentbuilderHelper::getByTypeTheIdsSystemNames('joomla_component')) !== false) + if (($joomla_components = JCBFilterHelper::names('joomla_component')) !== null) { $options = array( '' => '- ' . JText::_('COM_COMPONENTBUILDER_SELECT_COMPONENT') . ' -' @@ -78,7 +80,7 @@ class ComponentbuilderModelSite_views extends ListModel $options = $options + $joomla_components; } - $form->setField(ComponentbuilderHelper::getFieldXML($attributes, $options),'filter'); + $form->setField(JCBFormHelper::xml($attributes, $options),'filter'); $form->setValue( 'joomla_component', 'filter', @@ -301,7 +303,7 @@ class ComponentbuilderModelSite_views extends ListModel $filter_joomla_component = $this->state->get("filter.joomla_component"); if ($filter_joomla_component !== null && !empty($filter_joomla_component)) { - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($filter_joomla_component, 'joomla_component_site_views')) !== false) + if (($ids = JCBFilterHelper::linked((int) $filter_joomla_component, 'joomla_component_site_views')) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); } @@ -506,7 +508,7 @@ class ComponentbuilderModelSite_views extends ListModel $filter_joomla_component = $this->state->get("filter.joomla_component"); if ($filter_joomla_component !== null && !empty($filter_joomla_component)) { - if (($ids = ComponentbuilderHelper::getAreaLinkedIDs($filter_joomla_component, 'joomla_component_site_views')) !== false) + if (($ids = JCBFilterHelper::linked((int) $filter_joomla_component, 'joomla_component_site_views')) !== null) { $query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')'); } diff --git a/admin/sql/install.mysql.utf8.sql b/admin/sql/install.mysql.utf8.sql index 5621ae02c..1c589d42e 100644 --- a/admin/sql/install.mysql.utf8.sql +++ b/admin/sql/install.mysql.utf8.sql @@ -314,6 +314,8 @@ CREATE TABLE IF NOT EXISTS `#__componentbuilder_power` ( `asset_id` INT(10) unsigned NOT NULL DEFAULT 0 COMMENT 'FK to the #__assets table.', `add_head` TINYINT(1) NOT NULL DEFAULT 0, `add_licensing_template` TINYINT(1) NOT NULL DEFAULT 1, + `approved` TINYINT(1) NOT NULL DEFAULT 0, + `approved_paths` TEXT NOT NULL, `composer` TEXT NOT NULL, `description` TEXT NOT NULL, `extends` VARCHAR(36) NOT NULL DEFAULT '', @@ -349,8 +351,8 @@ CREATE TABLE IF NOT EXISTS `#__componentbuilder_power` ( KEY `idx_system_name` (`system_name`), KEY `idx_namespace` (`namespace`), KEY `idx_type` (`type`), - KEY `idx_implements_custom` (`implements_custom`), KEY `idx_extends_custom` (`extends_custom`), + KEY `idx_implements_custom` (`implements_custom`), KEY `idx_add_licensing_template` (`add_licensing_template`), KEY `idx_guid` (`guid`), KEY `idx_name` (`name`), @@ -1966,38 +1968,6 @@ CREATE TABLE IF NOT EXISTS `#__componentbuilder_joomla_plugin_files_folders_urls INSERT INTO `#__componentbuilder_joomla_component` (`id`, `add_license`, `license_type`, `mvc_versiondate`, `add_css_admin`, `add_css_site`, `add_email_helper`, `add_javascript`, `add_php_helper_admin`, `add_php_helper_both`, `add_php_helper_site`, `add_php_postflight_install`, `add_php_method_uninstall`, `add_php_postflight_update`, `add_php_preflight_install`, `add_php_preflight_update`, `add_placeholders`, `add_sql`, `add_sql_uninstall`, `addfootable`, `adduikit`, `add_admin_event`, `add_site_event`, `add_update_server`, `add_sales_server`, `sales_server`, `update_server`, `update_server_target`, `update_server_url`, `php_admin_event`, `php_site_event`, `addreadme`, `readme`, `author`, `bom`, `buildcomp`, `buildcompsql`, `companyname`, `component_version`, `copyright`, `creatuserhelper`, `css_admin`, `css_site`, `dashboard`, `dashboard_type`, `debug_linenr`, `description`, `email`, `emptycontributors`, `export_buy_link`, `joomla_source_link`, `export_key`, `image`, `javascript`, `license`, `name`, `system_name`, `toignore`, `name_code`, `number`, `php_helper_admin`, `php_helper_both`, `php_helper_site`, `php_postflight_install`, `php_method_uninstall`, `php_postflight_update`, `php_preflight_install`, `php_preflight_update`, `short_description`, `sql`, `sql_uninstall`, `website`, `published`, `created`, `modified`, `hits`, `ordering`, `whmcs_key`, `whmcs_url`, `guid`) VALUES (25, '', 1, '', '', '', '', '', '', '', 1, 1, '', '', '', '', '', '', '', '', 1, '', '', 1, '', '', '', 2, 'https://raw.githubusercontent.com/namibia/demo-joomla-3-component/master/demo_updateserver.xml', '', '', 1, 'IyAjIyNDb21wb25lbnRfbmFtZSMjIyAoIyMjVkVSU0lPTiMjIykNCg0KIVsjIyNDb21wb25lbnRfbmFtZSMjIyBpbWFnZV0oaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL25hbWliaWEvZGVtby1qb29tbGEtMy1jb21wb25lbnQvbWFzdGVyL2FkbWluL2Fzc2V0cy9pbWFnZXMvdmRtLWNvbXBvbmVudC5qcGcgIlRoZSAjIyNDb21wb25lbnRfbmFtZSMjIyIpDQoNCiMjI0RFU0NSSVBUSU9OIyMjDQoNCiMgQnVpbGQgRGV0YWlscw0KDQorICpDb21wYW55KjogWyMjI0NPTVBBTllOQU1FIyMjXSgjIyNBVVRIT1JXRUJTSVRFIyMjKQ0KKyAqQXV0aG9yKjogWyMjI0FVVEhPUiMjI10obWFpbHRvOiMjI0FVVEhPUkVNQUlMIyMjKQ0KKyAqTmFtZSo6IFsjIyNDb21wb25lbnRfbmFtZSMjI10oIyMjQVVUSE9SV0VCU0lURSMjIykNCisgKkZpcnN0IEJ1aWxkKjogIyMjQ1JFQVRJT05EQVRFIyMjDQorICpMYXN0IEJ1aWxkKjogIyMjQlVJTEREQVRFIyMjDQorICpWZXJzaW9uKjogIyMjVkVSU0lPTiMjIw0KKyAqQ29weXJpZ2h0KjogIyMjQ09QWVJJR0hUIyMjDQorICpMaWNlbnNlKjogIyMjTElDRU5TRSMjIw0KDQojIyBCdWlsZCBUaW1lDQoNCioqIyMjdG90YWxIb3VycyMjIyBIb3VycyoqIG9yICoqIyMjdG90YWxEYXlzIyMjIEVpZ2h0IEhvdXIgRGF5cyoqIChhY3R1YWwgdGltZSB0aGUgYXV0aG9yIHNhdmVkIC0NCmR1ZSB0byBbQXV0b21hdGVkIENvbXBvbmVudCBCdWlsZGVyXShodHRwczovL3d3dy52ZG0uaW8vam9vbWxhLWNvbXBvbmVudC1idWlsZGVyKSkNCg0KPiAoaWYgY3JlYXRpbmcgYSBmb2xkZXIgYW5kIGZpbGUgdG9vayAqKjUgc2Vjb25kcyoqIGFuZCB3cml0aW5nIG9uZSBsaW5lIG9mIGNvZGUgdG9vayAqKjEwIHNlY29uZHMqKiwNCj4gbmV2ZXIgbWFraW5nIG9uZSBtaXN0YWtlIG9yIHRha2luZyBhbnkgY29mZmVlIGJyZWFrLikNCg0KKyAqTGluZSBjb3VudCo6ICoqIyMjTElORV9DT1VOVCMjIyoqDQorICpGaWxlIGNvdW50KjogKiojIyNGSUxFX0NPVU5UIyMjKioNCisgKkZvbGRlciBjb3VudCo6ICoqIyMjRk9MREVSX0NPVU5UIyMjKioNCg0KKiojIyNhY3R1YWxIb3Vyc1NwZW50IyMjIEhvdXJzKiogb3IgKiojIyNhY3R1YWxEYXlzU3BlbnQjIyMgRWlnaHQgSG91ciBEYXlzKiogKHRoZSBhY3R1YWwgdGltZSB0aGUgYXV0aG9yIHNwZW50KQ0KDQo+ICh3aXRoIHRoZSBmb2xsb3dpbmcgYnJlYWsgZG93bjoNCj4gKipkZWJ1Z2dpbmcgQCMjI2RlYnVnZ2luZ0hvdXJzIyMjaG91cnMqKiA9IGNvZGluZ3RpbWUgLyA0Ow0KPiAqKnBsYW5uaW5nIEAjIyNwbGFubmluZ0hvdXJzIyMjaG91cnMqKiA9IGNvZGluZ3RpbWUgLyA3Ow0KPiAqKm1hcHBpbmcgQCMjI21hcHBpbmdIb3VycyMjI2hvdXJzKiogPSBjb2Rpbmd0aW1lIC8gMTA7DQo+ICoqb2ZmaWNlIEAjIyNvZmZpY2VIb3VycyMjI2hvdXJzKiogPSBjb2Rpbmd0aW1lIC8gNjspDQoNCioqIyMjYWN0dWFsVG90YWxIb3VycyMjIyBIb3VycyoqIG9yICoqIyMjYWN0dWFsVG90YWxEYXlzIyMjIEVpZ2h0IEhvdXIgRGF5cyoqDQooYSB0b3RhbCBvZiB0aGUgcmVhbGlzdGljIHRpbWUgZnJhbWUgZm9yIHRoaXMgcHJvamVjdCkNCg0KPiAoaWYgY3JlYXRpbmcgYSBmb2xkZXIgYW5kIGZpbGUgdG9vayAqKjUgc2Vjb25kcyoqIGFuZCB3cml0aW5nIG9uZSBsaW5lIG9mIGNvZGUgdG9vayAqKjEwIHNlY29uZHMqKiwNCj4gd2l0aCB0aGUgbm9ybWFsIGV2ZXJ5ZGF5IHJlYWxpdGllcyBhdCB0aGUgb2ZmaWNlLCB0aGF0IGluY2x1ZGVzIHRoZSBjb21wb25lbnQgcGxhbm5pbmcsIG1hcHBpbmcgJiBkZWJ1Z2dpbmcuKQ0KDQpQcm9qZWN0IGR1cmF0aW9uOiAqKiMjI3Byb2plY3RXZWVrVGltZSMjIyB3ZWVrcyoqIG9yICoqIyMjcHJvamVjdE1vbnRoVGltZSMjIyBtb250aHMqKg0KDQo+IFRoaXMgKipjb21wb25lbnQqKiB3YXMgYnVpbGQgd2l0aCBhIEpvb21sYSBbQXV0b21hdGVkIENvbXBvbmVudCBCdWlsZGVyXShodHRwczovL3d3dy52ZG0uaW8vam9vbWxhLWNvbXBvbmVudC1idWlsZGVyKS4NCj4gRGV2ZWxvcGVkIGJ5IFtMbGV3ZWxseW4gdmFuIGRlciBNZXJ3ZV0obWFpbHRvOmpvb21sYUB2ZG0uaW8pDQoNCltDVVNUT01DT0RFPXJlYWRNRWNvbnRyaWJ1dG9yc10=', 'Llewellyn van der Merwe', 'default.txt', '', '', 'Vast Development Method', '2.1.0', 'Copyright (C) 2015. All Rights Reserved', '', '', '', '', 1, '', 'Just a basic demo of the most basic implementations of the [Joomla](http://www.joomla.org) Component Builder\'s ability.', 'joomla@vdm.io', '', '', 'https://github.com/Llewellynvdm/Joomla-Demo-Component', 'hcYWdyvSGveEnSAqqDG8ybLDgwZ50qMcicGZ3GYQkHc=', 'images/vdm/demo500.jpg', '', 'GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html', 'Demo', 'Demo (public)', '.git', 'demo', 4, '', '', 'CS8qKg0KCSAqCUNoYW5nZSB0byBuaWNlIGZhbmN5IGRhdGUNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZhbmN5RGF0ZSgkZGF0ZSkNCgl7DQoJCWlmICghc2VsZjo6aXNWYWxpZFRpbWVTdGFtcCgkZGF0ZSkpDQoJCXsNCgkJCSRkYXRlID0gc3RydG90aW1lKCRkYXRlKTsNCgkJfQ0KCQlyZXR1cm4gZGF0ZSgnalMgXG9cZiBGIFknLCRkYXRlKTsNCgl9DQoNCgkvKioNCgkgKglDaGFuZ2UgdG8gbmljZSBmYW5jeSB0aW1lIGFuZCBkYXRlDQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmYW5jeURhdGVUaW1lKCR0aW1lKQ0KCXsNCgkJaWYgKCFzZWxmOjppc1ZhbGlkVGltZVN0YW1wKCR0aW1lKSkNCgkJew0KCQkJJHRpbWUgPSBzdHJ0b3RpbWUoJHRpbWUpOw0KCQl9DQoJCXJldHVybiBkYXRlKCcoRzppKSBqUyBcb1xmIEYgWScsJHRpbWUpOw0KCX0NCg0KCS8qKg0KCSAqCUNoYW5nZSB0byBuaWNlIGhvdXI6bWludXRlcyB0aW1lDQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmYW5jeVRpbWUoJHRpbWUpDQoJew0KCQlpZiAoIXNlbGY6OmlzVmFsaWRUaW1lU3RhbXAoJHRpbWUpKQ0KCQl7DQoJCQkkdGltZSA9IHN0cnRvdGltZSgkdGltZSk7DQoJCX0NCgkJcmV0dXJuIGRhdGUoJ0c6aScsJHRpbWUpOw0KCX0NCg0KCS8qKg0KCSAqCUNoZWNrIGlmIHN0cmluZyBpcyBhIHZhbGlkIHRpbWUgc3RhbXANCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGlzVmFsaWRUaW1lU3RhbXAoJHRpbWVzdGFtcCkNCgl7DQoJCXJldHVybiAoKGludCkgJHRpbWVzdGFtcCA9PT0gJHRpbWVzdGFtcCkNCgkJJiYgKCR0aW1lc3RhbXAgPD0gUEhQX0lOVF9NQVgpDQoJCSYmICgkdGltZXN0YW1wID49IH5QSFBfSU5UX01BWCk7DQoJfQ0K', 'CQkvLyBHZXQgQXBwbGljYXRpb24gb2JqZWN0DQoJCSRhcHAgPSBKRmFjdG9yeTo6Z2V0QXBwbGljYXRpb24oKTsNCgkJJGFwcC0+ZW5xdWV1ZU1lc3NhZ2UoJ1RoaXMgaXMgYSBkZW1vIGNvbXBvbmVudCBkZXZlbG9wZWQgaW4gPGEgaHJlZj0iaHR0cDovL3ZkbS5iei9jb21wb25lbnQtYnVpbGRlciIgdGFnZXQ9Il9iYWxuayIgdGl0bGU9Ikpvb21sYSBDb21wb25lbnQgQnVpbGRlciI+SkNCPC9hPiEgWW91IGNhbiBidWlsZCBtb3JlIGNvbXBvbmVudHMgbGlrZSB0aGlzIHdpdGggSkNCLCBjaGVja291dCBvdXIgcGFnZSBvbiA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vdmRtLWlvL0pvb21sYS1Db21wb25lbnQtQnVpbGRlciIgdGFnZXQ9Il9iYWxuayIgdGl0bGU9Ikpvb21sYSBDb21wb25lbnQgQnVpbGRlciI+Z2l0aHViPC9hPiBmb3IgbW9yZSBpbmZvLiBUaGUgZnV0dXJlIG9mIDxhIGhyZWY9Imh0dHA6Ly92ZG0uYnovY29tcG9uZW50LWJ1aWxkZXIiIHRhZ2V0PSJfYmFsbmsiIHRpdGxlPSJKb29tbGEgQ29tcG9uZW50IEJ1aWxkZXIiPkpvb21sYSBDb21wb25lbnQgRGV2ZWxvcG1lbnQ8L2E+IGlzIEhlcmUhJywgJ0luZm8nKTs=', '', '', '', '', 'Demo Component', '', '', 'https://www.vdm.io/', 1, '2016-10-18 11:44:09', '2020-11-17 17:19:57', '', 10, 'G2Rww7JuEI+de+Bm1ljKg72Hgt3MUfutTh1P15UayKU=', '', 'efde995e-60aa-4b39-b644-44349dfb660d'); --- --- Dumping data for table `#__componentbuilder_power` --- - -INSERT INTO `#__componentbuilder_power` (`id`, `add_head`, `description`, `extends`, `extends_custom`, `guid`, `head`, `implements`, `implements_custom`, `load_selection`, `main_class_code`, `method_selection`, `name`, `namespace`, `power_version`, `property_selection`, `system_name`, `type`, `use_selection`, `params`, `published`, `created`, `modified`, `version`, `ordering`) VALUES -(1, '', 'Basic shared utilities, a legacy implementation\r\n\r\n@since 3.0.9', '', '', '79d765b3-7319-4988-9730-446c7f347020', '', '', '', '{}', 'CS8qKg0KCSAqIFRoZSBNYWluIEFjdGl2ZSBMYW5ndWFnZQ0KCSAqIA0KCSAqIEB2YXIgICAgICBzdHJpbmcNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyAkbGFuZ1RhZzsNCg0KCS8qKg0KCSAqIENoZWNrIGlmIGhhdmUgYSBzdHJpbmcgd2l0aCBhIGxlbmd0aA0KCSAqDQoJICogQGlucHV0ICAgIHN0cmluZyAgJHN0cmluZyBUaGUgc3RyaW5nIHRvIGNoZWNrDQoJICoNCgkgKiBAcmV0dXJucyBib29sIHRydWUgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKg0KCSAqIEBkZXByZWNhdGVkICA0LjAgLSBVc2UgU3RyaW5nSGVscGVyOjpjaGVjaygkc3RyaW5nKTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNoZWNrU3RyaW5nKCRzdHJpbmcpOiBib29sDQoJew0KCQlyZXR1cm4gU3RyaW5nSGVscGVyOjpjaGVjaygkc3RyaW5nKTsNCgl9DQoNCgkvKioNCgkgKiBTaG9ydGVuIGEgc3RyaW5nDQoJICoNCgkgKiBAaW5wdXQgICAgc3RyaW5nICAkc3RyaW5nIFRoYXQgeW91IHdvdWxkIGxpa2UgdG8gc2hvcnRlbg0KCSAqDQoJICogQHJldHVybnMgc3RyaW5nIG9uIHN1Y2Nlc3MNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIFN0cmluZ0hlbHBlcjo6c2hvcnRlbigkc3RyaW5nLCAkbGVuZ3RoLCAkYWRkVGlwKTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNob3J0ZW4oJHN0cmluZywgJGxlbmd0aCA9IDQwLCAkYWRkVGlwID0gdHJ1ZSkNCgl7DQoJCXJldHVybiBTdHJpbmdIZWxwZXI6OnNob3J0ZW4oJHN0cmluZywgJGxlbmd0aCwgJGFkZFRpcCk7DQoJfQ0KDQoJLyoqDQoJICogTWFraW5nIHN0cmluZ3Mgc2FmZSAodmFyaW91cyB3YXlzKQ0KCSAqDQoJICogQGlucHV0ICAgIHN0cmluZyAgJHN0cmluZyBUaGF0IHlvdSB3b3VsZCBsaWtlIHRvIG1ha2Ugc2FmZQ0KCSAqDQoJICogQHJldHVybnMgc3RyaW5nIG9uIHN1Y2Nlc3MNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIFN0cmluZ0hlbHBlcjo6c2FmZSgkc3RyaW5nLCAkdHlwZSwgJHNwYWNlciwgJHJlcGxhY2VOdW1iZXJzLCAka2VlcE9ubHlDaGFyYWN0ZXJzKTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNhZmVTdHJpbmcoJHN0cmluZywgJHR5cGUgPSAnTCcsICRzcGFjZXIgPSAnXycsICRyZXBsYWNlTnVtYmVycyA9IHRydWUsICRrZWVwT25seUNoYXJhY3RlcnMgPSB0cnVlKQ0KCXsNCgkJLy8gc2V0IHRoZSBsb2NhbCBjb21wb25lbnQgb3B0aW9uDQoJCXNlbGY6OnNldENvbXBvbmVudE9wdGlvbigpOw0KDQoJCXJldHVybiBTdHJpbmdIZWxwZXI6OnNhZmUoJHN0cmluZywgJHR5cGUsICRzcGFjZXIsICRyZXBsYWNlTnVtYmVycywgJGtlZXBPbmx5Q2hhcmFjdGVycyk7DQoJfQ0KDQoJLyoqDQoJICogTWFraW5nIGNsYXNzIG9yIGZ1bmN0aW9uIG5hbWUgc2FmZQ0KCSAqDQoJICogQGlucHV0CXN0cmluZyAgICAgICBUaGUgbmFtZSB5b3Ugd291bGQgbGlrZSB0byBtYWtlIHNhZmUNCgkgKg0KCSAqIEByZXR1cm5zIHN0cmluZyBvbiBzdWNjZXNzDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBDbGFzc2Z1bmN0aW9uSGVscGVyOjpzYWZlKCRuYW1lKTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNhZmVDbGFzc0Z1bmN0aW9uTmFtZSgkbmFtZSkNCgl7DQoJCXJldHVybiBDbGFzc2Z1bmN0aW9uSGVscGVyOjpzYWZlKCRuYW1lKTsNCgl9DQoNCgkvKioNCgkgKiBNYWtpbmcgZmllbGQgbmFtZXMgc2FmZQ0KCSAqDQoJICogQGlucHV0CXN0cmluZyAgICAgICBUaGUgeW91IHdvdWxkIGxpa2UgdG8gbWFrZSBzYWZlDQoJICogQGlucHV0CWJvb2xlYW4gICAgICBUaGUgc3dpdGNoIHRvIHJldHVybiBhbiBBTEwgVVBQRVIgQ0FTRSBzdHJpbmcNCgkgKiBAaW5wdXQJc3RyaW5nICAgICAgIFRoZSBzdHJpbmcgdG8gdXNlIGluIHdoaXRlIHNwYWNlDQoJICoNCgkgKiBAcmV0dXJucyBzdHJpbmcgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKg0KCSAqIEBkZXByZWNhdGVkICA0LjAgLSBVc2UgRmllbGRIZWxwZXI6OnNhZmUoJHN0cmluZywgJGFsbGNhcCwgJHNwYWNlcik7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzYWZlRmllbGROYW1lKCRzdHJpbmcsICRhbGxjYXAgPSBmYWxzZSwgJHNwYWNlciA9ICdfJykNCgl7DQoJCS8vIHNldCB0aGUgbG9jYWwgY29tcG9uZW50IG9wdGlvbg0KCQlzZWxmOjpzZXRDb21wb25lbnRPcHRpb24oKTsNCg0KCQlyZXR1cm4gRmllbGRIZWxwZXI6OnNhZmUoJHN0cmluZywgJGFsbGNhcCwgJHNwYWNlcik7DQoJfQ0KDQoJLyoqDQoJICogTWFraW5nIGZpZWxkIHR5cGUgbmFtZSBzYWZlDQoJICoNCgkgKiBAaW5wdXQJc3RyaW5nICAgICAgIFRoZSB5b3Ugd291bGQgbGlrZSB0byBtYWtlIHNhZmUNCgkgKg0KCSAqIEByZXR1cm5zIHN0cmluZyBvbiBzdWNjZXNzDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBUeXBlSGVscGVyOjpzYWZlKCRzdHJpbmcpOw0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc2FmZVR5cGVOYW1lKCRzdHJpbmcpDQoJew0KCQkvLyBzZXQgdGhlIGxvY2FsIGNvbXBvbmVudCBvcHRpb24NCgkJc2VsZjo6c2V0Q29tcG9uZW50T3B0aW9uKCk7DQoNCgkJcmV0dXJuIFR5cGVIZWxwZXI6OnNhZmUoJHN0cmluZyk7DQoJfQ0KDQoJLyoqDQoJICogTWFraW5nIG5hbWVzcGFjZSBzYWZlDQoJICoNCgkgKiBAaW5wdXQJc3RyaW5nICAgICAgIFRoZSB5b3Ugd291bGQgbGlrZSB0byBtYWtlIHNhZmUNCgkgKg0KCSAqIEByZXR1cm5zIHN0cmluZyBvbiBzdWNjZXNzDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBOYW1lc3BhY2VIZWxwZXI6OnNhZmUoJHN0cmluZyk7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzYWZlTmFtZXNwYWNlKCRzdHJpbmcpDQoJew0KCQlyZXR1cm4gTmFtZXNwYWNlSGVscGVyOjpzYWZlKCRzdHJpbmcpOw0KCX0NCg0KCS8qKg0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKiANCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIFN0cmluZ0hlbHBlcjo6dHJhbnNsaXRlcmF0ZSgkc3RyaW5nKTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHRyYW5zbGl0ZXJhdGUoJHN0cmluZykNCgl7DQoJCS8vIHNldCB0aGUgbG9jYWwgY29tcG9uZW50IG9wdGlvbg0KCQlzZWxmOjpzZXRDb21wb25lbnRPcHRpb24oKTsNCg0KCQlyZXR1cm4gU3RyaW5nSGVscGVyOjp0cmFuc2xpdGVyYXRlKCRzdHJpbmcpOw0KCX0NCg0KCS8qKg0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKiANCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIFN0cmluZ0hlbHBlcjo6aHRtbCgkdmFyLCAkY2hhcnNldCwgJHNob3J0ZW4sICRsZW5ndGgpOw0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaHRtbEVzY2FwZSgkdmFyLCAkY2hhcnNldCA9ICdVVEYtOCcsICRzaG9ydGVuID0gZmFsc2UsICRsZW5ndGggPSA0MCkNCgl7DQoJCS8vIHNldCB0aGUgbG9jYWwgY29tcG9uZW50IG9wdGlvbg0KCQlzZWxmOjpzZXRDb21wb25lbnRPcHRpb24oKTsNCg0KCQlyZXR1cm4gU3RyaW5nSGVscGVyOjpodG1sKCR2YXIsICRjaGFyc2V0LCAkc2hvcnRlbiwgJGxlbmd0aCk7DQoJfQ0KDQoJLyoqDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqIA0KCSAqIEBkZXByZWNhdGVkICA0LjAgLSBVc2UgU3RyaW5nSGVscGVyOjpudW1iZXJzKCRzdHJpbmcpOw0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gcmVwbGFjZU51bWJlcnMoJHN0cmluZykNCgl7DQoJCXJldHVybiBTdHJpbmdIZWxwZXI6Om51bWJlcnMoJHN0cmluZyk7DQoJfQ0KDQoJLyoqDQoJICogQ29udmVydCBhbiBpbnRlZ2VyIGludG8gYW4gRW5nbGlzaCB3b3JkIHN0cmluZw0KCSAqIFRoYW5rcyB0byBUb20gTmljaG9sc29uIDxodHRwOi8vcGhwLm5ldC9tYW51YWwvZW4vZnVuY3Rpb24uc3RydmFsLnBocCM0MTk4OD4NCgkgKg0KCSAqIEBpbnB1dCAgICBpbnQgJHggYW4gaW50DQoJICoNCgkgKiBAcmV0dXJucyBzdHJpbmcgYSBzdHJpbmcNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIFN0cmluZ0hlbHBlcjo6bnVtYmVyKCR4KTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG51bWJlclRvU3RyaW5nKCR4KQ0KCXsNCgkJcmV0dXJuIFN0cmluZ0hlbHBlcjo6bnVtYmVyKCR4KTsNCgl9DQoNCgkvKioNCgkgKiBSYW5kb20gS2V5DQoJICoNCgkgKiBAaW5wdXQgaW50ICRzaXplIHRoZSBsZW5ndGggb2YgdGhlIHN0cmluZw0KCSAqDQoJICogQHJldHVybnMgc3RyaW5nIGEgc3RyaW5nIG9mIHJhbmRvbSBjaGFyYWN0ZXJzDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBTdHJpbmdIZWxwZXI6OnJhbmRvbSgkc2l6ZSk7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiByYW5kb21rZXkoJHNpemUpOiBzdHJpbmcNCgl7DQoJCXJldHVybiBTdHJpbmdIZWxwZXI6OnJhbmRvbSgkc2l6ZSk7DQoJfQ0KDQoJLyoqDQoJICogQ2hlY2sgaWYgeW91IGhhdmUgYSBqc29uIHN0cmluZw0KCSAqDQoJICogQGlucHV0ICAgIHN0cmluZyAgJHN0cmluZyAgVGhlIGpzb24gc3RyaW5nIHRvIGNoZWNrDQoJICoNCgkgKiBAcmV0dXJucyBib29sIHRydWUgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKg0KCSAqIEBkZXByZWNhdGVkICA0LjAgLSBVc2UgSnNvbkhlbHBlcjo6Y2hlY2soJHN0cmluZyk7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjaGVja0pzb24oJHN0cmluZyk6IGJvb2wNCgl7DQoJCXJldHVybiBKc29uSGVscGVyOjpjaGVjaygkc3RyaW5nKTsNCgl9DQoNCgkvKioNCgkgKiBAc2luY2UgIDMuMC45DQoJICogDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBKc29uSGVscGVyOjpzdHJpbmcoJHZhbHVlLCAkc3BlcmF0b3IsICR0YWJsZSwgJGlkLCAkbmFtZSk7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBqc29uVG9TdHJpbmcoJHZhbHVlLCAkc3BlcmF0b3IgPSAiLCAiLCAkdGFibGUgPSBudWxsLCAkaWQgPSAnaWQnLCAkbmFtZSA9ICduYW1lJykNCgl7DQoJCXJldHVybiBKc29uSGVscGVyOjpzdHJpbmcoJHZhbHVlLCAkc3BlcmF0b3IsICR0YWJsZSwgJGlkLCAkbmFtZSk7DQoJfQ0KDQoJLyoqDQoJICogQ2hlY2sgaWYgeW91IGhhdmUgYW4gYXJyYXkgd2l0aCBhIGxlbmd0aA0KCSAqDQoJICogQGlucHV0ICAgIG1peGVkICRhcnJheSAgICAgICAgICAgICAgVGhlIGFycmF5IHRvIGNoZWNrDQoJICogQGlucHV0ICAgIGJvb2wgICRyZW1vdmVFbXB0eVN0cmluZyAgU2hvdWxkIHdlIHJlbW92ZSBlbXB0eSB2YWx1ZXMNCgkgKg0KCSAqIEByZXR1cm5zIGludCAgbnVtYmVyIG9mIGl0ZW1zIGluIGFycmF5IG9uIHN1Y2Nlc3MNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIEFycmF5SGVscGVyOjpjaGVjaygkYXJyYXksICRyZW1vdmVFbXB0eVN0cmluZyk7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjaGVja0FycmF5KCRhcnJheSwgJHJlbW92ZUVtcHR5U3RyaW5nID0gZmFsc2UpOiBpbnQNCgl7DQoJCXJldHVybiBBcnJheUhlbHBlcjo6Y2hlY2soJGFycmF5LCAkcmVtb3ZlRW1wdHlTdHJpbmcpOw0KCX0NCg0KCS8qKg0KCSAqIE1lcmdlIGFuIGFycmF5IG9mIGFycmF5J3MNCgkgKg0KCSAqIEBpbnB1dCAgICBtaXhlZCAgJGFycmF5cyBUaGUgYXJyYXlzIHlvdSB3b3VsZCBsaWtlIHRvIG1lcmdlDQoJICoNCgkgKiBAcmV0dXJucyBtaXhlZCBhcnJheSBvbiBzdWNjZXNzDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBBcnJheUhlbHBlcjo6bWVyZ2UoJGFycmF5cyk7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBtZXJnZUFycmF5cygkYXJyYXlzKQ0KCXsNCgkJcmV0dXJuIEFycmF5SGVscGVyOjptZXJnZSgkYXJyYXlzKTsNCgl9DQoNCgkvKioNCgkgKiBDaGVjayBpZiB5b3UgaGF2ZSBhbiBvYmplY3Qgd2l0aCBhIGxlbmd0aA0KCSAqDQoJICogQGlucHV0ICAgIG9iamVjdCAkb2JqZWN0ICBUaGUgb2JqZWN0IHRvIGNoZWNrDQoJICoNCgkgKiBAcmV0dXJucyBib29sIHRydWUgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKg0KCSAqIEBkZXByZWNhdGVkICA0LjAgLSBVc2UgT2JqZWN0SGVscGVyOjpjaGVjaygkb2JqZWN0KTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNoZWNrT2JqZWN0KCRvYmplY3QpOiBib29sDQoJew0KCQlyZXR1cm4gT2JqZWN0SGVscGVyOjpjaGVjaygkb2JqZWN0KTsNCgl9DQoNCgkvKioNCgkgKiBHZXQgYSBWYXJpYWJsZSANCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICR0YWJsZSAgICAgICAgVGhlIHRhYmxlIGZyb20gd2hpY2ggdG8gZ2V0IHRoZSB2YXJpYWJsZQ0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICR3aGVyZSAgICAgICAgVGhlIHZhbHVlIHdoZXJlDQoJICogQHBhcmFtICAgc3RyaW5nICAgJHdoZXJlU3RyaW5nICBUaGUgdGFyZ2V0L2ZpZWxkIHN0cmluZyB3aGVyZS9uYW1lDQoJICogQHBhcmFtICAgc3RyaW5nICAgJHdoYXQgICAgICAgICBUaGUgcmV0dXJuIGZpZWxkDQoJICogQHBhcmFtICAgc3RyaW5nICAgJG9wZXJhdG9yICAgICBUaGUgb3BlcmF0b3IgYmV0d2VlbiAkd2hlcmVTdHJpbmcvZmllbGQgYW5kICR3aGVyZS92YWx1ZQ0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICRtYWluICAgICAgICAgVGhlIGNvbXBvbmVudCBpbiB3aGljaCB0aGUgdGFibGUgaXMgZm91bmQNCgkgKg0KCSAqIEByZXR1cm4gIG1peCBzdHJpbmcvaW50L2Zsb2F0DQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBHZXRIZWxwZXI6OnZhcigkdGFibGUsICR3aGVyZSwgJHdoZXJlU3RyaW5nLCAkd2hhdCwgJG9wZXJhdG9yLCAkbWFpbik7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRWYXIoJHRhYmxlLCAkd2hlcmUgPSBudWxsLCAkd2hlcmVTdHJpbmcgPSAndXNlcicsICR3aGF0ID0gJ2lkJywgJG9wZXJhdG9yID0gJz0nLCAkbWFpbiA9IG51bGwpDQoJew0KCQkvLyBzZXQgdGhlIGxvY2FsIGNvbXBvbmVudCBvcHRpb24NCgkJc2VsZjo6c2V0Q29tcG9uZW50T3B0aW9uKCk7DQoNCgkJcmV0dXJuIEdldEhlbHBlcjo6dmFyKCR0YWJsZSwgJHdoZXJlLCAkd2hlcmVTdHJpbmcsICR3aGF0LCAkb3BlcmF0b3IsICRtYWluKTsNCgl9DQoNCgkvKioNCgkgKiBHZXQgYXJyYXkgb2YgdmFyaWFibGVzDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkdGFibGUgICAgICAgIFRoZSB0YWJsZSBmcm9tIHdoaWNoIHRvIGdldCB0aGUgdmFyaWFibGVzDQoJICogQHBhcmFtICAgc3RyaW5nICAgJHdoZXJlICAgICAgICBUaGUgdmFsdWUgd2hlcmUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkd2hlcmVTdHJpbmcgIFRoZSB0YXJnZXQvZmllbGQgc3RyaW5nIHdoZXJlL25hbWUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkd2hhdCAgICAgICAgIFRoZSByZXR1cm4gZmllbGQNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkb3BlcmF0b3IgICAgIFRoZSBvcGVyYXRvciBiZXR3ZWVuICR3aGVyZVN0cmluZy9maWVsZCBhbmQgJHdoZXJlL3ZhbHVlDQoJICogQHBhcmFtICAgc3RyaW5nICAgJG1haW4gICAgICAgICBUaGUgY29tcG9uZW50IGluIHdoaWNoIHRoZSB0YWJsZSBpcyBmb3VuZA0KCSAqIEBwYXJhbSAgIGJvb2wgICAgICR1bmlxdWUgICAgICAgVGhlIHN3aXRjaCB0byByZXR1cm4gYSB1bmlxdWUgYXJyYXkNCgkgKg0KCSAqIEByZXR1cm4gIGFycmF5DQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBHZXRIZWxwZXI6OnZhcnMoJHRhYmxlLCAkd2hlcmUsICR3aGVyZVN0cmluZywgJHdoYXQsICRvcGVyYXRvciwgJG1haW4sICR1bmlxdWUpOw0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0VmFycygkdGFibGUsICR3aGVyZSA9IG51bGwsICR3aGVyZVN0cmluZyA9ICd1c2VyJywgJHdoYXQgPSAnaWQnLCAkb3BlcmF0b3IgPSAnSU4nLCAkbWFpbiA9IG51bGwsICR1bmlxdWUgPSB0cnVlKQ0KCXsNCgkJLy8gc2V0IHRoZSBsb2NhbCBjb21wb25lbnQgb3B0aW9uDQoJCXNlbGY6OnNldENvbXBvbmVudE9wdGlvbigpOw0KDQoJCXJldHVybiBHZXRIZWxwZXI6OnZhcnMoJHRhYmxlLCAkd2hlcmUsICR3aGVyZVN0cmluZywgJHdoYXQsICRvcGVyYXRvciwgJG1haW4sICR1bmlxdWUpOw0KCX0NCg0KCS8qKg0KCSAqIGdldCBhbGwgc3RyaW5ncyBiZXR3ZWVuIHR3byBvdGhlciBzdHJpbmdzDQoJICoNCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAkY29udGVudCAgICBUaGUgY29udGVudCB0byBzZWFyY2gNCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAkc3RhcnQgICAgICAgIFRoZSBzdGFydGluZyB2YWx1ZQ0KCSAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICRlbmQgICAgICAgICBUaGUgZW5kaW5nIHZhbHVlDQoJICoNCgkgKiBAcmV0dXJuICBhcnJheSAgICAgICAgICBPbiBzdWNjZXNzDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBHZXRIZWxwZXI6OmFsbEJldHdlZW4oJGNvbnRlbnQsICRzdGFydCwgJGVuZCk7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRBbGxCZXR3ZWVuKCRjb250ZW50LCAkc3RhcnQsICRlbmQpDQoJew0KCQlyZXR1cm4gR2V0SGVscGVyOjphbGxCZXR3ZWVuKCRjb250ZW50LCAkc3RhcnQsICRlbmQpOw0KCX0NCg0KCS8qKg0KCSAqIGdldCBhIHN0cmluZyBiZXR3ZWVuIHR3byBvdGhlciBzdHJpbmdzDQoJICogDQoJICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgJGNvbnRlbnQgICAgVGhlIGNvbnRlbnQgdG8gc2VhcmNoDQoJICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgJHN0YXJ0ICAgICAgICBUaGUgc3RhcnRpbmcgdmFsdWUNCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAkZW5kICAgICAgICAgVGhlIGVuZGluZyB2YWx1ZQ0KCSAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAgICRkZWZhdWx0ICAgICBUaGUgZGVmYXVsdCB2YWx1ZSBpZiBub25lIGZvdW5kDQoJICoNCgkgKiBAcmV0dXJuICBzdHJpbmcgICAgICAgICAgT24gc3VjY2VzcyAvIGVtcHR5IHN0cmluZyBvbiBmYWlsdXJlDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBHZXRIZWxwZXI6OmJldHdlZW4oJGNvbnRlbnQsICRzdGFydCwgJGVuZCwgJGRlZmF1bHQpOw0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0QmV0d2VlbigkY29udGVudCwgJHN0YXJ0LCAkZW5kLCAkZGVmYXVsdCA9ICcnKQ0KCXsNCgkJcmV0dXJuIEdldEhlbHBlcjo6YmV0d2VlbigkY29udGVudCwgJHN0YXJ0LCAkZW5kLCAkZGVmYXVsdCk7DQoJfQ0KDQoJLyoqDQoJICogYmMgbWF0aCB3cmFwcGVyICh2ZXJ5IGJhc2ljIG5vdCBmb3IgYWNjb3VudGluZykNCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICR0eXBlICAgIFRoZSB0eXBlIGJjIG1hdGgNCgkgKiBAcGFyYW0gICBpbnQgICAgICAkdmFsMSAgICBUaGUgZmlyc3QgdmFsdWUNCgkgKiBAcGFyYW0gICBpbnQgICAgICAkdmFsMiAgICBUaGUgc2Vjb25kIHZhbHVlDQoJICogQHBhcmFtICAgaW50ICAgICAgJHNjYWxlICAgVGhlIHNjYWxlIHZhbHVlDQoJICoNCgkgKiBAcmV0dXJuIGZsb2F0fGludA0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKg0KCSAqIEBkZXByZWNhdGVkICA0LjAgLSBVc2UgTWF0aEhlbHBlcjo6YmMoJHR5cGUsICR2YWwxLCAkdmFsMiwgJHNjYWxlKTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGJjbWF0aCgkdHlwZSwgJHZhbDEsICR2YWwyLCAkc2NhbGUgPSAwKQ0KCXsNCgkJcmV0dXJuIE1hdGhIZWxwZXI6OmJjKCR0eXBlLCAkdmFsMSwgJHZhbDIsICRzY2FsZSk7DQoJfQ0KDQoJLyoqDQoJICogQmFzaWMgc3VtIG9mIGFuIGFycmF5IHdpdGggbW9yZSBwcmVjaXNpb24NCgkgKg0KCSAqIEBwYXJhbSAgIGFycmF5ICAgJGFycmF5ICAgIFRoZSB2YWx1ZXMgdG8gc3VtDQoJICogQHBhcmFtICAgaW50ICAgICAgJHNjYWxlICAgVGhlIHNjYWxlIHZhbHVlDQoJICoNCgkgKiBAcmV0dXJuIGZsb2F0fGludA0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKg0KCSAqIEBkZXByZWNhdGVkICA0LjAgLSBVc2UgTWF0aEhlbHBlcjo6c3VtKCRhcnJheSwgJHNjYWxlKTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGJjc3VtKCRhcnJheSwgJHNjYWxlID0gNCkNCgl7DQoJCXJldHVybiBNYXRoSGVscGVyOjpzdW0oJGFycmF5LCAkc2NhbGUpOw0KCX0NCg0KICAgICAgICAvKioNCiAgICAgICAgICogY3JlYXRlIHBsdWdpbiBjbGFzcyBuYW1lDQoJICoNCgkgKiBAaW5wdXQJc3RyaW5nICAgICAgIFRoZSBncm91cCBuYW1lDQoJICogQGlucHV0CXN0cmluZyAgICAgICBUaGUgbmFtZQ0KCSAqDQoJICogQHJldHVybiBzdHJpbmcNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIFBsdWdpbkhlbHBlcjo6c2FmZSgkbmFtZSwgJGdyb3VwKTsNCiAgICAgICAgICovDQogICAgICAgIHB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY3JlYXRlUGx1Z2luQ2xhc3NOYW1lKCRncm91cCwgJG5hbWUpDQoJew0KCQlyZXR1cm4gUGx1Z2luSGVscGVyOjpzYWZlQ2xhc3NOYW1lKCRuYW1lLCAkZ3JvdXApOw0KCX0NCg0KCS8qKg0KCSAqIFJldHVybnMgYSBHVUlEdjQgc3RyaW5nDQoJICogDQoJICogVGhhbmtzIHRvIERhdmUgUGVhcnNvbiAoYW5kIG90aGVyKQ0KCSAqIGh0dHBzOi8vd3d3LnBocC5uZXQvbWFudWFsL2VuL2Z1bmN0aW9uLmNvbS1jcmVhdGUtZ3VpZC5waHAjMTE5MTY4IA0KCSAqDQoJICogVXNlcyB0aGUgYmVzdCBjcnlwdG9ncmFwaGljYWxseSBzZWN1cmUgbWV0aG9kDQoJICogZm9yIGFsbCBzdXBwb3J0ZWQgcGxhdGZvcm1zIHdpdGggZmFsbGJhY2sgdG8gYW4gb2xkZXIsDQoJICogbGVzcyBzZWN1cmUgdmVyc2lvbi4NCgkgKg0KCSAqIEBwYXJhbSBib29sICR0cmltDQoJICoNCgkgKiBAcmV0dXJuIHN0cmluZw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKg0KCSAqIEBkZXByZWNhdGVkICA0LjAgLSBVc2UgR3VpZEhlbHBlcjo6Z2V0KCR0cmltKTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIEdVSUQoJHRyaW0gPSB0cnVlKQ0KCXsNCgkJcmV0dXJuIEd1aWRIZWxwZXI6OmdldCgkdHJpbSk7DQoJfQ0KDQoJLyoqDQoJICogVmFsaWRhdGUgdGhlIEdsb2JhbGx5IFVuaXF1ZSBJZGVudGlmaWVyICggYW5kIGNoZWNrIGlmIHRhYmxlIGFscmVhZHkgaGFzIHRoaXMgaWRlbnRpZmllcikNCgkgKg0KCSAqIEBwYXJhbSBzdHJpbmcgICAgICAgJGd1aWQNCgkgKiBAcGFyYW0gc3RyaW5nICAgICAgICR0YWJsZQ0KCSAqIEBwYXJhbSBpbnQgICAgICAgICAgICAkaWQNCgkgKiBAcGFyYW0gc3RyaW5nfG51bGwgJGNvbXBvbmVudA0KCSAqDQoJICogQHJldHVybiBib29sDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBHdWlkSGVscGVyOjp2YWxpZCgkZ3VpZCwgJHRhYmxlLCAkaWQsICRjb21wb25lbnQpOw0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdmFsaWRHVUlEKCRndWlkLCAkdGFibGUgPSBudWxsLCAkaWQgPSAwLCAkY29tcG9uZW50ID0gbnVsbCkNCgl7DQoJCS8vIHNldCB0aGUgbG9jYWwgY29tcG9uZW50IG9wdGlvbg0KCQlzZWxmOjpzZXRDb21wb25lbnRPcHRpb24oKTsNCg0KCQlyZXR1cm4gR3VpZEhlbHBlcjo6dmFsaWQoJGd1aWQsICR0YWJsZSwgJGlkLCAkY29tcG9uZW50KTsNCgl9DQoNCgkvKioNCgkgKiBnZXQgdGhlIElURU0gb2YgYSBHVUlEIGJ5IHRhYmxlDQoJICoNCgkgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAkZ3VpZA0KCSAqIEBwYXJhbSBzdHJpbmcgICAgICAgICAgICR0YWJsZQ0KCSAqIEBwYXJhbSBzdHJpbmcvYXJyYXkgICR3aGF0DQoJICogQHBhcmFtIHN0cmluZ3xudWxsICAgICRjb21wb25lbnQNCgkgKg0KCSAqIEByZXR1cm4gbWl4DQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqDQoJICogQGRlcHJlY2F0ZWQgIDQuMCAtIFVzZSBHdWlkSGVscGVyOjp2YWxpZCgkZ3VpZCwgJHRhYmxlLCAkaWQsICRjb21wb25lbnQpOw0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0R1VJRCgkZ3VpZCwgJHRhYmxlLCAkd2hhdCA9ICdhLmlkJywgJGNvbXBvbmVudCA9IG51bGwpDQoJew0KCQkvLyBzZXQgdGhlIGxvY2FsIGNvbXBvbmVudCBvcHRpb24NCgkJc2VsZjo6c2V0Q29tcG9uZW50T3B0aW9uKCk7DQoNCgkJcmV0dXJuIEd1aWRIZWxwZXI6Oml0ZW0oJGd1aWQsICR0YWJsZSwgJHdoYXQsICRjb21wb25lbnQpOw0KCX0NCg0KCS8qKg0KCSAqIFZhbGlkYXRlIHRoZSBHbG9iYWxseSBVbmlxdWUgSWRlbnRpZmllcg0KCSAqDQoJICogVGhhbmtzIHRvIExld2llDQoJICogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzE1MTU0NTYvMTQyOTY3Nw0KCSAqDQoJICogQHBhcmFtIHN0cmluZyAkZ3VpZA0KCSAqDQoJICogQHJldHVybiBib29sDQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIEd1aWRIZWxwZXI6OnZhbGlkYXRlKCRndWlkKTsNCgkgKi8NCglwcm90ZWN0ZWQgc3RhdGljIGZ1bmN0aW9uIHZhbGlkYXRlR1VJRCgkZ3VpZCkNCgl7DQoJCXJldHVybiBHdWlkSGVscGVyOjp2YWxpZGF0ZSgkZ3VpZCk7DQoJfQ0KDQoJLyoqDQoJICogVGhlIHppcHBlciBtZXRob2QNCgkgKiANCgkgKiBAcGFyYW0gIHN0cmluZyAgICR3b3JraW5nRElSICAgIFRoZSBkaXJlY3Rvcnkgd2hlcmUgdGhlIGl0ZW1zIG11c3QgYmUgemlwcGVkDQoJICogQHBhcmFtICBzdHJpbmcgICAkZmlsZXBhdGggICAgICAgICAgVGhlIHBhdGggdG8gd2hlcmUgdGhlIHppcCBmaWxlIG11c3QgYmUgcGxhY2VkDQoJICoNCgkgKiBAcmV0dXJuICBib29sIHRydWUgICBPbiBzdWNjZXNzDQoJICoNCgkgKiBAc2luY2UgIDMuMC45DQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIEZpbGVIZWxwZXI6OnppcCgkd29ya2luZ0RJUiwgJGZpbGVwYXRoKTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHppcCgkd29ya2luZ0RJUiwgJiRmaWxlcGF0aCkNCgl7DQoJCXJldHVybiBGaWxlSGVscGVyOjp6aXAoJHdvcmtpbmdESVIsICRmaWxlcGF0aCk7DQoJfQ0KDQoJLyoqDQoJICogZ2V0IHRoZSBjb250ZW50IG9mIGEgZmlsZQ0KCSAqDQoJICogQHBhcmFtICBzdHJpbmcgICAgICAgICRwYXRoICAgVGhlIHBhdGggdG8gdGhlIGZpbGUNCgkgKiBAcGFyYW0gIHN0cmluZy9ib29sICAgJG5vbmUgICBUaGUgcmV0dXJuIHZhbHVlIGlmIG5vIGNvbnRlbnQgd2FzIGZvdW5kDQoJICoNCgkgKiBAcmV0dXJuICBzdHJpbmcgICBPbiBzdWNjZXNzDQoJICoNCgkgKiBAc2luY2UgIDMuMC45DQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIEZpbGVIZWxwZXI6OmdldENvbnRlbnQoJHBhdGgsICRub25lKTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEZpbGVDb250ZW50cygkcGF0aCwgJG5vbmUgPSAnJykNCgl7DQoJCXJldHVybiBGaWxlSGVscGVyOjpnZXRDb250ZW50KCRwYXRoLCAkbm9uZSk7DQoJfQ0KDQoJLyoqDQoJICogV3JpdGUgYSBmaWxlIHRvIHRoZSBzZXJ2ZXINCgkgKg0KCSAqIEBwYXJhbSAgc3RyaW5nICAgJHBhdGggICAgVGhlIHBhdGggYW5kIGZpbGUgbmFtZSB3aGVyZSB0byBzYWZlIHRoZSBkYXRhDQoJICogQHBhcmFtICBzdHJpbmcgICAkZGF0YSAgICBUaGUgZGF0YSB0byBzYWZlDQoJICoNCgkgKiBAcmV0dXJuICBib29sIHRydWUgICBPbiBzdWNjZXNzDQoJICoNCgkgKiBAc2luY2UgIDMuMC45DQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIEZpbGVIZWxwZXI6OndyaXRlKCRwYXRoLCAkZGF0YSk7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiB3cml0ZUZpbGUoJHBhdGgsICRkYXRhKQ0KCXsNCgkJcmV0dXJuIEZpbGVIZWxwZXI6OndyaXRlKCRwYXRoLCAkZGF0YSk7DQoJfQ0KDQoJLyoqDQoJICogZ2V0IGFsbCB0aGUgZmlsZSBwYXRocyBpbiBmb2xkZXIgYW5kIHN1YiBmb2xkZXJzDQoJICogDQoJICogQHBhcmFtICAgc3RyaW5nICAkZm9sZGVyICAgICBUaGUgbG9jYWwgcGF0aCB0byBwYXJzZQ0KCSAqIEBwYXJhbSAgIGFycmF5ICAgJGZpbGVUeXBlcyAgVGhlIHR5cGUgb2YgZmlsZXMgdG8gZ2V0DQoJICoNCgkgKiBAcmV0dXJuICB2b2lkDQoJICoNCgkgKiBAc2luY2UgIDMuMC45DQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIEZpbGVIZWxwZXI6OmdldFBhdGhzKCRmb2xkZXIsICRmaWxlVHlwZXMgLCAkcmVjdXJzZSwgJGZ1bGwpOw0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0QWxsRmlsZVBhdGhzKCRmb2xkZXIsICRmaWxlVHlwZXMgPSBhcnJheSgnXC5waHAnLCAnXC5qcycsICdcLmNzcycsICdcLmxlc3MnKSwgJHJlY3Vyc2UgPSB0cnVlLCAkZnVsbCA9IHRydWUpDQoJew0KCQlyZXR1cm4gRmlsZUhlbHBlcjo6Z2V0UGF0aHMoJGZvbGRlciwgJGZpbGVUeXBlcyAsICRyZWN1cnNlLCAkZnVsbCk7DQoJfQ0KDQoJLyoqDQoJICogR2V0IHRoZSBmaWxlIHBhdGggb3IgdXJsDQoJICoNCgkgKiBAcGFyYW0gIHN0cmluZyAgICR0eXBlICAgICAgICAgICAgICBUaGUgKHVybC9wYXRoKSB0eXBlIHRvIHJldHVybg0KCSAqIEBwYXJhbSAgc3RyaW5nICAgJHRhcmdldCAgICAgICAgICAgIFRoZSBQYXJhbXMgVGFyZ2V0IG5hbWUgKGlmIHNldCkNCgkgKiBAcGFyYW0gIHN0cmluZyAgICRmaWxlVHlwZSAgICAgICAgICBUaGUga2luZCBvZiBmaWxlbmFtZSB0byBnZW5lcmF0ZSAoaWYgbm90IHNldCBubyBmaWxlIG5hbWUgaXMgZ2VuZXJhdGVkKQ0KCSAqIEBwYXJhbSAgc3RyaW5nICAgJGtleSAgICAgICAgICAgICAgIFRoZSBrZXkgdG8gYWRqdXN0IHRoZSBmaWxlbmFtZSAoaWYgbm90IHNldCBpZ25vcmVkKQ0KCSAqIEBwYXJhbSAgc3RyaW5nICAgJGRlZmF1bHQgICAgICAgICAgIFRoZSBkZWZhdWx0IHBhdGggaWYgbm90IHNldCBpbiBQYXJhbXMgKGZhbGxiYWNrIHBhdGgpDQoJICogQHBhcmFtICBib29sICAgICAkY3JlYXRlSWZOb3RTZXQgICAgVGhlIHN3aXRjaCB0byBjcmVhdGUgdGhlIGZvbGRlciBpZiBub3QgZm91bmQNCgkgKg0KCSAqIEByZXR1cm4gIHN0cmluZyAgICBPbiBzdWNjZXNzIHRoZSBwYXRoIG9yIHVybCBpcyByZXR1cm5lZCBiYXNlZCBvbiB0aGUgdHlwZSByZXF1ZXN0ZWQNCgkgKg0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKg0KCSAqIEBkZXByZWNhdGVkICA0LjAgLSBVc2UgRmlsZUhlbHBlcjo6Z2V0UGF0aCgkdHlwZSwgJHRhcmdldCwgJGZpbGVUeXBlLCAka2V5LCAkZGVmYXVsdCwgJGNyZWF0ZUlmTm90U2V0KTsNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldEZpbGVQYXRoKCR0eXBlID0gJ3BhdGgnLCAkdGFyZ2V0ID0gJ2ZpbGVwYXRoJywgJGZpbGVUeXBlID0gbnVsbCwgJGtleSA9ICcnLCAkZGVmYXVsdCA9ICcnLCAkY3JlYXRlSWZOb3RTZXQgPSB0cnVlKQ0KCXsNCgkJLy8gc2V0IHRoZSBsb2NhbCBjb21wb25lbnQgb3B0aW9uDQoJCXNlbGY6OnNldENvbXBvbmVudE9wdGlvbigpOw0KDQoJCXJldHVybiBGaWxlSGVscGVyOjpnZXRQYXRoKCR0eXBlLCAkdGFyZ2V0LCAkZmlsZVR5cGUsICRrZXksICRkZWZhdWx0LCAkY3JlYXRlSWZOb3RTZXQpOw0KCX0NCg0KCS8qKg0KCSAqIENoZWNrIGlmIGZpbGUgZXhpc3QNCgkgKg0KCSAqIEBwYXJhbSAgc3RyaW5nICAgJHBhdGggICBUaGUgdXJsL3BhdGggdG8gY2hlY2sNCgkgKg0KCSAqIEByZXR1cm4gIGJvb2wgICAgICBJZiBleGlzdCB0cnVlDQoJICoNCgkgKiBAc2luY2UgIDMuMC45DQoJICoNCgkgKiBAZGVwcmVjYXRlZCAgNC4wIC0gVXNlIEZpbGVIZWxwZXI6OmV4aXN0cygkcGF0aCk7DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiB1cmxFeGlzdHMoJHBhdGgpDQoJew0KCQlyZXR1cm4gRmlsZUhlbHBlcjo6ZXhpc3RzKCRwYXRoKTsNCgl9DQoNCgkvKioNCgkgKiBTZXQgdGhlIGNvbXBvbmVudCBvcHRpb24NCgkgKg0KCSAqIEBwYXJhbSAgIFN0cmluZ3xudWxsICAgICAgICRvcHRpb24gICAgVGhlIG9wdGlvbiBmb3IgdGhlIGNvbXBvbmVudC4NCgkgKg0KCSAqIEBzaW5jZSAgMy4wLjExDQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzZXRDb21wb25lbnRPcHRpb24oJG9wdGlvbiA9IG51bGwpDQoJew0KCQkvLyBzZXQgdGhlIGxvY2FsIGNvbXBvbmVudCBvcHRpb24NCgkJaWYgKGVtcHR5KCRvcHRpb24pKQ0KCQl7DQoJCQlpZiAoZW1wdHkoSGVscGVyOjokb3B0aW9uKSAmJiBwcm9wZXJ0eV9leGlzdHMoX19DTEFTU19fLCAnQ29tcG9uZW50Q29kZU5hbWUnKSkNCgkJCXsNCgkJCQlIZWxwZXI6OiRvcHRpb24gPSAnY29tXycgLiBzZWxmOjokQ29tcG9uZW50Q29kZU5hbWU7DQoJCQl9DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQlIZWxwZXI6OiRvcHRpb24gPSAkb3B0aW9uOw0KCQl9DQoJfQ0K', '{}', 'Utilities', 'VDM\\Joomla\\Utilities', '1.0.0', '{}', 'Utilities', 'trait', '{\"use_selection0\":{\"use\":\"1f28cb53-60d9-4db1-b517-3c7dc6b429ef\",\"as\":\"default\"},\"use_selection1\":{\"use\":\"4b225c51-d293-48e4-b3f6-5136cf5c3f18\",\"as\":\"default\"},\"use_selection2\":{\"use\":\"0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a\",\"as\":\"default\"},\"use_selection3\":{\"use\":\"91004529-94a9-4590-b842-e7c6b624ecf5\",\"as\":\"default\"},\"use_selection4\":{\"use\":\"152c8793-8b75-4715-996a-257b9f65451c\",\"as\":\"default\"},\"use_selection5\":{\"use\":\"db87c339-5bb6-4291-a7ef-2c48ea1b06bc\",\"as\":\"default\"},\"use_selection6\":{\"use\":\"9c513baf-b279-43fd-ae29-a585c8cbc4f0\",\"as\":\"default\"},\"use_selection7\":{\"use\":\"a223b31e-ea1d-4cdf-92ae-5f9becffaff0\",\"as\":\"default\"},\"use_selection8\":{\"use\":\"9ef0eb24-aae4-4f5a-99af-d724db44808f\",\"as\":\"default\"},\"use_selection9\":{\"use\":\"a8935cbe-7701-40dc-bfd5-675f2d600954\",\"as\":\"default\"},\"use_selection10\":{\"use\":\"30c5b4c2-f75f-4d15-869a-f8bfedd87358\",\"as\":\"default\"},\"use_selection11\":{\"use\":\"ce8cf834-6bac-44fb-941c-861f7e046cc0\",\"as\":\"default\"},\"use_selection12\":{\"use\":\"3cf76fbf-fd95-4a33-878e-7aff6d36b7f6\",\"as\":\"default\"},\"use_selection13\":{\"use\":\"640b5352-fb09-425f-a26e-cd44eda03f15\",\"as\":\"default\"}}', '', 1, '2021-11-06 13:25:19', '2022-09-20 11:53:22', 77, 1), -(5, 1, '', '', '', 'db4a1e4d-be59-4e87-8b4d-c40512752232', 'dXNlIEpvb21sYVxDTVNcSHR0cFxIdHRwIGFzIEJhc2VIdHRwOw0KdXNlIEpvb21sYVxDTVNcSHR0cFxIdHRwRmFjdG9yeTsNCnVzZSBKb29tbGFcUmVnaXN0cnlcUmVnaXN0cnk7', '', '', '{\"load_selection0\":{\"load\":\"aa253bac-f4b4-41b4-8ace-071a73fc4d96\"},\"load_selection1\":{\"load\":\"c65aaf1f-817c-49a2-8202-282e3904f5b1\"},\"load_selection2\":{\"load\":\"51195163-1e87-4251-b755-a03c376798a6\"},\"load_selection3\":{\"load\":\"ef011ee1-64f0-4048-b013-777473b727dd\"},\"load_selection4\":{\"load\":\"c4a188de-ad78-4a6d-9d5b-01866846d701\"}}', 'CS8qKg0KCSAqIE9wdGlvbnMgZm9yIHRoZSBHaXRlYSBvYmplY3QuDQoJICoNCgkgKiBAdmFyICAgIGFycmF5DQoJICogQHNpbmNlICAxLjANCgkgKi8NCglwcm90ZWN0ZWQgJG9wdGlvbnM7DQoNCgkvKioNCgkgKiBUaGUgSFRUUCBjbGllbnQgb2JqZWN0IHRvIHVzZSBpbiBzZW5kaW5nIEhUVFAgcmVxdWVzdHMuDQoJICoNCgkgKiBAdmFyICAgIEJhc2VIdHRwDQoJICogQHNpbmNlICAxLjANCgkgKi8NCglwcm90ZWN0ZWQgJGNsaWVudDsNCg0KCS8qKg0KCSAqIENvbnN0cnVjdG9yLg0KCSAqDQoJICogQHBhcmFtICAgUmVnaXN0cnkgICRvcHRpb25zICBHaXRlYSBvcHRpb25zIG9iamVjdC4NCgkgKiBAcGFyYW0gICBIdHRwICAgICAgJGNsaWVudCAgIFRoZSBIVFRQIGNsaWVudCBvYmplY3QuDQoJICoNCgkgKiBAc2luY2UgICAxLjANCgkgKi8NCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoUmVnaXN0cnkgJG9wdGlvbnMgPSBudWxsLCBCYXNlSHR0cCAkY2xpZW50ID0gbnVsbCkNCgl7DQoJCSR0aGlzLT5vcHRpb25zID0gJG9wdGlvbnMgPzogbmV3IFJlZ2lzdHJ5Ow0KDQoJCS8vIFNldHVwIHRoZSBkZWZhdWx0IHVzZXIgYWdlbnQgaWYgbm90IGFscmVhZHkgc2V0Lg0KCQlpZiAoISR0aGlzLT5nZXRPcHRpb24oJ3VzZXJBZ2VudCcpKQ0KCQl7DQoJCQkkdGhpcy0+c2V0T3B0aW9uKCd1c2VyQWdlbnQnLCAnSkdpdGVhLzEuMCcpOw0KCQl9DQoNCgkJLy8gU2V0dXAgdGhlIGRlZmF1bHQgQVBJIHVybCBpZiBub3QgYWxyZWFkeSBzZXQuDQoJCWlmICghJHRoaXMtPmdldE9wdGlvbignYXBpLnVybCcpKQ0KCQl7DQoJCQkkdGhpcy0+c2V0T3B0aW9uKCdhcGkudXJsJywgJ1tbW2dpdGVhX2FwaV91cmxdXV0nKTsNCgkJfQ0KDQoJCSR0aGlzLT5jbGllbnQgPSAkY2xpZW50ID86IChuZXcgSHR0cEZhY3RvcnkpLT5nZXRIdHRwKCR0aGlzLT5vcHRpb25zKTsNCgl9DQoNCgkvKioNCgkgKiBNYWdpYyBtZXRob2QgdG8gbGF6aWx5IGNyZWF0ZSBBUEkgb2JqZWN0cw0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nICAkbmFtZSAgTmFtZSBvZiBwcm9wZXJ0eSB0byByZXRyaWV2ZQ0KCSAqDQoJICogQHJldHVybiAgQWJzdHJhY3RHaXRlYU9iamVjdCAgR2l0ZWEgQVBJIG9iamVjdCAoaXNzdWVzLCBwdWxscywgZXRjKS4NCgkgKg0KCSAqIEBzaW5jZSAgIDEuMA0KCSAqIEB0aHJvd3MgIFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24gSWYgJG5hbWUgaXMgbm90IGEgdmFsaWQgc3ViIGNsYXNzLg0KCSAqLw0KCXB1YmxpYyBmdW5jdGlvbiBfX2dldCgkbmFtZSkNCgl7DQoJCSRjbGFzcyA9ICdcXFZETVxcR2l0ZWFcXFBhY2thZ2VcXCcgLiB1Y2ZpcnN0KCRuYW1lKTsNCg0KCQlpZiAoY2xhc3NfZXhpc3RzKCRjbGFzcykpDQoJCXsNCgkJCWlmIChpc3NldCgkdGhpcy0+JG5hbWUpID09IGZhbHNlKQ0KCQkJew0KCQkJCSR0aGlzLT4kbmFtZSA9IG5ldyAkY2xhc3MoJHRoaXMtPm9wdGlvbnMsICR0aGlzLT5jbGllbnQpOw0KCQkJfQ0KDQoJCQlyZXR1cm4gJHRoaXMtPiRuYW1lOw0KCQl9DQoNCgkJdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignQXJndW1lbnQgJXMgcHJvZHVjZWQgYW4gaW52YWxpZCBjbGFzcyBuYW1lOiAlcycsICRuYW1lLCAkY2xhc3MpKTsNCgl9DQoNCgkvKioNCgkgKiBHZXQgYW4gb3B0aW9uIGZyb20gdGhlIEdpdGVhIGluc3RhbmNlLg0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nICAka2V5ICBUaGUgbmFtZSBvZiB0aGUgb3B0aW9uIHRvIGdldC4NCgkgKg0KCSAqIEByZXR1cm4gIG1peGVkICBUaGUgb3B0aW9uIHZhbHVlLg0KCSAqDQoJICogQHNpbmNlICAgMS4wDQoJICovDQoJcHVibGljIGZ1bmN0aW9uIGdldE9wdGlvbigka2V5KQ0KCXsNCgkJcmV0dXJuIGlzc2V0KCR0aGlzLT5vcHRpb25zWyRrZXldKSA/ICR0aGlzLT5vcHRpb25zWyRrZXldIDogbnVsbDsNCgl9DQoNCgkvKioNCgkgKiBTZXQgYW4gb3B0aW9uIGZvciB0aGUgR2l0ZWEgaW5zdGFuY2UuDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICRrZXkgICAgVGhlIG5hbWUgb2YgdGhlIG9wdGlvbiB0byBzZXQuDQoJICogQHBhcmFtICAgbWl4ZWQgICAkdmFsdWUgIFRoZSBvcHRpb24gdmFsdWUgdG8gc2V0Lg0KCSAqDQoJICogQHJldHVybiAgR2l0ZWEgIFRoaXMgb2JqZWN0IGZvciBtZXRob2QgY2hhaW5pbmcuDQoJICoNCgkgKiBAc2luY2UgICAxLjANCgkgKi8NCglwdWJsaWMgZnVuY3Rpb24gc2V0T3B0aW9uKCRrZXksICR2YWx1ZSkNCgl7DQoJCSR0aGlzLT5vcHRpb25zWyRrZXldID0gJHZhbHVlOw0KDQoJCXJldHVybiAkdGhpczsNCgl9DQo=', '{}', 'Gitea', 'VDM\\Gitea\\Gitea', '1.0.0', '{}', 'Gitea', 'class', '{}', '', 1, '2021-12-03 14:18:38', '2022-09-20 10:09:29', 28, 4), -(6, 1, '', '', '', 'aa253bac-f4b4-41b4-8ace-071a73fc4d96', 'dXNlIEpvb21sYVxDTVNcSHR0cFxIdHRwIGFzIEJhc2VIdHRwOw0KdXNlIEpvb21sYVxDTVNcSHR0cFxIdHRwRmFjdG9yeTsNCnVzZSBKb29tbGFcQ01TXEh0dHBcUmVzcG9uc2U7DQp1c2UgSm9vbWxhXFJlZ2lzdHJ5XFJlZ2lzdHJ5Ow0KdXNlIEpvb21sYVxVcmlcVXJpOw==', '', '', '{}', 'CS8qKg0KCSAqIE9wdGlvbnMgZm9yIHRoZSBHaXRlYSBvYmplY3QuDQoJICoNCgkgKiBAdmFyICAgIFJlZ2lzdHJ5DQoJICogQHNpbmNlICAxLjANCgkgKi8NCglwcm90ZWN0ZWQgJG9wdGlvbnM7DQoNCgkvKioNCgkgKiBUaGUgSFRUUCBjbGllbnQgb2JqZWN0IHRvIHVzZSBpbiBzZW5kaW5nIEhUVFAgcmVxdWVzdHMuDQoJICoNCgkgKiBAdmFyICAgIEJhc2VIdHRwDQoJICogQHNpbmNlICAxLjANCgkgKi8NCglwcm90ZWN0ZWQgJGNsaWVudDsNCg0KCS8qKg0KCSAqIFRoZSBwYWNrYWdlIHRoZSBvYmplY3QgcmVzaWRlcyBpbg0KCSAqDQoJICogQHZhciAgICBzdHJpbmcNCgkgKiBAc2luY2UgIDEuMA0KCSAqLw0KCXByb3RlY3RlZCAkcGFja2FnZSA9ICcnOw0KDQoJLyoqDQoJICogQ29uc3RydWN0b3IuDQoJICoNCgkgKiBAcGFyYW0gICBSZWdpc3RyeSAgJG9wdGlvbnMgIEdpdGVhIG9wdGlvbnMgb2JqZWN0Lg0KCSAqIEBwYXJhbSAgIEJhc2VIdHRwICAkY2xpZW50ICAgVGhlIEhUVFAgY2xpZW50IG9iamVjdC4NCgkgKg0KCSAqIEBzaW5jZSAgIDEuMA0KCSAqLw0KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChSZWdpc3RyeSAkb3B0aW9ucyA9IG51bGwsIEJhc2VIdHRwICRjbGllbnQgPSBudWxsKQ0KCXsNCgkJJHRoaXMtPm9wdGlvbnMgPSAkb3B0aW9ucyA/OiBuZXcgUmVnaXN0cnk7DQoJCSR0aGlzLT5jbGllbnQgID0gJGNsaWVudCA/OiAobmV3IEh0dHBGYWN0b3J5KS0+Z2V0SHR0cCgkdGhpcy0+b3B0aW9ucyk7DQoNCgkJJHRoaXMtPnBhY2thZ2UgPSBzdGF0aWM6OmNsYXNzOw0KCQkkdGhpcy0+cGFja2FnZSA9IHN1YnN0cigkdGhpcy0+cGFja2FnZSwgc3RycnBvcygkdGhpcy0+cGFja2FnZSwgJ1xcJykgKyAxKTsNCgl9DQoNCgkvKioNCgkgKiBNZXRob2QgdG8gYnVpbGQgYW5kIHJldHVybiBhIGZ1bGwgcmVxdWVzdCBVUkwgZm9yIHRoZSByZXF1ZXN0LiAgVGhpcyBtZXRob2Qgd2lsbA0KCSAqIGFkZCBhcHByb3ByaWF0ZSBwYWdpbmF0aW9uIGRldGFpbHMgaWYgbmVjZXNzYXJ5IGFuZCBhbHNvIHByZXBlbmQgdGhlIEFQSSB1cmwNCgkgKiB0byBoYXZlIGEgY29tcGxldGUgVVJMIGZvciB0aGUgcmVxdWVzdC4NCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICRwYXRoICAgVVJMIHRvIGluZmxlY3QNCgkgKiBAcGFyYW0gICBpbnRlZ2VyICAkcGFnZSAgIFBhZ2UgdG8gcmVxdWVzdA0KCSAqIEBwYXJhbSAgIGludGVnZXIgICRsaW1pdCAgTnVtYmVyIG9mIHJlc3VsdHMgdG8gcmV0dXJuIHBlciBwYWdlDQoJICoNCgkgKiBAcmV0dXJuICBVcmkNCgkgKg0KCSAqIEBzaW5jZSAgIDEuMA0KCSAqLw0KCXByb3RlY3RlZCBmdW5jdGlvbiBmZXRjaFVybCgkcGF0aCwgJHBhZ2UgPSAwLCAkbGltaXQgPSAwKQ0KCXsNCgkJLy8gR2V0IGEgbmV3IFVyaSBvYmplY3QgZm9jdXNpbmcgdGhlIGFwaSB1cmwgYW5kIGdpdmVuIHBhdGguDQoJCSR1cmkgPSBuZXcgVXJpKCR0aGlzLT5vcHRpb25zLT5nZXQoJ2FwaS51cmwnKSAuICRwYXRoKTsNCg0KCQlpZiAoJHRoaXMtPm9wdGlvbnMtPmdldCgnYWNjZXNzLnRva2VuJywgZmFsc2UpKQ0KCQl7DQoJCQkvLyBVc2Ugb0F1dGggYXV0aGVudGljYXRpb24NCgkJCSRoZWFkZXJzID0gJHRoaXMtPmNsaWVudC0+Z2V0T3B0aW9uKCdoZWFkZXJzJywgW10pOw0KDQoJCQlpZiAoIWlzc2V0KCRoZWFkZXJzWydBdXRob3JpemF0aW9uJ10pKQ0KCQkJew0KCQkJCSRoZWFkZXJzWydBdXRob3JpemF0aW9uJ10gPSAndG9rZW4gJyAuICR0aGlzLT5vcHRpb25zLT5nZXQoJ2FjY2Vzcy50b2tlbicpOw0KCQkJCSR0aGlzLT5jbGllbnQtPnNldE9wdGlvbignaGVhZGVycycsICRoZWFkZXJzKTsNCgkJCX0NCgkJfQ0KCQllbHNlDQoJCXsNCgkJCS8vIFVzZSBiYXNpYyBhdXRoZW50aWNhdGlvbg0KCQkJaWYgKCR0aGlzLT5vcHRpb25zLT5nZXQoJ2FwaS51c2VybmFtZScsIGZhbHNlKSkNCgkJCXsNCgkJCQkkdXJpLT5zZXRVc2VyKCR0aGlzLT5vcHRpb25zLT5nZXQoJ2FwaS51c2VybmFtZScpKTsNCgkJCX0NCg0KCQkJaWYgKCR0aGlzLT5vcHRpb25zLT5nZXQoJ2FwaS5wYXNzd29yZCcsIGZhbHNlKSkNCgkJCXsNCgkJCQkkdXJpLT5zZXRQYXNzKCR0aGlzLT5vcHRpb25zLT5nZXQoJ2FwaS5wYXNzd29yZCcpKTsNCgkJCX0NCgkJfQ0KDQoJCS8vIElmIHdlIGhhdmUgYSBkZWZpbmVkIHBhZ2UgbnVtYmVyIGFkZCBpdCB0byB0aGUgSlVyaSBvYmplY3QuDQoJCWlmICgkcGFnZSA+IDApDQoJCXsNCgkJCSR1cmktPnNldFZhcigncGFnZScsIChpbnQpICRwYWdlKTsNCgkJfQ0KDQoJCS8vIElmIHdlIGhhdmUgYSBkZWZpbmVkIGl0ZW1zIHBlciBwYWdlIGFkZCBpdCB0byB0aGUgSlVyaSBvYmplY3QuDQoJCWlmICgkbGltaXQgPiAwKQ0KCQl7DQoJCQkkdXJpLT5zZXRWYXIoJ2xpbWl0JywgKGludCkgJGxpbWl0KTsNCgkJfQ0KDQoJCXJldHVybiAkdXJpOw0KCX0NCg0KCS8qKg0KCSAqIFByb2Nlc3MgdGhlIHJlc3BvbnNlIGFuZCBkZWNvZGUgaXQuDQoJICoNCgkgKiBAcGFyYW0gICBSZXNwb25zZSAgJHJlc3BvbnNlICAgICAgVGhlIHJlc3BvbnNlLg0KCSAqIEBwYXJhbSAgIGludGVnZXIgICAkZXhwZWN0ZWRDb2RlICBUaGUgZXhwZWN0ZWQgImdvb2QiIGNvZGUuDQoJICoNCgkgKiBAcmV0dXJuICBtaXhlZA0KCSAqDQoJICogQHNpbmNlICAgMS4wDQoJICogQHRocm93cyAgUnVudGltZUV4Y2VwdGlvbg0KCSAqLw0KCXByb3RlY3RlZCBmdW5jdGlvbiBwcm9jZXNzUmVzcG9uc2UoUmVzcG9uc2UgJHJlc3BvbnNlLCAkZXhwZWN0ZWRDb2RlID0gMjAwKQ0KCXsNCgkJLy8gVmFsaWRhdGUgdGhlIHJlc3BvbnNlIGNvZGUuDQoJCWlmICgkcmVzcG9uc2UtPmNvZGUgIT0gJGV4cGVjdGVkQ29kZSkNCgkJew0KCQkJLy8gRGVjb2RlIHRoZSBlcnJvciByZXNwb25zZSBhbmQgdGhyb3cgYW4gZXhjZXB0aW9uLg0KCQkJJGVycm9yICAgPSBqc29uX2RlY29kZSgoc3RyaW5nKSAkcmVzcG9uc2UtPmJvZHkpOw0KCQkJJG1lc3NhZ2UgPSBpc3NldCgkZXJyb3ItPm1lc3NhZ2UpID8gJGVycm9yLT5tZXNzYWdlIDogJ0ludmFsaWQgcmVzcG9uc2UgcmVjZWl2ZWQgZnJvbSBHaXRlYS4nOw0KDQoJCQl0aHJvdyBuZXcgXERvbWFpbkV4Y2VwdGlvbigkbWVzc2FnZSwgJHJlc3BvbnNlLT5jb2RlKTsNCgkJfQ0KDQoJCWlmIChKc29uSGVscGVyOjpjaGVjaygkcmVzcG9uc2UtPmJvZHkpKQ0KCQl7DQoJCQkkYm9keSA9IGpzb25fZGVjb2RlKChzdHJpbmcpICRyZXNwb25zZS0+Ym9keSk7DQoNCgkJCWlmIChpc3NldCgkYm9keS0+Y29udGVudF9iYXNlNjQpKQ0KCQkJew0KCQkJCSRib2R5LT5jb250ZW50ID0gYmFzZTY0X2RlY29kZSgoc3RyaW5nKSAkYm9keS0+Y29udGVudF9iYXNlNjQpOw0KCQkJfQ0KCQl9DQoJCWVsc2UNCgkJew0KCQkJJGJvZHkgPSAkcmVzcG9uc2UtPmJvZHk7DQoJCX0NCg0KCQlyZXR1cm4gJGJvZHk7DQoJfQ0K', '{}', 'AbstractGiteaObject', 'VDM\\Gitea\\AbstractGiteaObject', '1.0.0', '{}', 'Abstract Gitea Object', 'abstract class', '{\"use_selection0\":{\"use\":\"4b225c51-d293-48e4-b3f6-5136cf5c3f18\",\"as\":\"default\"}}', '', 1, '2021-12-03 16:00:26', '2023-02-02 15:45:30', 22, 4), -(7, 1, '', 'aa253bac-f4b4-41b4-8ace-071a73fc4d96', '', 'c65aaf1f-817c-49a2-8202-282e3904f5b1', 'dXNlIEpvb21sYVxDTVNcSHR0cFxIdHRwIGFzIEJhc2VIdHRwOw0KdXNlIEpvb21sYVxSZWdpc3RyeVxSZWdpc3RyeTs=', '', '', '{}', 'CS8qKg0KCSAqIENvbnN0cnVjdG9yLg0KCSAqDQoJICogQHBhcmFtICAgUmVnaXN0cnkgICRvcHRpb25zICBHaXRlYSBvcHRpb25zIG9iamVjdC4NCgkgKiBAcGFyYW0gICBIdHRwICAgICAgJGNsaWVudCAgIFRoZSBIVFRQIGNsaWVudCBvYmplY3QuDQoJICoNCgkgKiBAc2luY2UgICAxLjANCgkgKi8NCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoUmVnaXN0cnkgJG9wdGlvbnMgPSBudWxsLCBCYXNlSHR0cCAkY2xpZW50ID0gbnVsbCkNCgl7DQoJCXBhcmVudDo6X19jb25zdHJ1Y3QoJG9wdGlvbnMsICRjbGllbnQpOw0KDQoJCSR0aGlzLT5wYWNrYWdlID0gc3RhdGljOjpjbGFzczsNCgkJJHRoaXMtPnBhY2thZ2UgPSBzdWJzdHIoJHRoaXMtPnBhY2thZ2UsIHN0cnJwb3MoJHRoaXMtPnBhY2thZ2UsICdcXCcpICsgMSk7DQoJfQ0KDQoJLyoqDQoJICogTWFnaWMgbWV0aG9kIHRvIGxhemlseSBjcmVhdGUgQVBJIG9iamVjdHMNCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJG5hbWUgIE5hbWUgb2YgcHJvcGVydHkgdG8gcmV0cmlldmUNCgkgKg0KCSAqIEBzaW5jZSAgIDEuMA0KCSAqIEB0aHJvd3MgXEludmFsaWRBcmd1bWVudEV4Y2VwdGlvbg0KCSAqDQoJICogQHJldHVybiAgQWJzdHJhY3RQYWNrYWdlICBHaXRlYSBBUEkgcGFja2FnZSBvYmplY3QuDQoJICovDQoJcHVibGljIGZ1bmN0aW9uIF9fZ2V0KCRuYW1lKQ0KCXsNCgkJJGNsYXNzID0gJ1xcVkRNXFxHaXRlYVxcUGFja2FnZVxcJyAuICR0aGlzLT5wYWNrYWdlIC4gJ1xcJyAuIHVjZmlyc3QoJG5hbWUpOw0KDQoJCWlmIChjbGFzc19leGlzdHMoJGNsYXNzKSA9PSBmYWxzZSkNCgkJew0KCQkJdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oDQoJCQkJc3ByaW50ZigNCgkJCQkJJ0FyZ3VtZW50ICUxJHMgcHJvZHVjZWQgYW4gaW52YWxpZCBjbGFzcyBuYW1lOiAlMiRzIGluIHBhY2thZ2UgJTMkcycsDQoJCQkJCSRuYW1lLCAkY2xhc3MsICR0aGlzLT5wYWNrYWdlDQoJCQkJKQ0KCQkJKTsNCgkJfQ0KDQoJCWlmIChpc3NldCgkdGhpcy0+JG5hbWUpID09IGZhbHNlKQ0KCQl7DQoJCQkkdGhpcy0+JG5hbWUgPSBuZXcgJGNsYXNzKCR0aGlzLT5vcHRpb25zLCAkdGhpcy0+Y2xpZW50KTsNCgkJfQ0KDQoJCXJldHVybiAkdGhpcy0+JG5hbWU7DQoJfQ0K', '{}', 'AbstractPackage', 'VDM\\Gitea\\AbstractPackage', '1.0.0', '{}', 'Abstract Gitea Package', 'abstract class', '{}', '', 1, '2021-12-03 16:03:06', '2023-02-02 15:45:48', 17, 4), -(8, 1, '', 'c65aaf1f-817c-49a2-8202-282e3904f5b1', '', '51195163-1e87-4251-b755-a03c376798a6', 'dXNlIEpvb21sYVxDTVNcSHR0cFxIdHRwOw0KdXNlIEpvb21sYVxSZWdpc3RyeVxSZWdpc3RyeTs=', '', '', '{}', 'CS8qKg0KCSAqIExpc3QgeW91ciByZXBvc2l0b3JpZXMuDQoJICoNCgkgKiBMaXN0IHJlcG9zaXRvcmllcyBmb3IgdGhlIGF1dGhlbnRpY2F0ZWQgdXNlci4NCgkgKg0KCSAqIEByZXR1cm4gIG9iamVjdA0KCSAqDQoJICogQHNpbmNlICAgMS4wDQoJICovDQoJcHVibGljIGZ1bmN0aW9uIGdldExpc3RPd24oKQ0KCXsNCgkJLy8gQnVpbGQgdGhlIHJlcXVlc3QgcGF0aC4NCgkJJHVyaSA9ICR0aGlzLT5mZXRjaFVybCgnL3VzZXIvcmVwb3MnKTsNCg0KCQkvLyBTZW5kIHRoZSByZXF1ZXN0Lg0KCQlyZXR1cm4gJHRoaXMtPnByb2Nlc3NSZXNwb25zZSgkdGhpcy0+Y2xpZW50LT5nZXQoJHVyaSkpOw0KCX0NCg0KCS8qKg0KCSAqIExpc3QgdXNlciByZXBvc2l0b3JpZXMuDQoJICoNCgkgKiBMaXN0IHB1YmxpYyByZXBvc2l0b3JpZXMgZm9yIHRoZSBzcGVjaWZpZWQgdXNlci4NCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJHVzZXIgICAgICAgVGhlIHVzZXIgbmFtZS4NCgkgKg0KCSAqIEByZXR1cm4gIG9iamVjdA0KCSAqDQoJICogQHNpbmNlICAgMS4wDQoJICovDQoJcHVibGljIGZ1bmN0aW9uIGdldExpc3RVc2VyKCR1c2VyKQ0KCXsNCgkJLy8gQnVpbGQgdGhlIHJlcXVlc3QgcGF0aC4NCgkJJHVyaSA9ICR0aGlzLT5mZXRjaFVybCgnL3VzZXJzLycgLiAkdXNlciAuICcvcmVwb3MnKTsNCg0KCQkvLyBTZW5kIHRoZSByZXF1ZXN0Lg0KCQlyZXR1cm4gJHRoaXMtPnByb2Nlc3NSZXNwb25zZSgkdGhpcy0+Y2xpZW50LT5nZXQoJHVyaSkpOw0KCX0NCg0KCS8qKg0KCSAqIExpc3Qgb3JnYW5pemF0aW9uIHJlcG9zaXRvcmllcy4NCgkgKg0KCSAqIExpc3QgcmVwb3NpdG9yaWVzIGZvciB0aGUgc3BlY2lmaWVkIG9yZy4NCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJG9yZyAgIFRoZSBuYW1lIG9mIHRoZSBvcmdhbml6YXRpb24uDQoJICoNCgkgKiBAcmV0dXJuICBvYmplY3QNCgkgKg0KCSAqIEBzaW5jZSAgIDEuMA0KCSAqLw0KCXB1YmxpYyBmdW5jdGlvbiBnZXRMaXN0T3JnKCRvcmcpDQoJew0KCQkvLyBCdWlsZCB0aGUgcmVxdWVzdCBwYXRoLg0KCQkkdXJpID0gJHRoaXMtPmZldGNoVXJsKCcvb3Jncy8nIC4gJG9yZyAuICcvcmVwb3MnKTsNCg0KCQkvLyBTZW5kIHRoZSByZXF1ZXN0Lg0KCQlyZXR1cm4gJHRoaXMtPnByb2Nlc3NSZXNwb25zZSgkdGhpcy0+Y2xpZW50LT5nZXQoJHVyaSkpOw0KCX0NCg0KCS8qKg0KCSAqIENyZWF0ZS4NCgkgKg0KCSAqIENyZWF0ZSBhIG5ldyByZXBvc2l0b3J5IGZvciB0aGUgYXV0aGVudGljYXRlZCB1c2VyIG9yIGFuIG9yZ2FuaXphdGlvbi4gT0F1dGggdXNlcnMgbXVzdCBzdXBwbHkgcmVwbyBzY29wZS4NCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICRuYW1lICAgICAgICAgICAgICAgVGhlIHJlcG9zaXRvcnkgbmFtZS4NCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkb3JnICAgICAgICAgICAgICAgIFRoZSBvcmdhbml6YXRpb24gbmFtZSAoaWYgbmVlZGVkKS4NCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkZGVzY3JpcHRpb24gICAgICAgIFRoZSByZXBvc2l0b3J5IGRlc2NyaXB0aW9uLg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICRyZWFkbWUgICAgICAgICAgICAgUmVhZG1lIG9mIHRoZSByZXBvc2l0b3J5IHRvIGNyZWF0ZS4NCgkgKiBAcGFyYW0gICBib29sZWFuICAkcHJpdmF0ZSAgICAgICAgICAgIFNldCB0cnVlIHRvIGNyZWF0ZSBhIHByaXZhdGUgcmVwb3NpdG9yeSwgZmFsc2UgdG8gY3JlYXRlIGEgcHVibGljIG9uZS4NCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkZGVmYXVsdEJyYW5jaCAgICAgIERlZmF1bHRCcmFuY2ggb2YgdGhlIHJlcG9zaXRvcnkgKHVzZWQgd2hlbiBpbml0aWFsaXplcyBhbmQgaW4gdGVtcGxhdGUpLg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICRsaWNlbnNlICAgICAgICAgICAgTGljZW5zZSB0byB1c2UuDQoJICogQHBhcmFtICAgYm9vbGVhbiAgJGF1dG9Jbml0ICAgICAgICAgICBXaGV0aGVyIHRoZSByZXBvc2l0b3J5IHNob3VsZCBhdXRvIGluaXQuDQoJICogQHBhcmFtICAgYm9vbGVhbiAgJHRlbXBsYXRlICAgICAgICAgICBXaGV0aGVyIHRoZSByZXBvc2l0b3J5IGlzIHRlbXBsYXRlLg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICRnaXRpZ25vcmVzICAgICAgICAgR2l0aWdub3JlcyB0byB1c2UuDQoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnM6IFsgSm9vbWxhLCBKZXRCcmFpbnMgXSBhbmQgbXVjaCBtb3JlLi4uDQoJICogQHBhcmFtICAgc3RyaW5nICAgJGlzc3VlTGFiZWxzICAgICAgICBMYWJlbC1TZXQgdG8gdXNlLg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICR0cnVzdE1vZGVsICAgICAgICAgVHJ1c3RNb2RlbCBvZiB0aGUgcmVwb3NpdG9yeS4NCgkgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uczogWyBkZWZhdWx0LCBjb2xsYWJvcmF0b3IsIGNvbW1pdHRlciwgY29sbGFib3JhdG9yY29tbWl0dGVyIF0NCgkgKg0KCSAqIEByZXR1cm4gIG9iamVjdA0KCSAqDQoJICogQHNpbmNlICAgMS4wDQoJICovDQoJcHVibGljIGZ1bmN0aW9uIGNyZWF0ZSgkbmFtZSwgJG9yZyA9ICcnLCAkZGVzY3JpcHRpb24gPSAnJywgJHJlYWRtZSA9ICdEZWZhdWx0JywgJHByaXZhdGUgPSBmYWxzZSwgJGRlZmF1bHRCcmFuY2ggPSAnbWFzdGVyJywNCgkJJGxpY2Vuc2UgPSAnR1BMLTIuMC1vci1sYXRlcicsICRhdXRvSW5pdCA9IHRydWUsICR0ZW1wbGF0ZSA9IGZhbHNlLCAkdHJ1c3RNb2RlbCA9ICdkZWZhdWx0JywgJGdpdGlnbm9yZXMgPSAnJywgJGlzc3VlTGFiZWxzID0gJycNCgkpDQoJew0KCQkkcGF0aCA9ICgkb3JnKQ0KCQkJLy8gQ3JlYXRlIGEgcmVwb3NpdG9yeSBmb3IgYW4gb3JnYW5pemF0aW9uDQoJCQk/ICcvb3Jncy8nIC4gJG9yZyAuICcvcmVwb3MnDQoJCQkvLyBDcmVhdGUgYSByZXBvc2l0b3J5IGZvciBhIHVzZXINCgkJCTogJy91c2VyL3JlcG9zJzsNCg0KCQkkZGF0YSA9IFsNCgkJCSduYW1lJyAgICAgICAgICAgICAgID0+ICRuYW1lLA0KCQkJJ2Rlc2NyaXB0aW9uJyAgICAgICAgPT4gJGRlc2NyaXB0aW9uLA0KCQkJJ3JlYWRtZScgICAgICAgICAgICAgPT4gJHJlYWRtZSwNCgkJCSdwcml2YXRlJyAgICAgICAgICAgID0+ICRwcml2YXRlLA0KCQkJJ2F1dG9faW5pdCcgICAgICAgICAgPT4gJGF1dG9Jbml0LA0KCQkJJ2RlZmF1bHRfYnJhbmNoJyAgICAgPT4gJGRlZmF1bHRCcmFuY2gsDQoJCQknaXNzdWVfbGFiZWxzJyAgICAgICA9PiAkaXNzdWVMYWJlbHMsDQoJCQknbGljZW5zZScgICAgICAgICAgICA9PiAkbGljZW5zZSwNCgkJCSd0ZW1wbGF0ZScgICAgICAgICAgID0+ICR0ZW1wbGF0ZSwNCgkJCSdnaXRpZ25vcmVzJyAgICAgICAgID0+ICRnaXRpZ25vcmVzLA0KCQkJJ3RydXN0X21vZGVsJyAgICAgICAgPT4gJHRydXN0TW9kZWwNCgkJXTsNCg0KCQkvLyBTZW5kIHRoZSByZXF1ZXN0Lg0KCQlyZXR1cm4gJHRoaXMtPnByb2Nlc3NSZXNwb25zZSgNCgkJCSR0aGlzLT5jbGllbnQtPnBvc3QoJHRoaXMtPmZldGNoVXJsKCRwYXRoKSwganNvbl9lbmNvZGUoJGRhdGEpKSwNCgkJCTIwMQ0KCQkpOw0KCX0NCg0KCS8qKg0KCSAqIEdldC4NCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJG93bmVyICBSZXBvc2l0b3J5IG93bmVyLg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJHJlcG8gICBSZXBvc2l0b3J5IG5hbWUuDQoJICoNCgkgKiBAcmV0dXJuICBvYmplY3QNCgkgKg0KCSAqIEBzaW5jZSAgIDEuMA0KCSAqLw0KCXB1YmxpYyBmdW5jdGlvbiBnZXQoJG93bmVyLCAkcmVwbykNCgl7DQoJCS8vIEJ1aWxkIHRoZSByZXF1ZXN0IHBhdGguDQoJCSRwYXRoID0gJy9yZXBvcy8nIC4gJG93bmVyIC4gJy8nIC4gJHJlcG87DQoNCgkJLy8gU2VuZCB0aGUgcmVxdWVzdC4NCgkJcmV0dXJuICR0aGlzLT5wcm9jZXNzUmVzcG9uc2UoDQoJCQkkdGhpcy0+Y2xpZW50LT5nZXQoJHRoaXMtPmZldGNoVXJsKCRwYXRoKSkNCgkJKTsNCgl9DQoNCgkvKioNCgkgKiBMaXN0IGNvbnRyaWJ1dG9ycy4NCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICRvd25lciAgUmVwb3NpdG9yeSBvd25lci4NCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkcmVwbyAgIFJlcG9zaXRvcnkgbmFtZS4NCgkgKg0KCSAqIEByZXR1cm4gIG9iamVjdA0KCSAqDQoJICogQHNpbmNlICAgMS4wDQoJICovDQoJcHVibGljIGZ1bmN0aW9uIGdldExpc3RDb250cmlidXRvcnMoJG93bmVyLCAkcmVwbykNCgl7DQoJCS8vIEJ1aWxkIHRoZSByZXF1ZXN0IHBhdGguDQoJCSR1cmkgPSAkdGhpcy0+ZmV0Y2hVcmwoJy9yZXBvcy8nIC4gJG93bmVyIC4gJy8nIC4gJHJlcG8gLiAnL2NvbnRyaWJ1dG9ycycpOw0KDQoJCS8vIFNlbmQgdGhlIHJlcXVlc3QuDQoJCXJldHVybiAkdGhpcy0+cHJvY2Vzc1Jlc3BvbnNlKCR0aGlzLT5jbGllbnQtPmdldCgkdXJpKSk7DQoJfQ0KDQoJLyoqDQoJICogTGlzdCBsYW5ndWFnZXMuDQoJICoNCgkgKiBMaXN0IGxhbmd1YWdlcyBmb3IgdGhlIHNwZWNpZmllZCByZXBvc2l0b3J5LiBUaGUgdmFsdWUgb24gdGhlIHJpZ2h0IG9mIGEgbGFuZ3VhZ2UgaXMgdGhlIG51bWJlciBvZiBieXRlcyBvZiBjb2RlDQoJICogd3JpdHRlbiBpbiB0aGF0IGxhbmd1YWdlLg0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nICAkb3duZXIgIFJlcG9zaXRvcnkgb3duZXIuDQoJICogQHBhcmFtICAgc3RyaW5nICAkcmVwbyAgIFJlcG9zaXRvcnkgbmFtZS4NCgkgKg0KCSAqIEByZXR1cm4gIG9iamVjdA0KCSAqDQoJICogQHNpbmNlICAgMS4wDQoJICovDQoJcHVibGljIGZ1bmN0aW9uIGdldExpc3RMYW5ndWFnZXMoJG93bmVyLCAkcmVwbykNCgl7DQoJCS8vIEJ1aWxkIHRoZSByZXF1ZXN0IHBhdGguDQoJCSRwYXRoID0gJy9yZXBvcy8nIC4gJG93bmVyIC4gJy8nIC4gJHJlcG8gLiAnL2xhbmd1YWdlcyc7DQoNCgkJLy8gU2VuZCB0aGUgcmVxdWVzdC4NCgkJcmV0dXJuICR0aGlzLT5wcm9jZXNzUmVzcG9uc2UoDQoJCQkkdGhpcy0+Y2xpZW50LT5nZXQoJHRoaXMtPmZldGNoVXJsKCRwYXRoKSkNCgkJKTsNCgl9DQoNCgkvKioNCgkgKiBMaXN0IFRlYW1zDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICRvd25lciAgUmVwb3NpdG9yeSBvd25lci4NCgkgKiBAcGFyYW0gICBzdHJpbmcgICRyZXBvICAgUmVwb3NpdG9yeSBuYW1lLg0KCSAqDQoJICogQHJldHVybiAgb2JqZWN0DQoJICoNCgkgKiBAc2luY2UgICAxLjANCgkgKi8NCglwdWJsaWMgZnVuY3Rpb24gZ2V0TGlzdFRlYW1zKCRvd25lciwgJHJlcG8pDQoJew0KCQkvLyBCdWlsZCB0aGUgcmVxdWVzdCBwYXRoLg0KCQkkcGF0aCA9ICcvcmVwb3MvJyAuICRvd25lciAuICcvJyAuICRyZXBvIC4gJy90ZWFtcyc7DQoNCgkJLy8gU2VuZCB0aGUgcmVxdWVzdC4NCgkJcmV0dXJuICR0aGlzLT5wcm9jZXNzUmVzcG9uc2UoDQoJCQkkdGhpcy0+Y2xpZW50LT5nZXQoJHRoaXMtPmZldGNoVXJsKCRwYXRoKSkNCgkJKTsNCgl9DQoNCgkvKioNCgkgKiBMaXN0IFRhZ3MuDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkb3duZXIgIFJlcG9zaXRvcnkgb3duZXIuDQoJICogQHBhcmFtICAgc3RyaW5nICAgJHJlcG8gICBSZXBvc2l0b3J5IG5hbWUuDQoJICogQHBhcmFtICAgaW50ZWdlciAgJHBhZ2UgICBQYWdlIHRvIHJlcXVlc3QNCgkgKiBAcGFyYW0gICBpbnRlZ2VyICAkbGltaXQgIE51bWJlciBvZiByZXN1bHRzIHRvIHJldHVybiBwZXIgcGFnZQ0KCSAqDQoJICogQHJldHVybiAgb2JqZWN0DQoJICoNCgkgKiBAc2luY2UgICAxLjANCgkgKi8NCglwdWJsaWMgZnVuY3Rpb24gZ2V0TGlzdFRhZ3MoJG93bmVyLCAkcmVwbywgJHBhZ2UgPSAwLCAkbGltaXQgPSAwKQ0KCXsNCgkJLy8gQnVpbGQgdGhlIHJlcXVlc3QgcGF0aC4NCgkJJHBhdGggPSAnL3JlcG9zLycgLiAkb3duZXIgLiAnLycgLiAkcmVwbyAuICcvdGFncyc7DQoNCgkJLy8gU2VuZCB0aGUgcmVxdWVzdC4NCgkJcmV0dXJuICR0aGlzLT5wcm9jZXNzUmVzcG9uc2UoDQoJCQkkdGhpcy0+Y2xpZW50LT5nZXQoJHRoaXMtPmZldGNoVXJsKCRwYXRoLCAkcGFnZSwgJGxpbWl0KSkNCgkJKTsNCgl9DQoNCgkvKioNCgkgKiBEZWxldGUgYSBSZXBvc2l0b3J5Lg0KCSAqDQoJICogRGVsZXRpbmcgYSByZXBvc2l0b3J5IHJlcXVpcmVzIGFkbWluIGFjY2Vzcy4gSWYgT0F1dGggaXMgdXNlZCwgdGhlIGRlbGV0ZV9yZXBvIHNjb3BlIGlzIHJlcXVpcmVkLg0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nICAkb3duZXIgIFJlcG9zaXRvcnkgb3duZXIuDQoJICogQHBhcmFtICAgc3RyaW5nICAkcmVwbyAgIFJlcG9zaXRvcnkgbmFtZS4NCgkgKg0KCSAqIEByZXR1cm4gIG9iamVjdA0KCSAqDQoJICogQHNpbmNlICAgMS4wDQoJICovDQoJcHVibGljIGZ1bmN0aW9uIGRlbGV0ZSgkb3duZXIsICRyZXBvKQ0KCXsNCgkJLy8gQnVpbGQgdGhlIHJlcXVlc3QgcGF0aC4NCgkJJHBhdGggPSAnL3JlcG9zLycgLiAkb3duZXIgLiAnLycgLiAkcmVwbzsNCg0KCQkvLyBTZW5kIHRoZSByZXF1ZXN0Lg0KCQlyZXR1cm4gJHRoaXMtPnByb2Nlc3NSZXNwb25zZSgNCgkJCSR0aGlzLT5jbGllbnQtPmRlbGV0ZSgkdGhpcy0+ZmV0Y2hVcmwoJHBhdGgpKQ0KCQkpOw0KCX0NCg==', '{}', 'Repo', 'VDM\\Gitea\\Package.Repo', '1.0.0', '{}', 'Gitea Repo', 'class', '{}', '', 1, '2021-12-03 16:37:20', '2022-07-09 10:28:45', 13, 4), -(9, 1, '', '', '', '011813ba-8dd2-4beb-98f9-50ab3f3665d1', 'dXNlIEpvb21sYVxDTVNcSHR0cFxIdHRwIGFzIEJhc2VIdHRwOw0KdXNlIEpvb21sYVxDTVNcSHR0cFxIdHRwRmFjdG9yeTsNCnVzZSBKb29tbGFcUmVnaXN0cnlcUmVnaXN0cnk7', '', '', '{\"load_selection0\":{\"load\":\"aa253bac-f4b4-41b4-8ace-071a73fc4d96\"},\"load_selection1\":{\"load\":\"c65aaf1f-817c-49a2-8202-282e3904f5b1\"},\"load_selection2\":{\"load\":\"51195163-1e87-4251-b755-a03c376798a6\"}}', 'CS8qKg0KCSAqIE9wdGlvbnMgZm9yIHRoZSBbW1tBcGldXV0gb2JqZWN0Lg0KCSAqDQoJICogQHZhciAgICBhcnJheQ0KCSAqIEBzaW5jZSAgMS4wDQoJICovDQoJcHJvdGVjdGVkICRvcHRpb25zOw0KDQoJLyoqDQoJICogVGhlIEhUVFAgY2xpZW50IG9iamVjdCB0byB1c2UgaW4gc2VuZGluZyBIVFRQIHJlcXVlc3RzLg0KCSAqDQoJICogQHZhciAgICBCYXNlSHR0cA0KCSAqIEBzaW5jZSAgMS4wDQoJICovDQoJcHJvdGVjdGVkICRjbGllbnQ7DQoNCgkvKioNCgkgKiBDb25zdHJ1Y3Rvci4NCgkgKg0KCSAqIEBwYXJhbSAgIFJlZ2lzdHJ5ICAkb3B0aW9ucyAgW1tbQXBpXV1dIG9wdGlvbnMgb2JqZWN0Lg0KCSAqIEBwYXJhbSAgIEh0dHAgICAgICAkY2xpZW50ICAgVGhlIEhUVFAgY2xpZW50IG9iamVjdC4NCgkgKg0KCSAqIEBzaW5jZSAgIDEuMA0KCSAqLw0KCXB1YmxpYyBmdW5jdGlvbiBfX2NvbnN0cnVjdChSZWdpc3RyeSAkb3B0aW9ucyA9IG51bGwsIEJhc2VIdHRwICRjbGllbnQgPSBudWxsKQ0KCXsNCgkJJHRoaXMtPm9wdGlvbnMgPSAkb3B0aW9ucyA/OiBuZXcgUmVnaXN0cnk7DQoNCgkJLy8gU2V0dXAgdGhlIGRlZmF1bHQgdXNlciBhZ2VudCBpZiBub3QgYWxyZWFkeSBzZXQuDQoJCWlmICghJHRoaXMtPmdldE9wdGlvbigndXNlckFnZW50JykpDQoJCXsNCgkJCSR0aGlzLT5zZXRPcHRpb24oJ3VzZXJBZ2VudCcsICdKW1tbQXBpXV1dLzEuMCcpOw0KCQl9DQoNCgkJLy8gU2V0dXAgdGhlIGRlZmF1bHQgQVBJIHVybCBpZiBub3QgYWxyZWFkeSBzZXQuDQoJCWlmICghJHRoaXMtPmdldE9wdGlvbignYXBpLnVybCcpKQ0KCQl7DQoJCQkkdGhpcy0+c2V0T3B0aW9uKCdhcGkudXJsJywgJ1tbW3Jvb3RfYXBpX3VybF1dXScpOw0KCQl9DQoNCgkJJHRoaXMtPmNsaWVudCA9ICRjbGllbnQgPzogKG5ldyBIdHRwRmFjdG9yeSktPmdldEh0dHAoJHRoaXMtPm9wdGlvbnMpOw0KCX0NCg0KCS8qKg0KCSAqIE1hZ2ljIG1ldGhvZCB0byBsYXppbHkgY3JlYXRlIEFQSSBvYmplY3RzDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICRuYW1lICBOYW1lIG9mIHByb3BlcnR5IHRvIHJldHJpZXZlDQoJICoNCgkgKiBAcmV0dXJuICBBYnN0cmFjdFtbW0FwaV1dXU9iamVjdCAgW1tbQXBpXV1dIEFQSSBvYmplY3QgKGlzc3VlcywgcHVsbHMsIGV0YykuDQoJICoNCgkgKiBAc2luY2UgICAxLjANCgkgKiBAdGhyb3dzICBcSW52YWxpZEFyZ3VtZW50RXhjZXB0aW9uIElmICRuYW1lIGlzIG5vdCBhIHZhbGlkIHN1YiBjbGFzcy4NCgkgKi8NCglwdWJsaWMgZnVuY3Rpb24gX19nZXQoJG5hbWUpDQoJew0KCQkkY2xhc3MgPSAnXFxbW1tDT01QQU5ZXV1dXFxbW1tBcGldXV1cXFBhY2thZ2VcXCcgLiB1Y2ZpcnN0KCRuYW1lKTsNCg0KCQlpZiAoY2xhc3NfZXhpc3RzKCRjbGFzcykpDQoJCXsNCgkJCWlmIChpc3NldCgkdGhpcy0+JG5hbWUpID09IGZhbHNlKQ0KCQkJew0KCQkJCSR0aGlzLT4kbmFtZSA9IG5ldyAkY2xhc3MoJHRoaXMtPm9wdGlvbnMsICR0aGlzLT5jbGllbnQpOw0KCQkJfQ0KDQoJCQlyZXR1cm4gJHRoaXMtPiRuYW1lOw0KCQl9DQoNCgkJdGhyb3cgbmV3IFxJbnZhbGlkQXJndW1lbnRFeGNlcHRpb24oc3ByaW50ZignQXJndW1lbnQgJXMgcHJvZHVjZWQgYW4gaW52YWxpZCBjbGFzcyBuYW1lOiAlcycsICRuYW1lLCAkY2xhc3MpKTsNCgl9DQoNCgkvKioNCgkgKiBHZXQgYW4gb3B0aW9uIGZyb20gdGhlIFtbW0FwaV1dXSBpbnN0YW5jZS4NCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJGtleSAgVGhlIG5hbWUgb2YgdGhlIG9wdGlvbiB0byBnZXQuDQoJICoNCgkgKiBAcmV0dXJuICBtaXhlZCAgVGhlIG9wdGlvbiB2YWx1ZS4NCgkgKg0KCSAqIEBzaW5jZSAgIDEuMA0KCSAqLw0KCXB1YmxpYyBmdW5jdGlvbiBnZXRPcHRpb24oJGtleSkNCgl7DQoJCXJldHVybiBpc3NldCgkdGhpcy0+b3B0aW9uc1ska2V5XSkgPyAkdGhpcy0+b3B0aW9uc1ska2V5XSA6IG51bGw7DQoJfQ0KDQoJLyoqDQoJICogU2V0IGFuIG9wdGlvbiBmb3IgdGhlIFtbW0FwaV1dXSBpbnN0YW5jZS4NCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZyAgJGtleSAgICBUaGUgbmFtZSBvZiB0aGUgb3B0aW9uIHRvIHNldC4NCgkgKiBAcGFyYW0gICBtaXhlZCAgICR2YWx1ZSAgVGhlIG9wdGlvbiB2YWx1ZSB0byBzZXQuDQoJICoNCgkgKiBAcmV0dXJuICBbW1tBcGldXV0gIFRoaXMgb2JqZWN0IGZvciBtZXRob2QgY2hhaW5pbmcuDQoJICoNCgkgKiBAc2luY2UgICAxLjANCgkgKi8NCglwdWJsaWMgZnVuY3Rpb24gc2V0T3B0aW9uKCRrZXksICR2YWx1ZSkNCgl7DQoJCSR0aGlzLT5vcHRpb25zWyRrZXldID0gJHZhbHVlOw0KDQoJCXJldHVybiAkdGhpczsNCgl9DQo=', '{}', '[[[Api]]]', '[[[COMPANY]]]\\[[[Api]]]\\[[[Api]]]', '1.0.0', '{}', 'API', 'class', '{}', '', 1, '2022-01-05 00:44:15', '2022-09-20 10:09:49', 6, 4), -(10, 1, 'Control the naming of a field\r\n\r\n@since 3.0.9', '', '', '9ef0eb24-aae4-4f5a-99af-d724db44808f', 'dXNlIEpvb21sYVxDTVNcQ29tcG9uZW50XENvbXBvbmVudEhlbHBlcjs=', '', '', '{}', 'CS8qKg0KCSAqIFRoZSBmaWVsZCBidWlsZGVyIHN3aXRjaA0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwcm90ZWN0ZWQgc3RhdGljICRidWlsZGVyID0gZmFsc2U7DQoNCgkvKioNCgkgKiBNYWtpbmcgZmllbGQgbmFtZXMgc2FmZQ0KCSAqDQoJICogQGlucHV0CXN0cmluZyAgICAgICBUaGUgc3RyaW5nIHlvdSB3b3VsZCBsaWtlIHRvIG1ha2Ugc2FmZQ0KCSAqIEBpbnB1dAlib29sZWFuICAgICAgVGhlIHN3aXRjaCB0byByZXR1cm4gYW4gQUxMIFVQUEVSIENBU0Ugc3RyaW5nDQoJICogQGlucHV0CXN0cmluZyAgICAgICBUaGUgc3RyaW5nIHRvIHVzZSBpbiB3aGl0ZSBzcGFjZQ0KCSAqDQoJICogQHJldHVybnMgc3RyaW5nIG9uIHN1Y2Nlc3MNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzYWZlKCRzdHJpbmcsICRhbGxjYXAgPSBmYWxzZSwgJHNwYWNlciA9ICdfJykNCgl7DQoJCS8vIGdldCBnbG9iYWwgdmFsdWUNCgkJaWYgKHNlbGY6OiRidWlsZGVyID09PSBmYWxzZSkNCgkJew0KCQkJc2VsZjo6JGJ1aWxkZXIgPSBIZWxwZXI6OmdldFBhcmFtcygpLT5nZXQoJ2ZpZWxkX25hbWVfYnVpbGRlcicsIDEpOw0KCQl9DQoNCgkJLy8gdXNlIHRoZSBuZXcgY29udmVudGlvbg0KCQlpZiAoMiA9PSBzZWxmOjokYnVpbGRlcikNCgkJew0KCQkJLy8gMG5seSBjb250aW51ZSBpZiB3ZSBoYXZlIGEgc3RyaW5nDQoJCQlpZiAoU3RyaW5nSGVscGVyOjpjaGVjaygkc3RyaW5nKSkNCgkJCXsNCgkJCQkvLyBjaGVjayB0aGF0IHRoZSBmaXJzdCBjaGFyYWN0ZXIgaXMgbm90IGEgbnVtYmVyDQoJCQkJaWYgKGlzX251bWVyaWMoc3Vic3RyKChzdHJpbmcpJHN0cmluZywgMCwgMSkpKQ0KCQkJCXsNCgkJCQkJJHN0cmluZyA9IFN0cmluZ0hlbHBlcjo6bnVtYmVycygkc3RyaW5nKTsNCgkJCQl9DQoNCgkJCQkvLyByZW1vdmUgYWxsIG90aGVyIHN0cmFuZ2UgY2hhcmFjdGVycw0KCQkJCSRzdHJpbmcgPSB0cmltKChzdHJpbmcpICRzdHJpbmcpOw0KCQkJCSRzdHJpbmcgPSBwcmVnX3JlcGxhY2UoJy8nLiRzcGFjZXIuJysvJywgJyAnLCAkc3RyaW5nKTsNCgkJCQkkc3RyaW5nID0gcHJlZ19yZXBsYWNlKCcvXHMrLycsICcgJywgJHN0cmluZyk7DQoNCgkJCQkvLyBUcmFuc2xpdGVyYXRlIHN0cmluZw0KCQkJCSRzdHJpbmcgPSBTdHJpbmdIZWxwZXI6OnRyYW5zbGl0ZXJhdGUoJHN0cmluZyk7DQoNCgkJCQkvLyByZW1vdmUgYWxsIGFuZCBrZWVwIG9ubHkgY2hhcmFjdGVycyBhbmQgbnVtYmVycw0KCQkJCSRzdHJpbmcgPSBwcmVnX3JlcGxhY2UoIi9bXkEtWmEtejAtOSBdLyIsICcnLCAoc3RyaW5nKSAkc3RyaW5nKTsNCg0KCQkJCS8vIHJlcGxhY2Ugd2hpdGUgc3BhY2Ugd2l0aCB1bmRlcnNjb3JlIChTQUZFU1QgT1BUSU9OKQ0KCQkJCSRzdHJpbmcgPSBwcmVnX3JlcGxhY2UoJy9ccysvJywgKHN0cmluZykgJHNwYWNlciwgJHN0cmluZyk7DQoNCgkJCQkvLyByZXR1cm4gYWxsIGNhcHMNCgkJCQlpZiAoJGFsbGNhcCkNCgkJCQl7DQoJCQkJCXJldHVybiBzdHJ0b3VwcGVyKCRzdHJpbmcpOw0KCQkJCX0NCg0KCQkJCS8vIGRlZmF1bHQgaXMgdG8gcmV0dXJuIGxvd2VyDQoJCQkJcmV0dXJuIHN0cnRvbG93ZXIoJHN0cmluZyk7DQoJCQl9DQoJCQkvLyBub3QgYSBzdHJpbmcNCgkJCXJldHVybiAnJzsNCgkJfQ0KDQoJCS8vIHJldHVybiBhbGwgY2Fwcw0KCQlpZiAoJGFsbGNhcCkNCgkJew0KCQkJcmV0dXJuIFN0cmluZ0hlbHBlcjo6c2FmZSgkc3RyaW5nLCAnVScpOw0KCQl9DQoNCgkJLy8gdXNlIHRoZSBkZWZhdWx0IChvcmlnaW5hbCBiZWhhdmlvci9jb252ZW50aW9uKQ0KCQlyZXR1cm4gU3RyaW5nSGVscGVyOjpzYWZlKCRzdHJpbmcpOw0KCX0NCg==', '{}', 'FieldHelper', 'VDM\\Joomla\\Utilities.String.FieldHelper', '1.0.0', '{}', 'String Field 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 20:46:56', '2023-01-14 18:06:18', 22, 5), -(11, '', 'The json checker\r\n\r\n@since 3.0.9', '', '', '4b225c51-d293-48e4-b3f6-5136cf5c3f18', '', '', '', '{\"load_selection0\":{\"load\":\"1f28cb53-60d9-4db1-b517-3c7dc6b429ef\"},\"load_selection1\":{\"load\":\"0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a\"},\"load_selection2\":{\"load\":\"db87c339-5bb6-4291-a7ef-2c48ea1b06bc\"}}', 'CS8qKg0KCSAqIENoZWNrIGlmIHlvdSBoYXZlIGEganNvbiBzdHJpbmcNCgkgKg0KCSAqIEBpbnB1dCAgICBzdHJpbmcgICRzdHJpbmcgIFRoZSBqc29uIHN0cmluZyB0byBjaGVjaw0KCSAqDQoJICogQHJldHVybnMgYm9vbCB0cnVlIG9uIHN1Y2Nlc3MNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBjaGVjaygkc3RyaW5nKTogYm9vbA0KCXsNCgkJaWYgKFN0cmluZ0hlbHBlcjo6Y2hlY2soJHN0cmluZykpDQoJCXsNCgkJCWpzb25fZGVjb2RlKChzdHJpbmcpICRzdHJpbmcpOw0KCQkJcmV0dXJuIChqc29uX2xhc3RfZXJyb3IoKSA9PT0gSlNPTl9FUlJPUl9OT05FKTsNCgkJfQ0KDQoJCXJldHVybiBmYWxzZTsNCgl9DQoNCgkvKioNCgkgKiBDb252ZXJ0IGEganNvbiBvYmplY3QgdG8gYSBzdHJpbmcNCgkgKg0KCSAqIEBpbnB1dCAgICBzdHJpbmcgICR2YWx1ZSAgVGhlIGpzb24gc3RyaW5nIHRvIGNvbnZlcnQNCgkgKg0KCSAqIEByZXR1cm5zIGEgc3RyaW5nDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc3RyaW5nKCR2YWx1ZSwgJHNlcGFyYXRvciA9ICIsICIsICR0YWJsZSA9IG51bGwsICRpZCA9ICdpZCcsICRuYW1lID0gJ25hbWUnKQ0KCXsNCgkJLy8gZG8gc29tZSB0YWJsZSBmb290IHdvcmsNCgkJJGV4dGVybmFsID0gZmFsc2U7DQoJCWlmIChpc19zdHJpbmcoJHRhYmxlKSAmJiBzdHJwb3MoKHN0cmluZykgJHRhYmxlLCAnI19fJykgIT09IGZhbHNlKQ0KCQl7DQoJCQkkZXh0ZXJuYWwgPSB0cnVlOw0KCQkJJHRhYmxlID0gc3RyX3JlcGxhY2UoJyNfXycsICcnLCAoc3RyaW5nKSAkdGFibGUpOw0KCQl9DQoNCgkJLy8gY2hlY2sgaWYgc3RyaW5nIGlzIEpTT04NCgkJJHJlc3VsdCA9IGpzb25fZGVjb2RlKChzdHJpbmcpICR2YWx1ZSwgdHJ1ZSk7DQoJCWlmIChqc29uX2xhc3RfZXJyb3IoKSA9PT0gSlNPTl9FUlJPUl9OT05FKQ0KCQl7DQoJCQkvLyBpcyBKU09ODQoJCQlpZiAoQXJyYXlIZWxwZXI6OmNoZWNrKCRyZXN1bHQpKQ0KCQkJew0KCQkJCWlmIChTdHJpbmdIZWxwZXI6OmNoZWNrKCR0YWJsZSkpDQoJCQkJew0KCQkJCQkkbmFtZXMgPSBbXTsNCgkJCQkJZm9yZWFjaCAoJHJlc3VsdCBhcyAkdmFsKQ0KCQkJCQl7DQoJCQkJCQlpZiAoJGV4dGVybmFsKQ0KCQkJCQkJew0KCQkJCQkJCWlmICgkX25hbWUgPSBHZXRIZWxwZXI6OnZhcihudWxsLCAkdmFsLCAkaWQsICRuYW1lLCAnPScsICR0YWJsZSkpDQoJCQkJCQkJew0KCQkJCQkJCQkkbmFtZXNbXSA9ICRfbmFtZTsNCgkJCQkJCQl9DQoJCQkJCQl9DQoJCQkJCQllbHNlDQoJCQkJCQl7DQoJCQkJCQkJaWYgKCRfbmFtZSA9IEdldEhlbHBlcjo6dmFyKCR0YWJsZSwgJHZhbCwgJGlkLCAkbmFtZSkpDQoJCQkJCQkJew0KCQkJCQkJCQkkbmFtZXNbXSA9ICRfbmFtZTsNCgkJCQkJCQl9DQoJCQkJCQl9DQoJCQkJCX0NCgkJCQkJaWYgKEFycmF5SGVscGVyOjpjaGVjaygkbmFtZXMpKQ0KCQkJCQl7DQoJCQkJCQlyZXR1cm4gKHN0cmluZykgaW1wbG9kZSgkc2VwYXJhdG9yLCAkbmFtZXMpOw0KCQkJCQl9CQ0KCQkJCX0NCgkJCQlyZXR1cm4gKHN0cmluZykgaW1wbG9kZSgkc2VwYXJhdG9yLCAkcmVzdWx0KTsNCgkJCX0NCgkJCXJldHVybiAoc3RyaW5nKSBqc29uX2RlY29kZSgoc3RyaW5nKSAkdmFsdWUpOw0KCQl9DQoJCXJldHVybiAkdmFsdWU7DQoJfQ0K', '{}', 'JsonHelper', 'VDM\\Joomla\\Utilities.JsonHelper', '1.0.0', '{}', 'Utilities Json Helper', 'abstract class', '{}', '', 1, '2022-03-08 21:03:54', '2023-01-14 18:11:18', 22, 6), -(12, 1, 'Some string tricks\r\n\r\n@since 3.0.9', '', '', '1f28cb53-60d9-4db1-b517-3c7dc6b429ef', 'dXNlIEpvb21sYVxDTVNcRmlsdGVyXElucHV0RmlsdGVyOw0KdXNlIEpvb21sYVxDTVNcTGFuZ3VhZ2VcTGFuZ3VhZ2U7', '', '', '{\"load_selection0\":{\"load\":\"0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a\"}}', 'CS8qKg0KCSAqIFRoZSBNYWluIEFjdGl2ZSBMYW5ndWFnZQ0KCSAqIA0KCSAqIEB2YXIgICAgICBzdHJpbmcNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyAkbGFuZ1RhZzsNCg0KCS8qKg0KCSAqIENoZWNrIGlmIHdlIGhhdmUgYSBzdHJpbmcgd2l0aCBhIGxlbmd0aA0KCSAqDQoJICogQGlucHV0ICAgIHN0cmluZyAgJHN0cmluZyBUaGUgc3RyaW5nIHRvIGNoZWNrDQoJICoNCgkgKiBAcmV0dXJucyBib29sIHRydWUgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNoZWNrKCRzdHJpbmcpOiBib29sDQoJew0KCQlyZXR1cm4gaXNfc3RyaW5nKCRzdHJpbmcpICYmIHN0cmxlbigkc3RyaW5nKSA+IDA7DQoJfQ0KDQoJLyoqDQoJICogU2hvcnRlbiBhIHN0cmluZw0KCSAqDQoJICogQGlucHV0CXN0cmluZyAgIFRoZSB5b3Ugd291bGQgbGlrZSB0byBzaG9ydGVuDQoJICoNCgkgKiBAcmV0dXJucyBzdHJpbmcgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNob3J0ZW4oJHN0cmluZywgJGxlbmd0aCA9IDQwLCAkYWRkVGlwID0gdHJ1ZSkNCgl7DQoJCWlmIChzZWxmOjpjaGVjaygkc3RyaW5nKSkNCgkJew0KCQkJJGluaXRpYWwgPSBzdHJsZW4oKHN0cmluZykgJHN0cmluZyk7DQoJCQkkd29yZHMgPSBwcmVnX3NwbGl0KCcvKFtcc1xuXHJdKykvJywgKHN0cmluZykgJHN0cmluZywgbnVsbCwgUFJFR19TUExJVF9ERUxJTV9DQVBUVVJFKTsNCgkJCSR3b3Jkc19jb3VudCA9IGNvdW50KChhcnJheSkkd29yZHMpOw0KDQoJCQkkd29yZF9sZW5ndGggPSAwOw0KCQkJJGxhc3Rfd29yZCA9IDA7DQoJCQlmb3IgKDsgJGxhc3Rfd29yZCA8ICR3b3Jkc19jb3VudDsgKyskbGFzdF93b3JkKQ0KCQkJew0KCQkJCSR3b3JkX2xlbmd0aCArPSBzdHJsZW4oJHdvcmRzWyRsYXN0X3dvcmRdKTsNCgkJCQlpZiAoJHdvcmRfbGVuZ3RoID4gJGxlbmd0aCkNCgkJCQl7DQoJCQkJCWJyZWFrOw0KCQkJCX0NCgkJCX0NCg0KCQkJJG5ld1N0cmluZwk9IGltcGxvZGUoYXJyYXlfc2xpY2UoJHdvcmRzLCAwLCAkbGFzdF93b3JkKSk7DQoJCQkkZmluYWwJPSBzdHJsZW4oJG5ld1N0cmluZyk7DQoJCQlpZiAoJGluaXRpYWwgIT09ICRmaW5hbCAmJiAkYWRkVGlwKQ0KCQkJew0KCQkJCSR0aXRsZSA9IHNlbGY6OnNob3J0ZW4oJHN0cmluZywgNDAwICwgZmFsc2UpOw0KCQkJCXJldHVybiAnPHNwYW4gY2xhc3M9Imhhc1RpcCIgdGl0bGU9IicgLiAkdGl0bGUgLiAnIiBzdHlsZT0iY3Vyc29yOmhlbHAiPicgLiB0cmltKCRuZXdTdHJpbmcpIC4gJy4uLjwvc3Bhbj4nOw0KCQkJfQ0KCQkJZWxzZWlmICgkaW5pdGlhbCAhPT0gJGZpbmFsICYmICEkYWRkVGlwKQ0KCQkJew0KCQkJCXJldHVybiB0cmltKCRuZXdTdHJpbmcpIC4gJy4uLic7DQoJCQl9DQoJCX0NCgkJcmV0dXJuICRzdHJpbmc7DQoJfQ0KDQoJLyoqDQoJICogTWFraW5nIHN0cmluZ3Mgc2FmZSAodmFyaW91cyB3YXlzKQ0KCSAqDQoJICogQGlucHV0CXN0cmluZyAgIFRoZSB5b3Ugd291bGQgbGlrZSB0byBtYWtlIHNhZmUNCgkgKg0KCSAqIEByZXR1cm5zIHN0cmluZyBvbiBzdWNjZXNzDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc2FmZSgkc3RyaW5nLCAkdHlwZSA9ICdMJywgJHNwYWNlciA9ICdfJywgJHJlcGxhY2VOdW1iZXJzID0gdHJ1ZSwgJGtlZXBPbmx5Q2hhcmFjdGVycyA9IHRydWUpDQoJew0KCQlpZiAoJHJlcGxhY2VOdW1iZXJzID09PSB0cnVlKQ0KCQl7DQoJCQkvLyByZW1vdmUgYWxsIG51bWJlcnMgYW5kIHJlcGxhY2Ugd2l0aCBFbmdsaXNoIHRleHQgdmVyc2lvbiAod29ya3Mgd2VsbCBvbmx5IHVwIHRvIG1pbGxpb25zKQ0KCQkJJHN0cmluZyA9IHNlbGY6Om51bWJlcnMoJHN0cmluZyk7DQoJCX0NCgkJLy8gMG5seSBjb250aW51ZSBpZiB3ZSBoYXZlIGEgc3RyaW5nDQoJCWlmIChzZWxmOjpjaGVjaygkc3RyaW5nKSkNCgkJew0KCQkJLy8gY3JlYXRlIGZpbGUgbmFtZSB3aXRob3V0IHRoZSBleHRlbnNpb24gdGhhdCBpcyBzYWZlDQoJCQlpZiAoJHR5cGUgPT09ICdmaWxlbmFtZScpDQoJCQl7DQoJCQkJLy8gbWFrZSBzdXJlIFZETSBpcyBub3QgaW4gdGhlIHN0cmluZw0KCQkJCSRzdHJpbmcgPSBzdHJfcmVwbGFjZSgnVkRNJywgJ3ZEbScsIChzdHJpbmcpICRzdHJpbmcpOw0KCQkJCS8vIFJlbW92ZSBhbnl0aGluZyB3aGljaCBpc24ndCBhIHdvcmQsIHdoaXRlc3BhY2UsIG51bWJlcg0KCQkJCS8vIG9yIGFueSBvZiB0aGUgZm9sbG93aW5nIGNhcmFjdGVycyAtXygpDQoJCQkJLy8gSWYgeW91IGRvbid0IG5lZWQgdG8gaGFuZGxlIG11bHRpLWJ5dGUgY2hhcmFjdGVycw0KCQkJCS8vIHlvdSBjYW4gdXNlIHByZWdfcmVwbGFjZSByYXRoZXIgdGhhbiBtYl9lcmVnX3JlcGxhY2UNCgkJCQkvLyBUaGFua3MgQMWBdWthc3ogUnlzaWFrIQ0KCQkJCS8vICRzdHJpbmcgPSBtYl9lcmVnX3JlcGxhY2UoIihbXlx3XHNcZFwtX1woXCldKSIsICcnLCAkc3RyaW5nKTsNCgkJCQkkc3RyaW5nID0gcHJlZ19yZXBsYWNlKCIoW15cd1xzXGRcLV9cKFwpXSkiLCAnJywgJHN0cmluZyk7DQoNCgkJCQkvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yMDIxNzI5LzE0Mjk2NzcNCgkJCQlyZXR1cm4gcHJlZ19yZXBsYWNlKCcvXHMrLycsICcgJywgKHN0cmluZykgJHN0cmluZyk7DQoJCQl9DQoJCQkvLyByZW1vdmUgYWxsIG90aGVyIGNoYXJhY3RlcnMNCgkJCSRzdHJpbmcgPSB0cmltKChzdHJpbmcpICRzdHJpbmcpOw0KCQkJJHN0cmluZyA9IHByZWdfcmVwbGFjZSgnLycuJHNwYWNlci4nKy8nLCAnICcsICRzdHJpbmcpOw0KCQkJJHN0cmluZyA9IHByZWdfcmVwbGFjZSgnL1xzKy8nLCAnICcsICRzdHJpbmcpOw0KCQkJLy8gVHJhbnNsaXRlcmF0ZSBzdHJpbmcNCgkJCSRzdHJpbmcgPSBzZWxmOjp0cmFuc2xpdGVyYXRlKCRzdHJpbmcpOw0KCQkJLy8gcmVtb3ZlIGFsbCBhbmQga2VlcCBvbmx5IGNoYXJhY3RlcnMNCgkJCWlmICgka2VlcE9ubHlDaGFyYWN0ZXJzKQ0KCQkJew0KCQkJCSRzdHJpbmcgPSBwcmVnX3JlcGxhY2UoIi9bXkEtWmEteiBdLyIsICcnLCAoc3RyaW5nKSAkc3RyaW5nKTsNCgkJCX0NCgkJCS8vIGtlZXAgYm90aCBudW1iZXJzIGFuZCBjaGFyYWN0ZXJzDQoJCQllbHNlDQoJCQl7DQoJCQkJJHN0cmluZyA9IHByZWdfcmVwbGFjZSgiL1teQS1aYS16MC05IF0vIiwgJycsIChzdHJpbmcpICRzdHJpbmcpOw0KCQkJfQ0KCQkJLy8gc2VsZWN0IGZpbmFsIGFkYXB0YXRpb25zDQoJCQlpZiAoJHR5cGUgPT09ICdMJyB8fCAkdHlwZSA9PT0gJ3N0cnRvbG93ZXInKQ0KCQkJew0KCQkJCS8vIHJlcGxhY2Ugd2hpdGUgc3BhY2Ugd2l0aCB1bmRlcnNjb3JlDQoJCQkJJHN0cmluZyA9IHByZWdfcmVwbGFjZSgnL1xzKy8nLCAoc3RyaW5nKSAkc3BhY2VyLCAoc3RyaW5nKSAkc3RyaW5nKTsNCgkJCQkvLyBkZWZhdWx0IGlzIHRvIHJldHVybiBsb3dlcg0KCQkJCXJldHVybiBzdHJ0b2xvd2VyKCRzdHJpbmcpOw0KCQkJfQ0KCQkJZWxzZWlmICgkdHlwZSA9PT0gJ1cnKQ0KCQkJew0KCQkJCS8vIHJldHVybiBhIHN0cmluZyB3aXRoIGFsbCBmaXJzdCBsZXR0ZXIgb2YgZWFjaCB3b3JkIHVwcGVyY2FzZShubyB1bmRlcnNjb3JlKQ0KCQkJCXJldHVybiB1Y3dvcmRzKHN0cnRvbG93ZXIoJHN0cmluZykpOw0KCQkJfQ0KCQkJZWxzZWlmICgkdHlwZSA9PT0gJ3cnIHx8ICR0eXBlID09PSAnd29yZCcpDQoJCQl7DQoJCQkJLy8gcmV0dXJuIGEgc3RyaW5nIHdpdGggYWxsIGxvd2VyY2FzZShubyB1bmRlcnNjb3JlKQ0KCQkJCXJldHVybiBzdHJ0b2xvd2VyKCRzdHJpbmcpOw0KCQkJfQ0KCQkJZWxzZWlmICgkdHlwZSA9PT0gJ1d3JyB8fCAkdHlwZSA9PT0gJ1dvcmQnKQ0KCQkJew0KCQkJCS8vIHJldHVybiBhIHN0cmluZyB3aXRoIGZpcnN0IGxldHRlciBvZiB0aGUgZmlyc3Qgd29yZCB1cHBlcmNhc2UgYW5kIGFsbCB0aGUgcmVzdCBsb3dlcmNhc2Uobm8gdW5kZXJzY29yZSkNCgkJCQlyZXR1cm4gdWNmaXJzdChzdHJ0b2xvd2VyKCRzdHJpbmcpKTsNCgkJCX0NCgkJCWVsc2VpZiAoJHR5cGUgPT09ICdXVycgfHwgJHR5cGUgPT09ICdXT1JEJykNCgkJCXsNCgkJCQkvLyByZXR1cm4gYSBzdHJpbmcgd2l0aCBhbGwgdGhlIHVwcGVyY2FzZShubyB1bmRlcnNjb3JlKQ0KCQkJCXJldHVybiBzdHJ0b3VwcGVyKCRzdHJpbmcpOw0KCQkJfQ0KCQkJZWxzZWlmICgkdHlwZSA9PT0gJ1UnIHx8ICR0eXBlID09PSAnc3RydG91cHBlcicpDQoJCQl7DQoJCQkJCS8vIHJlcGxhY2Ugd2hpdGUgc3BhY2Ugd2l0aCB1bmRlcnNjb3JlDQoJCQkJCSRzdHJpbmcgPSBwcmVnX3JlcGxhY2UoJy9ccysvJywgKHN0cmluZykgJHNwYWNlciwgJHN0cmluZyk7DQoJCQkJCS8vIHJldHVybiBhbGwgdXBwZXINCgkJCQkJcmV0dXJuIHN0cnRvdXBwZXIoJHN0cmluZyk7DQoJCQl9DQoJCQllbHNlaWYgKCR0eXBlID09PSAnRicgfHwgJHR5cGUgPT09ICd1Y2ZpcnN0JykNCgkJCXsNCgkJCQkJLy8gcmVwbGFjZSB3aGl0ZSBzcGFjZSB3aXRoIHVuZGVyc2NvcmUNCgkJCQkJJHN0cmluZyA9IHByZWdfcmVwbGFjZSgnL1xzKy8nLCAoc3RyaW5nKSAkc3BhY2VyLCAkc3RyaW5nKTsNCgkJCQkJLy8gcmV0dXJuIHdpdGggZmlyc3QgY2hhcmFjdGVyIHRvIHVwcGVyDQoJCQkJCXJldHVybiB1Y2ZpcnN0KHN0cnRvbG93ZXIoJHN0cmluZykpOw0KCQkJfQ0KCQkJZWxzZWlmICgkdHlwZSA9PT0gJ2NBJyB8fCAkdHlwZSA9PT0gJ2NBbWVsJyB8fCAkdHlwZSA9PT0gJ2NhbWVsY2FzZScpDQoJCQl7DQoJCQkJLy8gY29udmVydCBhbGwgd29yZHMgdG8gZmlyc3QgbGV0dGVyIHVwcGVyY2FzZQ0KCQkJCSRzdHJpbmcgPSB1Y3dvcmRzKHN0cnRvbG93ZXIoJHN0cmluZykpOw0KCQkJCS8vIHJlbW92ZSB3aGl0ZSBzcGFjZQ0KCQkJCSRzdHJpbmcgPSBwcmVnX3JlcGxhY2UoJy9ccysvJywgJycsICRzdHJpbmcpOw0KCQkJCS8vIG5vdyByZXR1cm4gZmlyc3QgbGV0dGVyIGxvd2VyY2FzZQ0KCQkJCXJldHVybiBsY2ZpcnN0KCRzdHJpbmcpOw0KCQkJfQ0KCQkJLy8gcmV0dXJuIHN0cmluZw0KCQkJcmV0dXJuICRzdHJpbmc7DQoJCX0NCgkJLy8gbm90IGEgc3RyaW5nDQoJCXJldHVybiAnJzsNCgl9DQoNCgkvKioNCgkgKiBDb252ZXJ0IG5vbmUgRW5nbGlzaCBzdHJpbmdzIHRvIGNvZGUgdXNhYmxlIHN0cmluZw0KCSAqDQoJICogQGlucHV0CWFuIHN0cmluZw0KCSAqDQoJICogQHJldHVybnMgYSBzdHJpbmcNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiB0cmFuc2xpdGVyYXRlKCRzdHJpbmcpDQoJew0KCQkvLyBzZXQgdGFnIG9ubHkgb25jZQ0KCQlpZiAoIXNlbGY6OmNoZWNrKHNlbGY6OiRsYW5nVGFnKSkNCgkJew0KCQkJLy8gZ2V0IGdsb2JhbCB2YWx1ZQ0KCQkJc2VsZjo6JGxhbmdUYWcgPSBIZWxwZXI6OmdldFBhcmFtcygpLT5nZXQoJ2xhbmd1YWdlJywgJ2VuLUdCJyk7DQoJCX0NCg0KCQkvLyBUcmFuc2xpdGVyYXRlIG9uIHRoZSBsYW5ndWFnZSByZXF1ZXN0ZWQNCgkJJGxhbmcgPSBMYW5ndWFnZTo6Z2V0SW5zdGFuY2Uoc2VsZjo6JGxhbmdUYWcpOw0KDQoJCXJldHVybiAkbGFuZy0+dHJhbnNsaXRlcmF0ZSgkc3RyaW5nKTsNCgl9DQoNCgkvKioNCgkgKiBtYWtlIHN1cmUgYSBzdHJpbmcgaXMgSFRNTCBzYXZlDQoJICoNCgkgKiBAaW5wdXQJYW4gaHRtbCBzdHJpbmcNCgkgKg0KCSAqIEByZXR1cm5zIGEgc3RyaW5nDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaHRtbCgkdmFyLCAkY2hhcnNldCA9ICdVVEYtOCcsICRzaG9ydGVuID0gZmFsc2UsICRsZW5ndGggPSA0MCwgJGFkZFRpcCA9IHRydWUpDQoJew0KCQlpZiAoc2VsZjo6Y2hlY2soJHZhcikpDQoJCXsNCgkJCSRmaWx0ZXIgPSBuZXcgSW5wdXRGaWx0ZXIoKTsNCgkJCSRzdHJpbmcgPSAkZmlsdGVyLT5jbGVhbigNCgkJCQlodG1sX2VudGl0eV9kZWNvZGUoDQoJCQkJCWh0bWxlbnRpdGllcygNCgkJCQkJCShzdHJpbmcpICR2YXIsDQoJCQkJCQlFTlRfQ09NUEFULA0KCQkJCQkJJGNoYXJzZXQNCgkJCQkJKQ0KCQkJCSksDQoJCQkJJ0hUTUwnDQoJCQkpOw0KCQkJaWYgKCRzaG9ydGVuKQ0KCQkJew0KCQkJCXJldHVybiBzZWxmOjpzaG9ydGVuKCRzdHJpbmcsICRsZW5ndGgsICRhZGRUaXApOw0KCQkJfQ0KCQkJcmV0dXJuICRzdHJpbmc7DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQlyZXR1cm4gJyc7DQoJCX0NCgl9DQoNCgkvKioNCgkgKiBDb252ZXJ0IGFsbCBpbnQgaW4gYSBzdHJpbmcgdG8gYW4gRW5nbGlzaCB3b3JkIHN0cmluZw0KCSAqDQoJICogQGlucHV0CWFuIHN0cmluZyB3aXRoIG51bWJlcnMNCgkgKg0KCSAqIEByZXR1cm5zIGEgc3RyaW5nDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbnVtYmVycygkc3RyaW5nKQ0KCXsNCgkJLy8gc2V0IG51bWJlcnMgYXJyYXkNCgkJJG51bWJlcnMgPSBbXTsNCgkJJHNlYXJjaF9yZXBsYWNlPSBbXTsNCg0KCQkvLyBmaXJzdCBnZXQgYWxsIG51bWJlcnMNCgkJcHJlZ19tYXRjaF9hbGwoJyFcZCshJywgKHN0cmluZykgJHN0cmluZywgJG51bWJlcnMpOw0KDQoJCS8vIGNoZWNrIGlmIHdlIGhhdmUgYW55IG51bWJlcnMNCgkJaWYgKGlzc2V0KCRudW1iZXJzWzBdKSAmJiBBcnJheUhlbHBlcjo6Y2hlY2soJG51bWJlcnNbMF0pKQ0KCQl7DQoJCQlmb3JlYWNoICgkbnVtYmVyc1swXSBhcyAkbnVtYmVyKQ0KCQkJew0KCQkJCSRzZWFyY2hfcmVwbGFjZVskbnVtYmVyXSA9IHNlbGY6Om51bWJlcigoaW50KSRudW1iZXIpOw0KCQkJfQ0KDQoJCQkvLyBub3cgcmVwbGFjZSBudW1iZXJzIGluIHN0cmluZw0KCQkJJHN0cmluZyA9IHN0cl9yZXBsYWNlKGFycmF5X2tleXMoJHNlYXJjaF9yZXBsYWNlKSwgYXJyYXlfdmFsdWVzKCRzZWFyY2hfcmVwbGFjZSksIChzdHJpbmcpICRzdHJpbmcpOw0KDQoJCQkvLyBjaGVjayBpZiB3ZSBtaXNzZWQgYW55LCBzdHJhbmdlIGlmIHdlIGRpZC4NCgkJCXJldHVybiBzZWxmOjpudW1iZXJzKCRzdHJpbmcpOw0KCQl9DQoNCgkJLy8gcmV0dXJuIHRoZSBzdHJpbmcgd2l0aCBubyBudW1iZXJzIHJlbWFpbmluZy4NCgkJcmV0dXJuICRzdHJpbmc7DQoJfQ0KDQoJLyoqDQoJICogQ29udmVydCBhbiBpbnRlZ2VyIGludG8gYW4gRW5nbGlzaCB3b3JkIHN0cmluZw0KCSAqIFRoYW5rcyB0byBUb20gTmljaG9sc29uIDxodHRwOi8vcGhwLm5ldC9tYW51YWwvZW4vZnVuY3Rpb24uc3RydmFsLnBocCM0MTk4OD4NCgkgKg0KCSAqIEBpbnB1dAlhbiBpbnQNCgkgKiBAcmV0dXJucyBhIHN0cmluZw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG51bWJlcigkeCkNCgl7DQoJCSRud29yZHMgPSBhcnJheSggInplcm8iLCAib25lIiwgInR3byIsICJ0aHJlZSIsICJmb3VyIiwgImZpdmUiLCAic2l4IiwgInNldmVuIiwNCgkJCSJlaWdodCIsICJuaW5lIiwgInRlbiIsICJlbGV2ZW4iLCAidHdlbHZlIiwgInRoaXJ0ZWVuIiwNCgkJCSJmb3VydGVlbiIsICJmaWZ0ZWVuIiwgInNpeHRlZW4iLCAic2V2ZW50ZWVuIiwgImVpZ2h0ZWVuIiwNCgkJCSJuaW5ldGVlbiIsICJ0d2VudHkiLCAzMCA9PiAidGhpcnR5IiwgNDAgPT4gImZvcnR5IiwNCgkJCTUwID0+ICJmaWZ0eSIsIDYwID0+ICJzaXh0eSIsIDcwID0+ICJzZXZlbnR5IiwgODAgPT4gImVpZ2h0eSIsDQoJCQk5MCA9PiAibmluZXR5IiApOw0KDQoJCWlmKCFpc19udW1lcmljKCR4KSkNCgkJew0KCQkJJHcgPSAkeDsNCgkJfQ0KCQllbHNlaWYoZm1vZCgkeCwgMSkgIT0gMCkNCgkJew0KCQkJJHcgPSAkeDsNCgkJfQ0KCQllbHNlDQoJCXsNCgkJCWlmKCR4IDwgMCkNCgkJCXsNCgkJCQkkdyA9ICdtaW51cyAnOw0KCQkJCSR4ID0gLSR4Ow0KCQkJfQ0KCQkJZWxzZQ0KCQkJew0KCQkJCSR3ID0gJyc7DQoJCQkJLy8gLi4uIG5vdyAkeCBpcyBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyLg0KCQkJfQ0KDQoJCQlpZigkeCA8IDIxKSAgIC8vIDAgdG8gMjANCgkJCXsNCgkJCQkkdyAuPSAkbndvcmRzWyR4XTsNCgkJCX0NCgkJCWVsc2VpZigkeCA8IDEwMCkgIC8vIDIxIHRvIDk5DQoJCQl7IA0KCQkJCSR3IC49ICRud29yZHNbMTAgKiBmbG9vcigkeC8xMCldOw0KCQkJCSRyID0gZm1vZCgkeCwgMTApOw0KCQkJCWlmKCRyID4gMCkNCgkJCQl7DQoJCQkJCSR3IC49ICcgJyAuICRud29yZHNbJHJdOw0KCQkJCX0NCgkJCX0NCgkJCWVsc2VpZigkeCA8IDEwMDApICAvLyAxMDAgdG8gOTk5DQoJCQl7DQoJCQkJJHcgLj0gJG53b3Jkc1tmbG9vcigkeC8xMDApXSAuJyBodW5kcmVkJzsNCgkJCQkkciA9IGZtb2QoJHgsIDEwMCk7DQoJCQkJaWYoJHIgPiAwKQ0KCQkJCXsNCgkJCQkJJHcgLj0gJyBhbmQgJy4gc2VsZjo6bnVtYmVyKCRyKTsNCgkJCQl9DQoJCQl9DQoJCQllbHNlaWYoJHggPCAxMDAwMDAwKSAgLy8gMTAwMCB0byA5OTk5OTkNCgkJCXsNCgkJCQkkdyAuPSBzZWxmOjpudW1iZXIoZmxvb3IoJHgvMTAwMCkpIC4nIHRob3VzYW5kJzsNCgkJCQkkciA9IGZtb2QoJHgsIDEwMDApOw0KCQkJCWlmKCRyID4gMCkNCgkJCQl7DQoJCQkJCSR3IC49ICcgJzsNCgkJCQkJaWYoJHIgPCAxMDApDQoJCQkJCXsNCgkJCQkJCSR3IC49ICdhbmQgJzsNCgkJCQkJfQ0KCQkJCQkkdyAuPSBzZWxmOjpudW1iZXIoJHIpOw0KCQkJCX0NCgkJCX0gDQoJCQllbHNlIC8vICBtaWxsaW9ucw0KCQkJeyAgICANCgkJCQkkdyAuPSBzZWxmOjpudW1iZXIoZmxvb3IoJHgvMTAwMDAwMCkpIC4nIG1pbGxpb24nOw0KCQkJCSRyID0gZm1vZCgkeCwgMTAwMDAwMCk7DQoJCQkJaWYoJHIgPiAwKQ0KCQkJCXsNCgkJCQkJJHcgLj0gJyAnOw0KCQkJCQlpZigkciA8IDEwMCkNCgkJCQkJew0KCQkJCQkJJHcgLj0gJ2FuZCAnOw0KCQkJCQl9DQoJCQkJCSR3IC49IHNlbGY6Om51bWJlcigkcik7DQoJCQkJfQ0KCQkJfQ0KCQl9DQoJCXJldHVybiAkdzsNCgl9DQoNCgkvKioNCgkgKiBSYW5kb20gS2V5DQoJICoNCgkgKiBAaW5wdXQJIGludCAgJHNpemUgICBUaGUgc2l6ZSBvZiB0aGUgcmFuZG9tIHN0cmluZw0KCSAqDQoJICogQHJldHVybnMgYSBzdHJpbmcNCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiByYW5kb20oaW50ICRzaXplKTogc3RyaW5nDQoJew0KCQkkYmFnID0gImFiY2VmZ2hpamtub3BxcnN0dXd4eXpBQkNEREVGR0hJSktMTE1NTk9QUVJTVFVWVldYWVphYmNkZGVmZ2hpamtsbG1tbm9wcXJzdHV2dnd4eXpBQkNFRkdISUpLTk9QUVJTVFVXWFlaIjsNCgkJJGtleSA9IFtdOw0KCQkkYmFnc2l6ZSA9IHN0cmxlbigkYmFnKSAtIDE7DQoNCgkJZm9yICgkaSA9IDA7ICRpIDwgJHNpemU7ICRpKyspDQoJCXsNCgkJCSRnZXQgPSByYW5kKDAsICRiYWdzaXplKTsNCgkJCSRrZXlbXSA9ICRiYWdbJGdldF07DQoJCX0NCg0KCQlyZXR1cm4gaW1wbG9kZSgka2V5KTsNCgl9DQo=', '{}', 'StringHelper', 'VDM\\Joomla\\Utilities.StringHelper', '1.0.0', '{}', 'Utilities String Helper', 'abstract class', '{\"use_selection0\":{\"use\":\"640b5352-fb09-425f-a26e-cd44eda03f15\",\"as\":\"default\"}}', '', 1, '2022-03-08 21:35:37', '2023-02-26 17:25:05', 32, 7), -(13, '', 'Some array tricks helper\r\n\r\n@since 3.0.9', '', '', '0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a', '', '', '', '{}', 'CS8qKg0KCSAqIENoZWNrIGlmIGhhdmUgYW4gYXJyYXkgd2l0aCBhIGxlbmd0aA0KCSAqDQoJICogQGlucHV0CWFycmF5ICAgVGhlIGFycmF5IHRvIGNoZWNrDQoJICoNCgkgKiBAcmV0dXJucyBpbnR8ZmFsc2UgIG51bWJlciBvZiBpdGVtcyBpbiBhcnJheSBvbiBzdWNjZXNzDQoJICogDQoJICogQHNpbmNlICAzLjIuMA0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gY2hlY2soJGFycmF5LCAkcmVtb3ZlRW1wdHlTdHJpbmcgPSBmYWxzZSkNCgl7DQoJCWlmIChpc19hcnJheSgkYXJyYXkpICYmICgkbnIgPSBjb3VudCgoYXJyYXkpICRhcnJheSkpID4gMCkNCgkJew0KCQkJLy8gYWxzbyBtYWtlIHN1cmUgdGhlIGVtcHR5IHN0cmluZ3MgYXJlIHJlbW92ZWQNCgkJCWlmICgkcmVtb3ZlRW1wdHlTdHJpbmcpDQoJCQl7DQoJCQkJJGFycmF5ID0gYXJyYXlfZmlsdGVyKCRhcnJheSk7DQoNCgkJCQlpZiAoJGFycmF5ID09PSBbXSkNCgkJCQl7DQoJCQkJCXJldHVybiBmYWxzZTsNCgkJCQl9DQoNCgkJCQlyZXR1cm4gY291bnQoJGFycmF5KTsNCgkJCX0NCg0KCQkJcmV0dXJuICRucjsNCgkJfQ0KDQoJCXJldHVybiBmYWxzZTsNCgl9DQoNCgkvKioNCgkgKiBNZXJnZSBhbiBhcnJheSBvZiBhcnJheSdzDQoJICoNCgkgKiBAaW5wdXQJYXJyYXkgICBUaGUgYXJyYXlzIHlvdSB3b3VsZCBsaWtlIHRvIG1lcmdlDQoJICoNCgkgKiBAcmV0dXJucyBhcnJheXxudWxsICBtZXJnZWQgYXJyYXkgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIG1lcmdlKCRhcnJheXMpOiA/YXJyYXkNCgl7DQoJCWlmKHNlbGY6OmNoZWNrKCRhcnJheXMpKQ0KCQl7DQoJCQkkbWVyZ2VkID0gW107DQoJCQlmb3JlYWNoICgkYXJyYXlzIGFzICRhcnJheSkNCgkJCXsNCgkJCQlpZiAoc2VsZjo6Y2hlY2soJGFycmF5KSkNCgkJCQl7DQoJCQkJCSRtZXJnZWQgPSBhcnJheV9tZXJnZSgkbWVyZ2VkLCAkYXJyYXkpOw0KCQkJCX0NCgkJCX0NCgkJCXJldHVybiAkbWVyZ2VkOw0KCQl9DQoJCXJldHVybiBudWxsOw0KCX0NCg0KCS8qKg0KCSAqIENoZWNrIGlmIGFycmF5cyBpbnRlcnNlY3QNCgkgKg0KCSAqIEBpbnB1dAlhcnJheSAgIFRoZSBmaXJzdCBhcnJheQ0KCSAqIEBpbnB1dAlhcnJheSAgIFRoZSBzZWNvbmQgYXJyYXkNCgkgKg0KCSAqIEByZXR1cm5zIGJvb2wgIHRydWUgaWYgaW50ZXJzZWN0IGVsc2UgZmFsc2UNCgkgKiANCgkgKiBAc2luY2UgIDMuMS4xDQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBpbnRlcnNlY3QoJGFfYXJyYXksICRiX2FycmF5KTogYm9vbA0KCXsNCgkJLy8gZmxpcCB0aGUgc2Vjb25kIGFycmF5DQoJCSRiX2FycmF5ID0gYXJyYXlfZmxpcCgkYl9hcnJheSk7DQoNCgkJLy8gbG9vcCB0aGUgZmlyc3QgYXJyYXkNCgkJZm9yZWFjaCAoJGFfYXJyYXkgYXMgJHYpDQoJCXsNCgkJCWlmIChpc3NldCgkYl9hcnJheVskdl0pKQ0KCQkJew0KCQkJCXJldHVybiB0cnVlOw0KCQkJfQ0KCQl9DQoJCXJldHVybiBmYWxzZTsNCgl9DQo=', '{}', 'ArrayHelper', 'VDM\\Joomla\\Utilities.ArrayHelper', '1.0.0', '{}', 'Utilities Array Helper', 'abstract class', '{}', '', 1, '2022-03-08 22:53:52', '2023-02-05 17:36:34', 21, 8), -(14, '', 'Control the naming of a namespace helper\r\n\r\n@since 3.0.9', '', '', 'ce8cf834-6bac-44fb-941c-861f7e046cc0', '', '', '', '{}', 'CS8qKg0KCSAqIE1ha2luZyBuYW1lc3BhY2Ugc2FmZQ0KCSAqDQoJICogQGlucHV0ICAgIHN0cmluZyAgICRzdHJpbmcgICAgICAgICAgIFRoZSB5b3Ugd291bGQgbGlrZSB0byBtYWtlIHNhZmUNCgkgKiBAaW5wdXQgICAgYm9vbCAgICAgJHJlbW92ZU51bWJlcnMgICAgVGhlIHN3aXRjaCB0byByZW1vdmUgbnVtYmVycw0KCSAqDQoJICogQHJldHVybnMgc3RyaW5nIG9uIHN1Y2Nlc3MNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzYWZlKHN0cmluZyAkc3RyaW5nLCBib29sICRyZW1vdmVOdW1iZXJzID0gdHJ1ZSk6IHN0cmluZw0KCXsNCgkJLy8gMG5seSBjb250aW51ZSBpZiB3ZSBoYXZlIGEgc3RyaW5nIHdpdGggbGVuZ3RoDQoJCWlmIChTdHJpbmdIZWxwZXI6OmNoZWNrKCRzdHJpbmcpKQ0KCQl7DQoJCQkvLyBtYWtlIHN1cmUgaXQgaGFzIG5vdCBudW1iZXJzDQoJCQlpZiAoJHJlbW92ZU51bWJlcnMpDQoJCQl7DQoJCQkJJHN0cmluZyA9IFN0cmluZ0hlbHBlcjo6bnVtYmVycygkc3RyaW5nKTsNCgkJCX0NCg0KCQkJLy8gVHJhbnNsaXRlcmF0ZSBzdHJpbmcgVE9ETzogbG9vayBhZ2FpbiBhcyB0aGlzIG1ha2VzIGl0IGxvd2VyY2FzZQ0KCQkJLy8gJHN0cmluZyA9IFN0cmluZ0hlbHBlcjo6dHJhbnNsaXRlcmF0ZSgkc3RyaW5nKTsNCg0KCQkJLy8gZmlyc3QgcmVtb3ZlIGFsbCBbXF0gYmFja3NsYXNoZXMNCgkJCSRzdHJpbmcgPSBzdHJfcmVwbGFjZSgnXFwnLCAnKycsIChzdHJpbmcpICRzdHJpbmcpOw0KDQoJCQkvLyByZW1vdmUgYWxsIGFuZCBrZWVwIG9ubHkgY2hhcmFjdGVycyBhbmQgW1xdIGJhY2tzbGFzaGVzIGluc2lkZSBvZiB0aGUgc3RyaW5nDQoJCQlpZiAoJHJlbW92ZU51bWJlcnMpDQoJCQl7DQoJCQkJJHN0cmluZyA9IHRyaW0oIHByZWdfcmVwbGFjZSgiL1teQS1aYS16XCtdLyIsICcnLCAkc3RyaW5nKSwgJysnKTsNCgkJCX0NCgkJCWVsc2UNCgkJCXsNCgkJCQkkc3RyaW5nID0gdHJpbSggcHJlZ19yZXBsYWNlKCIvW15BLVphLXowLTlcK10vIiwgJycsICRzdHJpbmcpLCAnKycpOw0KCQkJfQ0KDQoJCQkvLyBwbGFjZSB0aGUgW1xdIGJhY2tzbGFzaGVzIGJhY2sNCgkJCXJldHVybiB0cmltKCBwcmVnX3JlcGxhY2UoIi9cKysvIiwgJ1xcJywgJHN0cmluZykpOw0KCQl9DQoNCgkJLy8gbm90IGEgc3RyaW5nDQoJCXJldHVybiAnJzsNCgl9DQo=', '{}', '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', '2023-01-14 18:04:48', 19, 5), -(15, 1, 'Control the naming of a field type\r\n\r\n@since 3.0.9', '', '', 'a8935cbe-7701-40dc-bfd5-675f2d600954', 'dXNlIEpvb21sYVxDTVNcQ29tcG9uZW50XENvbXBvbmVudEhlbHBlcjs=', '', '', '{}', 'CS8qKg0KCSAqIFRoZSBmaWVsZCBidWlsZGVyIHN3aXRjaA0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwcm90ZWN0ZWQgc3RhdGljICRidWlsZGVyID0gZmFsc2U7DQoNCgkvKioNCgkgKiBNYWtpbmcgZmllbGQgdHlwZSBuYW1lIHNhZmUNCgkgKg0KCSAqIEBwYXJhbSAgIFN0cmluZyAgICAgICRzdHJpbmcgICAgIFRoZSB5b3Ugd291bGQgbGlrZSB0byBtYWtlIHNhZmUNCgkgKiBAcGFyYW0gICBTdHJpbmcgICAgICAkb3B0aW9uICAgIFRoZSBvcHRpb24gZm9yIHRoZSBjb21wb25lbnQuDQoJICoNCgkgKiBAcmV0dXJucyBzdHJpbmcgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNhZmUoJHN0cmluZywgJG9wdGlvbiA9IG51bGwpDQoJew0KCQkvLyBnZXQgZ2xvYmFsIHZhbHVlDQoJCWlmIChzZWxmOjokYnVpbGRlciA9PT0gZmFsc2UpDQoJCXsNCgkJCXNlbGY6OiRidWlsZGVyID0gSGVscGVyOjpnZXRQYXJhbXMoJG9wdGlvbiktPmdldCgndHlwZV9uYW1lX2J1aWxkZXInLCAxKTsNCgkJfQ0KDQoJCS8vIHVzZSB0aGUgbmV3IGNvbnZlbnRpb24NCgkJaWYgKDIgPT0gc2VsZjo6JGJ1aWxkZXIpDQoJCXsNCgkJCS8vIDBubHkgY29udGludWUgaWYgd2UgaGF2ZSBhIHN0cmluZw0KCQkJaWYgKFN0cmluZ0hlbHBlcjo6Y2hlY2soJHN0cmluZykpDQoJCQl7DQoJCQkJLy8gY2hlY2sgdGhhdCB0aGUgZmlyc3QgY2hhcmFjdGVyIGlzIG5vdCBhIG51bWJlcg0KCQkJCWlmIChpc19udW1lcmljKHN1YnN0cigkc3RyaW5nLCAwLCAxKSkpDQoJCQkJew0KCQkJCQkkc3RyaW5nID0gU3RyaW5nSGVscGVyOjpudW1iZXJzKCRzdHJpbmcpOw0KCQkJCX0NCg0KCQkJCS8vIFRyYW5zbGl0ZXJhdGUgc3RyaW5nDQoJCQkJJHN0cmluZyA9IFN0cmluZ0hlbHBlcjo6dHJhbnNsaXRlcmF0ZSgkc3RyaW5nKTsNCg0KCQkJCS8vIHJlbW92ZSBhbGwgYW5kIGtlZXAgb25seSBjaGFyYWN0ZXJzIGFuZCBudW1iZXJzIGFuZCBwb2ludCAoVE9ETyBqdXN0IG9uZSBwb2ludCkNCgkJCQkkc3RyaW5nID0gdHJpbShwcmVnX3JlcGxhY2UoIi9bXkEtWmEtejAtOVwuXS8iLCAnJywgKHN0cmluZykgJHN0cmluZykpOw0KDQoJCQkJLy8gYmVzdCBpcyB0byByZXR1cm4gbG93ZXIgKGZvciBhbGwgc3RyaW5nIGVxdWFsaXR5IGluIGNvbXBpbGVyKQ0KCQkJCXJldHVybiBzdHJ0b2xvd2VyKCRzdHJpbmcpOw0KCQkJfQ0KCQkJLy8gbm90IGEgc3RyaW5nDQoJCQlyZXR1cm4gJyc7DQoJCX0NCg0KCQkvLyB1c2UgdGhlIGRlZmF1bHQgKG9yaWdpbmFsIGJlaGF2aW91ci9jb252ZW50aW9uKQ0KCQlyZXR1cm4gU3RyaW5nSGVscGVyOjpzYWZlKCRzdHJpbmcpOw0KCX0NCg==', '{}', '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', '2023-01-14 17:56:28', 16, 5), -(16, '', 'Control the naming of a class and function\r\n\r\n@since 3.0.9', '', '', '30c5b4c2-f75f-4d15-869a-f8bfedd87358', '', '', '', '{}', 'CS8qKg0KCSAqIE1ha2luZyBjbGFzcyBvciBmdW5jdGlvbiBuYW1lIHNhZmUNCgkgKg0KCSAqIEBpbnB1dAlzdHJpbmcgICAgICAgVGhlIG5hbWUgeW91IHdvdWxkIGxpa2UgdG8gbWFrZSBzYWZlDQoJICoNCgkgKiBAcmV0dXJucyBzdHJpbmcgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNhZmUoJG5hbWUpOiBzdHJpbmcNCgl7DQoJCS8vIHJlbW92ZSBudW1iZXJzIGlmIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaXMgYSBudW1iZXINCgkJaWYgKGlzX251bWVyaWMoc3Vic3RyKChzdHJpbmcpICRuYW1lLCAwLCAxKSkpDQoJCXsNCgkJCSRuYW1lID0gU3RyaW5nSGVscGVyOjpudW1iZXJzKCRuYW1lKTsNCgkJfQ0KDQoJCS8vIHJlbW92ZSBhbGwgc3BhY2VzIGFuZCBzdHJhbmdlIGNoYXJhY3RlcnMNCgkJcmV0dXJuIHRyaW0ocHJlZ19yZXBsYWNlKCIvW15BLVphLXowLTlfLV0vIiwgJycsIChzdHJpbmcpICRuYW1lKSk7DQoJfQ0K', '{}', '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', '2023-02-05 18:04:30', 17, 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\"}}', 'CS8qKg0KCSAqIEdldCBhIFZhcmlhYmxlIA0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nfG51bGwgICR0YWJsZSAgICAgICAgVGhlIHRhYmxlIGZyb20gd2hpY2ggdG8gZ2V0IHRoZSB2YXJpYWJsZQ0KCSAqIEBwYXJhbSAgIG1peGVkICAgICAgICAkd2hlcmUgICAgICAgIFRoZSB2YWx1ZSB3aGVyZQ0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICAgICAkd2hlcmVTdHJpbmcgIFRoZSB0YXJnZXQvZmllbGQgc3RyaW5nIHdoZXJlL25hbWUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAgICAgJHdoYXQgICAgICAgICBUaGUgcmV0dXJuIGZpZWxkDQoJICogQHBhcmFtICAgc3RyaW5nICAgICAgICRvcGVyYXRvciAgICAgVGhlIG9wZXJhdG9yIGJldHdlZW4gJHdoZXJlU3RyaW5nL2ZpZWxkIGFuZCAkd2hlcmUvdmFsdWUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAgICAgJG1haW4gICAgICAgICBUaGUgY29tcG9uZW50IGluIHdoaWNoIHRoZSB0YWJsZSBpcyBmb3VuZA0KCSAqDQoJICogQHJldHVybiAgbWl4ZWQgc3RyaW5nL2ludC9mbG9hdA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHZhcig/c3RyaW5nICR0YWJsZSA9IG51bGwsICR3aGVyZSA9IG51bGwsDQoJCXN0cmluZyAkd2hlcmVTdHJpbmcgPSAndXNlcicsIHN0cmluZyAkd2hhdCA9ICdpZCcsDQoJCXN0cmluZyAkb3BlcmF0b3IgPSAnPScsID9zdHJpbmcgJG1haW4gPSBudWxsKQ0KCXsNCgkJaWYoZW1wdHkoJHdoZXJlKSkNCgkJew0KCQkJJHdoZXJlID0gRmFjdG9yeTo6Z2V0VXNlcigpLT5pZDsNCgkJfQ0KDQoJCWlmKGVtcHR5KCRtYWluKSkNCgkJew0KCQkJJG1haW4gPSBIZWxwZXI6OmdldENvZGUoKTsNCgkJfQ0KDQoJCS8vIEdldCBhIGRiIGNvbm5lY3Rpb24uDQoJCSRkYiA9IEZhY3Rvcnk6OmdldERibygpOw0KDQoJCS8vIENyZWF0ZSBhIG5ldyBxdWVyeSBvYmplY3QuDQoJCSRxdWVyeSA9ICRkYi0+Z2V0UXVlcnkodHJ1ZSk7DQoJCSRxdWVyeS0+c2VsZWN0KCRkYi0+cXVvdGVOYW1lKGFycmF5KCR3aGF0KSkpOw0KDQoJCWlmIChlbXB0eSgkdGFibGUpKQ0KCQl7DQoJCQkkcXVlcnktPmZyb20oJGRiLT5xdW90ZU5hbWUoJyNfXycgLiAkbWFpbikpOw0KCQl9DQoJCWVsc2UNCgkJew0KCQkJJHF1ZXJ5LT5mcm9tKCRkYi0+cXVvdGVOYW1lKCcjX18nIC4gJG1haW4gLiAnXycgLiAkdGFibGUpKTsNCgkJfQ0KDQoJCWlmIChpc19udW1lcmljKCR3aGVyZSkpDQoJCXsNCgkJCSRxdWVyeS0+d2hlcmUoJGRiLT5xdW90ZU5hbWUoJHdoZXJlU3RyaW5nKSAuICcgJyAuICRvcGVyYXRvciAuICcgJyAuIChpbnQpICR3aGVyZSk7DQoJCX0NCgkJZWxzZWlmIChpc19zdHJpbmcoJHdoZXJlKSkNCgkJew0KCQkJJHF1ZXJ5LT53aGVyZSgkZGItPnF1b3RlTmFtZSgkd2hlcmVTdHJpbmcpIC4gJyAnIC4gJG9wZXJhdG9yIC4gJyAnIC4gJGRiLT5xdW90ZSgoc3RyaW5nKSR3aGVyZSkpOw0KCQl9DQoJCWVsc2UNCgkJew0KCQkJcmV0dXJuIGZhbHNlOw0KCQl9DQoNCgkJJGRiLT5zZXRRdWVyeSgkcXVlcnkpOw0KCQkkZGItPmV4ZWN1dGUoKTsNCg0KCQlpZiAoJGRiLT5nZXROdW1Sb3dzKCkpDQoJCXsNCgkJCXJldHVybiAkZGItPmxvYWRSZXN1bHQoKTsNCgkJfQ0KDQoJCXJldHVybiBmYWxzZTsNCgl9DQoNCgkvKioNCgkgKiBHZXQgYXJyYXkgb2YgdmFyaWFibGVzDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmd8bnVsbCAgJHRhYmxlICAgICAgICBUaGUgdGFibGUgZnJvbSB3aGljaCB0byBnZXQgdGhlIHZhcmlhYmxlcw0KCSAqIEBwYXJhbSAgIG1peGVkICAgICAgICAkd2hlcmUgICAgICAgIFRoZSB2YWx1ZSB3aGVyZQ0KCSAqIEBwYXJhbSAgIHN0cmluZyAgICAgICAkd2hlcmVTdHJpbmcgIFRoZSB0YXJnZXQvZmllbGQgc3RyaW5nIHdoZXJlL25hbWUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAgICAgJHdoYXQgICAgICAgICBUaGUgcmV0dXJuIGZpZWxkDQoJICogQHBhcmFtICAgc3RyaW5nICAgICAgICRvcGVyYXRvciAgICAgVGhlIG9wZXJhdG9yIGJldHdlZW4gJHdoZXJlU3RyaW5nL2ZpZWxkIGFuZCAkd2hlcmUvdmFsdWUNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAgICAgJG1haW4gICAgICAgICBUaGUgY29tcG9uZW50IGluIHdoaWNoIHRoZSB0YWJsZSBpcyBmb3VuZA0KCSAqIEBwYXJhbSAgIGJvb2wgICAgICAgICAkdW5pcXVlICAgICAgIFRoZSBzd2l0Y2ggdG8gcmV0dXJuIGEgdW5pcXVlIGFycmF5DQoJICoNCgkgKiBAcmV0dXJuICBhcnJheXxudWxsDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gdmFycyg/c3RyaW5nICR0YWJsZSA9IG51bGwsICR3aGVyZSA9IG51bGwsDQoJCXN0cmluZyAkd2hlcmVTdHJpbmcgPSAndXNlcicsIHN0cmluZyAkd2hhdCA9ICdpZCcsIHN0cmluZyAkb3BlcmF0b3IgPSAnSU4nLA0KCQk/c3RyaW5nICRtYWluID0gbnVsbCwgYm9vbCAkdW5pcXVlID0gdHJ1ZSk6ID9hcnJheQ0KCXsNCgkJaWYoZW1wdHkoJHdoZXJlKSkNCgkJew0KCQkJJHdoZXJlID0gRmFjdG9yeTo6Z2V0VXNlcigpLT5pZDsNCgkJfQ0KDQoJCWlmKGlzX251bGwoJG1haW4pKQ0KCQl7DQoJCQkkbWFpbiA9IEhlbHBlcjo6Z2V0Q29kZSgpOw0KCQl9DQoNCgkJaWYgKCFBcnJheUhlbHBlcjo6Y2hlY2soJHdoZXJlKSAmJiAkd2hlcmUgPiAwKQ0KCQl7DQoJCQkkd2hlcmUgPSBhcnJheSgkd2hlcmUpOw0KCQl9DQoNCgkJaWYgKEFycmF5SGVscGVyOjpjaGVjaygkd2hlcmUpKQ0KCQl7DQoJCQkvLyBwcmVwIG1haW4gPC0tIHdoeT8gd2VsbCBpZiAkbWFpbj0nJyBpcyBlbXB0eSB0aGVuICR0YWJsZSBjYW4gYmUgY2F0ZWdvcmllcyBvciB1c2Vycw0KCQkJaWYgKFN0cmluZ0hlbHBlcjo6Y2hlY2soJG1haW4pKQ0KCQkJew0KCQkJCSRtYWluID0gJ18nIC4gbHRyaW0oJG1haW4sICdfJyk7DQoJCQl9DQoNCgkJCS8vIEdldCBhIGRiIGNvbm5lY3Rpb24uDQoJCQkkZGIgPSBGYWN0b3J5OjpnZXREYm8oKTsNCg0KCQkJLy8gQ3JlYXRlIGEgbmV3IHF1ZXJ5IG9iamVjdC4NCgkJCSRxdWVyeSA9ICRkYi0+Z2V0UXVlcnkodHJ1ZSk7DQoJCQkkcXVlcnktPnNlbGVjdCgkZGItPnF1b3RlTmFtZShhcnJheSgkd2hhdCkpKTsNCg0KCQkJaWYgKGVtcHR5KCR0YWJsZSkpDQoJCQl7DQoJCQkJJHF1ZXJ5LT5mcm9tKCRkYi0+cXVvdGVOYW1lKCcjX18nIC4gJG1haW4pKTsNCgkJCX0NCgkJCWVsc2UNCgkJCXsNCgkJCQkkcXVlcnktPmZyb20oJGRiLT5xdW90ZU5hbWUoJyNfJyAuICRtYWluIC4gJ18nIC4gJHRhYmxlKSk7DQoJCQl9DQoNCgkJCS8vIGFkZCBzdHJpbmdzIHRvIGFycmF5IHNlYXJjaA0KCQkJaWYgKCdJTl9TVFJJTkdTJyA9PT0gJG9wZXJhdG9yIHx8ICdOT1QgSU5fU1RSSU5HUycgPT09ICRvcGVyYXRvcikNCgkJCXsNCgkJCQkkcXVlcnktPndoZXJlKCRkYi0+cXVvdGVOYW1lKCR3aGVyZVN0cmluZykgLiAnICcgLiBzdHJfcmVwbGFjZSgnX1NUUklOR1MnLCAnJywgJG9wZXJhdG9yKSAuICcgKCInIC4gaW1wbG9kZSgnIiwiJywgJHdoZXJlKSAuICciKScpOw0KCQkJfQ0KCQkJZWxzZQ0KCQkJew0KCQkJCSRxdWVyeS0+d2hlcmUoJGRiLT5xdW90ZU5hbWUoJHdoZXJlU3RyaW5nKSAuICcgJyAuICRvcGVyYXRvciAuICcgKCcgLiBpbXBsb2RlKCcsJywgJHdoZXJlKSAuICcpJyk7DQoJCQl9DQoNCgkJCSRkYi0+c2V0UXVlcnkoJHF1ZXJ5KTsNCgkJCSRkYi0+ZXhlY3V0ZSgpOw0KDQoJCQlpZiAoJGRiLT5nZXROdW1Sb3dzKCkpDQoJCQl7DQoJCQkJaWYgKCR1bmlxdWUpDQoJCQkJew0KCQkJCQlyZXR1cm4gYXJyYXlfdW5pcXVlKCRkYi0+bG9hZENvbHVtbigpKTsNCgkJCQl9DQoJCQkJcmV0dXJuICRkYi0+bG9hZENvbHVtbigpOw0KCQkJfQ0KCQl9DQoNCgkJcmV0dXJuIG51bGw7DQoJfQ0KDQoJLyoqDQoJICogZ2V0IGFsbCBzdHJpbmdzIGJldHdlZW4gdHdvIG90aGVyIHN0cmluZ3MNCgkgKiANCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAkY29udGVudCAgICBUaGUgY29udGVudCB0byBzZWFyY2gNCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAkc3RhcnQgICAgICBUaGUgc3RhcnRpbmcgdmFsdWUNCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAkZW5kICAgICAgICBUaGUgZW5kaW5nIHZhbHVlDQoJICoNCgkgKiBAcmV0dXJuICBhcnJheXxudWxsICAgICAgICAgIE9uIHN1Y2Nlc3MNCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBhbGxCZXR3ZWVuKHN0cmluZyAkY29udGVudCwgc3RyaW5nICRzdGFydCwgc3RyaW5nICRlbmQpOiA/YXJyYXkNCgl7DQoJCS8vIHJlc2V0IGJ1Y2tldA0KCQkkYnVja2V0ID0gW107DQoJCWZvciAoJGkgPSAwOyA7ICRpKyspDQoJCXsNCgkJCS8vIHNlYXJjaCBmb3Igc3RyaW5nDQoJCQkkZm91bmQgPSBzZWxmOjpiZXR3ZWVuKCRjb250ZW50LCAkc3RhcnQsICRlbmQpOw0KDQoJCQlpZiAoU3RyaW5nSGVscGVyOjpjaGVjaygkZm91bmQpKQ0KCQkJew0KCQkJCS8vIGFkZCB0byBidWNrZXQNCgkJCQkkYnVja2V0W10gPSAkZm91bmQ7DQoNCgkJCQkvLyBidWlsZCByZW1vdmFsIHN0cmluZw0KCQkJCSRyZW1vdmUgPSAkc3RhcnQgLiAkZm91bmQgLiAkZW5kOw0KDQoJCQkJLy8gcmVtb3ZlIGZyb20gY29udGVudA0KCQkJCSRjb250ZW50ID0gc3RyX3JlcGxhY2UoJHJlbW92ZSwgJycsICRjb250ZW50KTsNCgkJCX0NCgkJCWVsc2UNCgkJCXsNCgkJCQlicmVhazsNCgkJCX0NCg0KCQkJLy8gc2FmZXR5IGNhdGNoDQoJCQlpZiAoJGkgPT0gNTAwKQ0KCQkJew0KCQkJCWJyZWFrOw0KCQkJfQ0KCQl9DQoNCgkJLy8gb25seSByZXR1cm4gdW5pcXVlIGFycmF5IG9mIHZhbHVlcw0KCQlpZiAoQXJyYXlIZWxwZXI6OmNoZWNrKCRidWNrZXQpKQ0KCQl7DQoJCQlyZXR1cm4gIGFycmF5X3VuaXF1ZSgkYnVja2V0KTsNCgkJfQ0KDQoJCXJldHVybiBudWxsOw0KCX0NCg0KCS8qKg0KCSAqIGdldCBhIHN0cmluZyBiZXR3ZWVuIHR3byBvdGhlciBzdHJpbmdzDQoJICogDQoJICogQHBhcmFtICBzdHJpbmcgICAgICAgJGNvbnRlbnQgICAgVGhlIGNvbnRlbnQgdG8gc2VhcmNoDQoJICogQHBhcmFtICBzdHJpbmcgICAgICAgJHN0YXJ0ICAgICAgVGhlIHN0YXJ0aW5nIHZhbHVlDQoJICogQHBhcmFtICBzdHJpbmcgICAgICAgJGVuZCAgICAgICAgVGhlIGVuZGluZyB2YWx1ZQ0KCSAqIEBwYXJhbSAgc3RyaW5nICAgICAgICRkZWZhdWx0ICAgIFRoZSBkZWZhdWx0IHZhbHVlIGlmIG5vbmUgZm91bmQNCgkgKg0KCSAqIEByZXR1cm4gIHN0cmluZyAgICAgICAgICBPbiBzdWNjZXNzIC8gZW1wdHkgc3RyaW5nIG9uIGZhaWx1cmUNCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBiZXR3ZWVuKHN0cmluZyAkY29udGVudCwgc3RyaW5nICRzdGFydCwgc3RyaW5nICRlbmQsIHN0cmluZyAkZGVmYXVsdCA9ICcnKTogc3RyaW5nDQoJew0KCQkkYXJyYXkgPSBleHBsb2RlKCRzdGFydCwgJGNvbnRlbnQpOw0KCQlpZiAoaXNzZXQoJGFycmF5WzFdKSAmJiBzdHJwb3MoJGFycmF5WzFdLCAkZW5kKSAhPT0gZmFsc2UpDQoJCXsNCgkJCSRhcnJheSA9IGV4cGxvZGUoJGVuZCwgJGFycmF5WzFdKTsNCg0KCQkJLy8gcmV0dXJuIHN0cmluZyBmb3VuZCBiZXR3ZWVuDQoJCQlyZXR1cm4gJGFycmF5WzBdOw0KCQl9DQoNCgkJcmV0dXJuICRkZWZhdWx0Ow0KCX0NCg==', '{}', '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', '2023-01-18 22:46:18', 26, 9), -(18, '', 'Some object tricks\r\n\r\n@since 3.0.9', '', '', '91004529-94a9-4590-b842-e7c6b624ecf5', '', '', '', '{}', 'CS8qKg0KCSAqIENoZWNrIGlmIGhhdmUgYW4gb2JqZWN0IHdpdGggYSBsZW5ndGgNCgkgKg0KCSAqIEBpbnB1dAlvYmplY3QgICBUaGUgb2JqZWN0IHRvIGNoZWNrDQoJICoNCgkgKiBAcmV0dXJucyBib29sIHRydWUgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGNoZWNrKCRvYmplY3QpDQoJew0KCQlpZiAoaXNfb2JqZWN0KCRvYmplY3QpKQ0KCQl7DQoJCQlyZXR1cm4gY291bnQoKGFycmF5KSAkb2JqZWN0KSA+IDA7DQoJCX0NCg0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0KDQoJLyoqDQoJICogQ29tcGFyZSB0d28gb2JqZWN0cyBmb3IgZXF1YWxpdHkgYmFzZWQgb24gdGhlaXIgcHJvcGVydHkgdmFsdWVzLg0KCSAqDQoJICogICBOb3RlIHRoYXQgdGhpcyBtZXRob2Qgd29ya3Mgb25seSBmb3Igc2ltcGxlIG9iamVjdHMgdGhhdCBkb24ndA0KCSAqICAgY29udGFpbiBhbnkgbmVzdGVkIG9iamVjdHMgb3IgcmVzb3VyY2UgcmVmZXJlbmNlcy4gSWYgeW91IG5lZWQNCgkgKiAgIHRvIGNvbXBhcmUgbW9yZSBjb21wbGV4IG9iamVjdHMsIHlvdSBtYXkgbmVlZCB0byB1c2UgYQ0KCSAqICAgbW9yZSBhZHZhbmNlZCBtZXRob2Qgc3VjaCBhcyBzZXJpYWxpemF0aW9uIG9yIHJlZmxlY3Rpb24uDQoJICoNCgkgKiBAcGFyYW0gb2JqZWN0fG51bGwgJG9iajEgVGhlIGZpcnN0IG9iamVjdCB0byBjb21wYXJlLg0KCSAqIEBwYXJhbSBvYmplY3R8bnVsbCAkb2JqMiBUaGUgc2Vjb25kIG9iamVjdCB0byBjb21wYXJlLg0KCSAqDQoJICogQHJldHVybiBib29sIFRydWUgaWYgdGhlIG9iamVjdHMgaGF2ZSB0aGUgc2FtZSBrZXktdmFsdWUgcGFpcnMgYW5kIGZhbHNlIG90aGVyd2lzZS4NCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGVxdWFsKD9vYmplY3QgJG9iajEsID9vYmplY3QgJG9iajIpOiBib29sDQoJew0KCQkvLyBpZiBhbnkgaXMgbnVsbCB3ZSByZXR1cm4gZmFsc2UgYXMgdGhhdCBtZWFucyB0aGVyZSBpcyBhIG5vbmUgb2JqZWN0DQoJCS8vIHdlIGFyZSBub3QgY29tcGFyaW5nIG51bGwgYnV0IG9iamVjdHMNCgkJLy8gYnV0IHdlIGFsbG93IG51bGwgYXMgc29tZSBvYmplY3RzIHdoaWxlDQoJCS8vIG5vdCBpbnN0YW50aWF0ZSBhcmUgc3RpbGwgbnVsbA0KCQlpZiAoaXNfbnVsbCgkb2JqMSkgfHwgaXNfbnVsbCgkb2JqMikpDQoJCXsNCgkJCXJldHVybiBmYWxzZTsNCgkJfQ0KDQoJCS8vIENvbnZlcnQgdGhlIG9iamVjdHMgdG8gYXJyYXlzIG9mIHRoZWlyIHByb3BlcnR5IHZhbHVlcyB1c2luZyBnZXRfb2JqZWN0X3ZhcnMuDQoJCSRhcnJheTEgPSBnZXRfb2JqZWN0X3ZhcnMoJG9iajEpOw0KCQkkYXJyYXkyID0gZ2V0X29iamVjdF92YXJzKCRvYmoyKTsNCg0KCQkvLyBDb21wYXJlIHRoZSBhcnJheXMgdXNpbmcgYXJyYXlfZGlmZl9hc3NvYyB0byBkZXRlY3QgYW55IGRpZmZlcmVuY2VzLg0KCQkkZGlmZjEgPSBhcnJheV9kaWZmX2Fzc29jKCRhcnJheTEsICRhcnJheTIpOw0KCQkkZGlmZjIgPSBhcnJheV9kaWZmX2Fzc29jKCRhcnJheTIsICRhcnJheTEpOw0KDQoJCS8vIElmIHRoZSBhcnJheXMgaGF2ZSB0aGUgc2FtZSBrZXktdmFsdWUgcGFpcnMsIHRoZXkgd2lsbCBoYXZlIG5vIGRpZmZlcmVuY2VzLCBzbyByZXR1cm4gdHJ1ZS4NCgkJcmV0dXJuIGVtcHR5KCRkaWZmMSkgJiYgZW1wdHkoJGRpZmYyKTsNCgl9DQo=', '{}', 'ObjectHelper', 'VDM\\Joomla\\Utilities.ObjectHelper', '1.0.0', '{}', 'Utilities Object Helper', 'abstract class', '{}', '', 1, '2022-03-09 00:35:23', '2023-02-23 10:21:53', 19, 8), -(19, '', 'Basic Math Helper\r\n\r\n@since 3.0.9', '', '', '152c8793-8b75-4715-996a-257b9f65451c', '', '', '', '{}', 'CS8qKg0KCSAqIGJjIG1hdGggd3JhcHBlciAodmVyeSBiYXNpYyBub3QgZm9yIGFjY291bnRpbmcpDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAkdHlwZSAgICBUaGUgdHlwZSBiYyBtYXRoDQoJICogQHBhcmFtICAgaW50ICAgICAgJHZhbDEgICAgVGhlIGZpcnN0IHZhbHVlDQoJICogQHBhcmFtICAgaW50ICAgICAgJHZhbDIgICAgVGhlIHNlY29uZCB2YWx1ZQ0KCSAqIEBwYXJhbSAgIGludCAgICAgICRzY2FsZSAgIFRoZSBzY2FsZSB2YWx1ZQ0KCSAqDQoJICogQHJldHVybiBpbnQNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBiYygkdHlwZSwgJHZhbDEsICR2YWwyLCAkc2NhbGUgPSAwKQ0KCXsNCgkJLy8gYnVpbGQgZnVuY3Rpb24gbmFtZQ0KCQkkZnVuY3Rpb24gPSAnYmMnIC4gJHR5cGU7DQoJCS8vIHVzZSB0aGUgYmNtYXRoIGZ1bmN0aW9uIGlmIGF2YWlsYWJsZQ0KCQlpZiAoZnVuY3Rpb25fZXhpc3RzKCRmdW5jdGlvbikpDQoJCXsNCgkJCXJldHVybiAkZnVuY3Rpb24oJHZhbDEsICR2YWwyLCAkc2NhbGUpOw0KCQl9DQoJCS8vIGlmIGZ1bmN0aW9uIGRvZXMgbm90IGV4aXN0IHdlIHVzZSArLSovIG9wZXJhdG9ycyAoZmFsbGJhY2sgLSBub3QgaWRlYWwpDQoJCXN3aXRjaCAoJHR5cGUpDQoJCXsNCgkJCS8vIE11bHRpcGx5IHR3byBudW1iZXJzDQoJCQljYXNlICdtdWwnOg0KCQkJCXJldHVybiAoc3RyaW5nKSByb3VuZCgkdmFsMSAqICR2YWwyLCAkc2NhbGUpOw0KCQkJCWJyZWFrOw0KCQkJLy8gRGl2aWRlIG9mIHR3byBudW1iZXJzDQoJCQljYXNlICdkaXYnOg0KCQkJCXJldHVybiAoc3RyaW5nKSByb3VuZCgkdmFsMSAvICR2YWwyLCAkc2NhbGUpOw0KCQkJCWJyZWFrOw0KCQkJLy8gQWRkaW5nIHR3byBudW1iZXJzDQoJCQljYXNlICdhZGQnOg0KCQkJCXJldHVybiAoc3RyaW5nKSByb3VuZCgkdmFsMSArICR2YWwyLCAkc2NhbGUpOw0KCQkJCWJyZWFrOw0KCQkJLy8gU3VidHJhY3Qgb25lIG51bWJlciBmcm9tIHRoZSBvdGhlcg0KCQkJY2FzZSAnc3ViJzoNCgkJCQlyZXR1cm4gKHN0cmluZykgcm91bmQoJHZhbDEgLSAkdmFsMiwgJHNjYWxlKTsNCgkJCQlicmVhazsNCgkJCS8vIFJhaXNlIGFuIGFyYml0cmFyeSBwcmVjaXNpb24gbnVtYmVyIHRvIGFub3RoZXINCgkJCWNhc2UgJ3Bvdyc6DQoJCQkJcmV0dXJuIChzdHJpbmcpIHJvdW5kKHBvdygkdmFsMSwgJHZhbDIpLCAkc2NhbGUpOw0KCQkJCWJyZWFrOw0KCQkJLy8gQ29tcGFyZSB0d28gYXJiaXRyYXJ5IHByZWNpc2lvbiBudW1iZXJzDQoJCQljYXNlICdjb21wJzoNCgkJCQlyZXR1cm4gKHJvdW5kKCR2YWwxLDIpID09IHJvdW5kKCR2YWwyLDIpKTsNCgkJCQlicmVhazsNCgkJfQ0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0KDQoJLyoqDQoJICogQmFzaWMgc3VtIG9mIGFuIGFycmF5IHdpdGggbW9yZSBwcmVjaXNpb24NCgkgKg0KCSAqIEBwYXJhbSAgIGFycmF5ICAgJGFycmF5ICAgIFRoZSB2YWx1ZXMgdG8gc3VtDQoJICogQHBhcmFtICAgaW50ICAgICAgJHNjYWxlICAgVGhlIHNjYWxlIHZhbHVlDQoJICoNCgkgKiBAcmV0dXJuIGZsb2F0DQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc3VtKCRhcnJheSwgJHNjYWxlID0gNCkNCgl7DQoJCS8vIHVzZSB0aGUgYmNhZGQgZnVuY3Rpb24gaWYgYXZhaWxhYmxlDQoJCWlmIChmdW5jdGlvbl9leGlzdHMoJ2JjYWRkJykpDQoJCXsNCgkJCS8vIHNldCB0aGUgc3RhcnQgdmFsdWUNCgkJCSR2YWx1ZSA9IDAuMDsNCgkJCS8vIGxvb3AgdGhlIHZhbHVlcyBhbmQgcnVuIGJjYWRkDQoJCQlmb3JlYWNoKCRhcnJheSBhcyAkdmFsKQ0KCQkJew0KCQkJCSR2YWx1ZSA9IGJjYWRkKCR2YWx1ZSwgKHN0cmluZykgJHZhbCwgJHNjYWxlKTsNCgkJCX0NCgkJCXJldHVybiAkdmFsdWU7DQoJCX0NCgkJLy8gZmFsbCBiYWNrIG9uIGFycmF5IHN1bQ0KCQlyZXR1cm4gYXJyYXlfc3VtKCRhcnJheSk7DQoJfQ0K', '{}', 'MathHelper', 'VDM\\Joomla\\Utilities.MathHelper', '1.0.0', '{}', 'Utilities Math Helper', 'abstract class', '{}', '', 1, '2022-03-09 13:05:39', '2023-01-31 13:10:26', 13, 9), -(20, '', 'Control the naming of a plugin\r\n\r\n@since 3.0.9', '', '', '3cf76fbf-fd95-4a33-878e-7aff6d36b7f6', '', '', '', '{}', 'CS8qKg0KCSAqIE1ha2luZyBwbHVnaW4gZm9sZGVyIG5hbWUgc2FmZQ0KCSAqDQoJICogQGlucHV0CXN0cmluZyAgICAkY29kZU5hbWUgICBUaGUgbmFtZQ0KCSAqIEBpbnB1dAlzdHJpbmcgICAgJGdyb3VwICAgVGhlIGdyb3VwIG5hbWUNCgkgKg0KCSAqIEByZXR1cm5zIHN0cmluZyBvbiBzdWNjZXNzDQoJICogDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gc2FmZUZvbGRlck5hbWUoc3RyaW5nICRjb2RlTmFtZSwgc3RyaW5nICRncm91cCk6IHN0cmluZw0KCXsNCgkJLy8gZWRpdG9ycy14dGQgZ3JvdXAgcGx1Z2lucyBtdXN0IGhhdmUgYSBjbGFzcyB3aXRoIHBsZ0J1dHRvbjxQbHVnaW5OYW1lPiBzdHJ1Y3R1cmUNCgkJaWYgKCRncm91cCA9PT0gJ2VkaXRvcnMteHRkJykNCgkJew0KCQkJJGdyb3VwID0gJ0J1dHRvbic7DQoJCX0NCg0KCQlyZXR1cm4gJ3BsZ18nIC4gc3RydG9sb3dlcigkZ3JvdXApIC4gJ18nIC4gc3RydG9sb3dlcigNCgkJCSRjb2RlTmFtZQ0KCQkpOw0KCX0NCg0KCS8qKg0KCSAqIE1ha2luZyBwbHVnaW4gY2xhc3MgbmFtZSBzYWZlDQoJICoNCgkgKiBAaW5wdXQJc3RyaW5nICAgICRjb2RlTmFtZSAgIFRoZSBuYW1lDQoJICogQGlucHV0CXN0cmluZyAgICAkZ3JvdXAgICBUaGUgZ3JvdXAgbmFtZQ0KCSAqDQoJICogQHJldHVybnMgc3RyaW5nIG9uIHN1Y2Nlc3MNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzYWZlQ2xhc3NOYW1lKHN0cmluZyAkY29kZU5hbWUsIHN0cmluZyAkZ3JvdXApOiBzdHJpbmcNCgl7DQoJCS8vIGVkaXRvcnMteHRkIGdyb3VwIHBsdWdpbnMgbXVzdCBoYXZlIGEgY2xhc3Mgd2l0aCBwbGdCdXR0b248UGx1Z2luTmFtZT4gc3RydWN0dXJlDQoJCWlmICgkZ3JvdXAgPT09ICdlZGl0b3JzLXh0ZCcpDQoJCXsNCgkJCSRncm91cCA9ICdCdXR0b24nOw0KCQl9DQoNCgkJcmV0dXJuICdQbGcnIC4gdWNmaXJzdCgkZ3JvdXApIC4gdWNmaXJzdCgNCgkJCSRjb2RlTmFtZQ0KCQkpOw0KCX0NCg0KCS8qKg0KCSAqIE1ha2luZyBwbHVnaW4gaW5zdGFsbCBjbGFzcyBuYW1lIHNhZmUNCgkgKg0KCSAqIEBpbnB1dAlzdHJpbmcgICAgJGNvZGVOYW1lICAgVGhlIG5hbWUNCgkgKiBAaW5wdXQJc3RyaW5nICAgICRncm91cCAgIFRoZSBncm91cCBuYW1lDQoJICoNCgkgKiBAcmV0dXJucyBzdHJpbmcgb24gc3VjY2Vzcw0KCSAqIA0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHNhZmVJbnN0YWxsQ2xhc3NOYW1lKHN0cmluZyAkY29kZU5hbWUsIHN0cmluZyAkZ3JvdXApOiBzdHJpbmcNCgl7DQoJCS8vIGVkaXRvcnMteHRkIGdyb3VwIHBsdWdpbnMgbXVzdCBoYXZlIGEgY2xhc3Mgd2l0aCBwbGdCdXR0b248UGx1Z2luTmFtZT4gc3RydWN0dXJlDQoJCWlmICgkZ3JvdXAgPT09ICdlZGl0b3JzLXh0ZCcpDQoJCXsNCgkJCSRncm91cCA9ICdCdXR0b24nOw0KCQl9DQoNCgkJcmV0dXJuICdwbGcnIC4gdWNmaXJzdCgkZ3JvdXApIC4gdWNmaXJzdCgNCgkJCSRjb2RlTmFtZQ0KCQkpIC4gJ0luc3RhbGxlclNjcmlwdCc7DQoJfQ0KDQoJLyoqDQoJICogTWFraW5nIGxhbmd1YWdlIHByZWZpeCBzYWZlDQoJICoNCgkgKiBAaW5wdXQJc3RyaW5nICAgICRjb2RlTmFtZSAgIFRoZSBuYW1lDQoJICogQGlucHV0CXN0cmluZyAgICAkZ3JvdXAgICBUaGUgZ3JvdXAgbmFtZQ0KCSAqDQoJICogQHJldHVybnMgc3RyaW5nIG9uIHN1Y2Nlc3MNCgkgKiANCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBzYWZlTGFuZ1ByZWZpeChzdHJpbmcgJGNvZGVOYW1lLCBzdHJpbmcgJGdyb3VwKTogc3RyaW5nDQoJew0KCQkvLyBlZGl0b3JzLXh0ZCBncm91cCBwbHVnaW5zIG11c3QgaGF2ZSBhIGNsYXNzIHdpdGggcGxnQnV0dG9uPFBsdWdpbk5hbWU+IHN0cnVjdHVyZQ0KCQlpZiAoJGdyb3VwID09PSAnZWRpdG9ycy14dGQnKQ0KCQl7DQoJCQkkZ3JvdXAgPSAnQnV0dG9uJzsNCgkJfQ0KDQoJCXJldHVybiAnUExHXycgLiBzdHJ0b3VwcGVyKCRncm91cCkgLiAnXycgLiBzdHJ0b3VwcGVyKA0KCQkJJGNvZGVOYW1lDQoJCSk7DQoJfQ0K', '{}', 'PluginHelper', 'VDM\\Joomla\\Utilities.String.PluginHelper', '1.0.0', '{}', 'String Plugin Helper', 'abstract class', '{}', '', 1, '2022-03-09 14:44:58', '2023-01-14 18:00:42', 16, 5), -(21, 1, 'Global Unique ID Helper\r\n\r\n@since 3.0.9', '', '', '9c513baf-b279-43fd-ae29-a585c8cbc4f0', 'dXNlIEpvb21sYVxDTVNcRmFjdG9yeTs=', '', '', '{\"load_selection0\":{\"load\":\"0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a\"},\"load_selection1\":{\"load\":\"1f28cb53-60d9-4db1-b517-3c7dc6b429ef\"}}', 'CS8qKg0KCSAqIFJldHVybnMgYSBHVUlEdjQgc3RyaW5nDQoJICogDQoJICogVGhhbmtzIHRvIERhdmUgUGVhcnNvbiAoYW5kIG90aGVyKQ0KCSAqIGh0dHBzOi8vd3d3LnBocC5uZXQvbWFudWFsL2VuL2Z1bmN0aW9uLmNvbS1jcmVhdGUtZ3VpZC5waHAjMTE5MTY4IA0KCSAqDQoJICogVXNlcyB0aGUgYmVzdCBjcnlwdG9ncmFwaGljYWxseSBzZWN1cmUgbWV0aG9kDQoJICogZm9yIGFsbCBzdXBwb3J0ZWQgcGxhdGZvcm1zIHdpdGggZmFsbGJhY2sgdG8gYW4gb2xkZXIsDQoJICogbGVzcyBzZWN1cmUgdmVyc2lvbi4NCgkgKg0KCSAqIEBwYXJhbSBib29sICR0cmltDQoJICoNCgkgKiBAcmV0dXJuIHN0cmluZw0KCSAqDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0KGJvb2wgJHRyaW0gPSB0cnVlKTogc3RyaW5nDQoJew0KCQkvLyBXaW5kb3dzDQoJCWlmIChmdW5jdGlvbl9leGlzdHMoJ2NvbV9jcmVhdGVfZ3VpZCcpKQ0KCQl7DQoJCQlpZiAoJHRyaW0pDQoJCQl7DQoJCQkJcmV0dXJuIHRyaW0oY29tX2NyZWF0ZV9ndWlkKCksICd7fScpOw0KCQkJfQ0KCQkJcmV0dXJuIGNvbV9jcmVhdGVfZ3VpZCgpOw0KCQl9DQoNCgkJLy8gc2V0IHRoZSBicmFjZXMgaWYgbmVlZGVkDQoJCSRsYnJhY2UgPSAkdHJpbSA/ICIiIDogY2hyKDEyMyk7ICAgIC8vICJ7Ig0KCQkkcmJyYWNlID0gJHRyaW0gPyAiIiA6IGNocigxMjUpOyAgICAvLyAifSINCg0KCQkvLyBPU1gvTGludXgNCgkJaWYgKGZ1bmN0aW9uX2V4aXN0cygnb3BlbnNzbF9yYW5kb21fcHNldWRvX2J5dGVzJykpDQoJCXsNCgkJCSRkYXRhID0gb3BlbnNzbF9yYW5kb21fcHNldWRvX2J5dGVzKDE2KTsNCgkJCSRkYXRhWzZdID0gY2hyKCBvcmQoJGRhdGFbNl0pICYgMHgwZiB8IDB4NDApOyAgICAvLyBzZXQgdmVyc2lvbiB0byAwMTAwDQoJCQkkZGF0YVs4XSA9IGNociggb3JkKCRkYXRhWzhdKSAmIDB4M2YgfCAweDgwKTsgICAgLy8gc2V0IGJpdHMgNi03IHRvIDEwDQoJCQlyZXR1cm4gJGxicmFjZSAuIHZzcHJpbnRmKCclcyVzLSVzLSVzLSVzLSVzJXMlcycsIHN0cl9zcGxpdChiaW4yaGV4KCRkYXRhKSwgNCkpIC4gJGxicmFjZTsNCgkJfQ0KDQoJCS8vIEZhbGxiYWNrIChQSFAgNC4yKykNCgkJbXRfc3JhbmQoKGRvdWJsZSkgbWljcm90aW1lKCkgKiAxMDAwMCk7DQoJCSRjaGFyaWQgPSBzdHJ0b2xvd2VyKCBtZDUoIHVuaXFpZCggcmFuZCgpLCB0cnVlKSkpOw0KCQkkaHlwaGVuID0gY2hyKDQ1KTsgICAgICAgICAgICAgICAgICAvLyAiLSINCgkJJGd1aWR2NCA9ICRsYnJhY2UuDQoJCQlzdWJzdHIoJGNoYXJpZCwgIDAsICA4KS4gJGh5cGhlbi4NCgkJCXN1YnN0cigkY2hhcmlkLCAgOCwgIDQpLiAkaHlwaGVuLg0KCQkJc3Vic3RyKCRjaGFyaWQsIDEyLCAgNCkuICRoeXBoZW4uDQoJCQlzdWJzdHIoJGNoYXJpZCwgMTYsICA0KS4gJGh5cGhlbi4NCgkJCXN1YnN0cigkY2hhcmlkLCAyMCwgMTIpLg0KCQkJJHJicmFjZTsNCgkJcmV0dXJuICRndWlkdjQ7DQoJfQ0KDQoJLyoqDQoJICogVmFsaWRhdGUgdGhlIEdsb2JhbGx5IFVuaXF1ZSBJZGVudGlmaWVyICggYW5kIGNoZWNrIGlmIHRhYmxlIGFscmVhZHkgaGFzIHRoaXMgaWRlbnRpZmllcikNCgkgKg0KCSAqIEBwYXJhbSBzdHJpbmcgICAgICAgJGd1aWQNCgkgKiBAcGFyYW0gc3RyaW5nfG51bGwgICAgICAgJHRhYmxlDQoJICogQHBhcmFtIGludCAgICAgICAgICAgICRpZA0KCSAqIEBwYXJhbSBzdHJpbmd8bnVsbCAkY29tcG9uZW50DQoJICoNCgkgKiBAcmV0dXJuIGJvb2wNCgkgKg0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHZhbGlkKCRndWlkLCA/c3RyaW5nICR0YWJsZSA9IG51bGwsIGludCAkaWQgPSAwLCA/c3RyaW5nICRjb21wb25lbnQgPSBudWxsKTogYm9vbA0KCXsNCgkJLy8gY2hlY2sgaWYgd2UgaGF2ZSBhIHN0cmluZw0KCQlpZiAoc2VsZjo6dmFsaWRhdGUoJGd1aWQpKQ0KCQl7DQoJCQkvLyBjaGVjayBpZiB0YWJsZSBhbHJlYWR5IGhhcyB0aGlzIGlkZW50aWZpZXINCgkJCWlmIChTdHJpbmdIZWxwZXI6OmNoZWNrKCR0YWJsZSkpDQoJCQl7DQoJCQkJLy8gY2hlY2sgdGhhdCB3ZSBoYXZlIHRoZSBjb21wb25lbnQgY29kZSBuYW1lDQoJCQkJaWYgKCFpc19zdHJpbmcoJGNvbXBvbmVudCkpDQoJCQkJew0KCQkJCQkkY29tcG9uZW50ID0gKHN0cmluZykgSGVscGVyOjpnZXRDb2RlKCk7DQoJCQkJfQ0KCQkJCS8vIEdldCB0aGUgZGF0YWJhc2Ugb2JqZWN0IGFuZCBhIG5ldyBxdWVyeSBvYmplY3QuDQoJCQkJJGRiID0gRmFjdG9yeTo6Z2V0RGJvKCk7DQoJCQkJJHF1ZXJ5ID0gJGRiLT5nZXRRdWVyeSh0cnVlKTsNCgkJCQkkcXVlcnktPnNlbGVjdCgnQ09VTlQoKiknKQ0KCQkJCQktPmZyb20oJyNfXycgLiAoc3RyaW5nKSAkY29tcG9uZW50IC4gJ18nIC4gKHN0cmluZykgJHRhYmxlKQ0KCQkJCQktPndoZXJlKCRkYi0+cXVvdGVOYW1lKCdndWlkJykgLiAnID0gJyAuICRkYi0+cXVvdGUoJGd1aWQpKTsNCg0KCQkJCS8vIHJlbW92ZSB0aGlzIGl0ZW0gZnJvbSB0aGUgbGlzdA0KCQkJCWlmICgkaWQgPiAwKQ0KCQkJCXsNCgkJCQkJJHF1ZXJ5LT53aGVyZSgkZGItPnF1b3RlTmFtZSgnaWQnKSAuICcgPD4gJyAuIChpbnQpICRpZCk7DQoJCQkJfQ0KDQoJCQkJLy8gU2V0IGFuZCBxdWVyeSB0aGUgZGF0YWJhc2UuDQoJCQkJJGRiLT5zZXRRdWVyeSgkcXVlcnkpOw0KCQkJCSRkdXBsaWNhdGUgPSAoYm9vbCkgJGRiLT5sb2FkUmVzdWx0KCk7DQoNCgkJCQlpZiAoJGR1cGxpY2F0ZSkNCgkJCQl7DQoJCQkJCXJldHVybiBmYWxzZTsNCgkJCQl9DQoJCQl9DQoJCQlyZXR1cm4gdHJ1ZTsNCgkJfQ0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0KDQoJLyoqDQoJICogZ2V0IHRoZSBpdGVtIGJ5IGd1aWQgaW4gYSB0YWJsZQ0KCSAqDQoJICogQHBhcmFtIHN0cmluZyAgICAgICAgICAgJGd1aWQNCgkgKiBAcGFyYW0gc3RyaW5nICAgICAgICAgICAkdGFibGUNCgkgKiBAcGFyYW0gc3RyaW5nfGFycmF5ICAkd2hhdA0KCSAqIEBwYXJhbSBzdHJpbmd8bnVsbCAgICAkY29tcG9uZW50DQoJICoNCgkgKiBAcmV0dXJuIG1peA0KCSAqDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gaXRlbSgkZ3VpZCwgJHRhYmxlLCAkd2hhdCA9ICdhLmlkJywgP3N0cmluZyAkY29tcG9uZW50ID0gbnVsbCkNCgl7DQoJCS8vIGNoZWNrIGlmIHdlIGhhdmUgYSBzdHJpbmcNCgkJLy8gY2hlY2sgaWYgdGFibGUgYWxyZWFkeSBoYXMgdGhpcyBpZGVudGlmaWVyDQoJCWlmIChzZWxmOjp2YWxpZGF0ZSgkZ3VpZCkgJiYgU3RyaW5nSGVscGVyOjpjaGVjaygkdGFibGUpKQ0KCQl7DQoJCQkvLyBjaGVjayB0aGF0IHdlIGhhdmUgdGhlIGNvbXBvbmVudCBjb2RlIG5hbWUNCgkJCWlmICghaXNfc3RyaW5nKCRjb21wb25lbnQpKQ0KCQkJew0KCQkJCSRjb21wb25lbnQgPSAoc3RyaW5nKSBIZWxwZXI6OmdldENvZGUoKTsNCgkJCX0NCgkJCS8vIEdldCB0aGUgZGF0YWJhc2Ugb2JqZWN0IGFuZCBhIG5ldyBxdWVyeSBvYmplY3QuDQoJCQkkZGIgPSBGYWN0b3J5OjpnZXREYm8oKTsNCgkJCSRxdWVyeSA9ICRkYi0+Z2V0UXVlcnkodHJ1ZSk7DQoNCgkJCWlmIChBcnJheUhlbHBlcjo6Y2hlY2soJHdoYXQpKQ0KCQkJew0KCQkJCSRxdWVyeS0+c2VsZWN0KCRkYi0+cXVvdGVOYW1lKCR3aGF0KSk7DQoJCQl9DQoJCQllbHNlDQoJCQl7DQoJCQkJJHF1ZXJ5LT5zZWxlY3QoJHdoYXQpOw0KCQkJfQ0KDQoJCQkkcXVlcnktPmZyb20oJGRiLT5xdW90ZU5hbWUoJyNfXycgLiAoc3RyaW5nKSAkY29tcG9uZW50IC4gJ18nIC4gKHN0cmluZykgJHRhYmxlLCAnYScpKQ0KCQkJCS0+d2hlcmUoJGRiLT5xdW90ZU5hbWUoJ2EuZ3VpZCcpIC4gJyA9ICcgLiAkZGItPnF1b3RlKCRndWlkKSk7DQoNCgkJCS8vIFNldCBhbmQgcXVlcnkgdGhlIGRhdGFiYXNlLg0KCQkJJGRiLT5zZXRRdWVyeSgkcXVlcnkpOw0KCQkJJGRiLT5leGVjdXRlKCk7DQoNCgkJCWlmICgkZGItPmdldE51bVJvd3MoKSkNCgkJCXsNCgkJCQlpZiAoQXJyYXlIZWxwZXI6OmNoZWNrKCR3aGF0KSB8fCAkd2hhdCA9PT0gJ2EuKicpDQoJCQkJew0KCQkJCQlyZXR1cm4gJGRiLT5sb2FkT2JqZWN0KCk7DQoJCQkJfQ0KCQkJCWVsc2UNCgkJCQl7DQoJCQkJCXJldHVybiAkZGItPmxvYWRSZXN1bHQoKTsNCgkJCQl9DQoJCQl9DQoJCX0NCgkJcmV0dXJuIGZhbHNlOw0KCX0NCg0KCS8qKg0KCSAqIFZhbGlkYXRlIHRoZSBHbG9iYWxseSBVbmlxdWUgSWRlbnRpZmllcg0KCSAqDQoJICogVGhhbmtzIHRvIExld2llDQoJICogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzE1MTU0NTYvMTQyOTY3Nw0KCSAqDQoJICogQHBhcmFtIHN0cmluZyAkZ3VpZA0KCSAqDQoJICogQHJldHVybiBib29sDQoJICoNCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiB2YWxpZGF0ZSgkZ3VpZCkNCgl7DQoJCS8vIGNoZWNrIGlmIHdlIGhhdmUgYSBzdHJpbmcNCgkJaWYgKFN0cmluZ0hlbHBlcjo6Y2hlY2soJGd1aWQpKQ0KCQl7DQoJCQlyZXR1cm4gcHJlZ19tYXRjaCgiL14oXHspP1thLWZcZF17OH0oLVthLWZcZF17NH0pezR9W2EtZlxkXXs4fSg/KDEpXH0pJC9pIiwgJGd1aWQpOw0KCQl9DQoJCXJldHVybiBmYWxzZTsNCgl9DQo=', '{}', 'GuidHelper', 'VDM\\Joomla\\Utilities.GuidHelper', '1.0.0', '{}', 'Utilities GuidHelper', 'abstract class', '{\"use_selection0\":{\"use\":\"640b5352-fb09-425f-a26e-cd44eda03f15\",\"as\":\"default\"}}', '', 1, '2022-03-12 01:27:10', '2023-01-14 20:50:52', 17, 9), -(22, 1, 'File helper\r\n\r\n@since 3.0.9', '', '', 'a223b31e-ea1d-4cdf-92ae-5f9becffaff0', 'dXNlIEpvb21sYVxDTVNcVXJpXFVyaTsNCnVzZSBKb29tbGFcQ01TXEZhY3Rvcnk7DQp1c2UgSm9vbWxhXENNU1xMYW5ndWFnZVxUZXh0Ow0KdXNlIEpvb21sYVxDTVNcRmlsZXN5c3RlbVxQYXRoOw0KdXNlIEpvb21sYVxDTVNcRmlsZXN5c3RlbVxGaWxlOw0KdXNlIEpvb21sYVxDTVNcRmlsZXN5c3RlbVxGb2xkZXI7DQp1c2UgSm9vbWxhXEFyY2hpdmVcQXJjaGl2ZTs=', '', '', '{\"load_selection0\":{\"load\":\"0a59c65c-9daf-4bc9-baf4-e063ff9e6a8a\"},\"load_selection1\":{\"load\":\"1f28cb53-60d9-4db1-b517-3c7dc6b429ef\"},\"load_selection2\":{\"load\":\"91004529-94a9-4590-b842-e7c6b624ecf5\"}}', 'CS8qKg0KCSAqIFRyaWdnZXIgZXJyb3Igbm90aWNlIG9ubHkgb25jZQ0KCSAqDQoJICogQHZhciAgICBib29sDQoJICoNCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHJvdGVjdGVkIHN0YXRpYyAkY3VybEVycm9yID0gZmFsc2U7DQoNCgkvKioNCgkgKiBUaGUgemlwcGVyIG1ldGhvZA0KCSAqIA0KCSAqIEBwYXJhbSAgc3RyaW5nICAgJHdvcmtpbmdEaXJlY3RvcnkgICAgVGhlIGRpcmVjdG9yeSB3aGVyZSB0aGUgaXRlbXMgbXVzdCBiZSB6aXBwZWQNCgkgKiBAcGFyYW0gIHN0cmluZyAgICRmaWxlcGF0aCAgICAgICAgICBUaGUgcGF0aCB0byB3aGVyZSB0aGUgemlwIGZpbGUgbXVzdCBiZSBwbGFjZWQNCgkgKg0KCSAqIEByZXR1cm4gIGJvb2wgdHJ1ZSAgIE9uIHN1Y2Nlc3MNCgkgKg0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHppcCgkd29ya2luZ0RpcmVjdG9yeSwgJiRmaWxlcGF0aCk6IGJvb2wNCgl7DQoJCS8vIHN0b3JlIHRoZSBjdXJyZW50IGpvb21sYSB3b3JraW5nIGRpcmVjdG9yeQ0KCQkkam9vbWxhID0gZ2V0Y3dkKCk7DQoNCgkJLy8gd2UgYXJlIGNoYW5naW5nIHRoZSB3b3JraW5nIGRpcmVjdG9yeSB0byB0aGUgY29tcG9uZW50IHRlbXAgZm9sZGVyDQoJCWNoZGlyKCR3b3JraW5nRGlyZWN0b3J5KTsNCg0KCQkvLyB0aGUgZnVsbCBmaWxlIHBhdGggb2YgdGhlIHppcCBmaWxlDQoJCSRmaWxlcGF0aCA9IFBhdGg6OmNsZWFuKCRmaWxlcGF0aCk7DQoNCgkJLy8gZGVsZXRlIGFuIGV4aXN0aW5nIHppcCBmaWxlIChvciB1c2UgYW4gZXhjbHVzaW9uIHBhcmFtZXRlciBpbiBGb2xkZXI6OmZpbGVzKCkNCgkJRmlsZTo6ZGVsZXRlKCRmaWxlcGF0aCk7DQoNCgkJLy8gZ2V0IGEgbGlzdCBvZiBmaWxlcyBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkgdHJlZSAoYWxzbyB0aGUgaGlkZGVuIGZpbGVzKQ0KCQkkZmlsZXMgPSBGb2xkZXI6OmZpbGVzKCcuJywgJycsIHRydWUsIHRydWUsIGFycmF5KCcuc3ZuJywgJ0NWUycsICcuRFNfU3RvcmUnLCAnX19NQUNPU1gnKSwgYXJyYXkoJy4qficpKTsNCg0KCQkkemlwQXJyYXkgPSBbXTsNCgkJLy8gc2V0dXAgdGhlIHppcCBhcnJheQ0KCQlmb3JlYWNoICgkZmlsZXMgYXMgJGZpbGUpDQoJCXsNCgkJCSR0bXAgPSBbXTsNCgkJCSR0bXBbJ25hbWUnXSA9IHN0cl9yZXBsYWNlKCcuLycsICcnLCAoc3RyaW5nKSAkZmlsZSk7DQoJCQkkdG1wWydkYXRhJ10gPSBzZWxmOjpnZXRDb250ZW50KCRmaWxlKTsNCgkJCSR0bXBbJ3RpbWUnXSA9IGZpbGVtdGltZSgkZmlsZSk7DQoJCQkkemlwQXJyYXlbXSA9ICR0bXA7DQoJCX0NCg0KCQkvLyBjaGFuZ2UgYmFjayB0byBqb29tbGEgd29ya2luZyBkaXJlY3RvcnkNCgkJY2hkaXIoJGpvb21sYSk7DQoNCgkJLy8gZ2V0IHRoZSB6aXAgYWRhcHRlcg0KCQkkemlwID0gKG5ldyBBcmNoaXZlKCkpLT5nZXRBZGFwdGVyKCd6aXAnKTsNCg0KCQkvL2NyZWF0ZSB0aGUgemlwIGZpbGUNCgkJcmV0dXJuIChib29sKSAkemlwLT5jcmVhdGUoJGZpbGVwYXRoLCAkemlwQXJyYXkpOw0KCX0NCg0KCS8qKg0KCSAqIGdldCB0aGUgY29udGVudCBvZiBhIGZpbGUNCgkgKg0KCSAqIEBwYXJhbSAgc3RyaW5nICAgICAgICAkcGF0aCAgIFRoZSBwYXRoIHRvIHRoZSBmaWxlDQoJICogQHBhcmFtICBzdHJpbmcvYm9vbCAgICRub25lICAgVGhlIHJldHVybiB2YWx1ZSBpZiBubyBjb250ZW50IHdhcyBmb3VuZA0KCSAqDQoJICogQHJldHVybiAgc3RyaW5nICAgT24gc3VjY2Vzcw0KCSAqDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0Q29udGVudCgkcGF0aCwgJG5vbmUgPSAnJykNCgl7DQoJCWlmIChTdHJpbmdIZWxwZXI6OmNoZWNrKCRwYXRoKSkNCgkJew0KCQkJLy8gdXNlIGJhc2ljIGZpbGUgZ2V0IGNvbnRlbnQgZm9yIG5vdw0KCQkJaWYgKCgkY29udGVudCA9IEBmaWxlX2dldF9jb250ZW50cygkcGF0aCkpICE9PSBGQUxTRSkNCgkJCXsNCgkJCQlyZXR1cm4gJGNvbnRlbnQ7DQoJCQl9DQoJCQkvLyB1c2UgY3VybCBpZiBhdmFpbGFibGUNCgkJCWVsc2VpZiAoZnVuY3Rpb25fZXhpc3RzKCdjdXJsX3ZlcnNpb24nKSkNCgkJCXsNCgkJCQkvLyBzdGFydCBjdXJsDQoJCQkJJGNoID0gY3VybF9pbml0KCk7DQoJCQkJLy8gc2V0IHRoZSBvcHRpb25zDQoJCQkJJG9wdGlvbnMgPSBbXTsNCgkJCQkkb3B0aW9uc1tDVVJMT1BUX1VSTF0gPSAkcGF0aDsNCgkJCQkkb3B0aW9uc1tDVVJMT1BUX1VTRVJBR0VOVF0gPSAnTW96aWxsYS81LjAgKFdpbmRvd3M7IFU7IFdpbmRvd3MgTlQgNi4xOyBlbi1VUzsgcnY6MS45LjIuMTIpIEdlY2tvLzIwMTAxMDI2IEZpcmVmb3gvMy42LjEyJzsNCgkJCQkkb3B0aW9uc1tDVVJMT1BUX1JFVFVSTlRSQU5TRkVSXSA9IFRSVUU7DQoJCQkJJG9wdGlvbnNbQ1VSTE9QVF9TU0xfVkVSSUZZUEVFUl0gPSBGQUxTRTsNCgkJCQkvLyBsb2FkIHRoZSBvcHRpb25zDQoJCQkJY3VybF9zZXRvcHRfYXJyYXkoJGNoLCAkb3B0aW9ucyk7DQoJCQkJLy8gZ2V0IHRoZSBjb250ZW50DQoJCQkJJGNvbnRlbnQgPSBjdXJsX2V4ZWMoJGNoKTsNCgkJCQkvLyBjbG9zZSB0aGUgY29ubmVjdGlvbg0KCQkJCWN1cmxfY2xvc2UoJGNoKTsNCg0KCQkJCS8vIHJldHVybiBpZiBmb3VuZA0KCQkJCWlmIChTdHJpbmdIZWxwZXI6OmNoZWNrKCRjb250ZW50KSkNCgkJCQl7DQoJCQkJCXJldHVybiAkY29udGVudDsNCgkJCQl9DQoJCQl9DQoJCQllbHNlaWYgKCFzZWxmOjokY3VybEVycm9yKQ0KCQkJew0KCQkJCS8vIHNldCB0aGUgbm90aWNlDQoJCQkJRmFjdG9yeTo6Z2V0QXBwbGljYXRpb24oKS0+ZW5xdWV1ZU1lc3NhZ2UoVGV4dDo6XygnPGgyPkN1cmwgTm90IEZvdW5kITwvaDI+PHA+UGxlYXNlIHNldHVwIGN1cmwgb24geW91ciBzeXN0ZW0sIG9yIDxiPltbW2NvbXBvbmVudF1dXTwvYj4gd2lsbCBub3QgZnVuY3Rpb24gY29ycmVjdGx5ITwvcD4nKSwgJ0Vycm9yJyk7DQoJCQkJLy8gbG9hZCB0aGlzIG5vdGljZSBvbmx5IG9uY2UNCgkJCQlzZWxmOjokY3VybEVycm9yID0gdHJ1ZTsNCgkJCX0NCgkJfQ0KCQlyZXR1cm4gJG5vbmU7DQoJfQ0KDQoJLyoqDQoJICogV3JpdGUgYSBmaWxlIHRvIHRoZSBzZXJ2ZXINCgkgKg0KCSAqIEBwYXJhbSAgc3RyaW5nICAgJHBhdGggICAgVGhlIHBhdGggYW5kIGZpbGUgbmFtZSB3aGVyZSB0byBzYWZlIHRoZSBkYXRhDQoJICogQHBhcmFtICBzdHJpbmcgICAkZGF0YSAgICBUaGUgZGF0YSB0byBzYWZlDQoJICoNCgkgKiBAcmV0dXJuICBib29sIHRydWUgICBPbiBzdWNjZXNzDQoJICoNCgkgKiBAc2luY2UgIDMuMC45DQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiB3cml0ZSgkcGF0aCwgJGRhdGEpDQoJew0KCQkka2xhYXIgPSBmYWxzZTsNCgkJaWYgKFN0cmluZ0hlbHBlcjo6Y2hlY2soJGRhdGEpKQ0KCQl7DQoJCQkvLyBvcGVuIHRoZSBmaWxlDQoJCQkkZmggPSBmb3BlbigkcGF0aCwgInciKTsNCgkJCWlmICghaXNfcmVzb3VyY2UoJGZoKSkNCgkJCXsNCgkJCQlyZXR1cm4gJGtsYWFyOw0KCQkJfQ0KCQkJLy8gd3JpdGUgdG8gdGhlIGZpbGUNCgkJCWlmIChmd3JpdGUoJGZoLCAkZGF0YSkpDQoJCQl7DQoJCQkJLy8gaGFzIGJlZW4gZG9uZQ0KCQkJCSRrbGFhciA9IHRydWU7DQoJCQl9DQoJCQkvLyBjbG9zZSBmaWxlLg0KCQkJZmNsb3NlKCRmaCk7DQoJCX0NCgkJcmV0dXJuICRrbGFhcjsNCgl9DQoNCgkvKioNCgkgKiBnZXQgYWxsIHRoZSBmaWxlIHBhdGhzIGluIGZvbGRlciBhbmQgc3ViIGZvbGRlcnMNCgkgKiANCgkgKiBAcGFyYW0gICBzdHJpbmcgICRmb2xkZXIgICAgIFRoZSBsb2NhbCBwYXRoIHRvIHBhcnNlDQoJICogQHBhcmFtICAgYXJyYXkgICAkZmlsZVR5cGVzICBUaGUgdHlwZSBvZiBmaWxlcyB0byBnZXQNCgkgKg0KCSAqIEByZXR1cm4gIHZvaWQNCgkgKg0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldFBhdGhzKCRmb2xkZXIsICRmaWxlVHlwZXMgPSBhcnJheSgnXC5waHAnLCAnXC5qcycsICdcLmNzcycsICdcLmxlc3MnKSwgJHJlY3Vyc2UgPSB0cnVlLCAkZnVsbCA9IHRydWUpDQoJew0KCQlpZiAoRm9sZGVyOjpleGlzdHMoJGZvbGRlcikpDQoJCXsNCgkJCS8vIHdlIG11c3QgZmlyc3Qgc3RvcmUgdGhlIGN1cnJlbnQgd29raW5nIGRpcmVjdG9yeQ0KCQkJJGpvb21sYSA9IGdldGN3ZCgpOw0KCQkJLy8gd2UgYXJlIGNoYW5naW5nIHRoZSB3b3JraW5nIGRpcmVjdG9yeSB0byB0aGUgY29tcG9uZW50IHBhdGgNCgkJCWNoZGlyKCRmb2xkZXIpOw0KDQoJCQkvLyBtYWtlIHN1cmUgd2UgaGF2ZSBmaWxlIHR5cGUgZmlsdGVyDQoJCQlpZiAoQXJyYXlIZWxwZXI6OmNoZWNrKCRmaWxlVHlwZXMpKQ0KCQkJew0KCQkJCS8vIGdldCB0aGUgZmlsZXMNCgkJCQlmb3JlYWNoICgkZmlsZVR5cGVzIGFzICR0eXBlKQ0KCQkJCXsNCgkJCQkJLy8gZ2V0IGEgbGlzdCBvZiBmaWxlcyBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkgdHJlZQ0KCQkJCQkkZmlsZXNbXSA9IEZvbGRlcjo6ZmlsZXMoJy4nLCAkdHlwZSwgJHJlY3Vyc2UsICRmdWxsKTsNCgkJCQl9DQoJCQl9DQoJCQllbHNlaWYgKFN0cmluZ0hlbHBlcjo6Y2hlY2soJGZpbGVUeXBlcykpDQoJCQl7DQoJCQkJLy8gZ2V0IGEgbGlzdCBvZiBmaWxlcyBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkgdHJlZQ0KCQkJCSRmaWxlc1tdID0gRm9sZGVyOjpmaWxlcygnLicsICRmaWxlVHlwZXMsICRyZWN1cnNlLCAkZnVsbCk7DQoJCQl9DQoJCQllbHNlDQoJCQl7DQoJCQkJLy8gZ2V0IGEgbGlzdCBvZiBmaWxlcyBpbiB0aGUgY3VycmVudCBkaXJlY3RvcnkgdHJlZQ0KCQkJCSRmaWxlc1tdID0gRm9sZGVyOjpmaWxlcygnLicsICcuJywgJHJlY3Vyc2UsICRmdWxsKTsNCgkJCX0NCg0KCQkJLy8gY2hhbmdlIGJhY2sgdG8gSm9vbWxhIHdvcmtpbmcgZGlyZWN0b3J5DQoJCQljaGRpcigkam9vbWxhKTsNCg0KCQkJLy8gcmV0dXJuIGFycmF5IG9mIGZpbGVzDQoJCQlyZXR1cm4gYXJyYXlfbWFwKCBmbigkZmlsZSkgPT4gc3RyX3JlcGxhY2UoJy4vJywgJy8nLCAoc3RyaW5nKSAkZmlsZSksIChhcnJheSkgQXJyYXlIZWxwZXI6Om1lcmdlKCRmaWxlcykpOw0KCQl9DQoJCXJldHVybiBmYWxzZTsNCgl9DQoNCgkvKioNCgkgKiBHZXQgdGhlIGZpbGUgcGF0aCBvciB1cmwNCgkgKg0KCSAqIEBwYXJhbSAgc3RyaW5nICAgJHR5cGUgICAgICAgICAgICAgIFRoZSAodXJsL3BhdGgpIHR5cGUgdG8gcmV0dXJuDQoJICogQHBhcmFtICBzdHJpbmcgICAkdGFyZ2V0ICAgICAgICAgICAgVGhlIFBhcmFtcyBUYXJnZXQgbmFtZSAoaWYgc2V0KQ0KCSAqIEBwYXJhbSAgc3RyaW5nICAgJGZpbGVUeXBlICAgICAgICAgIFRoZSBraW5kIG9mIGZpbGVuYW1lIHRvIGdlbmVyYXRlIChpZiBub3Qgc2V0IG5vIGZpbGUgbmFtZSBpcyBnZW5lcmF0ZWQpDQoJICogQHBhcmFtICBzdHJpbmcgICAka2V5ICAgICAgICAgICAgICAgVGhlIGtleSB0byBhZGp1c3QgdGhlIGZpbGVuYW1lIChpZiBub3Qgc2V0IGlnbm9yZWQpDQoJICogQHBhcmFtICBzdHJpbmcgICAkZGVmYXVsdCAgICAgICAgICAgVGhlIGRlZmF1bHQgcGF0aCBpZiBub3Qgc2V0IGluIFBhcmFtcyAoZmFsbGJhY2sgcGF0aCkNCgkgKiBAcGFyYW0gIGJvb2wgICAgICRjcmVhdGVJZk5vdFNldCAgICBUaGUgc3dpdGNoIHRvIGNyZWF0ZSB0aGUgZm9sZGVyIGlmIG5vdCBmb3VuZA0KCSAqDQoJICogQHJldHVybiAgc3RyaW5nICAgIE9uIHN1Y2Nlc3MgdGhlIHBhdGggb3IgdXJsIGlzIHJldHVybmVkIGJhc2VkIG9uIHRoZSB0eXBlIHJlcXVlc3RlZA0KCSAqDQoJICogQHNpbmNlICAzLjAuOQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0UGF0aCgkdHlwZSA9ICdwYXRoJywgJHRhcmdldCA9ICdmaWxlcGF0aCcsICRmaWxlVHlwZSA9IG51bGwsICRrZXkgPSAnJywgJGRlZmF1bHQgPSAnJywgJGNyZWF0ZUlmTm90U2V0ID0gdHJ1ZSkNCgl7DQoJCS8vIG1ha2Ugc3VyZSB0byBhbHdheXMgaGF2ZSBhIHN0cmluZy9wYXRoDQoJCWlmKCFTdHJpbmdIZWxwZXI6OmNoZWNrKCRkZWZhdWx0KSkNCgkJew0KCQkJJGRlZmF1bHQgPSBKUEFUSF9TSVRFIC4gJy9pbWFnZXMvJzsNCgkJfQ0KDQoJCS8vIGdldCB0aGUgZ2xvYmFsIHNldHRpbmdzDQoJCSRmaWxlUGF0aCA9IEhlbHBlcjo6Z2V0UGFyYW1zKCktPmdldCgkdGFyZ2V0LCAkZGVmYXVsdCk7DQoNCgkJLy8gY2hlY2sgdGhlIGZpbGUgcGF0aCAocmV2ZXJ0IHRvIGRlZmF1bHQgb25seSBvZiBub3QgYSBoaWRkZW4gZmlsZSBwYXRoKQ0KCQlpZiAoJ2hpZGRlbmZpbGVwYXRoJyAhPT0gJHRhcmdldCAmJiBzdHJwb3MoKHN0cmluZykgJGZpbGVQYXRoLCAoc3RyaW5nKSBKUEFUSF9TSVRFKSA9PT0gZmFsc2UpDQoJCXsNCgkJCSRmaWxlUGF0aCA9ICRkZWZhdWx0Ow0KCQl9DQoNCgkJLy8gY3JlYXRlIHRoZSBmb2xkZXIgaWYgaXQgZG9lcyBub3QgZXhpc3QNCgkJaWYgKCRjcmVhdGVJZk5vdFNldCAmJiAhRm9sZGVyOjpleGlzdHMoJGZpbGVQYXRoKSkNCgkJew0KCQkJRm9sZGVyOjpjcmVhdGUoJGZpbGVQYXRoKTsNCgkJfQ0KDQoJCS8vIHNldHVwIHRoZSBmaWxlIG5hbWUNCgkJJGZpbGVOYW1lID0gJyc7DQoNCgkJLy8gR2V0IGJhc2ljIGtleQ0KCQkkYmFzaWNrZXkgPSAnVGghc19pU19uMHRfc0FmZV9idVRfYjN0dGVyX3RoZW5fbjB0aGl1Zyc7DQoJCS8vIGdldCB0aGUgY29tcG9uZW50IGhlbHBlcg0KCQkkaGVscGVyID0gSGVscGVyOjpnZXQoKTsNCgkJLy8gY2hlY2sgaWYgbWV0aG9kIGV4aXN0IGluIGhlbHBlciBjbGFzcw0KCQlpZiAoJGhlbHBlciAmJiBIZWxwZXI6Om1ldGhvZEV4aXN0cygnZ2V0Q3J5cHRLZXknKSkgDQoJCXsNCgkJCSRiYXNpY2tleSA9ICRoZWxwZXI6OmdldENyeXB0S2V5KCdiYXNpYycsICRiYXNpY2tleSk7DQoJCX0NCg0KCQkvLyBjaGVjayB0aGUga2V5DQoJCWlmICghU3RyaW5nSGVscGVyOjpjaGVjaygka2V5KSkNCgkJew0KCQkJJGtleSA9ICd2RG0nOw0KCQl9DQoNCgkJLy8gc2V0IHRoZSBmaWxlIG5hbWUNCgkJaWYgKFN0cmluZ0hlbHBlcjo6Y2hlY2soJGZpbGVUeXBlKSkNCgkJew0KCQkJLy8gc2V0IHRoZSBuYW1lDQoJCQkkZmlsZU5hbWUgPSB0cmltKCBtZDUoJHR5cGUgLiAkdGFyZ2V0IC4gJGJhc2lja2V5IC4gJGtleSkgLiAnLicgLiB0cmltKCRmaWxlVHlwZSwgJy4nKSk7DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQkkZmlsZU5hbWUgPSB0cmltKCBtZDUoJHR5cGUgLiAkdGFyZ2V0IC4gJGJhc2lja2V5IC4gJGtleSkpIC4gJy50eHQnOw0KCQl9DQoNCgkJLy8gcmV0dXJuIHRoZSB1cmwNCgkJaWYgKCd1cmwnID09PSAkdHlwZSkNCgkJew0KCQkJaWYgKFxzdHJwb3MoKHN0cmluZykgJGZpbGVQYXRoLCAoc3RyaW5nKSBKUEFUSF9TSVRFKSAhPT0gZmFsc2UpDQoJCQl7DQoJCQkJJGZpbGVQYXRoID0gdHJpbSggc3RyX3JlcGxhY2UoIEpQQVRIX1NJVEUsICcnLCAoc3RyaW5nKSAkZmlsZVBhdGgpLCAnLycpOw0KDQoJCQkJcmV0dXJuIFVyaTo6cm9vdCgpIC4gJGZpbGVQYXRoIC4gJy8nIC4gJGZpbGVOYW1lOw0KCQkJfQ0KDQoJCQkvLyBzaW5jZSB0aGUgcGF0aCBpcyBiZWhpbmQgdGhlIHJvb3QgZm9sZGVyIG9mIHRoZSBzaXRlLCByZXR1cm4gb25seSB0aGUgcm9vdCB1cmwgKG1heSBiZSB1c2VkIHRvIGJ1aWxkIHRoZSBsaW5rKQ0KCQkJcmV0dXJuIFVyaTo6cm9vdCgpOw0KCQl9DQoNCgkJLy8gc2FuaXRpemUgdGhlIHBhdGgNCgkJcmV0dXJuICcvJyAuIHRyaW0oKHN0cmluZykgICRmaWxlUGF0aCwgJy8nICkgLiAnLycgLiAkZmlsZU5hbWU7DQoJfQ0KDQoJLyoqDQoJICogQ2hlY2sgaWYgZmlsZSBleGlzdA0KCSAqDQoJICogQHBhcmFtICBzdHJpbmcgICAkcGF0aCAgIFRoZSB1cmwvcGF0aCB0byBjaGVjaw0KCSAqDQoJICogQHJldHVybiAgYm9vbCAgICAgIElmIGV4aXN0IHRydWUNCgkgKg0KCSAqIEBzaW5jZSAgMy4wLjkNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGV4aXN0cygkcGF0aCkNCgl7DQoJCSRleGlzdHMgPSBmYWxzZTsNCgkJLy8gaWYgdGhpcyBpcyBhIGxvY2FsIHBhdGgNCgkJaWYgKHN0cnBvcygkcGF0aCwgJ2h0dHA6JykgPT09IGZhbHNlICYmIHN0cnBvcygkcGF0aCwgJ2h0dHBzOicpID09PSBmYWxzZSkNCgkJew0KCQkJaWYgKGZpbGVfZXhpc3RzKCRwYXRoKSkNCgkJCXsNCgkJCQkkZXhpc3RzID0gdHJ1ZTsNCgkJCX0NCgkJfQ0KCQkvLyBjaGVjayBpZiB3ZSBjYW4gdXNlIGN1cmwNCgkJZWxzZWlmIChmdW5jdGlvbl9leGlzdHMoJ2N1cmxfdmVyc2lvbicpKQ0KCQl7DQoJCQkvLyBpbml0aWF0ZSBjdXJsDQoJCQkkY2ggPSBjdXJsX2luaXQoJHBhdGgpOw0KCQkJLy8gQ1VSTE9QVF9OT0JPRFkgKGRvIG5vdCByZXR1cm4gYm9keSkNCgkJCWN1cmxfc2V0b3B0KCRjaCwgQ1VSTE9QVF9OT0JPRFksIHRydWUpOw0KCQkJLy8gbWFrZSBjYWxsDQoJCQkkcmVzdWx0ID0gY3VybF9leGVjKCRjaCk7DQoJCQkvLyBjaGVjayByZXR1cm4gdmFsdWUNCgkJCWlmICgkcmVzdWx0ICE9PSBmYWxzZSkNCgkJCXsNCgkJCQkvLyBnZXQgdGhlIGh0dHAgQ09ERQ0KCQkJCSRzdGF0dXNDb2RlID0gY3VybF9nZXRpbmZvKCRjaCwgQ1VSTElORk9fSFRUUF9DT0RFKTsNCgkJCQlpZiAoJHN0YXR1c0NvZGUgIT09IDQwNCkNCgkJCQl7DQoJCQkJCSRleGlzdHMgPSB0cnVlOw0KCQkJCX0NCgkJCX0NCgkJCS8vIGNsb3NlIHRoZSBjb25uZWN0aW9uDQoJCQljdXJsX2Nsb3NlKCRjaCk7DQoJCX0NCgkJZWxzZWlmICgkaGVhZGVycyA9IEBnZXRfaGVhZGVycygkcGF0aCkpDQoJCXsNCgkJCWlmKGlzc2V0KCRoZWFkZXJzWzBdKSAmJiBpc19zdHJpbmcoJGhlYWRlcnNbMF0pICYmIHN0cnBvcygkaGVhZGVyc1swXSwnNDA0JykgPT09IGZhbHNlKQ0KCQkJew0KCQkJCSRleGlzdHMgPSB0cnVlOw0KCQkJfQ0KCQl9DQoJCXJldHVybiAkZXhpc3RzOw0KCX0NCg==', '{}', 'FileHelper', 'VDM\\Joomla\\Utilities.FileHelper', '1.0.0', '{}', 'Utilities FileHelper', 'abstract class', '{\"use_selection0\":{\"use\":\"640b5352-fb09-425f-a26e-cd44eda03f15\",\"as\":\"default\"}}', '', 1, '2022-03-12 02:09:18', '2023-02-05 17:42:56', 33, 9), -(23, 1, 'Some component helper\r\n\r\n@since 3.0.11', '', '', '640b5352-fb09-425f-a26e-cd44eda03f15', 'dXNlIEpvb21sYVxJbnB1dFxJbnB1dDsNCnVzZSBKb29tbGFcQ01TXENvbXBvbmVudFxDb21wb25lbnRIZWxwZXI7DQp1c2UgSm9vbWxhXFJlZ2lzdHJ5XFJlZ2lzdHJ5Ow==', '', '', '{}', 'CS8qKg0KCSAqIFRoZSBjdXJyZW50IG9wdGlvbg0KCSAqDQoJICogQHZhciAgICBzdHJpbmcNCgkgKiBAc2luY2UgICAzLjAuMTENCgkgKi8NCglwdWJsaWMgc3RhdGljIHN0cmluZyAkb3B0aW9uOw0KDQoJLyoqDQoJICogVGhlIGNvbXBvbmVudCBwYXJhbXMgbGlzdCBjYWNoZQ0KCSAqDQoJICogQHZhciAgICBSZWdpc3RyeVtdDQoJICogQHNpbmNlICAgMy4wLjExDQoJICovDQoJcHJvdGVjdGVkIHN0YXRpYyBhcnJheSAkcGFyYW1zID0gW107DQoNCgkvKioNCgkgKiBHZXRzIHRoZSBwYXJhbWV0ZXIgb2JqZWN0IGZvciB0aGUgY29tcG9uZW50DQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmd8bnVsbCAgICAgJG9wdGlvbiAgVGhlIG9wdGlvbiBmb3IgdGhlIGNvbXBvbmVudC4NCgkgKg0KCSAqIEByZXR1cm4gIFJlZ2lzdHJ5ICAgICBBIFJlZ2lzdHJ5IG9iamVjdC4NCgkgKiBAc2VlICAgICBSZWdpc3RyeQ0KCSAqIEBzaW5jZSAgIDMuMC4xMQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0UGFyYW1zKD9zdHJpbmcgJG9wdGlvbiA9IG51bGwpOiBSZWdpc3RyeQ0KCXsNCgkJLy8gY2hlY2sgdGhhdCB3ZSBoYXZlIGFuIG9wdGlvbg0KCQlpZiAoZW1wdHkoJG9wdGlvbikpDQoJCXsNCgkJCSRvcHRpb24gPSBzZWxmOjpnZXRPcHRpb24oKTsNCgkJfQ0KDQoJCS8vIGdldCBnbG9iYWwgdmFsdWUNCgkJaWYgKCFpc3NldChzZWxmOjokcGFyYW1zWyRvcHRpb25dKSB8fCAhc2VsZjo6JHBhcmFtc1skb3B0aW9uXSBpbnN0YW5jZW9mIFJlZ2lzdHJ5KQ0KCQl7DQoJCQlzZWxmOjokcGFyYW1zWyRvcHRpb25dID0gQ29tcG9uZW50SGVscGVyOjpnZXRQYXJhbXMoJG9wdGlvbik7DQoJCX0NCg0KCQlyZXR1cm4gc2VsZjo6JHBhcmFtc1skb3B0aW9uXTsNCgl9DQoNCgkvKioNCgkgKiBHZXRzIHRoZSBjb21wb25lbnQgb3B0aW9uDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmd8bnVsbCAgICAgICRkZWZhdWx0ICBUaGUgZGVmYXVsdCByZXR1cm4gdmFsdWUgaWYgbm9uZSBpcyBmb3VuZA0KCSAqDQoJICogQHJldHVybiAgc3RyaW5nfG51bGwgICAgICBBIGNvbXBvbmVudCBvcHRpb24NCgkgKiBAc2luY2UgICAzLjAuMTENCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGdldE9wdGlvbihzdHJpbmcgJGRlZmF1bHQgPSAnZW1wdHknKTogP3N0cmluZw0KCXsNCgkJaWYgKGVtcHR5KHNlbGY6OiRvcHRpb24pKQ0KCQl7DQoJCQkvLyBnZXQgdGhlIG9wdGlvbiBmcm9tIHRoZSB1cmwgaW5wdXQNCgkJCXNlbGY6OiRvcHRpb24gPSAobmV3IElucHV0KS0+Z2V0U3RyaW5nKCdvcHRpb24nLCBmYWxzZSk7DQoJCX0NCg0KCQlpZiAoc2VsZjo6JG9wdGlvbikNCgkJew0KCQkJIHJldHVybiBzZWxmOjokb3B0aW9uOw0KCQl9DQoNCgkJcmV0dXJuICRkZWZhdWx0Ow0KCX0NCg0KCS8qKg0KCSAqIEdldHMgdGhlIGNvbXBvbmVudCBjb2RlIG5hbWUNCgkgKg0KCSAqIEBwYXJhbSAgIHN0cmluZ3xudWxsICAgICRvcHRpb24gICBUaGUgb3B0aW9uIGZvciB0aGUgY29tcG9uZW50Lg0KCSAqIEBwYXJhbSAgIHN0cmluZ3xudWxsICAgICRkZWZhdWx0ICBUaGUgZGVmYXVsdCByZXR1cm4gdmFsdWUgaWYgbm9uZSBpcyBmb3VuZA0KCSAqDQoJICogQHJldHVybiAgc3RyaW5nfG51bGwgICAgQSBjb21wb25lbnQgY29kZSBuYW1lDQoJICogQHNpbmNlICAgMy4wLjExDQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXRDb2RlKD9zdHJpbmcgJG9wdGlvbiA9IG51bGwsID9zdHJpbmcgJGRlZmF1bHQgPSBudWxsKTogP3N0cmluZw0KCXsNCgkJLy8gY2hlY2sgdGhhdCB3ZSBoYXZlIGFuIG9wdGlvbg0KCQlpZiAoZW1wdHkoJG9wdGlvbikpDQoJCXsNCgkJCSRvcHRpb24gPSBzZWxmOjpnZXRPcHRpb24oKTsNCgkJfQ0KCQkvLyBvcHRpb24gd2l0aCBjb21fDQoJCWlmIChpc19zdHJpbmcoJG9wdGlvbikgJiYgc3RycG9zKCRvcHRpb24sICdjb21fJykgPT09IDApDQoJCXsNCgkJCXJldHVybiBzdHJ0b2xvd2VyKHRyaW0oc3Vic3RyKCRvcHRpb24sIDQpKSk7DQoJCX0NCg0KCQlyZXR1cm4gJGRlZmF1bHQ7DQoJfQ0KDQoJLyoqDQoJICogR2V0cyB0aGUgY29tcG9uZW50IGFic3RyYWN0IGhlbHBlciBjbGFzcw0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nfG51bGwgICAgJG9wdGlvbiAgIFRoZSBvcHRpb24gZm9yIHRoZSBjb21wb25lbnQuDQoJICogQHBhcmFtICAgc3RyaW5nfG51bGwgICAgJGRlZmF1bHQgIFRoZSBkZWZhdWx0IHJldHVybiB2YWx1ZSBpZiBub25lIGlzIGZvdW5kDQoJICoNCgkgKiBAcmV0dXJuICBzdHJpbmd8bnVsbCAgICBBIGNvbXBvbmVudCBoZWxwZXIgbmFtZQ0KCSAqDQoJICogQHNpbmNlICAgMy4wLjExDQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXQoc3RyaW5nICRvcHRpb24gPSBudWxsLCBzdHJpbmcgJGRlZmF1bHQgPSBudWxsKTogP3N0cmluZw0KCXsNCgkJLy8gY2hlY2sgdGhhdCB3ZSBoYXZlIGFuIG9wdGlvbg0KCQkvLyBhbmQgZ2V0IHRoZSBjb2RlIG5hbWUgZnJvbSBpdA0KCQlpZiAoKCRjb2RlX25hbWUgPSBzZWxmOjpnZXRDb2RlKCRvcHRpb24sIGZhbHNlKSkgIT09IGZhbHNlKQ0KCQl7DQoJCQkvLyB3ZSBidWlsZCB0aGUgaGVscGVyIGNsYXNzIG5hbWUNCgkJCSRoZWxwZXJfbmFtZSA9ICdcXCcgLiBcdWNmaXJzdCgkY29kZV9uYW1lKSAuICdIZWxwZXInOw0KCQkJLy8gY2hlY2sgaWYgY2xhc3MgZXhpc3QNCgkJCWlmIChjbGFzc19leGlzdHMoJGhlbHBlcl9uYW1lKSkNCgkJCXsNCgkJCQlyZXR1cm4gJGhlbHBlcl9uYW1lOw0KCQkJfQ0KCQl9DQoNCgkJcmV0dXJuICRkZWZhdWx0Ow0KCX0NCg0KCS8qKg0KCSAqIENoZWNrIGlmIHRoZSBoZWxwZXIgY2xhc3Mgb2YgdGhpcyBjb21wb25lbnQgaGFzIGEgbWV0aG9kDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICAgICAgJG1ldGhvZCAgVGhlIG1ldGhvZCBuYW1lIHRvIHNlYXJjaCBmb3INCgkgKiBAcGFyYW0gICBzdHJpbmd8bnVsbCAgJG9wdGlvbiAgVGhlIG9wdGlvbiBmb3IgdGhlIGNvbXBvbmVudC4NCgkgKg0KCSAqIEByZXR1cm4gIGJvb2wgICAgdHJ1ZSBpZiBtZXRob2QgZXhpc3QNCgkgKg0KCSAqIEBzaW5jZSAgIDMuMC4xMQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gbWV0aG9kRXhpc3RzKHN0cmluZyAkbWV0aG9kLCBzdHJpbmcgJG9wdGlvbiA9IG51bGwpOiBib29sDQoJew0KCQkvLyBnZXQgdGhlIGhlbHBlciBjbGFzcw0KCQlyZXR1cm4gKCRoZWxwZXIgPSBzZWxmOjpnZXQoJG9wdGlvbiwgZmFsc2UpKSAhPT0gZmFsc2UgJiYNCgkJCW1ldGhvZF9leGlzdHMoJGhlbHBlciwgJG1ldGhvZCk7DQoJfQ0KDQoJLyoqDQoJICogQ2hlY2sgaWYgdGhlIGhlbHBlciBjbGFzcyBvZiB0aGlzIGNvbXBvbmVudCBoYXMgYSBtZXRob2QsIGFuZCBjYWxsIGl0IHdpdGggdGhlIGFyZ3VtZW50cw0KCSAqDQoJICogQHBhcmFtICAgc3RyaW5nICAgICAgICAkbWV0aG9kICAgICBUaGUgbWV0aG9kIG5hbWUgdG8gc2VhcmNoIGZvcg0KCSAqIEBwYXJhbSAgIGFycmF5ICAgICAgICAgJGFyZ3VtZW50cyAgVGhlIGFyZ3VtZW50cyBmb3IgZnVuY3Rpb24uDQoJICogQHBhcmFtICAgc3RyaW5nfG51bGwgICAkb3B0aW9uICAgICBUaGUgb3B0aW9uIGZvciB0aGUgY29tcG9uZW50Lg0KCSAqDQoJICogQHJldHVybiAgbWl4ZWQgICAgcmV0dXJuIHdoYXRldmVyIHRoZSBtZXRob2QgcmV0dXJucyBvciBudWxsDQoJICogQHNpbmNlICAgMy4yLjANCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIF8oc3RyaW5nICRtZXRob2QsIGFycmF5ICRhcmd1bWVudHMgPSBbXSwgP3N0cmluZyAkb3B0aW9uID0gbnVsbCkNCgl7DQoJCS8vIGdldCB0aGUgaGVscGVyIGNsYXNzDQoJCWlmICgoJGhlbHBlciA9IHNlbGY6OmdldCgkb3B0aW9uLCBmYWxzZSkpICE9PSBmYWxzZSAmJg0KCQkJbWV0aG9kX2V4aXN0cygkaGVscGVyLCAkbWV0aG9kKSkNCgkJew0KCQkJLy8gd2Uga25vdyB0aGlzIGlzIG5vdCBpZGVhbC4uLg0KCQkJLy8gc28gd2UgbmVlZCB0byBtb3ZlIHRoZXNlDQoJCQkvLyBmdW5jdGlvbnMgdG8gdGhlaXIgb3duIGNsYXNzZXMNCgkJCXJldHVybiBjYWxsX3VzZXJfZnVuY19hcnJheShbJGhlbHBlciwgJG1ldGhvZF0sICAkYXJndW1lbnRzKTsNCgkJfQ0KDQoJCXJldHVybiBudWxsOw0KCX0NCg==', '{}', 'Helper', 'VDM\\Joomla\\Utilities.Component.Helper', '1.0.0', '{}', 'Utilities Component Helper', 'abstract class', '{}', '', 1, '2022-05-13 05:36:32', '2023-02-17 12:44:28', 28, 7), -(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\"}}', 'CS8qKg0KCSAqIFRydWUgdG8gdXNlIHN0cmVhbXMNCgkgKg0KCSAqIEB2YXIgICAgYm9vbA0KCSAqDQoJICogQHNpbmNlICAzLjAuMTENCgkgKi8NCglwdWJsaWMgc3RhdGljICR1c2VTdHJlYW1zID0gZmFsc2U7DQoNCgkvKioNCgkgKiBBbGxvdyB0aGUgdXBsb2FkIG9mIHVuc2FmZSBmaWxlcw0KCSAqDQoJICogQHZhciAgICBib29sDQoJICoNCgkgKiBAc2luY2UgIDMuMC4xMQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgJGFsbG93VW5zYWZlID0gZmFsc2U7DQoNCgkvKioNCgkgKiBPcHRpb25zIHRvIElucHV0RmlsdGVyOjppc1NhZmVGaWxlDQoJICoNCgkgKiBAdmFyICAgIGFycmF5DQoJICoNCgkgKiBAc2luY2UgIDMuMC4xMQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgJHNhZmVGaWxlT3B0aW9ucyA9IFtdOw0KDQoJLyoqDQoJICogU2V0IHRoZSBlcnJvciBiZWhhdmlvcg0KCSAqDQoJICogQHZhciAgICBib29sDQoJICoNCgkgKiBAc2luY2UgIDMuMC4xMQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgJGVucXVldWVFcnJvciA9IHRydWU7DQoNCgkvKioNCgkgKiBFcnJvcnMNCgkgKg0KCSAqIEB2YXIgICAgYXJyYXkNCgkgKg0KCSAqIEBzaW5jZSAgMy4wLjExDQoJICovDQoJcHJvdGVjdGVkIHN0YXRpYyAkZXJyb3JzID0gW107DQoNCgkvKioNCgkgKiBHZXQgZmlsZS9maWxlcyBmcm9tIGEgSFRUUCB1cGxvYWQuDQoJICoNCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgICAkZmllbGQgICAgICAgIFRoZSBpbnB1dCBmaWVsZCBuYW1lDQoJICogQHBhcmFtICBzdHJpbmcgICAgICAgICAgJHR5cGUgICAgICAgIFRoZSBmaWxlIHR5cGUNCgkgKiBAcGFyYW0gIHN0cmluZ3xudWxsICAgJGZpbHRlciAgICAgICAgVGhlIGZpbHRlciB0byB1c2Ugd2hlbiB1cGxvYWRpbmcgdGhlIGZpbGUNCgkgKiBAcGFyYW0gIHN0cmluZ3xudWxsICAgJHBhdGggICAgICAgIFRoZSBwYXRoIHRvIHRoZSBkaXJlY3Rvcnkgd2hlcmUgdGhlIGltYWdlIG11c3QgYmUgcGxhY2VkDQoJICoNCgkgKiBAcmV0dXJuICBtaXhlZCAgIEZpbGUgZGV0YWlscyBvciBmYWxzZSBvbiBmYWlsdXJlLg0KCSAqIEBzaW5jZSAgMy4wLjExDQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBnZXQoc3RyaW5nICRmaWVsZCwgc3RyaW5nICR0eXBlLCBzdHJpbmcgJGZpbHRlciA9IG51bGwsIHN0cmluZyAkcGF0aCA9IG51bGwpDQoJew0KCQkvLyBHZXQgdGhlIHVwbG9hZGVkIGZpbGUgaW5mb3JtYXRpb24uDQoJCSRpbnB1dCAgICA9IEZhY3Rvcnk6OmdldEFwcGxpY2F0aW9uKCktPmlucHV0Ow0KDQoJCS8vIHNldCB0aGUgZGVmYXVsdCBmaWx0ZXINCgkJaWYgKGVtcHR5KCRmaWx0ZXIpKQ0KCQl7DQoJCQkkZmlsdGVyID0gJ2FycmF5JzsNCgkJfQ0KCQkvLyBpZiByYXcgdGhlbiBhbHNvIHVuc2FmZQ0KCQkvLyBzZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9qb29tbGEvam9vbWxhLWNtcy9ibG9iLzQuMS1kZXYvYWRtaW5pc3RyYXRvci9jb21wb25lbnRzL2NvbV9pbnN0YWxsZXIvc3JjL01vZGVsL0luc3RhbGxNb2RlbC5waHAjTDI1OQ0KCQllbHNlaWYgKCRmaWx0ZXIgPT09ICdyYXcnKQ0KCQl7DQoJCQlzZWxmOjokYWxsb3dVbnNhZmUgPSB0cnVlOw0KCQl9DQoNCgkJLy8gY2hlY2sgaWYgd2UgaGF2ZSBhIGZpbGUgZGVzdGluYXRpb24gbmFtZSBpbiB0aGUgZmllbGQgbmFtZQ0KCQkkbmFtZSA9IG51bGw7DQoJCWlmIChzdHJwb3MoJGZpZWxkLCAnOicpICE9PSBmYWxzZSkNCgkJew0KCQkJbGlzdCgkZmllbGQsICRuYW1lKSA9IGV4cGxvZGUoJzonLCAkZmllbGQpOw0KCQl9DQoNCgkJLy8gU2VlIEpJbnB1dEZpbGVzOjpnZXQuDQoJCSR1c2VyZmlsZSA9ICRpbnB1dC0+ZmlsZXMtPmdldCgkZmllbGQsIG51bGwsICRmaWx0ZXIpOw0KDQoJCS8vIE1ha2Ugc3VyZSB0aGF0IGZpbGUgdXBsb2FkcyBhcmUgZW5hYmxlZCBpbiBwaHAuDQoJCWlmICghKGJvb2wpIGluaV9nZXQoJ2ZpbGVfdXBsb2FkcycpKQ0KCQl7DQoJCQlzZWxmOjpzZXRFcnJvcihUZXh0OjpfKCdXYXJuaW5nLCB1cGxvYWQgZXJyb3IuJykpOw0KDQoJCQlyZXR1cm4gZmFsc2U7DQoJCX0NCg0KCQkvLyBJZiB0aGVyZSBpcyBubyB1cGxvYWRlZCBmaWxlLCB3ZSBoYXZlIGEgcHJvYmxlbS4uLg0KCQlpZiAoIWlzX2FycmF5KCR1c2VyZmlsZSkpDQoJCXsNCgkJCXNlbGY6OnNldEVycm9yKFRleHQ6Ol8oJ05vIHVwbG9hZCBzZWxlY3RlZCcpKTsNCg0KCQkJcmV0dXJuIGZhbHNlOw0KCQl9DQoNCgkJLy8gSXMgdGhlIFBIUCB0bXAgZGlyZWN0b3J5IG1pc3Npbmc/DQoJCWlmICgkdXNlcmZpbGVbJ2Vycm9yJ10gJiYgKCR1c2VyZmlsZVsnZXJyb3InXSA9PSBVUExPQURfRVJSX05PX1RNUF9ESVIpKQ0KCQl7DQoJCQlzZWxmOjpzZXRFcnJvcihUZXh0OjpfKCdUaGVyZSB3YXMgYW4gZXJyb3IgdXBsb2FkaW5nIHRvIHRoZSBzZXJ2ZXIuJykgLiAnPGJyPicgLiBUZXh0OjpfKCdUaGUgUEhQIHRlbXBvcmFyeSBmb2xkZXIgaXMgbm90IHNldC4nKSk7DQoNCgkJCXJldHVybiBmYWxzZTsNCgkJfQ0KDQoJCS8vIElzIHRoZSBtYXggdXBsb2FkIHNpemUgdG9vIHNtYWxsIGluIHBocC5pbmk/DQoJCWlmICgkdXNlcmZpbGVbJ2Vycm9yJ10gJiYgKCR1c2VyZmlsZVsnZXJyb3InXSA9PSBVUExPQURfRVJSX0lOSV9TSVpFKSkNCgkJew0KCQkJc2VsZjo6c2V0RXJyb3IoVGV4dDo6XygnVGhlcmUgd2FzIGFuIGVycm9yIHVwbG9hZGluZyB0byB0aGUgc2VydmVyLicpIC4gJzxicj4nIC4gVGV4dDo6XygnWW91ciBmaWxlIHdhcyBpcyBsYXJnZXIgdGhhbiB0aGUgYWxsb3dlZCBzaXplLicpKTsNCg0KCQkJcmV0dXJuIGZhbHNlOw0KCQl9DQoNCgkJLy8gQ2hlY2sgaWYgdGhlcmUgd2FzIGEgZGlmZmVyZW50IHByb2JsZW0gdXBsb2FkaW5nIHRoZSBmaWxlLg0KCQlpZiAoJHVzZXJmaWxlWydlcnJvciddIHx8ICR1c2VyZmlsZVsnc2l6ZSddIDwgMSkNCgkJew0KCQkJc2VsZjo6c2V0RXJyb3IoVGV4dDo6XygnVGhlcmUgd2FzIGFuIGVycm9yIHVwbG9hZGluZyB0byB0aGUgc2VydmVyLicpKTsNCg0KCQkJcmV0dXJuIGZhbHNlOw0KCQl9DQoNCgkJLy8gY2hlY2sgaWYgYSBwYXRoIHdhcyBwYXNzZWQgYW5kIGV4aXN0DQoJCWlmIChpc19zdHJpbmcoJHBhdGgpICYmIEZvbGRlcjo6Y3JlYXRlKCRwYXRoKSkNCgkJew0KCQkJLy8gc2V0IHRoZSBwYXRoDQoJCQkkdXNlcmZpbGVbJ3BhdGgnXSA9ICRwYXRoOw0KCQl9DQoJCWVsc2UNCgkJew0KCQkJLy8gZ2V0IHRoZSBKb29tbGEgY29uZmlnIGNsYXNzDQoJCQkkY29uZmlnID0gRmFjdG9yeTo6Z2V0Q29uZmlnKCk7DQoJCQkvLyBzZXQgdGhlIHBhdGgNCgkJCSR1c2VyZmlsZVsncGF0aCddID0gJGNvbmZpZy0+Z2V0KCd0bXBfcGF0aCcpOw0KCQl9DQoNCgkJLy8gc2V0IHRoZSByYW5kb20gcGFydCBvZiB0aGUgbmFtZQ0KCQkkdXNlcmZpbGVbJ3JhbmRvbSddID0gU3RyaW5nSGVscGVyOjpyYW5kb20oMTIpOw0KDQoJCS8vIHNldCB0aGUgZmlsZSBuYW1lDQoJCWlmIChlbXB0eSgkbmFtZSkpDQoJCXsNCgkJCS8vIHNldCB0aGUgZmlsZSBuYW1lDQoJCQkkdXNlcmZpbGVbJ2ZpbGVfbmFtZSddID0gJHVzZXJmaWxlWydyYW5kb20nXSAuICR1c2VyZmlsZVsnbmFtZSddOw0KCQl9DQoJCWVsc2UNCgkJew0KCQkJLy8gY2hlY2sgdGhhdCBoaXMgbmFtZSBoYXMgZmlsZSBmb3JtYXQNCgkJCWlmIChpc19zdHJpbmcoJG5hbWUpICYmIHN0cnBvcygkbmFtZSwgJy4nKSA9PT0gZmFsc2UpDQoJCQl7DQoJCQkJJG5hbWUgPSAkbmFtZSAuICcuJyAuIE1pbWVIZWxwZXI6OmV4dGVuc2lvbihudWxsLCAkdXNlcmZpbGVbJ3R5cGUnXSk7DQoJCQl9DQoJCQkkdXNlcmZpbGVbJ2ZpbGVfbmFtZSddID0gJG5hbWU7DQoJCX0NCg0KCQkvLyBzZXQgZnVsbCBwYXRoDQoJCSR1c2VyZmlsZVsnZnVsbF9wYXRoJ10gPSAkdXNlcmZpbGVbJ3BhdGgnXSAuICcvJyAuICR1c2VyZmlsZVsnZmlsZV9uYW1lJ107DQoNCgkJLy8gVXBsb2FkIHRoZSBmaWxlLg0KCQlpZiAoRmlsZTo6dXBsb2FkKCR1c2VyZmlsZVsndG1wX25hbWUnXSwgJHVzZXJmaWxlWydmdWxsX3BhdGgnXSwgc2VsZjo6JHVzZVN0cmVhbXMsIHNlbGY6OiRhbGxvd1Vuc2FmZSkpDQoJCXsNCgkJCS8vIENoZWNrIHRoYXQgdGhpcyBpcyBhIHZhbGlkIGZpbGUNCgkJCXJldHVybiBzZWxmOjpjaGVjaygkdXNlcmZpbGUsICR0eXBlKTsNCgkJfQ0KCQlyZXR1cm4gZmFsc2U7DQoJfQ0KDQoJLyoqDQoJICogR2V0IHRoZSBlcnJvcnMNCgkgKg0KCSAqIEBwYXJhbSAgYm9vbCAgICAgICAgICR0b1N0cmluZyAgICAgIFRoZSBvcHRpb24gdG8gcmV0dXJuIGVycm9ycyBhcyBhIHN0cmluZw0KCSAqDQoJICogQHJldHVybiAgYXJyYXkNCgkgKiBAc2luY2UgIDMuMC4xMQ0KCSAqLw0KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24gZ2V0RXJyb3IoJHRvU3RyaW5nID0gZmFsc2UpDQoJew0KCQlpZiAoJHRvU3RyaW5nKQ0KCQl7DQoJCQlyZXR1cm4gaW1wbG9kZSgnICcgLiBQSFBfRU9MLCBzZWxmOjokZXJyb3JzKTsNCgkJfQ0KCQlyZXR1cm4gc2VsZjo6JGVycm9yczsNCgl9DQoNCgkvKioNCgkgKiBDaGVjayBhIGZpbGUgYW5kIHZlcmlmaWVzIGl0IGFzIGEgYWxsb3dlZCBmaWxlIGZvcm1hdCBmaWxlDQoJICoNCgkgKiBAcGFyYW0gIGFycmF5ICAgICAgICAgJHVwbG9hZCAgICAgIFRoZSB1cGxvYWRlZCBkZXRhaWxzIGFycmF5DQoJICogQHBhcmFtICBzdHJpbmcgICAgICAgICR0eXBlICAgICAgICAgIFRoZSBmaWxlIHR5cGUNCgkgKg0KCSAqIEByZXR1cm4gIGFycmF5ICBvZiBlbGVtZW50cw0KCSAqDQoJICovDQoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBjaGVjayhhcnJheSAkdXBsb2FkLCBzdHJpbmcgJHR5cGUpDQoJew0KCQkvLyBEZWZhdWx0IGZvcm1hdHMNCgkJJGZvcm1hdHMgPSBNaW1lSGVscGVyOjpleHRlbnNpb25zKCR0eXBlKTsNCg0KCQkvLyBDbGVhbiB0aGUgcGF0aA0KCQkkdXBsb2FkX3BhdGggPSBQYXRoOjpjbGVhbigkdXBsb2FkWydmdWxsX3BhdGgnXSk7DQoNCgkJLy8gR2V0IGZpbGUgZXh0ZW5zaW9uL2Zvcm1hdA0KCQkkZm9ybWF0ID0gTWltZUhlbHBlcjo6ZXh0ZW5zaW9uKCR1cGxvYWRfcGF0aCk7DQoNCgkJLy8gTGVnYWwgZmlsZSBmb3JtYXRzDQoJCSRsZWdhbCA9IFtdOw0KDQoJCS8vIGNoZWNrIGlmIHRoZSBmaWxlIGZvcm1hdCBpcyBldmVuIGluIHRoZSBsaXN0DQoJCWlmIChpbl9hcnJheSgkZm9ybWF0LCAkZm9ybWF0cykpDQoJCXsNCgkJCS8vIGdldCBhbGxvd2VkIGZvcm1hdHMNCgkJCSRsZWdhbCA9IChhcnJheSkgSGVscGVyOjpnZXRQYXJhbXMoKS0+Z2V0KCR0eXBlIC4gJ19mb3JtYXRzJywgW10pOw0KCQl9DQoNCgkJLy8gY2hlY2sgdGhlIGV4dGVuc2lvbg0KCQlpZiAoIWluX2FycmF5KCRmb3JtYXQsICRsZWdhbCkpDQoJCXsNCgkJCS8vIENsZWFudXAgdGhlIGltcG9ydCBmaWxlDQoJCQlzZWxmOjpyZW1vdmUoJHVwbG9hZFsnZnVsbF9wYXRoJ10pOw0KDQoJCQlzZWxmOjpzZXRFcnJvcihUZXh0OjpfKCdVcGxvYWQgaXMgbm90IGEgdmFsaWQgdHlwZS4nKSk7DQoNCgkJCXJldHVybiBmYWxzZTsNCgkJfQ0KDQoJCXJldHVybiAkdXBsb2FkOw0KCX0NCg0KCS8qKg0KCSAqIENsZWFuIHVwIHRlbXBvcmFyeSB1cGxvYWRlZCBmaWxlDQoJICoNCgkgKiBAcGFyYW0gICBzdHJpbmcgICRmdWxsUGF0aCAgICBUaGUgZnVsbCBwYXRoIG9mIHRoZSB1cGxvYWRlZCBmaWxlDQoJICoNCgkgKiBAcmV0dXJuICBib29sZWFuICBUcnVlIG9uIHN1Y2Nlc3MNCgkgKg0KCSAqLw0KCXByb3RlY3RlZCBzdGF0aWMgZnVuY3Rpb24gcmVtb3ZlKCRmdWxsUGF0aCkNCgl7DQoJCS8vIElzIHRoZSBwYWNrYWdlIGZpbGUgYSB2YWxpZCBmaWxlPw0KCQlpZiAoaXNfZmlsZSgkZnVsbFBhdGgpKQ0KCQl7DQoJCQlGaWxlOjpkZWxldGUoJGZ1bGxQYXRoKTsNCgkJfQ0KCQllbHNlaWYgKGlzX2ZpbGUoUGF0aDo6Y2xlYW4oJGZ1bGxQYXRoKSkpDQoJCXsNCgkJCS8vIEl0IG1pZ2h0IGFsc28gYmUganVzdCBhIGJhc2UgZmlsZW5hbWUNCgkJCUZpbGU6OmRlbGV0ZShQYXRoOjpjbGVhbigkZnVsbFBhdGgpKTsNCgkJfQ0KCX0NCg0KCS8qKg0KCSAqIFNldCB0aGUgZXJyb3JzDQoJICoNCgkgKiBAcGFyYW0gIHN0cmluZyAgICAgICAgJG1lc3NhZ2UgICBUaGUgZXJyb3IgbWVzc2FnZQ0KCSAqDQoJICogQHJldHVybiAgdm9pZA0KCSAqIEBzaW5jZSAgMy4wLjExDQoJICovDQoJcHJvdGVjdGVkIHN0YXRpYyBmdW5jdGlvbiBzZXRFcnJvcigkbWVzc2FnZSkNCgl7DQoJCWlmIChzZWxmOjokZW5xdWV1ZUVycm9yKQ0KCQl7DQoJCQlGYWN0b3J5OjpnZXRBcHBsaWNhdGlvbigpLT5lbnF1ZXVlTWVzc2FnZSgkbWVzc2FnZSwgJ2Vycm9yJyk7DQoJCX0NCgkJZWxzZQ0KCQl7DQoJCQlzZWxmOjokZXJyb3JzW10gPSAkbWVzc2FnZTsNCgkJfQ0KCX0NCg==', '{}', '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_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+Y2xpZW50LT5nZXRPcHRpb24oJ2hlYWRlcnMnLCBbXSk7DQoNCgkJJGhlYWRlcnNbJ2FjY2VwdCddID0gJ3RleHQvaHRtbCc7DQoJCSRoZWFkZXJzWydDb250ZW50LVR5cGUnXSA9ICdhcHBsaWNhdGlvbi9qc29uJzsNCg0KCQkvLyBidWlsZCB0aGUgcG9zdCBib2R5DQoJCSRkYXRhID0gWw0KCQkJJ0NvbnRleHQnID0+ICdzdHJpbmcnLA0KCQkJJ01vZGUnID0+ICdzdHJpbmcnLA0KCQkJJ1RleHQnID0+ICRwYWdlLT5jb250ZW50LA0KCQkJJ1dpa2knID0+IHRydWUNCgkJXTsNCg0KCQkvLyBQb3N0IHRoZSByZXF1ZXN0Lg0KCQlyZXR1cm4gJHRoaXMtPnByb2Nlc3NSZXNwb25zZSgNCgkJCSR0aGlzLT5jbGllbnQtPnBvc3QoJHRoaXMtPmZldGNoVXJsKCRwYXRoKSwganNvbl9lbmNvZGUoJGRhdGEpLCAkaGVhZGVycykNCgkJKTsNCgl9DQo=', '{}', '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); - -- -- Dumping data for table `#__componentbuilder_admin_view` -- diff --git a/admin/sql/updates/mysql/3.1.19.sql b/admin/sql/updates/mysql/3.1.19.sql new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/admin/sql/updates/mysql/3.1.19.sql @@ -0,0 +1 @@ + diff --git a/admin/sql/updates/mysql/3.1.21.sql b/admin/sql/updates/mysql/3.1.21.sql new file mode 100644 index 000000000..c7d0397e8 --- /dev/null +++ b/admin/sql/updates/mysql/3.1.21.sql @@ -0,0 +1,2 @@ +ALTER TABLE `#__componentbuilder_power` ADD `approved` TINYINT(1) NOT NULL DEFAULT 0 AFTER `add_licensing_template`; +ALTER TABLE `#__componentbuilder_power` ADD `approved_paths` TEXT NOT NULL AFTER `approved`; diff --git a/admin/views/compiler/tmpl/default.php b/admin/views/compiler/tmpl/default.php index 2f7e8f188..744feffb5 100644 --- a/admin/views/compiler/tmpl/default.php +++ b/admin/views/compiler/tmpl/default.php @@ -11,6 +11,7 @@ // No direct access to this file defined('_JEXEC') or die('Restricted access'); +use VDM\Joomla\Utilities\StringHelper; JHtml::addIncludePath(JPATH_COMPONENT.'/helpers/html'); JHtml::_('behavior.formvalidator'); @@ -125,7 +126,7 @@ jQuery('
')
- SuccessMessage)): ?> + SuccessMessage)): ?>
SuccessMessage; ?> diff --git a/admin/views/compiler/view.html.php b/admin/views/compiler/view.html.php index 5c27af451..cc0036ac9 100644 --- a/admin/views/compiler/view.html.php +++ b/admin/views/compiler/view.html.php @@ -356,6 +356,45 @@ class ComponentbuilderViewCompiler extends HtmlView $form->setField($xml, null, true, 'advanced'); } + // powers repository attributes + $attributes = [ + 'type' => 'radio', + 'name' => 'powers_repository', + 'label' => 'COM_COMPONENTBUILDER_ACTIVATE_SUPER_POWERS', + 'class' => 'btn-group btn-group-yesno', + 'description' => 'COM_COMPONENTBUILDER_THIS_ADDS_POWERS_TO_A_LOCAL_REPOSITORY_FOLDER_ALL_BAPPROVEDB_POWERS_LINKED_TO_THIS_COMPONENT_WILL_BE_MOVED_TO_YOUR_BLOCALB_POWERS_REPOSITORY_FOLDER_INTO_THEIR_SELECTIVE_TARGET_PATHS_THIS_LOCAL_FOLDER_PATH_MUST_BE_SET_IN_THE_GLOBAL_OPTIONS_OF_JCB_UNDER_THE_BSUPER_POWERB_TAB', + 'default' => '2', + 'showon' => 'show_advanced_options:1']; + // start the repository options + $options = [ + '2' => 'COM_COMPONENTBUILDER_GLOBAL', + '1' => 'COM_COMPONENTBUILDER_YES', + '0' => 'COM_COMPONENTBUILDER_NO']; + + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes, $options); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'advanced'); + } + + // powers local path to repositories attributes + $attributes = [ + 'type' => 'text', + 'name' => 'local_powers_repository_path', + 'label' => 'COM_COMPONENTBUILDER_LOCAL_POWERS_REPOSITORY_PATH', + 'class' => 'btn-group btn-group-yesno', + 'description' => 'COM_COMPONENTBUILDER_HERE_YOU_CAN_SET_THE_PATH_TO_THE_SUPER_POWERS_LOCAL_REPOSITORY_FOLDER_WHERE_BLAYERCOREB_AND_ALL_TARGETED_BLAYEROWNB_SUB_PATHS_WILL_BE_PLACED_WITH_THEIR_SELECTIVE_BSWITCHAPPROVEDB_POWERS', + 'default' => $this->params->get('local_powers_repository_path', ''), + 'showon' => 'show_advanced_options:1[AND]powers_repository:1']; + + // add to form + $xml = ComponentbuilderHelper::getFieldXML($attributes); + if ($xml instanceof SimpleXMLElement) + { + $form->setField($xml, null, true, 'advanced'); + } + // Indentation attributes $attributes = [ 'type' => 'radio', diff --git a/admin/views/power/tmpl/edit.php b/admin/views/power/tmpl/edit.php index ce03bbe52..de7e111bd 100644 --- a/admin/views/power/tmpl/edit.php +++ b/admin/views/power/tmpl/edit.php @@ -64,6 +64,17 @@ $componentParams = $this->params; // will be removed just use $this->params inst
+ +
+
+ +
+
+ +
+
+ +
diff --git a/admin/views/power/view.html.php b/admin/views/power/view.html.php index a155c497f..7c9237097 100644 --- a/admin/views/power/view.html.php +++ b/admin/views/power/view.html.php @@ -146,6 +146,16 @@ class ComponentbuilderViewPower extends HtmlView { JToolBarHelper::custom('power.save2copy', 'save-copy.png', 'save-copy_f2.png', 'JTOOLBAR_SAVE_AS_COPY', false); } + if ($this->canDo->get('power.sync')) + { + // add Sync button. + JToolBarHelper::custom('power.syncPowers', 'loop custom-button-syncpowers', '', 'COM_COMPONENTBUILDER_SYNC', false); + } + if ($this->canDo->get('power.reset')) + { + // add Reset button. + JToolBarHelper::custom('power.resetPowers', 'joomla custom-button-resetpowers', '', 'COM_COMPONENTBUILDER_RESET', false); + } JToolBarHelper::cancel('power.cancel', 'JTOOLBAR_CLOSE'); } } diff --git a/admin/views/powers/tmpl/default_body.php b/admin/views/powers/tmpl/default_body.php index 4c886a499..8d8d7708b 100644 --- a/admin/views/powers/tmpl/default_body.php +++ b/admin/views/powers/tmpl/default_body.php @@ -67,7 +67,7 @@ $edit = "index.php?option=com_componentbuilder&view=powers&task=power.edit"; escape($item->system_name); ?>
GUID: - escape($item->guid); ?> + escape($item->guid); ?>super_power_key)): ?>
SPK: super_power_key; ?>
@@ -81,7 +81,8 @@ $edit = "index.php?option=com_componentbuilder&view=powers&task=power.edit"; escape($item->extends_name); ?> extends === '-1') : ?>
: - escape($item->extends_custom); ?> + escape($item->extends_custom); ?>
: + approved); ?> diff --git a/admin/views/powers/view.html.php b/admin/views/powers/view.html.php index 93a32c5e5..bf4c6215d 100644 --- a/admin/views/powers/view.html.php +++ b/admin/views/powers/view.html.php @@ -141,6 +141,21 @@ class ComponentbuilderViewPowers extends HtmlView // add Run Expansion button. JToolBarHelper::custom('powers.runExpansion', 'expand-2 custom-button-runexpansion', '', 'COM_COMPONENTBUILDER_RUN_EXPANSION', false); } + if ($this->user->authorise('power.init', 'com_componentbuilder')) + { + // add Init button. + JToolBarHelper::custom('powers.initPowers', 'health custom-button-initpowers', '', 'COM_COMPONENTBUILDER_INIT', false); + } + if ($this->user->authorise('power.sync', 'com_componentbuilder')) + { + // add Sync button. + JToolBarHelper::custom('powers.syncPowers', 'loop custom-button-syncpowers', '', 'COM_COMPONENTBUILDER_SYNC', false); + } + if ($this->user->authorise('power.reset', 'com_componentbuilder')) + { + // add Reset button. + JToolBarHelper::custom('powers.resetPowers', 'joomla custom-button-resetpowers', '', 'COM_COMPONENTBUILDER_RESET', false); + } // set help url for this view if found $this->help_url = ComponentbuilderHelper::getHelpUrl('powers'); @@ -195,43 +210,23 @@ class ComponentbuilderViewPowers extends HtmlView ); } - // Only load Power Version batch if create, edit, and batch is allowed + // Only load Approved batch if create, edit, and batch is allowed if ($this->canBatch && $this->canCreate && $this->canEdit) { - // Set Power Version Selection - $this->power_versionOptions = JFormHelper::loadFieldType('powersfilterpowerversion')->options; - // We do some sanitation for Power Version filter - if (ComponentbuilderHelper::checkArray($this->power_versionOptions) && - isset($this->power_versionOptions[0]->value) && - !ComponentbuilderHelper::checkString($this->power_versionOptions[0]->value)) + // Set Approved Selection + $this->approvedOptions = JFormHelper::loadFieldType('powersfilterapproved')->options; + // We do some sanitation for Approved filter + if (ComponentbuilderHelper::checkArray($this->approvedOptions) && + isset($this->approvedOptions[0]->value) && + !ComponentbuilderHelper::checkString($this->approvedOptions[0]->value)) { - unset($this->power_versionOptions[0]); + unset($this->approvedOptions[0]); } - // Power Version Batch Selection + // Approved Batch Selection JHtmlBatch_::addListSelection( - '- Keep Original '.JText::_('COM_COMPONENTBUILDER_POWER_POWER_VERSION_LABEL').' -', - 'batch[power_version]', - JHtml::_('select.options', $this->power_versionOptions, 'value', 'text') - ); - } - - // Only load Extends Name batch if create, edit, and batch is allowed - if ($this->canBatch && $this->canCreate && $this->canEdit) - { - // Set Extends Name Selection - $this->extendsNameOptions = JFormHelper::loadFieldType('Classpowers')->options; - // We do some sanitation for Extends Name filter - if (ComponentbuilderHelper::checkArray($this->extendsNameOptions) && - isset($this->extendsNameOptions[0]->value) && - !ComponentbuilderHelper::checkString($this->extendsNameOptions[0]->value)) - { - unset($this->extendsNameOptions[0]); - } - // Extends Name Batch Selection - JHtmlBatch_::addListSelection( - '- Keep Original '.JText::_('COM_COMPONENTBUILDER_POWER_EXTENDS_LABEL').' -', - 'batch[extends]', - JHtml::_('select.options', $this->extendsNameOptions, 'value', 'text') + '- Keep Original '.JText::_('COM_COMPONENTBUILDER_POWER_APPROVED_LABEL').' -', + 'batch[approved]', + JHtml::_('select.options', $this->approvedOptions, 'value', 'text') ); } } diff --git a/componentbuilder.xml b/componentbuilder.xml index 317dc70ae..f0348ef73 100644 --- a/componentbuilder.xml +++ b/componentbuilder.xml @@ -1,15 +1,15 @@ COM_COMPONENTBUILDER - 27th February, 2023 + 2nd May, 2023 Llewellyn van der Merwe joomla@vdm.io https://dev.vdm.io Copyright (C) 2015 Vast Development Method. All rights reserved. GNU General Public License version 2 or later; see LICENSE.txt - 3.1.19 + 3.1.24 Component Builder (v.3.1.19) +

Component Builder (v.3.1.24)

The Component Builder for [Joomla](https://extensions.joomla.org/extension/component-builder/) is highly advanced tool that is truly able to build extremely complex components in a fraction of the time. diff --git a/componentbuilder_update_server.xml b/componentbuilder_update_server.xml index 85c4c353f..8d3ad83f9 100644 --- a/componentbuilder_update_server.xml +++ b/componentbuilder_update_server.xml @@ -1127,4 +1127,40 @@ https://dev.vdm.io + + Component Builder + Builds Complex Joomla Components + pkg_component_builder + package + site + 3.1.21 + https://dev.vdm.io + + https://git.vdm.dev/api/v1/repos/joomla-beta/pkg-component-builder/archive/v3.1.22.zip + + + beta + + Llewellyn van der Merwe + https://dev.vdm.io + + + + Component Builder + Builds Complex Joomla Components + pkg_component_builder + package + site + 3.1.24 + https://dev.vdm.io + + https://git.vdm.dev/api/v1/repos/joomla/pkg-component-builder/archive/v3.1.24.zip + + + stable + + Llewellyn van der Merwe + https://dev.vdm.io + + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Gitea/src/AbstractGiteaObject.php b/libraries/jcb_powers/VDM.Gitea/src/AbstractGiteaObject.php deleted file mode 100644 index 5509676f9..000000000 --- a/libraries/jcb_powers/VDM.Gitea/src/AbstractGiteaObject.php +++ /dev/null @@ -1,164 +0,0 @@ - - * @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 - */ - -namespace VDM\Gitea; - - -use Joomla\CMS\Http\Http as BaseHttp; -use Joomla\CMS\Http\HttpFactory; -use Joomla\CMS\Http\Response; -use Joomla\Registry\Registry; -use Joomla\Uri\Uri; -use VDM\Joomla\Utilities\JsonHelper; - -abstract class AbstractGiteaObject -{ - /** - * Options for the Gitea object. - * - * @var Registry - * @since 1.0 - */ - protected $options; - - /** - * The HTTP client object to use in sending HTTP requests. - * - * @var BaseHttp - * @since 1.0 - */ - protected $client; - - /** - * The package the object resides in - * - * @var string - * @since 1.0 - */ - protected $package = ''; - - /** - * Constructor. - * - * @param Registry $options Gitea options object. - * @param BaseHttp $client The HTTP client object. - * - * @since 1.0 - */ - public function __construct(Registry $options = null, BaseHttp $client = null) - { - $this->options = $options ?: new Registry; - $this->client = $client ?: (new HttpFactory)->getHttp($this->options); - - $this->package = static::class; - $this->package = substr($this->package, strrpos($this->package, '\\') + 1); - } - - /** - * Method to build and return a full request URL for the request. This method will - * add appropriate pagination details if necessary and also prepend the API url - * to have a complete URL for the request. - * - * @param string $path URL to inflect - * @param integer $page Page to request - * @param integer $limit Number of results to return per page - * - * @return Uri - * - * @since 1.0 - */ - protected function fetchUrl($path, $page = 0, $limit = 0) - { - // Get a new Uri object focusing the api url and given path. - $uri = new Uri($this->options->get('api.url') . $path); - - if ($this->options->get('access.token', false)) - { - // Use oAuth authentication - $headers = $this->client->getOption('headers', []); - - if (!isset($headers['Authorization'])) - { - $headers['Authorization'] = 'token ' . $this->options->get('access.token'); - $this->client->setOption('headers', $headers); - } - } - else - { - // Use basic authentication - if ($this->options->get('api.username', false)) - { - $uri->setUser($this->options->get('api.username')); - } - - if ($this->options->get('api.password', false)) - { - $uri->setPass($this->options->get('api.password')); - } - } - - // If we have a defined page number add it to the JUri object. - if ($page > 0) - { - $uri->setVar('page', (int) $page); - } - - // If we have a defined items per page add it to the JUri object. - if ($limit > 0) - { - $uri->setVar('limit', (int) $limit); - } - - return $uri; - } - - /** - * Process the response and decode it. - * - * @param Response $response The response. - * @param integer $expectedCode The expected "good" code. - * - * @return mixed - * - * @since 1.0 - * @throws RuntimeException - */ - protected function processResponse(Response $response, $expectedCode = 200) - { - // Validate the response code. - if ($response->code != $expectedCode) - { - // Decode the error response and throw an exception. - $error = json_decode((string) $response->body); - $message = isset($error->message) ? $error->message : 'Invalid response received from Gitea.'; - - throw new \DomainException($message, $response->code); - } - - if (JsonHelper::check($response->body)) - { - $body = json_decode((string) $response->body); - - if (isset($body->content_base64)) - { - $body->content = base64_decode((string) $body->content_base64); - } - } - else - { - $body = $response->body; - } - - return $body; - } - -} - diff --git a/libraries/jcb_powers/VDM.Gitea/src/AbstractPackage.php b/libraries/jcb_powers/VDM.Gitea/src/AbstractPackage.php deleted file mode 100644 index 883b20484..000000000 --- a/libraries/jcb_powers/VDM.Gitea/src/AbstractPackage.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @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 - */ - -namespace VDM\Gitea; - - -use Joomla\CMS\Http\Http as BaseHttp; -use Joomla\Registry\Registry; -use VDM\Gitea\AbstractGiteaObject; - -abstract class AbstractPackage extends AbstractGiteaObject -{ - /** - * Constructor. - * - * @param Registry $options Gitea options object. - * @param Http $client The HTTP client object. - * - * @since 1.0 - */ - public function __construct(Registry $options = null, BaseHttp $client = null) - { - parent::__construct($options, $client); - - $this->package = static::class; - $this->package = substr($this->package, strrpos($this->package, '\\') + 1); - } - - /** - * Magic method to lazily create API objects - * - * @param string $name Name of property to retrieve - * - * @since 1.0 - * @throws \InvalidArgumentException - * - * @return AbstractPackage Gitea API package object. - */ - public function __get($name) - { - $class = '\\VDM\\Gitea\\Package\\' . $this->package . '\\' . ucfirst($name); - - if (class_exists($class) == false) - { - throw new \InvalidArgumentException( - sprintf( - 'Argument %1$s produced an invalid class name: %2$s in package %3$s', - $name, $class, $this->package - ) - ); - } - - if (isset($this->$name) == false) - { - $this->$name = new $class($this->options, $this->client); - } - - return $this->$name; - } - -} - diff --git a/libraries/jcb_powers/VDM.Gitea/src/Gitea.php b/libraries/jcb_powers/VDM.Gitea/src/Gitea.php deleted file mode 100644 index 2929904fd..000000000 --- a/libraries/jcb_powers/VDM.Gitea/src/Gitea.php +++ /dev/null @@ -1,123 +0,0 @@ - - * @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 - */ - -namespace VDM\Gitea; - - -use Joomla\CMS\Http\Http as BaseHttp; -use Joomla\CMS\Http\HttpFactory; -use Joomla\Registry\Registry; - -class Gitea -{ - /** - * Options for the Gitea object. - * - * @var array - * @since 1.0 - */ - protected $options; - - /** - * The HTTP client object to use in sending HTTP requests. - * - * @var BaseHttp - * @since 1.0 - */ - protected $client; - - /** - * Constructor. - * - * @param Registry $options Gitea options object. - * @param Http $client The HTTP client object. - * - * @since 1.0 - */ - public function __construct(Registry $options = null, BaseHttp $client = null) - { - $this->options = $options ?: new Registry; - - // Setup the default user agent if not already set. - if (!$this->getOption('userAgent')) - { - $this->setOption('userAgent', 'JGitea/1.0'); - } - - // Setup the default API url if not already set. - if (!$this->getOption('api.url')) - { - $this->setOption('api.url', 'https://git.vdm.dev/api/v1'); - } - - $this->client = $client ?: (new HttpFactory)->getHttp($this->options); - } - - /** - * Magic method to lazily create API objects - * - * @param string $name Name of property to retrieve - * - * @return AbstractGiteaObject Gitea API object (issues, pulls, etc). - * - * @since 1.0 - * @throws \InvalidArgumentException If $name is not a valid sub class. - */ - public function __get($name) - { - $class = '\\VDM\\Gitea\\Package\\' . ucfirst($name); - - if (class_exists($class)) - { - if (isset($this->$name) == false) - { - $this->$name = new $class($this->options, $this->client); - } - - return $this->$name; - } - - throw new \InvalidArgumentException(sprintf('Argument %s produced an invalid class name: %s', $name, $class)); - } - - /** - * Get an option from the Gitea instance. - * - * @param string $key The name of the option to get. - * - * @return mixed The option value. - * - * @since 1.0 - */ - public function getOption($key) - { - return isset($this->options[$key]) ? $this->options[$key] : null; - } - - /** - * Set an option for the Gitea instance. - * - * @param string $key The name of the option to set. - * @param mixed $value The option value to set. - * - * @return Gitea This object for method chaining. - * - * @since 1.0 - */ - public function setOption($key, $value) - { - $this->options[$key] = $value; - - return $this; - } - -} - diff --git a/libraries/jcb_powers/VDM.Gitea/src/Package/Repo.php b/libraries/jcb_powers/VDM.Gitea/src/Package/Repo.php deleted file mode 100644 index 409c6f536..000000000 --- a/libraries/jcb_powers/VDM.Gitea/src/Package/Repo.php +++ /dev/null @@ -1,266 +0,0 @@ - - * @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 - */ - -namespace VDM\Gitea\Package; - - -use Joomla\CMS\Http\Http; -use Joomla\Registry\Registry; -use VDM\Gitea\AbstractPackage; - -class Repo extends AbstractPackage -{ - /** - * List your repositories. - * - * List repositories for the authenticated user. - * - * @return object - * - * @since 1.0 - */ - public function getListOwn() - { - // Build the request path. - $uri = $this->fetchUrl('/user/repos'); - - // Send the request. - return $this->processResponse($this->client->get($uri)); - } - - /** - * List user repositories. - * - * List public repositories for the specified user. - * - * @param string $user The user name. - * - * @return object - * - * @since 1.0 - */ - public function getListUser($user) - { - // Build the request path. - $uri = $this->fetchUrl('/users/' . $user . '/repos'); - - // Send the request. - return $this->processResponse($this->client->get($uri)); - } - - /** - * List organization repositories. - * - * List repositories for the specified org. - * - * @param string $org The name of the organization. - * - * @return object - * - * @since 1.0 - */ - public function getListOrg($org) - { - // Build the request path. - $uri = $this->fetchUrl('/orgs/' . $org . '/repos'); - - // Send the request. - return $this->processResponse($this->client->get($uri)); - } - - /** - * Create. - * - * Create a new repository for the authenticated user or an organization. OAuth users must supply repo scope. - * - * @param string $name The repository name. - * @param string $org The organization name (if needed). - * @param string $description The repository description. - * @param string $readme Readme of the repository to create. - * @param boolean $private Set true to create a private repository, false to create a public one. - * @param string $defaultBranch DefaultBranch of the repository (used when initializes and in template). - * @param string $license License to use. - * @param boolean $autoInit Whether the repository should auto init. - * @param boolean $template Whether the repository is template. - * @param string $gitignores Gitignores to use. - * options: [ Joomla, JetBrains ] and much more... - * @param string $issueLabels Label-Set to use. - * @param string $trustModel TrustModel of the repository. - * options: [ default, collaborator, committer, collaboratorcommitter ] - * - * @return object - * - * @since 1.0 - */ - public function create($name, $org = '', $description = '', $readme = 'Default', $private = false, $defaultBranch = 'master', - $license = 'GPL-2.0-or-later', $autoInit = true, $template = false, $trustModel = 'default', $gitignores = '', $issueLabels = '' - ) - { - $path = ($org) - // Create a repository for an organization - ? '/orgs/' . $org . '/repos' - // Create a repository for a user - : '/user/repos'; - - $data = [ - 'name' => $name, - 'description' => $description, - 'readme' => $readme, - 'private' => $private, - 'auto_init' => $autoInit, - 'default_branch' => $defaultBranch, - 'issue_labels' => $issueLabels, - 'license' => $license, - 'template' => $template, - 'gitignores' => $gitignores, - 'trust_model' => $trustModel - ]; - - // Send the request. - return $this->processResponse( - $this->client->post($this->fetchUrl($path), json_encode($data)), - 201 - ); - } - - /** - * Get. - * - * @param string $owner Repository owner. - * @param string $repo Repository name. - * - * @return object - * - * @since 1.0 - */ - public function get($owner, $repo) - { - // Build the request path. - $path = '/repos/' . $owner . '/' . $repo; - - // Send the request. - return $this->processResponse( - $this->client->get($this->fetchUrl($path)) - ); - } - - /** - * List contributors. - * - * @param string $owner Repository owner. - * @param string $repo Repository name. - * - * @return object - * - * @since 1.0 - */ - public function getListContributors($owner, $repo) - { - // Build the request path. - $uri = $this->fetchUrl('/repos/' . $owner . '/' . $repo . '/contributors'); - - // Send the request. - return $this->processResponse($this->client->get($uri)); - } - - /** - * List languages. - * - * List languages for the specified repository. The value on the right of a language is the number of bytes of code - * written in that language. - * - * @param string $owner Repository owner. - * @param string $repo Repository name. - * - * @return object - * - * @since 1.0 - */ - public function getListLanguages($owner, $repo) - { - // Build the request path. - $path = '/repos/' . $owner . '/' . $repo . '/languages'; - - // Send the request. - return $this->processResponse( - $this->client->get($this->fetchUrl($path)) - ); - } - - /** - * List Teams - * - * @param string $owner Repository owner. - * @param string $repo Repository name. - * - * @return object - * - * @since 1.0 - */ - public function getListTeams($owner, $repo) - { - // Build the request path. - $path = '/repos/' . $owner . '/' . $repo . '/teams'; - - // Send the request. - return $this->processResponse( - $this->client->get($this->fetchUrl($path)) - ); - } - - /** - * List Tags. - * - * @param string $owner Repository owner. - * @param string $repo Repository name. - * @param integer $page Page to request - * @param integer $limit Number of results to return per page - * - * @return object - * - * @since 1.0 - */ - public function getListTags($owner, $repo, $page = 0, $limit = 0) - { - // Build the request path. - $path = '/repos/' . $owner . '/' . $repo . '/tags'; - - // Send the request. - return $this->processResponse( - $this->client->get($this->fetchUrl($path, $page, $limit)) - ); - } - - /** - * Delete a Repository. - * - * Deleting a repository requires admin access. If OAuth is used, the delete_repo scope is required. - * - * @param string $owner Repository owner. - * @param string $repo Repository name. - * - * @return object - * - * @since 1.0 - */ - public function delete($owner, $repo) - { - // Build the request path. - $path = '/repos/' . $owner . '/' . $repo; - - // Send the request. - return $this->processResponse( - $this->client->delete($this->fetchUrl($path)) - ); - } - -} - diff --git a/libraries/jcb_powers/VDM.Gitea/src/Package/Repo/File.php b/libraries/jcb_powers/VDM.Gitea/src/Package/Repo/File.php deleted file mode 100644 index 323e2a6b6..000000000 --- a/libraries/jcb_powers/VDM.Gitea/src/Package/Repo/File.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @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 - */ - -namespace VDM\Gitea\Package\Repo; - - -use Joomla\CMS\Http\Http; -use Joomla\Registry\Registry; -use VDM\Gitea\AbstractPackage; - - -/** - * Start looking here: - * https://git.vdm.dev/api/swagger#/repository/repoGetContents - */ -class File extends AbstractPackage -{ - /** - * Gets the metadata and contents (if a file) of an entry in a repository, or a list of entries if a dir - * - * @param string $owner Repository owner. - * @param string $repo Repository name. - * @param string $filepath Repository file path. - * - * @return object - * - * @since 1.0 - */ - public function get($owner, $repo, $filepath) - { - // Build the request path. - $path = '/repos/' . $owner . '/' . $repo . '/contents/' . $filepath; - - // Send the request. - return $this->processResponse( - $this->client->get($this->fetchUrl($path)) - ); - } - -} - diff --git a/libraries/jcb_powers/VDM.Gitea/src/Package/Repo/Wiki.php b/libraries/jcb_powers/VDM.Gitea/src/Package/Repo/Wiki.php deleted file mode 100644 index c193ec01e..000000000 --- a/libraries/jcb_powers/VDM.Gitea/src/Package/Repo/Wiki.php +++ /dev/null @@ -1,93 +0,0 @@ - - * @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 - */ - -namespace VDM\Gitea\Package\Repo; - - -use Joomla\CMS\Http\Http; -use Joomla\Registry\Registry; -use VDM\Gitea\AbstractPackage; - - -/** - * Start looking here: - * https://git.vdm.dev/api/swagger#/repository/repoCreateWikiPage - */ -class Wiki extends AbstractPackage -{ - /** - * Get a repository wiki page - * - * @param string $owner The repository owner - * @param string $repo The repository name - * @param string $pageName The page name - * - * @return object - * - * @since 1.0 - */ - public function get(string $owner, string $repo, string $pageName) - { - // Build the request path. - $path = '/repos/' . $owner . '/' . $repo . '/wiki/page/' . $pageName; - - // Send the request. - return $this->processResponse( - $this->client->get($this->fetchUrl($path)) - ); - } - - /** - * Get a repository wiki html page - * - * @param string $owner The repository owner - * @param string $repo The repository name - * @param string $pageName The page name - * - * @return object - * - * @since 1.0 - */ - public function getHtml(string $owner, string $repo, string $pageName) - { - // get the gitea wiki page - $page = $this->get($owner, $repo, $pageName); - - if (empty($page->content)) - { - throw new \Exception('Wiki page could not be found.'); - } - - // Build the request path. - $path = '/markdown'; - - // Get headers - $headers = $this->client->getOption('headers', []); - - $headers['accept'] = 'text/html'; - $headers['Content-Type'] = 'application/json'; - - // build the post body - $data = [ - 'Context' => 'string', - 'Mode' => 'string', - 'Text' => $page->content, - 'Wiki' => true - ]; - - // Post the request. - return $this->processResponse( - $this->client->post($this->fetchUrl($path), json_encode($data), $headers) - ); - } - -} - diff --git a/libraries/jcb_powers/VDM.Gitea/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/index.html similarity index 100% rename from libraries/jcb_powers/VDM.Gitea/index.html rename to libraries/jcb_powers/VDM.Joomla.Gitea/index.html diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Abstraction/Api.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Abstraction/Api.php new file mode 100644 index 000000000..7f766573f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Abstraction/Api.php @@ -0,0 +1,83 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Abstraction; + + +use VDM\Joomla\Gitea\Utilities\Http; +use VDM\Joomla\Gitea\Utilities\Uri; +use VDM\Joomla\Gitea\Utilities\Response; + + +/** + * The Gitea Api + * + * @since 3.2.0 + */ +abstract class Api +{ + /** + * The Http class + * + * @var Http + * @since 3.2.0 + */ + protected Http $http; + + /** + * The Uri class + * + * @var Uri + * @since 3.2.0 + */ + protected Uri $uri; + + /** + * The Response class + * + * @var Response + * @since 3.2.0 + */ + protected Response $response; + + /** + * Constructor. + * + * @param Http $http The http class. + * @param Uri $uri The uri class. + * @param Response $response The response class. + * + * @since 3.2.0 + **/ + public function __construct(Http $http, Uri $uri, Response $response) + { + $this->http = $http; + $this->uri = $uri; + $this->response = $response; + } + + /** + * Load/Reload API. + * + * @param string $url The url. + * @param token $token The token. + * + * @return void + * @since 3.2.0 + **/ + public function load_(string $url, string $token) + { + $this->uri->setUrl($url); + $this->http->setToken($token); + } + +} + diff --git a/libraries/jcb_powers/VDM.Gitea/src/Package/Repo/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Abstraction/index.html similarity index 100% rename from libraries/jcb_powers/VDM.Gitea/src/Package/Repo/index.html rename to libraries/jcb_powers/VDM.Joomla.Gitea/src/Abstraction/index.html diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Cron.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Cron.php new file mode 100644 index 000000000..04031c26a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Cron.php @@ -0,0 +1,72 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Admin; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Admin Cron + * + * @since 3.2.0 + */ +class Cron extends Api +{ + /** + * List cron tasks. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(int $page = 1, int $limit = 10): ?array + { + // Build the request path. + $path = "/admin/cron"; + + // Set the query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Run cron task. + * + * @param string $task The cron task to run. + * + * @return string + * @since 3.2.0 + **/ + public function run(string $task): string + { + // Build the request path. + $path = "/admin/cron/{$task}"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Organizations.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Organizations.php new file mode 100644 index 000000000..df1e6b444 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Organizations.php @@ -0,0 +1,51 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Admin; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Admin Organizations + * + * @since 3.2.0 + */ +class Organizations extends Api +{ + /** + * List all organizations. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(int $page = 1, int $limit = 10): ?array + { + // Build the request path. + $path = "/admin/orgs"; + + // Set the query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Unadopted.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Unadopted.php new file mode 100644 index 000000000..c73cf3ebe --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Unadopted.php @@ -0,0 +1,101 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Admin; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Admin Unadopted + * + * @since 3.2.0 + */ +class Unadopted extends Api +{ + /** + * List unadopted repositories. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * @param string $pattern Pattern of repositories to search for. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(int $page = 1, int $limit = 10, string $pattern = ''): ?array + { + // Build the request path. + $path = "/admin/unadopted"; + + // Set the query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + if (!empty($pattern)) + { + $uri->setVar('pattern', $pattern); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Adopt unadopted files as a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return string + * @since 3.2.0 + **/ + public function adopt(string $owner, string $repo): string + { + // Build the request path. + $path = "/admin/unadopted/{$owner}/{$repo}"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), '' + ), 204, 'success' + ); + } + + /** + * Delete unadopted files. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $owner, string $repo): string + { + // Build the request path. + $path = "/admin/unadopted/{$owner}/{$repo}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users.php new file mode 100644 index 000000000..47ec3e54a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users.php @@ -0,0 +1,207 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Admin; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Admin Users + * + * @since 3.2.0 + */ +class Users extends Api +{ + /** + * List all users. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(int $page = 1, int $limit = 10): ?array + { + // Build the request path. + $path = "/admin/users"; + + // build the URL + $url = $this->uri->get($path); + $url->setVar('page', $page); + $url->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + + /** + * Create a user with extended options. + * + * @param string $loginName The user's login name. + * @param string $email The user's email address. + * @param string $password The user's password. + * @param string|null $username The username. + * @param string|null $fullName The user's full name (optional). + * @param bool|null $mustChangePassword User must change password on next login (optional). + * @param bool|null $restricted Restrict the user (optional). + * @param bool|null $sendNotify Send a notification email to the user (optional). + * @param int|null $sourceId Source ID (optional). + * @param string|null $visibility The user's visibility (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $loginName, + string $email, + string $password, + string $username, + ?string $fullName = null, + ?bool $mustChangePassword = null, + ?bool $restricted = null, + ?bool $sendNotify = null, + ?int $sourceId = null, + ?string $visibility = null + ): ?object + { + // Build the request path. + $path = "/admin/users"; + + // Set the user data. + $data = new \stdClass(); + $data->login_name = $loginName; + $data->email = $email; + $data->password = $password; + $data->username = $username; + $data->full_name = $fullName; + $data->must_change_password = $mustChangePassword; + $data->restricted = $restricted; + $data->send_notify = $sendNotify; + $data->source_id = $sourceId; + $data->visibility = $visibility; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Delete a user. + * + * @param string $username The user's display name. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $username): string + { + // Build the request path. + $path = "/admin/users/{$username}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Edit an existing user. + * + * @param string $username The user's display name. + * @param string $loginName The user's login name. + * @param int $sourceId The user's source ID. + * @param bool $active Optional. Is the user active? Default: false. + * @param bool $admin Optional. Is the user an admin? Default: false. + * @param bool $allowCreateOrganization Optional. Can the user create an organization? Default: false. + * @param bool $allowGitHook Optional. Can the user create Git hooks? Default: false. + * @param bool $allowImportLocal Optional. Can the user import local repositories? Default: false. + * @param string $description Optional. The user's description. Default: ''. + * @param string $email Optional. The user's email address. Default: ''. + * @param string $fullName Optional. The user's full name. Default: ''. + * @param string $location Optional. The user's location. Default: ''. + * @param int $maxRepoCreation Optional. Maximum repositories the user can create. Default: 0. + * @param bool $mustChangePassword Optional. Must the user change their password? Default: false. + * @param string $password Optional. The user's password. Default: ''. + * @param bool $prohibitLogin Optional. Is the user's login prohibited? Default: false. + * @param bool $restricted Optional. Is the user restricted? Default: false. + * @param string $visibility Optional. The user's visibility setting. Default: ''. + * @param string $website Optional. The user's website. Default: ''. + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + string $username, + string $loginName, + int $sourceId, + bool $active = false, + bool $admin = false, + bool $allowCreateOrganization = false, + bool $allowGitHook = false, + bool $allowImportLocal = false, + string $description = '', + string $email = '', + string $fullName = '', + string $location = '', + int $maxRepoCreation = 0, + bool $mustChangePassword = false, + string $password = '', + bool $prohibitLogin = false, + bool $restricted = false, + string $visibility = '', + string $website = '' + ): ?object + { + // Build the request path. + $path = "/admin/users/{$username}"; + + // Set the data. + $data = [ + 'login_name' => $loginName, + 'source_id' => $sourceId, + 'active' => $active, + 'admin' => $admin, + 'allow_create_organization' => $allowCreateOrganization, + 'allow_git_hook' => $allowGitHook, + 'allow_import_local' => $allowImportLocal, + 'description' => $description, + 'email' => $email, + 'full_name' => $fullName, + 'location' => $location, + 'max_repo_creation' => $maxRepoCreation, + 'must_change_password' => $mustChangePassword, + 'password' => $password, + 'prohibit_login' => $prohibitLogin, + 'restricted' => $restricted, + 'visibility' => $visibility, + 'website' => $website + ]; + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/Keys.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/Keys.php new file mode 100644 index 000000000..bea01deb0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/Keys.php @@ -0,0 +1,86 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Admin\Users; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Admin Users Keys + * + * @since 3.2.0 + */ +class Keys extends Api +{ + /** + * Add a public key on behalf of a user. + * + * @param string $userName The user's display name. + * @param string $publicKey The public key to add. + * @param string $keyTitle Title of the key to add. + * @param bool $readOnly Whether the key has only read access or read/write (optional). + * @param string|null $description Description of the key (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function add( + string $userName, + string $publicKey, + string $keyTitle, + bool $readOnly = false, + ?string $description = null + ): ?object + { + // Build the request path. + $path = "/admin/users/{$userName}/keys"; + + // Set the key data. + $data = new \stdClass(); + $data->key = $publicKey; + $data->title = $keyTitle; + $data->read_only = $readOnly; + $data->description = $description; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Delete a user's public key. + * + * @param string $username The user's display name. + * @param int $id The public key ID. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $username, int $id): string + { + // Build the request path. + $path = "/admin/users/{$username}/keys/{$id}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/Organization.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/Organization.php new file mode 100644 index 000000000..ec1843ff9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/Organization.php @@ -0,0 +1,70 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Admin\Users; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Admin Users Organization + * + * @since 3.2.0 + */ +class Organization extends Api +{ + /** + * Create an organization on behalf of a user. + * + * @param string $username The user's display name. + * @param string $fullName The organization full name. + * @param string|null $description The organization description (optional). + * @param string|null $location The organization location (optional). + * @param bool $repoAdminChangeTeamAccess Whether repo admin can change team access (optional). + * @param string $visibility The organization visibility (optional). + * @param string|null $website The organization website (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $username, + string $fullName, + ?string $description = null, + ?string $location = null, + bool $repoAdminChangeTeamAccess = false, + string $visibility = 'public', + ?string $website = null + ): ?object + { + // Build the request path. + $path = "/admin/users/{$username}/orgs"; + + // Set the organization data. + $data = new \stdClass(); + $data->full_name = $fullName; + $data->description = $description; + $data->location = $location; + $data->repo_admin_change_team_access = $repoAdminChangeTeamAccess; + $data->visibility = $visibility; + $data->website = $website; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/Repository.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/Repository.php new file mode 100644 index 000000000..bfade26a8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/Repository.php @@ -0,0 +1,85 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Admin\Users; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Admin Users Repository + * + * @since 3.2.0 + */ +class Repository extends Api +{ + /** + * Create a repository on behalf of a user. + * + * @param string $username The user's display name. + * @param string $repoName The repository name. + * @param string|null $description The repository description (optional). + * @param bool $auto_init Whether the repository should be auto-initialized? (optional). + * @param string|null $default_branch Default branch of the repository (optional). + * @param string|null $gitignores Gitignores to use (optional). + * @param string|null $issue_labels Label-Set to use (optional). + * @param string|null $license License to use (optional). + * @param bool $private Whether the repository is private (optional). + * @param string|null $readme Readme of the repository to create (optional). + * @param bool $template Whether the repository is template (optional). + * @param string|null $trust_model TrustModel of the repository (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $username, + string $repoName, + ?string $description = null, + bool $auto_init = false, + ?string $default_branch = null, + ?string $gitignores = null, + ?string $issue_labels = null, + ?string $license = null, + bool $private = false, + ?string $readme = null, + bool $template = false, + ?string $trust_model = null + ): ?object + { + // Build the request path. + $path = "/admin/users/{$username}/repos"; + + // Set the repository data. + $data = new \stdClass(); + $data->name = $repoName; + $data->description = $description; + $data->auto_init = $auto_init; + $data->default_branch = $default_branch; + $data->gitignores = $gitignores; + $data->issue_labels = $issue_labels; + $data->license = $license; + $data->private = $private; + $data->readme = $readme; + $data->template = $template; + $data->trust_model = $trust_model; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Gitea/src/Package/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/index.html similarity index 100% rename from libraries/jcb_powers/VDM.Gitea/src/Package/index.html rename to libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/Users/index.html diff --git a/libraries/jcb_powers/VDM.Gitea/src/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/index.html similarity index 100% rename from libraries/jcb_powers/VDM.Gitea/src/index.html rename to libraries/jcb_powers/VDM.Joomla.Gitea/src/Admin/index.html diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Factory.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Factory.php new file mode 100644 index 000000000..23bb27387 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Factory.php @@ -0,0 +1,97 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea; + + +use Joomla\DI\Container; +use VDM\Joomla\Gitea\Service\Utilities; +use VDM\Joomla\Gitea\Service\Jcb; +use VDM\Joomla\Gitea\Service\Settings; +use VDM\Joomla\Gitea\Service\Organization; +use VDM\Joomla\Gitea\Service\User; +use VDM\Joomla\Gitea\Service\Repository; +use VDM\Joomla\Gitea\Service\Package; +use VDM\Joomla\Gitea\Service\Issue; +use VDM\Joomla\Gitea\Service\Notifications; +use VDM\Joomla\Gitea\Service\Miscellaneous; +use VDM\Joomla\Gitea\Service\Admin; +use VDM\Joomla\Componentbuilder\Interfaces\FactoryInterface; + + +/** + * Gitea Factory + * + * @since 3.2.0 + */ +abstract class Factory implements FactoryInterface +{ + /** + * Global Package Container + * + * @var Container + * @since 3.2.0 + **/ + protected static $container = null; + + /** + * Get any class from the package container + * + * @param string $key The container class key + * + * @return Mixed + * @since 3.2.0 + */ + public static function _($key) + { + return self::getContainer()->get($key); + } + + /** + * Get the global package container + * + * @return Container + * @since 3.2.0 + */ + public static function getContainer(): Container + { + if (!self::$container) + { + self::$container = self::createContainer(); + } + + return self::$container; + } + + /** + * Create a container object + * + * @return Container + * @since 3.2.0 + */ + protected static function createContainer(): Container + { + return (new Container()) + ->registerServiceProvider(new Utilities()) + ->registerServiceProvider(new Jcb()) + ->registerServiceProvider(new Settings()) + ->registerServiceProvider(new Organization()) + ->registerServiceProvider(new User()) + ->registerServiceProvider(new Repository()) + ->registerServiceProvider(new Package()) + ->registerServiceProvider(new Issue()) + ->registerServiceProvider(new Notifications()) + ->registerServiceProvider(new Miscellaneous()) + ->registerServiceProvider(new Admin()); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue.php new file mode 100644 index 000000000..bfeb418ea --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue.php @@ -0,0 +1,406 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue + * + * @since 3.2.0 + */ +class Issue extends Api +{ + /** + * List a repository's issues. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string $state The state of the issues to get, defaults to 'open'. + * @param int $page The page to get, defaults to null. + * @param int $limit The number of issues per page, defaults to null. + * @param string|null $labels Comma-separated list of labels, defaults to null. + * @param string|null $q The search string, defaults to null. + * @param string|null $type The type to filter by (issues/pulls), defaults to null. + * @param string|null $milestones Comma-separated list of milestone names or IDs, defaults to null. + * @param string|null $since Only show items updated after the given time, defaults to null. + * @param string|null $before Only show items updated before the given time, defaults to null. + * @param string|null $createdBy Only show items created by the given user, defaults to null. + * @param string|null $assignedBy Only show items assigned to the given user, defaults to null. + * @param string|null $mentionedBy Only show items where the given user is mentioned, defaults to null. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $owner, + string $repo, + string $state = 'open', + int $page = 1, + int $limit = 10, + ?string $labels = null, + ?string $q = null, + ?string $type = null, + ?string $milestones = null, + ?string $since = null, + ?string $before = null, + ?string $createdBy = null, + ?string $assignedBy = null, + ?string $mentionedBy = null + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues"; + + // Build the URI. + $uri = $this->uri->get($path); + + // Set the query parameters + $uri->setVar('state', $state); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + $uri->setVar('labels', $labels); + $uri->setVar('q', $q); + $uri->setVar('type', $type); + $uri->setVar('milestones', $milestones); + $uri->setVar('since', $since); + $uri->setVar('before', $before); + $uri->setVar('created_by', $createdBy); + $uri->setVar('assigned_by', $assignedBy); + $uri->setVar('mentioned_by', $mentionedBy); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo, int $index): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Create an issue. If using deadline only the date will be taken into account, and time of day ignored. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string $issueTitle The issue title. + * @param array|null $assignees The array of assignees, defaults to null. + * @param string|null $issueBody The issue body, defaults to null. + * @param bool|null $closed If the issue is closed, defaults to null. + * @param string|null $dueDate The deadline for the issue, format: "YYYY-MM-DD", defaults to null. + * @param array|null $labelIds The array of label IDs to attach to the issue, defaults to null. + * @param int|null $milestoneId The milestone ID, defaults to null. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $owner, + string $repo, + string $issueTitle, + ?array $assignees = null, + ?string $issueBody = null, + ?bool $closed = null, + ?string $dueDate = null, + ?array $labelIds = null, + ?int $milestoneId = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues"; + + // Build the request data. + $data = new \stdClass(); + $data->title = $issueTitle; + $data->body = $issueBody; + $data->assignees = $assignees; + $data->closed = $closed; + $data->due_date = $dueDate; + $data->labels = $labelIds; + $data->milestone = $milestoneId; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Search for issues across the repositories that the user has access to. + * + * @param string $q Search query. + * @param int $page Page number (default 1). + * @param int $limit Page size (default 10, max 50). + * @param string|null $state Issue state (default open). + * @param string|null $labels Label filter, comma-separated. + * @param string|null $milestones Milestone filter, comma-separated. + * @param int|null $priorityRepoId Repository to prioritize in the results. + * @param string|null $type Filter by type (issues/pulls). + * @param string|null $since Only show notifications updated after the given time (RFC 3339 format). + * @param string|null $before Only show notifications updated before the given time (RFC 3339 format). + * @param bool|null $assigned Filter assigned to you (default false). + * @param bool|null $created Filter created by you (default false). + * @param bool|null $mentioned Filter mentioning you (default false). + * @param bool|null $reviewRequested Filter pulls requesting your review (default false). + * @param string|null $owner Filter by owner. + * @param string|null $team Filter by team (requires organization owner parameter). + * + * @return array|null + * @since 3.2.0 + **/ + public function search( + string $q, + int $page = 1, + int $limit = 10, + ?string $state = 'open', + ?string $labels = null, + ?string $milestones = null, + ?int $priorityRepoId = null, + ?string $type = null, + ?string $since = null, + ?string $before = null, + ?bool $assigned = null, + ?bool $created = null, + ?bool $mentioned = null, + ?bool $reviewRequested = null, + ?string $owner = null, + ?string $team = null + ): ?array + { + // Build the request path. + $path = "/repos/issues/search"; + + // Set the URL parameters. + $uri = $this->uri->get($path); + $uri->setVar('q', $q); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + $uri->setVar('state', $state); + + if ($labels !== null) + { + $uri->setVar('labels', $labels); + } + + if ($milestones !== null) + { + $uri->setVar('milestones', $milestones); + } + + if ($priorityRepoId !== null) + { + $uri->setVar('priority_repo_id', $priorityRepoId); + } + + if ($type !== null) + { + $uri->setVar('type', $type); + } + + if ($since !== null) + { + $uri->setVar('since', $since); + } + + if ($before !== null) + { + $uri->setVar('before', $before); + } + + if ($assigned !== null) + { + $uri->setVar('assigned', $assigned); + } + + if ($created !== null) + { + $uri->setVar('created', $created); + } + + if ($mentioned !== null) + { + $uri->setVar('mentioned', $mentioned); + } + + if ($reviewRequested !== null) + { + $uri->setVar('review_requested', $reviewRequested); + } + + if ($owner !== null) + { + $uri->setVar('owner', $owner); + } + + if ($team !== null) + { + $uri->setVar('team', $team); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Edit an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param string|null $assignee The assignee, defaults to null. + * @param array|null $assignees The assignees, defaults to null. + * @param string|null $body The issue body, defaults to null. + * @param string|null $dueDate The due date, defaults to null. + * @param int|null $milestone The milestone, defaults to null. + * @param string|null $ref The reference, defaults to null. + * @param string|null $state The issue state, defaults to null. + * @param string|null $title The issue title, defaults to null. + * @param bool|null $unsetDueDate The flag to unset due date, defaults to null. + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + string $owner, + string $repo, + int $index, + ?string $assignee = null, + ?array $assignees = null, + ?string $body = null, + ?string $dueDate = null, + ?int $milestone = null, + ?string $ref = null, + ?string $state = null, + ?string $title = null, + ?bool $unsetDueDate = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}"; + + // Prepare the issue data. + $editIssueData = new \stdClass(); + + if ($assignee !== null || $assignees !== null) + { + $editIssueData->assignee = new \stdClass(); + + if ($assignee !== null) + { + $editIssueData->assignee->name = $assignee; + } + + if ($assignees !== null) + { + $editIssueData->assignee->names = $assignees; + } + } + + if ($body !== null) + { + $editIssueData->body = $body; + } + + if ($dueDate !== null || $unsetDueDate !== null) + { + $editIssueData->dueDate = new \stdClass(); + + if ($dueDate !== null) + { + $editIssueData->dueDate->date = $dueDate; + } + + if ($unsetDueDate !== null) + { + $editIssueData->dueDate->unset = $unsetDueDate; + } + } + + if ($milestone !== null) + { + $editIssueData->milestone = $milestone; + } + + if ($ref !== null) + { + $editIssueData->ref = $ref; + } + + if ($state !== null) + { + $editIssueData->state = $state; + } + + if ($title !== null) + { + $editIssueData->title = $title; + } + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), json_encode($editIssueData) + ) + ); + } + + /** + * Delete an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $owner, string $repo, int $index): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Comments.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Comments.php new file mode 100644 index 000000000..c244035c9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Comments.php @@ -0,0 +1,176 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Issue; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Comments + * + * @since 3.2.0 + */ +class Comments extends Api +{ + /** + * List all comments on an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param int $page The page number to get, defaults to 1. + * @param int $limit The number of comments per page, defaults to 10. + * @param string|null $since The date-time since when to get comments, defaults to null. + * @param string|null $before The date-time before when to get comments, defaults to null. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $owner, + string $repo, + int $index, + int $page = 1, + int $limit = 10, + ?string $since = null, + ?string $before = null + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/comments"; + + // Build the URI. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Set the 'since' and 'before' parameters if not null. + if ($since !== null) + { + $uri->setVar('since', $since); + } + if ($before !== null) + { + $uri->setVar('before', $before); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get a comment. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $commentId The comment ID. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo, int $commentId): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/comments/{$commentId}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a comment. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $commentId The comment ID. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $owner, string $repo, int $commentId): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/comments/{$commentId}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Edit a comment. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $commentId The comment ID. + * @param string $commentBody The new comment body. + * + * @return object|null + * @since 3.2.0 + **/ + public function edit(string $owner, string $repo, int $commentId, string $commentBody): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/comments/{$commentId}"; + + // Build the request data. + $data = new \stdClass(); + $data->body = $commentBody; + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Add a comment to an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $issueIndex The issue index. + * @param string $commentBody The comment body. + * + * @return object|null + * @since 3.2.0 + **/ + public function add(string $owner, string $repo, int $issueIndex, string $commentBody): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$issueIndex}/comments"; + + // Build the request data. + $data = new \stdClass(); + $data->body = $commentBody; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Deadline.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Deadline.php new file mode 100644 index 000000000..6c13d07a4 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Deadline.php @@ -0,0 +1,54 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Issue; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Deadline + * + * @since 3.2.0 + */ +class Deadline extends Api +{ + /** + * Set an issue deadline. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param string|null $dueDate The deadline date string in the format YYYY-MM-DD or null to delete the deadline. + * + * @return object + * @since 3.2.0 + **/ + public function set(string $owner, string $repo, int $index, ?string $dueDate): object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/deadline"; + + // Build the request data. + $data = new \stdClass(); + $data->due_date = $dueDate; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Labels.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Labels.php new file mode 100644 index 000000000..fda80dce9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Labels.php @@ -0,0 +1,181 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Issue; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Labels + * + * @since 3.2.0 + */ +class Labels extends Api +{ + /** + * Get all of a repository's labels. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(string $owner, string $repo, int $page = 1, int $limit = 10): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/labels"; + + // Get the URI object with the request path. + $uri = $this->uri->get($path); + + // Add the page and limit query parameters if provided. + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get an issue's labels. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * + * @return array|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo, int $index): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/labels"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Replace an issue's labels. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param array $labels An array of labels to replace the current issue labels. + * + * @return object + * @since 3.2.0 + **/ + public function replace(string $owner, string $repo, int $index, array $labels): object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/labels"; + + // Build the request data. + $data = new \stdClass(); + $data->labels = $labels; + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Add a label to an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param array $labels An array of label IDs to add. + * + * @return array|null + * @since 3.2.0 + **/ + public function add(string $owner, string $repo, int $index, array $labels): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/labels"; + + // Build the request data. + $data = new \stdClass(); + $data->labels = $labels; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Remove a label from an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param int $labelId The ID of the label to remove. + * + * @return string + * @since 3.2.0 + **/ + public function remove(string $owner, string $repo, int $index, int $labelId): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/labels/{$labelId}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Remove all labels from an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * + * @return string + * @since 3.2.0 + **/ + public function clear(string $owner, string $repo, int $index): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/labels"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Milestones.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Milestones.php new file mode 100644 index 000000000..5178a7371 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Milestones.php @@ -0,0 +1,230 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Issue; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Milestones + * + * @since 3.2.0 + */ +class Milestones extends Api +{ + /** + * Create a milestone. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string $title The title of the milestone. + * @param string|null $description Optional. The description of the milestone. + * @param string|null $dueOn Optional. The due date of the milestone. + * @param string|null $state Optional. The state of the milestone. Default is 'open'. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $owner, + string $repo, + string $title, + ?string $description = null, + ?string $dueOn = null, + ?string $state = 'open' + ): ?object + { + // Set the lines data + $data = new \stdClass(); + + // Set all the required data. + $data->title = $title; + + // Set all the optional data that has been provided. + if ($description !== null) + { + $data->description = $description; + } + if ($dueOn !== null) + { + $data->due_on = $dueOn; + } + if ($state !== null) + { + $data->state = $state; + } + + // Build the request path. + $path = "/repos/{$owner}/{$repo}/milestones"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * Get all of a repository's opened milestones. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string|null $state Optional. Milestone state. Recognized values are open, closed, and all. Defaults to "open". + * @param string|null $name Optional. Filter by milestone name. + * @param int|null $page Optional. Page number of results to return (1-based). + * @param int|null $limit Optional. Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $owner, + string $repo, + ?string $state = 'open', + ?string $name = null, + ?int $page = null, + ?int $limit = null + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/milestones"; + + // Build the URI. + $uri = $this->uri->get($path); + $uri->setVar('state', $state); + if ($name !== null) + { + $uri->setVar('name', $name); + } + if ($page !== null) + { + $uri->setVar('page', $page); + } + if ($limit !== null) + { + $uri->setVar('limit', $limit); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get a milestone. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string $milestoneId The ID of the milestone. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo, string $milestoneId): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/milestones/{$milestoneId}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a milestone. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string $milestoneId The ID of the milestone to delete. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $owner, string $repo, string $milestoneId): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/milestones/{$milestoneId}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Update a milestone. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string $milestoneId The ID of the milestone to update. + * @param string $title Optional. The new title of the milestone. + * @param string $description Optional. The new description of the milestone. + * @param string $dueOn Optional. The new due date of the milestone. + * @param string $state Optional. The new state of the milestone. + * + * @return object|null + * @since 3.2.0 + **/ + public function update( + string $owner, + string $repo, + string $milestoneId, + string $title = null, + string $description = null, + string $dueOn = null, + string $state = null + ): ?object + { + // Set the lines data + $data = new \stdClass(); + + // Set all the optional data that has been provided. + if ($title !== null) + { + $data->title = $title; + } + if ($description !== null) + { + $data->description = $description; + } + if ($dueOn !== null) + { + $data->due_on = $dueOn; + } + if ($state !== null) + { + $data->state = $state; + } + + // Build the request path. + $path = "/repos/{$owner}/{$repo}/milestones/{$milestoneId}"; + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), + json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Reactions.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Reactions.php new file mode 100644 index 000000000..759529592 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Reactions.php @@ -0,0 +1,110 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Issue; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Reactions + * + * @since 3.2.0 + */ +class Reactions extends Api +{ + /** + * Get a list reactions of an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param int $page The page to get, defaults to 1. + * @param int $limit The number of reactions per page, defaults to 10. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(string $owner, string $repo, int $index, int $page = 1, int $limit = 10): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/reactions"; + + // Build the URI. + $uri = $this->uri->get($path); + + // Set the URI variables. + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Add a reaction to an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param string $content The name of the reaction to add. + * + * @return object|null + * @since 3.2.0 + **/ + public function add(string $owner, string $repo, int $index, string $content): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/reactions"; + + // Build the request data. + $data = new \stdClass(); + $data->content = $content; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Remove a reaction from an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param string $content The name of the reaction to remove. + * + * @return string + * @since 3.2.0 + **/ + public function remove(string $owner, string $repo, int $index, string $content): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/reactions"; + + // Build the URI. + $uri = $this->uri->get($path); + $uri->setVar('content', $content); + + // Send the delete request. + return $this->response->get( + $this->http->delete($uri), 200, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Reactions/Comment.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Reactions/Comment.php new file mode 100644 index 000000000..0f2ca7818 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Reactions/Comment.php @@ -0,0 +1,103 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Issue\Reactions; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Reactions Comment + * + * @since 3.2.0 + */ +class Comment extends Api +{ + /** + * Get a list of reactions from a comment of an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $commentId The comment ID. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(string $owner, string $repo, int $commentId): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/comments/{$commentId}/reactions"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Add a reaction to a comment of an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $commentId The comment ID. + * @param string $content The reaction to add, e.g. "+1". + * + * @return object|null + * @since 3.2.0 + **/ + public function add(string $owner, string $repo, int $commentId, string $content): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/comments/{$commentId}/reactions"; + + // Build the request data. + $data = new \stdClass(); + $data->content = $content; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Remove a reaction from a comment of an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $commentId The comment ID. + * @param string $content The reaction to remove, e.g. "+1". + * + * @return string + * @since 3.2.0 + **/ + public function remove(string $owner, string $repo, int $commentId, string $content): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/comments/{$commentId}/reactions"; + + // Build the URI. + $uri = $this->uri->get($path); + $uri->setVar('content', $content); + + // Send the delete request. + return $this->response->get( + $this->http->delete($uri), 200, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Reactions/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Reactions/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Reactions/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Repository/Comments.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Repository/Comments.php new file mode 100644 index 000000000..3ca83fc75 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Repository/Comments.php @@ -0,0 +1,67 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Issue\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Repository Comments + * + * @since 3.2.0 + */ +class Comments extends Api +{ + /** + * List all comments in a repository. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $page The page to get, defaults to 1. + * @param int $limit The number of comments per page, defaults to 10. + * @param string|null $since The date-time string to filter updated comments since, defaults to null. + * @param string|null $before The date-time string to filter updated comments before, defaults to null. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(string $owner, string $repo, int $page = 1, int $limit = 10, ?string $since = null, ?string $before = null): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/comments"; + + // Build the URI. + $uri = $this->uri->get($path); + + // Set the URI variables. + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + if ($since !== null) + { + $uri->setVar('since', $since); + } + + if ($before !== null) + { + $uri->setVar('before', $before); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Repository/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Repository/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Repository/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Stopwatch.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Stopwatch.php new file mode 100644 index 000000000..674541641 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Stopwatch.php @@ -0,0 +1,95 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Issue; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Stopwatch + * + * @since 3.2.0 + */ +class Stopwatch extends Api +{ + /** + * Start stopwatch on an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * + * @return string + * @since 3.2.0 + **/ + public function start(string $owner, string $repo, int $index): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/stopwatch/start"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), '' + ), 201, 'success' + ); + } + + /** + * Stop an issue's existing stopwatch. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * + * @return string + * @since 3.2.0 + **/ + public function stop(string $owner, string $repo, int $index): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/stopwatch/stop"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), '' + ), 201, 'success' + ); + } + + /** + * Delete an issue's existing stopwatch. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $owner, string $repo, int $index): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/stopwatch/delete"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Subscriptions.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Subscriptions.php new file mode 100644 index 000000000..c29bfb680 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Subscriptions.php @@ -0,0 +1,137 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Issue; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Subscriptions + * + * @since 3.2.0 + */ +class Subscriptions extends Api +{ + /** + * Get users who subscribed on an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param int|null $page Optional. Page number of results to return (1-based). + * @param int|null $limit Optional. Page size of results. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + int $index, + ?int $page = null, + ?int $limit = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/subscriptions"; + + // Set the query parameters. + $uri = $this->uri->get($path); + if ($page !== null) + { + $uri->setVar('page', $page); + } + if ($limit !== null) + { + $uri->setVar('limit', $limit); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Check if user is subscribed to an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * + * @return object|null + * @since 3.2.0 + **/ + public function check(string $owner, string $repo, int $index): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/subscriptions/check"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Subscribe user to issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param string $user The username to subscribe. + * + * @return string + * @since 3.2.0 + **/ + public function subscribe(string $owner, string $repo, int $index, string $user): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/subscriptions/{$user}"; + + // Send the put request. + return $this->response->get_( + $this->http->put( + $this->uri->get($path), '' + ), [200 => 'already subscribed', 201 => 'success'] + ); + } + + /** + * Unsubscribe user from issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param string $user The username to unsubscribe. + * + * @return string + * @since 3.2.0 + **/ + public function unsubscribe(string $owner, string $repo, int $index, string $user): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/subscriptions/{$user}"; + + // Send the delete request. + return $this->response->get_( + $this->http->delete( + $this->uri->get($path) + ), [200 => 'already unsubscribed', 201 => 'success'] + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Timeline.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Timeline.php new file mode 100644 index 000000000..4c54937b4 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Timeline.php @@ -0,0 +1,78 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Issue; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Timeline + * + * @since 3.2.0 + */ +class Timeline extends Api +{ + /** + * List all comments and events on an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param string|null $since Optional. If provided, only comments updated since the specified time are returned. + * @param int|null $page Optional. Page number of results to return (1-based). + * @param int|null $limit Optional. Page size of results. + * @param string|null $before Optional. If provided, only comments updated before the provided time are returned. + * + * @return array|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + int $index, + ?string $since = null, + ?int $page = null, + ?int $limit = null, + ?string $before = null + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/timeline"; + + // Set the query parameters. + $uri = $this->uri->get($path); + if ($since !== null) + { + $uri->setVar('since', $since); + } + if ($page !== null) + { + $uri->setVar('page', $page); + } + if ($limit !== null) + { + $uri->setVar('limit', $limit); + } + if ($before !== null) + { + $uri->setVar('before', $before); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Times.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Times.php new file mode 100644 index 000000000..7c33c2ab6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/Times.php @@ -0,0 +1,179 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Issue; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Issue Times + * + * @since 3.2.0 + */ +class Times extends Api +{ + /** + * List an issue's tracked times. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param string $user Optional. Filter by user. + * @param string $since Optional. Show times updated after the given time. + * @param string $before Optional. Show times updated before the given time. + * @param int $page Optional. Page number of results to return (1-based). + * @param int $limit Optional. Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $owner, + string $repo, + int $index, + string $user = null, + string $since = null, + string $before = null, + int $page = null, + int $limit = null + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/times"; + + // Prepare the query parameters. + $uri = $this->uri->get($path); + if ($user !== null) + { + $uri->setVar('user', $user); + } + if ($since !== null) + { + $uri->setVar('since', $since); + } + if ($before !== null) + { + $uri->setVar('before', $before); + } + if ($page !== null) + { + $uri->setVar('page', $page); + } + if ($limit !== null) + { + $uri->setVar('limit', $limit); + } + + // Send the get request with the query parameters. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Add tracked time to an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param int $time The tracked time in seconds. + * @param string $created Optional. The date and time of the tracked time in RFC 3339 format. + * @param string $userName Optional. User who spent the time. + * + * @return object|null + * @since 3.2.0 + **/ + public function add( + string $owner, + string $repo, + int $index, + int $time, + string $created = null, + string $userName = null + ): ?object + { + // Set the lines data + $data = new \stdClass(); + + // Set all the needed data. + $data->time = $time; + if ($created !== null) + { + $data->created = $created; + } + if ($userName !== null) + { + $data->user_name = $userName; + } + + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/times"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ) + ); + } + + /** + * Reset a tracked time of an issue. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * + * @return string + * @since 3.2.0 + **/ + public function reset(string $owner, string $repo, int $index): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/times"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Delete specific tracked time. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param int $index The issue index. + * @param int $id The ID of the tracked time to delete. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $owner, string $repo, int $index, int $id): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issues/{$index}/times/{$id}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Issue/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Labels.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Labels.php new file mode 100644 index 000000000..43f2c9f6f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Labels.php @@ -0,0 +1,162 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Labels + * + * @since 3.2.0 + */ +class Labels extends Api +{ + /** + * Create a label. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string $labelName The name of the label. + * @param string $labelColor The color of the label, in hexadecimal format with the leading '#'. + * @param string $labelDescription Optional. The description of the label. + * + * @return object|null + * @since 3.2.0 + **/ + public function create(string $owner, string $repo, string $labelName, string $labelColor, string $labelDescription = ''): ?object + { + // Set the lines data + $data = new \stdClass(); + + // Set all the needed data. + $data->name = $labelName; + $data->color = $labelColor; + if (!empty($labelDescription)) + { + $data->description = $labelDescription; + } + + // Build the request path. + $path = "/repos/{$owner}/{$repo}/labels"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * Get a single label. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string $id The ID of the label to retrieve. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo, string $id): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/labels/{$id}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a label. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string $id The ID of the label to delete. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $owner, string $repo, string $id): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/labels/{$id}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Update a label. + * + * @param string $owner The owner name. + * @param string $repo The repo name. + * @param string $id The ID of the label to update. + * @param string $labelName Optional. The new name of the label. + * @param string $labelColor Optional. The new color of the label, in hexadecimal format without the leading '#'. + * @param string $labelDescription Optional. The new description of the label. + * + * @return object|null + * @since 3.2.0 + **/ + public function update( + string $owner, + string $repo, + string $id, + string $labelName = '', + string $labelColor = '', + string $labelDescription = '' + ): ?object + { + // Set the lines data + $data = new \stdClass(); + + // Set all the optional data that has been provided. + if (!empty($labelName)) + { + $data->name = $labelName; + } + + if (!empty($labelColor)) + { + $data->color = $labelColor; + } + + if (!empty($labelDescription)) + { + $data->description = $labelDescription; + } + + // Build the request path. + $path = "/repos/{$owner}/{$repo}/labels/{$id}"; + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), + json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Activitypub.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Activitypub.php new file mode 100644 index 000000000..78c6d270b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Activitypub.php @@ -0,0 +1,69 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Miscellaneous; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Miscellaneous Activitypub + * + * @since 3.2.0 + */ +class Activitypub extends Api +{ + /** + * Returns the Person actor for a user. + * + * @param string $username The user's username. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $username): ?object + { + // Build the request path. + $path = "/activitypub/user/{$username}"; + + // Send the GET request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Send to the user's inbox. + * + * @param string $username The user's username. + * @param object $postData The post data. + * + * @return string + * @since 3.2.0 + **/ + public function send(string $username, object $postData): string + { + // Build the request path. + $path = "/activitypub/user/{$username}/inbox"; + + // Send the POST request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($postData) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Gpg.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Gpg.php new file mode 100644 index 000000000..5a92c54a6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Gpg.php @@ -0,0 +1,45 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Miscellaneous; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Miscellaneous Gpg + * + * @since 3.2.0 + */ +class Gpg extends Api +{ + /** + * Get default signing-key.gpg. + * + * @return string|null + * @since 3.2.0 + **/ + public function get(): ?string + { + // Build the request path. + $path = "/signing-key.gpg"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Markdown.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Markdown.php new file mode 100644 index 000000000..f6f54e5b9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Markdown.php @@ -0,0 +1,87 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Miscellaneous; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Miscellaneous Markdown + * + * @since 3.2.0 + */ +class Markdown extends Api +{ + /** + * Render a markdown document as HTML. + * + * @param string $markdownText The markdown text to render. + * @param bool $isWikiPage Is it a wiki page? + * @param string $context Context to render. + * @param string $mode Mode to render. + * + * @return string|null + * @since 3.2.0 + **/ + public function render( + string $markdownText, + bool $isWikiPage = false, + string $context = 'string', + string $mode = 'string' + ): ?string + { + // Build the request path. + $path = "/markdown"; + + // Set the markdown data. + $data = new \stdClass(); + $data->Text = $markdownText; + $data->Wiki = $isWikiPage; + $data->Context = $context; + $data->Mode = $mode; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data), + ['accept' => 'text/html'] + ) + ); + } + + /** + * Render raw markdown as HTML. + * + * @param string $rawMarkdown The raw markdown text to render. + * + * @return string|null + * @since 3.2.0 + **/ + public function raw(string $rawMarkdown): ?string + { + // Build the request path. + $path = "/markdown/raw"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + $rawMarkdown, + ['Content-Type' => 'text/plain', 'accept' => 'text/html'] + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/NodeInfo.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/NodeInfo.php new file mode 100644 index 000000000..fe714b220 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/NodeInfo.php @@ -0,0 +1,45 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Miscellaneous; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Miscellaneous NodeInfo + * + * @since 3.2.0 + */ +class NodeInfo extends Api +{ + /** + * Returns the nodeinfo of the Gitea application. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(): ?object + { + // Build the request path. + $path = "/nodeinfo"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Version.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Version.php new file mode 100644 index 000000000..696db50e9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/Version.php @@ -0,0 +1,45 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Miscellaneous; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Miscellaneous Version + * + * @since 3.2.0 + */ +class Version extends Api +{ + /** + * Returns the version of the Gitea application. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(): ?object + { + // Build the request path. + $path = "/version"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Miscellaneous/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications.php new file mode 100644 index 000000000..ffe33a83b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications.php @@ -0,0 +1,149 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Notifications + * + * @since 3.2.0 + */ +class Notifications extends Api +{ + /** + * List user's notification threads. + * + * @param bool|null $all Show notifications marked as read (optional). + * @param array|null $statusTypes Show notifications with the provided status types (optional). + * @param array|null $subjectType Filter notifications by subject type (optional). + * @param string|null $since Show notifications updated after the given time (optional). + * @param string|null $before Show notifications updated before the given time (optional). + * @param int $page Page number of results to return (optional). + * @param int $limit Page size of results (optional). + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + ?bool $all = null, + ?array $statusTypes = null, + ?array $subjectType = null, + ?string $since = null, + ?string $before = null, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/notifications"; + + // Configure the URI with query parameters. + $uri = $this->uri->get($path); + if ($all !== null) + { + $uri->setVar('all', $all); + } + if ($statusTypes !== null) + { + $uri->setVar('status-types', implode(',', $statusTypes)); + } + if ($subjectType !== null) + { + $uri->setVar('subject-type', implode(',', $subjectType)); + } + if ($since !== null) + { + $uri->setVar('since', $since); + } + if ($before !== null) + { + $uri->setVar('before', $before); + } + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Mark notification threads as read, pinned, or unread. + * + * @param string|null $lastReadAt Describes the last point that notifications were checked (optional). + * @param bool|null $all If true, mark all notifications on this repo (optional). + * @param array|null $statusTypes Mark notifications with the provided status types (optional). + * @param string|null $toStatus Status to mark notifications as (optional). + * + * @return array|null + * @since 3.2.0 + **/ + public function update( + ?string $lastReadAt = null, + ?bool $all = null, + ?array $statusTypes = null, + ?string $toStatus = null + ): ?array + { + // Build the request path. + $path = "/notifications"; + + // Configure the URI with query parameters. + $uri = $this->uri->get($path); + if ($lastReadAt !== null) + { + $uri->setVar('last_read_at', $lastReadAt); + } + if ($all !== null) + { + $uri->setVar('all', $all); + } + if ($statusTypes !== null) + { + $uri->setVar('status-types', implode(',', $statusTypes)); + } + if ($toStatus !== null) + { + $uri->setVar('to-status', $toStatus); + } + + // Send the put request. + return $this->response->get( + $this->http->put($uri, ''), 205 + ); + } + + /** + * Check if unread notifications exist. + * + * @return object|null + * @since 3.2.0 + **/ + public function check(): ?object + { + // Build the request path. + $path = "/notifications/new"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications/Repository.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications/Repository.php new file mode 100644 index 000000000..452039144 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications/Repository.php @@ -0,0 +1,144 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Notifications; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Notifications Repository + * + * @since 3.2.0 + */ +class Repository extends Api +{ + /** + * List user's notification threads on a specific repo. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param bool $all Show notifications marked as read. + * @param array $statusTypes Show notifications with the provided status types. + * @param array $subjectTypes Filter notifications by subject type. + * @param string $since Show notifications updated after the given time. + * @param string $before Show notifications updated before the given time. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + bool $all = false, + array $statusTypes = [], + array $subjectTypes = [], + string $since = '', + string $before = '', + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/notifications"; + + // Configure the URI with query parameters. + $uri = $this->uri->get($path); + + if ($all) + { + $uri->setVar('all', $all); + } + + if (!empty($statusTypes)) + { + $uri->setVar('status-types', implode(',', $statusTypes)); + } + + if (!empty($subjectTypes)) + { + $uri->setVar('subject-type', implode(',', $subjectTypes)); + } + + if (!empty($since)) + { + $uri->setVar('since', $since); + } + + if (!empty($before)) + { + $uri->setVar('before', $before); + } + + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Mark notification threads as read, pinned, or unread on a specific repo. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param bool|null $all Mark all notifications on this repo (optional). + * @param array|null $statusTypes Mark notifications with the provided status types (optional). + * @param string|null $toStatus Status to mark notifications as (optional). + * @param string|null $lastReadAt Last point that notifications were checked (optional). + * + * @return array|null + * @since 3.2.0 + **/ + public function update( + string $owner, + string $repo, + ?bool $all = null, + ?array $statusTypes = null, + ?string $toStatus = null, + ?string $lastReadAt = null + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/notifications"; + + // Configure the URI with query parameters. + $uri = $this->uri->get($path); + if ($all !== null) + { + $uri->setVar('all', $all); + } + if ($statusTypes !== null) + { + $uri->setVar('status-types', implode(',', $statusTypes)); + } + if ($toStatus !== null) + { + $uri->setVar('to-status', $toStatus); + } + if ($lastReadAt !== null) + { + $uri->setVar('last_read_at', $lastReadAt); + } + + // Send the put request. + return $this->response->get( + $this->http->put($uri, ''), 205 + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications/Thread.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications/Thread.php new file mode 100644 index 000000000..ae8daaab0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications/Thread.php @@ -0,0 +1,96 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Notifications; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Notifications Thread + * + * @since 3.2.0 + */ +class Thread extends Api +{ + /** + * Get notification thread by ID. + * + * @param int $id The notification thread ID. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(int $id): ?object + { + // Build the request path. + $path = "/notifications/threads/{$id}"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Mark notification threads as read, pinned, or unread by ID. + * + * @param int $id The notification thread ID. + * @param string|null $lastReadAt Last point that notifications were checked (optional). + * @param bool|null $all Mark all notifications on this repo (optional). + * @param array|null $statusTypes Mark notifications with the provided status types (optional). + * @param string|null $toStatus Status to mark notifications as (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function mark( + int $id, + ?string $lastReadAt = null, + ?bool $all = null, + ?array $statusTypes = null, + ?string $toStatus = null + ): ?object + { + // Build the request path. + $path = "/notifications/threads/{$id}"; + + // Configure the URI with query parameters. + $uri = $this->uri->get($path); + if ($lastReadAt !== null) + { + $uri->setVar('last_read_at', $lastReadAt); + } + if ($all !== null) + { + $uri->setVar('all', $all); + } + if ($statusTypes !== null) + { + $uri->setVar('status-types', implode(',', $statusTypes)); + } + if ($toStatus !== null) + { + $uri->setVar('to-status', $toStatus); + } + + // Send the put request. + return $this->response->get( + $this->http->put($uri, ''), 205 + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Notifications/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization.php new file mode 100644 index 000000000..0e7255cea --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization.php @@ -0,0 +1,209 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Organization + * + * @since 3.2.0 + */ +class Organization extends Api +{ + /** + * Create an organization. + * + * @param string $login Required. The organization's username. + * @param string $fullName Required. The full name of the organization. + * @param string $email Required. The email of the organization. + * @param string $description Optional. The description of the organization. + * @param bool $repoAdmin Optional. Whether the user has repository admin access. + * @param bool $teamAdmin Optional. Whether the user has team admin access. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $login, + string $fullName, + string $email, + string $description = '', + bool $repoAdmin = false, + bool $teamAdmin = false + ): ?object + { + // Set the lines data + $data = new \stdClass(); + $data->username = $login; + $data->full_name = $fullName; + $data->email = $email; + $data->description = $description; + $data->repo_admin_change_team_access = $repoAdmin; + $data->team_admin_change_team_access = $teamAdmin; + + // Build the request path. + $path = '/orgs'; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * Get an organization. + * + * @param string $org The organization name. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $org): ?object + { + // Build the request path. + $path = "/orgs/{$org}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Get a list of organizations. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/orgs'; + + // Get the URI and set query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Delete an organization. + * + * @param string $org The organization name. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $org): string + { + // Build the request path. + $path = "/orgs/{$org}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Edit an organization. + * + * @param string $org The organization name. + * @param string $fullName Optional. The full name of the organization. + * @param string $location Optional. The location of the organization. + * @param string $description Optional. The description of the organization. + * @param bool $repoAdmin Optional. Whether the user has repository admin access. + * @param string $visibility Optional. The visibility of the organization (public, limited, or private). + * @param string $website Optional. The website of the organization. + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + string $org, + ?string $fullName = null, + ?string $email = null, + ?string $location = null, + ?string $description = null, + ?bool $repoAdmin = null, + ?string $visibility = null, + ?string $website = null + ): ?object + { + // Set the lines data + $data = new \stdClass(); + + if ($fullName !== null) + { + $data->full_name = $fullName; + } + + if ($location !== null) + { + $data->location = $location; + } + + if ($description !== null) + { + $data->description = $description; + } + + if ($repoAdmin !== null) + { + $data->repo_admin_change_team_access = $repoAdmin; + } + + if ($visibility !== null) + { + $data->visibility = $visibility; + } + + if ($website !== null) + { + $data->website = $website; + } + + // Build the request path. + $path = "/orgs/{$org}"; + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), + json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Hooks.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Hooks.php new file mode 100644 index 000000000..981c065d5 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Hooks.php @@ -0,0 +1,200 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Organization; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Organization Hooks + * + * @since 3.2.0 + */ +class Hooks extends Api +{ + /** + * List an organization's webhooks. + * + * @param string $orgName The organization name. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $orgName, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/orgs/{$orgName}/hooks"; + + // Get the URI and set query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a hook for an organization. + * + * @param string $org The organization name. + * @param string $type The type of hook (e.g. "gitea", "slack", "discord", etc.). + * @param string $url The URL of the hook. + * @param string $secret Optional. The secret for the hook. + * @param bool $events Optional. The events that trigger the hook. + * @param bool $active Optional. Whether the hook is active. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $org, + string $type, + string $url, + string $secret = '', + bool $events = true, + bool $active = true + ): ?object + { + // Set the lines data + $data = new \stdClass(); + $data->type = $type; + $data->config = new \stdClass(); + $data->config->url = $url; + $data->config->secret = $secret; + $data->events = []; + $data->active = $active; + + // Build the request path. + $path = "/orgs/{$org}/hooks"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * Get a hook for an organization. + * + * @param string $org The organization name. + * @param int $id The ID of the hook. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $org, int $id): ?object + { + // Build the request path. + $path = "/orgs/{$org}/hooks/{$id}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a hook for an organization. + * + * @param string $org The organization name. + * @param int $id The hook ID. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $org, int $id): string + { + // Build the request path. + $path = "/orgs/{$org}/hooks/{$id}"; + + // Send the DELETE request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Update a hook for an organization. + * + * @param string $orgName The organization name. + * @param int $hookId The ID of the hook. + * @param bool|null $active Optional. Whether the hook is active. + * @param string|null $branchFilter Optional. Branch filter for the hook. + * @param array|null $config Optional. Configuration for the hook. + * @param array|null $events Optional. Events for the hook. + * + * @return object|null + * @since 3.2.0 + **/ + public function update( + string $orgName, + int $hookId, + ?bool $active = null, + ?string $branchFilter = null, + ?array $config = null, + ?array $events = null + ): ?object + { + // Set the lines data + $data = new \stdClass(); + + if ($active !== null) + { + $data->active = $active; + } + + if ($branchFilter !== null) + { + $data->branch_filter = $branchFilter; + } + + if ($config !== null) + { + $data->config = (object) $config; + } + + if ($events !== null) + { + $data->events = $events; + } + + // Build the request path. + $path = "/orgs/{$orgName}/hooks/{$hookId}"; + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), + json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Labels.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Labels.php new file mode 100644 index 000000000..0836501aa --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Labels.php @@ -0,0 +1,183 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Organization; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Organization Labels + * + * @since 3.2.0 + */ +class Labels extends Api +{ + /** + * List an organization's labels. + * + * @param string $orgName The organization name. + * @param int $pageNum Page number of results to return (1-based). + * @param int $pageSize Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $orgName, + int $pageNum = 1, + int $pageSize = 10 + ): ?array + { + // Build the request path. + $path = "/orgs/{$orgName}/labels"; + + // Build the URL + $url = $this->uri->get($path); + $url->setVar('page', $pageNum); + $url->setVar('limit', $pageSize); + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + + /** + * Create a label for an organization. + * + * @param string $org The organization name. + * @param string $name The name of the label. + * @param string $color The color of the label. + * @param string $description Optional. The description of the label. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $org, + string $name, + string $color, + string $description = '' + ): ?object + { + // Set the lines data + $data = new \stdClass(); + $data->name = $name; + $data->color = $color; + $data->description = $description; + + // Build the request path. + $path = "/orgs/{$org}/labels"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * Get a single label for an organization. + * + * @param string $org The organization name. + * @param int $id The ID of the label. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $org, int $id): ?object + { + // Build the request path. + $path = "/orgs/{$org}/labels/{$id}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a label for an organization. + * + * @param string $org The organization name. + * @param int $id The ID of the label. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $org, int $id): string + { + // Build the request path. + $path = "/orgs/{$org}/labels/{$id}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Update a label for an organization. + * + * @param string $org The organization name. + * @param int $id The ID of the label. + * @param string $name Optional. The name of the label. + * @param string $color Optional. The color of the label. + * @param string $description Optional. The description of the label. + * + * @return object|null + * @since 3.2.0 + **/ + public function update( + string $org, + int $id, + string $name = '', + string $color = '', + string $description = '' + ): ?object + { + // Set the lines data + $data = new \stdClass(); + + if ($name) { + $data->name = $name; + } + + if ($color) { + $data->color = $color; + } + + if ($description) { + $data->description = $description; + } + + // Build the request path. + $path = "/orgs/{$org}/labels/{$id}"; + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), + json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Members.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Members.php new file mode 100644 index 000000000..97bf82bd8 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Members.php @@ -0,0 +1,100 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Organization; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Organization Members + * + * @since 3.2.0 + */ +class Members extends Api +{ + /** + * Get a list of members of an organization. + * + * @param string $orgName The organization name. + * @param int $page The page number. + * @param int $limit The number of members per page. + * + * @return array|null The organization members. + * @since 3.2.0 + */ + public function list( + string $orgName, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/orgs/{$orgName}/members"; + + // Get the URI and set query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Check if a user is a member of an organization. + * + * @param string $org The organization name. + * @param string $username The username. + * + * @return string Whether the user is a member of the organization. + * @since 3.2.0 + */ + public function check(string $org, string $username): string + { + // Build the request path. + $path = "/orgs/{$org}/members/{$username}"; + + // Send the request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Remove a member from an organization. + * + * @param string $org The organization name. + * @param string $username The username of the user to remove. + * + * @return string Whether the user was successfully removed from the organization. + * @since 3.2.0 + */ + public function remove(string $org, string $username): string + { + // Build the request path. + $path = "/orgs/{$org}/members/{$username}"; + + // Send the request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/PublicMembers.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/PublicMembers.php new file mode 100644 index 000000000..c82853249 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/PublicMembers.php @@ -0,0 +1,119 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Organization; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Organization Public Members + * + * @since 3.2.0 + */ +class PublicMembers extends Api +{ + /** + * List an organization's public members. + * + * @param string $orgName The organization name. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(string $orgName, int $page = 1, int $limit = 10): ?array + { + // Build the request path. + $path = "/orgs/{$orgName}/public_members"; + + // Configure the request URI. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + + /** + * Check if a user is a public member of an organization. + * + * @param string $org The organization name. + * @param string $username The user's username. + * + * @return string|null + * @since 3.2.0 + **/ + public function check(string $org, string $username): ?string + { + // Build the request path. + $path = "/orgs/{$org}/public_members/{$username}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ), 204 + ); + } + + /** + * Publicize a user's membership. + * + * @param string $org The organization name. + * @param string $username The user's username. + * + * @return string|null + * @since 3.2.0 + **/ + public function publicize(string $org, string $username): ?string + { + // Build the request path. + $path = "/orgs/{$org}/public_members/{$username}"; + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), '' + ), 204 + ); + } + + /** + * Conceal a user's membership. + * + * @param string $org The organization name. + * @param string $username The user's username. + * + * @return string + * @since 3.2.0 + **/ + public function conceal(string $org, string $username): string + { + // Build the request path. + $path = "/orgs/{$org}/public_members/{$username}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Repository.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Repository.php new file mode 100644 index 000000000..18c53840e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Repository.php @@ -0,0 +1,145 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Organization; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Organization Repository + * + * @since 3.2.0 + */ +class Repository extends Api +{ + /** + * List an organization's repos. + * + * @param string $org The organization name. + * @param int $pageNumber The page number. + * @param int $pageSize The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $org, + int $pageNumber = 1, + int $pageSize = 10 + ): ?array + { + // Build the request path. + $path = "/orgs/{$org}/repos"; + + // Configure the request URI. + $uri = $this->uri->get($path); + $uri->setVar('page', $pageNumber); + $uri->setVar('limit', $pageSize); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a repository in an organization. + * + * @param string $org The organization name. + * @param string $repoName The name of the repository. + * @param string|null $description The description of the repository (optional). + * @param bool|null $autoInit Whether the repository should be auto-initialized (optional). + * @param string|null $defaultBranch Default branch of the repository (optional). + * @param string|null $gitignores Gitignores to use (optional). + * @param string|null $issueLabels Label-set to use (optional). + * @param string|null $license License to use (optional). + * @param bool|null $private Whether the repository is private (optional). + * @param string|null $readme Readme of the repository to create (optional). + * @param bool|null $template Whether the repository is a template (optional). + * @param string|null $trustModel Trust model of the repository (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $org, + string $repoName, + ?string $description = null, + ?bool $autoInit = null, + ?string $defaultBranch = null, + ?string $gitignores = null, + ?string $issueLabels = null, + ?string $license = null, + ?bool $private = null, + ?string $readme = null, + ?bool $template = null, + ?string $trustModel = null + ): ?object + { + // Build the request path. + $path = "/orgs/{$org}/repos"; + + // Set the repository data. + $data = new \stdClass(); + $data->name = $repoName; + if ($description !== null) + { + $data->description = $description; + } + if ($autoInit !== null) + { + $data->auto_init = $autoInit; + } + if ($defaultBranch !== null) + { + $data->default_branch = $defaultBranch; + } + if ($gitignores !== null) + { + $data->gitignores = $gitignores; + } + if ($issueLabels !== null) + { + $data->issue_labels = $issueLabels; + } + if ($license !== null) + { + $data->license = $license; + } + if ($private !== null) + { + $data->private = $private; + } + if ($readme !== null) + { + $data->readme = $readme; + } + if ($template !== null) + { + $data->template = $template; + } + if ($trustModel !== null) + { + $data->trust_model = $trustModel; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams.php new file mode 100644 index 000000000..46a27b078 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams.php @@ -0,0 +1,274 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Organization; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Organization Teams + * + * @since 3.2.0 + */ +class Teams extends Api +{ + /** + * List an organization's teams. + * + * @param string $organization The organization name. + * @param int $pageNumber The page number of results to return (1-based). + * @param int $pageSize The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $organization, + int $pageNumber = 1, + int $pageSize = 10 + ): ?array + { + // Build the request path. + $path = "/orgs/{$organization}/teams"; + + // Get the URI object. + $uri = $this->uri->get($path); + + // Add the query parameters for page number and page size. + $uri->setVar('page', $pageNumber); + $uri->setVar('limit', $pageSize); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get a team. + * + * @param int $id The team ID. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(int $id): ?object + { + // Build the request path. + $path = "/teams/{$id}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Create a team. + * + * @param string $organization The organization name. + * @param string $name The name of the team. + * @param string $description The description of the team. + * @param array $repoNames An array of repository names for the team (optional). + * @param string $permission The team's permission level (optional). + * @param array $units Units for the team (optional). + * @param array $unitsMap Units map for the team (optional). + * @param bool $canCreateOrgRepo Can create organization repository flag (optional). + * @param bool $includesAllRepositories Includes all repositories flag (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $organization, + string $name, + string $description, + array $repoNames = [], + string $permission = 'read', + array $units = [], + array $unitsMap = [], + bool $canCreateOrgRepo = null, + bool $includesAllRepositories = null + ): ?object + { + // Build the request path. + $path = "/orgs/{$organization}/teams"; + + // Set the team data. + $data = new \stdClass(); + $data->name = $name; + $data->description = $description; + $data->permission = $permission; + + if (!empty($repoNames)) + { + $data->repo_names = $repoNames; + } + + if (!empty($units)) + { + $data->units = $units; + } + + if (!empty($unitsMap)) + { + $data->units_map = (object)$unitsMap; + } + + if ($canCreateOrgRepo !== null) + { + $data->can_create_org_repo = $canCreateOrgRepo; + } + + if ($includesAllRepositories !== null) + { + $data->includes_all_repositories = $includesAllRepositories; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Search for teams within an organization. + * + * @param string $organization The organization name. + * @param string $keywords The search keywords. + * @param bool $includeDesc Include search within team description (defaults to true). + * @param int $page The page number. + * @param int $limit The number of results per page. + * + * @return object|null + * @since 3.2.0 + **/ + public function search( + string $organization, + string $keywords, + bool $includeDesc = true, + int $page = 1, + int $limit = 10 + ): ?object + { + // Build the request path. + $path = "/orgs/{$organization}/teams/search"; + + // Configure the request URI. + $uri = $this->uri->get($path); + $uri->setVar('q', $keywords); + $uri->setVar('include_desc', $includeDesc); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Delete a team. + * + * @param int $id The team ID. + * + * @return string + * @since 3.2.0 + **/ + public function delete(int $id): string + { + // Build the request path. + $path = "/teams/{$id}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Edit a team. + * + * @param int $teamId The team ID. + * @param string|null $teamName The team name (optional). + * @param string|null $teamDescription The team description (optional). + * @param string|null $teamPermission The team's permission level (optional). + * @param bool|null $canCreateOrgRepo Can team create organization repositories (optional). + * @param bool|null $includesAllRepositories Include all repositories (optional). + * @param array|null $units List of units (optional). + * @param array|null $unitsMap Units map (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + int $teamId, + ?string $teamName = null, + ?string $teamDescription = null, + ?string $teamPermission = null, + ?bool $canCreateOrgRepo = null, + ?bool $includesAllRepositories = null, + ?array $units = null, + ?array $unitsMap = null + ): ?object + { + // Build the request path. + $path = "/teams/{$teamId}"; + + // Set the team data. + $data = new \stdClass(); + if ($teamName !== null) + { + $data->name = $teamName; + } + if ($teamDescription !== null) + { + $data->description = $teamDescription; + } + if ($teamPermission !== null) + { + $data->permission = $teamPermission; + } + if ($canCreateOrgRepo !== null) + { + $data->can_create_org_repo = $canCreateOrgRepo; + } + if ($includesAllRepositories !== null) + { + $data->includes_all_repositories = $includesAllRepositories; + } + if ($units !== null) + { + $data->units = $units; + } + if ($unitsMap !== null) + { + $data->units_map = $unitsMap; + } + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams/Members.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams/Members.php new file mode 100644 index 000000000..89e914518 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams/Members.php @@ -0,0 +1,124 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Organization\Teams; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Organization Teams Members + * + * @since 3.2.0 + */ +class Members extends Api +{ + /** + * List a team's members. + * + * @param int $teamId The team ID. + * @param int $pageNumber The page number of results to return (1-based). + * @param int $pageSize The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $teamId, + int $pageNumber = 1, + int $pageSize = 10 + ): ?array + { + // Build the request path. + $path = "/teams/{$teamId}/members"; + + // Get the URI object. + $uri = $this->uri->get($path); + + // Add the query parameters for page number and page size. + $uri->setVar('page', $pageNumber); + $uri->setVar('limit', $pageSize); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * List a particular member of the team. + * + * @param int $id The team ID. + * @param string $username The user's username. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(int $id, string $username): ?object + { + // Build the request path. + $path = "/teams/{$id}/members/{$username}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Add a team member. + * + * @param int $id The team ID. + * @param string $username The user's username. + * + * @return string + * @since 3.2.0 + **/ + public function add(int $id, string $username): string + { + // Build the request path. + $path = "/teams/{$id}/members/{$username}"; + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), '' + ), 204, 'success' + ); + } + + /** + * Remove a team member. + * + * @param int $id The team ID. + * @param string $username The user's username. + * + * @return string + * @since 3.2.0 + **/ + public function remove(int $id, string $username): string + { + // Build the request path. + $path = "/teams/{$id}/members/{$username}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams/Repository.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams/Repository.php new file mode 100644 index 000000000..f485c0972 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams/Repository.php @@ -0,0 +1,135 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Organization\Teams; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Organization Teams Repository + * + * @since 3.2.0 + */ +class Repository extends Api +{ + /** + * List a team's repos. + * + * @param int $teamId The team ID. + * @param int $pageNumber The page number of results to return (1-based). + * @param int $pageSize The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $teamId, + int $pageNumber = 1, + int $pageSize = 10 + ): ?array + { + // Build the request path. + $path = "/teams/{$teamId}/repos"; + + // Get the URI object. + $uri = $this->uri->get($path); + + // Add the query parameters for page number and page size. + $uri->setVar('page', $pageNumber); + $uri->setVar('limit', $pageSize); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * List a particular repo of the team. + * + * @param int $teamId The team ID. + * @param string $organization The organization name. + * @param string $repository The repository name. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + int $teamId, + string $organization, + string $repository + ): ?object + { + // Build the request path. + $path = "/teams/{$teamId}/repos/{$organization}/{$repository}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Add a repository to a team. + * + * @param int $id The team ID. + * @param string $org The organization name. + * @param string $repo The repository name. + * + * @return string + * @since 3.2.0 + **/ + public function add( + int $id, + string $org, + string $repo + ): string + { + // Build the request path. + $path = "/teams/{$id}/repos/{$org}/{$repo}"; + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), '' + ),204, 'success' + ); + } + + /** + * Remove a repository from a team. + * + * @param int $id The team ID. + * @param string $org The organization name. + * @param string $repo The repository name. + * + * @return string + * @since 3.2.0 + **/ + public function remove(int $id, string $org, string $repo): string + { + // Build the request path. + $path = "/teams/{$id}/repos/{$org}/{$repo}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/Teams/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/User.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/User.php new file mode 100644 index 000000000..b59fe9b6f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/User.php @@ -0,0 +1,111 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Organization; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Organization User + * + * @since 3.2.0 + */ +class User extends Api +{ + /** + * List the current user's organizations. + * + * @param int $pageNumber The page number of results to return (1-based). + * @param int $pageSize The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $pageNumber = 1, + int $pageSize = 10 + ): ?array + { + // Build the request path. + $path = "/user/orgs"; + + // Get the URI object. + $uri = $this->uri->get($path); + + // Add the query parameters for page number and page size. + $uri->setVar('page', $pageNumber); + $uri->setVar('limit', $pageSize); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * List a user's organizations. + * + * @param string $username The user's username. + * @param int $pageNumber The page number of results to return (1-based). + * @param int $pageSize The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function get( + string $username, + int $pageNumber = 1, + int $pageSize = 10 + ): ?array + { + // Build the request path. + $path = "/users/{$username}/orgs"; + + // Get the URI object. + $uri = $this->uri->get($path); + + // Add the query parameters for page number and page size. + $uri->setVar('page', $pageNumber); + $uri->setVar('limit', $pageSize); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get user permissions in an organization. + * + * @param string $username The user's username. + * @param string $org The organization name. + * + * @return object|null + * @since 3.2.0 + **/ + public function permissions(string $username, string $org): ?object + { + // Build the request path. + $path = "/users/{$username}/orgs/{$org}/permissions"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Organization/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package.php new file mode 100644 index 000000000..8fb1ac22a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package.php @@ -0,0 +1,84 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Package + * + * @since 3.2.0 + */ +class Package extends Api +{ + /** + * Gets a package. + * + * @param string $owner The owner of the package. + * @param string $type The type of the package. + * @param string $name The name of the package. + * @param string $version The version of the package. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $type, + string $name, + string $version + ): ?object + { + // Build the request path. + $path = "/packages/{$owner}/{$type}/{$name}/{$version}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a package. + * + * @param string $owner The owner of the package. + * @param string $type The type of the package. + * @param string $name The name of the package. + * @param string $version The version of the package. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $owner, + string $type, + string $name, + string $version + ): string + { + // Build the request path. + $path = "/packages/{$owner}/{$type}/{$name}/{$version}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package/Files.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package/Files.php new file mode 100644 index 000000000..c3851c070 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package/Files.php @@ -0,0 +1,55 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Package; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Package Files + * + * @since 3.2.0 + */ +class Files extends Api +{ + /** + * Gets all files of a package. + * + * @param string $owner The owner of the package. + * @param string $type The type of the package. + * @param string $name The name of the package. + * @param string $version The version of the package. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $type, + string $name, + string $version + ): ?object + { + // Build the request path. + $path = "/packages/{$owner}/{$type}/{$name}/{$version}/files"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package/Owner.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package/Owner.php new file mode 100644 index 000000000..93960d12c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package/Owner.php @@ -0,0 +1,68 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Package; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Package Owner + * + * @since 3.2.0 + */ +class Owner extends Api +{ + /** + * Gets all packages of an owner. + * + * @param string $owner The owner of the packages. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * @param string|null $type Package type filter (optional). + * @param string|null $name Filter Name filter (optional). + * + * @return array|null + * @since 3.2.0 + **/ + public function get( + string $owner, + int $page = 1, + int $limit = 10, + ?string $type = null, + ?string $nameFilter = null + ): ?array + { + // Build the request path. + $path = "/packages/{$owner}"; + + // Configure the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + if ($type !== null) + { + $uri->setVar('type', $type); + } + if ($nameFilter !== null) + { + $uri->setVar('q', $nameFilter); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Package/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository.php new file mode 100644 index 000000000..c1e71264f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository.php @@ -0,0 +1,439 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository + * + * @since 3.2.0 + */ +class Repository extends Api +{ + /** + * Search for repositories. + * + * @param string $q The search query. + * @param array $options Additional search options (optional). + * @param int $page The page number (optional). + * @param int $limit The number of items per page (optional). + * @param string $sort The sort order (optional). + * @param string $order The order direction (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function search( + string $q, + array $options = [], + int $page = 1, + int $limit = 10, + string $sort = 'alpha', + string $order = 'asc' + ): ?object + { + // Build the request path. + $path = '/repos/search'; + + // Create the URI object and set URL values. + $uri = $this->uri->get($path); + $uri->setVar('q', $q); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + $uri->setVar('sort', $sort); + $uri->setVar('order', $order); + + foreach ($options as $key => $val) + { + $uri->setVar($key, $val); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Get a repository by owner and repo name. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return object|null + * @since 3.2.0 + **/ + public function id(string $owner, string $repo): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $owner, string $repo): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Edit a repository's properties. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string|null $description The repository description (optional). + * @param string|null $website The repository website (optional). + * @param bool|null $private Set the repository to private (optional). + * @param bool|null $hasIssues Set the repository to have issues (optional). + * @param bool|null $hasWiki Set the repository to have a wiki (optional). + * @param bool|null $hasProjects Set the repository to have projects (optional). + * @param bool|null $allowManualMerge Allow manual merge of pull requests (optional). + * @param bool|null $allowMergeCommits Allow merge commits for pull requests (optional). + * @param bool|null $allowRebase Allow rebase-merging pull requests (optional). + * @param bool|null $allowRebaseExplicit Allow rebase with explicit merge commits (optional). + * @param bool|null $allowRebaseUpdate Allow updating pull request branch by rebase (optional). + * @param bool|null $allowSquashMerge Allow squash-merging pull requests (optional). + * @param bool|null $archived + * @param bool|null $archived Set to true to archive this repository (optional). + * @param bool|null $autodetectManualMerge Enable AutodetectManualMerge (optional). + * @param string|null $defaultBranch Sets the default branch for this repository (optional). + * @param bool|null $defaultDeleteBranchAfterMerge Set to true to delete pr branch after merge by default (optional). + * @param string|null $defaultMergeStyle Set to a merge style to be used by this repository (optional). + * @param bool|null $enablePrune Enable prune - remove obsolete remote-tracking references (optional). + * @param object|null $externalTracker External tracker settings (optional). + * @param object|null $externalWiki External wiki settings (optional). + * @param bool|null $hasPullRequests Set the repository to have pull requests (optional). + * @param bool|null $ignoreWhitespaceConflicts Ignore whitespace for conflicts (optional). + * @param object|null $internalTracker Internal tracker settings (optional). + * @param string|null $mirrorInterval Set the mirror interval time (optional). + * @param bool|null $template Set to true to make this repository a template (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + string $owner, + string $repo, + ?string $description = null, + ?string $website = null, + ?bool $private = null, + ?bool $hasIssues = null, + ?bool $hasWiki = null, + ?bool $hasProjects = null, + ?bool $allowManualMerge = null, + ?bool $allowMergeCommits = null, + ?bool $allowRebase = null, + ?bool $allowRebaseExplicit = null, + ?bool $allowRebaseUpdate = null, + ?bool $allowSquashMerge = null, + ?bool $archived = null, + ?bool $autodetectManualMerge = null, + ?string $defaultBranch = null, + ?bool $defaultDeleteBranchAfterMerge = null, + ?string $defaultMergeStyle = null, + ?bool $enablePrune = null, + ?object $externalTracker = null, + ?object $externalWiki = null, + ?bool $hasPullRequests = null, + ?bool $ignoreWhitespaceConflicts = null, + ?object $internalTracker = null, + ?string $mirrorInterval = null, + ?bool $template = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}"; + + // Set the repository properties to update. + $data = new \stdClass(); + + if ($description !== null) + { + $data->description = $description; + } + + if ($website !== null) + { + $data->website = $website; + } + + if ($private !== null) + { + $data->private = $private; + } + + if ($hasIssues !== null) + { + $data->has_issues = $hasIssues; + } + + if ($hasWiki !== null) + { + $data->has_wiki = $hasWiki; + } + + if ($hasProjects !== null) + { + $data->has_projects = $hasProjects; + } + + // Add the additional properties to update. + if ($allowManualMerge !== null) + { + $data->allow_manual_merge = $allowManualMerge; + } + + if ($allowMergeCommits !== null) + { + $data->allow_merge_commits = $allowMergeCommits; + } + + if ($allowRebase !== null) + { + $data->allow_rebase = $allowRebase; + } + + if ($allowRebaseExplicit !== null) + { + $data->allow_rebase_explicit = $allowRebaseExplicit; + } + + if ($allowRebaseUpdate !== null) + { + $data->allow_rebase_update = $allowRebaseUpdate; + } + + if ($allowSquashMerge !== null) + { + $data->allow_squash_merge = $allowSquashMerge; + } + + if ($archived !== null) + { + $data->archived = $archived; + } + + if ($autodetectManualMerge !== null) + { + $data->autodetect_manual_merge = $autodetectManualMerge; + } + + if ($defaultBranch !== null) + { + $data->default_branch = $defaultBranch; + } + + if ($defaultDeleteBranchAfterMerge !== null) + { + $data->default_delete_branch_after_merge = $defaultDeleteBranchAfterMerge; + } + + if ($defaultMergeStyle !== + null) + { + $data->default_merge_style = $defaultMergeStyle; + } + + if ($enablePrune !== null) + { + $data->enable_prune = $enablePrune; + } + + if ($externalTracker !== null) + { + $data->external_tracker = $externalTracker; + } + + if ($externalWiki !== null) + { + $data->external_wiki = $externalWiki; + } + + if ($hasPullRequests !== null) + { + $data->has_pull_requests = $hasPullRequests; + } + + if ($ignoreWhitespaceConflicts !== null) + { + $data->ignore_whitespace_conflicts = $ignoreWhitespaceConflicts; + } + + if ($internalTracker !== null) + { + $data->internal_tracker = $internalTracker; + } + + if ($mirrorInterval !== null) + { + $data->mirror_interval = $mirrorInterval; + } + + if ($template !== null) + { + $data->template = $template; + } + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Create a repository. + * + * @param string $name The name of the new repository. + * @param string|null $description Optional. The description of the new repository. + * @param bool|null $private Optional. Set to true if the new repository should be private. + * @param bool|null $autoInit Optional. Set to true to initialize the repository with a README. + * @param string|null $defaultBranch Optional. Default branch of the repository (used when initializes and in template). + * @param string|null $gitignores Optional. The desired .gitignore templates to apply. + * @param string|null $issueLabels Optional. Label-Set to use. + * @param string|null $license Optional. The desired license for the repository. + * @param string|null $readme Optional. Readme of the repository to create. + * @param bool|null $template Optional. Set to true if the repository is a template. + * @param string|null $trustModel Optional. TrustModel of the repository. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $name, + ?string $description = null, + ?bool $private = null, + ?bool $autoInit = null, + ?string $defaultBranch = null, + ?string $gitignores = null, + ?string $issueLabels = null, + ?string $license = null, + ?string $readme = null, + ?bool $template = null, + ?string $trustModel = null + ): ?object { + // Build the request path. + $path = "/user/repos"; + + // Set the repo data. + $data = new \stdClass(); + $data->name = $name; + + if ($description !== null) + { + $data->description = $description; + } + + if ($private !== null) + { + $data->private = $private; + } + + if ($autoInit !== null) + { + $data->auto_init = $autoInit; + } + + if ($defaultBranch !== null) + { + $data->default_branch = $defaultBranch; + } + + if ($gitignores !== null) + { + $data->gitignores = $gitignores; + } + + if ($issueLabels !== null) + { + $data->issue_labels = $issueLabels; + } + + if ($license !== null) + { + $data->license = $license; + } + + if ($readme !== null) + { + $data->readme = $readme; + } + + if ($template !== null) + { + $data->template = $template; + } + + if ($trustModel !== null) + { + $data->trust_model = $trustModel; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Archive.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Archive.php new file mode 100644 index 000000000..8cc349973 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Archive.php @@ -0,0 +1,58 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Archive + * + * @since 3.2.0 + */ +class Archive extends Api +{ + /** + * Get an archive of a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $archive The archive format, e.g., "zip" or "tar.gz". + * + * @return string + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + string $archive + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/archive/{$archive}"; + + // Set the required variables to the URI. + $uri = $this->uri->get($path); + $uri->setVar('owner', $owner); + $uri->setVar('repo', $repo); + $uri->setVar('archive', $archive); + + // Send the get request. + return $this->response->get( + $this->http->get($uri), 200, 'success' + ); + } + + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Assignees.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Assignees.php new file mode 100644 index 000000000..f6c8c751f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Assignees.php @@ -0,0 +1,51 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Assignees + * + * @since 3.2.0 + */ +class Assignees extends Api +{ + /** + * Return all users that have write access and can be assigned to issues. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return array|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/assignees"; + + // Set the required variables to the URI. + $uri = $this->uri->get($path); + $uri->setVar('owner', $owner); + $uri->setVar('repo', $repo); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Attachments.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Attachments.php new file mode 100644 index 000000000..121da5d78 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Attachments.php @@ -0,0 +1,196 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Attachments + * + * @since 3.2.0 + */ +class Attachments extends Api +{ + /** + * List release's attachments. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param int $releaseId The release ID. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $ownerName, + string $repoName, + int $releaseId + ): ?array + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/releases/{$releaseId}/assets"; + + // Retrieve the URI object with the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a release attachment. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param int $releaseId The release ID. + * @param string $attachmentFile The attachment file content. + * @param string $attachmentName The attachment file name. + * @param string $contentType The attachment content type. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $ownerName, + string $repoName, + int $releaseId, + string $attachmentFile, + string $attachmentName, + string $contentType + ): ?object + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/releases/{$releaseId}/assets"; + + // Retrieve the URI object with the path. + $uri = $this->uri->get($path); + + // Add the attachment name as a query parameter. + $uri->setVar('name', $attachmentName); + + // Set the request headers. + $headers = [ + "Content-Type: {$contentType}", + "Content-Disposition: attachment; filename={$attachmentName}" + ]; + + // Send the post request. + return $this->response->get( + $this->http->post( + $uri, $attachmentFile, $headers + ), 201 + ); + } + + /** + * Get a release attachment. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $id The release ID. + * @param int $attachmentId The attachment ID. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + int $id, + int $attachmentId + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/releases/{$id}/assets/{$attachmentId}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a release attachment. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $id The release ID. + * @param int $attachmentId The attachment ID. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $owner, + string $repo, + int $id, + int $attachmentId + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/releases/{$id}/assets/{$attachmentId}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Edit a release attachment. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $id The release ID. + * @param int $attachmentId The attachment ID. + * @param string|null $name The new name of the attachment (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + string $owner, + string $repo, + int $id, + int $attachmentId, + ?string $name = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/releases/{$id}/assets/{$attachmentId}"; + + // Set the attachment data + $data = new \stdClass(); + + if ($name !== null) + { + $data->name = $name; + } + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Branch.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Branch.php new file mode 100644 index 000000000..0936bbe3c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Branch.php @@ -0,0 +1,148 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Branch + * + * @since 3.2.0 + */ +class Branch extends Api +{ + /** + * List a repository's branches. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $owner, + string $repo, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/branches"; + + // Set the required variables to the URI. + $uri = $this->uri->get($path); + $uri->setVar('owner', $owner); + $uri->setVar('repo', $repo); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a branch. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $branch_name The name of the new branch. + * @param string $old_branch The name of the existing branch from which to create the new branch. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $owner, + string $repo, + string $branch_name, + string $old_branch + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/branches"; + + // Set the branch data. + $data = new \stdClass(); + $data->branch_name = $branch_name; + $data->old_branch = $old_branch; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Retrieve a specific branch from a repository, including its effective branch protection. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $branch The branch name. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo, string $branch): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/branches/{$branch}"; + + // Set the required variables to the URI. + $uri = $this->uri->get($path); + $uri->setVar('owner', $owner); + $uri->setVar('repo', $repo); + $uri->setVar('branch', $branch); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Delete a specific branch from a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $branch The branch name. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $owner, + string $repo, + string $branch + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/branches/{$branch}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Branch/Protection.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Branch/Protection.php new file mode 100644 index 000000000..946bce20a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Branch/Protection.php @@ -0,0 +1,380 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository\Branch; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Branch Protection + * + * @since 3.2.0 + */ +class Protection extends Api +{ + /** + * List branch protections for a repository. + * + * @param string $ownerName The owner name. + * @param string $repositoryName The repository name. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(string $ownerName, string $repositoryName): ?array + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repositoryName}/branch_protections"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a branch protection for a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $branchName The name of the branch to protect. + * @param array $approvalsWhitelistUsernames An array of usernames that can approve. + * @param array $approvalsWhitelistTeams An array of team names that can approve. + * @param bool $blockOnOfficialReviewRequests Enable/disable blocking on official review requests (optional, default false). + * @param bool $blockOnOutdatedBranch Enable/disable blocking on outdated branch (optional, default false). + * @param bool $blockOnRejectedReviews Enable/disable blocking on rejected reviews (optional, default false). + * @param bool $dismissStaleApprovals Enable/disable dismissing stale approvals (optional, default false). + * @param bool $enableApprovalsWhitelist Enable/disable approvals whitelist (optional, default false). + * @param bool $enableMergeWhitelist Enable/disable merge whitelist (optional, default false). + * @param bool $enablePush Enable/disable push (optional, default true). + * @param bool $enablePushWhitelist Enable/disable push whitelist (optional, default false). + * @param bool $enableStatusCheck Enable/disable status check (optional, default false). + * @param array $mergeWhitelistUsernames An array of usernames that can merge (optional). + * @param array $mergeWhitelistTeams An array of team names that can merge (optional). + * @param string $protectedFilePatterns Protected file patterns (optional). + * @param bool $pushWhitelistDeployKeys Enable/disable push whitelist deploy keys (optional, default false). + * @param array $pushWhitelistUsernames An array of usernames that can push (optional). + * @param array $pushWhitelistTeams An array of team names that can push (optional). + * @param bool $requireSignedCommits Enable/disable requiring signed commits (optional, default false). + * @param int $requiredApprovals Number of required approvals (optional, default 0). + * @param array $statusCheckContexts An array of status check contexts (optional). + * @param string $unprotectedFilePatterns Unprotected file patterns (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $owner, + string $repo, + string $branchName, + array $approvalsWhitelistUsernames, + array $approvalsWhitelistTeams, + bool $blockOnOfficialReviewRequests = false, + bool $blockOnOutdatedBranch = false, + bool $blockOnRejectedReviews = false, + bool $dismissStaleApprovals = false, + bool $enableApprovalsWhitelist = false, + bool $enableMergeWhitelist = false, + bool $enablePush = true, + bool $enablePushWhitelist = false, + bool $enableStatusCheck = false, + array $mergeWhitelistUsernames = [], + array $mergeWhitelistTeams = [], + string $protectedFilePatterns = '', + bool $pushWhitelistDeployKeys = false, + array $pushWhitelistUsernames = [], + array $pushWhitelistTeams = [], + bool $requireSignedCommits = false, + int $requiredApprovals = 0, + array $statusCheckContexts = [], + string $unprotectedFilePatterns = '' + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/branch_protections"; + + // Set the branch protection data. + $data = new \stdClass(); + $data->branch_name = $branchName; + $data->approvals_whitelist_usernames = $approvalsWhitelistUsernames; + $data->approvals_whitelist_teams = $approvalsWhitelistTeams; + $data->block_on_official_review_requests = $blockOnOfficialReviewRequests; + $data->block_on_outdated_branch = $blockOnOutdatedBranch; + $data->block_on_rejected_reviews = $blockOnRejectedReviews; + $data->dismiss_stale_approvals = $dismissStaleApprovals; + $data->enable_approvals_whitelist = $enableApprovalsWhitelist; + $data->enable_merge_whitelist = $enableMergeWhitelist; + $data->enable_push = $enablePush; + $data->enable_push_whitelist = $enablePushWhitelist; + $data->enable_status_check = $enableStatusCheck; + $data->merge_whitelist_usernames = $mergeWhitelistUsernames; + $data->merge_whitelist_teams = $mergeWhitelistTeams; + $data->protected_file_patterns = $protectedFilePatterns; + $data->push_whitelist_deploy_keys = $pushWhitelistDeployKeys; + $data->push_whitelist_usernames = $pushWhitelistUsernames; + $data->push_whitelist_teams = $pushWhitelistTeams; + $data->require_signed_commits = $requireSignedCommits; + $data->required_approvals = $requiredApprovals; + $data->status_check_contexts = $statusCheckContexts; + $data->unprotected_file_patterns = $unprotectedFilePatterns; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Get a specific branch protection for the repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $branchName The branch protection name. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + string $branchName + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/branch_protections/{$branchName}"; + + // Get the URI object with the given path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Delete a specific branch protection for the repository. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $branchName The branch protection name. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $ownerName, + string $repoName, + string $branchName + ): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/branch_protections/{$branchName}"; + + // Set the required variables in the URI. + $this->uri->setVar('owner', $ownerName); + $this->uri->setVar('repo', $repoName); + $this->uri->setVar('name', $branchName); + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Edit a branch protection for a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $name The branch protection name. + * @param array|null $approvalsWhitelistTeams An array of team names that are allowed to approve (optional). + * @param array|null $approvalsWhitelistUsernames An array of usernames that are allowed to approve (optional). + * @param bool|null $blockOnOfficialReviewRequests Block when official review requests are pending (optional). + * @param bool|null $blockOnOutdatedBranch Block when the branch is outdated (optional). + * @param bool|null $blockOnRejectedReviews Block when reviews are rejected (optional). + * @param bool|null $dismissStaleApprovals Dismiss stale approvals when new commits are pushed (optional). + * @param bool|null $enableApprovalsWhitelist Enable/disable approvals whitelist (optional). + * @param bool|null $enableMergeWhitelist Enable/disable merge whitelist (optional). + * @param bool|null $enablePush Enable/disable push (optional). + * @param bool|null $enablePushWhitelist Enable/disable push whitelist (optional). + * @param bool|null $enableStatusCheck Enable/disable status check (optional). + * @param array|null $mergeWhitelistTeams An array of team names that are allowed to merge (optional). + * @param array|null $mergeWhitelistUsernames An array of usernames that are allowed to merge (optional). + * @param string|null $protectedFilePatterns A string pattern for protected files (optional). + * @param bool|null $pushWhitelistDeployKeys Enable/disable push whitelist for deploy keys (optional). + * @param array|null $pushWhitelistTeams An array of team names that are allowed to push (optional). + * @param array|null $pushWhitelistUsernames An array of usernames that are allowed to push (optional). + * @param bool|null $requireSignedCommits Require signed commits (optional). + * @param int|null $requiredApprovals Number of required approvals (optional). + * @param array|null $statusCheckContexts An array of status check contexts (optional). + * @param string|null $unprotectedFilePatterns A string pattern for unprotected files (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + string $owner, + string $repo, + string $name, + ?array $approvalsWhitelistTeams = null, + ?array $approvalsWhitelistUsernames = null, + ?bool $blockOnOfficialReviewRequests = null, + ?bool $blockOnOutdatedBranch = null, + ?bool $blockOnRejectedReviews = null, + ?bool $dismissStaleApprovals = null, + ?bool $enableApprovalsWhitelist = null, + ?bool $enableMergeWhitelist = null, + ?bool $enablePush = null, + ?bool $enablePushWhitelist = null, + ?bool $enableStatusCheck = null, + ?array $mergeWhitelistTeams = null, + ?array $mergeWhitelistUsernames = null, + ?string $protectedFilePatterns = null, + ?bool $pushWhitelistDeployKeys = null, + ?array $pushWhitelistTeams = null, + ?array $pushWhitelistUsernames = null, + ?bool $requireSignedCommits = null, + ?int $requiredApprovals = null, + ?array $statusCheckContexts = null, + ?string $unprotectedFilePatterns = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/branch_protections/{$name}"; + + // Set the branch protection data. + $data = new \stdClass(); + + if ($approvalsWhitelistTeams !== null) + { + $data->approvals_whitelist_teams = $approvalsWhitelistTeams; + } + + if ($approvalsWhitelistUsernames !== null) + { + $data->approvals_whitelist_usernames = $approvalsWhitelistUsernames; + } + + if ($blockOnOfficialReviewRequests !== null) + { + $data->block_on_official_review_requests = $blockOnOfficialReviewRequests; + } + + if ($blockOnOutdatedBranch !== null) + { + $data->block_on_outdated_branch = $blockOnOutdatedBranch; + } + + if ($blockOnRejectedReviews !== null) + { + $data->block_on_rejected_reviews = $blockOnRejectedReviews; + } + + if ($dismissStaleApprovals !== null) + { + $data->dismiss_stale_approvals = $dismissStaleApprovals; + } + + if ($enableApprovalsWhitelist !== null) + { + $data->enable_approvals_whitelist = $enableApprovalsWhitelist; + } + + if ($enableMergeWhitelist !== null) + { + $data->enable_merge_whitelist = $enableMergeWhitelist; + } + + if ($enablePush !== null) + { + $data->enable_push = $enablePush; + } + + if ($enablePushWhitelist !== null) + { + $data->enable_push_whitelist = $enablePushWhitelist; + } + + if ($enableStatusCheck !== null) + { + $data->enable_status_check = $enableStatusCheck; + } + + if ($mergeWhitelistTeams !== null) + { + $data->merge_whitelist_teams = $mergeWhitelistTeams; + } + + if ($mergeWhitelistUsernames !== null) + { + $data->merge_whitelist_usernames = $mergeWhitelistUsernames; + } + + if ($protectedFilePatterns !== null) + { + $data->protected_file_patterns = $protectedFilePatterns; + } + + if ($pushWhitelistDeployKeys !== null) + { + $data->push_whitelist_deploy_keys = $pushWhitelistDeployKeys; + } + + if ($pushWhitelistTeams !== null) + { + $data->push_whitelist_teams = $pushWhitelistTeams; + } + + if ($pushWhitelistUsernames !== null) + { + $data->push_whitelist_usernames = $pushWhitelistUsernames; + } + + if ($requireSignedCommits !== null) + { + $data->require_signed_commits = $requireSignedCommits; + } + + if ($requiredApprovals !== null) + { + $data->required_approvals = $requiredApprovals; + } + + if ($statusCheckContexts !== null) + { + $data->status_check_contexts = $statusCheckContexts; + } + + if ($unprotectedFilePatterns !== null) + { + $data->unprotected_file_patterns = $unprotectedFilePatterns; + } + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Branch/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Branch/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Branch/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Collaborator.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Collaborator.php new file mode 100644 index 000000000..38ee5127f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Collaborator.php @@ -0,0 +1,175 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Collaborator + * + * @since 3.2.0 + */ +class Collaborator extends Api +{ + /** + * List a repository's collaborators. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(string $owner, string $repo, int $page = 1, int $limit = 10): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/collaborators"; + + // Get the URI object for the path. + $uri = $this->uri->get($path); + + // Set the page and limit variables. + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Check if a user is a collaborator of a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $collaborator The collaborator username. + * + * @return string + * @since 3.2.0 + **/ + public function check( + string $owner, + string $repo, + string $collaborator + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/collaborators/{$collaborator}"; + + // Get the URI object for the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri), 204, 'success' + ); + } + + /** + * Add a collaborator to a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $collaborator The collaborator username. + * @param string $permission The permission level for the collaborator (optional). + * + * @return string + * @since 3.2.0 + **/ + public function add( + string $owner, + string $repo, + string $collaborator, + string $permission = null + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/collaborators/{$collaborator}"; + + // Get the URI object for the path. + $uri = $this->uri->get($path); + + // Prepare the request body. + $body = new stdClass(); + if ($permission !== null) { + $body->permission = $permission; + } + $bodyJson = json_encode($body); + + // Send the put request. + return $this->response->get( + $this->http->put($uri, $bodyJson), 204, 'success' + ); + } + + /** + * Delete a collaborator from a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $collaborator The collaborator username. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $owner, + string $repo, + string $collaborator + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/collaborators/{$collaborator}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Get repository permissions for a user. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $collaborator The collaborator username. + * + * @return object|null + * @since 3.2.0 + **/ + public function permission( + string $owner, + string $repo, + string $collaborator + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/collaborators/{$collaborator}/permission"; + + // Get the URI object for the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Commits.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Commits.php new file mode 100644 index 000000000..d8142c230 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Commits.php @@ -0,0 +1,225 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Commit + * + * @since 3.2.0 + */ +class Commits extends Api +{ + /** + * Get a list of all commits from a repository. + * + * @param string $owner The owner of the repo. + * @param string $repo The name of the repo. + * @param string|null $sha SHA or branch to start listing commits from (usually 'master'). + * @param string|null $path Filepath of a file/dir. + * @param bool|null $stat Include diff stats for every commit (disable for speedup, default 'true'). + * @param int|null $page Page number of results to return (1-based). + * @param int|null $limit Page size of results (ignored if used with 'path'). + * + * @return array|null + * @since 3.2.0 + */ + public function getList( + string $owner, + string $repo, + ?string $sha = null, + ?string $path = null, + ?bool $stat = true, + ?int $page = 1, + ?int $limit = 10 + ): ?object + { + // Build the request path. + $uriPath = "/repos/{$owner}/{$repo}/commits"; + + // Set query parameters. + $uri = $this->uri->get($uriPath); + + if ($sha !== null) + { + $uri->setVar('sha', $sha); + } + + if ($path !== null) + { + $uri->setVar('path', $path); + } + + if ($stat !== null) + { + $uri->setVar('stat', $stat ? 'true' : 'false'); + } + + if ($page !== null) + { + $uri->setVar('page', $page); + } + + if ($limit !== null) + { + $uri->setVar('limit', $limit); + } + + // Send the GET request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get a single commit from a repository. + * + * @param string $owner The owner of the repo. + * @param string $repo The name of the repo. + * @param string $sha A git ref or commit sha. + * + * @return object|null + * @since 3.2.0 + */ + public function getCommit(string $owner, string $repo, string $sha): ?object + { + // Build the request path. + $uriPath = "/repos/{$owner}/{$repo}/git/commits/{$sha}"; + + // Send the GET request. + return $this->response->get( + $this->http->get( + $this->uri->get($uriPath) + ) + ); + } + + /** + * Get a commit's combined status, by branch/tag/commit reference. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $ref The branch, tag, or commit reference. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return object|null + * @since 3.2.0 + **/ + public function status( + string $owner, + string $repo, + string $ref, + int $page = 1, + int $limit = 10 + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/commits/{$ref}/status"; + + // Set up the URI with the required parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get a commit's statuses, by branch/tag/commit reference. + * + * @param string $owner The owner of the repository. + * @param string $repo The name of the repository. + * @param string $ref The branch, tag, or commit reference. + * @param string $sort The type of sort. Available values: oldest, recentupdate, leastupdate, leastindex, highestindex. + * @param string $state The type of state. Available values: pending, success, error, failure, warning. + * @param int $page The page number of results to return (1-based). Default value: 1. + * @param int $limit The page size of results. Default value: 10. + * + * @return array|null + * @since 3.2.0 + */ + public function statuses( + string $owner, + string $repo, + string $ref, + string $sort = null, + string $state = null, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/commits/{$ref}/statuses"; + + // Add query parameters to the URI. + $uri = $this->uri->get($path); + + if ($sort !== null) + { + $uri->setVar('sort', $sort); + } + + if ($state !== null) + { + $uri->setVar('state', $state); + } + + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the GET request. + $response = $this->http->get($uri); + return $this->response->get($response); + } + + /** + * Get a commit's diff or patch. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $sha The SHA hash of the commit. + * @param string $diffType The diff type, either 'diff' or 'patch'. + * + * @return string + * @since 3.2.0 + **/ + public function diff( + string $owner, + string $repo, + string $sha, + string $diffType + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/git/commits/{$sha}"; + + // Set the diffType as a variable in the URI. + $this->uri->setVar('diffType', $diffType); + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Contents.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Contents.php new file mode 100644 index 000000000..982403c9b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Contents.php @@ -0,0 +1,509 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Contents + * + * @since 3.2.0 + */ +class Contents extends Api +{ + /** + * Get a file from a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $filepath The file path. + * @param string|null $ref Optional. The name of the commit/branch/tag. + * Default the repository's default branch (usually master). + * + * @return mixed + * @since 3.2.0 + **/ + public function get(string $owner, string $repo, string $filepath, ?string $ref = null) + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/raw/{$filepath}"; + + // Get the URI with the specified path. + $uri = $this->uri->get($path); + + // Add the ref parameter if provided. + if ($ref !== null) + { + $uri->setVar('ref', $ref); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get the metadata and contents (if a file) of an entry in a repository, + * or a list of entries if a directory. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $filepath The file or directory path. + * @param string|null $ref Optional. The name of the commit/branch/tag. + * Default the repository's default branch (usually master). + * + * @return object|null + * @since 3.2.0 + **/ + public function metadata(string $owner, string $repo, string $filepath, ?string $ref = null): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/contents/{$filepath}"; + + // Get the URI with the specified path. + $uri = $this->uri->get($path); + + // Add the ref parameter if provided. + if ($ref !== null) + { + $uri->setVar('ref', $ref); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a file in a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $filepath The file path. + * @param string $content The file content. + * @param string $message The commit message. + * @param string $branch The branch name. Defaults to the repository's default branch. + * @param string|null $authorName The author's name. + * @param string|null $authorEmail The author's email. + * @param string|null $committerName The committer's name. + * @param string|null $committerEmail The committer's email. + * @param bool|null $newBranch Whether to create a new branch. Defaults to false. + * @param string|null $authorDate The author's date. + * @param string|null $committerDate The committer's date. + * @param bool|null $signoff Add a Signed-off-by trailer. Defaults to null. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $owner, + string $repo, + string $filepath, + string $content, + string $message, + string $branch = 'master', + ?string $authorName = null, + ?string $authorEmail = null, + ?string $committerName = null, + ?string $committerEmail = null, + ?bool $newBranch = false, + ?string $authorDate = null, + ?string $committerDate = null, + ?bool $signoff = null + ): ?object { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/contents/{$filepath}"; + + // Set the post data + $data = new \stdClass(); + $data->content = base64_encode($content); + $data->message = $message; + $data->branch = $branch; + + if ($authorName !== null || $authorEmail !== null) + { + $data->author = new \stdClass(); + if ($authorName !== null) + { + $data->author->name = $authorName; + } + if ($authorEmail !== null) + { + $data->author->email = $authorEmail; + } + } + + if ($committerName !== null || $committerEmail !== null) + { + $data->committer = new \stdClass(); + if ($committerName !== null) + { + $data->committer->name = $committerName; + } + if ($committerEmail !== null) + { + $data->committer->email = $committerEmail; + } + } + + if ($newBranch !== null) + { + $data->new_branch = $newBranch; + } + + if ($authorDate !== null || $committerDate !== null) + { + $data->dates = new \stdClass(); + if ($authorDate !== null) + { + $data->dates->author = $authorDate; + } + if ($committerDate !== null) + { + $data->dates->committer = $committerDate; + } + } + + if ($signoff !== null) + { + $data->signoff = $signoff; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Get the metadata of all the entries of the root directory. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string|null $ref The name of the commit/branch/tag. Default the repository's default branch (usually master). + * + * @return array|null + * @since 3.2.0 + **/ + public function root(string $owner, string $repo, ?string $ref = null): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/contents"; + + // Add the 'ref' parameter if it's provided. + if ($ref !== null) + { + $this->uri->setVar('ref', $ref); + } + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Update a file in a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $filepath The file path. + * @param string $content The file content. + * @param string $message The commit message. + * @param string $branch The branch name. Defaults to the repository's default branch. + * @param string $sha The blob SHA of the file. + * @param string|null $authorName The author name. Defaults to the authenticated user. + * @param string|null $authorEmail The author email. Defaults to the authenticated user. + * @param string|null $committerName The committer name. Defaults to the authenticated user. + * @param string|null $committerEmail The committer email. Defaults to the authenticated user. + * @param string|null $authorDate The author date. + * @param string|null $committerDate The committer date. + * @param string|null $fromPath The original file path to move/rename. + * @param string|null $newBranch The new branch to create from the specified branch. + * @param bool|null $signoff Add a Signed-off-by trailer. + * + * @return object|null + * @since 3.2.0 + **/ + public function update( + string $owner, + string $repo, + string $filepath, + string $content, + string $message, + string $branch = 'master', + string $sha, + ?string $authorName = null, + ?string $authorEmail = null, + ?string $committerName = null, + ?string $committerEmail = null, + ?string $authorDate = null, + ?string $committerDate = null, + ?string $fromPath = null, + ?string $newBranch = null, + ?bool $signoff = null + ): ?object { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/contents/{$filepath}"; + + // Set the file data. + $data = new \stdClass(); + $data->content = base64_encode($content); + $data->message = $message; + $data->branch = $branch; + $data->sha = $sha; + + if ($authorName !== null || $authorEmail !== null) + { + $data->author = new \stdClass(); + + if ($authorName !== null) + { + $data->author->name = $authorName; + } + + if ($authorEmail !== null) + { + $data->author->email = $authorEmail; + } + } + + if ($committerName !== null || $committerEmail !== null) + { + $data->committer = new \stdClass(); + + if ($committerName !== null) + { + $data->committer->name = $committerName; + } + + if ($committerEmail !== null) + { + $data->committer->email = $committerEmail; + } + } + + if ($authorDate !== null || $committerDate !== null) + { + $data->dates = new \stdClass(); + + if ($authorDate !== null) + { + $data->dates->author = $authorDate; + } + + if ($committerDate !== null) + { + $data->dates->committer = $committerDate; + } + } + + if ($fromPath !== null) + { + $data->from_path = $fromPath; + } + + if ($newBranch !== null) + { + $data->new_branch = $newBranch; + } + + if ($signoff !== null) + { + $data->signoff = $signoff; + } + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), + json_encode($data) + ) + ); + } + + /** + * Delete a file in a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $filepath The file path. + * @param string $message The commit message. + * @param string $branch The branch name (optional). + * @param string $sha The blob SHA of the file. + * @param string $authorName The author name (optional). + * @param string $authorEmail The author email (optional). + * @param string $committerName The committer name (optional). + * @param string $committerEmail The committer email (optional). + * @param string $authorDate The author date (optional). + * @param string $committerDate The committer date (optional). + * @param string $newBranch The new branch name (optional). + * @param bool $signoff Add a Signed-off-by trailer (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function delete( + string $owner, + string $repo, + string $filepath, + string $message, + string $sha, + ?string $branch = null, + ?string $authorName = null, + ?string $authorEmail = null, + ?string $committerName = null, + ?string $committerEmail = null, + ?string $authorDate = null, + ?string $committerDate = null, + ?string $newBranch = null, + ?bool $signoff = null + ): ?object { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/contents/{$filepath}"; + + // Set the file data. + $data = new \stdClass(); + $data->message = $message; + $data->sha = $sha; + + if ($branch !== null) { + $data->branch = $branch; + } + + if ($authorName !== null || $authorEmail !== null) + { + $data->author = new \stdClass(); + + if ($authorName !== null) + { + $data->author->name = $authorName; + } + + if ($authorEmail !== null) + { + $data->author->email = $authorEmail; + } + } + + if ($committerName !== null || $committerEmail !== null) + { + $data->committer = new \stdClass(); + + if ($committerName !== null) + { + $data->committer->name = $committerName; + } + + if ($committerEmail !== null) + { + $data->committer->email = $committerEmail; + } + } + + if ($authorDate !== null || $committerDate !== null) + { + $data->dates = new \stdClass(); + + if ($authorDate !== null) + { + $data->dates->author = $authorDate; + } + + if ($committerDate !== null) + { + $data->dates->committer = $committerDate; + } + } + + if ($newBranch !== null) + { + $data->new_branch = $newBranch; + } + + if ($signoff !== null) + { + $data->signoff = $signoff; + } + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path), + json_encode($data) + ) + ); + } + + /** + * Get the EditorConfig definitions of a file in a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $filepath The file path. + * @param string $ref The name of the commit/branch/tag. + * + * @return string|null + * @since 3.2.0 + **/ + public function editor(string $owner, string $repo, string $filepath, string $ref = null): ?string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/editorconfig/{$filepath}"; + + // Set the request parameters. + $uri = $this->uri->get($path); + + if ($ref !== null) + { + $uri->setVar('ref', $ref); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get the blob of a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $sha The SHA hash of the blob. + * + * @return object|null + * @since 3.2.0 + **/ + public function blob(string $owner, string $repo, string $sha): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/git/blobs/{$sha}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Forks.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Forks.php new file mode 100644 index 000000000..224e286a3 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Forks.php @@ -0,0 +1,102 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Forks + * + * @since 3.2.0 + */ +class Forks extends Api +{ + /** + * List a repository's forks. + * + * @param string $owner The owner of the repo. + * @param string $repo The name of the repo. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + */ + public function listForks( + string $owner, + string $repo, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $uriPath = "/repos/{$owner}/{$repo}/forks"; + + // Set the query parameters. + $uri = $this->uri->get($uriPath); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Fork a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $forkName The name of the forked repository (optional). + * @param string $organization The organization name (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function repo( + string $owner, + string $repo, + string $forkName = '', + string $organization = '' + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/forks"; + + // Set the fork data. + $data = new \stdClass(); + + if (!empty($forkName)) + { + $data->name = $forkName; + } + + if (!empty($organization)) + { + $data->organization = $organization; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 202 + ); + } + + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Gpg.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Gpg.php new file mode 100644 index 000000000..0a6c317d4 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Gpg.php @@ -0,0 +1,48 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Gpg + * + * @since 3.2.0 + */ +class Gpg extends Api +{ + /** + * Get signing-key.gpg for a given repository. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * + * @return string + * @since 3.2.0 + **/ + public function get(string $ownerName, string $repoName): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/signing-key.gpg"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Hooks.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Hooks.php new file mode 100644 index 000000000..eadb2e61d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Hooks.php @@ -0,0 +1,214 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Hooks + * + * @since 3.2.0 + */ +class Hooks extends Api +{ + /** + * List the hooks in a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $owner, + string $repo, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/hooks"; + + // Set up the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a hook in a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $type The hook type. + * @param array $config The hook configuration. + * @param bool $active The hook's active status (optional, default: false). + * @param array|null $events The events for the hook (optional). + * @param string $branchFilter The branch filter (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $owner, + string $repo, + string $type, + array $config, + string $type, + array $config, + bool $active = false, + ?array $events = null, + string $branchFilter = '' + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/hooks"; + + // Set the hook data. + $data = new \stdClass(); + $data->type = $type; + $data->config = (object) $config; + $data->active = $active; + + if ($events !== null) + { + $data->events = $events; + } + + if (!empty($branchFilter)) + { + $data->branch_filter = $branchFilter; + } + + // Send the request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Get a hook. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $hookId The hook ID. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + int $hookId + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/hooks/{$hookId}"; + + // Get the URI for the request path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Edit a hook in a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $id The hook ID. + * @param array $config The hook configuration. + * @param array $events The events to trigger the hook. + * @param bool $active Whether the hook is active. + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + string $owner, + string $repo, + int $id, + array $config, + array $events, + bool $active + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/hooks/{$id}"; + + // Set the hook data. + $data = new \stdClass(); + $data->config = $config; + $data->events = $events; + $data->active = $active; + + // Send the PATCH request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), + json_encode($data) + ) + ); + } + + /** + * Test a push webhook. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $hookId The hook ID. + * @param string $ref The name of the commit/branch/tag (optional). + * + * @return string + * @since 3.2.0 + **/ + public function test( + string $owner, + string $repo, + int $hookId, + string $ref = '' + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/hooks/{$hookId}/tests"; + + // Get the URI for the request path. + $uri = $this->uri->get($path); + + if (!empty($ref)) + { + $uri->setVar('ref', $ref); + } + + // Send the POST request. + return $this->response->get( + $this->http->post($uri), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Hooks/Git.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Hooks/Git.php new file mode 100644 index 000000000..0b0a84922 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Hooks/Git.php @@ -0,0 +1,137 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository\Hooks; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Hooks Git + * + * @since 3.2.0 + */ +class Git extends Api +{ + /** + * List the Git hooks in a repository. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(string $ownerName, string $repoName): ?array + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/hooks/git"; + + // Get the URI object with the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get a Git hook. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param int $hookId The Git hook ID. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $ownerName, + string $repoName, + int $hookId + ): ?object + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/hooks/git/{$hookId}"; + + // Get the URI object with the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Delete a Git hook in a repository. + * + * @param string $ownerName The owner name. + * @param string $repositoryName The repository name. + * @param string $hookId The Git hook ID. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $ownerName, + string $repositoryName, + string $hookId + ): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repositoryName}/hooks/git/{$hookId}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Edit a Git hook in a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $hookId The Git hook ID. + * @param array $hookOptions The hook configuration. + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + string $owner, + string $repo, + string $hookId, + array $hookOptions + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/hooks/git/{$hookId}"; + + // Set the hook data. + $data = new \stdClass(); + $data->config = (object) $hookOptions; + + // Send the PATCH request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Hooks/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Hooks/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Hooks/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Keys.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Keys.php new file mode 100644 index 000000000..5e7757fd6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Keys.php @@ -0,0 +1,159 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Keys + * + * @since 3.2.0 + */ +class Keys extends Api +{ + /** + * List a repository's keys. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int|null $keyId The key_id to search for. (Optional) + * @param string|null $fingerprint The fingerprint of the key. (Optional) + * @param int $page The page number of results to return. (Default: 1) + * @param int $limit The page size of results. (Default: 10) + * + * @return array|null + * @since 3.2.0 + */ + public function list(string $owner, string $repo, ?int $keyId = null, ?string $fingerprint = null, int $page = 1, int $limit = 10): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/keys"; + + // Prepare the URI. + $uri = $this->uri->get($path); + + // Add the optional query parameters. + if ($keyId !== null) + { + $uri->setVar('key_id', $keyId); + } + + if ($fingerprint !== null) + { + $uri->setVar('fingerprint', $fingerprint); + } + + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the GET request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Add a key to a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $key The public key. + * @param string $title The title of the key. + * @param bool $readOnly Whether the key is read-only. + * + * @return object|null + * @since 3.2.0 + **/ + public function add( + string $owner, + string $repo, + string $key, + string $title, + bool $readOnly + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/keys"; + + // Set the key data. + $data = new \stdClass(); + $data->key = $key; + $data->title = $title; + $data->read_only = $readOnly; + + // Send the POST request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * Get a repository's key by id. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $id The key ID. + * + * @return object|null + * @since 3.2.0 + */ + public function id( + string $owner, + string $repo, + int $id + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/keys/{$id}"; + + // Send the GET request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a key from a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $id The key ID. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $owner, + string $repo, + int $id + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/keys/{$id}"; + + // Send the DELETE request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Languages.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Languages.php new file mode 100644 index 000000000..e4f4f0e21 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Languages.php @@ -0,0 +1,49 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Languages + * + * @since 3.2.0 + */ +class Languages extends Api +{ + /** + * Get languages and number of bytes of code written in a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return object|null + * @since 3.2.0 + **/ + public function getLanguages(string $owner, string $repo): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/languages"; + + // Build the URI. + $uri = $this->uri->get($path); + + // Send the GET request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Media.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Media.php new file mode 100644 index 000000000..74ea839e0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Media.php @@ -0,0 +1,63 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Media + * + * @since 3.2.0 + */ +class Media extends Api +{ + /** + * Get a file or its LFS object from a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $filepath The file path. + * @param string|null $ref The name of the commit/branch/tag. (Optional) + * + * @return string + * @since 3.2.0 + */ + public function get( + string $owner, + string $repo, + string $filepath, + ?string $ref = null + ): string + { + // Build the request path. + $encodedFilepath = rawurlencode($filepath); + $path = "/repos/{$owner}/{$repo}/media/{$encodedFilepath}"; + + // Prepare the URI. + $uri = $this->uri->get($path); + + // Add the 'ref' query parameter if provided. + if ($ref !== null) + { + $uri->setVar('ref', $ref); + } + + // Send the GET request. + return $this->response->get( + $this->http->get($uri), 200, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Merge.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Merge.php new file mode 100644 index 000000000..2b2cd2d1c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Merge.php @@ -0,0 +1,167 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Merge + * + * @since 3.2.0 + */ +class Merge extends Api +{ + /** + * Check if a pull request has been merged. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * + * @return string + * @since 3.2.0 + **/ + public function check( + string $owner, + string $repo, + int $index + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/merge"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Merge a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param string|null $mergeMethod Merge method to use (optional). + * @param string|null $mergeCommitId Merge commit ID (optional). + * @param string|null $mergeMessageField Merge message field (optional). + * @param string|null $mergeTitleField Merge title field (optional). + * @param bool|null $deleteBranchAfterMerge Delete branch after merge (optional). + * @param bool|null $forceMerge Force merge (optional). + * @param string|null $headCommitId Head commit ID (optional). + * @param bool|null $mergeWhenChecksSucceed Merge when checks succeed (optional). + * + * @return string + * @since 3.2.0 + **/ + public function pull( + string $owner, + string $repo, + int $index, + ?string $mergeMethod = null, + ?string $mergeCommitId = null, + ?string $mergeMessageField = null, + ?string $mergeTitleField = null, + ?bool $deleteBranchAfterMerge = null, + ?bool $forceMerge = null, + ?string $headCommitId = null, + ?bool $mergeWhenChecksSucceed = null + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/merge"; + + // Set the merge data. + $data = new \stdClass(); + + if ($mergeMethod !== null) + { + $data->do = $mergeMethod; + } + + if ($mergeCommitId !== null) + { + $data->merge_commit_id = $mergeCommitId; + } + + if ($mergeMessageField !== null) + { + $data->merge_message_field = $mergeMessageField; + } + + if ($mergeTitleField !== null) + { + $data->merge_title_field = $mergeTitleField; + } + + if ($deleteBranchAfterMerge !== null) + { + $data->delete_branch_after_merge = $deleteBranchAfterMerge; + } + + if ($forceMerge !== null) + { + $data->force_merge = $forceMerge; + } + + if ($headCommitId !== null) + { + $data->head_commit_id = $headCommitId; + } + + if ($mergeWhenChecksSucceed !== null) + { + $data->merge_when_checks_succeed = $mergeWhenChecksSucceed; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 200, 'success' + ); + } + + /** + * Cancel the scheduled auto merge for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * + * @return string + * @since 3.2.0 + **/ + public function cancel( + string $owner, + string $repo, + int $index + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/merge"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Send the delete request. + return $this->response->get( + $this->http->delete($uri), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Mirror.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Mirror.php new file mode 100644 index 000000000..37e3b578e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Mirror.php @@ -0,0 +1,48 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Mirror + * + * @since 3.2.0 + */ +class Mirror extends Api +{ + /** + * Sync a mirrored repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return string + * @since 3.2.0 + */ + public function sync(string $owner, string $repo): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/mirror-sync"; + + // Send the POST request. + return $this->response->get( + $this->http->post( + $this->uri->get($path) + ), 200, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Mirrors.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Mirrors.php new file mode 100644 index 000000000..2dd60edce --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Mirrors.php @@ -0,0 +1,190 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Mirrors + * + * @since 3.2.0 + */ +class Mirrors extends Api +{ + /** + * Get all push mirrors of the repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + */ + public function get( + string $owner, + string $repo, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/push_mirrors"; + + // Set query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Add a push mirror to the repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $remoteAddress The push mirror address. + * @param string|null $remoteUsername The push mirror user. (Optional) + * @param string|null $remotePassword The push mirror password. (Optional) + * @param string $interval The interval for the push mirror. + * @param bool $syncOnCommit Sync on commit option. + * + * @return object|null + * @since 3.2.0 + */ + public function add( + string $owner, + string $repo, + string $remoteAddress, + ?string $remoteUsername = null, + ?string $remotePassword = null, + string $interval, + bool $syncOnCommit + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/push_mirrors"; + + // Set the mirror data. + $data = new \stdClass(); + $data->remote_address = $remoteAddress; + $data->interval = $interval; + $data->sync_on_commit = $syncOnCommit; + + if ($remoteUsername !== null) + { + $data->remote_username = $remoteUsername; + } + + if ($remotePassword !== null) + { + $data->remote_password = $remotePassword; + } + + // Send the request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Sync all push mirrored repositories. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return string + * @since 3.2.0 + */ + public function sync( + string $owner, + string $repo + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/push_mirrors-sync"; + + // Send the request. + return $this->response->get( + $this->http->post( + $this->uri->get($path) + ), 200, 'success' + ); + } + + /** + * Get push mirror of the repository by remoteName. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $name The remote name. + * + * @return object|null + * @since 3.2.0 + */ + public function name( + string $owner, + string $repo, + string $name + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/push_mirrors/{$name}"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Send the request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Delete a push mirror from a repository by remoteName. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $name The remote name. + * + * @return string + * @since 3.2.0 + */ + public function delete( + string $owner, + string $repo, + string $name + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/push_mirrors/{$name}"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Send the request. + return $this->response->get( + $this->http->delete($uri), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Notes.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Notes.php new file mode 100644 index 000000000..823d61344 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Notes.php @@ -0,0 +1,53 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Notes + * + * @since 3.2.0 + */ +class Notes extends Api +{ + /** + * Get a note corresponding to a single commit from a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $commitSha The SHA hash of the commit. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + string $commitSha + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/git/notes/{$commitSha}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Patch.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Patch.php new file mode 100644 index 000000000..d7d80076b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Patch.php @@ -0,0 +1,78 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Patch + * + * @since 3.2.0 + */ +class Patch extends Api +{ + /** + * Apply a diff patch to a repository. + * + * @param string $owner The owner of the repo. + * @param string $repo The name of the repo. + * @param array $options Options for updating files. + * $options = [ + * 'description' => 'UpdateFileOptions', + * 'body' => [ + * 'content' => 'string', // Content must be base64 encoded. + * 'sha' => 'string', // The SHA for the file that already exists. + * 'branch' => 'string', // Branch (optional) to base this file from. If not given, the default branch is used. + * 'new_branch' => 'string', // New branch (optional) will make a new branch from branch before creating the file. + * 'from_path' => 'string', // From_path (optional) is the path of the original file which will be moved/renamed to the path in the URL. + * 'message' => 'string', // Message (optional) for the commit of this file. If not supplied, a default message will be used. + * 'author' => [ // Identity for a person's identity like an author or committer. + * 'name' => 'string', + * 'email' => 'string($email)' + * ], + * 'committer' => [ // Identity for a person's identity like an author or committer. + * 'name' => 'string', + * 'email' => 'string($email)' + * ], + * 'dates' => [ // Store dates for GIT_AUTHOR_DATE and GIT_COMMITTER_DATE. + * 'author' => 'string($date-time)', + * 'committer' => 'string($date-time)' + * ], + * 'signoff' => 'boolean' // Add a Signed-off-by trailer by the committer at the end of the commit log message. + * ] + * ] + * + * @return object|null + * @since 3.2.0 + */ + public function applyDiffPatch( + string $owner, + string $repo, + array $option + ): ?object + { + // Build the request path. + $uriPath = "/repos/{$owner}/{$repo}/diffpatch"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($uriPath), + json_encode($options) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Pulls.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Pulls.php new file mode 100644 index 000000000..a979e797e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Pulls.php @@ -0,0 +1,547 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Pulls + * + * @since 3.2.0 + */ +class Pulls extends Api +{ + /** + * List a repository's pull requests. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string|null $state State of pull request: open, closed, or all (optional). + * @param string|null $sort Type of sort (optional). + * @param int|null $milestone ID of the milestone (optional). + * @param array|null $labels Label IDs (optional). + * @param int $page Page number of results to return (1-based, default: 1). + * @param int $limit Page size of results (default: 10). + * + * @return array|null + * @since 3.2.0 + */ + public function list( + string $owner, + string $repo, + ?string $state = null, + ?string $sort = null, + ?int $milestone = null, + ?array $labels = null, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls"; + + // Set query parameters. + $this->uri->setVar('page', $page); + $this->uri->setVar('limit', $limit); + + if ($state !== null) + { + $this->uri->setVar('state', $state); + } + + if ($sort !== null) + { + $this->uri->setVar('sort', $sort); + } + + if ($milestone !== null) + { + $this->uri->setVar('milestone', $milestone); + } + + if ($labels !== null) + { + $this->uri->setVar('labels', implode(',', $labels)); + } + + // Send the GET request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Create a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $title The title of the pull request. + * @param string $head The head branch. + * @param string $base The base branch. + * @param string|null $body The description of the pull request (optional). + * @param string|null $assignee The assignee of the pull request (optional). + * @param array|null $assignees Additional assignees (optional). + * @param array|null $labels Label IDs (optional). + * @param int|null $milestone ID of the milestone (optional). + * @param string|null $dueDate Due date of the pull request (optional). + * + * @return object|null + * @since 3.2.0 + */ + public function create( + string $owner, + string $repo, + string $title, + string $head, + string $base, + ?string $body = null, + ?string $assignee = null, + ?array $assignees = null, + ?array $labels = null, + ?int $milestone = null, + ?string $dueDate = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls"; + + // Set the pull request data. + $data = new \stdClass(); + $data->title = $title; + $data->head = $head; + $data->base = $base; + + if ($body !== null) + { + $data->body = $body; + } + + if ($assignee !== null) + { + $data->assignee = $assignee; + } + + if ($assignees !== null) + { + $data->assignees = $assignees; + } + + if ($labels !== null) + { + $data->labels = $labels; + } + + if ($milestone !== null) + { + $data->milestone = $milestone; + } + + if ($dueDate !== null) + { + $data->due_date = $dueDate; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Get a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo, int $index): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Update a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param string|null $title The title of the pull request (optional). + * @param string|null $body The description of the pull request (optional). + * @param string|null $assignee The assignee of the pull request (optional). + * @param array|null $assignees Additional assignees (optional). + * @param string|null $base The base branch (optional). + * @param string|null $state The state of the pull request (optional). + * @param array|null $labels Label IDs (optional). + * @param int|null $milestone ID of the milestone (optional). + * @param string|null $dueDate Due date of the pull request (optional). + * @param bool|null $unsetDueDate Whether to unset the due date (optional). + * @param bool|null $allowMaintainerEdit Allow maintainer to edit the pull request (optional). + * + * @return object|null + * @since 3.2.0 + */ + public function update( + string $owner, + string $repo, + int $index, + ?string $title = null, + ?string $body = null, + ?string $assignee = null, + ?array $assignees = null, + ?string $base = null, + ?string $state = null, + ?array $labels = null, + ?int $milestone = null, + ?string $dueDate = null, + ?bool $unsetDueDate = null, + ?bool $allowMaintainerEdit = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}"; + + // Set the pull request data. + $data = new \stdClass(); + + if ($title !== null) + { + $data->title = $title; + } + + if ($body !== null) + { + $data->body = $body; + } + + if ($assignee !== null) + { + $data->assignee = $assignee; + } + + if ($assignees !== null) + { + $data->assignees = $assignees; + } + + if ($base !== null) + { + $data->base = $base; + } + + if ($state !== null) + { + $data->state = $state; + } + + if ($labels !== null) + { + $data->labels = $labels; + } + + if ($milestone !== null) + { + $data->milestone = $milestone; + } + + if ($dueDate !== null) + { + $data->due_date = $dueDate; + } + + if ($unsetDueDate !== null) + { + $data->unset_due_date = $unsetDueDate; + } + + if ($allowMaintainerEdit !== null) + { + $data->allow_maintainer_edit = $allowMaintainerEdit; + } + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Get a pull request diff or patch. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param string $diffType The type of the requested data, either "diff" or "patch". + * @param bool $binary Whether to include binary file changes. If true, the diff is applicable with git apply. + * + * @return string + * @since 3.2.0 + **/ + public function diff( + string $owner, + string $repo, + int $index, + string $diffType, + bool $binary = false + ): string + { + // Validate the diff type. + if (!in_array($diffType, ['diff', 'patch'])) + { + throw new \InvalidArgumentException('Invalid diff type. Allowed types are "diff" and "patch".'); + } + + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}.{$diffType}"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Set the binary query parameter if required. + if ($binary) + { + $uri->setVar('binary', 'true'); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get commits for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function commits( + string $owner, + string $repo, + int $index, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/commits"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Set the page and limit query parameters. + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get changed files for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param string $skipTo Skip to the given file. + * @param string $whitespace Whitespace behavior. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function files( + string $owner, + string $repo, + int $index, + ?string $skipTo = null, + ?string $whitespace = null, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/files"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Set the skip-to, whitespace, page, and limit query parameters if needed. + if ($skipTo !== null) + { + $uri->setVar('skip-to', $skipTo); + } + if ($whitespace !== null) + { + $uri->setVar('whitespace', $whitespace); + } + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Merge a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param string|null $do Merge method. + * @param string|null $mergeCommitId Merge commit ID. + * @param string|null $mergeMessageField Merge message field. + * @param string|null $mergeTitleField Merge title field. + * @param bool|null $deleteBranchAfterMerge Whether to delete the branch after merge. + * @param bool|null $forceMerge Whether to force merge. + * @param string|null $headCommitId Head commit ID. + * @param bool|null $mergeWhenChecksSucceed Whether to merge when checks succeed. + * + * @return string + * @since 3.2.0 + **/ + public function merge( + string $owner, + string $repo, + int $index, + ?string $do = null, + ?string $mergeCommitId = null, + ?string $mergeMessageField = null, + ?string $mergeTitleField = null, + ?bool $deleteBranchAfterMerge = null, + ?bool $forceMerge = null, + ?string $headCommitId = null, + ?bool $mergeWhenChecksSucceed = null + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/merge"; + + // Set the merge data. + $data = new \stdClass(); + + if ($do !== null) + { + $data->do = $do; + } + + if ($mergeCommitId !== null) + { + $data->merge_commit_id = $mergeCommitId; + } + + if ($mergeMessageField !== null) + { + $data->merge_message_field = $mergeMessageField; + } + + if ($mergeTitleField !== null) + { + $data->merge_title_field = $mergeTitleField; + } + + if ($deleteBranchAfterMerge !== null) + { + $data->delete_branch_after_merge = $deleteBranchAfterMerge; + } + + if ($forceMerge !== null) + { + $data->force_merge = $forceMerge; + } + + if ($headCommitId !== null) + { + $data->head_commit_id = $headCommitId; + } + + if ($mergeWhenChecksSucceed !== null) + { + $data->merge_when_checks_succeed = $mergeWhenChecksSucceed; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 200, 'success' + ); + } + + /** + * Merge PR's baseBranch into headBranch. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param string|null $style How to update the pull request. (Optional) + * + * @return string + * @since 3.2.0 + */ + public function update( + string $owner, + string $repo, + int $index, + ?string $style = null + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/update"; + + // Set the merge data. + $data = new \stdClass(); + + if ($style !== null) + { + $data->style = $style; + } + + // Send the request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 200, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Refs.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Refs.php new file mode 100644 index 000000000..6abc59136 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Refs.php @@ -0,0 +1,77 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Refs + * + * @since 3.2.0 + */ +class Refs extends Api +{ + /** + * Get specified ref or filtered repository's refs. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(string $owner, string $repo): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/git/refs"; + + // Build the URI. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get specified ref. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $ref The ref name. + * + * @return array|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + string $ref + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/git/refs/{$ref}"; + + // Build the URI. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Releases.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Releases.php new file mode 100644 index 000000000..5723b5610 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Releases.php @@ -0,0 +1,309 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Releases + * + * @since 3.2.0 + */ +class Releases extends Api +{ + /** + * List a repo's releases. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param bool|null $draft Filter (exclude/include) drafts (optional). + * @param bool|null $preRelease Filter (exclude/include) pre-releases (optional). + * @param int $page Page number of results to return (1-based, optional). + * @param int $limit Page size of results (optional). + * + * @return array|null + * @since 3.2.0 + */ + public function list( + string $ownerName, + string $repoName, + ?bool $draft = null, + ?bool $preRelease = null, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/releases"; + + // Set additional URI values. + $this->uri->setVar('page', $page); + $this->uri->setVar('limit', $limit); + + if ($draft !== null) + { + $this->uri->setVar('draft', $draft); + } + + if ($preRelease !== null) + { + $this->uri->setVar('pre-release', $preRelease); + } + + // Send the request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Create a release. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $tagName The tag name. + * @param string $targetCommitish The commitish value that determines where the Git tag is created from. + * @param string $releaseName The name of the release. + * @param string $releaseBody The description of the release. + * @param bool $isDraft Whether the release is a draft. + * @param bool $isPrerelease Whether the release is a pre-release. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $ownerName, + string $repoName, + string $tagName, + string $targetCommitish, + string $releaseName, + string $releaseBody, + bool $isDraft = false, + bool $isPrerelease = false + ): ?object + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/releases"; + + // Set the release data + $data = new \stdClass(); + $data->tag_name = $tagName; + $data->target_commitish = $targetCommitish; + $data->name = $releaseName; + $data->body = $releaseBody; + $data->draft = $isDraft; + $data->prerelease = $isPrerelease; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Get a release by ID. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param int $releaseId The release ID. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $ownerName, + string $repoName, + int $releaseId + ): ?object + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/releases/{$releaseId}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a release by ID. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param int $releaseId The release ID. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $ownerName, + string $repoName, + int $releaseId + ): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/releases/{$releaseId}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Update a release. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param int $releaseId The release ID. + * @param string|null $tagName The tag name (optional). + * @param string|null $targetCommitish The commitish value that determines where the Git tag is created from (optional). + * @param string|null $releaseName The name of the release (optional). + * @param string|null $description The description of the release (optional). + * @param bool|null $isDraft Whether the release is a draft (optional). + * @param bool|null $isPrerelease Whether the release is a pre-release (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function update( + string $ownerName, + string $repoName, + int $releaseId, + ?string $tagName = null, + ?string $targetCommitish = null, + ?string $releaseName = null, + ?string $description = null, + ?bool $isDraft = null, + ?bool $isPrerelease = null + ): ?object + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/releases/{$releaseId}"; + + // Set the release data + $data = new \stdClass(); + + if ($tagName !== null || $targetCommitish !== null || $releaseName !== null || $description !== null || $isDraft !== null || $isPrerelease !== null) + { + $data->editReleaseOption = new \stdClass(); + + if ($tagName !== null) + { + $data->editReleaseOption->tag_name = $tagName; + } + + if ($targetCommitish !== null) + { + $data->editReleaseOption->target_commitish = $targetCommitish; + } + + if ($releaseName !== null) + { + $data->editReleaseOption->name = $releaseName; + } + + if ($description !== null) + { + $data->editReleaseOption->body = $description; + } + + if ($isDraft !== null) + { + $data->editReleaseOption->draft = $isDraft; + } + + if ($isPrerelease !== null) + { + $data->editReleaseOption->prerelease = $isPrerelease; + } + } + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Get a release by tag name. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $tagName The tag name. + * + * @return object|null + * @since 3.2.0 + **/ + public function getByTag( + string $ownerName, + string $repoName, + string $tagName + ): ?object + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/releases/tags/{$tagName}"; + + // Configure the URI with the path. + $this->uri->setVar('owner', $ownerName); + $this->uri->setVar('repo', $repoName); + $this->uri->setVar('tag', $tagName); + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a release by tag name. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $tagName The tag name. + * + * @return string + * @since 3.2.0 + **/ + public function deleteByTag( + string $ownerName, + string $repoName, + string $tagName + ): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/releases/tags/{$tagName}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Remote.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Remote.php new file mode 100644 index 000000000..f1bf1145b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Remote.php @@ -0,0 +1,96 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Remote + * + * @since 3.2.0 + */ +class Remote extends Api +{ + /** + * Migrate a remote git repository. + * + * @param string $cloneAddr The URL to clone the repository from. + * @param string $repoName The desired name for the new repository. + * @param string $repoOwner The name of the user or organization who will own the repo after migration. + * @param string $uid The ID of the user that will own the new repository (deprecated). + * @param string $description The description for the new repository (optional). + * @param bool $private Set the repository to private (optional, default false). + * @param string|null $authToken Authentication token (optional). + * @param string|null $authUsername Authentication username (optional). + * @param string|null $authPassword Authentication password (optional). + * @param array $options Additional migration options (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function migrate( + string $cloneAddr, + string $repoName, + string $repoOwner, + string $uid, + string $description = '', + bool $private = false, + ?string $authToken = null, + ?string $authUsername = null, + ?string $authPassword = null, + array $options = [] + ): ?object + { + // Build the request path. + $path = "/repos/migrate"; + + // Set the repository migration data. + $data = new \stdClass(); + $data->cloneAddr = $cloneAddr; + $data->repoName = $repoName; + $data->repoOwner = $repoOwner; + $data->uid = $uid; + $data->description = $description; + $data->private = $private; + + if ($authToken !== null) + { + $data->authToken = $authToken; + } + + if ($authUsername !== null) + { + $data->authUsername = $authUsername; + } + + if ($authPassword !== null) + { + $data->authPassword = $authPassword; + } + + foreach ($options as $key => $val) + { + $data->{$key} = $val; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Reviewers.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Reviewers.php new file mode 100644 index 000000000..ee0a4a04d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Reviewers.php @@ -0,0 +1,126 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Reviewers + * + * @since 3.2.0 + */ +class Reviewers extends Api +{ + /** + * Create review requests for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param array $reviewers Array of reviewers usernames. + * @param array|null $teamReviewers Array of team reviewers (optional). + * + * @return array|null + * @since 3.2.0 + **/ + public function request( + string $owner, + string $repo, + int $index, + array $reviewers, + ?array $teamReviewers = null + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/requested_reviewers"; + + // Set the review requests data. + $data = new \stdClass(); + $data->reviewers = $reviewers; + + if ($teamReviewers !== null) + { + $data->team_reviewers = $teamReviewers; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + + /** + * Cancel review requests for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param array $reviewers Array of reviewers usernames. + * @param array|null $teamReviewers Array of team reviewers (optional). + * + * @return string + * @since 3.2.0 + **/ + public function cancel( + string $owner, + string $repo, + int $index, + array $reviewers, + ?array $teamReviewers = null + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/requested_reviewers"; + + // Get the URI and set the required variables. + $uri = $this->uri->get($path); + $uri->setVar('reviewers', json_encode($reviewers)); + + if ($teamReviewers !== null) + { + $uri->setVar('teamReviewers', json_encode($teamReviewers)); + } + + // Send the delete request. + return $this->response->get( + $this->http->delete($uri), 204, 'success' + ); + } + + /** + * Return all users that can be requested to review in this repo. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return array|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/reviewers"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Reviews.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Reviews.php new file mode 100644 index 000000000..17e3ac319 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Reviews.php @@ -0,0 +1,321 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Reviews + * + * @since 3.2.0 + */ +class Reviews extends Api +{ + /** + * List all reviews for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $owner, + string $repo, + int $index, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/reviews"; + + // Get the URI. + $uri = $this->uri->get($path); + + // Set query parameters. + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a review for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param string $body The review body text. + * @param string $event The review event type (APPROVE, REQUEST_CHANGES, COMMENT). + * @param array|null $comments An array of CreatePullReviewComment objects. + * @param string|null $commitId The commit ID. + * + * @return object|null + * @since 3.2.0 + */ + public function create( + string $owner, + string $repo, + int $index, + string $body, + string $event, + ?array $comments = null, + ?string $commitId = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/reviews"; + + // Set the review data. + $data = new \stdClass(); + $data->body = $body; + $data->event = $event; + + // Add comments if available. + if ($comments !== null) + { + $data->comments = $comments; + } + + // Add commitId if available. + if ($commitId !== null) + { + $data->commit_id = $commitId; + } + + // Send the request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Get a specific review for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param int $id The review ID. + * + * @return object|null + * @since 3.2.0 + */ + public function get( + string $owner, + string $repo, + int $index, + int $id + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/reviews/{$id}"; + + // Set the variables for the URI. + $uri = $this->uri->get($path); + $uri->setVar('owner', $owner); + $uri->setVar('repo', $repo); + $uri->setVar('index', $index); + $uri->setVar('id', $id); + + // Send the request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Submit a pending review to a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param int $id The review ID. + * @param string $body The review body text. + * @param string $event The review event type (APPROVE, REQUEST_CHANGES, COMMENT). + * + * @return object|null + * @since 3.2.0 + */ + public function submit( + string $owner, + string $repo, + int $index, + int $id, + string $body, + string $event + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/reviews/{$id}"; + + // Set the review data. + $data = new \stdClass(); + $data->body = $body; + $data->event = $event; + + // Send the request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Delete a specific review from a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param int $id The review ID. + * + * @return string + * @since 3.2.0 + */ + public function delete( + string $owner, + string $repo, + int $index, + int $id + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/reviews/{$id}"; + + // Set the variables for the URI. + $uri = $this->uri->get($path); + $uri->setVar('owner', $owner); + $uri->setVar('repo', $repo); + $uri->setVar('index', $index); + $uri->setVar('id', $id); + + // Send the delete request. + return $this->response->get( + $this->http->delete($uri), 204, 'success' + ); + } + + /** + * Get the comments of a specific review for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param int $id The review ID. + * + * @return array|null + * @since 3.2.0 + */ + public function comments( + string $owner, + string $repo, + int $index, + int $id + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/reviews/{$id}/comments"; + + // Set the variables for the URI. + $uri = $this->uri->get($path); + $uri->setVar('owner', $owner); + $uri->setVar('repo', $repo); + $uri->setVar('index', $index); + $uri->setVar('id', $id); + + // Send the request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Dismiss a review for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param int $id The review ID. + * @param string $message The dismissal message. + * @param bool $priors The flag to dismiss prior reviews. + * + * @return object|null + * @since 3.2.0 + */ + public function dismiss( + string $owner, + string $repo, + int $index, + int $id, + string $message, + bool $priors = false + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/reviews/{$id}/dismissals"; + + // Set the dismissal data. + $data = new \stdClass(); + $data->message = $message; + $data->priors = $priors; + + // Send the request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Cancel the dismissal of a review for a pull request. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $index The pull request index. + * @param int $id The review ID. + * + * @return object|null + * @since 3.2.0 + */ + public function undismiss( + string $owner, + string $repo, + int $index, + int $id + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/pulls/{$index}/reviews/{$id}/undismissals"; + + // Send the request. + return $this->response->get( + $this->http->post( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Stargazers.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Stargazers.php new file mode 100644 index 000000000..0c72b6d72 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Stargazers.php @@ -0,0 +1,59 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Stargazers + * + * @since 3.2.0 + */ +class Stargazers extends Api +{ + /** + * List a repo's stargazers. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $ownerName, + string $repoName, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/stargazers"; + + // Set the page and limit values. + $this->uri->setVar('page', $page); + $this->uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Statuses.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Statuses.php new file mode 100644 index 000000000..ba6e3c16c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Statuses.php @@ -0,0 +1,122 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Statuses + * + * @since 3.2.0 + */ +class Statuses extends Api +{ + /** + * Get a commit's statuses. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $commitSha The commit SHA. + * @param string $sort The type of sort. + * @param string $state The type of state. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function get( + string $ownerName, + string $repoName, + string $commitSha, + string $sort = 'recentupdate', + string $state = 'pending', + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/statuses/{$commitSha}"; + + // Prepare the URI with the path. + $uri = $this->uri->get($path); + + // Set the query parameters. + $uri->setVar('sort', $sort); + $uri->setVar('state', $state); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a commit status. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $commitSha The commit SHA. + * @param string $state The commit status state (error, failure, pending, success, or warning). + * @param string|null $context The context of the status (optional). + * @param string|null $statusDescription The status description (optional). + * @param string|null $targetUrl The URL of the associated build status (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $ownerName, + string $repoName, + string $commitSha, + string $state, + ?string $context = null, + ?string $statusDescription = null, + ?string $targetUrl = null + ): ?object + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/statuses/{$commitSha}"; + + // Set the commit status data + $data = new \stdClass(); + $data->state = $state; + + if ($context !== null) + { + $data->context = $context; + } + + if ($statusDescription !== null) + { + $data->description = $statusDescription; + } + + if ($targetUrl !== null) + { + $data->target_url = $targetUrl; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ), 201 + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Tags.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Tags.php new file mode 100644 index 000000000..600bfc2b0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Tags.php @@ -0,0 +1,182 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Tags + * + * @since 3.2.0 + */ +class Tags extends Api +{ + /** + * List a repository's tags + * + * @param string $owner The owner of the repo. + * @param string $repo The name of the repo. + * @param int|null $page The page number of results to return (1-based). + * @param int|null $limit The page size of results, default maximum page size is 10. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $owner, + string $repo, + ?int $page = 1, + ?int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/tags"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Add query parameters if they are provided. + if ($page !== null) + { + $uri->setVar('page', $page); + } + + if ($limit !== null) + { + $uri->setVar('limit', $limit); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get the tag of a repository by tag name. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $tag The tag name. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $owner, string $repo, string $tag): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/tags/{$tag}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Get the tag object of an annotated tag (not lightweight tags). + * + * @param string $owner The owner of the repo. + * @param string $repo The name of the repo. + * @param string $sha The sha of the tag. The Git tags API only supports annotated tag objects, not lightweight tags. + * + * @return object|null + * @since 3.2.0 + **/ + public function sha( + string $owner, + string $repo, + string $sha + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/git/tags/{$sha}"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a new git tag in a repository. + * + * @param string $owner The owner of the repo. + * @param string $repo The name of the repo. + * @param string $tagName The name of the tag. + * @param string $target The SHA of the git object this is tagging. + * @param string $message The tag message. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $owner, + string $repo, + string $tagName, + string $target, + string $message + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/tags"; + + // Set the tag data + $data = new \stdClass(); + $data->tag_name = $tagName; + $data->target = $target; + $data->message = $message; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Delete a repository's tag by name. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $tag The tag name. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $owner, + string $repo, + string $tag + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/tags/{$tag}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'succes' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Teams.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Teams.php new file mode 100644 index 000000000..cb39f7c4f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Teams.php @@ -0,0 +1,133 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Teams + * + * @since 3.2.0 + */ +class Teams extends Api +{ + /** + * List a repository's teams. + * + * @param string $ownerOfRepo The owner name. + * @param string $nameOfRepo The repository name. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(string $ownerOfRepo, string $nameOfRepo): ?array + { + // Build the request path. + $path = "/repos/{$ownerOfRepo}/{$nameOfRepo}/teams"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Check if a team is assigned to a repository. + * + * @param string $ownerOfRepo The owner name. + * @param string $nameOfRepo The repository name. + * @param string $teamName The team name. + * + * @return object|null + * @since 3.2.0 + **/ + public function check( + string $ownerOfRepo, + string $nameOfRepo, + string $teamName + ): ?object + { + // Build the request path. + $path = "/repos/{$ownerOfRepo}/{$nameOfRepo}/teams/{$teamName}"; + + // Get the URI with the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Add a team to a repository. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $teamName The team name. + * + * @return string + * @since 3.2.0 + **/ + public function add( + string $ownerName, + string $repoName, + string $teamName + ): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/teams/{$teamName}"; + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), '' + ), 204, 'success' + ); + } + + /** + * Delete a team from a repository. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $teamName The team name. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $ownerName, + string $repoName, + string $teamName + ): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/teams/{$teamName}"; + + // Prepare the URI with the path. + $uri = $this->uri->get($path); + + // Send the delete request. + return $this->response->get( + $this->http->delete($uri), + 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Templates.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Templates.php new file mode 100644 index 000000000..40246fcc0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Templates.php @@ -0,0 +1,91 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Templates + * + * @since 3.2.0 + */ +class Templates extends Api +{ + /** + * Get available issue templates for a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return array|null + * @since 3.2.0 + **/ + public function issue(string $owner, string $repo): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/issue_templates"; + + // Get the URI. + $uri = $this->uri->get($path); + + // Send the GET request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Create a repository using a template. + * + * @param string $templateOwner The template owner's name. + * @param string $templateRepo The template repository name. + * @param string $name The name of the new repository. + * @param array $options Optional. Additional options for the new repository. + * + * @return object|null + * @since 3.2.0 + **/ + public function repo( + string $templateOwner, + string $templateRepo, + string $name, + array $options = [] + ): ?object + { + // Build the request path. + $path = "/repos/{$templateOwner}/{$templateRepo}/generate"; + + // Set the repo data. + $data = new \stdClass(); + $data->name = $name; + + foreach ($options as $key => $value) + { + if ($value !== null) + { + $data->{$key} = $value; + } + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Times.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Times.php new file mode 100644 index 000000000..bae141607 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Times.php @@ -0,0 +1,80 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Times + * + * @since 3.2.0 + */ +class Times extends Api +{ + /** + * List a repo's tracked times. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $user Optional filter by user (available for issue managers). + * @param string $since Only show times updated after the given time. This is a timestamp in RFC 3339 format. + * @param string $before Only show times updated before the given time. This is a timestamp in RFC 3339 format. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $ownerName, + string $repoName, + string $user = null, + string $since = null, + string $before = null, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/times"; + + // Set the query parameters. + $uri = $this->uri->get($path); + + if ($user !== null) + { + $uri->setVar('user', $user); + } + + if ($since !== null) + { + $uri->setVar('since', $since); + } + + if ($before !== null) + { + $uri->setVar('before', $before); + } + + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Topics.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Topics.php new file mode 100644 index 000000000..bbd24b874 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Topics.php @@ -0,0 +1,175 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Topics + * + * @since 3.2.0 + */ +class Topics extends Api +{ + /** + * Get the list of topics that a repository has. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + int $page = 1, + int $limit = 10 + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/topics"; + + // Set query parameters for pagination. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Replace the list of topics for a repository. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param array $topicNames The new list of topics. + * + * @return string + * @since 3.2.0 + **/ + public function replace( + string $ownerName, + string $repoName, + array $topicNames + ): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/topics"; + + // Set the topics data. + $data = new \stdClass(); + $data->topics = $topicNames; + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), + json_encode($data) + ), 204, 'success' + ); + } + + /** + * Add a topic to a repository. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $topicName The topic to add. + * + * @return string + * @since 3.2.0 + **/ + public function add( + string $ownerName, + string $repoName, + string $topicName + ): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/topics/{$topicName}"; + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), '' + ), 204, 'success' + ); + } + + /** + * Delete a topic from a repository. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param string $topicName The topic to delete. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $ownerName, + string $repoName, + string $topicName + ): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/topics/{$topicName}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Search topics via keyword. + * + * @param string $searchKeyword The keyword to search for. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function search( + string $searchKeyword, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/topics/search"; + + // Set the query parameters. + $uri = $this->uri->get($path); + $uri->setVar('q', $searchKeyword); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Transfer.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Transfer.php new file mode 100644 index 000000000..b2e80be06 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Transfer.php @@ -0,0 +1,108 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Transfer + * + * @since 3.2.0 + */ +class Transfer extends Api +{ + /** + * Transfer a repo ownership. + * + * @param string $owner The current owner name. + * @param string $repo The repository name. + * @param string $newOwner The new owner's name. + * @param array|null $teamIDs Optional. The IDs of the teams that will be granted access. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $owner, + string $repo, + string $newOwner, + ?array $teamIDs = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/transfer"; + + // Set the transfer data. + $data = new \stdClass(); + $data->new_owner = $newOwner; + if ($teamIDs !== null) + { + $data->team_ids = $teamIDs; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 202 + ); + } + + /** + * Accept a repo transfer. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return object|null + * @since 3.2.0 + **/ + public function accept(string $owner, string $repo): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/transfer/accept"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path) + ), 202 + ); + } + + /** + * Reject a repo transfer. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return object|null + * @since 3.2.0 + **/ + public function reject(string $owner, string $repo): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/transfer/reject"; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Trees.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Trees.php new file mode 100644 index 000000000..a9e1974c2 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Trees.php @@ -0,0 +1,63 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Trees + * + * @since 3.2.0 + */ +class Trees extends Api +{ + /** + * Get the tree of a repository. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $sha The commit SHA. + * @param bool $recursive Show all directories and files. + * @param int $page Page number. + * @param int $perPage Number of items per page. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + string $sha, + bool $recursive = false, + int $page = 1, + int $perPage = 30 + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/git/trees/{$sha}"; + + // Set URI variables. + $uri = $this->uri->get($path); + $uri->setVar('recursive', $recursive); + $uri->setVar('page', $page); + $uri->setVar('per_page', $perPage); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Watchers.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Watchers.php new file mode 100644 index 000000000..131482a3b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Watchers.php @@ -0,0 +1,140 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Watchers + * + * @since 3.2.0 + */ +class Watchers extends Api +{ + /** + * List a repo's watchers. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $ownerName, + string $repoName, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/subscribers"; + + // Prepare the URI with the path. + $uri = $this->uri->get($path); + + // Set the page and limit query parameters. + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Check if the current user is watching a repo. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * + * @return object|null + * @since 3.2.0 + **/ + public function check(string $ownerName, string $repoName): ?object + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/subscription"; + + // Prepare the URI with the path. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Watch a repo. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * @param bool $subscribed Determine if notifications should be received from this repository. + * @param bool $ignored Determine if all notifications should be blocked from this repository. + * + * @return object|null + * @since 3.2.0 + **/ + public function watch( + string $ownerName, + string $repoName, + bool $subscribed = true, + bool $ignored = false + ): ?object + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/subscription"; + + // Set the subscription data + $data = new \stdClass(); + $data->subscribed = $subscribed; + $data->ignored = $ignored; + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), json_encode($data) + ) + ); + } + + /** + * Unwatch a repo. + * + * @param string $ownerName The owner name. + * @param string $repoName The repository name. + * + * @return string + * @since 3.2.0 + **/ + public function unwatch(string $ownerName, string $repoName): string + { + // Build the request path. + $path = "/repos/{$ownerName}/{$repoName}/subscription"; + + // Prepare the URI with the path. + $uri = $this->uri->get($path); + + // Send the delete request. + return $this->response->get( + $this->http->delete($uri), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Wiki.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Wiki.php new file mode 100644 index 000000000..748860817 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/Wiki.php @@ -0,0 +1,232 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Repository; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Repository Wiki + * + * @since 3.2.0 + */ +class Wiki extends Api +{ + /** + * Create a wiki page. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $title The title of the wiki page. + * @param string $contentBase64 The base64 encoded content of the wiki page. + * @param string|null $message Optional commit message summarizing the change. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $owner, + string $repo, + string $title, + string $contentBase64, + ?string $message = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/wiki/new"; + + // Set the wiki data. + $data = new \stdClass(); + $data->title = $title; + $data->content_base64 = $contentBase64; + + if ($message !== null) + { + $data->message = $message; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * Get a wiki page. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $pageName The name of the wiki page. + * + * @return object|null + * @since 3.2.0 + **/ + public function get( + string $owner, + string $repo, + string $pageName + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/wiki/page/{$pageName}"; + + // Set the URI. + $uri = $this->uri->get($path); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get all wiki pages. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function pages( + string $owner, + string $repo, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/wiki/pages"; + + // Set the URI. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Delete a wiki page. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $pageName The name of the wiki page. + * + * @return string + * @since 3.2.0 + **/ + public function delete( + string $owner, + string $repo, + string $pageName + ): string + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/wiki/page/{$pageName}"; + + // Get the URI. + $uri = $this->uri->get($path); + + // Send the delete request. + return $this->response->get( + $this->http->delete($uri), 204, 'success' + ); + } + + /** + * Edit a wiki page. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $pageName The name of the wiki page. + * @param string $title The new title of the wiki page. + * @param string $content The new content of the wiki page. + * @param string $message The optional commit message summarizing the change. + * + * @return object|null + * @since 3.2.0 + **/ + public function edit( + string $owner, + string $repo, + string $pageName, + string $title, + string $content, + string $message = null + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/wiki/page/{$pageName}"; + + // Set the wiki data. + $data = new \stdClass(); + $data->title = $title; + $data->content_base64 = base64_encode($content); + + if ($message !== null) + { + $data->message = $message; + } + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), + json_encode($data) + ) + ); + } + + /** + * Get revisions of a wiki page. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * @param string $pageName The name of the wiki page. + * @param int $page The page number of results to return (1-based). + * + * @return object|null + * @since 3.2.0 + **/ + public function revisions( + string $owner, + string $repo, + string $pageName, + int $page = 1 + ): ?object + { + // Build the request path. + $path = "/repos/{$owner}/{$repo}/wiki/revisions/{$pageName}"; + + // Set the page number. + $this->uri->setVar('page', $page); + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Repository/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Admin.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Admin.php new file mode 100644 index 000000000..be64aa181 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Admin.php @@ -0,0 +1,185 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Admin\Cron; +use VDM\Joomla\Gitea\Admin\Organizations; +use VDM\Joomla\Gitea\Admin\Unadopted; +use VDM\Joomla\Gitea\Admin\Users; +use VDM\Joomla\Gitea\Admin\Users\Keys; +use VDM\Joomla\Gitea\Admin\Users\Organization; +use VDM\Joomla\Gitea\Admin\Users\Repository; + + +/** + * The Gitea Admin Service + * + * @since 3.2.0 + */ +class Admin implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Cron::class, 'Gitea.Admin.Cron') + ->share('Gitea.Admin.Cron', [$this, 'getCron'], true); + + $container->alias(Organizations::class, 'Gitea.Admin.Organizations') + ->share('Gitea.Admin.Organizations', [$this, 'getOrganizations'], true); + + $container->alias(Unadopted::class, 'Gitea.Admin.Unadopted') + ->share('Gitea.Admin.Unadopted', [$this, 'getUnadopted'], true); + + $container->alias(Users::class, 'Gitea.Admin.Users') + ->share('Gitea.Admin.Users', [$this, 'getUsers'], true); + + $container->alias(Keys::class, 'Gitea.Admin.Users.Keys') + ->share('Gitea.Admin.Users.Keys', [$this, 'getKeys'], true); + + $container->alias(Organization::class, 'Gitea.Admin.Users.Organization') + ->share('Gitea.Admin.Users.Organization', [$this, 'getOrganization'], true); + + $container->alias(Repository::class, 'Gitea.Admin.Users.Repository') + ->share('Gitea.Admin.Users.Repository', [$this, 'getRepository'], true); + } + + /** + * Get the Cron class + * + * @param Container $container The DI container. + * + * @return Cron + * @since 3.2.0 + */ + public function getCron(Container $container): Cron + { + return new Cron( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Organizations class + * + * @param Container $container The DI container. + * + * @return Organizations + * @since 3.2.0 + */ + public function getOrganizations(Container $container): Organizations + { + return new Organizations( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Unadopted class + * + * @param Container $container The DI container. + * + * @return Unadopted + * @since 3.2.0 + */ + public function getUnadopted(Container $container): Unadopted + { + return new Unadopted( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Users class + * + * @param Container $container The DI container. + * + * @return Users + * @since 3.2.0 + */ + public function getUsers(Container $container): Users + { + return new Users( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Keys class + * + * @param Container $container The DI container. + * + * @return Keys + * @since 3.2.0 + */ + public function getKeys(Container $container): Keys + { + return new Keys( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Organization class + * + * @param Container $container The DI container. + * + * @return Organization + * @since 3.2.0 + */ + public function getOrganization(Container $container): Organization + { + return new Organization( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Repository class + * + * @param Container $container The DI container. + * + * @return Repository + * @since 3.2.0 + */ + public function getRepository(Container $container): Repository + { + return new Repository( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Issue.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Issue.php new file mode 100644 index 000000000..9c49a5a3c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Issue.php @@ -0,0 +1,294 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Issue as Issu; +use VDM\Joomla\Gitea\Issue\Comments; +use VDM\Joomla\Gitea\Issue\Repository\Comments as RepoComments; +use VDM\Joomla\Gitea\Issue\Deadline; +use VDM\Joomla\Gitea\Labels; +use VDM\Joomla\Gitea\Issue\Labels as IssueLabels; +use VDM\Joomla\Gitea\Issue\Milestones; +use VDM\Joomla\Gitea\Issue\Reactions; +use VDM\Joomla\Gitea\Issue\Reactions\Comment; +use VDM\Joomla\Gitea\Issue\Stopwatch; +use VDM\Joomla\Gitea\Issue\Subscriptions; +use VDM\Joomla\Gitea\Issue\Timeline; +use VDM\Joomla\Gitea\Issue\Times; + + +/** + * The Gitea Issue Service + * + * @since 3.2.0 + */ +class Issue implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Issu::class, 'Gitea.Issue') + ->share('Gitea.Issue', [$this, 'getIssue'], true); + + $container->alias(Comments::class, 'Gitea.Issue.Comments') + ->share('Gitea.Issue.Comments', [$this, 'getComments'], true); + + $container->alias(RepoComments::class, 'Gitea.Issue.Repository.Comments') + ->share('Gitea.Issue.Repository.Comments', [$this, 'getRepoComments'], true); + + $container->alias(Deadline::class, 'Gitea.Issue.Deadline') + ->share('Gitea.Issue.Deadline', [$this, 'getDeadline'], true); + + $container->alias(Labels::class, 'Gitea.Labels') + ->share('Gitea.Labels', [$this, 'getLabels'], true); + + $container->alias(IssueLabels::class, 'Gitea.Issue.Labels') + ->share('Gitea.Issue.Labels', [$this, 'getIssueLabels'], true); + + $container->alias(Milestones::class, 'Gitea.Issue.Milestones') + ->share('Gitea.Issue.Milestones', [$this, 'getMilestones'], true); + + $container->alias(Reactions::class, 'Gitea.Issue.Reactions') + ->share('Gitea.Issue.Reactions', [$this, 'getReactions'], true); + + $container->alias(Comment::class, 'Gitea.Issue.Reactions.Comment') + ->share('Gitea.Issue.Reactions.Comment', [$this, 'getComment'], true); + + $container->alias(Stopwatch::class, 'Gitea.Issue.Stopwatch') + ->share('Gitea.Issue.Stopwatch', [$this, 'getStopwatch'], true); + + $container->alias(Subscriptions::class, 'Gitea.Issue.Subscriptions') + ->share('Gitea.Issue.Subscriptions', [$this, 'getSubscriptions'], true); + + $container->alias(Timeline::class, 'Gitea.Issue.Timeline') + ->share('Gitea.Issue.Timeline', [$this, 'getTimeline'], true); + + $container->alias(Times::class, 'Gitea.Issue.Times') + ->share('Gitea.Issue.Times', [$this, 'getTimes'], true); + } + + /** + * Get the Issue class + * + * @param Container $container The DI container. + * + * @return Issu + * @since 3.2.0 + */ + public function getIssue(Container $container): Issu + { + return new Issu( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Comments class + * + * @param Container $container The DI container. + * + * @return Comments + * @since 3.2.0 + */ + public function getComments(Container $container): Comments + { + return new Comments( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Repository Comments class + * + * @param Container $container The DI container. + * + * @return RepoComments + * @since 3.2.0 + */ + public function getRepoComments(Container $container): RepoComments + { + return new RepoComments( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Labels class + * + * @param Container $container The DI container. + * + * @return Labels + * @since 3.2.0 + */ + public function getLabels(Container $container): Labels + { + return new Labels( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Issue Labels class + * + * @param Container $container The DI container. + * + * @return IssueLabels + * @since 3.2.0 + */ + public function getIssueLabels(Container $container): IssueLabels + { + return new IssueLabels( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Milestones class + * + * @param Container $container The DI container. + * + * @return Milestones + * @since 3.2.0 + */ + public function getMilestones(Container $container): Milestones + { + return new Milestones( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Reactions class + * + * @param Container $container The DI container. + * + * @return Reactions + * @since 3.2.0 + */ + public function getReactions(Container $container): Reactions + { + return new Reactions( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Reactions Comment class + * + * @param Container $container The DI container. + * + * @return Comment + * @since 3.2.0 + */ + public function getComment(Container $container): Comment + { + return new Comment( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Stopwatch class + * + * @param Container $container The DI container. + * + * @return Stopwatch + * @since 3.2.0 + */ + public function getStopwatch(Container $container): Stopwatch + { + return new Stopwatch( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Subscriptions class + * + * @param Container $container The DI container. + * + * @return Subscriptions + * @since 3.2.0 + */ + public function getSubscriptions(Container $container): Subscriptions + { + return new Subscriptions( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Timeline class + * + * @param Container $container The DI container. + * + * @return Timeline + * @since 3.2.0 + */ + public function getTimeline(Container $container): Timeline + { + return new Timeline( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Times class + * + * @param Container $container The DI container. + * + * @return Times + * @since 3.2.0 + */ + public function getTimes(Container $container): Times + { + return new Times( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Jcb.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Jcb.php new file mode 100644 index 000000000..5e6a7a887 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Jcb.php @@ -0,0 +1,85 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Utilities\Uri; +use VDM\Joomla\Gitea\Utilities\Http; +use VDM\Joomla\Utilities\Component\Helper; + + +/** + * The Gitea Utilities Service + * + * @since 3.2.0 + */ +class Jcb implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Uri::class, 'Gitea.Dynamic.Uri') + ->share('Gitea.Dynamic.Uri', [$this, 'getUri'], true); + + $container->alias(Http::class, 'Gitea.Utilities.Http') + ->share('Gitea.Utilities.Http', [$this, 'getHttp'], true); + } + + /** + * Get the Dynamic Uri class + * + * @param Container $container The DI container. + * + * @return Uri + * @since 3.2.0 + */ + public function getUri(Container $container): Uri + { + // get the global gitea URL + $add_gitea_url = Helper::getParams('com_componentbuilder')->get('add_custom_gitea_url', 1); + $gitea_url = Helper::getParams('com_componentbuilder')->get('custom_gitea_url'); + + // only load this if we have a custom URL set + if ($add_gitea_url == 2 && is_string($gitea_url) && strpos($gitea_url, 'http') !== false) + { + return new Uri($gitea_url); + } + + return $container->get('Gitea.Utilities.Uri'); + } + + /** + * Get the Http class + * + * @param Container $container The DI container. + * + * @return Http + * @since 3.2.0 + */ + public function getHttp(Container $container): Http + { + return new Http( + Helper::getParams('com_componentbuilder')->get('gitea_token') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Miscellaneous.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Miscellaneous.php new file mode 100644 index 000000000..14abf45bb --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Miscellaneous.php @@ -0,0 +1,143 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Miscellaneous\Activitypub; +use VDM\Joomla\Gitea\Miscellaneous\Gpg; +use VDM\Joomla\Gitea\Miscellaneous\Markdown; +use VDM\Joomla\Gitea\Miscellaneous\NodeInfo; +use VDM\Joomla\Gitea\Miscellaneous\Version; + + +/** + * The Gitea Miscellaneous Service + * + * @since 3.2.0 + */ +class Miscellaneous implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Activitypub::class, 'Gitea.Miscellaneous.Activitypub') + ->share('Gitea.Miscellaneous.Activitypub', [$this, 'getActivitypub'], true); + + $container->alias(Gpg::class, 'Gitea.Miscellaneous.Gpg') + ->share('Gitea.Miscellaneous.Gpg', [$this, 'getGpg'], true); + + $container->alias(Markdown::class, 'Gitea.Miscellaneous.Markdown') + ->share('Gitea.Miscellaneous.Markdown', [$this, 'getMarkdown'], true); + + $container->alias(NodeInfo::class, 'Gitea.Miscellaneous.NodeInfo') + ->share('Gitea.Miscellaneous.NodeInfo', [$this, 'getNodeInfo'], true); + + $container->alias(Version::class, 'Gitea.Miscellaneous.Version') + ->share('Gitea.Miscellaneous.Version', [$this, 'getVersion'], true); + } + + /** + * Get the Activitypub class + * + * @param Container $container The DI container. + * + * @return Activitypub + * @since 3.2.0 + */ + public function getActivitypub(Container $container): Activitypub + { + return new Activitypub( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Gpg class + * + * @param Container $container The DI container. + * + * @return Gpg + * @since 3.2.0 + */ + public function getGpg(Container $container): Gpg + { + return new Gpg( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Markdown class + * + * @param Container $container The DI container. + * + * @return Markdown + * @since 3.2.0 + */ + public function getMarkdown(Container $container): Markdown + { + return new Markdown( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the NodeInfo class + * + * @param Container $container The DI container. + * + * @return NodeInfo + * @since 3.2.0 + */ + public function getNodeInfo(Container $container): NodeInfo + { + return new NodeInfo( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Version class + * + * @param Container $container The DI container. + * + * @return Version + * @since 3.2.0 + */ + public function getVersion(Container $container): Version + { + return new Version( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Notifications.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Notifications.php new file mode 100644 index 000000000..b6b5a29b2 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Notifications.php @@ -0,0 +1,101 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Notifications as Notifi; +use VDM\Joomla\Gitea\Notifications\Repository; +use VDM\Joomla\Gitea\Notifications\Thread; + + +/** + * The Gitea Notifications Service + * + * @since 3.2.0 + */ +class Notifications implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Notifi::class, 'Gitea.Notifications') + ->share('Gitea.Notifications', [$this, 'getNotifications'], true); + + $container->alias(Repository::class, 'Gitea.Notifications.Repository') + ->share('Gitea.Notifications.Repository', [$this, 'getRepository'], true); + + $container->alias(Thread::class, 'Gitea.Notifications.Thread') + ->share('Gitea.Notifications.Thread', [$this, 'getThread'], true); + } + + /** + * Get the Notifications class + * + * @param Container $container The DI container. + * + * @return Notifi + * @since 3.2.0 + */ + public function getNotifications(Container $container): Notifi + { + return new Notifi( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Repository class + * + * @param Container $container The DI container. + * + * @return Repository + * @since 3.2.0 + */ + public function getRepository(Container $container): Repository + { + return new Repository( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Thread class + * + * @param Container $container The DI container. + * + * @return Thread + * @since 3.2.0 + */ + public function getThread(Container $container): Thread + { + return new Thread( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Organization.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Organization.php new file mode 100644 index 000000000..dab899e8e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Organization.php @@ -0,0 +1,248 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Organization as Org; +use VDM\Joomla\Gitea\Organization\Hooks; +use VDM\Joomla\Gitea\Organization\Labels; +use VDM\Joomla\Gitea\Organization\Members; +use VDM\Joomla\Gitea\Organization\PublicMembers as PublicMembers; +use VDM\Joomla\Gitea\Organization\Repository; +use VDM\Joomla\Gitea\Organization\Teams; +use VDM\Joomla\Gitea\Organization\Teams\Members as TeamsMembers; +use VDM\Joomla\Gitea\Organization\Teams\Repository as TeamsRepository; +use VDM\Joomla\Gitea\Organization\User; + + +/** + * The Gitea Organization Service + * + * @since 3.2.0 + */ +class Organization implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Org::class, 'Gitea.Organization') + ->share('Gitea.Organization', [$this, 'getOrganization'], true); + + $container->alias(Hooks::class, 'Gitea.Organization.Hooks') + ->share('Gitea.Organization.Hooks', [$this, 'getHooks'], true); + + $container->alias(Labels::class, 'Gitea.Organization.Labels') + ->share('Gitea.Organization.Labels', [$this, 'getLabels'], true); + + $container->alias(Members::class, 'Gitea.Organization.Members') + ->share('Gitea.Organization.Members', [$this, 'getMembers'], true); + + $container->alias(PublicMembers::class, 'Gitea.Organization.Public.Members') + ->share('Gitea.Organization.Public.Members', [$this, 'getPublicMembers'], true); + + $container->alias(Repository::class, 'Gitea.Organization.Repository') + ->share('Gitea.Organization.Repository', [$this, 'getRepository'], true); + + $container->alias(Teams::class, 'Gitea.Organization.Teams') + ->share('Gitea.Organization.Teams', [$this, 'getTeams'], true); + + $container->alias(TeamsMembers::class, 'Gitea.Organization.Teams.Members') + ->share('Gitea.Organization.Teams.Members', [$this, 'getTeamsMembers'], true); + + $container->alias(TeamsRepository::class, 'Gitea.Organization.Teams.Repository') + ->share('Gitea.Organization.Teams.Repository', [$this, 'getTeamsRepository'], true); + + $container->alias(User::class, 'Gitea.Organization.User') + ->share('Gitea.Organization.User', [$this, 'getUser'], true); + } + + /** + * Get the Organization class + * + * @param Container $container The DI container. + * + * @return Org + * @since 3.2.0 + */ + public function getOrganization(Container $container): Org + { + return new Org( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Hooks class + * + * @param Container $container The DI container. + * + * @return Hooks + * @since 3.2.0 + */ + public function getHooks(Container $container): Hooks + { + return new Hooks( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Labels class + * + * @param Container $container The DI container. + * + * @return Labels + * @since 3.2.0 + */ + public function getLabels(Container $container): Labels + { + return new Labels( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Members class + * + * @param Container $container The DI container. + * + * @return Members + * @since 3.2.0 + */ + public function getMembers(Container $container): Members + { + return new Members( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Public Members class + * + * @param Container $container The DI container. + * + * @return PublicMembers + * @since 3.2.0 + */ + public function getPublicMembers(Container $container): PublicMembers + { + return new PublicMembers( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Repository class + * + * @param Container $container The DI container. + * + * @return Repository + * @since 3.2.0 + */ + public function getRepository(Container $container): Repository + { + return new Repository( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Teams class + * + * @param Container $container The DI container. + * + * @return Teams + * @since 3.2.0 + */ + public function getTeams(Container $container): Teams + { + return new Teams( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Teams Members class + * + * @param Container $container The DI container. + * + * @return TeamsMembers + * @since 3.2.0 + */ + public function getTeamsMembers(Container $container): TeamsMembers + { + return new TeamsMembers( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Teams Repository class + * + * @param Container $container The DI container. + * + * @return TeamsRepository + * @since 3.2.0 + */ + public function getTeamsRepository(Container $container): TeamsRepository + { + return new TeamsRepository( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the User class + * + * @param Container $container The DI container. + * + * @return User + * @since 3.2.0 + */ + public function getUser(Container $container): User + { + return new User( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Package.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Package.php new file mode 100644 index 000000000..75d92cb66 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Package.php @@ -0,0 +1,101 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Package as Pack; +use VDM\Joomla\Gitea\Package\Files; +use VDM\Joomla\Gitea\Package\Owner; + + +/** + * The Gitea Package Service + * + * @since 3.2.0 + */ +class Package implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Pack::class, 'Gitea.Package') + ->share('Gitea.Package', [$this, 'getPackage'], true); + + $container->alias(Files::class, 'Gitea.Package.Files') + ->share('Gitea.Package.Files', [$this, 'getFiles'], true); + + $container->alias(Owner::class, 'Gitea.Package.Owner') + ->share('Gitea.Package.Owner', [$this, 'getOwner'], true); + } + + /** + * Get the Package class + * + * @param Container $container The DI container. + * + * @return Pack + * @since 3.2.0 + */ + public function getPackage(Container $container): Pack + { + return new Pack( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Files class + * + * @param Container $container The DI container. + * + * @return Files + * @since 3.2.0 + */ + public function getFiles(Container $container): Files + { + return new Files( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Owner class + * + * @param Container $container The DI container. + * + * @return Owner + * @since 3.2.0 + */ + public function getOwner(Container $container): Owner + { + return new Owner( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Repository.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Repository.php new file mode 100644 index 000000000..edfab0d2f --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Repository.php @@ -0,0 +1,836 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Repository as Repo; +use VDM\Joomla\Gitea\Repository\Archive; +use VDM\Joomla\Gitea\Repository\Assignees; +use VDM\Joomla\Gitea\Repository\Attachments; +use VDM\Joomla\Gitea\Repository\Branch; +use VDM\Joomla\Gitea\Repository\Branch\Protection; +use VDM\Joomla\Gitea\Repository\Collaborator; +use VDM\Joomla\Gitea\Repository\Commits; +use VDM\Joomla\Gitea\Repository\Contents; +use VDM\Joomla\Gitea\Repository\Forks; +use VDM\Joomla\Gitea\Repository\Gpg; +use VDM\Joomla\Gitea\Repository\Hooks; +use VDM\Joomla\Gitea\Repository\Hooks\Git; +use VDM\Joomla\Gitea\Repository\Keys; +use VDM\Joomla\Gitea\Repository\Languages; +use VDM\Joomla\Gitea\Repository\Media; +use VDM\Joomla\Gitea\Repository\Merge; +use VDM\Joomla\Gitea\Repository\Mirror; +use VDM\Joomla\Gitea\Repository\Mirrors; +use VDM\Joomla\Gitea\Repository\Notes; +use VDM\Joomla\Gitea\Repository\Patch; +use VDM\Joomla\Gitea\Repository\Pulls; +use VDM\Joomla\Gitea\Repository\Refs; +use VDM\Joomla\Gitea\Repository\Releases; +use VDM\Joomla\Gitea\Repository\Remote; +use VDM\Joomla\Gitea\Repository\Reviewers; +use VDM\Joomla\Gitea\Repository\Reviews; +use VDM\Joomla\Gitea\Repository\Stargazers; +use VDM\Joomla\Gitea\Repository\Statuses; +use VDM\Joomla\Gitea\Repository\Tags; +use VDM\Joomla\Gitea\Repository\Teams; +use VDM\Joomla\Gitea\Repository\Templates; +use VDM\Joomla\Gitea\Repository\Times; +use VDM\Joomla\Gitea\Repository\Topics; +use VDM\Joomla\Gitea\Repository\Transfer; +use VDM\Joomla\Gitea\Repository\Trees; +use VDM\Joomla\Gitea\Repository\Watchers; +use VDM\Joomla\Gitea\Repository\Wiki; + + +/** + * The Gitea Repository Service + * + * @since 3.2.0 + */ +class Repository implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Repo::class, 'Gitea.Repository') + ->share('Gitea.Repository', [$this, 'getRepository'], true); + + $container->alias(Archive::class, 'Gitea.Repository.Archive') + ->share('Gitea.Repository.Archive', [$this, 'getArchive'], true); + + $container->alias(Assignees::class, 'Gitea.Repository.Assignees') + ->share('Gitea.Repository.Assignees', [$this, 'getAssignees'], true); + + $container->alias(Attachments::class, 'Gitea.Repository.Attachments') + ->share('Gitea.Repository.Attachments', [$this, 'getAttachments'], true); + + $container->alias(Branch::class, 'Gitea.Repository.Branch') + ->share('Gitea.Repository.Branch', [$this, 'getBranch'], true); + + $container->alias(Protection::class, 'Gitea.Repository.Branch.Protection') + ->share('Gitea.Repository.Branch.Protection', [$this, 'getProtection'], true); + + $container->alias(Collaborator::class, 'Gitea.Repository.Collaborator') + ->share('Gitea.Repository.Collaborator', [$this, 'getCollaborator'], true); + + $container->alias(Commits::class, 'Gitea.Repository.Commits') + ->share('Gitea.Repository.Commits', [$this, 'getCommits'], true); + + $container->alias(Contents::class, 'Gitea.Repository.Contents') + ->share('Gitea.Repository.Contents', [$this, 'getContents'], true); + + $container->alias(Forks::class, 'Gitea.Repository.Forks') + ->share('Gitea.Repository.Forks', [$this, 'getForks'], true); + + $container->alias(Gpg::class, 'Gitea.Repository.Gpg') + ->share('Gitea.Repository.Gpg', [$this, 'getGpg'], true); + + $container->alias(Hooks::class, 'Gitea.Repository.Hooks') + ->share('Gitea.Repository.Hooks', [$this, 'getHooks'], true); + + $container->alias(Git::class, 'Gitea.Repository.Hooks.Git') + ->share('Gitea.Repository.Hooks.Git', [$this, 'getGit'], true); + + $container->alias(Keys::class, 'Gitea.Repository.Keys') + ->share('Gitea.Repository.Keys', [$this, 'getKeys'], true); + + $container->alias(Languages::class, 'Gitea.Repository.Languages') + ->share('Gitea.Repository.Languages', [$this, 'getLanguages'], true); + + $container->alias(Media::class, 'Gitea.Repository.Media') + ->share('Gitea.Repository.Media', [$this, 'getMedia'], true); + + $container->alias(Merge::class, 'Gitea.Repository.Merge') + ->share('Gitea.Repository.Merge', [$this, 'getMerge'], true); + + $container->alias(Mirror::class, 'Gitea.Repository.Mirror') + ->share('Gitea.Repository.Mirror', [$this, 'getMirror'], true); + + $container->alias(Mirrors::class, 'Gitea.Repository.Mirrors') + ->share('Gitea.Repository.Mirrors', [$this, 'getMirrors'], true); + + $container->alias(Notes::class, 'Gitea.Repository.Notes') + ->share('Gitea.Repository.Notes', [$this, 'getNotes'], true); + + $container->alias(Patch::class, 'Gitea.Repository.Patch') + ->share('Gitea.Repository.Patch', [$this, 'getPatch'], true); + + $container->alias(Pulls::class, 'Gitea.Repository.Pulls') + ->share('Gitea.Repository.Pulls', [$this, 'getPulls'], true); + + $container->alias(Refs::class, 'Gitea.Repository.Refs') + ->share('Gitea.Repository.Refs', [$this, 'getRefs'], true); + + $container->alias(Releases::class, 'Gitea.Repository.Releases') + ->share('Gitea.Repository.Releases', [$this, 'getReleases'], true); + + $container->alias(Remote::class, 'Gitea.Repository.Remote') + ->share('Gitea.Repository.Remote', [$this, 'getRemote'], true); + + $container->alias(Reviewers::class, 'Gitea.Repository.Reviewers') + ->share('Gitea.Repository.Reviewers', [$this, 'getReviewers'], true); + + $container->alias(Reviews::class, 'Gitea.Repository.Reviews') + ->share('Gitea.Repository.Reviews', [$this, 'getReviews'], true); + + $container->alias(Stargazers::class, 'Gitea.Repository.Stargazers') + ->share('Gitea.Repository.Stargazers', [$this, 'getStargazers'], true); + + $container->alias(Statuses::class, 'Gitea.Repository.Statuses') + ->share('Gitea.Repository.Statuses', [$this, 'getStatuses'], true); + + $container->alias(Tags::class, 'Gitea.Repository.Tags') + ->share('Gitea.Repository.Tags', [$this, 'getTags'], true); + + $container->alias(Teams::class, 'Gitea.Repository.Teams') + ->share('Gitea.Repository.Teams', [$this, 'getTeams'], true); + + $container->alias(Templates::class, 'Gitea.Repository.Templates') + ->share('Gitea.Repository.Templates', [$this, 'getTemplates'], true); + + $container->alias(Times::class, 'Gitea.Repository.Times') + ->share('Gitea.Repository.Times', [$this, 'getTimes'], true); + + $container->alias(Topics::class, 'Gitea.Repository.Topics') + ->share('Gitea.Repository.Topics', [$this, 'getTopics'], true); + + $container->alias(Transfer::class, 'Gitea.Repository.Transfer') + ->share('Gitea.Repository.Transfer', [$this, 'getTransfer'], true); + + $container->alias(Trees::class, 'Gitea.Repository.Trees') + ->share('Gitea.Repository.Trees', [$this, 'getTrees'], true); + + $container->alias(Watchers::class, 'Gitea.Repository.Watchers') + ->share('Gitea.Repository.Watchers', [$this, 'getWatchers'], true); + + $container->alias(Wiki::class, 'Gitea.Repository.Wiki') + ->share('Gitea.Repository.Wiki', [$this, 'getWiki'], true); + } + + /** + * Get the Repository class + * + * @param Container $container The DI container. + * + * @return Repo + * @since 3.2.0 + */ + public function getRepository(Container $container): Repo + { + return new Repo( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Archive class + * + * @param Container $container The DI container. + * + * @return Archive + * @since 3.2.0 + */ + public function getArchive(Container $container): Archive + { + return new Archive( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Assignees class + * + * @param Container $container The DI container. + * + * @return Assignees + * @since 3.2.0 + */ + public function getAssignees(Container $container): Assignees + { + return new Assignees( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Attachments class + * + * @param Container $container The DI container. + * + * @return Attachments + * @since 3.2.0 + */ + public function getAttachments(Container $container): Attachments + { + return new Attachments( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Branch class + * + * @param Container $container The DI container. + * + * @return Branch + * @since 3.2.0 + */ + public function getBranch(Container $container): Branch + { + return new Branch( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Branch Protection class + * + * @param Container $container The DI container. + * + * @return Protection + * @since 3.2.0 + */ + public function getProtection(Container $container): Protection + { + return new Protection( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Collaborator class + * + * @param Container $container The DI container. + * + * @return Collaborator + * @since 3.2.0 + */ + public function getCollaborator(Container $container): Collaborator + { + return new Collaborator( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Commits class + * + * @param Container $container The DI container. + * + * @return Commits + * @since 3.2.0 + */ + public function getCommits(Container $container): Commits + { + return new Commits( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Contents class + * + * @param Container $container The DI container. + * + * @return Contents + * @since 3.2.0 + */ + public function getContents(Container $container): Contents + { + return new Contents( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Forks class + * + * @param Container $container The DI container. + * + * @return Forks + * @since 3.2.0 + */ + public function getForks(Container $container): Forks + { + return new Forks( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Gpg class + * + * @param Container $container The DI container. + * + * @return Gpg + * @since 3.2.0 + */ + public function getGpg(Container $container): Gpg + { + return new Gpg( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Hooks class + * + * @param Container $container The DI container. + * + * @return Hooks + * @since 3.2.0 + */ + public function getHooks(Container $container): Hooks + { + return new Hooks( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Hooks Git class + * + * @param Container $container The DI container. + * + * @return Git + * @since 3.2.0 + */ + public function getGit(Container $container): Git + { + return new Git( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Keys class + * + * @param Container $container The DI container. + * + * @return Keys + * @since 3.2.0 + */ + public function getKeys(Container $container): Keys + { + return new Keys( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Languages class + * + * @param Container $container The DI container. + * + * @return Languages + * @since 3.2.0 + */ + public function getLanguages(Container $container): Languages + { + return new Languages( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Media class + * + * @param Container $container The DI container. + * + * @return Media + * @since 3.2.0 + */ + public function getMedia(Container $container): Media + { + return new Media( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Merge class + * + * @param Container $container The DI container. + * + * @return Merge + * @since 3.2.0 + */ + public function getMerge(Container $container): Merge + { + return new Merge( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Mirror class + * + * @param Container $container The DI container. + * + * @return Mirror + * @since 3.2.0 + */ + public function getMirror(Container $container): Mirror + { + return new Mirror( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Mirrors class + * + * @param Container $container The DI container. + * + * @return Mirrors + * @since 3.2.0 + */ + public function getMirrors(Container $container): Mirrors + { + return new Mirrors( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Notes class + * + * @param Container $container The DI container. + * + * @return Notes + * @since 3.2.0 + */ + public function getNotes(Container $container): Notes + { + return new Notes( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Patch class + * + * @param Container $container The DI container. + * + * @return Patch + * @since 3.2.0 + */ + public function getPatch(Container $container): Patch + { + return new Patch( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Pulls class + * + * @param Container $container The DI container. + * + * @return Pulls + * @since 3.2.0 + */ + public function getPulls(Container $container): Pulls + { + return new Pulls( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Refs class + * + * @param Container $container The DI container. + * + * @return Refs + * @since 3.2.0 + */ + public function getRefs(Container $container): Refs + { + return new Refs( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Releases class + * + * @param Container $container The DI container. + * + * @return Releases + * @since 3.2.0 + */ + public function getReleases(Container $container): Releases + { + return new Releases( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Remote class + * + * @param Container $container The DI container. + * + * @return Remote + * @since 3.2.0 + */ + public function getRemote(Container $container): Remote + { + return new Remote( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Reviewers class + * + * @param Container $container The DI container. + * + * @return Reviewers + * @since 3.2.0 + */ + public function getReviewers(Container $container): Reviewers + { + return new Reviewers( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Reviews class + * + * @param Container $container The DI container. + * + * @return Reviews + * @since 3.2.0 + */ + public function getReviews(Container $container): Reviews + { + return new Reviews( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Stargazers class + * + * @param Container $container The DI container. + * + * @return Stargazers + * @since 3.2.0 + */ + public function getStargazers(Container $container): Stargazers + { + return new Stargazers( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Statuses class + * + * @param Container $container The DI container. + * + * @return Statuses + * @since 3.2.0 + */ + public function getStatuses(Container $container): Statuses + { + return new Statuses( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Tags class + * + * @param Container $container The DI container. + * + * @return Tags + * @since 3.2.0 + */ + public function getTags(Container $container): Tags + { + return new Tags( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Teams class + * + * @param Container $container The DI container. + * + * @return Teams + * @since 3.2.0 + */ + public function getTeams(Container $container): Teams + { + return new Teams( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Templates class + * + * @param Container $container The DI container. + * + * @return Templates + * @since 3.2.0 + */ + public function getTemplates(Container $container): Templates + { + return new Templates( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Times class + * + * @param Container $container The DI container. + * + * @return Times + * @since 3.2.0 + */ + public function getTimes(Container $container): Times + { + return new Times( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Topics class + * + * @param Container $container The DI container. + * + * @return Topics + * @since 3.2.0 + */ + public function getTopics(Container $container): Topics + { + return new Topics( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Transfer class + * + * @param Container $container The DI container. + * + * @return Transfer + * @since 3.2.0 + */ + public function getTransfer(Container $container): Transfer + { + return new Transfer( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Trees class + * + * @param Container $container The DI container. + * + * @return Trees + * @since 3.2.0 + */ + public function getTrees(Container $container): Trees + { + return new Trees( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Watchers class + * + * @param Container $container The DI container. + * + * @return Watchers + * @since 3.2.0 + */ + public function getWatchers(Container $container): Watchers + { + return new Watchers( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Wiki class + * + * @param Container $container The DI container. + * + * @return Wiki + * @since 3.2.0 + */ + public function getWiki(Container $container): Wiki + { + return new Wiki( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Settings.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Settings.php new file mode 100644 index 000000000..e4b1a7e46 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Settings.php @@ -0,0 +1,123 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Settings\Api; +use VDM\Joomla\Gitea\Settings\Attachment; +use VDM\Joomla\Gitea\Settings\Repository; +use VDM\Joomla\Gitea\Settings\Ui; + + +/** + * The Gitea Settings Service + * + * @since 3.2.0 + */ +class Settings implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Api::class, 'Gitea.Settings.Api') + ->share('Gitea.Settings.Api', [$this, 'getApi'], true); + + $container->alias(Attachment::class, 'Gitea.Settings.Attachment') + ->share('Gitea.Settings.Attachment', [$this, 'getAttachment'], true); + + $container->alias(Repository::class, 'Gitea.Settings.Repository') + ->share('Gitea.Settings.Repository', [$this, 'getRepository'], true); + + $container->alias(Ui::class, 'Gitea.Settings.Ui') + ->share('Gitea.Settings.Ui', [$this, 'getUi'], true); + } + + /** + * Get the Api class + * + * @param Container $container The DI container. + * + * @return Api + * @since 3.2.0 + */ + public function getApi(Container $container): Api + { + return new Api( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Attachment class + * + * @param Container $container The DI container. + * + * @return Attachment + * @since 3.2.0 + */ + public function getAttachment(Container $container): Attachment + { + return new Attachment( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Repository class + * + * @param Container $container The DI container. + * + * @return Repository + * @since 3.2.0 + */ + public function getRepository(Container $container): Repository + { + return new Repository( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Ui class + * + * @param Container $container The DI container. + * + * @return Ui + * @since 3.2.0 + */ + public function getUi(Container $container): Ui + { + return new Ui( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/User.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/User.php new file mode 100644 index 000000000..63bc120a9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/User.php @@ -0,0 +1,332 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\User as Usr; +use VDM\Joomla\Gitea\User\Applications; +use VDM\Joomla\Gitea\User\Emails; +use VDM\Joomla\Gitea\User\Followers; +use VDM\Joomla\Gitea\User\Following; +use VDM\Joomla\Gitea\User\Gpg; +use VDM\Joomla\Gitea\User\Keys; +use VDM\Joomla\Gitea\User\Repos; +use VDM\Joomla\Gitea\User\Settings; +use VDM\Joomla\Gitea\User\Starred; +use VDM\Joomla\Gitea\User\Subscriptions; +use VDM\Joomla\Gitea\User\Teams; +use VDM\Joomla\Gitea\User\Times; +use VDM\Joomla\Gitea\User\Tokens; + + +/** + * The Gitea User Service + * + * @since 3.2.0 + */ +class User implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Usr::class, 'Gitea.User') + ->share('Gitea.User', [$this, 'getUser'], true); + + $container->alias(Applications::class, 'Gitea.User.Applications') + ->share('Gitea.User.Applications', [$this, 'getApplications'], true); + + $container->alias(Emails::class, 'Gitea.User.Emails') + ->share('Gitea.User.Emails', [$this, 'getEmails'], true); + + $container->alias(Followers::class, 'Gitea.User.Followers') + ->share('Gitea.User.Followers', [$this, 'getFollowers'], true); + + $container->alias(Following::class, 'Gitea.User.Following') + ->share('Gitea.User.Following', [$this, 'getFollowing'], true); + + $container->alias(Gpg::class, 'Gitea.User.Gpg') + ->share('Gitea.User.Gpg', [$this, 'getGpg'], true); + + $container->alias(Keys::class, 'Gitea.User.Keys') + ->share('Gitea.User.Keys', [$this, 'getKeys'], true); + + $container->alias(Repos::class, 'Gitea.User.Repos') + ->share('Gitea.User.Repos', [$this, 'getRepos'], true); + + $container->alias(Settings::class, 'Gitea.User.Settings') + ->share('Gitea.User.Settings', [$this, 'getSettings'], true); + + $container->alias(Starred::class, 'Gitea.User.Starred') + ->share('Gitea.User.Starred', [$this, 'getStarred'], true); + + $container->alias(Subscriptions::class, 'Gitea.User.Subscriptions') + ->share('Gitea.User.Subscriptions', [$this, 'getSubscriptions'], true); + + $container->alias(Teams::class, 'Gitea.User.Teams') + ->share('Gitea.User.Teams', [$this, 'getTeams'], true); + + $container->alias(Times::class, 'Gitea.User.Times') + ->share('Gitea.User.Times', [$this, 'getTimes'], true); + + $container->alias(Tokens::class, 'Gitea.User.Tokens') + ->share('Gitea.User.Tokens', [$this, 'getTokens'], true); + } + + /** + * Get the User class + * + * @param Container $container The DI container. + * + * @return Usr + * @since 3.2.0 + */ + public function getUser(Container $container): Usr + { + return new Usr( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Applications class + * + * @param Container $container The DI container. + * + * @return Applications + * @since 3.2.0 + */ + public function getApplications(Container $container): Applications + { + return new Applications( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Emails class + * + * @param Container $container The DI container. + * + * @return Emails + * @since 3.2.0 + */ + public function getEmails(Container $container): Emails + { + return new Emails( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Followers class + * + * @param Container $container The DI container. + * + * @return Followers + * @since 3.2.0 + */ + public function getFollowers(Container $container): Followers + { + return new Followers( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Following class + * + * @param Container $container The DI container. + * + * @return Following + * @since 3.2.0 + */ + public function getFollowing(Container $container): Following + { + return new Following( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Gpg class + * + * @param Container $container The DI container. + * + * @return Gpg + * @since 3.2.0 + */ + public function getGpg(Container $container): Gpg + { + return new Gpg( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Keys class + * + * @param Container $container The DI container. + * + * @return Keys + * @since 3.2.0 + */ + public function getKeys(Container $container): Keys + { + return new Keys( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Repos class + * + * @param Container $container The DI container. + * + * @return Repos + * @since 3.2.0 + */ + public function getRepos(Container $container): Repos + { + return new Repos( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Settings class + * + * @param Container $container The DI container. + * + * @return Settings + * @since 3.2.0 + */ + public function getSettings(Container $container): Settings + { + return new Settings( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Starred class + * + * @param Container $container The DI container. + * + * @return Starred + * @since 3.2.0 + */ + public function getStarred(Container $container): Starred + { + return new Starred( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Subscriptions class + * + * @param Container $container The DI container. + * + * @return Subscriptions + * @since 3.2.0 + */ + public function getSubscriptions(Container $container): Subscriptions + { + return new Subscriptions( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Teams class + * + * @param Container $container The DI container. + * + * @return Teams + * @since 3.2.0 + */ + public function getTeams(Container $container): Teams + { + return new Teams( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Times class + * + * @param Container $container The DI container. + * + * @return Times + * @since 3.2.0 + */ + public function getTimes(Container $container): Times + { + return new Times( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + + /** + * Get the Tokens class + * + * @param Container $container The DI container. + * + * @return Tokens + * @since 3.2.0 + */ + public function getTokens(Container $container): Tokens + { + return new Tokens( + $container->get('Gitea.Utilities.Http'), + $container->get('Gitea.Dynamic.Uri'), + $container->get('Gitea.Utilities.Response') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Utilities.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Utilities.php new file mode 100644 index 000000000..09112d2b7 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/Utilities.php @@ -0,0 +1,72 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Utilities\Uri; +use VDM\Joomla\Gitea\Utilities\Response; + + +/** + * The Gitea Utilities Service + * + * @since 3.2.0 + */ +class Utilities implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Uri::class, 'Gitea.Utilities.Uri') + ->share('Gitea.Utilities.Uri', [$this, 'getUri'], true); + + $container->alias(Response::class, 'Gitea.Utilities.Response') + ->share('Gitea.Utilities.Response', [$this, 'getResponse'], true); + } + + /** + * Get the Uri class + * + * @param Container $container The DI container. + * + * @return Uri + * @since 3.2.0 + */ + public function getUri(Container $container): Uri + { + return new Uri(); + } + + /** + * Get the Response class + * + * @param Container $container The DI container. + * + * @return Response + * @since 3.2.0 + */ + public function getResponse(Container $container): Response + { + return new Response(); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Service/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Api.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Api.php new file mode 100644 index 000000000..cf2d56f96 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Api.php @@ -0,0 +1,45 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Settings; + + +use VDM\Joomla\Gitea\Abstraction\Api as BaseAPI; + + +/** + * The Gitea Settings Api + * + * @since 3.2.0 + */ +class Api extends BaseAPI +{ + /** + * Get instance's global settings for API. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(): ?object + { + // Build the request path. + $path = "/settings/api"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Attachment.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Attachment.php new file mode 100644 index 000000000..921938821 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Attachment.php @@ -0,0 +1,45 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Settings; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Settings Attachment + * + * @since 3.2.0 + */ +class Attachment extends Api +{ + /** + * Get instance's global settings for Attachment. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(): ?object + { + // Build the request path. + $path = "/settings/attachment"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Repository.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Repository.php new file mode 100644 index 000000000..adbf90846 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Repository.php @@ -0,0 +1,45 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Settings; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Settings Repository + * + * @since 3.2.0 + */ +class Repository extends Api +{ + /** + * Get instance's global settings for repositories. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(): ?object + { + // Build the request path. + $path = "/settings/repository"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Ui.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Ui.php new file mode 100644 index 000000000..def2668c0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/Ui.php @@ -0,0 +1,45 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Settings; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea Settings Ui + * + * @since 3.2.0 + */ +class Ui extends Api +{ + /** + * Get instance's global settings for UI. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(): ?object + { + // Build the request path. + $path = "/settings/ui"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Settings/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User.php new file mode 100644 index 000000000..bb9c82e7a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User.php @@ -0,0 +1,335 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User + * + * @since 3.2.0 + */ +class User extends Api +{ + /** + * Get the authenticated user. + * + * @return object|null + * @since 3.2.0 + **/ + public function authenticate(): ?object + { + // Build the request path. + $path = '/user'; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Search for users. + * + * @param string $keyword The search keyword. + * @param int|null $uid Optional. ID of the user to search for. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return object|null + * @since 3.2.0 + **/ + public function search( + string $keyword, + ?int $uid = null, + int $page = 1, + int $limit = 10 + ): ?object + { + // Build the request path. + $path = '/users/search'; + + // Build the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('q', $keyword); + + if ($uid !== null) + { + $uri->setVar('uid', $uid); + } + + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get a user by their username. + * + * @param string $username The username of the user to retrieve. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(string $username): o?bject + { + // Build the request path. + $path = "/users/{$username}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * List the given user's followers. + * + * @param string $userName The username of the user to retrieve followers for. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function followers( + string $userName, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/users/{$userName}/followers"; + + // Build the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * List the users that the given user is following. + * + * @param string $userName The username of the user to retrieve the following users for. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function following( + string $userName, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/users/{$userName}/following"; + + // Build the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Check if one user is following another user. + * + * @param string $username The username of the user to check. + * @param string $target The username of the target user. + * + * @return string + * @since 3.2.0 + **/ + public function check(string $username, string $target): string + { + // Build the request path. + $path = "/users/{$username}/following/{$target}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * List the given user's GPG keys. + * + * @param string $userName The username of the user to retrieve GPG keys for. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function gpg( + string $userName, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/users/{$userName}/gpg_keys"; + + // Build the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get a user's heatmap. + * + * @param string $username The username of the user to retrieve heatmap for. + * + * @return array|null + * @since 3.2.0 + **/ + public function heatmap(string $username): ?array + { + // Build the request path. + $path = "/users/{$username}/heatmap"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * List the given user's public keys. + * + * @param string $userName The username of the user to retrieve public keys for. + * @param string|null $fingerprint Optional. The fingerprint of the key. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function keys( + string $userName, + ?string $fingerprint = null, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/users/{$userName}/keys"; + + // Build the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + if ($fingerprint !== null) + { + $uri->setVar('fingerprint', $fingerprint); + } + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * List the repos that the given user has starred. + * + * @param string $userName The username of the user to retrieve starred repos for. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function repos( + string $userName, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/users/{$userName}/starred"; + + // Build the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * List the repositories watched by a user. + * + * @param string $userName The username of the user to retrieve watched repositories for. + * @param int $page The page number of results to return (1-based). + * @param int $limit The page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function watched( + string $userName, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = "/users/{$userName}/subscriptions"; + + // Build the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Applications.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Applications.php new file mode 100644 index 000000000..10d8dc600 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Applications.php @@ -0,0 +1,166 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Applications + * + * @since 3.2.0 + */ +class Applications extends Api +{ + /** + * List the authenticated user's oauth2 applications. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function get( + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/user/applications/oauth2'; + + // Build the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get an OAuth2 application by ID. + * + * @param int $id The OAuth2 application ID. + * + * @return object|null + * @since 3.2.0 + **/ + public function id(int $id): ?object + { + // Build the request path. + $path = "/user/applications/oauth2/{$id}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Creates a new OAuth2 application. + * + * @param string $appName The application name. + * @param array $redirectUris The application redirect URIs. + * @param bool $confidentialClient The confidentiality of the client (default: true). + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $appName, + array $redirectUris, + bool $confidentialClient = true + ): ?object + { + // Build the request path. + $path = '/user/applications/oauth2'; + + // Set the application data. + $data = new \stdClass(); + $data->name = $appName; + $data->redirect_uris = $redirectUris; + $data->confidential_client = $confidentialClient; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * Delete an OAuth2 application by ID. + * + * @param int $id The OAuth2 application ID. + * + * @return string + * @since 3.2.0 + **/ + public function delete(int $id): string + { + // Build the request path. + $path = "/user/applications/oauth2/{$id}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + + /** + * Update an OAuth2 application by ID, this includes regenerating the client secret. + * + * @param int $appId The OAuth2 application ID. + * @param string $appName The application name. + * @param array $redirectUris The application redirect URIs. + * @param bool $confidentialClient The confidentiality of the client (default: true). + * + * @return object|null + * @since 3.2.0 + **/ + public function update( + int $appId, + string $appName, + array $redirectUris, + bool $confidentialClient = true + ): ?object + { + // Build the request path. + $path = "/user/applications/oauth2/{$appId}"; + + // Set the application data. + $data = new \stdClass(); + $data->name = $appName; + $data->redirect_uris = $redirectUris; + $data->confidential_client = $confidentialClient; + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), + json_encode($data) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Emails.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Emails.php new file mode 100644 index 000000000..aa63b288a --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Emails.php @@ -0,0 +1,94 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Emails + * + * @since 3.2.0 + */ +class Emails extends Api +{ + /** + * List the authenticated user's email addresses. + * + * @return array|null + * @since 3.2.0 + **/ + public function list(): ?array + { + // Build the request path. + $path = '/user/emails'; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Add email addresses for the authenticated user. + * + * @param array $emails An array of email addresses to add. + * + * @return array|null + * @since 3.2.0 + **/ + public function add(array $emails): ?array + { + // Build the request path. + $path = '/user/emails'; + + // Create the request body. + $body = new \stdClass(); + $body->emails = $emails; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($body) + ), 201 + ); + } + + /** + * Delete email addresses for the authenticated user. + * + * @param array $$emails An array of email addresses to delete. + * + * @return string + * @since 3.2.0 + **/ + public function delete(array $emails): string + { + // Build the request path. + $path = '/user/emails'; + + // Build the URI. + $uri = $this->uri->get($path); + $uri->setVar('emails', json_encode($emails)); + + // Send the delete request. + return $this->response->get( + $this->http->delete($uri), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Followers.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Followers.php new file mode 100644 index 000000000..71b028a28 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Followers.php @@ -0,0 +1,54 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Followers + * + * @since 3.2.0 + */ +class Followers extends Api +{ + /** + * List the authenticated user's followers. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/user/followers'; + + // Build the URL + $url = $this->uri->get($path); + $url->setVar('page', $page); + $url->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Following.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Following.php new file mode 100644 index 000000000..339244969 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Following.php @@ -0,0 +1,122 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Following + * + * @since 3.2.0 + */ +class Following extends Api +{ + /** + * List the users that the authenticated user is following. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/user/following'; + + // Build the URL + $url = $this->uri->get($path); + $url->setVar('page', $page); + $url->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + + /** + * Check whether a user is followed by the authenticated user. + * + * @param string $username The username to check. + * + * @return bool + * @since 3.2.0 + **/ + public function check(string $username): bool + { + // Build the request path. + $path = "/user/following/{$username}"; + + // Send the get request. + $response = $this->http->get( + $this->uri->get($path) + ); + + // Check if the user is followed by the authenticated user. + if ($response->code === 204) + { + return true; + } + return false; + } + + /** + * Follow a user. + * + * @param string $username The username to follow. + * + * @return string + * @since 3.2.0 + **/ + public function follow(string $username): string + { + // Build the request path. + $path = "/user/following/{$username}"; + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), '' + ), 204, 'success' + ); + } + + /** + * Unfollow a user. + * + * @param string $username The username to unfollow. + * + * @return string + * @since 3.2.0 + **/ + public function unfollow(string $username): string + { + // Build the request path. + $path = "/user/following/{$username}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Gpg.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Gpg.php new file mode 100644 index 000000000..bf8f6c671 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Gpg.php @@ -0,0 +1,173 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Gpg + * + * @since 3.2.0 + */ +class Gpg extends Api +{ + /** + * Create a GPG key for the authenticated user. + * + * @param string $armoredPublicKey The armored public GPG key. + * @param string|null $armoredSignature The armored signature (optional). + * + * @return object|null + * @since 3.2.0 + **/ + public function createGPGKey( + string $armoredPublicKey, + ?string $armoredSignature = null + ): ?object + { + // Build the request path. + $path = '/user/gpg_keys'; + + // Set the GPG key data. + $data = array_filter([ + 'armored_public_key' => $armoredPublicKey, + 'armored_signature' => $armoredSignature + ]); + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * Get a GPG key for the authenticated user. + * + * @param int $id The GPG key ID. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(int $id): ?object + { + // Build the request path. + $path = "/user/gpg_keys/{$id}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Get a token to verify. + * + * @return string|null + * @since 3.2.0 + **/ + public function token(): ?string + { + // Build the request path. + $path = '/user/gpg_key_token'; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Verify a GPG key. + * + * @param string $armoredPublicKey The armored public GPG key. + * + * @return object|null + * @since 3.2.0 + **/ + public function verify(string $armoredPublicKey): ?object + { + // Build the request path. + $path = '/user/gpg_key_verify'; + + // Set the GPG key data. + $data = new \stdClass(); + $data->armoredPublicKey = $armoredPublicKey; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * List the authenticated user's GPG keys. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/user/gpg_keys'; + + // Build the URL + $url = $this->uri->get($path); + $url->setVar('page', $page); + $url->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + + /** + * Remove a GPG key for the authenticated user. + * + * @param int $id The GPG key ID. + * + * @return string + * @since 3.2.0 + **/ + public function remove(int $id): string + { + // Build the request path. + $path = "/user/gpg_keys/{$id}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Keys.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Keys.php new file mode 100644 index 000000000..ed22c4033 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Keys.php @@ -0,0 +1,135 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Keys + * + * @since 3.2.0 + */ +class Keys extends Api +{ + /** + * Create a public key for the authenticated user. + * + * @param string $title The title of the public key. + * @param string $key The content of the public key. + * @param bool $readOnly Optional. True if the key has only read access, false for read/write access. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $title, + string $key, + bool $readOnly = false + ): ?object + { + // Build the request path. + $path = '/user/keys'; + + // Set the public key data. + $data = new \stdClass(); + $data->title = $title; + $data->key = $key; + $data->read_only = $readOnly; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * List the authenticated user's public keys. + * + * @param string|null $fingerprint Optional. The fingerprint of the key. + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + ?string $fingerprint = null, + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/user/keys'; + + // Build the URI with query parameters. + $uri = $this->uri->get($path); + if ($fingerprint !== null) { + $uri->setVar('fingerprint', $fingerprint); + } + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Get a public key for the authenticated user. + * + * @param int $id The public key ID. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(int $id): ?object + { + // Build the request path. + $path = "/user/keys/{$id}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Delete a public key for the authenticated user. + * + * @param int $id The public key ID. + * + * @return string + * @since 3.2.0 + **/ + public function delete(int $id): string + { + // Build the request path. + $path = "/user/keys/{$id}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Repos.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Repos.php new file mode 100644 index 000000000..a7f8021c9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Repos.php @@ -0,0 +1,188 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Repos + * + * @since 3.2.0 + */ +class Repos extends Api +{ + /** + * Create a repository for the authenticated user. + * + * @param string $name The name of the repository. + * @param string|null $description Optional. The description of the repository. + * @param bool $private Optional. Indicates whether the repository should be private or not. + * @param bool $autoInit Optional. Indicates whether the repository should be auto-initialized. + * @param string|null $defaultBranch Optional. The default branch of the repository. + * @param string|null $gitignores Optional. Gitignores to use. + * @param string|null $issueLabels Optional. Label-Set to use. + * @param string|null $license Optional. License to use. + * @param string|null $readme Optional. Readme of the repository to create. + * @param bool|null $template Optional. Whether the repository is a template. + * @param string|null $trustModel Optional. TrustModel of the repository. + * + * @return object|null + * @since 3.2.0 + **/ + public function create( + string $name, + ?string $description = null, + bool $private = false, + bool $autoInit = false, + ?string $defaultBranch = null, + ?string $gitignores = null, + ?string $issueLabels = null, + ?string $license = null, + ?string $readme = null, + ?bool $template = null, + ?string $trustModel = null + ): ?object { + // Build the request path. + $path = '/user/repos'; + + // Set the repository data. + $data = new \stdClass(); + $data->name = $name; + + if ($description !== null) + { + $data->description = $description; + } + + $data->private = $private; + $data->auto_init = $autoInit; + + if ($defaultBranch !== null) + { + $data->default_branch = $defaultBranch; + } + + if ($gitignores !== null) + { + $data->gitignores = $gitignores; + } + + if ($issueLabels !== null) + { + $data->issue_labels = $issueLabels; + } + + if ($license !== null) + { + $data->license = $license; + } + + if ($readme !== null) + { + $data->readme = $readme; + } + + if ($template !== null) + { + $data->template = $template; + } + + if ($trustModel !== null) + { + $data->trust_model = $trustModel; + } + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * List the repos that the authenticated user owns. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/user/repos'; + + // Build the URI with query parameters. + $uri = $this->uri->get($path); + $uri->setVar('page', $page); + $uri->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($uri) + ); + } + + /** + * Star the given repo for the authenticated user. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return string + * @since 3.2.0 + **/ + public function star(string $owner, string $repo): string + { + // Build the request path. + $path = "/user/starred/{$owner}/{$repo}"; + + // Send the put request. + return $this->response->get( + $this->http->put( + $this->uri->get($path), '' + ), 204, 'success' + ); + } + + /** + * Unstar the given repo for the authenticated user. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return string + * @since 3.2.0 + **/ + public function unstar(string $owner, string $repo): string + { + // Build the request path. + $path = "/user/starred/{$owner}/{$repo}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Settings.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Settings.php new file mode 100644 index 000000000..2118c9e0e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Settings.php @@ -0,0 +1,124 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Settings + * + * @since 3.2.0 + */ +class Settings extends Api +{ + /** + * Get user settings for the authenticated user. + * + * @return object|null + * @since 3.2.0 + **/ + public function get(): ?object + { + // Build the request path. + $path = '/user/settings'; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ) + ); + } + + /** + * Update user settings for the authenticated user. + * + * @param string|null $description Optional. The description to update. + * @param string|null $diffViewStyle Optional. The diff view style to update. + * @param string|null $fullName Optional. The full name to update. + * @param bool|null $hideActivity Optional. Whether to hide activity or not. + * @param bool|null $hideEmail Optional. Whether to hide email or not. + * @param string|null $language Optional. The language to update. + * @param string|null $location Optional. The location to update. + * @param string|null $theme Optional. The theme to update. + * @param string|null $website Optional. The website to update. + * + * @return array|null + * @since 3.2.0 + **/ + public function update( + ?string $description = null, + ?string $diffViewStyle = null, + ?string $fullName = null, + ?bool $hideActivity = null, + ?bool $hideEmail = null, + ?string $language = null, + ?string $location = null, + ?string $theme = null, + ?string $website = null + ): ?array + { + // Prepare settings data + $settings = []; + if ($description !== null) + { + $settings['description'] = $description; + } + if ($diffViewStyle !== null) + { + $settings['diff_view_style'] = $diffViewStyle; + } + if ($fullName !== null) + { + $settings['full_name'] = $fullName; + } + if ($hideActivity !== null) + { + $settings['hide_activity'] = $hideActivity; + } + if ($hideEmail !== null) + { + $settings['hide_email'] = $hideEmail; + } + if ($language !== null) + { + $settings['language'] = $language; + } + if ($location !== null) + { + $settings['location'] = $location; + } + if ($theme !== null) + { + $settings['theme'] = $theme; + } + if ($website !== null) + { + $settings['website'] = $website; + } + + // Build the request path. + $path = '/user/settings'; + + // Send the patch request. + return $this->response->get( + $this->http->patch( + $this->uri->get($path), + json_encode($settings) + ) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Starred.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Starred.php new file mode 100644 index 000000000..24140662b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Starred.php @@ -0,0 +1,76 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Starred + * + * @since 3.2.0 + */ +class Starred extends Api +{ + /** + * List the repos that the authenticated user has starred. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/user/starred'; + + // Build the URL + $url = $this->uri->get($path); + $url->setVar('page', $page); + $url->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + + /** + * Check whether the authenticated user is starring the repo. + * + * @param string $owner The owner name. + * @param string $repo The repository name. + * + * @return string + * @since 3.2.0 + **/ + public function check(string $owner, string $repo): string + { + // Build the request path. + $path = "/user/starred/{$owner}/{$repo}"; + + // Send the get request. + return $this->response->get( + $this->http->get( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Subscriptions.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Subscriptions.php new file mode 100644 index 000000000..b62780355 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Subscriptions.php @@ -0,0 +1,54 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Subscriptions + * + * @since 3.2.0 + */ +class Subscriptions extends Api +{ + /** + * List repositories watched by the authenticated user. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/user/subscriptions'; + + // Build the URL + $url = $this->uri->get($path); + $url->setVar('page', $page); + $url->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Teams.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Teams.php new file mode 100644 index 000000000..ce3f32be0 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Teams.php @@ -0,0 +1,54 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Teams + * + * @since 3.2.0 + */ +class Teams extends Api +{ + /** + * List all the teams a user belongs to. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/user/teams'; + + // Build the URL + $url = $this->uri->get($path); + $url->setVar('page', $page); + $url->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Times.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Times.php new file mode 100644 index 000000000..027405880 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Times.php @@ -0,0 +1,96 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Times + * + * @since 3.2.0 + */ +class Times extends Api +{ + /** + * List the current user's tracked times. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * @param string|null $since Optional. Only show times updated after the given time (RFC 3339 format). + * @param string|null $before Optional. Only show times updated before the given time (RFC 3339 format). + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + int $page = 1, + int $limit = 10, + ?string $since = null, + ?string $before = null + ): ?array + { + // Build the request path. + $path = '/user/times'; + + // Build the URL + $url = $this->uri->get($path); + $url->setVar('page', $page); + $url->setVar('limit', $limit); + + if ($since !== null) + { + $url->setVar('since', $since); + } + + if ($before !== null) + { + $url->setVar('before', $before); + } + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + + /** + * Get list of all existing stopwatches for the authenticated user. + * + * @param int $page Page number of results to return (1-based). + * @param int $limit Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function stopwatches( + int $page = 1, + int $limit = 10 + ): ?array + { + // Build the request path. + $path = '/user/stopwatches'; + + // Build the URL + $url = $this->uri->get($path); + $url->setVar('page', $page); + $url->setVar('limit', $limit); + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Tokens.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Tokens.php new file mode 100644 index 000000000..431ba71a7 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/Tokens.php @@ -0,0 +1,111 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\User; + + +use VDM\Joomla\Gitea\Abstraction\Api; + + +/** + * The Gitea User Tokens + * + * @since 3.2.0 + */ +class Tokens extends Api +{ + /** + * List the authenticated user's access tokens. + * + * @param string $username The username of the authenticated user to retrieve access tokens for. + * @param int|null $page Optional. Page number of results to return (1-based). + * @param int|null $limit Optional. Page size of results. + * + * @return array|null + * @since 3.2.0 + **/ + public function list( + string $username, + ?int $page = null, + ?int $limit = null + ): ?array + { + // Build the request path. + $path = "/users/{$username}/tokens"; + + // Build the URL + $url = $this->uri->get($path); + if ($page !== null) + { + $url->setVar('page', $page); + } + if ($limit !== null) + { + $url->setVar('limit', $limit); + } + + // Send the get request. + return $this->response->get( + $this->http->get($url) + ); + } + + /** + * Create an access token for a user. + * + * @param string $username The username of the user to create the access token for. + * @param string $name The name of the access token. + * + * @return object|null + * @since 3.2.0 + **/ + public function create(string $username, string $name): ?object + { + // Build the request path. + $path = "/users/{$username}/tokens"; + + // Set the token data + $data = new \stdClass(); + $data->name = $name; + + // Send the post request. + return $this->response->get( + $this->http->post( + $this->uri->get($path), + json_encode($data) + ), 201 + ); + } + + /** + * Delete an access token for a user. + * + * @param string $username The username of the user to delete the access token for. + * @param string $token The token to delete. + * + * @return string + * @since 3.2.0 + **/ + public function delete(string $username, string $token): string + { + // Build the request path. + $path = "/users/{$username}/tokens/{$token}"; + + // Send the delete request. + return $this->response->get( + $this->http->delete( + $this->uri->get($path) + ), 204, 'success' + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/User/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/Http.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/Http.php new file mode 100644 index 000000000..7f0b817b6 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/Http.php @@ -0,0 +1,78 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Utilities; + + +use Joomla\CMS\Http\Http as JoomlaHttp; +use Joomla\Registry\Registry; + + +/** + * The Gitea Http + * + * @since 3.2.0 + */ +final class Http extends JoomlaHttp +{ + /** + * Constructor. + * + * @param string|null $token The Gitea API token. + * + * @since 3.2.0 + * @throws \InvalidArgumentException + **/ + public function __construct(?string $token) + { + // setup config + $config = [ + 'userAgent' => 'JoomlaGitea/3.0', + 'headers' => [ + 'Content-Type' => 'application/json' + ] + ]; + + // add the token if given + if (is_string($token)) + { + $config['headers']['Authorization'] = 'token ' . $token; + } + + $options = new Registry($config); + + // run parent constructor + parent::__construct($options); + } + + /** + * Change the Token. + * + * @param string $token The Gitea API token. + * + * @since 3.2.0 + **/ + public function setToken(string $token) + { + // get the current headers + $headers = (array) $this->getOption('headers', [ + 'Content-Type' => 'application/json' + ] + ); + + // add the token + $headers['Authorization'] = 'token ' . $token; + + $this->setOption('headers', $headers); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/Response.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/Response.php new file mode 100644 index 000000000..5e6d764e3 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/Response.php @@ -0,0 +1,142 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Utilities; + + +use Joomla\CMS\Http\Response as JoomlaResponse; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\StringHelper; + + +/** + * The Gitea Response + * + * @since 3.2.0 + */ +final class Response +{ + /** + * Process the response and decode it. + * + * @param JoomlaResponse $response The response. + * @param integer $expectedCode The expected "good" code. + * @param mixed $default The default if body not have length + * + * @return mixed + * + * @since 3.2.0 + * @throws \DomainException + **/ + public function get(JoomlaResponse $response, int $expectedCode = 200, $default = null) + { + // Validate the response code. + if ($response->code != $expectedCode) + { + // Decode the error response and throw an exception. + $message = $this->error($response); + + throw new \DomainException("Invalid response received from API.$message", $response->code); + + } + + return $this->body($response, $default); + } + + /** + * Process the response and decode it. (when we have multiple success codes) + * + * @param JoomlaResponse $response The response. + * @param array [$expectedCode => $default] The expected "good" code. and The default if body not have length + * + * @return mixed + * + * @since 3.2.0 + * @throws \DomainException + **/ + public function get_(JoomlaResponse $response, array $validate = [200 => null]) + { + // Validate the response code. + if (!isset($validate[$response->code])) + { + // Decode the error response and throw an exception. + $message = $this->error($response); + + throw new \DomainException("Invalid response received from API.$message", $response->code); + + } + + return $this->body($response, $validate[$response->code]); + } + + /** + * Return the body from the response + * + * @param JoomlaResponse $response The response. + * @param mixed $default The default if body not have length + * + * @return mixed + * @since 3.2.0 + **/ + protected function body(JoomlaResponse $response, $default = null) + { + // check that we have a body and that its JSON + if (isset($response->body) && StringHelper::check($response->body)) + { + if (JsonHelper::check($response->body)) + { + $body = json_decode((string) $response->body); + + if (isset($body->content_base64)) + { + $body->content = base64_decode((string) $body->content_base64); + } + + return $body; + } + + return $response->body; + } + + return $default; + } + + /** + * Get the error message from the return object + * + * @param JoomlaResponse $response The response. + * + * @return string + * @since 3.2.0 + **/ + protected function error(JoomlaResponse $response): string + { + // do we have a json string + if (isset($response->body) && JsonHelper::check($response->body)) + { + $error = json_decode($response->body); + } + else + { + return ''; + } + + // check + if (isset($error->error)) + { + return $error->error; + } + + return ''; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/Uri.php b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/Uri.php new file mode 100644 index 000000000..d31ac8e65 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/Uri.php @@ -0,0 +1,140 @@ + + * @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 + */ + +namespace VDM\Joomla\Gitea\Utilities; + + +use Joomla\Uri\Uri as JoomlaUri; + + +/** + * The Gitea Uri + * + * @since 3.2.0 + */ +final class Uri +{ + /** + * The api endpoint + * + * @var string + * @since 3.2.0 + */ + private string $endpoint; + + /** + * The api version + * + * @var string + * @since 3.2.0 + */ + private string $version; + + /** + * The api URL + * + * @var string + * @since 3.2.0 + */ + private string $url; + + /** + * Constructor + * + * @param string $url URL to the gitea system + * example: https://git.vdm.dev + * @param string $endpoint Endpoint to the gitea system + * @param string $version Version to the gitea system + * + * @since 3.2.0 + **/ + public function __construct( + string $url = 'https://git.vdm.dev', + string $endpoint = 'api', + string $version = 'v1') + { + // set the API details + $this->setUrl($url); + $this->setEndpoint($endpoint); + $this->setVersion($version); + } + + /** + * Method to build and return a full request URL for the request. This method will + * add appropriate pagination details if necessary and also prepend the API url + * to have a complete URL for the request. + * + * @param string $path URL to inflect + * + * @return JoomlaUri + * @since 3.2.0 + **/ + public function get(string $path): JoomlaUri + { + // Get a new Uri object focusing the api url and given path. + $uri = new JoomlaUri($this->api() . $path); + + return $uri; + } + + /** + * Get the full API URL + * + * @return string + * @since 3.2.0 + **/ + public function api(): string + { + return $this->url . '/' . $this->endpoint . '/' . $this->version; + } + + /** + * Set the URL of the API + * + * @param string $url URL to your gitea system + * example: https://git.vdm.dev + * + * @return void + * @since 3.2.0 + **/ + public function setUrl(string $url) + { + return $this->url = $url; + } + + /** + * Set the endpoint of the API + * + * @param string $endpoint endpoint to your gitea API + * + * @return void + * @since 3.2.0 + **/ + private function setEndpoint(string $endpoint) + { + return $this->endpoint = $endpoint; + } + + /** + * Set the version of the API + * + * @param string $version version to your gitea API + * + * @return void + * @since 3.2.0 + **/ + private function setVersion($version) + { + return $this->version = $version; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/Utilities/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla.Gitea/src/index.html b/libraries/jcb_powers/VDM.Joomla.Gitea/src/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla.Gitea/src/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/Database.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/Database.php index 5e1453547..eff386940 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/Database.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/Database.php @@ -65,6 +65,11 @@ abstract class Database **/ protected function quote($value) { + if ($value === null) // hmm the null does pose an issue (will keep an eye on this) + { + return 'NULL'; + } + if (is_numeric($value)) { if (filter_var($value, FILTER_VALIDATE_INT)) @@ -76,12 +81,18 @@ abstract class Database return (float) $value; } } - elseif (is_bool($value)) + elseif (is_bool($value)) // not sure if this will work well (but its correct) { - return (int) $value; + return $value ? 'TRUE' : 'FALSE'; } - // default just escape it + // For date and datetime values + if ($value instanceof \DateTime) + { + return $this->db->quote($value->format('Y-m-d H:i:s')); + } + + // For other data types, just escape it return $this->db->quote($value); } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/Mapper.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/Mapper.php index 37f2e0d7a..fec5fdc0c 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/Mapper.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/Mapper.php @@ -32,6 +32,17 @@ abstract class Mapper implements Mapperdoubleinterface, Mappersingleinterface **/ public array $active = []; + /** + * Check if any values are set in the active array + * + * @return bool Returns true if the active array is not empty, false otherwise + * @since 3.2.0 + */ + public function isActive(): bool + { + return !empty($this->active); + } + /** * Set content * @@ -128,6 +139,32 @@ abstract class Mapper implements Mapperdoubleinterface, Mappersingleinterface **/ public array $_active = []; + /** + * Check if any values are set in the active array. + * + * @param string|null $firstKey Optional. The first key to check for values. + * + * @return bool True if the active array or the specified subarray is not empty, false otherwise. + * @since 3.2.0 + */ + public function isActive_(string $firstKey = null): bool + { + // If a firstKey is provided, check if it has any values. + if (is_string($firstKey)) + { + // Get the first key from the input parameter and check if it exists in the active array. + $firstKey = $this->firstKey($firstKey); + if (isset($this->_active[$firstKey])) + { + return !empty($this->_active[$firstKey]); + } + return false; + } + + // If no firstKey is provided, check if the entire active array has any values. + return !empty($this->_active); + } + /** * Set dynamic content * diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/MapperSingle.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/MapperSingle.php index a7c347a04..988644fd4 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/MapperSingle.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/MapperSingle.php @@ -31,6 +31,17 @@ abstract class MapperSingle implements Mappersingleinterface **/ public array $active = []; + /** + * Check if any values are set in the active array + * + * @return bool Returns true if the active array is not empty, false otherwise + * @since 3.2.0 + */ + public function isActive(): bool + { + return !empty($this->active); + } + /** * Set content * diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/Model.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/Model.php index a15d16208..82636ba3e 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/Model.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Abstraction/Model.php @@ -67,7 +67,7 @@ abstract class Model /** * Model the values of an item - * Example: $this->item('table_name', Object); + * Example: $this->item(Object, 'table_name'); * * @param object $item The item object * @param string|null $table The table @@ -83,35 +83,42 @@ abstract class Model $table = $this->getTable(); } - // field counter - $field_number = 0; - - // check if this is a valid table - if (($fields = $this->getTableFields($table)) !== null) + if (($fields = $this->getTableFields($table, true)) !== null) { + // field counter + $field_number = 0; + + // check if this is a valid table + $item_bucket = new \stdClass(); + foreach ($fields as $field) { // model a value if it exists if(isset($item->{$field})) { + if (!$this->validateBefore($item->{$field}, $field, $table)) + { + continue; + } + $item->{$field} = $this->value($item->{$field}, $field, $table); - if ($this->validate($item->{$field})) + if (!$this->validateAfter($item->{$field}, $field, $table)) { - $field_number++; - } - else - { - unset($item->{$field}); + continue; } + + $item_bucket->{$field} = $item->{$field}; + + $field_number++; } } - } - // all items must have more than one field or its empty (1 = id) - if ($field_number > 1) - { - return $item; + // all items must have more than one field or its empty (1 = id or guid) + if ($field_number > 1) + { + return $item_bucket; + } } return null; @@ -144,7 +151,110 @@ abstract class Model if (($item = $this->item($item, $table)) !== null) { // add the last ID - $this->last[$table] = $item->id; + $this->last[$table] = $item->id ?? $this->last[$table] ?? null; + } + else + { + unset($items[$id]); + } + } + + if (ArrayHelper::check($items)) + { + return $items; + } + } + + return null; + } + + /** + * Model the values of an row + * Example: $this->item(Array, 'table_name'); + * + * @param array $item The item array + * @param string|null $table The table + * + * @return array|null + * @since 3.2.0 + */ + public function row(array $item, ?string $table = null): ?array + { + // set the table name + if (empty($table)) + { + $table = $this->getTable(); + } + + if (($fields = $this->getTableFields($table, true)) !== null) + { + // field counter + $field_number = 0; + + // check if this is a valid table + $item_bucket = []; + + foreach ($fields as $field) + { + // model a value if it exists + if(isset($item[$field])) + { + if (!$this->validateBefore($item[$field], $field, $table)) + { + continue; + } + + $item[$field] = $this->value($item[$field], $field, $table); + + if (!$this->validateAfter($item[$field], $field, $table)) + { + continue; + } + + $item_bucket[$field] = $item[$field]; + + $field_number++; + } + } + + // all items must have more than one field or its empty (1 = id or guid) + if ($field_number > 1) + { + return $item_bucket; + } + } + + return null; + } + + /** + * Model the values of multiple rows + * Example: $this->items(Array, 'table_name'); + * + * @param array|null $items The array of item array + * @param string|null $table The table + * + * @return array|null + * @since 3.2.0 + */ + public function rows(?array $items = null, ?string $table = null): ?array + { + // check if this is a valid table + if (ArrayHelper::check($items)) + { + // set the table name + if (empty($table)) + { + $table = $this->getTable(); + } + + foreach ($items as $id => &$item) + { + // model the item + if (($item = $this->row($item, $table)) !== null) + { + // add the last ID + $this->last[$table] = $item['id'] ?? $this->last[$table] ?? null; } else { @@ -188,7 +298,21 @@ abstract class Model } /** - * Validate the values (basic, override in child class) + * Get the current active table's fields (including defaults) + * + * @param string $table The area + * @param bool $default Add the default fields + * + * @return array + * @since 3.2.0 + */ + protected function getTableFields(string $table, bool $default = false): ?array + { + return $this->table->fields($table, $default); + } + + /** + * Validate before the value is modelled (basic, override in child class) * * @param mixed $value The field value * @param string|null $field The field key @@ -197,29 +321,19 @@ abstract class Model * @return bool * @since 3.2.0 */ - protected function validate(&$value, ?string $field = null, ?string $table = null): bool - { - // check values - if (StringHelper::check($value) || ArrayHelper::check($value, true)) - { - return true; - } - // remove empty values - return false; - } + abstract protected function validateBefore(&$value, ?string $field = null, ?string $table = null): bool; /** - * Get the current active table's fields + * Validate after the value is modelled (basic, override in child class) * - * @param string $table The table + * @param mixed $value The field value + * @param string|null $field The field key + * @param string|null $table The table * - * @return array + * @return bool * @since 3.2.0 */ - protected function getTableFields(string $table): ?array - { - return $this->table->fields($table); - } + abstract protected function validateAfter(&$value, ?string $field = null, ?string $table = null): bool; /** * Get the current active table diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Update/Mysql.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Update/Mysql.php new file mode 100644 index 000000000..8f56a753b --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Update/Mysql.php @@ -0,0 +1,40 @@ + + * @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 + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Builder\Update; + + +use VDM\Joomla\Componentbuilder\Interfaces\Mappersingleinterface; +use VDM\Joomla\Componentbuilder\Abstraction\MapperSingle; + + +/** + * Compiler Builder Update Mysql + * + * @since 3.2.0 + */ +class Mysql extends MapperSingle implements Mappersingleinterface +{ + /** + * Model the key + * + * @param string $key The key to model + * + * @return string + * @since 3.2.0 + */ + protected function key(string $key): string + { + return preg_replace('/\s+/', '', $key); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Update/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Update/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Builder/Update/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Data.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Data.php index fe3bc19bc..e9aad596b 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Data.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Component/Data.php @@ -796,15 +796,16 @@ class Data $this->config->lang_target = $nowLang; // catch empty URL to update server TODO: we need to fix this in better way later - if ($component->add_update_server == 1 && $component->update_server_target !== 3 + if (empty($component->add_update_server) || ($component->add_update_server == 1 && $component->update_server_target != 3 && ( !StringHelper::check($component->update_server_url) || strpos($component->update_server_url, 'http') === false - )) + ))) { // we fall back to other, since we can't work with an empty update server URL $component->add_update_server = 0; $component->update_server_target = 3; + $component->update_server_url = ''; } // add the update/sales server FTP details if that is the expected protocol diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Config.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Config.php index ee6e44a3e..e55249dca 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Config.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Config.php @@ -57,6 +57,17 @@ class Config extends BaseConfig $this->config = $config ?: JoomlaFactory::getConfig(); } + /** + * get Gitea Access Token + * + * @return string the access token + * @since 3.2.0 + */ + protected function getGiteatoken(): ?string + { + return $this->params->get('access.token'); + } + /** * get add contributors switch * @@ -538,6 +549,68 @@ class Config extends BaseConfig return $this->params->get('jcb_powers_path', 'libraries/jcb_powers'); } + /** + * Get local super powers repository path + * + * @return string The path to the local repository + * @since 3.2.0 + */ + protected function getLocalpowersrepositorypath(): string + { + $default = $this->tmp_path . '/super_powers'; + + if (!$this->add_super_powers) + { + return $default; + } + + $global = $this->params->get('local_powers_repository_path', $default); + + if (!$this->show_advanced_options) + { + return $global; + } + + $value = $this->input->post->get('powers_repository', 2, 'INT'); + + return $value == 1 + ? $this->input->post->get('local_powers_repository_path', $global, 'PATH') + : $global; + } + + /** + * Get super power approved paths + * + * @return array The approved paths to the repositories on Gitea + * @since 3.2.0 + */ + protected function getApprovedpaths(): array + { + $default = (object) ['owner' => 'joomla', 'repo' => 'super-powers', 'branch' => 'master']; + + if (!$this->add_own_powers) + { + return [$default]; + } + + $paths = $this->params->get('approved_paths'); + + $approved = []; + if (!empty($paths)) + { + foreach ($paths as $path) + { + // we make sure to get only the objects + $approved[] = $path; + } + } + + // finally we add the default + $approved[] = $default; + + return $approved; + } + /** * get bom path * @@ -661,6 +734,42 @@ class Config extends BaseConfig return (bool) $value; } + /** + * Get switch to add super powers + * + * @return bool Switch to add super powers + * @since 3.2.0 + */ + protected function getAddsuperpowers(): bool + { + $default = (bool) $this->params->get('powers_repository', 0); + + if (!$this->show_advanced_options) + { + return $default; + } + + $value = $this->input->post->get('powers_repository', 2, 'INT'); + + return $value == 2 ? $default : (bool) $value; + } + + /** + * Get switch to add own super powers + * + * @return bool Switch to add own super powers + * @since 3.2.0 + */ + protected function getAddownpowers(): bool + { + if ($this->add_super_powers) + { + return (bool) $this->params->get('super_powers_repositories', 0); + } + + return false; + } + /** * get switch build target switch * diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode.php index 4a11e95d3..54510fd05 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode.php @@ -20,6 +20,7 @@ use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; use VDM\Joomla\Componentbuilder\Compiler\Config; use VDM\Joomla\Componentbuilder\Compiler\Placeholder; use VDM\Joomla\Componentbuilder\Compiler\Language\Extractor; +use VDM\Joomla\Componentbuilder\Compiler\Power\Extractor as Power; use VDM\Joomla\Componentbuilder\Compiler\Customcode\External; use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix; use VDM\Joomla\Componentbuilder\Compiler\Interfaces\CustomcodeInterface; @@ -102,6 +103,14 @@ class Customcode implements CustomcodeInterface **/ protected Extractor $extractor; + /** + * Super Power Extractor + * + * @var Power + * @since 3.2.0 + **/ + protected Power $power; + /** * Compiler Custom Code External * @@ -124,17 +133,19 @@ class Customcode implements CustomcodeInterface * @param Config|null $config The compiler config object. * @param Placeholder|null $placeholder The compiler placeholder object. * @param Extractor|null $extractor The compiler language extractor object. - * @param External|null $external The compiler external custom code object. + * @param Power|null $power The compiler power extractor object. + * @param External|null $external The compiler external custom code object. * @param \JDatabaseDriver $db The Database Driver object. * * @since 3.2.0 */ public function __construct(?Config $config = null, ?Placeholder $placeholder = null, - ?Extractor $extractor = null, ?External $external = null, ?\JDatabaseDriver $db = null) + ?Extractor $extractor = null, ?Power $power = null, ?External $external = null, ?\JDatabaseDriver $db = null) { $this->config = $config ?: Compiler::_('Config'); $this->placeholder = $placeholder ?: Compiler::_('Placeholder'); $this->extractor = $extractor ?: Compiler::_('Language.Extractor'); + $this->power = $power ?: Compiler::_('Power.Extractor'); $this->external = $external ?: Compiler::_('Customcode.External'); $this->db = $db ?: Factory::getDbo(); } @@ -159,6 +170,9 @@ class Customcode implements CustomcodeInterface $this->external->set($string, $debug), $debug ) ); + + // extract any found super powers + $this->power->search($string); } // if debug if ($debug) @@ -276,8 +290,7 @@ class Customcode implements CustomcodeInterface if (strpos($array[1], ',') !== false) { // update the function values with the custom code key placeholders (this allow the use of [] + and , in the values) - $this->data[$id]['args'][$key] - = array_map( + $this->data[$id]['args'][$key] = array_map( fn($_key) => $this->placeholder->update( $_key, $this->keys @@ -288,8 +301,7 @@ class Customcode implements CustomcodeInterface $array[1] )) { - $this->data[$id]['args'][$key] - = []; + $this->data[$id]['args'][$key] = []; // update the function values with the custom code key placeholders (this allow the use of [] + and , in the values) $this->data[$id]['args'][$key][] = $this->placeholder->update( diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/Dispenser.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/Dispenser.php index 26c417661..5e0b85de2 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/Dispenser.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/Dispenser.php @@ -124,39 +124,10 @@ class Dispenser implements DispenserInterface { return false; } - // this needs refactoring (TODO) - if (!isset($this->hub[$first]) - || ($second - && !isset($this->hub[$first][$second]))) - { - // check if the script first key is set - if ($second && !isset($this->hub[$first])) - { - $this->hub[$first] = []; - } - elseif ($add && !$second - && !isset($this->hub[$first])) - { - $this->hub[$first] = ''; - } - // check if the script second key is set - if ($second && $third - && !isset($this->hub[$first][$second])) - { - $this->hub[$first][$second] = []; - } - elseif ($add && $second && !$third - && !isset($this->hub[$first][$second])) - { - $this->hub[$first][$second] = ''; - } - // check if the script third key is set - if ($add && $second && $third - && !isset($this->hub[$first][$second][$third])) - { - $this->hub[$first][$second][$third] = ''; - } - } + + // init all needed arrays + $this->initHub($first, $second, $third, $add); + // prep the script string if ($base64 && $dynamic) { @@ -166,7 +137,7 @@ class Dispenser implements DispenserInterface { $script = base64_decode($script); } - elseif ($dynamic) // this does not happen (just incase) + elseif ($dynamic) // this does not happen (just in-case) { $script = $this->customcode->update($script); } @@ -178,49 +149,15 @@ class Dispenser implements DispenserInterface { $script = $this->gui->set($script, $config); } + // add Dynamic HASHING option of a file/string $script = $this->hash->set($script); + // add base64 locking option of a string $script = $this->base64->set($script); + // load the script - if ($first && $second && $third) - { - // now act on loading option - if ($add) - { - $this->hub[$first][$second][$third] - .= $script; - } - else - { - $this->hub[$first][$second][$third] - = $script; - } - } - elseif ($first && $second) - { - // now act on loading option - if ($add) - { - $this->hub[$first][$second] .= $script; - } - else - { - $this->hub[$first][$second] = $script; - } - } - else - { - // now act on loading option - if ($add) - { - $this->hub[$first] .= $script; - } - else - { - $this->hub[$first] = $script; - } - } + $this->setHub($script, $first, $second, $third, $add); return true; } @@ -240,7 +177,6 @@ class Dispenser implements DispenserInterface * @param string $suffix The suffix to add after the script if found * * @return mixed The string/script if found or the default value if not found - * * @since 3.2.0 */ public function get(string $first, string $second, string $prefix = '', ?string $note = null, @@ -279,6 +215,71 @@ class Dispenser implements DispenserInterface return $script; } - + + /** + * Make sure the hub arrays are all set + * + * @param string $first The first key + * @param string|null $second The second key (if not set we use only first key) + * @param string|null $third The third key (if not set we use only first and second key) + * @param bool $add The switch to add to exiting instead of replace + * default: false + * + * @return void + * @since 3.2.0 + */ + protected function initHub(string $first, ?string $second = null, ?string $third = null, bool $add = false) + { + if (!isset($this->hub[$first])) + { + $this->hub[$first] = ($second !== null || $add) ? ($second !== null ? [] : '') : []; + } + + if ($second !== null && !isset($this->hub[$first][$second])) + { + $this->hub[$first][$second] = ($third !== null || $add) ? ($third !== null ? [] : '') : []; + } + + if ($third !== null && !isset($this->hub[$first][$second][$third])) + { + $this->hub[$first][$second][$third] = $add ? '' : []; + } + } + + /** + * Set a script in the hub + * + * @param string $script The script + * @param string $first The first key + * @param string|null $second The second key (if not set we use only first key) + * @param string|null $third The third key (if not set we use only first and second key) + * @param bool $add The switch to add to exiting instead of replace + * default: false + * + * @return void + * @since 3.2.0 + */ + protected function setHub(string $script, string $first, ?string $second = null, ?string $third = null, bool $add = false) + { + // Load the script + if ($second !== null) + { + if ($third !== null) + { + $this->hub[$first][$second][$third] = + $add ? $this->hub[$first][$second][$third] . $script : $script; + } + else + { + $this->hub[$first][$second] = + $add ? $this->hub[$first][$second] . $script : $script; + } + } + else + { + $this->hub[$first] = + $add ? $this->hub[$first] . $script : $script; + } + } } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/Gui.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/Gui.php index d827bd49b..36553af87 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/Gui.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Customcode/Gui.php @@ -23,6 +23,7 @@ use VDM\Joomla\Utilities\String\FieldHelper; use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; use VDM\Joomla\Componentbuilder\Compiler\Config; use VDM\Joomla\Componentbuilder\Compiler\Placeholder\Reverse; +use VDM\Joomla\Componentbuilder\Compiler\Power\Parser; use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Customcode\GuiInterface; @@ -49,6 +50,14 @@ class Gui implements GuiInterface **/ protected Reverse $reverse; + /** + * Compiler Powers Parser + * + * @var Parser + * @since 3.2.0 + **/ + protected Parser $parser; + /** * Database object to query local DB * @@ -70,17 +79,19 @@ class Gui implements GuiInterface * * @param Config|null $config The compiler config object. * @param Reverse|null $reverse The compiler placeholder reverse object. + * @param Parser|null $parser The powers parser object. * @param \JDatabaseDriver|null $db The Database Driver object. * @param CMSApplication|null $app The CMS Application object. * * @throws \Exception * @since 3.2.0 */ - public function __construct(?Config $config = null, ?Reverse $reverse = null, + public function __construct(?Config $config = null, ?Reverse $reverse = null, ?Parser $parser = null, ?\JDatabaseDriver $db = null, ?CMSApplication $app = null) { $this->config = $config ?: Compiler::_('Config'); $this->reverse = $reverse ?: Compiler::_('Placeholder.Reverse'); + $this->parser = $parser ?: Compiler::_('Power.Parser'); $this->db = $db ?: Factory::getDbo(); $this->app = $app ?: Factory::getApplication(); } @@ -181,15 +192,18 @@ class Gui implements GuiInterface public function search(string &$file, array &$placeholders, string &$today, string &$target) { // get file content - $file_conent = FileHelper::getContent($file); + $file_content = FileHelper::getContent($file); + + // get the USE statements (to reverse engineer super power keys) + $use_statements = $this->parser->getUseStatements($file_content); $guiCode = []; // we add a new search for the GUI CODE Blocks $guiCode[] = GetHelper::allBetween( - $file_conent, '/***[JCB' . 'GUI<>', '/***[/JCBGUI' . '$$$$]***/' + $file_content, '/***[JCB' . 'GUI<>', '/***[/JCBGUI' . '$$$$]***/' ); $guiCode[] = GetHelper::allBetween( - $file_conent, '' + $file_content, '' ); if (($guiCode = ArrayHelper::merge($guiCode)) !== false @@ -214,7 +228,7 @@ class Gui implements GuiInterface $table = StringHelper::safe($query[0]); // reverse placeholder as much as we can $code = $this->reverse->engine( - $code, $placeholders, $target, $id, $field, $table + $code, $placeholders, $target, $id, $field, $table, $use_statements ); // update the GUI/Tables/Database $object = new \stdClass(); diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Factory.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Factory.php index d6273b893..6bdd6ce9d 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Factory.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Factory.php @@ -35,6 +35,18 @@ use VDM\Joomla\Componentbuilder\Compiler\Service\Field; use VDM\Joomla\Componentbuilder\Compiler\Service\Joomlamodule; use VDM\Joomla\Componentbuilder\Compiler\Service\Joomlaplugin; use VDM\Joomla\Componentbuilder\Compiler\Service\Utilities; +use VDM\Joomla\Componentbuilder\Compiler\Service\Builder; +use VDM\Joomla\Componentbuilder\Service\Gitea; +use VDM\Joomla\Gitea\Service\Utilities as GiteaUtilities; +use VDM\Joomla\Gitea\Service\Settings as GiteaSettings; +use VDM\Joomla\Gitea\Service\Organization as GiteaOrg; +use VDM\Joomla\Gitea\Service\User as GiteaUser; +use VDM\Joomla\Gitea\Service\Repository as GiteaRepo; +use VDM\Joomla\Gitea\Service\Package as GiteaPackage; +use VDM\Joomla\Gitea\Service\Issue as GiteaIssue; +use VDM\Joomla\Gitea\Service\Notifications as GiteNotifi; +use VDM\Joomla\Gitea\Service\Miscellaneous as GiteaMisc; +use VDM\Joomla\Gitea\Service\Admin as GiteaAdmin; use VDM\Joomla\Componentbuilder\Interfaces\FactoryInterface; @@ -138,7 +150,19 @@ abstract class Factory implements FactoryInterface ->registerServiceProvider(new Field()) ->registerServiceProvider(new Joomlamodule()) ->registerServiceProvider(new Joomlaplugin()) - ->registerServiceProvider(new Utilities()); + ->registerServiceProvider(new Utilities()) + ->registerServiceProvider(new Builder()) + ->registerServiceProvider(new Gitea()) + ->registerServiceProvider(new GiteaUtilities()) + ->registerServiceProvider(new GiteaSettings()) + ->registerServiceProvider(new GiteaOrg()) + ->registerServiceProvider(new GiteaUser()) + ->registerServiceProvider(new GiteaRepo()) + ->registerServiceProvider(new GiteaPackage()) + ->registerServiceProvider(new GiteaIssue()) + ->registerServiceProvider(new GiteNotifi()) + ->registerServiceProvider(new GiteaMisc()) + ->registerServiceProvider(new GiteaAdmin()); } } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Historyadminview.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Historyadminview.php index c24c99ebd..d85d0876c 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Historyadminview.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Historyadminview.php @@ -77,7 +77,7 @@ class Historyadminview */ public function set(object &$item) { - if ($old = $this->history->get('admin_view', $item->id)) + if (($old = $this->history->get('admin_view', $item->id)) !== null) { // check if the view name changed if (StringHelper::check($old->name_single)) diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Historycomponent.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Historycomponent.php index 21d5176ef..dca3671c8 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Historycomponent.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Historycomponent.php @@ -78,54 +78,72 @@ class Historycomponent * @since 3.2.0 */ public function set(object &$item) + { + // update SQL for admin views + $this->setAdminView($item); + + // update SQL for component + $this->setComponent($item); + } + + /** + * check if an update SQL is needed + * + * @param object $item The item data + * + * @return void + * @since 3.2.0 + */ + private function setAdminView(object $item) { $old_admin_views = $this->history->get( 'component_admin_views', $item->addadmin_views_id ); + + // add new views if found + if ($old_admin_views && ObjectHelper::check($old_admin_views)) + { + if (isset($old_admin_views->addadmin_views) + && JsonHelper::check( + $old_admin_views->addadmin_views + )) + { + $this->updatesql->set( + json_decode((string) $old_admin_views->addadmin_views, true), + $item->addadmin_views, 'adminview' + ); + } + } + } + + /** + * Set the component history + * + * @param object $item The item data + * + * @return void + * @since 3.2.0 + */ + private function setComponent(object &$item) + { $old_component = $this->history->get( 'joomla_component', $this->config->component_id ); - if ($old_component || $old_admin_views) + // check if a new version was manually set + if ($old_component && ObjectHelper::check($old_component)) { - if (ObjectHelper::check($old_admin_views)) + $old_component_version = preg_replace( + '/[^0-9.]+/', '', (string) $old_component->component_version + ); + if ($old_component_version != $this->config->component_version) { - // add new views if found - if (isset($old_admin_views->addadmin_views) - && JsonHelper::check( - $old_admin_views->addadmin_views - )) - { - $this->updatesql->set( - json_decode((string) $old_admin_views->addadmin_views, true), - $item->addadmin_views, 'adminview' - ); - } - - // check if a new version was manually set - if (ObjectHelper::check($old_component)) - { - $old_component_version = preg_replace( - '/[^0-9.]+/', '', (string) $old_component->component_version - ); - if ($old_component_version != $this->config->component_version) - { - // yes, this is a new version, this mean there may - // be manual sql and must be checked and updated - $item->old_component_version - = $old_component_version; - } - // clear this data - unset($old_component); - } - - // clear this data - unset($old_admin_views); + // yes, this is a new version, this mean there may + // be manual sql and must be checked and updated + $item->old_component_version + = $old_component_version; } } - - // unset original value - unset($item->addadmin_views); } } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Updateserver.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Updateserver.php index a81fa510f..02c8cdbb8 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Updateserver.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Updateserver.php @@ -12,8 +12,6 @@ namespace VDM\Joomla\Componentbuilder\Compiler\Model; -use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; -use VDM\Joomla\Componentbuilder\Compiler\Registry; use VDM\Joomla\Utilities\ArrayHelper; use VDM\Joomla\Utilities\JsonHelper; use VDM\Joomla\Utilities\StringHelper; @@ -26,26 +24,6 @@ use VDM\Joomla\Utilities\StringHelper; */ class Updateserver { - /** - * Compiler Registry Class - * - * @var Registry - * @since 3.2.0 - */ - protected Registry $registry; - - /** - * Constructor - * - * @param Registry|null $registry The compiler registry object. - * - * @since 3.2.0 - */ - public function __construct(?Registry $registry = null) - { - $this->registry = $registry ?: Compiler::_('Registry'); - } - /** * Set version updates * @@ -72,9 +50,9 @@ class Updateserver } /** - * Set changelog values to registry + * Set changelog values to component changelog * - * @param array $updates The update data + * @param object $item The item data * * @return void * @since 3.2.0 @@ -82,9 +60,9 @@ class Updateserver protected function changelog(object &$item) { // set the version updates + $bucket = []; foreach ($item->version_update as $update) { - $bucket = []; if (isset($update['change_log']) && StringHelper::check($update['change_log']) && isset($update['version']) && StringHelper::check($update['version'])) { diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Updatesql.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Updatesql.php index 9387d151d..c2242e14d 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Updatesql.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Model/Updatesql.php @@ -223,8 +223,8 @@ class Updatesql // convert admin view id to name if ('adminview' === $type) { - $this->registry->set('builder.add_sql.' . $type, - $this->name($item) + $this->registry->set('builder.add_sql.' . $type . '.' . $this->name($item), + $item ); } else diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Placeholder/Reverse.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Placeholder/Reverse.php index 9c866ab3e..6a075540e 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Placeholder/Reverse.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Placeholder/Reverse.php @@ -20,6 +20,7 @@ use VDM\Joomla\Componentbuilder\Compiler\Config; use VDM\Joomla\Componentbuilder\Compiler\Placeholder; use VDM\Joomla\Componentbuilder\Compiler\Language; use VDM\Joomla\Componentbuilder\Compiler\Language\Extractor; +use VDM\Joomla\Componentbuilder\Compiler\Power\Extractor as Power; /** @@ -61,41 +62,54 @@ class Reverse **/ protected Extractor $extractor; + /** + * Super Power Extractor + * + * @var Power + * @since 3.2.0 + **/ + protected Power $power; + /** * Constructor. * * @param Config|null $config The compiler config object. * @param Placeholder|null $placeholder The compiler placeholder object. * @param Language|null $language The compiler language object. - * @param Extract|null $extractor The compiler language extractor object. + * @param Extractor|null $extractor The compiler language extractor object. + * @param Power|null $power The compiler power extractor object. * * @since 3.2.0 */ public function __construct( ?Config $config = null, ?Placeholder $placeholder = null, - ?Language $language = null, ?Extractor $extractor = null) + ?Language $language = null, ?Extractor $extractor = null, + ?Power $power = null) { $this->config = $config ?: Compiler::_('Config'); $this->placeholder = $placeholder ?: Compiler::_('Placeholder'); $this->language = $language ?: Compiler::_('Language'); $this->extractor = $extractor ?: Compiler::_('Language.Extractor'); + $this->power = $power ?: Compiler::_('Power.Extractor'); } /** * Reverse Engineer the dynamic placeholders (TODO hmmmm this is not ideal) * - * @param string $string The string to revers - * @param array $placeholders The values to search for - * @param string $target The target path type - * @param int|null $id The custom code id - * @param string $field The field name - * @param string $table The table name + * @param string $string The string to reverse + * @param array $placeholders The values to search for + * @param string $target The target path type + * @param int|null $id The custom code id + * @param string $field The field name + * @param string $table The table name + * @param array|null $useStatements The file use statements (needed for super powers) * * @return string * @since 3.2.0 */ public function engine(string $string, array &$placeholders, - string $target, ?int $id = null, string $field = 'code', string $table = 'custom_code'): string + string $target, ?int $id = null, string $field = 'code', + string $table = 'custom_code', ?array $useStatements = null): string { // get local code if set if ($id > 0 && $code = base64_decode( @@ -103,13 +117,112 @@ class Reverse )) { $string = $this->setReverse( - $string, $code, $target + $string, $code, $target, $useStatements ); } return $this->placeholder->update($string, $placeholders, 2); } + /** + * Reverse engineer the dynamic language, and super powers + * + * @param string $updateString The string to update + * @param string $string The string to use language update + * @param string $target The target path type + * @param array|null $useStatements The file use statements (needed for super powers) + * + * @return string + * @since 3.2.0 + */ + protected function setReverse(string $updateString, string $string, + string $target, ?array $useStatements): string + { + // we have to reverse engineer to super powers + $updateString = $this->reverseSuperPowers($updateString, $string, $useStatements); + + // reverse engineer the language strings + $updateString = $this->reverseLanguage($updateString, $string, $target); + + // reverse engineer the custom code (if possible) + // $updateString = $this->reverseCustomCode($updateString, $string); // TODO - we would like to also reverse basic customcode + + return $updateString; + } + + /** + * Set the super powers keys for the reveres process + * + * @param string $updateString The string to update + * @param string $string The string to use for super power update + * @param array|null $useStatements The file use statements (needed for super powers) + * + * @return string + * @since 3.2.0 + */ + protected function reverseSuperPowers(string $updateString, string $string, + ?array $useStatements): string + { + // only if we have use statements can we reverse engineer this + if ($useStatements !== null && ($powers = $this->power->reverse($string)) !== null && + ($reverse = $this->getReversePower($powers, $useStatements)) !== null) + { + return $this->placeholder->update($updateString, $reverse); + } + + return $updateString; + } + + /** + * Set the super powers keys for the reveres process + * + * @param array $powers The powers found in the database text + * @param array $useStatements The file use statements + * + * @return array|null + * @since 3.2.0 + */ + protected function getReversePower(array $powers, array $useStatements): ?array + { + $matching_statements = []; + foreach ($useStatements as $use_statement) + { + $namespace = substr($use_statement, 4, -1); // remove 'use ' and ';' + $class_name = ''; + + // Check for 'as' alias + if (strpos($namespace, ' as ') !== false) + { + list($namespace, $class_name) = explode(' as ', $namespace); + } + + // If there is no 'as' alias, get the class name from the last '\' + if (empty($class_name)) + { + $last_slash = strrpos($namespace, '\\'); + if ($last_slash !== false) + { + $class_name = substr($namespace, $last_slash + 1); + } + } + + // Check if the namespace is in the powers array + if (in_array($namespace, $powers)) + { + $guid = array_search($namespace, $powers); + $matching_statements[$class_name] = + 'Super_'.'_'.'_' . str_replace('-', '_', $guid) . '_'.'_'.'_Power'; + } + } + + if ($matching_statements !== []) + { + return $matching_statements; + } + + return null; + } + /** * Set the language strings for the reveres process * @@ -120,7 +233,7 @@ class Reverse * @return string * @since 3.2.0 */ - protected function setReverse(string $updateString, string $string, string $target): string + protected function reverseLanguage(string $updateString, string $string, string $target): string { // get targets to search for $lang_string_targets = array_filter( @@ -184,7 +297,7 @@ class Reverse $string, $lang_string_target . "'", "'" ); $lang_check[] = GetHelper::allBetween( - $string, $lang_string_target . "'", "'" + $string, $lang_string_target . '"', '"' ); } // merge arrays @@ -232,6 +345,56 @@ class Reverse return $updateString; } - + + /** + * Set the custom code placeholder for the reveres process + * + * @param string $updateString The string to update + * @param string $string The string to use for super power update + * + * @return string + * @since 3.2.0 + */ + protected function reverseCustomCode(string $updateString, string $string): string + { + // check if content has custom code place holder + if (strpos($string, '[CUSTO' . 'MCODE=') !== false) + { + $found = GetHelper::allBetween( + $string, '[CUSTO' . 'MCODE=', ']' + ); + $bucket = []; + if (ArrayHelper::check($found)) + { + foreach ($found as $key) + { + // we only update those without args + if (is_numeric($key) && $get_func_name = GetHelper::var( + 'custom_code', $key, 'id', 'function_name' + )) + { + $bucket[$get_func_name] = (int) $key; + } + elseif (StringHelper::check($key) + && strpos((string) $key, '+') === false) + { + $get_func_name = trim((string) $key); + if (isset($bucket[$get_func_name]) || !$found_local = GetHelper::var( + 'custom_code', $get_func_name, 'function_name', + 'id' + )) + { + continue; + } + $bucket[$get_func_name] = (int) $found_local; + } + } + // TODO - we need to now get the customcode + // search and replace the customcode with the placeholder + } + } + + return $updateString; + } } 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 99c2ed362..115c10162 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power.php @@ -26,6 +26,7 @@ use VDM\Joomla\Componentbuilder\Compiler\Config; use VDM\Joomla\Componentbuilder\Compiler\Placeholder; use VDM\Joomla\Componentbuilder\Compiler\Customcode; use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui; +use VDM\Joomla\Componentbuilder\Power\Super as Superpower; use VDM\Joomla\Componentbuilder\Compiler\Interfaces\PowerInterface; @@ -60,6 +61,14 @@ class Power implements PowerInterface **/ public array $composer = []; + /** + * All super powers of this build + * + * @var array + * @since 3.2.0 + **/ + public array $superpowers = []; + /** * The url to the power, if there is an error. * @@ -76,6 +85,14 @@ class Power implements PowerInterface **/ protected array $state = []; + /** + * The state of retry to loaded powers + * + * @var array + * @since 3.2.0 + **/ + protected array $retry = []; + /** * Compiler Config * @@ -108,6 +125,14 @@ class Power implements PowerInterface **/ protected Gui $gui; + /** + * The JCB Superpower class + * + * @var Superpower + * @since 3.2.0 + **/ + protected Superpower $superpower; + /** * Database object to query local DB * @@ -131,6 +156,7 @@ class Power implements PowerInterface * @param Placeholder|null $placeholder The compiler placeholder object. * @param Customcode|null $customcode The compiler customcode object. * @param Gui|null $gui The compiler customcode gui object. + * @param Superpower|null $superpower The JCB superpower object. * @param \JDatabaseDriver|null $db The Database Driver object. * @param CMSApplication|null $app The CMS Application object. * @@ -138,13 +164,14 @@ class Power implements PowerInterface * @since 3.2.0 */ public function __construct(?Config $config = null, ?Placeholder $placeholder = null, - ?Customcode $customcode = null, ?Gui $gui = null, + ?Customcode $customcode = null, ?Gui $gui = null, ?Superpower $superpower = null, ?\JDatabaseDriver $db = null, ?CMSApplication $app = null) { $this->config = $config ?: Compiler::_('Config'); $this->placeholder = $placeholder ?: Compiler::_('Placeholder'); $this->customcode = $customcode ?: Compiler::_('Customcode'); $this->gui = $gui ?: Compiler::_('Customcode.Gui'); + $this->superpower = $superpower ?: Compiler::_('Superpower'); $this->db = $db ?: Factory::getDbo(); $this->app = $app ?: Factory::getApplication(); } @@ -229,6 +256,10 @@ class Power implements PowerInterface $this->active[$guid]->target_type = 'P0m3R!'; $this->active[$guid]->key = $this->active[$guid]->id . '_' . $this->active[$guid]->target_type; + // reserve some values for the linker + $this->active[$guid]->unchanged_namespace = $this->active[$guid]->namespace; + $this->active[$guid]->unchanged_description = $this->active[$guid]->description; + // now set the name $this->active[$guid]->name = $this->placeholder->update_( $this->customcode->update($this->active[$guid]->name) @@ -301,6 +332,9 @@ class Power implements PowerInterface // reset back to starting value $this->config->lang_target = $tmp_lang_target; + // set the approved super power values + $this->setSuperPowers($guid); + return true; } } @@ -310,6 +344,20 @@ class Power implements PowerInterface // only if guid is valid if ($this->isGuidValid($guid)) { + // now we search for it via the super power paths + if (empty($this->retry[$guid]) && $this->superpower->load($guid, ['remote', 'local'])) + { + // we found it and it was loaded into the database + unset($this->state[$guid]); + unset($this->active[$guid]); + + // we make sure that this retry only happen once! (just in-case...) + $this->retry[$guid] = true; + + // so we try to load it again + return $this->set($guid); + } + $this->app->enqueueMessage( Text::sprintf('COM_COMPONENTBUILDER_PPOWER_BGUIDSB_NOT_FOUNDP', $guid), 'Error' @@ -513,7 +561,7 @@ class Power implements PowerInterface } /** - * Set Use Classess + * Set Use Classes * * @param string $guid The global unique id of the power * @param array $use The use array @@ -596,6 +644,9 @@ class Power implements PowerInterface if (ArrayHelper::check($_composer)) { + // reserve composer values for the linker + $this->active[$guid]->unchanged_composer = $_composer; + foreach ($_composer as $composer) { if (isset($composer['access_point']) && StringHelper::check($composer['access_point']) && @@ -641,6 +692,11 @@ class Power implements PowerInterface } } } + else + { + // reserve composer values for the linker + $this->active[$guid]->unchanged_composer = ''; + } } /** @@ -670,9 +726,13 @@ class Power implements PowerInterface if ($implement == -1 && StringHelper::check($this->active[$guid]->implements_custom)) { + // reserve implements custom for the linker + $this->active[$guid]->unchanged_implements_custom = $this->active[$guid]->implements_custom; + $this->active[$guid]->implement_names[] = $this->placeholder->update_( $this->customcode->update($this->active[$guid]->implements_custom) ); + // just add this once unset($this->active[$guid]->implements_custom); } @@ -710,9 +770,13 @@ class Power implements PowerInterface if ($this->active[$guid]->extends == -1 && StringHelper::check($this->active[$guid]->extends_custom)) { + // reserve extends custom for the linker + $this->active[$guid]->unchanged_extends_custom = $this->active[$guid]->extends_custom; + $this->active[$guid]->extends_name = $this->placeholder->update_( $this->customcode->update($this->active[$guid]->extends_custom) ); + // just add once unset($this->active[$guid]->extends_custom); } @@ -838,13 +902,16 @@ class Power implements PowerInterface // set GUI mapper field $guiMapper['field'] = 'licensing_template'; + // reserve licensing template for the linker + $this->active[$guid]->unchanged_licensing_template = base64_decode( + (string) $this->active[$guid]->licensing_template + ); + // base64 Decode code $this->active[$guid]->licensing_template = $this->gui->set( $this->placeholder->update_( $this->customcode->update( - base64_decode( - (string) $this->active[$guid]->licensing_template - ) + $this->active[$guid]->unchanged_licensing_template ) ), $guiMapper @@ -854,6 +921,7 @@ class Power implements PowerInterface { $this->active[$guid]->add_licensing_template = 1; $this->active[$guid]->licensing_template = ''; + $this->active[$guid]->unchanged_licensing_template = ''; } } @@ -873,13 +941,16 @@ class Power implements PowerInterface // set GUI mapper field $guiMapper['field'] = 'head'; + // reserve header for the linker + $this->active[$guid]->unchanged_head = base64_decode( + (string) $this->active[$guid]->head + ); + // base64 Decode code $this->active[$guid]->head = $this->gui->set( $this->placeholder->update_( $this->customcode->update( - base64_decode( - (string) $this->active[$guid]->head - ) + $this->active[$guid]->unchanged_head ) ), $guiMapper @@ -888,6 +959,7 @@ class Power implements PowerInterface else { $this->active[$guid]->head = ''; + $this->active[$guid]->unchanged_head = ''; } } @@ -904,6 +976,11 @@ class Power implements PowerInterface { if (StringHelper::check($this->active[$guid]->main_class_code)) { + // reserve main class code for the linker + $this->active[$guid]->unchanged_main_class_code = base64_decode( + (string) $this->active[$guid]->main_class_code + ); + // set GUI mapper field $guiMapper['field'] = 'main_class_code'; @@ -911,15 +988,75 @@ class Power implements PowerInterface $this->active[$guid]->main_class_code = $this->gui->set( $this->placeholder->update_( $this->customcode->update( - base64_decode( - (string) $this->active[$guid]->main_class_code - ) + $this->active[$guid]->unchanged_main_class_code ) ), $guiMapper ); } } - + + /** + * Set the super powers of this power + * + * @param string $guid The global unique id of the power + * + * @return void + * @since 3.2.0 + */ + private function setSuperPowers(string $guid): void + { + // set the approved super power values + if ($this->config->add_super_powers && $this->active[$guid]->approved == 1) + { + $this->active[$guid]->approved_paths = (isset($this->active[$guid]->approved_paths) + && JsonHelper::check( + $this->active[$guid]->approved_paths + )) ? json_decode((string) $this->active[$guid]->approved_paths, true) : null; + + if (ArrayHelper::check($this->active[$guid]->approved_paths)) + { + $global_path = $this->config->local_powers_repository_path; + + // update all paths + $this->active[$guid]->super_power_paths = array_map(function($path) use($global_path, $guid) { + + // remove branch + if (($pos = strpos($path, ':')) !== false) + { + $path = substr($path, 0, $pos); + } + + // set the repo path + $repo = $global_path . '/' . $path; + + // set SuperPowerKey (spk) + $spk = 'Super_'.'_' . str_replace('-', '_', $guid) . '_'.'_Power'; + + // set the global super power + $this->superpowers[$repo][$guid] = [ + 'name' => $this->active[$guid]->code_name, + 'type' => $this->active[$guid]->type, + 'namespace' => $this->active[$guid]->_namespace, + 'code' => 'src/' . $guid . '/code.php', + 'power' => 'src/' . $guid . '/code.power', + 'settings' => 'src/' . $guid . '/settings.json', + 'path' => 'src/' . $guid, + 'spk' => $spk, + 'guid' => $guid + ]; + + return $repo . '/src/' . $guid; + }, array_values($this->active[$guid]->approved_paths)); + + return; + } + } + + // reset all to avoid any misunderstanding down steam + $this->active[$guid]->super_power_paths = null; + $this->active[$guid]->approved_paths = null; + $this->active[$guid]->approved = null; + } } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Extractor.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Extractor.php new file mode 100644 index 000000000..b1b0c5287 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Extractor.php @@ -0,0 +1,244 @@ + + * @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 + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Power; + + +use Joomla\CMS\Factory; +use VDM\Joomla\Utilities\GuidHelper; + + +/** + * Compiler Power Extractor + * @since 3.2.0 + */ +final class Extractor +{ + /** + * The pattern to get the powers + * + * @var string + * @since 3.2.0 + **/ + protected string $pattern = '/Super_'.'_'.'_[a-zA-Z0-9_]+_'.'_'.'_Power/'; + + /** + * Powers GUID's + * + * @var array + * @since 3.2.0 + **/ + protected array $powers = []; + + /** + * Database object to query local DB + * + * @var \JDatabaseDriver + * @since 3.2.0 + **/ + protected \JDatabaseDriver $db; + + /** + * Constructor + * + * @param \JDatabaseDriver|null $db The database object. + * @since 3.2.0 + */ + public function __construct(?\JDatabaseDriver $db = null) + { + $this->db = $db ?: Factory::getDbo(); + } + + /** + * Get Super Powers from the code string + * + * @param string $code The code + * + * @return array|null + * @since 3.2.0 + */ + public function get_(): ?array + { + return $this->powers !== [] ? $this->powers : null; + } + + /** + * Get Super Powers from the code string + * + * @param string $code The code + * + * @return array|null + * @since 3.2.0 + */ + public function get(string $code): ?array + { + $matches = []; + preg_match_all($this->pattern, $code, $matches); + + $found = $matches[0]; + + if (!empty($found)) + { + return $this->map($found); + } + + return null; + } + + /** + * Get Super Powers from the code string + * + * @param string $code The code + * + * @return array|null + * @since 3.2.0 + */ + public function reverse(string $code): ?array + { + $matches = []; + preg_match_all($this->pattern, $code, $matches); + + $found = $matches[0]; + + if (!empty($found) && ($guids = $this->filter($found)) !== null) + { + return $this->namespaces($guids); + } + + return null; + } + + /** + * Get Super Powers from the code string and load it + * + * @param string $code The code + * + * @return void + * @since 3.2.0 + */ + public function search(string $code) + { + $matches = []; + preg_match_all($this->pattern, $code, $matches); + + $found = $matches[0]; + + if (!empty($found)) + { + $this->load($found); + } + } + + /** + * Load the Super Powers found + * + * @param array $found The found Super Powers + * + * @return void + * @since 3.2.0 + */ + protected function load(array $found) + { + foreach ($found as $super_power) + { + $guid = str_replace(['Super_'.'_'.'_', '_'.'_'.'_Power'], '', $super_power); + $guid = str_replace('_', '-', $guid); + + if (GuidHelper::valid($guid)) + { + $this->powers[$guid] = 1; // 1 force the power to be added + } + } + } + + /** + * Map the Super Powers to GUIDs + * + * @param array $found The found Super Powers + * + * @return array + * @since 3.2.0 + */ + protected function map(array $found): ?array + { + $guids = []; + + foreach ($found as $super_power) + { + $guid = str_replace(['Super_'.'_'.'_', '_'.'_'.'_Power'], '', $super_power); + $guid = str_replace('_', '-', $guid); + + if (GuidHelper::valid($guid)) + { + $guids[$super_power] = $guid; + } + } + + return $guids !== [] ? $guids : null; + } + + /** + * Filter the Super Powers to GUIDs + * + * @param array $found The found Super Powers + * + * @return array + * @since 3.2.0 + */ + protected function filter(array $found): ?array + { + $guids = []; + + foreach ($found as $super_power) + { + $guid = str_replace(['Super_'.'_'.'_', '_'.'_'.'_Power'], '', $super_power); + $guid = str_replace('_', '-', $guid); + + if (GuidHelper::valid($guid)) + { + $guids[$guid] = $guid; + } + } + + return $guids !== [] ? array_values($guids) : null; + } + + /** + * Get the complete namespace strings of the guids passed as an array. + * + * @param array $guids The guids to filter the results + * + * @return array|null The result namespaces with their guids + * @since 3.2.0 + **/ + protected function namespaces(array $guids): ?array + { + $query = $this->db->getQuery(true); + $query->select( + 'DISTINCT REPLACE(' + . $this->db->quoteName('namespace') + . ', ".", "\\\") AS full_namespace, ' + . $this->db->quoteName('guid') + ) + ->from($this->db->quoteName('#__componentbuilder_power')) + ->where($this->db->quoteName('guid') . ' IN (' . implode(',', array_map([$this->db, 'quote'], $guids)) . ')'); + $this->db->setQuery($query); + $this->db->execute(); + + if ($this->db->getNumRows()) + { + return $this->db->loadAssocList('guid', 'full_namespace'); + } + + return null; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Infusion.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Infusion.php index f72181638..c0dd35bf6 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Infusion.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Infusion.php @@ -17,6 +17,9 @@ use VDM\Joomla\Componentbuilder\Compiler\Config; use VDM\Joomla\Componentbuilder\Compiler\Power; use VDM\Joomla\Componentbuilder\Compiler\Content; use VDM\Joomla\Componentbuilder\Compiler\Power\Autoloader; +use VDM\Joomla\Componentbuilder\Compiler\Power\Parser; +use VDM\Joomla\Componentbuilder\Compiler\Power\Repo\Readme as RepoReadme; +use VDM\Joomla\Componentbuilder\Compiler\Power\Repos\Readme as ReposReadme; use VDM\Joomla\Componentbuilder\Compiler\Placeholder; use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface as Event; use VDM\Joomla\Utilities\StringHelper; @@ -62,6 +65,30 @@ class Infusion **/ protected Autoloader $autoloader; + /** + * Compiler Powers Parser + * + * @var Parser + * @since 3.2.0 + **/ + protected Parser $parser; + + /** + * Compiler Powers Repo Readme Builder + * + * @var RepoReadme + * @since 3.2.0 + **/ + protected RepoReadme $reporeadme; + + /** + * Compiler Powers Repos Readme Builder + * + * @var ReposReadme + * @since 3.2.0 + **/ + protected ReposReadme $reposreadme; + /** * Compiler Placeholder * @@ -78,6 +105,34 @@ class Infusion **/ protected Event $event; + /** + * Power linker values + * + * @var array + * @since 3.2.0 + **/ + protected array $linker = [ + 'add_head' => 'add_head', + 'unchanged_composer' => 'composer', + 'unchanged_description' => 'description', + 'extends' => 'extends', + 'unchanged_extends_custom' => 'extends_custom', + 'guid' => 'guid', + 'unchanged_head' => 'head', + 'use_selection' => 'use_selection', + 'implements' => 'implements', + 'unchanged_implements_custom' => 'implements_custom', + 'load_selection' => 'load_selection', + 'name' => 'name', + 'power_version' => 'power_version', + 'system_name' => 'system_name', + 'type' => 'type', + 'unchanged_namespace' => 'namespace', + 'unchanged_composer' => 'composer', + 'add_licensing_template' => 'add_licensing_template', + 'unchanged_licensing_template' => 'licensing_template' + ]; + /** * Constructor. * @@ -85,18 +140,25 @@ class Infusion * @param Power|null $power The power object. * @param Content|null $content The compiler content object. * @param Autoloader|null $autoloader The powers autoloader object. + * @param Parser|null $parser The powers parser object. + * @param RepoReadme|null $reporeadme The powers repo readme builder object. + * @param ReposReadme|null $reposreadme The powers repos readme builder object. * @param Placeholder|null $placeholder The placeholder object. * @param Event|null $event The events object. * * @since 3.2.0 */ public function __construct(?Config $config = null, ?Power $power = null, ?Content $content = null, - ?Autoloader $autoloader = null, ?Placeholder $placeholder = null, ?Event $event = null) + ?Autoloader $autoloader = null, ?Parser $parser = null, ?RepoReadme $reporeadme = null, + ?ReposReadme $reposreadme = null, ?Placeholder $placeholder = null, ?Event $event = null) { $this->config = $config ?: Compiler::_('Config'); $this->power = $power ?: Compiler::_('Power'); $this->content = $content ?: Compiler::_('Content'); $this->autoloader = $autoloader ?: Compiler::_('Power.Autoloader'); + $this->parser = $parser ?: Compiler::_('Power.Parser'); + $this->reporeadme = $reporeadme ?: Compiler::_('Power.Repo.Readme'); + $this->reposreadme = $reposreadme ?: Compiler::_('Power.Repos.Readme'); $this->placeholder = $placeholder ?: Compiler::_('Placeholder'); $this->event = $event ?: Compiler::_('Event'); } @@ -108,6 +170,90 @@ class Infusion * @since 3.2.0 */ public function set() + { + // parse all powers main code + $this->parsePowers(); + + // set the powers + $this->setSuperPowers(); + + // set the powers + $this->setPowers(); + } + + /** + * We parse the powers to get the class map of all methods + * + * @return void + * @since 3.2.0 + */ + private function parsePowers() + { + // we only do this if super powers are active + if ($this->config->add_super_powers && ArrayHelper::check($this->power->superpowers)) + { + foreach ($this->power->active as $n => &$power) + { + if (ObjectHelper::check($power) && isset($power->main_class_code) && + StringHelper::check($power->main_class_code)) + { + // only parse those approved + if ($power->approved == 1) + { + $power->main_class_code = $this->placeholder->update($power->main_class_code, $this->content->active); + $power->parsed_class_code = $this->parser->code($power->main_class_code); + } + } + } + } + } + + /** + * Set the Super Powers details + * + * @return void + * @since 3.2.0 + */ + private function setSuperPowers() + { + // infuse super powers details if set + if ($this->config->add_super_powers && ArrayHelper::check($this->power->superpowers)) + { + // TODO we need to update the event signatures + $context = $this->config->component_context; + + foreach ($this->power->superpowers as $path => $powers) + { + $key = StringHelper::safe($path); + + // Trigger Event: jcb_ce_onBeforeInfuseSuperPowerDetails + $this->event->trigger( + 'jcb_ce_onBeforeInfuseSuperPowerDetails', + array(&$context, &$path, &$key, &$powers) + ); + + // POWERREADME + $this->content->set_($key, 'POWERREADME', $this->reposreadme->get($powers)); + + // POWERINDEX + $this->content->set_($key, 'POWERINDEX', $this->index($powers)); + + // Trigger Event: jcb_ce_onAfterInfuseSuperPowerDetails + $this->event->trigger( + 'jcb_ce_onAfterInfuseSuperPowerDetails', + array(&$context, &$path, &$key, &$powers) + ); + } + } + } + + /** + * Set the Powers code + * + * @return void + * @since 3.2.0 + */ + private function setPowers() { // infuse powers data if set if (ArrayHelper::check($this->power->active)) @@ -126,12 +272,16 @@ class Infusion ); // POWERCODE - $this->content->set_($power->key, 'POWERCODE', $this->get($power)); + $this->content->set_($power->key, 'POWERCODE', $this->code($power)); + + // CODEPOWER + $this->content->set_($power->key, 'CODEPOWER', $this->raw($power)); // POWERLINKER - // SOON WE STILL NEED TO THINK THIS OVER - // $this->content->set_($power->key, 'POWERLINKER', $this->linker($power)); - $this->content->set_($power->key, 'POWERLINKER', ''); + $this->content->set_($power->key, 'POWERLINKER', $this->linker($power)); + + // POWERLINKER + $this->content->set_($power->key, 'POWERREADME', $this->reporeadme->get($power)); // Trigger Event: jcb_ce_onAfterInfusePowerData $this->event->trigger( @@ -146,6 +296,19 @@ class Infusion } } + /** + * Build the Super Power Index + * + * @param array $powers All powers of this super power. + * + * @return string + * @since 3.2.0 + */ + private function index(array &$powers): string + { + return json_encode($powers, JSON_PRETTY_PRINT); + } + /** * Get the Power code * @@ -154,7 +317,7 @@ class Infusion * @return string * @since 3.2.0 */ - protected function get(object &$power): string + private function code(object &$power): string { $code = []; @@ -208,6 +371,24 @@ class Infusion return $this->placeholder->update(implode(PHP_EOL, $code), $this->content->active); } + /** + * Get the Raw (unchanged) Power code + * + * @param object $power A power object. + * + * @return string + * @since 3.2.0 + */ + private function raw(object &$power): string + { + // add the raw main code if set + if (isset($power->unchanged_main_class_code) && StringHelper::check($power->unchanged_main_class_code)) + { + return $power->unchanged_main_class_code; + } + return ''; + } + /** * Get the Power Linker * @@ -216,70 +397,20 @@ class Infusion * @return string * @since 3.2.0 */ - protected function linker(object &$power): string + private function linker(object &$power): string { - $map = []; - $body = []; + $linker = []; - // set the LINKER - $map[] = '/******************| POWER LINKER |*******************|'; - $map[] = ''; - $map[] = '{'; - - // we build the JSON body - $body[] = ' "guid": "' . $power->guid . '"'; - - // load extends - if (GuidHelper::valid($power->extends)) + // set the linking values + foreach ($power as $key => $value) { - $body[] = ' "extends": "' . $power->extends . '"'; - } - - // load implements - if (ArrayHelper::check($power->implements)) - { - $sud = []; - foreach ($power->implements as $implement) + if (isset($this->linker[$key])) { - $sud[] = ' "' . $implement . '"'; + $linker[$this->linker[$key]] = $value; } - $sud = implode(','. PHP_EOL, $sud); - - $body[] = ' "implements": [' . PHP_EOL . $sud . PHP_EOL . ' ]'; } - // load (Use Selection) - if (ArrayHelper::check($power->use_selection)) - { - $sud = []; - foreach ($power->use_selection as $use) - { - $sud[] = ' "' . $use['use'] . '"'; - } - $sud = implode(','. PHP_EOL, $sud); - - $body[] = ' "use": [' . PHP_EOL . $sud . PHP_EOL . ' ]'; - } - - // load (Load Selection) - if (ArrayHelper::check($power->load_selection)) - { - $sud = []; - foreach ($power->load_selection as $load) - { - $sud[] = ' "' . $load['load'] . '"'; - } - $sud = implode(','. PHP_EOL, $sud); - - $body[] = ' "load": [' . PHP_EOL . $sud . PHP_EOL . ' ]'; - } - $map[] = implode(','. PHP_EOL, $body); - - $map[] = '}'; - $map[] = ''; - $map[] = '|******************| POWER LINKER |*******************/' . PHP_EOL . PHP_EOL; - - return implode(PHP_EOL, $map); + return json_encode($linker, JSON_PRETTY_PRINT); } } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Injector.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Injector.php new file mode 100644 index 000000000..e650f4b71 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Injector.php @@ -0,0 +1,481 @@ + + * @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 + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Power; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Power; +use VDM\Joomla\Componentbuilder\Compiler\Power\Extractor; +use VDM\Joomla\Componentbuilder\Compiler\Power\Parser; +use VDM\Joomla\Componentbuilder\Compiler\Placeholder; + + +/** + * Compiler Power Injector + * @since 3.2.0 + */ +final class Injector +{ + /** + * Power Objects + * + * @var Power + * @since 3.2.0 + **/ + protected Power $power; + + /** + * Compiler Powers Extractor + * + * @var Extractor + * @since 3.2.0 + **/ + protected Extractor $extractor; + + /** + * Compiler Powers Parser + * + * @var Parser + * @since 3.2.0 + **/ + protected Parser $parser; + + /** + * Compiler Placeholder + * + * @var Placeholder + * @since 3.2.0 + */ + protected Placeholder $placeholder; + + /** + * Super Power Update Map + * + * @var array + * @since 3.2.0 + */ + protected array $map = []; + + /** + * Insert Use Statements + * + * @var array + * @since 3.2.0 + */ + protected array $useStatements = []; + + /** + * Insert Trait Statements + * + * @var array + * @since 3.2.0 + */ + protected array $traits = []; + + /** + * Constructor. + * + * @param Power|null $power The power object. + * @param Extractor|null $extractor The powers extractor object. + * @param Parser|null $parser The powers parser object. + * @param Placeholder|null $placeholder The compiler placeholder object. + * + * @since 3.2.0 + */ + public function __construct(?Power $power = null, ?Extractor $extractor = null, + ?Parser $parser = null, ?Placeholder $placeholder = null) + { + $this->power = $power ?: Compiler::_('Power'); + $this->extractor = $extractor ?: Compiler::_('Power.Extractor'); + $this->parser = $parser ?: Compiler::_('Power.Parser'); + $this->placeholder = $placeholder ?: Compiler::_('Placeholder'); + } + + /** + * Inject the powers found in the code + * + * @param string $code The class code + * + * @return string The updated code + * @since 3.2.0 + */ + public function power(string $code): string + { + if (($guids = $this->extractor->get($code)) !== null) + { + return $this->update($guids, $code); + } + + return $code; + } + + /** + * Update the code + * + * @param array $guids The Power guids found + * @param string $code The class code + * + * @return string The updated code + * @since 3.2.0 + */ + protected function update(array $guids, string $code): string + { + $use_statements = $this->parser->getUseStatements($code); + $traits = $this->parser->getTraits( + $this->parser->getClassCode($code) ?? '' + ); + + // reset with each file + $this->map = []; + $this->useStatements = []; + $this->traits = []; + + foreach ($guids as $key => $guid) + { + if (($power = $this->power->get($guid)) !== null) + { + if (($name = $this->inspect($power, $use_statements, $traits)) !== null) + { + $this->map[$key] = $name; + } + } + } + + // update + if ($this->map !== []) + { + if ($this->useStatements !== []) + { + $code = $this->addUseStatements($code, $use_statements); + } + + return $this->placeholder->update($code, $this->map); + } + + return $code; + } + + /** + * inspect the super power + * + * @param object|null $power The power object. + * @param array|null $useStatements The code use statments + * @param array|null $traits The code traits use statments + * + * @return string|null The class name (or as name) + * @since 3.2.0 + */ + protected function inspect(object $power, ?array $useStatements, ?array $traits): ?string + { + if (isset($power->type) && in_array($power->type, ['class', 'abstract class', 'final class', 'trait'])) + { + $statement = 'use ' . $power->_namespace . '\\' . $power->class_name; + // other class names + $use_other = []; + $trait_other = []; + // some tracker globals + $has_use_statement = false; // add if not found + $has_trait_statement = !('trait' === $power->type); // don't add if not trait + $name = null; + $trait_name = null; + + // check if the name space is loaded + if ($useStatements !== null) + { + foreach ($useStatements as $use_statement) + { + if ($use_statement === $statement . ';' || strpos($use_statement, $statement . ' as ') !== false) + { + $name = $this->getName($use_statement); + $has_use_statement = true; + } + else + { + $tmp = $this->getName($use_statement); + if ($power->class_name === $tmp) + { + $use_other[$tmp] = $tmp; + } + } + } + } + + // check if the trait is loaded + if (!$has_trait_statement && $traits !== null) + { + $trait_statement = $name ?? $power->class_name; + + foreach ($traits as $trait) + { + if ($trait === $trait_statement) + { + $trait_name = $trait; + $has_trait_statement = true; + } + } + } + + // build the name + $name = $trait_name ?? $name ?? $power->class_name; + + // if we have a trait we may need to add use and trait + if ('trait' === $power->type) + { + if (!$has_trait_statement) + { + $this->traits[$name] = 'use ' . $name . ';'; + } + } + + // check if we need to update the name + if ($use_other !== []) + { + // set search namespace + $namespace = ($name !== $power->class_name) ? $power->_namespace . '\\' . $power->class_name : $power->_namespace; + + // get the unique name + $name = $this->getUniqueName($name, $namespace, $use_other); + } + + if (!$has_use_statement) + { + // if the name is not the same as class name + if ($name !== $power->class_name) + { + $statement .= ' as ' . $name . ';'; + } + else + { + $statement .= ';'; + } + + $this->useStatements[$name] = $statement; + } + + return $name; + } + + return null; + } + + /** + * Extracts the class name from a use statement. + * + * @param string $useStatement The use statement from which to extract the class name + * + * @return string|null The class name or null if not found + * @since 3.2.0 + */ + protected function getName(string $useStatement): ?string + { + // If the input doesn't start with 'use ', assume it's a class name without a use statement + if (strpos($useStatement, 'use ') !== 0) + { + $parts = explode('\\', $useStatement); + $result = end($parts); + + // Remove '\\' from the beginning and end of the resulting string + $result = trim($result, '\\'); + + // If the resulting string is empty, return null + return empty($result) ? null : $result; + } + + $pattern = '/use\s+([\w\\\\]+)(?:\s+as\s+)?([\w]+)?;/'; + + if (preg_match($pattern, $useStatement, $matches)) + { + // If there's an alias, return it + if (!empty($matches[2])) + { + return $matches[2]; + } + + // If there's no alias, extract the class name from the namespace + $parts = explode('\\', $matches[1]); + return end($parts); + } + + return null; + } + + /** + * Removes the last space from the namespace. + * + * @param string $name The current name + * @param string $namespace The namespace + * @param array $useOther The other use names + * + * @return string The namespace shortened + * @since 3.2.0 + */ + protected function getUniqueName(string $name, string $namespace, array $useOther): string + { + // if the name is already used + while (isset($useOther[$name])) + { + if (($tmp = $this->getName($namespace)) !== null) + { + $name = ucfirst($tmp) . $name; + $namespace = $this->removeLastSpace($namespace); + } + } + + return $name; + } + + /** + * Removes the last space from the namespace. + * + * @param string $namespace The namespace + * + * @return string The namespace shortened + * @since 3.2.0 + */ + protected function removeLastSpace(string $namespace): string + { + // Remove '\\' from the beginning and end of the resulting string + $namespace = trim($namespace, '\\'); + + $parts = explode('\\', $namespace); + + // Remove the last part (the class name) + array_pop($parts); + + // Reassemble the namespace without the class name + return implode('\\', $parts); + } + + /** + * Insert a line before the class declaration in the given class code. + * + * @param string $code The class code + * @param array|null $useStatements The existing use statements + * + * @return string The modified file content + * @since 3.2.0 + */ + protected function addUseStatements(string $code, ?array $useStatements): string + { + if ($useStatements !== null) + { + // we add the use statements using existing use statements + $key = end($useStatements); + + array_unshift($this->useStatements, $key); + + return $this->placeholder->update($code, [$key => implode(PHP_EOL, array_values($this->useStatements))]); + } + + return $this->addLines($code, implode(PHP_EOL, array_values($this->useStatements))); + } + + /** + * Insert a line before the class declaration in the given class code. + * + * @param string $code The class code + * @param string $lines The new lines to insert + * + * @return string The modified file content + * @since 3.2.0 + */ + protected function addLines(string $code, string $lines): string + { + // Pattern to match class, final class, abstract class, interface, and trait + $pattern = '/(?:class|final class|abstract class|interface|trait)\s+[a-zA-Z0-9_]+\s*(?:extends\s+[a-zA-Z0-9_]+\s*)?(?:implements\s+[a-zA-Z0-9_]+(?:\s*,\s*[a-zA-Z0-9_]+)*)?\s*\{/s'; + + // Find the position of the class declaration + preg_match($pattern, $code, $matches, PREG_OFFSET_CAPTURE); + $class_declaration_pos = $matches[0][1] ?? null; + + if (null !== $class_declaration_pos) + { + // Find the position of the last newline character before the class declaration + $last_newline_pos = strrpos($code, PHP_EOL, -(strlen($code) - $class_declaration_pos)); + + // Find the position of the comment block right before the class declaration + $comment_pattern = '/\s*\*\/\s*$/m'; + $insert_pos = null; + if (preg_match($comment_pattern, $code, $comment_matches, PREG_OFFSET_CAPTURE, 0, $last_newline_pos)) + { + $insert_pos = (int) $comment_matches[0][1] + strlen($comment_matches[0][0]); + } + else + { + // Find the last empty line before the class declaration + $empty_line_pattern = '/(^|\r\n|\r|\n)[\s]*($|\r\n|\r|\n)/'; + if (preg_match($empty_line_pattern, $code, $empty_line_matches, PREG_OFFSET_CAPTURE, 0, $last_newline_pos)) + { + $insert_pos = (int) $empty_line_matches[0][1] + strlen($empty_line_matches[0][0]); + } + } + + // Insert the new line at the found position + if (null !== $insert_pos) + { + return substr_replace($code, $lines . PHP_EOL, $insert_pos, 0); + } + } + + // last try targeting the defined line + return $this->addLinesAfterDefinedLine($code, $lines); + } + + /** + * Inserts a new line after the defined('_JEXEC') line. + * + * @param string $code The class code + * @param string $lines The new lines to insert + * + * @return string The modified file content + * @since 3.2.0 + */ + protected function addLinesAfterDefinedLine(string $code, string $lines): string + { + // Patterns to match the defined('_JEXEC') and defined('JPATH_BASE') lines + $patterns = [ + "/defined\('_JEXEC'\)(.*?)\s*;/", + "/defined\('JPATH_BASE'\)(.*?)\s*;/", + ]; + + $insert_pos = null; + + // Iterate through the patterns and try to find a match + foreach ($patterns as $pattern) + { + preg_match($pattern, $code, $matches, PREG_OFFSET_CAPTURE); + $defined_line_pos = $matches[0][1] ?? null; + + if ($defined_line_pos !== null) + { + // Find the position of the newline character after the defined() line + $next_lines_pos = strpos($code, PHP_EOL, (int) $defined_line_pos + strlen($matches[0][0])); + + // Insert the new line at the found position + if ($next_lines_pos !== false) + { + $insert_pos = $next_lines_pos; + break; + } + } + } + + // Insert the new line at the found position + if ($insert_pos !== null) + { + $code = substr_replace($code, PHP_EOL . $lines, $insert_pos, 0); + } + + return $code; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Parser.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Parser.php new file mode 100644 index 000000000..ab94a787e --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Parser.php @@ -0,0 +1,592 @@ + + * @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 + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Power; + + +/** + * Compiler Power Parser + * Very basic php class methods parser, does not catch all edge-cases! + * Use this only on code that are following standard good practices + * Suggested improvements are welcome + * @since 3.2.0 + */ +final class Parser +{ + /** + * Get properties and method declarations and other details from the given code. + * + * @param string $code The code containing class properties & methods + * + * @return array An array of properties & method declarations of the given code + * @since 3.2.0 + */ + public function code(string $code): array + { + return [ + 'properties' => $this->properties($code), + 'methods' => $this->methods($code) + ]; + } + + /** + * Get the class body + * + * @param string $code The class as a string + * + * @return string|null The class body, or null if not found + * @since 3.2.0 + **/ + public function getClassCode(string $code): ?string + { + // Match class, final class, abstract class, interface, and trait + $pattern = '/(?:class|final class|abstract class|interface|trait)\s+[a-zA-Z0-9_]+\s*(?:extends\s+[a-zA-Z0-9_]+\s*)?(?:implements\s+[a-zA-Z0-9_]+(?:\s*,\s*[a-zA-Z0-9_]+)*)?\s*\{/s'; + + // Split the input code based on the class declaration pattern + $parts = preg_split($pattern, $code, 2, PREG_SPLIT_DELIM_CAPTURE); + $body = $parts[1] ?? ''; + + if ($body !== '') + { + // Remove leading and trailing white space + $body = trim($body); + + // Remove the first opening curly brace if it exists + if (mb_substr($body, 0, 1) === '{') + { + $body = mb_substr($body, 1); + } + + // Remove the last closing curly brace if it exists + if (mb_substr($body, -1) === '}') + { + $body = mb_substr($body, 0, -1); + } + + return $body; + } + + // No class body found, return null + return null; + } + + /** + * Get the class license + * + * @param string $code The class as a string + * + * @return string|null The class license, or null if not found + * @since 3.2.0 + **/ + public function getClassLicense(string $code): ?string + { + // Check if the file starts with ' $match) + { + $declaration = $match[0] ?? null; + + if ($declaration !== null) + { + $names = preg_replace('/\s*use\s+/', '', $declaration); + $names = preg_replace('/\s*;/', '', $names); + $names = preg_split('/\s*,\s*/', $names); + + $traitNames = array_merge($traitNames, $names); + } + } + + return $traitNames; + } + + return null; + } + + /** + * Extracts properties declarations and other details from the given code. + * + * @param string $code The code containing class properties + * + * @return array|null An array of properties declarations and details + * @since 3.2.0 + */ + private function properties(string $code): ?array + { + // regex to target all properties + $access = '(?var|public|protected|private)'; + $type = '(?(?:\?|)[\p{L}0-9\\\\]*\s+)?'; + $static = '(?static)?'; + $name = '\$(?\p{L}[\p{L}0-9]*)'; + $default = '(?:\s*=\s*(?\[[^\]]*\]|\d+|\'[^\']*?\'|"[^"]*?"|false|true|null))?'; + $property_pattern = "/\b{$access}\s*{$type}{$static}\s*{$name}{$default};/u"; + + preg_match_all($property_pattern, $code, $matches, PREG_SET_ORDER); + + if ($matches != []) + { + $properties = []; + foreach ($matches as $n => $match) + { + $declaration = $match[0] ?? null; + + if (is_string($declaration)) + { + $comment = $this->extractDocBlock($code, $declaration); + $declaration = trim(preg_replace('/\s{2,}/', ' ', + preg_replace('/[\r\n]+/', ' ', $declaration))); + + $properties[] = [ + 'name' => isset($match['name']) ? '$' . $match['name'] : 'error', + 'access' => $match['access'] ?? 'public', + 'type' => isset($match['type']) ? trim($match['type']) : null, + 'static' => (bool) $match['static'] ?? false, + 'default' => $match['default'] ?? null, + 'comment' => $comment, + 'declaration' => $declaration + ]; + } + } + + return $properties; + } + + return null; + } + + /** + * Extracts method declarations and other details from the given code. + * + * @param string $code The code containing class methods + * + * @return array|null An array of method declarations and details + * @since 3.2.0 + */ + private function methods(string $code): ?array + { + // regex to target all methods/functions + $final_modifier = '(?Pfinal)?\s*'; + $abstract_modifier = '(?Pabstract)?\s*'; + $access_modifier = '(?Ppublic|protected|private)?\s*'; + $static_modifier = '(?Pstatic)?\s*'; + $modifier = "{$final_modifier}{$abstract_modifier}{$access_modifier}{$static_modifier}"; + $name = '(?P\w+)'; + $arguments = '(?P\(.*?\))?'; + $return_type = '(?P\s*:\s*(?:\?[\w\\\\]+|\\\\?[\w\\\\]+(?:\|\s*(?:\?[\w\\\\]+|\\\\?[\w\\\\]+))*)?)?'; + $method_pattern = "/(^\s*?\b{$modifier}function\s+{$name}{$arguments}{$return_type})/sm"; + + preg_match_all($method_pattern, $code, $matches, PREG_SET_ORDER); + + if ($matches != []) + { + $methods = []; + foreach ($matches as $n => $match) + { + $full_declaration = $match[0] ?? null; + + if (is_string($full_declaration)) + { + $comment = $this->extractDocBlock($code, $full_declaration); + + $full_declaration = trim(preg_replace('/\s{2,}/', ' ', + preg_replace('/[\r\n]+/', ' ', $full_declaration))); + + // now load what we found + $methods[] = [ + 'name' => $match['name'] ?? 'error', + 'access' => $match['access_modifier'] ?? 'public', + 'static' => (bool) $match['static_modifier'] ?? false, + 'final' => (bool) $match['final_modifier'] ?? false, + 'abstract' => (bool) $match['abstract_modifier'] ?? false, + 'return_type' => $this->extractReturnType($match['return_type'] ?? null, $comment), + 'since' => $this->extractSinceVersion($comment), + 'deprecated' => $this->extractDeprecatedVersion($comment), + 'arguments' => $this->extractFunctionArgumentDetails($comment, $match['arguments'] ?? null), + 'comment' => $comment, + 'declaration' => str_replace(["\r\n", "\r", "\n"], '', $full_declaration) + ]; + } + } + + return $methods; + } + + return null; + } + + /** + * Extracts the PHPDoc block for a given function declaration. + * + * @param string $code The source code containing the function + * @param string $declaration The part of the function declaration + * + * @return string|null The PHPDoc block, or null if not found + * @since 3.2.0 + */ + private function extractDocBlock(string $code, string $declaration): ?string + { + // Split the code string with the function declaration + $parts = explode($declaration, $code); + if (count($parts) < 2) + { + // Function declaration not found in the code + return null; + } + + // Get the part with the comment (if any) + $comment = $parts[0]; + + // Split the last part using the comment block start marker + $commentParts = preg_split('/(})?\s+(?=\s*\/\*)(\*)?/', $comment); + + // Get the last comment block + $lastCommentPart = end($commentParts); + + // Search for the comment block in the last comment part + if (preg_match('/(\/\*\*[\s\S]*?\*\/)\s*$/u', $lastCommentPart, $matches)) + { + $comment = $matches[1] ?? null; + // check if we actually have a comment + if ($comment) + { + return $this->removeWhiteSpaceFromComment($comment); + } + } + + return null; + } + + /** + * Extracts the function argument details. + * + * @param string|null $comment The function comment if found + * @param string|null $arguments The arguments found on function declaration + * + * @return array|null The function argument details + * @since 3.2.0 + */ + private function extractFunctionArgumentDetails(?string $comment, ?string $arguments): ?array + { + $arg_types_from_declaration = $this->extractArgTypesArguments($arguments); + $arg_types_from_comments = null; + + if ($comment) + { + $arg_types_from_comments = $this->extractArgTypesFromComment($comment); + } + + // merge the types + if ($arg_types_from_declaration) + { + return $this->mergeArgumentTypes($arg_types_from_declaration, $arg_types_from_comments); + } + + return null; + } + + /** + * Extracts the function return type. + * + * @param string|null $returnType The return type found in declaration + * @param string|null $comment The function comment if found + * + * @return string|null The function return type + * @since 3.2.0 + */ + private function extractReturnType(?string $returnType, ?string $comment): ?string + { + if ($returnType === null && $comment) + { + return $this->extractReturnTypeFromComment($comment); + } + + return trim(trim($returnType, ':')); + } + + /** + * Extracts argument types from a given comment. + * + * @param string $comment The comment containing the argument types + * + * @return array|null An array of argument types + * @since 3.2.0 + */ + private function extractArgTypesFromComment(string $comment): ?array + { + preg_match_all('/@param\s+((?:[^\s|]+(?:\|)?)+)?\s+\$([^\s]+)/', $comment, $matches, PREG_SET_ORDER); + + if ($matches !== []) + { + $arg_types = []; + + foreach ($matches as $match) + { + $arg = $match[2] ?? null; + $type = $match[1] ?: null; + if (is_string($arg)) + { + $arg_types['$' .$arg] = $type; + } + } + + return $arg_types; + } + + return null; + } + + /** + * Extracts argument types from a given declaration. + * + * @param string|null $arguments The arguments found on function declaration + * + * @return array|null An array of argument types + * @since 3.2.0 + */ + private function extractArgTypesArguments(?string $arguments): ?array + { + if ($arguments) + { + $args = preg_split('/,(?![^()\[\]]*(\)|\]))/', trim($arguments, '()')); + if ($args !== []) + { + $argument_types = []; + foreach ($args as $arg) + { + $eqPos = strpos($arg, '='); + + if ($eqPos !== false) + { + $arg_parts = [ + substr($arg, 0, $eqPos), + substr($arg, $eqPos + 1) + ]; + } + else + { + $arg_parts = [$arg]; + } + + if (preg_match('/(?:(\??(?:\w+|\\\\[\w\\\\]+)(?:\|\s*\??(?:\w+|\\\\[\w\\\\]+))*)\s+)?\$(\w+)/', $arg_parts[0], $arg_matches)) + { + $type = $arg_matches[1] ?: null; + $name = $arg_matches[2] ?: null; + $default = isset($arg_parts[1]) ? preg_replace('/\s{2,}/', ' ', + preg_replace('/[\r\n]+/', ' ', trim($arg_parts[1]))) : null; + + if (is_string($name)) + { + $argument_types['$' . $name] = [ + 'type' => $type, + 'default' => $default, + ]; + } + } + } + + return $argument_types; + } + } + + return null; + } + + /** + * Extracts return type from a given declaration. + * + * @param string $comment The comment containing the return type + * + * @return string|null The return type + * @since 3.2.0 + */ + private function extractReturnTypeFromComment(string $comment): ?string + { + if (preg_match('/@return\s+((?:[^\s|]+(?:\|)?)+)/', $comment, $matches)) + { + return $matches[1] ?: null; + } + + return null; + } + + /** + * Extracts the version number from the @since tag in the given comment. + * + * @param string|null $comment The comment containing the @since tag and version number + * + * @return string|null The extracted version number or null if not found + * @since 3.2.0 + */ + private function extractSinceVersion(?string $comment): ?string + { + if (is_string($comment) && preg_match('/@since\s+(v?\d+(?:\.\d+)*(?:-(?:alpha|beta|rc)\d*)?)/', $comment, $matches)) + { + return $matches[1] ?: null; + } + + return null; + } + + /** + * Extracts the version number from the deprecated tag in the given comment. + * + * @param string|null $comment The comment containing the deprecated tag and version number + * + * @return string|null The extracted version number or null if not found + * @since 3.2.0 + */ + private function extractDeprecatedVersion(?string $comment): ?string + { + if (is_string($comment) && preg_match('/@deprecated\s+(v?\d+(?:\.\d+)*(?:-(?:alpha|beta|rc)\d*)?)/', $comment, $matches)) + { + return $matches[1] ?: null; + } + + return null; + } + + /** + * Remove all white space from each line of the comment + * + * @param string $comment The function declaration containing the return type + * + * @return string The return comment + * @since 3.2.0 + */ + private function removeWhiteSpaceFromComment(string $comment): string + { + // Remove comment markers and leading/trailing whitespace + $comment = preg_replace('/^\/\*\*[\r\n\s]*|[\r\n\s]*\*\/$/m', '', $comment); + $comment = preg_replace('/^[\s]*\*[\s]?/m', '', $comment); + + // Split the comment into lines + $lines = preg_split('/\r\n|\r|\n/', $comment); + + // Remove white spaces from each line + $trimmedLines = array_map('trim', $lines); + + // Join the lines back together + return implode("\n", array_filter($trimmedLines)); + } + + /** + * Merges the types from the comments and the arguments. + * + * @param array $argTypesFromDeclaration An array of argument types and default values from the declaration + * @param array|null $argTypesFromComments An array of argument types from the comments + * + * @return array A merged array of argument information + * @since 3.2.0 + */ + private function mergeArgumentTypes(array $argTypesFromDeclaration, ?array $argTypesFromComments): array + { + $mergedArguments = []; + + foreach ($argTypesFromDeclaration as $name => $declarationInfo) + { + $mergedArguments[$name] = [ + 'name' => $name, + 'type' => $declarationInfo['type'] ?: $argTypesFromComments[$name] ?? null, + 'default' => $declarationInfo['default'] ?: null, + ]; + } + + return $mergedArguments; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Plantuml.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Plantuml.php new file mode 100644 index 000000000..27ed05da3 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Plantuml.php @@ -0,0 +1,459 @@ + + * @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 + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Power; + + +/** + * Compiler Power Plantuml Builder + * @since 3.2.0 + */ +class Plantuml +{ + /** + * Get a namespace diagram of a group of class + * + * @param string $namespace the namespace name + * @param string $classes the ready build class uml + * + * @return string + * @since 3.2.0 + */ + public function namespaceDiagram(string $namespace, string $classes): string + { + $namespace_depth = substr_count($namespace, '\\'); + $namespace_color = $this->getNamespaceColor($namespace_depth); + + // Set the scale of the diagram + // $plant_uml = "scale 0.8\n\n"; + + // Add namespace + $plant_uml = "namespace $namespace #$namespace_color {\n\n"; + + // Add class + $plant_uml .= $classes; + + $plant_uml .= "}\n"; + + return $plant_uml; + } + + /** + * Get a class basic diagram of a class + * + * @param array $power the class being built + * @param array $code the class code being built + * + * @return string + * @since 3.2.0 + */ + public function classBasicDiagram(array $power, array $code): string + { + // Set some global values + $class_name = $power['name']; + $class_type = $power['type']; + + // set the class color + $class_color = $this->getClassColor($class_type); + + // set the class type label + $type_label = $this->getClassTypeLable($class_type); + + // set the class type tag + $type_tag = $this->getClassTypeTag($class_type); + + // Add class + $plant_uml = "\n $type_label $class_name $type_tag #$class_color {\n"; + + // Add properties + if ($code['properties']) + { + $plant_uml .= $this->generatePropertiesPlantUML($code['properties'], ' '); + } + + // Add methods + if ($code['methods']) + { + $plant_uml .= $this->generateBasicMethodsPlantUML($code['methods']); + } + + $plant_uml .= " }\n"; + + return $plant_uml; + } + + /** + * Get a class detailed diagram of a class + * + * @param array $power the class being built + * @param array $code the class code being built + * + * @return string + * @since 3.2.0 + */ + public function classDetailedDiagram(array $power, array $code): string + { + // Set some global values + $class_name = $power['name']; + $class_type = $power['type']; + + // set the class color + $class_color = $this->getClassColor($class_type); + + // set the class type label + $type_label = $this->getClassTypeLable($class_type); + + // set the class type tag + $type_tag = $this->getClassTypeTag($class_type); + + // Add class + $plant_uml = "\n$type_label $class_name $type_tag #$class_color {\n"; + + // Add properties + if ($code['properties']) + { + $plant_uml .= $this->generatePropertiesPlantUML($code['properties'], ' '); + } + + // Add methods + if ($code['methods']) + { + list($methods_plant_uml, $notes) = $this->generateDetailedMethodsPlantUML($code['methods'], $class_name); + $plant_uml .= $methods_plant_uml; + } + + $plant_uml .= "}\n"; + + if (!empty($notes)) + { + $plant_uml .= $this->generateNotesPlantUML($notes); + } + + return $plant_uml; + } + + /** + * Generate properties PlantUML + * + * @param array $properties + * @param string $space + * + * @return string + * @since 3.2.0 + */ + private function generatePropertiesPlantUML(array $properties, string $space): string + { + $plant_uml = ""; + + foreach ($properties as $property) + { + $access_sign = $this->getAccessSign($property['access']); + $static = $property['static'] ? '{static} ' : ''; + $type = $property['type'] ? $property['type'] . ' ' : ''; + $plant_uml .= "{$space}$access_sign $static{$type}{$property['name']}\n"; + } + + return $plant_uml; + } + + /** + * Generate detailed methods PlantUML + * + * @param array $methods + * @param string $class_name + * + * @return array + * @since 3.2.0 + */ + private function generateDetailedMethodsPlantUML(array $methods, string $class_name): array + { + $plant_uml = ""; + $notes = []; + + foreach ($methods as $method) + { + $notes = $this->generateMethodNotes($method, $class_name, $notes); + + $access_sign = $this->getAccessSign($method['access']); + + $arguments = ''; + if ($method['arguments']) + { + $arguments = $this->generateMethodArgumentsAndNotes( + $method['arguments'], $class_name, $method['name'], $notes); + + $arguments = implode(', ', $arguments); + } + + $static = $method['static'] ? '{static} ' : ''; + $abstract = $method['abstract'] ? '{abstract} ' : ''; + $return_type = $method['return_type'] ? " : {$method['return_type']}" : ''; + + $plant_uml .= " $access_sign {$abstract}$static{$method['name']}({$arguments})$return_type\n"; + } + + return [$plant_uml, $notes]; + } + + /** + * Generate basic methods PlantUML + * + * @param array $properties + * + * @return string + * @since 3.2.0 + */ + private function generateBasicMethodsPlantUML(array $methods): string + { + $plant_uml = ""; + + foreach ($methods as $method) + { + $access_sign = $this->getAccessSign($method['access']); + $static = $method['static'] ? '{static} ' : ''; + $abstract = $method['abstract'] ? '{abstract} ' : ''; + $return_type = $method['return_type'] ? " : {$method['return_type']}" : ''; + $plant_uml .= " $access_sign {$abstract}$static{$method['name']}()$return_type\n"; + } + + return $plant_uml; + } + + /** + * Generate method arguments and notes + * + * @param array $arguments + * @param string $class_name + * @param string $method_name + * @param array $notes + * + * @return array + * @since 3.2.0 + */ + private function generateMethodArgumentsAndNotes(array $arguments, string $class_name, + string $method_name, array &$notes): array + { + $formatted_arguments = []; + $notes_bucket = []; + $limit = 2; + + foreach ($arguments as $name => $arg) + { + $arg_type = $arg['type'] ? "{$arg['type']} " : ''; + $arg_default = $arg['default'] ? " = {$arg['default']}" : ''; + $arg_statment = "{$arg_type}$name{$arg_default}"; + + if ($limit == 0) + { + $formatted_arguments[] = "..."; + $limit = -1; + } + elseif ($limit > 0) + { + $formatted_arguments[] = $arg_statment; + $limit--; + } + + $notes_bucket[] = $arg_statment; + } + + if ($limit == -1) + { + $notes["{$class_name}::{$method_name}"][] = "\n arguments:\n " . implode("\n ", $notes_bucket); + } + + return $formatted_arguments; + } + + /** + * Generate method notes + * + * @param array $method + * @param string $class_name + * @param array $notes + * + * @return array + */ + private function generateMethodNotes(array $method, string $class_name, array &$notes): array + { + $notes_key = "{$class_name}::{$method['name']}"; + + if (is_string($method['comment']) && strlen($method['comment']) > 4) + { + $notes[$notes_key][] = trim(preg_replace("/^@.*[\r\n]*/m", '', $method['comment'])) . "\n"; + } + + if (is_string($method['since']) && strlen($method['since']) > 3) + { + $notes[$notes_key][] = "since: {$method['since']}"; + } + + if (is_string($method['return_type']) && strlen($method['return_type']) > 1) + { + $notes[$notes_key][] = "return: {$method['return_type']}"; + } + + if (is_string($method['deprecated']) && strlen($method['deprecated']) > 3) + { + $notes[$notes_key][] = "deprecated: {$method['deprecated']}"; + } + + return $notes; + } + + /** + * Generate notes PlantUML + * + * @param array $notes + * + * @return string + * @since 3.2.0 + */ + private function generateNotesPlantUML(array $notes): string + { + $plant_uml = ""; + $note_count = count($notes); + + $positions = ['right', 'left']; + $position_index = 0; + + foreach ($notes as $area => $note) + { + if ($note_count <= 7) + { + $position = 'right'; + } + else + { + $position = $positions[$position_index % 2]; + $position_index++; + } + + $plant_uml .= "\nnote $position of {$area}\n"; + $plant_uml .= " " . implode("\n ", $note) . "\n"; + $plant_uml .= "end note\n"; + } + + return $plant_uml; + } + + /** + * Get the access sign based on the access level. + * + * @param string $access The access level. + * + * @return string The corresponding access sign. + * @since 3.2.0 + */ + private function getAccessSign(string $access): string + { + switch ($access) + { + case 'private': + return '-'; + case 'protected': + return '#'; + case 'public': + return '+'; + case 'var': + return '+'; + default: + return ''; + } + } + + /** + * Get the correct class type. + * + * @param string $type The class type. + * + * @return string The correct class type label. + * @since 3.2.0 + */ + private function getClassTypeLable(string $type): string + { + $class_type_updater = [ + 'final class' => 'class', + 'abstract class' => 'abstract', + 'trait' => 'class' + ]; + + return $class_type_updater[$type] ?? $type; + } + + /** + * Get the extra class type tag. + * + * @param string $type The class type. + * + * @return string The correct class type label. + * @since 3.2.0 + */ + private function getClassTypeTag(string $type): string + { + $class_type_updater = [ + 'final class' => '<< (F,LightGreen) >>', + 'trait' => '<< (T,Orange) >>' + ]; + + return $class_type_updater[$type] ?? ''; + } + + /** + * Get class color based on class type. + * + * @param string $classType The class type. + * + * @return string The corresponding color. + * @since 3.2.0 + */ + private function getClassColor(string $classType): string + { + $class_colors = [ + 'class' => 'Gold', + 'final' => 'RoyalBlue', + 'abstract class' => 'Orange', + 'interface' => 'Lavender', + 'trait' => 'Turquoise' + ]; + + return $class_colors[$classType] ?? 'Green'; + } + + /** + * Get namespace color based on namespace depth. + * + * @param int $namespaceDepth The depth of the namespace. + * + * @return string The corresponding color. + * @since 3.2.0 + */ + private function getNamespaceColor(int $namespaceDepth): string + { + $namespace_colors = [ + 'lightgrey', + 'Azure', + 'DarkCyan', + 'Olive', + 'LightGreen', + 'DeepSkyBlue', + 'Wheat', + 'Coral', + 'Beige', + 'DeepPink', + 'DeepSkyBlue' + ]; + + return $namespace_colors[$namespaceDepth % count($namespace_colors)] ?? 'lightgrey'; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repo/Readme.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repo/Readme.php new file mode 100644 index 000000000..c3eb0e197 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repo/Readme.php @@ -0,0 +1,104 @@ + + * @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 + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Power\Repo; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Power; +use VDM\Joomla\Componentbuilder\Compiler\Power\Plantuml; + + +/** + * Compiler Power Repo Readme + * @since 3.2.0 + */ +class Readme +{ + /** + * Power Objects + * + * @var Power + * @since 3.2.0 + **/ + protected Power $power; + + /** + * Compiler Powers Plantuml Builder + * + * @var Plantuml + * @since 3.2.0 + **/ + protected Plantuml $plantuml; + + /** + * Constructor. + * + * @param Power|null $power The power object. + * @param Plantuml|null $plantuml The powers plantuml builder object. + * + * @since 3.2.0 + */ + public function __construct(?Power $power = null, ?Plantuml $plantuml = null) + { + $this->power = $power ?: Compiler::_('Power'); + $this->plantuml = $plantuml ?: Compiler::_('Power.Plantuml'); + } + + /** + * Get a Power Readme + * + * @param object $power A power details. + * + * @return string + * @since 3.2.0 + */ + public function get(object $power): string + { + // build readme + $readme = ["``` +██████╗ ██████╗ ██╗ ██╗███████╗██████╗ +██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗ +██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝ +██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗ +██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║ +╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝ +```"]; + // add the class diagram + if (isset($power->parsed_class_code) && is_array($power->parsed_class_code)) + { + $readme[] = "# " . $power->type . " " . $power->code_name . " (Details)"; + $readme[] = "> namespace: **" . $power->_namespace . "**"; + $readme[] = "```uml\n@startuml" . $this->plantuml->classDetailedDiagram( + ['name' => $power->code_name, 'type' => $power->type], + $power->parsed_class_code + ) . " \n@enduml\n```"; + } + else + { + $readme[] = "> Error adding class diagram"; + } + + // yes you can remove this, but why? + $readme[] = "\n---\n``` + ██╗ ██████╗██████╗ + ██║██╔════╝██╔══██╗ + ██║██║ ██████╔╝ +██ ██║██║ ██╔══██╗ +╚█████╔╝╚██████╗██████╔╝ + ╚════╝ ╚═════╝╚═════╝ +```\n> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)\n\n"; + + return implode("\n", $readme); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repo/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repo/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repo/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repos/Readme.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repos/Readme.php new file mode 100644 index 000000000..4b4ec0fc9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repos/Readme.php @@ -0,0 +1,409 @@ + + * @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 + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Power\Repos; + + +use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; +use VDM\Joomla\Componentbuilder\Compiler\Power; +use VDM\Joomla\Componentbuilder\Compiler\Power\Plantuml; + + +/** + * Compiler Power Repos Readme + * @since 3.2.0 + */ +class Readme +{ + /** + * Power Objects + * + * @var Power + * @since 3.2.0 + **/ + protected Power $power; + + /** + * Compiler Powers Plantuml Builder + * + * @var Plantuml + * @since 3.2.0 + **/ + protected Plantuml $plantuml; + + /** + * Constructor. + * + * @param Power|null $power The power object. + * @param Plantuml|null $plantuml The powers plantuml builder object. + * + * @since 3.2.0 + */ + public function __construct(?Power $power = null, ?Plantuml $plantuml = null) + { + $this->power = $power ?: Compiler::_('Power'); + $this->plantuml = $plantuml ?: Compiler::_('Power.Plantuml'); + } + + /** + * Get Super Power Readme + * + * @param array $powers All powers of this super power. + * + * @return string + * @since 3.2.0 + */ + public function get(array $powers): string + { + // build readme + $readme = ["``` +███████╗██╗ ██╗██████╗ ███████╗██████╗ +██╔════╝██║ ██║██╔══██╗██╔════╝██╔══██╗ +███████╗██║ ██║██████╔╝█████╗ ██████╔╝ +╚════██║██║ ██║██╔═══╝ ██╔══╝ ██╔══██╗ +███████║╚██████╔╝██║ ███████╗██║ ██║ +╚══════╝ ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ +██████╗ ██████╗ ██╗ ██╗███████╗██████╗ ███████╗ +██╔══██╗██╔═══██╗██║ ██║██╔════╝██╔══██╗██╔════╝ +██████╔╝██║ ██║██║ █╗ ██║█████╗ ██████╔╝███████╗ +██╔═══╝ ██║ ██║██║███╗██║██╔══╝ ██╔══██╗╚════██║ +██║ ╚██████╔╝╚███╔███╔╝███████╗██║ ██║███████║ +╚═╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝╚═╝ ╚═╝╚══════╝ +```"]; + + // default description of super powers + $readme[] = "\n### What is JCB Super Powers?\nThe Joomla Component Builder (JCB) Super Power features are designed to enhance JCB's functionality and streamline the development process. These Super Powers enable developers to efficiently manage and share their custom powers across multiple JCB instances through repositories hosted on [https://git.vdm.dev/[username]/[repository-name]](https://git.vdm.dev). JCB Super Powers are managed using a combination of layers, events, tasks, methods, switches, and algorithms, which work together to provide powerful customization and extensibility options. More details on JCB Super Powers can be found in the [Super Powers Documentation](https://git.vdm.dev/joomla/super-powers/wiki).\n\nIn summary, JCB Super Powers offer a flexible and efficient way to manage and share functionalities between JCB instances. By utilizing a sophisticated system of layers, events, tasks, methods, switches, and algorithms, developers can seamlessly integrate JCB core powers and their custom powers. For more information on how to work with JCB Super Powers, refer to the [Super Powers User Guide](https://git.vdm.dev/joomla/super-powers/wiki).\n\n### What can I find here?\nThis repository contains an index (see below) of all the approved powers within the JCB GUI. During the compilation of a component, these powers are automatically added to the repository, ensuring a well-organized and accessible collection of functionalities.\n"; + + // get the readme body + $readme[] = $this->readmeBuilder($powers); + + // yes you can remove this, but why? + $readme[] = "\n---\n``` + ██╗ ██████╗ ██████╗ ███╗ ███╗██╗ █████╗ + ██║██╔═══██╗██╔═══██╗████╗ ████║██║ ██╔══██╗ + ██║██║ ██║██║ ██║██╔████╔██║██║ ███████║ +██ ██║██║ ██║██║ ██║██║╚██╔╝██║██║ ██╔══██║ +╚█████╔╝╚██████╔╝╚██████╔╝██║ ╚═╝ ██║███████╗██║ ██║ + ╚════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ + ██████╗ ██████╗ ███╗ ███╗██████╗ ██████╗ ███╗ ██╗███████╗███╗ ██╗████████╗ +██╔════╝██╔═══██╗████╗ ████║██╔══██╗██╔═══██╗████╗ ██║██╔════╝████╗ ██║╚══██╔══╝ +██║ ██║ ██║██╔████╔██║██████╔╝██║ ██║██╔██╗ ██║█████╗ ██╔██╗ ██║ ██║ +██║ ██║ ██║██║╚██╔╝██║██╔═══╝ ██║ ██║██║╚██╗██║██╔══╝ ██║╚██╗██║ ██║ +╚██████╗╚██████╔╝██║ ╚═╝ ██║██║ ╚██████╔╝██║ ╚████║███████╗██║ ╚████║ ██║ + ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═════╝ ╚═╝ ╚═══╝╚══════╝╚═╝ ╚═══╝ ╚═╝ +██████╗ ██╗ ██╗██╗██╗ ██████╗ ███████╗██████╗ +██╔══██╗██║ ██║██║██║ ██╔══██╗██╔════╝██╔══██╗ +██████╔╝██║ ██║██║██║ ██║ ██║█████╗ ██████╔╝ +██╔══██╗██║ ██║██║██║ ██║ ██║██╔══╝ ██╔══██╗ +██████╔╝╚██████╔╝██║███████╗██████╔╝███████╗██║ ██║ +╚═════╝ ╚═════╝ ╚═╝╚══════╝╚═════╝ ╚══════╝╚═╝ ╚═╝ +```\n> Build with [Joomla Component Builder](https://git.vdm.dev/joomla/Component-Builder)\n\n"; + + return implode("\n", $readme); + } + + /** + * The readme builder + * + * @param array $classes The powers. + * + * @return string + * @since 3.2.0 + */ + private function readmeBuilder(array &$powers): string + { + $classes = []; + foreach ($powers as $guid => $power) + { + $power_object = $this->power->get($guid); + if (isset($power_object->parsed_class_code) && is_array($power_object->parsed_class_code)) + { + // add to the sort bucket + $classes[] = [ + 'namespace' => $power['namespace'], + 'type' => $power['type'], + 'name' => $power['name'], + 'link' => $this->indexLinkPower($power), + 'diagram' => $this->plantuml->classBasicDiagram($power, $power_object->parsed_class_code) + ]; + } + } + + return $this->readmeModel($classes); + } + + /** + * Sort and model the readme classes + * + * @param array $classes The powers. + * + * @return string + * @since 3.2.0 + */ + private function readmeModel(array &$classes): string + { + $this->sortClasses($classes, $this->defineTypeOrder()); + + $result = $this->generateIndex($classes); + + $diagram_bucket = $this->generateDiagramBucket($classes); + + return $result . $diagram_bucket; + } + + /** + * Generate the index string for classes + * + * @param array $classes The sorted classes + * + * @return string The index string + */ + private function generateIndex(array &$classes): string + { + $result = "# Index of powers\n"; + $current_namespace = null; + + foreach ($classes as $class) + { + if ($class['namespace'] !== $current_namespace) + { + $current_namespace = $class['namespace']; + $result .= "\n- **Namespace**: [{$current_namespace}](#" . + strtolower(str_replace('\\', '-', $current_namespace)) . ")\n"; + } + + // Add the class details + $result .= "\n - " . $class['link']; + } + + return $result; + } + + /** + * Generate the diagram bucket string for classes + * + * @param array $classes The sorted classes + * + * @return string The diagram bucket string + */ + private function generateDiagramBucket(array &$classes): string + { + $diagram_bucket = "\n\n# Class Diagrams\n"; + $current_namespace = null; + $diagrams = ''; + + foreach ($classes as $class) + { + if ($class['namespace'] !== $current_namespace) + { + if ($current_namespace !== null) + { + $diagram_bucket .= $this->generateNamespaceDiagram($current_namespace, $diagrams); + } + $current_namespace = $class['namespace']; + $diagrams = ''; + } + + $diagrams .= $class['diagram']; + } + + // Add the last namespace diagram + $diagram_bucket .= $this->generateNamespaceDiagram($current_namespace, $diagrams); + + return $diagram_bucket; + } + + /** + * Define the order of types for sorting purposes + * + * @return array The order of types + * @since 3.2.0 + */ + private function defineTypeOrder(): array + { + return [ + 'interface' => 1, + 'abstract' => 2, + 'abstract class' => 2, + 'final' => 3, + 'final class' => 3, + 'class' => 4, + 'trait' => 5 + ]; + } + + /** + * Sort the flattened array using a single sorting function + * + * @param array $classes The classes to sort + * @param array $typeOrder The order of types + * @since 3.2.0 + */ + private function sortClasses(array &$classes, array $typeOrder): void + { + usort($classes, function ($a, $b) use ($typeOrder) { + $namespaceDiff = $this->compareNamespace($a, $b); + + if ($namespaceDiff !== 0) + { + return $namespaceDiff; + } + + $typeDiff = $this->compareType($a, $b, $typeOrder); + + if ($typeDiff !== 0) + { + return $typeDiff; + } + + return $this->compareName($a, $b); + }); + } + + /** + * Compare the namespace of two classes + * + * @param array $a First class + * @param array $b Second class + * + * @return int Comparison result + * @since 3.2.0 + */ + private function compareNamespace(array $a, array $b): int + { + $namespaceDepthDiff = substr_count($a['namespace'], '\\') - substr_count($b['namespace'], '\\'); + + if ($namespaceDepthDiff === 0) + { + return strcmp($a['namespace'], $b['namespace']); + } + + return $namespaceDepthDiff; + } + + /** + * Compare the type of two classes + * + * @param array $a First class + * @param array $b Second class + * @param array $typeOrder The order of types + * + * @return int Comparison result + * @since 3.2.0 + */ + private function compareType(array $a, array $b, array $typeOrder): int + { + return $typeOrder[$a['type']] - $typeOrder[$b['type']]; + } + + /** + * Compare the name of two classes + * + * @param array $a First class + * @param array $b Second class + * + * @return int Comparison result + * @since 3.2.0 + */ + private function compareName(array $a, array $b): int + { + return strcmp($a['name'], $b['name']); + } + + /** + * Generate a namespace diagram string + * + * @param string $current_namespace The current namespace + * @param string $diagrams The diagrams for the namespace + * + * @return string The namespace diagram string + */ + private function generateNamespaceDiagram(string $current_namespace, string $diagrams): string + { + $namespace_title = str_replace('\\', ' ', $current_namespace); + $diagram_code = "\n## {$namespace_title}\n> namespace {$current_namespace}\n"; + $diagram_code .= "```uml\n@startuml\n\n" . + $this->plantuml->namespaceDiagram($current_namespace, $diagrams) . "\n\n@enduml\n```\n"; + + return $diagram_code; + } + + /** + * Build the Link to the power in this repository + * + * @param string $power The power details. + * + * @return string + * @since 3.2.0 + */ + private function indexLinkPower(array &$power): string + { + return '**' . $power['type'] . ' ' . $power['name'] . "** | " + . $this->linkPowerRepo($power) . ' | ' + . $this->linkPowerCode($power) . ' | ' + . $this->linkPowerSettings($power) . ' | ' + . $this->linkPowerSPK($power); + } + + /** + * Build the Link to the power in this repository + * + * @param string $power The power details. + * + * @return string + * @since 3.2.0 + */ + private function linkPowerRepo(array &$power): string + { + return '[Details](' . $power['path'] . ')'; + } + + /** + * Build the Link to the power settings in this repository + * + * @param string $power The power details. + * + * @return string + * @since 3.2.0 + */ + private function linkPowerCode(array &$power): string + { + return '[Code](' . $power['code'] . ')'; + } + + /** + * Build the Link to the power settings in this repository + * + * @param string $power The power details. + * + * @return string + * @since 3.2.0 + */ + private function linkPowerSettings(array &$power): string + { + return '[Settings](' . $power['settings'] . ')'; + } + + /** + * Get the SuperPowerKey (SPK) + * + * @param string $power The power details. + * + * @return string + * @since 3.2.0 + */ + private function linkPowerSPK(array &$power): string + { + return $power['spk']; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repos/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repos/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Repos/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Structure.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Structure.php index 644f21765..5549fd955 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Structure.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Power/Structure.php @@ -181,6 +181,9 @@ class Structure // for plugin event TODO change event api signatures $this->power->active = $powers; + // set super power details + $this->setSuperPowerDetails(); + foreach ($this->power->active as $power) { if (ObjectHelper::check($power) @@ -209,11 +212,6 @@ class Structure $this->folder->create($power->full_path_parent); $this->folder->create($power->full_path); - // set power file - $fileDetails = array('path' => $power->full_path . '/' - . $power->file_name . '.php', - 'name' => $power->file_name . '.php', - 'zip' => $power->file_name . '.php'); $bom = 'licensing_template; } - $this->file->write( - $fileDetails['path'], - $bom . PHP_EOL . Placefix::_h('POWERCODE') - . PHP_EOL . Placefix::_h('POWERLINKER') - ); - $this->files->appendArray($power->key, $fileDetails); - // count the file created - $this->counter->file++; + // set the main power php file + $this->createFile($bom . PHP_EOL . Placefix::_h('POWERCODE') . PHP_EOL, + $power->full_path, $power->file_name . '.php', $power->key); + + // set super power files + $this->setSuperPowerFiles($power, $bom); // set htaccess once per path $this->setHtaccess($power); @@ -239,6 +235,35 @@ class Structure } } + /** + * Create a file with optional custom content and save it to the given path. + * + * @param string $content The content. + * @param string $fullPath The full path to the destination folder. + * @param string $fileName The file name without the extension. + * @param string $key The key to append the file details. + * + * @return void + * @since 3.2.0 + */ + private function createFile(string $content, string $fullPath, string $fileName, string $key) + { + $file_details = [ + 'path' => $fullPath . '/' . $fileName, + 'name' => $fileName, + 'zip' => $fileName + ]; + + // Write the content to the file + $this->file->write($file_details['path'], $content); + + // Append the file details to the files array + $this->files->appendArray($key, $file_details); + + // Increment the file counter + $this->counter->file++; + } + /** * Set the .htaccess for this power path * @@ -247,7 +272,7 @@ class Structure * @return void * @since 3.2.0 */ - protected function setHtaccess(object &$power) + private function setHtaccess(object &$power) { if (!isset($this->htaccess[$power->path_jcb])) { @@ -320,7 +345,7 @@ class Structure // check if we should add the dynamic folder moving script to the installer script if (!$this->registry->get('set_move_folders_install_script')) { - // add the setDynamicF0ld3rs() method to the install scipt.php file + // add the setDynamicF0ld3rs() method to the install script.php file $this->registry->set('set_move_folders_install_script', true); // set message that this was done (will still add a tutorial link later) @@ -334,6 +359,71 @@ class Structure ); } } + + /** + * Set the super powers details structure + * + * @return void + * @since 3.2.0 + */ + private function setSuperPowerDetails() + { + if ($this->config->add_super_powers && ArrayHelper::check($this->power->superpowers)) + { + foreach ($this->power->superpowers as $path => $powers) + { + // create the path if it does not exist + $this->folder->create($path, false); + + $key = StringHelper::safe($path); + + // set the super powers readme file + $this->createFile(Placefix::_h('POWERREADME'), + $path, 'README.md', $key); + + // set the super power index file + $this->createFile(Placefix::_h('POWERINDEX'), $path, + 'super-powers.json', $key); + } + } + } + + /** + * Set the super power file paths + * + * @param object $power The power object + * @param string $bom The bom for the top of the PHP files + * + * @return void + * @since 3.2.0 + */ + private function setSuperPowerFiles(object &$power, string $bom) + { + if ($this->config->add_super_powers && is_array($power->super_power_paths) && $power->super_power_paths !== []) + { + foreach ($power->super_power_paths as $path) + { + // create the path if it does not exist + $this->folder->create($path, false); + + // set the super power php file + $this->createFile($bom . PHP_EOL . Placefix::_h('POWERCODE') . PHP_EOL, + $path, 'code.php', $power->key); + + // set the super power php RAW file + $this->createFile(Placefix::_h('CODEPOWER'), + $path, 'code.power', $power->key); + + // set the super power json file + $this->createFile(Placefix::_h('POWERLINKER'), $path, + 'settings.json', $power->key); + + // set the super power readme file + $this->createFile(Placefix::_h('POWERREADME'), $path, + 'README.md', $power->key); + } + } + } } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Builder.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Builder.php new file mode 100644 index 000000000..c33779c41 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Builder.php @@ -0,0 +1,55 @@ + + * @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 + */ + +namespace VDM\Joomla\Componentbuilder\Compiler\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Componentbuilder\Compiler\Builder\Update\Mysql; + + +/** + * Builder Service Provider + * + * @since 3.2.0 + */ +class Builder implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Mysql::class, 'Builder.Update.Mysql') + ->share('Builder.Update.Mysql', [$this, 'getMysql'], true); + } + + /** + * Get the Compiler Builder Mysql + * + * @param Container $container The DI container. + * + * @return Mysql + * @since 3.2.0 + */ + public function getMysql(Container $container): Mysql + { + return new Mysql(); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Customcode.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Customcode.php index 1f9cd2181..f33011fb6 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Customcode.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Customcode.php @@ -81,6 +81,7 @@ class Customcode implements ServiceProviderInterface $container->get('Config'), $container->get('Placeholder'), $container->get('Language.Extractor'), + $container->get('Power.Extractor'), $container->get('Customcode.External') ); } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Database.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Database.php index 2e216c5ea..c0dcc208d 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Database.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Database.php @@ -16,6 +16,7 @@ use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use VDM\Joomla\Componentbuilder\Database\Load; use VDM\Joomla\Componentbuilder\Database\Insert; +use VDM\Joomla\Componentbuilder\Database\Update; /** @@ -40,6 +41,9 @@ class Database implements ServiceProviderInterface $container->alias(Insert::class, 'Insert') ->share('Insert', [$this, 'getInsert'], true); + + $container->alias(Update::class, 'Update') + ->share('Update', [$this, 'getUpdate'], true); } /** @@ -67,6 +71,18 @@ class Database implements ServiceProviderInterface { return new Insert(); } - + + /** + * Get the Core Update Database + * + * @param Container $container The DI container. + * + * @return Update + * @since 3.2.0 + */ + public function getUpdate(Container $container): Update + { + return new Update(); + } } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Model.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Model.php index 3650a8279..c7fd1d310 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Model.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Model.php @@ -772,9 +772,7 @@ class Model implements ServiceProviderInterface */ public function getUpdateserver(Container $container): Updateserver { - return new Updateserver( - $container->get('Registry') - ); + return new Updateserver(); } /** diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Placeholder.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Placeholder.php index c25b86f29..4561b63c7 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Placeholder.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Placeholder.php @@ -71,7 +71,8 @@ class Placeholder implements ServiceProviderInterface $container->get('Config'), $container->get('Placeholder'), $container->get('Language'), - $container->get('Language.Extractor') + $container->get('Language.Extractor'), + $container->get('Power.Extractor') ); } } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Power.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Power.php index 7f39613be..2222e5a2a 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Power.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Service/Power.php @@ -15,9 +15,20 @@ namespace VDM\Joomla\Componentbuilder\Compiler\Service; use Joomla\DI\Container; use Joomla\DI\ServiceProviderInterface; use VDM\Joomla\Componentbuilder\Compiler\Power as Powers; +use VDM\Joomla\Componentbuilder\Power\Grep; +use VDM\Joomla\Componentbuilder\Power\Super as Superpower; use VDM\Joomla\Componentbuilder\Compiler\Power\Infusion; use VDM\Joomla\Componentbuilder\Compiler\Power\Autoloader; use VDM\Joomla\Componentbuilder\Compiler\Power\Structure; +use VDM\Joomla\Componentbuilder\Compiler\Power\Parser; +use VDM\Joomla\Componentbuilder\Compiler\Power\Plantuml; +use VDM\Joomla\Componentbuilder\Compiler\Power\Repo\Readme as RepoReadme; +use VDM\Joomla\Componentbuilder\Compiler\Power\Repos\Readme as ReposReadme; +use VDM\Joomla\Componentbuilder\Compiler\Power\Extractor; +use VDM\Joomla\Componentbuilder\Compiler\Power\Injector; +use VDM\Joomla\Componentbuilder\Power\Model; +use VDM\Joomla\Componentbuilder\Power\Database\Insert; +use VDM\Joomla\Componentbuilder\Power\Database\Update; /** @@ -40,6 +51,12 @@ class Power implements ServiceProviderInterface $container->alias(Powers::class, 'Power') ->share('Power', [$this, 'getPowers'], true); + $container->alias(Superpower::class, 'Superpower') + ->share('Superpower', [$this, 'getSuperpower'], true); + + $container->alias(Grep::class, 'Power.Grep') + ->share('Power.Grep', [$this, 'getGrep'], true); + $container->alias(Autoloader::class, 'Power.Autoloader') ->share('Power.Autoloader', [$this, 'getAutoloader'], true); @@ -48,6 +65,33 @@ class Power implements ServiceProviderInterface $container->alias(Structure::class, 'Power.Structure') ->share('Power.Structure', [$this, 'getStructure'], true); + + $container->alias(Parser::class, 'Power.Parser') + ->share('Power.Parser', [$this, 'getParser'], true); + + $container->alias(Plantuml::class, 'Power.Plantuml') + ->share('Power.Plantuml', [$this, 'getPlantuml'], true); + + $container->alias(RepoReadme::class, 'Power.Repo.Readme') + ->share('Power.Repo.Readme', [$this, 'getRepoReadme'], true); + + $container->alias(ReposReadme::class, 'Power.Repos.Readme') + ->share('Power.Repos.Readme', [$this, 'getReposReadme'], true); + + $container->alias(Extractor::class, 'Power.Extractor') + ->share('Power.Extractor', [$this, 'getExtractor'], true); + + $container->alias(Injector::class, 'Power.Injector') + ->share('Power.Injector', [$this, 'getInjector'], true); + + $container->alias(Model::class, 'Power.Model') + ->share('Power.Model', [$this, 'getModel'], true); + + $container->alias(Insert::class, 'Power.Insert') + ->share('Power.Insert', [$this, 'getInsert'], true); + + $container->alias(Update::class, 'Power.Update') + ->share('Power.Update', [$this, 'getUpdate'], true); } /** @@ -68,6 +112,40 @@ class Power implements ServiceProviderInterface ); } + /** + * Get the Superpower + * + * @param Container $container The DI container. + * + * @return Superpower + * @since 3.2.0 + */ + public function getSuperpower(Container $container): Superpower + { + return new Superpower( + $container->get('Power.Grep'), + $container->get('Power.Insert'), + $container->get('Power.Update') + ); + } + + /** + * Get the Grep + * + * @param Container $container The DI container. + * + * @return Grep + * @since 3.2.0 + */ + public function getGrep(Container $container): Grep + { + return new Grep( + $container->get('Config')->local_powers_repository_path, + $container->get('Config')->approved_paths, + $container->get('Gitea.Repository.Contents') + ); + } + /** * Get the Compiler Autoloader * @@ -100,6 +178,9 @@ class Power implements ServiceProviderInterface $container->get('Power'), $container->get('Content'), $container->get('Power.Autoloader'), + $container->get('Power.Parser'), + $container->get('Power.Repo.Readme'), + $container->get('Power.Repos.Readme'), $container->get('Placeholder'), $container->get('Event') ); @@ -127,6 +208,141 @@ class Power implements ServiceProviderInterface $container->get('Utilities.Files') ); } - + + /** + * Get the Compiler Power Parser + * + * @param Container $container The DI container. + * + * @return Structure + * @since 3.2.0 + */ + public function getParser(Container $container): Parser + { + return new Parser(); + } + + /** + * Get the Compiler Power Plantuml Builder + * + * @param Container $container The DI container. + * + * @return Plantuml + * @since 3.2.0 + */ + public function getPlantuml(Container $container): Plantuml + { + return new Plantuml(); + } + + /** + * Get the Compiler Power Repo Readme Builder + * + * @param Container $container The DI container. + * + * @return RepoReadme + * @since 3.2.0 + */ + public function getRepoReadme(Container $container): RepoReadme + { + return new RepoReadme( + $container->get('Power'), + $container->get('Power.Plantuml') + ); + } + + /** + * Get the Compiler Power Repos Readme Builder + * + * @param Container $container The DI container. + * + * @return ReposReadme + * @since 3.2.0 + */ + public function getReposReadme(Container $container): ReposReadme + { + return new ReposReadme( + $container->get('Power'), + $container->get('Power.Plantuml') + ); + } + + /** + * Get the Compiler Power Extractor + * + * @param Container $container The DI container. + * + * @return Extractor + * @since 3.2.0 + */ + public function getExtractor(Container $container): Extractor + { + return new Extractor(); + } + + /** + * Get the Compiler Power Injector + * + * @param Container $container The DI container. + * + * @return Injector + * @since 3.2.0 + */ + public function getInjector(Container $container): Injector + { + return new Injector( + $container->get('Power'), + $container->get('Power.Extractor'), + $container->get('Power.Parser'), + $container->get('Placeholder') + ); + } + + /** + * Get the Power Model + * + * @param Container $container The DI container. + * + * @return Model + * @since 3.2.0 + */ + public function getModel(Container $container): Model + { + return new Model( + $container->get('Table') + ); + } + + /** + * Get the Power Insert + * + * @param Container $container The DI container. + * + * @return Insert + * @since 3.2.0 + */ + public function getInsert(Container $container): Insert + { + return new Insert( + $container->get('Power.Model'), + $container->get('Insert') + ); + } + + /** + * Get the Power Update + * + * @param Container $container The DI container. + * + * @return Update + * @since 3.2.0 + */ + public function getUpdate(Container $container): Update + { + return new Update( + $container->get('Power.Model'), + $container->get('Update') + ); + } } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Folder.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Folder.php index 2c983eac8..b59a62dbb 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Folder.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Compiler/Utilities/Folder.php @@ -60,12 +60,13 @@ class Folder /** * Create Path if not exist * - * @param string $path The path to folder to create + * @param string $path The path to folder to create + * @param bool $addHtml The the switch to add the HTML * * @return void * @since 3.2.0 */ - public function create(string $path) + public function create(string $path, bool $addHtml = true) { // check if the path exist if (!JoomlaFolder::exists($path)) @@ -78,10 +79,13 @@ class Folder // count the folder created $this->counter->folder++; - // add index.html (boring I know) - $this->file->html( - $path, '' - ); + if ($addHtml) + { + // add index.html (boring I know) + $this->file->html( + $path, '' + ); + } } } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Database/Insert.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Database/Insert.php index 501258703..7e149d487 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Database/Insert.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Database/Insert.php @@ -23,7 +23,7 @@ use VDM\Joomla\Componentbuilder\Abstraction\Database; * * @since 3.2.0 */ -class Insert extends Database implements InsertInterface +final class Insert extends Database implements InsertInterface { /** * Switch to set the defaults @@ -31,33 +31,156 @@ class Insert extends Database implements InsertInterface * @var bool * @since 1.2.0 **/ - public bool $defaults = true; + protected bool $defaults = true; /** - * Set rows to the database + * Switch to prevent/allow defaults from being added. + * + * @param bool $trigger toggle the defaults + * + * @return void + * @since 3.2.0 + **/ + public function defaults(bool $trigger = true) + { + $this->defaults = $trigger; + } + + /** + * Insert rows to the database (with remapping and filtering columns option) * * @param array $data Dataset to store in database [array of arrays (key => value)] * @param string $table The table where the data is being added + * @param array $columns Data columns for remapping and filtering + * + * @return bool + * @since 3.2.0 + **/ + public function rows(array $data, string $table, array $columns = []): bool + { + if (!ArrayHelper::check($data)) + { + return false; + } + + if ($columns === []) + { + $columns = $this->getArrayColumns($data); + } + + return ($columns === []) ? false : $this->insert($data, $table, $columns, true); + } + + /** + * Insert items to the database (with remapping and filtering columns option) + * + * @param array $data Data to store in database (array of objects) + * @param string $table The table where the data is being added + * @param array $columns Data columns for remapping and filtering + * + * @return bool + * @since 3.2.0 + **/ + public function items(array $data, string $table, array $columns = []): bool + { + if (!ArrayHelper::check($data)) + { + return false; + } + + if ($columns === []) + { + $columns = $this->getObjectsColumns($data); + } + + return ($columns === []) ? false : $this->insert($data, $table, $columns, false); + } + + /** + * Insert row to the database + * + * @param array $data Dataset to store in database (key => value) + * @param string $table The table where the data is being added * * @return bool * @since 3.2.0 **/ - public function rows(array $data, string $table): bool + public function row(array $data, string $table): bool { - // get a query object - $query = $this->db->getQuery(true); + return $this->rows([$data], $table); + } - // get the first row + /** + * Insert item to the database + * + * @param object $data Dataset to store in database (key => value) + * @param string $table The table where the data is being added + * + * @return bool + * @since 3.2.0 + **/ + public function item(object $data, string $table): bool + { + return $this->items([$data], $table); + } + + /** + * Get columns from data array + * + * @param array $data Data array + * + * @return array + * @since 3.2.0 + **/ + protected function getArrayColumns(array &$data): array + { $row = array_values($data)[0]; - // set the insert columns if (!ArrayHelper::check($row)) { - return false; + return []; } $columns = array_keys($row); + return array_combine($columns, $columns); + } + + /** + * Get columns from data objects + * + * @param array $data Data objects + * + * @return array + * @since 3.2.0 + **/ + protected function getObjectsColumns(array &$data): array + { + $row = array_values($data)[0]; + + if (!is_object($row)) + { + return []; + } + + $columns = get_object_vars($row); + + return array_combine(array_keys($columns), array_keys($columns)); + } + + /** + * Insert data into the database + * + * @param array $data Data to store in database + * @param string $table The table where the data is being added + * @param array $columns Data columns for remapping and filtering + * @param bool $isArray Whether the data is an array of arrays or an array of objects + * + * @return bool + * @since 3.2.0 + **/ + protected function insert(array &$data, string $table, array $columns, bool $isArray): bool + { // set joomla default columns $add_created = false; $add_version = false; @@ -69,31 +192,37 @@ class Insert extends Database implements InsertInterface // get the date $date = (new Date())->toSql(); - if (!in_array('created', $columns)) + if (!isset($columns['created'])) { - $columns[] = 'created'; + $columns['created'] = ' (o_O) '; $add_created = true; } - if (!in_array('version', $columns)) + + if (!isset($columns['version'])) { - $columns[] = 'version'; + $columns['version'] = ' (o_O) '; $add_version = true; } - if (!in_array('published', $columns)) + + if (!isset($columns['version'])) { - $columns[] = 'published'; + $columns['published'] = ' (o_O) '; $add_published = true; } + // the (o_O) prevents an empty value from being loaded } + // get a query object + $query = $this->db->getQuery(true); + // set the query targets - $query->insert($this->db->quoteName($table))->columns($this->db->quoteName($columns)); + $query->insert($this->db->quoteName($this->getTable($table)))->columns($this->db->quoteName(array_keys($columns))); // limiting factor on the amount of rows to insert before we reset the query $limit = 300; // set the insert values - foreach ($data as $set) + foreach ($data as $nr => $value) { // check the limit if ($limit <= 1) @@ -109,13 +238,17 @@ class Insert extends Database implements InsertInterface $query = $this->db->getQuery(true); // set the query targets - $query->insert($this->db->quoteName($table))->columns($this->db->quoteName($columns)); + $query->insert($this->db->quoteName($this->getTable($table)))->columns($this->db->quoteName(array_keys($columns))); } $row = []; - foreach ($set as $value) + foreach ($columns as $column => $key) { - $row[] = $this->quote($value); + if (' (o_O) ' !== $key) + { + $row[] = ($isArray && isset($value[$key])) ? $this->quote($value[$key]) + : ((!$isArray && isset($value->{$key})) ? $this->quote($value->{$key}) : ''); + } } // set joomla default columns @@ -123,10 +256,12 @@ class Insert extends Database implements InsertInterface { $row[] = $this->db->quote($date); } + if ($add_version) { $row[] = 1; } + if ($add_published) { $row[] = 1; @@ -137,71 +272,6 @@ class Insert extends Database implements InsertInterface // decrement the limiter $limit--; - } - - // execute the final query - $this->db->setQuery($query); - $this->db->execute(); - - // always reset the default switch - $this->defaults = true; - - return true; - } - - /** - * Set items to the database - * - * @param array $data Data to store in database (array of objects) - * @param array $columns Data columns - * @param string $table The table where the data is being added - * - * @return bool - * @since 3.2.0 - **/ - public function items(array $data, array $columns, string $table): bool - { - // get a query object - $query = $this->db->getQuery(true); - - // set the query targets - $query->insert($this->db->quoteName($table))->columns($this->db->quoteName(array_keys($columns))); - - // limiting factor on the amount of rows to insert before we reset the query - $limit = 400; - - // set the insert values - foreach ($data as $nr => $value) - { - // check the limit - if ($limit <= 1) - { - // execute and reset the query - $this->db->setQuery($query); - $this->db->execute(); - - // reset limit - $limit = 400; - - // get a query object - $query = $this->db->getQuery(true); - - // set the query targets - $query->insert($this->db->quoteName($table))->columns($this->db->quoteName(array_keys($columns))); - } - - $row = []; - // load only what is part of the columns set - foreach ($columns as $key) - { - $row[] = isset($value->{$key}) ? $this->quote($value->{$key}) : ''; - } - - // add to query - $query->values(implode(',', $row)); - - // decrement the limiter - $limit--; // clear the data from memory unset($data[$nr]); @@ -211,89 +281,10 @@ class Insert extends Database implements InsertInterface $this->db->setQuery($query); $this->db->execute(); - return true; - } - - /** - * Set row to the database - * - * @param array $data Dataset to store in database (key => value) - * @param string $table The table where the data is being added - * - * @return bool - * @since 3.2.0 - **/ - public function row(array $data, string $table): bool - { - // get a query object - $query = $this->db->getQuery(true); - - $columns = array_keys($data); - - // set joomla default columns - $add_created = false; - $add_version = false; - $add_published = false; - - // check if we should load the defaults - if ($this->defaults) - { - // get the date - $date = (new Date())->toSql(); - - if (!in_array('created', $columns)) - { - $columns[] = 'created'; - $add_created = true; - } - if (!in_array('version', $columns)) - { - $columns[] = 'version'; - $add_version = true; - } - if (!in_array('published', $columns)) - { - $columns[] = 'published'; - $add_published = true; - } - } - - // set the query targets - $query->insert($this->db->quoteName($table))->columns($this->db->quoteName($columns)); - - // set the insert values - $row = []; - foreach ($data as $value) - { - $row[] = $this->quote($value); - } - - // set joomla default columns - if ($add_created) - { - $row[] = $this->db->quote($date); - } - if ($add_version) - { - $row[] = 1; - } - if ($add_published) - { - $row[] = 1; - } - - // add to query - $query->values(implode(',', $row)); - - // execute the final query - $this->db->setQuery($query); - $this->db->execute(); - // always reset the default switch - $this->defaults = true; + $this->defaults(); return true; - } - + } } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Database/Load.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Database/Load.php index 058506bbe..8d91af9e3 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Database/Load.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Database/Load.php @@ -22,7 +22,7 @@ use VDM\Joomla\Componentbuilder\Abstraction\Database; * * @since 3.2.0 */ -class Load extends Database implements LoadInterface +final class Load extends Database implements LoadInterface { /** * Load data rows as an array of associated arrays diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Database/Update.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Database/Update.php new file mode 100644 index 000000000..8cce8f402 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Database/Update.php @@ -0,0 +1,189 @@ + + * @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 + */ + +namespace VDM\Joomla\Componentbuilder\Database; + + +use VDM\Joomla\Componentbuilder\Interfaces\UpdateInterface; +use VDM\Joomla\Componentbuilder\Abstraction\Database; + + +/** + * Database Update Class + * + * @since 3.2.0 + */ +final class Update extends Database implements UpdateInterface +{ + /** + * Update rows in the database (with remapping and filtering columns option) + * + * @param array $data Dataset to update in database [array of arrays (key => value)] + * @param string $key Dataset key column to use in updating the values in the Database + * @param string $table The table where the data is being updated + * @param array $columns Data columns for remapping and filtering + * + * @return bool + * @since 3.2.0 + **/ + public function rows(array $data, string $key, string $table, array $columns = []): bool + { + // set the update columns + if ($data === [] || strlen($key) == 0) + { + return false; + } + + // set the update values + foreach ($data as $values) + { + if ($columns !== []) + { + // load only what is part of the columns set + $row = []; + foreach ($columns as $column => $key_) + { + if (isset($values[$key_])) + { + $row[$column] = $values[$key_]; + } + } + + // update the row + $this->row($row, $key, $table); + } + else + { + // update the row + $this->row((array) $values, $key, $table); + } + } + + return true; + } + + /** + * Update items in the database (with remapping and filtering columns option) + * + * @param array $data Data to updated in database (array of objects) + * @param string $key Dataset key column to use in updating the values in the Database + * @param string $table The table where the data is being update + * @param array $columns Data columns for remapping and filtering + * + * @return bool + * @since 3.2.0 + **/ + public function items(array $data, string $key, string $table, array $columns = []): bool + { + // set the update columns + if ($data === [] || strlen($key) == 0) + { + return false; + } + + // set the update values + foreach ($data as $nr => $values) + { + if ($columns !== []) + { + // load only what is part of the columns set + $row = []; + foreach ($columns as $column => $key_) + { + if (isset($values->{$key_})) + { + $row[$column] = $values->{$key_}; + } + } + + // update the row + $this->row($row, $key, $table); + } + else + { + // update the row + $this->row((array) $values, $key, $table); + } + } + + return true; + } + + /** + * Update row in the database + * + * @param array $data Dataset to update in database (key => value) + * @param string $key Dataset key column to use in updating the values in the Database + * @param string $table The table where the data is being updated + * + * @return bool + * @since 3.2.0 + **/ + public function row(array $data, string $key, string $table): bool + { + // set the update columns + if ($data === [] || strlen($key) == 0) + { + return false; + } + + // get a query object + $query = $this->db->getQuery(true); + + // set the query targets + $query->update($this->db->quoteName($this->getTable($table))); + + // set the update values + $key_ = null; + foreach ($data as $column => $value) + { + if ($column === $key) + { + $key_ = $value; + } + else + { + $query->set($this->db->quoteName($column) . ' = ' . $this->quote($value)); + } + } + + // add the key condition + if ($key_ !== null) + { + $query->where($this->db->quoteName($key) . ' = ' . $this->quote($key_)); + + // execute the final query + $this->db->setQuery($query); + + return $this->db->execute(); + } + + return false; + } + + /** + * Update item in the database + * + * @param object $data Dataset to update in database (key => value) + * @param string $key Dataset key column to use in updating the values in the Database + * @param string $table The table where the data is being updated + * + * @return bool + * @since 3.2.0 + **/ + public function item(object $data, string $key, string $table): bool + { + // convert to an array + return $this->row((array) get_object_vars($data), $key, $table); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/InsertInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/InsertInterface.php index 59481aec3..d00fc58c7 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/InsertInterface.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/InsertInterface.php @@ -20,30 +20,41 @@ namespace VDM\Joomla\Componentbuilder\Interfaces; interface InsertInterface { /** - * Set rows to the database + * Switch to prevent/allow defaults from being added. + * + * @param bool $trigger toggle the defaults + * + * @return void + * @since 3.2.0 + **/ + public function defaults(bool $trigger = true); + + /** + * Insert rows to the database (with remapping and filtering columns option) * * @param array $data Dataset to store in database [array of arrays (key => value)] * @param string $table The table where the data is being added + * @param array $columns Data columns for remapping and filtering * * @return bool * @since 3.2.0 **/ - public function rows(array $data, string $table): bool; + public function rows(array $data, string $table, array $columns = []): bool; /** - * Set items to the database + * Insert items to the database (with remapping and filtering columns option) * * @param array $data Data to store in database (array of objects) - * @param array $columns Data columns - * @param string $table The table where the data is being added + * @param string $table The table where the data is being added + * @param array $columns Data columns for remapping and filtering * * @return bool * @since 3.2.0 **/ - public function items(array $data, array $columns, string $table): bool; + public function items(array $data, string $table, array $columns = []): bool; /** - * Set row to the database + * Insert row to the database * * @param array $data Dataset to store in database (key => value) * @param string $table The table where the data is being added @@ -52,6 +63,17 @@ interface InsertInterface * @since 3.2.0 **/ public function row(array $data, string $table): bool; + + /** + * Insert item to the database + * + * @param object $data Dataset to store in database (key => value) + * @param string $table The table where the data is being added + * + * @return bool + * @since 3.2.0 + **/ + public function item(object $data, string $table): bool; } diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/Mapperdoubleinterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/Mapperdoubleinterface.php index 8b1cc8caf..1975ac84d 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/Mapperdoubleinterface.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/Mapperdoubleinterface.php @@ -17,6 +17,16 @@ namespace VDM\Joomla\Componentbuilder\Interfaces; */ interface Mapperdoubleinterface { + /** + * Check if any values are set in the active array. + * + * @param string|null $firstKey Optional. The first key to check for values. + * + * @return bool True if the active array or the specified subarray is not empty, false otherwise. + * @since 3.2.0 + */ + public function isActive_(string $firstKey = null): bool; + /** * Set dynamic content * diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/Mappersingleinterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/Mappersingleinterface.php index dcaa949bc..b00e1fbef 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/Mappersingleinterface.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/Mappersingleinterface.php @@ -17,6 +17,14 @@ namespace VDM\Joomla\Componentbuilder\Interfaces; */ interface Mappersingleinterface { + /** + * Check if any values are set in the active array + * + * @return bool Returns true if the active array is not empty, false otherwise + * @since 3.2.0 + */ + public function isActive(): bool; + /** * Set content * diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/ModelInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/ModelInterface.php index 2760500e0..379266047 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/ModelInterface.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/ModelInterface.php @@ -23,9 +23,9 @@ interface ModelInterface * Model the value * Example: $this->value(value, 'value_key', 'table_name'); * - * @param mixed $value The value to model - * @param string $field The field key - * @param string|null $table The table + * @param mixed $value The value to model + * @param string $field The field key + * @param string|null $table The table * * @return mixed * @since 3.2.0 @@ -56,6 +56,30 @@ interface ModelInterface */ public function items(?array $items = null, ?string $table = null): ?array; + /** + * Model the values of an row + * Example: $this->item(Array, 'table_name'); + * + * @param array $item The item array + * @param string|null $table The table + * + * @return array|null + * @since 3.2.0 + */ + public function row(array $item, ?string $table = null): ?array; + + /** + * Model the values of multiple rows + * Example: $this->items(Array, 'table_name'); + * + * @param array|null $items The array of item array + * @param string|null $table The table + * + * @return array|null + * @since 3.2.0 + */ + public function rows(?array $items = null, ?string $table = null): ?array; + /** * Get last modeled ID * Example: $this->last('table_name'); diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/UpdateInterface.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/UpdateInterface.php new file mode 100644 index 000000000..3e0cba027 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Interfaces/UpdateInterface.php @@ -0,0 +1,73 @@ + + * @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 + */ + +namespace VDM\Joomla\Componentbuilder\Interfaces; + + +/** + * Database Update Interface + * + * @since 3.2.0 + */ +interface UpdateInterface +{ + /** + * Update rows in the database (with remapping and filtering columns option) + * + * @param array $data Dataset to update in database [array of arrays (key => value)] + * @param string $key Dataset key column to use in updating the values in the Database + * @param string $table The table where the data is being updated + * @param array $columns Data columns for remapping and filtering + * + * @return bool + * @since 3.2.0 + **/ + public function rows(array $data, string $key, string $table, array $columns = []): bool; + + /** + * Update items in the database (with remapping and filtering columns option) + * + * @param array $data Data to updated in database (array of objects) + * @param string $key Dataset key column to use in updating the values in the Database + * @param string $table The table where the data is being update + * @param array $columns Data columns for remapping and filtering + * + * @return bool + * @since 3.2.0 + **/ + public function items(array $data, string $key, string $table, array $columns = []): bool; + + /** + * Update row in the database + * + * @param array $data Dataset to update in database (key => value) + * @param string $key Dataset key column to use in updating the values in the Database + * @param string $table The table where the data is being updated + * + * @return bool + * @since 3.2.0 + **/ + public function row(array $data, string $key, string $table): bool; + + /** + * Update item in the database + * + * @param object $data Dataset to update in database (key => value) + * @param string $key Dataset key column to use in updating the values in the Database + * @param string $table The table where the data is being updated + * + * @return bool + * @since 3.2.0 + **/ + public function item(object $data, string $key, string $table): bool; + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/Insert.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/Insert.php new file mode 100644 index 000000000..e0b0edb6c --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/Insert.php @@ -0,0 +1,160 @@ + + * @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 + */ + +namespace VDM\Joomla\Componentbuilder\Power\Database; + + +use VDM\Joomla\Componentbuilder\Power\Model as Model; +use VDM\Joomla\Componentbuilder\Database\Insert as Database; + + +/** + * Power Database Insert + * + * @since 3.2.0 + */ +final class Insert +{ + /** + * Model + * + * @var Model + * @since 3.2.0 + */ + protected Model $model; + + /** + * Database + * + * @var Database + * @since 3.2.0 + */ + protected Database $database; + + /** + * Constructor + * + * @param Model $model The set model object. + * @param Database $database The insert database object. + * + * @since 3.2.0 + */ + public function __construct(Model $model, Database $database) + { + $this->model = $model; + $this->database = $database; + } + + /** + * Insert a value to a given table + * Example: $this->value(Value, 'value_key', 'GUID'); + * + * @param mixed $value The field value + * @param string $field The field key + * @param string $keyValue The key value + * @param string $key The key name + * + * @return bool + * @since 3.2.0 + */ + public function value($value, string $field, string $keyValue, string $key = 'guid'): bool + { + // build the array + $item = []; + $item[$key] = $keyValue; + $item[$field] = $value; + + // Insert the column of this table + return $this->row($item); + } + + /** + * Insert single row with multiple values to a given table + * Example: $this->item(Array); + * + * @param array $item The item to save + * + * @return bool + * @since 3.2.0 + */ + public function row(array $item): bool + { + // check if object could be modelled + if (($item = $this->model->row($item, 'power')) !== null) + { + // Insert the column of this table + return $this->database->row($item, 'power'); + } + return false; + } + + /** + * Insert multiple rows to a given table + * Example: $this->items(Array); + * + * @param array|null $items The items updated in database (array of arrays) + * + * @return bool + * @since 3.2.0 + */ + public function rows(?array $items): bool + { + // check if object could be modelled + if (($items = $this->model->rows($items, 'power')) !== null) + { + // Insert the column of this table + return $this->database->rows($items, 'power'); + } + return false; + } + + /** + * Insert single item with multiple values to a given table + * Example: $this->item(Object); + * + * @param object $item The item to save + * + * @return bool + * @since 3.2.0 + */ + public function item(object $item): bool + { + // check if object could be modelled + if (($item = $this->model->item($item, 'power')) !== null) + { + // Insert the column of this table + return $this->database->item($item, 'power'); + } + return false; + } + + /** + * Insert multiple items to a given table + * Example: $this->items(Array); + * + * @param array|null $items The items updated in database (array of objects) + * + * @return bool + * @since 3.2.0 + */ + public function items(?array $items): bool + { + // check if object could be modelled + if (($items = $this->model->items($items, 'power')) !== null) + { + // Update the column of this table using guid as the primary key. + return $this->database->items($items, 'power'); + } + return false; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/Update.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/Update.php new file mode 100644 index 000000000..2d5f0e7a3 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/Update.php @@ -0,0 +1,160 @@ + + * @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 + */ + +namespace VDM\Joomla\Componentbuilder\Power\Database; + + +use VDM\Joomla\Componentbuilder\Power\Model as Model; +use VDM\Joomla\Componentbuilder\Database\Update as Database; + + +/** + * Power Database Update + * + * @since 3.2.0 + */ +final class Update +{ + /** + * Model + * + * @var Model + * @since 3.2.0 + */ + protected Model $model; + + /** + * Database + * + * @var Database + * @since 3.2.0 + */ + protected Database $database; + + /** + * Constructor + * + * @param Model $model The set model object. + * @param Database $database The update database object. + * + * @since 3.2.0 + */ + public function __construct(Model $model, Database $database) + { + $this->model = $model; + $this->database = $database; + } + + /** + * Update a value to a given table + * Example: $this->value(Value, 'value_key', 'GUID'); + * + * @param mixed $value The field value + * @param string $field The field key + * @param string $keyValue The key value + * @param string $key The key name + * + * @return bool + * @since 3.2.0 + */ + public function value($value, string $field, string $keyValue, string $key = 'guid'): bool + { + // build the array + $item = []; + $item[$key] = $keyValue; + $item[$field] = $value; + + // Update the column of this table using guid as the primary key. + return $this->row($item); + } + + /** + * Update single row with multiple values to a given table + * Example: $this->item(Array); + * + * @param array $item The item to save + * + * @return bool + * @since 3.2.0 + */ + public function row(array $item): bool + { + // check if object could be modelled + if (($item = $this->model->row($item, 'power')) !== null) + { + // Update the column of this table using guid as the primary key. + return $this->database->row($item, 'guid', 'power'); + } + return false; + } + + /** + * Update multiple rows to a given table + * Example: $this->items(Array); + * + * @param array|null $items The items updated in database (array of arrays) + * + * @return bool + * @since 3.2.0 + */ + public function rows(?array $items): bool + { + // check if object could be modelled + if (($items = $this->model->rows($items, 'power')) !== null) + { + // Update the column of this table using guid as the primary key. + return $this->database->rows($items, 'guid', 'power'); + } + return false; + } + + /** + * Update single item with multiple values to a given table + * Example: $this->item(Object); + * + * @param object $item The item to save + * + * @return bool + * @since 3.2.0 + */ + public function item(object $item): bool + { + // check if object could be modelled + if (($item = $this->model->item($item, 'power')) !== null) + { + // Update the column of this table using guid as the primary key. + return $this->database->item($item, 'guid', 'power'); + } + return false; + } + + /** + * Update multiple items to a given table + * Example: $this->items(Array); + * + * @param array|null $items The items updated in database (array of objects) + * + * @return bool + * @since 3.2.0 + */ + public function items(?array $items): bool + { + // check if object could be modelled + if (($items = $this->model->items($items, 'power')) !== null) + { + // Update the column of this table using guid as the primary key. + return $this->database->items($items, 'guid', 'power'); + } + return false; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Database/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Grep.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Grep.php new file mode 100644 index 000000000..3db88b54d --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Grep.php @@ -0,0 +1,375 @@ + + * @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 + */ + +namespace VDM\Joomla\Componentbuilder\Power; + + +use Joomla\CMS\Factory; +use Joomla\CMS\Filesystem\Folder; +use Joomla\CMS\Application\CMSApplication; +use Joomla\CMS\Language\Text; +use VDM\Joomla\Gitea\Repository\Contents; +use VDM\Joomla\Utilities\FileHelper; +use VDM\Joomla\Utilities\JsonHelper; + + +/** + * Global Resource Empowerment Platform + * + * The Grep feature will try to find your power in the repositories listed in the global + * Options of JCB in the super powers tab, and if it can't be found there will try the global core + * Super powers of JCB. All searches are performed according the the [algorithm:cascading] + * See documentation for more details: https://git.vdm.dev/joomla/super-powers/wiki + * + * @since 3.2.0 + */ +final class Grep +{ + /** + * The local path + * + * @var string + * @since 3.2.0 + **/ + public ?string $path; + + /** + * All approved paths + * + * @var array + * @since 3.2.0 + **/ + public ?array $paths; + + /** + * Gitea Repository Contents + * + * @var Contents + * @since 3.2.0 + **/ + protected Contents $contents; + + /** + * Joomla Application object + * + * @var CMSApplication + * @since 3.2.0 + **/ + protected CMSApplication $app; + + /** + * Constructor. + * + * @param string $path The local path + * @param array $paths The approved paths + * @param Contents $contents The Gitea Repository Contents object. + * @param CMSApplication|null $app The CMS Application object. + * + * @throws \Exception + * @since 3.2.0 + */ + public function __construct(string $path, array $paths, Contents $contents, ?CMSApplication $app = null) + { + $this->path = $path; + $this->paths = $paths; + $this->contents = $contents; + $this->app = $app ?: Factory::getApplication(); + + $this->init(); + } + + /** + * Get a power + * + * @param string $guid The global unique id of the power + * @param array $order The search order + * + * @return object|null + * @since 3.2.0 + */ + public function get(string $guid, array $order = ['local', 'remote']): ?object + { + // we can only search if we have paths + if (is_array($this->paths) && $this->paths !== []) + { + foreach ($order as $target) + { + if (($function_name = $this->getFunctionName($target)) !== null && + ($power = $this->{$function_name}($guid)) !== null) + { + return $power; + } + } + } + + return null; + } + + /** + * Search for a local power + * + * @param string $guid The global unique id of the power + * + * @return object|null + * @since 3.2.0 + */ + private function searchLocal(string $guid): ?object + { + // we can only search if we have paths + if ($this->path && $this->paths) + { + foreach ($this->paths as $path) + { + // get local index + $this->localIndex($path); + + if (!empty($path->local) && isset($path->local->{$guid})) + { + return $this->getLocal($path, $guid); + } + } + } + + return null; + } + + /** + * Search for a remote power + * + * @param string $guid The global unique id of the power + * + * @return object|null + * @since 3.2.0 + */ + private function searchRemote(string $guid): ?object + { + // we can only search if we have paths + if ($this->path && $this->paths) + { + foreach ($this->paths as $path) + { + // get local index + $this->remoteIndex($path); + + if (!empty($path->index) && isset($path->index->{$guid})) + { + return $this->getRemote($path, $guid); + } + } + } + + return null; + } + + /** + * Get a local power + * + * @param object $path The repository path details + * @param string $guid The global unique id of the power + * + * @return object|null + * @since 3.2.0 + */ + private function getLocal(object $path, string $guid): ?object + { + if (empty($path->local->{$guid}->settings) || empty($path->local->{$guid}->code)) + { + return null; + } + + // get the settings + if (($settings = FileHelper::getContent($path->full_path . '/' . $path->local->{$guid}->settings, null)) !== null && + JsonHelper::check($settings)) + { + $power = json_decode($settings); + + // get the code + if (($code = FileHelper::getContent($path->full_path . '/' . $path->local->{$guid}->power, null)) !== null) + { + $power->main_class_code = $code; + return $power; + } + } + + return null; + } + + /** + * Get a remote power + * + * @param object $path The repository path details + * @param string $guid The global unique id of the power + * + * @return object|null + * @since 3.2.0 + */ + private function getRemote(object $path, string $guid): ?object + { + if (empty($path->index->{$guid}->settings) || empty($path->index->{$guid}->code)) + { + return null; + } + + // get the settings + if (($power = $this->loadRemoteFile($path->owner, $path->repo, $path->index->{$guid}->settings, $path->branch)) !== null && + isset($power->guid)) + { + // get the code + if (($code = $this->loadRemoteFile($path->owner, $path->repo, $path->index->{$guid}->power, $path->branch)) !== null) + { + $power->main_class_code = $code; + return $power; + } + } + + return null; + } + + /** + * Set path details + * + * @return void + * @since 3.2.0 + */ + private function init() + { + if (is_array($this->paths) && $this->paths !== []) + { + foreach ($this->paths as $n => &$path) + { + if (isset($path->owner) && strlen($path->owner) > 1 && + isset($path->repo) && strlen($path->repo) > 1) + { + // build the path + $path->path = trim($path->owner) . '/' . trim($path->repo); + + // update the branch + if ($path->branch === 'default' || empty($path->branch)) + { + $path->branch = null; + } + + // set local path + if ($this->path && Folder::exists($this->path . '/' . $path->path)) + { + $path->full_path = $this->path . '/' . $path->path; + } + } + else + { + unset($this->paths[$n]); + } + } + } + } + + /** + * Load the local repository index of powers + * + * @param object $path The repository path details + * + * @return void + * @since 3.2.0 + */ + private function localIndex(object &$path) + { + if (isset($path->local) || !isset($path->full_path)) + { + return; + } + + if (($content = FileHelper::getContent($path->full_path . '/super-powers.json', null)) !== null && + JsonHelper::check($content)) + { + $path->local = json_decode($content); + + return; + } + + $path->local = null; + } + + /** + * Load the remote repository index of powers + * + * @param object $path The repository path details + * + * @return void + * @since 3.2.0 + */ + private function remoteIndex(object &$path) + { + if (isset($path->index)) + { + return; + } + + try + { + $path->index = $this->contents->get($path->owner, $path->repo, 'super-powers.json', $path->branch); + } + catch (\DomainException $e) + { + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_PSUPER_POWERB_REPOSITORY_AT_BGITVDMDEVSB_GAVE_THE_FOLLOWING_ERRORBR_SP', $path->path, $e->getMessage()), + 'Error' + ); + + $path->index = null; + } + } + + /** + * Load the remote file + * + * @param string $owner The repository owner + * @param string $repo The repository name + * @param string $path The repository path to file + * @param string|null $branch The repository branch name + * + * @return mixed + * @since 3.2.0 + */ + private function loadRemoteFile(string $owner, string $repo, string $path, ?string $branch) + { + try + { + $data = $this->contents->get($owner, $repo, $path, $branch); + } + catch (\DomainException $e) + { + $this->app->enqueueMessage( + Text::sprintf('COM_COMPONENTBUILDER_PFILE_AT_BGITEAREMOTESB_GAVE_THE_FOLLOWING_ERRORBR_SP', $path, $e->getMessage()), + 'Error' + ); + + return null; + } + + return $data; + } + + /** + * Get function name + * + * @param string $name The targeted function name + * + * @return string|null + * @since 3.2.0 + */ + private function getFunctionName(string $name): ?string + { + $function_name = 'search' . ucfirst(strtolower($name)); + + return method_exists($this, $function_name) ? $function_name : null; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Model.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Model.php new file mode 100644 index 000000000..0e7695120 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Model.php @@ -0,0 +1,120 @@ + + * @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 + */ + +namespace VDM\Joomla\Componentbuilder\Power; + + +use VDM\Joomla\Componentbuilder\Abstraction\Model as AbstractionModel; +use VDM\Joomla\Utilities\StringHelper; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\ObjectHelper; +use VDM\Joomla\Componentbuilder\Interfaces\ModelInterface; + + +/** + * Power Model + * + * @since 3.2.0 + */ +final class Model extends AbstractionModel implements ModelInterface +{ + /** + * Model the value + * Example: $this->value(value, 'field_key', 'table_name'); + * + * @param mixed $value The value to model + * @param string $field The field key + * @param string|null $table The table + * + * @return mixed + * @since 3.2.0 + */ + public function value($value, string $field, ?string $table = null) + { + // set the table name + if (empty($table)) + { + $table = $this->getTable(); + } + + // check if this is a valid table + if (($store = $this->table->get($table, $field, 'store')) !== null) + { + // open the value based on the store method + switch($store) + { + case 'base64': + $value = base64_encode((string) $value); + break; + case 'json': + $value = json_encode($value, JSON_FORCE_OBJECT); + break; + } + } + + return $value; + } + + /** + * Validate before the value is modelled + * + * @param mixed $value The field value + * @param string|null $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + protected function validateBefore(&$value, ?string $field = null, ?string $table = null): bool + { + // check values + if (StringHelper::check($value) || ArrayHelper::check($value, true) || ObjectHelper::check($value) || is_numeric($value)) + { + return true; + } + // remove empty values + return false; + } + + /** + * Validate after the value is modelled + * + * @param mixed $value The field value + * @param string|null $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + protected function validateAfter(&$value, ?string $field = null, ?string $table = null): bool + { + // only strings or numbers allowed + if (StringHelper::check($value) || is_numeric($value)) + { + return true; + } + // remove empty values + return false; + } + + /** + * Get the current active table + * + * @return string + * @since 3.2.0 + */ + protected function getTable(): string + { + return 'power'; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Super.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Super.php new file mode 100644 index 000000000..583422258 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/Super.php @@ -0,0 +1,133 @@ + + * @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 + */ + +namespace VDM\Joomla\Componentbuilder\Power; + + +use VDM\Joomla\Componentbuilder\Power\Database\Insert; +use VDM\Joomla\Componentbuilder\Power\Database\Update; +use VDM\Joomla\Componentbuilder\Power\Grep; +use VDM\Joomla\Utilities\GuidHelper; + + +/** + * Superpower of JCB + * + * @since 3.2.0 + */ +final class Super +{ + /** + * The Power Search Tool + * + * @var Grep + * @since 3.2.0 + **/ + protected Grep $grep; + + /** + * Insert Data Class + * + * @var Insert + * @since 3.2.0 + **/ + protected Insert $insert; + + /** + * Update Data Class + * + * @var Update + * @since 3.2.0 + **/ + protected Update $update; + + /** + * Constructor. + * + * @param Grep $grep The Power Grep object. + * @param Insert $insert The Power Database Insert object. + * @param Update $update The Power Database Update object. + * + * @since 3.2.0 + */ + public function __construct(Grep $grep, Insert $insert, Update $update) + { + $this->grep = $grep; + $this->insert = $insert; + $this->update = $update; + } + + /** + * Load a superpower + * + * @param string $guid The global unique id of the power + * @param array $order The search order + * @param string|null $action The action to load power + * + * @return bool + * @since 3.2.0 + */ + public function load(string $guid, array $order = ['remote', 'local'], ?string $action = null): bool + { + if (($power = $this->grep->get($guid, $order)) !== null && + ($action !== null || ($action = $this->action($power->guid)) !== null)) + { + return method_exists($this, $action) ? $this->{$action}($power) : false; + } + + return false; + } + + /** + * Insert a superpower + * + * @param object $power The power + * + * @return bool + * @since 3.2.0 + */ + private function insert(object $power): bool + { + return $this->insert->item($power); + } + + /** + * Update a superpower + * + * @param object $power The power + * + * @return bool + * @since 3.2.0 + */ + private function update(object $power): bool + { + return $this->update->item($power); + } + + /** + * Get loading action + * + * @param string $guid The global unique id of the power + * + * @return string + * @since 3.2.0 + */ + private function action(string $guid): string + { + if (($id = GuidHelper::item($guid, 'power')) !== null && $id > 0) + { + return 'update'; + } + + return 'insert'; + } +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/index.html b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/index.html new file mode 100644 index 000000000..fa6d84e80 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Power/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Database/Insert.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Database/Insert.php index 30488ad1f..afce63c7c 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Database/Insert.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Database/Insert.php @@ -115,7 +115,7 @@ class Insert implements InsertInterface /** * Set values to a given table - * Example: $this->item(Object, 23, 'table_name'); + * Example: $this->item(Object, 'table_name'); * * @param object $item The item to save * @param string|null $table The table diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Model/Insert.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Model/Insert.php index 437ea81f0..d4e32be92 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Model/Insert.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Model/Insert.php @@ -15,6 +15,7 @@ namespace VDM\Joomla\Componentbuilder\Search\Model; use VDM\Joomla\Componentbuilder\Search\Factory; use VDM\Joomla\Componentbuilder\Table; use VDM\Joomla\Componentbuilder\Search\Config; +use VDM\Joomla\Utilities\ArrayHelper; use VDM\Joomla\Componentbuilder\Interfaces\ModelInterface; use VDM\Joomla\Componentbuilder\Abstraction\Model; @@ -86,6 +87,42 @@ class Insert extends Model implements ModelInterface return $value; } + /** + * Validate before the value is modelled (basic, override in child class) + * + * @param mixed $value The field value + * @param string|null $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + protected function validateBefore(&$value, ?string $field = null, ?string $table = null): bool + { + // check values + if (StringHelper::check($value) || ArrayHelper::check($value, true)) + { + return true; + } + // remove empty values + return false; + } + + /** + * Validate after the value is modelled (basic, override in child class) + * + * @param mixed $value The field value + * @param string|null $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + protected function validateAfter(&$value, ?string $field = null, ?string $table = null): bool + { + return true; + } + /** * Get the current active table * diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Model/Load.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Model/Load.php index 63e887057..41ae10c23 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Model/Load.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Search/Model/Load.php @@ -15,6 +15,7 @@ namespace VDM\Joomla\Componentbuilder\Search\Model; use VDM\Joomla\Componentbuilder\Search\Factory; use VDM\Joomla\Componentbuilder\Table; use VDM\Joomla\Componentbuilder\Search\Config; +use VDM\Joomla\Utilities\ArrayHelper; use VDM\Joomla\Utilities\JsonHelper; use VDM\Joomla\Utilities\StringHelper; use VDM\Joomla\Componentbuilder\Interfaces\ModelInterface; @@ -91,6 +92,42 @@ class Load extends Model implements ModelInterface return $value; } + /** + * Validate before the value is modelled (basic, override in child class) + * + * @param mixed $value The field value + * @param string|null $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + protected function validateBefore(&$value, ?string $field = null, ?string $table = null): bool + { + return true; + } + + /** + * Validate after the value is modelled (basic, override in child class) + * + * @param mixed $value The field value + * @param string|null $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + protected function validateAfter(&$value, ?string $field = null, ?string $table = null): bool + { + // check values + if (StringHelper::check($value) || ArrayHelper::check($value, true)) + { + return true; + } + // remove empty values + return false; + } + /** * Get the current active table * diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/Model/Load.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/Model/Load.php index 305e72340..2a8553cfc 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/Model/Load.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Server/Model/Load.php @@ -108,7 +108,7 @@ class Load extends Model implements ModelInterface } /** - * Validate the values (basic, override in child class) + * Validate before the value is modelled * * @param mixed $value The field value * @param string|null $field The field key @@ -117,12 +117,27 @@ class Load extends Model implements ModelInterface * @return bool * @since 3.2.0 */ - protected function validate(&$value, ?string $field = null, ?string $table = null): bool + protected function validateBefore(&$value, ?string $field = null, ?string $table = null): bool { // remove none return true; } + /** + * Validate after the value is modelled + * + * @param mixed $value The field value + * @param string|null $field The field key + * @param string|null $table The table + * + * @return bool + * @since 3.2.0 + */ + protected function validateAfter(&$value, ?string $field = null, ?string $table = null): bool + { + return true; + } + /** * Get the current active table * diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Service/Gitea.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Service/Gitea.php new file mode 100644 index 000000000..9287313a9 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Service/Gitea.php @@ -0,0 +1,84 @@ + + * @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 + */ + +namespace VDM\Joomla\Componentbuilder\Service; + + +use Joomla\DI\Container; +use Joomla\DI\ServiceProviderInterface; +use VDM\Joomla\Gitea\Utilities\Uri; +use VDM\Joomla\Gitea\Utilities\Http; + + +/** + * The Gitea Utilities Service + * + * @since 3.2.0 + */ +class Gitea implements ServiceProviderInterface +{ + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * @since 3.2.0 + */ + public function register(Container $container) + { + $container->alias(Uri::class, 'Gitea.Dynamic.Uri') + ->share('Gitea.Dynamic.Uri', [$this, 'getUri'], true); + + $container->alias(Http::class, 'Gitea.Utilities.Http') + ->share('Gitea.Utilities.Http', [$this, 'getHttp'], true); + } + + /** + * Get the Dynamic Uri class + * + * @param Container $container The DI container. + * + * @return Uri + * @since 3.2.0 + */ + public function getUri(Container $container): Uri + { + // get the global gitea URL + $add_gitea_url = $container->get('Config')->get('add_custom_gitea_url', 1); + $gitea_url = $container->get('Config')->get('custom_gitea_url'); + + // only load this if we have a custom URL set + if ($add_gitea_url == 2 && is_string($gitea_url) && strpos($gitea_url, 'http') !== false) + { + return new Uri($gitea_url); + } + + return $container->get('Gitea.Utilities.Uri'); + } + + /** + * Get the Http class + * + * @param Container $container The DI container. + * + * @return Http + * @since 3.2.0 + */ + public function getHttp(Container $container): Http + { + return new Http( + $container->get('Config')->get('gitea_token') + ); + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Table.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Table.php index dee028f69..6ae6bdd70 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Table.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Table.php @@ -1593,6 +1593,15 @@ class Table implements Tableinterface 'store' => NULL, 'tab_name' => 'Code', ], + 'method_selection' => [ + 'name' => 'method_selection', + 'label' => 'COM_COMPONENTBUILDER_POWER_METHOD_SELECTION_LABEL', + 'type' => 'subform', + 'title' => false, + 'list' => 'powers', + 'store' => 'json', + 'tab_name' => 'Code', + ], 'load_selection' => [ 'name' => 'load_selection', 'label' => 'COM_COMPONENTBUILDER_POWER_LOAD_SELECTION_LABEL', @@ -1602,15 +1611,6 @@ class Table implements Tableinterface 'store' => 'json', 'tab_name' => 'Code', ], - 'description' => [ - 'name' => 'description', - 'label' => 'COM_COMPONENTBUILDER_POWER_DESCRIPTION_LABEL', - 'type' => 'textarea', - 'title' => false, - 'list' => 'powers', - 'store' => NULL, - 'tab_name' => 'Code', - ], 'licensing_template' => [ 'name' => 'licensing_template', 'label' => 'COM_COMPONENTBUILDER_POWER_LICENSING_TEMPLATE_LABEL', @@ -1620,6 +1620,15 @@ class Table implements Tableinterface 'store' => 'base64', 'tab_name' => 'Licensing', ], + 'description' => [ + 'name' => 'description', + 'label' => 'COM_COMPONENTBUILDER_POWER_DESCRIPTION_LABEL', + 'type' => 'textarea', + 'title' => false, + 'list' => 'powers', + 'store' => NULL, + 'tab_name' => 'Code', + ], 'composer' => [ 'name' => 'composer', 'label' => 'COM_COMPONENTBUILDER_POWER_COMPOSER_LABEL', @@ -1629,6 +1638,24 @@ class Table implements Tableinterface 'store' => 'json', 'tab_name' => 'Composer', ], + 'extends' => [ + 'name' => 'extends', + 'label' => 'COM_COMPONENTBUILDER_POWER_EXTENDS_LABEL', + 'type' => 'classpowers', + 'title' => false, + 'list' => 'powers', + 'store' => NULL, + 'tab_name' => 'Code', + ], + 'approved' => [ + 'name' => 'approved', + 'label' => 'COM_COMPONENTBUILDER_POWER_APPROVED_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'powers', + 'store' => NULL, + 'tab_name' => 'Super Power', + ], 'property_selection' => [ 'name' => 'property_selection', 'label' => 'COM_COMPONENTBUILDER_POWER_PROPERTY_SELECTION_LABEL', @@ -1647,6 +1674,15 @@ class Table implements Tableinterface 'store' => NULL, 'tab_name' => 'Code', ], + 'extends_custom' => [ + 'name' => 'extends_custom', + 'label' => 'COM_COMPONENTBUILDER_POWER_EXTENDS_CUSTOM_LABEL', + 'type' => 'text', + 'title' => false, + 'list' => 'powers', + 'store' => NULL, + 'tab_name' => 'Code', + ], 'implements_custom' => [ 'name' => 'implements_custom', 'label' => 'COM_COMPONENTBUILDER_POWER_IMPLEMENTS_CUSTOM_LABEL', @@ -1665,33 +1701,6 @@ class Table implements Tableinterface 'store' => 'json', 'tab_name' => 'Code', ], - 'extends_custom' => [ - 'name' => 'extends_custom', - 'label' => 'COM_COMPONENTBUILDER_POWER_EXTENDS_CUSTOM_LABEL', - 'type' => 'text', - 'title' => false, - 'list' => 'powers', - 'store' => NULL, - 'tab_name' => 'Code', - ], - 'extends' => [ - 'name' => 'extends', - 'label' => 'COM_COMPONENTBUILDER_POWER_EXTENDS_LABEL', - 'type' => 'classpowers', - 'title' => false, - 'list' => 'powers', - 'store' => NULL, - 'tab_name' => 'Code', - ], - 'method_selection' => [ - 'name' => 'method_selection', - 'label' => 'COM_COMPONENTBUILDER_POWER_METHOD_SELECTION_LABEL', - 'type' => 'subform', - 'title' => false, - 'list' => 'powers', - 'store' => 'json', - 'tab_name' => 'Code', - ], 'head' => [ 'name' => 'head', 'label' => 'COM_COMPONENTBUILDER_POWER_HEAD_LABEL', @@ -1701,6 +1710,15 @@ class Table implements Tableinterface 'store' => 'base64', 'tab_name' => 'Code', ], + 'approved_paths' => [ + 'name' => 'approved_paths', + 'label' => 'COM_COMPONENTBUILDER_POWER_APPROVED_PATHS_LABEL', + 'type' => 'superpowerpaths', + 'title' => false, + 'list' => 'powers', + 'store' => 'json', + 'tab_name' => 'Super Power', + ], 'use_selection' => [ 'name' => 'use_selection', 'label' => 'COM_COMPONENTBUILDER_POWER_USE_SELECTION_LABEL', @@ -1710,15 +1728,6 @@ class Table implements Tableinterface 'store' => 'json', 'tab_name' => 'Code', ], - 'add_licensing_template' => [ - 'name' => 'add_licensing_template', - 'label' => 'COM_COMPONENTBUILDER_POWER_ADD_LICENSING_TEMPLATE_LABEL', - 'type' => 'radio', - 'title' => false, - 'list' => 'powers', - 'store' => NULL, - 'tab_name' => 'Licensing', - ], 'main_class_code' => [ 'name' => 'main_class_code', 'label' => 'COM_COMPONENTBUILDER_POWER_MAIN_CLASS_CODE_LABEL', @@ -1728,6 +1737,15 @@ class Table implements Tableinterface 'store' => 'base64', 'tab_name' => 'Code', ], + 'add_licensing_template' => [ + 'name' => 'add_licensing_template', + 'label' => 'COM_COMPONENTBUILDER_POWER_ADD_LICENSING_TEMPLATE_LABEL', + 'type' => 'radio', + 'title' => false, + 'list' => 'powers', + 'store' => NULL, + 'tab_name' => 'Licensing', + ], 'guid' => [ 'name' => 'guid', 'label' => 'COM_COMPONENTBUILDER_POWER_GUID_LABEL', diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Utilities/FilterHelper.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Utilities/FilterHelper.php new file mode 100644 index 000000000..86dec4d31 --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Utilities/FilterHelper.php @@ -0,0 +1,814 @@ + + * @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 + */ + +namespace VDM\Joomla\Componentbuilder\Utilities; + + +use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; +use VDM\Joomla\Utilities\ArrayHelper; +use VDM\Joomla\Utilities\JsonHelper; +use VDM\Joomla\Utilities\GetHelper; + + +/** + * Filter Helper + * + * @since 3.2.0 + */ +abstract class FilterHelper +{ + /** + * get extensions grouped list xml + * + * @return string The XML string of Extentions + * @since 3.2.0 + */ + public static function extensions(): string + { + // the extension types + $extensions = array( + 'joomla_component' => 'COM_COMPONENTBUILDER_COMPONENT', + 'joomla_module' => 'COM_COMPONENTBUILDER_MODULE', + 'joomla_plugin' => 'COM_COMPONENTBUILDER_PLUGIN' + ); + + // get the extension values + foreach ($extensions as $extension => $label) + { + ${$extension} = self::names($extension); + } + + $xml = new \DOMDocument(); + $xml->formatOutput = true; + + $root = $xml->createElement('field'); + $root->setAttributeNode(new \DOMAttr('name', 'extension')); + $root->setAttributeNode(new \DOMAttr('type', 'groupedlist')); + $root->setAttributeNode(new \DOMAttr('onchange', 'this.form.submit();')); + + $root + ->appendChild($xml->createElement('option', '- ' . Text::_('COM_COMPONENTBUILDER_SELECT_EXTENSION') . ' -')) + ->setAttributeNode(new \DOMAttr('value', '')); + + foreach ($extensions as $extension => $label) + { + $extension_node = $xml->createElement('group'); + $extension_node->setAttributeNode(new \DOMAttr('label', $label)); + if (!ArrayHelper::check(${$extension})) + { + $extension_node + ->appendChild($xml->createElement('option', '- ' . Text::_('COM_COMPONENTBUILDER_NONE') . ' -')) + ->setAttributeNode(new \DOMAttr('disabled', 'true')); + } + else + { + foreach (${$extension} as $id => $element) + { + $extension_node + ->appendChild($xml->createElement('option', $element)) + ->setAttributeNode(new \DOMAttr('value', $extension . '__' . $id)); + } + } + $root->appendChild($extension_node); + } + $xml->appendChild($root); + + return $xml->saveXML(); + } + + /** + * Get by type the ids and system names + * + * @param string $type The table name to get system names for + * @param string|null $limiter The to limit by limiter table + * + * @return array|null The array of system name and IDs + * @since 3.2.0 + */ + public static function names(string $type, ?string $limiter = null): ?array + { + $db = Factory::getDbo(); + $query = $db->getQuery(true); + + $query + ->select($db->quoteName(array('id', 'system_name'))) + ->from($db->quoteName('#__componentbuilder_' . $type)) + ->where($db->quoteName('published') . ' >= 1') + ->order($db->quoteName('modified') . ' desc') + ->order($db->quoteName('created') . ' desc'); + + // check if we have a limiter for admin views + if ($type === 'admin_view' && $limiter) + { + // first get all views + $admin_view_ids = array(); + + // if this is a plugin or a module, then no views + if (strpos($limiter, 'joomla_component') !== false) + { + $component = (int) str_replace('joomla_component__', '', $limiter); + // get the views of this component + if ($add_views = GetHelper::var('component_admin_views', (int) $component, 'joomla_component', 'addadmin_views')) + { + if (JsonHelper::check($add_views)) + { + $add_views = json_decode($add_views, true); + if (ArrayHelper::check($add_views)) + { + foreach($add_views as $add_view) + { + if (isset($add_view['adminview'])) + { + $admin_view_ids[(int) $add_view['adminview']] = (int) $add_view['adminview']; + } + } + } + } + } + } + // now check if we still have admin views + if (ArrayHelper::check($admin_view_ids)) + { + $query->where($db->quoteName('id') . ' IN (' . implode(',', $admin_view_ids) . ')'); + } + else + { + return null; + } + } + + $db->setQuery($query); + $db->execute(); + + if ($db->getNumRows()) + { + return $db->loadAssocList('id', 'system_name'); + } + + return null; + } + + /** + * get any area linked IDs + * + * @param int $id The target ID + * @param string $method The target method + * + * @return array|null The result ids + * @since 3.2.0 + **/ + public static function linked(int $id, string $method): ?array + { + // check if method exist + if (method_exists(__CLASS__, $method)) + { + return self::{$method}($id); + } + + return null; + } + + /** + * get the substrings of the namespace until the last "\" or "." + * + * @return array|null The result substrings + * @since 3.2.0 + **/ + public static function namespaces(): ?array + { + $db = Factory::getDbo(); + $query = $db->getQuery(true); + $query + ->select( + 'DISTINCT REPLACE(SUBSTRING(' + . $db->quoteName('namespace') + . ', 1, LENGTH(' + . $db->quoteName('namespace') + . ') - LEAST(' + . 'IF(LOCATE(' + . $db->quote('\\') + . ', ' . $db->quoteName('namespace') + . ') > 0, LOCATE(' + . $db->quote('\\') + . ', REVERSE(' + . $db->quoteName('namespace') + . ')), 0), ' + . 'IF(LOCATE(' + . $db->quote('.') + . ', ' . $db->quoteName('namespace') + . ') > 0, LOCATE(' + . $db->quote('.') + . ', REVERSE(' + . $db->quoteName('namespace') + . ')), 0))), ".", "\\\") AS trimmed_namespace' + ) + ->from($db->quoteName('#__componentbuilder_power')) + ->where($db->quoteName('published') . ' = 1') + ->order('LENGTH(trimmed_namespace) ASC, trimmed_namespace ASC'); + $db->setQuery($query); + $db->execute(); + + if ($db->getNumRows()) + { + return $db->loadAssocList('trimmed_namespace', 'trimmed_namespace'); + } + + return null; + } + + /** + * get get IDs of powers matching namespaces + * + * @param string $namespace The target namespace + * + * @return array|null The result ids + * @since 3.2.0 + **/ + public static function namegroup(string $namespace): ?array + { + $db = Factory::getDbo(); + $query = $db->getQuery(true); + $query + ->select($db->quoteName(array('id'))) + ->from($db->quoteName('#__componentbuilder_power')) + ->where($db->quoteName('published') . ' = 1'); + + // we get only those that match the owner and repo (smaller set) + $paths = explode('\\', $namespace); + foreach ($paths as $path) + { + $query->where($db->quoteName('namespace') . ' REGEXP ' . $db->quote($path)); + } + + $db->setQuery($query); + $db->execute(); + + if ($db->getNumRows()) + { + return $db->loadColumn(); + } + + return null; + } + + /** + * get translation extension ids + * + * @param int $extension The target ID + * @param string $type The target method + * + * @return array|null The result ids + * @since 3.2.0 + **/ + public static function translation(int $extension, string $type): ?array + { + // only allow these columns (extension types) + $columns = array( + 'joomla_component' => 'components', + 'joomla_module' => 'modules', + 'joomla_plugin' => 'plugins' + ); + + // check if the column name is correct + if (isset($columns[$type])) + { + $column = $columns[$type]; + $db = Factory::getDbo(); + $query = $db->getQuery(true); + $query + ->select($db->quoteName(array('id', $column))) + ->from($db->quoteName('#__componentbuilder_language_translation')) + ->where($db->quoteName($column) . ' != ' . $db->quote('')); + + $db->setQuery($query); + $db->execute(); + + if ($db->getNumRows()) + { + $results = $db->loadAssocList(); + $matches = []; + foreach ($results as $k => $v) + { + $value = json_decode($v[$column], true); + if (in_array($extension, $value)) + { + $matches[$v['id']] = $v['id']; + } + } + + // Checks that we found matches + if (ArrayHelper::check($matches)) + { + return array_values($matches); + } + } + } + + return null; + } + + /** + * get translation ids + * + * @param int $id The target ID + * + * @return array|null The result ids + * @since 3.2.0 + **/ + public static function translations($language, $translated = true): ?array + { + $db = Factory::getDbo(); + $query = $db->getQuery(true); + + $query + ->select($db->quoteName('id')) + ->from($db->quoteName('#__componentbuilder_language_translation')); + + // Build the where condition + if ($translated === true) // Translated + { + if ($language === 'all') + { + if (($languages = self::languages()) !== null) + { + $wheres = []; + foreach ($languages as $k => $v) + { + $wheres[] = $db->quoteName('translation') . ' LIKE ' . $db->quote('%' . $k . '%'); + } + $query->where($wheres); + } + } + else + { + $query->where($db->quoteName('translation') . ' LIKE ' . $db->quote('%' . $language . '%')); + } + } + else // Not translated + { + if ($language === 'none') + { + $query->where( + array( + $db->quoteName('translation') . ' = ' . $db->quote(''), + $db->quoteName('translation') . ' = ' . $db->quote('[]'), + $db->quoteName('translation') . ' = ' . $db->quote('{}') + ), 'OR' + ); + } + else + { + $query->where($db->quoteName('translation') . ' NOT LIKE ' . $db->quote('%' . $language . '%')); + } + } + + $db->setQuery($query); + $db->execute(); + + if ($db->getNumRows()) + { + return array_unique($db->loadColumn()); + } + + return null; + } + + /** + * get available languages + * + * @return array|null The result ids + * @since 3.2.0 + **/ + public static function languages(): ?array + { + $db = Factory::getDbo(); + $query = $db->getQuery(true); + $query + ->select($db->quoteName(array('langtag', 'name'))) + ->from($db->quoteName('#__componentbuilder_language')) + ->where($db->quoteName('published') . ' = 1') + ->order($db->quoteName('name') . ' desc'); + $db->setQuery($query); + $db->execute(); + + if ($db->getNumRows()) + { + return $db->loadAssocList('langtag', 'name'); + } + + return null; + } + + /** + * get get IDs of powers link to this path + * + * @param string $path The target PATH + * + * @return array|null The result ids + * @since 3.2.0 + **/ + public static function paths(string $path): ?array + { + // get all this power ids + $ids = []; + + $db = Factory::getDbo(); + $query = $db->getQuery(true); + $query + ->select($db->quoteName(array('id', 'approved_paths'))) + ->from($db->quoteName('#__componentbuilder_power')) + ->where($db->quoteName('published') . ' = 1'); + + // we get only those that match the owner and repo (smaller set) + if (($pos = strpos($path, '/')) !== false) + { + $owner = substr($path, 0, $pos); + $repo = substr($path, $pos + 1); + $query + ->where($db->quoteName('approved_paths') . ' REGEXP ' . $db->quote($owner)) + ->where($db->quoteName('approved_paths') . ' REGEXP ' . $db->quote($repo)); + } + + $db->setQuery($query); + $db->execute(); + + if ($db->getNumRows()) + { + $result = $db->loadAssocList('id', 'approved_paths'); + foreach ($result as $id => $paths) + { + if (JsonHelper::check($paths)) + { + $paths = json_decode($paths, true); + if (ArrayHelper::check($paths) && in_array($path, $paths, true)) + { + $ids[$id] = $id; + } + } + } + + if (ArrayHelper::check($ids)) + { + return $ids; + } + } + + return null; + } + + /** + * Get a component admin views IDs + * + * @param int $id The target ID + * + * @return array|null The result ids + * @since 3.2.0 + */ + private static function joomla_component_admin_views(int $id): ?array + { + // get all this components views + $admin_view_ids = []; + + // get the views of this component + if ($add_views = GetHelper::var('component_admin_views', (int) $id, 'joomla_component', 'addadmin_views')) + { + if (JsonHelper::check($add_views)) + { + $add_views = json_decode($add_views, true); + if (ArrayHelper::check($add_views)) + { + foreach($add_views as $add_view) + { + if (isset($add_view['adminview'])) + { + $admin_view_ids[(int) $add_view['adminview']] = (int) $add_view['adminview']; + } + } + } + } + } + + // check that we have fields + if (ArrayHelper::check($admin_view_ids)) + { + return array_values($admin_view_ids); + } + + return null; + } + + /** + * get a component custom admin views IDs + * + * @param int $id The target ID + * + * @return array|null The result ids + * @since 3.2.0 + */ + private static function joomla_component_custom_admin_views($id): ?array + { + // get all this components views + $admin_view_ids = []; + + // get the views of this component + if ($add_views = GetHelper::var('component_custom_admin_views', (int) $id, 'joomla_component', 'addcustom_admin_views')) + { + if (JsonHelper::check($add_views)) + { + $add_views = json_decode($add_views, true); + if (ArrayHelper::check($add_views)) + { + foreach($add_views as $add_view) + { + if (isset($add_view['customadminview'])) + { + $admin_view_ids[(int) $add_view['customadminview']] = (int) $add_view['customadminview']; + } + } + } + } + } + + // check that we have fields + if (ArrayHelper::check($admin_view_ids)) + { + return array_values($admin_view_ids); + } + + return null; + } + + /** + * get a component site views IDs + * + * @param int $id The target ID + * + * @return array|null The result ids + * @since 3.2.0 + */ + private static function joomla_component_site_views($id): ?array + { + // get all this components views + $admin_view_ids = []; + + // get the views of this component + if ($add_views = GetHelper::var('component_site_views', (int) $id, 'joomla_component', 'addsite_views')) + { + if (JsonHelper::check($add_views)) + { + $add_views = json_decode($add_views, true); + if (ArrayHelper::check($add_views)) + { + foreach($add_views as $add_view) + { + if (isset($add_view['siteview'])) + { + $admin_view_ids[(int) $add_view['siteview']] = (int) $add_view['siteview']; + } + } + } + } + } + + // check that we have fields + if (ArrayHelper::check($admin_view_ids)) + { + return array_values($admin_view_ids); + } + + return null; + } + + /** + * get a component fields IDs + * + * @param int $id The target ID + * + * @return array|null The result ids + * @since 3.2.0 + */ + private static function joomla_component($id): ?array + { + // we start the field array + $field_ids = []; + + // first get all views + $admin_view_ids = []; + + // get the views of this component + if ($add_views = GetHelper::var('component_admin_views', (int) $id, 'joomla_component', 'addadmin_views')) + { + if (JsonHelper::check($add_views)) + { + $add_views = json_decode($add_views, true); + if (ArrayHelper::check($add_views)) + { + foreach($add_views as $add_view) + { + if (isset($add_view['adminview'])) + { + $admin_view_ids[(int) $add_view['adminview']] = (int) $add_view['adminview']; + } + } + } + } + } + + // check that we have views + if (ArrayHelper::check($admin_view_ids)) + { + foreach ($admin_view_ids as $admin_view) + { + // get all the fields linked to the admin view + if ($add_fields = GetHelper::var('admin_fields', (int) $admin_view, 'admin_view', 'addfields')) + { + if (JsonHelper::check($add_fields)) + { + $add_fields = json_decode($add_fields, true); + if (ArrayHelper::check($add_fields)) + { + foreach($add_fields as $add_field) + { + if (isset($add_field['field'])) + { + $field_ids[(int) $add_field['field']] = (int) $add_field['field']; + } + } + } + } + } + } + } + + // get config values + if ($add_config = GetHelper::var('component_config', (int) $id, 'joomla_component', 'addconfig')) + { + if (JsonHelper::check($add_config)) + { + $add_config = json_decode($add_config, true); + if (ArrayHelper::check($add_config)) + { + foreach($add_config as $add_conf) + { + if (isset($add_conf['field'])) + { + $field_ids[(int) $add_conf['field']] = (int) $add_conf['field']; + } + } + } + } + } + + // check that we have fields + if (ArrayHelper::check($field_ids)) + { + return array_values($field_ids); + } + + return null; + } + + /** + * get a module fields IDs + * + * @param int $id The target ID + * + * @return array|null The result ids + * @since 3.2.0 + */ + private static function joomla_module($id): ?array + { + // we start the field array + $field_ids = []; + + if ($fields = GetHelper::var('joomla_module', (int) $id, 'id', 'fields')) + { + if (JsonHelper::check($fields)) + { + $fields = json_decode($fields, true); + if (ArrayHelper::check($fields)) + { + foreach($fields as $form) + { + if (isset($form['fields']) && ArrayHelper::check($form['fields'])) + { + foreach ($form['fields'] as $field) + { + if (isset($field['field'])) + { + $field_ids[(int) $field['field']] = (int) $field['field']; + } + } + } + } + } + } + } + + // check that we have fields + if (ArrayHelper::check($field_ids)) + { + return array_values($field_ids); + } + + return null; + } + + /** + * get a plugin fields IDs + * + * @param int $id The target ID + * + * @return array|null The result ids + * @since 3.2.0 + */ + private static function joomla_plugin($id): ?array + { + // we start the field array + $field_ids = []; + + if ($fields = GetHelper::var('joomla_plugin', (int) $id, 'id', 'fields')) + { + if (JsonHelper::check($fields)) + { + $fields = json_decode($fields, true); + if (ArrayHelper::check($fields)) + { + foreach($fields as $form) + { + if (isset($form['fields']) && ArrayHelper::check($form['fields'])) + { + foreach ($form['fields'] as $field) + { + if (isset($field['field'])) + { + $field_ids[(int) $field['field']] = (int) $field['field']; + } + } + } + } + } + } + } + + // check that we have fields + if (ArrayHelper::check($field_ids)) + { + return array_values($field_ids); + } + + return null; + } + + /** + * get an admin view fields IDs + * + * @param int $id The target ID + * + * @return array|null The result ids + * @since 3.2.0 + */ + private static function admin_view($id): ?array + { + // we start the field array + $field_ids = []; + + // get all the fields linked to the admin view + if ($add_fields = GetHelper::var('admin_fields', (int) $id, 'admin_view', 'addfields')) + { + if (JsonHelper::check($add_fields)) + { + $add_fields = json_decode($add_fields, true); + if (ArrayHelper::check($add_fields)) + { + foreach($add_fields as $add_field) + { + if (isset($add_field['field'])) + { + $field_ids[(int) $add_field['field']] = (int) $add_field['field']; + } + } + } + } + } + + // check that we have fields + if (ArrayHelper::check($field_ids)) + { + return array_values($field_ids); + } + + return null; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Utilities/FormHelper.php b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Utilities/FormHelper.php new file mode 100644 index 000000000..6fff729be --- /dev/null +++ b/libraries/jcb_powers/VDM.Joomla/src/Componentbuilder/Utilities/FormHelper.php @@ -0,0 +1,189 @@ + + * @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 + */ + +namespace VDM\Joomla\Componentbuilder\Utilities; + + +use Joomla\CMS\Form\FormHelper as JoomlaFormHelper; +use Joomla\CMS\Form\FormField; +use VDM\Joomla\Utilities\ArrayHelper; + + +/** + * Form Helper + * + * @since 3.2.0 + */ +abstract class FormHelper +{ + /** + * get the field xml + * + * @param array $attributes The array of attributes + * @param array $options The options to apply to the XML element + * + * @return \SimpleXMLElement|null + * @since 3.2.0 + */ + public static function xml(array $attributes, ?array $options = null): ?\SimpleXMLElement + { + // make sure we have attributes and a type value + if (ArrayHelper::check($attributes)) + { + // start field xml + $XML = new \SimpleXMLElement(''); + + // load the attributes + self::attributes($XML, $attributes); + + // check if we have options + if (ArrayHelper::check($options)) + { + // load the options + self::options($XML, $options); + } + + // return the field xml + return $XML; + } + + return null; + } + + /** + * xmlAppend + * + * @param \SimpleXMLElement $xml The XML element reference in which to inject a comment + * @param mixed $node A SimpleXMLElement node to append to the XML element reference, + * or a stdClass object containing a comment attribute to be injected + * before the XML node and a fieldXML attribute containing a SimpleXMLElement + * + * @return void + * @since 3.2.0 + */ + public static function append(\SimpleXMLElement &$xml, $node) + { + if (!$node) + { + // element was not returned + return; + } + switch (get_class($node)) + { + case 'stdClass': + if (property_exists($node, 'comment')) + { + self::comment($xml, $node->comment); + } + if (property_exists($node, 'fieldXML')) + { + self::append($xml, $node->fieldXML); + } + break; + case 'SimpleXMLElement': + $domXML = \dom_import_simplexml($xml); + $domNode = \dom_import_simplexml($node); + $domXML->appendChild($domXML->ownerDocument->importNode($domNode, true)); + $xml = \simplexml_import_dom($domXML); + break; + } + } + + /** + * xmlComment + * + * @param \SimpleXMLElement $xml The XML element reference in which to inject a comment + * @param string $comment The comment to inject + * + * @return void + * @since 3.2.0 + */ + public static function comment(\SimpleXMLElement &$xml, string $comment) + { + $domXML = \dom_import_simplexml($xml); + $domComment = new \DOMComment($comment); + $nodeTarget = $domXML->ownerDocument->importNode($domComment, true); + $domXML->appendChild($nodeTarget); + $xml = \simplexml_import_dom($domXML); + } + + /** + * xmlAddAttributes + * + * @param \SimpleXMLElement $xml The XML element reference in which to inject a comment + * @param array $attributes The attributes to apply to the XML element + * + * @return void + * @since 3.2.0 + */ + public static function attributes(\SimpleXMLElement &$xml, array $attributes = []) + { + foreach ($attributes as $key => $value) + { + $xml->addAttribute($key, $value); + } + } + + /** + * xmlAddOptions + * + * @param \SimpleXMLElement $xml The XML element reference in which to inject a comment + * @param array $options The options to apply to the XML element + * + * @return void + * @since 3.2.0 + */ + public static function options(\SimpleXMLElement &$xml, array $options = []) + { + foreach ($options as $key => $value) + { + $addOption = $xml->addChild('option'); + $addOption->addAttribute('value', $key); + $addOption[] = $value; + } + } + + /** + * get the field object + * + * @param array $attributes The array of attributes + * @param string $default The default of the field + * @param array $options The options to apply to the XML element + * + * @return FormField|null + * @since 3.2.0 + */ + public static function field(array $attributes, string $default = '', ?array $options = null): ?FormField + { + // make sure we have attributes and a type value + if (ArrayHelper::check($attributes) && isset($attributes['type'])) + { + // get field type + if (($field = JoomlaFormHelper::loadFieldType($attributes['type'], true)) === false) + { + return null; + } + + // get field xml + $XML = self::xml($attributes, $options); + + // setup the field + $field->setup($XML, $default); + + // return the field object + return $field; + } + + return null; + } + +} + diff --git a/libraries/jcb_powers/VDM.Joomla/src/Utilities/GuidHelper.php b/libraries/jcb_powers/VDM.Joomla/src/Utilities/GuidHelper.php index 1f338db1b..e21947347 100644 --- a/libraries/jcb_powers/VDM.Joomla/src/Utilities/GuidHelper.php +++ b/libraries/jcb_powers/VDM.Joomla/src/Utilities/GuidHelper.php @@ -185,7 +185,8 @@ abstract class GuidHelper } } } - return false; + + return null; } /** diff --git a/script.php b/script.php index 5257edbff..58d8ebaa7 100644 --- a/script.php +++ b/script.php @@ -6174,9 +6174,9 @@ class com_componentbuilderInstallerScript $power->type_title = 'Componentbuilder Power'; $power->type_alias = 'com_componentbuilder.power'; $power->table = '{"special": {"dbtable": "#__componentbuilder_power","key": "id","type": "Power","prefix": "componentbuilderTable","config": "array()"},"common": {"dbtable": "#__ucm_content","key": "ucm_id","type": "Corecontent","prefix": "JTable","config": "array()"}}'; - $power->field_mappings = '{"common": {"core_content_item_id": "id","core_title": "system_name","core_state": "published","core_alias": "null","core_created_time": "created","core_modified_time": "modified","core_body": "head","core_hits": "hits","core_publish_up": "null","core_publish_down": "null","core_access": "access","core_params": "params","core_featured": "null","core_metadata": "null","core_language": "null","core_images": "null","core_urls": "null","core_version": "version","core_ordering": "ordering","core_metakey": "null","core_metadesc": "null","core_catid": "null","core_xreference": "null","asset_id": "asset_id"},"special": {"system_name":"system_name","namespace":"namespace","type":"type","power_version":"power_version","description":"description","licensing_template":"licensing_template","add_head":"add_head","implements_custom":"implements_custom","implements":"implements","extends_custom":"extends_custom","extends":"extends","head":"head","add_licensing_template":"add_licensing_template","main_class_code":"main_class_code","guid":"guid","name":"name"}}'; + $power->field_mappings = '{"common": {"core_content_item_id": "id","core_title": "system_name","core_state": "published","core_alias": "null","core_created_time": "created","core_modified_time": "modified","core_body": "head","core_hits": "hits","core_publish_up": "null","core_publish_down": "null","core_access": "access","core_params": "params","core_featured": "null","core_metadata": "null","core_language": "null","core_images": "null","core_urls": "null","core_version": "version","core_ordering": "ordering","core_metakey": "null","core_metadesc": "null","core_catid": "null","core_xreference": "null","asset_id": "asset_id"},"special": {"system_name":"system_name","namespace":"namespace","type":"type","power_version":"power_version","licensing_template":"licensing_template","description":"description","extends":"extends","approved":"approved","add_head":"add_head","extends_custom":"extends_custom","implements_custom":"implements_custom","implements":"implements","head":"head","approved_paths":"approved_paths","main_class_code":"main_class_code","add_licensing_template":"add_licensing_template","guid":"guid","name":"name"}}'; $power->router = 'ComponentbuilderHelperRoute::getPowerRoute'; - $power->content_history_options = '{"formFile": "administrator/components/com_componentbuilder/models/forms/power.xml","hideFields": ["asset_id","checked_out","checked_out_time","version"],"ignoreChanges": ["modified_by","modified","checked_out","checked_out_time","version","hits"],"convertToInt": ["published","ordering","add_head","add_licensing_template"],"displayLookup": [{"sourceColumn": "created_by","targetTable": "#__users","targetColumn": "id","displayColumn": "name"},{"sourceColumn": "access","targetTable": "#__viewlevels","targetColumn": "id","displayColumn": "title"},{"sourceColumn": "modified_by","targetTable": "#__users","targetColumn": "id","displayColumn": "name"},{"sourceColumn": "implements","targetTable": "#__componentbuilder_power","targetColumn": "guid","displayColumn": "name"},{"sourceColumn": "extends","targetTable": "#__componentbuilder_power","targetColumn": "guid","displayColumn": "name"}]}'; + $power->content_history_options = '{"formFile": "administrator/components/com_componentbuilder/models/forms/power.xml","hideFields": ["asset_id","checked_out","checked_out_time","version"],"ignoreChanges": ["modified_by","modified","checked_out","checked_out_time","version","hits"],"convertToInt": ["published","ordering","approved","add_head","add_licensing_template"],"displayLookup": [{"sourceColumn": "created_by","targetTable": "#__users","targetColumn": "id","displayColumn": "name"},{"sourceColumn": "access","targetTable": "#__viewlevels","targetColumn": "id","displayColumn": "title"},{"sourceColumn": "modified_by","targetTable": "#__users","targetColumn": "id","displayColumn": "name"},{"sourceColumn": "extends","targetTable": "#__componentbuilder_power","targetColumn": "guid","displayColumn": "name"},{"sourceColumn": "implements","targetTable": "#__componentbuilder_power","targetColumn": "guid","displayColumn": "name"}]}'; // Set the object into the content types table. $power_Inserted = $db->insertObject('#__content_types', $power); @@ -6738,7 +6738,7 @@ class com_componentbuilderInstallerScript $query = $db->getQuery(true); // Field to update. $fields = array( - $db->quoteName('params') . ' = ' . $db->quote('{"autorName":"Llewellyn van der Merwe","autorEmail":"joomla@vdm.io","subform_layouts":"default","editor":"none","manage_jcb_package_directories":"2","set_browser_storage":"1","storage_time_to_live":"global","builder_gif_size":"480-272","add_menu_prefix":"1","menu_prefix":"»","minify":"0","language":"en-GB","percentagelanguageadd":"30","assets_table_fix":"2","compiler_field_builder_type":"2","field_name_builder":"1","type_name_builder":"1","import_guid_only":"1","export_language_strings":"1","development_method":"1","expansion":"0","return_options_build":"2","cronjob_backup_type":"1","cronjob_backup_server":"0","backup_package_name":"JCB_Backup_[YEAR]_[MONTH]_[DAY]","export_license":"GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html","export_copyright":"Copyright (C) 2015. All Rights Reserved","check_in":"-1 day","save_history":"1","history_limit":"10","uikit_load":"1","uikit_min":"","uikit_style":""}'), + $db->quoteName('params') . ' = ' . $db->quote('{"autorName":"Llewellyn van der Merwe","autorEmail":"joomla@vdm.io","subform_layouts":"default","editor":"none","manage_jcb_package_directories":"2","set_browser_storage":"1","storage_time_to_live":"global","super_powers_documentation":"0","powers_repository":"0","super_powers_repositories":"0","approved_paths":"default","add_custom_gitea_url":"1","custom_gitea_url":"https://git.vdm.dev","super_powers_core":"joomla/super-powers","builder_gif_size":"480-272","compiler_plugin":["componentbuilderactionlogcompiler","componentbuilderfieldorderingcompiler","componentbuilderheaderscompiler","componentbuilderpowersautoloadercompiler","componentbuilderprivacycompiler"],"add_menu_prefix":"1","menu_prefix":"»","minify":"0","language":"en-GB","percentagelanguageadd":"30","assets_table_fix":"2","compiler_field_builder_type":"2","field_name_builder":"1","type_name_builder":"1","import_guid_only":"1","export_language_strings":"1","development_method":"1","expansion":"0","return_options_build":"2","cronjob_backup_type":"1","cronjob_backup_server":"0","backup_package_name":"JCB_Backup_[YEAR]_[MONTH]_[DAY]","export_license":"GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html","export_copyright":"Copyright (C) 2015. All Rights Reserved","check_in":"-1 day","save_history":"1","history_limit":"10","uikit_load":"1","uikit_min":"","uikit_style":""}'), ); // Condition. $conditions = array( @@ -6755,7 +6755,7 @@ class com_componentbuilderInstallerScript { $rule_length = $db->loadResult(); // Check the size of the rules column - if ($rule_length <= 97280) + if ($rule_length <= 97760) { // Fix the assets table rules column size $fix_rules_size = "ALTER TABLE `#__assets` CHANGE `rules` `rules` MEDIUMTEXT NOT NULL COMMENT 'JSON encoded access control. Enlarged to MEDIUMTEXT by JCB';"; @@ -7695,9 +7695,9 @@ class com_componentbuilderInstallerScript $power->type_title = 'Componentbuilder Power'; $power->type_alias = 'com_componentbuilder.power'; $power->table = '{"special": {"dbtable": "#__componentbuilder_power","key": "id","type": "Power","prefix": "componentbuilderTable","config": "array()"},"common": {"dbtable": "#__ucm_content","key": "ucm_id","type": "Corecontent","prefix": "JTable","config": "array()"}}'; - $power->field_mappings = '{"common": {"core_content_item_id": "id","core_title": "system_name","core_state": "published","core_alias": "null","core_created_time": "created","core_modified_time": "modified","core_body": "head","core_hits": "hits","core_publish_up": "null","core_publish_down": "null","core_access": "access","core_params": "params","core_featured": "null","core_metadata": "null","core_language": "null","core_images": "null","core_urls": "null","core_version": "version","core_ordering": "ordering","core_metakey": "null","core_metadesc": "null","core_catid": "null","core_xreference": "null","asset_id": "asset_id"},"special": {"system_name":"system_name","namespace":"namespace","type":"type","power_version":"power_version","description":"description","licensing_template":"licensing_template","add_head":"add_head","implements_custom":"implements_custom","implements":"implements","extends_custom":"extends_custom","extends":"extends","head":"head","add_licensing_template":"add_licensing_template","main_class_code":"main_class_code","guid":"guid","name":"name"}}'; + $power->field_mappings = '{"common": {"core_content_item_id": "id","core_title": "system_name","core_state": "published","core_alias": "null","core_created_time": "created","core_modified_time": "modified","core_body": "head","core_hits": "hits","core_publish_up": "null","core_publish_down": "null","core_access": "access","core_params": "params","core_featured": "null","core_metadata": "null","core_language": "null","core_images": "null","core_urls": "null","core_version": "version","core_ordering": "ordering","core_metakey": "null","core_metadesc": "null","core_catid": "null","core_xreference": "null","asset_id": "asset_id"},"special": {"system_name":"system_name","namespace":"namespace","type":"type","power_version":"power_version","licensing_template":"licensing_template","description":"description","extends":"extends","approved":"approved","add_head":"add_head","extends_custom":"extends_custom","implements_custom":"implements_custom","implements":"implements","head":"head","approved_paths":"approved_paths","main_class_code":"main_class_code","add_licensing_template":"add_licensing_template","guid":"guid","name":"name"}}'; $power->router = 'ComponentbuilderHelperRoute::getPowerRoute'; - $power->content_history_options = '{"formFile": "administrator/components/com_componentbuilder/models/forms/power.xml","hideFields": ["asset_id","checked_out","checked_out_time","version"],"ignoreChanges": ["modified_by","modified","checked_out","checked_out_time","version","hits"],"convertToInt": ["published","ordering","add_head","add_licensing_template"],"displayLookup": [{"sourceColumn": "created_by","targetTable": "#__users","targetColumn": "id","displayColumn": "name"},{"sourceColumn": "access","targetTable": "#__viewlevels","targetColumn": "id","displayColumn": "title"},{"sourceColumn": "modified_by","targetTable": "#__users","targetColumn": "id","displayColumn": "name"},{"sourceColumn": "implements","targetTable": "#__componentbuilder_power","targetColumn": "guid","displayColumn": "name"},{"sourceColumn": "extends","targetTable": "#__componentbuilder_power","targetColumn": "guid","displayColumn": "name"}]}'; + $power->content_history_options = '{"formFile": "administrator/components/com_componentbuilder/models/forms/power.xml","hideFields": ["asset_id","checked_out","checked_out_time","version"],"ignoreChanges": ["modified_by","modified","checked_out","checked_out_time","version","hits"],"convertToInt": ["published","ordering","approved","add_head","add_licensing_template"],"displayLookup": [{"sourceColumn": "created_by","targetTable": "#__users","targetColumn": "id","displayColumn": "name"},{"sourceColumn": "access","targetTable": "#__viewlevels","targetColumn": "id","displayColumn": "title"},{"sourceColumn": "modified_by","targetTable": "#__users","targetColumn": "id","displayColumn": "name"},{"sourceColumn": "extends","targetTable": "#__componentbuilder_power","targetColumn": "guid","displayColumn": "name"},{"sourceColumn": "implements","targetTable": "#__componentbuilder_power","targetColumn": "guid","displayColumn": "name"}]}'; // Check if power type is already in content_type DB. $power_id = null; @@ -9418,11 +9418,18 @@ class com_componentbuilderInstallerScript // set a notice that this was done $app->enqueueMessage('

Best Practice!
We have removed the internal JCB composer-vendor folder /libraries/vdm_io/ and placed the targeted library (phpseclib) in its own folder /libraries/phpseclib/.

', 'Notice'); } - + // check if we still have the old Gitea Classes + $giteaPath = JPATH_ROOT . '/libraries/jcb_powers/VDM.Gitea'; + if (JFolder::exists($giteaPath)) + { + ComponentbuilderHelper::removeFolder($giteaPath); + // set a notice that this was done + $app->enqueueMessage('

Clean-up!
We have removed the internal old Gitea folder /libraries/jcb_powers/VDM.Gitea that is no longer used.
The new Gitea classes are now found here /libraries/jcb_powers/VDM.Joomla.Gitea and is available to any JCB project from the following super power: https://git.vdm.dev/joomla/gitea

', 'Notice'); + } echo '
-

Upgrade to Version 3.1.19 Was Successful! Let us know if anything is not working as expected.

'; +

Upgrade to Version 3.1.24 Was Successful! Let us know if anything is not working as expected.

'; // Set db if not set already. if (!isset($db)) diff --git a/site/helpers/componentbuilder.php b/site/helpers/componentbuilder.php index a2607db63..fbbf69827 100644 --- a/site/helpers/componentbuilder.php +++ b/site/helpers/componentbuilder.php @@ -23,9 +23,9 @@ if (file_exists($composer_autoloader)) spl_autoload_register(function ($class) { // project-specific base directories and namespace prefix $search = [ + 'libraries/jcb_powers/VDM.Joomla.Gitea' => 'VDM\\Joomla\\Gitea', 'libraries/jcb_powers/VDM.Joomla' => 'VDM\\Joomla', 'libraries/jcb_powers/VDM.Minify' => 'VDM\\Minify', - 'libraries/jcb_powers/VDM.Gitea' => 'VDM\\Gitea', 'libraries/jcb_powers/VDM.Psr' => 'VDM\\Psr' ]; // Start the search and load if found @@ -5520,571 +5520,6 @@ abstract class ComponentbuilderHelper } - /** - * get extensions grouped list xml - **/ - public static function getExtensionGroupedListXml() - { - // the extension types - $extensions = array( - 'joomla_component' => 'COM_COMPONENTBUILDER_COMPONENT', - 'joomla_module' => 'COM_COMPONENTBUILDER_MODULE', - 'joomla_plugin' => 'COM_COMPONENTBUILDER_PLUGIN' - ); - // get the extension values - foreach ($extensions as $extension => $label) - { - ${$extension} = self::getByTypeTheIdsSystemNames($extension); - } - - $xml = new DOMDocument(); - $xml->formatOutput = true; - - $root = $xml->createElement('field'); - $root->setAttributeNode(new DOMAttr('name', 'extension')); - $root->setAttributeNode(new DOMAttr('type', 'groupedlist')); - $root->setAttributeNode(new DOMAttr('onchange', 'this.form.submit();')); - - $root - ->appendChild($xml->createElement('option', '- ' . JText::_('COM_COMPONENTBUILDER_SELECT_EXTENSION') . ' -')) - ->setAttributeNode(new DOMAttr('value', '')); - - foreach ($extensions as $extension => $label) - { - $extension_node = $xml->createElement('group'); - $extension_node->setAttributeNode(new DOMAttr('label', $label)); - if (!self::checkArray(${$extension})) - { - $extension_node - ->appendChild($xml->createElement('option', '- ' . JText::_('COM_COMPONENTBUILDER_NONE') . ' -')) - ->setAttributeNode(new DOMAttr('disabled', 'true')); - } - else - { - foreach (${$extension} as $id => $element) - { - $extension_node - ->appendChild($xml->createElement('option', $element)) - ->setAttributeNode(new DOMAttr('value', $extension . '__' . $id)); - } - } - $root->appendChild($extension_node); - } - $xml->appendChild($root); - return $xml->saveXML(); - } - - /** - * get by type the ids and system names - **/ - public static function getByTypeTheIdsSystemNames($type, $limiter = null) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true); - - $query - ->select($db->quoteName(array('id', 'system_name'))) - ->from($db->quoteName('#__componentbuilder_' . $type)) - ->where($db->quoteName('published') . ' >= 1') - ->order($db->quoteName('modified') . ' desc') - ->order($db->quoteName('created') . ' desc'); - // check if we have a limter for admin views - if ($type === 'admin_view' && $limiter) - { - // first get all views - $adminviewIds = array(); - // if this is a plugin or a module, then no views - if (strpos($limiter, 'joomla_component') !== false) - { - $component = (int) str_replace('joomla_component__', '', $limiter); - // get the views of this component - if ($addViews = self::getVar('component_admin_views', (int) $component, 'joomla_component', 'addadmin_views')) - { - if (self::checkJson($addViews)) - { - $addViews = json_decode($addViews, true); - if (self::checkArray($addViews)) - { - foreach($addViews as $addView) - { - if (isset($addView['adminview'])) - { - $adminviewIds[(int) $addView['adminview']] = (int) $addView['adminview']; - } - } - } - } - } - } - // now check if we still have admin views - if (self::checkArray($adminviewIds)) - { - $query->where($db->quoteName('id') . ' IN (' . implode(',', $adminviewIds) . ')'); - } - else - { - return false; - } - } - $db->setQuery($query); - $db->execute(); - if ($db->getNumRows()) - { - return $db->loadAssocList('id', 'system_name'); - } - return false; - } - - - /** - * get any area linked IDs - */ - public static function getAreaLinkedIDs($extension, $type) - { - // What ever... - if ($type === 'joomla_component_admin_views') - { - return self::getComponentAdminViewsIDs($extension); - } - elseif ($type === 'joomla_component_custom_admin_views') - { - return self::getComponentCustomAdminViewsIDs($extension); - } - elseif ($type === 'joomla_component_site_views') - { - return self::getComponentSiteViewsIDs($extension); - } - elseif ($type === 'joomla_component') - { - return self::getComponentFieldsIDs($extension); - } - elseif ($type === 'joomla_module') - { - return self::getModuleFieldsIDs($extension); - } - elseif ($type === 'joomla_plugin') - { - return self::getPluginFieldsIDs($extension); - } - elseif ($type === 'admin_view') - { - return self::getAdminViewFieldsIDs($extension); - } - return false; - } - - /** - * get a component admin views IDs - */ - public static function getComponentAdminViewsIDs($id) - { - // get all this components views - $adminviewIds = array(); - // get the views of this component - if ($addViews = self::getVar('component_admin_views', (int) $id, 'joomla_component', 'addadmin_views')) - { - if (self::checkJson($addViews)) - { - $addViews = json_decode($addViews, true); - if (self::checkArray($addViews)) - { - foreach($addViews as $addView) - { - if (isset($addView['adminview'])) - { - $adminviewIds[(int) $addView['adminview']] = (int) $addView['adminview']; - } - } - } - } - } - // check that we have fields - if (self::checkArray($adminviewIds)) - { - return array_values($adminviewIds); - } - return false; - } - - /** - * get a component custom admin views IDs - */ - public static function getComponentCustomAdminViewsIDs($id) - { - // get all this components views - $adminviewIds = array(); - // get the views of this component - if ($addViews = self::getVar('component_custom_admin_views', (int) $id, 'joomla_component', 'addcustom_admin_views')) - { - if (self::checkJson($addViews)) - { - $addViews = json_decode($addViews, true); - if (self::checkArray($addViews)) - { - foreach($addViews as $addView) - { - if (isset($addView['customadminview'])) - { - $adminviewIds[(int) $addView['customadminview']] = (int) $addView['customadminview']; - } - } - } - } - } - // check that we have fields - if (self::checkArray($adminviewIds)) - { - return array_values($adminviewIds); - } - return false; - } - - /** - * get a component site views IDs - */ - public static function getComponentSiteViewsIDs($id) - { - // get all this components views - $adminviewIds = array(); - // get the views of this component - if ($addViews = self::getVar('component_site_views', (int) $id, 'joomla_component', 'addsite_views')) - { - if (self::checkJson($addViews)) - { - $addViews = json_decode($addViews, true); - if (self::checkArray($addViews)) - { - foreach($addViews as $addView) - { - if (isset($addView['siteview'])) - { - $adminviewIds[(int) $addView['siteview']] = (int) $addView['siteview']; - } - } - } - } - } - // check that we have fields - if (self::checkArray($adminviewIds)) - { - return array_values($adminviewIds); - } - return false; - } - - /** - * get a component fields IDs - */ - public static function getComponentFieldsIDs($id) - { - // we start the field array - $fieldIds = array(); - // first get all views - $adminviewIds = array(); - // get the views of this component - if ($addViews = self::getVar('component_admin_views', (int) $id, 'joomla_component', 'addadmin_views')) - { - if (self::checkJson($addViews)) - { - $addViews = json_decode($addViews, true); - if (self::checkArray($addViews)) - { - foreach($addViews as $addView) - { - if (isset($addView['adminview'])) - { - $adminviewIds[(int) $addView['adminview']] = (int) $addView['adminview']; - } - } - } - } - } - // check that we have views - if (self::checkArray($adminviewIds)) - { - foreach ($adminviewIds as $adminView) - { - // get all the fields linked to the admin view - if ($addFields = self::getVar('admin_fields', (int) $adminView, 'admin_view', 'addfields')) - { - if (self::checkJson($addFields)) - { - $addFields = json_decode($addFields, true); - if (self::checkArray($addFields)) - { - foreach($addFields as $addField) - { - if (isset($addField['field'])) - { - $fieldIds[(int) $addField['field']] = (int) $addField['field']; - } - } - } - } - } - } - } - // get config values - if ($addconfig = self::getVar('component_config', (int) $id, 'joomla_component', 'addconfig')) - { - if (self::checkJson($addconfig)) - { - $addconfig = json_decode($addconfig, true); - if (self::checkArray($addconfig)) - { - foreach($addconfig as $addconf) - { - if (isset($addconf['field'])) - { - $fieldIds[(int) $addconf['field']] = (int) $addconf['field']; - } - } - } - } - } - // check that we have fields - if (self::checkArray($fieldIds)) - { - return array_values($fieldIds); - } - return false; - } - - /** - * get a module fields IDs - */ - public static function getModuleFieldsIDs($id) - { - // we start the field array - $fieldIds = array(); - if ($fields = self::getVar('joomla_module', (int) $id, 'id', 'fields')) - { - if (self::checkJson($fields)) - { - $fields = json_decode($fields, true); - if (self::checkArray($fields)) - { - foreach($fields as $form) - { - if (isset($form['fields']) && self::checkArray($form['fields'])) - { - foreach ($form['fields'] as $field) - { - if (isset($field['field'])) - { - $fieldIds[(int) $field['field']] = (int) $field['field']; - } - } - } - } - } - } - } - // check that we have fields - if (self::checkArray($fieldIds)) - { - return array_values($fieldIds); - } - return false; - } - - /** - * get a plugin fields IDs - */ - public static function getPluginFieldsIDs($id) - { - // we start the field array - $fieldIds = array(); - if ($fields = self::getVar('joomla_plugin', (int) $id, 'id', 'fields')) - { - if (self::checkJson($fields)) - { - $fields = json_decode($fields, true); - if (self::checkArray($fields)) - { - foreach($fields as $form) - { - if (isset($form['fields']) && self::checkArray($form['fields'])) - { - foreach ($form['fields'] as $field) - { - if (isset($field['field'])) - { - $fieldIds[(int) $field['field']] = (int) $field['field']; - } - } - } - } - } - } - } - // check that we have fields - if (self::checkArray($fieldIds)) - { - return array_values($fieldIds); - } - return false; - } - - /** - * get an admin view fields IDs - */ - public static function getAdminViewFieldsIDs($id) - { - // we start the field array - $fieldIds = array(); - // get all the fields linked to the admin view - if ($addFields = self::getVar('admin_fields', (int) $id, 'admin_view', 'addfields')) - { - if (self::checkJson($addFields)) - { - $addFields = json_decode($addFields, true); - if (self::checkArray($addFields)) - { - foreach($addFields as $addField) - { - if (isset($addField['field'])) - { - $fieldIds[(int) $addField['field']] = (int) $addField['field']; - } - } - } - } - } - // check that we have fields - if (self::checkArray($fieldIds)) - { - return array_values($fieldIds); - } - return false; - } - - /** - * get translation extension ids - **/ - public static function getTranslationExtensionsIds($extension, $type) - { - // only allow these columns (extension types) - $columns = array( - 'joomla_component' => 'components', - 'joomla_module' => 'modules', - 'joomla_plugin' => 'plugins' - ); - // check if the column name is correct - if (isset($columns[$type])) - { - $column = $columns[$type]; - $db = JFactory::getDbo(); - $query = $db->getQuery(true); - $query - ->select($db->quoteName(array('id', $column))) - ->from($db->quoteName('#__componentbuilder_language_translation')) - ->where($db->quoteName($column) . ' != ' . $db->quote('')); - $db->setQuery($query); - $db->execute(); - if ($db->getNumRows()) - { - $results = $db->loadAssocList(); - $matches = array(); - foreach ($results as $k => $v) - { - $value = json_decode($v[$column], true); - if (in_array($extension, $value)) - { - $matches[$v['id']] = $v['id']; - } - } - // Checks that we found matches - if (self::checkArray($matches)) - { - return array_values($matches); - } - } - } - return false; - } - - /** - * get translation ids - **/ - public static function getTranslationIds($language, $translated = true) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true); - - $query - ->select($db->quoteName('id')) - ->from($db->quoteName('#__componentbuilder_language_translation')); - - // Build the where condition - if ($translated === true) // Translated - { - if ($language === 'all') - { - if (($languages = self::getAvailableLanguages()) !== false) - { - $wheres = array(); - foreach ($languages as $k => $v) - { - $wheres[] = $db->quoteName('translation') . ' LIKE ' . $db->quote('%' . $k . '%'); - } - $query->where($wheres); - } - } - else - { - $query->where($db->quoteName('translation') . ' LIKE ' . $db->quote('%' . $language . '%')); - } - } - else // Not translated - { - if ($language === 'none') - { - $query->where( - array( - $db->quoteName('translation') . ' = ' . $db->quote(''), - $db->quoteName('translation') . ' = ' . $db->quote('[]'), - $db->quoteName('translation') . ' = ' . $db->quote('{}') - ), 'OR' - ); - } - else - { - $query->where($db->quoteName('translation') . ' NOT LIKE ' . $db->quote('%' . $language . '%')); - } - } - - $db->setQuery($query); - $db->execute(); - if ($db->getNumRows()) - { - return array_unique($db->loadColumn()); - } - return false; - } - - /** - * get available languages - **/ - public static function getAvailableLanguages() - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true); - $query - ->select($db->quoteName(array('langtag', 'name'))) - ->from($db->quoteName('#__componentbuilder_language')) - ->where($db->quoteName('published') . ' = 1') - ->order($db->quoteName('name') . ' desc'); - $db->setQuery($query); - $db->execute(); - if ($db->getNumRows()) - { - return $db->loadAssocList('langtag', 'name'); - } - return false; - } - - /** * Check if a row already exist * diff --git a/site/language/en-GB/en-GB.com_componentbuilder.ini b/site/language/en-GB/en-GB.com_componentbuilder.ini index f9cc9f346..9a68ed7b8 100644 --- a/site/language/en-GB/en-GB.com_componentbuilder.ini +++ b/site/language/en-GB/en-GB.com_componentbuilder.ini @@ -80,9 +80,11 @@ COM_COMPONENTBUILDER_PACKAGE_OWNER_DETAILS="Package Owner Details" COM_COMPONENTBUILDER_PACKAGE_OWNER_DETAILS_NOT_FOUND="Package owner details not found!" COM_COMPONENTBUILDER_PACKAGE_OWNER_NOT_SET="Package Owner Not Set" COM_COMPONENTBUILDER_PAIDLOCKED="Paid/Locked" +COM_COMPONENTBUILDER_PFILE_AT_BGITEAREMOTESB_GAVE_THE_FOLLOWING_ERRORBR_SP="

File at gitea.remote/%s gave the following error!
%s

" COM_COMPONENTBUILDER_PLUGIN="Plugin" COM_COMPONENTBUILDER_PPOWER_BGUIDSB_NOT_FOUNDP="

Power guid:%s not found!

" COM_COMPONENTBUILDER_PROPERTY="Property" +COM_COMPONENTBUILDER_PSUPER_POWERB_REPOSITORY_AT_BGITVDMDEVSB_GAVE_THE_FOLLOWING_ERRORBR_SP="

Super Power repository at git.vdm.dev/%s gave the following error!
%s

" COM_COMPONENTBUILDER_PS_NAMING_MISMATCH_ERROR_SPPTHE_S_NAME_IS_BSB_AND_THE_ENDING_FILE_NAME_IN_THE_NAMESPACE_IS_BSB_THIS_IS_BAD_CONVENTION_PLEASE_SEE_A_HREFS_PSRFOURA_FOR_MORE_INFOPPA_HREFSCLICK_HEREA_TO_FIX_THIS_ISSUEP="

%s naming mismatch error (%s)

The %s name is %s and the ending file name in the namespace is %s. This is bad convention, please see psr-4 for more info.

Click here to fix this issue.

" COM_COMPONENTBUILDER_SBR_YOU_CAN_ADD_A_BGITHUB_ACCESS_TOKENB_TO_COMPONENTBUILDER_GLOBAL_OPTIONS_TO_MAKE_AUTHENTICATED_REQUESTS_TO_GITHUB_AN_ACCESS_TOKEN_WITH_ONLY_PUBLIC_ACCESS_WILL_DO_TO_RETRIEVE_S="%s
You can add a gitHub Access Token to Componentbuilder global options to make authenticated requests to gitHub. An access token with only public access will do to retrieve %s." COM_COMPONENTBUILDER_SELECT_EXTENSION="Select Extension"