diff --git a/README.md b/README.md index b84e913f0..1a69e03c2 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) @@ -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*: 14th April, 2018 -+ *Version*: 2.7.5 ++ *Last Build*: 30th 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*: **182312** -+ *Field count*: **1012** -+ *File count*: **1199** ++ *Line count*: **193305** ++ *Field count*: **1027** ++ *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 b84e913f0..1a69e03c2 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) @@ -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*: 14th April, 2018 -+ *Version*: 2.7.5 ++ *Last Build*: 30th 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*: **182312** -+ *Field count*: **1012** -+ *File count*: **1199** ++ *Line count*: **193305** ++ *Field count*: **1027** ++ *File count*: **1201** + *Folder count*: **193** > This **component** was build with a Joomla [Automated Component Builder](http://joomlacomponentbuilder.com). diff --git a/admin/access.xml b/admin/access.xml index 1e03fea0e..eea0f6756 100644 --- a/admin/access.xml +++ b/admin/access.xml @@ -232,8 +232,9 @@ - - + + + @@ -247,6 +248,7 @@ + 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/config.xml b/admin/config.xml index 0f2763316..890b879d7 100644 --- a/admin/config.xml +++ b/admin/config.xml @@ -61,6 +61,21 @@ + + + + + + - - + + COM_COMPONENTBUILDER_CONFIG_SIMPLEXMLELEMENT_CLASS - - + + COM_COMPONENTBUILDER_CONFIG_NEVER_UPDATE - - + +
+ name="development_method_custom_config" + label="COM_COMPONENTBUILDER_CONFIG_DEVELOPMENT_METHOD"> + + + + + + + + + + + + + +
+
diff --git a/admin/controllers/compiler.php b/admin/controllers/compiler.php index 784b28daf..5da805b60 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); @@ -193,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/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/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/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 d240acccf..8b08bdfa6 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 @@ -607,6 +614,13 @@ class Get */ public $libraries = array(); + /** + * Is minify Enabled + * + * @var int + */ + public $minify = 0; + /** * Is Tidy Enabled * @@ -631,10 +645,16 @@ 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); + // 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 $this->fieldBuilderType = $this->params->get('compiler_field_builder_type', 2); // check the field builder type logic @@ -648,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')) { @@ -658,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. @@ -952,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)); } @@ -1436,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 @@ -2095,7 +2116,7 @@ class Get // Create a new query object. $query = $this->db->getQuery(true); - // Order it by the ordering field. + // Select all the values in the field $query->select('a.*'); $query->select($this->db->quoteName(array('c.name', 'c.properties'), array('type_name', 'properties'))); $query->from('#__componentbuilder_field AS a'); @@ -2263,16 +2284,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) { @@ -4507,8 +4528,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)) . ')'); @@ -4516,7 +4537,7 @@ class Get $this->db->execute(); if ($this->db->getNumRows()) { - return $this->db->loadAssocList('entranslation'); + return $this->db->loadAssocList('source'); } } return false; @@ -4534,7 +4555,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) { @@ -4621,7 +4642,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' @@ -4659,7 +4680,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)); @@ -4754,7 +4775,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)) . ')'); @@ -5386,7 +5407,7 @@ class Get } /** - * search for the system id in the line given + * set the start replace placeholder * * @param int $id The comment id * @param int $commentType The comment type @@ -5417,6 +5438,7 @@ class Get * * @param string $lineContent The file path to search * @param string $placeholders The values to search for + * @param int $commentType The comment type * * @return array on success * @@ -5442,7 +5464,7 @@ class Get } /** - * Reverse Engineer the dynamic placeholders (hmmmm) + * Reverse Engineer the dynamic placeholders (TODO hmmmm this is not ideal) * * @param string $string The string to revers * @param int $id The custom code id @@ -5475,13 +5497,13 @@ class Get // get targets to search for $langStringTargets = array_filter( $this->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)) { @@ -5598,7 +5620,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/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/c_Fields.php b/admin/helpers/compiler/c_Fields.php index 3e944137f..f0eb83aac 100644 --- a/admin/helpers/compiler/c_Fields.php +++ b/admin/helpers/compiler/c_Fields.php @@ -2013,7 +2013,18 @@ class Fields extends Structure // set the decoding methods if (in_array($set, $decode)) { - $this->siteFieldData['decode'][$array['site']][$code][$array['as']][$array['key']] = array('decode' => $set, 'type' => $type); + if (isset($this->siteFieldData['decode'][$array['site']][$code][$array['as']][$array['key']]) && + isset($this->siteFieldData['decode'][$array['site']][$code][$array['as']][$array['key']]['decode'])) + { + if (!in_array($set, $this->siteFieldData['decode'][$array['site']][$code][$array['as']][$array['key']]['decode'])) + { + $this->siteFieldData['decode'][$array['site']][$code][$array['as']][$array['key']]['decode'][] = $set; + } + } + else + { + $this->siteFieldData['decode'][$array['site']][$code][$array['as']][$array['key']] = array('decode' => array($set), 'type' => $type); + } } // set the uikit checker if ((2 == $this->uikit || 1 == $this->uikit) && in_array($type, $textareas)) @@ -2355,7 +2366,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 +2485,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])) { @@ -2556,6 +2567,7 @@ class Fields extends Structure // setup checkboxes and other json items for this view if ($dbSwitch && (($typeName === 'subform' || $typeName === 'checkboxes' || $multiple || $field['settings']->store != 0) && $typeName != 'tag')) { + $subformJsonSwitch = true; switch ($field['settings']->store) { case 1: @@ -2593,6 +2605,8 @@ class Fields extends Structure $this->jsonItemBuilder[$view_name_single][] = $name; // Site settings of each field if needed $this->buildSiteFieldData($view_name_single, $name, 'json', $typeName); + // no londer add the json again (already added) + $subformJsonSwitch = false; break; } // just a heads-up for usergroups set to multiple @@ -2614,10 +2628,19 @@ class Fields extends Structure } } - // if subform the values must revert to array + // subform house keeping if ('subform' === $typeName) { + // the values must revert to array $this->jsonItemBuilderArray[$view_name_single][] = $name; + // should the json builder still be added + if ($subformJsonSwitch) + { + // and insure the if is converted to json + $this->jsonItemBuilder[$view_name_single][] = $name; + // Site settings of each field if needed + $this->buildSiteFieldData($view_name_single, $name, 'json', $typeName); + } } } // build the data for the export & import methods $typeName === 'repeatable' || diff --git a/admin/helpers/compiler/e_Interpretation.php b/admin/helpers/compiler/e_Interpretation.php index 94bdc993b..90dfc205b 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"; @@ -1686,37 +1686,43 @@ class Interpretation extends Fields $fieldDecode = ''; foreach ($checker as $field => $array) { - if (strpos($get['selection']['select'], $field) !== false) + if (strpos($get['selection']['select'], $field) !== false && ComponentbuilderHelper::checkArray($array['decode'])) { - if ('json' === $array['decode']) + // insure it is unique + $array['decode'] = (array) array_unique(array_reverse((array) $array['decode'])); + // now loop the array + foreach ($array['decode'] as $decode) { - $if = PHP_EOL . "\t" . $tab . "\tif (" . $this->fileContentStatic['###Component###'] . "Helper::checkJson(" . $string . "->" . $field . "))" . PHP_EOL . "\t" . $tab . "\t{"; - // json_decode - $decoder = $string . "->" . $field . " = json_decode(" . $string . "->" . $field . ", true);"; - } - elseif ('base64' === $array['decode']) - { - $if = PHP_EOL . "\t" . $tab . "\tif (!empty(" . $string . "->" . $field . ") && " . $string . "->" . $field . " === base64_encode(base64_decode(" . $string . "->" . $field . ")))" . PHP_EOL . "\t" . $tab . "\t{"; - // base64_decode - $decoder = $string . "->" . $field . " = base64_decode(" . $string . "->" . $field . ");"; - } - elseif (strpos($array['decode'], '_encryption') !== false) - { - foreach ($this->cryptionTypes as $cryptionType) + if ('json' === $decode) { - if ($cryptionType . '_encryption' === $array['decode']) + $if = PHP_EOL . "\t" . $tab . "\tif (" . $this->fileContentStatic['###Component###'] . "Helper::checkJson(" . $string . "->" . $field . "))" . PHP_EOL . "\t" . $tab . "\t{"; + // json_decode + $decoder = $string . "->" . $field . " = json_decode(" . $string . "->" . $field . ", true);"; + } + elseif ('base64' === $decode) + { + $if = PHP_EOL . "\t" . $tab . "\tif (!empty(" . $string . "->" . $field . ") && " . $string . "->" . $field . " === base64_encode(base64_decode(" . $string . "->" . $field . ")))" . PHP_EOL . "\t" . $tab . "\t{"; + // base64_decode + $decoder = $string . "->" . $field . " = base64_decode(" . $string . "->" . $field . ");"; + } + elseif (strpos($decode, '_encryption') !== false) + { + foreach ($this->cryptionTypes as $cryptionType) { - $if = PHP_EOL . "\t" . $tab . "\tif (!empty(" . $string . "->" . $field . ") && \$" . $cryptionType . "key && !is_numeric(" . $string . "->" . $field . ") && " . $string . "->" . $field . " === base64_encode(base64_decode(" . $string . "->" . $field . ", true)))" . PHP_EOL . "\t" . $tab . "\t{"; - // set decryption - $decoder = $string . "->" . $field . " = rtrim(\$" . $cryptionType . "->decryptString(" . $string . "->" . $field . "), " . '"\0"' . ");"; - $this->siteDecrypt[$cryptionType][$code] = true; + if ($cryptionType . '_encryption' === $decode) + { + $if = PHP_EOL . "\t" . $tab . "\tif (!empty(" . $string . "->" . $field . ") && \$" . $cryptionType . "key && !is_numeric(" . $string . "->" . $field . ") && " . $string . "->" . $field . " === base64_encode(base64_decode(" . $string . "->" . $field . ", true)))" . PHP_EOL . "\t" . $tab . "\t{"; + // set decryption + $decoder = $string . "->" . $field . " = rtrim(\$" . $cryptionType . "->decryptString(" . $string . "->" . $field . "), " . '"\0"' . ");"; + $this->siteDecrypt[$cryptionType][$code] = true; + } } } - } - // build decoder string - $fieldDecode .= $if . PHP_EOL . "\t" . $tab . "\t\t//" . $this->setLine(__LINE__) . " Decode " . $field; - $fieldDecode .= PHP_EOL . "\t" . $tab . "\t\t" . $decoder . PHP_EOL . "\t" . $tab . "\t}"; + // build decoder string + $fieldDecode .= $if . PHP_EOL . "\t" . $tab . "\t\t//" . $this->setLine(__LINE__) . " Decode " . $field; + $fieldDecode .= PHP_EOL . "\t" . $tab . "\t\t" . $decoder . PHP_EOL . "\t" . $tab . "\t}"; + } } } return $fieldDecode; @@ -2821,10 +2827,25 @@ class Interpretation extends Fields return $method; } + /** + * 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 $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 + * + */ 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 @@ -2832,6 +2853,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) @@ -3087,6 +3109,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'); @@ -3132,6 +3165,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) @@ -3297,12 +3333,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) { @@ -3320,10 +3357,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) { @@ -4219,6 +4252,39 @@ class Interpretation extends Fields public function setMethodGetItem(&$view) { $script = ''; + // get the component name + $Component = $this->fileContentStatic['###Component###']; + // go from base64 to string + if (isset($this->base64Builder[$view]) && ComponentbuilderHelper::checkArray($this->base64Builder[$view])) + { + foreach ($this->base64Builder[$view] as $baseString) + { + $script .= PHP_EOL . PHP_EOL . "\t\t\tif (!empty(\$item->" . $baseString . "))"; // TODO && base64_encode(base64_decode(\$item->".$baseString.", true)) === \$item->".$baseString.")"; + $script .= PHP_EOL . "\t\t\t{"; + $script .= PHP_EOL . "\t\t\t\t//" . $this->setLine(__LINE__) . " base64 Decode " . $baseString . "."; + $script .= PHP_EOL . "\t\t\t\t\$item->" . $baseString . " = base64_decode(\$item->" . $baseString . ");"; + $script .= PHP_EOL . "\t\t\t}"; + } + } + // decryption + foreach ($this->cryptionTypes as $cryptionType) + { + if (isset($this->{$cryptionType . 'EncryptionBuilder'}[$view]) && ComponentbuilderHelper::checkArray($this->{$cryptionType . 'EncryptionBuilder'}[$view])) + { + $script .= PHP_EOL . PHP_EOL . "\t\t\t//" . $this->setLine(__LINE__) . " Get the " . $cryptionType . " encryption."; + $script .= PHP_EOL . "\t\t\t\$" . $cryptionType . "key = " . $Component . "Helper::getCryptKey('" . $cryptionType . "');"; + $script .= PHP_EOL . "\t\t\t//" . $this->setLine(__LINE__) . " Get the encryption object."; + $script .= PHP_EOL . "\t\t\t\$" . $cryptionType . " = new FOFEncryptAes(\$" . $cryptionType . "key);"; + foreach ($this->{$cryptionType . 'EncryptionBuilder'}[$view] as $baseString) + { + $script .= PHP_EOL . PHP_EOL . "\t\t\tif (!empty(\$item->" . $baseString . ") && \$" . $cryptionType . "key && !is_numeric(\$item->" . $baseString . ") && \$item->" . $baseString . " === base64_encode(base64_decode(\$item->" . $baseString . ", true)))"; + $script .= PHP_EOL . "\t\t\t{"; + $script .= PHP_EOL . "\t\t\t\t//" . $this->setLine(__LINE__) . " " . $cryptionType . " decrypt data " . $baseString . "."; + $script .= PHP_EOL . "\t\t\t\t\$item->" . $baseString . " = rtrim(\$" . $cryptionType . "->decryptString(\$item->" . $baseString . "), " . '"\0"' . ");"; + $script .= PHP_EOL . "\t\t\t}"; + } + } + } // go from json to array if (isset($this->jsonItemBuilder[$view]) && ComponentbuilderHelper::checkArray($this->jsonItemBuilder[$view])) { @@ -4254,39 +4320,6 @@ class Interpretation extends Fields $script .= PHP_EOL . "\t\t\t}"; } } - // go from base64 to string - if (isset($this->base64Builder[$view]) && ComponentbuilderHelper::checkArray($this->base64Builder[$view])) - { - foreach ($this->base64Builder[$view] as $baseString) - { - $script .= PHP_EOL . PHP_EOL . "\t\t\tif (!empty(\$item->" . $baseString . "))"; // TODO && base64_encode(base64_decode(\$item->".$baseString.", true)) === \$item->".$baseString.")"; - $script .= PHP_EOL . "\t\t\t{"; - $script .= PHP_EOL . "\t\t\t\t//" . $this->setLine(__LINE__) . " base64 Decode " . $baseString . "."; - $script .= PHP_EOL . "\t\t\t\t\$item->" . $baseString . " = base64_decode(\$item->" . $baseString . ");"; - $script .= PHP_EOL . "\t\t\t}"; - } - } - // get the component name - $Component = $this->fileContentStatic['###Component###']; - // decryption - foreach ($this->cryptionTypes as $cryptionType) - { - if (isset($this->{$cryptionType . 'EncryptionBuilder'}[$view]) && ComponentbuilderHelper::checkArray($this->{$cryptionType . 'EncryptionBuilder'}[$view])) - { - $script .= PHP_EOL . PHP_EOL . "\t\t\t//" . $this->setLine(__LINE__) . " Get the " . $cryptionType . " encryption."; - $script .= PHP_EOL . "\t\t\t\$" . $cryptionType . "key = " . $Component . "Helper::getCryptKey('" . $cryptionType . "');"; - $script .= PHP_EOL . "\t\t\t//" . $this->setLine(__LINE__) . " Get the encryption object."; - $script .= PHP_EOL . "\t\t\t\$" . $cryptionType . " = new FOFEncryptAes(\$" . $cryptionType . "key);"; - foreach ($this->{$cryptionType . 'EncryptionBuilder'}[$view] as $baseString) - { - $script .= PHP_EOL . PHP_EOL . "\t\t\tif (!empty(\$item->" . $baseString . ") && \$" . $cryptionType . "key && !is_numeric(\$item->" . $baseString . ") && \$item->" . $baseString . " === base64_encode(base64_decode(\$item->" . $baseString . ", true)))"; - $script .= PHP_EOL . "\t\t\t{"; - $script .= PHP_EOL . "\t\t\t\t//" . $this->setLine(__LINE__) . " " . $cryptionType . " decrypt data " . $baseString . "."; - $script .= PHP_EOL . "\t\t\t\t\$item->" . $baseString . " = rtrim(\$" . $cryptionType . "->decryptString(\$item->" . $baseString . "), " . '"\0"' . ");"; - $script .= PHP_EOL . "\t\t\t}"; - } - } - } // add custom php to getitem method $script .= $this->getCustomScriptBuilder('php_getitem', $view, PHP_EOL . PHP_EOL); @@ -6065,7 +6098,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']); @@ -6118,7 +6151,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']); @@ -6146,7 +6179,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']); @@ -6169,7 +6202,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']); @@ -9052,7 +9085,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 +9093,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; @@ -13021,12 +13054,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) @@ -13038,10 +13065,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 47b9ae014..53a43be1a 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,17 +478,30 @@ 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]); + unset($footerScript); } else { - // ###VIEWCSS### <<>> - $this->fileContentDynamic[$viewName_list]['###VIEWSCSS###'] = ''; + $this->fileContentDynamic[$viewName_list]['###VIEWS_FOOTER_SCRIPT###'] = ''; } } @@ -617,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### <<>> @@ -908,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) { @@ -946,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])) @@ -1174,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 @@ -1214,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); @@ -1228,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'; @@ -1271,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 3fa015523..fac68f0dd 100644 --- a/admin/helpers/componentbuilder.php +++ b/admin/helpers/componentbuilder.php @@ -39,13 +39,819 @@ abstract class ComponentbuilderHelper { // the Session keeps track of all data related to the current session of this user self::loadSession(); - } + } + /** + * Locked Libraries (we can not have these change) + **/ + public static $libraryNames = array(1 => 'No Library', 2 => 'Bootstrap v4', 3 => 'Uikit v3', 4 => 'Uikit v2', 5 => 'FooTable v2', 6 => 'FooTable v3'); + + /** + * The global params + **/ + protected static $params = false; + /** * The global updater **/ protected static $globalUpdater = array(); + /** + * The local company details + **/ + protected static $localCompany = array(); + + /** + * The snippet paths + **/ + public static $snippetPath = 'https://raw.githubusercontent.com/vdm-io/Joomla-Component-Builder-Snippets/master/'; + public static $snippetsPath = 'https://api.github.com/repos/vdm-io/Joomla-Component-Builder-Snippets/git/trees/master'; + + /** + * The packages paths + **/ + public static $jcbGithubPackagesUrl = "https://api.github.com/repos/vdm-io/JCB-Packages/git/trees/master"; + public static $jcbGithubPackageUrl = "https://github.com/vdm-io/JCB-Packages/raw/master/"; + + // not needed at this time (maybe latter) + public static $accessToken = ""; + + /** + * get the github repo file list + * + * @return array on success + * + */ + public static function getGithubRepoFileList($type, $target) + { + // get the current Packages (public) + if (!$repoData = self::get($type)) + { + if (self::urlExists($target)) + { + $repoData = self::getFileContents($target); + if (self::checkJson($repoData)) + { + $test = json_decode($repoData); + if (self::checkObject($test) && isset($test->tree) && self::checkArray($test->tree) ) + { + // remember to set it + self::set($type, $repoData); + } + // check if we have error message from github + elseif ($errorMessage = self::githubErrorHandeler(array('error' => null), $test)) + { + if (self::checkString($errorMessage['error'])) + { + JFactory::getApplication()->enqueueMessage($errorMessage['error'], 'Error'); + } + $repoData = false; + } + } + else + { + $repoData = false; + } + } + else + { + JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_URL_S_SET_TO_RETRIEVE_THE_PACKAGES_DOES_NOT_EXIST', $target), 'Error'); + } + } + // check if we could find packages + if (isset($repoData) && self::checkJson($repoData)) + { + $repoData = json_decode($repoData); + if (self::checkObject($repoData) && isset($repoData->tree) && self::checkArray($repoData->tree) ) + { + return $repoData->tree; + } + } + return false; + } + + /** + * get the github error messages + * + * @return array of errors on success + * + */ + protected static function githubErrorHandeler($message, &$github) + { + if (self::checkObject($github) && isset($github->message) && self::checkString($github->message)) + { + // set the message + $errorMessage = $github->message; + // add the documentation URL + if (isset($github->documentation_url) && self::checkString($github->documentation_url)) + { + $errorMessage = $errorMessage.'
'.$github->documentation_url; + } + // check the message + if (strpos($errorMessage, 'Authenticated') !== false) + { + // add little more help if it is an access token issue + $errorMessage = JText::sprintf('COM_COMPONENTBUILDER_SBR_YOU_CAN_ADD_AN_BACCESS_TOKENB_TO_GETBIBLE_GLOBAL_OPTIONS_TO_MAKE_AUTHENTICATED_REQUESTS_AN_ACCESS_TOKEN_WITH_ONLY_PUBLIC_ACCESS_WILL_DO', $errorMessage); + } + // set error notice + $message['error'] = $errorMessage; + // we have error message + return $message; + } + return false; + } + + /** + * The array of constant paths + * + * JPATH_SITE is meant to represent the root path of the JSite application, + * just as JPATH_ADMINISTRATOR is mean to represent the root path of the JAdministrator application. + * + * JPATH_BASE is the root path for the current requested application.... so if you are in the administrator application: + * + * JPATH_BASE == JPATH_ADMINISTRATOR + * + * If you are in the site application: + * + * JPATH_BASE == JPATH_SITE + * + * If you are in the installation application: + * + * JPATH_BASE == JPATH_INSTALLATION. + * + * JPATH_ROOT is the root path for the Joomla install and does not depend upon any application. + * + * @var array + */ + public static $constantPaths = array( + // The path to the administrator folder. + 'JPATH_ADMINISTRATOR' => JPATH_ADMINISTRATOR, + // The path to the installed Joomla! site, or JPATH_ROOT/administrator if executed from the backend. + 'JPATH_BASE' => JPATH_BASE, + // The path to the cache folder. + 'JPATH_CACHE' => JPATH_CACHE, + // The path to the administration folder of the current component being executed. + 'JPATH_COMPONENT_ADMINISTRATOR' => JPATH_COMPONENT_ADMINISTRATOR, + // The path to the site folder of the current component being executed. + 'JPATH_COMPONENT_SITE' => JPATH_COMPONENT_SITE, + // The path to the current component being executed. + 'JPATH_COMPONENT' => JPATH_COMPONENT, + // The path to folder containing the configuration.php file. + 'JPATH_CONFIGURATION' => JPATH_CONFIGURATION, + // The path to the installation folder. + 'JPATH_INSTALLATION' => JPATH_INSTALLATION, + // The path to the libraries folder. + 'JPATH_LIBRARIES' => JPATH_LIBRARIES, + // The path to the plugins folder. + 'JPATH_PLUGINS' => JPATH_PLUGINS, + // The path to the installed Joomla! site. + 'JPATH_ROOT' => JPATH_ROOT, + // The path to the installed Joomla! site. + 'JPATH_SITE' => JPATH_SITE, + // The path to the templates folder. + 'JPATH_THEMES' => JPATH_THEMES + ); + + /* + * Get the Array of Existing Validation Rule Names + * + * @return array + */ + public static function getExistingValidationRuleNames($lowercase = false) + { + // get the items + $items = self::get('_existing_validation_rules_VDM', null); + if (!$items) + { + // load the file class + jimport('joomla.filesystem.file'); + jimport('joomla.filesystem.folder'); + // set the path to the form validation rules + $path = JPATH_LIBRARIES . '/src/Form/Rule'; + // check if the path exist + if (!JFolder::exists($path)) + { + return false; + } + // we must first store the current working directory + $joomla = getcwd(); + // go to that folder + chdir($path); + // load all the files in this path + $items = JFolder::files('.', '\.php', true, true); + // change back to Joomla working directory + chdir($joomla); + // make sure we have an array + if (!self::checkArray($items)) + { + return false; + } + // remove the Rule.php from the name + $items = array_map( function ($name) { + return str_replace(array('./','Rule.php'), '', $name); + }, $items); + // store the names for next run + self::set('_existing_validation_rules_VDM', json_encode($items)); + } + // make sure it is no longer json + if (self::checkJson($items)) + { + $items = json_decode($items, true); + } + // check if the names should be all lowercase + if ($lowercase) + { + $items = array_map( function($item) { + return strtolower($item); + }, $items); + } + return $items; + } + + /** + * Get the snippet contributor details + * + * @param string $filename The file name + * @param string $type The type of file + * + * @return array On success the contributor details + * + */ + public static function getContributorDetails($filename, $type = 'snippet') + { + // start loading he contributor details + $contributor = array(); + // get the path & content + switch ($type) + { + case 'snippet': + $path = $snippetPath.$filename; + // get the file if available + $content = self::getFileContents($path); + if (self::checkJson($content)) + { + $content = json_decode($content, true); + } + break; + default: + // only allow types that are being targeted + return false; + break; + } + // see if we have content and all needed details + if (isset($content) && self::checkArray($content) + && isset($content['contributor_company']) + && isset($content['contributor_name']) + && isset($content['contributor_email']) + && isset($content['contributor_website'])) + { + // got the details from file + return array('contributor_company' => $content['contributor_company'] ,'contributor_name' => $content['contributor_name'], 'contributor_email' => $content['contributor_email'], 'contributor_website' => $content['contributor_website'], 'origin' => 'file'); + } + // get the global settings + if (!self::checkObject(self::$params)) + { + self::$params = JComponentHelper::getParams('com_componentbuilder'); + } + // get the global company details + if (!self::checkArray(self::$localCompany)) + { + // Set the person sharing information (default VDM ;) + self::$localCompany['company'] = self::$params->get('export_company', 'Vast Development Method'); + self::$localCompany['owner'] = self::$params->get('export_owner', 'Llewellyn van der Merwe'); + self::$localCompany['email'] = self::$params->get('export_email', 'joomla@vdm.io'); + self::$localCompany['website'] = self::$params->get('export_website', 'https://www.vdm.io/'); + } + // default global + return array('contributor_company' => self::$localCompany['company'] ,'contributor_name' => self::$localCompany['owner'], 'contributor_email' => self::$localCompany['email'], 'contributor_website' => self::$localCompany['website'], 'origin' => 'global'); + } + + /** + * Get the library files + * + * @param int $id The library id to target + * + * @return array On success the array of files that belong to this library + * + */ + public static function getLibraryFiles($id) + { + // get the library files, folders, and urls + $files = array(); + // Get a db connection. + $db = JFactory::getDbo(); + // Create a new query object. + $query = $db->getQuery(true); + $query->select($db->quoteName(array('b.name','a.addurls','a.addfolders','a.addfiles'))); + $query->from($db->quoteName('#__componentbuilder_library_files_folders_urls','a')); + $query->join('LEFT', $db->quoteName('#__componentbuilder_library', 'b') . ' ON (' . $db->quoteName('a.library') . ' = ' . $db->quoteName('b.id') . ')'); + $query->where($db->quoteName('a.library') . ' = ' . (int) $id); + $db->setQuery($query); + $db->execute(); + if ($db->getNumRows()) + { + // prepare the files + $result = $db->loadObject(); + // first we load the URLs + if (self::checkJson($result->addurls)) + { + // convert to array + $result->addurls = json_decode($result->addurls, true); + // set urls + if (self::checkArray($result->addurls)) + { + // build media folder path + $mediaPath = '/media/' . strtolower( preg_replace('/\s+/', '-', self::safeString($result->name, 'filename', ' ', false))); + // load the urls + foreach($result->addurls as $url) + { + if (isset($url['url']) && self::checkString($url['url'])) + { + // set the path if needed + if (isset($url['type']) && $url['type'] > 1) + { + $fileName = basename($url['url']); + // build sub path + if (strpos($fileName, '.js') !== false) + { + $path = '/js'; + } + elseif (strpos($fileName, '.css') !== false) + { + $path = '/css'; + } + else + { + $path = ''; + } + // set the path to library file + $url['path'] = $mediaPath . $path . '/' . $fileName; // we need this for later + } + // if local path is set, then use it first + if (isset($url['path'])) + { + // load document script + $files[md5($url['path'])] = '(' . JText::_('URL') . ') ' . basename($url['url']) . ' - ' . JText::_('COM_COMPONENTBUILDER_LOCAL'); + } + // check if link must be added + if (isset($url['url']) && ((isset($url['type']) && $url['type'] == 1) || (isset($url['type']) && $url['type'] == 3) || !isset($url['type']))) + { + // load url also if not building document + $files[md5($url['url'])] = '(' . JText::_('URL') . ') ' . basename($url['url']) . ' - ' . JText::_('COM_COMPONENTBUILDER_LINK'); + } + } + } + } + } + // load the local files + if (self::checkJson($result->addfiles)) + { + // convert to array + $result->addfiles = json_decode($result->addfiles, true); + // set files + if (self::checkArray($result->addfiles)) + { + foreach($result->addfiles as $file) + { + if (isset($file['file']) && isset($file['path'])) + { + $path = '/'.trim($file['path'], '/'); + // check if path has new file name (has extetion) + $pathInfo = pathinfo($path); + if (isset($pathInfo['extension']) && $pathInfo['extension']) + { + // load document script + $files[md5($path)] = '(' . JText::_('COM_COMPONENTBUILDER_FILE') . ') ' . $file['file']; + } + else + { + // load document script + $files[md5($path.'/'.trim($file['file'],'/'))] = '(' . JText::_('COM_COMPONENTBUILDER_FILE') . ') ' . $file['file']; + } + } + } + } + } + // load the files in the folder + if (self::checkJson($result->addfolders)) + { + // convert to array + $result->addfolders = json_decode($result->addfolders, true); + // set folder + if (self::checkArray($result->addfolders)) + { + // get the global settings + if (!self::checkObject(self::$params)) + { + self::$params = JComponentHelper::getParams('com_componentbuilder'); + } + // reset bucket + $bucket = array(); + // get custom folder path + $customPath = '/'.trim(self::$params->get('custom_folder_path', JPATH_COMPONENT_ADMINISTRATOR.'/custom'), '/'); + // get all the file paths + foreach ($result->addfolders as $folder) + { + if (isset($folder['path']) && isset($folder['folder'])) + { + $_path = '/'.trim($folder['path'], '/'); + $customFolder = '/'.trim($folder['folder'], '/'); + if (isset($folder['rename']) && 1 == $folder['rename']) + { + if ($_paths = self::getAllFilePaths($customPath.$customFolder)) + { + $bucket[$_path] = $_paths; + } + } + else + { + $path = $_path.$customFolder; + if ($_paths = self::getAllFilePaths($customPath.$customFolder)) + { + $bucket[$path] = $_paths; + } + } + } + } + // now load the script + if (self::checkArray($bucket)) + { + foreach ($bucket as $root => $paths) + { + // load per path + foreach($paths as $path) + { + $files[md5($root.'/'.trim($path, '/'))] = '(' . JText::_('COM_COMPONENTBUILDER_FOLDER') . ') ' . basename($path) . ' - ' . basename($root); + } + } + } + } + } + // return files if found + if (self::checkArray($files)) + { + return $files; + } + } + return false; + } + + /** + * get all the file paths in folder and sub folders + * + * @param string $folder The local path to parse + * @param array $fileTypes The type of files to get + * + * @return void + * + */ + public static function getAllFilePaths($folder, $fileTypes = array('\.php', '\.js', '\.css', '\.less')) + { + if (JFolder::exists($folder)) + { + // we must first store the current woking directory + $joomla = getcwd(); + // we are changing the working directory to the componet path + chdir($folder); + // get the files + foreach ($fileTypes as $type) + { + // get a list of files in the current directory tree + $files[] = JFolder::files('.', $type, true, true); + } + // change back to Joomla working directory + chdir($joomla); + // return array of files + return array_map( function($file) { return str_replace('./', '/', $file); }, (array) self::mergeArrays($files)); + } + return false; + } + + /** + * get all component IDs + */ + public static function getComponentIDs() + { + // Get a db connection. + $db = JFactory::getDbo(); + // Create a new query object. + $query = $db->getQuery(true); + $query->select($db->quoteName(array('id'))); + $query->from($db->quoteName('#__componentbuilder_joomla_component')); + $query->where($db->quoteName('published') . ' >= 1'); // do not backup trash + $db->setQuery($query); + $db->execute(); + if ($db->getNumRows()) + { + return $db->loadColumn(); + } + return false; + } + + /** + * Autoloader + */ + public static function autoLoader($type = 'compiler') + { + // load the type classes + if ('smart' !== $type) + { + foreach (glob(JPATH_ADMINISTRATOR."/components/com_componentbuilder/helpers/".$type."/*.php") as $autoFile) + { + require_once $autoFile; + } + } + // load only if compiler + if ('compiler' === $type) + { + // import the Joomla librarys + jimport('joomla.filesystem.file'); + jimport('joomla.filesystem.folder'); + jimport('joomla.filesystem.archive'); + jimport('joomla.application.component.modellist'); + // include class to minify js + require_once JPATH_ADMINISTRATOR.'/components/com_componentbuilder/helpers/js.php'; + } + // load only if smart + if ('smart' === $type) + { + // import the Joomla libraries + jimport('joomla.filesystem.file'); + jimport('joomla.filesystem.folder'); + jimport('joomla.filesystem.archive'); + jimport('joomla.application.component.modellist'); + } + // load this for all + jimport('joomla.application'); + } + + /** + * Remove folders with files + * + * @param string $dir The path to folder to remove + * @param boolean $ignore The folders and files to ignore and not remove + * + * @return boolean True in all is removed + * + */ + public static function removeFolder($dir, $ignore = false) + { + if (JFolder::exists($dir)) + { + $it = new RecursiveDirectoryIterator($dir); + $it = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST); + foreach ($it as $file) + { + if ('.' === $file->getBasename() || '..' === $file->getBasename()) continue; + if ($file->isDir()) + { + $keeper = false; + if (self::checkArray($ignore)) + { + foreach ($ignore as $keep) + { + if (strpos($file->getPathname(), $dir.'/'.$keep) !== false) + { + $keeper = true; + } + } + } + if ($keeper) + { + continue; + } + JFolder::delete($file->getPathname()); + } + else + { + $keeper = false; + if (self::checkArray($ignore)) + { + foreach ($ignore as $keep) + { + if (strpos($file->getPathname(), $dir.'/'.$keep) !== false) + { + $keeper = true; + } + } + } + if ($keeper) + { + continue; + } + JFile::delete($file->getPathname()); + } + } + if (!self::checkArray($ignore)) + { + return JFolder::delete($dir); + } + return true; + } + return false; + } + + /** + * The dynamic builder of views, tables and fields + **/ + public static function dynamicBuilder(&$data, $type) + { + self::autoLoader('extrusion'); + $extruder = new Extrusion($data); + } + + public static function getFieldOptions($value, $type, $settings = array(), $xml = null) + { + // Get a db connection. + $db = JFactory::getDbo(); + + // Create a new query object. + $query = $db->getQuery(true); + $query->select($db->quoteName(array('properties', 'short_description', 'description'))); + $query->from($db->quoteName('#__componentbuilder_fieldtype')); + $query->where($db->quoteName('published') . ' = 1'); + $query->where($db->quoteName($type) . ' = '. $value); + + // Reset the query using our newly populated query object. + $db->setQuery($query); + $db->execute(); + if ($db->getNumRows()) + { + $result = $db->loadObject(); + $properties = json_decode($result->properties,true); + $field = array( + 'subform' => array(), + 'nameListOptions' => array(), + 'php' => array(), + 'values' => " '', + 'short_description' => $result->short_description, + 'description' => $result->description); + // number pointer + $nr = 0; + // value to check since there are false and null values even 0 in the values returned + $confirmation = '8qvZHoyuFYQqpj0YQbc6F3o5DhBlmS-_-a8pmCZfOVSfANjkmV5LG8pCdAY2JNYu6cB'; + // set the headers + $field['values_description'] .= ''; + foreach ($properties as $property) + { + $example = (isset($property['example']) && self::checkString($property['example'])) ? $property['example'] : ''; + $field['values_description'] .= ''; + // check if we should load the value + $value = self::getValueFromXMLstring($xml, $property['name'], $confirmation); + // check if this is a php field + $addPHP = false; + if (strpos($property['name'], 'type_php') !== false) + { + $addPHP = true; + $phpKey = trim(preg_replace('/[0-9]+/', '', $property['name']), '_'); + // start array if not already set + if (!isset($field['php'][$phpKey])) + { + $field['php'][$phpKey] = array(); + $field['php'][$phpKey]['value'] = array(); + $field['php'][$phpKey]['desc'] = $property['description']; + } + } + // was the settings for the property passed + if(self::checkArray($settings) && isset($settings[$property['name']])) + { + // add the xml values + $field['values'] .= PHP_EOL."\t".$property['name'].'="'.$settings[$property['name']].'" '; + // add the json values + if ($addPHP) + { + $field['php'][$phpKey]['value'][] = $settings[$property['name']]; + } + else + { + $field['subform']['properties'.$nr] = array('name' => $property['name'], 'value' => $settings[$property['name']], 'desc' => $property['description']); + } + } + elseif (!$xml || $confirmation !== $value) + { + // add the xml values + $field['values'] .= PHP_EOL."\t" . $property['name'] . '="'. ($confirmation !== $value) ? $value : $example .'" '; + // add the json values + if ($addPHP) + { + $field['php'][$phpKey]['value'][] = ($confirmation !== $value) ? $value : $example; + } + else + { + $field['subform']['properties' . $nr] = array('name' => $property['name'], 'value' => ($confirmation !== $value) ? $value : $example, 'desc' => $property['description']); + } + } + // add the name List Options + if (!$addPHP) + { + $field['nameListOptions'][$property['name']] = $property['name']; + } + // increment the number + $nr++; + } + $field['values'] .= PHP_EOL."/>"; + $field['values_description'] .= '
'.JText::_('COM_COMPONENTBUILDER_PROPERTY').''.JText::_('COM_COMPONENTBUILDER_EXAMPLE').''.JText::_('COM_COMPONENTBUILDER_DESCRIPTION').'
'.$property['name'].''.$example.''.$property['description'].'
'; + // return found field options + return $field; + } + return false; + } + + public static function getValueFromXMLstring($xml, $get, $confirmation) + { + if (self::checkString($xml)) + { + return self::getBetween($xml, $get.'="', '"', $confirmation); + } + return $confirmation; + } + + + /** + * The zipper method + * + * @param string $workingDIR The directory where the items must be zipped + * @param string $filepath The path to where the zip file must be placed + * + * @return bool true On success + * + */ + public static function zip($workingDIR, &$filepath) + { + // store the current joomla working directory + $joomla = getcwd(); + + // we are changing the working directory to the component temp folder + chdir($workingDIR); + + // the full file path of the zip file + $filepath = JPath::clean($filepath); + + // delete an existing zip file (or use an exclusion parameter in JFolder::files() + JFile::delete($filepath); + + // get a list of files in the current directory tree + $files = JFolder::files('.', '', true, true); + $zipArray = array(); + // setup the zip array + foreach ($files as $file) + { + $tmp = array(); + $tmp['name'] = str_replace('./', '', $file); + $tmp['data'] = JFile::read($file); + $tmp['time'] = filemtime($file); + $zipArray[] = $tmp; + } + + // change back to joomla working directory + chdir($joomla); + + // get the zip adapter + $zip = JArchive::getAdapter('zip'); + + //create the zip file + if ($zip->create($filepath, $zipArray)) + { + return true; + } + return false; + } + + + /** + * Write a file to the server + * + * @param string $path The path and file name where to safe the data + * @param string $data The data to safe + * + * @return bool true On success + * + */ + public static function writeFile($path, $data) + { + $klaar = false; + if (self::checkString($data)) + { + // open the file + $fh = fopen($path, "w"); + if (!is_resource($fh)) + { + return $klaar; + } + // write to the file + if (fwrite($fh, $data)) + { + // has been done + $klaar = true; + } + // close file. + fclose($fh); + } + return $klaar; + } + + /* * Convert repeatable field to subform * @@ -157,60 +963,6 @@ abstract class ComponentbuilderHelper } return $object; } - - /* - * Get the Array of Existing Validation Rule Names - * - * @return array - */ - public static function getExistingValidationRuleNames($lowercase = false) - { - if (!$items = self::get('_existing_validation_rules_VDM', null)) - { - // load the file class - jimport('joomla.filesystem.file'); - jimport('joomla.filesystem.folder'); - // set the path to the form validation rules - $path = JPATH_LIBRARIES . '/src/Form/Rule'; - // check if the path exist - if (!JFolder::exists($path)) - { - return false; - } - // we must first store the current working directory - $joomla = getcwd(); - // go to that folder - chdir($path); - // load all the files in this path - $items = JFolder::files('.', '\.php', true, true); - // change back to Joomla working directory - chdir($joomla); - // make sure we have an array - if (!self::checkArray($items)) - { - return false; - } - // remove the Rule.php from the name - $items = array_map( function ($name) { - return str_replace(array('./','Rule.php'), '', $name); - }, $items); - // store the names for next run - self::set('_existing_validation_rules_VDM', json_encode($items)); - } - // make sure it is no longer json - if (self::checkJson($items)) - { - $items = json_decode($items, true); - } - // check if the names should be all lowercase - if ($lowercase) - { - $items = array_map( function($item) { - return strtolower($item); - }, $items); - } - return $items; - } public static function getDynamicScripts($type, $fieldName = false) { @@ -1018,724 +1770,6 @@ abstract class ComponentbuilderHelper } } return false; - } - - /** - * Locked Libraries (we can not have these change) - **/ - public static $libraryNames = array(1 => 'No Library', 2 => 'Bootstrap v4', 3 => 'Uikit v3', 4 => 'Uikit v2', 5 => 'FooTable v2', 6 => 'FooTable v3'); - - /** - * The global params - **/ - protected static $params = false; - - /** - * The local company details - **/ - protected static $localCompany = array(); - - /** - * The snippet paths - **/ - public static $snippetPath = 'https://raw.githubusercontent.com/vdm-io/Joomla-Component-Builder-Snippets/master/'; - public static $snippetsPath = 'https://api.github.com/repos/vdm-io/Joomla-Component-Builder-Snippets/git/trees/master'; - - /** - * The packages paths - **/ - public static $jcbGithubPackagesUrl = "https://api.github.com/repos/vdm-io/JCB-Packages/git/trees/master"; - public static $jcbGithubPackageUrl = "https://github.com/vdm-io/JCB-Packages/raw/master/"; - - // not needed at this time (maybe latter) - public static $accessToken = ""; - - /** - * get the github repo file list - * - * @return array on success - * - */ - public static function getGithubRepoFileList($type, $target) - { - // get the current Packages (public) - if (!$repoData = self::get($type)) - { - if (self::urlExists($target)) - { - $repoData = self::getFileContents($target); - if (self::checkJson($repoData)) - { - $test = json_decode($repoData); - if (self::checkObject($test) && isset($test->tree) && self::checkArray($test->tree) ) - { - // remember to set it - self::set($type, $repoData); - } - // check if we have error message from github - elseif ($errorMessage = self::githubErrorHandeler(array('error' => null), $test)) - { - if (self::checkString($errorMessage['error'])) - { - JFactory::getApplication()->enqueueMessage($errorMessage['error'], 'Error'); - } - $repoData = false; - } - } - else - { - $repoData = false; - } - } - else - { - JFactory::getApplication()->enqueueMessage(JText::sprintf('COM_COMPONENTBUILDER_THE_URL_S_SET_TO_RETRIEVE_THE_PACKAGES_DOES_NOT_EXIST', $target), 'Error'); - } - } - // check if we could find packages - if (isset($repoData) && self::checkJson($repoData)) - { - $repoData = json_decode($repoData); - if (self::checkObject($repoData) && isset($repoData->tree) && self::checkArray($repoData->tree) ) - { - return $repoData->tree; - } - } - return false; - } - - /** - * get the github error messages - * - * @return array of errors on success - * - */ - protected static function githubErrorHandeler($message, &$github) - { - if (self::checkObject($github) && isset($github->message) && self::checkString($github->message)) - { - // set the message - $errorMessage = $github->message; - // add the documentation URL - if (isset($github->documentation_url) && self::checkString($github->documentation_url)) - { - $errorMessage = $errorMessage.'
'.$github->documentation_url; - } - // check the message - if (strpos($errorMessage, 'Authenticated') !== false) - { - // add little more help if it is an access token issue - $errorMessage = JText::sprintf('COM_COMPONENTBUILDER_SBR_YOU_CAN_ADD_AN_BACCESS_TOKENB_TO_GETBIBLE_GLOBAL_OPTIONS_TO_MAKE_AUTHENTICATED_REQUESTS_AN_ACCESS_TOKEN_WITH_ONLY_PUBLIC_ACCESS_WILL_DO', $errorMessage); - } - // set error notice - $message['error'] = $errorMessage; - // we have error message - return $message; - } - return false; - } - - /** - * The array of constant paths - * - * JPATH_SITE is meant to represent the root path of the JSite application, - * just as JPATH_ADMINISTRATOR is mean to represent the root path of the JAdministrator application. - * - * JPATH_BASE is the root path for the current requested application.... so if you are in the administrator application: - * - * JPATH_BASE == JPATH_ADMINISTRATOR - * - * If you are in the site application: - * - * JPATH_BASE == JPATH_SITE - * - * If you are in the installation application: - * - * JPATH_BASE == JPATH_INSTALLATION. - * - * JPATH_ROOT is the root path for the Joomla install and does not depend upon any application. - * - * @var array - */ - public static $constantPaths = array( - // The path to the administrator folder. - 'JPATH_ADMINISTRATOR' => JPATH_ADMINISTRATOR, - // The path to the installed Joomla! site, or JPATH_ROOT/administrator if executed from the backend. - 'JPATH_BASE' => JPATH_BASE, - // The path to the cache folder. - 'JPATH_CACHE' => JPATH_CACHE, - // The path to the administration folder of the current component being executed. - 'JPATH_COMPONENT_ADMINISTRATOR' => JPATH_COMPONENT_ADMINISTRATOR, - // The path to the site folder of the current component being executed. - 'JPATH_COMPONENT_SITE' => JPATH_COMPONENT_SITE, - // The path to the current component being executed. - 'JPATH_COMPONENT' => JPATH_COMPONENT, - // The path to folder containing the configuration.php file. - 'JPATH_CONFIGURATION' => JPATH_CONFIGURATION, - // The path to the installation folder. - 'JPATH_INSTALLATION' => JPATH_INSTALLATION, - // The path to the libraries folder. - 'JPATH_LIBRARIES' => JPATH_LIBRARIES, - // The path to the plugins folder. - 'JPATH_PLUGINS' => JPATH_PLUGINS, - // The path to the installed Joomla! site. - 'JPATH_ROOT' => JPATH_ROOT, - // The path to the installed Joomla! site. - 'JPATH_SITE' => JPATH_SITE, - // The path to the templates folder. - 'JPATH_THEMES' => JPATH_THEMES - ); - - /** - * Get the snippet contributor details - * - * @param string $filename The file name - * @param string $type The type of file - * - * @return array On success the contributor details - * - */ - public static function getContributorDetails($filename, $type = 'snippet') - { - // start loading he contributor details - $contributor = array(); - // get the path & content - switch ($type) - { - case 'snippet': - $path = $snippetPath.$filename; - // get the file if available - $content = self::getFileContents($path); - if (self::checkJson($content)) - { - $content = json_decode($content, true); - } - break; - default: - // only allow types that are being targeted - return false; - break; - } - // see if we have content and all needed details - if (isset($content) && self::checkArray($content) - && isset($content['contributor_company']) - && isset($content['contributor_name']) - && isset($content['contributor_email']) - && isset($content['contributor_website'])) - { - // got the details from file - return array('contributor_company' => $content['contributor_company'] ,'contributor_name' => $content['contributor_name'], 'contributor_email' => $content['contributor_email'], 'contributor_website' => $content['contributor_website'], 'origin' => 'file'); - } - // get the global settings - if (!self::checkObject(self::$params)) - { - self::$params = JComponentHelper::getParams('com_componentbuilder'); - } - // get the global company details - if (!self::checkArray(self::$localCompany)) - { - // Set the person sharing information (default VDM ;) - self::$localCompany['company'] = self::$params->get('export_company', 'Vast Development Method'); - self::$localCompany['owner'] = self::$params->get('export_owner', 'Llewellyn van der Merwe'); - self::$localCompany['email'] = self::$params->get('export_email', 'joomla@vdm.io'); - self::$localCompany['website'] = self::$params->get('export_website', 'https://www.vdm.io/'); - } - // default global - return array('contributor_company' => self::$localCompany['company'] ,'contributor_name' => self::$localCompany['owner'], 'contributor_email' => self::$localCompany['email'], 'contributor_website' => self::$localCompany['website'], 'origin' => 'global'); - } - - /** - * Get the library files - * - * @param int $id The library id to target - * - * @return array On success the array of files that belong to this library - * - */ - public static function getLibraryFiles($id) - { - // get the library files, folders, and urls - $files = array(); - // Get a db connection. - $db = JFactory::getDbo(); - // Create a new query object. - $query = $db->getQuery(true); - $query->select($db->quoteName(array('b.name','a.addurls','a.addfolders','a.addfiles'))); - $query->from($db->quoteName('#__componentbuilder_library_files_folders_urls','a')); - $query->join('LEFT', $db->quoteName('#__componentbuilder_library', 'b') . ' ON (' . $db->quoteName('a.library') . ' = ' . $db->quoteName('b.id') . ')'); - $query->where($db->quoteName('a.library') . ' = ' . (int) $id); - $db->setQuery($query); - $db->execute(); - if ($db->getNumRows()) - { - // prepare the files - $result = $db->loadObject(); - // first we load the URLs - if (self::checkJson($result->addurls)) - { - // convert to array - $result->addurls = json_decode($result->addurls, true); - // set urls - if (self::checkArray($result->addurls)) - { - // build media folder path - $mediaPath = '/media/' . strtolower( preg_replace('/\s+/', '-', self::safeString($result->name, 'filename', ' ', false))); - // load the urls - foreach($result->addurls as $url) - { - if (isset($url['url']) && self::checkString($url['url'])) - { - // set the path if needed - if (isset($url['type']) && $url['type'] > 1) - { - $fileName = basename($url['url']); - // build sub path - if (strpos($fileName, '.js') !== false) - { - $path = '/js'; - } - elseif (strpos($fileName, '.css') !== false) - { - $path = '/css'; - } - else - { - $path = ''; - } - // set the path to library file - $url['path'] = $mediaPath . $path . '/' . $fileName; // we need this for later - } - // if local path is set, then use it first - if (isset($url['path'])) - { - // load document script - $files[md5($url['path'])] = '(' . JText::_('URL') . ') ' . basename($url['url']) . ' - ' . JText::_('COM_COMPONENTBUILDER_LOCAL'); - } - // check if link must be added - if (isset($url['url']) && ((isset($url['type']) && $url['type'] == 1) || (isset($url['type']) && $url['type'] == 3) || !isset($url['type']))) - { - // load url also if not building document - $files[md5($url['url'])] = '(' . JText::_('URL') . ') ' . basename($url['url']) . ' - ' . JText::_('COM_COMPONENTBUILDER_LINK'); - } - } - } - } - } - // load the local files - if (self::checkJson($result->addfiles)) - { - // convert to array - $result->addfiles = json_decode($result->addfiles, true); - // set files - if (self::checkArray($result->addfiles)) - { - foreach($result->addfiles as $file) - { - if (isset($file['file']) && isset($file['path'])) - { - $path = '/'.trim($file['path'], '/'); - // check if path has new file name (has extetion) - $pathInfo = pathinfo($path); - if (isset($pathInfo['extension']) && $pathInfo['extension']) - { - // load document script - $files[md5($path)] = '(' . JText::_('COM_COMPONENTBUILDER_FILE') . ') ' . $file['file']; - } - else - { - // load document script - $files[md5($path.'/'.trim($file['file'],'/'))] = '(' . JText::_('COM_COMPONENTBUILDER_FILE') . ') ' . $file['file']; - } - } - } - } - } - // load the files in the folder - if (self::checkJson($result->addfolders)) - { - // convert to array - $result->addfolders = json_decode($result->addfolders, true); - // set folder - if (self::checkArray($result->addfolders)) - { - // get the global settings - if (!self::checkObject(self::$params)) - { - self::$params = JComponentHelper::getParams('com_componentbuilder'); - } - // reset bucket - $bucket = array(); - // get custom folder path - $customPath = '/'.trim(self::$params->get('custom_folder_path', JPATH_COMPONENT_ADMINISTRATOR.'/custom'), '/'); - // get all the file paths - foreach ($result->addfolders as $folder) - { - if (isset($folder['path']) && isset($folder['folder'])) - { - $_path = '/'.trim($folder['path'], '/'); - $customFolder = '/'.trim($folder['folder'], '/'); - if (isset($folder['rename']) && 1 == $folder['rename']) - { - if ($_paths = self::getAllFilePaths($customPath.$customFolder)) - { - $bucket[$_path] = $_paths; - } - } - else - { - $path = $_path.$customFolder; - if ($_paths = self::getAllFilePaths($customPath.$customFolder)) - { - $bucket[$path] = $_paths; - } - } - } - } - // now load the script - if (self::checkArray($bucket)) - { - foreach ($bucket as $root => $paths) - { - // load per path - foreach($paths as $path) - { - $files[md5($root.'/'.trim($path, '/'))] = '(' . JText::_('COM_COMPONENTBUILDER_FOLDER') . ') ' . basename($path) . ' - ' . basename($root); - } - } - } - } - } - // return files if found - if (self::checkArray($files)) - { - return $files; - } - } - return false; - } - - /** - * get all the file paths in folder and sub folders - * - * @param string $folder The local path to parse - * @param array $fileTypes The type of files to get - * - * @return void - * - */ - public static function getAllFilePaths($folder, $fileTypes = array('\.php', '\.js', '\.css', '\.less')) - { - if (JFolder::exists($folder)) - { - // we must first store the current woking directory - $joomla = getcwd(); - // we are changing the working directory to the componet path - chdir($folder); - // get the files - foreach ($fileTypes as $type) - { - // get a list of files in the current directory tree - $files[] = JFolder::files('.', $type, true, true); - } - // change back to Joomla working directory - chdir($joomla); - // return array of files - return array_map( function($file) { return str_replace('./', '/', $file); }, (array) self::mergeArrays($files)); - } - return false; - } - - /** - * get all component IDs - */ - public static function getComponentIDs() - { - // Get a db connection. - $db = JFactory::getDbo(); - // Create a new query object. - $query = $db->getQuery(true); - $query->select($db->quoteName(array('id'))); - $query->from($db->quoteName('#__componentbuilder_joomla_component')); - $query->where($db->quoteName('published') . ' >= 1'); // do not backup trash - $db->setQuery($query); - $db->execute(); - if ($db->getNumRows()) - { - return $db->loadColumn(); - } - return false; - } - - /** - * Autoloader - */ - public static function autoLoader($type = 'compiler') - { - // load the type classes - if ('smart' !== $type) - { - foreach (glob(JPATH_ADMINISTRATOR."/components/com_componentbuilder/helpers/".$type."/*.php") as $autoFile) - { - require_once $autoFile; - } - } - // load only if compiler - if ('compiler' === $type) - { - // import the Joomla librarys - jimport('joomla.filesystem.file'); - jimport('joomla.filesystem.folder'); - jimport('joomla.filesystem.archive'); - jimport('joomla.application.component.modellist'); - // include class to minify js - require_once JPATH_ADMINISTRATOR.'/components/com_componentbuilder/helpers/js.php'; - } - // load only if smart - if ('smart' === $type) - { - // import the Joomla libraries - jimport('joomla.filesystem.file'); - jimport('joomla.filesystem.folder'); - jimport('joomla.filesystem.archive'); - jimport('joomla.application.component.modellist'); - } - // load this for all - jimport('joomla.application'); - } - - /** - * Remove folders with files - * - * @param string $dir The path to folder to remove - * @param boolean $ignore The folders and files to ignore and not remove - * - * @return boolean True in all is removed - * - */ - public static function removeFolder($dir, $ignore = false) - { - if (JFolder::exists($dir)) - { - $it = new RecursiveDirectoryIterator($dir); - $it = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST); - foreach ($it as $file) - { - if ('.' === $file->getBasename() || '..' === $file->getBasename()) continue; - if ($file->isDir()) - { - $keeper = false; - if (self::checkArray($ignore)) - { - foreach ($ignore as $keep) - { - if (strpos($file->getPathname(), $dir.'/'.$keep) !== false) - { - $keeper = true; - } - } - } - if ($keeper) - { - continue; - } - JFolder::delete($file->getPathname()); - } - else - { - $keeper = false; - if (self::checkArray($ignore)) - { - foreach ($ignore as $keep) - { - if (strpos($file->getPathname(), $dir.'/'.$keep) !== false) - { - $keeper = true; - } - } - } - if ($keeper) - { - continue; - } - JFile::delete($file->getPathname()); - } - } - if (!self::checkArray($ignore)) - { - return JFolder::delete($dir); - } - return true; - } - return false; - } - - /** - * The dynamic builder of views, tables and fields - **/ - public static function dynamicBuilder(&$data, $type) - { - self::autoLoader('extrusion'); - $extruder = new Extrusion($data); - } - - public static function getFieldOptions($value, $type, $settings = array(), $xml = null) - { - // Get a db connection. - $db = JFactory::getDbo(); - - // Create a new query object. - $query = $db->getQuery(true); - $query->select($db->quoteName(array('properties', 'short_description', 'description'))); - $query->from($db->quoteName('#__componentbuilder_fieldtype')); - $query->where($db->quoteName('published') . ' = 1'); - $query->where($db->quoteName($type) . ' = '. $value); - - // Reset the query using our newly populated query object. - $db->setQuery($query); - $db->execute(); - if ($db->getNumRows()) - { - $result = $db->loadObject(); - $properties = json_decode($result->properties,true); - $field = array( - 'subform' => array(), - 'nameListOptions' => array(), - 'values' => " '', - 'short_description' => $result->short_description, - 'description' => $result->description); - // number pointer - $nr = 0; - // value to check since there are false and null values even 0 in the values returned - $confirmation = '8qvZHoyuFYQqpj0YQbc6F3o5DhBlmS-_-a8pmCZfOVSfANjkmV5LG8pCdAY2JNYu6cB'; - // set the headers - $field['values_description'] .= ''; - foreach ($properties as $property) - { - $example = (isset($property['example']) && self::checkString($property['example'])) ? self::shorten($property['example'], 30) : ''; - $field['values_description'] .= ''; - // check if we should load the value - $value = self::getValueFromXMLstring($xml, $property['name'], $confirmation); - if(self::checkArray($settings) && isset($settings[$property['name']])) - { - // add the xml values - $field['values'] .= "\n\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']; - } - elseif (!$xml || $confirmation !== $value) - { - // add the xml values - $field['values'] .= "\n\t" . $property['name'] . '="'. ($confirmation !== $value) ? $value : $property['example'] .'" '; - // add the json values - $field['subform']['properties' . $nr] = array('name' => $property['name'], 'value' => ($confirmation !== $value) ? $value : $property['example'], 'desc' => $property['description']); - } - // add the name List Options - $field['nameListOptions'][$property['name']] = $property['name']; - // increment the number - $nr++; - } - $field['values'] .= "\n/>"; - $field['values_description'] .= '
'.JText::_('COM_COMPONENTBUILDER_PROPERTY').''.JText::_('COM_COMPONENTBUILDER_EXAMPLE').''.JText::_('COM_COMPONENTBUILDER_DESCRIPTION').'
'.$property['name'].''.$example.''.$property['description'].'
'; - // return found field options - return $field; - } - return false; - } - - public static function getValueFromXMLstring($xml, $get, $confirmation) - { - if (self::checkString($xml)) - { - return self::getBetween($xml, $get.'="', '"', $confirmation); - } - return $confirmation; - } - - - /** - * The zipper method - * - * @param string $workingDIR The directory where the items must be zipped - * @param string $filepath The path to where the zip file must be placed - * - * @return bool true On success - * - */ - public static function zip($workingDIR, &$filepath) - { - // store the current joomla working directory - $joomla = getcwd(); - - // we are changing the working directory to the component temp folder - chdir($workingDIR); - - // the full file path of the zip file - $filepath = JPath::clean($filepath); - - // delete an existing zip file (or use an exclusion parameter in JFolder::files() - JFile::delete($filepath); - - // get a list of files in the current directory tree - $files = JFolder::files('.', '', true, true); - $zipArray = array(); - // setup the zip array - foreach ($files as $file) - { - $tmp = array(); - $tmp['name'] = str_replace('./', '', $file); - $tmp['data'] = JFile::read($file); - $tmp['time'] = filemtime($file); - $zipArray[] = $tmp; - } - - // change back to joomla working directory - chdir($joomla); - - // get the zip adapter - $zip = JArchive::getAdapter('zip'); - - //create the zip file - if ($zip->create($filepath, $zipArray)) - { - return true; - } - return false; - } - - - /** - * Write a file to the server - * - * @param string $path The path and file name where to safe the data - * @param string $data The data to safe - * - * @return bool true On success - * - */ - public static function writeFile($path, $data) - { - $klaar = false; - if (self::checkString($data)) - { - // open the file - $fh = fopen($path, "w"); - if (!is_resource($fh)) - { - return $klaar; - } - // write to the file - if (fwrite($fh, $data)) - { - // has been done - $klaar = true; - } - // close file. - fclose($fh); - } - return $klaar; } /** @@ -2256,6 +2290,624 @@ 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; + + /** + * check if a worker has more work + * + * @param string $function The function to target to perform the task + * + * @return bool + * + */ + public static function hasWork(&$function) + { + if (isset(self::$worker[$function]) && self::checkArray(self::$worker[$function])) + { + return count( (array) self::$worker[$function]); + } + return 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 1afa0e238..fe0910bfe 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!" @@ -923,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" @@ -931,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" @@ -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" @@ -952,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" @@ -2037,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.
@@ -2214,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" +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)" @@ -2276,6 +2282,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" @@ -2299,7 +2306,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_CRONJOB="CronJob" +COM_COMPONENTBUILDER_CONFIG_COMPONENT="Component" +COM_COMPONENTBUILDER_CONFIG_COMPONENT_LABEL="Component" 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" @@ -2312,6 +2320,11 @@ 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_DISPLAY_MESSAGE="Display Message" 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" @@ -2356,6 +2369,38 @@ 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_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." 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)" @@ -2397,6 +2442,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" @@ -2414,6 +2460,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 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:

