From 4e7d4af1d3ac00788e37d445a7882d53591fce13 Mon Sep 17 00:00:00 2001 From: Llewellyn van der Merwe Date: Sun, 15 Apr 2018 00:52:48 +0200 Subject: [PATCH 01/14] Added the php field properties to a textarea outside of the subform for easier editing --- README.md | 2 +- admin/README.txt | 2 +- admin/helpers/componentbuilder.php | 49 +++++++++++++++---- .../en-GB/en-GB.com_componentbuilder.ini | 1 + admin/models/ajax.php | 40 +++++++++++++++ admin/models/field.php | 18 ++++++- admin/models/forms/field.js | 7 +++ admin/sql/install.mysql.utf8.sql | 2 +- site/helpers/componentbuilder.php | 49 +++++++++++++++---- 9 files changed, 148 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index b84e913f0..041103f52 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,7 @@ Component Builder is mapped as a component in itself on my local development env + *Version*: 2.7.5 + *Copyright*: Copyright (C) 2015. All Rights Reserved + *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html -+ *Line count*: **182312** ++ *Line count*: **182437** + *Field count*: **1012** + *File count*: **1199** + *Folder count*: **193** diff --git a/admin/README.txt b/admin/README.txt index b84e913f0..041103f52 100644 --- a/admin/README.txt +++ b/admin/README.txt @@ -130,7 +130,7 @@ Component Builder is mapped as a component in itself on my local development env + *Version*: 2.7.5 + *Copyright*: Copyright (C) 2015. All Rights Reserved + *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html -+ *Line count*: **182312** ++ *Line count*: **182437** + *Field count*: **1012** + *File count*: **1199** + *Folder count*: **193** diff --git a/admin/helpers/componentbuilder.php b/admin/helpers/componentbuilder.php index 3fa015523..fbe7b3a3e 100644 --- a/admin/helpers/componentbuilder.php +++ b/admin/helpers/componentbuilder.php @@ -1600,6 +1600,7 @@ abstract class ComponentbuilderHelper $field = array( 'subform' => array(), 'nameListOptions' => array(), + 'php' => array(), 'values' => " '', 'short_description' => $result->short_description, @@ -1612,32 +1613,62 @@ abstract class ComponentbuilderHelper $field['values_description'] .= ''; foreach ($properties as $property) { - $example = (isset($property['example']) && self::checkString($property['example'])) ? self::shorten($property['example'], 30) : ''; + $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'] .= "\n\t".$property['name'].'="'.$settings[$property['name']].'" '; + $field['values'] .= PHP_EOL."\t".$property['name'].'="'.$settings[$property['name']].'" '; // add the json values - $field['subform']['properties'.$nr] = array('name' => $property['name'], 'value' => $settings[$property['name']]); - // add the name List Options as set - $field['nameListOptionsSet'][$property['name']] = $property['name']; + 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'] .= "\n\t" . $property['name'] . '="'. ($confirmation !== $value) ? $value : $property['example'] .'" '; + $field['values'] .= PHP_EOL."\t" . $property['name'] . '="'. ($confirmation !== $value) ? $value : $example .'" '; // add the json values - $field['subform']['properties' . $nr] = array('name' => $property['name'], 'value' => ($confirmation !== $value) ? $value : $property['example'], 'desc' => $property['description']); + 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 - $field['nameListOptions'][$property['name']] = $property['name']; + if (!$addPHP) + { + $field['nameListOptions'][$property['name']] = $property['name']; + } // increment the number $nr++; } - $field['values'] .= "\n/>"; + $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; diff --git a/admin/language/en-GB/en-GB.com_componentbuilder.ini b/admin/language/en-GB/en-GB.com_componentbuilder.ini index 1afa0e238..5b51136b9 100644 --- a/admin/language/en-GB/en-GB.com_componentbuilder.ini +++ b/admin/language/en-GB/en-GB.com_componentbuilder.ini @@ -6577,6 +6577,7 @@ COM_COMPONENTBUILDER_YOU_SHOULD_ADD_THE_CORRECT_OWNER_DETAILS="You should add th COM_COMPONENTBUILDER_YOU_SHOULD_ONLY_CONTINUE_THIS_IMPORT_IF_YOU_HAVE_BACKUP_YOUR_COMPONENTS_AND_INSURED_THAT_THE_PACKAGE_OWNER_IS_REPUTABLE="You should only continue this import if you have backup your components, and insured that the package owner is reputable." COM_COMPONENTBUILDER_YOU_WILL_NEED_TO_KNOW_HOW_S_WORKS_BASIC_YOU_WILL_ALSO_NEED_A_S_ACCOUNT_AND_KNOW_HOW_TO_MAKE_A_PULL_REQUEST_ON_GITHUB="you will need to know how %s works (basic). You will also need a %s account and know how to make a pull request on github." COM_COMPONENTBUILDER_ZIPPED_FILE_LOCATION="Zipped File Location" +COM_COMPONENTBUILDER__ADD_YOUR_PHP_SCRIPT_HERE="// Add your php script here" COM_COMPONENTBUILDER__SELECT_COMPONENT_="- Select Component -" COM_COMPONENTBUILDER__SELECT_PACKAGE_="- Select Package -" COM_COMPONENTBUILDER__SINCE_YOU_DONT_HAVE_PERMISSION_TO_CREATE_S=", since you don't have permission to create %s!" diff --git a/admin/models/ajax.php b/admin/models/ajax.php index 6422e2aea..4a956ea70 100644 --- a/admin/models/ajax.php +++ b/admin/models/ajax.php @@ -2244,6 +2244,20 @@ class ComponentbuilderModelAjax extends JModelList // load the html $field['subform'] = '
'. $properties->label . '
' . $properties->input . '
'; $field['extra'] = '
'. $extras->label . '
' . $extras->input . '
'; + // check if we have PHP values + if (ComponentbuilderHelper::checkArray($field['php'])) + { + $field['textarea'] = array(); + foreach($field['php'] as $name => $values) + { + $value = implode(PHP_EOL, $values['value']); + $textarea = $this->buildFieldTexteara($name, $values['desc'], $value, substr_count( $value, PHP_EOL )); + // load the html + $field['textarea'][] = '
'. $textarea->label . '
' . $textarea->input . '

'; + } + } + // remove some unneeded values + unset($field['values']); // return found field options return $field; } @@ -2277,6 +2291,32 @@ class ComponentbuilderModelAjax extends JModelList return null; } + protected function buildFieldTexteara($name, $desc, $default, $rows) + { + // get the textarea + $textarea = JFormHelper::loadFieldType('textarea', true); + // start building the name field XML + $textareaXML = new SimpleXMLElement(''); + // textarea attributes + $textareaAttribute = array( + 'type' => 'textarea', + 'name' => 'property_'.$name, + 'label' => $desc, + 'rows' => (int) ($rows >= 3) ? $rows : $rows + 2, + 'cols' => '15', + 'class' => 'text_area span12', + 'filter' => 'RAW', + 'hint' => 'COM_COMPONENTBUILDER__ADD_YOUR_PHP_SCRIPT_HERE'); + // load the textarea attributes + ComponentbuilderHelper::xmlAddAttributes($textareaXML, $textareaAttribute); + + // setup subform with values + $textarea->setup($textareaXML, $default); + + // return textarea object + return $textarea; + } + protected function buildFieldOptionsSubform($values, $nameListOptions = null, $name = 'properties', $label = 'COM_COMPONENTBUILDER_PROPERTIESBR_SMALLHERE_YOU_CAN_SET_THE_PROPERTIES_FOR_THIS_FIELDSMALL') { // get the subform diff --git a/admin/models/field.php b/admin/models/field.php index 3b41ed481..6f820e1f7 100644 --- a/admin/models/field.php +++ b/admin/models/field.php @@ -893,6 +893,10 @@ class ComponentbuilderModelField extends JModelAdmin $properties = $input->get('properties', null, 'ARRAY'); // get the extra properties $extraproperties = $input->get('extraproperties', null, 'ARRAY'); + // get the type phpx property + $typephpx = $input->get('property_type_phpx', null, 'RAW'); + // get the type php property + $typephp = $input->get('property_type_php', null, 'RAW'); // make sure we have an array if (ComponentbuilderHelper::checkArray($properties)) { @@ -931,10 +935,22 @@ class ComponentbuilderModelField extends JModelAdmin } } } + // make sure we have a string + if (ComponentbuilderHelper::checkString($typephp)) + { + // load the type_php property + $bucket[] = "\t".'type_php_1="'. str_replace('"', "'", $typephp).'"'; + } + // make sure we have a string + if (ComponentbuilderHelper::checkString($typephpx)) + { + // load the type_phpx property + $bucket[] = "\t".'type_phpx_1="'. str_replace('"', "'", $typephp).'"'; + } // if the bucket has been loaded if (ComponentbuilderHelper::checkArray($bucket)) { - $data['xml'] = ""; + $data['xml'] = ""; } } diff --git a/admin/models/forms/field.js b/admin/models/forms/field.js index f46323ec2..6b445cddb 100644 --- a/admin/models/forms/field.js +++ b/admin/models/forms/field.js @@ -601,6 +601,13 @@ function getFieldOptions(fieldtype){ // append to note_filter_information class jQuery('.note_filter_information').closest('.control-group').prepend(result.extra); // append to note_filter_information class + if(result.textarea){ + jQuery.each( result.textarea, function( i, tField ) { + // append to note_filter_information class + jQuery('.note_filter_information').closest('.control-group').prepend(tField); + }); + } + // append to note_filter_information class jQuery('.note_filter_information').closest('.control-group').prepend(result.subform); // add the watcher rowWatcher(); diff --git a/admin/sql/install.mysql.utf8.sql b/admin/sql/install.mysql.utf8.sql index 8bc8f66d8..233413ac8 100644 --- a/admin/sql/install.mysql.utf8.sql +++ b/admin/sql/install.mysql.utf8.sql @@ -1496,7 +1496,7 @@ INSERT INTO `#__componentbuilder_fieldtype` (`id`, `catid`, `description`, `name (3, '', 'The checkbox form field type provides a single checkbox. If the parameter has a saved value this is selected when the page is first loaded. If not, the default value (if any) is selected.', 'Checkbox', '{\"properties0\":{\"name\":\"type\",\"example\":\"checkbox\",\"mandatory\":\"1\",\"description\":\"(mandatory) must be checkbox\"},\"properties1\":{\"name\":\"name\",\"example\":\"show_title\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"description\":\"(mandatory) is the unique name of the parameter.\"},\"properties2\":{\"name\":\"label\",\"example\":\"Show title\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"translatable\":\"1\",\"description\":\"(mandatory) (translatable) is the descriptive title of the field.\"},\"properties3\":{\"name\":\"value\",\"example\":\"1\",\"adjustable\":\"1\",\"description\":\"(optional) is the value of the parameter if this checkbox is set (usually 1).\"},\"properties4\":{\"name\":\"default\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) is the default value (usually 0 or 1).\"},\"properties5\":{\"name\":\"required\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) The field must be filled before submitting the form.\"},\"properties6\":{\"name\":\"description\",\"example\":\"Show the title of the item\",\"adjustable\":\"1\",\"translatable\":\"1\",\"description\":\"(optional) (translatable) is text that will be shown as a tooltip when the user moves the mouse over the label.\"},\"properties7\":{\"name\":\"class\",\"example\":\"inputbox\",\"adjustable\":\"1\",\"description\":\"(optional) is a CSS class name for the HTML form field. If omitted this will default to \'inputbox\'.\"},\"properties8\":{\"name\":\"showon\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) show this field on the bases of the value in another field.\"},\"properties9\":{\"name\":\"onchange\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) HTML equivalent attribute (JavaScript use)\"}}', 'provides a single checkbox to be checked or unchecked', '', 1, 4, '', ''), (4, '', 'The checkboxes form field type provides a set of checkboxes. Note: unlike most standard form field types, such as textfield or checkbox, this field is not an \"out of the box\" solution. It will create checkboxes for you, and submit their values in form of ', 'Checkboxes', '{\"properties0\":{\"name\":\"type\",\"example\":\"checkboxes\",\"adjustable\":\"0\",\"mandatory\":\"1\",\"translatable\":\"0\",\"description\":\"(mandatory) must be checkboxs\"},\"properties1\":{\"name\":\"name\",\"example\":\"toppings\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"translatable\":\"0\",\"description\":\"(mandatory) is the unique name of the parameter.\"},\"properties2\":{\"name\":\"label\",\"example\":\"Select Toppings\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"1\",\"description\":\"(optional) (translatable) is the descriptive title of the field.\"},\"properties3\":{\"name\":\"option\",\"example\":\"anch|Anchovies,chor|Chorizo,on|Onions,mush|Mushrooms\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"translatable\":\"0\",\"description\":\"(mandatory) set the options of this radio. Separate options with commas and use the pipe symbol to separate value from text.\"},\"properties4\":{\"name\":\"default\",\"example\":\"\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"(optional) is the default value.\"},\"properties5\":{\"name\":\"description\",\"example\":\"Select the topping of your choice\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"1\",\"description\":\"(optional) (translatable) is text that will be shown as a tooltip when the user moves the mouse over the label.\"},\"properties6\":{\"name\":\"required\",\"example\":\"\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"(optional) The field must be filled before submitting the form.\"},\"properties7\":{\"name\":\"class\",\"example\":\"\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"(optional) is a CSS class name for the HTML form field. If omitted this will default to \'inputbox\'.\"},\"properties8\":{\"name\":\"showon\",\"example\":\"\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"(optional) show this field on the bases of the value in another field.\"}}', 'provides unlimited checkboxes that can be used for multi-select.', '', 1, 2, '', ''), (5, '', 'Provides a color picker. Enter the color as #ff00ff or pick it from the palet.', 'Color', '{\"properties0\":{\"name\":\"type\",\"example\":\"color\",\"adjustable\":\"0\",\"mandatory\":\"1\",\"translatable\":\"0\",\"description\":\"(mandatory) must be color.\"},\"properties1\":{\"name\":\"name\",\"example\":\"backgroundcolor\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"translatable\":\"0\",\"description\":\"(mandatory) is the unique name of the parameter.\"},\"properties2\":{\"name\":\"default\",\"example\":\"#FFFFFF\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"(optional) provides a color when not set.\"},\"properties3\":{\"name\":\"label\",\"example\":\"Background\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"translatable\":\"1\",\"description\":\"(mandatory) (translatable) is the descriptive title of the field.\"},\"properties4\":{\"name\":\"description\",\"example\":\"Select the background color here.\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"1\",\"description\":\"(optional) (translatable) tooltip for the form field.\"},\"properties5\":{\"name\":\"required\",\"example\":\"\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"(optional) The field must be filled before submitting the form.\"},\"properties6\":{\"name\":\"showon\",\"example\":\"\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"(optional) show this field on the bases of the value in another field.\"}}', 'provides a color picker when clicking the input box.', '', 1, 2, '', ''), -(6, '', 'The list form field type provides a drop down list or a list box of other current component table entries. If the field has a saved value this is selected when the page is first loaded. If not, the default value (if any) is selected.', 'Custom', '{\"properties0\":{\"name\":\"type\",\"example\":\"subjects\",\"mandatory\":\"1\",\"description\":\"(mandatory) can be anything, just not the same as any other default Joomla field type.\"},\"properties1\":{\"name\":\"name\",\"example\":\"subject\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"description\":\"(mandatory) is the unique name of the field.\"},\"properties2\":{\"name\":\"label\",\"example\":\"Select a Subject\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"translatable\":\"1\",\"description\":\"(mandatory) (translatable) is the descriptive title of the field.\"},\"properties3\":{\"name\":\"description\",\"example\":\"\",\"adjustable\":\"1\",\"translatable\":\"1\",\"description\":\"(optional) (translatable) is text that will be shown as a tooltip when the user moves the mouse over the drop-down box.\"},\"properties4\":{\"name\":\"message\",\"example\":\"\",\"adjustable\":\"1\",\"translatable\":\"1\",\"description\":\"(optional) (translatable) is text that will be shown as error on validation.\"},\"properties5\":{\"name\":\"class\",\"example\":\"list_class\",\"adjustable\":\"1\",\"description\":\"(optional) is a CSS class name for the HTML form field. If omitted this will default to \'inputbox\'.\"},\"properties6\":{\"name\":\"multiple\",\"example\":\"false\",\"adjustable\":\"1\",\"description\":\"(optional) is whether multiple items can be selected at the same time (true or false).\"},\"properties7\":{\"name\":\"default\",\"example\":\"0\",\"adjustable\":\"1\",\"description\":\"(optional) (not translatable) is the default value.\"},\"properties8\":{\"name\":\"required\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) The field must be filled before submitting the form.\"},\"properties9\":{\"name\":\"validate\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) The validation method for the form field. This value will determine which method is used to validate the value for a field.\"},\"properties10\":{\"name\":\"readonly\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) The field cannot be changed and will automatically inherit the default value\"},\"properties11\":{\"name\":\"disabled\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) The field cannot be changed and will automatically inherit the default value - it will also not submit\"},\"properties12\":{\"name\":\"showon\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) show this field on the bases of the value in another field.\"},\"properties13\":{\"name\":\"onchange\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) HTML equivalent attribute (javascript use)\"},\"properties14\":{\"name\":\"extends\",\"example\":\"list\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"description\":\"The JFormField sub class that should be extended. The options are (\'list\',\'radio\',\'checkboxes\')\"},\"properties15\":{\"name\":\"button\",\"example\":\"true\",\"adjustable\":\"1\",\"description\":\"(optional) to add new button next to field in edit view\"},\"properties16\":{\"name\":\"table\",\"example\":\"#__###component###_subject\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"description\":\"(mandatory) The table being linked to. \"},\"properties17\":{\"name\":\"component\",\"example\":\"com_###component###\",\"mandatory\":\"1\",\"description\":\"(mandatory) The name of the component where this table is found. Must be com_users\"},\"properties18\":{\"name\":\"view\",\"example\":\"subject\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"description\":\"(mandatory) The single view name if the place this field is added.\"},\"properties19\":{\"name\":\"views\",\"example\":\"subjects\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"description\":\"(mandatory) The list view name if the place this field is added.\"},\"properties20\":{\"name\":\"value_field\",\"example\":\"name\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"description\":\"(mandatory) The name of the text field in table linked to.\"},\"properties21\":{\"name\":\"key_field\",\"example\":\"id\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"description\":\"(mandatory) The field from the linked table to save in this table as the unique key.\"},\"properties22\":{\"name\":\"prime_php\",\"example\":\"1\",\"adjustable\":\"1\",\"description\":\"This field makes sure that the PHP used here is used to build the field type, and other are custom fields with the same field type are ignored. So to avoid that they over write the PHP added here. You should only have one prime per\\/type. To disable remove the field or set to 0\"},\"properties23\":{\"name\":\"type_php_1\",\"example\":\"$db = JFactory::getDBO();\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties24\":{\"name\":\"type_php_2\",\"example\":\"$query = $db->getQuery(true);\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties25\":{\"name\":\"type_php_3\",\"example\":\"$query->select($db->quoteName(array(\'a.###ID###\',\'a.###TEXT###\'),array(\'###ID###\',\'###CODE_TEXT###\')));\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties26\":{\"name\":\"type_php_4\",\"example\":\"$query->from($db->quoteName(\'###TABLE###\', \'a\'));\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties27\":{\"name\":\"type_php_5\",\"example\":\"$query->where($db->quoteName(\'a.published\') . \' = 1\');\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties28\":{\"name\":\"type_php_6\",\"example\":\"$query->order(\'a.###TEXT### ASC\');\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties29\":{\"name\":\"type_php_7\",\"example\":\"$db->setQuery((string)$query);\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties30\":{\"name\":\"type_php_8\",\"example\":\"$items = $db->loadObjectList();\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties31\":{\"name\":\"type_php_9\",\"example\":\"$options = array();\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties32\":{\"name\":\"type_php_10\",\"example\":\"if ($items)\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties33\":{\"name\":\"type_php_11\",\"example\":\"{\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties34\":{\"name\":\"type_php_12\",\"example\":\"\\\\t$options[] = JHtml::_(\'select.option\', \'\', \'Select an option\');\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties35\":{\"name\":\"type_php_13\",\"example\":\"\\\\tforeach($items as $item)\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties36\":{\"name\":\"type_php_14\",\"example\":\"\\\\t{\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties37\":{\"name\":\"type_php_15\",\"example\":\"\\\\t\\\\t$options[] = JHtml::_(\'select.option\', $item->###ID###, $item->###CODE_TEXT###);\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties38\":{\"name\":\"type_php_16\",\"example\":\"\\\\t}\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties39\":{\"name\":\"type_php_17\",\"example\":\"}\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties40\":{\"name\":\"type_php_18\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties41\":{\"name\":\"type_php_19\",\"example\":\"return $options;\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"}}', 'provides a drop down list of items entries.', '', 1, 8, '', ''), +(6, '', 'The list form field type provides a drop down list or a list box of other current component table entries. If the field has a saved value this is selected when the page is first loaded. If not, the default value (if any) is selected.', 'Custom', '{\"properties0\":{\"name\":\"type\",\"example\":\"subjects\",\"mandatory\":\"1\",\"description\":\"(mandatory) can be anything, just not the same as any other default Joomla field type.\"},\"properties1\":{\"name\":\"name\",\"example\":\"subject\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"description\":\"(mandatory) is the unique name of the field.\"},\"properties2\":{\"name\":\"label\",\"example\":\"Select a Subject\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"translatable\":\"1\",\"description\":\"(mandatory) (translatable) is the descriptive title of the field.\"},\"properties3\":{\"name\":\"description\",\"example\":\"\",\"adjustable\":\"1\",\"translatable\":\"1\",\"description\":\"(optional) (translatable) is text that will be shown as a tooltip when the user moves the mouse over the drop-down box.\"},\"properties4\":{\"name\":\"message\",\"example\":\"\",\"adjustable\":\"1\",\"translatable\":\"1\",\"description\":\"(optional) (translatable) is text that will be shown as error on validation.\"},\"properties5\":{\"name\":\"class\",\"example\":\"list_class\",\"adjustable\":\"1\",\"description\":\"(optional) is a CSS class name for the HTML form field. If omitted this will default to \'inputbox\'.\"},\"properties6\":{\"name\":\"multiple\",\"example\":\"false\",\"adjustable\":\"1\",\"description\":\"(optional) is whether multiple items can be selected at the same time (true or false).\"},\"properties7\":{\"name\":\"default\",\"example\":\"0\",\"adjustable\":\"1\",\"description\":\"(optional) (not translatable) is the default value.\"},\"properties8\":{\"name\":\"required\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) The field must be filled before submitting the form.\"},\"properties9\":{\"name\":\"validate\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) The validation method for the form field. This value will determine which method is used to validate the value for a field.\"},\"properties10\":{\"name\":\"readonly\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) The field cannot be changed and will automatically inherit the default value\"},\"properties11\":{\"name\":\"disabled\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) The field cannot be changed and will automatically inherit the default value - it will also not submit\"},\"properties12\":{\"name\":\"showon\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) show this field on the bases of the value in another field.\"},\"properties13\":{\"name\":\"onchange\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) HTML equivalent attribute (javascript use)\"},\"properties14\":{\"name\":\"extends\",\"example\":\"list\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"description\":\"The JFormField sub class that should be extended. The options are (\'list\',\'radio\',\'checkboxes\')\"},\"properties15\":{\"name\":\"button\",\"example\":\"true\",\"adjustable\":\"1\",\"description\":\"(optional) to add new button next to field in edit view\"},\"properties16\":{\"name\":\"table\",\"example\":\"#__###component###_subject\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"description\":\"(mandatory) The table being linked to. The ###TABLE### placeholder holds the table in the php.\"},\"properties17\":{\"name\":\"component\",\"example\":\"com_###component###\",\"mandatory\":\"1\",\"description\":\"(mandatory) The name of the component where this table is found. Must be com_users\"},\"properties18\":{\"name\":\"view\",\"example\":\"subject\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"description\":\"(mandatory) The single view name if the place this field is added.\"},\"properties19\":{\"name\":\"views\",\"example\":\"subjects\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"description\":\"(mandatory) The list view name if the place this field is added.\"},\"properties20\":{\"name\":\"value_field\",\"example\":\"name\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"description\":\"(mandatory) The name of the text field in table linked to. The ###TEXT### placeholder holds the value_field in the php.\"},\"properties21\":{\"name\":\"key_field\",\"example\":\"id\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"description\":\"(mandatory) The field from the linked table to save in this table as the unique key. The ###ID### placeholder holds the key_field in the php.\"},\"properties22\":{\"name\":\"prime_php\",\"example\":\"1\",\"adjustable\":\"1\",\"description\":\"This field makes sure that the PHP used here is used to build the field type, and other are custom fields with the same field type are ignored. So to avoid that they over write the PHP added here. You should only have one prime per\\/type. To disable remove the field or set to 0\"},\"properties23\":{\"name\":\"type_php_1\",\"example\":\"$db = JFactory::getDBO();\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties24\":{\"name\":\"type_php_2\",\"example\":\"$query = $db->getQuery(true);\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties25\":{\"name\":\"type_php_3\",\"example\":\"$query->select($db->quoteName(array(\'a.###ID###\',\'a.###TEXT###\'),array(\'###ID###\',\'###CODE_TEXT###\')));\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties26\":{\"name\":\"type_php_4\",\"example\":\"$query->from($db->quoteName(\'###TABLE###\', \'a\'));\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties27\":{\"name\":\"type_php_5\",\"example\":\"$query->where($db->quoteName(\'a.published\') . \' = 1\');\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties28\":{\"name\":\"type_php_6\",\"example\":\"$query->order(\'a.###TEXT### ASC\');\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties29\":{\"name\":\"type_php_7\",\"example\":\"$db->setQuery((string)$query);\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties30\":{\"name\":\"type_php_8\",\"example\":\"$items = $db->loadObjectList();\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties31\":{\"name\":\"type_php_9\",\"example\":\"$options = array();\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties32\":{\"name\":\"type_php_10\",\"example\":\"if ($items)\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties33\":{\"name\":\"type_php_11\",\"example\":\"{\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties34\":{\"name\":\"type_php_12\",\"example\":\"\\\\t$options[] = JHtml::_(\'select.option\', \'\', \'Select an option\');\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties35\":{\"name\":\"type_php_13\",\"example\":\"\\\\tforeach($items as $item)\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties36\":{\"name\":\"type_php_14\",\"example\":\"\\\\t{\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties37\":{\"name\":\"type_php_15\",\"example\":\"\\\\t\\\\t$options[] = JHtml::_(\'select.option\', $item->###ID###, $item->###CODE_TEXT###);\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties38\":{\"name\":\"type_php_16\",\"example\":\"\\\\t}\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties39\":{\"name\":\"type_php_17\",\"example\":\"}\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties40\":{\"name\":\"type_php_18\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"},\"properties41\":{\"name\":\"type_php_19\",\"example\":\"return $options;\",\"adjustable\":\"1\",\"description\":\"The php for the getOptions method.\"}}', 'provides a drop down list of items entries.', '', 1, 9, '', ''), (7, '', 'The a list of users that can be targeting one or more groups and excluded users that already belongs to an item in a view.', 'CustomUser', '{\"properties0\":{\"name\":\"type\",\"example\":\"staffusers\",\"adjustable\":\"0\",\"mandatory\":\"1\",\"translatable\":\"0\",\"description\":\"(mandatory) can be anything, just not the same as any other default Joomla field type.\"},\"properties1\":{\"name\":\"name\",\"example\":\"staff\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"translatable\":\"0\",\"description\":\"(mandatory) is the unique name of the field.\"},\"properties2\":{\"name\":\"label\",\"example\":\"Staff\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"translatable\":\"1\",\"description\":\"(mandatory) (translatable) is the descriptive title of the field.\"},\"properties3\":{\"name\":\"description\",\"example\":\"\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"1\",\"description\":\"(optional) (translatable) is text that will be shown as a tooltip when the user moves the mouse over the drop-down box.\"},\"properties4\":{\"name\":\"class\",\"example\":\"\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"(optional) is a CSS class name for the HTML form field. If omitted this will default to \'inputbox\'.\"},\"properties5\":{\"name\":\"multiple\",\"example\":\"false\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"(optional) is whether multiple items can be selected at the same time (true or false).\"},\"properties6\":{\"name\":\"required\",\"example\":\"\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"(optional) The field must be filled before submitting the form.\"},\"properties7\":{\"name\":\"readonly\",\"example\":\"\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"(optional) The field cannot be changed and will automatically inherit the default value\"},\"properties8\":{\"name\":\"disabled\",\"example\":\"\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"(optional) The field cannot be changed and will automatically inherit the default value - it will also not submit\"},\"properties9\":{\"name\":\"default\",\"example\":\"\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"1\",\"description\":\"\"},\"properties10\":{\"name\":\"hint\",\"example\":\"select a user\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"1\",\"description\":\"\"},\"properties11\":{\"name\":\"showon\",\"example\":\"\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"(optional) show this field on the bases of the value in another field.\"},\"properties12\":{\"name\":\"extends\",\"example\":\"user\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"translatable\":\"0\",\"description\":\"The JFormField sub class that should be extended. The options are (\'list\',\'radio\',\'checkboxes\')\"},\"properties13\":{\"name\":\"table\",\"example\":\"#__users\",\"adjustable\":\"0\",\"mandatory\":\"1\",\"translatable\":\"0\",\"description\":\"(mandatory) The table being linked to. Must be #__users\"},\"properties14\":{\"name\":\"component\",\"example\":\"com_users\",\"adjustable\":\"0\",\"mandatory\":\"1\",\"translatable\":\"0\",\"description\":\"(mandatory) The name of the component where this table is found. Must be com_users\"},\"properties15\":{\"name\":\"view\",\"example\":\"###view###\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"translatable\":\"0\",\"description\":\"(mandatory) The single view name if the place this field is added.\"},\"properties16\":{\"name\":\"views\",\"example\":\"###views###\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"translatable\":\"0\",\"description\":\"(mandatory) The list view name if the place this field is added.\"},\"properties17\":{\"name\":\"value_field\",\"example\":\"name\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"translatable\":\"0\",\"description\":\"(mandatory) The name of the text field in table linked to.\"},\"properties18\":{\"name\":\"key_field\",\"example\":\"id\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"translatable\":\"0\",\"description\":\"(mandatory) The field from the linked table to save in this table as the unique key.\"},\"properties19\":{\"name\":\"type_php_1\",\"example\":\"\\/\\/ set the groups array\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"The php for the getGroups method.\"},\"properties20\":{\"name\":\"type_php_2\",\"example\":\"$groups = JComponentHelper::getParams(\'com_###component###\')->get(\'###type###\');\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"The php for the getGroups method.\"},\"properties21\":{\"name\":\"type_php_3\",\"example\":\"return $groups;\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"The php for the getGroups method.\"},\"properties22\":{\"name\":\"type_phpx_1\",\"example\":\"\\/\\/ To ensure that there is only one record per user\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"The php for the getExcluded method.\"},\"properties23\":{\"name\":\"type_phpx_2\",\"example\":\"\\/\\/ Get a db connection.\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"The php for the getExcluded method.\"},\"properties24\":{\"name\":\"type_phpx_3\",\"example\":\"$db = JFactory::getDbo();\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"The php for the getExcluded method.\"},\"properties25\":{\"name\":\"type_phpx_4\",\"example\":\"\\/\\/ Create a new query object.\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"The php for the getExcluded method.\"},\"properties26\":{\"name\":\"type_phpx_5\",\"example\":\"$query = $db->getQuery(true);\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"The php for the getExcluded method.\"},\"properties27\":{\"name\":\"type_phpx_6\",\"example\":\"\\/\\/ Select all records from the #__###component###_###view### table from ###CODE### column\\\".\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"The php for the getExcluded method.\"},\"properties28\":{\"name\":\"type_phpx_7\",\"example\":\"$query->select($db->quoteName(\'###CODE###\'));\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"The php for the getExcluded method.\"},\"properties29\":{\"name\":\"type_phpx_8\",\"example\":\"$query->from($db->quoteName(\'#__###component###_###view###\'));\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"The php for the getExcluded method.\"},\"properties30\":{\"name\":\"type_phpx_9\",\"example\":\"$db->setQuery($query);\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"The php for the getExcluded method.\"},\"properties31\":{\"name\":\"type_phpx_10\",\"example\":\"$db->execute();\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"The php for the getExcluded method.\"},\"properties32\":{\"name\":\"type_phpx_11\",\"example\":\"$found = $db->getNumRows();\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"The php for the getExcluded method.\"},\"properties33\":{\"name\":\"type_phpx_12\",\"example\":\"if ($found)\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"The php for the getExcluded method.\"},\"properties34\":{\"name\":\"type_phpx_13\",\"example\":\"{\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"The php for the getExcluded method.\"},\"properties35\":{\"name\":\"type_phpx_14\",\"example\":\"\\\\t\\/\\/ return all users already used\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"The php for the getExcluded method.\"},\"properties36\":{\"name\":\"type_phpx_15\",\"example\":\"\\\\treturn array_unique($db->loadColumn());\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"The php for the getExcluded method.\"},\"properties37\":{\"name\":\"type_phpx_16\",\"example\":\"}\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"The php for the getExcluded method.\"},\"properties38\":{\"name\":\"type_phpx_17\",\"example\":\"return null;\",\"adjustable\":\"1\",\"mandatory\":\"0\",\"translatable\":\"0\",\"description\":\"The php for the getExcluded method.\"}}', 'Provides list of users.', '', 1, 2, '', ''), (8, '', 'The Editor field type provides a WYSIWYG editor.', 'Editor', '{\"properties0\":{\"name\":\"type\",\"example\":\"editor\",\"mandatory\":\"1\",\"description\":\"(mandatory) must be editor.\"},\"properties1\":{\"name\":\"name\",\"example\":\"mytextblock\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"description\":\"(mandatory) is the unique name of the parameter.\"},\"properties2\":{\"name\":\"label\",\"example\":\"Test Field\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"translatable\":\"1\",\"description\":\"(mandatory) (translatable) is the descriptive title of the field.\"},\"properties3\":{\"name\":\"default\",\"example\":\"Some text\",\"adjustable\":\"1\",\"description\":\"(optional) (not translatable) is the default value.\"},\"properties16\":{\"name\":\"message\",\"example\":\"\",\"adjustable\":\"1\",\"translatable\":\"1\",\"description\":\"(optional) (translatable) is text that will be shown as error on validation.\"},\"properties4\":{\"name\":\"width\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) defines the width (in pixels) of the wysiwyg editor and defaults to 100%.\"},\"properties5\":{\"name\":\"height\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) defines the height (in pixels) of the wysiwyg editor and defaults to 250px.\"},\"properties6\":{\"name\":\"cols\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) defines the width of the editor (in columns).\"},\"properties7\":{\"name\":\"rows\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) defines the height of the editor (in rows).\"},\"properties8\":{\"name\":\"buttons\",\"example\":\"false\",\"adjustable\":\"1\",\"description\":\"(optional) can be an array of plugin buttons to be excluded or set to false. The default editors-xtd are: article, image, pagebreak and readmore.\"},\"properties9\":{\"name\":\"hide\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) array of plugin buttons to be hidden. eg... set buttons=\\\"true\\\" hide=\\\"readmore,pagebreak\\\"\"},\"properties10\":{\"name\":\"editor\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"specifies the editor to be used and can include two options (editor=\\\"desired|alternative\\\")\"},\"properties11\":{\"name\":\"filter\",\"example\":\"safehtml\",\"adjustable\":\"1\",\"description\":\"(optional) allow the system to save certain html tags or raw data.\"},\"properties12\":{\"name\":\"required\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) The field must be filled before submitting the form.\"},\"properties15\":{\"name\":\"validate\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) The validation method for the form field. This value will determine which method is used to validate the value for a field.\"},\"properties13\":{\"name\":\"showon\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) show this field on the bases of the value in another field.\"}}', 'provides an editor area field.', '', 1, 5, '', ''), (9, '', 'The hidden form field type provides a hidden field for saving a field whose value cannot be altered directly by a user in the Administrator (it can be altered in code or by editing the params.ini file). If the parameter has a saved value this is entered i', 'Hidden', '{\"properties0\":{\"name\":\"type\",\"example\":\"hidden\",\"mandatory\":\"1\",\"description\":\"(mandatory) must be hidden.\"},\"properties1\":{\"name\":\"name\",\"example\":\"mysecretvariable\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"description\":\"(mandatory) is the unique name of the field.\"},\"properties2\":{\"name\":\"default\",\"example\":\"1\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"description\":\"(mandatory) is the data which needs to be collected.\"},\"properties5\":{\"name\":\"filter\",\"example\":\"STRING\",\"adjustable\":\"1\",\"description\":\"(optional) allow the system to save certain html tags or raw data.\"},\"properties4\":{\"name\":\"validate\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) The validation method for the form field. This value will determine which method is used to validate the value for a field.\"}}', 'provides a hidden field for saving a form field whose value cannot be altered directly by a user.', '', 1, 2, '', ''), diff --git a/site/helpers/componentbuilder.php b/site/helpers/componentbuilder.php index 41f782d35..8bb1331fa 100644 --- a/site/helpers/componentbuilder.php +++ b/site/helpers/componentbuilder.php @@ -612,6 +612,7 @@ abstract class ComponentbuilderHelper $field = array( 'subform' => array(), 'nameListOptions' => array(), + 'php' => array(), 'values' => " '', 'short_description' => $result->short_description, @@ -624,32 +625,62 @@ abstract class ComponentbuilderHelper $field['values_description'] .= ''; foreach ($properties as $property) { - $example = (isset($property['example']) && self::checkString($property['example'])) ? self::shorten($property['example'], 30) : ''; + $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'] .= "\n\t".$property['name'].'="'.$settings[$property['name']].'" '; + $field['values'] .= PHP_EOL."\t".$property['name'].'="'.$settings[$property['name']].'" '; // add the json values - $field['subform']['properties'.$nr] = array('name' => $property['name'], 'value' => $settings[$property['name']]); - // add the name List Options as set - $field['nameListOptionsSet'][$property['name']] = $property['name']; + 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'] .= "\n\t" . $property['name'] . '="'. ($confirmation !== $value) ? $value : $property['example'] .'" '; + $field['values'] .= PHP_EOL."\t" . $property['name'] . '="'. ($confirmation !== $value) ? $value : $example .'" '; // add the json values - $field['subform']['properties' . $nr] = array('name' => $property['name'], 'value' => ($confirmation !== $value) ? $value : $property['example'], 'desc' => $property['description']); + 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 - $field['nameListOptions'][$property['name']] = $property['name']; + if (!$addPHP) + { + $field['nameListOptions'][$property['name']] = $property['name']; + } // increment the number $nr++; } - $field['values'] .= "\n/>"; + $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; -- 2.40.1 From dfff74989e16707f81d97701f5fe28dd6aa1f36b Mon Sep 17 00:00:00 2001 From: Llewellyn van der Merwe Date: Sun, 15 Apr 2018 22:21:34 +0200 Subject: [PATCH 02/14] Keeping naming consistency resolved gh-265. Started adding the needed features for the new translation improvment gh-261 --- README.md | 4 +- admin/README.txt | 4 +- admin/access.xml | 5 +- admin/controllers/languages.php | 28 ++++- .../en-GB/en-GB.com_componentbuilder.ini | 17 ++- .../en-GB/en-GB.com_componentbuilder.sys.ini | 10 +- admin/models/languages.php | 116 ++++++++++++++++++ admin/sql/install.mysql.utf8.sql | 4 +- admin/views/joomla_components/view.html.php | 12 +- admin/views/languages/view.html.php | 5 + componentbuilder.xml | 2 +- 11 files changed, 181 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 041103f52..ef50ea798 100644 --- a/README.md +++ b/README.md @@ -126,11 +126,11 @@ Component Builder is mapped as a component in itself on my local development env + *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + *Name*: [Component Builder](http://joomlacomponentbuilder.com) + *First Build*: 30th April, 2015 -+ *Last Build*: 14th April, 2018 ++ *Last Build*: 15th April, 2018 + *Version*: 2.7.5 + *Copyright*: Copyright (C) 2015. All Rights Reserved + *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html -+ *Line count*: **182437** ++ *Line count*: **182585** + *Field count*: **1012** + *File count*: **1199** + *Folder count*: **193** diff --git a/admin/README.txt b/admin/README.txt index 041103f52..ef50ea798 100644 --- a/admin/README.txt +++ b/admin/README.txt @@ -126,11 +126,11 @@ Component Builder is mapped as a component in itself on my local development env + *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + *Name*: [Component Builder](http://joomlacomponentbuilder.com) + *First Build*: 30th April, 2015 -+ *Last Build*: 14th April, 2018 ++ *Last Build*: 15th April, 2018 + *Version*: 2.7.5 + *Copyright*: Copyright (C) 2015. All Rights Reserved + *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html -+ *Line count*: **182437** ++ *Line count*: **182585** + *Field count*: **1012** + *File count*: **1199** + *Folder count*: **193** diff --git a/admin/access.xml b/admin/access.xml index 1e03fea0e..2bded6af0 100644 --- a/admin/access.xml +++ b/admin/access.xml @@ -232,8 +232,8 @@ - - + + @@ -247,6 +247,7 @@ + diff --git a/admin/controllers/languages.php b/admin/controllers/languages.php index e025c02f5..7565876a4 100644 --- a/admin/controllers/languages.php +++ b/admin/controllers/languages.php @@ -107,5 +107,31 @@ class ComponentbuilderControllerLanguages extends JControllerAdmin $message = JText::_('COM_COMPONENTBUILDER_IMPORT_FAILED'); $this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=languages', false), $message, 'error'); return; - } + } + + public function buildLanguages() + { + // Check for request forgeries + JSession::checkToken() or die(JText::_('JINVALID_TOKEN')); + // check if user has the right + $user = JFactory::getUser(); + if($user->authorise('core.create', 'com_componentbuilder')) + { + // get the model + $model = $this->getModel('languages'); + if ($model->buildLanguages()) + { + // set success message + $message = '

'.JText::_('COM_COMPONENTBUILDER_IMPORT_SUCCESS').'

'; + $message .= '

'.JText::_('COM_COMPONENTBUILDER_ALL_THE_LANGUAGES_FOUND_IN_JOOMLA_WERE_SUCCESSFULLY_IMPORTED').'

'; + // set redirect + $redirect_url = JRoute::_('index.php?option=com_componentbuilder&view=languages', false); + $this->setRedirect($redirect_url, $message); + } + } + // set redirect + $redirect_url = JRoute::_('index.php?option=com_componentbuilder&view=languages', false); + $this->setRedirect($redirect_url); + 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 5b51136b9..66b7fa495 100644 --- a/admin/language/en-GB/en-GB.com_componentbuilder.ini +++ b/admin/language/en-GB/en-GB.com_componentbuilder.ini @@ -894,6 +894,7 @@ COM_COMPONENTBUILDER_ALL="All" COM_COMPONENTBUILDER_ALL_IS_GOOD_PLEASE_CHECK_AGAIN_LATTER="All is good, please check again latter." COM_COMPONENTBUILDER_ALL_IS_GOOD_THERE_IS_NO_NOTICE_AT_THIS_TIME="All is good, there is no notice at this time." COM_COMPONENTBUILDER_ALL_OF_THESE_PACKAGES_ARE_A_FULLY_DEVELOPEDMAPPED_COMPONENTS_FOR_JCB_THEY_CAN_BE_SEEN_AS_DEMO_CONTENT_OR_BASE_IMAGES_FROM_WHICH_TO_START_YOUR_PROJECTBR_ALWAYS_MAKE_SURE_YOU_ARE_ON_THE_LATEST_VERSION_OF_JCB_BEFORE_IMPORTING_ANY_OF_THESE_PACKAGES_SHOULD_ANY_OF_THEM_FAIL_TO_IMPORT_A_S_PLEASE_LET_US_KNOWA="All of these packages are a fully developed/mapped components for JCB. They can be seen as demo content, or base images from which to start your project.
Always make sure you are on the latest version of JCB before importing any of these packages, should any of them fail to import please let us know." +COM_COMPONENTBUILDER_ALL_THE_LANGUAGES_FOUND_IN_JOOMLA_WERE_SUCCESSFULLY_IMPORTED="All the languages found in Joomla were successfully imported." COM_COMPONENTBUILDER_ALL_UNSAVED_WORK_ON_THIS_PAGE_WILL_BE_LOST_ARE_YOU_SURE_YOU_WANT_TO_CONTINUE="All unsaved work on this page will be lost, are you sure you want to continue?" COM_COMPONENTBUILDER_ALWAYS_ADD="Always Add" COM_COMPONENTBUILDER_ALWAYS_INSURE_THAT_YOU_HAVE_YOUR_LOCAL_COMPONENTS_BACKED_UP_BY_MAKING_AN_EXPORT_OF_ALL_YOUR_LOCAL_COMPONENTS_BEFORE_IMPORTING_ANY_NEW_COMPONENTS_SMALLMAKE_BSUREB_TO_MOVE_THIS_ZIPPED_BACKUP_PACKAGE_OUT_OF_THE_TMP_FOLDER_BEFORE_DOING_AN_IMPORTSMALLBR_IF_YOU_ARE_IMPORTING_A_PACKAGE_OF_A_THREERD_PARTY_JCB_PACKAGE_DEVELOPER_BMAKE_SURE_IT_IS_A_REPUTABLE_JCB_PACKAGE_DEVELOPERSB="Always insure that you have your local components backed up, by making an export of all your local components before importing any new components. (Make SURE to move this zipped backup package out of the tmp folder before doing an import)
If you are importing a package of a 3rd party JCB package developer, make sure it is a reputable JCB package developers!" @@ -939,6 +940,7 @@ COM_COMPONENTBUILDER_BSB_EMCOMPONENT_DETAILSEM="%s component details< COM_COMPONENTBUILDER_BSB_HAS_BEEN_IMPORTED="%s has been imported!" COM_COMPONENTBUILDER_BSB_HAS_BEEN_UPDATED="%s has been updated!" COM_COMPONENTBUILDER_BSB_WAS_FOUND="%s was found!" +COM_COMPONENTBUILDER_BUILD="Build" COM_COMPONENTBUILDER_BUILDIN="Build-in" COM_COMPONENTBUILDER_BULK="Bulk" COM_COMPONENTBUILDER_BULK_GET_ALL_NEW_SNIPPETS="Bulk Get All New Snippets" @@ -3582,11 +3584,11 @@ COM_COMPONENTBUILDER_EXACT_LENGTH_ONLY_FOUR_TEXT_FIELD="Exact Length (only 4 tex COM_COMPONENTBUILDER_EXAMPLE="Example" COM_COMPONENTBUILDER_EXPORTIMPORT_DATA="Export/Import Data" COM_COMPONENTBUILDER_EXPORT_COMPLETED="Export Completed!" -COM_COMPONENTBUILDER_EXPORT_COMPONENTS="Export Components" COM_COMPONENTBUILDER_EXPORT_DATA="Export Data" COM_COMPONENTBUILDER_EXPORT_DATA_DESC=" Allows users in this group to export data." COM_COMPONENTBUILDER_EXPORT_FAILED="Export Failed" COM_COMPONENTBUILDER_EXPORT_FAILED_PLEASE_TRY_AGAIN_LATTER="Export failed, please try again latter!" +COM_COMPONENTBUILDER_EXPORT_JCB_PACKAGES="Export JCB Packages" COM_COMPONENTBUILDER_EXTRA_PROPERTIES_LIKE_LISTCLASS_ESCAPE_DISPLAY_VALIDATEBR_SMALLHERE_YOU_CAN_SET_THE_EXTRA_PROPERTIES_FOR_THIS_FIELDSMALL="Extra properties like (listclass, escape, display, validate)
Here you can set the extra properties for this field" COM_COMPONENTBUILDER_FIELD="Field" COM_COMPONENTBUILDER_FIELDS="Fields" @@ -4123,7 +4125,6 @@ COM_COMPONENTBUILDER_HTWOCURL_NOT_FOUNDHTWOPPLEASE_SETUP_CURL_ON_YOUR_SYSTEM_OR_ COM_COMPONENTBUILDER_HTWODATA_IS_CORRUPTHTWOTHIS_COULD_BE_DUE_TO_BROKEN_PACKAGE="

Data is corrupt!

This could be due to broken package!" COM_COMPONENTBUILDER_HTWODATA_IS_CORRUPTHTWOTHIS_COULD_BE_DUE_TO_KEY_ERROR_OR_BROKEN_PACKAGE="

Data is corrupt!

This could be due to key error, or broken package!" COM_COMPONENTBUILDER_ICON="Icon" -COM_COMPONENTBUILDER_IMPORT_COMPONENTS="Import Components" COM_COMPONENTBUILDER_IMPORT_CONTINUE="Continue" COM_COMPONENTBUILDER_IMPORT_DATA="Import Data" COM_COMPONENTBUILDER_IMPORT_DATA_DESC=" Allows users in this group to import data." @@ -4136,6 +4137,7 @@ COM_COMPONENTBUILDER_IMPORT_FROM_UPLOAD="Upload" COM_COMPONENTBUILDER_IMPORT_FROM_URL="URL" COM_COMPONENTBUILDER_IMPORT_GET_BOTTON="Get File" COM_COMPONENTBUILDER_IMPORT_IGNORE_COLUMN="-- Ignore This Column --" +COM_COMPONENTBUILDER_IMPORT_JCB_PACKAGES="Import JCB Packages" COM_COMPONENTBUILDER_IMPORT_LINK_FILE_TO_TABLE_COLUMNS="Link File to Table Columns" COM_COMPONENTBUILDER_IMPORT_MSG_DOES_NOT_HAVE_A_VALID_FILE_TYPE="Does not have a valid file type." COM_COMPONENTBUILDER_IMPORT_MSG_ENTER_A_URL="Please enter a url." @@ -4372,8 +4374,8 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_BUY_LINK_DESCRIPTION="Enter link wh COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_BUY_LINK_HINT="http://www.example.com/buy-keys" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_BUY_LINK_LABEL="Buy Link
(to get key)" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_BUY_LINK_MESSAGE="Error! Please add link here." -COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_COMPONENTS_BUTTON_ACCESS="Joomla Component Export Components Button Access" -COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_COMPONENTS_BUTTON_ACCESS_DESC=" Allows the users in this group to access the export components button." +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_JCB_PACKAGES_BUTTON_ACCESS="Joomla Component Export JCB Packages Button Access" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_JCB_PACKAGES_BUTTON_ACCESS_DESC=" Allows the users in this group to access the export jcb packages button." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_KEY="Export Key" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_KEY_DESCRIPTION="The key used to lock the data during export." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_KEY_HINT="Export Key Here" @@ -4389,8 +4391,8 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_ID="Id" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_IMAGE="Image" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_IMAGE_DESCRIPTION="The component image (product box) for the dashboard and install page, must be 300px X 300px." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_IMAGE_LABEL="Component Image" -COM_COMPONENTBUILDER_JOOMLA_COMPONENT_IMPORT_COMPONENTS_BUTTON_ACCESS="Joomla Component Import Components Button Access" -COM_COMPONENTBUILDER_JOOMLA_COMPONENT_IMPORT_COMPONENTS_BUTTON_ACCESS_DESC=" Allows the users in this group to access the import components button." +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_IMPORT_JCB_PACKAGES_BUTTON_ACCESS="Joomla Component Import JCB Packages Button Access" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_IMPORT_JCB_PACKAGES_BUTTON_ACCESS_DESC=" Allows the users in this group to access the import jcb packages button." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_JAVASCRIPT="Javascript" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_JAVASCRIPT_DESCRIPTION="Add your JavaScript here! [Do not add the script tags]" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_JAVASCRIPT_HINT="// JavaScript for the entire back-end" @@ -4696,6 +4698,8 @@ COM_COMPONENTBUILDER_LANGUAGES_N_ITEMS_UNPUBLISHED="%s Languages unpublished." COM_COMPONENTBUILDER_LANGUAGES_N_ITEMS_UNPUBLISHED_1="%s Language unpublished." COM_COMPONENTBUILDER_LANGUAGES_SUBMENU="Languages Submenu" COM_COMPONENTBUILDER_LANGUAGES_SUBMENU_DESC="Allows the users in this group to update the submenu of the language" +COM_COMPONENTBUILDER_LANGUAGE_BUILD_BUTTON_ACCESS="Language Build Button Access" +COM_COMPONENTBUILDER_LANGUAGE_BUILD_BUTTON_ACCESS_DESC=" Allows the users in this group to access the build button." COM_COMPONENTBUILDER_LANGUAGE_CREATED_BY_DESC="The user that created this Language." COM_COMPONENTBUILDER_LANGUAGE_CREATED_BY_LABEL="Created By" COM_COMPONENTBUILDER_LANGUAGE_CREATED_DATE_DESC="The date this Language was created." @@ -5340,6 +5344,7 @@ COM_COMPONENTBUILDER_NO_FILES_LINKED="No Files Linked" COM_COMPONENTBUILDER_NO_FOUND="No Found" COM_COMPONENTBUILDER_NO_ITEM_FOUND="No Item Found" COM_COMPONENTBUILDER_NO_KEYS_WERE_FOUND_TO_ADD_AN_EXPORT_KEY_SIMPLY_OPEN_THE_COMPONENT_GO_TO_THE_TAB_CALLED_SETTINGS_BOTTOM_RIGHT_THERE_IS_A_FIELD_CALLED_EXPORT_KEY="No keys were found. To add an export key simply open the component, go to the tab called settings, bottom right there is a field called Export Key." +COM_COMPONENTBUILDER_NO_LANGUAGES_UPDATE_SERVER_FOUND="No Languages Update server found." COM_COMPONENTBUILDER_NO_NEED_TO_GET_IT_SINCE_IT_IS_ALREADY_IN_SYNC_WITH_YOUR_LOCAL_VERSION="No need to get it since it is already in sync with your local version" COM_COMPONENTBUILDER_NO_RESULTS_MATCH="No results match" COM_COMPONENTBUILDER_NO_SNIPPETS_WERE_SELECTED_PLEASE_MAKE_A_SELECTION_AND_TRY_AGAIN="No snippets were selected, please make a selection and try again!" diff --git a/admin/language/en-GB/en-GB.com_componentbuilder.sys.ini b/admin/language/en-GB/en-GB.com_componentbuilder.sys.ini index 137fd7205..b634546e5 100644 --- a/admin/language/en-GB/en-GB.com_componentbuilder.sys.ini +++ b/admin/language/en-GB/en-GB.com_componentbuilder.sys.ini @@ -480,10 +480,10 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_SUBMENU="Joomla Components Submenu" COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_SUBMENU_DESC="Allows the users in this group to update the submenu of the joomla component" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BACKUP_BUTTON_ACCESS="Joomla Component Backup Button Access" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BACKUP_BUTTON_ACCESS_DESC=" Allows the users in this group to access the backup button." -COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_COMPONENTS_BUTTON_ACCESS="Joomla Component Export Components Button Access" -COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_COMPONENTS_BUTTON_ACCESS_DESC=" Allows the users in this group to access the export components button." -COM_COMPONENTBUILDER_JOOMLA_COMPONENT_IMPORT_COMPONENTS_BUTTON_ACCESS="Joomla Component Import Components Button Access" -COM_COMPONENTBUILDER_JOOMLA_COMPONENT_IMPORT_COMPONENTS_BUTTON_ACCESS_DESC=" Allows the users in this group to access the import components button." +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_JCB_PACKAGES_BUTTON_ACCESS="Joomla Component Export JCB Packages Button Access" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_JCB_PACKAGES_BUTTON_ACCESS_DESC=" Allows the users in this group to access the export jcb packages button." +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_IMPORT_JCB_PACKAGES_BUTTON_ACCESS="Joomla Component Import JCB Packages Button Access" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_IMPORT_JCB_PACKAGES_BUTTON_ACCESS_DESC=" Allows the users in this group to access the import jcb packages button." COM_COMPONENTBUILDER_LANGUAGES_ACCESS="Languages Access" COM_COMPONENTBUILDER_LANGUAGES_ACCESS_DESC="Allows the users in this group to access access languages" COM_COMPONENTBUILDER_LANGUAGES_BATCH_USE="Languages Batch Use" @@ -506,6 +506,8 @@ COM_COMPONENTBUILDER_LANGUAGES_IMPORT="Languages Import" COM_COMPONENTBUILDER_LANGUAGES_IMPORT_DESC="Allows the users in this group to import import languages" COM_COMPONENTBUILDER_LANGUAGES_SUBMENU="Languages Submenu" COM_COMPONENTBUILDER_LANGUAGES_SUBMENU_DESC="Allows the users in this group to update the submenu of the language" +COM_COMPONENTBUILDER_LANGUAGE_BUILD_BUTTON_ACCESS="Language Build Button Access" +COM_COMPONENTBUILDER_LANGUAGE_BUILD_BUTTON_ACCESS_DESC=" Allows the users in this group to access the build button." COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_ACCESS="Language Translations Access" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_ACCESS_DESC="Allows the users in this group to access access language translations" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS_BATCH_USE="Language Translations Batch Use" diff --git a/admin/models/languages.php b/admin/models/languages.php index afc83e428..420bad3e0 100644 --- a/admin/models/languages.php +++ b/admin/models/languages.php @@ -50,6 +50,122 @@ class ComponentbuilderModelLanguages extends JModelList } parent::__construct($config); + } + + /** + * Load all the languages found in Joomla into JCB + * + * @since 2.7.5 + * + * @return bool true on success + */ + public function buildLanguages() + { + if ($languages = $this->getLanguages()) + { + // make sure we have an array + if (ComponentbuilderHelper::checkArray($languages)) + { + // get the model + $model = ComponentbuilderHelper::getModel('language'); + foreach ($languages as $language) + { + // only load it is a package + if ('package' === $language->type) + { + // build array to store/update + $tmp = array(); + $tmp['id'] = 0; + $tmp['name'] = (string) $language->name; + $tmp['langtag'] = (string) str_replace('pkg_', '', $language->element); + // check if already set + if ($id = ComponentbuilderHelper::getVar('language', $tmp['langtag'], 'langtag', 'id')) + { + $tmp['id'] = (int) $id; + } + // save update the language in the database + $model->save($tmp); + } + } + return true; + } + } + return false; + } + + /** + * Gets an array of objects from the updatesite. + * + * @return object[] An array of results. + * + * @since 2.7.5 + * @throws RuntimeException + */ + protected function getLanguages() + { + $updateSite = $this->getUpdateSite(); + + $http = new JHttp; + + try + { + $response = $http->get($updateSite); + } + catch (RuntimeException $e) + { + $response = null; + } + + if ($response === null || $response->code !== 200) + { + JFactory::getApplication()->enqueueMessage(JText::_('COM_COMPONENTBUILDER_NO_LANGUAGES_UPDATE_SERVER_FOUND'), 'warning'); + + return; + } + + $updateSiteXML = simplexml_load_string($response->body); + $languages = array(); + + foreach ($updateSiteXML->extension as $extension) + { + $language = new stdClass; + + foreach ($extension->attributes() as $key => $value) + { + $language->$key = (string) $value; + } + + $languages[$language->name] = $language; + } + + usort($languages, function($a, $b) + { + return strcmp($a->name, $b->name); + }); + + return $languages; + } + + /** + * Get the Update Site + * + * @since 2.7.5 + * + * @return string The URL of the Accredited Languagepack Updatesite XML + */ + private function getUpdateSite() + { + $db = $this->getDbo(); + $query = $db->getQuery(true) + ->select($db->qn('us.location')) + ->from($db->qn('#__extensions', 'e')) + ->where($db->qn('e.type') . ' = ' . $db->q('package')) + ->where($db->qn('e.element') . ' = ' . $db->q('pkg_en-GB')) + ->where($db->qn('e.client_id') . ' = 0') + ->join('LEFT', $db->qn('#__update_sites_extensions', 'use') . ' ON ' . $db->qn('use.extension_id') . ' = ' . $db->qn('e.extension_id')) + ->join('LEFT', $db->qn('#__update_sites', 'us') . ' ON ' . $db->qn('us.update_site_id') . ' = ' . $db->qn('use.update_site_id')); + + return $db->setQuery($query)->loadResult(); } /** diff --git a/admin/sql/install.mysql.utf8.sql b/admin/sql/install.mysql.utf8.sql index 233413ac8..557620855 100644 --- a/admin/sql/install.mysql.utf8.sql +++ b/admin/sql/install.mysql.utf8.sql @@ -1278,7 +1278,7 @@ CREATE TABLE IF NOT EXISTS `#__componentbuilder_library_files_folders_urls` ( -- INSERT INTO `#__componentbuilder_joomla_component` (`id`, `add_license`, `license_type`, `mvc_versiondate`, `add_css_admin`, `add_css_site`, `add_email_helper`, `add_javascript`, `add_php_helper_admin`, `add_php_helper_both`, `add_php_helper_site`, `add_php_postflight_install`, `add_php_method_uninstall`, `add_php_postflight_update`, `add_php_preflight_install`, `add_php_preflight_update`, `add_placeholders`, `add_sql`, `addfootable`, `adduikit`, `add_admin_event`, `add_site_event`, `add_update_server`, `add_sales_server`, `sales_server`, `update_server`, `update_server_target`, `update_server_url`, `php_admin_event`, `php_site_event`, `addreadme`, `readme`, `author`, `bom`, `buildcomp`, `buildcompsql`, `companyname`, `component_version`, `copyright`, `creatuserhelper`, `css_admin`, `css_site`, `dashboard`, `dashboard_type`, `debug_linenr`, `description`, `email`, `emptycontributors`, `export_buy_link`, `export_package_link`, `export_key`, `image`, `javascript`, `license`, `name`, `system_name`, `toignore`, `name_code`, `number`, `php_helper_admin`, `php_helper_both`, `php_helper_site`, `php_postflight_install`, `php_method_uninstall`, `php_postflight_update`, `php_preflight_install`, `php_preflight_update`, `short_description`, `sql`, `website`, `published`, `created`, `modified`, `hits`, `ordering`, `whmcs_key`, `whmcs_url`) VALUES -(25, '', 1, '', '', '', '', '', '', '', 1, 1, '', '', '', '', '', '', '', 1, '', '', 1, '', '', '', 2, 'https://www.vdm.io/updates/demo_update_server.xml', '', '', 1, 'IyAjIyNDb21wb25lbnRfbmFtZSMjIyAoIyMjVkVSU0lPTiMjIykNCg0KIVsjIyNDb21wb25lbnRfbmFtZSMjIyBpbWFnZV0oaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL25hbWliaWEvZGVtby1qb29tbGEtMy1jb21wb25lbnQvbWFzdGVyL2FkbWluL2Fzc2V0cy9pbWFnZXMvdmRtLWNvbXBvbmVudC5qcGcgIlRoZSAjIyNDb21wb25lbnRfbmFtZSMjIyIpDQoNCiMjI0RFU0NSSVBUSU9OIyMjDQoNCiMgQnVpbGQgRGV0YWlscw0KDQorICpDb21wYW55KjogWyMjI0NPTVBBTllOQU1FIyMjXSgjIyNBVVRIT1JXRUJTSVRFIyMjKQ0KKyAqQXV0aG9yKjogWyMjI0FVVEhPUiMjI10obWFpbHRvOiMjI0FVVEhPUkVNQUlMIyMjKQ0KKyAqTmFtZSo6IFsjIyNDb21wb25lbnRfbmFtZSMjI10oIyMjQVVUSE9SV0VCU0lURSMjIykNCisgKkZpcnN0IEJ1aWxkKjogIyMjQ1JFQVRJT05EQVRFIyMjDQorICpMYXN0IEJ1aWxkKjogIyMjQlVJTEREQVRFIyMjDQorICpWZXJzaW9uKjogIyMjVkVSU0lPTiMjIw0KKyAqQ29weXJpZ2h0KjogIyMjQ09QWVJJR0hUIyMjDQorICpMaWNlbnNlKjogIyMjTElDRU5TRSMjIw0KDQojIyBCdWlsZCBUaW1lDQoNCioqIyMjdG90YWxIb3VycyMjIyBIb3VycyoqIG9yICoqIyMjdG90YWxEYXlzIyMjIEVpZ2h0IEhvdXIgRGF5cyoqIChhY3R1YWwgdGltZSB0aGUgYXV0aG9yIHNhdmVkIC0NCmR1ZSB0byBbQXV0b21hdGVkIENvbXBvbmVudCBCdWlsZGVyXShodHRwczovL3d3dy52ZG0uaW8vam9vbWxhLWNvbXBvbmVudC1idWlsZGVyKSkNCg0KPiAoaWYgY3JlYXRpbmcgYSBmb2xkZXIgYW5kIGZpbGUgdG9vayAqKjUgc2Vjb25kcyoqIGFuZCB3cml0aW5nIG9uZSBsaW5lIG9mIGNvZGUgdG9vayAqKjEwIHNlY29uZHMqKiwNCj4gbmV2ZXIgbWFraW5nIG9uZSBtaXN0YWtlIG9yIHRha2luZyBhbnkgY29mZmVlIGJyZWFrLikNCg0KKyAqTGluZSBjb3VudCo6ICoqIyMjTElORV9DT1VOVCMjIyoqDQorICpGaWxlIGNvdW50KjogKiojIyNGSUxFX0NPVU5UIyMjKioNCisgKkZvbGRlciBjb3VudCo6ICoqIyMjRk9MREVSX0NPVU5UIyMjKioNCg0KKiojIyNhY3R1YWxIb3Vyc1NwZW50IyMjIEhvdXJzKiogb3IgKiojIyNhY3R1YWxEYXlzU3BlbnQjIyMgRWlnaHQgSG91ciBEYXlzKiogKHRoZSBhY3R1YWwgdGltZSB0aGUgYXV0aG9yIHNwZW50KQ0KDQo+ICh3aXRoIHRoZSBmb2xsb3dpbmcgYnJlYWsgZG93bjoNCj4gKipkZWJ1Z2dpbmcgQCMjI2RlYnVnZ2luZ0hvdXJzIyMjaG91cnMqKiA9IGNvZGluZ3RpbWUgLyA0Ow0KPiAqKnBsYW5uaW5nIEAjIyNwbGFubmluZ0hvdXJzIyMjaG91cnMqKiA9IGNvZGluZ3RpbWUgLyA3Ow0KPiAqKm1hcHBpbmcgQCMjI21hcHBpbmdIb3VycyMjI2hvdXJzKiogPSBjb2Rpbmd0aW1lIC8gMTA7DQo+ICoqb2ZmaWNlIEAjIyNvZmZpY2VIb3VycyMjI2hvdXJzKiogPSBjb2Rpbmd0aW1lIC8gNjspDQoNCioqIyMjYWN0dWFsVG90YWxIb3VycyMjIyBIb3VycyoqIG9yICoqIyMjYWN0dWFsVG90YWxEYXlzIyMjIEVpZ2h0IEhvdXIgRGF5cyoqDQooYSB0b3RhbCBvZiB0aGUgcmVhbGlzdGljIHRpbWUgZnJhbWUgZm9yIHRoaXMgcHJvamVjdCkNCg0KPiAoaWYgY3JlYXRpbmcgYSBmb2xkZXIgYW5kIGZpbGUgdG9vayAqKjUgc2Vjb25kcyoqIGFuZCB3cml0aW5nIG9uZSBsaW5lIG9mIGNvZGUgdG9vayAqKjEwIHNlY29uZHMqKiwNCj4gd2l0aCB0aGUgbm9ybWFsIGV2ZXJ5ZGF5IHJlYWxpdGllcyBhdCB0aGUgb2ZmaWNlLCB0aGF0IGluY2x1ZGVzIHRoZSBjb21wb25lbnQgcGxhbm5pbmcsIG1hcHBpbmcgJiBkZWJ1Z2dpbmcuKQ0KDQpQcm9qZWN0IGR1cmF0aW9uOiAqKiMjI3Byb2plY3RXZWVrVGltZSMjIyB3ZWVrcyoqIG9yICoqIyMjcHJvamVjdE1vbnRoVGltZSMjIyBtb250aHMqKg0KDQo+IFRoaXMgKipjb21wb25lbnQqKiB3YXMgYnVpbGQgd2l0aCBhIEpvb21sYSBbQXV0b21hdGVkIENvbXBvbmVudCBCdWlsZGVyXShodHRwczovL3d3dy52ZG0uaW8vam9vbWxhLWNvbXBvbmVudC1idWlsZGVyKS4NCj4gRGV2ZWxvcGVkIGJ5IFtMbGV3ZWxseW4gdmFuIGRlciBNZXJ3ZV0obWFpbHRvOmpvb21sYUB2ZG0uaW8pDQoNCiMjIERvbmF0aW9ucw0KDQpJZiB5b3Ugd2FudCB0byBzdXBwb3J0IHRoaXMgcHJvamVjdCwgcGxlYXNlIGNvbnNpZGVyIGRvbmF0aW5nOg0KKiBQYXlQYWw6IFtwYXlwYWwubWUvcGF5dmRtXShodHRwczovL3d3dy5wYXlwYWwubWUvcGF5dmRtKQ0KKiBCaXRjb2luOiAxRkx4aVQ2d3l4Z1ozYm9ldmlMa1lKMURScHA0MXV6cHhhDQoqIEV0aGVyZXVtOiAweDI0MzM5MmRhYTNjOWM4YmM4NDFmY2FjZjdjN2Y3MjU0MWNiMTY4MjMg', 'Llewellyn van der Merwe', 'default.txt', '', '', 'Vast Development Method', '2.0.0', 'Copyright (C) 2015. All Rights Reserved', '', '', '', '', 1, '', 'Just a basic demo of the most basic implementations of the [Joomla](http://www.joomla.org) Component Builder\'s ability.', 'joomla@vdm.io', '', '', '', 'zrpRHd5ViJh++86Rz3akdntYdwLRNP0VxTz+ktp/Hko=', 'images/vdm/demo500.jpg', '', 'GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html', 'Demo', 'Demo', '.git', 'demo', 4, '', '', 'CS8qKg0KCSAqCUNoYW5nZSB0byBuaWNlIGZhbmN5IGRhdGUNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZhbmN5RGF0ZSgkZGF0ZSkNCgl7DQoJCWlmICghc2VsZjo6aXNWYWxpZFRpbWVTdGFtcCgkZGF0ZSkpDQoJCXsNCgkJCSRkYXRlID0gc3RydG90aW1lKCRkYXRlKTsNCgkJfQ0KCQlyZXR1cm4gZGF0ZSgnalMgXG9cZiBGIFknLCRkYXRlKTsNCgl9DQoNCgkvKioNCgkgKglDaGFuZ2UgdG8gbmljZSBmYW5jeSB0aW1lIGFuZCBkYXRlDQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmYW5jeURhdGVUaW1lKCR0aW1lKQ0KCXsNCgkJaWYgKCFzZWxmOjppc1ZhbGlkVGltZVN0YW1wKCR0aW1lKSkNCgkJew0KCQkJJHRpbWUgPSBzdHJ0b3RpbWUoJHRpbWUpOw0KCQl9DQoJCXJldHVybiBkYXRlKCcoRzppKSBqUyBcb1xmIEYgWScsJHRpbWUpOw0KCX0NCg0KCS8qKg0KCSAqCUNoYW5nZSB0byBuaWNlIGhvdXI6bWludXRlcyB0aW1lDQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmYW5jeVRpbWUoJHRpbWUpDQoJew0KCQlpZiAoIXNlbGY6OmlzVmFsaWRUaW1lU3RhbXAoJHRpbWUpKQ0KCQl7DQoJCQkkdGltZSA9IHN0cnRvdGltZSgkdGltZSk7DQoJCX0NCgkJcmV0dXJuIGRhdGUoJ0c6aScsJHRpbWUpOw0KCX0NCg0KCS8qKg0KCSAqCUNoZWNrIGlmIHN0cmluZyBpcyBhIHZhbGlkIHRpbWUgc3RhbXANCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGlzVmFsaWRUaW1lU3RhbXAoJHRpbWVzdGFtcCkNCgl7DQoJCXJldHVybiAoKGludCkgJHRpbWVzdGFtcCA9PT0gJHRpbWVzdGFtcCkNCgkJJiYgKCR0aW1lc3RhbXAgPD0gUEhQX0lOVF9NQVgpDQoJCSYmICgkdGltZXN0YW1wID49IH5QSFBfSU5UX01BWCk7DQoJfQ0K', 'CQkvLyBHZXQgQXBwbGljYXRpb24gb2JqZWN0DQoJCSRhcHAgPSBKRmFjdG9yeTo6Z2V0QXBwbGljYXRpb24oKTsNCgkJJGFwcC0+ZW5xdWV1ZU1lc3NhZ2UoJ1RoaXMgaXMgYSBkZW1vIGNvbXBvbmVudCBkZXZlbG9wZWQgaW4gPGEgaHJlZj0iaHR0cDovL3ZkbS5iei9jb21wb25lbnQtYnVpbGRlciIgdGFnZXQ9Il9iYWxuayIgdGl0bGU9Ikpvb21sYSBDb21wb25lbnQgQnVpbGRlciI+SkNCPC9hPiEgWW91IGNhbiBidWlsZCBtb3JlIGNvbXBvbmVudHMgbGlrZSB0aGlzIHdpdGggSkNCLCBjaGVja291dCBvdXIgcGFnZSBvbiA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vdmRtLWlvL0pvb21sYS1Db21wb25lbnQtQnVpbGRlciIgdGFnZXQ9Il9iYWxuayIgdGl0bGU9Ikpvb21sYSBDb21wb25lbnQgQnVpbGRlciI+Z2l0aHViPC9hPiBmb3IgbW9yZSBpbmZvLiBUaGUgZnV0dXJlIG9mIDxhIGhyZWY9Imh0dHA6Ly92ZG0uYnovY29tcG9uZW50LWJ1aWxkZXIiIHRhZ2V0PSJfYmFsbmsiIHRpdGxlPSJKb29tbGEgQ29tcG9uZW50IEJ1aWxkZXIiPkpvb21sYSBDb21wb25lbnQgRGV2ZWxvcG1lbnQ8L2E+IGlzIEhlcmUhJywgJ0luZm8nKTs=', '', '', '', '', 'Demo Component', '', 'https://www.vdm.io/', 1, '2016-10-18 11:44:09', '2018-03-30 01:31:16', '', 3, '2QGAdd979/Dn1ryWxTrLkUvnxZoyL5PV/BWMJU500lA=', ''); +(25, '', 1, '', '', '', '', '', '', '', 1, 1, '', '', '', '', '', '', '', 1, '', '', 1, '', '', '', 2, 'https://www.vdm.io/updates/demo_update_server.xml', '', '', 1, 'IyAjIyNDb21wb25lbnRfbmFtZSMjIyAoIyMjVkVSU0lPTiMjIykNCg0KIVsjIyNDb21wb25lbnRfbmFtZSMjIyBpbWFnZV0oaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL25hbWliaWEvZGVtby1qb29tbGEtMy1jb21wb25lbnQvbWFzdGVyL2FkbWluL2Fzc2V0cy9pbWFnZXMvdmRtLWNvbXBvbmVudC5qcGcgIlRoZSAjIyNDb21wb25lbnRfbmFtZSMjIyIpDQoNCiMjI0RFU0NSSVBUSU9OIyMjDQoNCiMgQnVpbGQgRGV0YWlscw0KDQorICpDb21wYW55KjogWyMjI0NPTVBBTllOQU1FIyMjXSgjIyNBVVRIT1JXRUJTSVRFIyMjKQ0KKyAqQXV0aG9yKjogWyMjI0FVVEhPUiMjI10obWFpbHRvOiMjI0FVVEhPUkVNQUlMIyMjKQ0KKyAqTmFtZSo6IFsjIyNDb21wb25lbnRfbmFtZSMjI10oIyMjQVVUSE9SV0VCU0lURSMjIykNCisgKkZpcnN0IEJ1aWxkKjogIyMjQ1JFQVRJT05EQVRFIyMjDQorICpMYXN0IEJ1aWxkKjogIyMjQlVJTEREQVRFIyMjDQorICpWZXJzaW9uKjogIyMjVkVSU0lPTiMjIw0KKyAqQ29weXJpZ2h0KjogIyMjQ09QWVJJR0hUIyMjDQorICpMaWNlbnNlKjogIyMjTElDRU5TRSMjIw0KDQojIyBCdWlsZCBUaW1lDQoNCioqIyMjdG90YWxIb3VycyMjIyBIb3VycyoqIG9yICoqIyMjdG90YWxEYXlzIyMjIEVpZ2h0IEhvdXIgRGF5cyoqIChhY3R1YWwgdGltZSB0aGUgYXV0aG9yIHNhdmVkIC0NCmR1ZSB0byBbQXV0b21hdGVkIENvbXBvbmVudCBCdWlsZGVyXShodHRwczovL3d3dy52ZG0uaW8vam9vbWxhLWNvbXBvbmVudC1idWlsZGVyKSkNCg0KPiAoaWYgY3JlYXRpbmcgYSBmb2xkZXIgYW5kIGZpbGUgdG9vayAqKjUgc2Vjb25kcyoqIGFuZCB3cml0aW5nIG9uZSBsaW5lIG9mIGNvZGUgdG9vayAqKjEwIHNlY29uZHMqKiwNCj4gbmV2ZXIgbWFraW5nIG9uZSBtaXN0YWtlIG9yIHRha2luZyBhbnkgY29mZmVlIGJyZWFrLikNCg0KKyAqTGluZSBjb3VudCo6ICoqIyMjTElORV9DT1VOVCMjIyoqDQorICpGaWxlIGNvdW50KjogKiojIyNGSUxFX0NPVU5UIyMjKioNCisgKkZvbGRlciBjb3VudCo6ICoqIyMjRk9MREVSX0NPVU5UIyMjKioNCg0KKiojIyNhY3R1YWxIb3Vyc1NwZW50IyMjIEhvdXJzKiogb3IgKiojIyNhY3R1YWxEYXlzU3BlbnQjIyMgRWlnaHQgSG91ciBEYXlzKiogKHRoZSBhY3R1YWwgdGltZSB0aGUgYXV0aG9yIHNwZW50KQ0KDQo+ICh3aXRoIHRoZSBmb2xsb3dpbmcgYnJlYWsgZG93bjoNCj4gKipkZWJ1Z2dpbmcgQCMjI2RlYnVnZ2luZ0hvdXJzIyMjaG91cnMqKiA9IGNvZGluZ3RpbWUgLyA0Ow0KPiAqKnBsYW5uaW5nIEAjIyNwbGFubmluZ0hvdXJzIyMjaG91cnMqKiA9IGNvZGluZ3RpbWUgLyA3Ow0KPiAqKm1hcHBpbmcgQCMjI21hcHBpbmdIb3VycyMjI2hvdXJzKiogPSBjb2Rpbmd0aW1lIC8gMTA7DQo+ICoqb2ZmaWNlIEAjIyNvZmZpY2VIb3VycyMjI2hvdXJzKiogPSBjb2Rpbmd0aW1lIC8gNjspDQoNCioqIyMjYWN0dWFsVG90YWxIb3VycyMjIyBIb3VycyoqIG9yICoqIyMjYWN0dWFsVG90YWxEYXlzIyMjIEVpZ2h0IEhvdXIgRGF5cyoqDQooYSB0b3RhbCBvZiB0aGUgcmVhbGlzdGljIHRpbWUgZnJhbWUgZm9yIHRoaXMgcHJvamVjdCkNCg0KPiAoaWYgY3JlYXRpbmcgYSBmb2xkZXIgYW5kIGZpbGUgdG9vayAqKjUgc2Vjb25kcyoqIGFuZCB3cml0aW5nIG9uZSBsaW5lIG9mIGNvZGUgdG9vayAqKjEwIHNlY29uZHMqKiwNCj4gd2l0aCB0aGUgbm9ybWFsIGV2ZXJ5ZGF5IHJlYWxpdGllcyBhdCB0aGUgb2ZmaWNlLCB0aGF0IGluY2x1ZGVzIHRoZSBjb21wb25lbnQgcGxhbm5pbmcsIG1hcHBpbmcgJiBkZWJ1Z2dpbmcuKQ0KDQpQcm9qZWN0IGR1cmF0aW9uOiAqKiMjI3Byb2plY3RXZWVrVGltZSMjIyB3ZWVrcyoqIG9yICoqIyMjcHJvamVjdE1vbnRoVGltZSMjIyBtb250aHMqKg0KDQo+IFRoaXMgKipjb21wb25lbnQqKiB3YXMgYnVpbGQgd2l0aCBhIEpvb21sYSBbQXV0b21hdGVkIENvbXBvbmVudCBCdWlsZGVyXShodHRwczovL3d3dy52ZG0uaW8vam9vbWxhLWNvbXBvbmVudC1idWlsZGVyKS4NCj4gRGV2ZWxvcGVkIGJ5IFtMbGV3ZWxseW4gdmFuIGRlciBNZXJ3ZV0obWFpbHRvOmpvb21sYUB2ZG0uaW8pDQoNCiMjIERvbmF0aW9ucw0KDQpJZiB5b3Ugd2FudCB0byBzdXBwb3J0IHRoaXMgcHJvamVjdCwgcGxlYXNlIGNvbnNpZGVyIGRvbmF0aW5nOg0KKiBQYXlQYWw6IFtwYXlwYWwubWUvcGF5dmRtXShodHRwczovL3d3dy5wYXlwYWwubWUvcGF5dmRtKQ0KKiBCaXRjb2luOiAxRkx4aVQ2d3l4Z1ozYm9ldmlMa1lKMURScHA0MXV6cHhhDQoqIEV0aGVyZXVtOiAweDI0MzM5MmRhYTNjOWM4YmM4NDFmY2FjZjdjN2Y3MjU0MWNiMTY4MjMg', 'Llewellyn van der Merwe', 'default.txt', '', '', 'Vast Development Method', '2.0.0', 'Copyright (C) 2015. All Rights Reserved', '', '', '', '', 1, '', 'Just a basic demo of the most basic implementations of the [Joomla](http://www.joomla.org) Component Builder\'s ability.', 'joomla@vdm.io', '', '', '', 'Ymgaue824e/KwVrIUNp13XOL309i9CH+3Bpu2Pv6cdg=', 'images/vdm/demo500.jpg', '', 'GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html', 'Demo', 'Demo', '.git', 'demo', 4, '', '', 'CS8qKg0KCSAqCUNoYW5nZSB0byBuaWNlIGZhbmN5IGRhdGUNCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGZhbmN5RGF0ZSgkZGF0ZSkNCgl7DQoJCWlmICghc2VsZjo6aXNWYWxpZFRpbWVTdGFtcCgkZGF0ZSkpDQoJCXsNCgkJCSRkYXRlID0gc3RydG90aW1lKCRkYXRlKTsNCgkJfQ0KCQlyZXR1cm4gZGF0ZSgnalMgXG9cZiBGIFknLCRkYXRlKTsNCgl9DQoNCgkvKioNCgkgKglDaGFuZ2UgdG8gbmljZSBmYW5jeSB0aW1lIGFuZCBkYXRlDQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmYW5jeURhdGVUaW1lKCR0aW1lKQ0KCXsNCgkJaWYgKCFzZWxmOjppc1ZhbGlkVGltZVN0YW1wKCR0aW1lKSkNCgkJew0KCQkJJHRpbWUgPSBzdHJ0b3RpbWUoJHRpbWUpOw0KCQl9DQoJCXJldHVybiBkYXRlKCcoRzppKSBqUyBcb1xmIEYgWScsJHRpbWUpOw0KCX0NCg0KCS8qKg0KCSAqCUNoYW5nZSB0byBuaWNlIGhvdXI6bWludXRlcyB0aW1lDQoJICovDQoJcHVibGljIHN0YXRpYyBmdW5jdGlvbiBmYW5jeVRpbWUoJHRpbWUpDQoJew0KCQlpZiAoIXNlbGY6OmlzVmFsaWRUaW1lU3RhbXAoJHRpbWUpKQ0KCQl7DQoJCQkkdGltZSA9IHN0cnRvdGltZSgkdGltZSk7DQoJCX0NCgkJcmV0dXJuIGRhdGUoJ0c6aScsJHRpbWUpOw0KCX0NCg0KCS8qKg0KCSAqCUNoZWNrIGlmIHN0cmluZyBpcyBhIHZhbGlkIHRpbWUgc3RhbXANCgkgKi8NCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIGlzVmFsaWRUaW1lU3RhbXAoJHRpbWVzdGFtcCkNCgl7DQoJCXJldHVybiAoKGludCkgJHRpbWVzdGFtcCA9PT0gJHRpbWVzdGFtcCkNCgkJJiYgKCR0aW1lc3RhbXAgPD0gUEhQX0lOVF9NQVgpDQoJCSYmICgkdGltZXN0YW1wID49IH5QSFBfSU5UX01BWCk7DQoJfQ0K', 'CQkvLyBHZXQgQXBwbGljYXRpb24gb2JqZWN0DQoJCSRhcHAgPSBKRmFjdG9yeTo6Z2V0QXBwbGljYXRpb24oKTsNCgkJJGFwcC0+ZW5xdWV1ZU1lc3NhZ2UoJ1RoaXMgaXMgYSBkZW1vIGNvbXBvbmVudCBkZXZlbG9wZWQgaW4gPGEgaHJlZj0iaHR0cDovL3ZkbS5iei9jb21wb25lbnQtYnVpbGRlciIgdGFnZXQ9Il9iYWxuayIgdGl0bGU9Ikpvb21sYSBDb21wb25lbnQgQnVpbGRlciI+SkNCPC9hPiEgWW91IGNhbiBidWlsZCBtb3JlIGNvbXBvbmVudHMgbGlrZSB0aGlzIHdpdGggSkNCLCBjaGVja291dCBvdXIgcGFnZSBvbiA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vdmRtLWlvL0pvb21sYS1Db21wb25lbnQtQnVpbGRlciIgdGFnZXQ9Il9iYWxuayIgdGl0bGU9Ikpvb21sYSBDb21wb25lbnQgQnVpbGRlciI+Z2l0aHViPC9hPiBmb3IgbW9yZSBpbmZvLiBUaGUgZnV0dXJlIG9mIDxhIGhyZWY9Imh0dHA6Ly92ZG0uYnovY29tcG9uZW50LWJ1aWxkZXIiIHRhZ2V0PSJfYmFsbmsiIHRpdGxlPSJKb29tbGEgQ29tcG9uZW50IEJ1aWxkZXIiPkpvb21sYSBDb21wb25lbnQgRGV2ZWxvcG1lbnQ8L2E+IGlzIEhlcmUhJywgJ0luZm8nKTs=', '', '', '', '', 'Demo Component', '', 'https://www.vdm.io/', 1, '2016-10-18 11:44:09', '2018-04-15 16:22:29', '', 3, 'Ptju6C7zkyklxbyhF0B69sLUK6QZRjv48Ob6l+2GUmA=', ''); -- -- Dumping data for table `#__componentbuilder_admin_view` @@ -1570,7 +1570,7 @@ INSERT INTO `#__componentbuilder_component_admin_views` (`id`, `addadmin_views`, -- INSERT INTO `#__componentbuilder_component_site_views` (`id`, `addsite_views`, `joomla_component`, `published`, `created`, `modified`, `version`, `hits`, `ordering`) VALUES -(27, '{\"addsite_views0\":{\"siteview\":\"23\",\"menu\":\"1\",\"metadata\":\"1\",\"default_view\":\"1\",\"access\":\"1\",\"public\":\"1\"},\"addsite_views1\":{\"siteview\":\"25\",\"menu\":\"0\",\"metadata\":\"1\",\"default_view\":\"0\",\"access\":\"1\",\"public\":\"1\"}}', 25, 1, '2017-10-28 03:56:26', '0000-00-00 00:00:00', 2, '', ''); +(27, '{\"addsite_views0\":{\"siteview\":\"23\",\"menu\":\"1\",\"metadata\":\"1\",\"default_view\":\"1\",\"access\":\"1\",\"public_access\":\"1\"},\"addsite_views1\":{\"siteview\":\"25\",\"metadata\":\"1\",\"access\":\"1\",\"public_access\":\"1\"}}', 25, 1, '2017-10-28 03:56:26', '2018-04-15 16:22:24', 3, '', ''); -- -- Dumping data for table `#__componentbuilder_component_custom_admin_views` diff --git a/admin/views/joomla_components/view.html.php b/admin/views/joomla_components/view.html.php index 5783ca032..0f346928b 100644 --- a/admin/views/joomla_components/view.html.php +++ b/admin/views/joomla_components/view.html.php @@ -134,10 +134,10 @@ class ComponentbuilderViewJoomla_components extends JViewLegacy $dhtml = $layout->render(array('title' => $title)); $bar->appendButton('Custom', $dhtml, 'batch'); } - if ($this->user->authorise('joomla_component.export_components', 'com_componentbuilder')) + if ($this->user->authorise('joomla_component.export_jcb_packages', 'com_componentbuilder')) { - // add Export Components button. - JToolBarHelper::custom('joomla_components.smartExport', 'download', '', 'COM_COMPONENTBUILDER_EXPORT_COMPONENTS', false); + // add Export JCB Packages button. + JToolBarHelper::custom('joomla_components.smartExport', 'download', '', 'COM_COMPONENTBUILDER_EXPORT_JCB_PACKAGES', false); } if ($this->user->authorise('joomla_component.backup', 'com_componentbuilder')) { @@ -159,10 +159,10 @@ class ComponentbuilderViewJoomla_components extends JViewLegacy JToolBarHelper::custom('joomla_components.exportData', 'download', '', 'COM_COMPONENTBUILDER_EXPORT_DATA', true); } } - if ($this->user->authorise('joomla_component.import_components', 'com_componentbuilder')) + if ($this->user->authorise('joomla_component.import_jcb_packages', 'com_componentbuilder')) { - // add Import Components button. - JToolBarHelper::custom('joomla_components.smartImport', 'upload', '', 'COM_COMPONENTBUILDER_IMPORT_COMPONENTS', false); + // add Import JCB Packages button. + JToolBarHelper::custom('joomla_components.smartImport', 'upload', '', 'COM_COMPONENTBUILDER_IMPORT_JCB_PACKAGES', false); } if ($this->canDo->get('core.import') && $this->canDo->get('joomla_component.import')) diff --git a/admin/views/languages/view.html.php b/admin/views/languages/view.html.php index 36b46e873..23c45e6db 100644 --- a/admin/views/languages/view.html.php +++ b/admin/views/languages/view.html.php @@ -148,6 +148,11 @@ class ComponentbuilderViewLanguages extends JViewLegacy { JToolBarHelper::custom('languages.exportData', 'download', '', 'COM_COMPONENTBUILDER_EXPORT_DATA', true); } + } + if ($this->user->authorise('language.build', 'com_componentbuilder')) + { + // add Build button. + JToolBarHelper::custom('languages.buildLanguages', 'joomla', '', 'COM_COMPONENTBUILDER_BUILD', false); } if ($this->canDo->get('core.import') && $this->canDo->get('language.import')) diff --git a/componentbuilder.xml b/componentbuilder.xml index c4c2fad97..ff5f4a70b 100644 --- a/componentbuilder.xml +++ b/componentbuilder.xml @@ -1,7 +1,7 @@ COM_COMPONENTBUILDER - 14th April, 2018 + 15th April, 2018 Llewellyn van der Merwe llewellyn@joomlacomponentbuilder.com http://joomlacomponentbuilder.com -- 2.40.1 From 0dc22b100ba9c13866c47f3d8b71b1eb6cfac07b Mon Sep 17 00:00:00 2001 From: Llewellyn van der Merwe Date: Tue, 17 Apr 2018 23:25:03 +0200 Subject: [PATCH 03/14] Added the option to clone a Component and all its linked data, also to import a JCB package without merging with local Component --- README.md | 4 +- admin/README.txt | 4 +- admin/access.xml | 1 + admin/controllers/joomla_components.php | 50 ++ .../en-GB/en-GB.com_componentbuilder.ini | 10 + .../en-GB/en-GB.com_componentbuilder.sys.ini | 2 + admin/models/import_joomla_components.php | 77 +- admin/models/joomla_components.php | 671 +++++++++++------- .../import_joomla_components/view.html.php | 25 + admin/views/joomla_components/view.html.php | 5 + componentbuilder.xml | 2 +- 11 files changed, 578 insertions(+), 273 deletions(-) diff --git a/README.md b/README.md index ef50ea798..7be410712 100644 --- a/README.md +++ b/README.md @@ -126,11 +126,11 @@ Component Builder is mapped as a component in itself on my local development env + *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + *Name*: [Component Builder](http://joomlacomponentbuilder.com) + *First Build*: 30th April, 2015 -+ *Last Build*: 15th April, 2018 ++ *Last Build*: 17th April, 2018 + *Version*: 2.7.5 + *Copyright*: Copyright (C) 2015. All Rights Reserved + *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html -+ *Line count*: **182585** ++ *Line count*: **182878** + *Field count*: **1012** + *File count*: **1199** + *Folder count*: **193** diff --git a/admin/README.txt b/admin/README.txt index ef50ea798..7be410712 100644 --- a/admin/README.txt +++ b/admin/README.txt @@ -126,11 +126,11 @@ Component Builder is mapped as a component in itself on my local development env + *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + *Name*: [Component Builder](http://joomlacomponentbuilder.com) + *First Build*: 30th April, 2015 -+ *Last Build*: 15th April, 2018 ++ *Last Build*: 17th April, 2018 + *Version*: 2.7.5 + *Copyright*: Copyright (C) 2015. All Rights Reserved + *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html -+ *Line count*: **182585** ++ *Line count*: **182878** + *Field count*: **1012** + *File count*: **1199** + *Folder count*: **193** diff --git a/admin/access.xml b/admin/access.xml index 2bded6af0..eea0f6756 100644 --- a/admin/access.xml +++ b/admin/access.xml @@ -232,6 +232,7 @@ + diff --git a/admin/controllers/joomla_components.php b/admin/controllers/joomla_components.php index a843fbc7c..d16eab8fd 100644 --- a/admin/controllers/joomla_components.php +++ b/admin/controllers/joomla_components.php @@ -398,6 +398,56 @@ class ComponentbuilderControllerJoomla_components extends JControllerAdmin return; } + public function cloner() + { + // Get the model + $model = $this->getModel('Joomla_components'); + // check if export is allowed for this user. + $model->user = JFactory::getUser(); + if ($model->user->authorise('joomla_component.cloner', 'com_componentbuilder') && $model->user->authorise('core.copy', 'com_componentbuilder')) + { + // Get the input + $input = JFactory::getApplication()->input; + $pks = $input->post->get('cid', array(), 'array'); + // Sanitize the input + JArrayHelper::toInteger($pks); + // check if there is any selections + if (!ComponentbuilderHelper::checkArray($pks)) + { + // Redirect to the list screen with error. + $message = JText::_('COM_COMPONENTBUILDER_NO_COMPONENT_WAS_SELECTED_PLEASE_MAKE_A_SELECTION_OF_ONE_COMPONENT_AND_TRY_AGAIN'); + $this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=joomla_components', false), $message, 'error'); + return; + } + // only one component allowed at this time + elseif (count( (array) $pks) !== 1) + { + // Redirect to the list screen with error. + $message = JText::_('COM_COMPONENTBUILDER_ONLY_ONE_COMPONENT_CAN_BE_CLONED_AT_A_TIME_PLEASE_SELECT_ONE_AND_TRY_AGAIN'); + $this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=joomla_components', false), $message, 'error'); + return; + } + // set the active type + $model->activeType = 'clone'; + // clone the component and the views and the fields... everything linked to the component. + if ($model->cloner($pks)) + { + // clone was successful + $message = JText::_('COM_COMPONENTBUILDER_THE_COMPONENT_WITH_ALL_LINKED_ADMIN_VIEWS_FIELDS_LINKED_TO_ADMIN_VIEWS_CUSTOM_ADMIN_VIEWS_SITE_VIEWS_TEMPLATES_AND_LAYOUTS_WERE_CLONED_SUCCESSFUL'); + $this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=joomla_components', false), $message); + return; + } + // Redirect to the list screen with error. + $message = JText::_('COM_COMPONENTBUILDER_CLONE_FAILED'); + $this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=joomla_components', false), $message, 'error'); + return; + } + // Redirect to the list screen with error. + $message = JText::_('COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_CLONE_A_COMPONENT_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_HELP'); + $this->setRedirect(JRoute::_('index.php?option=com_componentbuilder&view=joomla_components', false), $message, 'error'); + return; + } + protected function getApiUser() { // admin area does not have API user, only front-end (so we fallback on login user) diff --git a/admin/language/en-GB/en-GB.com_componentbuilder.ini b/admin/language/en-GB/en-GB.com_componentbuilder.ini index 66b7fa495..9a1ac3110 100644 --- a/admin/language/en-GB/en-GB.com_componentbuilder.ini +++ b/admin/language/en-GB/en-GB.com_componentbuilder.ini @@ -954,6 +954,8 @@ COM_COMPONENTBUILDER_CANCEL="Cancel" COM_COMPONENTBUILDER_CHAIN="Chain" COM_COMPONENTBUILDER_CHECK_YOUR_OWNER_DETAILS_IT_HAS_NOT_BEEN_SET_OPEN_THE_JCB_GLOBAL_OPTIONS_GO_TO_THE_COMPANY_TAB_AND_ADD_THE_CORRECT_COMPANY_DETAILS_THERE="Check your owner details, it has not been set. Open the JCB Global Options, go to the Company tab and add the correct company details there." COM_COMPONENTBUILDER_CLEAR_TMP="Clear tmp" +COM_COMPONENTBUILDER_CLONE="Clone" +COM_COMPONENTBUILDER_CLONE_FAILED="Clone failed!" COM_COMPONENTBUILDER_CLOSE_NEW="Close & New" COM_COMPONENTBUILDER_COMPANY="Company" COM_COMPONENTBUILDER_COMPANY_NAME="Company Name" @@ -4310,6 +4312,8 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BUILDCOMPSQL_LABEL="MySQL" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BUILDCOMP_DESCRIPTION="To build the component fields and back-end views dynamically using a mySQL table file." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BUILDCOMP_LABEL="Build Backend-views Dynamically" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BUILDER_BACKUP_KEY="Joomla Component Builder - Backup Key" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_CLONE_BUTTON_ACCESS="Joomla Component Clone Button Access" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_CLONE_BUTTON_ACCESS_DESC=" Allows the users in this group to access the clone button." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_COMPANYNAME="Companyname" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_COMPANYNAME_DESCRIPTION="Enter Company Name Here" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_COMPANYNAME_HINT="Company Name Here" @@ -5320,6 +5324,7 @@ COM_COMPONENTBUILDER_MATCH_BEHAVIOUR="Match Behaviour" COM_COMPONENTBUILDER_MATCH_FIELD="Match Field" COM_COMPONENTBUILDER_MATCH_OPTIONS="Match Options" COM_COMPONENTBUILDER_MAX_LENGTH_ONLY_FOUR_TEXT_FIELD="Max Length (only 4 text_field)" +COM_COMPONENTBUILDER_MERGE="Merge" COM_COMPONENTBUILDER_MIN_LENGTH_ONLY_FOUR_TEXT_FIELD="Min Length (only 4 text_field)" COM_COMPONENTBUILDER_NAME="Name" COM_COMPONENTBUILDER_NAME_ASC="Name (Asc)" @@ -5337,6 +5342,7 @@ COM_COMPONENTBUILDER_NOT_FOUND_OR_ACCESS_DENIED="Not found or access denied!" COM_COMPONENTBUILDER_NOT_SET="not set" COM_COMPONENTBUILDER_NO_ACCESS_GRANTED="No Access Granted!" COM_COMPONENTBUILDER_NO_COMPONENTS_WERE_SELECTED_PLEASE_MAKE_A_SELECTION_AND_TRY_AGAIN="No components were selected, please make a selection and try again!" +COM_COMPONENTBUILDER_NO_COMPONENT_WAS_SELECTED_PLEASE_MAKE_A_SELECTION_OF_ONE_COMPONENT_AND_TRY_AGAIN="No component was selected, please make a selection of one component and try again!" COM_COMPONENTBUILDER_NO_CRONJOB_PATH_FOUND_FOR_S="No cronjob path found for (%s)" COM_COMPONENTBUILDER_NO_CRONJOB_PATH_FOUND_SINCE_INCORRECT_TYPE_REQUESTED="No cronjob path found since incorrect type requested." COM_COMPONENTBUILDER_NO_DESCRIPTION_FOUND="No description found." @@ -5353,6 +5359,7 @@ COM_COMPONENTBUILDER_NO_S_HAVE_BEEN_LINKED_TO_THIS_VIEW_SOON_AS_THIS_IS_DONE_IT_ COM_COMPONENTBUILDER_NO_TYPE="No Type" COM_COMPONENTBUILDER_NO_VALIDATION_RULES_FOUND="No validation rules found." COM_COMPONENTBUILDER_OFFICIAL_VDM_PACKAGES="Official VDM Packages" +COM_COMPONENTBUILDER_ONLY_ONE_COMPONENT_CAN_BE_CLONED_AT_A_TIME_PLEASE_SELECT_ONE_AND_TRY_AGAIN="Only one component can be cloned at a time, please select one and try again!" COM_COMPONENTBUILDER_ONLY_USE_THE_BNONE_DBB_OPTION_IF_YOU_ARE_PLANNING_ON_TARGETING_THIS_FIELD_WITH_JAVASCRIPTCUSTOM_PHP_TO_MOVE_ITS_VALUE_INTO_ANOTHER_FIELD_THAT_DOES_GET_SAVED_TO_THE_DATABASE="Only use the None DB option if you are planning on targeting this field with JavaScript/Custom PHP to move its value into another field that does get saved to the database." COM_COMPONENTBUILDER_ON_GITHUB="on Github" COM_COMPONENTBUILDER_OPEN="Open" @@ -5571,6 +5578,7 @@ COM_COMPONENTBUILDER_SHOULD_THE_ZIPPED_PACKAGE_OF_THE_COMPONENT_BE_MOVED_TO_THE_ COM_COMPONENTBUILDER_SHOULD_THIS_FIELD_BE_ESCAPED_IN_THE_LIST_VIEW="Should this field be escaped in the list view." COM_COMPONENTBUILDER_SHOULD_WE_BE_SHOWING_MORE_ELABORATE_INFORMATION_DURING_IMPORT="Should we be showing more elaborate information during import." COM_COMPONENTBUILDER_SHOULD_WE_FORCE_THE_UPDATE_OF_ALL_LOCAL_DATA_EVEN_IF_IT_IS_NEWER_THEN_THE_DATA_BEING_IMPORTED="Should we force the update of all local data, even if it is newer then the data being imported." +COM_COMPONENTBUILDER_SHOULD_WE_MERGE_THE_COMPONENTS_WITH_SIMILAR_LOCAL_COMPONENTS_MERGING_THE_COMPONENTS_USE_TO_BE_THE_DEFAULT_BEHAVIOUR_BUT_NOW_YOU_CAN_IMPORT_THE_COMPONENTS_AND_FORCE_IT_NOT_TO_MERGE_THE_FOLLOWING_AREAS_VALIDATION_RULE_FIELDTYPE_SNIPPET_LANGUAGE_LANGUAGE_TRANSLATION_BMUST_AND_WILL_STILLB_MERGE_EVEN_OF_YOUR_SELECTION_IS_BNOB_BECAUSE_OF_THE_SINGULAR_NATURE_OF_THOSE_AREAS="Should we merge the component/s with similar local component/s. Merging the component/s use to be the default behaviour, but now you can import the component/s and force it not to merge. The following areas (validation_rule, fieldtype, snippet, language, language_translation) must and will still merge even of your selection is No, because of the singular nature of those areas." COM_COMPONENTBUILDER_SHOW="Show" COM_COMPONENTBUILDER_SHOW_IN_LIST_VIEW="Show in list view" COM_COMPONENTBUILDER_SINCE_THE_OWNER_DETAILS_ARE_DISPLAYED_DURING_BIMPORT_PROCESSB_BEFORE_ADDING_THE_KEY_THIS_WAY_IF_THE_USERDEV_BDOES_NOTB_HAVE_THE_KEY_THEY_CAN_SEE_BWHERE_TO_GET_ITB="Since the owner details are displayed during import process before adding the key, this way if the user/dev does not have the key they can see where to get it." @@ -6411,6 +6419,7 @@ COM_COMPONENTBUILDER_THE_COMPONENT_FILES_FOLDERS="The component files & folders" COM_COMPONENTBUILDER_THE_COMPONENT_MYSQL_TWEAKS="The component mysql tweaks" COM_COMPONENTBUILDER_THE_COMPONENT_SITE_VIEWS="The component site views" COM_COMPONENTBUILDER_THE_COMPONENT_UPDATES="The component updates" +COM_COMPONENTBUILDER_THE_COMPONENT_WITH_ALL_LINKED_ADMIN_VIEWS_FIELDS_LINKED_TO_ADMIN_VIEWS_CUSTOM_ADMIN_VIEWS_SITE_VIEWS_TEMPLATES_AND_LAYOUTS_WERE_CLONED_SUCCESSFUL="The Component with all linked admin views, fields linked to admin views, custom admin views, site views, templates and layouts were cloned successful!" COM_COMPONENTBUILDER_THE_FTP_CONNECTION_FOR_BSB_COULD_NOT_BE_MADE_PLEASE_CHECK_YOUR_SIGNATURE_DETAILS="The FTP connection for %s could not be made. Please check your signature details!" COM_COMPONENTBUILDER_THE_FTP_SIGNATURE_FOR_BSB_WAS_NOT_WELL_FORMED_PLEASE_CHECK_YOUR_SIGNATURE_DETAILS="The FTP signature for %s was not well formed, please check your signature details!" COM_COMPONENTBUILDER_THE_KEY_OF_THIS_PACKAGE="The key of this package." @@ -6570,6 +6579,7 @@ COM_COMPONENTBUILDER_YOUR_DATA_IS_ENCRYPTED_WITH_A_AES_ONE_HUNDRED_AND_TWENTY_EI COM_COMPONENTBUILDER_YOUR_DATA_IS_ENCRYPTED_WITH_A_AES_ONE_HUNDRED_AND_TWENTY_EIGHT_BIT_ENCRYPTION_USING_THE_ABOVE_THIRTY_TWO_CHARACTER_KEY_WITHOUT_THIS_KEY_IT_WILL_TAKE_THE_CURRENT_TECHNOLOGY_WITH_A_BRUTE_FORCE_ATTACK_METHOD_MORE_THEN_A_HREFHTTPRANDOMIZECOMHOWLONGTOHACKPASS_TARGET_BLANK_TITLEHOW_LONG_TO_HACK_PASSSEVEN_HUNDRED_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZERO_ZEROA_YEARS_TO_CRACK_THEORETICALLY_UNLESS_THEY_HAVE_THIS_KEY_ABOVE_SO_DO_KEEP_IT_SAFE="Your data is encrypted with a AES 128 bit encryption using the above 32 character key. Without this key it will take the current technology with a brute force attack method more then 700 000 000 000 000 000 000 000 000 000 000 years to crack theoretically. Unless they have this key above, so do keep it safe." COM_COMPONENTBUILDER_YOU_CAN_NOW_SELECT_THE_COMPONENT_BZIPB_PACKAGE_YOU_WOULD_LIKE_TO_IMPORTBR_SMALLPLEASE_NOTE_THAT_SMART_COMPONENT_IMPORT_ONLY_WORKS_WITH_THE_FOLLOWING_FORMAT_BZIPBSMALL="You can now select the component zip package you would like to import.
Please note that smart component import only works with the following format: (.zip)" COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_ACCESS_THE_SERVER_DETAILS_BS_DENIEDB_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_INFO="You do not have permission to access the server details (%s - denied), please contact your system administrator for more info." +COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_CLONE_A_COMPONENT_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_HELP="You do not have permission to clone a component, please contact your system administrator for more help." COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_IMPORT_A_COMPONENT_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_HELP="You do not have permission to import a component, please contact your system administrator for more help." COM_COMPONENTBUILDER_YOU_DO_NOT_HAVE_PERMISSION_TO_SHARE_THE_SNIPPETS_PLEASE_CONTACT_YOUR_SYSTEM_ADMINISTRATOR_FOR_MORE_HELP="You do not have permission to share the snippets, please contact your system administrator for more help." COM_COMPONENTBUILDER_YOU_HAVE_S_S_ADDING_MORE_THEN_FIFTY_S_IS_CONSIDERED_BAD_PRACTICE="You have %s %s. Adding more then 50 %s is considered bad practice." diff --git a/admin/language/en-GB/en-GB.com_componentbuilder.sys.ini b/admin/language/en-GB/en-GB.com_componentbuilder.sys.ini index b634546e5..356a5dbdc 100644 --- a/admin/language/en-GB/en-GB.com_componentbuilder.sys.ini +++ b/admin/language/en-GB/en-GB.com_componentbuilder.sys.ini @@ -480,6 +480,8 @@ COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_SUBMENU="Joomla Components Submenu" COM_COMPONENTBUILDER_JOOMLA_COMPONENTS_SUBMENU_DESC="Allows the users in this group to update the submenu of the joomla component" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BACKUP_BUTTON_ACCESS="Joomla Component Backup Button Access" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_BACKUP_BUTTON_ACCESS_DESC=" Allows the users in this group to access the backup button." +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_CLONE_BUTTON_ACCESS="Joomla Component Clone Button Access" +COM_COMPONENTBUILDER_JOOMLA_COMPONENT_CLONE_BUTTON_ACCESS_DESC=" Allows the users in this group to access the clone button." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_JCB_PACKAGES_BUTTON_ACCESS="Joomla Component Export JCB Packages Button Access" COM_COMPONENTBUILDER_JOOMLA_COMPONENT_EXPORT_JCB_PACKAGES_BUTTON_ACCESS_DESC=" Allows the users in this group to access the export jcb packages button." COM_COMPONENTBUILDER_JOOMLA_COMPONENT_IMPORT_JCB_PACKAGES_BUTTON_ACCESS="Joomla Component Import JCB Packages Button Access" diff --git a/admin/models/import_joomla_components.php b/admin/models/import_joomla_components.php index 695852c00..4aad147f7 100644 --- a/admin/models/import_joomla_components.php +++ b/admin/models/import_joomla_components.php @@ -80,14 +80,17 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy parent::populateState(); } - protected $app; + public $canmerge = 1; + public $postfix = false; + public $forceUpdate = 0; + public $hasKey = 0; + public $sleutle = null; + public $data = false; + public $app; + protected $dir = false; - protected $data = false; protected $target = false; protected $newID = array(); - protected $forceUpdate = 0; - protected $hasKey = 0; - protected $sleutle = null; protected $updateAfter = array('field' => array(), 'adminview' => array()); protected $divergedDataMover = array(); protected $fieldTypes = array(); @@ -95,6 +98,7 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy protected $specialValue = false; protected $checksum = null; protected $checksumURLs = array('vdm' => 'https://raw.githubusercontent.com/vdm-io/JCB-Packages/master/'); + protected $mustMerge = array('validation_rule', 'fieldtype', 'snippet', 'language', 'language_translation'); /** * Import an spreadsheet from either folder, url or upload. @@ -225,6 +229,8 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy $this->forceUpdate = $this->app->input->getInt('force_update', 0); // show more information $this->moreInfo = $this->app->input->getInt('more_info', 0); + // allow merge + $this->canmerge = $this->app->input->getInt('canmerge', 1); // has a key $this->hasKey = $this->app->input->getInt('haskey', 0); // die sleutle @@ -695,6 +701,12 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy $this->user = JFactory::getUser(); // set some defaults $this->today = JFactory::getDate()->toSql(); + // if we can't merge add postfix to name + if (!$this->canmerge) + { + // set some postfix + $this->postfix = ' ('.ComponentbuilderHelper::randomkey(2).')'; + } // the array of tables to store $tables = array( 'validation_rule', 'fieldtype', 'field', 'admin_view', 'snippet', 'dynamic_get', 'custom_admin_view', 'site_view', @@ -732,7 +744,7 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy * @return boolean false on failure * **/ - protected function saveSmartItems($table) + public function saveSmartItems($table) { if (isset($this->data[$table]) && ComponentbuilderHelper::checkArray($this->data[$table])) { @@ -741,6 +753,8 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy $canEdit = $canDo->get('core.edit'); $canState = $canDo->get('core.edit.state'); $canCreate = $canDo->get('core.create'); + // check if we should allow merge of local values + $canmerge = $this->allowMerge($table); // set id keeper if (!isset($this->newID[$table])) { @@ -750,7 +764,7 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy { $oldID = (int) $item->id; // first check if exist - if ($local = $this->getLocalItem($item, $table, 1)) + if ($canmerge && $local = $this->getLocalItem($item, $table, 1)) { // display more import info if ($this->moreInfo) @@ -821,6 +835,21 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy return true; } + /** + * Check if we should allow merge for this table + * + * @return boolean + * + **/ + protected function allowMerge($table) + { + if ($this->canmerge == 1 || in_array($table, $this->mustMerge)) + { + return true; + } + return false; + } + /** * Move the smart content (files & folders) into place * @@ -989,7 +1018,7 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy * @return void * **/ - protected function updateAfter() + public function updateAfter() { if (ComponentbuilderHelper::checkArray($this->updateAfter['field'])) { @@ -1097,7 +1126,7 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy * @return void * **/ - protected function moveDivergedData() + public function moveDivergedData() { // check if there is data to move if (ComponentbuilderHelper::checkArray($this->divergedDataMover)) @@ -1429,6 +1458,11 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_BFIELD_TYPEB_IDS_MISMATCH_IN_BSB', $item->fieldtype, ComponentbuilderHelper::safeString($type, 'w').':'.$item->id), 'error'); return false; } + // if we can't merge add postfix to name + if ($this->postfix) + { + $item->name = $item->name.$this->postfix; + } break; case 'dynamic_get': // update the view_table_main ID @@ -1455,6 +1489,11 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy ); // update the subform ids $this->updateSubformsIDs($item, 'dynamic_get', $updaterT); + // if we can't merge add postfix to name + if ($this->postfix) + { + $item->name = $item->name.$this->postfix; + } break; case 'layout': case 'template': @@ -1462,6 +1501,11 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy $item = $this->setNewID($item, 'dynamic_get', 'dynamic_get', $type); // update the snippet $item = $this->setNewID($item, 'snippet', 'snippet', $type); + // if we can't merge add postfix to name + if ($this->postfix) + { + $item->name = $item->name.$this->postfix; + } break; case 'custom_admin_view': case 'site_view': @@ -1481,6 +1525,11 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy ); // update the repeatable fields $item = ComponentbuilderHelper::convertRepeatableFields($item, $updaterR); + // if we can't merge add postfix to name + if ($this->postfix) + { + $item->system_name = $item->system_name.$this->postfix; + } break; case 'admin_view': // set the getters anchors @@ -1530,6 +1579,11 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy ); // update the repeatable fields $item = ComponentbuilderHelper::convertRepeatableFields($item, $updaterR); + // if we can't merge add postfix to name + if ($this->postfix) + { + $item->system_name = $item->system_name.$this->postfix; + } break; case 'joomla_component': // set the anchors getters @@ -1656,6 +1710,11 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy ); // update the repeatable fields $item = ComponentbuilderHelper::convertRepeatableFields($item, $updaterR); + // if we can't merge add postfix to name + if ($this->postfix) + { + $item->system_name = $item->system_name.$this->postfix; + } break; case 'component_admin_views': // diverged id already updated diff --git a/admin/models/joomla_components.php b/admin/models/joomla_components.php index 5ce685ea9..749eb03d3 100644 --- a/admin/models/joomla_components.php +++ b/admin/models/joomla_components.php @@ -80,18 +80,300 @@ class ComponentbuilderModelJoomla_components extends JModelList protected $params; protected $tempPath; protected $customPath; - protected $smartExport = array(); - protected $exportIDs = array(); + protected $smartBox = array(); + protected $smartIDs = array(); protected $customCodeM = array(); protected $fieldTypes = array(); protected $isMultiple = array(); + /** + * Method to clone the component + * + * @return bool on success. + */ + public function cloner($pks) + { + // get the components + if ($items = $this->getComponents($pks)) + { + // update $pks with returned IDs + $pks = array(); + // start loading the components + $this->smartBox['joomla_component'] = array(); + foreach ($items as $nr => &$item) + { + // check if user has access + $access = ($this->user->authorise('joomla_component.access', 'com_componentbuilder.joomla_component.' . (int) $item->id) && $this->user->authorise('joomla_component.access', 'com_componentbuilder')); + if (!$access) + { + unset($items[$nr]); + continue; + } + // make sure old fields are not exported any more + $this->removeOldComponentValues($item); + // load to global object + $this->smartBox['joomla_component'][$item->id] = $item; + // add to pks + $pks[] = $item->id; + } + + // has any data been set for this component + if (ComponentbuilderHelper::checkArray($pks)) + { + // load the linked stuff + $this->getLinkedToComponents($pks); + } + + // has any data been set for this component + if (isset($this->smartBox['joomla_component']) && ComponentbuilderHelper::checkArray($this->smartBox['joomla_component'])) + { + // set the folder and move the files of each component to the folder + return $this->smartCloner(); + } + } + return false; + } + /** * Method to build the export package * * @return bool on success. */ public function getSmartExport($pks) + { + // get the components + if ($items = $this->getComponents($pks)) + { + // set custom folder path + $this->customPath = $this->params->get('custom_folder_path', JPATH_COMPONENT_ADMINISTRATOR.'/custom'); + // check what type of export or backup this is + if ('backup' === $this->activeType || 'manualBackup' === $this->activeType) + { + // set the paths + if (!$this->backupPath = $this->params->get('cronjob_backup_folder_path', null)) + { + // set the paths + $comConfig = JFactory::getConfig(); + $this->backupPath = $comConfig->get('tmp_path'); + } + // check what backup type we are working with here + $this->backupType = $this->params->get('cronjob_backup_type', 1); // 1 = local folder; 2 = remote server (default is local) + // if remote server get the ID + if (2 == $this->backupType) + { + $this->backupServer = $this->params->get('cronjob_backup_server', null); + } + // set the date array + $date = JFactory::getDate(); + $placeholderDate = array(); + $placeholderDate['[YEAR]'] = $date->format('Y'); + $placeholderDate['[MONTH]'] = $date->format('m'); + $placeholderDate['[DAY]'] = $date->format('d'); + $placeholderDate['[HOUR]'] = $date->format('H'); + $placeholderDate['[MINUTE]'] = $date->format('i'); + // get the package name + $packageName = $this->params->get('backup_package_name', 'JCB_Backup_[YEAR]_[MONTH]_[DAY]'); + $this->packageName = str_replace(array_keys($placeholderDate), array_values($placeholderDate), $packageName); + } + else + { + // set the paths + $comConfig = JFactory::getConfig(); + $this->backupPath = $comConfig->get('tmp_path'); + // set the package name + if (count($items) == 1) + { + $this->packageName = 'JCB_' . $this->getPackageName($items); + } + else + { + $this->packageName = 'JCB_smartPackage'; + } + } + // set the package path + $this->packagePath = rtrim($this->backupPath, '/') . '/' . $this->packageName; + $this->zipPath = $this->packagePath .'.zip'; + if (JFolder::exists($this->packagePath)) + { + // remove if old folder is found + ComponentbuilderHelper::removeFolder($this->packagePath); + } + // create the folders + JFolder::create($this->packagePath); + // Get the basic encryption. + $basickey = ComponentbuilderHelper::getCryptKey('basic'); + // Get the encription object. + if ($basickey) + { + $basic = new FOFEncryptAes($basickey, 128); + } + // update $pks with returned IDs + $pks = array(); + // start loading the components + $this->smartBox['joomla_component'] = array(); + foreach ($items as $nr => &$item) + { + // check if user has access + $access = ($this->user->authorise('joomla_component.access', 'com_componentbuilder.joomla_component.' . (int) $item->id) && $this->user->authorise('joomla_component.access', 'com_componentbuilder')); + if (!$access) + { + unset($items[$nr]); + continue; + } + // make sure old fields are not exported any more + $this->removeOldComponentValues($item); + // build information data set + $this->info['name'][$item->id] = $item->name; + $this->info['short_description'][$item->id] = $item->short_description; + $this->info['component_version'][$item->id] = $item->component_version; + $this->info['companyname'][$item->id] = $item->companyname; + $this->info['author'][$item->id] = $item->author; + $this->info['email'][$item->id] = $item->email; + $this->info['website'][$item->id] = $item->website; + $this->info['license'][$item->id] = $item->license; + $this->info['copyright'][$item->id] = $item->copyright; + // set the keys + if (isset($item->export_key) && ComponentbuilderHelper::checkString($item->export_key)) + { + // keep the key locked for exported data set + $export_key = $item->export_key; + if ($basickey && !is_numeric($item->export_key) && $item->export_key === base64_encode(base64_decode($item->export_key, true))) + { + $export_key = rtrim($basic->decryptString($item->export_key), "\0"); + } + // make sure we have a string + if (strlen($export_key) > 4 ) + { + $this->key[$item->id] = $export_key; + } + } + // get name of this item key_name + if (isset($item->system_name)) + { + $keyName = ComponentbuilderHelper::safeString($item->system_name, 'cAmel'); + } + else + { + $keyName = ComponentbuilderHelper::safeString($item->name_code); + } + // set the export buy links + if (isset($item->export_buy_link) && ComponentbuilderHelper::checkString($item->export_buy_link)) + { + // keep the key locked for exported data set + $this->exportBuyLinks[$keyName] = $item->export_buy_link; + } + // set the export buy links + if (isset($item->export_package_link) && ComponentbuilderHelper::checkString($item->export_package_link)) + { + // keep the key locked for exported data set + $this->exportPackageLinks[$keyName] = $item->export_package_link; + } + // component image + $this->moveIt(array($item->image), 'image'); + // set the custom code ID's + $this->setCustomCodeIds($item, 'joomla_component'); + // set the language strings for this component + $this->setLanguageTranslation($item->id); + // load to global object + $this->smartBox['joomla_component'][$item->id] = $item; + // add to pks + $pks[] = $item->id; + } + + // has any data been set for this component + if (ComponentbuilderHelper::checkArray($pks)) + { + // load the linked stuff + $this->getLinkedToComponents($pks); + } + + // has any data been set for this component + if (isset($this->smartBox['joomla_component']) && ComponentbuilderHelper::checkArray($this->smartBox['joomla_component'])) + { + // set the folder and move the files of each component to the folder + return $this->smartExportBuilder(); + } + } + return false; + } + + /** + * Get Everything Linked to Components + * + * @return void + */ + protected function getLinkedToComponents($pks) + { + // array of tables linked to joomla_component + $linkedTables = array( + 'custom_code' => 'component', + 'component_files_folders' => 'joomla_component', + 'component_admin_views' => 'joomla_component', + 'component_config' => 'joomla_component', + 'component_site_views' => 'joomla_component', + 'component_custom_admin_views' => 'joomla_component', + 'component_updates' => 'joomla_component', + 'component_mysql_tweaks' => 'joomla_component', + 'component_custom_admin_menus' => 'joomla_component', + 'component_dashboard' => 'joomla_component' ); + // load all tables linked to joomla_component + foreach($linkedTables as $table => $field) + { + $this->setData($table, $pks, $field); + } + // add fields and conditions + if (isset($this->smartIDs['admin_view']) && ComponentbuilderHelper::checkArray($this->smartIDs['admin_view'])) + { + $this->setData('admin_fields', array_values($this->smartIDs['admin_view']), 'admin_view'); + $this->setData('admin_fields_conditions', array_values($this->smartIDs['admin_view']), 'admin_view'); + } + // add validation rules + if (isset($this->smartIDs['validation_rule']) && ComponentbuilderHelper::checkArray($this->smartIDs['validation_rule'])) + { + $this->setData('validation_rule', array_values($this->smartIDs['validation_rule']), 'name'); + } + // add field types + if (isset($this->smartIDs['fieldtype']) && ComponentbuilderHelper::checkArray($this->smartIDs['fieldtype'])) + { + $this->setData('fieldtype', array_values($this->smartIDs['fieldtype']), 'id'); + } + // add templates + if (isset($this->smartIDs['template']) && ComponentbuilderHelper::checkArray($this->smartIDs['template'])) + { + $this->setData('template', array_values($this->smartIDs['template']), 'id'); + } + // add layouts + if (isset($this->smartIDs['layout']) && ComponentbuilderHelper::checkArray($this->smartIDs['layout'])) + { + $this->setData('layout', array_values($this->smartIDs['layout']), 'id'); + } + // add dynamic get + if (isset($this->smartIDs['dynamic_get']) && ComponentbuilderHelper::checkArray($this->smartIDs['dynamic_get'])) + { + $this->setData('dynamic_get', array_values($this->smartIDs['dynamic_get']), 'id'); + } + // only if exporting + if ('clone' !== $this->activeType) + { + // add snippets + if (isset($this->smartIDs['snippet']) && ComponentbuilderHelper::checkArray($this->smartIDs['snippet'])) + { + $this->setData('snippet', array_values($this->smartIDs['snippet']), 'id'); + } + // add custom code + if (isset($this->smartIDs['custom_code']) && ComponentbuilderHelper::checkArray($this->smartIDs['custom_code'])) + { + $this->setData('custom_code', array_values($this->smartIDs['custom_code']), 'id'); + } + } + } + + /** + * Get Components + * + * @return array of objects. + */ + protected function getComponents($pks) { // setup the query if (ComponentbuilderHelper::checkArray($pks)) @@ -140,233 +422,45 @@ class ComponentbuilderModelJoomla_components extends JModelList { $this->params = JComponentHelper::getParams('com_componentbuilder'); } - // set custom folder path - $this->customPath = $this->params->get('custom_folder_path', JPATH_COMPONENT_ADMINISTRATOR.'/custom'); - // check what type of export or backup this is - if ('backup' === $this->activeType || 'manualBackup' === $this->activeType) - { - // set the paths - if (!$this->backupPath = $this->params->get('cronjob_backup_folder_path', null)) - { - // set the paths - $comConfig = JFactory::getConfig(); - $this->backupPath = $comConfig->get('tmp_path'); - } - // check what backup type we are working with here - $this->backupType = $this->params->get('cronjob_backup_type', 1); // 1 = local folder; 2 = remote server (default is local) - // if remote server get the ID - if (2 == $this->backupType) - { - $this->backupServer = $this->params->get('cronjob_backup_server', null); - } - // set the date array - $date = JFactory::getDate(); - $placeholderDate = array(); - $placeholderDate['[YEAR]'] = $date->format('Y'); - $placeholderDate['[MONTH]'] = $date->format('m'); - $placeholderDate['[DAY]'] = $date->format('d'); - $placeholderDate['[HOUR]'] = $date->format('H'); - $placeholderDate['[MINUTE]'] = $date->format('i'); - // get the package name - $packageName = $this->params->get('backup_package_name', 'JCB_Backup_[YEAR]_[MONTH]_[DAY]'); - $this->packageName = str_replace(array_keys($placeholderDate), array_values($placeholderDate), $packageName); - } - else - { - // set the paths - $comConfig = JFactory::getConfig(); - $this->backupPath = $comConfig->get('tmp_path'); - // set the package name - if (count($items) == 1) - { - $this->packageName = 'JCB_' . $this->getPackageName($items); - } - else - { - $this->packageName = 'JCB_smartPackage'; - } - } - // set the package path - $this->packagePath = rtrim($this->backupPath, '/') . '/' . $this->packageName; - $this->zipPath = $this->packagePath .'.zip'; - if (JFolder::exists($this->packagePath)) - { - // remove if old folder is found - ComponentbuilderHelper::removeFolder($this->packagePath); - } - // create the folders - JFolder::create($this->packagePath); - // Get the basic encryption. - $basickey = ComponentbuilderHelper::getCryptKey('basic'); - // Get the encription object. - if ($basickey) - { - $basic = new FOFEncryptAes($basickey, 128); - } - // update $pks with returned IDs - $pks = array(); - // start loading the components - $this->smartExport['joomla_component'] = array(); - foreach ($items as $nr => &$item) - { - // check if user has access - $access = ($this->user->authorise('joomla_component.access', 'com_componentbuilder.joomla_component.' . (int) $item->id) && $this->user->authorise('joomla_component.access', 'com_componentbuilder')); - if (!$access) - { - unset($items[$nr]); - continue; - } - // make sure old fields are not exported any more - unset($item->addconfig); - unset($item->addadmin_views); - unset($item->addcustom_admin_views); - unset($item->addsite_views); - unset($item->version_update); - unset($item->sql_tweak); - unset($item->addcustommenus); - unset($item->dashboard_tab); - unset($item->php_dashboard_methods); - unset($item->addfiles); - unset($item->addfolders); - // build information data set - $this->info['name'][$item->id] = $item->name; - $this->info['short_description'][$item->id] = $item->short_description; - $this->info['component_version'][$item->id] = $item->component_version; - $this->info['companyname'][$item->id] = $item->companyname; - $this->info['author'][$item->id] = $item->author; - $this->info['email'][$item->id] = $item->email; - $this->info['website'][$item->id] = $item->website; - $this->info['license'][$item->id] = $item->license; - $this->info['copyright'][$item->id] = $item->copyright; - // set the keys - if (isset($item->export_key) && ComponentbuilderHelper::checkString($item->export_key)) - { - // keep the key locked for exported data set - $export_key = $item->export_key; - if ($basickey && !is_numeric($item->export_key) && $item->export_key === base64_encode(base64_decode($item->export_key, true))) - { - $export_key = rtrim($basic->decryptString($item->export_key), "\0"); - } - // make sure we have a string - if (strlen($export_key) > 4 ) - { - $this->key[$item->id] = $export_key; - } - } - // get name of this item key_name - if (isset($item->system_name)) - { - $keyName = ComponentbuilderHelper::safeString($item->system_name, 'cAmel'); - } - else - { - $keyName = ComponentbuilderHelper::safeString($item->name_code); - } - // set the export buy links - if (isset($item->export_buy_link) && ComponentbuilderHelper::checkString($item->export_buy_link)) - { - // keep the key locked for exported data set - $this->exportBuyLinks[$keyName] = $item->export_buy_link; - } - // set the export buy links - if (isset($item->export_package_link) && ComponentbuilderHelper::checkString($item->export_package_link)) - { - // keep the key locked for exported data set - $this->exportPackageLinks[$keyName] = $item->export_package_link; - } - // component image - $this->moveIt(array($item->image), 'image'); - // set the custom code ID's - $this->setCustomCodeIds($item, 'joomla_component'); - // set the language strings for this component - $this->setLanguageTranslation($item->id); - // load to global object - $this->smartExport['joomla_component'][$item->id] = $item; - // add to pks - $pks[] = $item->id; - } - // array of tables linked to joomla_component - $linkedTables = array( - 'custom_code' => 'component', - 'component_files_folders' => 'joomla_component', - 'component_admin_views' => 'joomla_component', - 'component_config' => 'joomla_component', - 'component_site_views' => 'joomla_component', - 'component_custom_admin_views' => 'joomla_component', - 'component_updates' => 'joomla_component', - 'component_mysql_tweaks' => 'joomla_component', - 'component_custom_admin_menus' => 'joomla_component', - 'component_dashboard' => 'joomla_component' ); - // load all tables linked to joomla_component - foreach($linkedTables as $table => $field) - { - $this->setData($table, $pks, $field); - } - // add fields and conditions - if (isset($this->exportIDs['admin_view']) && ComponentbuilderHelper::checkArray($this->exportIDs['admin_view'])) - { - $this->setData('admin_fields', array_values($this->exportIDs['admin_view']), 'admin_view'); - $this->setData('admin_fields_conditions', array_values($this->exportIDs['admin_view']), 'admin_view'); - } - // add validation rules - if (isset($this->exportIDs['validation_rule']) && ComponentbuilderHelper::checkArray($this->exportIDs['validation_rule'])) - { - $this->setData('validation_rule', array_values($this->exportIDs['validation_rule']), 'name'); - } - // add field types - if (isset($this->exportIDs['fieldtype']) && ComponentbuilderHelper::checkArray($this->exportIDs['fieldtype'])) - { - $this->setData('fieldtype', array_values($this->exportIDs['fieldtype']), 'id'); - } - // add templates - if (isset($this->exportIDs['template']) && ComponentbuilderHelper::checkArray($this->exportIDs['template'])) - { - $this->setData('template', array_values($this->exportIDs['template']), 'id'); - } - // add layouts - if (isset($this->exportIDs['layout']) && ComponentbuilderHelper::checkArray($this->exportIDs['layout'])) - { - $this->setData('layout', array_values($this->exportIDs['layout']), 'id'); - } - // add dynamic get - if (isset($this->exportIDs['dynamic_get']) && ComponentbuilderHelper::checkArray($this->exportIDs['dynamic_get'])) - { - $this->setData('dynamic_get', array_values($this->exportIDs['dynamic_get']), 'id'); - } - // add snippets - if (isset($this->exportIDs['snippet']) && ComponentbuilderHelper::checkArray($this->exportIDs['snippet'])) - { - $this->setData('snippet', array_values($this->exportIDs['snippet']), 'id'); - } - // add custom code - if (isset($this->exportIDs['custom_code']) && ComponentbuilderHelper::checkArray($this->exportIDs['custom_code'])) - { - $this->setData('custom_code', array_values($this->exportIDs['custom_code']), 'id'); - } - - // has any data been set for this component - if (isset($this->smartExport['joomla_component']) && ComponentbuilderHelper::checkArray($this->smartExport['joomla_component'])) - { - // set the folder and move the files of each component to the folder - return $this->smartExportBuilder(); - } + return $items; } } } return false; } + /** + * Remove all values that are no longer relevant. + * + * @return void. + */ + protected function removeOldComponentValues(&$item) + { + // make sure old fields are not used any more + unset($item->addconfig); + unset($item->addadmin_views); + unset($item->addcustom_admin_views); + unset($item->addsite_views); + unset($item->version_update); + unset($item->sql_tweak); + unset($item->addcustommenus); + unset($item->dashboard_tab); + unset($item->php_dashboard_methods); + unset($item->addfiles); + unset($item->addfolders); + } + /** * Set export IDs. * * @return void. */ - protected function setExportIDs($value, $table, $int = true) + protected function setSmartIDs($value, $table, $int = true) { // check if table has been set - if (!isset($this->exportIDs[$table])) + if (!isset($this->smartIDs[$table])) { - $this->exportIDs[$table] = array(); + $this->smartIDs[$table] = array(); } // convert if value is in json if (ComponentbuilderHelper::checkJson($value)) @@ -380,21 +474,21 @@ class ComponentbuilderModelJoomla_components extends JModelList { if ($int && (ComponentbuilderHelper::checkString($id) || is_numeric($id)) && 0 !== (int) $id) { - $this->exportIDs[$table][(int) $id] = (int) $id; + $this->smartIDs[$table][(int) $id] = (int) $id; } elseif (!$int && ComponentbuilderHelper::checkString($id)) { - $this->exportIDs[$table][$id] = $this->_db->quote($id); + $this->smartIDs[$table][$id] = $this->_db->quote($id); } } } elseif ($int && (ComponentbuilderHelper::checkString($value) || is_numeric($value)) && 0 !== (int) $value) { - $this->exportIDs[$table][(int) $value] = (int) $value; + $this->smartIDs[$table][(int) $value] = (int) $value; } elseif (!$int && ComponentbuilderHelper::checkString($value)) { - $this->exportIDs[$table][$value] = $this->_db->quote($value); + $this->smartIDs[$table][$value] = $this->_db->quote($value); } } @@ -519,22 +613,22 @@ class ComponentbuilderModelJoomla_components extends JModelList // reset the global array if ('template' === $table) { - $this->exportIDs['template'] = array(); + $this->smartIDs['template'] = array(); } elseif ('layout' === $table) { - $this->exportIDs['layout'] = array(); + $this->smartIDs['layout'] = array(); } // start loading the data - if (!isset($this->smartExport[$table])) + if (!isset($this->smartBox[$table])) { - $this->smartExport[$table] = array(); + $this->smartBox[$table] = array(); } // start loading the found items foreach ($items as $nr => &$item) { // set the data per id only once - if (!isset($item->id) || 0 === (int) $item->id || isset($this->smartExport[$table][$item->id])) + if (!isset($item->id) || 0 === (int) $item->id || isset($this->smartBox[$table][$item->id])) { continue; } @@ -571,11 +665,11 @@ class ComponentbuilderModelJoomla_components extends JModelList unset($item->addconditions); } // load to global object - $this->smartExport[$table][$item->id] = $item; + $this->smartBox[$table][$item->id] = $item; // set the custom code ID's $this->setCustomCodeIds($item, $table); // actions to take if table is component_files_folders - if ('component_files_folders' === $table) + if ('component_files_folders' === $table && 'clone' !== $this->activeType) { // build files $this->moveIt($this->getValues($item->addfiles, 'subform', 'file', null), 'file'); @@ -614,13 +708,17 @@ class ComponentbuilderModelJoomla_components extends JModelList if ('admin_view' === $table) { // add fields & conditions - $this->setExportIDs($item->id, 'admin_view'); - // admin icon - $this->moveIt(array($item->icon), 'image'); - // admin icon_add - $this->moveIt(array($item->icon_add), 'image'); - // admin icon_category - $this->moveIt(array($item->icon_category), 'image'); + $this->setSmartIDs($item->id, 'admin_view'); + // do not move anything if clone + if ('clone' !== $this->activeType) + { + // admin icon + $this->moveIt(array($item->icon), 'image'); + // admin icon_add + $this->moveIt(array($item->icon_add), 'image'); + // admin icon_category + $this->moveIt(array($item->icon_category), 'image'); + } } // actions to take if table is admin_fields if ('admin_fields' === $table) @@ -639,7 +737,7 @@ class ComponentbuilderModelJoomla_components extends JModelList if ('field' === $table) { // add field types - $this->setExportIDs($item->fieldtype, 'fieldtype'); + $this->setSmartIDs($item->fieldtype, 'fieldtype'); // check if this field has multiple fields if ($this->checkMultiFields($item->fieldtype)) { @@ -674,7 +772,7 @@ class ComponentbuilderModelJoomla_components extends JModelList if (!in_array($validationRule, (array) $coreValidationRules)) { // okay load the rule - $this->setExportIDs($validationRule, 'validation_rule', false); + $this->setSmartIDs($validationRule, 'validation_rule', false); } } } @@ -693,11 +791,11 @@ class ComponentbuilderModelJoomla_components extends JModelList } } // add dynamic gets - $this->setExportIDs($item->main_get, 'dynamic_get'); - $this->setExportIDs($item->custom_get, 'dynamic_get'); - $this->setExportIDs($item->dynamic_get, 'dynamic_get'); + $this->setSmartIDs($item->main_get, 'dynamic_get'); + $this->setSmartIDs($item->custom_get, 'dynamic_get'); + $this->setSmartIDs($item->dynamic_get, 'dynamic_get'); // move the icon - if ('custom_admin_view' === $table && isset($item->icon)) + if ('custom_admin_view' === $table && isset($item->icon) && 'clone' !== $this->activeType) { // view icon $this->moveIt(array($item->icon), 'image'); @@ -705,7 +803,7 @@ class ComponentbuilderModelJoomla_components extends JModelList // add snippets (was removed please use snippet importer) if (isset($item->snippet) && is_numeric($item->snippet)) { - $this->setExportIDs((int) $item->snippet, 'snippet'); + $this->setSmartIDs((int) $item->snippet, 'snippet'); } } // actions to take if table is template and layout @@ -714,7 +812,7 @@ class ComponentbuilderModelJoomla_components extends JModelList // add snippets (was removed please use snippet importer) if (isset($item->snippet) && is_numeric($item->snippet)) { - $this->setExportIDs((int) $item->snippet, 'snippet'); + $this->setSmartIDs((int) $item->snippet, 'snippet'); } // search for templates & layouts $this->getTemplateLayout(base64_decode($item->$table), $this->user); @@ -724,25 +822,80 @@ class ComponentbuilderModelJoomla_components extends JModelList $this->getTemplateLayout($item->php_view, $this->user); } // add dynamic gets - $this->setExportIDs((int) $item->dynamic_get, 'dynamic_get'); + $this->setSmartIDs((int) $item->dynamic_get, 'dynamic_get'); } } } } } + /** + * Method to do the smart cloning + * + * @return bool + */ + protected function smartCloner() + { + // check if data is set + if (isset($this->smartBox) && ComponentbuilderHelper::checkArray($this->smartBox)) + { + // get the import_joomla_components + $model = ComponentbuilderHelper::getModel('import_joomla_components'); + // do not show more information + $model->moreInfo = 0; + // trigger the create new (clone) feature + $model->canmerge = 0; + // set some postfix + $model->postfix = ' ('.ComponentbuilderHelper::randomkey(2).')'; + // get App + $model->app = JFactory::getApplication(); + // set user + $model->user = $this->user; + // set today's date + $model->today = JFactory::getDate()->toSql(); + // load the data + $model->data = $this->smartBox; + // remove smart box to safe on memory + unset($this->smartBox); + // the array of tables to store + $tables = array( + 'fieldtype', 'field', 'admin_view', 'snippet', 'dynamic_get', 'custom_admin_view', 'site_view', + 'template', 'layout', 'joomla_component', 'language', 'language_translation', 'custom_code', + 'admin_fields', 'admin_fields_conditions', 'component_admin_views', 'component_site_views', + 'component_custom_admin_views', 'component_updates', 'component_mysql_tweaks', + 'component_custom_admin_menus', 'component_config', 'component_dashboard', 'component_files_folders' + ); + // smart table loop + foreach ($tables as $table) + { + // save the table to database + if (!$model->saveSmartItems($table)) + { + return false; + } + } + // do an after all run on all items that need it + $model->updateAfter(); + // finally move the old datasets + $model->moveDivergedData(); + // we had success + return true; + } + return false; + } + /** * Method to build the package to export * - * @return void + * @return bool */ protected function smartExportBuilder() { // check if data is set - if (isset($this->smartExport) && ComponentbuilderHelper::checkArray($this->smartExport)) + if (isset($this->smartBox) && ComponentbuilderHelper::checkArray($this->smartBox)) { // set db data - $data = serialize($this->smartExport); + $data = serialize($this->smartBox); // lock the data if set if (ComponentbuilderHelper::checkArray($this->key)) { @@ -1096,9 +1249,9 @@ class ComponentbuilderModelJoomla_components extends JModelList $data = $this->getDataWithAlias($template, 'template'); if (ComponentbuilderHelper::checkArray($data)) { - if (!isset($this->exportIDs['template']) || !isset($this->exportIDs['template'][$data['id']])) + if (!isset($this->smartIDs['template']) || !isset($this->smartIDs['template'][$data['id']])) { - $this->setExportIDs($data['id'], 'template'); + $this->setSmartIDs($data['id'], 'template'); // call self to get child data $again[] = $data['html']; $again[] = $data['php_view']; @@ -1131,9 +1284,9 @@ class ComponentbuilderModelJoomla_components extends JModelList $data = $this->getDataWithAlias($layout, 'layout'); if (ComponentbuilderHelper::checkArray($data)) { - if (!isset($this->exportIDs['layout']) || !isset($this->exportIDs['layout'][$data['id']])) + if (!isset($this->smartIDs['layout']) || !isset($this->smartIDs['layout'][$data['id']])) { - $this->setExportIDs($data['id'], 'layout'); + $this->setSmartIDs($data['id'], 'layout'); // call self to get child data $again[] = $data['html']; $again[] = $data['php_view']; @@ -1152,14 +1305,14 @@ class ComponentbuilderModelJoomla_components extends JModelList if ($user) { // add templates - if (isset($this->exportIDs['template']) && ComponentbuilderHelper::checkArray($this->exportIDs['template'])) + if (isset($this->smartIDs['template']) && ComponentbuilderHelper::checkArray($this->smartIDs['template'])) { - $this->setData('template', array_values($this->exportIDs['template']), 'id'); + $this->setData('template', array_values($this->smartIDs['template']), 'id'); } // add layouts - if (isset($this->exportIDs['layout']) && ComponentbuilderHelper::checkArray($this->exportIDs['layout'])) + if (isset($this->smartIDs['layout']) && ComponentbuilderHelper::checkArray($this->smartIDs['layout'])) { - $this->setData('layout', array_values($this->exportIDs['layout']), 'id'); + $this->setData('layout', array_values($this->smartIDs['layout']), 'id'); } } } @@ -1247,13 +1400,13 @@ class ComponentbuilderModelJoomla_components extends JModelList // if numeric add to ids if (is_numeric($func)) { - $this->setExportIDs($func, 'custom_code'); + $this->setSmartIDs($func, 'custom_code'); } elseif (ComponentbuilderHelper::checkString($func)) { if ($funcID = ComponentbuilderHelper::getVar('custom_code', $func, 'function_name', 'id')) { - $this->setExportIDs($funcID, 'custom_code'); + $this->setSmartIDs($funcID, 'custom_code'); } } } @@ -1296,19 +1449,19 @@ class ComponentbuilderModelJoomla_components extends JModelList // check if we have items if (ComponentbuilderHelper::checkArray($items)) { - if (!isset($this->smartExport['language_translation'])) + if (!isset($this->smartBox['language_translation'])) { - $this->smartExport['language_translation'] = array(); + $this->smartBox['language_translation'] = array(); } foreach ($items as $item) { - if (!isset($this->smartExport['language_translation'][$item->id]) && ComponentbuilderHelper::checkJson($item->components)) + if (!isset($this->smartBox['language_translation'][$item->id]) && ComponentbuilderHelper::checkJson($item->components)) { $components = json_decode($item->components, true); if (in_array($id, $components)) { // load to global object - $this->smartExport['language_translation'][$item->id] = $item; + $this->smartBox['language_translation'][$item->id] = $item; // add languages if (isset($item->translation)) { diff --git a/admin/views/import_joomla_components/view.html.php b/admin/views/import_joomla_components/view.html.php index 56a985f0e..dadb90135 100644 --- a/admin/views/import_joomla_components/view.html.php +++ b/admin/views/import_joomla_components/view.html.php @@ -153,6 +153,31 @@ class ComponentbuilderViewImport_joomla_components extends JViewLegacy $more_info->setup($more_infoXML,0); // add to form $form[] = $more_info; + + // get the merge radio field + $merge = JFormHelper::loadFieldType('radio',true); + // start merge xml + $mergeXML = new SimpleXMLElement(''); + // merge attributes + $mergeAttributes = array( + 'type' => 'radio', + 'name' => 'canmerge', + 'label' => 'COM_COMPONENTBUILDER_MERGE', + 'class' => 'btn-group btn-group-yesno', + 'description' => 'COM_COMPONENTBUILDER_SHOULD_WE_MERGE_THE_COMPONENTS_WITH_SIMILAR_LOCAL_COMPONENTS_MERGING_THE_COMPONENTS_USE_TO_BE_THE_DEFAULT_BEHAVIOUR_BUT_NOW_YOU_CAN_IMPORT_THE_COMPONENTS_AND_FORCE_IT_NOT_TO_MERGE_THE_FOLLOWING_AREAS_VALIDATION_RULE_FIELDTYPE_SNIPPET_LANGUAGE_LANGUAGE_TRANSLATION_BMUST_AND_WILL_STILLB_MERGE_EVEN_OF_YOUR_SELECTION_IS_BNOB_BECAUSE_OF_THE_SINGULAR_NATURE_OF_THOSE_AREAS', + 'default' => '1'); + // load the merge attributes + ComponentbuilderHelper::xmlAddAttributes($mergeXML, $mergeAttributes); + // set the merge options + $mergeOptions = array( + '1' => 'COM_COMPONENTBUILDER_YES', + '0' => 'COM_COMPONENTBUILDER_NO'); + // load the merge options + ComponentbuilderHelper::xmlAddOptions($mergeXML, $mergeOptions); + // setup the merge radio field + $merge->setup($mergeXML,1); + // add to form + $form[] = $merge; if (!$this->packageInfo || (isset($this->packageInfo['getKeyFrom']) && ComponentbuilderHelper::checkArray($this->packageInfo['getKeyFrom']))) { diff --git a/admin/views/joomla_components/view.html.php b/admin/views/joomla_components/view.html.php index 0f346928b..3d27333da 100644 --- a/admin/views/joomla_components/view.html.php +++ b/admin/views/joomla_components/view.html.php @@ -143,6 +143,11 @@ class ComponentbuilderViewJoomla_components extends JViewLegacy { // add Backup button. JToolBarHelper::custom('joomla_components.backup', 'archive', '', 'COM_COMPONENTBUILDER_BACKUP', false); + } + if ($this->user->authorise('joomla_component.clone', 'com_componentbuilder')) + { + // add Clone button. + JToolBarHelper::custom('joomla_components.cloner', 'save-copy', '', 'COM_COMPONENTBUILDER_CLONE', false); } if ($this->state->get('filter.published') == -2 && ($this->canState && $this->canDelete)) diff --git a/componentbuilder.xml b/componentbuilder.xml index ff5f4a70b..ed5453cf9 100644 --- a/componentbuilder.xml +++ b/componentbuilder.xml @@ -1,7 +1,7 @@ COM_COMPONENTBUILDER - 15th April, 2018 + 17th April, 2018 Llewellyn van der Merwe llewellyn@joomlacomponentbuilder.com http://joomlacomponentbuilder.com -- 2.40.1 From 98448b24b7b4c9060a12794397dd53943b164108 Mon Sep 17 00:00:00 2001 From: Llewellyn van der Merwe Date: Wed, 18 Apr 2018 14:03:07 +0200 Subject: [PATCH 04/14] Fixed the Add JavaScript (views-footer) option, since it did not add the javascript, but now does. Also added some spinner to the Joomla Components view. --- README.md | 4 +-- admin/README.txt | 4 +-- admin/compiler/joomla_3/default.php | 2 +- admin/helpers/compiler/a_Get.php | 6 ++-- admin/helpers/compiler/f_Infusion.php | 9 +++++ .../views/joomla_components/tmpl/default.php | 34 ++++++++++++++++++- componentbuilder.xml | 2 +- 7 files changed, 51 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 7be410712..4434c3a56 100644 --- a/README.md +++ b/README.md @@ -126,11 +126,11 @@ Component Builder is mapped as a component in itself on my local development env + *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + *Name*: [Component Builder](http://joomlacomponentbuilder.com) + *First Build*: 30th April, 2015 -+ *Last Build*: 17th April, 2018 ++ *Last Build*: 18th April, 2018 + *Version*: 2.7.5 + *Copyright*: Copyright (C) 2015. All Rights Reserved + *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html -+ *Line count*: **182878** ++ *Line count*: **182910** + *Field count*: **1012** + *File count*: **1199** + *Folder count*: **193** diff --git a/admin/README.txt b/admin/README.txt index 7be410712..4434c3a56 100644 --- a/admin/README.txt +++ b/admin/README.txt @@ -126,11 +126,11 @@ Component Builder is mapped as a component in itself on my local development env + *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + *Name*: [Component Builder](http://joomlacomponentbuilder.com) + *First Build*: 30th April, 2015 -+ *Last Build*: 17th April, 2018 ++ *Last Build*: 18th April, 2018 + *Version*: 2.7.5 + *Copyright*: Copyright (C) 2015. All Rights Reserved + *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html -+ *Line count*: **182878** ++ *Line count*: **182910** + *Field count*: **1012** + *File count*: **1199** + *Folder count*: **193** diff --git a/admin/compiler/joomla_3/default.php b/admin/compiler/joomla_3/default.php index 5cd0cd318..c4370612f 100644 --- a/admin/compiler/joomla_3/default.php +++ b/admin/compiler/joomla_3/default.php @@ -99,4 +99,4 @@ if ($this->saveOrder) - \ No newline at end of file +###VIEWS_FOOTER_SCRIPT### \ No newline at end of file diff --git a/admin/helpers/compiler/a_Get.php b/admin/helpers/compiler/a_Get.php index d240acccf..15fe7638a 100644 --- a/admin/helpers/compiler/a_Get.php +++ b/admin/helpers/compiler/a_Get.php @@ -2263,16 +2263,16 @@ class Get { $this->customScriptBuilder['views_footer'] = array(); } - if (!isset($this->customScriptBuilder['views_footer'][$name_list])) + if (!isset($this->customScriptBuilder['views_footer'][$name_single])) { - $this->customScriptBuilder['views_footer'][$name_list] = ''; + $this->customScriptBuilder['views_footer'][$name_single] = ''; } if (!isset($this->_fieldData[$id]->javascript_views_footer_decoded)) { $this->_fieldData[$id]->javascript_views_footer = $this->setDynamicValues(base64_decode($this->_fieldData[$id]->javascript_views_footer)); $this->_fieldData[$id]->javascript_views_footer_decoded = true; } - $this->customScriptBuilder['views_footer'][$name_list] .= PHP_EOL . $this->_fieldData[$id]->javascript_views_footer; + $this->customScriptBuilder['views_footer'][$name_single] .= PHP_EOL . $this->_fieldData[$id]->javascript_views_footer; if (strpos($this->_fieldData[$id]->javascript_views_footer, "token") !== false || strpos($this->_fieldData[$id]->javascript_views_footer, "task=ajax") !== false) { diff --git a/admin/helpers/compiler/f_Infusion.php b/admin/helpers/compiler/f_Infusion.php index 47b9ae014..b95d8c1ec 100644 --- a/admin/helpers/compiler/f_Infusion.php +++ b/admin/helpers/compiler/f_Infusion.php @@ -501,6 +501,15 @@ class Infusion extends Interpretation // ###VIEWCSS### <<>> $this->fileContentDynamic[$viewName_list]['###VIEWSCSS###'] = ''; } + // ###VIEWS_FOOTER_SCRIPT### + if ($footerScript = $this->getCustomScriptBuilder('views_footer', $viewName_single, PHP_EOL)) + { + $this->fileContentDynamic[$viewName_list]['###VIEWS_FOOTER_SCRIPT###'] = PHP_EOL . '"; + } + else + { + $this->fileContentDynamic[$viewName_list]['###VIEWS_FOOTER_SCRIPT###'] = ''; + } } // set u fields used in batch diff --git a/admin/views/joomla_components/tmpl/default.php b/admin/views/joomla_components/tmpl/default.php index fcb342518..9e03d5ff1 100644 --- a/admin/views/joomla_components/tmpl/default.php +++ b/admin/views/joomla_components/tmpl/default.php @@ -96,4 +96,36 @@ if ($this->saveOrder) - \ No newline at end of file + + \ No newline at end of file diff --git a/componentbuilder.xml b/componentbuilder.xml index ed5453cf9..4937c249b 100644 --- a/componentbuilder.xml +++ b/componentbuilder.xml @@ -1,7 +1,7 @@ COM_COMPONENTBUILDER - 17th April, 2018 + 18th April, 2018 Llewellyn van der Merwe llewellyn@joomlacomponentbuilder.com http://joomlacomponentbuilder.com -- 2.40.1 From 48a3a49d6f444e336d209ae41cec8bdcef4918d0 Mon Sep 17 00:00:00 2001 From: Llewellyn van der Merwe Date: Wed, 18 Apr 2018 21:11:14 +0200 Subject: [PATCH 05/14] Added minify of JS to the compiler area, also improved the infusion area to make more use of the getCustomScriptBuilder method --- README.md | 2 +- admin/README.txt | 2 +- admin/controllers/compiler.php | 23 ++- admin/helpers/compiler/a_Get.php | 13 +- admin/helpers/compiler/e_Interpretation.php | 18 +- admin/helpers/compiler/f_Infusion.php | 193 ++++-------------- .../en-GB/en-GB.com_componentbuilder.ini | 2 + admin/models/compiler.php | 5 +- admin/views/compiler/view.html.php | 26 +++ .../views/joomla_components/tmpl/default.php | 2 +- .../language_translations/tmpl/default.php | 25 ++- admin/views/languages/tmpl/default.php | 25 ++- 12 files changed, 165 insertions(+), 171 deletions(-) diff --git a/README.md b/README.md index 4434c3a56..3b9fc641f 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,7 @@ Component Builder is mapped as a component in itself on my local development env + *Version*: 2.7.5 + *Copyright*: Copyright (C) 2015. All Rights Reserved + *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html -+ *Line count*: **182910** ++ *Line count*: **182984** + *Field count*: **1012** + *File count*: **1199** + *Folder count*: **193** diff --git a/admin/README.txt b/admin/README.txt index 4434c3a56..3b9fc641f 100644 --- a/admin/README.txt +++ b/admin/README.txt @@ -130,7 +130,7 @@ Component Builder is mapped as a component in itself on my local development env + *Version*: 2.7.5 + *Copyright*: Copyright (C) 2015. All Rights Reserved + *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html -+ *Line count*: **182910** ++ *Line count*: **182984** + *Field count*: **1012** + *File count*: **1199** + *Folder count*: **193** diff --git a/admin/controllers/compiler.php b/admin/controllers/compiler.php index 784b28daf..445d35742 100644 --- a/admin/controllers/compiler.php +++ b/admin/controllers/compiler.php @@ -66,17 +66,18 @@ class ComponentbuilderControllerCompiler extends JControllerAdmin if($user->authorise('core.admin', 'com_componentbuilder')) { // get the post values - $jinput = JFactory::getApplication()->input; - $componentId = $jinput->post->get('component', 0, 'INT'); - $version = $jinput->post->get('version', 0, 'INT'); - $addBackup = $jinput->post->get('backup', 0, 'INT'); - $addRepo = $jinput->post->get('repository', 0, 'INT'); - $addPlaceholders = $jinput->post->get('placeholders', 2, 'INT'); - $debugLinenr = $jinput->post->get('debuglinenr', 2, 'INT'); + $jinput = JFactory::getApplication()->input; + $componentId = $jinput->post->get('component', 0, 'INT'); + $version = $jinput->post->get('version', 0, 'INT'); + $addBackup = $jinput->post->get('backup', 0, 'INT'); + $addRepo = $jinput->post->get('repository', 0, 'INT'); + $addPlaceholders = $jinput->post->get('placeholders', 2, 'INT'); + $debugLinenr = $jinput->post->get('debuglinenr', 2, 'INT'); + $minify = $jinput->post->get('minify', 2, 'INT'); // include component compiler require_once JPATH_ADMINISTRATOR.'/components/com_componentbuilder/helpers/compiler.php'; - $model = $this->getModel('compiler'); - if ($model->builder($version,$componentId,$addBackup,$addRepo,$addPlaceholders,$debugLinenr)) + $model = $this->getModel('compiler'); + if ($model->builder($version,$componentId,$addBackup,$addRepo,$addPlaceholders,$debugLinenr, $minify)) { $cache = JFactory::getCache('mod_menu'); $cache->clean(); @@ -88,8 +89,8 @@ class ComponentbuilderControllerCompiler extends JControllerAdmin } $app = JFactory::getApplication(); - $redirect_url = $app->getUserState('com_componentbuilder.redirect_url'); - $message = $app->getUserState('com_componentbuilder.message'); + $redirect_url = $app->getUserState('com_componentbuilder.redirect_url'); + $message = $app->getUserState('com_componentbuilder.message'); if (empty($redirect_url) && $componentId > 0) { $redirect_url = JRoute::_('index.php?option=com_componentbuilder&view=compiler', false); diff --git a/admin/helpers/compiler/a_Get.php b/admin/helpers/compiler/a_Get.php index 15fe7638a..ede4bf8b9 100644 --- a/admin/helpers/compiler/a_Get.php +++ b/admin/helpers/compiler/a_Get.php @@ -607,6 +607,13 @@ class Get */ public $libraries = array(); + /** + * Is minify Enabled + * + * @var int + */ + public $minify = 0; + /** * Is Tidy Enabled * @@ -631,10 +638,12 @@ class Get { // load application $this->app = JFactory::getApplication(); - // check if we have Tidy enabled - $this->tidy = extension_loaded('Tidy'); // Set the params $this->params = JComponentHelper::getParams('com_componentbuilder'); + // set the minfy switch of the JavaScript + $this->minify = (isset($config['minify']) && $config['minify'] != 2) ? $config['minify'] : $this->params->get('minify', 0); + // check if we have Tidy enabled + $this->tidy = extension_loaded('Tidy'); // set the field type builder $this->fieldBuilderType = $this->params->get('compiler_field_builder_type', 2); // check the field builder type logic diff --git a/admin/helpers/compiler/e_Interpretation.php b/admin/helpers/compiler/e_Interpretation.php index 94bdc993b..185be36c6 100644 --- a/admin/helpers/compiler/e_Interpretation.php +++ b/admin/helpers/compiler/e_Interpretation.php @@ -2821,6 +2821,20 @@ class Interpretation extends Fields return $method; } + /** + * get the custom script in the script builder + * + * @param string $first The first key + * @param string $second The second key + * @param string $prefix The prefix to add in front of the script if found + * @param string/bool $note The switch/note to add to the script + * @param bool $unset The switch to unset the value if found + * @param string/bool $unset The switch/string to use as default return if script not found + * @param string $sufix The sufix to add after the script if found + * + * @return mix The string/script if found or the default value if not found + * + */ public function getCustomScriptBuilder($first, $second, $prefix = '', $note = null, $unset = null, $default = null, $sufix = '') { // check if there is any custom script @@ -9052,7 +9066,7 @@ class Interpretation extends Fields } } // minfy the script - if ($this->params->get('minify') && isset($fileScript) && ComponentbuilderHelper::checkString($fileScript)) + if ($this->minify && isset($fileScript) && ComponentbuilderHelper::checkString($fileScript)) { // minify the fielScript javscript $minifier = new JS; @@ -9060,7 +9074,7 @@ class Interpretation extends Fields $fileScript = $minifier->minify(); } // minfy the script - if ($this->params->get('minify') && isset($footerScript) && ComponentbuilderHelper::checkString($footerScript)) + if ($this->minify && isset($footerScript) && ComponentbuilderHelper::checkString($footerScript)) { // minify the footerScript javscript $minifier = new JS; diff --git a/admin/helpers/compiler/f_Infusion.php b/admin/helpers/compiler/f_Infusion.php index b95d8c1ec..ee6805652 100644 --- a/admin/helpers/compiler/f_Infusion.php +++ b/admin/helpers/compiler/f_Infusion.php @@ -299,14 +299,12 @@ class Infusion extends Interpretation // ###AJAXTOKE### <<>> $this->fileContentDynamic[$viewName_single]['###AJAXTOKE###'] = $this->setAjaxToke($viewName_single); - if (isset($this->customScriptBuilder['php_document'][$viewName_single]) && ComponentbuilderHelper::checkString($this->customScriptBuilder['php_document'][$viewName_single])) + // ###DOCUMENT_CUSTOM_PHP### <<>> + if ($phpDocument = $this->getCustomScriptBuilder('php_document', $viewName_single, PHP_EOL, null, true, false)) { - // ###DOCUMENT_CUSTOM_PHP### <<>> - $this->customScriptBuilder['php_document'][$viewName_single] = str_replace('$document->', '$this->document->', $this->customScriptBuilder['php_document'][$viewName_single]); - $this->fileContentDynamic[$viewName_single]['###DOCUMENT_CUSTOM_PHP###'] = PHP_EOL . $this->setPlaceholders( - $this->customScriptBuilder['php_document'][$viewName_single], $this->placeholders); + $this->fileContentDynamic[$viewName_single]['###DOCUMENT_CUSTOM_PHP###'] = str_replace('$document->', '$this->document->', $phpDocument); // clear some memory - unset($this->customScriptBuilder['php_document'][$viewName_single]); + unset($phpDocument); } else { @@ -361,18 +359,9 @@ class Infusion extends Interpretation // ###POSTSAVEHOOK### <<>> $this->fileContentDynamic[$viewName_single]['###POSTSAVEHOOK###'] = $this->getCustomScriptBuilder('php_postsavehook', $viewName_single, PHP_EOL, null, true, PHP_EOL . "\t\treturn;", PHP_EOL . PHP_EOL . "\t\treturn;"); - if (isset($this->customScriptBuilder['css_view'][$viewName_single]) && ComponentbuilderHelper::checkString($this->customScriptBuilder['css_view'][$viewName_single])) - { - // ###VIEWCSS### <<>> - $this->fileContentDynamic[$viewName_single]['###VIEWCSS###'] = $this->setPlaceholders($this->customScriptBuilder['css_view'][$viewName_single], $this->placeholders); - // clear some memory - unset($this->customScriptBuilder['css_view'][$viewName_single]); - } - else - { - // ###VIEWCSS### <<>> - $this->fileContentDynamic[$viewName_single]['###VIEWCSS###'] = ''; - } + // ###VIEWCSS### <<>> + $this->fileContentDynamic[$viewName_single]['###VIEWCSS###'] = $this->getCustomScriptBuilder('css_view', $viewName_single, '', null, true); + // add css to front end if (isset($view['edit_create_site_view']) && $view['edit_create_site_view']) { @@ -489,22 +478,26 @@ class Infusion extends Interpretation // ###JVIEWLISTCANDO### <<>> $this->fileContentDynamic[$viewName_list]['###JVIEWLISTCANDO###'] = $this->setJviewListCanDo($viewName_single, $viewName_list); - if (isset($this->customScriptBuilder['css_views'][$viewName_list]) && ComponentbuilderHelper::checkString($this->customScriptBuilder['css_views'][$viewName_list])) + // ###VIEWSCSS### <<>> + $this->fileContentDynamic[$viewName_list]['###VIEWSCSS###'] = $this->getCustomScriptBuilder('css_views', $viewName_list, '', null, true); + + // ###VIEWS_FOOTER_SCRIPT### <<>> + $scriptNote = PHP_EOL . '//' . $this->setLine(__LINE__) . ' ' . $viewName_list.' footer script'; + if ($footerScript = $this->getCustomScriptBuilder('views_footer', $viewName_single, '', $scriptNote, true, false, PHP_EOL)) { - // ###VIEWCSS### <<>> - $this->fileContentDynamic[$viewName_list]['###VIEWSCSS###'] = $this->setPlaceholders($this->customScriptBuilder['css_views'][$viewName_list], $this->placeholders); + // only minfy if no php is added to the footer script + if ($this->minify && strpos($footerScript, 'add($footerScript); + $footerScript = $minifier->minify(); + // clear some memory + unset($minifier); + } + $this->fileContentDynamic[$viewName_list]['###VIEWS_FOOTER_SCRIPT###'] = PHP_EOL . '"; // clear some memory - unset($this->customScriptBuilder['css_views'][$viewName_list]); - } - else - { - // ###VIEWCSS### <<>> - $this->fileContentDynamic[$viewName_list]['###VIEWSCSS###'] = ''; - } - // ###VIEWS_FOOTER_SCRIPT### - if ($footerScript = $this->getCustomScriptBuilder('views_footer', $viewName_single, PHP_EOL)) - { - $this->fileContentDynamic[$viewName_list]['###VIEWS_FOOTER_SCRIPT###'] = PHP_EOL . '"; + unset($footerScript); } else { @@ -626,86 +619,31 @@ class Infusion extends Interpretation if ($view['settings']->main_get->gettype == 1) { - // check if there is any custom script - if (isset($this->customScriptBuilder[$this->target . '_php_before_getitem'][$view['settings']->code]) && ComponentbuilderHelper::checkString($this->customScriptBuilder[$this->target . '_php_before_getitem'][$view['settings']->code])) - { - // ###CUSTOM_ADMIN_BEFORE_GET_ITEM### <<>> - $this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_BEFORE_GET_ITEM###'] = $this->setPlaceholders($this->customScriptBuilder[$this->target . '_php_before_getitem'][$view['settings']->code], $this->placeholders); - // clear some memory - unset($this->customScriptBuilder[$this->target . '_php_before_getitem'][$view['settings']->code]); - } - else - { - // ###CUSTOM_ADMIN_BEFORE_GET_ITEM### <<>> - $this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_BEFORE_GET_ITEM###'] = ''; - } + // ###CUSTOM_ADMIN_BEFORE_GET_ITEM### <<>> + $this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_BEFORE_GET_ITEM###'] = $this->getCustomScriptBuilder($this->target . '_php_before_getitem', $view['settings']->code, '', null, true); // ###CUSTOM_ADMIN_GET_ITEM### <<>> $this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_GET_ITEM###'] = $this->setCustomViewGetItem($view['settings']->main_get, $view['settings']->code, "\t\t"); - // check if there is any custom script - if (isset($this->customScriptBuilder[$this->target . '_php_after_getitem'][$view['settings']->code]) && ComponentbuilderHelper::checkString($this->customScriptBuilder[$this->target . '_php_after_getitem'][$view['settings']->code])) - { - // ###CUSTOM_ADMIN_AFTER_GET_ITEM### <<>> - $this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_AFTER_GET_ITEM###'] = $this->setPlaceholders($this->customScriptBuilder[$this->target . '_php_after_getitem'][$view['settings']->code], $this->placeholders); - // clear some memory - unset($this->customScriptBuilder[$this->target . '_php_after_getitem'][$view['settings']->code]); - } - else - { - // ###CUSTOM_ADMIN_AFTER_GET_ITEM### <<>> - $this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_AFTER_GET_ITEM###'] = ''; - } + // ###CUSTOM_ADMIN_AFTER_GET_ITEM### <<>> + $this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_AFTER_GET_ITEM###'] = $this->getCustomScriptBuilder($this->target . '_php_after_getitem', $view['settings']->code, '', null, true); } elseif ($view['settings']->main_get->gettype == 2) { // ###CUSTOM_ADMIN_GET_LIST_QUERY### <<>> $this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_GET_LIST_QUERY###'] = $this->setCustomViewListQuery($view['settings']->main_get, $view['settings']->code); - // check if there is any custom script - if (isset($this->customScriptBuilder[$this->target . '_php_getlistquery'][$view['settings']->code]) && ComponentbuilderHelper::checkString($this->customScriptBuilder[$this->target . '_php_getlistquery'][$view['settings']->code])) - { - // ###CUSTOM_ADMIN_CUSTOM_BEFORE_LIST_QUERY### <<>> - $this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_CUSTOM_BEFORE_LIST_QUERY###'] = PHP_EOL . $this->setPlaceholders($this->customScriptBuilder[$this->target . '_php_getlistquery'][$view['settings']->code], $this->placeholders); - // clear some memory - unset($this->customScriptBuilder[$this->target . '_php_getlistquery'][$view['settings']->code]); - } - else - { - // ###CUSTOM_ADMIN_CUSTOM_BEFORE_LIST_QUERY### <<>> - $this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_CUSTOM_BEFORE_LIST_QUERY###'] = ''; - } + // ###CUSTOM_ADMIN_CUSTOM_BEFORE_LIST_QUERY### <<>> + $this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_CUSTOM_BEFORE_LIST_QUERY###'] = $this->getCustomScriptBuilder($this->target . '_php_getlistquery', $view['settings']->code, PHP_EOL, null, true); - // check if there is any custom script - if (isset($this->customScriptBuilder[$this->target . '_php_before_getitems'][$view['settings']->code]) && ComponentbuilderHelper::checkString($this->customScriptBuilder[$this->target . '_php_before_getitems'][$view['settings']->code])) - { - // ###CUSTOM_ADMIN_BEFORE_GET_ITEMS### <<>> - $this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_BEFORE_GET_ITEMS###'] = PHP_EOL . $this->setPlaceholders($this->customScriptBuilder[$this->target . '_php_before_getitems'][$view['settings']->code], $this->placeholders); - // clear some memory - unset($this->customScriptBuilder[$this->target . '_php_before_getitems'][$view['settings']->code]); - } - else - { - // ###CUSTOM_ADMIN_BEFORE_GET_ITEMS### <<>> - $this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_BEFORE_GET_ITEMS###'] = ''; - } + // ###CUSTOM_ADMIN_BEFORE_GET_ITEMS### <<>> + $this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_BEFORE_GET_ITEMS###'] = $this->getCustomScriptBuilder($this->target . '_php_before_getitems', $view['settings']->code, PHP_EOL, null, true); // ###CUSTOM_ADMIN_GET_ITEMS### <<>> $this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_GET_ITEMS###'] = $this->setCustomViewGetItems($view['settings']->main_get, $view['settings']->code); - // check if there is any custom script - if (isset($this->customScriptBuilder[$this->target . '_php_after_getitems'][$view['settings']->code]) && ComponentbuilderHelper::checkString($this->customScriptBuilder[$this->target . '_php_after_getitems'][$view['settings']->code])) - { - // ###CUSTOM_ADMIN_AFTER_GET_ITEMS### <<>> - $this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_AFTER_GET_ITEMS###'] = PHP_EOL . $this->setPlaceholders($this->customScriptBuilder[$this->target . '_php_after_getitems'][$view['settings']->code], $this->placeholders); - // clear some memory - unset($this->customScriptBuilder[$this->target . '_php_after_getitems'][$view['settings']->code]); - } - else - { - // ###CUSTOM_ADMIN_AFTER_GET_ITEMS### <<>> - $this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_AFTER_GET_ITEMS###'] = ''; - } + // ###CUSTOM_ADMIN_AFTER_GET_ITEMS### <<>> + $this->fileContentDynamic[$view['settings']->code]['###CUSTOM_ADMIN_AFTER_GET_ITEMS###'] = $this->getCustomScriptBuilder($this->target . '_php_after_getitems', $view['settings']->code, PHP_EOL, null, true); } // ###CUSTOM_ADMIN_CUSTOM_METHODS### <<>> @@ -917,36 +855,15 @@ class Infusion extends Interpretation { // set user permission access check ###USER_PERMISSION_CHECK_ACCESS### <<>> $this->fileContentDynamic[$view['settings']->code]['###USER_PERMISSION_CHECK_ACCESS###'] = $this->setUserPermissionCheckAccess($view, 1); - // check if there is any custom script - if (isset($this->customScriptBuilder[$this->target . '_php_before_getitem'][$view['settings']->code]) && ComponentbuilderHelper::checkString($this->customScriptBuilder[$this->target . '_php_before_getitem'][$view['settings']->code])) - { - // ###SITE_BEFORE_GET_ITEM### <<>> - $this->fileContentDynamic[$view['settings']->code]['###SITE_BEFORE_GET_ITEM###'] = $this->setPlaceholders($this->customScriptBuilder[$this->target . '_php_before_getitem'][$view['settings']->code], $this->placeholders); - // clear some memory - unset($this->customScriptBuilder[$this->target . '_php_before_getitem'][$view['settings']->code]); - } - else - { - // ###SITE_BEFORE_GET_ITEM### <<>> - $this->fileContentDynamic[$view['settings']->code]['###SITE_BEFORE_GET_ITEM###'] = ''; - } + + // ###SITE_BEFORE_GET_ITEM### <<>> + $this->fileContentDynamic[$view['settings']->code]['###SITE_BEFORE_GET_ITEM###'] = $this->getCustomScriptBuilder($this->target . '_php_before_getitem', $view['settings']->code, '', null, true); // ###SITE_GET_ITEM### <<>> $this->fileContentDynamic[$view['settings']->code]['###SITE_GET_ITEM###'] = $this->setCustomViewGetItem($view['settings']->main_get, $view['settings']->code, "\t\t"); - // check if there is any custom script - if (isset($this->customScriptBuilder[$this->target . '_php_after_getitem'][$view['settings']->code]) && ComponentbuilderHelper::checkString($this->customScriptBuilder[$this->target . '_php_after_getitem'][$view['settings']->code])) - { - // ###SITE_AFTER_GET_ITEM### <<>> - $this->fileContentDynamic[$view['settings']->code]['###SITE_AFTER_GET_ITEM###'] = $this->setPlaceholders($this->customScriptBuilder[$this->target . '_php_after_getitem'][$view['settings']->code], $this->placeholders); - // clear some memory - unset($this->customScriptBuilder[$this->target . '_php_after_getitem'][$view['settings']->code]); - } - else - { - // ###SITE_AFTER_GET_ITEM### <<>> - $this->fileContentDynamic[$view['settings']->code]['###SITE_AFTER_GET_ITEM###'] = ''; - } + // ###SITE_AFTER_GET_ITEM### <<>> + $this->fileContentDynamic[$view['settings']->code]['###SITE_AFTER_GET_ITEM###'] = $this->getCustomScriptBuilder($this->target . '_php_after_getitem', $view['settings']->code, '', null, true); } elseif ($view['settings']->main_get->gettype == 2) { @@ -955,36 +872,14 @@ class Infusion extends Interpretation // ###SITE_GET_LIST_QUERY### <<>> $this->fileContentDynamic[$view['settings']->code]['###SITE_GET_LIST_QUERY###'] = $this->setCustomViewListQuery($view['settings']->main_get, $view['settings']->code); - // check if there is any custom script - if (isset($this->customScriptBuilder[$this->target . '_php_before_getitems'][$view['settings']->code]) && ComponentbuilderHelper::checkString($this->customScriptBuilder[$this->target . '_php_before_getitems'][$view['settings']->code])) - { - // ###SITE_BEFORE_GET_ITEMS### <<>> - $this->fileContentDynamic[$view['settings']->code]['###SITE_BEFORE_GET_ITEMS###'] = PHP_EOL . $this->setPlaceholders($this->customScriptBuilder[$this->target . '_php_before_getitems'][$view['settings']->code], $this->placeholders); - // clear some memory - unset($this->customScriptBuilder[$this->target . '_php_before_getitems'][$view['settings']->code]); - } - else - { - // ###SITE_BEFORE_GET_ITEMS### <<>> - $this->fileContentDynamic[$view['settings']->code]['###SITE_BEFORE_GET_ITEMS###'] = ''; - } + // ###SITE_BEFORE_GET_ITEMS### <<>> + $this->fileContentDynamic[$view['settings']->code]['###SITE_BEFORE_GET_ITEMS###'] = $this->getCustomScriptBuilder($this->target . '_php_before_getitems', $view['settings']->code, PHP_EOL, null, true); // ###SITE_GET_ITEMS### <<>> $this->fileContentDynamic[$view['settings']->code]['###SITE_GET_ITEMS###'] = $this->setCustomViewGetItems($view['settings']->main_get, $view['settings']->code); - // check if there is any custom script - if (isset($this->customScriptBuilder[$this->target . '_php_after_getitems'][$view['settings']->code]) && ComponentbuilderHelper::checkString($this->customScriptBuilder[$this->target . '_php_after_getitems'][$view['settings']->code])) - { - // ###SITE_AFTER_GET_ITEMS### <<>> - $this->fileContentDynamic[$view['settings']->code]['###SITE_AFTER_GET_ITEMS###'] = PHP_EOL . $this->setPlaceholders($this->customScriptBuilder[$this->target . '_php_after_getitems'][$view['settings']->code], $this->placeholders); - // clear some memory - unset($this->customScriptBuilder[$this->target . '_php_after_getitems'][$view['settings']->code]); - } - else - { - // ###SITE_AFTER_GET_ITEMS### <<>> - $this->fileContentDynamic[$view['settings']->code]['###SITE_AFTER_GET_ITEMS###'] = ''; - } + // ###SITE_AFTER_GET_ITEMS### <<>> + $this->fileContentDynamic[$view['settings']->code]['###SITE_AFTER_GET_ITEMS###'] = $this->getCustomScriptBuilder($this->target . '_php_after_getitems', $view['settings']->code, PHP_EOL, null, true); } // add to lang array if (!isset($this->langContent['site'][$this->langPrefix . '_' . $view['settings']->CODE])) diff --git a/admin/language/en-GB/en-GB.com_componentbuilder.ini b/admin/language/en-GB/en-GB.com_componentbuilder.ini index 9a1ac3110..3251cc8e8 100644 --- a/admin/language/en-GB/en-GB.com_componentbuilder.ini +++ b/admin/language/en-GB/en-GB.com_componentbuilder.ini @@ -5325,6 +5325,7 @@ COM_COMPONENTBUILDER_MATCH_FIELD="Match Field" COM_COMPONENTBUILDER_MATCH_OPTIONS="Match Options" COM_COMPONENTBUILDER_MAX_LENGTH_ONLY_FOUR_TEXT_FIELD="Max Length (only 4 text_field)" COM_COMPONENTBUILDER_MERGE="Merge" +COM_COMPONENTBUILDER_MINIFY_JAVASCRIPT="Minify JavaScript" COM_COMPONENTBUILDER_MIN_LENGTH_ONLY_FOUR_TEXT_FIELD="Min Length (only 4 text_field)" COM_COMPONENTBUILDER_NAME="Name" COM_COMPONENTBUILDER_NAME_ASC="Name (Asc)" @@ -5574,6 +5575,7 @@ COM_COMPONENTBUILDER_SET_A_CLASS_VALUE_FOR_THE_LIST_VIEW_OF_THIS_FIELD="Set a cl COM_COMPONENTBUILDER_SHARE_SNIPPETS="Share Snippets" COM_COMPONENTBUILDER_SHOULD_JCB_INSERT_THE_CUSTOM_CODE_PLACEHOLDERS_THIS_IS_ONLY_APPLICABLE_IF_THIS_COMPONENT_HAS_CUSTOM_CODE="Should JCB insert the custom code placeholders? This is only applicable if this component has custom code." COM_COMPONENTBUILDER_SHOULD_THE_COMPONENT_BE_MOVED_TO_YOUR_LOCAL_REPOSITORY_FOLDER="Should the component be moved to your local repository folder?" +COM_COMPONENTBUILDER_SHOULD_THE_JAVASCRIPT_BE_MINIFIED_IN_THE_COMPONENT="Should the JavaScript be minified in the component." COM_COMPONENTBUILDER_SHOULD_THE_ZIPPED_PACKAGE_OF_THE_COMPONENT_BE_MOVED_TO_THE_LOCAL_BACKUP_AND_REMOTE_SALES_SERVER_THIS_IS_ONLY_APPLICABLE_IF_THIS_COMPONENT_HAS_THOSE_VALUES_SET="Should the zipped package of the component be moved to the local backup and remote sales server? This is only applicable if this component has those values set." COM_COMPONENTBUILDER_SHOULD_THIS_FIELD_BE_ESCAPED_IN_THE_LIST_VIEW="Should this field be escaped in the list view." COM_COMPONENTBUILDER_SHOULD_WE_BE_SHOWING_MORE_ELABORATE_INFORMATION_DURING_IMPORT="Should we be showing more elaborate information during import." diff --git a/admin/models/compiler.php b/admin/models/compiler.php index af518f26f..3406f632c 100644 --- a/admin/models/compiler.php +++ b/admin/models/compiler.php @@ -170,14 +170,15 @@ class ComponentbuilderModelCompiler extends JModelList return $db->loadObjectList(); } - public function builder($version, $id, $backup, $repo, $addPlaceholders, $debugLinenr) + public function builder($version, $id, $backup, $repo, $addPlaceholders, $debugLinenr, $minify) { - $set['joomlaVersion'] = $version; + $set['joomlaVersion'] = $version; $set['componentId'] = $id; $set['addBackup'] = $backup; $set['addRepo'] = $repo; $set['addPlaceholders'] = $addPlaceholders; $set['debugLinenr'] = $debugLinenr; + $set['minify'] = $minify; // start up Compiler $this->compiler = new Compiler($set); if($this->compiler) diff --git a/admin/views/compiler/view.html.php b/admin/views/compiler/view.html.php index dfa370c99..7f6dbdeac 100644 --- a/admin/views/compiler/view.html.php +++ b/admin/views/compiler/view.html.php @@ -186,6 +186,32 @@ class ComponentbuilderViewCompiler extends JViewLegacy // add to form $form[] = $debuglinenr; + // get the minify radio field + $minify = JFormHelper::loadFieldType('radio',true); + // start minify xml + $minifyXML = new SimpleXMLElement(''); + // minify attributes + $minifyAttributes = array( + 'type' => 'radio', + 'name' => 'minify', + 'label' => 'COM_COMPONENTBUILDER_MINIFY_JAVASCRIPT', + 'class' => 'btn-group btn-group-yesno', + 'description' => 'COM_COMPONENTBUILDER_SHOULD_THE_JAVASCRIPT_BE_MINIFIED_IN_THE_COMPONENT', + 'default' => '2'); + // load the minify attributes + ComponentbuilderHelper::xmlAddAttributes($minifyXML, $minifyAttributes); + // start the minify options + $minifyOptions = array( + '2' => 'COM_COMPONENTBUILDER_GLOBAL', + '1' => 'COM_COMPONENTBUILDER_YES', + '0' => 'COM_COMPONENTBUILDER_NO'); + // load the minify options + ComponentbuilderHelper::xmlAddOptions($minifyXML, $minifyOptions); + // setup the minify radio field + $minify->setup($minifyXML,2); + // add to form + $form[] = $minify; + // get the component list field $component = JFormHelper::loadFieldType('list',true); // start component xml diff --git a/admin/views/joomla_components/tmpl/default.php b/admin/views/joomla_components/tmpl/default.php index 9e03d5ff1..0c65d07f6 100644 --- a/admin/views/joomla_components/tmpl/default.php +++ b/admin/views/joomla_components/tmpl/default.php @@ -98,7 +98,7 @@ if ($this->saveOrder) \ No newline at end of file diff --git a/admin/views/languages/tmpl/default.php b/admin/views/languages/tmpl/default.php index d3869dddc..c70621df2 100644 --- a/admin/views/languages/tmpl/default.php +++ b/admin/views/languages/tmpl/default.php @@ -96,4 +96,27 @@ if ($this->saveOrder) - \ No newline at end of file + + \ No newline at end of file -- 2.40.1 From d1813147d377242821b8e1cc71ba202adebee944 Mon Sep 17 00:00:00 2001 From: Llewellyn van der Merwe Date: Thu, 19 Apr 2018 17:52:47 +0200 Subject: [PATCH 06/14] Added edit links to templates and layouts. Fixed the alias and title selection issue in admin fields area. Added all available languages in Joomla to language area. --- README.md | 6 +- admin/README.txt | 6 +- admin/config.xml | 11 +++ admin/helpers/compiler/a_Get.php | 19 +++-- admin/helpers/compiler/e_Interpretation.php | 35 +++++--- .../en-GB/en-GB.com_componentbuilder.ini | 2 + admin/models/ajax.php | 43 +++++++--- admin/models/fields/lang.php | 36 ++++---- admin/models/forms/admin_fields.xml | 2 + admin/models/forms/custom_admin_view.js | 4 +- admin/models/forms/layout.js | 2 +- admin/models/forms/site_view.js | 4 +- admin/models/forms/template.js | 4 +- admin/models/languages.php | 7 ++ admin/models/layout.php | 26 ++++++ admin/models/template.php | 26 ++++++ admin/sql/install.mysql.utf8.sql | 82 +++++++++++++++++++ admin/views/admin_fields/tmpl/edit.php | 46 +++++++++++ admin/views/layout/view.html.php | 2 + admin/views/template/view.html.php | 2 + componentbuilder.xml | 2 +- script.php | 2 +- 22 files changed, 306 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index 3b9fc641f..13ba48366 100644 --- a/README.md +++ b/README.md @@ -126,12 +126,12 @@ Component Builder is mapped as a component in itself on my local development env + *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + *Name*: [Component Builder](http://joomlacomponentbuilder.com) + *First Build*: 30th April, 2015 -+ *Last Build*: 18th April, 2018 ++ *Last Build*: 19th April, 2018 + *Version*: 2.7.5 + *Copyright*: Copyright (C) 2015. All Rights Reserved + *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html -+ *Line count*: **182984** -+ *Field count*: **1012** ++ *Line count*: **183282** ++ *Field count*: **1013** + *File count*: **1199** + *Folder count*: **193** diff --git a/admin/README.txt b/admin/README.txt index 3b9fc641f..13ba48366 100644 --- a/admin/README.txt +++ b/admin/README.txt @@ -126,12 +126,12 @@ Component Builder is mapped as a component in itself on my local development env + *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + *Name*: [Component Builder](http://joomlacomponentbuilder.com) + *First Build*: 30th April, 2015 -+ *Last Build*: 18th April, 2018 ++ *Last Build*: 19th April, 2018 + *Version*: 2.7.5 + *Copyright*: Copyright (C) 2015. All Rights Reserved + *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html -+ *Line count*: **182984** -+ *Field count*: **1012** ++ *Line count*: **183282** ++ *Field count*: **1013** + *File count*: **1199** + *Folder count*: **193** diff --git a/admin/config.xml b/admin/config.xml index 0f2763316..6032371c5 100644 --- a/admin/config.xml +++ b/admin/config.xml @@ -61,6 +61,17 @@ + + langStringTargets, function($get) use($string) - { - if (strpos($string, $get) !== false) { - return true; - } - return false; - }); + if (strpos($string, $get) !== false) + { + return true; + } + return false; + }); // check if we should continue if (ComponentbuilderHelper::checkArray($langStringTargets)) { @@ -5607,7 +5608,7 @@ class Get } /** - * return the placeholders for insered and replaced code + * return the placeholders for inserted and replaced code * * @param int $type The type of placement * @param int $id The code id in the system diff --git a/admin/helpers/compiler/e_Interpretation.php b/admin/helpers/compiler/e_Interpretation.php index 185be36c6..e6991f340 100644 --- a/admin/helpers/compiler/e_Interpretation.php +++ b/admin/helpers/compiler/e_Interpretation.php @@ -2822,14 +2822,14 @@ class Interpretation extends Fields } /** - * get the custom script in the script builder + * get the a script from the custom script builder * * @param string $first The first key * @param string $second The second key * @param string $prefix The prefix to add in front of the script if found * @param string/bool $note The switch/note to add to the script * @param bool $unset The switch to unset the value if found - * @param string/bool $unset The switch/string to use as default return if script not found + * @param string/bool $default The switch/string to use as default return if script not found * @param string $sufix The sufix to add after the script if found * * @return mix The string/script if found or the default value if not found @@ -2837,8 +2837,9 @@ class Interpretation extends Fields */ public function getCustomScriptBuilder($first, $second, $prefix = '', $note = null, $unset = null, $default = null, $sufix = '') { - // check if there is any custom script + // default is to return an empty string $script = ''; + // check if there is any custom script if (isset($this->customScriptBuilder[$first][$second]) && ComponentbuilderHelper::checkString($this->customScriptBuilder[$first][$second])) { // add not if set @@ -2846,6 +2847,7 @@ class Interpretation extends Fields { $script .= $note; } + // load the actual script $script .= $prefix . str_replace(array_keys($this->placeholders), array_values($this->placeholders), $this->customScriptBuilder[$first][$second]) . $sufix; // clear some memory if ($unset) @@ -3101,6 +3103,17 @@ class Interpretation extends Fields public function setPrepareDocument(&$view) { + // fix just incase we missed it somewhere + $tmp = $this->lang; + if ('site' === $this->target) + { + $this->lang = 'site'; + } + else + { + $this->lang = 'admin'; + } + // ensure correct target is set $TARGET = ComponentbuilderHelper::safeString($this->target, 'U'); @@ -3146,6 +3159,9 @@ class Interpretation extends Fields // set a JavaScript file if needed $this->fileContentDynamic[$view['settings']->code]['###' . $TARGET . '_LIBRARIES_LOADER###'] .= $this->setJavaScriptFile($view, $TARGET); + + // fix just incase we missed it somewhere + $this->lang = $tmp; } public function setGetModules($view, $TARGET) @@ -3311,12 +3327,13 @@ class Interpretation extends Fields { foreach ($view['settings']->custom_buttons as $custom_button) { + // Load to lang + $keyLang = $this->langPrefix . '_' . ComponentbuilderHelper::safeString($custom_button['name'], 'U'); + $keyCode = ComponentbuilderHelper::safeString($custom_button['name']); + $this->langContent[$this->lang][$keyLang] = trim($custom_button['name']); + // load the button if (3 !== $type && ($custom_button['target'] != 2 || $this->target === 'site')) { - // Load to lang - $keyLang = $this->langPrefix . '_' . ComponentbuilderHelper::safeString($custom_button['name'], 'U'); - $keyCode = ComponentbuilderHelper::safeString($custom_button['name']); - $this->langContent[$this->lang][$keyLang] = trim($custom_button['name']); // add cpanel button TODO does not work well on site with permissions if ($custom_button['target'] == 2) { @@ -3334,10 +3351,6 @@ class Interpretation extends Fields // load the list button elseif (3 == $type && $custom_button['target'] != 1) { - // Load to lang - $keyLang = $this->langPrefix . '_' . ComponentbuilderHelper::safeString($custom_button['name'], 'U'); - $keyCode = ComponentbuilderHelper::safeString($custom_button['name']); - $this->langContent[$this->lang][$keyLang] = trim($custom_button['name']); // add cpanel button TODO does not work well on site with permissions if (isset($custom_button['type']) && $custom_button['type'] == 2) { diff --git a/admin/language/en-GB/en-GB.com_componentbuilder.ini b/admin/language/en-GB/en-GB.com_componentbuilder.ini index 3251cc8e8..c9e95f13d 100644 --- a/admin/language/en-GB/en-GB.com_componentbuilder.ini +++ b/admin/language/en-GB/en-GB.com_componentbuilder.ini @@ -2401,6 +2401,7 @@ COM_COMPONENTBUILDER_CONFIG_GLOBAL_DESC="The Global Parameters" COM_COMPONENTBUILDER_CONFIG_GLOBAL_LABEL="Global" COM_COMPONENTBUILDER_CONFIG_GRADIANT_LOAD="Gradient" COM_COMPONENTBUILDER_CONFIG_INACTIVE="Inactive" +COM_COMPONENTBUILDER_CONFIG_LANGUAGE_LABEL="Language" COM_COMPONENTBUILDER_CONFIG_LOCAL_FOLDER="Local Folder" COM_COMPONENTBUILDER_CONFIG_MAILER_DESCRIPTION="Select what mailer you would like to use to send emails." COM_COMPONENTBUILDER_CONFIG_MAILER_LABEL="Mailer" @@ -5338,6 +5339,7 @@ COM_COMPONENTBUILDER_NEW_MEANS_THAT_WE_COULD_NOT_FIND_A_LOCAL_SNIPPET_WITH_THE_S COM_COMPONENTBUILDER_NEW_NOTICE="New Notice" COM_COMPONENTBUILDER_NO="No" COM_COMPONENTBUILDER_NONE_DB="None DB" +COM_COMPONENTBUILDER_NONE_SELECTED="None selected" COM_COMPONENTBUILDER_NOTRANSLATION="no-translation" COM_COMPONENTBUILDER_NOT_FOUND_OR_ACCESS_DENIED="Not found or access denied!" COM_COMPONENTBUILDER_NOT_SET="not set" diff --git a/admin/models/ajax.php b/admin/models/ajax.php index 4a956ea70..0dbd077a3 100644 --- a/admin/models/ajax.php +++ b/admin/models/ajax.php @@ -1362,14 +1362,14 @@ class ComponentbuilderModelAjax extends JModelList // set table $table = false; // Get a db connection. - $db = JFactory::getDbo(); + $db = JFactory::getDbo(); // Create a new query object. $query = $db->getQuery(true); - $query->select($db->quoteName(array('a.alias','a.template','b.name'))); + $query->select($db->quoteName(array('a.id','a.alias','a.template','b.name','a.dynamic_get'))); $query->from($db->quoteName('#__componentbuilder_template', 'a')); $query->join('LEFT', $db->quoteName('#__componentbuilder_dynamic_get', 'b') . ' ON (' . $db->quoteName('b.id') . ' = ' . $db->quoteName('a.dynamic_get') . ')'); $query->where($db->quoteName('a.id') . ' != '.(int) $id); - $query->where($db->quoteName('a.published') . ' = 1'); + $query->where($db->quoteName('a.published') . ' = 1'); // Reset the query using our newly populated query object. $db->setQuery($query); $db->execute(); @@ -1377,9 +1377,20 @@ class ComponentbuilderModelAjax extends JModelList { $results = $db->loadObjectList(); $templateString = array(); + // get the view name & id + $values = $this->getViewID(); + // check if we are in the correct view. + if (!is_null($values['a_id']) && $values['a_id'] > 0 && strlen($values['a_view'])) + { + // set the return ref + $this->ref = '&ref=' . $values['a_view'] . '&refid=' . $values['a_id']; + } foreach ($results as $result) { - $templateString[] = "".$result->name."<?php echo \$this->loadTemplate('".ComponentbuilderHelper::safeString($result->alias)."'); ?>"; + $edit = ($button = $this->addEditLink($result->id, 'template', 'templates')) ? $button : ''; + $editget = (isset($result->dynamic_get) && $result->dynamic_get > 0 && $button = $this->addEditLink($result->dynamic_get, 'dynamic_get', 'dynamic_gets')) ? $button : ''; + $result->name = (ComponentbuilderHelper::checkString($result->name)) ? $result->name : JText::_('COM_COMPONENTBUILDER_NONE_SELECTED'); + $templateString[] = "".$result->name." ".$editget."<?php echo \$this->loadTemplate('".ComponentbuilderHelper::safeString($result->alias)."'); ?> ".$edit.""; } // build the table $table = '

'.JText::_('COM_COMPONENTBUILDER_TEMPLATE_CODE_SNIPPETS').'

'; @@ -1396,14 +1407,14 @@ class ComponentbuilderModelAjax extends JModelList // set table $table = false; // Get a db connection. - $db = JFactory::getDbo(); + $db = JFactory::getDbo(); // Create a new query object. $query = $db->getQuery(true); - $query->select($db->quoteName(array('a.alias','a.layout','b.getcustom','b.gettype','b.name'))); + $query->select($db->quoteName(array('a.id','a.alias','a.layout','b.getcustom','b.gettype','b.name','a.dynamic_get'))); $query->from($db->quoteName('#__componentbuilder_layout', 'a')); $query->join('LEFT', $db->quoteName('#__componentbuilder_dynamic_get', 'b') . ' ON (' . $db->quoteName('b.id') . ' = ' . $db->quoteName('a.dynamic_get') . ')'); $query->where($db->quoteName('a.id') . ' != '.(int) $id); - $query->where($db->quoteName('a.published') . ' = 1'); + $query->where($db->quoteName('a.published') . ' = 1'); // Reset the query using our newly populated query object. $db->setQuery($query); $db->execute(); @@ -1411,17 +1422,29 @@ class ComponentbuilderModelAjax extends JModelList { $results = $db->loadObjectList(); $layoutString = array(); + // get the view name & id + $values = $this->getViewID(); + // check if we are in the correct view. + if (!is_null($values['a_id']) && $values['a_id'] > 0 && strlen($values['a_view'])) + { + // set the return ref + $this->ref = '&ref=' . $values['a_view'] . '&refid=' . $values['a_id']; + } foreach ($results as $result) { + $edit = ($button = $this->addEditLink($result->id, 'layout', 'layouts')) ? $button : ''; + $editget = (isset($result->dynamic_get) && $result->dynamic_get > 0 && $button = $this->addEditLink($result->dynamic_get, 'dynamic_get', 'dynamic_gets')) ? $button : ''; + $result->name = (ComponentbuilderHelper::checkString($result->name)) ? $result->name : JText::_('COM_COMPONENTBUILDER_NONE_SELECTED'); + switch ($result->gettype) { case 1: // single - $layoutString[] = ""; + $layoutString[] = ""; break; case 2: // list - $layoutString[] = ""; + $layoutString[] = ""; break; case 3: case 4: @@ -1435,7 +1458,7 @@ class ComponentbuilderModelAjax extends JModelList { $varName = $result->getcustom; } - $layoutString[] = ""; + $layoutString[] = ""; break; } } diff --git a/admin/models/fields/lang.php b/admin/models/fields/lang.php index b44765c54..10b3952f8 100644 --- a/admin/models/fields/lang.php +++ b/admin/models/fields/lang.php @@ -49,23 +49,23 @@ class JFormFieldLang extends JFormFieldList */ public function getOptions() { - $db = JFactory::getDBO(); - $query = $db->getQuery(true); - $query->select($db->quoteName(array('a.langtag','a.name'),array('langtag','language_name'))); - $query->from($db->quoteName('#__componentbuilder_language', 'a')); - $query->where($db->quoteName('a.published') . ' >= 1'); - $query->order('a.langtag ASC'); - $db->setQuery((string)$query); - $items = $db->loadObjectList(); - $options = array(); - if ($items) - { - $options[] = JHtml::_('select.option', '', 'Select an option'); - foreach($items as $item) - { - $options[] = JHtml::_('select.option', trim($item->langtag), $item->language_name . ' (' .$item->langtag.')'); - } - } - return $options; + $db = JFactory::getDBO(); +$query = $db->getQuery(true); +$query->select($db->quoteName(array('a.langtag','a.name'),array('langtag','language_name'))); +$query->from($db->quoteName('#__componentbuilder_language', 'a')); +$query->where($db->quoteName('a.published') . ' >= 1'); +$query->order('a.langtag ASC'); +$db->setQuery((string)$query); +$items = $db->loadObjectList(); +$options = array(); +if ($items) +{ + $options[] = JHtml::_('select.option', '', 'Select an option'); + foreach($items as $item) + { + $options[] = JHtml::_('select.option', trim($item->langtag), $item->language_name . ' (' .$item->langtag.')'); + } +} +return $options; } } diff --git a/admin/models/forms/admin_fields.xml b/admin/models/forms/admin_fields.xml index 131580f77..244c5cad5 100644 --- a/admin/models/forms/admin_fields.xml +++ b/admin/models/forms/admin_fields.xml @@ -158,6 +158,7 @@ required="false" description="COM_COMPONENTBUILDER_ADMIN_FIELDS_TITLE_DESCRIPTION" class="inputbox" + onchange="checkTitle(this)" /> 0 && id > 0){ var request = 'token='+token+'&id='+id; } @@ -570,7 +570,7 @@ function getLayoutDetails(id){ } function getTemplateDetails_server(id){ - var getUrl = "index.php?option=com_componentbuilder&task=ajax.templateDetails&format=json"; + var getUrl = "index.php?option=com_componentbuilder&task=ajax.templateDetails&format=json&vdm="+vastDevMod; if(token.length > 0 && id > 0){ var request = 'token='+token+'&id='+id; } diff --git a/admin/models/forms/layout.js b/admin/models/forms/layout.js index fa47acd91..bd9d7c403 100644 --- a/admin/models/forms/layout.js +++ b/admin/models/forms/layout.js @@ -178,7 +178,7 @@ function getDynamicValues(id){ } function getLayoutDetails_server(id){ - var getUrl = "index.php?option=com_componentbuilder&task=ajax.getLayoutDetails&format=json"; + var getUrl = "index.php?option=com_componentbuilder&task=ajax.getLayoutDetails&format=json&vdm="+vastDevMod; if(token.length > 0 && id > 0){ var request = 'token='+token+'&id='+id; } diff --git a/admin/models/forms/site_view.js b/admin/models/forms/site_view.js index d8d24db88..da82408e6 100644 --- a/admin/models/forms/site_view.js +++ b/admin/models/forms/site_view.js @@ -585,7 +585,7 @@ function getDynamicValues(id){ } function getLayoutDetails_server(id){ - var getUrl = "index.php?option=com_componentbuilder&task=ajax.getLayoutDetails&format=json"; + var getUrl = "index.php?option=com_componentbuilder&task=ajax.getLayoutDetails&format=json&vdm="+vastDevMod; if(token.length > 0 && id > 0){ var request = 'token='+token+'&id='+id; } @@ -611,7 +611,7 @@ function getLayoutDetails(id){ } function getTemplateDetails_server(id){ - var getUrl = "index.php?option=com_componentbuilder&task=ajax.templateDetails&format=json"; + var getUrl = "index.php?option=com_componentbuilder&task=ajax.templateDetails&format=json&vdm="+vastDevMod; if(token.length > 0 && id > 0){ var request = 'token='+token+'&id='+id; } diff --git a/admin/models/forms/template.js b/admin/models/forms/template.js index d3da0c767..0abe306a9 100644 --- a/admin/models/forms/template.js +++ b/admin/models/forms/template.js @@ -178,7 +178,7 @@ function getDynamicValues(id){ } function getLayoutDetails_server(id){ - var getUrl = "index.php?option=com_componentbuilder&task=ajax.getLayoutDetails&format=json"; + var getUrl = "index.php?option=com_componentbuilder&task=ajax.getLayoutDetails&format=json&vdm="+vastDevMod; if(token.length > 0 && id > 0){ var request = 'token='+token+'&id='+id; } @@ -204,7 +204,7 @@ function getLayoutDetails(id){ } function getTemplateDetails_server(id){ - var getUrl = "index.php?option=com_componentbuilder&task=ajax.templateDetails&format=json"; + var getUrl = "index.php?option=com_componentbuilder&task=ajax.templateDetails&format=json&vdm="+vastDevMod; if(token.length > 0 && id > 0){ var request = 'token='+token+'&id='+id; } diff --git a/admin/models/languages.php b/admin/models/languages.php index 420bad3e0..301e8ef62 100644 --- a/admin/models/languages.php +++ b/admin/models/languages.php @@ -138,6 +138,13 @@ class ComponentbuilderModelLanguages extends JModelList $languages[$language->name] = $language; } + // we must add the British language en-GB (since Joomla Ships with it) + $language = new stdClass; + $language->name = 'English GB'; + $language->element = 'pkg_en-GB'; + $language->type = 'package'; + $languages[$language->name] = $language; + usort($languages, function($a, $b) { return strcmp($a->name, $b->name); diff --git a/admin/models/layout.php b/admin/models/layout.php index c379ae4e2..136e4dd06 100644 --- a/admin/models/layout.php +++ b/admin/models/layout.php @@ -64,6 +64,11 @@ class ComponentbuilderModelLayout extends JModelAdmin public function getTable($type = 'layout', $prefix = 'ComponentbuilderTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); + } + + public function getVDM() + { + return $this->vastDevMod; } /** @@ -113,6 +118,27 @@ class ComponentbuilderModelLayout extends JModelAdmin { // base64 Decode layout. $item->layout = base64_decode($item->layout); + } + + + if (empty($item->id)) + { + $id = 0; + } + else + { + $id = $item->id; + } + // set the id and view name to session + if ($vdm = ComponentbuilderHelper::get('layout__'.$id)) + { + $this->vastDevMod = $vdm; + } + else + { + $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + ComponentbuilderHelper::set($this->vastDevMod, 'layout__'.$id); + ComponentbuilderHelper::set('layout__'.$id, $this->vastDevMod); } if (!empty($item->id)) diff --git a/admin/models/template.php b/admin/models/template.php index 52805d544..d3077def8 100644 --- a/admin/models/template.php +++ b/admin/models/template.php @@ -64,6 +64,11 @@ class ComponentbuilderModelTemplate extends JModelAdmin public function getTable($type = 'template', $prefix = 'ComponentbuilderTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); + } + + public function getVDM() + { + return $this->vastDevMod; } /** @@ -113,6 +118,27 @@ class ComponentbuilderModelTemplate extends JModelAdmin { // base64 Decode template. $item->template = base64_decode($item->template); + } + + + if (empty($item->id)) + { + $id = 0; + } + else + { + $id = $item->id; + } + // set the id and view name to session + if ($vdm = ComponentbuilderHelper::get('template__'.$id)) + { + $this->vastDevMod = $vdm; + } + else + { + $this->vastDevMod = ComponentbuilderHelper::randomkey(50); + ComponentbuilderHelper::set($this->vastDevMod, 'template__'.$id); + ComponentbuilderHelper::set('template__'.$id, $this->vastDevMod); } if (!empty($item->id)) diff --git a/admin/sql/install.mysql.utf8.sql b/admin/sql/install.mysql.utf8.sql index 557620855..d5aec9d4e 100644 --- a/admin/sql/install.mysql.utf8.sql +++ b/admin/sql/install.mysql.utf8.sql @@ -1527,6 +1527,88 @@ INSERT INTO `#__componentbuilder_fieldtype` (`id`, `catid`, `description`, `name (34, '', 'Remember all views already have [accesslevel] added by default, only add this if you need more custom access selection! Provides a dropdown list of accesslevel options with the current option selected.', 'Accesslevel', '{\"properties0\":{\"name\":\"type\",\"example\":\"accesslevel\",\"mandatory\":\"1\",\"description\":\"(mandatory) must be accesslevel\"},\"properties1\":{\"name\":\"name\",\"example\":\"accesstwo\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"description\":\"(mandatory) is the unique name of the field. This must match the name of the query results column that contains the values that will be shown to the user in the drop-down list, unless a different name is specified in the value_field attribute. \"},\"properties2\":{\"name\":\"label\",\"example\":\"Access Two\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"translatable\":\"1\",\"description\":\"(mandatory) (translatable) is the descriptive title of the field.\"},\"properties3\":{\"name\":\"description\",\"example\":\"Select an access level to this concept.\",\"adjustable\":\"1\",\"translatable\":\"1\",\"description\":\"(optional) (translatable) is text that will be shown as a tooltip when the user moves the mouse over the drop-down box.\"},\"properties4\":{\"name\":\"class\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) is a CSS class name for the HTML form field.\"},\"properties5\":{\"name\":\"required\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) is the field required true if yes.\"},\"properties6\":{\"name\":\"multiple\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) If set to multiple then allows more than one usergroup to be selected.\"},\"properties7\":{\"name\":\"showon\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) show this field on the bases of the value in another field.\"}}', 'List of accesslevels', '', 1, 2, '', 5), (35, '', 'Provides a form with rows of fields that you specify. As many options can be added as desired. Note this form field has a jQuery based javascript file as a dependency.', 'Subform', '{\"properties0\":{\"name\":\"type\",\"example\":\"subform\",\"description\":\"(mandatory) must be subform.\"},\"properties1\":{\"name\":\"name\",\"example\":\"options\",\"adjustable\":\"1\",\"description\":\"(mandatory) is the unique name of the parameter\"},\"properties2\":{\"name\":\"label\",\"example\":\"The Option List\",\"adjustable\":\"1\",\"translatable\":\"1\",\"description\":\"(mandatory) (translatable) is the descriptive title of the field.\"},\"properties3\":{\"name\":\"layout\",\"example\":\"joomla.form.field.subform.repeatable-table\",\"adjustable\":\"1\",\"description\":\"(mandatory) The layout for the repeatable table.\"},\"properties4\":{\"name\":\"component\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) To change the component where it should search for layout\"},\"properties5\":{\"name\":\"client\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) Function to initialise the application client
Frontend: site<\\/code> or 0<\\/code>
Backend: admin<\\/code> or 1<\\/code>\"},\"properties6\":{\"name\":\"multiple\",\"example\":\"true\",\"adjustable\":\"1\",\"mandatory\":\"1\",\"description\":\"(mandatory) The rows to be multiple.\"},\"properties7\":{\"name\":\"buttons\",\"example\":\"add,remove,move\",\"adjustable\":\"1\",\"description\":\"(optional) Which buttons to show if multiple mode is true.
Options: add,remove,move<\\/code>\"},\"properties8\":{\"name\":\"fields\",\"example\":\"1,2,3\",\"adjustable\":\"1\",\"description\":\"(mandatory) The fields to add to the modal. All fields must first be created in component builder as a field before you can add them here, since you must use the id of the field. Separate the field ids with commas. Do not add custom fields that are not also used in this component.\"},\"properties9\":{\"name\":\"formsource\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) you can add a path to a xml file containing the fields.\"},\"properties10\":{\"name\":\"description\",\"example\":\"\",\"adjustable\":\"1\",\"translatable\":\"1\",\"description\":\"(optional) (translatable) description text for the form field. Displays at the top of the modal with the name as well as in the usual position in the form\"},\"properties11\":{\"name\":\"default\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) The default value for the form field if the field is left empty. Note this has to be a json string compatible with the contents of the form field.\"},\"properties12\":{\"name\":\"icon\",\"example\":\"list\",\"adjustable\":\"1\",\"description\":\"(optional) The icon to show on the select button (is prefixed with \\\"icon-\\\").\"},\"properties13\":{\"name\":\"max\",\"example\":\"50\",\"adjustable\":\"1\",\"description\":\"(optional) The maximum number of rows of fields allowed (by default 999 to be effectively infinite)\"},\"properties14\":{\"name\":\"min\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) The minimum number of rows of fields required\"},\"properties15\":{\"name\":\"filter\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) Use only if you would like to save raw data, since the default is best.\"},\"properties16\":{\"name\":\"showon\",\"example\":\"\",\"adjustable\":\"1\",\"description\":\"(optional) show this field on the bases of the value in another field.\"}}', 'Allows form fields which can have as many options as the user desires.', '', 1, 12, '', 6); +-- +-- Dumping data for table `#__componentbuilder_language` +-- + +INSERT INTO `#__componentbuilder_language` (`id`, `langtag`, `name`, `params`, `published`, `created`, `modified`, `version`, `hits`, `ordering`) VALUES +(1, 'af-ZA', 'Afrikaans', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(2, 'sq-AL', 'Albanian', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(3, 'ar-AA', 'Arabic Unitag', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(4, 'hy-AM', 'Armenian', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(5, 'id-ID', 'Bahasa Indonesia', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(6, 'eu-ES', 'Basque', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(7, 'be-BY', 'Belarusian', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(8, 'bn-BD', 'Bengali', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(9, 'bs-BA', 'Bosnian', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(10, 'bg-BG', 'Bulgarian', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(11, 'ca-ES', 'Catalan', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(12, 'zh-CN', 'Chinese Simplified', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(13, 'zh-TW', 'Chinese Traditional', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(14, 'hr-HR', 'Croatian', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(15, 'cs-CZ', 'Czech', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(16, 'da-DK', 'Danish', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(17, 'prs-AF', 'Dari Persian', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(18, 'nl-NL', 'Dutch', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(19, 'dz-BT', 'Dzongkha', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(20, 'en-AU', 'English AU', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(21, 'en-CA', 'English CA', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(22, 'en-GB', 'English GB', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(23, 'en-NZ', 'English NZ', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(24, 'en-US', 'English US', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(25, 'eo-XX', 'Esperanto', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(26, 'et-EE', 'Estonian', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(27, 'fi-FI', 'Finnish', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(28, 'nl-BE', 'Flemish', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(29, 'fr-FR', 'French', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(30, 'fr-CA', 'French CA', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(31, 'gl-ES', 'Galician', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(32, 'ka-GE', 'Georgian', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(33, 'de-AT', 'German AT', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(34, 'de-CH', 'German CH', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(35, 'de-DE', 'German DE', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(36, 'de-LI', 'German LI', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(37, 'de-LU', 'German LU', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(38, 'el-GR', 'Greek', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(39, 'he-IL', 'Hebrew', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(40, 'hi-IN', 'Hindi', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(41, 'hu-HU', 'Hungarian', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(42, 'ga-IE', 'Irish', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(43, 'it-IT', 'Italian', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(44, 'ja-JP', 'Japanese', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(45, 'km-KH', 'Khmer', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(46, 'ko-KR', 'Korean', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(47, 'lv-LV', 'Latvian', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(48, 'mk-MK', 'Macedonian', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(49, 'ms-MY', 'Malay', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(50, 'srp-ME', 'Montenegrin', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(51, 'nb-NO', 'Norwegian Bokmal', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(52, 'nn-NO', 'Norwegian Nynorsk', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(53, 'fa-IR', 'Persian', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(54, 'pl-PL', 'Polish', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(55, 'pt-PT', 'Portuguese', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(56, 'pt-BR', 'Portuguese Brazil', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(57, 'ro-RO', 'Romanian', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(58, 'ru-RU', 'Russian', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(59, 'sr-RS', 'Serbian Cyrillic', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(60, 'sr-YU', 'Serbian Latin', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(61, 'si-LK', 'Sinhala', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(62, 'sk-SK', 'Slovak', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(63, 'sl-SI', 'Slovenian', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(64, 'es-ES', 'Spanish', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(65, 'es-CO', 'Spanish CO', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(66, 'sw-KE', 'Swahili', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(67, 'sv-SE', 'Swedish', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(68, 'sy-IQ', 'Syriac', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(69, 'ta-IN', 'Tamil', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(70, 'th-TH', 'Thai', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(71, 'tr-TR', 'Turkish', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(72, 'tk-TM', 'Turkmen', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(73, 'uk-UA', 'Ukrainian', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(74, 'ug-CN', 'Uyghur', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(75, 'vi-VN', 'Vietnamese', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1), +(76, 'cy-GB', 'Welsh', '', 1, '2018-04-19 13:43:44', '0000-00-00 00:00:00', 1, '', 1); + -- -- Dumping data for table `#__componentbuilder_help_document` -- diff --git a/admin/views/admin_fields/tmpl/edit.php b/admin/views/admin_fields/tmpl/edit.php index 7aed1cc32..748e873be 100644 --- a/admin/views/admin_fields/tmpl/edit.php +++ b/admin/views/admin_fields/tmpl/edit.php @@ -236,4 +236,50 @@ function fanAsgfdSffsAbsent(arr){ } return absentArray; } +// little script to check that only one title is selected +function checkTitle(field) { + // get the ID + var id = jQuery(field).attr('id'); + var target = id.split('__'); + //set the subID + var subID = target[0]+'__'+target[1]; + var subID = subID.replace(/\d+/g, ''); + // set notice and do house cleaning + if (jQuery('#'+id).prop('checked')) { + // get number of items + var numItems = jQuery('.count-the-items1235').length + 10; + for (i = 0; i < numItems; i++) { // for now this is the number of field we should check + // build ID + var id_check = subID+i+'__title'; + // first check if Id is on page + if (jQuery("#"+id_check).length && id_check !== id) { + // uncheck it + jQuery("#"+id_check).prop('checked', false).trigger('change'); + } + } + } +} +// little script to check that only one title is selected +function checkAlias(field) { + // get the ID + var id = jQuery(field).attr('id'); + var target = id.split('__'); + //set the subID + var subID = target[0]+'__'+target[1]; + var subID = subID.replace(/\d+/g, ''); + // set notice and do house cleaning + if (jQuery('#'+id).prop('checked')) { + // get number of items + var numItems = jQuery('.count-the-items1235').length + 10; + for (i = 0; i < numItems; i++) { // for now this is the number of field we should check + // build ID + var id_check = subID+i+'__alias'; + // first check if Id is on page + if (jQuery("#"+id_check).length && id_check !== id) { + // uncheck it + jQuery("#"+id_check).prop('checked', false).trigger('change'); + } + } + } +} diff --git a/admin/views/layout/view.html.php b/admin/views/layout/view.html.php index b40760787..e076495c0 100644 --- a/admin/views/layout/view.html.php +++ b/admin/views/layout/view.html.php @@ -208,6 +208,8 @@ class ComponentbuilderViewLayout extends JViewLegacy $this->document->addScript( JURI::root(true) .'/media/com_componentbuilder/uikit-v2/js/uikit.min.js' , (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/javascript'); $this->document->addScript( JURI::root(true) .'/media/com_componentbuilder/uikit-v2/js/components/lightbox.min.js', (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/javascript', (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('type' => 'text/javascript', 'async' => 'async') : true); $this->document->addScript( JURI::root(true) .'/media/com_componentbuilder/uikit-v2/js/components/notify.min.js', (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/javascript', (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('type' => 'text/javascript', 'async' => 'async') : true); + // add var key + $this->document->addScriptDeclaration("var vastDevMod = '".$this->get('VDM')."';"); JText::script('view not acceptable. Error'); } } diff --git a/admin/views/template/view.html.php b/admin/views/template/view.html.php index b6530d026..308fb6f39 100644 --- a/admin/views/template/view.html.php +++ b/admin/views/template/view.html.php @@ -208,6 +208,8 @@ class ComponentbuilderViewTemplate extends JViewLegacy $this->document->addScript( JURI::root(true) .'/media/com_componentbuilder/uikit-v2/js/uikit.min.js' , (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/javascript'); $this->document->addScript( JURI::root(true) .'/media/com_componentbuilder/uikit-v2/js/components/lightbox.min.js', (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/javascript', (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('type' => 'text/javascript', 'async' => 'async') : true); $this->document->addScript( JURI::root(true) .'/media/com_componentbuilder/uikit-v2/js/components/notify.min.js', (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('version' => 'auto') : 'text/javascript', (ComponentbuilderHelper::jVersion()->isCompatible('3.8.0')) ? array('type' => 'text/javascript', 'async' => 'async') : true); + // add var key + $this->document->addScriptDeclaration("var vastDevMod = '".$this->get('VDM')."';"); JText::script('view not acceptable. Error'); } } diff --git a/componentbuilder.xml b/componentbuilder.xml index 4937c249b..4ef73e581 100644 --- a/componentbuilder.xml +++ b/componentbuilder.xml @@ -1,7 +1,7 @@ COM_COMPONENTBUILDER - 18th April, 2018 + 19th April, 2018 Llewellyn van der Merwe llewellyn@joomlacomponentbuilder.com http://joomlacomponentbuilder.com diff --git a/script.php b/script.php index e69da93da..44645018f 100644 --- a/script.php +++ b/script.php @@ -3692,7 +3692,7 @@ class com_componentbuilderInstallerScript $query = $db->getQuery(true); // Field to update. $fields = array( - $db->quoteName('params') . ' = ' . $db->quote('{"autorName":"Llewellyn van der Merwe","autorEmail":"llewellyn@joomlacomponentbuilder.com","minify":"0","percentagelanguageadd":"50","compiler_field_builder_type":"2","set_browser_storage":"1","storage_time_to_live":"global","cronjob_backup_type":"1","cronjob_backup_server":"0","backup_package_name":"JCB_Backup_[YEAR]_[MONTH]_[DAY]","export_license":"GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html","export_copyright":"Copyright (C) 2015. All Rights Reserved","check_in":"-1 day","save_history":"1","history_limit":"10","uikit_load":"1","uikit_min":"","uikit_style":""}'), + $db->quoteName('params') . ' = ' . $db->quote('{"autorName":"Llewellyn van der Merwe","autorEmail":"llewellyn@joomlacomponentbuilder.com","minify":"0","language":"en-GB","percentagelanguageadd":"50","compiler_field_builder_type":"2","set_browser_storage":"1","storage_time_to_live":"global","cronjob_backup_type":"1","cronjob_backup_server":"0","backup_package_name":"JCB_Backup_[YEAR]_[MONTH]_[DAY]","export_license":"GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html","export_copyright":"Copyright (C) 2015. All Rights Reserved","check_in":"-1 day","save_history":"1","history_limit":"10","uikit_load":"1","uikit_min":"","uikit_style":""}'), ); // Condition. $conditions = array( -- 2.40.1 From 4b57e69edba8a6b5c99d5282608d9d3fd31e4565 Mon Sep 17 00:00:00 2001 From: Llewellyn van der Merwe Date: Fri, 20 Apr 2018 01:36:21 +0200 Subject: [PATCH 07/14] Improved JCB to now be able to have other languanges then en-GB as its base/main/global language. This will allow you to build your components in a language of your choice. --- README.md | 8 +++--- admin/README.txt | 8 +++--- admin/helpers/compiler/a_Get.php | 27 +++++++++++++------ admin/helpers/compiler/e_Interpretation.php | 12 ++++----- admin/helpers/compiler/f_Infusion.php | 24 ++++++++--------- .../en-GB/en-GB.com_componentbuilder.ini | 8 +++--- .../details_fullwidth.php | 2 +- admin/models/forms/language_translation.xml | 12 ++++----- admin/models/import_language_translations.php | 15 ++++++++--- admin/models/language_translation.php | 4 +-- admin/models/language_translations.php | 24 ++++++++--------- admin/sql/install.mysql.utf8.sql | 2 +- admin/sql/updates/mysql/2.7.5.sql | 1 + .../tmpl/default_body.php | 4 +-- .../tmpl/default_head.php | 2 +- .../views/language_translations/view.html.php | 2 +- componentbuilder.xml | 4 +-- componentbuilder_update_server.xml | 17 ++++++++++++ script.php | 6 ++--- 19 files changed, 109 insertions(+), 73 deletions(-) create mode 100644 admin/sql/updates/mysql/2.7.5.sql diff --git a/README.md b/README.md index 13ba48366..b6c1ee71a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ The Component Builder for [Joomla](https://extensions.joomla.org/extension/compo Whether you're a seasoned [Joomla](https://extensions.joomla.org/extension/component-builder/) developer, or have just started, Component Builder will safe you lots of time and money. A real must have! -You can install it quite easily and with no limitations. On [github](https://github.com/vdm-io/Joomla-Component-Builder/releases) is the latest release (2.7.5) with **ALL** its features and **ALL** concepts totally open-source and free! +You can install it quite easily and with no limitations. On [github](https://github.com/vdm-io/Joomla-Component-Builder/releases) is the latest release (2.7.6) with **ALL** its features and **ALL** concepts totally open-source and free! > Watch Quick Build of a Hello World component in [JCB on Youtube](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45) @@ -127,12 +127,12 @@ Component Builder is mapped as a component in itself on my local development env + *Name*: [Component Builder](http://joomlacomponentbuilder.com) + *First Build*: 30th April, 2015 + *Last Build*: 19th April, 2018 -+ *Version*: 2.7.5 ++ *Version*: 2.7.6 + *Copyright*: Copyright (C) 2015. All Rights Reserved + *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html -+ *Line count*: **183282** ++ *Line count*: **183307** + *Field count*: **1013** -+ *File count*: **1199** ++ *File count*: **1200** + *Folder count*: **193** > This **component** was build with a Joomla [Automated Component Builder](http://joomlacomponentbuilder.com). diff --git a/admin/README.txt b/admin/README.txt index 13ba48366..b6c1ee71a 100644 --- a/admin/README.txt +++ b/admin/README.txt @@ -9,7 +9,7 @@ The Component Builder for [Joomla](https://extensions.joomla.org/extension/compo Whether you're a seasoned [Joomla](https://extensions.joomla.org/extension/component-builder/) developer, or have just started, Component Builder will safe you lots of time and money. A real must have! -You can install it quite easily and with no limitations. On [github](https://github.com/vdm-io/Joomla-Component-Builder/releases) is the latest release (2.7.5) with **ALL** its features and **ALL** concepts totally open-source and free! +You can install it quite easily and with no limitations. On [github](https://github.com/vdm-io/Joomla-Component-Builder/releases) is the latest release (2.7.6) with **ALL** its features and **ALL** concepts totally open-source and free! > Watch Quick Build of a Hello World component in [JCB on Youtube](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45) @@ -127,12 +127,12 @@ Component Builder is mapped as a component in itself on my local development env + *Name*: [Component Builder](http://joomlacomponentbuilder.com) + *First Build*: 30th April, 2015 + *Last Build*: 19th April, 2018 -+ *Version*: 2.7.5 ++ *Version*: 2.7.6 + *Copyright*: Copyright (C) 2015. All Rights Reserved + *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html -+ *Line count*: **183282** ++ *Line count*: **183307** + *Field count*: **1013** -+ *File count*: **1199** ++ *File count*: **1200** + *Folder count*: **193** > This **component** was build with a Joomla [Automated Component Builder](http://joomlacomponentbuilder.com). diff --git a/admin/helpers/compiler/a_Get.php b/admin/helpers/compiler/a_Get.php index 9c0e3df60..b9c17d696 100644 --- a/admin/helpers/compiler/a_Get.php +++ b/admin/helpers/compiler/a_Get.php @@ -204,7 +204,14 @@ class Get * * @var array */ - public $languages = array('en-GB' => array()); + public $languages = array(); + + /** + * The Main Languages + * + * @var string + */ + public $langTag = 'en-GB'; /** * The Multi Languages bucket @@ -642,6 +649,10 @@ class Get $this->params = JComponentHelper::getParams('com_componentbuilder'); // set the minfy switch of the JavaScript $this->minify = (isset($config['minify']) && $config['minify'] != 2) ? $config['minify'] : $this->params->get('minify', 0); + // set the global language + $this->langTag = $this->params->get('language', $this->langTag); + // setup the main language array + $this->languages[$this->langTag] = array(); // check if we have Tidy enabled $this->tidy = extension_loaded('Tidy'); // set the field type builder @@ -4516,8 +4527,8 @@ class Get $query->from($this->db->quoteName('#__componentbuilder_language_translation', 'a')); if (ComponentbuilderHelper::checkArray($values)) { - $query->select($this->db->quoteName(array('a.id', 'a.translation', 'a.entranslation', 'a.components', 'a.published'))); - $query->where($this->db->quoteName('a.entranslation') . ' IN (' . implode(',', array_map(function($a) + $query->select($this->db->quoteName(array('a.id', 'a.translation', 'a.source', 'a.components', 'a.published'))); + $query->where($this->db->quoteName('a.source') . ' IN (' . implode(',', array_map(function($a) { return $this->db->quote($a); }, $values)) . ')'); @@ -4525,7 +4536,7 @@ class Get $this->db->execute(); if ($this->db->getNumRows()) { - return $this->db->loadAssocList('entranslation'); + return $this->db->loadAssocList('source'); } } return false; @@ -4543,7 +4554,7 @@ class Get $counterInsert = 0; $counterUpdate = 0; $today = JFactory::getDate()->toSql(); - foreach ($this->languages['en-GB'] as $area => $placeholders) + foreach ($this->languages[$this->langTag] as $area => $placeholders) { foreach ($placeholders as $placeholder => $string) { @@ -4630,7 +4641,7 @@ class Get // add the new lang placeholder to the db $this->newLangStrings[$counterInsert] = array(); $this->newLangStrings[$counterInsert][] = $this->db->quote(json_encode(array($this->componentID))); // 'components' - $this->newLangStrings[$counterInsert][] = $this->db->quote($string); // 'entranslation' + $this->newLangStrings[$counterInsert][] = $this->db->quote($string); // 'source' $this->newLangStrings[$counterInsert][] = $this->db->quote(1); // 'published' $this->newLangStrings[$counterInsert][] = $this->db->quote($today); // 'created' $this->newLangStrings[$counterInsert][] = $this->db->quote((int) $this->user->id); // 'created_by' @@ -4668,7 +4679,7 @@ class Get $query = $this->db->getQuery(true); $continue = false; // Insert columns. - $columns = array('components', 'entranslation', 'published', 'created', 'created_by', 'version', 'access'); + $columns = array('components', 'source', 'published', 'created', 'created_by', 'version', 'access'); // Prepare the insert query. $query->insert($this->db->quoteName('#__componentbuilder_language_translation')); $query->columns($this->db->quoteName($columns)); @@ -4763,7 +4774,7 @@ class Get $query->from($this->db->quoteName('#__componentbuilder_language_translation', 'a')); $query->select($this->db->quoteName(array('a.id', 'a.translation', 'a.components'))); // get all string that are not linked to this component - $query->where($this->db->quoteName('a.entranslation') . ' NOT IN (' . implode(',', array_map(function($a) + $query->where($this->db->quoteName('a.source') . ' NOT IN (' . implode(',', array_map(function($a) { return $this->db->quote($a); }, $values)) . ')'); diff --git a/admin/helpers/compiler/e_Interpretation.php b/admin/helpers/compiler/e_Interpretation.php index e6991f340..4ae4c32a7 100644 --- a/admin/helpers/compiler/e_Interpretation.php +++ b/admin/helpers/compiler/e_Interpretation.php @@ -1270,7 +1270,7 @@ class Interpretation extends Fields $method[] = "\t\t\$lang = JFactory::getLanguage();"; $method[] = "\t\t\$extension = 'com_users';"; $method[] = "\t\t\$base_dir = JPATH_SITE;"; - $method[] = "\t\t\$language_tag = 'en-GB';"; + $method[] = "\t\t\$language_tag = '".$this->langTag."';"; $method[] = "\t\t\$reload = true;"; $method[] = "\t\t\$lang->load(\$extension, \$base_dir, \$language_tag, \$reload);"; $method[] = "\t\t//" . $this->setLine(__LINE__) . " load the user regestration model"; @@ -1351,7 +1351,7 @@ class Interpretation extends Fields $method[] = "\t\t\$lang = JFactory::getLanguage();"; $method[] = "\t\t\$extension = 'com_users';"; $method[] = "\t\t\$base_dir = JPATH_ADMINISTRATOR;"; - $method[] = "\t\t\$language_tag = 'en-GB';"; + $method[] = "\t\t\$language_tag = '".$this->langTag."';"; $method[] = "\t\t\$reload = true;"; $method[] = "\t\t\$lang->load(\$extension, \$base_dir, \$language_tag, \$reload);"; $method[] = "\t\t// load the user model"; @@ -6092,7 +6092,7 @@ class Interpretation extends Fields { ksort($this->langContent['admin']); // load to global languages - $this->languages['en-GB']['admin'] = $this->langContent['admin']; + $this->languages[$this->langTag]['admin'] = $this->langContent['admin']; // remove tmp array unset($this->langContent['admin']); @@ -6145,7 +6145,7 @@ class Interpretation extends Fields { ksort($this->langContent['site']); // load to global languages - $this->languages['en-GB']['site'] = $this->langContent['site']; + $this->languages[$this->langTag]['site'] = $this->langContent['site']; // remove tmp array unset($this->langContent['site']); @@ -6173,7 +6173,7 @@ class Interpretation extends Fields { ksort($this->langContent['sitesys']); // load to global languages - $this->languages['en-GB']['sitesys'] = $this->langContent['sitesys']; + $this->languages[$this->langTag]['sitesys'] = $this->langContent['sitesys']; // remove tmp array unset($this->langContent['sitesys']); @@ -6196,7 +6196,7 @@ class Interpretation extends Fields { ksort($this->langContent['adminsys']); // load to global languages - $this->languages['en-GB']['adminsys'] = $this->langContent['adminsys']; + $this->languages[$this->langTag]['adminsys'] = $this->langContent['adminsys']; // remove tmp array unset($this->langContent['adminsys']); diff --git a/admin/helpers/compiler/f_Infusion.php b/admin/helpers/compiler/f_Infusion.php index ee6805652..a5bfa1b87 100644 --- a/admin/helpers/compiler/f_Infusion.php +++ b/admin/helpers/compiler/f_Infusion.php @@ -1078,26 +1078,26 @@ class Infusion extends Interpretation // check the admin lang is set if ($this->setLangAdmin()) { - $values[] = array_values($this->languages['en-GB']['admin']); - $mainLangLoader['admin'] = count($this->languages['en-GB']['admin']); + $values[] = array_values($this->languages[$this->langTag]['admin']); + $mainLangLoader['admin'] = count($this->languages[$this->langTag]['admin']); } // check the admin system lang is set if ($this->setLangAdminSys()) { - $values[] = array_values($this->languages['en-GB']['adminsys']); - $mainLangLoader['adminsys'] = count($this->languages['en-GB']['adminsys']); + $values[] = array_values($this->languages[$this->langTag]['adminsys']); + $mainLangLoader['adminsys'] = count($this->languages[$this->langTag]['adminsys']); } // check the site lang is set if (!$this->removeSiteFolder && $this->setLangSite()) { - $values[] = array_values($this->languages['en-GB']['site']); - $mainLangLoader['site'] = count($this->languages['en-GB']['site']); + $values[] = array_values($this->languages[$this->langTag]['site']); + $mainLangLoader['site'] = count($this->languages[$this->langTag]['site']); } // check the site system lang is set if (!$this->removeSiteFolder && $this->setLangSiteSys()) { - $values[] = array_values($this->languages['en-GB']['sitesys']); - $mainLangLoader['sitesys'] = count($this->languages['en-GB']['sitesys']); + $values[] = array_values($this->languages[$this->langTag]['sitesys']); + $mainLangLoader['sitesys'] = count($this->languages[$this->langTag]['sitesys']); } $values = array_unique(ComponentbuilderHelper::mergeArrays($values)); // get the other lang strings if there is any @@ -1118,8 +1118,8 @@ class Infusion extends Interpretation $tag = trim($tag); foreach ($areas as $area => $languageStrings) { - // only log messages for none en-GB translations - if ('en-GB' !== $tag) + // only log messages for none $this->langTag translations + if ($this->langTag !== $tag) { $langStringNr = count($languageStrings); $langStringSum = $this->bcmath('mul', $langStringNr, 100); @@ -1132,12 +1132,12 @@ class Infusion extends Interpretation if ($percentage < $this->percentageLanguageAdd) { // dont add - $this->langNot[$area . ' ' . $tag] = '' . $mainLangLoader[$area] . '(total en-GB strings) only ' . $langStringNr . '' . $stringNAme . ' = ' . $percentage; + $this->langNot[$area . ' ' . $tag] = '' . $mainLangLoader[$area] . '(total '.$this->langTag.' strings) only ' . $langStringNr . '' . $stringNAme . ' = ' . $percentage; continue; } } // show if it was added as well - $this->langSet[$area . ' ' . $tag] = '' . $mainLangLoader[$area] . '(total en-GB strings) and ' . $langStringNr . '' . $stringNAme . ' = ' . $percentage; + $this->langSet[$area . ' ' . $tag] = '' . $mainLangLoader[$area] . '(total '.$this->langTag.' strings) and ' . $langStringNr . '' . $stringNAme . ' = ' . $percentage; } // set naming convention $p = 'admin'; diff --git a/admin/language/en-GB/en-GB.com_componentbuilder.ini b/admin/language/en-GB/en-GB.com_componentbuilder.ini index c9e95f13d..2e118ab76 100644 --- a/admin/language/en-GB/en-GB.com_componentbuilder.ini +++ b/admin/language/en-GB/en-GB.com_componentbuilder.ini @@ -4786,10 +4786,6 @@ COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_CREATED_DATE_DESC="The date this Langu COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_CREATED_DATE_LABEL="Created Date" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_DETAILS="Details" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_EDIT="Editing the Language Translation" -COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_ENTRANSLATION="Entranslation" -COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_ENTRANSLATION_HINT="Automatically generated!" -COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_ENTRANSLATION_LABEL="English String" -COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_ENTRANSLATION_MESSAGE="Error! Please English translated string here." COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_ERROR_UNIQUE_ALIAS="Another Language Translation has the same alias." COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_ID="Id" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_LANGUAGE="Language" @@ -4803,6 +4799,10 @@ COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_ORDERING_LABEL="Ordering" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_PERMISSION="Permissions" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_PUBLISHING="Publishing" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_SAVE_WARNING="Alias already existed so a number was added at the end. You can re-edit the Language Translation to customise the alias." +COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_SOURCE="Source" +COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_SOURCE_HINT="Automatically generated!" +COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_SOURCE_LABEL="Source String" +COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_SOURCE_MESSAGE="Error! Please source translated string here." COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_STATUS="Status" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_TRANSLATION="Translation" COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_TRANSLATION_DESCRIPTION="The translation strings." diff --git a/admin/layouts/language_translation/details_fullwidth.php b/admin/layouts/language_translation/details_fullwidth.php index ab232d359..7d8bcca3f 100644 --- a/admin/layouts/language_translation/details_fullwidth.php +++ b/admin/layouts/language_translation/details_fullwidth.php @@ -30,7 +30,7 @@ defined('_JEXEC') or die('Restricted access'); $form = $displayData->getForm(); $fields = $displayData->get('fields') ?: array( - 'entranslation', + 'source', 'translation', 'components' ); diff --git a/admin/models/forms/language_translation.xml b/admin/models/forms/language_translation.xml index 49080cd7a..8cf765254 100644 --- a/admin/models/forms/language_translation.xml +++ b/admin/models/forms/language_translation.xml @@ -85,18 +85,18 @@ filter="unset" /> - + diff --git a/admin/models/import_language_translations.php b/admin/models/import_language_translations.php index d1c4a1c30..30ab47841 100644 --- a/admin/models/import_language_translations.php +++ b/admin/models/import_language_translations.php @@ -470,12 +470,19 @@ class ComponentbuilderModelImport_language_translations extends JModelLegacy $user = JFactory::getUser(); // remove header if it has headers $id_key = $data['target_headers']['id']; - $english_key = $data['target_headers']['English']; + if (isset($data['target_headers']['Source'])) + { + $source_key = $data['target_headers']['Source']; + } + else + { + $source_key = $data['target_headers']['English']; + } // get the first array set $firstSet = reset($data['array']); // check if first array is a header array and remove if true - if($firstSet[$id_key] == 'id' || $firstSet[$english_key] == 'English') + if($firstSet[$id_key] == 'id' || $firstSet[$source_key] == 'Source' || $firstSet[$source_key] == 'English') { array_shift($data['array']); } @@ -504,7 +511,7 @@ class ComponentbuilderModelImport_language_translations extends JModelLegacy ->select($db->quoteName(array('version', 'translation'))) ->from($db->quoteName('#__componentbuilder_'.$table)) ->where($db->quoteName('id') . ' = '. $db->quote($row[$id_key])) - ->where($db->quoteName('entranslation') . ' = '. $db->quote($row[$english_key])); + ->where($db->quoteName('source') . ' = '. $db->quote($row[$source_key])); // Reset the query using our newly populated query object. $db->setQuery($query); $db->execute(); @@ -538,7 +545,7 @@ class ComponentbuilderModelImport_language_translations extends JModelLegacy foreach($row as $key => $cell) { // ignore column - if ('IGNORE' === $target[$key] || 'modified_by' === $target[$key] || 'modified' === $target[$key] || 'English' === $target[$key] ) + if ('IGNORE' === $target[$key] || 'modified_by' === $target[$key] || 'modified' === $target[$key] || 'Source' === $target[$key] || 'English' === $target[$key] ) { continue; } diff --git a/admin/models/language_translation.php b/admin/models/language_translation.php index 98d084811..2440cca2c 100644 --- a/admin/models/language_translation.php +++ b/admin/models/language_translation.php @@ -614,9 +614,9 @@ class ComponentbuilderModelLanguage_translation extends JModelAdmin } // Only for strings - if (ComponentbuilderHelper::checkString($this->table->entranslation) && !is_numeric($this->table->entranslation)) + if (ComponentbuilderHelper::checkString($this->table->source) && !is_numeric($this->table->source)) { - $this->table->entranslation = $this->generateUniqe('entranslation',$this->table->entranslation); + $this->table->source = $this->generateUniqe('source',$this->table->source); } // insert all set values diff --git a/admin/models/language_translations.php b/admin/models/language_translations.php index 7732c2cc3..b9efbf413 100644 --- a/admin/models/language_translations.php +++ b/admin/models/language_translations.php @@ -44,7 +44,7 @@ class ComponentbuilderModelLanguage_translations extends JModelList 'a.ordering','ordering', 'a.created_by','created_by', 'a.modified_by','modified_by', - 'a.entranslation','entranslation' + 'a.source','source' ); } @@ -65,8 +65,8 @@ class ComponentbuilderModelLanguage_translations extends JModelList { $this->context .= '.' . $layout; } - $entranslation = $this->getUserStateFromRequest($this->context . '.filter.entranslation', 'filter_entranslation'); - $this->setState('filter.entranslation', $entranslation); + $source = $this->getUserStateFromRequest($this->context . '.filter.source', 'filter_source'); + $this->setState('filter.source', $source); $sorting = $this->getUserStateFromRequest($this->context . '.filter.sorting', 'filter_sorting', 0, 'int'); $this->setState('filter.sorting', $sorting); @@ -153,11 +153,11 @@ class ComponentbuilderModelLanguage_translations extends JModelList // load the languages to the string if (ComponentbuilderHelper::checkArray($langBucket)) { - $item->entranslation = '(' . implode(', ', $langBucket) . ') ' . ComponentbuilderHelper::htmlEscape($item->entranslation, 'UTF-8', true, 150) . $componentCounter; + $item->source = '(' . implode(', ', $langBucket) . ') ' . ComponentbuilderHelper::htmlEscape($item->source, 'UTF-8', true, 150) . $componentCounter; } else { - $item->entranslation = '(' . JText::_('COM_COMPONENTBUILDER_NOTRANSLATION') . ') ' . ComponentbuilderHelper::htmlEscape($item->entranslation, 'UTF-8', true, 150) . $componentCounter; + $item->source = '(' . JText::_('COM_COMPONENTBUILDER_NOTRANSLATION') . ') ' . ComponentbuilderHelper::htmlEscape($item->source, 'UTF-8', true, 150) . $componentCounter; } } } @@ -187,7 +187,7 @@ class ComponentbuilderModelLanguage_translations extends JModelList { $item->{$lanTag} = ''; } - // now adapt the entranslation + // now adapt the source if (isset($item->translation) && ComponentbuilderHelper::checkJson($item->translation)) { $translations = json_decode($item->translation, true); @@ -268,7 +268,7 @@ class ComponentbuilderModelLanguage_translations extends JModelList else { $search = $db->quote('%' . $db->escape($search) . '%'); - $query->where('(a.entranslation LIKE '.$search.')'); + $query->where('(a.source LIKE '.$search.')'); } } @@ -386,11 +386,11 @@ class ComponentbuilderModelLanguage_translations extends JModelList // load the languages to the string if (ComponentbuilderHelper::checkArray($langBucket)) { - $item->entranslation = '(' . implode(', ', $langBucket) . ') ' . ComponentbuilderHelper::htmlEscape($item->entranslation, 'UTF-8', true, 150) . $componentCounter; + $item->source = '(' . implode(', ', $langBucket) . ') ' . ComponentbuilderHelper::htmlEscape($item->source, 'UTF-8', true, 150) . $componentCounter; } else { - $item->entranslation = '(' . JText::_('COM_COMPONENTBUILDER_NOTRANSLATION') . ') ' . ComponentbuilderHelper::htmlEscape($item->entranslation, 'UTF-8', true, 150) . $componentCounter; + $item->source = '(' . JText::_('COM_COMPONENTBUILDER_NOTRANSLATION') . ') ' . ComponentbuilderHelper::htmlEscape($item->source, 'UTF-8', true, 150) . $componentCounter; } } } @@ -420,7 +420,7 @@ class ComponentbuilderModelLanguage_translations extends JModelList { $item->{$lanTag} = ''; } - // now adapt the entranslation + // now adapt the source if (isset($item->translation) && ComponentbuilderHelper::checkJson($item->translation)) { $translations = json_decode($item->translation, true); @@ -458,7 +458,7 @@ class ComponentbuilderModelLanguage_translations extends JModelList // start setup of headers $headers = new stdClass(); $headers->id = 'id'; - $headers->English = 'English'; + $headers->Source = 'Source'; // add the languages if (ComponentbuilderHelper::checkArray($languages)) { @@ -485,7 +485,7 @@ class ComponentbuilderModelLanguage_translations extends JModelList $id .= ':' . $this->getState('filter.ordering'); $id .= ':' . $this->getState('filter.created_by'); $id .= ':' . $this->getState('filter.modified_by'); - $id .= ':' . $this->getState('filter.entranslation'); + $id .= ':' . $this->getState('filter.source'); return parent::getStoreId($id); } diff --git a/admin/sql/install.mysql.utf8.sql b/admin/sql/install.mysql.utf8.sql index d5aec9d4e..66b7343db 100644 --- a/admin/sql/install.mysql.utf8.sql +++ b/admin/sql/install.mysql.utf8.sql @@ -774,7 +774,7 @@ CREATE TABLE IF NOT EXISTS `#__componentbuilder_language_translation` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `asset_id` INT(10) unsigned NOT NULL DEFAULT 0 COMMENT 'FK to the #__assets table.', `components` TEXT NOT NULL, - `entranslation` TEXT NOT NULL, + `source` TEXT NOT NULL, `translation` TEXT NOT NULL, `params` text NOT NULL DEFAULT '', `published` TINYINT(3) NOT NULL DEFAULT 1, diff --git a/admin/sql/updates/mysql/2.7.5.sql b/admin/sql/updates/mysql/2.7.5.sql new file mode 100644 index 000000000..0452705a0 --- /dev/null +++ b/admin/sql/updates/mysql/2.7.5.sql @@ -0,0 +1 @@ +ALTER TABLE `#__componentbuilder_language_translation` CHANGE `entranslation` `source` TEXT NOT NULL; diff --git a/admin/views/language_translations/tmpl/default_body.php b/admin/views/language_translations/tmpl/default_body.php index 87141f9ed..cbe0f505b 100644 --- a/admin/views/language_translations/tmpl/default_body.php +++ b/admin/views/language_translations/tmpl/default_body.php @@ -77,13 +77,13 @@ $edit = "index.php?option=com_componentbuilder&view=language_translations&task=l
canState): ?>
".$result->name."<?php echo JLayoutHelper::render('".ComponentbuilderHelper::safeString($result->alias)."', \$this->item); ?>".$result->name." ".$editget."<?php echo JLayoutHelper::render('".ComponentbuilderHelper::safeString($result->alias)."', \$this->item); ?> ".$edit."".$result->name."<?php echo JLayoutHelper::render('".ComponentbuilderHelper::safeString($result->alias)."', \$this->items); ?>".$result->name." ".$editget."<?php echo JLayoutHelper::render('".ComponentbuilderHelper::safeString($result->alias)."', \$this->items); ?> ".$edit."".$result->name."<?php echo JLayoutHelper::render('".ComponentbuilderHelper::safeString($result->alias)."', \$this->".$varName."); ?>".$result->name." ".$editget."<?php echo JLayoutHelper::render('".ComponentbuilderHelper::safeString($result->alias)."', \$this->".$varName."); ?> ".$edit." get('language_translation.edit')): ?>
- entranslation; ?> + source; ?> checked_out): ?> name, $item->checked_out_time, 'language_translations.', $canCheckin); ?>
-
entranslation; ?>
+
source; ?>
diff --git a/admin/views/language_translations/tmpl/default_head.php b/admin/views/language_translations/tmpl/default_head.php index 3035c4aca..7a4cf5d6e 100644 --- a/admin/views/language_translations/tmpl/default_head.php +++ b/admin/views/language_translations/tmpl/default_head.php @@ -44,7 +44,7 @@ defined('_JEXEC') or die('Restricted access'); - listDirn, $this->listOrder); ?> + listDirn, $this->listOrder); ?> diff --git a/admin/views/language_translations/view.html.php b/admin/views/language_translations/view.html.php index f4fe7a9c7..5fff88485 100644 --- a/admin/views/language_translations/view.html.php +++ b/admin/views/language_translations/view.html.php @@ -245,7 +245,7 @@ class ComponentbuilderViewLanguage_translations extends JViewLegacy return array( 'a.sorting' => JText::_('JGRID_HEADING_ORDERING'), 'a.published' => JText::_('JSTATUS'), - 'a.entranslation' => JText::_('COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_ENTRANSLATION_LABEL'), + 'a.source' => JText::_('COM_COMPONENTBUILDER_LANGUAGE_TRANSLATION_SOURCE_LABEL'), 'a.id' => JText::_('JGRID_HEADING_ID') ); } diff --git a/componentbuilder.xml b/componentbuilder.xml index 4ef73e581..a08099ab4 100644 --- a/componentbuilder.xml +++ b/componentbuilder.xml @@ -7,9 +7,9 @@ http://joomlacomponentbuilder.com Copyright (C) 2015. All Rights Reserved GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html - 2.7.5 + 2.7.6 Component Builder (v.2.7.5) +

Component Builder (v.2.7.6)

The Component Builder for [Joomla](https://extensions.joomla.org/extension/component-builder/) is highly advanced tool that is truly able to build extremely complex components in a fraction of the time. diff --git a/componentbuilder_update_server.xml b/componentbuilder_update_server.xml index 004a44475..e6e3ef180 100644 --- a/componentbuilder_update_server.xml +++ b/componentbuilder_update_server.xml @@ -339,4 +339,21 @@ http://joomlacomponentbuilder.com + + Component Builder + Builds Complex Joomla Components + com_componentbuilder + component + 2.7.6 + http://joomlacomponentbuilder.com + + https://github.com/vdm-io/Joomla-Component-Builder/releases/download/v2.7.6/JCB_v2.7.6.zip + + + stable + + Llewellyn van der Merwe + http://joomlacomponentbuilder.com + + \ No newline at end of file diff --git a/script.php b/script.php index 44645018f..521ba55c4 100644 --- a/script.php +++ b/script.php @@ -3476,7 +3476,7 @@ class com_componentbuilderInstallerScript $language_translation->type_title = 'Componentbuilder Language_translation'; $language_translation->type_alias = 'com_componentbuilder.language_translation'; $language_translation->table = '{"special": {"dbtable": "#__componentbuilder_language_translation","key": "id","type": "Language_translation","prefix": "componentbuilderTable","config": "array()"},"common": {"dbtable": "#__ucm_content","key": "ucm_id","type": "Corecontent","prefix": "JTable","config": "array()"}}'; - $language_translation->field_mappings = '{"common": {"core_content_item_id": "id","core_title": "entranslation","core_state": "published","core_alias": "null","core_created_time": "created","core_modified_time": "modified","core_body": "null","core_hits": "hits","core_publish_up": "null","core_publish_down": "null","core_access": "access","core_params": "params","core_featured": "null","core_metadata": "null","core_language": "null","core_images": "null","core_urls": "null","core_version": "version","core_ordering": "ordering","core_metakey": "null","core_metadesc": "null","core_catid": "null","core_xreference": "null","asset_id": "asset_id"},"special": {"entranslation":"entranslation","components":"components"}}'; + $language_translation->field_mappings = '{"common": {"core_content_item_id": "id","core_title": "source","core_state": "published","core_alias": "null","core_created_time": "created","core_modified_time": "modified","core_body": "null","core_hits": "hits","core_publish_up": "null","core_publish_down": "null","core_access": "access","core_params": "params","core_featured": "null","core_metadata": "null","core_language": "null","core_images": "null","core_urls": "null","core_version": "version","core_ordering": "ordering","core_metakey": "null","core_metadesc": "null","core_catid": "null","core_xreference": "null","asset_id": "asset_id"},"special": {"source":"source","components":"components"}}'; $language_translation->router = 'ComponentbuilderHelperRoute::getLanguage_translationRoute'; $language_translation->content_history_options = '{"formFile": "administrator/components/com_componentbuilder/models/forms/language_translation.xml","hideFields": ["asset_id","checked_out","checked_out_time","version"],"ignoreChanges": ["modified_by","modified","checked_out","checked_out_time","version","hits"],"convertToInt": ["published","ordering"],"displayLookup": [{"sourceColumn": "created_by","targetTable": "#__users","targetColumn": "id","displayColumn": "name"},{"sourceColumn": "access","targetTable": "#__viewlevels","targetColumn": "id","displayColumn": "title"},{"sourceColumn": "modified_by","targetTable": "#__users","targetColumn": "id","displayColumn": "name"},{"sourceColumn": "components","targetTable": "#__componentbuilder_joomla_component","targetColumn": "id","displayColumn": "system_name"}]}'; @@ -4153,7 +4153,7 @@ class com_componentbuilderInstallerScript $language_translation->type_title = 'Componentbuilder Language_translation'; $language_translation->type_alias = 'com_componentbuilder.language_translation'; $language_translation->table = '{"special": {"dbtable": "#__componentbuilder_language_translation","key": "id","type": "Language_translation","prefix": "componentbuilderTable","config": "array()"},"common": {"dbtable": "#__ucm_content","key": "ucm_id","type": "Corecontent","prefix": "JTable","config": "array()"}}'; - $language_translation->field_mappings = '{"common": {"core_content_item_id": "id","core_title": "entranslation","core_state": "published","core_alias": "null","core_created_time": "created","core_modified_time": "modified","core_body": "null","core_hits": "hits","core_publish_up": "null","core_publish_down": "null","core_access": "access","core_params": "params","core_featured": "null","core_metadata": "null","core_language": "null","core_images": "null","core_urls": "null","core_version": "version","core_ordering": "ordering","core_metakey": "null","core_metadesc": "null","core_catid": "null","core_xreference": "null","asset_id": "asset_id"},"special": {"entranslation":"entranslation","components":"components"}}'; + $language_translation->field_mappings = '{"common": {"core_content_item_id": "id","core_title": "source","core_state": "published","core_alias": "null","core_created_time": "created","core_modified_time": "modified","core_body": "null","core_hits": "hits","core_publish_up": "null","core_publish_down": "null","core_access": "access","core_params": "params","core_featured": "null","core_metadata": "null","core_language": "null","core_images": "null","core_urls": "null","core_version": "version","core_ordering": "ordering","core_metakey": "null","core_metadesc": "null","core_catid": "null","core_xreference": "null","asset_id": "asset_id"},"special": {"source":"source","components":"components"}}'; $language_translation->router = 'ComponentbuilderHelperRoute::getLanguage_translationRoute'; $language_translation->content_history_options = '{"formFile": "administrator/components/com_componentbuilder/models/forms/language_translation.xml","hideFields": ["asset_id","checked_out","checked_out_time","version"],"ignoreChanges": ["modified_by","modified","checked_out","checked_out_time","version","hits"],"convertToInt": ["published","ordering"],"displayLookup": [{"sourceColumn": "created_by","targetTable": "#__users","targetColumn": "id","displayColumn": "name"},{"sourceColumn": "access","targetTable": "#__viewlevels","targetColumn": "id","displayColumn": "title"},{"sourceColumn": "modified_by","targetTable": "#__users","targetColumn": "id","displayColumn": "name"},{"sourceColumn": "components","targetTable": "#__componentbuilder_joomla_component","targetColumn": "id","displayColumn": "system_name"}]}'; @@ -4878,7 +4878,7 @@ class com_componentbuilderInstallerScript echo ' -

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

'; +

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

'; } } -- 2.40.1 From a110ff0e3530011533e1a1c689991506a98a43ef Mon Sep 17 00:00:00 2001 From: Llewellyn van der Merwe Date: Fri, 20 Apr 2018 23:14:49 +0200 Subject: [PATCH 08/14] Fixed a strange mismatch issue with JCB package import with more then 10 components at a time. Also fixed the translation entranslation to source. --- README.md | 4 +- admin/README.txt | 4 +- .../en-GB/en-GB.com_componentbuilder.ini | 8 +- admin/models/import_joomla_components.php | 119 ++++++++++-------- componentbuilder.xml | 2 +- 5 files changed, 78 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index b6c1ee71a..ee72fba30 100644 --- a/README.md +++ b/README.md @@ -126,11 +126,11 @@ Component Builder is mapped as a component in itself on my local development env + *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + *Name*: [Component Builder](http://joomlacomponentbuilder.com) + *First Build*: 30th April, 2015 -+ *Last Build*: 19th April, 2018 ++ *Last Build*: 20th April, 2018 + *Version*: 2.7.6 + *Copyright*: Copyright (C) 2015. All Rights Reserved + *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html -+ *Line count*: **183307** ++ *Line count*: **183326** + *Field count*: **1013** + *File count*: **1200** + *Folder count*: **193** diff --git a/admin/README.txt b/admin/README.txt index b6c1ee71a..ee72fba30 100644 --- a/admin/README.txt +++ b/admin/README.txt @@ -126,11 +126,11 @@ Component Builder is mapped as a component in itself on my local development env + *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + *Name*: [Component Builder](http://joomlacomponentbuilder.com) + *First Build*: 30th April, 2015 -+ *Last Build*: 19th April, 2018 ++ *Last Build*: 20th April, 2018 + *Version*: 2.7.6 + *Copyright*: Copyright (C) 2015. All Rights Reserved + *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html -+ *Line count*: **183307** ++ *Line count*: **183326** + *Field count*: **1013** + *File count*: **1200** + *Folder count*: **193** diff --git a/admin/language/en-GB/en-GB.com_componentbuilder.ini b/admin/language/en-GB/en-GB.com_componentbuilder.ini index 2e118ab76..7f78bf580 100644 --- a/admin/language/en-GB/en-GB.com_componentbuilder.ini +++ b/admin/language/en-GB/en-GB.com_componentbuilder.ini @@ -924,7 +924,7 @@ COM_COMPONENTBUILDER_BACK_TO_LIBRARIES="Back to Libraries" COM_COMPONENTBUILDER_BASIC_TUTORIAL_ON_GIT_BSB="Basic Tutorial on git: %s" COM_COMPONENTBUILDER_BBEST_TO_NOT_CONTINUEBBR_THIS_PACKAGE_BFAILEDB_CHECKSUM_VALIDATION_THIS_COULD_BE_A_SERIOUS_SECURITY_BREACH_DO_NOT_CONTINUE="Best to not continue!
This package FAILED checksum validation, this could be a serious security breach! DO NOT CONTINUE!!!" COM_COMPONENTBUILDER_BBEST_TO_NOT_CONTINUEBBR_WE_COULD_NOT_LOAD_THE_CHECKSUM_FOR_THIS_PACKAGE_AND_SO_NO_VALIDATION_WAS_POSSIBLE_THIS_MAY_BE_DUE_TO_YOUR_NETWORK_OR_A_CHANGE_TO_THAT_PACKAGE_NAME="Best to not continue!
We could not load the checksum for this package, and so no validation was possible. This may be due to your network, or a change to that package name." -COM_COMPONENTBUILDER_BCUSTOM_FILESB_NOT_MOVE_TO_CORRECT_LOCATION="Custom files not move to correct location!" +COM_COMPONENTBUILDER_BCUSTOM_FILESB_NOT_MOVED_TO_CORRECT_LOCATION="Custom files not moved to correct location!" COM_COMPONENTBUILDER_BEHIND="Behind" COM_COMPONENTBUILDER_BEHIND_MEANS_YOUR_BLOCAL_SNIPPETB_WITH_THE_SAME_NAME_LIBRARY_AND_TYPE_HAS_A_BOLDER_MODIFIED_DATEB_THEN_THE_COMMUNITY_SNIPPET_WITH_THE_SAME_NAME_LIBRARY_AND_TYPE="Behind means your local snippet (with the same name, library and type) has a older modified date then the community snippet (with the same name, library and type)." COM_COMPONENTBUILDER_BETA_RELEASE="Beta Release" @@ -932,7 +932,7 @@ COM_COMPONENTBUILDER_BE_CAUTIOUS_DO_NOT_CONTINUE_UNLESS_YOU_TRUST_THE_ORIGIN_OF_ COM_COMPONENTBUILDER_BFIELD_TYPEB_IDS_MISMATCH_IN_BSB="Field type id:%s mismatch in %s." COM_COMPONENTBUILDER_BFIELD_TYPEB_NOT_SET_FOR_BSB="Field type not set for %s." COM_COMPONENTBUILDER_BGET_THE_KEY_FROMB_A_CLASSBTN_BTNPRIMARY_HREFS_TARGET_BLANK_TITLEGET_A_KEY_FROM_SSA="Get the key from %s" -COM_COMPONENTBUILDER_BIMAGESB_NOT_MOVE_TO_CORRECT_LOCATION="Images not move to correct location!" +COM_COMPONENTBUILDER_BIMAGESB_NOT_MOVED_TO_CORRECT_LOCATION="Images not moved to correct location!" COM_COMPONENTBUILDER_BMULTIPLE_FIELD_REPEATABLE_MODEB_IDS_MISMATCH_IN_BFIELDSB_AND_WAS_EMREMOVEDEM_FROM_THE_FIELD="Multiple Field (repeatable mode) id:%s mismatch in field:%s, and was removed from the field." COM_COMPONENTBUILDER_BSBS_IN_BSB_HAS_ID_MISMATCH_SO_THE_BSB_WAS_REMOVED="%s->%s in %s has id mismatch. So the %s was removed!" COM_COMPONENTBUILDER_BSB_COULD_NOT_BE_IMPORTEDS="%s could not be imported%s" @@ -3971,12 +3971,12 @@ COM_COMPONENTBUILDER_FIELD_ZERO="0" COM_COMPONENTBUILDER_FILE="File" COM_COMPONENTBUILDER_FILE_BSB_COULD_NOT_BE_UNLOCKED="File %s could not be unlocked!" COM_COMPONENTBUILDER_FILE_BSB_WAS_MOVED_TO_BSB="File %s was moved to %s" -COM_COMPONENTBUILDER_FILE_BSB_WAS_NOT_MOVE_TO_BSB="File %s was not move to %s" +COM_COMPONENTBUILDER_FILE_BSB_WAS_NOT_MOVED_TO_BSB="File %s was not moved to %s" COM_COMPONENTBUILDER_FILE_BSB_WAS_SUCCESSFULLY_UNLOCKED="File %s was successfully unlocked!" COM_COMPONENTBUILDER_FILTER="Filter" COM_COMPONENTBUILDER_FOLDER="Folder" COM_COMPONENTBUILDER_FOLDER_BSB_WAS_MOVED_TO_BSB="Folder %s was moved to %s" -COM_COMPONENTBUILDER_FOLDER_BSB_WAS_NOT_MOVE_TO_BSB="Folder %s was not move to %s" +COM_COMPONENTBUILDER_FOLDER_BSB_WAS_NOT_MOVED_TO_BSB="Folder %s was not moved to %s" COM_COMPONENTBUILDER_FORCE_LOCAL_UPDATE="Force Local Update" COM_COMPONENTBUILDER_FULL_WIDTH_IN_TAB="Full Width in Tab" COM_COMPONENTBUILDER_FUNCTION_NAME_ALREADY_TAKEN_PLEASE_TRY_AGAIN="Function name already taken, please try again." diff --git a/admin/models/import_joomla_components.php b/admin/models/import_joomla_components.php index 4aad147f7..48a2c4b07 100644 --- a/admin/models/import_joomla_components.php +++ b/admin/models/import_joomla_components.php @@ -725,7 +725,7 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy } } // do a after all run on all items that need it - $this->updateAfter(); + $this->updateAfterAll(); // finally move the old datasets $this->moveDivergedData(); // lets move all the files to its correct location @@ -739,7 +739,7 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy /** * Save the smart items * - * @param string $type The type of values + * @param string $table The table * * @return boolean false on failure * @@ -873,7 +873,7 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy // great we have some custom stuff lets move it if (!JFolder::copy($customDir, $customPath,'',true)) { - $this->app->enqueueMessage(JText::_('COM_COMPONENTBUILDER_BCUSTOM_FILESB_NOT_MOVE_TO_CORRECT_LOCATION'), 'error'); + $this->app->enqueueMessage(JText::_('COM_COMPONENTBUILDER_BCUSTOM_FILESB_NOT_MOVED_TO_CORRECT_LOCATION'), 'error'); $success = false; } // display more import info @@ -889,7 +889,7 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy // great we have some images lets move them if (!JFolder::copy($imageDir, $imagesPath,'',true)) { - $this->app->enqueueMessage(JText::_('COM_COMPONENTBUILDER_BIMAGESB_NOT_MOVE_TO_CORRECT_LOCATION'), 'error'); + $this->app->enqueueMessage(JText::_('COM_COMPONENTBUILDER_BIMAGESB_NOT_MOVED_TO_CORRECT_LOCATION'), 'error'); $success = false; } // display more import info @@ -913,7 +913,7 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy $fullPath = str_replace('//', '/', $dynamicDir . '/' . $folder); if (!JFolder::exists($fullPath) || !JFolder::copy($fullPath, $destination,'',true)) { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_FOLDER_BSB_WAS_NOT_MOVE_TO_BSB', $folder, $destination), 'error'); + $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_FOLDER_BSB_WAS_NOT_MOVED_TO_BSB', $folder, $destination), 'error'); $success = false; } // display more import info @@ -934,7 +934,7 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy $fullPath = str_replace('//', '/', $dynamicDir . '/' . $file); if (!JFile::exists($fullPath) || !JFile::copy($fullPath, $destination)) { - $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_FILE_BSB_WAS_NOT_MOVE_TO_BSB', $file, $destination), 'error'); + $this->app->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_FILE_BSB_WAS_NOT_MOVED_TO_BSB', $file, $destination), 'error'); $success = false; } // display more import info @@ -1018,7 +1018,7 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy * @return void * **/ - public function updateAfter() + public function updateAfterAll() { if (ComponentbuilderHelper::checkArray($this->updateAfter['field'])) { @@ -1097,7 +1097,7 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy if (ComponentbuilderHelper::checkJson($addlinked_views)) { $addlinked_views = json_decode($addlinked_views, true); - // convert Repetable Fields + // convert Repeatable Fields if (ComponentbuilderHelper::checkArray($addlinked_views) && isset($addlinked_views['adminview'])) { $addlinked_views = ComponentbuilderHelper::convertRepeatable($addlinked_views, 'addlinked_views'); @@ -1385,7 +1385,7 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy * object on success * **/ - protected function prepItem($item, &$type, $action, $diverged = false) + protected function prepItem($item, $type, $action, $diverged = false) { // remove access if (isset($item->access)) @@ -1806,9 +1806,9 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy } // repeatable fields to update $updaterR = array( - // repeatablefield => checker - 'sql_tweak' => 'adminview' - ); + // repeatablefield => checker + 'sql_tweak' => 'adminview' + ); // update the repeatable fields $item = ComponentbuilderHelper::convertRepeatableFields($item, $updaterR); // subform fields to target @@ -2006,6 +2006,13 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy { unset($item->localTranslation); } + // move entranslation to source + if (isset($item->entranslation)) + { + $item->source = $item->entranslation; + // also remove the old field + unset($item->entranslation); + } break; case 'admin_fields': case 'admin_fields_conditions': @@ -2217,7 +2224,7 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy * ID int on success * **/ - protected function updateLocalItem(&$item, &$type, &$canState) + protected function updateLocalItem(&$item, $type, &$canState) { // prep the item if ($update = $this->prepItem($item, $type, 'update')) @@ -2248,7 +2255,7 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy * ID int on success * **/ - protected function addLocalItem(&$item, &$type, $diverged = false) + protected function addLocalItem(&$item, $type, $diverged = false) { // prep the item if ($add = $this->prepItem($item, $type, 'add', $diverged)) @@ -2279,15 +2286,26 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy * ID int on success * **/ - protected function getLocalItem(&$item, &$type, $retry = false, $get = 1, $diverged = false) + protected function getLocalItem($item, $type, $retry = false, $get = 1, $diverged = false) { $query = $this->_db->getQuery(true); $query->select('a.*'); $query->from($this->_db->quoteName('#__componentbuilder_' . $type, 'a')); // only run query if where is set $runQuery = false; - if ($get == 1 && isset($item->created) && isset($item->id)) + if ($get == 1 && isset($item->created) && isset($item->id) && (isset($item->name) || isset($item->system_name))) { + // to prefent crazy mismatch with old IDs (I know very weired) + if (isset($item->system_name)) + { + $query->where($this->_db->quoteName('a.system_name') . ' = '. $this->_db->quote($item->system_name)); + } + // to prefent crazy mismatch with old IDs (I know very weired) + if (isset($item->name)) + { + $query->where($this->_db->quoteName('a.name') . ' = '. $this->_db->quote($item->name)); + } + // load the created and id $query->where($this->_db->quoteName('a.created') . ' = '. $this->_db->quote($item->created)); $query->where($this->_db->quoteName('a.id') .' = '. (int) $item->id); $runQuery = true; @@ -2330,19 +2348,7 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy } } } - elseif (isset($item->{$get}) && componentbuilderHelper::checkString($item->{$get})) // do not allow empty strings (since it could be major mis match) - { - // set the value - $value = $item->{$get}; - // check if we have special value - if ($this->specialValue && ComponentbuilderHelper::checkArray($this->specialValue) && isset($this->specialValue[$get])) - { - $value = $this->specialValue[$get]; - } - $query->where($this->_db->quoteName('a.' . $get) . ' = '. $this->_db->quote($value)); - $runQuery = true; - } - elseif (isset($item->{$get}) && is_numeric($item->{$get})) + elseif (isset($item->{$get})) { // set the value $value = $item->{$get}; @@ -2352,14 +2358,18 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy $value = $this->specialValue[$get]; } // load to query - if (is_int($value)) + if (is_numeric($value) && is_int($value)) { $query->where($this->_db->quoteName('a.' . $get) . ' = '. (int) $value); } - elseif (is_float($value)) + elseif (is_numeric($value) && is_float($value)) { $query->where($this->_db->quoteName('a.' . $get) . ' = '. (float) $value); } + elseif(componentbuilderHelper::checkString($value)) // do not allow empty strings (since it could be major mis match) + { + $query->where($this->_db->quoteName('a.' . $get) . ' = '. $this->_db->quote($value)); + } else { return false; // really not needed but who knows for sure... @@ -2399,6 +2409,11 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy { $this->specialValue['admin_view'] = $this->newID['admin_view'][(int) $item->admin_view]; } + // (TODO) I have seen this happen, seems dangerous! + else + { + return false; + } break; case 'validation_rule': case 'fieldtype': @@ -2549,27 +2564,31 @@ class ComponentbuilderModelImport_joomla_components extends JModelLegacy case 'component_config': case 'component_dashboard': case 'component_files_folders': - // get by joomla_component (since there should only be one of each component) - $getter = array('joomla_component'); - $this->specialValue = array(); - // Yet if diverged it makes sense that the ID is updated. - if ($diverged) - { - $this->specialValue['joomla_component'] = (int) $item->joomla_component; - } - elseif (isset($this->newID['joomla_component'][(int) $item->joomla_component])) - { - $this->specialValue['joomla_component'] = $this->newID['joomla_component'][(int) $item->joomla_component]; - } - // (TODO) I have seen this happen, seems dangerous! - else - { - return false; - } + // get by joomla_component (since there should only be one of each component) + $getter = array('joomla_component'); + $this->specialValue = array(); + // Yet if diverged it makes sense that the ID is updated. + if ($diverged) + { + $this->specialValue['joomla_component'] = (int) $item->joomla_component; + } + elseif (isset($this->newID['joomla_component'][(int) $item->joomla_component])) + { + $this->specialValue['joomla_component'] = $this->newID['joomla_component'][(int) $item->joomla_component]; + } + // (TODO) I have seen this happen, seems dangerous! + else + { + return false; + } break; case 'language_translation': - // get by English translation since there should just be one - $getter = 'entranslation'; + // get by source translation since there should just be one + $getter = 'source'; + if (isset($item->entranslation)) + { + $item->source = $item->entranslation; + } break; case 'language': // get by language tag since there should just be one diff --git a/componentbuilder.xml b/componentbuilder.xml index a08099ab4..584011a06 100644 --- a/componentbuilder.xml +++ b/componentbuilder.xml @@ -1,7 +1,7 @@ COM_COMPONENTBUILDER - 19th April, 2018 + 20th April, 2018 Llewellyn van der Merwe llewellyn@joomlacomponentbuilder.com http://joomlacomponentbuilder.com -- 2.40.1 From 0857101371f1716d0bcc935cb691058e49881b77 Mon Sep 17 00:00:00 2001 From: Llewellyn van der Merwe Date: Mon, 23 Apr 2018 02:42:41 +0200 Subject: [PATCH 09/14] Tweaked the field database area to insure that users are forced to set the database values --- README.md | 8 +- admin/README.txt | 8 +- admin/config.xml | 107 +++++++++++++++++- admin/helpers/compiler/a_Get.php | 3 +- admin/helpers/compiler/c_Fields.php | 4 +- .../en-GB/en-GB.com_componentbuilder.ini | 28 +++++ admin/layouts/field/data_base_fullwidth.php | 48 ++++++++ admin/models/fields.php | 1 + admin/models/fields/component.php | 37 +++--- admin/models/fieldtype.php | 1 + admin/models/forms/field.js | 49 ++++++++ admin/models/forms/field.xml | 80 ++++++------- admin/sql/install.mysql.utf8.sql | 2 +- admin/views/field/tmpl/edit.php | 9 ++ componentbuilder.xml | 2 +- script.php | 6 +- 16 files changed, 315 insertions(+), 78 deletions(-) create mode 100644 admin/layouts/field/data_base_fullwidth.php diff --git a/README.md b/README.md index ee72fba30..74e626d04 100644 --- a/README.md +++ b/README.md @@ -126,13 +126,13 @@ Component Builder is mapped as a component in itself on my local development env + *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + *Name*: [Component Builder](http://joomlacomponentbuilder.com) + *First Build*: 30th April, 2015 -+ *Last Build*: 20th April, 2018 ++ *Last Build*: 23rd April, 2018 + *Version*: 2.7.6 + *Copyright*: Copyright (C) 2015. All Rights Reserved + *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html -+ *Line count*: **183326** -+ *Field count*: **1013** -+ *File count*: **1200** ++ *Line count*: **183707** ++ *Field count*: **1024** ++ *File count*: **1201** + *Folder count*: **193** > This **component** was build with a Joomla [Automated Component Builder](http://joomlacomponentbuilder.com). diff --git a/admin/README.txt b/admin/README.txt index ee72fba30..74e626d04 100644 --- a/admin/README.txt +++ b/admin/README.txt @@ -126,13 +126,13 @@ Component Builder is mapped as a component in itself on my local development env + *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + *Name*: [Component Builder](http://joomlacomponentbuilder.com) + *First Build*: 30th April, 2015 -+ *Last Build*: 20th April, 2018 ++ *Last Build*: 23rd April, 2018 + *Version*: 2.7.6 + *Copyright*: Copyright (C) 2015. All Rights Reserved + *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html -+ *Line count*: **183326** -+ *Field count*: **1013** -+ *File count*: **1200** ++ *Line count*: **183707** ++ *Field count*: **1024** ++ *File count*: **1201** + *Folder count*: **193** > This **component** was build with a Joomla [Automated Component Builder](http://joomlacomponentbuilder.com). diff --git a/admin/config.xml b/admin/config.xml index 6032371c5..8dc88dc04 100644 --- a/admin/config.xml +++ b/admin/config.xml @@ -61,6 +61,10 @@ + + + + - - + + COM_COMPONENTBUILDER_CONFIG_SIMPLEXMLELEMENT_CLASS - - + + COM_COMPONENTBUILDER_CONFIG_NEVER_UPDATE - - + + +
+ + + + + + + + + + + + + +
diff --git a/admin/helpers/compiler/a_Get.php b/admin/helpers/compiler/a_Get.php index b9c17d696..d11230710 100644 --- a/admin/helpers/compiler/a_Get.php +++ b/admin/helpers/compiler/a_Get.php @@ -972,6 +972,7 @@ class Get $array['view'] = $array['adminview']; // get the admin settings/data $array['settings'] = $this->getAdminViewData($array['view']); + return $array; }, array_values($component->addadmin_views)); } @@ -1456,7 +1457,7 @@ class Get $view->fields = array_map(function($field) use($name_single, $name_list) { // set hash - static $hash = 1; + static $hash = 123467890; // (TODO) I found this making duplicates // load hash $field['hash'] = md5($field['field'] . $hash); // increment hash diff --git a/admin/helpers/compiler/c_Fields.php b/admin/helpers/compiler/c_Fields.php index 3e944137f..2b80724fc 100644 --- a/admin/helpers/compiler/c_Fields.php +++ b/admin/helpers/compiler/c_Fields.php @@ -2355,7 +2355,7 @@ class Fields extends Structure // set tags for this view but don't load to DB $this->tagsBuilder[$view_name_single] = $view_name_single; } - else + elseif (isset($field['settings']->datatype)) { // insure default not none if number type $intKeys = array('INT', 'TINYINT', 'BIGINT', 'FLOAT', 'DECIMAL', 'DOUBLE'); @@ -2474,7 +2474,7 @@ class Fields extends Structure $this->hiddenFieldsBuilder[$view_name_single] .= ',"' . $name . '"'; } // set all int fields of this view - if ($dbSwitch && ($field['settings']->datatype === 'INT' || $field['settings']->datatype === 'TINYINT' || $field['settings']->datatype === 'BIGINT')) + if ($dbSwitch && isset($field['settings']->datatype) && ($field['settings']->datatype === 'INT' || $field['settings']->datatype === 'TINYINT' || $field['settings']->datatype === 'BIGINT')) { if (!isset($this->intFieldsBuilder[$view_name_single])) { diff --git a/admin/language/en-GB/en-GB.com_componentbuilder.ini b/admin/language/en-GB/en-GB.com_componentbuilder.ini index 7f78bf580..d27188ffd 100644 --- a/admin/language/en-GB/en-GB.com_componentbuilder.ini +++ b/admin/language/en-GB/en-GB.com_componentbuilder.ini @@ -2272,6 +2272,7 @@ function getCronPath(getType, token){ } " COM_COMPONENTBUILDER_CONFIG_BACKUPCRONJOB_NOTE_LABEL="Backup JCB Mapped Components" +COM_COMPONENTBUILDER_CONFIG_BACKUP_DESCRIPTION="Should the zipped package of the component be moved to the local backup and remote sales server? This is only applicable if this component has those values set." COM_COMPONENTBUILDER_CONFIG_BACKUP_EMAIL_DESCRIPTION="Enter the email where the backup key should be send. It will only send an email if a key change is detected, and not on every backup." COM_COMPONENTBUILDER_CONFIG_BACKUP_EMAIL_HINT="Email Address Here" COM_COMPONENTBUILDER_CONFIG_BACKUP_EMAIL_LABEL="Email (backup key)" @@ -2280,6 +2281,7 @@ COM_COMPONENTBUILDER_CONFIG_BACKUP_FOLDER_PATH_DESCRIPTION="Here you can set the COM_COMPONENTBUILDER_CONFIG_BACKUP_FOLDER_PATH_HINT="/home/user/backup" COM_COMPONENTBUILDER_CONFIG_BACKUP_FOLDER_PATH_LABEL="Backup Folder Path" COM_COMPONENTBUILDER_CONFIG_BACKUP_FOLDER_PATH_MESSAGE="Error! Please add folder path here." +COM_COMPONENTBUILDER_CONFIG_BACKUP_LABEL="Add to Backup Folder & Sales Server (if set)" COM_COMPONENTBUILDER_CONFIG_BACKUP_PACKAGE_NAME_DESCRIPTION="Enter Package Name Here" COM_COMPONENTBUILDER_CONFIG_BACKUP_PACKAGE_NAME_HINT="JCB_Backup_[YEAR]_[MONTH]_[DAY]" COM_COMPONENTBUILDER_CONFIG_BACKUP_PACKAGE_NAME_LABEL="Package Name" @@ -2303,6 +2305,8 @@ COM_COMPONENTBUILDER_CONFIG_COMPILER_FOLDER_PATH_DESCRIPTION="Here you can set t COM_COMPONENTBUILDER_CONFIG_COMPILER_FOLDER_PATH_HINT="/home/user/compiler" COM_COMPONENTBUILDER_CONFIG_COMPILER_FOLDER_PATH_LABEL="Compiler Folder Path" COM_COMPONENTBUILDER_CONFIG_COMPILER_FOLDER_PATH_MESSAGE="Error! Please add some text here." +COM_COMPONENTBUILDER_CONFIG_COMPONENT="Component" +COM_COMPONENTBUILDER_CONFIG_COMPONENT_LABEL="Component" COM_COMPONENTBUILDER_CONFIG_CRONJOB="CronJob" COM_COMPONENTBUILDER_CONFIG_CRONJOB_BACKUP_FOLDER_PATH_DESCRIPTION="Here you can set the path to where all components are backed up to." COM_COMPONENTBUILDER_CONFIG_CRONJOB_BACKUP_FOLDER_PATH_HINT="/home/user/fullbackup" @@ -2316,6 +2320,10 @@ COM_COMPONENTBUILDER_CONFIG_CUSTOM_FOLDER_PATH_DESCRIPTION="Here you can set the COM_COMPONENTBUILDER_CONFIG_CUSTOM_FOLDER_PATH_HINT="/home/user/custom" COM_COMPONENTBUILDER_CONFIG_CUSTOM_FOLDER_PATH_LABEL="Custom Folder Path" COM_COMPONENTBUILDER_CONFIG_CUSTOM_FOLDER_PATH_MESSAGE="Error! Please add folder path here." +COM_COMPONENTBUILDER_CONFIG_DEFAULT="Default" +COM_COMPONENTBUILDER_CONFIG_DEVELOPMENT_METHOD="Development Method" +COM_COMPONENTBUILDER_CONFIG_DEVELOPMENT_METHOD_DESCRIPTION="Select what development method you would like to use." +COM_COMPONENTBUILDER_CONFIG_DEVELOPMENT_METHOD_LABEL="Development Method" COM_COMPONENTBUILDER_CONFIG_DKIM="DKIM" COM_COMPONENTBUILDER_CONFIG_DKIM_DESCRIPTION="Set this option to Yes if you want to sign your emails using DKIM." COM_COMPONENTBUILDER_CONFIG_DKIM_DOMAIN_DESCRIPTION="Set the domain. Eg. domain.com" @@ -2349,6 +2357,7 @@ COM_COMPONENTBUILDER_CONFIG_EMAILREPLY_HINT="Email Address Here" COM_COMPONENTBUILDER_CONFIG_EMAILREPLY_LABEL=" Reply to Email" COM_COMPONENTBUILDER_CONFIG_ENCRYPTION_DESC="The encryption key for the field encryption is set here." COM_COMPONENTBUILDER_CONFIG_ENCRYPTION_LABEL="Encryption Settings" +COM_COMPONENTBUILDER_CONFIG_EVENT_LABEL="Trigger Event" COM_COMPONENTBUILDER_CONFIG_EVERY_DAY="Every Day" COM_COMPONENTBUILDER_CONFIG_EVERY_FIFTEEN_MINUTES="Every 15 Minutes" COM_COMPONENTBUILDER_CONFIG_EVERY_FIVE_HOURS="Every 5 Hours" @@ -2360,6 +2369,9 @@ COM_COMPONENTBUILDER_CONFIG_EVERY_TEN_HOURS="Every 10 Hours" COM_COMPONENTBUILDER_CONFIG_EVERY_THIRTY_MINUTES="Every 30 Minutes" COM_COMPONENTBUILDER_CONFIG_EVERY_THIRTY_SECONDS="Every 30 Seconds" COM_COMPONENTBUILDER_CONFIG_EVERY_WEEK="Every Week" +COM_COMPONENTBUILDER_CONFIG_EXPANSION="Expansion" +COM_COMPONENTBUILDER_CONFIG_EXPANSION_DESCRIPTION="Properties for this field" +COM_COMPONENTBUILDER_CONFIG_EXPANSION_LABEL="Expansion" COM_COMPONENTBUILDER_CONFIG_EXPORT_BUY_LINK_DESCRIPTION="Enter link where your JCB package key can be bought." COM_COMPONENTBUILDER_CONFIG_EXPORT_BUY_LINK_HINT="http://www.example.com/buy-keys" COM_COMPONENTBUILDER_CONFIG_EXPORT_BUY_LINK_LABEL="Buy Link
(to get key)" @@ -2419,6 +2431,10 @@ COM_COMPONENTBUILDER_CONFIG_NOTE_COMPILER_FOLDER_PATH_DESCRIPTION="The compiler COM_COMPONENTBUILDER_CONFIG_NOTE_COMPILER_FOLDER_PATH_LABEL="Moving The Compiler Folder" COM_COMPONENTBUILDER_CONFIG_NOTE_CUSTOM_FOLDER_PATH_DESCRIPTION="The custom folder is where all files and folders that you would like to include in your components are stored, the default location is [administrator/components/com_componentbuilder/custom]. You can move this folder by adding your own path here. Remember to move the content of the default custom folder to this new location." COM_COMPONENTBUILDER_CONFIG_NOTE_CUSTOM_FOLDER_PATH_LABEL="Moving The Custom Folder" +COM_COMPONENTBUILDER_CONFIG_NOTE_DEVELOPMENT_METHOD_DEFAULT_DESCRIPTION="

This method is basically the way JCB has always worked by default.

You have a compiler area, once you have made changes you go to the compiler view and compile your component. Then you have the option to install and/or distribute the Joomla install package.

This can also be called the manual development method.

" +COM_COMPONENTBUILDER_CONFIG_NOTE_DEVELOPMENT_METHOD_DEFAULT_LABEL="Default Development Method" +COM_COMPONENTBUILDER_CONFIG_NOTE_DEVELOPMENT_METHOD_EXPANSION_DESCRIPTION="

This method adds auto expansion to the current Joomla automatically.

Below you setup events that trigger auto build and install of a selected set of components. So you do not need to manually compile and install those components any more, the system does all that automatically for you.

So your experience is that you change the field, view or something else in JCB and then the component in Joomla moments later, based on your events and the size of your component, reflect those changed automatically.

This can also be called the automatic development method.

" +COM_COMPONENTBUILDER_CONFIG_NOTE_DEVELOPMENT_METHOD_EXPANSION_LABEL="Expansion Development Method" COM_COMPONENTBUILDER_CONFIG_NOTE_DKIM_USE_DESCRIPTION="

Using the below details, you need to configure your DNS by adding a TXT record on your domain:

"; + $script['view'][] = ""; + $script['view'][] = "\n
"; + $script['view'][] = "
\" method=\"post\" name=\"adminForm\" id=\"adminForm\" class=\"form-horizontal form-validate\">"; + $script['view'][] = ""; + $script['view'][] = "\n\tsidebar)) : ?>"; + $script['view'][] = "\t\t
"; + $script['view'][] = "\t\t\tsidebar; ?>"; + $script['view'][] = "\t\t
"; + $script['view'][] = "\t\t
"; + $script['view'][] = "\t"; + $script['view'][] = "\t\t
"; + $script['view'][] = "\t"; + $script['view'][] = ""; + $script['view'][] = "\n\thasPackage && [[[-#-#-Component]]]Helper::checkArray(\$this->headerList) && [[[-#-#-Component]]]Helper::checkArray(\$this->headers)) : ?>"; + $script['view'][] = "\t\t
"; + $script['view'][] = "\t\t\t"; + $script['view'][] = "\t\t\t
"; + $script['view'][] = "\t\t\t\t"; + $script['view'][] = "\t\t\t\t
"; + $script['view'][] = "\t\t\t\t\t"; + $script['view'][] = "\t\t\t\t
"; + $script['view'][] = "\t\t\t
"; + $script['view'][] = "\t\t\theaderList as \$name => \$title): ?>"; + $script['view'][] = "\t\t\t\t
"; + $script['view'][] = "\t\t\t\t\t"; + $script['view'][] = "\t\t\t\t\t
"; + $script['view'][] = "\t\t\t\t\t\t"; + $script['view'][] = "\t\t\t\t\t
"; + $script['view'][] = "\t\t\t\t
"; + $script['view'][] = "\t\t\t"; + $script['view'][] = "\t\t\t
"; + $script['view'][] = "\t\t\t\t\" onclick=\"Joomla.continueImport()\" />"; + $script['view'][] = "\t\t\t
"; + $script['view'][] = "\t\t
"; + $script['view'][] = "\t\t"; + $script['view'][] = "\t"; + $script['view'][] = "\t\t 'upload')); ?>"; + $script['view'][] = "\t\t"; + $script['view'][] = "\t\t"; + $script['view'][] = "\t\t\t
"; + $script['view'][] = "\t\t\t\t"; + $script['view'][] = "\t\t\t\t
"; + $script['view'][] = "\t\t\t\t\t"; + $script['view'][] = "\t\t\t\t\t
"; + $script['view'][] = "\t\t\t\t\t\t"; + $script['view'][] = "\t\t\t\t\t
"; + $script['view'][] = "\t\t\t\t
"; + $script['view'][] = "\t\t\t\t
"; + $script['view'][] = "\t\t\t\t\t\" onclick=\"Joomla.submitbutton()\" />    (.csv .xls .ods)"; + $script['view'][] = "\t\t\t\t
"; + $script['view'][] = "\t\t\t
"; + $script['view'][] = "\t\t"; + $script['view'][] = "\t\t"; + $script['view'][] = "\t\t"; + $script['view'][] = "\t\t\t
"; + $script['view'][] = "\t\t\t\t"; + $script['view'][] = "\t\t\t\t
"; + $script['view'][] = "\t\t\t\t\t"; + $script['view'][] = "\t\t\t\t\t
"; + $script['view'][] = "\t\t\t\t\t\tstate->get('import.directory'); ?>\" />"; + $script['view'][] = "\t\t\t\t\t
"; + $script['view'][] = "\t\t\t\t
"; + $script['view'][] = "\t\t\t\t
"; + $script['view'][] = "\t\t\t\t\t\" onclick=\"Joomla.submitbutton3()\" />    (.csv .xls .ods)"; + $script['view'][] = "\t\t\t\t
"; + $script['view'][] = "\t\t\t\t
"; + $script['view'][] = "\t\t"; + $script['view'][] = ""; + $script['view'][] = "\n\t\t"; + $script['view'][] = "\t\t\t
"; + $script['view'][] = "\t\t\t\t"; + $script['view'][] = "\t\t\t\t
"; + $script['view'][] = "\t\t\t\t\t"; + $script['view'][] = "\t\t\t\t\t
"; + $script['view'][] = "\t\t\t\t\t\t"; + $script['view'][] = "\t\t\t\t\t
"; + $script['view'][] = "\t\t\t\t
"; + $script['view'][] = "\t\t\t\t
"; + $script['view'][] = "\t\t\t\t\t\" onclick=\"Joomla.submitbutton4()\" />    (.csv .xls .ods)"; + $script['view'][] = "\t\t\t\t
"; + $script['view'][] = "\t\t\t
"; + $script['view'][] = "\t\t"; + $script['view'][] = "\t\t"; + $script['view'][] = "\t\t"; + $script['view'][] = "\t"; + $script['view'][] = "\t"; + $script['view'][] = "\t"; + $script['view'][] = ""; + $script['view'][] = "
"; + } + elseif ('import' === $type) + { + $script['import'] = array(); + $script['import'][] = "\t/**"; + $script['import'][] = "\t * Import an spreadsheet from either folder, url or upload."; + $script['import'][] = "\t *"; + $script['import'][] = "\t * @return boolean result of import"; + $script['import'][] = "\t *"; + $script['import'][] = "\t */"; + $script['import'][] = "\tpublic function import()"; + $script['import'][] = "\t{"; + $script['import'][] = "\t\t\$this->setState('action', 'import');"; + $script['import'][] = "\t\t\$app \t\t= JFactory::getApplication();"; + $script['import'][] = "\t\t\$session \t= JFactory::getSession();"; + $script['import'][] = "\t\t\$package \t= null;"; + $script['import'][] = "\t\t\$continue\t= false;"; + $script['import'][] = "\t\t// get import type"; + $script['import'][] = "\t\t\$this->getType = \$app->input->getString('gettype', NULL);"; + $script['import'][] = "\t\t// get import type"; + $script['import'][] = "\t\t\$this->dataType\t= \$session->get('dataType_VDM_IMPORTINTO', NULL);"; + $script['import'][] = "\n\t\tif (\$package === null)"; + $script['import'][] = "\t\t{"; + $script['import'][] = "\t\t\tswitch (\$this->getType)"; + $script['import'][] = "\t\t\t{"; + $script['import'][] = "\t\t\t\tcase 'folder':"; + $script['import'][] = "\t\t\t\t\t// Remember the 'Import from Directory' path."; + $script['import'][] = "\t\t\t\t\t\$app->getUserStateFromRequest(\$this->_context . '.import_directory', 'import_directory');"; + $script['import'][] = "\t\t\t\t\t\$package = \$this->_getPackageFromFolder();"; + $script['import'][] = "\t\t\t\t\tbreak;"; + $script['import'][] = "\n\t\t\t\tcase 'upload':"; + $script['import'][] = "\t\t\t\t\t\$package = \$this->_getPackageFromUpload();"; + $script['import'][] = "\t\t\t\t\tbreak;"; + $script['import'][] = "\n\t\t\t\tcase 'url':"; + $script['import'][] = "\t\t\t\t\t\$package = \$this->_getPackageFromUrl();"; + $script['import'][] = "\t\t\t\t\tbreak;"; + $script['import'][] = "\n\t\t\t\tcase 'continue':"; + $script['import'][] = "\t\t\t\t\t\$continue \t= true;"; + $script['import'][] = "\t\t\t\t\t\$package\t= \$session->get('package', null);"; + $script['import'][] = "\t\t\t\t\t\$package\t= json_decode(\$package, true);"; + $script['import'][] = "\t\t\t\t\t// clear session"; + $script['import'][] = "\t\t\t\t\t\$session->clear('package');"; + $script['import'][] = "\t\t\t\t\t\$session->clear('dataType');"; + $script['import'][] = "\t\t\t\t\t\$session->clear('hasPackage');"; + $script['import'][] = "\t\t\t\t\tbreak;"; + $script['import'][] = "\n\t\t\t\tdefault:"; + $script['import'][] = "\t\t\t\t\t\$app->setUserState('com_[[[-#-#-component]]].message', JTe-#-#-xt::_('COM_[[[-#-#-COMPONENT]]]_IMPORT_NO_IMPORT_TYPE_FOUND'));"; + $script['import'][] = "\n\t\t\t\t\treturn false;"; + $script['import'][] = "\t\t\t\t\tbreak;"; + $script['import'][] = "\t\t\t}"; + $script['import'][] = "\t\t}"; + $script['import'][] = "\t\t// Was the package valid?"; + $script['import'][] = "\t\tif (!\$package || !\$package['type'])"; + $script['import'][] = "\t\t{"; + $script['import'][] = "\t\t\tif (in_array(\$this->getType, array('upload', 'url')))"; + $script['import'][] = "\t\t\t{"; + $script['import'][] = "\t\t\t\t\$this->remove(\$package['packagename']);"; + $script['import'][] = "\t\t\t}"; + $script['import'][] = "\n\t\t\t\$app->setUserState('com_[[[-#-#-component]]].message', JTe-#-#-xt::_('COM_[[[-#-#-COMPONENT]]]_IMPORT_UNABLE_TO_FIND_IMPORT_PACKAGE'));"; + $script['import'][] = "\t\t\treturn false;"; + $script['import'][] = "\t\t}"; + $script['import'][] = "\t\t"; + $script['import'][] = "\t\t// first link data to table headers"; + $script['import'][] = "\t\tif(!\$continue){"; + $script['import'][] = "\t\t\t\$package\t= json_encode(\$package);"; + $script['import'][] = "\t\t\t\$session->set('package', \$package);"; + $script['import'][] = "\t\t\t\$session->set('dataType', \$this->dataType);"; + $script['import'][] = "\t\t\t\$session->set('hasPackage', true);"; + $script['import'][] = "\t\t\treturn true;"; + $script['import'][] = "\t\t}"; + $script['import'][] = "\t\t// set the data"; + $script['import'][] = "\t\t\$headerList = json_decode(\$session->get(\$this->dataType.'_VDM_IMPORTHEADERS', false), true);"; + $script['import'][] = "\t\tif (!\$this->setData(\$package,\$this->dataType,\$headerList))"; + $script['import'][] = "\t\t{"; + $script['import'][] = "\t\t\t// There was an error importing the package"; + $script['import'][] = "\t\t\t\$msg = JTe-#-#-xt::_('COM_[[[-#-#-COMPONENT]]]_IMPORT_ERROR');"; + $script['import'][] = "\t\t\t\$back = \$session->get('backto_VDM_IMPORT', NULL);"; + $script['import'][] = "\t\t\tif (\$back)"; + $script['import'][] = "\t\t\t{"; + $script['import'][] = "\t\t\t\t\$app->setUserState('com_[[[-#-#-component]]].redirect_url', 'index.php?option=com_[[[-#-#-component]]]&view='.\$back);"; + $script['import'][] = "\t\t\t\t\$session->clear('backto_VDM_IMPORT');"; + $script['import'][] = "\t\t\t}"; + $script['import'][] = "\t\t\t\$result = false;"; + $script['import'][] = "\t\t}"; + $script['import'][] = "\t\telse"; + $script['import'][] = "\t\t{"; + $script['import'][] = "\t\t\t// Package imported sucessfully"; + $script['import'][] = "\t\t\t\$msg = JTe-#-#-xt::sprintf('COM_[[[-#-#-COMPONENT]]]_IMPORT_SUCCESS', \$package['packagename']);"; + $script['import'][] = "\t\t\t\$back = \$session->get('backto_VDM_IMPORT', NULL);"; + $script['import'][] = "\t\t\tif (\$back)"; + $script['import'][] = "\t\t\t{"; + $script['import'][] = "\t\t\t \$app->setUserState('com_[[[-#-#-component]]].redirect_url', 'index.php?option=com_[[[-#-#-component]]]&view='.\$back);"; + $script['import'][] = "\t\t\t \$session->clear('backto_VDM_IMPORT');"; + $script['import'][] = "\t\t\t}"; + $script['import'][] = "\t\t\t\$result = true;"; + $script['import'][] = "\t\t}"; + $script['import'][] = "\n\t\t// Set some model state values"; + $script['import'][] = "\t\t\$app->enqueueMessage(\$msg);"; + $script['import'][] = "\n\t\t// remove file after import"; + $script['import'][] = "\t\t\$this->remove(\$package['packagename']);"; + $script['import'][] = "\t\t\$session->clear(\$this->getType.'_VDM_IMPORTHEADERS');"; + $script['import'][] = "\t\treturn \$result;"; + $script['import'][] = "\t}"; + } + elseif ('ext' === $type) + { + $script['ext'][] = "\t/**"; + $script['ext'][] = "\t * Check the extension"; + $script['ext'][] = "\t *"; + $script['ext'][] = "\t * @param string \$file Name of the uploaded file"; + $script['ext'][] = "\t *"; + $script['ext'][] = "\t * @return boolean True on success"; + $script['ext'][] = "\t *"; + $script['ext'][] = "\t */"; + $script['ext'][] = "\tprotected function checkExtension(\$file)"; + $script['ext'][] = "\t{"; + $script['ext'][] = "\t\t// check the extention"; + $script['ext'][] = "\t\tswitch(strtolower(pathinfo(\$file, PATHINFO_EXTENSION)))"; + $script['ext'][] = "\t\t{"; + $script['ext'][] = "\t\t\tcase 'xls':"; + $script['ext'][] = "\t\t\tcase 'ods':"; + $script['ext'][] = "\t\t\tcase 'csv':"; + $script['ext'][] = "\t\t\treturn true;"; + $script['ext'][] = "\t\t\tbreak;"; + $script['ext'][] = "\t\t}"; + $script['ext'][] = "\t\treturn false;"; + $script['ext'][] = "\t}"; + } + elseif ('routerparse' === $type) + { + $script['routerparse'][] = "\t\t\t\t// default script in switch for this view"; + $script['routerparse'][] = "\t\t\t\t\$vars['view'] = '[[[-#-#-sview]]]';"; + $script['routerparse'][] = "\t\t\t\tif (is_numeric(\$segments[\$count-1]))"; + $script['routerparse'][] = "\t\t\t\t{"; + $script['routerparse'][] = "\t\t\t\t\t\$vars['id'] = (int) \$segments[\$count-1];"; + $script['routerparse'][] = "\t\t\t\t}"; + $script['routerparse'][] = "\t\t\t\telseif (\$segments[\$count-1])"; + $script['routerparse'][] = "\t\t\t\t{"; + $script['routerparse'][] = "\t\t\t\t\t\$id = \$this->getVar('[[[-#-#-sview]]]', \$segments[\$count-1], 'alias', 'id');"; + $script['routerparse'][] = "\t\t\t\t\tif(\$id)"; + $script['routerparse'][] = "\t\t\t\t\t{"; + $script['routerparse'][] = "\t\t\t\t\t\t\$vars['id'] = \$id;"; + $script['routerparse'][] = "\t\t\t\t\t}"; + $script['routerparse'][] = "\t\t\t\t}"; + } + // return the needed script + if (isset($script[$type])) + { + return str_replace('-#-#-', '', implode("\n",$script[$type])); + } + 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 **/ -- 2.40.1 From 47d1a6c155c0a74b4987fd9ca04afb5933d2433c Mon Sep 17 00:00:00 2001 From: Llewellyn van der Merwe Date: Wed, 25 Apr 2018 00:36:05 +0200 Subject: [PATCH 11/14] Added the feature that allows you to setup the behaviour of a selected set of components that will be auto build and installed. So you do not need to manually compile and install those components any more, the system does all that automatically for you. We have called the feature Expansion Development Method, and it can be set in the global settings of JCB under the Development Method tab. --- README.md | 6 +- admin/README.txt | 6 +- admin/config.xml | 33 +- admin/controllers/compiler.php | 2 +- admin/helpers/compiler.php | 4 +- admin/helpers/compiler/a_Get.php | 6 +- admin/helpers/compiler/b_Structure.php | 4 +- admin/helpers/compiler/e_Interpretation.php | 24 +- admin/helpers/compiler/f_Infusion.php | 2 +- admin/helpers/componentbuilder.php | 601 ++++++++++++++++++ .../en-GB/en-GB.com_componentbuilder.ini | 69 +- admin/models/ajax.php | 15 +- admin/models/compiler.php | 22 +- componentbuilder.xml | 2 +- site/controllers/api.php | 134 ++++ site/helpers/componentbuilder.php | 601 ++++++++++++++++++ .../en-GB/en-GB.com_componentbuilder.ini | 6 + site/models/api.php | 70 +- 18 files changed, 1525 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index 65b2d5ef8..1b002a182 100644 --- a/README.md +++ b/README.md @@ -126,12 +126,12 @@ Component Builder is mapped as a component in itself on my local development env + *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + *Name*: [Component Builder](http://joomlacomponentbuilder.com) + *First Build*: 30th April, 2015 -+ *Last Build*: 23rd April, 2018 ++ *Last Build*: 24th April, 2018 + *Version*: 2.7.6 + *Copyright*: Copyright (C) 2015. All Rights Reserved + *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html -+ *Line count*: **184709** -+ *Field count*: **1025** ++ *Line count*: **193223** ++ *Field count*: **1026** + *File count*: **1201** + *Folder count*: **193** diff --git a/admin/README.txt b/admin/README.txt index 65b2d5ef8..1b002a182 100644 --- a/admin/README.txt +++ b/admin/README.txt @@ -126,12 +126,12 @@ Component Builder is mapped as a component in itself on my local development env + *Author*: [Llewellyn van der Merwe](mailto:llewellyn@joomlacomponentbuilder.com) + *Name*: [Component Builder](http://joomlacomponentbuilder.com) + *First Build*: 30th April, 2015 -+ *Last Build*: 23rd April, 2018 ++ *Last Build*: 24th April, 2018 + *Version*: 2.7.6 + *Copyright*: Copyright (C) 2015. All Rights Reserved + *License*: GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html -+ *Line count*: **184709** -+ *Field count*: **1025** ++ *Line count*: **193223** ++ *Field count*: **1026** + *File count*: **1201** + *Folder count*: **193** diff --git a/admin/config.xml b/admin/config.xml index 8dc88dc04..acedbd074 100644 --- a/admin/config.xml +++ b/admin/config.xml @@ -653,33 +653,24 @@ description="COM_COMPONENTBUILDER_CONFIG_REPOSITORY_DESCRIPTION" class="inputbox" /> - + - - - - - - - + description="COM_COMPONENTBUILDER_CONFIG_PLACEHOLDERS_DESCRIPTION" + class="inputbox" + /> + +
+ name="auto_backup_custom_config" + label="COM_COMPONENTBUILDER_CONFIG_AUTO_BACKUP"> diff --git a/admin/controllers/compiler.php b/admin/controllers/compiler.php index 445d35742..5da805b60 100644 --- a/admin/controllers/compiler.php +++ b/admin/controllers/compiler.php @@ -194,7 +194,7 @@ class ComponentbuilderControllerCompiler extends JControllerAdmin $lang->load($extension, $base_dir, $language_tag, $reload); $message = '('.$fileName.'.zip) file was also removed from tmp!'; $this->setRedirect($redirect_url,$message,'message'); - return $model->install($fileName.'.zip');; + return $model->install($fileName.'.zip'); } } $this->setRedirect($redirect_url,$message,'error'); diff --git a/admin/helpers/compiler.php b/admin/helpers/compiler.php index 6a58752f6..0aa5b18b2 100644 --- a/admin/helpers/compiler.php +++ b/admin/helpers/compiler.php @@ -72,12 +72,12 @@ class Compiler extends Infusion $comConfig = JFactory::getConfig(); $this->tempPath = $comConfig->get('tmp_path'); // set some folder paths in relation to distribution - if ($config['addBackup']) + if ($config['backup']) { $this->backupPath = $this->params->get('backup_folder_path', $this->tempPath) . '/' . $this->componentBackupName . '.zip'; $this->dynamicIntegration = true; } - if ($config['addRepo']) + if ($config['repository']) { $this->repoPath = $this->params->get('git_folder_path', null); } diff --git a/admin/helpers/compiler/a_Get.php b/admin/helpers/compiler/a_Get.php index d11230710..add968cbf 100644 --- a/admin/helpers/compiler/a_Get.php +++ b/admin/helpers/compiler/a_Get.php @@ -668,7 +668,7 @@ class Get // load the compiler path $this->compilerPath = $this->params->get('compiler_folder_path', JPATH_COMPONENT_ADMINISTRATOR . '/compiler'); // set the component ID - $this->componentID = (int) $config['componentId']; + $this->componentID = (int) $config['component']; // set this components code name if ($name_code = ComponentbuilderHelper::getVar('joomla_component', $this->componentID, 'id', 'name_code')) { @@ -678,10 +678,10 @@ class Get $this->componentCodeName = ComponentbuilderHelper::safeString($name_code); // set if placeholders should be added to customcode $global = ((int) ComponentbuilderHelper::getVar('joomla_component', $this->componentID, 'id', 'add_placeholders') == 1) ? true : false; - $this->addPlaceholders = ((int) $config['addPlaceholders'] == 0) ? false : (((int) $config['addPlaceholders'] == 1) ? true : $global); + $this->addPlaceholders = ((int) $config['placeholders'] == 0) ? false : (((int) $config['placeholders'] == 1) ? true : $global); // set if line numbers should be added to comments $global = ((int) ComponentbuilderHelper::getVar('joomla_component', $this->componentID, 'id', 'debug_linenr') == 1) ? true : false; - $this->debugLinenr = ((int) $config['debugLinenr'] == 0) ? false : (((int) $config['debugLinenr'] == 1) ? true : $global); + $this->debugLinenr = ((int) $config['debuglinenr'] == 0) ? false : (((int) $config['debuglinenr'] == 1) ? true : $global); // set the current user $this->user = JFactory::getUser(); // Get a db connection. diff --git a/admin/helpers/compiler/b_Structure.php b/admin/helpers/compiler/b_Structure.php index 5dd4a69ea..acc8df02a 100644 --- a/admin/helpers/compiler/b_Structure.php +++ b/admin/helpers/compiler/b_Structure.php @@ -338,9 +338,9 @@ class Structure extends Get // run global updater ComponentbuilderHelper::runGlobalUpdater(); // set the Joomla version - $this->joomlaVersion = $config['joomlaVersion']; + $this->joomlaVersion = $config['version']; // set the template path - $this->templatePath = $this->compilerPath . '/joomla_' . $config['joomlaVersion']; + $this->templatePath = $this->compilerPath . '/joomla_' . $config['version']; // set some default names $this->componentSalesName = 'com_' . $this->componentData->sales_name . '__J' . $this->joomlaVersion; $this->componentBackupName = 'com_' . $this->componentData->sales_name . '_v' . str_replace('.', '_', $this->componentData->component_version) . '__J' . $this->joomlaVersion; diff --git a/admin/helpers/compiler/e_Interpretation.php b/admin/helpers/compiler/e_Interpretation.php index 4ae4c32a7..0776a654d 100644 --- a/admin/helpers/compiler/e_Interpretation.php +++ b/admin/helpers/compiler/e_Interpretation.php @@ -13048,12 +13048,6 @@ class Interpretation extends Fields $tabCode = ComponentbuilderHelper::safeString($tab) . '_custom_config'; $tabUpper = ComponentbuilderHelper::safeString($tab, 'U'); $tabLower = ComponentbuilderHelper::safeString($tab); - // setup lang - $this->langContent[$this->lang][$lang . '_' . $tabUpper] = $tab; - // start field set - $this->configFieldSets[] = "\tconfigFieldSets[] = "\t\t" . 'name="' . $tabCode . '"'; - $this->configFieldSets[] = "\t\t" . 'label="' . $lang . '_' . $tabUpper . '">'; // remove display targeted fields $bucket = array(); foreach ($tabFields as $tabField) @@ -13065,10 +13059,20 @@ class Interpretation extends Fields $bucket[] = str_replace('display="config"', '', $tabField); } } - // set the fields - $this->configFieldSets[] = implode("", $bucket); - // close field set - $this->configFieldSets[] = "\t
"; + // only add the tab if it has values + if (ComponentbuilderHelper::checkArray($bucket)) + { + // setup lang + $this->langContent[$this->lang][$lang . '_' . $tabUpper] = $tab; + // start field set + $this->configFieldSets[] = "\tconfigFieldSets[] = "\t\t" . 'name="' . $tabCode . '"'; + $this->configFieldSets[] = "\t\t" . 'label="' . $lang . '_' . $tabUpper . '">'; + // set the fields + $this->configFieldSets[] = implode("", $bucket); + // close field set + $this->configFieldSets[] = "\t"; + } // remove after loading unset($this->configFieldSetsCustomField[$tab]); } diff --git a/admin/helpers/compiler/f_Infusion.php b/admin/helpers/compiler/f_Infusion.php index a5bfa1b87..53a43be1a 100644 --- a/admin/helpers/compiler/f_Infusion.php +++ b/admin/helpers/compiler/f_Infusion.php @@ -1175,7 +1175,7 @@ class Infusion extends Interpretation // add to language file $this->writeFile($path . '/' . $fileName, implode(PHP_EOL, $lang)); // set the line counter - $this->lineCount = $this->lineCount + substr_count($lang, PHP_EOL); + $this->lineCount = $this->lineCount + count((array)$lang); // build xml strings if (!isset($langXML[$p])) { diff --git a/admin/helpers/componentbuilder.php b/admin/helpers/componentbuilder.php index fc47d736c..1825d5d0b 100644 --- a/admin/helpers/componentbuilder.php +++ b/admin/helpers/componentbuilder.php @@ -2290,6 +2290,607 @@ abstract class ComponentbuilderHelper } } + /** + * the locker + * + * @var array + **/ + protected static $locker = array(); + + /** + * the dynamic replacement salt + * + * @var array + **/ + protected static $globalSalt = array(); + + /** + * the timer + * + * @var object + **/ + protected static $keytimer; + + /** + * To Lock string + * + * @param string $string The string/array to lock + * @param string $key The custom key to use + * @param int $salt The switch to add salt and type of salt + * @param int $dynamic The dynamic replacement array of salt build string + * @param int $urlencode The switch to control url encoding + **/ + public static function lock($string, $key = null, $salt = 2, $dynamic = null, $urlencode = true) + { + // get the global settings + if (!$key || !self::checkString($key)) + { + // set temp timer + $timer = 2; + // if we have a timer use it + if ($salt > 0) + { + $timer = $salt; + } + if (method_exists(get_called_class(), "getCryptKey")) + { + $key = self::getCryptKey('basic', self::salt($timer, $dynamic)); + } + else + { + $key = self::salt($timer, $dynamic); + } + } + // check if we have a salt timer + if ($salt > 0) + { + $key .= self::salt($salt, $dynamic); + } + // get the locker settings + if (!isset(self::$locker[$key]) || !self::checkObject(self::$locker[$key])) + { + self::$locker[$key] = new FOFEncryptAes($key, 128); + } + // convert array or object to string + if (self::checkArray($string) || self::checkObject($string)) + { + $string = serialize($string); + } + // prep for url + if ($urlencode) + { + return self::base64_urlencode(self::$locker[$key]->encryptString($string)); + } + return self::$locker[$key]->encryptString($string); + } + + /** + * To un-Lock string + * + * @param string $string The string to unlock + * @param string $key The custom key to use + * @param int $salt The switch to add salt and type of salt + * @param int $dynamic The dynamic replacement array of salt build string + * @param int $urlencode The switch to control url decoding + **/ + public static function unlock($string, $key = null, $salt = 2, $dynamic = null, $urlencode = true) + { + // get the global settings + if (!$key || !self::checkString($key)) + { + // set temp timer + $timer = 2; + // if we have a timer use it + if ($salt > 0) + { + $timer = $salt; + } + // get secure key + if (method_exists(get_called_class(), "getCryptKey")) + { + $key = self::getCryptKey('basic', self::salt($timer, $dynamic)); + } + else + { + $key = self::salt($timer, $dynamic); + } + } + // check if we have a salt timer + if ($salt > 0) + { + $key .= self::salt($salt, $dynamic); + } + // get the locker settings + if (!isset(self::$locker[$key]) || !self::checkObject(self::$locker[$key])) + { + self::$locker[$key] = new FOFEncryptAes($key, 128); + } + // make sure we have real base64 + if ($urlencode) + { + $string = self::base64_urldecode($string); + } + // basic decrypt string. + if (!empty($string) && !is_numeric($string) && $string === base64_encode(base64_decode($string, true))) + { + $string = rtrim(self::$locker[$key]->decryptString($string), "\0"); + // convert serial string to array + if (self::is_serial($string)) + { + $string = unserialize($string); + } + } + return $string; + } + + /** + * The Salt + * + * @param int $type The type of length the salt should be valid + * @param int $dynamic The dynamic replacement array of salt build string + **/ + public static function salt($type = 1, $dynamic = null) + { + // get dynamic replacement salt + $dynamic = self::getDynamicSalt($dynamic); + // get the key timer + if (!self::checkObject(self::$keytimer)) + { + // load the date time object + self::$keytimer = new DateTime; + // set the correct time stamp + $vdmLocalTime = new DateTimeZone('Africa/Windhoek'); + self::$keytimer->setTimezone($vdmLocalTime); + } + // set type + if ($type == 2) + { + // hour + $format = 'Y-m-d \o\n ' . self::periodFix(self::$keytimer->format('H')); + } + elseif ($type == 3) + { + // day + $format = 'Y-m-' . self::periodFix(self::$keytimer->format('d')); + } + elseif ($type == 4) + { + // month + $format = 'Y-' . self::periodFix(self::$keytimer->format('m')); + } + else + { + // minute + $format = 'Y-m-d \o\n H:' . self::periodFix(self::$keytimer->format('i')); + } + // get key + if (self::checkArray($dynamic)) + { + return md5(str_replace(array_keys($dynamic), array_values($dynamic), self::$keytimer->format($format) . ' @ VDM.I0')); + } + return md5(self::$keytimer->format($format) . ' @ VDM.I0'); + } + + /** + * The function to insure the salt is valid within the given period (third try) + * + * @param int $main The main number + */ + protected static function periodFix($main) + { + return round($main / 3) * 3; + } + + /** + * Check if a string is serialized + * @param string $string + */ + public static function is_serial($string) + { + return (@unserialize($string) !== false); + } + + /** + * Get dynamic replacement salt + */ + public static function getDynamicSalt($dynamic = null) + { + // load global if not manually set + if (!self::checkArray($dynamic)) + { + return self::getGlobalSalt(); + } + // return manual values if set + else + { + return $dynamic; + } + } + + /** + * The random or dynamic secret salt + */ + public static function getSecretSalt($string = null, $size = 9) + { + // set the string + if (!$string) + { + // get random string + $string = self::randomkey($size); + } + // convert string to array + $string = self::safeString($string); + // convert string to array + $array = str_split($string); + // insure only unique values are used + $array = array_unique($array); + // set the size + $size = ($size <= count($array)) ? $size : count($array); + // down size the + return array_slice($array, 0, $size); + } + + /** + * Get global replacement salt + */ + public static function getGlobalSalt() + { + // load from memory if found + if (!self::checkArray(self::$globalSalt)) + { + // get the global settings + if (!self::checkObject(self::$params)) + { + self::$params = JComponentHelper::getParams('com_componentbuilder'); + } + // check if we have a global dynamic replacement array available (format --> ' 1->!,3->E,4->A') + $tmp = self::$params->get('dynamic_salt', null); + if (self::checkString($tmp) && strpos($tmp, ',') !== false && strpos($tmp, '->') !== false) + { + $salt = array_map('trim', (array) explode(',', $tmp)); + if (self::checkArray($salt )) + { + foreach($salt as $replace) + { + $dynamic = array_map('trim', (array) explode('->', $replace)); + if (isset($dynamic[0]) && isset($dynamic[1])) + { + self::$globalSalt[$dynamic[0]] = $dynamic[1]; + } + } + } + } + } + // return global if found + if (self::checkArray(self::$globalSalt)) + { + return self::$globalSalt; + } + // return default as fail safe + return array('1' => '!', '3' => 'E', '4' => 'A'); + } + + /** + * Close public protocol + */ + public static function closePublicProtocol($id, $public) + { + // get secret salt + $secretSalt = self::getSecretSalt(self::salt(1,array('4' => 'R','1' => 'E','2' => 'G','7' => 'J','8' => 'A'))); + // get the key + $key = self::salt(1, $secretSalt); + // get secret salt + $secret = self::getSecretSalt(); + // set the secret + $close['SECRET'] = self::lock($secret, $key, 1, array('1' => 's', '3' => 'R', '4' => 'D')); + // get the key + $key = self::salt(1, $secret); + // get the public key + $close['PUBLIC'] = self::lock($public, $key, 1, array('1' => '!', '3' => 'E', '4' => 'A')); + // get secret salt + $secretSalt = self::getSecretSalt($public); + // get the key + $key = self::salt(1, $secretSalt); + // get the ID + $close['ID'] = self::unlock($id, $key, 1, array('1' => 'i', '3' => 'e', '4' => 'B')); + // return closed values + return $close; + } + + /** + * Open public protocol + */ + public static function openPublicProtocol($SECRET, $ID, $PUBLIC) + { + // get secret salt + $secretSalt = self::getSecretSalt(self::salt(1,array('4' => 'R','1' => 'E','2' => 'G','7' => 'J','8' => 'A'))); + // get the key + $key = self::salt(1, $secretSalt); + // get the $SECRET + $SECRET = self::unlock($SECRET, $key, 1, array('1' => 's', '3' => 'R', '4' => 'D')); + // get the key + $key = self::salt(1, $SECRET); + // get the public key + $open['public'] = self::unlock($PUBLIC, $key, 1, array('1' => '!', '3' => 'E', '4' => 'A')); + // get secret salt + $secretSalt = self::getSecretSalt($open['public']); + // get the key + $key = self::salt(1, $secretSalt); + // get the ID + $open['id'] = self::unlock($ID, $key, 1, array('1' => 'i', '3' => 'e', '4' => 'B')); + // return opened values + return $open; + } + + /** + * Workers to load tasks + * + * @var array + */ + protected static $worker = array(); + + /** + * Set a worker dynamic URLs + * + * @var array + */ + protected static $workerURL = array(); + + /** + * Set a worker dynamic HEADERs + * + * @var array + */ + protected static $workerHEADER = array(); + + /** + * Curl Error Notice + * + * @var bool + */ + protected static $curlErrorLoaded = false; + + /** + * Set a worker url + * + * @param string $function The function to target to perform the task + * @param string $url The url of where the task is to be performed + * + * @return void + * + */ + public static function setWorkerUrl(&$function, &$url) + { + // set the URL if found + if (self::checkString($url)) + { + // make sure task function url is up + self::$workerURL[$function] = $url; + } + } + + /** + * Set a worker headers + * + * @param string $function The function to target to perform the task + * @param array $headers The headers needed for these workers/function + * + * @return void + * + */ + public static function setWorkerHeaders(&$function, &$headers) + { + // set the Headers if found + if (self::checkArray($headers)) + { + // make sure task function headers are set + self::$workerHEADER[$function] = $headers; + } + } + + /** + * Set a worker that needs to perform a task + * + * @param mixed $data The data to pass to the task + * @param string $function The function to target to perform the task + * @param string $url The url of where the task is to be performed + * @param array $headers The headers needed for these workers/function + * + * @return void + * + */ + public static function setWorker($data, $function, $url = null, $headers = null) + { + // make sure task function is up + if (!isset(self::$worker[$function])) + { + self::$worker[$function] = array(); + } + // load the task + self::$worker[$function][] = self::lock($data); + // set the Headers if found + if ($headers && !isset(self::$workerHEADER[$function])) + { + self::setWorkerHeaders($function, $headers); + } + // set the URL if found + if ($url && !isset(self::$workerURL[$function])) + { + self::setWorkerUrl($function, $url); + } + } + + /** + * Run set Workers + * + * @param string $function The function to target to perform the task + * @param string $perTask The amount of task per worker + * @param function $callback The option to do a call back when task is completed + * @param int $threadSize The size of the thread + * + * @return bool true On success + * + */ + public static function runWorker($function, $perTask = 50, $callback = null, $threadSize = 20) + { + // set task + $task = self::lock($function); + // build headers + $headers = array('VDM-TASK: ' .$task); + // build dynamic headers + if (isset(self::$workerHEADER[$function]) && self::checkArray(self::$workerHEADER[$function])) + { + foreach (self::$workerHEADER[$function] as $header) + { + $headers[] = $header; + } + } + // build worker options + $options = array(); + // make sure worker is up + if (isset(self::$worker[$function]) && self::checkArray(self::$worker[$function])) + { + // this load method is for each + if (1 == $perTask) + { + // working with a string = 1 + $headers[] = 'VDM-VALUE-TYPE: ' .self::lock(1); + // now load the options + foreach (self::$worker[$function] as $data) + { + $options[] = array(CURLOPT_HTTPHEADER => $headers, CURLOPT_POST => 1, CURLOPT_POSTFIELDS => 'VDM_DATA='. $data); + } + } + // this load method is for bundles + else + { + // working with an array = 2 + $headers[] = 'VDM-VALUE-TYPE: ' .self::lock(2); + // now load the options + $work = array_chunk(self::$worker[$function], $perTask); + foreach ($work as $data) + { + $options[] = array(CURLOPT_HTTPHEADER => $headers, CURLOPT_POST => 1, CURLOPT_POSTFIELDS => 'VDM_DATA='. implode('___VDM___', $data)); + } + } + // relieve worker of task/function + self::$worker[$function] = array(); + } + // do the execution + if (self::checkArray($options)) + { + if (isset(self::$workerURL[$function])) + { + $url = self::$workerURL[$function]; + } + else + { + $url = JURI::root() . '/index.php?option=com_componentbuilder&task=api.worker'; + } + return self::curlMultiExec($url, $options, $callback, $threadSize); + } + return false; + } + + /** + * Do a multi curl execution of tasks + * + * @param string $url The url of where the task is to be performed + * @param array $_options The array of curl options/headers to set + * @param function $callback The option to do a call back when task is completed + * @param int $threadSize The size of the thread + * + * @return bool true On success + * + */ + public static function curlMultiExec(&$url, &$_options, $callback = null, $threadSize = 20) + { + // make sure we have curl available + if (!function_exists('curl_version')) + { + if (!self::$curlErrorLoaded) + { + // set the notice + JFactory::getApplication()->enqueueMessage(JText::_('COM_COMPONENTBUILDER_HTWOCURL_NOT_FOUNDHTWOPPLEASE_SETUP_CURL_ON_YOUR_SYSTEM_OR_BCOMPONENTBUILDERB_WILL_NOT_FUNCTION_CORRECTLYP'), 'Error'); + // load the notice only once + self::$curlErrorLoaded = true; + } + return false; + } + // make sure we have an url + if (self::checkString($url)) + { + // make sure the thread size isn't greater than the # of _options + $threadSize = (count($_options) < $threadSize) ? count($_options) : $threadSize; + // set the options + $options = array(); + $options[CURLOPT_URL] = $url; + $options[CURLOPT_USERAGENT] = 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'; + $options[CURLOPT_RETURNTRANSFER] = TRUE; + $options[CURLOPT_SSL_VERIFYPEER] = FALSE; + // start multi threading :) + $handle = curl_multi_init(); + // start the first batch of requests + for ($i = 0; $i < $threadSize; $i++) + { + if (isset($_options[$i])) + { + $ch = curl_init(); + foreach ($_options[$i] as $curlopt => $string) + { + $options[$curlopt] = $string; + } + curl_setopt_array($ch, $options); + curl_multi_add_handle($handle, $ch); + } + } + // we wait for all the calls to finish (should not take long) + do { + while(($execrun = curl_multi_exec($handle, $working)) == CURLM_CALL_MULTI_PERFORM); + if($execrun != CURLM_OK) + break; + // a request was just completed -- find out which one + while($done = curl_multi_info_read($handle)) + { + if (is_callable($callback)) + { + // $info = curl_getinfo($done['handle']); + // request successful. process output using the callback function. + $output = curl_multi_getcontent($done['handle']); + $callback($output); + } + $key = $i + 1; + if(isset($_options[$key])) + { + // start a new request (it's important to do this before removing the old one) + $ch = curl_init(); $i++; + // add options + foreach ($_options[$key] as $curlopt => $string) + { + $options[$curlopt] = $string; + } + curl_setopt_array($ch, $options); + curl_multi_add_handle($handle, $ch); + // remove options again + foreach ($_options[$key] as $curlopt => $string) + { + unset($options[$curlopt]); + } + } + // remove the curl handle that just completed + curl_multi_remove_handle($handle, $done['handle']); + } + // stop wasting CPU cycles and rest for a couple ms + usleep(10000); + } while ($working); + // close the curl multi thread + curl_multi_close($handle); + // okay done + return true; + } + return false; + } + /** * Move File to Server * diff --git a/admin/language/en-GB/en-GB.com_componentbuilder.ini b/admin/language/en-GB/en-GB.com_componentbuilder.ini index a103fa9c2..d0c324446 100644 --- a/admin/language/en-GB/en-GB.com_componentbuilder.ini +++ b/admin/language/en-GB/en-GB.com_componentbuilder.ini @@ -2041,12 +2041,12 @@ COM_COMPONENTBUILDER_COMPONENT_FILES_FOLDERS_NOTE_CONSTANT_PATHS_DESCRIPTION="

JPATH_BASE
// The path to the cache folder.
JPATH_CACHE
-// The path to the administration folder of the current component being executed.
-JPATH_COMPONENT_ADMINISTRATOR
-// The path to the site folder of the current component being executed.
-JPATH_COMPONENT_SITE
-// The path to the current component being executed.
-JPATH_COMPONENT
+// The path to the administration folder of JCB component.
+JPATH_COMPONENT_ADMINISTRATOR no ideal to use
+// The path to the site folder of JCB component.
+JPATH_COMPONENT_SITE no ideal to use
+// The path to the JCB component.
+JPATH_COMPONENT no ideal to use
// The path to folder containing the configuration.php file.
JPATH_CONFIGURATION
// The path to the installation folder.
@@ -2218,6 +2218,7 @@ COM_COMPONENTBUILDER_CONFIG_AUTHOR_EMAIL_DESC="The email address of the author o COM_COMPONENTBUILDER_CONFIG_AUTHOR_EMAIL_LABEL="Author Email" COM_COMPONENTBUILDER_CONFIG_AUTHOR_NAME_DESC="The name of the author of this component." COM_COMPONENTBUILDER_CONFIG_AUTHOR_NAME_LABEL="Author Name" +COM_COMPONENTBUILDER_CONFIG_AUTO_BACKUP="Auto Backup" COM_COMPONENTBUILDER_CONFIG_AUTO_LOAD="Auto" COM_COMPONENTBUILDER_CONFIG_BACKUPCRONJOB_NOTE_DESCRIPTION="You can run a cronjob that will backup all your components as they are mapped in JCB.

USE THE FOLLOWING: loading...

Please note that if your Joomla website has a Firewall installed, it will not allow cronjob via direct URL (most of the time), you will then need to adapt the cornjob request to look like a browser. For more info please read https://stackoverflow.com/a/31597823/1429677 " COM_COMPONENTBUILDER_CONFIG_BACKUPCRONJOB_NOTE_LABEL="Backup JCB Mapped Components" @@ -2307,7 +2308,6 @@ COM_COMPONENTBUILDER_CONFIG_COMPILER_FOLDER_PATH_LABEL="Compiler Folder Path" COM_COMPONENTBUILDER_CONFIG_COMPILER_FOLDER_PATH_MESSAGE="Error! Please add some text here." COM_COMPONENTBUILDER_CONFIG_COMPONENT="Component" COM_COMPONENTBUILDER_CONFIG_COMPONENT_LABEL="Component" -COM_COMPONENTBUILDER_CONFIG_CRONJOB="CronJob" COM_COMPONENTBUILDER_CONFIG_CRONJOB_BACKUP_FOLDER_PATH_DESCRIPTION="Here you can set the path to where all components are backed up to." COM_COMPONENTBUILDER_CONFIG_CRONJOB_BACKUP_FOLDER_PATH_HINT="/home/user/fullbackup" COM_COMPONENTBUILDER_CONFIG_CRONJOB_BACKUP_FOLDER_PATH_LABEL="Cronjob Backup Folder Path" @@ -2357,7 +2357,6 @@ COM_COMPONENTBUILDER_CONFIG_EMAILREPLY_HINT="Email Address Here" COM_COMPONENTBUILDER_CONFIG_EMAILREPLY_LABEL=" Reply to Email" COM_COMPONENTBUILDER_CONFIG_ENCRYPTION_DESC="The encryption key for the field encryption is set here." COM_COMPONENTBUILDER_CONFIG_ENCRYPTION_LABEL="Encryption Settings" -COM_COMPONENTBUILDER_CONFIG_EVENT_LABEL="Trigger Event" COM_COMPONENTBUILDER_CONFIG_EVERY_DAY="Every Day" COM_COMPONENTBUILDER_CONFIG_EVERY_FIFTEEN_MINUTES="Every 15 Minutes" COM_COMPONENTBUILDER_CONFIG_EVERY_FIVE_HOURS="Every 5 Hours" @@ -2370,6 +2369,35 @@ COM_COMPONENTBUILDER_CONFIG_EVERY_THIRTY_MINUTES="Every 30 Minutes" COM_COMPONENTBUILDER_CONFIG_EVERY_THIRTY_SECONDS="Every 30 Seconds" COM_COMPONENTBUILDER_CONFIG_EVERY_WEEK="Every Week" COM_COMPONENTBUILDER_CONFIG_EXPANSION="Expansion" +COM_COMPONENTBUILDER_CONFIG_EXPANSIONCRONJOB_NOTE_DESCRIPTION="You must run a cronjob that will trigger the expansion events for JCB.

USE THE FOLLOWING: loading...

Please note that if your Joomla website has a Firewall installed, it will not allow cronjob via direct URL (most of the time), you will then need to adapt the cornjob request to look like a browser. For more info please read https://stackoverflow.com/a/31597823/1429677 +" +COM_COMPONENTBUILDER_CONFIG_EXPANSIONCRONJOB_NOTE_LABEL="Expansion Cronjob" COM_COMPONENTBUILDER_CONFIG_EXPANSION_DESCRIPTION="Properties for this field" COM_COMPONENTBUILDER_CONFIG_EXPANSION_LABEL="Expansion" COM_COMPONENTBUILDER_CONFIG_EXPORT_BUY_LINK_DESCRIPTION="Enter link where your JCB package key can be bought." @@ -2433,7 +2461,7 @@ COM_COMPONENTBUILDER_CONFIG_NOTE_CUSTOM_FOLDER_PATH_DESCRIPTION="The custom fold COM_COMPONENTBUILDER_CONFIG_NOTE_CUSTOM_FOLDER_PATH_LABEL="Moving The Custom Folder" COM_COMPONENTBUILDER_CONFIG_NOTE_DEVELOPMENT_METHOD_DEFAULT_DESCRIPTION="

This method is basically the way JCB has always worked by default.

You have a compiler area, once you have made changes you go to the compiler view and compile your component. Then you have the option to install and/or distribute the Joomla install package.

This can also be called the manual development method.

" COM_COMPONENTBUILDER_CONFIG_NOTE_DEVELOPMENT_METHOD_DEFAULT_LABEL="Default Development Method" -COM_COMPONENTBUILDER_CONFIG_NOTE_DEVELOPMENT_METHOD_EXPANSION_DESCRIPTION="

This method adds auto expansion to the current Joomla automatically.

Below you setup events that trigger auto build and install of a selected set of components. So you do not need to manually compile and install those components any more, the system does all that automatically for you.

So your experience is that you change the field, view or something else in JCB and then the component in Joomla moments later, based on your events and the size of your component, reflect those changed automatically.

This can also be called the automatic development method.

" +COM_COMPONENTBUILDER_CONFIG_NOTE_DEVELOPMENT_METHOD_EXPANSION_DESCRIPTION="

This method adds auto expansion to the current Joomla automatically.

Below you setup the behaviour of a selected set of components that will be auto build and installed. So you do not need to manually compile and install those components any more, the system does all that automatically for you.

So your experience is that you change the field, view or something else in JCB and then the component in Joomla moments later reflect those changed automatically. The latency of the workflow is based on your cronjob frequency and the size of your component. You can pause the build in a few ways, one by actually checking out/opening the Joomla Component view of the component in JCB, or changing the state to unpublish, archive or trashed, or simply remove if from the list below.

This can also be called the automatic development method.

" COM_COMPONENTBUILDER_CONFIG_NOTE_DEVELOPMENT_METHOD_EXPANSION_LABEL="Expansion Development Method" COM_COMPONENTBUILDER_CONFIG_NOTE_DKIM_USE_DESCRIPTION="

Using the below details, you need to configure your DNS by adding a TXT record on your domain: