diff --git a/README.md b/README.md index 3f09e23ff..136efe5cf 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Joomla Component Builder (JCB) -[![GitHub release](https://img.shields.io/github/release/vdm-io/Joomla-Component-Builder.svg)](https://github.com/vdm-io/Joomla-Component-Builder/releases) [![Total Downloads](https://img.shields.io/github/downloads/vdm-io/Joomla-Component-Builder/total.svg)](https://github.com/vdm-io/Joomla-Component-Builder/releases) +[![GitHub release](https://img.shields.io/github/release/vdm-io/Joomla-Component-Builder.svg)](https://github.com/vdm-io/Joomla-Component-Builder/releases) [![Total Downloads](https://img.shields.io/github/downloads/vdm-io/Joomla-Component-Builder/total.svg)](https://github.com/vdm-io/Joomla-Component-Builder/releases) +[![Backers on Open Collective](https://opencollective.com/Joomla-Component-Builder/backers/badge.svg)](#backers) +[![Sponsors on Open Collective](https://opencollective.com/Joomla-Component-Builder/sponsors/badge.svg)](#sponsors) This is a [Joomla 3.x](https://extensions.joomla.org/extension/component-builder/) component. [__See In Action__](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45) @@ -117,7 +119,15 @@ Our idea was to almost let this tool serve as a cheat sheet to how things can be MAKING IT BETTER! ==================== -Watch the [proposed development workflow](https://vdm.bz/proposed-development-workflow). +Get involved on the forums, and the GitHub issues, and you can even help us develop/improve the pipeline of JCB for continues delivery. We really want to see JCB remain the tool of choice for all Joomla Component Development needs and ideas. + +TODO +====== + +- Add automatic (REST) API ability for all components build with JCB. So we can link any component build with JCB to an Android/Apple APP. +- Add automatic unit testing. To nurture pipeline integration for all components build with JCB. +- Team collaborative development across JCB installations offline and online. +- Documentation (maintained by the community) for JCB. (help us select the best system for this) # Build Details @@ -125,21 +135,52 @@ Watch the [proposed development workflow](https://vdm.bz/proposed-development-wo + *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + *Name*: [Component Builder](https://github.com/vdm-io/Joomla-Component-Builder) + *First Build*: 30th April, 2015 -+ *Last Build*: 7th October, 2018 ++ *Last Build*: 27th November, 2018 + *Version*: 2.9.7 + *Copyright*: Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + *License*: GNU General Public License version 2 or later; see LICENSE.txt -+ *Line count*: **195701** ++ *Line count*: **195519** + *Field count*: **1087** -+ *File count*: **1277** ++ *File count*: **1275** + *Folder count*: **201** > This **component** was build with a Joomla [Automated Component Builder](http://joomlacomponentbuilder.com). > Developed by [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + +## Contributors + +This project exists thanks to all the people who contribute. + + ## Donations Come on buy VDM a coffee :) * PayPal: [paypal.me/asseblief](https://www.paypal.me/asseblief) (Asseblief = Please) in Afrikaans * Bitcoin: 18vURxYpPFjvNk8BnUy1ovCAyQmY3MzkSf - * Ethereum: 0x9548144662b47327c954f3e214edb96662d51218 \ No newline at end of file + * Ethereum: 0x9548144662b47327c954f3e214edb96662d51218 + + +### Backers + +Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/Joomla-Component-Builder#backer)] + + + + +### Sponsors + +Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/Joomla-Component-Builder#sponsor)] + + + + + + + + + + + + + diff --git a/admin/README.txt b/admin/README.txt index 3f09e23ff..dd42ce373 100644 --- a/admin/README.txt +++ b/admin/README.txt @@ -117,7 +117,15 @@ Our idea was to almost let this tool serve as a cheat sheet to how things can be MAKING IT BETTER! ==================== -Watch the [proposed development workflow](https://vdm.bz/proposed-development-workflow). +Get involved on the forums, and the GitHub issues, and you can even help us develop/improve the pipeline of JCB for continues delivery. We really want to see JCB remain the tool of choice for all Joomla Component Development needs and ideas. + +TODO +====== + +- Add automatic (REST) API ability for all components build with JCB. So we can link any component build with JCB to an Android/Apple APP. +- Add automatic unit testing. To nurture pipeline integration for all components build with JCB. +- Team collaborative development across JCB installations offline and online. +- Documentation (maintained by the community) for JCB. (help us select the best system for this) # Build Details @@ -125,13 +133,13 @@ Watch the [proposed development workflow](https://vdm.bz/proposed-development-wo + *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + *Name*: [Component Builder](https://github.com/vdm-io/Joomla-Component-Builder) + *First Build*: 30th April, 2015 -+ *Last Build*: 7th October, 2018 ++ *Last Build*: 27th November, 2018 + *Version*: 2.9.7 + *Copyright*: Copyright (C) 2015 - 2018 Vast Development Method. All rights reserved. + *License*: GNU General Public License version 2 or later; see LICENSE.txt -+ *Line count*: **195701** ++ *Line count*: **195519** + *Field count*: **1087** -+ *File count*: **1277** ++ *File count*: **1275** + *Folder count*: **201** > This **component** was build with a Joomla [Automated Component Builder](http://joomlacomponentbuilder.com). diff --git a/admin/compiler/joomla_3/Helper.php b/admin/compiler/joomla_3/Helper.php index 2913f37da..854e96267 100644 --- a/admin/compiler/joomla_3/Helper.php +++ b/admin/compiler/joomla_3/Helper.php @@ -854,11 +854,11 @@ abstract class ###Component###Helper * * @input array The array to check * - * @returns bool true on success + * @returns bool/int number of items in array on success **/ public static function checkArray($array, $removeEmptyString = false) { - if (isset($array) && is_array($array) && count((array)$array) > 0) + if (isset($array) && is_array($array) && ($nr = count((array)$array)) > 0) { // also make sure the empty strings are removed if ($removeEmptyString) @@ -872,7 +872,7 @@ abstract class ###Component###Helper } return self::checkArray($array, false); } - return true; + return $nr; } return false; } diff --git a/admin/compiler/joomla_3/Helper_site.php b/admin/compiler/joomla_3/Helper_site.php index db1f8c8f1..ae2ce5aad 100644 --- a/admin/compiler/joomla_3/Helper_site.php +++ b/admin/compiler/joomla_3/Helper_site.php @@ -846,11 +846,11 @@ abstract class ###Component###Helper * * @input array The array to check * - * @returns bool true on success + * @returns bool/int number of items in array on success **/ public static function checkArray($array, $removeEmptyString = false) { - if (isset($array) && is_array($array) && count((array)$array) > 0) + if (isset($array) && is_array($array) && ($nr = count((array)$array)) > 0) { // also make sure the empty strings are removed if ($removeEmptyString) @@ -864,7 +864,7 @@ abstract class ###Component###Helper } return self::checkArray($array, false); } - return true; + return $nr; } return false; } diff --git a/admin/compiler/joomla_3/JTable.php b/admin/compiler/joomla_3/JTable.php index 061b1410d..73304bb31 100644 --- a/admin/compiler/joomla_3/JTable.php +++ b/admin/compiler/joomla_3/JTable.php @@ -222,7 +222,7 @@ class ###Component###Table###View### extends JTable { // asset alread set so use saved rules $assetId = (int) $db->loadResult(); - return JAccess::getAssetRules($assetId); + return JAccess::getAssetRules($assetId); // (TODO) instead of keeping inherited Allowed it becomes Allowed. } // try again elseif ($try) diff --git a/admin/controllers/admin_view.php b/admin/controllers/admin_view.php index d58bda581..f787a500f 100644 --- a/admin/controllers/admin_view.php +++ b/admin/controllers/admin_view.php @@ -328,7 +328,8 @@ class ComponentbuilderControllerAdmin_view extends JControllerForm $_tablesArray = array( 'admin_fields', 'admin_fields_conditions', - 'admin_fields_relations' + 'admin_fields_relations', + 'admin_custom_tabs' ); foreach($_tablesArray as $_updateTable) { diff --git a/admin/custom/wiki_menu.txt b/admin/custom/wiki_menu.txt deleted file mode 100644 index 647db7539..000000000 --- a/admin/custom/wiki_menu.txt +++ /dev/null @@ -1 +0,0 @@ -[EXTERNALCODE=https://raw.githubusercontent.com/wiki/vdm-io/Joomla-Component-Builder/1.---Home.md] diff --git a/admin/helpers/compiler/a_Get.php b/admin/helpers/compiler/a_Get.php index aa9873fae..bf929fb01 100644 --- a/admin/helpers/compiler/a_Get.php +++ b/admin/helpers/compiler/a_Get.php @@ -83,7 +83,8 @@ class Get '[' => '[', ']' => ']', ',' => ',', - '+' => '+' + '+' => '+', + '=' => '=' ); /** @@ -2713,7 +2714,7 @@ class Get return $field['type_name']; } // check that we have the poperties - if (ComponentbuilderHelper::checkArray($field['settings']->properties)) + if (isset($field['settings']) && ComponentbuilderHelper::checkObject($field['settings']) && isset($field['settings']->properties) && ComponentbuilderHelper::checkArray($field['settings']->properties)) { // search for own custom fields if (strpos($field['settings']->type_name, '@') !== false) @@ -4316,139 +4317,155 @@ class Get $counter = 'a'; // Create a new query object. $query = $this->db->getQuery(true); + // switch to onlu trigger the run of the query if we have tables to query + $runQuery = false; foreach ($tables as $table) { - if ($counter === 'a') + if (isset($table['table'])) { - // the main table fields - if (strpos($table['sourcemap'], PHP_EOL) !== false) + if ($counter === 'a') { - $fields = explode(PHP_EOL, $table['sourcemap']); - if (ComponentbuilderHelper::checkArray($fields)) + // the main table fields + if (strpos($table['sourcemap'], PHP_EOL) !== false) { - // reset array buckets - $sourceArray = array(); - $targetArray = array(); - foreach ($fields as $field) + $fields = explode(PHP_EOL, $table['sourcemap']); + if (ComponentbuilderHelper::checkArray($fields)) { - if (strpos($field, "=>") !== false) + // reset array buckets + $sourceArray = array(); + $targetArray = array(); + foreach ($fields as $field) { - list($source, $target) = explode("=>", $field); - $sourceArray[] = $counter . '.' . trim($source); - $targetArray[] = trim($target); + if (strpos($field, "=>") !== false) + { + list($source, $target) = explode("=>", $field); + $sourceArray[] = $counter . '.' . trim($source); + $targetArray[] = trim($target); + } } - } - if (ComponentbuilderHelper::checkArray($sourceArray) && ComponentbuilderHelper::checkArray($targetArray)) - { - // add to query - $query->select($this->db->quoteName($sourceArray, $targetArray)); - $query->from('#__' . $table['table'] . ' AS a'); - } - // we may need to filter the selection - if (isset($this->sqlTweak[$view_id]['where'])) - { - // add to query the where filter - $query->where('a.id IN (' . $this->sqlTweak[$view_id]['where'] . ')'); - } - } - } - } - else - { - // the other tables - if (strpos($table['sourcemap'], PHP_EOL) !== false) - { - $fields = explode(PHP_EOL, $table['sourcemap']); - if (ComponentbuilderHelper::checkArray($fields)) - { - // reset array buckets - $sourceArray = array(); - $targetArray = array(); - foreach ($fields as $field) - { - if (strpos($field, "=>") !== false) + if (ComponentbuilderHelper::checkArray($sourceArray) && ComponentbuilderHelper::checkArray($targetArray)) { - list($source, $target) = explode("=>", $field); - $sourceArray[] = $counter . '.' . trim($source); - $targetArray[] = trim($target); - } - if (strpos($field, "==") !== false) - { - list($aKey, $bKey) = explode("==", $field); // add to query - $query->join('LEFT', $this->db->quoteName('#__' . $table['table'], $counter) . ' ON (' . $this->db->quoteName('a.' . trim($aKey)) . ' = ' . $this->db->quoteName($counter . '.' . trim($bKey)) . ')'); + $query->select($this->db->quoteName($sourceArray, $targetArray)); + $query->from('#__' . $table['table'] . ' AS a'); + $runQuery = true; + } + // we may need to filter the selection + if (isset($this->sqlTweak[$view_id]['where'])) + { + // add to query the where filter + $query->where('a.id IN (' . $this->sqlTweak[$view_id]['where'] . ')'); } } - if (ComponentbuilderHelper::checkArray($sourceArray) && ComponentbuilderHelper::checkArray($targetArray)) - { - // add to query - $query->select($this->db->quoteName($sourceArray, $targetArray)); - } } } - } - $counter++; - } - // now get the data - $this->db->setQuery($query); - $this->db->execute(); - if ($this->db->getNumRows()) - { - // get the data - $data = $this->db->loadObjectList(); - // start building the MySql dump - $dump = "--"; - $dump .= PHP_EOL . "-- Dumping data for table `#__" . $this->bbb . "component" . $this->ddd . "_" . $view . "`"; - $dump .= PHP_EOL . "--"; - $dump .= PHP_EOL . PHP_EOL . "INSERT INTO `#__" . $this->bbb . "component" . $this->ddd . "_" . $view . "` ("; - foreach ($data as $line) - { - $comaSet = 0; - foreach ($line as $fieldName => $fieldValue) - { - if ($comaSet == 0) - { - $dump .= $this->db->quoteName($fieldName); - } - else - { - $dump .= ", " . $this->db->quoteName($fieldName); - } - $comaSet++; - } - break; - } - $dump .= ") VALUES"; - $coma = 0; - foreach ($data as $line) - { - if ($coma == 0) - { - $dump .= PHP_EOL . "("; - } else { - $dump .= "," . PHP_EOL . "("; - } - $comaSet = 0; - foreach ($line as $fieldName => $fieldValue) - { - if ($comaSet == 0) + // the other tables + if (strpos($table['sourcemap'], PHP_EOL) !== false) { - $dump .= $this->mysql_escape($fieldValue); + $fields = explode(PHP_EOL, $table['sourcemap']); + if (ComponentbuilderHelper::checkArray($fields)) + { + // reset array buckets + $sourceArray = array(); + $targetArray = array(); + foreach ($fields as $field) + { + if (strpos($field, "=>") !== false) + { + list($source, $target) = explode("=>", $field); + $sourceArray[] = $counter . '.' . trim($source); + $targetArray[] = trim($target); + } + if (strpos($field, "==") !== false) + { + list($aKey, $bKey) = explode("==", $field); + // add to query + $query->join('LEFT', $this->db->quoteName('#__' . $table['table'], $counter) . ' ON (' . $this->db->quoteName('a.' . trim($aKey)) . ' = ' . $this->db->quoteName($counter . '.' . trim($bKey)) . ')'); + } + } + if (ComponentbuilderHelper::checkArray($sourceArray) && ComponentbuilderHelper::checkArray($targetArray)) + { + // add to query + $query->select($this->db->quoteName($sourceArray, $targetArray)); + } + } + } + } + $counter++; + } + else + { + // see where + // var_dump($view); + // jexit(); + } + } + // check if we should run query + if ($runQuery) + { + // now get the data + $this->db->setQuery($query); + $this->db->execute(); + if ($this->db->getNumRows()) + { + // get the data + $data = $this->db->loadObjectList(); + // start building the MySql dump + $dump = "--"; + $dump .= PHP_EOL . "-- Dumping data for table `#__" . $this->bbb . "component" . $this->ddd . "_" . $view . "`"; + $dump .= PHP_EOL . "--"; + $dump .= PHP_EOL . PHP_EOL . "INSERT INTO `#__" . $this->bbb . "component" . $this->ddd . "_" . $view . "` ("; + foreach ($data as $line) + { + $comaSet = 0; + foreach ($line as $fieldName => $fieldValue) + { + if ($comaSet == 0) + { + $dump .= $this->db->quoteName($fieldName); + } + else + { + $dump .= ", " . $this->db->quoteName($fieldName); + } + $comaSet++; + } + break; + } + $dump .= ") VALUES"; + $coma = 0; + foreach ($data as $line) + { + if ($coma == 0) + { + $dump .= PHP_EOL . "("; } else { - $dump .= ", " . $this->mysql_escape($fieldValue); + $dump .= "," . PHP_EOL . "("; } - $comaSet++; + $comaSet = 0; + foreach ($line as $fieldName => $fieldValue) + { + if ($comaSet == 0) + { + $dump .= $this->mysql_escape($fieldValue); + } + else + { + $dump .= ", " . $this->mysql_escape($fieldValue); + } + $comaSet++; + } + $dump .= ")"; + $coma++; } - $dump .= ")"; - $coma++; + $dump .= ";"; + // return build dump query + return $dump; } - $dump .= ";"; - // return build dump query - return $dump; } } return false; @@ -4764,7 +4781,7 @@ class Get * @return string * */ - public function setCustomCodeData($string, $debug = 0) + public function setCustomCodeData($string, $debug = 0, $not = null) { // insure the code is loaded $loaded = false; @@ -4863,6 +4880,11 @@ class Get { continue; } + // make sure to remove the not if set + if ($not && is_numeric($not) && $not > 0 && $not == $id) + { + continue; + } $bucket[$id] = $id; } } @@ -4879,7 +4901,7 @@ class Get // insure we add the langs to both site and admin $this->lang = 'both'; // now load the code to memory - $loaded = $this->getCustomCode($bucket, false); + $loaded = $this->getCustomCode($bucket, false, $debug); // revert lang to current setting $this->lang = $_tmpLang; } @@ -4922,6 +4944,7 @@ class Get echo '$this->customCode:'; var_dump($this->customCode); } + // load the code foreach ($this->customCode as $item) { $this->buildCustomCodePlaceholders($item, $code, $debug); @@ -5401,7 +5424,7 @@ class Get * @return void * */ - public function getCustomCode($ids = null, $setLang = true) + public function getCustomCode($ids = null, $setLang = true, $debug = 0) { // should the result be stored in memory $loadInMemory = false; @@ -5410,7 +5433,7 @@ class Get $query->from($this->db->quoteName('#__componentbuilder_custom_code', 'a')); if (ComponentbuilderHelper::checkArray($ids)) { - if ($idArray = $this->customCodeMemory($ids)) + if ($idArray = $this->checkCustomCodeMemory($ids)) { $query->select($this->db->quoteName(array('a.id', 'a.code', 'a.comment_type'))); $query->where($this->db->quoteName('a.id') . ' IN (' . implode(',', $idArray) . ')'); @@ -5449,6 +5472,11 @@ class Get { $customCode['code'] = $this->setLangStrings($customCode['code']); } + // check for more custom code (since this is a custom code placeholder) + else + { + $customCode['code'] = $this->setCustomCodeData($customCode['code'], $debug, $nr); + } if (isset($customCode['hashtarget'])) { $customCode['hashtarget'] = explode("__", $customCode['hashtarget']); @@ -5475,7 +5503,7 @@ class Get * @return void * */ - protected function customCodeMemory($ids) + protected function checkCustomCodeMemory($ids) { // reset custom code $this->customCode = array(); diff --git a/admin/helpers/compiler/c_Fields.php b/admin/helpers/compiler/c_Fields.php index 9a31387ff..c45d28f8c 100644 --- a/admin/helpers/compiler/c_Fields.php +++ b/admin/helpers/compiler/c_Fields.php @@ -2107,6 +2107,8 @@ class Fields extends Structure // setup a default field if (ComponentbuilderHelper::checkArray($field['settings']->properties)) { + // we need a deeper php code search tracker + $phpTracker = array(); foreach ($field['settings']->properties as $property) { // reset @@ -2155,6 +2157,8 @@ class Fields extends Structure $this->setDynamicValues(ComponentbuilderHelper::openValidBase64( ComponentbuilderHelper::getBetween($field['settings']->xml, $property['name'] . '="', '"') )); + // load tracker + $phpTracker['type_' . $phpKey] = $phpKey; } elseif ($property['name'] === 'prime_php' && $setCustom) { @@ -2338,6 +2342,24 @@ class Fields extends Structure $fieldAttributes['default'] = $xmlValue; } } + // check if all php is loaded using the tracker + if (ComponentbuilderHelper::checkArray($phpTracker)) + { + // litle search validation + $confirmation = '8qvZHoyuFYQqpj0YQbc6F3o5DhBlmS-_-a8pmCZfOVSfANjkmV5LG8pCdAY2JNYu6cB'; + foreach ($phpTracker as $searchKey => $phpKey) + { + // we must search for more code in the xml just incase + foreach(range(2, 30) as $phpLine) + { + $get_ = $searchKey . '_' . $phpLine; + if (!isset($fieldAttributes['custom'][$phpKey][$phpLine]) && ($value = ComponentbuilderHelper::getValueFromXMLstring($field['settings']->xml, $get_, $confirmation)) !== $confirmation) + { + $fieldAttributes['custom'][$phpKey][$phpLine] = $this->setDynamicValues(ComponentbuilderHelper::openValidBase64($value)); + } + } + } + } // do some nice twigs beyond the default if (isset($fieldAttributes['name'])) { @@ -2460,7 +2482,7 @@ class Fields extends Structure } } // set list switch - $listSwitch = (isset($field['list']) && $field['list'] == 1); + $listSwitch = (isset($field['list']) && ($field['list'] == 1 || $field['list'] == 3 || $field['list'] == 4 )); // set list join $listJoin = (isset($this->listJoinBuilder[$view_name_list][(int) $field['field']])); // add history to this view @@ -2523,7 +2545,8 @@ class Fields extends Structure 'sort' => (isset($field['sort']) && $field['sort']) ? true : false, 'custom' => $custom, 'multiple' => $multiple, - 'options' => $options); + 'options' => $options, + 'target' => (int) $field['list']); } // build custom builder list if ($listSwitch || $listJoin) diff --git a/admin/helpers/compiler/e_Interpretation.php b/admin/helpers/compiler/e_Interpretation.php index d496e21a2..53191cb53 100644 --- a/admin/helpers/compiler/e_Interpretation.php +++ b/admin/helpers/compiler/e_Interpretation.php @@ -4554,6 +4554,9 @@ class Interpretation extends Fields public function setMethodItemSave(&$view) { $script = ''; + // get component name + $Component = $this->fileContentStatic[$this->hhh . 'Component' . $this->hhh]; + $component = $this->fileContentStatic[$this->hhh . 'component' . $this->hhh]; // check if there was script added before modeling of data $script .= $this->getCustomScriptBuilder('php_before_save', $view, PHP_EOL . PHP_EOL); // turn array into JSON string @@ -4568,7 +4571,22 @@ class Interpretation extends Fields $script .= PHP_EOL . $this->_t(3) . "\$" . $jsonItem . "->loadArray(\$data['" . $jsonItem . "']);"; $script .= PHP_EOL . $this->_t(3) . "\$data['" . $jsonItem . "'] = (string) \$" . $jsonItem . ";"; $script .= PHP_EOL . $this->_t(2) . "}"; - $script .= PHP_EOL . $this->_t(2) . "elseif (!isset(\$data['" . $jsonItem . "']))"; + if (isset($this->permissionFields[$view]) && isset($this->permissionFields[$view][$jsonItem]) && ComponentbuilderHelper::checkArray($this->permissionFields[$view][$jsonItem])) + { + $script .= PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) . " Also check permission since the value may be removed due to permissions"; + $script .= PHP_EOL . $this->_t(2) . "//" . $this->setLine(__LINE__) . " Then we do not want to clear it out, but simple ignore the empty " . $jsonItem; + $script .= PHP_EOL . $this->_t(2) . "elseif (!isset(\$data['" . $jsonItem . "'])"; + // only add permission that are available + foreach ($this->permissionFields[$view][$jsonItem] as $permission_option => $fieldType) + { + $script .= PHP_EOL . $this->_t(3) . "&& JFactory::getUser()->authorise('" . $view . "." . $permission_option . "." . $jsonItem . "', 'com_" . $component . "')"; + } + $script .= ")"; + } + else + { + $script .= PHP_EOL . $this->_t(2) . "elseif (!isset(\$data['" . $jsonItem . "']))"; + } $script .= PHP_EOL . $this->_t(2) . "{"; $script .= PHP_EOL . $this->_t(3) . "//" . $this->setLine(__LINE__) . " Set the empty " . $jsonItem . " to data"; $script .= PHP_EOL . $this->_t(3) . "\$data['" . $jsonItem . "'] = '';"; @@ -4600,7 +4618,6 @@ class Interpretation extends Fields } } // turn string into encrypted string - $Component = $this->fileContentStatic[$this->hhh . 'Component' . $this->hhh]; foreach ($this->cryptionTypes as $cryptionType) { if (isset($this->{$cryptionType . 'EncryptionBuilder'}[$view]) && ComponentbuilderHelper::checkArray($this->{$cryptionType . 'EncryptionBuilder'}[$view])) @@ -6759,25 +6776,29 @@ class Interpretation extends Fields // start adding the dynamic foreach ($this->listBuilder[$viewName_list] as $item) { - // set some defaults - $customAdminViewButtons = ''; - // set the item default class - $itemClass = 'hidden-phone'; - // set the item row - $itemRow = $this->getListItemBuilder($item, $viewName_single, $viewName_list, $itemClass, $doNotEscape, $coreLoad, $core); - // check if buttons was aready added - if ($firstTimeBeingAdded) // TODO we must improve this to allow more items to be targeted instead of just the first item :) + // check if target is admin list + if (1 == $item['target'] || 3 == $item['target']) { - // get custom admin view buttons - $customAdminViewButtons = $this->getCustomAdminViewButtons($viewName_list); - // make sure the custom admin view buttons are only added once - $firstTimeBeingAdded = false; + // set some defaults + $customAdminViewButtons = ''; + // set the item default class + $itemClass = 'hidden-phone'; + // set the item row + $itemRow = $this->getListItemBuilder($item, $viewName_single, $viewName_list, $itemClass, $doNotEscape, $coreLoad, $core); + // check if buttons was aready added + if ($firstTimeBeingAdded) // TODO we must improve this to allow more items to be targeted instead of just the first item :) + { + // get custom admin view buttons + $customAdminViewButtons = $this->getCustomAdminViewButtons($viewName_list); + // make sure the custom admin view buttons are only added once + $firstTimeBeingAdded = false; + } + // add row to body + $body .= PHP_EOL . $this->_t(2) . "getListFieldClass($item['code'], $viewName_list, $itemClass) . "\">"; + $body .= $itemRow; + $body .= $customAdminViewButtons; + $body .= PHP_EOL . $this->_t(2) . ""; } - // add row to body - $body .= PHP_EOL . $this->_t(2) . "getListFieldClass($item['code'], $viewName_list, $itemClass) . "\">"; - $body .= $itemRow; - $body .= $customAdminViewButtons; - $body .= PHP_EOL . $this->_t(2) . ""; } // add the defaults if (!isset($this->fieldsNames[$viewName_single]['published'])) @@ -7253,30 +7274,34 @@ class Interpretation extends Fields // build the dynamic fields foreach ($this->listBuilder[$viewName_list] as $item) { - // check if we have an over-ride - if (isset($this->listHeadOverRide[$viewName_list]) && ComponentbuilderHelper::checkArray($this->listHeadOverRide[$viewName_list]) && isset($this->listHeadOverRide[$viewName_list][$item['id']])) + // check if target is admin list + if (1 == $item['target'] || 3 == $item['target']) { - $item['lang'] = $this->listHeadOverRide[$viewName_list][$item['id']]; + // check if we have an over-ride + if (isset($this->listHeadOverRide[$viewName_list]) && ComponentbuilderHelper::checkArray($this->listHeadOverRide[$viewName_list]) && isset($this->listHeadOverRide[$viewName_list][$item['id']])) + { + $item['lang'] = $this->listHeadOverRide[$viewName_list][$item['id']]; + } + // set the custom code + if (ComponentbuilderHelper::checkArray($item['custom'])) + { + $item['code'] = $item['code'] . '_' . $item['custom']['text']; + } + $class = 'nowrap hidden-phone'; + if ($item['link']) + { + $class = 'nowrap'; + } + $title = ""; + if ($item['sort']) + { + $title = "listDirn, \$this->listOrder); ?>"; + } + $head .= PHP_EOL . $this->_t(1) . ''; + $head .= PHP_EOL . $this->_t(3) . $title; + $head .= PHP_EOL . $this->_t(1) . ""; + $this->listColnrBuilder[$viewName_list] ++; } - // set the custom code - if (ComponentbuilderHelper::checkArray($item['custom'])) - { - $item['code'] = $item['code'] . '_' . $item['custom']['text']; - } - $class = 'nowrap hidden-phone'; - if ($item['link']) - { - $class = 'nowrap'; - } - $title = ""; - if ($item['sort']) - { - $title = "listDirn, \$this->listOrder); ?>"; - } - $head .= PHP_EOL . $this->_t(1) . ''; - $head .= PHP_EOL . $this->_t(3) . $title; - $head .= PHP_EOL . $this->_t(1) . ""; - $this->listColnrBuilder[$viewName_list] ++; } // set default if (!isset($this->fieldsNames[$viewName_single]['published'])) @@ -8212,27 +8237,31 @@ class Interpretation extends Fields // start adding the dynamic foreach ($this->listBuilder[$viewName_list] as $item) { - // set the ref - $ref = ''; - // set some defaults - $customAdminViewButtons = ''; - // set the item row - $itemRow = $this->getListItemBuilder($item, $viewName_single, $viewName_list, $itemClass, $doNotEscape, $coreLoad, $core, false, $ref, '$displayData->escape', '$user', $refview); - // check if buttons was aready added - if ($firstTimeBeingAdded) // TODO we must improve this to allow more items to be targeted instead of just the first item :) + // check if target is linked list view + if (1 == $item['target'] || 4 == $item['target']) { - // get custom admin view buttons - $customAdminViewButtons = $this->getCustomAdminViewButtons($viewName_list, $ref); - // make sure the custom admin view buttons are only added once - $firstTimeBeingAdded = false; + // set the ref + $ref = ''; + // set some defaults + $customAdminViewButtons = ''; + // set the item row + $itemRow = $this->getListItemBuilder($item, $viewName_single, $viewName_list, $itemClass, $doNotEscape, $coreLoad, $core, false, $ref, '$displayData->escape', '$user', $refview); + // check if buttons was aready added + if ($firstTimeBeingAdded) // TODO we must improve this to allow more items to be targeted instead of just the first item :) + { + // get custom admin view buttons + $customAdminViewButtons = $this->getCustomAdminViewButtons($viewName_list, $ref); + // make sure the custom admin view buttons are only added once + $firstTimeBeingAdded = false; + } + // add row to body + $body .= PHP_EOL . $this->_t(2) . ""; + $body .= $itemRow; + $body .= $customAdminViewButtons; + $body .= PHP_EOL . $this->_t(2) . ""; + // increment counter + $counter++; } - // add row to body - $body .= PHP_EOL . $this->_t(2) . ""; - $body .= $itemRow; - $body .= $customAdminViewButtons; - $body .= PHP_EOL . $this->_t(2) . ""; - // increment counter - $counter++; } $counter = $counter + 2; $data_value = (3 == $this->footableVersion) ? 'data-sort-value' : 'data-value'; @@ -8397,31 +8426,35 @@ class Interpretation extends Fields // build the dynamic fields foreach ($this->listBuilder[$viewName_list] as $item) { - // check if we have an over-ride - if (isset($this->listHeadOverRide[$viewName_list]) && ComponentbuilderHelper::checkArray($this->listHeadOverRide[$viewName_list]) && isset($this->listHeadOverRide[$viewName_list][$item['id']])) + // check if target is linked list view + if (1 == $item['target'] || 4 == $item['target']) { - $item['lang'] = $this->listHeadOverRide[$viewName_list][$item['id']]; - } - $setin = (2 == $this->footableVersion) ? ' data-hide="phone"' : ' data-breakpoints="xs sm"'; - if ($controller > 3) - { - $setin = (2 == $this->footableVersion) ? ' data-hide="phone,tablet"' : ' data-breakpoints="xs sm md"'; - } + // check if we have an over-ride + if (isset($this->listHeadOverRide[$viewName_list]) && ComponentbuilderHelper::checkArray($this->listHeadOverRide[$viewName_list]) && isset($this->listHeadOverRide[$viewName_list][$item['id']])) + { + $item['lang'] = $this->listHeadOverRide[$viewName_list][$item['id']]; + } + $setin = (2 == $this->footableVersion) ? ' data-hide="phone"' : ' data-breakpoints="xs sm"'; + if ($controller > 3) + { + $setin = (2 == $this->footableVersion) ? ' data-hide="phone,tablet"' : ' data-breakpoints="xs sm md"'; + } - if ($controller > 6) - { - $setin = (2 == $this->footableVersion) ? ' data-hide="all"' : ' data-breakpoints="all"'; - } + if ($controller > 6) + { + $setin = (2 == $this->footableVersion) ? ' data-hide="all"' : ' data-breakpoints="all"'; + } - if ($item['link'] && $firstLink) - { - $setin = (2 == $this->footableVersion) ? ' data-toggle="true"' : ''; - $firstLink = false; + if ($item['link'] && $firstLink) + { + $setin = (2 == $this->footableVersion) ? ' data-toggle="true"' : ''; + $firstLink = false; + } + $head .= PHP_EOL . $this->_t(2) . ""; + $head .= PHP_EOL . $this->_t(3) . ""; + $head .= PHP_EOL . $this->_t(2) . ""; + $controller++; } - $head .= PHP_EOL . $this->_t(2) . ""; - $head .= PHP_EOL . $this->_t(3) . ""; - $head .= PHP_EOL . $this->_t(2) . ""; - $controller++; } // set some V3 attr $data_hide = (2 == $this->footableVersion) ? 'data-hide="phone,tablet"' : 'data-breakpoints="xs sm md"'; @@ -11284,6 +11317,19 @@ class Interpretation extends Fields $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) . " Disable fields while saving."; $allow[] = $this->_t(3) . "\$form->setFieldAttribute('created', 'filter', 'unset');"; $allow[] = $this->_t(2) . "}"; + // check if the item has access permissions. + if ($coreLoad && isset($core['core.edit.access']) && isset($this->permissionBuilder[$core['core.edit.access']]) && ComponentbuilderHelper::checkArray($this->permissionBuilder[$core['core.edit.access']]) && in_array($viewName_single, $this->permissionBuilder[$core['core.edit.access']])) + { + $allow[] = $this->_t(2) . "//" . $this->setLine(__LINE__) . " Modify the form based on Edit Access 'access' controls."; + $allow[] = $this->_t(2) . "if (\$id != 0 && (!\$user->authorise('" . $core['core.edit.access'] . "', 'com_" . $component . "." . $viewName_single . ".' . (int) \$id))"; + $allow[] = $this->_t(3) . "|| (\$id == 0 && !\$user->authorise('" . $core['core.edit.access'] . "', 'com_" . $component . "')))"; + $allow[] = $this->_t(2) . "{"; + $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) . " Disable fields for display."; + $allow[] = $this->_t(3) . "\$form->setFieldAttribute('access', 'disabled', 'true');"; + $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) . " Disable fields while saving."; + $allow[] = $this->_t(3) . "\$form->setFieldAttribute('access', 'filter', 'unset');"; + $allow[] = $this->_t(2) . "}"; + } // handel the fields permissions if (isset($this->permissionFields[$viewName_single]) && ComponentbuilderHelper::checkArray($this->permissionFields[$viewName_single])) { @@ -11382,12 +11428,21 @@ class Interpretation extends Fields $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) . " Make the field hidded."; $allow[] = $this->_t(3) . "\$form->setFieldAttribute('" . $fieldName . "', 'type', 'hidden');"; $allow[] = $this->_t(3) . "//" . $this->setLine(__LINE__) . " If there is no value continue."; - $allow[] = $this->_t(3) . "if (!\$form->getValue('" . $fieldName . "'))"; + $allow[] = $this->_t(3) . "if (!(\$val = \$form->getValue('" . $fieldName . "')))"; $allow[] = $this->_t(3) . "{"; $allow[] = $this->_t(4) . "//" . $this->setLine(__LINE__) . " Disable fields while saving."; $allow[] = $this->_t(4) . "\$form->setFieldAttribute('" . $fieldName . "', 'filter', 'unset');"; $allow[] = $this->_t(4) . "//" . $this->setLine(__LINE__) . " Disable fields while saving."; $allow[] = $this->_t(4) . "\$form->setFieldAttribute('" . $fieldName . "', 'required', 'false');"; + $allow[] = $this->_t(4) . "//" . $this->setLine(__LINE__) . " Make sure"; + $allow[] = $this->_t(4) . "\$form->setValue('" . $fieldName . "', null, '');"; + $allow[] = $this->_t(3) . "}"; + $allow[] = $this->_t(3) . "elseif (" . ucfirst($component) . "Helper::checkArray(\$val))"; + $allow[] = $this->_t(3) . "{"; + $allow[] = $this->_t(4) . "//" . $this->setLine(__LINE__) . " We have to unset then (TODO)"; + $allow[] = $this->_t(4) . "//" . $this->setLine(__LINE__) . " Hiddend field can not handel array value"; + $allow[] = $this->_t(4) . "//" . $this->setLine(__LINE__) . " Even if we conver to json we get an error"; + $allow[] = $this->_t(4) . "\$form->removeField('" . $fieldName . "');"; $allow[] = $this->_t(3) . "}"; $allow[] = $this->_t(2) . "}"; } @@ -12336,6 +12391,8 @@ class Interpretation extends Fields // JSON_ARRAY_ENCODE $decode = 'json_decode'; $suffix_decode = ', true'; + // fallback on json + $item['method'] = 1; break; } @@ -12486,7 +12543,7 @@ class Interpretation extends Fields { if (!$export) { - // For thos we have not cached yet. + // For those we have not cached yet. $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "//" . $this->setLine(__LINE__) . " convert " . $item['name']; $fix .= PHP_EOL . $this->_t(1) . $tab . $this->_t(3) . "\$item->" . $item['name'] . " = " . $Component . "Helper::jsonToString(\$item->" . $item['name'] . ");"; } @@ -15469,7 +15526,7 @@ function vdm_dkim() { // set the permission for this field $fieldView['action'] = 'view.' . $permission_option . '.' . $fieldName; $fieldView['implementation'] = '3'; - // check if persmissions was laready set + // check if persmissions was already set if (isset($view['settings']->permissions) && ComponentbuilderHelper::checkArray($view['settings']->permissions)) { array_push($view['settings']->permissions, $fieldView); @@ -15600,6 +15657,7 @@ function vdm_dkim() { $view['settings']->permissions[] = $versionView; } } + // add batch permissions if ($type === 'admin') { // set batch control @@ -15615,6 +15673,7 @@ function vdm_dkim() { $view['settings']->permissions[] = $batchView; } } + // load the permissions foreach ($view['settings']->permissions as $permission) { // set acction name @@ -15639,6 +15698,12 @@ function vdm_dkim() { array_shift($actionNameBuilder); $nameBuilder = trim(implode('___', $actionNameBuilder)); $customName = trim(implode(' ', $actionNameBuilder)); + // check if we have access set for this view (if not skip) + if ($nameBuilder === 'edit___access' && $type === 'admin' && (!isset($view['access']) || $view['access'] != 1)) + { + continue; + } + // build the names if ($type === 'admin') { $W_NameList = ComponentbuilderHelper::safeString($view['settings']->name_list, 'W'); @@ -15666,6 +15731,12 @@ function vdm_dkim() { // set edit description $permission['description'] = ' Allows the users in this group to edit ' . $w_NameList . ' created by them'; break; + case 'edit___access': + // set edit title + $permission['title'] = $W_NameList . ' Edit Access'; + // set edit description + $permission['description'] = ' Allows the users in this group to change the access of the ' . $w_NameList; + break; case 'edit___state': // set edit title $permission['title'] = $W_NameList . ' Edit State'; diff --git a/admin/helpers/componentbuilder.php b/admin/helpers/componentbuilder.php index ae86abcb3..10b829abc 100644 --- a/admin/helpers/componentbuilder.php +++ b/admin/helpers/componentbuilder.php @@ -28,135 +28,50 @@ abstract class ComponentbuilderHelper } /** - * Locked Libraries (we can not have these change) + * Locked Libraries (we can not have these change) **/ public static $libraryNames = array(1 => 'No Library', 2 => 'Bootstrap v4', 3 => 'Uikit v3', 4 => 'Uikit v2', 5 => 'FooTable v2', 6 => 'FooTable v3'); /** - * Array of php fields Allowed (16) + * Array of php fields Allowed (16) **/ public static $phpFieldArray = array('', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'x'); /** - * The global params + * The global params **/ protected static $params = false; /** - * The global updater + * The global updater **/ protected static $globalUpdater = array(); /** - * The local company details + * The local company details **/ protected static $localCompany = array(); /** - * The snippet paths + * The snippet paths **/ public static $snippetPath = 'https://raw.githubusercontent.com/vdm-io/Joomla-Component-Builder-Snippets/master/'; public static $snippetsPath = 'https://api.github.com/repos/vdm-io/Joomla-Component-Builder-Snippets/git/trees/master'; /** - * The VDM packages paths + * The VDM packages paths **/ public static $vdmGithubPackagesUrl = "https://api.github.com/repos/vdm-io/JCB-Packages/git/trees/master"; public static $vdmGithubPackageUrl = "https://github.com/vdm-io/JCB-Packages/raw/master/"; /** - * The JCB packages paths + * The JCB packages paths **/ public static $jcbGithubPackagesUrl = "https://api.github.com/repos/vdm-io/JCB-Community-Packages/git/trees/master"; public static $jcbGithubPackageUrl = "https://github.com/vdm-io/JCB-Community-Packages/raw/master/"; // not needed at this time (maybe latter) public static $accessToken = ""; - - /** - * get the github repo file list - * - * @return array on success - * - */ - public static function getGithubRepoFileList($type, $target) - { - // get the current Packages (public) - if (!$repoData = self::get($type)) - { - if (self::urlExists($target)) - { - $repoData = self::getFileContents($target); - if (self::checkJson($repoData)) - { - $test = json_decode($repoData); - if (self::checkObject($test) && isset($test->tree) && self::checkArray($test->tree) ) - { - // remember to set it - self::set($type, $repoData); - } - // check if we have error message from github - elseif ($errorMessage = self::githubErrorHandeler(array('error' => null), $test)) - { - if (self::checkString($errorMessage['error'])) - { - JFactory::getApplication()->enqueueMessage($errorMessage['error'], 'Error'); - } - $repoData = false; - } - } - else - { - $repoData = false; - } - } - else - { - JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_URL_S_SET_TO_RETRIEVE_THE_PACKAGES_DOES_NOT_EXIST', $target), 'Error'); - } - } - // check if we could find packages - if (isset($repoData) && self::checkJson($repoData)) - { - $repoData = json_decode($repoData); - if (self::checkObject($repoData) && isset($repoData->tree) && self::checkArray($repoData->tree) ) - { - return $repoData->tree; - } - } - return false; - } - - /** - * get the github error messages - * - * @return array of errors on success - * - */ - protected static function githubErrorHandeler($message, &$github) - { - if (self::checkObject($github) && isset($github->message) && self::checkString($github->message)) - { - // set the message - $errorMessage = $github->message; - // add the documentation URL - if (isset($github->documentation_url) && self::checkString($github->documentation_url)) - { - $errorMessage = $errorMessage.'
'.$github->documentation_url; - } - // check the message - if (strpos($errorMessage, 'Authenticated') !== false) - { - // add little more help if it is an access token issue - $errorMessage = JText::sprintf('COM_COMPONENTBUILDER_SBR_YOU_CAN_ADD_AN_BACCESS_TOKENB_TO_GETBIBLE_GLOBAL_OPTIONS_TO_MAKE_AUTHENTICATED_REQUESTS_AN_ACCESS_TOKEN_WITH_ONLY_PUBLIC_ACCESS_WILL_DO', $errorMessage); - } - // set error notice - $message['error'] = $errorMessage; - // we have error message - return $message; - } - return false; - } /** * The array of constant paths @@ -581,72 +496,6 @@ abstract class ComponentbuilderHelper // load this for all jimport('joomla.application'); } - - /** - * Remove folders with files - * - * @param string $dir The path to folder to remove - * @param boolean $ignore The folders and files to ignore and not remove - * - * @return boolean True in all is removed - * - */ - public static function removeFolder($dir, $ignore = false) - { - if (JFolder::exists($dir)) - { - $it = new RecursiveDirectoryIterator($dir); - $it = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST); - foreach ($it as $file) - { - if ('.' === $file->getBasename() || '..' === $file->getBasename()) continue; - if ($file->isDir()) - { - $keeper = false; - if (self::checkArray($ignore)) - { - foreach ($ignore as $keep) - { - if (strpos($file->getPathname(), $dir.'/'.$keep) !== false) - { - $keeper = true; - } - } - } - if ($keeper) - { - continue; - } - JFolder::delete($file->getPathname()); - } - else - { - $keeper = false; - if (self::checkArray($ignore)) - { - foreach ($ignore as $keep) - { - if (strpos($file->getPathname(), $dir.'/'.$keep) !== false) - { - $keeper = true; - } - } - } - if ($keeper) - { - continue; - } - JFile::delete($file->getPathname()); - } - } - if (!self::checkArray($ignore)) - { - return JFolder::delete($dir); - } - return true; - } - return false; - } /** * The dynamic builder of views, tables and fields @@ -656,203 +505,6 @@ abstract class ComponentbuilderHelper self::autoLoader('extrusion'); $extruder = new Extrusion($data); } - - public static function getFieldOptions($value, $type, $settings = array(), $xml = null) - { - // Get a db connection. - $db = JFactory::getDbo(); - - // Create a new query object. - $query = $db->getQuery(true); - $query->select($db->quoteName(array('properties', 'short_description', 'description'))); - $query->from($db->quoteName('#__componentbuilder_fieldtype')); - $query->where($db->quoteName('published') . ' = 1'); - $query->where($db->quoteName($type) . ' = '. $value); - - // Reset the query using our newly populated query object. - $db->setQuery($query); - $db->execute(); - if ($db->getNumRows()) - { - $result = $db->loadObject(); - $properties = json_decode($result->properties, true); - $field = array( - 'subform' => array(), - 'nameListOptions' => array(), - 'php' => array(), - 'values' => " '', - 'short_description' => $result->short_description, - 'description' => $result->description); - // number pointer - $nr = 0; - // value to check since there are false and null values even 0 in the values returned - $confirmation = '8qvZHoyuFYQqpj0YQbc6F3o5DhBlmS-_-a8pmCZfOVSfANjkmV5LG8pCdAY2JNYu6cB'; - // set the headers - $field['values_description'] .= ''; - foreach ($properties as $property) - { - $example = (isset($property['example']) && self::checkString($property['example'])) ? $property['example'] : ''; - $field['values_description'] .= ''; - // check if we should load the value - $value = self::getValueFromXMLstring($xml, $property['name'], $confirmation); - // check if this is a php field - $addPHP = false; - if (strpos($property['name'], 'type_php') !== false) - { - $addPHP = true; - $phpKey = trim(preg_replace('/[0-9]+/', '', $property['name']), '_'); - // start array if not already set - if (!isset($field['php'][$phpKey])) - { - $field['php'][$phpKey] = array(); - $field['php'][$phpKey]['value'] = array(); - $field['php'][$phpKey]['desc'] = $property['description']; - } - } - // was the settings for the property passed - if(self::checkArray($settings) && isset($settings[$property['name']])) - { - // add the xml values - $field['values'] .= PHP_EOL . "\t" . $property['name'] . '="'. $settings[$property['name']] . '" '; - // add the json values - if ($addPHP) - { - $field['php'][$phpKey]['value'][] = $settings[$property['name']]; - } - else - { - $field['subform']['properties'.$nr] = array('name' => $property['name'], 'value' => $settings[$property['name']], 'desc' => $property['description']); - } - } - elseif (!$xml || $confirmation !== $value) - { - // add the xml values - $field['values'] .= PHP_EOL."\t" . $property['name'] . '="' . ($confirmation !== $value) ? $value : $example .'" '; - // add the json values - if ($addPHP) - { - $field['php'][$phpKey]['value'][] = ($confirmation !== $value) ? $value : $example; - } - else - { - $field['subform']['properties' . $nr] = array('name' => $property['name'], 'value' => ($confirmation !== $value) ? $value : $example, 'desc' => $property['description']); - } - } - // add the name List Options - if (!$addPHP) - { - $field['nameListOptions'][$property['name']] = $property['name']; - } - // increment the number - $nr++; - } - $field['values'] .= PHP_EOL . "/>"; - $field['values_description'] .= '
' . JText::_('COM_COMPONENTBUILDER_PROPERTY') . '' . JText::_('COM_COMPONENTBUILDER_EXAMPLE') . '' . JText::_('COM_COMPONENTBUILDER_DESCRIPTION') . '
' . $property['name'] . '' . $example . '' . $property['description'] . '
'; - // return found field options - return $field; - } - return false; - } - - public static function getValueFromXMLstring(&$xml, &$get, $confirmation = '') - { - if (self::checkString($xml)) - { - // if we have a PHP value, we must base64 decode it - if (strpos($get, 'type_php') !== false) - { - return self::openValidBase64(self::getBetween($xml, $get.'="', '"', $confirmation)); - } - return self::getBetween($xml, $get . '="', '"', $confirmation); - } - return $confirmation; - } - - - /** - * The zipper method - * - * @param string $workingDIR The directory where the items must be zipped - * @param string $filepath The path to where the zip file must be placed - * - * @return bool true On success - * - */ - public static function zip($workingDIR, &$filepath) - { - // store the current joomla working directory - $joomla = getcwd(); - - // we are changing the working directory to the component temp folder - chdir($workingDIR); - - // the full file path of the zip file - $filepath = JPath::clean($filepath); - - // delete an existing zip file (or use an exclusion parameter in JFolder::files() - JFile::delete($filepath); - - // get a list of files in the current directory tree - $files = JFolder::files('.', '', true, true); - $zipArray = array(); - // setup the zip array - foreach ($files as $file) - { - $tmp = array(); - $tmp['name'] = str_replace('./', '', $file); - $tmp['data'] = JFile::read($file); - $tmp['time'] = filemtime($file); - $zipArray[] = $tmp; - } - - // change back to joomla working directory - chdir($joomla); - - // get the zip adapter - $zip = JArchive::getAdapter('zip'); - - //create the zip file - if ($zip->create($filepath, $zipArray)) - { - return true; - } - return false; - } - - - /** - * Write a file to the server - * - * @param string $path The path and file name where to safe the data - * @param string $data The data to safe - * - * @return bool true On success - * - */ - public static function writeFile($path, $data) - { - $klaar = false; - if (self::checkString($data)) - { - // open the file - $fh = fopen($path, "w"); - if (!is_resource($fh)) - { - return $klaar; - } - // write to the file - if (fwrite($fh, $data)) - { - // has been done - $klaar = true; - } - // close file. - fclose($fh); - } - return $klaar; - } - /* * Convert repeatable field to subform @@ -965,6 +617,880 @@ abstract class ComponentbuilderHelper } return $object; } + + /** + * Run Global Updater if any are set + * + * @return void + * + */ + public static function runGlobalUpdater() + { + // check if any updates are set to run + if (self::checkArray(self::$globalUpdater)) + { + // get the database object + $db = JFactory::getDbo(); + foreach (self::$globalUpdater as $tableKeyID => $object) + { + // get the table + $table = explode('.', $tableKeyID); + // update the item + $db->updateObject('#__componentbuilder_' . (string) $table[0] , $object, (string) $table[1]); + } + // rest updater + self::$globalUpdater = array(); + } + } + + /** + * Copy Any Item (only use for direct database copying) + * + * @param int $id The item to copy + * @param string $table The table and model to copy from and with + * @param array $config The values that should change + * + * @return boolean True if success + * + */ + public static function copyItem($id, $type, $config = array()) + { + // only continue if we have an id + if ((int) $id > 0) + { + // get the model + $model = self::getModel($type); + $app = \JFactory::getApplication(); + // get item + if ($item = $model->getItem($id)) + { + // update values that should change + if (self::checkArray($config)) + { + foreach($config as $key => $value) + { + if (isset($item->{$key})) + { + $item->{$key} = $value; + } + } + } + // clone the object + $data = array(); + foreach ($item as $key => $value) + { + $data[$key] = $value; + } + // reset some values + $data['id'] = 0; + $data['version'] = 1; + if (isset($data['tags'])) + { + $data['tags'] = null; + } + if (isset($data['associations'])) + { + $data['associations'] = array(); + } + // remove some unneeded values + unset($data['params']); + unset($data['asset_id']); + unset($data['checked_out']); + unset($data['checked_out_time']); + // Attempt to save the data. + if ($model->save($data)) + { + return true; + } + } + } + return false; + } + + /** + * the basic localkey + **/ + protected static $localkey = false; + + /** + * get the localkey + **/ + public static function getLocalKey() + { + if (!self::$localkey) + { + // get the basic key + self::$localkey = md5(self::getCryptKey('basic', 'localKey34fdWEkl')); + } + return self::$localkey; + } + + /** + * indent HTML + */ + public static function indent($html) + { + // load the class + require_once JPATH_ADMINISTRATOR.'/components/com_componentbuilder/helpers/indenter.php'; + // set new indenter + $indenter = new Indenter(); + // return indented html + return $indenter->indent($html); + } + + public static function checkFileType($file, $sufix) + { + // now check if the file ends with the sufix + return $sufix === "" || ($sufix == substr(strrchr($file, "."), -strlen($sufix))); + } + + public static function imageInfo($path, $request = 'type') + { + // set image + $image = JPATH_SITE.'/'.$path; + // check if exists + if (file_exists($image) && $result = @getimagesize($image)) + { + // return type request + switch ($request) + { + case 'width': + return $result[0]; + break; + case 'height': + return $result[1]; + break; + case 'type': + $extensions = array( + IMAGETYPE_GIF => "gif", + IMAGETYPE_JPEG => "jpg", + IMAGETYPE_PNG => "png", + IMAGETYPE_SWF => "swf", + IMAGETYPE_PSD => "psd", + IMAGETYPE_BMP => "bmp", + IMAGETYPE_TIFF_II => "tiff", + IMAGETYPE_TIFF_MM => "tiff", + IMAGETYPE_JPC => "jpc", + IMAGETYPE_JP2 => "jp2", + IMAGETYPE_JPX => "jpx", + IMAGETYPE_JB2 => "jb2", + IMAGETYPE_SWC => "swc", + IMAGETYPE_IFF => "iff", + IMAGETYPE_WBMP => "wbmp", + IMAGETYPE_XBM => "xbm", + IMAGETYPE_ICO => "ico" + ); + return $extensions[$result[2]]; + break; + case 'attr': + return $result[3]; + break; + case 'all': + default: + return $result; + break; + } + } + return false; + } + + /** + * set the session defaults if not set + **/ + protected static function setSessionDefaults() + { + // noting for now + return true; + } + + /** + * check if it is a new hash + **/ + public static function newHash($hash, $name = 'backup', $type = 'hash', $key = '', $fileType = 'txt') + { + // make sure we have a hash + if (self::checkString($hash)) + { + // first get the file path + $path_filename = self::getFilePath('path', $name.$type, $fileType, $key, JPATH_COMPONENT_ADMINISTRATOR); + // set as read if not already set + if ($content = self::getFileContents($path_filename, false)) + { + if ($hash == $content) + { + return false; + } + } + // set the hash + return self::writeFile($path_filename, $hash); + } + return false; + } + + protected static $pkOwnerSearch = array( + 'company' => 'COM_COMPONENTBUILDER_DTCOMPANYDTDDSDD', + 'owner' => 'COM_COMPONENTBUILDER_DTOWNERDTDDSDD', + 'email' => 'COM_COMPONENTBUILDER_DTEMAILDTDDSDD', + 'website' => 'COM_COMPONENTBUILDER_DTWEBSITEDTDDSDD', + 'license' => 'COM_COMPONENTBUILDER_DTLICENSEDTDDSDD', + 'copyright' => 'COM_COMPONENTBUILDER_DTCOPYRIGHTDTDDSDD' + ); + + /** + * get the JCB package owner details display + **/ + public static function getPackageOwnerDetailsDisplay(&$info, $trust = false) + { + $hasOwner = false; + $ownerDetails = ''; + $ownerDetails .= '
'; + // load the list items + foreach (self::$pkOwnerSearch as $key => $dd) + { + if ($value = self::getPackageOwnerValue($key, $info)) + { + $ownerDetails .= JText::sprintf($dd, $value); + // check if we have a owner/source name + if (('owner' === $key || 'company' === $key) && !$hasOwner) + { + $hasOwner = true; + $owner = $value; + } + } + } + $ownerDetails .= '
'; + + // provide some details to how the user can get a key + if ($hasOwner && isset($info['getKeyFrom']['buy_link']) && self::checkString($info['getKeyFrom']['buy_link'])) + { + $ownerDetails .= '
'; + $ownerDetails .= JText::sprintf('COM_COMPONENTBUILDER_BGET_THE_KEY_FROMB_A_SSA', 'class="btn btn-primary" href="'.$info['getKeyFrom']['buy_link'].'" target="_blank" title="get a key from '.$owner.'"', $owner); + } + // add more custom links + elseif ($hasOwner && isset($info['getKeyFrom']['buy_links']) && self::checkArray($info['getKeyFrom']['buy_links'])) + { + $buttons = array(); + foreach ($info['getKeyFrom']['buy_links'] as $keyName => $link) + { + $buttons[] = JText::sprintf('COM_COMPONENTBUILDER_BGET_THE_KEY_FROM_SB_FOR_A_SSA', $owner, 'class="btn btn-primary" href="'.$link.'" target="_blank" title="get a key from '.$owner.'"', $keyName); + } + $ownerDetails .= '
'; + $ownerDetails .= implode('
', $buttons); + } + // return the owner details + if (!$hasOwner) + { + $ownerDetails = '

' . JText::_('COM_COMPONENTBUILDER_PACKAGE_OWNER_DETAILS_NOT_FOUND') . '

'; + if (!$trust) + { + $ownerDetails .= '

' . JText::_('COM_COMPONENTBUILDER_BE_CAUTIOUS_DO_NOT_CONTINUE_UNLESS_YOU_TRUST_THE_ORIGIN_OF_THIS_PACKAGE') . '

'; + } + } + return '
'.$ownerDetails.'
'; + } + + public static function getPackageOwnerValue($key, &$info) + { + $source = (isset($info['source']) && isset($info['source'][$key])) ? 'source' : ((isset($info['getKeyFrom']) && isset($info['getKeyFrom'][$key])) ? 'getKeyFrom' : false); + if ($source && self::checkString($info[$source][$key])) + { + return $info[$source][$key]; + } + return false; + } + + /** + * get the JCB package component key status + **/ + public static function getPackageComponentsKeyStatus(&$info) + { + // check the package key status + if (!isset($info['key'])) + { + if (isset($info['getKeyFrom']) && isset($info['getKeyFrom']['owner'])) + { + // this just confirms it for older packages + $info['key'] = true; + } + else + { + // this just confirms it for older packages + $info['key'] = false; + } + } + return $info['key']; + } + + protected static $compOwnerSearch = array( + 'ul' => array ( + 'companyname' => 'COM_COMPONENTBUILDER_ICOMPANYI_BSB', + 'author' => 'COM_COMPONENTBUILDER_IAUTHORI_BSB', + 'email' => 'COM_COMPONENTBUILDER_IEMAILI_BSB', + 'website' => 'COM_COMPONENTBUILDER_IWEBSITEI_BSB', + ), + 'other' => array( + 'license' => 'COM_COMPONENTBUILDER_HFOUR_CLASSNAVHEADERLICENSEHFOURPSP', + 'copyright' => 'COM_COMPONENTBUILDER_HFOUR_CLASSNAVHEADERCOPYRIGHTHFOURPSP' + ) + ); + + /** + * get the JCB package component details display + **/ + public static function getPackageComponentsDetailsDisplay(&$info) + { + // check if these components need a key + $needKey = self::getPackageComponentsKeyStatus($info); + if (isset($info['name']) && self::checkArray($info['name'])) + { + $cAmount = count((array) $info['name']); + $class2 = ($cAmount == 1) ? 'span12' : 'span6'; + $counter = 1; + $display = array(); + foreach ($info['name'] as $key => $value) + { + // set the name + $name= $value . ' v' . $info['component_version'][$key]; + if ($cAmount > 1 && $counter == 3) + { + $display[] = ''; + $counter = 1; + } + if ($cAmount > 1 && $counter == 1) + { + $display[] = '
'; + } + $display[] = '
'; + $display[] = '

'; + $display[] = $name; + if ($needKey) + { + $display[] = ' - ' . JText::sprintf('COM_COMPONENTBUILDER_PAIDLOCKED') . ''; + } + else + { + $display[] = ' - ' . JText::sprintf('COM_COMPONENTBUILDER_FREEOPEN') . ''; + } + $display[] = '

'; + $display[] = $info['short_description'][$key]; + $display[] = '

'; + $display[] = '
    '; + // load the list items + foreach (self::$compOwnerSearch['ul'] as $li => $value) + { + if (isset($info[$li]) && isset($info[$li][$key])) + { + $display[] = '
  • '.JText::sprintf($value, $info[$li][$key]).'
  • '; + } + } + $display[] = '
'; + // if we have a source link we add it + if (isset($info['joomla_source_link']) && self::checkArray($info['joomla_source_link']) && isset($info['joomla_source_link'][$key]) && self::checkString($info['joomla_source_link'][$key])) + { + $display[] = 'source code'; + } + // load other + foreach (self::$compOwnerSearch['other'] as $other => $value) + { + if (isset($info[$other]) && isset($info[$other][$key])) + { + $display[] = JText::sprintf($value, $info[$other][$key]); + } + } + $display[] = '
'; + + $counter++; + } + // close the div if needed + if ($cAmount > 1) + { + $display[] = '
'; + } + return implode("\n",$display); + } + return '
'.JText::_('COM_COMPONENTBUILDER_NO_COMPONENT_DETAILS_FOUND_SO_IT_IS_NOT_SAFE_TO_CONTINUE').'
'; + } + + /** + * The array of dynamic content + * + * @var array + */ + protected static $dynamicContent = array( + // The banners by size + 'banner' => array( + '728-90' => array( + 'Joomla! Volunteers Portal', + 'Joomla! Community Magazine | Because community matters...' + ), + '160-600' => array( + 'Joomla! Volunteers Portal', + 'Joomla! Community Magazine | Because community matters...' + ) + ), + // The build-gif by size + 'builder-gif' => array( + '707-400' => array( + '' + ) + ) + ); + + /** + * get the dynamic content + * + * @param string $type The type of content + * @param string $size The size of the content + * + * @return string on success + * + */ + public static function getDynamicContent($type, $size, $default = '') + { + if (isset(self::$dynamicContent[$type]) && isset(self::$dynamicContent[$type][$size]) && ($nr = self::checkArray(self::$dynamicContent[$type][$size]))) + { + // get the random item number + $get = (int) rand(0, --$nr); + // return found content + return self::$dynamicContent[$type][$size][$get]; + } + return $default; + } + + /** + * the Butler + **/ + public static $session = array(); + + /** + * the Butler Assistant + **/ + protected static $localSession = array(); + + /** + * start a session if not already set, and load with data + **/ + public static function loadSession() + { + if (!isset(self::$session) || !self::checkObject(self::$session)) + { + self::$session = JFactory::getSession(); + } + // set the defaults + self::setSessionDefaults(); + } + + /** + * give Session more to keep + **/ + public static function set($key, $value) + { + if (!isset(self::$session) || !self::checkObject(self::$session)) + { + self::$session = JFactory::getSession(); + } + // set to local memory to speed up program + self::$localSession[$key] = $value; + // load to session for later use + return self::$session->set($key, self::$localSession[$key]); + } + + /** + * get info from Session + **/ + public static function get($key, $default = null) + { + if (!isset(self::$session) || !self::checkObject(self::$session)) + { + self::$session = JFactory::getSession(); + } + // check if in local memory + if (!isset(self::$localSession[$key])) + { + // set to local memory to speed up program + self::$localSession[$key] = self::$session->get($key, $default); + } + return self::$localSession[$key]; + } + + + public static function getFieldOptions($value, $type, $settings = array(), $xml = null) + { + // Get a db connection. + $db = JFactory::getDbo(); + + // Create a new query object. + $query = $db->getQuery(true); + $query->select($db->quoteName(array('properties', 'short_description', 'description'))); + $query->from($db->quoteName('#__componentbuilder_fieldtype')); + $query->where($db->quoteName('published') . ' = 1'); + $query->where($db->quoteName($type) . ' = '. $value); + + // Reset the query using our newly populated query object. + $db->setQuery($query); + $db->execute(); + if ($db->getNumRows()) + { + $result = $db->loadObject(); + $properties = json_decode($result->properties, true); + $field = array( + 'subform' => array(), + 'nameListOptions' => array(), + 'php' => array(), + 'values' => " '', + 'short_description' => $result->short_description, + 'description' => $result->description); + // number pointer + $nr = 0; + // php tracker (we must try to load alteast 17 rows + $phpTracker = array(); + // value to check since there are false and null values even 0 in the values returned + $confirmation = '8qvZHoyuFYQqpj0YQbc6F3o5DhBlmS-_-a8pmCZfOVSfANjkmV5LG8pCdAY2JNYu6cB'; + // set the headers + $field['values_description'] .= ''; + foreach ($properties as $property) + { + $example = (isset($property['example']) && self::checkString($property['example'])) ? $property['example'] : ''; + $field['values_description'] .= ''; + // check if we should load the value + $value = self::getValueFromXMLstring($xml, $property['name'], $confirmation); + // check if this is a php field + $addPHP = false; + if (strpos($property['name'], 'type_php') !== false) + { + $addPHP = true; + // set the line number + $phpLine = (int) preg_replace('/[^0-9]/', '', $property['name']); + // set the key + $phpKey = trim(preg_replace('/[0-9]+/', '', $property['name']), '_'); + // start array if not already set + if (!isset($field['php'][$phpKey])) + { + $field['php'][$phpKey] = array(); + $field['php'][$phpKey]['value'] = array(); + $field['php'][$phpKey]['desc'] = $property['description']; + // start tracker + $phpTracker[$phpKey] = 1; + } + } + // was the settings for the property passed + if(self::checkArray($settings) && isset($settings[$property['name']])) + { + // add the xml values + $field['values'] .= PHP_EOL . "\t" . $property['name'] . '="'. $settings[$property['name']] . '" '; + // add the json values + if ($addPHP) + { + $field['php'][$phpKey]['value'][$phpLine] = $settings[$property['name']]; + $phpTracker[$phpKey]++; + } + else + { + $field['subform']['properties'.$nr] = array('name' => $property['name'], 'value' => $settings[$property['name']], 'desc' => $property['description']); + } + } + elseif (!$xml || $confirmation !== $value) + { + // add the xml values + $field['values'] .= PHP_EOL."\t" . $property['name'] . '="' . ($confirmation !== $value) ? $value : $example .'" '; + // add the json values + if ($addPHP) + { + $field['php'][$phpKey]['value'][$phpLine] = ($confirmation !== $value) ? $value : $example; + $phpTracker[$phpKey]++; + } + else + { + $field['subform']['properties' . $nr] = array('name' => $property['name'], 'value' => ($confirmation !== $value) ? $value : $example, 'desc' => $property['description']); + } + } + // add the name List Options + if (!$addPHP) + { + $field['nameListOptions'][$property['name']] = $property['name']; + } + // increment the number + $nr++; + } + // check if all php is loaded using the tracker + if (self::checkString($xml) && isset($phpTracker) && self::checkArray($phpTracker)) + { + foreach ($phpTracker as $phpKey => $start) + { + if ($start < 30) + { + // we must search for more code in the xml just incase + foreach(range(2, 30) as $t_nr) + { + $get_ = $phpKey . '_' . $t_nr; + if (!isset($field['php'][$phpKey]['value'][$t_nr]) && ($value = self::getValueFromXMLstring($xml, $get_, $confirmation)) !== $confirmation) + { + $field['php'][$phpKey]['value'][$t_nr] = $value; + } + } + } + } + } + $field['values'] .= PHP_EOL . "/>"; + $field['values_description'] .= '
' . JText::_('COM_COMPONENTBUILDER_PROPERTY') . '' . JText::_('COM_COMPONENTBUILDER_EXAMPLE') . '' . JText::_('COM_COMPONENTBUILDER_DESCRIPTION') . '
' . $property['name'] . '' . $example . '' . $property['description'] . '
'; + // return found field options + return $field; + } + return false; + } + + public static function getValueFromXMLstring(&$xml, &$get, $confirmation = '') + { + if (self::checkString($xml)) + { + // if we have a PHP value, we must base64 decode it + if (strpos($get, 'type_php') !== false) + { + return self::openValidBase64(self::getBetween($xml, $get.'="', '"', $confirmation)); + } + return self::getBetween($xml, $get . '="', '"', $confirmation); + } + return $confirmation; + } + + + /** + * The zipper method + * + * @param string $workingDIR The directory where the items must be zipped + * @param string $filepath The path to where the zip file must be placed + * + * @return bool true On success + * + */ + public static function zip($workingDIR, &$filepath) + { + // store the current joomla working directory + $joomla = getcwd(); + + // we are changing the working directory to the component temp folder + chdir($workingDIR); + + // the full file path of the zip file + $filepath = JPath::clean($filepath); + + // delete an existing zip file (or use an exclusion parameter in JFolder::files() + JFile::delete($filepath); + + // get a list of files in the current directory tree + $files = JFolder::files('.', '', true, true); + $zipArray = array(); + // setup the zip array + foreach ($files as $file) + { + $tmp = array(); + $tmp['name'] = str_replace('./', '', $file); + $tmp['data'] = JFile::read($file); + $tmp['time'] = filemtime($file); + $zipArray[] = $tmp; + } + + // change back to joomla working directory + chdir($joomla); + + // get the zip adapter + $zip = JArchive::getAdapter('zip'); + + //create the zip file + if ($zip->create($filepath, $zipArray)) + { + return true; + } + return false; + } + + + /** + * Write a file to the server + * + * @param string $path The path and file name where to safe the data + * @param string $data The data to safe + * + * @return bool true On success + * + */ + public static function writeFile($path, $data) + { + $klaar = false; + if (self::checkString($data)) + { + // open the file + $fh = fopen($path, "w"); + if (!is_resource($fh)) + { + return $klaar; + } + // write to the file + if (fwrite($fh, $data)) + { + // has been done + $klaar = true; + } + // close file. + fclose($fh); + } + return $klaar; + } + + + /** + * Remove folders with files + * + * @param string $dir The path to folder to remove + * @param boolean $ignore The folders and files to ignore and not remove + * + * @return boolean True in all is removed + * + */ + public static function removeFolder($dir, $ignore = false) + { + if (JFolder::exists($dir)) + { + $it = new RecursiveDirectoryIterator($dir); + $it = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST); + foreach ($it as $file) + { + if ('.' === $file->getBasename() || '..' === $file->getBasename()) continue; + if ($file->isDir()) + { + $keeper = false; + if (self::checkArray($ignore)) + { + foreach ($ignore as $keep) + { + if (strpos($file->getPathname(), $dir.'/'.$keep) !== false) + { + $keeper = true; + } + } + } + if ($keeper) + { + continue; + } + JFolder::delete($file->getPathname()); + } + else + { + $keeper = false; + if (self::checkArray($ignore)) + { + foreach ($ignore as $keep) + { + if (strpos($file->getPathname(), $dir.'/'.$keep) !== false) + { + $keeper = true; + } + } + } + if ($keeper) + { + continue; + } + JFile::delete($file->getPathname()); + } + } + if (!self::checkArray($ignore)) + { + return JFolder::delete($dir); + } + return true; + } + return false; + } + + + /** + * get the github repo file list + * + * @return array on success + * + */ + public static function getGithubRepoFileList($type, $target) + { + // get the current Packages (public) + if (!$repoData = self::get($type)) + { + if (self::urlExists($target)) + { + $repoData = self::getFileContents($target); + if (self::checkJson($repoData)) + { + $test = json_decode($repoData); + if (self::checkObject($test) && isset($test->tree) && self::checkArray($test->tree) ) + { + // remember to set it + self::set($type, $repoData); + } + // check if we have error message from github + elseif ($errorMessage = self::githubErrorHandeler(array('error' => null), $test)) + { + if (self::checkString($errorMessage['error'])) + { + JFactory::getApplication()->enqueueMessage($errorMessage['error'], 'Error'); + } + $repoData = false; + } + } + else + { + $repoData = false; + } + } + else + { + JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_URL_S_SET_TO_RETRIEVE_THE_PACKAGES_DOES_NOT_EXIST', $target), 'Error'); + } + } + // check if we could find packages + if (isset($repoData) && self::checkJson($repoData)) + { + $repoData = json_decode($repoData); + if (self::checkObject($repoData) && isset($repoData->tree) && self::checkArray($repoData->tree) ) + { + return $repoData->tree; + } + } + return false; + } + + /** + * get the github error messages + * + * @return array of errors on success + * + */ + protected static function githubErrorHandeler($message, &$github) + { + if (self::checkObject($github) && isset($github->message) && self::checkString($github->message)) + { + // set the message + $errorMessage = $github->message; + // add the documentation URL + if (isset($github->documentation_url) && self::checkString($github->documentation_url)) + { + $errorMessage = $errorMessage.'
'.$github->documentation_url; + } + // check the message + if (strpos($errorMessage, 'Authenticated') !== false) + { + // add little more help if it is an access token issue + $errorMessage = JText::sprintf('COM_COMPONENTBUILDER_SBR_YOU_CAN_ADD_AN_BACCESS_TOKENB_TO_GETBIBLE_GLOBAL_OPTIONS_TO_MAKE_AUTHENTICATED_REQUESTS_AN_ACCESS_TOKEN_WITH_ONLY_PUBLIC_ACCESS_WILL_DO', $errorMessage); + } + // set error notice + $message['error'] = $errorMessage; + // we have error message + return $message; + } + return false; + } + public static function getDynamicScripts($type, $fieldName = false) { @@ -1685,181 +2211,6 @@ abstract class ComponentbuilderHelper return false; } - /** - * Run Global Updater if any are set - * - * @return void - * - */ - public static function runGlobalUpdater() - { - // check if any updates are set to run - if (self::checkArray(self::$globalUpdater)) - { - // get the database object - $db = JFactory::getDbo(); - foreach (self::$globalUpdater as $tableKeyID => $object) - { - // get the table - $table = explode('.', $tableKeyID); - // update the item - $db->updateObject('#__componentbuilder_' . (string) $table[0] , $object, (string) $table[1]); - } - // rest updater - self::$globalUpdater = array(); - } - } - - /** - * Copy Any Item (only use for direct database copying) - * - * @param int $id The item to copy - * @param string $table The table and model to copy from and with - * @param array $config The values that should change - * - * @return boolean True if success - * - */ - public static function copyItem($id, $type, $config = array()) - { - // only continue if we have an id - if ((int) $id > 0) - { - // get the model - $model = self::getModel($type); - $app = \JFactory::getApplication(); - // get item - if ($item = $model->getItem($id)) - { - // update values that should change - if (self::checkArray($config)) - { - foreach($config as $key => $value) - { - if (isset($item->{$key})) - { - $item->{$key} = $value; - } - } - } - // clone the object - $data = array(); - foreach ($item as $key => $value) - { - $data[$key] = $value; - } - // reset some values - $data['id'] = 0; - $data['version'] = 1; - if (isset($data['tags'])) - { - $data['tags'] = null; - } - if (isset($data['associations'])) - { - $data['associations'] = array(); - } - // remove some unneeded values - unset($data['params']); - unset($data['asset_id']); - unset($data['checked_out']); - unset($data['checked_out_time']); - // Attempt to save the data. - if ($model->save($data)) - { - return true; - } - } - } - return false; - } - - /** - * the basic localkey - **/ - protected static $localkey = false; - - /** - * get the localkey - **/ - public static function getLocalKey() - { - if (!self::$localkey) - { - // get the basic key - self::$localkey = md5(self::getCryptKey('basic', 'localKey34fdWEkl')); - } - return self::$localkey; - } - - /** - * indent HTML - */ - public static function indent($html) - { - // load the class - require_once JPATH_ADMINISTRATOR.'/components/com_componentbuilder/helpers/indenter.php'; - // set new indenter - $indenter = new Indenter(); - // return indented html - return $indenter->indent($html); - } - - public static function checkFileType($file, $sufix) - { - // now check if the file ends with the sufix - return $sufix === "" || ($sufix == substr(strrchr($file, "."), -strlen($sufix))); - } - - public static function imageInfo($path, $request = 'type') - { - // set image - $image = JPATH_SITE.'/'.$path; - // check if exists - if (file_exists($image) && $result = @getimagesize($image)) - { - // return type request - switch ($request) - { - case 'width': - return $result[0]; - break; - case 'height': - return $result[1]; - break; - case 'type': - $extensions = array( - IMAGETYPE_GIF => "gif", - IMAGETYPE_JPEG => "jpg", - IMAGETYPE_PNG => "png", - IMAGETYPE_SWF => "swf", - IMAGETYPE_PSD => "psd", - IMAGETYPE_BMP => "bmp", - IMAGETYPE_TIFF_II => "tiff", - IMAGETYPE_TIFF_MM => "tiff", - IMAGETYPE_JPC => "jpc", - IMAGETYPE_JP2 => "jp2", - IMAGETYPE_JPX => "jpx", - IMAGETYPE_JB2 => "jb2", - IMAGETYPE_SWC => "swc", - IMAGETYPE_IFF => "iff", - IMAGETYPE_WBMP => "wbmp", - IMAGETYPE_XBM => "xbm", - IMAGETYPE_ICO => "ico" - ); - return $extensions[$result[2]]; - break; - case 'attr': - return $result[3]; - break; - case 'all': - default: - return $result; - break; - } - } - return false; - } /** * get between @@ -1999,278 +2350,6 @@ abstract class ComponentbuilderHelper return self::getVars('fieldtype', (array) array_map(function($name) use($db) { return $db->quote(ucfirst($name)); }, self::$fieldGroups['spacer']), 'name', 'id'); } - /** - * set the session defaults if not set - **/ - protected static function setSessionDefaults() - { - // noting for now - return true; - } - - /** - * the Butler - **/ - public static $session = array(); - - /** - * the Butler Assistant - **/ - protected static $localSession = array(); - - /** - * start a session if not already set, and load with data - **/ - public static function loadSession() - { - if (!isset(self::$session) || !self::checkObject(self::$session)) - { - self::$session = JFactory::getSession(); - } - // set the defaults - self::setSessionDefaults(); - } - - /** - * give Session more to keep - **/ - public static function set($key, $value) - { - if (!isset(self::$session) || !self::checkObject(self::$session)) - { - self::$session = JFactory::getSession(); - } - // set to local memory to speed up program - self::$localSession[$key] = $value; - // load to session for later use - return self::$session->set($key, self::$localSession[$key]); - } - - /** - * get info from Session - **/ - public static function get($key, $default = null) - { - if (!isset(self::$session) || !self::checkObject(self::$session)) - { - self::$session = JFactory::getSession(); - } - // check if in local memory - if (!isset(self::$localSession[$key])) - { - // set to local memory to speed up program - self::$localSession[$key] = self::$session->get($key, $default); - } - return self::$localSession[$key]; - } - - /** - * check if it is a new hash - **/ - public static function newHash($hash, $name = 'backup', $type = 'hash', $key = '', $fileType = 'txt') - { - // make sure we have a hash - if (self::checkString($hash)) - { - // first get the file path - $path_filename = self::getFilePath('path', $name.$type, $fileType, $key, JPATH_COMPONENT_ADMINISTRATOR); - // set as read if not already set - if ($content = self::getFileContents($path_filename, false)) - { - if ($hash == $content) - { - return false; - } - } - // set the hash - return self::writeFile($path_filename, $hash); - } - return false; - } - - protected static $pkOwnerSearch = array( - 'company' => 'COM_COMPONENTBUILDER_DTCOMPANYDTDDSDD', - 'owner' => 'COM_COMPONENTBUILDER_DTOWNERDTDDSDD', - 'email' => 'COM_COMPONENTBUILDER_DTEMAILDTDDSDD', - 'website' => 'COM_COMPONENTBUILDER_DTWEBSITEDTDDSDD', - 'license' => 'COM_COMPONENTBUILDER_DTLICENSEDTDDSDD', - 'copyright' => 'COM_COMPONENTBUILDER_DTCOPYRIGHTDTDDSDD' - ); - - /** - * get the JCB package owner details display - **/ - public static function getPackageOwnerDetailsDisplay(&$info, $trust = false) - { - $hasOwner = false; - $ownerDetails = ''; - $ownerDetails .= '
'; - // load the list items - foreach (self::$pkOwnerSearch as $key => $dd) - { - if ($value = self::getPackageOwnerValue($key, $info)) - { - $ownerDetails .= JText::sprintf($dd, $value); - // check if we have a owner/source name - if (('owner' === $key || 'company' === $key) && !$hasOwner) - { - $hasOwner = true; - $owner = $value; - } - } - } - $ownerDetails .= '
'; - - // provide some details to how the user can get a key - if ($hasOwner && isset($info['getKeyFrom']['buy_link']) && self::checkString($info['getKeyFrom']['buy_link'])) - { - $ownerDetails .= '
'; - $ownerDetails .= JText::sprintf('COM_COMPONENTBUILDER_BGET_THE_KEY_FROMB_A_SSA', 'class="btn btn-primary" href="'.$info['getKeyFrom']['buy_link'].'" target="_blank" title="get a key from '.$owner.'"', $owner); - } - // add more custom links - elseif ($hasOwner && isset($info['getKeyFrom']['buy_links']) && self::checkArray($info['getKeyFrom']['buy_links'])) - { - $buttons = array(); - foreach ($info['getKeyFrom']['buy_links'] as $keyName => $link) - { - $buttons[] = JText::sprintf('COM_COMPONENTBUILDER_BGET_THE_KEY_FROM_SB_FOR_A_SSA', $owner, 'class="btn btn-primary" href="'.$link.'" target="_blank" title="get a key from '.$owner.'"', $keyName); - } - $ownerDetails .= '
'; - $ownerDetails .= implode('
', $buttons); - } - // return the owner details - if (!$hasOwner) - { - $ownerDetails = '