diff --git a/admin/views/admin_fields_conditions/tmpl/edit.php b/admin/views/admin_fields_conditions/tmpl/edit.php index e116f3920..c0a899449 100644 --- a/admin/views/admin_fields_conditions/tmpl/edit.php +++ b/admin/views/admin_fields_conditions/tmpl/edit.php @@ -120,7 +120,7 @@ $componentParams = JComponentHelper::getParams('com_componentbuilder'); -item->addconditions) + 3, 1);?> +item->addconditions) + 3, 1);?> // for the values already set jQuery(document).ready(function(){ 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/field/tmpl/edit.php b/admin/views/field/tmpl/edit.php index 10cadc4e5..cfdd14f59 100644 --- a/admin/views/field/tmpl/edit.php +++ b/admin/views/field/tmpl/edit.php @@ -82,6 +82,11 @@ $componentParams = JComponentHelper::getParams('com_componentbuilder'); +
+
+ +
+
@@ -343,6 +348,10 @@ jQuery('#adminForm').on('change', '#jform_fieldtype',function (e) { // get type value var fieldId = jQuery("#jform_fieldtype option:selected").val(); getFieldOptions(fieldId); + // get the field type text + var fieldText = jQuery("#jform_fieldtype option:selected").text().toLowerCase(); + // now check if database input is needed + dbChecker(fieldText); }); 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/tmpl/default.php b/admin/views/joomla_components/tmpl/default.php index fcb342518..0c65d07f6 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/admin/views/joomla_components/view.html.php b/admin/views/joomla_components/view.html.php index 5783ca032..3d27333da 100644 --- a/admin/views/joomla_components/view.html.php +++ b/admin/views/joomla_components/view.html.php @@ -134,15 +134,20 @@ 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')) { // 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)) @@ -159,10 +164,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/language_translations/tmpl/default.php b/admin/views/language_translations/tmpl/default.php index b69f3cb74..45a498a61 100644 --- a/admin/views/language_translations/tmpl/default.php +++ b/admin/views/language_translations/tmpl/default.php @@ -96,4 +96,27 @@ if ($this->saveOrder) - \ No newline at end of file + + \ No newline at end of file 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 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); ?> canState): ?> 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/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 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/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 c4c2fad97..88cc77ebd 100644 --- a/componentbuilder.xml +++ b/componentbuilder.xml @@ -1,15 +1,15 @@ COM_COMPONENTBUILDER - 14th April, 2018 + 30th April, 2018 Llewellyn van der Merwe llewellyn@joomlacomponentbuilder.com 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 e69da93da..b4b18579d 100644 --- a/script.php +++ b/script.php @@ -3428,9 +3428,9 @@ class com_componentbuilderInstallerScript $field->type_title = 'Componentbuilder Field'; $field->type_alias = 'com_componentbuilder.field'; $field->table = '{"special": {"dbtable": "#__componentbuilder_field","key": "id","type": "Field","prefix": "componentbuilderTable","config": "array()"},"common": {"dbtable": "#__ucm_content","key": "ucm_id","type": "Corecontent","prefix": "JTable","config": "array()"}}'; - $field->field_mappings = '{"common": {"core_content_item_id": "id","core_title": "name","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": "catid","core_xreference": "null","asset_id": "asset_id"},"special": {"name":"name","fieldtype":"fieldtype","datatype":"datatype","indexes":"indexes","null_switch":"null_switch","store":"store","javascript_view_footer":"javascript_view_footer","add_javascript_view_footer":"add_javascript_view_footer","css_views":"css_views","add_css_views":"add_css_views","css_view":"css_view","add_css_view":"add_css_view","datadefault_other":"datadefault_other","datadefault":"datadefault","datalenght_other":"datalenght_other","datalenght":"datalenght","add_javascript_views_footer":"add_javascript_views_footer","javascript_views_footer":"javascript_views_footer","not_required":"not_required","xml":"xml"}}'; + $field->field_mappings = '{"common": {"core_content_item_id": "id","core_title": "name","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": "catid","core_xreference": "null","asset_id": "asset_id"},"special": {"name":"name","fieldtype":"fieldtype","datatype":"datatype","indexes":"indexes","null_switch":"null_switch","store":"store","css_views":"css_views","add_css_views":"add_css_views","css_view":"css_view","add_css_view":"add_css_view","datalenght":"datalenght","add_javascript_views_footer":"add_javascript_views_footer","datadefault_other":"datadefault_other","datadefault":"datadefault","datalenght_other":"datalenght_other","add_javascript_view_footer":"add_javascript_view_footer","javascript_view_footer":"javascript_view_footer","javascript_views_footer":"javascript_views_footer","not_required":"not_required","xml":"xml"}}'; $field->router = 'ComponentbuilderHelperRoute::getFieldRoute'; - $field->content_history_options = '{"formFile": "administrator/components/com_componentbuilder/models/forms/field.xml","hideFields": ["asset_id","checked_out","checked_out_time","version","not_required","xml"],"ignoreChanges": ["modified_by","modified","checked_out","checked_out_time","version","hits"],"convertToInt": ["published","ordering","fieldtype","store","catid","add_javascript_view_footer","add_css_views","add_css_view","add_javascript_views_footer"],"displayLookup": [{"sourceColumn": "catid","targetTable": "#__categories","targetColumn": "id","displayColumn": "title"},{"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": "fieldtype","targetTable": "#__componentbuilder_fieldtype","targetColumn": "id","displayColumn": "name"}]}'; + $field->content_history_options = '{"formFile": "administrator/components/com_componentbuilder/models/forms/field.xml","hideFields": ["asset_id","checked_out","checked_out_time","version","not_required","xml"],"ignoreChanges": ["modified_by","modified","checked_out","checked_out_time","version","hits"],"convertToInt": ["published","ordering","fieldtype","store","catid","add_css_views","add_css_view","add_javascript_views_footer","add_javascript_view_footer"],"displayLookup": [{"sourceColumn": "catid","targetTable": "#__categories","targetColumn": "id","displayColumn": "title"},{"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": "fieldtype","targetTable": "#__componentbuilder_fieldtype","targetColumn": "id","displayColumn": "name"}]}'; // Set the object into the content types table. $field_Inserted = $db->insertObject('#__content_types', $field); @@ -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"}]}'; @@ -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","development_method":"1","expansion":"0","return_options_build":"2","cronjob_backup_type":"1","cronjob_backup_server":"0","backup_package_name":"JCB_Backup_[YEAR]_[MONTH]_[DAY]","export_license":"GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html","export_copyright":"Copyright (C) 2015. All Rights Reserved","check_in":"-1 day","save_history":"1","history_limit":"10","uikit_load":"1","uikit_min":"","uikit_style":""}'), ); // Condition. $conditions = array( @@ -4037,9 +4037,9 @@ class com_componentbuilderInstallerScript $field->type_title = 'Componentbuilder Field'; $field->type_alias = 'com_componentbuilder.field'; $field->table = '{"special": {"dbtable": "#__componentbuilder_field","key": "id","type": "Field","prefix": "componentbuilderTable","config": "array()"},"common": {"dbtable": "#__ucm_content","key": "ucm_id","type": "Corecontent","prefix": "JTable","config": "array()"}}'; - $field->field_mappings = '{"common": {"core_content_item_id": "id","core_title": "name","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": "catid","core_xreference": "null","asset_id": "asset_id"},"special": {"name":"name","fieldtype":"fieldtype","datatype":"datatype","indexes":"indexes","null_switch":"null_switch","store":"store","javascript_view_footer":"javascript_view_footer","add_javascript_view_footer":"add_javascript_view_footer","css_views":"css_views","add_css_views":"add_css_views","css_view":"css_view","add_css_view":"add_css_view","datadefault_other":"datadefault_other","datadefault":"datadefault","datalenght_other":"datalenght_other","datalenght":"datalenght","add_javascript_views_footer":"add_javascript_views_footer","javascript_views_footer":"javascript_views_footer","not_required":"not_required","xml":"xml"}}'; + $field->field_mappings = '{"common": {"core_content_item_id": "id","core_title": "name","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": "catid","core_xreference": "null","asset_id": "asset_id"},"special": {"name":"name","fieldtype":"fieldtype","datatype":"datatype","indexes":"indexes","null_switch":"null_switch","store":"store","css_views":"css_views","add_css_views":"add_css_views","css_view":"css_view","add_css_view":"add_css_view","datalenght":"datalenght","add_javascript_views_footer":"add_javascript_views_footer","datadefault_other":"datadefault_other","datadefault":"datadefault","datalenght_other":"datalenght_other","add_javascript_view_footer":"add_javascript_view_footer","javascript_view_footer":"javascript_view_footer","javascript_views_footer":"javascript_views_footer","not_required":"not_required","xml":"xml"}}'; $field->router = 'ComponentbuilderHelperRoute::getFieldRoute'; - $field->content_history_options = '{"formFile": "administrator/components/com_componentbuilder/models/forms/field.xml","hideFields": ["asset_id","checked_out","checked_out_time","version","not_required","xml"],"ignoreChanges": ["modified_by","modified","checked_out","checked_out_time","version","hits"],"convertToInt": ["published","ordering","fieldtype","store","catid","add_javascript_view_footer","add_css_views","add_css_view","add_javascript_views_footer"],"displayLookup": [{"sourceColumn": "catid","targetTable": "#__categories","targetColumn": "id","displayColumn": "title"},{"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": "fieldtype","targetTable": "#__componentbuilder_fieldtype","targetColumn": "id","displayColumn": "name"}]}'; + $field->content_history_options = '{"formFile": "administrator/components/com_componentbuilder/models/forms/field.xml","hideFields": ["asset_id","checked_out","checked_out_time","version","not_required","xml"],"ignoreChanges": ["modified_by","modified","checked_out","checked_out_time","version","hits"],"convertToInt": ["published","ordering","fieldtype","store","catid","add_css_views","add_css_view","add_javascript_views_footer","add_javascript_view_footer"],"displayLookup": [{"sourceColumn": "catid","targetTable": "#__categories","targetColumn": "id","displayColumn": "title"},{"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": "fieldtype","targetTable": "#__componentbuilder_fieldtype","targetColumn": "id","displayColumn": "name"}]}'; // Check if field type is already in content_type DB. $field_id = null; @@ -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.

'; } } diff --git a/site/componentbuilder.php b/site/componentbuilder.php index d21ea2051..16c6e2b18 100644 --- a/site/componentbuilder.php +++ b/site/componentbuilder.php @@ -34,7 +34,10 @@ $document->addScript('components/com_componentbuilder/assets/js/site.js'); // Require helper files JLoader::register('ComponentbuilderHelper', dirname(__FILE__) . '/helpers/componentbuilder.php'); JLoader::register('ComponentbuilderEmail', JPATH_COMPONENT_ADMINISTRATOR . '/helpers/componentbuilderemail.php'); -JLoader::register('ComponentbuilderHelperRoute', dirname(__FILE__) . '/helpers/route.php'); +JLoader::register('ComponentbuilderHelperRoute', dirname(__FILE__) . '/helpers/route.php'); + +// Triger the Global Site Event +ComponentbuilderHelper::globalEvent($document); // import joomla controller library jimport('joomla.application.component.controller'); diff --git a/site/controllers/api.php b/site/controllers/api.php index b815a6de1..dd934c995 100644 --- a/site/controllers/api.php +++ b/site/controllers/api.php @@ -210,12 +210,170 @@ class ComponentbuilderControllerApi extends JControllerForm return; } + public function expand() + { + // get params first + if (!isset($this->params) || !ComponentbuilderHelper::checkObject($this->params)) + { + $this->params = JComponentHelper::getParams('com_componentbuilder'); + } + // check if expansion is enabled + $method = $this->params->get('development_method', 1); + // check what kind of return values show we give + $returnOptionsBuild = $this->params->get('return_options_build', 2); + if (2 == $method) + { + // get expansion components + $expansion = $this->params->get('expansion', null); + // check if they are set + if (ComponentbuilderHelper::checkObject($expansion)) + { + // check if user has the right + $user = $this->getApiUser(); + // the message package + $message = array(); + if ($user->authorise('core.admin', 'com_componentbuilder')) + { + // make sure to not unlock + $unlock = false; + // get messages + $callback = function($messages) use (&$message, &$unlock) { + // unlock messages if needed + if ($unlock) { + $messages = ComponentbuilderHelper::unlock($messages); + } + // check if we have any messages + if (ComponentbuilderHelper::checkArray($messages)) { + $message[] = implode("
\n", $messages); + } else { + // var_dump($messages); // error debug message + } + }; + // we have two options, doing them one at a time, use using curl to do tome somewhat asynchronously + if (count ( (array) $expansion) > 1 && function_exists('curl_version')) + { + // set workers + foreach ($expansion as $component) + { + ComponentbuilderHelper::setWorker($component, 'compileInstall'); + } + // make sure to unlock + $unlock = true; + // run workers + ComponentbuilderHelper::runWorker('compileInstall', 1, $callback); + } + else + { + // get model + $model = $this->getModel('api'); + // load the compiler + $this->_autoloader(); + // set workers + foreach ($expansion as $component) + { + // compile and install + $model->compileInstall($component); + } + // check if we have any messages + $callback($model->messages); + } + // return messages if found + if (1== $returnOptionsBuild && ComponentbuilderHelper::checkArray($message)) + { + echo implode("
\n", $message); + } + else + { + echo 1; + } + // clear session + JFactory::getApplication()->getSession()->destroy(); + jexit(); + } + // check if message is to be returned + if (1== $returnOptionsBuild) + { + // clear session + JFactory::getApplication()->getSession()->destroy(); + jexit('Access Denied!'); + } + } + } + // clear session + JFactory::getApplication()->getSession()->destroy(); + // check if message is to be returned + if (1== $returnOptionsBuild) + { + jexit('Expansion Disabled!'); + } + // return bool + echo 0; + jexit(); + } + protected function getApiUser() { // return user object return JFactory::getUser($this->params->get('api', 0, 'INT')); } + public function worker() + { + // get input values + $input = JFactory::getApplication()->input; + // get DATA + $DATA = $input->post->get('VDM_DATA', null, 'STRING'); + // get TASK + $TASK = $input->server->get('HTTP_VDM_TASK', null, 'STRING'); + // get TYPE + $TYPE = $input->server->get('HTTP_VDM_VALUE_TYPE', null, 'STRING'); + // check if correct value is given + if (ComponentbuilderHelper::checkString($DATA) && ComponentbuilderHelper::checkString($TASK) && ComponentbuilderHelper::checkString($TYPE)) + { + // get the type of values we are working with ( 2 = array; 1 = string) + $type = ComponentbuilderHelper::unlock($TYPE); + // get data value + $dataValues = ComponentbuilderHelper::unlock($DATA); + // get the task + $task = ComponentbuilderHelper::unlock($TASK); + // check the for a string + if (1 == $type && ComponentbuilderHelper::checkObject($dataValues) && ComponentbuilderHelper::checkString($task)) + { + // get params first + if (!isset($this->params) || !ComponentbuilderHelper::checkObject($this->params)) + { + $this->params = JComponentHelper::getParams('com_componentbuilder'); + } + // get model + $model = $this->getModel('api'); + // open the compile Install function + if ('compileInstall' === $task) + { + // load the compiler + $this->_autoloader(); + // compile and install + $model->compileInstall($dataValues); + // return locked values + echo ComponentbuilderHelper::lock($model->messages); + // clear session + JFactory::getApplication()->getSession()->destroy(); + jexit(); + } + } + } + // not success + echo 0; + // clear session + JFactory::getApplication()->getSession()->destroy(); + jexit(); + } + + protected function _autoloader() + { + // include component compiler + require_once JPATH_ADMINISTRATOR.'/components/com_componentbuilder/helpers/compiler.php'; + } + /** * Method to check if you can edit an existing record. * diff --git a/site/helpers/componentbuilder.php b/site/helpers/componentbuilder.php index 41f782d35..85534fe73 100644 --- a/site/helpers/componentbuilder.php +++ b/site/helpers/componentbuilder.php @@ -30,7 +30,16 @@ defined('_JEXEC') or die('Restricted access'); * Componentbuilder component helper */ abstract class ComponentbuilderHelper -{ +{ + + /** + * The Global Site Event Method. + **/ + public static function globalEvent($document) + { + // the Session keeps track of all data related to the current session of this user + self::loadSession(); + } /** * Locked Libraries (we can not have these change) @@ -42,6 +51,11 @@ abstract class ComponentbuilderHelper **/ protected static $params = false; + /** + * The global updater + **/ + protected static $globalUpdater = array(); + /** * The local company details **/ @@ -198,6 +212,62 @@ abstract class ComponentbuilderHelper 'JPATH_THEMES' => JPATH_THEMES ); + /* + * Get the Array of Existing Validation Rule Names + * + * @return array + */ + public static function getExistingValidationRuleNames($lowercase = false) + { + // get the items + $items = self::get('_existing_validation_rules_VDM', null); + if (!$items) + { + // load the file class + jimport('joomla.filesystem.file'); + jimport('joomla.filesystem.folder'); + // set the path to the form validation rules + $path = JPATH_LIBRARIES . '/src/Form/Rule'; + // check if the path exist + if (!JFolder::exists($path)) + { + return false; + } + // we must first store the current working directory + $joomla = getcwd(); + // go to that folder + chdir($path); + // load all the files in this path + $items = JFolder::files('.', '\.php', true, true); + // change back to Joomla working directory + chdir($joomla); + // make sure we have an array + if (!self::checkArray($items)) + { + return false; + } + // remove the Rule.php from the name + $items = array_map( function ($name) { + return str_replace(array('./','Rule.php'), '', $name); + }, $items); + // store the names for next run + self::set('_existing_validation_rules_VDM', json_encode($items)); + } + // make sure it is no longer json + if (self::checkJson($items)) + { + $items = json_decode($items, true); + } + // check if the names should be all lowercase + if ($lowercase) + { + $items = array_map( function($item) { + return strtolower($item); + }, $items); + } + return $items; + } + /** * Get the snippet contributor details * @@ -612,6 +682,7 @@ abstract class ComponentbuilderHelper $field = array( 'subform' => array(), 'nameListOptions' => array(), + 'php' => array(), 'values' => " '', 'short_description' => $result->short_description, @@ -624,32 +695,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; @@ -750,6 +851,927 @@ abstract class ComponentbuilderHelper return $klaar; } + + /* + * Convert repeatable field to subform + * + * @param array $item The array to convert + * @param string $name The main field name + * + * @return array + */ + public static function convertRepeatable($item, $name) + { + // continue only if we have an array + if (self::checkArray($item)) + { + $bucket = array(); + foreach ($item as $key => $values) + { + foreach ($values as $nr => $value) + { + if (!isset($bucket[$name . $nr]) || !self::checkArray($bucket[$name . $nr])) + { + $bucket[$name . $nr] = array(); + } + $bucket[$name . $nr][$key] = $value; + } + } + return $bucket; + } + return $item; + } + + /* + * Convert repeatable field to subform + * + * @param object $item The item to update + * @param array $searcher The fields to check and update + * @param array $updater To update the local table + * + * @return void + */ + public static function convertRepeatableFields($object, $searcher, $updater = array()) + { + // update the repeatable fields + foreach ($searcher as $key => $sleutel) + { + if (isset($object->{$key})) + { + $isJson = false; + if (self::checkJson($object->{$key})) + { + $object->{$key} = json_decode($object->{$key}, true); + $isJson = true; + } + // check if this is old values for repeatable fields + if (self::checkArray($object->{$key}) && isset($object->{$key}[$sleutel])) + { + // load it back + $object->{$key} = self::convertRepeatable($object->{$key}, $key); + // add to global updater + if ( + self::checkArray($object->{$key}) && self::checkArray($updater) && + ( + ( isset($updater['table']) && isset($updater['val']) && isset($updater['key']) ) || + ( isset($updater['unique']) && isset($updater['unique'][$key]) && isset($updater['unique'][$key]['table']) && isset($updater['unique'][$key]['val']) && isset($updater['unique'][$key]['key']) ) + ) + ) + { + $_key = null; + $_value = null; + $_table = null; + // check if we have unique id table for this repeatable/subform field + if ( isset($updater['unique']) && isset($updater['unique'][$key]) && isset($updater['unique'][$key]['table']) && isset($updater['unique'][$key]['val']) && isset($updater['unique'][$key]['key']) ) + { + $_key = $updater['unique'][$key]['key']; + $_value = $updater['unique'][$key]['val']; + $_table = $updater['unique'][$key]['table']; + } + elseif ( isset($updater['table']) && isset($updater['val']) && isset($updater['key']) ) + { + $_key = $updater['key']; + $_value = $updater['val']; + $_table = $updater['table']; + } + // continue only if values are valid + if (self::checkString($_table) && self::checkString($_key) && $_value > 0) + { + // set target table & item + $target = trim($_table) . '.' . trim($_key) . '.' . trim($_value); + if (!isset(self::$globalUpdater[$target])) + { + self::$globalUpdater[$target] = new stdClass; + self::$globalUpdater[$target]->{$_key} = (int) $_value; + } + // load the new subform values to global updater + self::$globalUpdater[$target]->{$key} = json_encode($object->{$key}); + } + } + } + // no set back to json if came in as json + if ($isJson && self::checkArray($object->{$key})) + { + $object->{$key} = json_encode($object->{$key}); + } + // remove if not json or array + elseif (!self::checkArray($object->{$key}) && !self::checkJson($object->{$key})) + { + unset($object->{$key}); + } + } + } + return $object; + } + + public static function getDynamicScripts($type, $fieldName = false) + { + // if field name is passed the convert to type + if ($fieldName) + { + $fieldNames = array( + 'php_import_display' => 'display', + 'php_import_setdata' => 'setdata', + 'php_import_save' => 'save', + 'html_import_view' => 'view', + 'php_import' => 'import', + 'php_import_ext' => 'ext', + 'php_import_headers' => 'headers' + ); + // first check if the field name is found + if (isset($fieldNames[$type])) + { + $type = $fieldNames[$type]; + } + else + { + return ''; + } + } + $script = array(); + if ('display' === $type) + { + // set the display script + $script['display'][] = "\tprotected \$headerList;"; + $script['display'][] = "\tprotected \$hasPackage = false;"; + $script['display'][] = "\tprotected \$headers;"; + $script['display'][] = "\tprotected \$hasHeader = 0;"; + $script['display'][] = "\tprotected \$dataType;"; + $script['display'][] = "\n\tpublic function display(\$tpl = null)"; + $script['display'][] = "\t{"; + $script['display'][] = "\t\tif (\$this->getLayout() !== 'modal')"; + $script['display'][] = "\t\t{"; + $script['display'][] = "\t\t\t// Include helper submenu"; + $script['display'][] = "\t\t\t[[[-#-#-Component]]]Helper::addSubmenu('import');"; + $script['display'][] = "\t\t}"; + $script['display'][] = "\n\t\t\$paths = new stdClass;"; + $script['display'][] = "\t\t\$paths->first = '';"; + $script['display'][] = "\t\t\$state = \$this->get('state');"; + $script['display'][] = "\n\t\t\$this->paths = &\$paths;"; + $script['display'][] = "\t\t\$this->state = &\$state;"; + $script['display'][] = "\t\t// get global action permissions"; + $script['display'][] = "\t\t\$this->canDo = [[[-#-#-Component]]]Helper::getActions('import');"; + $script['display'][] = "\n\t\t// We don't need toolbar in the modal window."; + $script['display'][] = "\t\tif (\$this->getLayout() !== 'modal')"; + $script['display'][] = "\t\t{"; + $script['display'][] = "\t\t\t\$this->addToolbar();"; + $script['display'][] = "\t\t\t\$this->sidebar = JHtmlSidebar::render();"; + $script['display'][] = "\t\t}"; + $script['display'][] = "\n\t\t// get the session object"; + $script['display'][] = "\t\t\$session = JFactory::getSession();"; + $script['display'][] = "\t\t// check if it has package"; + $script['display'][] = "\t\t\$this->hasPackage \t= \$session->get('hasPackage', false);"; + $script['display'][] = "\t\t\$this->dataType \t= \$session->get('dataType', false);"; + $script['display'][] = "\t\tif(\$this->hasPackage && \$this->dataType)"; + $script['display'][] = "\t\t{"; + $script['display'][] = "\t\t\t\$this->headerList \t= json_decode(\$session->get(\$this->dataType.'_VDM_IMPORTHEADERS', false),true);"; + $script['display'][] = "\t\t\t\$this->headers \t\t= [[[-#-#-Component]]]Helper::getFileHeaders(\$this->dataType);"; + $script['display'][] = "\t\t\t// clear the data type"; + $script['display'][] = "\t\t\t\$session->clear('dataType');"; + $script['display'][] = "\t\t}"; + $script['display'][] = "\n\t\t// Check for errors."; + $script['display'][] = "\t\tif (count(\$errors = \$this->get('Errors'))){"; + $script['display'][] = "\t\t\tthrow new Exception(implode(".'"\n", $errors), 500);'; + $script['display'][] = "\t\t}"; + $script['display'][] = "\n\t\t// Display the template"; + $script['display'][] = "\t\tparent::display(\$tpl);"; + $script['display'][] = "\t}"; + } + elseif ('setdata' === $type) + { + // set the setdata script + $script['setdata'] = array(); + $script['setdata'][] = "\t/**"; + $script['setdata'][] = "\t* Set the data from the spreadsheet to the database"; + $script['setdata'][] = "\t*"; + $script['setdata'][] = "\t* @param string \$package Paths to the uploaded package file"; + $script['setdata'][] = "\t*"; + $script['setdata'][] = "\t* @return boolean false on failure"; + $script['setdata'][] = "\t*"; + $script['setdata'][] = "\t**/"; + $script['setdata'][] = "\tprotected function setData(\$package,\$table,\$target_headers)"; + $script['setdata'][] = "\t{"; + $script['setdata'][] = "\t\tif ([[[-#-#-Component]]]Helper::checkArray(\$target_headers))"; + $script['setdata'][] = "\t\t{"; + $script['setdata'][] = "\t\t\t// make sure the file is loaded\t\t"; + $script['setdata'][] = "\t\t\tJLoader::import('PHPExcel', JPATH_COMPONENT_ADMINISTRATOR . '/helpers');"; + $script['setdata'][] = "\t\t\t\$jinput = JFactory::getApplication()->input;"; + $script['setdata'][] = "\t\t\tforeach(\$target_headers as \$header)"; + $script['setdata'][] = "\t\t\t{"; + $script['setdata'][] = "\t\t\t\t\$data['target_headers'][\$header] = \$jinput->getString(\$header, null);"; + $script['setdata'][] = "\t\t\t}"; + $script['setdata'][] = "\t\t\t// set the data"; + $script['setdata'][] = "\t\t\tif(isset(\$package['dir']))"; + $script['setdata'][] = "\t\t\t{"; + $script['setdata'][] = "\t\t\t\t\$inputFileType = PHPExcel_IOFactory::identify(\$package['dir']);"; + $script['setdata'][] = "\t\t\t\t\$excelReader = PHPExcel_IOFactory::createReader(\$inputFileType);"; + $script['setdata'][] = "\t\t\t\t\$excelReader->setReadDataOnly(true);"; + $script['setdata'][] = "\t\t\t\t\$excelObj = \$excelReader->load(\$package['dir']);"; + $script['setdata'][] = "\t\t\t\t\$data['array'] = \$excelObj->getActiveSheet()->toArray(null, true,true,true);"; + $script['setdata'][] = "\t\t\t\t\$excelObj->disconnectWorksheets();"; + $script['setdata'][] = "\t\t\t\tunset(\$excelObj);"; + $script['setdata'][] = "\t\t\t\treturn \$this->save(\$data,\$table);"; + $script['setdata'][] = "\t\t\t}"; + $script['setdata'][] = "\t\t}"; + $script['setdata'][] = "\t\treturn false;"; + $script['setdata'][] = "\t}"; + } + elseif ('headers' === $type) + { + $script['headers'] = array(); + $script['headers'][] = "\t/**"; + $script['headers'][] = "\t* Method to get header."; + $script['headers'][] = "\t*"; + $script['headers'][] = "\t* @return mixed An array of data items on success, false on failure."; + $script['headers'][] = "\t*/"; + $script['headers'][] = "\tpublic function getExImPortHeaders()"; + $script['headers'][] = "\t{"; + $script['headers'][] = "\t\t// Get a db connection."; + $script['headers'][] = "\t\t\$db = JFactory::getDbo();"; + $script['headers'][] = "\t\t// get the columns"; + $script['headers'][] = "\t\t\$columns = \$db->getTableColumns(\"#__[[[-#-#-component]]]_[[[-#-#-view]]]\");"; + $script['headers'][] = "\t\tif ([[[-#-#-Component]]]Helper::checkArray(\$columns))"; + $script['headers'][] = "\t\t{"; + $script['headers'][] = "\t\t\t// remove the headers you don't import/export."; + $script['headers'][] = "\t\t\tunset(\$columns['asset_id']);"; + $script['headers'][] = "\t\t\tunset(\$columns['checked_out']);"; + $script['headers'][] = "\t\t\tunset(\$columns['checked_out_time']);"; + $script['headers'][] = "\t\t\t\$headers = new stdClass();"; + $script['headers'][] = "\t\t\tforeach (\$columns as \$column => \$type)"; + $script['headers'][] = "\t\t\t{"; + $script['headers'][] = "\t\t\t\t\$headers->{\$column} = \$column;"; + $script['headers'][] = "\t\t\t}"; + $script['headers'][] = "\t\t\treturn \$headers;"; + $script['headers'][] = "\t\t}"; + $script['headers'][] = "\t\treturn false;"; + $script['headers'][] = "\t}"; + } + elseif ('save' === $type) + { + $script['save'] = array(); + $script['save'][] = "\t/**"; + $script['save'][] = "\t* Save the data from the file to the database"; + $script['save'][] = "\t*"; + $script['save'][] = "\t* @param string \$package Paths to the uploaded package file"; + $script['save'][] = "\t*"; + $script['save'][] = "\t* @return boolean false on failure"; + $script['save'][] = "\t*"; + $script['save'][] = "\t**/"; + $script['save'][] = "\tprotected function save(\$data,\$table)"; + $script['save'][] = "\t{"; + $script['save'][] = "\t\t// import the data if there is any"; + $script['save'][] = "\t\tif([[[-#-#-Component]]]Helper::checkArray(\$data['array']))"; + $script['save'][] = "\t\t{"; + $script['save'][] = "\t\t\t// get user object"; + $script['save'][] = "\t\t\t\$user \t\t= JFactory::getUser();"; + $script['save'][] = "\t\t\t// remove header if it has headers"; + $script['save'][] = "\t\t\t\$id_key \t= \$data['target_headers']['id'];"; + $script['save'][] = "\t\t\t\$published_key \t= \$data['target_headers']['published'];"; + $script['save'][] = "\t\t\t\$ordering_key \t= \$data['target_headers']['ordering'];"; + $script['save'][] = "\t\t\t// get the first array set"; + $script['save'][] = "\t\t\t\$firstSet = reset(\$data['array']);"; + $script['save'][] = ""; + $script['save'][] = "\t\t\t// check if first array is a header array and remove if true"; + $script['save'][] = "\t\t\tif(\$firstSet[\$id_key] == 'id' || \$firstSet[\$published_key] == 'published' || \$firstSet[\$ordering_key] == 'ordering')"; + $script['save'][] = "\t\t\t{"; + $script['save'][] = "\t\t\t\tarray_shift(\$data['array']);"; + $script['save'][] = "\t\t\t}"; + $script['save'][] = "\t\t\t"; + $script['save'][] = "\t\t\t// make sure there is still values in array and that it was not only headers"; + $script['save'][] = "\t\t\tif([[[-#-#-Component]]]Helper::checkArray(\$data['array']) && \$user->authorise(\$table.'.import', 'com_[[[-#-#-component]]]') && \$user->authorise('core.import', 'com_[[[-#-#-component]]]'))"; + $script['save'][] = "\t\t\t{"; + $script['save'][] = "\t\t\t\t// set target."; + $script['save'][] = "\t\t\t\t\$target\t= array_flip(\$data['target_headers']);"; + $script['save'][] = "\t\t\t\t// Get a db connection."; + $script['save'][] = "\t\t\t\t\$db = JFactory::getDbo();"; + $script['save'][] = "\t\t\t\t// set some defaults"; + $script['save'][] = "\t\t\t\t\$todayDate\t\t= JFactory::getDate()->toSql();"; + $script['save'][] = "\t\t\t\t// get global action permissions"; + $script['save'][] = "\t\t\t\t\$canDo\t\t\t= [[[-#-#-Component]]]Helper::getActions(\$table);"; + $script['save'][] = "\t\t\t\t\$canEdit\t\t= \$canDo->get('core.edit');"; + $script['save'][] = "\t\t\t\t\$canState\t\t= \$canDo->get('core.edit.state');"; + $script['save'][] = "\t\t\t\t\$canCreate\t\t= \$canDo->get('core.create');"; + $script['save'][] = "\t\t\t\t\$hasAlias\t\t= \$this->getAliasesUsed(\$table);"; + $script['save'][] = "\t\t\t\t// prosses the data"; + $script['save'][] = "\t\t\t\tforeach(\$data['array'] as \$row)"; + $script['save'][] = "\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\$found = false;"; + $script['save'][] = "\t\t\t\t\tif (isset(\$row[\$id_key]) && is_numeric(\$row[\$id_key]) && \$row[\$id_key] > 0)"; + $script['save'][] = "\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t// raw items import & update!"; + $script['save'][] = "\t\t\t\t\t\t\$query = \$db->getQuery(true);"; + $script['save'][] = "\t\t\t\t\t\t\$query"; + $script['save'][] = "\t\t\t\t\t\t\t->select('version')"; + $script['save'][] = "\t\t\t\t\t\t\t->from(\$db->quoteName('#__[[[-#-#-component]]]_'.\$table))"; + $script['save'][] = "\t\t\t\t\t\t\t->where(\$db->quoteName('id') . ' = '. \$db->quote(\$row[\$id_key]));"; + $script['save'][] = "\t\t\t\t\t\t// Reset the query using our newly populated query object."; + $script['save'][] = "\t\t\t\t\t\t\$db->setQuery(\$query);"; + $script['save'][] = "\t\t\t\t\t\t\$db->execute();"; + $script['save'][] = "\t\t\t\t\t\t\$found = \$db->getNumRows();"; + $script['save'][] = "\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t"; + $script['save'][] = "\t\t\t\t\tif(\$found && \$canEdit)"; + $script['save'][] = "\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t// update item"; + $script['save'][] = "\t\t\t\t\t\t\$id \t\t= \$row[\$id_key];"; + $script['save'][] = "\t\t\t\t\t\t\$version\t= \$db->loadResult();"; + $script['save'][] = "\t\t\t\t\t\t// reset all buckets"; + $script['save'][] = "\t\t\t\t\t\t\$query \t\t= \$db->getQuery(true);"; + $script['save'][] = "\t\t\t\t\t\t\$fields \t= array();"; + $script['save'][] = "\t\t\t\t\t\t// Fields to update."; + $script['save'][] = "\t\t\t\t\t\tforeach(\$row as \$key => \$cell)"; + $script['save'][] = "\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t// ignore column"; + $script['save'][] = "\t\t\t\t\t\t\tif ('IGNORE' == \$target[\$key])"; + $script['save'][] = "\t\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t\tcontinue;"; + $script['save'][] = "\t\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t\t\t// update modified"; + $script['save'][] = "\t\t\t\t\t\t\tif ('modified_by' == \$target[\$key])"; + $script['save'][] = "\t\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t\tcontinue;"; + $script['save'][] = "\t\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t\t\t// update modified"; + $script['save'][] = "\t\t\t\t\t\t\tif ('modified' == \$target[\$key])"; + $script['save'][] = "\t\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t\tcontinue;"; + $script['save'][] = "\t\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t\t\t// update version"; + $script['save'][] = "\t\t\t\t\t\t\tif ('version' == \$target[\$key])"; + $script['save'][] = "\t\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t\t\$cell = (int) \$version + 1;"; + $script['save'][] = "\t\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t\t\t// verify publish authority"; + $script['save'][] = "\t\t\t\t\t\t\tif ('published' == \$target[\$key] && !\$canState)"; + $script['save'][] = "\t\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t\tcontinue;"; + $script['save'][] = "\t\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t\t\t// set to update array"; + $script['save'][] = "\t\t\t\t\t\t\tif(in_array(\$key, \$data['target_headers']) && is_numeric(\$cell))"; + $script['save'][] = "\t\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t\t\$fields[] = \$db->quoteName(\$target[\$key]) . ' = ' . \$cell;"; + $script['save'][] = "\t\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t\t\telseif(in_array(\$key, \$data['target_headers']) && is_string(\$cell))"; + $script['save'][] = "\t\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t\t\$fields[] = \$db->quoteName(\$target[\$key]) . ' = ' . \$db->quote(\$cell);"; + $script['save'][] = "\t\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t\t\telseif(in_array(\$key, \$data['target_headers']) && is_null(\$cell))"; + $script['save'][] = "\t\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t\t// if import data is null then set empty"; + $script['save'][] = "\t\t\t\t\t\t\t\t\$fields[] = \$db->quoteName(\$target[\$key]) . \" = ''\";"; + $script['save'][] = "\t\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t\t// load the defaults"; + $script['save'][] = "\t\t\t\t\t\t\$fields[]\t= \$db->quoteName('modified_by') . ' = ' . \$db->quote(\$user->id);"; + $script['save'][] = "\t\t\t\t\t\t\$fields[]\t= \$db->quoteName('modified') . ' = ' . \$db->quote(\$todayDate);"; + $script['save'][] = "\t\t\t\t\t\t// Conditions for which records should be updated."; + $script['save'][] = "\t\t\t\t\t\t\$conditions = array("; + $script['save'][] = "\t\t\t\t\t\t\t\$db->quoteName('id') . ' = ' . \$id"; + $script['save'][] = "\t\t\t\t\t\t);"; + $script['save'][] = "\t\t\t\t\t\t"; + $script['save'][] = "\t\t\t\t\t\t\$query->update(\$db->quoteName('#__[[[-#-#-component]]]_'.\$table))->set(\$fields)->where(\$conditions);"; + $script['save'][] = "\t\t\t\t\t\t\$db->setQuery(\$query);"; + $script['save'][] = "\t\t\t\t\t\t\$db->execute();"; + $script['save'][] = "\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\telseif (\$canCreate)"; + $script['save'][] = "\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t// insert item"; + $script['save'][] = "\t\t\t\t\t\t\$query = \$db->getQuery(true);"; + $script['save'][] = "\t\t\t\t\t\t// reset all buckets"; + $script['save'][] = "\t\t\t\t\t\t\$columns \t= array();"; + $script['save'][] = "\t\t\t\t\t\t\$values \t= array();"; + $script['save'][] = "\t\t\t\t\t\t\$version\t= false;"; + $script['save'][] = "\t\t\t\t\t\t// Insert columns. Insert values."; + $script['save'][] = "\t\t\t\t\t\tforeach(\$row as \$key => \$cell)"; + $script['save'][] = "\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t// ignore column"; + $script['save'][] = "\t\t\t\t\t\t\tif ('IGNORE' == \$target[\$key])"; + $script['save'][] = "\t\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t\tcontinue;"; + $script['save'][] = "\t\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t\t\t// remove id"; + $script['save'][] = "\t\t\t\t\t\t\tif ('id' == \$target[\$key])"; + $script['save'][] = "\t\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t\tcontinue;"; + $script['save'][] = "\t\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t\t\t// update created"; + $script['save'][] = "\t\t\t\t\t\t\tif ('created_by' == \$target[\$key])"; + $script['save'][] = "\t\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t\tcontinue;"; + $script['save'][] = "\t\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t\t\t// update created"; + $script['save'][] = "\t\t\t\t\t\t\tif ('created' == \$target[\$key])"; + $script['save'][] = "\t\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t\tcontinue;"; + $script['save'][] = "\t\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t\t\t// Make sure the alias is incremented"; + $script['save'][] = "\t\t\t\t\t\t\tif ('alias' == \$target[\$key])"; + $script['save'][] = "\t\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t\t\$cell = \$this->getAlias(\$cell,\$table);"; + $script['save'][] = "\t\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t\t\t// update version"; + $script['save'][] = "\t\t\t\t\t\t\tif ('version' == \$target[\$key])"; + $script['save'][] = "\t\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t\t\$cell = 1;"; + $script['save'][] = "\t\t\t\t\t\t\t\t\$version = true;"; + $script['save'][] = "\t\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t\t\t// set to insert array"; + $script['save'][] = "\t\t\t\t\t\t\tif(in_array(\$key, \$data['target_headers']) && is_numeric(\$cell))"; + $script['save'][] = "\t\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t\t\$columns[] \t= \$target[\$key];"; + $script['save'][] = "\t\t\t\t\t\t\t\t\$values[] \t= \$cell;"; + $script['save'][] = "\t\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t\t\telseif(in_array(\$key, \$data['target_headers']) && is_string(\$cell))"; + $script['save'][] = "\t\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t\t\$columns[] \t= \$target[\$key];"; + $script['save'][] = "\t\t\t\t\t\t\t\t\$values[] \t= \$db->quote(\$cell);"; + $script['save'][] = "\t\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t\t\telseif(in_array(\$key, \$data['target_headers']) && is_null(\$cell))"; + $script['save'][] = "\t\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t\t// if import data is null then set empty"; + $script['save'][] = "\t\t\t\t\t\t\t\t\$columns[] \t= \$target[\$key];"; + $script['save'][] = "\t\t\t\t\t\t\t\t\$values[] \t= \"''\";"; + $script['save'][] = "\t\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t\t// load the defaults"; + $script['save'][] = "\t\t\t\t\t\t\$columns[] \t= 'created_by';"; + $script['save'][] = "\t\t\t\t\t\t\$values[] \t= \$db->quote(\$user->id);"; + $script['save'][] = "\t\t\t\t\t\t\$columns[] \t= 'created';"; + $script['save'][] = "\t\t\t\t\t\t\$values[] \t= \$db->quote(\$todayDate);"; + $script['save'][] = "\t\t\t\t\t\tif (!\$version)"; + $script['save'][] = "\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t\$columns[] \t= 'version';"; + $script['save'][] = "\t\t\t\t\t\t\t\$values[] \t= 1;"; + $script['save'][] = "\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t\t// Prepare the insert query."; + $script['save'][] = "\t\t\t\t\t\t\$query"; + $script['save'][] = "\t\t\t\t\t\t\t->insert(\$db->quoteName('#__[[[-#-#-component]]]_'.\$table))"; + $script['save'][] = "\t\t\t\t\t\t\t->columns(\$db->quoteName(\$columns))"; + $script['save'][] = "\t\t\t\t\t\t\t->values(implode(',', \$values));"; + $script['save'][] = "\t\t\t\t\t\t// Set the query using our newly populated query object and execute it."; + $script['save'][] = "\t\t\t\t\t\t\$db->setQuery(\$query);"; + $script['save'][] = "\t\t\t\t\t\t\$done = \$db->execute();"; + $script['save'][] = "\t\t\t\t\t\tif (\$done)"; + $script['save'][] = "\t\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\t\t\$aId = \$db->insertid();"; + $script['save'][] = "\t\t\t\t\t\t\t// make sure the access of asset is set"; + $script['save'][] = "\t\t\t\t\t\t\t[[[-#-#-Component]]]Helper::setAsset(\$aId,\$table);"; + $script['save'][] = "\t\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t\telse"; + $script['save'][] = "\t\t\t\t\t{"; + $script['save'][] = "\t\t\t\t\t\treturn false;"; + $script['save'][] = "\t\t\t\t\t}"; + $script['save'][] = "\t\t\t\t}"; + $script['save'][] = "\t\t\t\treturn true;"; + $script['save'][] = "\t\t\t}"; + $script['save'][] = "\t\t}"; + $script['save'][] = "\t\treturn false;"; + $script['save'][] = "\t}"; + } + elseif ('view' === $type) + { + $script['view'] = array(); + $script['view'][] = ""; + $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 **/ @@ -1268,6 +2290,624 @@ 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; + + /** + * check if a worker has more work + * + * @param string $function The function to target to perform the task + * + * @return bool + * + */ + public static function hasWork(&$function) + { + if (isset(self::$worker[$function]) && self::checkArray(self::$worker[$function])) + { + return count( (array) self::$worker[$function]); + } + return 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/site/language/en-GB/en-GB.com_componentbuilder.ini b/site/language/en-GB/en-GB.com_componentbuilder.ini index d13047e84..b55082f73 100644 --- a/site/language/en-GB/en-GB.com_componentbuilder.ini +++ b/site/language/en-GB/en-GB.com_componentbuilder.ini @@ -6,6 +6,9 @@ COM_COMPONENTBUILDER_BACKUP_FAILED_PLEASE_TRY_AGAIN_IF_THE_ERROR_CONTINUE_PLEASE COM_COMPONENTBUILDER_BACKUP_WAS_DONE_SUCCESSFULLY="Backup was done successfully" 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_COMPANY_S="Company: %s" +COM_COMPONENTBUILDER_COMPONENT_DID_NOT_COMPILE="Component did not compile!" +COM_COMPONENTBUILDER_COMPONENT_IS_NOT_PUBLISHED_OR_IS_CHECKED_OUT="Component is not published, or is checked out!" +COM_COMPONENTBUILDER_COMPONENT_WAS_NOT_FOUND="Component was not found!" COM_COMPONENTBUILDER_COPYRIGHT_S="Copyright: %s" COM_COMPONENTBUILDER_CREATE_NEW_S="Create New %s" COM_COMPONENTBUILDER_DESCRIPTION="Description" @@ -54,6 +57,9 @@ COM_COMPONENTBUILDER_THE_PACKAGE_KEY_IS_S="The package key is: %s" COM_COMPONENTBUILDER_THE_PRIVATE_KEY_FIELD_COULD_NOT_BE_LOADED_FOR_BSB_SERVER="The private key field could not be loaded for %s server!" COM_COMPONENTBUILDER_THE_PRIVATE_KEY_FILE_COULD_NOT_BE_LOADEDFOUND_FOR_BSB_SERVER="The private key file could not be loaded/found for %s server!" COM_COMPONENTBUILDER_THE_SERVER_DETAILS_FOR_BID_SB_COULD_NOT_BE_RETRIEVED="The server details for (ID: %s) could not be retrieved!" +COM_COMPONENTBUILDER_THE_S_WAS_NOT_INSTALLED_AND_IS_STILL_IN_THE_TEMP_FOLDER="The %s was not Installed and is still in the temp folder." +COM_COMPONENTBUILDER_THE_S_WAS_SUCCESSFULLY_COMPILED="The %s was successfully compiled." +COM_COMPONENTBUILDER_THE_S_WAS_SUCCESSFULLY_INSTALLED_AND_REMOVED_FROM_TEMP_FOLDER="The %s was successfully Installed and removed from temp folder." COM_COMPONENTBUILDER_THE_URL_S_SET_TO_RETRIEVE_THE_PACKAGES_DOES_NOT_EXIST="The url (%s) set to retrieve the packages does not exist!" COM_COMPONENTBUILDER_THIS_PACKAGE_HAS_NO_KEY="This package has no key." COM_COMPONENTBUILDER_TO_CHANGE_THE_PACKAGE_OWNER_DEFAULTS_OPEN_THE_BJCB_GLOBAL_OPTIONSB_GO_TO_THE_BCOMPANYB_TAB_AND_ADD_THE_CORRECT_COMPANY_DETAILS_THERE="To change the package owner defaults. Open the JCB Global Options, go to the Company tab and add the correct company details there." diff --git a/site/models/api.php b/site/models/api.php index 11110afb4..de3b92dff 100644 --- a/site/models/api.php +++ b/site/models/api.php @@ -175,5 +175,73 @@ class ComponentbuilderModelApi extends JModelItem return $this->uikitComp; } return false; - } + } + + public $messages = array(); + public $model; + + protected $compiler; + + public function compileInstall($component) + { + $values = array( + 'version' => 3, + 'component' => 0, + 'backup' => 0, + 'repository' => 0, + 'placeholders' => 2, + 'debuglinenr' => 2, + 'minify' => 2 + ); + // set the values + foreach ($values as $key => $val) + { + if (isset($component->{$key})) + { + $values[$key] = $component->{$key}; + } + } + // make sure we have a component + if (isset($values['component']) && $values['component'] > 1) + { + // make sure the component is published + $published = ComponentbuilderHelper::getVar('joomla_component', (int) $values['component'], 'id', 'published'); + // make sure the component is checked in + $checked_out = ComponentbuilderHelper::getVar('joomla_component', (int) $values['component'], 'id', 'checked_out'); + if (1 == $published && $checked_out == 0) + { + // start up Compiler + $this->compiler = new Compiler($values); + if($this->compiler) + { + // component was compiled + $this->messages[] = JText::sprintf('COM_COMPONENTBUILDER_THE_S_WAS_SUCCESSFULLY_COMPILED', $this->compiler->componentFolderName); + // get compiler model to run the installer + $model = ComponentbuilderHelper::getModel('compiler', JPATH_COMPONENT_ADMINISTRATOR); + // now install components + if ($model->install($this->compiler->componentFolderName.'.zip')) + { + // component was installed + $this->messages[] = JText::sprintf('COM_COMPONENTBUILDER_THE_S_WAS_SUCCESSFULLY_INSTALLED_AND_REMOVED_FROM_TEMP_FOLDER', $this->compiler->componentFolderName); + } + else + { + // component was not installed + $this->messages[] = JText::sprintf('COM_COMPONENTBUILDER_THE_S_WAS_NOT_INSTALLED_AND_IS_STILL_IN_THE_TEMP_FOLDER', $this->compiler->componentFolderName); + } + // get all the messages from application (TODO) + return true; + } + // set that the component was not found + $this->messages[] = JText::_('COM_COMPONENTBUILDER_COMPONENT_DID_NOT_COMPILE'); + return false; + } + // set that the component was not found + $this->messages[] = JText::_('COM_COMPONENTBUILDER_COMPONENT_IS_NOT_PUBLISHED_OR_IS_CHECKED_OUT'); + return false; + } + // set that the component was not found + $this->messages[] = JText::_('COM_COMPONENTBUILDER_COMPONENT_WAS_NOT_FOUND'); + return false; + } }