' . JText::_('COM_COMPONENTBUILDER_PACKAGE_OWNER_DETAILS_NOT_FOUND') . '

'; - if (!$trust) - { - $ownerDetails .= '

' . JText::_('COM_COMPONENTBUILDER_BE_CAUTIOUS_DO_NOT_CONTINUE_UNLESS_YOU_TRUST_THE_ORIGIN_OF_THIS_PACKAGE') . '

'; - } - } - return '
'.$ownerDetails.'
'; - } - - public static function getPackageOwnerValue($key, &$info) - { - $source = (isset($info['source']) && isset($info['source'][$key])) ? 'source' : ((isset($info['getKeyFrom']) && isset($info['getKeyFrom'][$key])) ? 'getKeyFrom' : false); - if ($source && self::checkString($info[$source][$key])) - { - return $info[$source][$key]; - } - return false; - } - - /** - * get the JCB package component key status - **/ - public static function getPackageComponentsKeyStatus(&$info) - { - // check the package key status - if (!isset($info['key'])) - { - if (isset($info['getKeyFrom']) && isset($info['getKeyFrom']['owner'])) - { - // this just confirms it for older packages - $info['key'] = true; - } - else - { - // this just confirms it for older packages - $info['key'] = false; - } - } - return $info['key']; - } - - protected static $compOwnerSearch = array( - 'ul' => array ( - 'companyname' => 'COM_COMPONENTBUILDER_ICOMPANYI_BSB', - 'author' => 'COM_COMPONENTBUILDER_IAUTHORI_BSB', - 'email' => 'COM_COMPONENTBUILDER_IEMAILI_BSB', - 'website' => 'COM_COMPONENTBUILDER_IWEBSITEI_BSB', - ), - 'other' => array( - 'license' => 'COM_COMPONENTBUILDER_HFOUR_CLASSNAVHEADERLICENSEHFOURPSP', - 'copyright' => 'COM_COMPONENTBUILDER_HFOUR_CLASSNAVHEADERCOPYRIGHTHFOURPSP' - ) - ); - - /** - * get the JCB package component details display - **/ - public static function getPackageComponentsDetailsDisplay(&$info) - { - // check if these components need a key - $needKey = self::getPackageComponentsKeyStatus($info); - if (isset($info['name']) && self::checkArray($info['name'])) - { - $cAmount = count((array) $info['name']); - $class2 = ($cAmount == 1) ? 'span12' : 'span6'; - $counter = 1; - $display = array(); - foreach ($info['name'] as $key => $value) - { - // set the name - $name= $value . ' v' . $info['component_version'][$key]; - if ($cAmount > 1 && $counter == 3) - { - $display[] = ''; - $counter = 1; - } - if ($cAmount > 1 && $counter == 1) - { - $display[] = '
'; - } - $display[] = '
'; - $display[] = '

'; - $display[] = $name; - if ($needKey) - { - $display[] = ' - ' . JText::sprintf('COM_COMPONENTBUILDER_PAIDLOCKED') . ''; - } - else - { - $display[] = ' - ' . JText::sprintf('COM_COMPONENTBUILDER_FREEOPEN') . ''; - } - $display[] = '

'; - $display[] = $info['short_description'][$key]; - $display[] = '

'; - $display[] = '
    '; - // load the list items - foreach (self::$compOwnerSearch['ul'] as $li => $value) - { - if (isset($info[$li]) && isset($info[$li][$key])) - { - $display[] = '
  • '.JText::sprintf($value, $info[$li][$key]).'
  • '; - } - } - $display[] = '
'; - // if we have a source link we add it - if (isset($info['joomla_source_link']) && self::checkArray($info['joomla_source_link']) && isset($info['joomla_source_link'][$key]) && self::checkString($info['joomla_source_link'][$key])) - { - $display[] = 'source code'; - } - // load other - foreach (self::$compOwnerSearch['other'] as $other => $value) - { - if (isset($info[$other]) && isset($info[$other][$key])) - { - $display[] = JText::sprintf($value, $info[$other][$key]); - } - } - $display[] = '
'; - - $counter++; - } - // close the div if needed - if ($cAmount > 1) - { - $display[] = '
'; - } - return implode("\n",$display); - } - return '
'.JText::_('COM_COMPONENTBUILDER_NO_COMPONENT_DETAILS_FOUND_SO_IT_IS_NOT_SAFE_TO_CONTINUE').'
'; - } /** * open base64 string if stored as base64 @@ -5192,11 +5271,11 @@ abstract class ComponentbuilderHelper * * @input array The array to check * - * @returns bool true on success + * @returns bool/int number of items in array on success **/ public static function checkArray($array, $removeEmptyString = false) { - if (isset($array) && is_array($array) && count((array)$array) > 0) + if (isset($array) && is_array($array) && ($nr = count((array)$array)) > 0) { // also make sure the empty strings are removed if ($removeEmptyString) @@ -5210,7 +5289,7 @@ abstract class ComponentbuilderHelper } return self::checkArray($array, false); } - return true; + return $nr; } return false; } diff --git a/admin/language/en-GB/en-GB.com_componentbuilder.ini b/admin/language/en-GB/en-GB.com_componentbuilder.ini index 1d75c498a..9dc3bd2b3 100644 --- a/admin/language/en-GB/en-GB.com_componentbuilder.ini +++ b/admin/language/en-GB/en-GB.com_componentbuilder.ini @@ -322,6 +322,8 @@ COM_COMPONENTBUILDER_ADMIN_FIELDS_NEW="A New Admin Fields" COM_COMPONENTBUILDER_ADMIN_FIELDS_NONE_DB="None DB" COM_COMPONENTBUILDER_ADMIN_FIELDS_NOTE_ON_VIEWS_DESCRIPTION="id, asset_id, state, access, ordering, created_by, created, modified_by, modified, checked_out, checked_out_time, version, hits, metakey, metadesc, metadata (you don't need to add them again)
For more help please watch this tutorial." COM_COMPONENTBUILDER_ADMIN_FIELDS_NOTE_ON_VIEWS_LABEL="The following fields are added by default to all views." +COM_COMPONENTBUILDER_ADMIN_FIELDS_ONLY_IN_ADMIN_LIST_VIEW="Only in Admin List View" +COM_COMPONENTBUILDER_ADMIN_FIELDS_ONLY_IN_LINKED_LIST_VIEWS="Only in Linked List Views" COM_COMPONENTBUILDER_ADMIN_FIELDS_ORDERING_LABEL="Ordering" COM_COMPONENTBUILDER_ADMIN_FIELDS_ORDER_EDIT_DESCRIPTION="Order in relation to tab & alignment of admin and site." COM_COMPONENTBUILDER_ADMIN_FIELDS_ORDER_EDIT_LABEL="Order in Edit" @@ -385,7 +387,7 @@ COM_COMPONENTBUILDER_ADMIN_FIELDS_RIGHT_OF_TABS="Right of Tabs" COM_COMPONENTBUILDER_ADMIN_FIELDS_SAVE_WARNING="Alias already existed so a number was added at the end. You can re-edit the Admin Fields to customise the alias." COM_COMPONENTBUILDER_ADMIN_FIELDS_SEARCH_DESCRIPTION="Select if the field is to be searchable in list view, if shown." COM_COMPONENTBUILDER_ADMIN_FIELDS_SEARCH_LABEL="Searchable" -COM_COMPONENTBUILDER_ADMIN_FIELDS_SHOW_IN_LIST_VIEW="Show in list view" +COM_COMPONENTBUILDER_ADMIN_FIELDS_SHOW_IN_ALL_LIST_VIEWS="Show in All List Views" COM_COMPONENTBUILDER_ADMIN_FIELDS_SORT_DESCRIPTION="Select if the field should be sortable in list view, if shown." COM_COMPONENTBUILDER_ADMIN_FIELDS_SORT_LABEL="Sortable" COM_COMPONENTBUILDER_ADMIN_FIELDS_STATUS="Status" @@ -614,6 +616,7 @@ COM_COMPONENTBUILDER_ADMIN_VIEW_CONTRACT_TWO="Contract 2" COM_COMPONENTBUILDER_ADMIN_VIEW_CORECREATE="core.create" COM_COMPONENTBUILDER_ADMIN_VIEW_COREDELETE="core.delete" COM_COMPONENTBUILDER_ADMIN_VIEW_COREEDIT="core.edit" +COM_COMPONENTBUILDER_ADMIN_VIEW_COREEDITACCESS="core.edit.access" COM_COMPONENTBUILDER_ADMIN_VIEW_COREEDITCREATED="core.edit.created" COM_COMPONENTBUILDER_ADMIN_VIEW_COREEDITCREATED_BY="core.edit.created_by" COM_COMPONENTBUILDER_ADMIN_VIEW_COREEDITOWN="core.edit.own" @@ -1324,6 +1327,7 @@ COM_COMPONENTBUILDER_ADMIN_VIEW_VIEWACCESS="view.access" COM_COMPONENTBUILDER_ADMIN_VIEW_VIEWCREATE="view.create" COM_COMPONENTBUILDER_ADMIN_VIEW_VIEWDELETE="view.delete" COM_COMPONENTBUILDER_ADMIN_VIEW_VIEWEDIT="view.edit" +COM_COMPONENTBUILDER_ADMIN_VIEW_VIEWEDITACCESS="view.edit.access" COM_COMPONENTBUILDER_ADMIN_VIEW_VIEWEDITCREATED="view.edit.created" COM_COMPONENTBUILDER_ADMIN_VIEW_VIEWEDITCREATED_BY="view.edit.created_by" COM_COMPONENTBUILDER_ADMIN_VIEW_VIEWEDITOWN="view.edit.own" @@ -3597,7 +3601,10 @@ COM_COMPONENTBUILDER_CUSTOM_CODE_MODIFIED_BY_LABEL="Modified By" COM_COMPONENTBUILDER_CUSTOM_CODE_MODIFIED_DATE_DESC="The date this Custom Code was modified." COM_COMPONENTBUILDER_CUSTOM_CODE_MODIFIED_DATE_LABEL="Modified Date" COM_COMPONENTBUILDER_CUSTOM_CODE_NEW="A New Custom Code" -COM_COMPONENTBUILDER_CUSTOM_CODE_NOTE_JCB_PLACEHOLDER_DESCRIPTION="[save to see placeholder]
You can also pass values to this code like this: [save to see placeholder trick]
Those values will be replace placeholders called args. These placeholders are zero based and should look like this: [[[arg0]]], [[[arg1]]] ... as many as you like. If you use 5 args in your code, you must always pass 5 values, since they are zero based your fifth arg will look like this [[[arg4]]]
Please note that you can not use this placeholder in other custom code views, but in all other custom code areas in JCB found in other views like the admin, site and custom admin views.
Another important note, all code with args will not be reversed updated from the changes in the editor out side of JCB at this time, since that will remove all the arg placeholders this means you will only be able to update the code here in the JCB UI.
This note will change once we have resolved these limitations." +COM_COMPONENTBUILDER_CUSTOM_CODE_NOTE_JCB_PLACEHOLDER_DESCRIPTION="

[save to see placeholder]
You can also pass values to this code like this: [save to see placeholder trick]

+

Those values will be replace placeholders called args. These placeholders are zero based and should look like this: [[[arg0]]], [[[arg1]]] ... as many as you like. If you use 5 args in your code, you must always pass 5 values, since they are zero based your fifth arg will look like this [[[arg4]]]

+

To use the following [ ] , + = in your string being passed, use the following: [ &#91;; ] &#93;; , &#44;; + &#43;; = &#61;

+

Please note that you can not use this placeholder in other custom code views, but in all other custom code areas in JCB found in other views like the admin, site and custom admin views.
Another important note, all code with args will not be reversed updated from the changes in the editor out side of JCB at this time, since that will remove all the arg placeholders this means you will only be able to update the code here in the JCB UI.

This note will change once we have resolved these limitations." COM_COMPONENTBUILDER_CUSTOM_CODE_NOTE_JCB_PLACEHOLDER_LABEL="You can use this code in any JCB code area, simply add this PlaceHolder." COM_COMPONENTBUILDER_CUSTOM_CODE_NOTE_PLACEHOLDERS_EXPLAINED_DESCRIPTION="

Understand how the placeholders work in (IDE)

@@ -3703,6 +3710,7 @@ COM_COMPONENTBUILDER_CUSTOM_CODE_NOTE_PLACEHOLDERS_EXPLAINED_DESCRIPTION=" + @@ -4691,6 +4699,8 @@ COM_COMPONENTBUILDER_HI="Hi" COM_COMPONENTBUILDER_HIDE_ONLY="Hide Only" COM_COMPONENTBUILDER_HIDE_TOGGLE="Hide Toggle" COM_COMPONENTBUILDER_HOW_TO_GET_A_S_FREE_KEYSA_FROM_VDM="How to get free keys from VDM." +COM_COMPONENTBUILDER_HTHREEPLACEHOLDER_REMOVEDHTHREEPBTHISB_CUSTOM_CODE_CAN_ONLY_BE_USED_IN_BOTHERB_CUSTOM_CODE_NOT_IN_IT_SELF_SINCE_THAT_WILL_CAUSE_A_INFINITE_LOOP_IN_THE_COMPILERP="

Placeholder Removed!

This custom code can only be used in other custom code, not in it self! Since that will cause a infinite loop in the compiler.

" +COM_COMPONENTBUILDER_HTHREESHTHREEPCUSTOM_CODE_CAN_ONLY_BE_USED_IN_OTHER_CUSTOM_CODE_IF_SET_AS_BJCB_MANUALB_YOU_CAN_NOT_ADD_THEM_TO_EMHASH_AUTOMATIONEM_CODE_AT_THIS_POINTP="

%s

Custom code can only be used in other custom code if set as JCB (manual), you can not add them to Hash (Automation) code at this point.

" 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!" @@ -5986,6 +5996,8 @@ 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_PLACEHOLDERS_REMOVED="Placeholders Removed!" +COM_COMPONENTBUILDER_PLACEHOLDER_REMOVED="Placeholder Removed!" COM_COMPONENTBUILDER_PLACES_ACROSS_JCB_WHERE_THIS_S_IS_LINKED="Places across JCB where this %s is linked." COM_COMPONENTBUILDER_PLEASE_ADD_FILES_TO_S="Please add files to (%s)" COM_COMPONENTBUILDER_PLEASE_ADD_FOLDERS_TO_S="Please add folders to (%s)" @@ -7016,12 +7028,14 @@ COM_COMPONENTBUILDER_THE_ADMIN_FIELDS_CONDITIONS="The admin fields conditions" COM_COMPONENTBUILDER_THE_ADMIN_FIELDS_RELATIONS="The admin fields relations" COM_COMPONENTBUILDER_THE_AVAILABLE_VALIDATION_RULES_FOR_THE_VALIDATE_ATTRIBUTE_ARE="The available validation rules for the validate attribute are:" COM_COMPONENTBUILDER_THE_BNONE_DBB_OPTION_WILL_REMOVE_THIS_FIELD_FROM_BEING_SAVED_IN_THE_DATABASE="The None DB option will remove this field from being saved in the database." +COM_COMPONENTBUILDER_THE_BONLY_IN_ADMIN_LIST_VIEWB_OPTION_WILL_ONLY_ADD_THIS_FIELD_TO_THE_ADMIN_LIST_VIEW_NOT_TO_ANY_LINKED_VIEWS="The Only in Admin List View option will only Add this field to the admin list view, not to any linked views." +COM_COMPONENTBUILDER_THE_BONLY_IN_LINKED_LIST_VIEWSB_OPTION_WILL_ONLY_ADD_THIS_FIELD_TO_THE_LINKED_LIST_VIEW_IF_THIS_VIEW_GETS_LINKED_TO_OTHER_VIEW_NOT_TO_THIS_ADMIN_LIST_VIEW="The Only in Linked List Views option will only Add this field to the linked list view, if this view gets linked to other view, not to this admin list view." COM_COMPONENTBUILDER_THE_BPHPSECLIBNETSFTPB_LIBRARYCLASS_IS_NOT_AVAILABLE_THIS_LIBRARYCLASS_SHOULD_HAVE_BEEN_ADDED_TO_YOUR_BLIBRARIESVDM_IOVENDORB_FOLDER_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_INFO="The phpseclib\NET\SFTP library\class is not available! This library\class should have been added to your libraries/vdm_io/vendor folder. Please contact your system administrator for more info" COM_COMPONENTBUILDER_THE_BSB_FILE_COULD_NOT_BE_MOVED_TO_BSB_PATH_ON_BSB_SERVER="The %s file could not be moved to %s path on %s server." COM_COMPONENTBUILDER_THE_BSB_FILE_COULD_NOT_BE_MOVED_TO_BSB_SERVER="The %s file could not be moved to %s server." COM_COMPONENTBUILDER_THE_BSB_LIBRARYCLASS_IS_NOT_AVAILABLE_THIS_LIBRARYCLASS_SHOULD_HAVE_BEEN_ADDED_TO_YOUR_BLIBRARIESVDM_IOVENDORB_FOLDER_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_INFO="The %s library\class is not available! This library\class should have been added to your libraries/vdm_io/vendor folder. Please contact your system administrator for more info!" COM_COMPONENTBUILDER_THE_BSB_LIBRARY_CAN_NOT_BE_DELETED_OR_THINGS_WILL_BREAK="The %s library can not be deleted, or things will break." -COM_COMPONENTBUILDER_THE_BSHOW_IN_LIST_VIEWB_OPTION_WILL_ADD_THIS_FIELD_TO_THE_ADMIN_LIST_VIEW="The Show in list view option will Add this field to the admin list view." +COM_COMPONENTBUILDER_THE_BSHOW_IN_ALL_LIST_VIEWSB_OPTION_WILL_ADD_THIS_FIELD_TO_ALL_LIST_VIEWS_ADMIN_AMP_LINKED="The Show in All List Views option will Add this field to all list views, admin & linked." COM_COMPONENTBUILDER_THE_COMPONENT_ADMIN_VIEWS="The component admin views" COM_COMPONENTBUILDER_THE_COMPONENT_CONFIG="The component config" COM_COMPONENTBUILDER_THE_COMPONENT_CUSTOM_ADMIN_MENUS="The component custom admin menus" @@ -7049,8 +7063,8 @@ COM_COMPONENTBUILDER_THE_SEARCH_FOR_THE_SNIPPETS_ARE_CASE_SENSITIVE_SO_IF_YOU_CH COM_COMPONENTBUILDER_THE_SERVER_DETAILS_FOR_BID_SB_COULD_NOT_BE_RETRIEVED="The server details for (ID: %s) could not be retrieved!" COM_COMPONENTBUILDER_THE_SNIPPETS_WERE_SUCCESSFULLY_EXPORTED="The Snippets Were Successfully Exported!" COM_COMPONENTBUILDER_THE_SNIPPET_WAS_SUCCESSFULLY_EXPORTED="The Snippet Was Successfully Exported!" -COM_COMPONENTBUILDER_THE_TEXT_IS_LOADING="The text is loading" COM_COMPONENTBUILDER_THE_URL_S_SET_TO_RETRIEVE_THE_PACKAGES_DOES_NOT_EXIST="The url (%s) set to retrieve the packages does not exist!" +COM_COMPONENTBUILDER_THE_WIKI_IS_LOADING="The wiki is loading" 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_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." diff --git a/admin/models/admin_view.php b/admin/models/admin_view.php index 186d3ba04..ec753ce76 100644 --- a/admin/models/admin_view.php +++ b/admin/models/admin_view.php @@ -770,7 +770,8 @@ class ComponentbuilderModelAdmin_view extends JModelAdmin $_tablesArray = array( 'admin_fields', 'admin_fields_conditions', - 'admin_fields_relations' + 'admin_fields_relations', + 'admin_custom_tabs' ); foreach($_tablesArray as $_updateTable) { @@ -811,7 +812,8 @@ class ComponentbuilderModelAdmin_view extends JModelAdmin $_tablesArray = array( 'admin_fields', 'admin_fields_conditions', - 'admin_fields_relations' + 'admin_fields_relations', + 'admin_custom_tabs' ); foreach($_tablesArray as $_updateTable) { diff --git a/admin/models/ajax.php b/admin/models/ajax.php index 6a7a009b2..030b35111 100644 --- a/admin/models/ajax.php +++ b/admin/models/ajax.php @@ -2180,102 +2180,109 @@ class ComponentbuilderModelAjax extends JModelList * @var array */ protected $codeSearchKeys = array( - // #__componentbuilder_joomla_component + // #__componentbuilder_joomla_component (a) 'joomla_component' => array( - 'search' => array('id', 'system_name', 'php_preflight_install','php_postflight_install', - 'php_preflight_update','php_postflight_update','php_method_uninstall', - 'php_helper_admin','php_admin_event','php_helper_both','php_helper_site', - 'php_site_event','javascript'), + 'search' => array('id', 'system_name', 'php_preflight_install', 'php_postflight_install', + 'php_preflight_update', 'php_postflight_update', 'php_method_uninstall', + 'php_helper_admin', 'php_admin_event', 'php_helper_both', 'php_helper_site', + 'php_site_event', 'javascript'), 'views' => 'joomla_components', 'not_base64' => array(), 'name' => 'system_name' ), - // #__componentbuilder_component_dashboard + // #__componentbuilder_component_dashboard (b) 'component_dashboard' => array( - 'search' => array('id', 'joomla_component', 'php_dashboard_methods','dashboard_tab'), + 'search' => array('id', 'joomla_component', 'php_dashboard_methods', 'dashboard_tab'), 'views' => 'components_dashboard', 'not_base64' => array('dashboard_tab' => 'json'), 'name' => 'joomla_component->id:joomla_component.system_name' ), - // #__componentbuilder_admin_view + // #__componentbuilder_admin_view (c) 'admin_view' => array( - 'search' => array('id', 'system_name', 'javascript_view_file','javascript_view_footer', - 'javascript_views_file','javascript_views_footer','html_import_view', - 'php_after_delete','php_after_publish','php_ajaxmethod','php_allowedit','php_batchcopy', - 'php_batchmove','php_before_delete','php_before_publish','php_before_save','php_controller', - 'php_controller_list','php_document','php_getitem','php_getitems','php_getitems_after_all', - 'php_getlistquery','php_import','php_import_display','php_import_ext','php_import_headers','php_getform', - 'php_import_save','php_import_setdata','php_model','php_model_list','php_postsavehook','php_save'), + 'search' => array('id', 'system_name', 'javascript_view_file', 'javascript_view_footer', + 'javascript_views_file', 'javascript_views_footer', 'html_import_view', + 'php_after_delete', 'php_after_publish', 'php_ajaxmethod', 'php_allowedit', 'php_batchcopy', + 'php_batchmove', 'php_before_delete', 'php_before_publish', 'php_before_save', 'php_controller', + 'php_controller_list', 'php_document', 'php_getitem', 'php_getitems', 'php_getitems_after_all', + 'php_getlistquery', 'php_import', 'php_import_display', 'php_import_ext', 'php_import_headers', 'php_getform', + 'php_import_save', 'php_import_setdata', 'php_model', 'php_model_list', 'php_postsavehook', 'php_save'), 'views' => 'admin_views', 'not_base64' => array(), 'name' => 'system_name' ), - // #__componentbuilder_admin_fields_relations + // #__componentbuilder_admin_fields_relations (d) 'admin_fields_relations' => array( 'search' => array('id', 'admin_view', 'addrelations'), 'views' => 'admins_fields_relations', 'not_base64' => array('addrelations' => 'json'), 'name' => 'admin_view->id:admin_view.system_name' ), - // #__componentbuilder_custom_admin_view + // #__componentbuilder_custom_admin_view (e) 'custom_admin_view' => array( - 'search' => array('id', 'system_name', 'default','php_view','php_jview','php_jview_display','php_document', - 'js_document','css_document','css','php_ajaxmethod','php_model','php_controller'), + 'search' => array('id', 'system_name', 'default', 'php_view', 'php_jview', 'php_jview_display', 'php_document', + 'js_document', 'css_document', 'css', 'php_ajaxmethod', 'php_model', 'php_controller'), 'views' => 'custom_admin_views', 'not_base64' => array(), 'name' => 'system_name' ), - // #__componentbuilder_site_view + // #__componentbuilder_site_view (f) 'site_view' => array( - 'search' => array('id', 'system_name', 'default','php_view','php_jview','php_jview_display','php_document', - 'js_document','css_document','css','php_ajaxmethod','php_model','php_controller'), + 'search' => array('id', 'system_name', 'default', 'php_view', 'php_jview', 'php_jview_display', 'php_document', + 'js_document', 'css_document', 'css', 'php_ajaxmethod', 'php_model', 'php_controller'), 'views' => 'site_views', 'not_base64' => array(), 'name' => 'system_name' ), - // #__componentbuilder_field + // #__componentbuilder_field (g) 'field' => array( - 'search' => array('id', 'name', 'xml','javascript_view_footer','javascript_views_footer'), + 'search' => array('id', 'name', 'xml', 'javascript_view_footer', 'javascript_views_footer'), 'views' => 'fields', 'not_base64' => array('xml' => 'json'), 'base64_search' => array('xml' => array('start' => 'type_php', '_start' => '="', 'end' => '"')), 'name' => 'name' ), - // #__componentbuilder_fieldtype + // #__componentbuilder_fieldtype (h) 'fieldtype' => array( 'search' => array('id', 'name', 'properties'), 'views' => 'fieldtypes', 'not_base64' => array('properties' => 'json'), 'name' => 'name' ), - // #__componentbuilder_dynamic_get + // #__componentbuilder_dynamic_get (i) 'dynamic_get' => array( - 'search' => array('id', 'name', 'php_before_getitem','php_after_getitem','php_before_getitems','php_after_getitems', + 'search' => array('id', 'name', 'php_before_getitem', 'php_after_getitem', 'php_before_getitems', 'php_after_getitems', 'php_getlistquery'), 'views' => 'dynamic_gets', 'not_base64' => array(), 'name' => 'name' ), - // #__componentbuilder_template + // #__componentbuilder_template (j) 'template' => array( - 'search' => array('id', 'name', 'php_view','template'), + 'search' => array('id', 'name', 'php_view', 'template'), 'views' => 'templates', 'not_base64' => array(), 'name' => 'name' ), - // #__componentbuilder_layout + // #__componentbuilder_layout (k) 'layout' => array( - 'search' => array('id', 'name', 'php_view','layout'), + 'search' => array('id', 'name', 'php_view', 'layout'), 'views' => 'layouts', 'not_base64' => array(), 'name' => 'name' ), - // #__componentbuilder_library + // #__componentbuilder_library (l) 'library' => array( 'search' => array('id', 'name', 'php_setdocument'), 'views' => 'libraries', 'not_base64' => array(), 'name' => 'name' + ), + // #__componentbuilder_custom_code (m) + 'custom_code' => array( + 'search' => array('id', 'system_name', 'code'), + 'views' => 'custom_codes', + 'not_base64' => array(), + 'name' => 'system_name' ) ); diff --git a/admin/models/componentbuilder.php b/admin/models/componentbuilder.php index 19e1f18ef..10e7b1aa2 100644 --- a/admin/models/componentbuilder.php +++ b/admin/models/componentbuilder.php @@ -441,8 +441,9 @@ class ComponentbuilderModelComponentbuilder extends JModelList public function getWiki() { - JFactory::getDocument()->addScriptDeclaration(' - var gewiki = "'. JURI::root() . 'administrator/components/com_componentbuilder/wiki_menu.txt"; + $document = JFactory::getDocument(); + $document->addScriptDeclaration(' + var gewiki = "https://raw.githubusercontent.com/wiki/vdm-io/Joomla-Component-Builder/Home.md"; jQuery(document).ready(function () { jQuery.get(gewiki) .success(function(wiki) { @@ -453,9 +454,10 @@ class ComponentbuilderModelComponentbuilder extends JModelList }); });'); - return '
'.JText::_('COM_COMPONENTBUILDER_THE_TEXT_IS_LOADING').'..
'; + return '
'.JText::_('COM_COMPONENTBUILDER_THE_WIKI_IS_LOADING').'..
'; } + public function getNoticeboard() { diff --git a/admin/models/custom_code.php b/admin/models/custom_code.php index 6d933e0ca..a4611a277 100644 --- a/admin/models/custom_code.php +++ b/admin/models/custom_code.php @@ -825,6 +825,39 @@ class ComponentbuilderModelCustom_code extends JModelAdmin $data['metadata'] = (string) $metadata; } + // few checks with the new option of using custom code in custom code + if (isset($data['code']) && ($placholders = ComponentbuilderHelper::getAllBetween($data['code'], '[CUSTOM' . 'CODE=', ']')) + && ComponentbuilderHelper::checkArray($placholders)) + { + // make sure custom code as Hash (automation) target does not have other custom code placeholders + if (isset($data['target']) && 1 == $data['target']) + { + foreach ($placholders as $placholder) + { + $data['code'] = str_replace('[CUSTOM' . 'CODE=' . $placholder . ']', '', $data['code']); + } + // set title + $title = (count($placholders) == 1) ? JText::_('COM_COMPONENTBUILDER_PLACEHOLDER_REMOVED') : JText::_('COM_COMPONENTBUILDER_PLACEHOLDERS_REMOVED'); + // show message that we have had to remove the custom placeholders + JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_HTHREESHTHREEPCUSTOM_CODE_CAN_ONLY_BE_USED_IN_OTHER_CUSTOM_CODE_IF_SET_AS_BJCB_MANUALB_YOU_CAN_NOT_ADD_THEM_TO_EMHASH_AUTOMATIONEM_CODE_AT_THIS_POINTP', $title), 'Warning'); + } + // make sure that the same custom code is not added to itself + else + { + foreach ($placholders as $placholder) + { + if (strpos($placholder, $data['function_name']) !== false) + { + $data['code'] = str_replace('[CUSTOM' . 'CODE=' . $placholder . ']', '', $data['code']); + // show message that we have had to remove the custom placeholders + JFactory::getApplication()->enqueueMessage(JText::_('COM_COMPONENTBUILDER_HTHREEPLACEHOLDER_REMOVEDHTHREEPBTHISB_CUSTOM_CODE_CAN_ONLY_BE_USED_IN_BOTHERB_CUSTOM_CODE_NOT_IN_IT_SELF_SINCE_THAT_WILL_CAUSE_A_INFINITE_LOOP_IN_THE_COMPILERP'), 'Warning'); + // stop the loop :) + break; + } + } + } + } + // Set the code string to base64 string. if (isset($data['code'])) { diff --git a/admin/models/fields/dbtables.php b/admin/models/fields/dbtables.php index cd3653456..a1594c157 100644 --- a/admin/models/fields/dbtables.php +++ b/admin/models/fields/dbtables.php @@ -35,23 +35,27 @@ class JFormFieldDbtables extends JFormFieldList */ protected function getOptions() { - $db = JFactory::getDBO(); - $tables= $db->getTableList(); - $config = JFactory::getConfig(); - $options = array(); - $db = JFactory::getDBO(); $options[] = JHtml::_('select.option', '', 'Select an option'); - for ($i=0; $i < count($tables); $i++) - { - //only tables with primary key - $db->setQuery('SHOW FIELDS FROM `'.$tables[$i].'` WHERE LOWER( `Key` ) = \'pri\''); - if ($db->loadResult()) - { - $dbprefix = version_compare(JVERSION,'3.0','lt') ? $config->getValue('config.dbprefix') : $config->get('dbprefix'); $key = $i+1; - $options[$key] = new stdClass; - $options[$key]->value = str_replace($dbprefix, '', $tables[$i]); - $options[$key]->text = $tables[$i]; - } - } + // get db object + $db = JFactory::getDBO(); + // get all tables + $tables= $db->getTableList(); + // get config + $config = JFactory::getConfig(); + $dbprefix = version_compare(JVERSION,'3.0','lt') ? $config->getValue('config.dbprefix') : $config->get('dbprefix'); + $options = array(); + $options[] = JHtml::_('select.option', '', 'Select an option'); + for ($i=0; $i < count($tables); $i++) + { + //only tables with primary key + $db->setQuery('SHOW FIELDS FROM `'.$tables[$i].'` WHERE LOWER( `Key` ) = \'pri\''); + if ($db->loadResult()) + { + $key = $i+1; + $options[$key] = new stdClass; + $options[$key]->value = str_replace($dbprefix, '', $tables[$i]); + $options[$key]->text = $tables[$i]; + } + } return $options; } } diff --git a/admin/models/fieldtype.php b/admin/models/fieldtype.php index 5d0118887..4ebaaab40 100644 --- a/admin/models/fieldtype.php +++ b/admin/models/fieldtype.php @@ -1075,7 +1075,10 @@ class ComponentbuilderModelFieldtype extends JModelAdmin $properties->loadArray($data['properties']); $data['properties'] = (string) $properties; } - elseif (!isset($data['properties'])) + // Also check permission since the value may be removed due to permissions + // Then we do not want to clear it out, but simple ignore the empty properties + elseif (!isset($data['properties']) + && JFactory::getUser()->authorise('fieldtype.edit.properties', 'com_componentbuilder')) { // Set the empty properties to data $data['properties'] = ''; diff --git a/admin/models/forms/admin_fields.xml b/admin/models/forms/admin_fields.xml index 4c3bc5522..2948f6b46 100644 --- a/admin/models/forms/admin_fields.xml +++ b/admin/models/forms/admin_fields.xml @@ -136,7 +136,11 @@ + COM_COMPONENTBUILDER_ADMIN_FIELDS_SHOW_IN_ALL_LIST_VIEWS + + diff --git a/admin/models/forms/admin_view.xml b/admin/models/forms/admin_view.xml index b31ba9b01..ffefef0af 100644 --- a/admin/models/forms/admin_view.xml +++ b/admin/models/forms/admin_view.xml @@ -427,6 +427,8 @@ COM_COMPONENTBUILDER_ADMIN_VIEW_COREEDITOWN + +
@@ -134,7 +134,7 @@ jQuery(document).ready(function($) {
diff --git a/admin/views/componentbuilder/tmpl/default.php b/admin/views/componentbuilder/tmpl/default.php index 9a357b22a..3cba321fa 100644 --- a/admin/views/componentbuilder/tmpl/default.php +++ b/admin/views/componentbuilder/tmpl/default.php @@ -87,7 +87,7 @@ JHtml::_('behavior.tooltip');
- Joomla! Volunteers Portal +
diff --git a/admin/wiki_menu.txt b/admin/wiki_menu.txt deleted file mode 100644 index a26c43e03..000000000 --- a/admin/wiki_menu.txt +++ /dev/null @@ -1,396 +0,0 @@ -## JCB Wiki! - -> These tutorials will give you a basic understanding on how JCB works! - -A new manual to accompany these videos is underway titled [Developing with Joomla Component Builder](https://github.com/vdm-io/Joomla-Component-Builder/wiki/3.-Developing-with-Joomla-Component-Builder). It is a work in progress and anticipated completion date is no later than the end of this year and hopefully sooner. Chapters 1 - 10 have been transcribed from the corresponding videos and are being edited. The first chapter, [Intro to JCB](https://github.com/vdm-io/Joomla-Component-Builder/wiki/4.-Intro-to-JCB) is near completion. I'll do short updates here on progress. - -If you have more questions, [use the forum](https://groups.google.com/a/vdm.io/d/forum/jcb)! - -The [list of videos](https://www.youtube.com/playlist?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) that are already available are listed below. - -# [Intro](https://youtu.be/9evJkBTnKxE?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ Basic introduction - -# [Installation](https://youtu.be/t6Eux157428?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ Basic installation instructions - -# [General Planning](https://youtu.be/gEgwiVNj6N0?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ Planning your component - -# [Field Types](https://youtu.be/OhLzvThDXls?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [01:05](https://youtu.be/OhLzvThDXls?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m5s) **Field types** _Create Field Types Using basic joomla article to explain field types and their relationship within views_ -+ [01:57](https://youtu.be/OhLzvThDXls?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m57s) **List view** _Difference between list view and edit view. Plural and single_ -+ [05:45](https://youtu.be/OhLzvThDXls?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=5m45s) **Compile error** _Remember to select correct options that suit your build._ -+ [06:35](https://youtu.be/OhLzvThDXls?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=6m35s) **Install compiled component** _Installing from within component builder, quick link_ -+ [08:04](https://youtu.be/OhLzvThDXls?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=8m4s) **Admin fields-views edit** _explanation of adding-editing fields_ -+ [09:26](https://youtu.be/OhLzvThDXls?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=9m26s) **Default field-types** _Default field-types that come shipped within Component_ -+ [12:29](https://youtu.be/OhLzvThDXls?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=12m29s) **Joomla standard form fields** _Joomla website for standards regarding form fields_ -+ [14:05](https://youtu.be/OhLzvThDXls?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=14m05s) **XML string format for joomla** _Reusable field types_ -+ [14:45](https://youtu.be/OhLzvThDXls?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=14m45s) **Text field type example** _Fields within Text field type_ -+ [15:15](https://youtu.be/OhLzvThDXls?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=15m15s) **Joomla XML example Text Field** _XML example_ -+ [17:43](https://youtu.be/OhLzvThDXls?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=17m43s) **XML string within compilier** _How XML string is build and compilied within component builder._ - -# [Basic Fields](https://youtu.be/9NO2rKnC6Ug?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [01:05](https://youtu.be/9NO2rKnC6Ug?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m5s) **New Field Type** _Using text field as example_ -+ [01:08](https://youtu.be/9NO2rKnC6Ug?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m8s) **Basic field type** _Using text field as example_ -+ [03:16](https://youtu.be/9NO2rKnC6Ug?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m16s) **Data Types** _Basic introduction to data types_ -+ [03:35](https://youtu.be/9NO2rKnC6Ug?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m35s) **Indexes Types** -+ [04:29](https://youtu.be/9NO2rKnC6Ug?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=4m29s) **Store Method** _Default, JSON and other options_ -+ [08:00](https://youtu.be/9NO2rKnC6Ug?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=8m) **Compiled info in UI** _Explanation of compiled fields_ -+ [09:30](https://youtu.be/9NO2rKnC6Ug?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=9m30s) **Store Methods support Encryption** _Encryption of fields supported_ -+ [10:50](https://youtu.be/9NO2rKnC6Ug?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=10m50s) **Example E-mail Field** _E-mail field and XML fields example_ -+ [14:30](https://youtu.be/9NO2rKnC6Ug?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=14m30s) **Target Fields with custom CSS/Javascript** _Adding custom CSS/javascript to fields, in both edit and list views using Jform and Jquery_ -+ [17:52](https://youtu.be/9NO2rKnC6Ug?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=17m52s) **Repeatable field with date** _Adding PHP and Javascript in custom script_ -+ [20:29](https://youtu.be/9NO2rKnC6Ug?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=20m29s) **List Field and adding options, Static** _Setting up a static list field_ -+ [24:43](https://youtu.be/9NO2rKnC6Ug?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=24m43s) **Radio Button example** -+ [26:57](https://youtu.be/9NO2rKnC6Ug?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=26m57s) **Colour Field example** -+ [28:00](https://youtu.be/9NO2rKnC6Ug?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=28m) **Showon Attrib example** -+ [29:24](https://youtu.be/9NO2rKnC6Ug?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=29m24s) **Category Field example** -+ [32:14](https://youtu.be/9NO2rKnC6Ug?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=32m14s) **Editor Field example** -+ [33:30](https://youtu.be/9NO2rKnC6Ug?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=33m30s) **Media Field example** -+ [34:37](https://youtu.be/9NO2rKnC6Ug?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=34m37s) **Notes Field example** -+ [37:20](https://youtu.be/9NO2rKnC6Ug?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=37m20s) **Translation brief overview** - -# [Admin Views](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [01:05](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m5s) **Admin Views/ Naming convention** -+ [03:00](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m) **Example View Preacher** -+ [04:35](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=4m35s) **View Icons** -+ [06:19](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=6m19s) **Permission Implementation** -+ [19:25](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=19m25s) **Tabs** -+ [19:34](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=19m34s) **Tabs - Default - Publishing -Permissions** -+ [20:30](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=20m30s) **Tabs - Preacher example** -+ [20:55](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=20m55s) **Tabs - Fields Linking (Preacher)** -+ [22:20](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=22m20s) **Tabs - Fields Linked Views (Sermons)** -+ [32:28](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=32m28s) **Fields** -+ [38:00](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=38m) **Fields Alignment in Admin View** -+ [40:35](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=40m35s) **Fields Alignment order** -+ [41:45](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=41m45s) **Fields Title - Alias** -+ [43:46](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=43m46s) **Conditions** -+ [44:37](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=44m37s) **Conditions using Sermons example** -+ [59:58](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=59m58s) **Field Listing** -+ [60:15](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=60m15s) **Custom CSS View - List** -+ [60:42](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=60m42s) **Custom Javascript View - List Footer** -+ [61:46](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=61m46s) **Custom PhP - Adding AJAX for Controller - Model** -+ [70:50](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=70m50s) **Get Item - Items Joomla API Method** -+ [72:09](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=72m9s) **Batch Copy - Move Method** -+ [75:07](https://youtu.be/CdSKSCTzmRA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=75m7s) **MySQL Dumps Test Data (insert into table)** - -# [Advanced Fields](https://youtu.be/VpzYbifqv0M?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:39](https://youtu.be/VpzYbifqv0M?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=39s) **Local file list example** -+ [05:29](https://youtu.be/VpzYbifqv0M?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=5m29s) **Sermon Preacher Custom Field** -+ [07:29](https://youtu.be/VpzYbifqv0M?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=7m29s) **Field Information Guide** -+ [08:00](https://youtu.be/VpzYbifqv0M?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=8m) **Jform in Component Builder** -+ [09:21](https://youtu.be/VpzYbifqv0M?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=9m21s) **Extending List in Custom Field** -+ [10:50](https://youtu.be/VpzYbifqv0M?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=10m50s) **Naming Convention for Component and Table names** -+ [16:02](https://youtu.be/VpzYbifqv0M?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=16m2s) **Custom PHP layout in Field Definition** -+ [18:08](https://youtu.be/VpzYbifqv0M?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=18m8s) **Built code for Sermon Preacher** -+ [22:36](https://youtu.be/VpzYbifqv0M?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=22m36s) **Dropbox custom List example** -+ [23:32](https://youtu.be/VpzYbifqv0M?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=23m32s) **Component Helper Class** -+ [31:02](https://youtu.be/VpzYbifqv0M?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=31m2s) **Custom User** -+ [40:40](https://youtu.be/VpzYbifqv0M?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=40m40s) **Repeatable Custom Fields** -+ [45:21](https://youtu.be/VpzYbifqv0M?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=45m21s) **Joomla Icons Info & Link** - -# [Adding Admin Views to a Component](https://youtu.be/39vY66X7GGU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:54](https://youtu.be/39vY66X7GGU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=54s) **Sermon Component settings as Example** -+ [01:43](https://youtu.be/39vY66X7GGU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m43s) **Adding Views settings icons** -+ [02:45](https://youtu.be/39vY66X7GGU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=2m45s) **Settings Switch Admin Menu** -+ [03:00](https://youtu.be/39vY66X7GGU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m) **Settings Switch Dashboard Items** -+ [03:45](https://youtu.be/39vY66X7GGU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m45s) **Settings Switch Submenu** -+ [03:58](https://youtu.be/39vY66X7GGU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m58s) **Settings Switch Auto Check-in** -+ [05:04](https://youtu.be/39vY66X7GGU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=5m4s) **Settings Switch Keep History** -+ [14:15](https://youtu.be/39vY66X7GGU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=14m15s) **Settings Switch MetaData** -+ [15:32](https://youtu.be/39vY66X7GGU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=15m32s) **Settings Switch Access** -+ [16:34](https://youtu.be/39vY66X7GGU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=16m34s) **Settings Switch Export/Import** -+ [18:14](https://youtu.be/39vY66X7GGU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=18m14s) **Settings Switch Edit - Create - Site Views** -+ [24:38](https://youtu.be/39vY66X7GGU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=24m38s) **Settings Switch Order** - -# [Component Settings](https://youtu.be/V2WkTjNFjvo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:50](https://youtu.be/V2WkTjNFjvo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=50s) **Compiler Info** -+ [04:20](https://youtu.be/V2WkTjNFjvo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=4m20s) **Adding Custom Files - Folders** -+ [04:54](https://youtu.be/V2WkTjNFjvo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=4m54s) **Adding Custom Admin Views** -+ [07:28](https://youtu.be/V2WkTjNFjvo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=7m28s) **Adding Custom Config Fields** -+ [08:21](https://youtu.be/V2WkTjNFjvo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=8m21s) **Custom Switches using Sermon Component as example** -+ [09:45](https://youtu.be/V2WkTjNFjvo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=9m45s) **Adding Contributers** -+ [10:25](https://youtu.be/V2WkTjNFjvo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=10m25s) **Adding Uikit** -+ [11:05](https://youtu.be/V2WkTjNFjvo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=11m5s) **Adding Fields to Custom Config Fields** -+ [13:27](https://youtu.be/V2WkTjNFjvo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=13m27s) **Space HR field in Component Fields** -+ [15:09](https://youtu.be/V2WkTjNFjvo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=15m9s) **Tab - View names fields added to Site Menu** -+ [20:00](https://youtu.be/V2WkTjNFjvo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=20m) **Site View explanation of above tabs** -+ [20:52](https://youtu.be/V2WkTjNFjvo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=20m52s) **Quick explanation of creating site views** - -# [Component Scripts](https://youtu.be/xY9TWQrF8AQ?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:46](https://youtu.be/xY9TWQrF8AQ?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=46s) **Create User Helper Methods** -+ [01:45](https://youtu.be/xY9TWQrF8AQ?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m45s) **Example Helper Method (Create User)** -+ [07:15](https://youtu.be/xY9TWQrF8AQ?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=7m15s) **Add UiKit** -+ [07:35](https://youtu.be/xY9TWQrF8AQ?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=7m35s) **Add Global CSS to Admin Backend** -+ [07:45](https://youtu.be/xY9TWQrF8AQ?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=7m45s) **Add Custom PhP Helper Admin Class** -+ [08:00](https://youtu.be/xY9TWQrF8AQ?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=8m) **Add Global Admin Event** -+ [11:36](https://youtu.be/xY9TWQrF8AQ?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=11m36s) **Add Custom PhP Helper Site Class** -+ [13:50](https://youtu.be/xY9TWQrF8AQ?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=13m50s) **Add MySQL Dump (Att 2nd place it can be done)** -+ [14:15](https://youtu.be/xY9TWQrF8AQ?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=14m15s) **Dashboard Methods (With Example)** - -# [Component FTP and more](https://youtu.be/hzbZlLl-xlA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:05](https://youtu.be/hzbZlLl-xlA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=5s) **Adding Readme script** -+ [01:30](https://youtu.be/hzbZlLl-xlA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m30s) **Place Holders** -+ [02:20](https://youtu.be/hzbZlLl-xlA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=2m20s) **Component-Builder Link Back Info*** -+ [02:47](https://youtu.be/hzbZlLl-xlA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=2m47s) **Markdown Info** -+ [03:10](https://youtu.be/hzbZlLl-xlA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m10s) **Admin - Site Views Adding Editing** -+ [03:52](https://youtu.be/hzbZlLl-xlA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m52s) **FTP Info - Updating Component** -+ [06:30](https://youtu.be/hzbZlLl-xlA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=6m30s) **FTP Info - Sales Server** -+ [08:03](https://youtu.be/hzbZlLl-xlA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=8m3s) **Component Builder Global Options** -+ [08:13](https://youtu.be/hzbZlLl-xlA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=8m13s) **Component Builder Encryption Settings** -+ [09:07](https://youtu.be/hzbZlLl-xlA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=9m7s) **Component Builder Folder Paths** -+ [12:20](https://youtu.be/hzbZlLl-xlA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=12m20s) **Component Builder Compiler.PhP FTP Info** -+ [14:15](https://youtu.be/hzbZlLl-xlA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=14m15s) **Update Server extra Info (Versions)** - -# [dynamicGet](https://youtu.be/OPuCoxPW35s?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:15](https://youtu.be/OPuCoxPW35s?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=15s) **Sermon - Preacher Get Example** -+ [00:40](https://youtu.be/OPuCoxPW35s?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=40s) **Dynamic Get Source Selection** -+ [03:45](https://youtu.be/OPuCoxPW35s?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m45s) **Dynamic Get Preacher View** -+ [04:23](https://youtu.be/OPuCoxPW35s?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=4m23s) **Get Types - Get Item/List Get Custom** -+ [06:42](https://youtu.be/OPuCoxPW35s?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=6m42s) **Get List Pagination** -+ [08:50](https://youtu.be/OPuCoxPW35s?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=8m50s) **Join Data Views - Tables** -+ [10:22](https://youtu.be/OPuCoxPW35s?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=10m22s) **Join View Tables Example** -+ [15:00](https://youtu.be/OPuCoxPW35s?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=15m) **Dynamic Get Sermon Preacher in Code** -+ [21:49](https://youtu.be/OPuCoxPW35s?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=21m49s) **Dynamic Get Custom Script** -+ [23:18](https://youtu.be/OPuCoxPW35s?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=23m18s) **Dynamic Get Join DB Tables** -+ [24:05](https://youtu.be/OPuCoxPW35s?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=24m5s) **Dynamic Get Filters - Where - Ordering - Globals** -+ [27:34](https://youtu.be/OPuCoxPW35s?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=27m34s) **Dynamic Get Get Access (Default added)** -+ [29:49](https://youtu.be/OPuCoxPW35s?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=29m49s) **Dynamic Get Where** -+ [30:41](https://youtu.be/OPuCoxPW35s?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=30m41s) **Dynamic Get Ordering** - -# [Adding dynamicGet to a Site View](https://youtu.be/vEJZe6XqHJE?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:24](https://youtu.be/vEJZe6XqHJE?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=24s) **Checking the Target Datasets** -+ [00:35](https://youtu.be/vEJZe6XqHJE?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=35s) **Populate Fields from Get's** -+ [01:38](https://youtu.be/vEJZe6XqHJE?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m38s) **Dynamic Values** -+ [03:29](https://youtu.be/vEJZe6XqHJE?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m29s) **Inserting Values into View** -+ [06:35](https://youtu.be/vEJZe6XqHJE?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=6m35s) **Var Dump** -+ [07:45](https://youtu.be/vEJZe6XqHJE?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=7m45s) **Gets in the Code eg: Preacher.php** -+ [09:17](https://youtu.be/vEJZe6XqHJE?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=9m17s) **Looking at the Dynamic get** -+ [10:59](https://youtu.be/vEJZe6XqHJE?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=10m59s) **Preacher View.html.php generated code** -+ [11:50](https://youtu.be/vEJZe6XqHJE?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=11m50s) **Checking the target datasets** -+ [13:40](https://youtu.be/vEJZe6XqHJE?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=13m40s) **Site Preacher tmpl folder** - -# [Adding Templates and Layouts to a Site View](https://youtu.be/6VBbi3Rl2eY?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:05](https://youtu.be/6VBbi3Rl2eY?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=5s) **Relationship between templates/layouts in views** -+ [00:47](https://youtu.be/6VBbi3Rl2eY?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=47s) **Preacher View Example** -+ [01:38](https://youtu.be/6VBbi3Rl2eY?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m38s) **Preacher Site View Example** -+ [02:20](https://youtu.be/6VBbi3Rl2eY?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=2m20s) **Location of Templates** -+ [03:40](https://youtu.be/6VBbi3Rl2eY?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m40s) **Default View in Code** -+ [06:47](https://youtu.be/6VBbi3Rl2eY?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=6m47s) **Quick Layout Example Within View** -+ [08:00](https://youtu.be/6VBbi3Rl2eY?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=8m) **Explantation Templates / Layouts within Joomla** - -# [Template Setup](https://youtu.be/khxKeeubhiY?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:10](https://youtu.be/khxKeeubhiY?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=10s) **Creating Templates** -+ [00:37](https://youtu.be/khxKeeubhiY?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=37s) **New - Copying templates** -+ [01:25](https://youtu.be/khxKeeubhiY?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m25s) **Language String** -+ [02:20](https://youtu.be/khxKeeubhiY?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=2m20s) **Adding custom script/code to template** -+ [03:10](https://youtu.be/khxKeeubhiY?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m10s) **Adding Javascript to template** - -# [Layout Setup](https://youtu.be/52OLSZio0F8?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:05](https://youtu.be/52OLSZio0F8?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=5s) **Layouts** -+ [00:40](https://youtu.be/52OLSZio0F8?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=40s) **How layouts work with dynamic gets** -+ [01:53](https://youtu.be/52OLSZio0F8?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m53s) **How Templates call Layouts** -+ [03:10](https://youtu.be/52OLSZio0F8?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m10s) **Sermon List-item Layout** -+ [04:00](https://youtu.be/52OLSZio0F8?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=4m) **Using the View Key** -+ [05:16](https://youtu.be/52OLSZio0F8?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=5m16s) **Layout to Template Custom Scripting** -+ [06:00](https://youtu.be/52OLSZio0F8?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=6m) **Dynamic Custom Views using Template** -+ [06:20](https://youtu.be/52OLSZio0F8?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=6m20s) **Above in the Code** -+ [07:35](https://youtu.be/52OLSZio0F8?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=7m35s) **Config.xml** -+ [09:30](https://youtu.be/52OLSZio0F8?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=9m30s) **Layout Concept** -+ [11:05](https://youtu.be/52OLSZio0F8?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=11m5s) **Layout Custom Script Area** - -# [Custom Admin Views](https://youtu.be/gtdQ1lwB9ds?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:35](https://youtu.be/gtdQ1lwB9ds?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=35s) **Example view from other Component** -+ [03:55](https://youtu.be/gtdQ1lwB9ds?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m55s) **Component Builder Custom Admin View from above** -+ [04:15](https://youtu.be/gtdQ1lwB9ds?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=4m15s) **Add custom button example** -+ [05:13](https://youtu.be/gtdQ1lwB9ds?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=5m13s) **Adding Script for the controller methods** -+ [06:20](https://youtu.be/gtdQ1lwB9ds?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=6m20s) **Area for Custom Scripting** -+ [07:00](https://youtu.be/gtdQ1lwB9ds?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=7m) **Combing multiple data results example** - -# [Adding Site Views to a Component](https://youtu.be/zZ_HJeYL8ps?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:30](https://youtu.be/zZ_HJeYL8ps?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=30s) **Using Sermon Dist as Example** -+ [00:42](https://youtu.be/zZ_HJeYL8ps?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=42s) **Settings - Views** -+ [01:25](https://youtu.be/zZ_HJeYL8ps?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m25s) **Adding Site Views Important *Glitch*** -+ [02:34](https://youtu.be/zZ_HJeYL8ps?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=2m34s) **Site View Options (Menu-Metadata-Default View-Access)** - -# [Adding Custom Admin Views to a Component](https://youtu.be/sPEkbuNXwds?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:03](https://youtu.be/sPEkbuNXwds?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3s) **Example Component not Sermon Dist** -+ [00:16](https://youtu.be/sPEkbuNXwds?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=16s) **Settings - Settings - Custom Admin View** -+ [00:34](https://youtu.be/sPEkbuNXwds?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=34s) **Multiple Switches due to being dynamic** -+ [00:56](https://youtu.be/sPEkbuNXwds?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=56s) **Icon-main menu-dashboard-sub menu see time for more switches** -+ [01:45](https://youtu.be/sPEkbuNXwds?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m45s) **Targeting Item so some switches are No** -+ [01:55](https://youtu.be/sPEkbuNXwds?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m55s) **Select target view** -+ [02:19](https://youtu.be/sPEkbuNXwds?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=2m19s) **Showing within the component** -+ [03:46](https://youtu.be/sPEkbuNXwds?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m46s) **Order Before Selection** -+ **View rest for how buttons are implemented - *Important*** - -# [Tweaking MySQL Demo Data](https://youtu.be/wkSLZUEN-RE?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [Global Settings of Component Builder](https://youtu.be/LA2WDi8G79E?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:25](https://youtu.be/LA2WDi8G79E?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=25s) **Options Button For Global Config** -+ [01:20](https://youtu.be/LA2WDi8G79E?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m20s) **Check in Timer** -+ [01:49](https://youtu.be/LA2WDi8G79E?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m49s) **Enable Versions** -+ [02:28](https://youtu.be/LA2WDi8G79E?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=2m28s) **Minify JS** -+ [03:14](https://youtu.be/LA2WDi8G79E?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m14s) **Contributor Info** -+ [03:40](https://youtu.be/LA2WDi8G79E?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m40s) **UiKit Settings** -+ [04:48](https://youtu.be/LA2WDi8G79E?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=4m48s) **Encryption Settings *Key Important*** -+ [05:41](https://youtu.be/LA2WDi8G79E?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=5m41s) **Folder Paths** -+ [06:53](https://youtu.be/LA2WDi8G79E?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=6m53s) **Permissions** -+ [11:25](https://youtu.be/LA2WDi8G79E?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=11m25s) **Example Preacher Permissions** -+ [13:15](https://youtu.be/LA2WDi8G79E?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=13m15s) **Field Permission Switch** - -# [Adding a custom time field](https://youtu.be/epA9zv4yWu0?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:06](https://youtu.be/epA9zv4yWu0?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=6s) **Fields** -+ [02:25](https://youtu.be/epA9zv4yWu0?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=2m25s) **Joomla Form-rule Example** -+ [04:30](https://youtu.be/epA9zv4yWu0?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=4m30s) **Component builder new text field example** -+ [05:19](https://youtu.be/epA9zv4yWu0?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=5m19s) **Script JS** -+ [07:00](https://youtu.be/epA9zv4yWu0?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=7m) **Example time-date (custom component)** -+ [08:51](https://youtu.be/epA9zv4yWu0?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=8m51s) **JS repeatable field time-date *Important*** - -# [How to integrate the Create User Helper Method in your Components](https://youtu.be/ckFakaQ90JY?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [How to use email helper in your components.](https://youtu.be/tp6mMUTOF2Y?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:25](https://youtu.be/tp6mMUTOF2Y?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=25s) **Example of Email Helper Class** -+ [01:10](https://youtu.be/tp6mMUTOF2Y?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m10s) **Setting Up Email Helper Class** -+ [01:20](https://youtu.be/tp6mMUTOF2Y?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m20s) **Libs - Helpers in Component** -+ [01:50](https://youtu.be/tp6mMUTOF2Y?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m50s) **Settings - Config area** -+ [03:05](https://youtu.be/tp6mMUTOF2Y?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m05s) **In Code Field Names** -+ [03:36](https://youtu.be/tp6mMUTOF2Y?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m36s) **Component Global Options - Mail Configuration** -+ [04:00](https://youtu.be/tp6mMUTOF2Y?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=4m) **Switch Global Mailer Options** -+ [04:12](https://youtu.be/tp6mMUTOF2Y?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=4m12s) **Joomla Global Configuration - Server** -+ [05:10](https://youtu.be/tp6mMUTOF2Y?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=5m10s) **Component Builder Email Switch Options** -+ [05:42](https://youtu.be/tp6mMUTOF2Y?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=5m42s) **DKIM Settings (Encryption)** -+ [07:15](https://youtu.be/tp6mMUTOF2Y?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=7m15s) **Default Global in Code** -+ [08:45](https://youtu.be/tp6mMUTOF2Y?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=8m45s) **DKIM Values in Code** -+ [09:30](https://youtu.be/tp6mMUTOF2Y?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=9m30s) **Error Checking for emails in code** -+ [11:45](https://youtu.be/tp6mMUTOF2Y?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=11m45s) **Implementated example** -+ [13:56](https://youtu.be/tp6mMUTOF2Y?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=13m56s) **Above example in code *Worth Watching*** - -# [How to setup a store message method along side the email helper class](https://youtu.be/peVNLsAncGY?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:03](https://youtu.be/peVNLsAncGY?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3s) **Example in Code** -+ [01:31](https://youtu.be/peVNLsAncGY?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m31s) **Code Snippet in Method** -+ [02:17](https://youtu.be/peVNLsAncGY?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=2m17s) **Adding Code to Admin Helper Area** -+ ***Important watch to end*** - -# [How to ensure that a field is not escaped when added to list views.](https://youtu.be/bfl0l3AoLKU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:02](https://youtu.be/bfl0l3AoLKU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=2s) **Example extra styling in fields** -+ [00:37](https://youtu.be/bfl0l3AoLKU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=37s) **Settings - Editing View - PhP Area** -+ [01:05](https://youtu.be/bfl0l3AoLKU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m5s) **Settings Values in the code - Add PhP Getitems Method** -+ [02:00](https://youtu.be/bfl0l3AoLKU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=2m) **Looping through data till target found - adding styling** -+ [03:20](https://youtu.be/bfl0l3AoLKU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m20s) **Preventing the escaped info** -+ [04:16](https://youtu.be/bfl0l3AoLKU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=4m16s) **Field adding escape=false to code** - -# [How to change exported values and setup custom import options](https://youtu.be/fau5mZ6naLc?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:25](https://youtu.be/fau5mZ6naLc?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=25s) **Example Component** -+ [01:00](https://youtu.be/fau5mZ6naLc?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m) **Example IP Tables** -+ [01:39](https://youtu.be/fau5mZ6naLc?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m39s) **Export feature** -+ [02:56](https://youtu.be/fau5mZ6naLc?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=2m56s) **Exported example in xls format** -+ [03:27](https://youtu.be/fau5mZ6naLc?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m27s) **Export data in code** -+ [05:06](https://youtu.be/fau5mZ6naLc?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=5m6s) **Admin View - PhP - (GetListQuery)** -+ [09:37](https://youtu.be/fau5mZ6naLc?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=9m37s) **Import features explained** -+ [10:15](https://youtu.be/fau5mZ6naLc?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=10m15s) **Custom Import Tab (default import code)** - -# [How to overwrite the custom fields](https://youtu.be/FHQfIhWHYyQ?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:03](https://youtu.be/FHQfIhWHYyQ?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3s) **Using default fields with custom code** -+ [01:33](https://youtu.be/FHQfIhWHYyQ?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=1m33s) **Example of shown default fields in list view** -+ [02:50](https://youtu.be/FHQfIhWHYyQ?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=2m50s) **Example created_by field in View** -+ [03:56](https://youtu.be/FHQfIhWHYyQ?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m56s) **Compiled in code** -+ [05:12](https://youtu.be/FHQfIhWHYyQ?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=5m12s) **Adding the Fields** -+ [05:45](https://youtu.be/FHQfIhWHYyQ?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=5m45s) **Adding in tabs (default 15 tab)** - -# [How to filter a list field based on association with another field](https://youtu.be/Z8FLifQOjUk?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:02](https://youtu.be/Z8FLifQOjUk?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=2s) **Explanation of filter fields** -+ [00:45](https://youtu.be/Z8FLifQOjUk?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=45s) **Example component with filters** -+ ***Volume to low to fully understand - Will be done over soon*** - -# [Automatic import of custom code during compilation in JCB](https://youtu.be/DFMfIl-VkSk?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -*Excellent Update to JCB* -+ [00:02](https://youtu.be/DFMfIl-VkSk?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=2s) **Custom Code** -+ [02:00](https://youtu.be/DFMfIl-VkSk?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=2m) **Example demo compiled** -+ [02:35](https://youtu.be/DFMfIl-VkSk?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=2m35s) **Editing code in the editor** -+ [03:13](https://youtu.be/DFMfIl-VkSk?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m13s) **Conventions used (Insert code - Replace code)** -+ [05:45](https://youtu.be/DFMfIl-VkSk?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=5m45s) **Limitations for Inserting and updating** -+ [08:11](https://youtu.be/DFMfIl-VkSk?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=8m11s) **Showing example with replace** -+ [09:06](https://youtu.be/DFMfIl-VkSk?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=9m06s) **Recompiling the demo component with replace** -+ [09:30](https://youtu.be/DFMfIl-VkSk?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=9m30s) **Checking the custom code tab before installing** -+ [10:00](https://youtu.be/DFMfIl-VkSk?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=10m) **Looking at the replaced code in editor** -+ [11:40](https://youtu.be/DFMfIl-VkSk?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=11m40s) **Inserting custom code via editor** -+ [13:55](https://youtu.be/DFMfIl-VkSk?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=13m55s) **Checking the custom code tab for new entry before new installation** - -[[TIPS: Custom Code]] - -# [JCB manual custom code implementation](https://youtu.be/KiAtJawZ3oo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) -+ [00:02](https://youtu.be/KiAtJawZ3oo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=2s) **Brief explanation** -+ [03:18](https://youtu.be/KiAtJawZ3oo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=3m18s) **Updating code from JCB in the editor** -+ [06:43](https://youtu.be/KiAtJawZ3oo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=6m43s) **Github explanation for update and insert issue 37** -+ [12:34](https://youtu.be/KiAtJawZ3oo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=12m34s) **Custom Codes in JCB** -+ [13:00](https://youtu.be/KiAtJawZ3oo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=13m) **Placeholder** -+ [13:57](https://youtu.be/KiAtJawZ3oo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=13m57s) **Example Field** -+ [18:55](https://youtu.be/KiAtJawZ3oo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&t=18m55s) **Difference between editor changes and custom code changes** -+ ***Imptortant - Watch till end*** - -# [Export & Import of fully mapped components](https://youtu.be/lkE0ZiSWufg?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [Translation Manager in JCB explained](https://youtu.be/zzAcVkn_cWU?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [How to import JCB package using a KEY](https://www.youtube.com/watch?v=PGmEoliopv8&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=64) - -# [Setting Site View Permission](https://youtu.be/gWjQjdhYqXI?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [Auto create SQL updates for Components in JCB](https://youtu.be/bRPJTRat158?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [Setup Site Edit View in JCB](https://youtu.be/tmB22d9dQ4M?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [Automated backup system in JCB](https://youtu.be/GUWZaODo_IM?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [Adding Helper Structures to any JCB component](https://youtu.be/nw9YPu9emws?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [Upgrade to JCB v2.5.8 and using the new Admin View and Admin Fields](https://youtu.be/YaycQcsMpOs?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [How to setup taps after upgrade to v2.5.8 in JCB](https://youtu.be/NFp_CtE0LZI?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [Major Release of JCB v2.6.0](https://youtu.be/MQrLBYhvGyA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [Hello World Component with Joomla Component Builder/Creator - Extended](https://youtu.be/IQfsLYIeblk?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [Adding your own rule validation to a field in JCB](https://youtu.be/Z6-ggKtX35o?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [General overview of how community snippets work](https://youtu.be/qr4I1jeCp7I?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [Tutorial on forking JCB snippets so you can share your snippets with the rest of the Cummunity](https://youtu.be/0hgHeQVTLOk?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [Tutorial on making a pull request at Joomla Component Builder Snippets](https://youtu.be/vQ-yxVtc-Co?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [The New Library Manager Area](https://youtu.be/rDjvgLYOt1o?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [Easy Translation via excel](https://youtu.be/q5NwKGnOHoQ?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [Dynamic Router Implementation Explained](https://youtu.be/hYycPLbaMos?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [Automated database updates in Joomla during development of a component](https://youtu.be/zN2M15fzf_M?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [Quick Subform Demonstration](https://youtu.be/3j4xPQC4apI?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [VDM Package Import Option](https://youtu.be/OHvawooT67s?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [Dynamic File and Folder Inclusion concept](https://youtu.be/_c7wzW075lA?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [How to use the file field type to upload a file in JCB](https://youtu.be/o482sK4DxkM?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [Drag and Drop Upload functionality in JCB](https://youtu.be/UvzDyVQyHDI?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [The Quick Hello Word with JCB](https://youtu.be/MEKs1c7LfO8?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [Adding none database fields to an admin view](https://youtu.be/6OTRDIgxgq0?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# [The custom dashboard option in JCB](https://youtu.be/tU7TeYn1Djo?list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE) - -# More coming.... - -> I will constantly be adding more tutorials, and would encourage you to support our efforts. -## Come on buy me a coffee :) - - * PayPal: [paypal.me/asseblief](https://www.paypal.me/asseblief) - * Bitcoin: 18vURxYpPFjvNk8BnUy1ovCAyQmY3MzkSf - * Ethereum: 0x9548144662b47327c954f3e214edb96662d51218 diff --git a/componentbuilder.xml b/componentbuilder.xml index c44cf475f..baf02b816 100644 --- a/componentbuilder.xml +++ b/componentbuilder.xml @@ -1,7 +1,7 @@ COM_COMPONENTBUILDER - 7th October, 2018 + 27th November, 2018 Llewellyn van der Merwe llewellyn@joomlacomponentbuilder.com http://www.joomlacomponentbuilder.com @@ -103,7 +103,6 @@ Whether you're a seasoned [Joomla](https://extensions.joomla.org/extension/compo controller.php componentbuilder.php README.txt - wiki_menu.txt README.txt assets controllers diff --git a/script.php b/script.php index 541b1678e..2144f8891 100644 --- a/script.php +++ b/script.php @@ -3467,6 +3467,16 @@ class com_componentbuilderInstallerScript } } } + // target version less then 2.9.8 + if (count($this->JCBversion) == 3 && $this->JCBversion[0] <= 2 && (($this->JCBversion[1] == 9 && $this->JCBversion[2] <= 7) || $this->JCBversion[1] < 9)) + { + // check if this install has the wiki file (just remove it) + $wiki_menu = JPATH_ADMINISTRATOR . '/components/com_componentbuilder/wiki_menu.txt'; + if (JFile::exists($wiki_menu)) + { + JFile::delete($wiki_menu); + } + } } } // do any install needed diff --git a/site/helpers/componentbuilder.php b/site/helpers/componentbuilder.php index abb9df196..6fa255e0a 100644 --- a/site/helpers/componentbuilder.php +++ b/site/helpers/componentbuilder.php @@ -28,135 +28,50 @@ abstract class ComponentbuilderHelper } /** - * Locked Libraries (we can not have these change) + * Locked Libraries (we can not have these change) **/ public static $libraryNames = array(1 => 'No Library', 2 => 'Bootstrap v4', 3 => 'Uikit v3', 4 => 'Uikit v2', 5 => 'FooTable v2', 6 => 'FooTable v3'); /** - * Array of php fields Allowed (16) + * Array of php fields Allowed (16) **/ public static $phpFieldArray = array('', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'x'); /** - * The global params + * The global params **/ protected static $params = false; /** - * The global updater + * The global updater **/ protected static $globalUpdater = array(); /** - * The local company details + * The local company details **/ protected static $localCompany = array(); /** - * The snippet paths + * The snippet paths **/ public static $snippetPath = 'https://raw.githubusercontent.com/vdm-io/Joomla-Component-Builder-Snippets/master/'; public static $snippetsPath = 'https://api.github.com/repos/vdm-io/Joomla-Component-Builder-Snippets/git/trees/master'; /** - * The VDM packages paths + * The VDM packages paths **/ public static $vdmGithubPackagesUrl = "https://api.github.com/repos/vdm-io/JCB-Packages/git/trees/master"; public static $vdmGithubPackageUrl = "https://github.com/vdm-io/JCB-Packages/raw/master/"; /** - * The JCB packages paths + * The JCB packages paths **/ public static $jcbGithubPackagesUrl = "https://api.github.com/repos/vdm-io/JCB-Community-Packages/git/trees/master"; public static $jcbGithubPackageUrl = "https://github.com/vdm-io/JCB-Community-Packages/raw/master/"; // not needed at this time (maybe latter) public static $accessToken = ""; - - /** - * get the github repo file list - * - * @return array on success - * - */ - public static function getGithubRepoFileList($type, $target) - { - // get the current Packages (public) - if (!$repoData = self::get($type)) - { - if (self::urlExists($target)) - { - $repoData = self::getFileContents($target); - if (self::checkJson($repoData)) - { - $test = json_decode($repoData); - if (self::checkObject($test) && isset($test->tree) && self::checkArray($test->tree) ) - { - // remember to set it - self::set($type, $repoData); - } - // check if we have error message from github - elseif ($errorMessage = self::githubErrorHandeler(array('error' => null), $test)) - { - if (self::checkString($errorMessage['error'])) - { - JFactory::getApplication()->enqueueMessage($errorMessage['error'], 'Error'); - } - $repoData = false; - } - } - else - { - $repoData = false; - } - } - else - { - JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_URL_S_SET_TO_RETRIEVE_THE_PACKAGES_DOES_NOT_EXIST', $target), 'Error'); - } - } - // check if we could find packages - if (isset($repoData) && self::checkJson($repoData)) - { - $repoData = json_decode($repoData); - if (self::checkObject($repoData) && isset($repoData->tree) && self::checkArray($repoData->tree) ) - { - return $repoData->tree; - } - } - return false; - } - - /** - * get the github error messages - * - * @return array of errors on success - * - */ - protected static function githubErrorHandeler($message, &$github) - { - if (self::checkObject($github) && isset($github->message) && self::checkString($github->message)) - { - // set the message - $errorMessage = $github->message; - // add the documentation URL - if (isset($github->documentation_url) && self::checkString($github->documentation_url)) - { - $errorMessage = $errorMessage.'
'.$github->documentation_url; - } - // check the message - if (strpos($errorMessage, 'Authenticated') !== false) - { - // add little more help if it is an access token issue - $errorMessage = JText::sprintf('COM_COMPONENTBUILDER_SBR_YOU_CAN_ADD_AN_BACCESS_TOKENB_TO_GETBIBLE_GLOBAL_OPTIONS_TO_MAKE_AUTHENTICATED_REQUESTS_AN_ACCESS_TOKEN_WITH_ONLY_PUBLIC_ACCESS_WILL_DO', $errorMessage); - } - // set error notice - $message['error'] = $errorMessage; - // we have error message - return $message; - } - return false; - } /** * The array of constant paths @@ -581,72 +496,6 @@ abstract class ComponentbuilderHelper // load this for all jimport('joomla.application'); } - - /** - * Remove folders with files - * - * @param string $dir The path to folder to remove - * @param boolean $ignore The folders and files to ignore and not remove - * - * @return boolean True in all is removed - * - */ - public static function removeFolder($dir, $ignore = false) - { - if (JFolder::exists($dir)) - { - $it = new RecursiveDirectoryIterator($dir); - $it = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST); - foreach ($it as $file) - { - if ('.' === $file->getBasename() || '..' === $file->getBasename()) continue; - if ($file->isDir()) - { - $keeper = false; - if (self::checkArray($ignore)) - { - foreach ($ignore as $keep) - { - if (strpos($file->getPathname(), $dir.'/'.$keep) !== false) - { - $keeper = true; - } - } - } - if ($keeper) - { - continue; - } - JFolder::delete($file->getPathname()); - } - else - { - $keeper = false; - if (self::checkArray($ignore)) - { - foreach ($ignore as $keep) - { - if (strpos($file->getPathname(), $dir.'/'.$keep) !== false) - { - $keeper = true; - } - } - } - if ($keeper) - { - continue; - } - JFile::delete($file->getPathname()); - } - } - if (!self::checkArray($ignore)) - { - return JFolder::delete($dir); - } - return true; - } - return false; - } /** * The dynamic builder of views, tables and fields @@ -656,203 +505,6 @@ abstract class ComponentbuilderHelper self::autoLoader('extrusion'); $extruder = new Extrusion($data); } - - public static function getFieldOptions($value, $type, $settings = array(), $xml = null) - { - // Get a db connection. - $db = JFactory::getDbo(); - - // Create a new query object. - $query = $db->getQuery(true); - $query->select($db->quoteName(array('properties', 'short_description', 'description'))); - $query->from($db->quoteName('#__componentbuilder_fieldtype')); - $query->where($db->quoteName('published') . ' = 1'); - $query->where($db->quoteName($type) . ' = '. $value); - - // Reset the query using our newly populated query object. - $db->setQuery($query); - $db->execute(); - if ($db->getNumRows()) - { - $result = $db->loadObject(); - $properties = json_decode($result->properties, true); - $field = array( - 'subform' => array(), - 'nameListOptions' => array(), - 'php' => array(), - 'values' => " '', - 'short_description' => $result->short_description, - 'description' => $result->description); - // number pointer - $nr = 0; - // value to check since there are false and null values even 0 in the values returned - $confirmation = '8qvZHoyuFYQqpj0YQbc6F3o5DhBlmS-_-a8pmCZfOVSfANjkmV5LG8pCdAY2JNYu6cB'; - // set the headers - $field['values_description'] .= ''; - foreach ($properties as $property) - { - $example = (isset($property['example']) && self::checkString($property['example'])) ? $property['example'] : ''; - $field['values_description'] .= ''; - // check if we should load the value - $value = self::getValueFromXMLstring($xml, $property['name'], $confirmation); - // check if this is a php field - $addPHP = false; - if (strpos($property['name'], 'type_php') !== false) - { - $addPHP = true; - $phpKey = trim(preg_replace('/[0-9]+/', '', $property['name']), '_'); - // start array if not already set - if (!isset($field['php'][$phpKey])) - { - $field['php'][$phpKey] = array(); - $field['php'][$phpKey]['value'] = array(); - $field['php'][$phpKey]['desc'] = $property['description']; - } - } - // was the settings for the property passed - if(self::checkArray($settings) && isset($settings[$property['name']])) - { - // add the xml values - $field['values'] .= PHP_EOL . "\t" . $property['name'] . '="'. $settings[$property['name']] . '" '; - // add the json values - if ($addPHP) - { - $field['php'][$phpKey]['value'][] = $settings[$property['name']]; - } - else - { - $field['subform']['properties'.$nr] = array('name' => $property['name'], 'value' => $settings[$property['name']], 'desc' => $property['description']); - } - } - elseif (!$xml || $confirmation !== $value) - { - // add the xml values - $field['values'] .= PHP_EOL."\t" . $property['name'] . '="' . ($confirmation !== $value) ? $value : $example .'" '; - // add the json values - if ($addPHP) - { - $field['php'][$phpKey]['value'][] = ($confirmation !== $value) ? $value : $example; - } - else - { - $field['subform']['properties' . $nr] = array('name' => $property['name'], 'value' => ($confirmation !== $value) ? $value : $example, 'desc' => $property['description']); - } - } - // add the name List Options - if (!$addPHP) - { - $field['nameListOptions'][$property['name']] = $property['name']; - } - // increment the number - $nr++; - } - $field['values'] .= PHP_EOL . "/>"; - $field['values_description'] .= '
' . JText::_('COM_COMPONENTBUILDER_PROPERTY') . '' . JText::_('COM_COMPONENTBUILDER_EXAMPLE') . '' . JText::_('COM_COMPONENTBUILDER_DESCRIPTION') . '
' . $property['name'] . '' . $example . '' . $property['description'] . '
'; - // return found field options - return $field; - } - return false; - } - - public static function getValueFromXMLstring(&$xml, &$get, $confirmation = '') - { - if (self::checkString($xml)) - { - // if we have a PHP value, we must base64 decode it - if (strpos($get, 'type_php') !== false) - { - return self::openValidBase64(self::getBetween($xml, $get.'="', '"', $confirmation)); - } - return self::getBetween($xml, $get . '="', '"', $confirmation); - } - return $confirmation; - } - - - /** - * The zipper method - * - * @param string $workingDIR The directory where the items must be zipped - * @param string $filepath The path to where the zip file must be placed - * - * @return bool true On success - * - */ - public static function zip($workingDIR, &$filepath) - { - // store the current joomla working directory - $joomla = getcwd(); - - // we are changing the working directory to the component temp folder - chdir($workingDIR); - - // the full file path of the zip file - $filepath = JPath::clean($filepath); - - // delete an existing zip file (or use an exclusion parameter in JFolder::files() - JFile::delete($filepath); - - // get a list of files in the current directory tree - $files = JFolder::files('.', '', true, true); - $zipArray = array(); - // setup the zip array - foreach ($files as $file) - { - $tmp = array(); - $tmp['name'] = str_replace('./', '', $file); - $tmp['data'] = JFile::read($file); - $tmp['time'] = filemtime($file); - $zipArray[] = $tmp; - } - - // change back to joomla working directory - chdir($joomla); - - // get the zip adapter - $zip = JArchive::getAdapter('zip'); - - //create the zip file - if ($zip->create($filepath, $zipArray)) - { - return true; - } - return false; - } - - - /** - * Write a file to the server - * - * @param string $path The path and file name where to safe the data - * @param string $data The data to safe - * - * @return bool true On success - * - */ - public static function writeFile($path, $data) - { - $klaar = false; - if (self::checkString($data)) - { - // open the file - $fh = fopen($path, "w"); - if (!is_resource($fh)) - { - return $klaar; - } - // write to the file - if (fwrite($fh, $data)) - { - // has been done - $klaar = true; - } - // close file. - fclose($fh); - } - return $klaar; - } - /* * Convert repeatable field to subform @@ -965,6 +617,880 @@ abstract class ComponentbuilderHelper } return $object; } + + /** + * Run Global Updater if any are set + * + * @return void + * + */ + public static function runGlobalUpdater() + { + // check if any updates are set to run + if (self::checkArray(self::$globalUpdater)) + { + // get the database object + $db = JFactory::getDbo(); + foreach (self::$globalUpdater as $tableKeyID => $object) + { + // get the table + $table = explode('.', $tableKeyID); + // update the item + $db->updateObject('#__componentbuilder_' . (string) $table[0] , $object, (string) $table[1]); + } + // rest updater + self::$globalUpdater = array(); + } + } + + /** + * Copy Any Item (only use for direct database copying) + * + * @param int $id The item to copy + * @param string $table The table and model to copy from and with + * @param array $config The values that should change + * + * @return boolean True if success + * + */ + public static function copyItem($id, $type, $config = array()) + { + // only continue if we have an id + if ((int) $id > 0) + { + // get the model + $model = self::getModel($type); + $app = \JFactory::getApplication(); + // get item + if ($item = $model->getItem($id)) + { + // update values that should change + if (self::checkArray($config)) + { + foreach($config as $key => $value) + { + if (isset($item->{$key})) + { + $item->{$key} = $value; + } + } + } + // clone the object + $data = array(); + foreach ($item as $key => $value) + { + $data[$key] = $value; + } + // reset some values + $data['id'] = 0; + $data['version'] = 1; + if (isset($data['tags'])) + { + $data['tags'] = null; + } + if (isset($data['associations'])) + { + $data['associations'] = array(); + } + // remove some unneeded values + unset($data['params']); + unset($data['asset_id']); + unset($data['checked_out']); + unset($data['checked_out_time']); + // Attempt to save the data. + if ($model->save($data)) + { + return true; + } + } + } + return false; + } + + /** + * the basic localkey + **/ + protected static $localkey = false; + + /** + * get the localkey + **/ + public static function getLocalKey() + { + if (!self::$localkey) + { + // get the basic key + self::$localkey = md5(self::getCryptKey('basic', 'localKey34fdWEkl')); + } + return self::$localkey; + } + + /** + * indent HTML + */ + public static function indent($html) + { + // load the class + require_once JPATH_ADMINISTRATOR.'/components/com_componentbuilder/helpers/indenter.php'; + // set new indenter + $indenter = new Indenter(); + // return indented html + return $indenter->indent($html); + } + + public static function checkFileType($file, $sufix) + { + // now check if the file ends with the sufix + return $sufix === "" || ($sufix == substr(strrchr($file, "."), -strlen($sufix))); + } + + public static function imageInfo($path, $request = 'type') + { + // set image + $image = JPATH_SITE.'/'.$path; + // check if exists + if (file_exists($image) && $result = @getimagesize($image)) + { + // return type request + switch ($request) + { + case 'width': + return $result[0]; + break; + case 'height': + return $result[1]; + break; + case 'type': + $extensions = array( + IMAGETYPE_GIF => "gif", + IMAGETYPE_JPEG => "jpg", + IMAGETYPE_PNG => "png", + IMAGETYPE_SWF => "swf", + IMAGETYPE_PSD => "psd", + IMAGETYPE_BMP => "bmp", + IMAGETYPE_TIFF_II => "tiff", + IMAGETYPE_TIFF_MM => "tiff", + IMAGETYPE_JPC => "jpc", + IMAGETYPE_JP2 => "jp2", + IMAGETYPE_JPX => "jpx", + IMAGETYPE_JB2 => "jb2", + IMAGETYPE_SWC => "swc", + IMAGETYPE_IFF => "iff", + IMAGETYPE_WBMP => "wbmp", + IMAGETYPE_XBM => "xbm", + IMAGETYPE_ICO => "ico" + ); + return $extensions[$result[2]]; + break; + case 'attr': + return $result[3]; + break; + case 'all': + default: + return $result; + break; + } + } + return false; + } + + /** + * set the session defaults if not set + **/ + protected static function setSessionDefaults() + { + // noting for now + return true; + } + + /** + * check if it is a new hash + **/ + public static function newHash($hash, $name = 'backup', $type = 'hash', $key = '', $fileType = 'txt') + { + // make sure we have a hash + if (self::checkString($hash)) + { + // first get the file path + $path_filename = self::getFilePath('path', $name.$type, $fileType, $key, JPATH_COMPONENT_ADMINISTRATOR); + // set as read if not already set + if ($content = self::getFileContents($path_filename, false)) + { + if ($hash == $content) + { + return false; + } + } + // set the hash + return self::writeFile($path_filename, $hash); + } + return false; + } + + protected static $pkOwnerSearch = array( + 'company' => 'COM_COMPONENTBUILDER_DTCOMPANYDTDDSDD', + 'owner' => 'COM_COMPONENTBUILDER_DTOWNERDTDDSDD', + 'email' => 'COM_COMPONENTBUILDER_DTEMAILDTDDSDD', + 'website' => 'COM_COMPONENTBUILDER_DTWEBSITEDTDDSDD', + 'license' => 'COM_COMPONENTBUILDER_DTLICENSEDTDDSDD', + 'copyright' => 'COM_COMPONENTBUILDER_DTCOPYRIGHTDTDDSDD' + ); + + /** + * get the JCB package owner details display + **/ + public static function getPackageOwnerDetailsDisplay(&$info, $trust = false) + { + $hasOwner = false; + $ownerDetails = ''; + $ownerDetails .= '
'; + // load the list items + foreach (self::$pkOwnerSearch as $key => $dd) + { + if ($value = self::getPackageOwnerValue($key, $info)) + { + $ownerDetails .= JText::sprintf($dd, $value); + // check if we have a owner/source name + if (('owner' === $key || 'company' === $key) && !$hasOwner) + { + $hasOwner = true; + $owner = $value; + } + } + } + $ownerDetails .= '
'; + + // provide some details to how the user can get a key + if ($hasOwner && isset($info['getKeyFrom']['buy_link']) && self::checkString($info['getKeyFrom']['buy_link'])) + { + $ownerDetails .= '
'; + $ownerDetails .= JText::sprintf('COM_COMPONENTBUILDER_BGET_THE_KEY_FROMB_A_SSA', 'class="btn btn-primary" href="'.$info['getKeyFrom']['buy_link'].'" target="_blank" title="get a key from '.$owner.'"', $owner); + } + // add more custom links + elseif ($hasOwner && isset($info['getKeyFrom']['buy_links']) && self::checkArray($info['getKeyFrom']['buy_links'])) + { + $buttons = array(); + foreach ($info['getKeyFrom']['buy_links'] as $keyName => $link) + { + $buttons[] = JText::sprintf('COM_COMPONENTBUILDER_BGET_THE_KEY_FROM_SB_FOR_A_SSA', $owner, 'class="btn btn-primary" href="'.$link.'" target="_blank" title="get a key from '.$owner.'"', $keyName); + } + $ownerDetails .= '
'; + $ownerDetails .= implode('
', $buttons); + } + // return the owner details + if (!$hasOwner) + { + $ownerDetails = '

' . JText::_('COM_COMPONENTBUILDER_PACKAGE_OWNER_DETAILS_NOT_FOUND') . '

'; + if (!$trust) + { + $ownerDetails .= '

' . JText::_('COM_COMPONENTBUILDER_BE_CAUTIOUS_DO_NOT_CONTINUE_UNLESS_YOU_TRUST_THE_ORIGIN_OF_THIS_PACKAGE') . '

'; + } + } + return '
'.$ownerDetails.'
'; + } + + public static function getPackageOwnerValue($key, &$info) + { + $source = (isset($info['source']) && isset($info['source'][$key])) ? 'source' : ((isset($info['getKeyFrom']) && isset($info['getKeyFrom'][$key])) ? 'getKeyFrom' : false); + if ($source && self::checkString($info[$source][$key])) + { + return $info[$source][$key]; + } + return false; + } + + /** + * get the JCB package component key status + **/ + public static function getPackageComponentsKeyStatus(&$info) + { + // check the package key status + if (!isset($info['key'])) + { + if (isset($info['getKeyFrom']) && isset($info['getKeyFrom']['owner'])) + { + // this just confirms it for older packages + $info['key'] = true; + } + else + { + // this just confirms it for older packages + $info['key'] = false; + } + } + return $info['key']; + } + + protected static $compOwnerSearch = array( + 'ul' => array ( + 'companyname' => 'COM_COMPONENTBUILDER_ICOMPANYI_BSB', + 'author' => 'COM_COMPONENTBUILDER_IAUTHORI_BSB', + 'email' => 'COM_COMPONENTBUILDER_IEMAILI_BSB', + 'website' => 'COM_COMPONENTBUILDER_IWEBSITEI_BSB', + ), + 'other' => array( + 'license' => 'COM_COMPONENTBUILDER_HFOUR_CLASSNAVHEADERLICENSEHFOURPSP', + 'copyright' => 'COM_COMPONENTBUILDER_HFOUR_CLASSNAVHEADERCOPYRIGHTHFOURPSP' + ) + ); + + /** + * get the JCB package component details display + **/ + public static function getPackageComponentsDetailsDisplay(&$info) + { + // check if these components need a key + $needKey = self::getPackageComponentsKeyStatus($info); + if (isset($info['name']) && self::checkArray($info['name'])) + { + $cAmount = count((array) $info['name']); + $class2 = ($cAmount == 1) ? 'span12' : 'span6'; + $counter = 1; + $display = array(); + foreach ($info['name'] as $key => $value) + { + // set the name + $name= $value . ' v' . $info['component_version'][$key]; + if ($cAmount > 1 && $counter == 3) + { + $display[] = ''; + $counter = 1; + } + if ($cAmount > 1 && $counter == 1) + { + $display[] = '
'; + } + $display[] = '
'; + $display[] = '

'; + $display[] = $name; + if ($needKey) + { + $display[] = ' - ' . JText::sprintf('COM_COMPONENTBUILDER_PAIDLOCKED') . ''; + } + else + { + $display[] = ' - ' . JText::sprintf('COM_COMPONENTBUILDER_FREEOPEN') . ''; + } + $display[] = '

'; + $display[] = $info['short_description'][$key]; + $display[] = '

'; + $display[] = '
    '; + // load the list items + foreach (self::$compOwnerSearch['ul'] as $li => $value) + { + if (isset($info[$li]) && isset($info[$li][$key])) + { + $display[] = '
  • '.JText::sprintf($value, $info[$li][$key]).'
  • '; + } + } + $display[] = '
'; + // if we have a source link we add it + if (isset($info['joomla_source_link']) && self::checkArray($info['joomla_source_link']) && isset($info['joomla_source_link'][$key]) && self::checkString($info['joomla_source_link'][$key])) + { + $display[] = 'source code'; + } + // load other + foreach (self::$compOwnerSearch['other'] as $other => $value) + { + if (isset($info[$other]) && isset($info[$other][$key])) + { + $display[] = JText::sprintf($value, $info[$other][$key]); + } + } + $display[] = '
'; + + $counter++; + } + // close the div if needed + if ($cAmount > 1) + { + $display[] = '
'; + } + return implode("\n",$display); + } + return '
'.JText::_('COM_COMPONENTBUILDER_NO_COMPONENT_DETAILS_FOUND_SO_IT_IS_NOT_SAFE_TO_CONTINUE').'
'; + } + + /** + * The array of dynamic content + * + * @var array + */ + protected static $dynamicContent = array( + // The banners by size + 'banner' => array( + '728-90' => array( + 'Joomla! Volunteers Portal', + 'Joomla! Community Magazine | Because community matters...' + ), + '160-600' => array( + 'Joomla! Volunteers Portal', + 'Joomla! Community Magazine | Because community matters...' + ) + ), + // The build-gif by size + 'builder-gif' => array( + '707-400' => array( + '' + ) + ) + ); + + /** + * get the dynamic content + * + * @param string $type The type of content + * @param string $size The size of the content + * + * @return string on success + * + */ + public static function getDynamicContent($type, $size, $default = '') + { + if (isset(self::$dynamicContent[$type]) && isset(self::$dynamicContent[$type][$size]) && ($nr = self::checkArray(self::$dynamicContent[$type][$size]))) + { + // get the random item number + $get = (int) rand(0, --$nr); + // return found content + return self::$dynamicContent[$type][$size][$get]; + } + return $default; + } + + /** + * the Butler + **/ + public static $session = array(); + + /** + * the Butler Assistant + **/ + protected static $localSession = array(); + + /** + * start a session if not already set, and load with data + **/ + public static function loadSession() + { + if (!isset(self::$session) || !self::checkObject(self::$session)) + { + self::$session = JFactory::getSession(); + } + // set the defaults + self::setSessionDefaults(); + } + + /** + * give Session more to keep + **/ + public static function set($key, $value) + { + if (!isset(self::$session) || !self::checkObject(self::$session)) + { + self::$session = JFactory::getSession(); + } + // set to local memory to speed up program + self::$localSession[$key] = $value; + // load to session for later use + return self::$session->set($key, self::$localSession[$key]); + } + + /** + * get info from Session + **/ + public static function get($key, $default = null) + { + if (!isset(self::$session) || !self::checkObject(self::$session)) + { + self::$session = JFactory::getSession(); + } + // check if in local memory + if (!isset(self::$localSession[$key])) + { + // set to local memory to speed up program + self::$localSession[$key] = self::$session->get($key, $default); + } + return self::$localSession[$key]; + } + + + public static function getFieldOptions($value, $type, $settings = array(), $xml = null) + { + // Get a db connection. + $db = JFactory::getDbo(); + + // Create a new query object. + $query = $db->getQuery(true); + $query->select($db->quoteName(array('properties', 'short_description', 'description'))); + $query->from($db->quoteName('#__componentbuilder_fieldtype')); + $query->where($db->quoteName('published') . ' = 1'); + $query->where($db->quoteName($type) . ' = '. $value); + + // Reset the query using our newly populated query object. + $db->setQuery($query); + $db->execute(); + if ($db->getNumRows()) + { + $result = $db->loadObject(); + $properties = json_decode($result->properties, true); + $field = array( + 'subform' => array(), + 'nameListOptions' => array(), + 'php' => array(), + 'values' => " '', + 'short_description' => $result->short_description, + 'description' => $result->description); + // number pointer + $nr = 0; + // php tracker (we must try to load alteast 17 rows + $phpTracker = array(); + // value to check since there are false and null values even 0 in the values returned + $confirmation = '8qvZHoyuFYQqpj0YQbc6F3o5DhBlmS-_-a8pmCZfOVSfANjkmV5LG8pCdAY2JNYu6cB'; + // set the headers + $field['values_description'] .= ''; + foreach ($properties as $property) + { + $example = (isset($property['example']) && self::checkString($property['example'])) ? $property['example'] : ''; + $field['values_description'] .= ''; + // check if we should load the value + $value = self::getValueFromXMLstring($xml, $property['name'], $confirmation); + // check if this is a php field + $addPHP = false; + if (strpos($property['name'], 'type_php') !== false) + { + $addPHP = true; + // set the line number + $phpLine = (int) preg_replace('/[^0-9]/', '', $property['name']); + // set the key + $phpKey = trim(preg_replace('/[0-9]+/', '', $property['name']), '_'); + // start array if not already set + if (!isset($field['php'][$phpKey])) + { + $field['php'][$phpKey] = array(); + $field['php'][$phpKey]['value'] = array(); + $field['php'][$phpKey]['desc'] = $property['description']; + // start tracker + $phpTracker[$phpKey] = 1; + } + } + // was the settings for the property passed + if(self::checkArray($settings) && isset($settings[$property['name']])) + { + // add the xml values + $field['values'] .= PHP_EOL . "\t" . $property['name'] . '="'. $settings[$property['name']] . '" '; + // add the json values + if ($addPHP) + { + $field['php'][$phpKey]['value'][$phpLine] = $settings[$property['name']]; + $phpTracker[$phpKey]++; + } + else + { + $field['subform']['properties'.$nr] = array('name' => $property['name'], 'value' => $settings[$property['name']], 'desc' => $property['description']); + } + } + elseif (!$xml || $confirmation !== $value) + { + // add the xml values + $field['values'] .= PHP_EOL."\t" . $property['name'] . '="' . ($confirmation !== $value) ? $value : $example .'" '; + // add the json values + if ($addPHP) + { + $field['php'][$phpKey]['value'][$phpLine] = ($confirmation !== $value) ? $value : $example; + $phpTracker[$phpKey]++; + } + else + { + $field['subform']['properties' . $nr] = array('name' => $property['name'], 'value' => ($confirmation !== $value) ? $value : $example, 'desc' => $property['description']); + } + } + // add the name List Options + if (!$addPHP) + { + $field['nameListOptions'][$property['name']] = $property['name']; + } + // increment the number + $nr++; + } + // check if all php is loaded using the tracker + if (self::checkString($xml) && isset($phpTracker) && self::checkArray($phpTracker)) + { + foreach ($phpTracker as $phpKey => $start) + { + if ($start < 30) + { + // we must search for more code in the xml just incase + foreach(range(2, 30) as $t_nr) + { + $get_ = $phpKey . '_' . $t_nr; + if (!isset($field['php'][$phpKey]['value'][$t_nr]) && ($value = self::getValueFromXMLstring($xml, $get_, $confirmation)) !== $confirmation) + { + $field['php'][$phpKey]['value'][$t_nr] = $value; + } + } + } + } + } + $field['values'] .= PHP_EOL . "/>"; + $field['values_description'] .= '
' . JText::_('COM_COMPONENTBUILDER_PROPERTY') . '' . JText::_('COM_COMPONENTBUILDER_EXAMPLE') . '' . JText::_('COM_COMPONENTBUILDER_DESCRIPTION') . '
' . $property['name'] . '' . $example . '' . $property['description'] . '
'; + // return found field options + return $field; + } + return false; + } + + public static function getValueFromXMLstring(&$xml, &$get, $confirmation = '') + { + if (self::checkString($xml)) + { + // if we have a PHP value, we must base64 decode it + if (strpos($get, 'type_php') !== false) + { + return self::openValidBase64(self::getBetween($xml, $get.'="', '"', $confirmation)); + } + return self::getBetween($xml, $get . '="', '"', $confirmation); + } + return $confirmation; + } + + + /** + * The zipper method + * + * @param string $workingDIR The directory where the items must be zipped + * @param string $filepath The path to where the zip file must be placed + * + * @return bool true On success + * + */ + public static function zip($workingDIR, &$filepath) + { + // store the current joomla working directory + $joomla = getcwd(); + + // we are changing the working directory to the component temp folder + chdir($workingDIR); + + // the full file path of the zip file + $filepath = JPath::clean($filepath); + + // delete an existing zip file (or use an exclusion parameter in JFolder::files() + JFile::delete($filepath); + + // get a list of files in the current directory tree + $files = JFolder::files('.', '', true, true); + $zipArray = array(); + // setup the zip array + foreach ($files as $file) + { + $tmp = array(); + $tmp['name'] = str_replace('./', '', $file); + $tmp['data'] = JFile::read($file); + $tmp['time'] = filemtime($file); + $zipArray[] = $tmp; + } + + // change back to joomla working directory + chdir($joomla); + + // get the zip adapter + $zip = JArchive::getAdapter('zip'); + + //create the zip file + if ($zip->create($filepath, $zipArray)) + { + return true; + } + return false; + } + + + /** + * Write a file to the server + * + * @param string $path The path and file name where to safe the data + * @param string $data The data to safe + * + * @return bool true On success + * + */ + public static function writeFile($path, $data) + { + $klaar = false; + if (self::checkString($data)) + { + // open the file + $fh = fopen($path, "w"); + if (!is_resource($fh)) + { + return $klaar; + } + // write to the file + if (fwrite($fh, $data)) + { + // has been done + $klaar = true; + } + // close file. + fclose($fh); + } + return $klaar; + } + + + /** + * Remove folders with files + * + * @param string $dir The path to folder to remove + * @param boolean $ignore The folders and files to ignore and not remove + * + * @return boolean True in all is removed + * + */ + public static function removeFolder($dir, $ignore = false) + { + if (JFolder::exists($dir)) + { + $it = new RecursiveDirectoryIterator($dir); + $it = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST); + foreach ($it as $file) + { + if ('.' === $file->getBasename() || '..' === $file->getBasename()) continue; + if ($file->isDir()) + { + $keeper = false; + if (self::checkArray($ignore)) + { + foreach ($ignore as $keep) + { + if (strpos($file->getPathname(), $dir.'/'.$keep) !== false) + { + $keeper = true; + } + } + } + if ($keeper) + { + continue; + } + JFolder::delete($file->getPathname()); + } + else + { + $keeper = false; + if (self::checkArray($ignore)) + { + foreach ($ignore as $keep) + { + if (strpos($file->getPathname(), $dir.'/'.$keep) !== false) + { + $keeper = true; + } + } + } + if ($keeper) + { + continue; + } + JFile::delete($file->getPathname()); + } + } + if (!self::checkArray($ignore)) + { + return JFolder::delete($dir); + } + return true; + } + return false; + } + + + /** + * get the github repo file list + * + * @return array on success + * + */ + public static function getGithubRepoFileList($type, $target) + { + // get the current Packages (public) + if (!$repoData = self::get($type)) + { + if (self::urlExists($target)) + { + $repoData = self::getFileContents($target); + if (self::checkJson($repoData)) + { + $test = json_decode($repoData); + if (self::checkObject($test) && isset($test->tree) && self::checkArray($test->tree) ) + { + // remember to set it + self::set($type, $repoData); + } + // check if we have error message from github + elseif ($errorMessage = self::githubErrorHandeler(array('error' => null), $test)) + { + if (self::checkString($errorMessage['error'])) + { + JFactory::getApplication()->enqueueMessage($errorMessage['error'], 'Error'); + } + $repoData = false; + } + } + else + { + $repoData = false; + } + } + else + { + JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_URL_S_SET_TO_RETRIEVE_THE_PACKAGES_DOES_NOT_EXIST', $target), 'Error'); + } + } + // check if we could find packages + if (isset($repoData) && self::checkJson($repoData)) + { + $repoData = json_decode($repoData); + if (self::checkObject($repoData) && isset($repoData->tree) && self::checkArray($repoData->tree) ) + { + return $repoData->tree; + } + } + return false; + } + + /** + * get the github error messages + * + * @return array of errors on success + * + */ + protected static function githubErrorHandeler($message, &$github) + { + if (self::checkObject($github) && isset($github->message) && self::checkString($github->message)) + { + // set the message + $errorMessage = $github->message; + // add the documentation URL + if (isset($github->documentation_url) && self::checkString($github->documentation_url)) + { + $errorMessage = $errorMessage.'
'.$github->documentation_url; + } + // check the message + if (strpos($errorMessage, 'Authenticated') !== false) + { + // add little more help if it is an access token issue + $errorMessage = JText::sprintf('COM_COMPONENTBUILDER_SBR_YOU_CAN_ADD_AN_BACCESS_TOKENB_TO_GETBIBLE_GLOBAL_OPTIONS_TO_MAKE_AUTHENTICATED_REQUESTS_AN_ACCESS_TOKEN_WITH_ONLY_PUBLIC_ACCESS_WILL_DO', $errorMessage); + } + // set error notice + $message['error'] = $errorMessage; + // we have error message + return $message; + } + return false; + } + public static function getDynamicScripts($type, $fieldName = false) { @@ -1685,181 +2211,6 @@ abstract class ComponentbuilderHelper return false; } - /** - * Run Global Updater if any are set - * - * @return void - * - */ - public static function runGlobalUpdater() - { - // check if any updates are set to run - if (self::checkArray(self::$globalUpdater)) - { - // get the database object - $db = JFactory::getDbo(); - foreach (self::$globalUpdater as $tableKeyID => $object) - { - // get the table - $table = explode('.', $tableKeyID); - // update the item - $db->updateObject('#__componentbuilder_' . (string) $table[0] , $object, (string) $table[1]); - } - // rest updater - self::$globalUpdater = array(); - } - } - - /** - * Copy Any Item (only use for direct database copying) - * - * @param int $id The item to copy - * @param string $table The table and model to copy from and with - * @param array $config The values that should change - * - * @return boolean True if success - * - */ - public static function copyItem($id, $type, $config = array()) - { - // only continue if we have an id - if ((int) $id > 0) - { - // get the model - $model = self::getModel($type); - $app = \JFactory::getApplication(); - // get item - if ($item = $model->getItem($id)) - { - // update values that should change - if (self::checkArray($config)) - { - foreach($config as $key => $value) - { - if (isset($item->{$key})) - { - $item->{$key} = $value; - } - } - } - // clone the object - $data = array(); - foreach ($item as $key => $value) - { - $data[$key] = $value; - } - // reset some values - $data['id'] = 0; - $data['version'] = 1; - if (isset($data['tags'])) - { - $data['tags'] = null; - } - if (isset($data['associations'])) - { - $data['associations'] = array(); - } - // remove some unneeded values - unset($data['params']); - unset($data['asset_id']); - unset($data['checked_out']); - unset($data['checked_out_time']); - // Attempt to save the data. - if ($model->save($data)) - { - return true; - } - } - } - return false; - } - - /** - * the basic localkey - **/ - protected static $localkey = false; - - /** - * get the localkey - **/ - public static function getLocalKey() - { - if (!self::$localkey) - { - // get the basic key - self::$localkey = md5(self::getCryptKey('basic', 'localKey34fdWEkl')); - } - return self::$localkey; - } - - /** - * indent HTML - */ - public static function indent($html) - { - // load the class - require_once JPATH_ADMINISTRATOR.'/components/com_componentbuilder/helpers/indenter.php'; - // set new indenter - $indenter = new Indenter(); - // return indented html - return $indenter->indent($html); - } - - public static function checkFileType($file, $sufix) - { - // now check if the file ends with the sufix - return $sufix === "" || ($sufix == substr(strrchr($file, "."), -strlen($sufix))); - } - - public static function imageInfo($path, $request = 'type') - { - // set image - $image = JPATH_SITE.'/'.$path; - // check if exists - if (file_exists($image) && $result = @getimagesize($image)) - { - // return type request - switch ($request) - { - case 'width': - return $result[0]; - break; - case 'height': - return $result[1]; - break; - case 'type': - $extensions = array( - IMAGETYPE_GIF => "gif", - IMAGETYPE_JPEG => "jpg", - IMAGETYPE_PNG => "png", - IMAGETYPE_SWF => "swf", - IMAGETYPE_PSD => "psd", - IMAGETYPE_BMP => "bmp", - IMAGETYPE_TIFF_II => "tiff", - IMAGETYPE_TIFF_MM => "tiff", - IMAGETYPE_JPC => "jpc", - IMAGETYPE_JP2 => "jp2", - IMAGETYPE_JPX => "jpx", - IMAGETYPE_JB2 => "jb2", - IMAGETYPE_SWC => "swc", - IMAGETYPE_IFF => "iff", - IMAGETYPE_WBMP => "wbmp", - IMAGETYPE_XBM => "xbm", - IMAGETYPE_ICO => "ico" - ); - return $extensions[$result[2]]; - break; - case 'attr': - return $result[3]; - break; - case 'all': - default: - return $result; - break; - } - } - return false; - } /** * get between @@ -1999,278 +2350,6 @@ abstract class ComponentbuilderHelper return self::getVars('fieldtype', (array) array_map(function($name) use($db) { return $db->quote(ucfirst($name)); }, self::$fieldGroups['spacer']), 'name', 'id'); } - /** - * set the session defaults if not set - **/ - protected static function setSessionDefaults() - { - // noting for now - return true; - } - - /** - * the Butler - **/ - public static $session = array(); - - /** - * the Butler Assistant - **/ - protected static $localSession = array(); - - /** - * start a session if not already set, and load with data - **/ - public static function loadSession() - { - if (!isset(self::$session) || !self::checkObject(self::$session)) - { - self::$session = JFactory::getSession(); - } - // set the defaults - self::setSessionDefaults(); - } - - /** - * give Session more to keep - **/ - public static function set($key, $value) - { - if (!isset(self::$session) || !self::checkObject(self::$session)) - { - self::$session = JFactory::getSession(); - } - // set to local memory to speed up program - self::$localSession[$key] = $value; - // load to session for later use - return self::$session->set($key, self::$localSession[$key]); - } - - /** - * get info from Session - **/ - public static function get($key, $default = null) - { - if (!isset(self::$session) || !self::checkObject(self::$session)) - { - self::$session = JFactory::getSession(); - } - // check if in local memory - if (!isset(self::$localSession[$key])) - { - // set to local memory to speed up program - self::$localSession[$key] = self::$session->get($key, $default); - } - return self::$localSession[$key]; - } - - /** - * check if it is a new hash - **/ - public static function newHash($hash, $name = 'backup', $type = 'hash', $key = '', $fileType = 'txt') - { - // make sure we have a hash - if (self::checkString($hash)) - { - // first get the file path - $path_filename = self::getFilePath('path', $name.$type, $fileType, $key, JPATH_COMPONENT_ADMINISTRATOR); - // set as read if not already set - if ($content = self::getFileContents($path_filename, false)) - { - if ($hash == $content) - { - return false; - } - } - // set the hash - return self::writeFile($path_filename, $hash); - } - return false; - } - - protected static $pkOwnerSearch = array( - 'company' => 'COM_COMPONENTBUILDER_DTCOMPANYDTDDSDD', - 'owner' => 'COM_COMPONENTBUILDER_DTOWNERDTDDSDD', - 'email' => 'COM_COMPONENTBUILDER_DTEMAILDTDDSDD', - 'website' => 'COM_COMPONENTBUILDER_DTWEBSITEDTDDSDD', - 'license' => 'COM_COMPONENTBUILDER_DTLICENSEDTDDSDD', - 'copyright' => 'COM_COMPONENTBUILDER_DTCOPYRIGHTDTDDSDD' - ); - - /** - * get the JCB package owner details display - **/ - public static function getPackageOwnerDetailsDisplay(&$info, $trust = false) - { - $hasOwner = false; - $ownerDetails = ''; - $ownerDetails .= '
'; - // load the list items - foreach (self::$pkOwnerSearch as $key => $dd) - { - if ($value = self::getPackageOwnerValue($key, $info)) - { - $ownerDetails .= JText::sprintf($dd, $value); - // check if we have a owner/source name - if (('owner' === $key || 'company' === $key) && !$hasOwner) - { - $hasOwner = true; - $owner = $value; - } - } - } - $ownerDetails .= '
'; - - // provide some details to how the user can get a key - if ($hasOwner && isset($info['getKeyFrom']['buy_link']) && self::checkString($info['getKeyFrom']['buy_link'])) - { - $ownerDetails .= '
'; - $ownerDetails .= JText::sprintf('COM_COMPONENTBUILDER_BGET_THE_KEY_FROMB_A_SSA', 'class="btn btn-primary" href="'.$info['getKeyFrom']['buy_link'].'" target="_blank" title="get a key from '.$owner.'"', $owner); - } - // add more custom links - elseif ($hasOwner && isset($info['getKeyFrom']['buy_links']) && self::checkArray($info['getKeyFrom']['buy_links'])) - { - $buttons = array(); - foreach ($info['getKeyFrom']['buy_links'] as $keyName => $link) - { - $buttons[] = JText::sprintf('COM_COMPONENTBUILDER_BGET_THE_KEY_FROM_SB_FOR_A_SSA', $owner, 'class="btn btn-primary" href="'.$link.'" target="_blank" title="get a key from '.$owner.'"', $keyName); - } - $ownerDetails .= '
'; - $ownerDetails .= implode('
', $buttons); - } - // return the owner details - if (!$hasOwner) - { - $ownerDetails = '

' . JText::_('COM_COMPONENTBUILDER_PACKAGE_OWNER_DETAILS_NOT_FOUND') . '

'; - if (!$trust) - { - $ownerDetails .= '

' . JText::_('COM_COMPONENTBUILDER_BE_CAUTIOUS_DO_NOT_CONTINUE_UNLESS_YOU_TRUST_THE_ORIGIN_OF_THIS_PACKAGE') . '

'; - } - } - return '
'.$ownerDetails.'
'; - } - - public static function getPackageOwnerValue($key, &$info) - { - $source = (isset($info['source']) && isset($info['source'][$key])) ? 'source' : ((isset($info['getKeyFrom']) && isset($info['getKeyFrom'][$key])) ? 'getKeyFrom' : false); - if ($source && self::checkString($info[$source][$key])) - { - return $info[$source][$key]; - } - return false; - } - - /** - * get the JCB package component key status - **/ - public static function getPackageComponentsKeyStatus(&$info) - { - // check the package key status - if (!isset($info['key'])) - { - if (isset($info['getKeyFrom']) && isset($info['getKeyFrom']['owner'])) - { - // this just confirms it for older packages - $info['key'] = true; - } - else - { - // this just confirms it for older packages - $info['key'] = false; - } - } - return $info['key']; - } - - protected static $compOwnerSearch = array( - 'ul' => array ( - 'companyname' => 'COM_COMPONENTBUILDER_ICOMPANYI_BSB', - 'author' => 'COM_COMPONENTBUILDER_IAUTHORI_BSB', - 'email' => 'COM_COMPONENTBUILDER_IEMAILI_BSB', - 'website' => 'COM_COMPONENTBUILDER_IWEBSITEI_BSB', - ), - 'other' => array( - 'license' => 'COM_COMPONENTBUILDER_HFOUR_CLASSNAVHEADERLICENSEHFOURPSP', - 'copyright' => 'COM_COMPONENTBUILDER_HFOUR_CLASSNAVHEADERCOPYRIGHTHFOURPSP' - ) - ); - - /** - * get the JCB package component details display - **/ - public static function getPackageComponentsDetailsDisplay(&$info) - { - // check if these components need a key - $needKey = self::getPackageComponentsKeyStatus($info); - if (isset($info['name']) && self::checkArray($info['name'])) - { - $cAmount = count((array) $info['name']); - $class2 = ($cAmount == 1) ? 'span12' : 'span6'; - $counter = 1; - $display = array(); - foreach ($info['name'] as $key => $value) - { - // set the name - $name= $value . ' v' . $info['component_version'][$key]; - if ($cAmount > 1 && $counter == 3) - { - $display[] = ''; - $counter = 1; - } - if ($cAmount > 1 && $counter == 1) - { - $display[] = '
'; - } - $display[] = '
'; - $display[] = '

'; - $display[] = $name; - if ($needKey) - { - $display[] = ' - ' . JText::sprintf('COM_COMPONENTBUILDER_PAIDLOCKED') . ''; - } - else - { - $display[] = ' - ' . JText::sprintf('COM_COMPONENTBUILDER_FREEOPEN') . ''; - } - $display[] = '

'; - $display[] = $info['short_description'][$key]; - $display[] = '

'; - $display[] = '
    '; - // load the list items - foreach (self::$compOwnerSearch['ul'] as $li => $value) - { - if (isset($info[$li]) && isset($info[$li][$key])) - { - $display[] = '
  • '.JText::sprintf($value, $info[$li][$key]).'
  • '; - } - } - $display[] = '
'; - // if we have a source link we add it - if (isset($info['joomla_source_link']) && self::checkArray($info['joomla_source_link']) && isset($info['joomla_source_link'][$key]) && self::checkString($info['joomla_source_link'][$key])) - { - $display[] = 'source code'; - } - // load other - foreach (self::$compOwnerSearch['other'] as $other => $value) - { - if (isset($info[$other]) && isset($info[$other][$key])) - { - $display[] = JText::sprintf($value, $info[$other][$key]); - } - } - $display[] = '
'; - - $counter++; - } - // close the div if needed - if ($cAmount > 1) - { - $display[] = '
'; - } - return implode("\n",$display); - } - return '
'.JText::_('COM_COMPONENTBUILDER_NO_COMPONENT_DETAILS_FOUND_SO_IT_IS_NOT_SAFE_TO_CONTINUE').'
'; - } /** * open base64 string if stored as base64 @@ -4926,11 +5005,11 @@ abstract class ComponentbuilderHelper * * @input array The array to check * - * @returns bool true on success + * @returns bool/int number of items in array on success **/ public static function checkArray($array, $removeEmptyString = false) { - if (isset($array) && is_array($array) && count((array)$array) > 0) + if (isset($array) && is_array($array) && ($nr = count((array)$array)) > 0) { // also make sure the empty strings are removed if ($removeEmptyString) @@ -4944,7 +5023,7 @@ abstract class ComponentbuilderHelper } return self::checkArray($array, false); } - return true; + return $nr; } return false; }