* @CAsubpackage architectcomp.admin * @CAtemplate joomla_3_x_enhanced (Release 1.0.0) * @CAcopyright Copyright (c)2013 - 2015 Simply Open Source Ltd. (trading as Component Architect). All Rights Reserved * @Joomlacopyright Copyright (c)2005 - 2015 Open Source Matters, Inc. All rights reserved. * @CAlicense GNU General Public License version 3 or later; See http://www.gnu.org/copyleft/gpl.html * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ defined('_JEXEC') or die; // Create shortcut to parameters. $params = $this->state->get('params'); $max_file_size = (string) ComponentArchitectHelper::convert_max_file_size($params->get('default_max_upload_size', '2mb')); $app = JFactory::getApplication(); $input = $app->input; ?> <noscript> <p style="color: red;"><?php echo JText::_('COM_COMPONENTARCHITECT_WARNING_NOSCRIPT'); ?> <p> </noscript> <?php if (version_compare(JVERSION, '3.0', 'lt')) { ?> <div id="nojquerywarning"> <p style="color: red;"><?php echo JText::_('COM_COMPONENTARCHITECT_WARNING_NOJQUERY');
/** * Stores a Object/Table * * @param boolean $update_nulls True to update fields even if they are null. * * @return boolean $result True on success, false on failure. * */ public function store($update_nulls = false) { $date = JFactory::getDate(); $user = JFactory::getUser(); $app = JFactory::getApplication(); // Store any $_FILES input $files = $app->input->files->get('jform'); if (empty($this->id)) { // New Object/Table. A created and created_by field can be set by the user, // so we don't touch either of these if they are set. if (!intval($this->created)) { $this->created = $date->toSQL(); } if (empty($this->created_by)) { $this->created_by = $user->get('id'); } } // Existing item $this->modified = $date->toSQL(); $this->modified_by = $user->get('id'); if (count($files) > 0 and isset($files['icon_16px']) and $files['icon_16px']['name'] != '') { $file = $files['icon_16px']; // Add parameters to the saveUpload call to specify the output file name and the width and height for image file uploads // e.g. saveUpload($file,'icon_16px.png', 100, 0) //[%%START_CUSTOM_CODE%%] //$result = ComponentArchitectHelper::saveUpload($file, 'Icon 16px'); $result = ComponentArchitectHelper::saveUpload($file, 'Icon 16px', '', 16, 16); //[%%END_CUSTOM_CODE%%] if ($result === true) { $this->icon_16px = $file['name']; } else { if ($result !== false) { $this->setError($result); return false; } } } if (count($files) > 0 and isset($files['icon_48px']) and $files['icon_48px']['name'] != '') { $file = $files['icon_48px']; // Add parameters to the saveUpload call to specify the output file name and the width and height for image file uploads // e.g. saveUpload($file,'icon_48px.png', 100, 0) //[%%START_CUSTOM_CODE%%] //$result = ComponentArchitectHelper::saveUpload($file, 'Icon 48px'); $result = ComponentArchitectHelper::saveUpload($file, 'Icon 48px', '', 48, 48); //[%%END_CUSTOM_CODE%%] if ($result === true) { $this->icon_48px = $file['name']; } else { if ($result !== false) { $this->setError($result); return false; } } } // Check and reformat entries in the json array $field_array = $this->joomla_parts; $this->joomla_parts = $field_array; if (isset($this->joomla_parts) and is_array($this->joomla_parts)) { $registry = new JRegistry(); $registry->loadArray($this->joomla_parts); $this->joomla_parts = (string) $registry; $registry = null; //release memory } // Check and reformat entries in the json array $field_array = $this->joomla_features; $this->joomla_features = $field_array; if (isset($this->joomla_features) and is_array($this->joomla_features)) { $registry = new JRegistry(); $registry->loadArray($this->joomla_features); $this->joomla_features = (string) $registry; $registry = null; //release memory } // Attempt to store the data. return parent::store($update_nulls); }
/** * Generate component * * @param component_id integer Id of the component to be generated * @param code_template_id integer Id of the template to use as source * @param output_path string Path to where the generated component will be stored * @param zip_format string format of the zip file, currently only 'zip' allowed. No zip if blank * @param logging integer 0 or 1 specfying whether a log file will be created * * @return true or false */ public function generateComponent($component_id, $code_template_id, $token, $output_path = 'tmp', $zip_format = '', $logging = 0) { $this->_token = $token; $this->_logging = $logging; // Generate can be a very long running process so if possible set the php max execution time so it does not expire if (function_exists('ini_set')) { ini_set('max_execution_time', '0'); // 0 = no limit. } // If logging requested then set up the log file. if ($this->_logging) { if (!$this->_progress->openLog()) { $error = array('message' => JText::_('COM_COMPONENTARCHITECT_GENERATE_ERROR_GEN0000_LOG_FILE_OPEN_FAILED'), 'errorcode' => 'gen0000'); $this->_progress->outputError($this->_token, $error); $this->_progress->completeProgress($this->_token); return false; } } $this->_search_replace_helper = new ComponentArchitectSearchReplaceHelper($this->_progress); $this->_search_replace_helper->setToken($this->_token); $this->_search_replace_helper->setLogging($this->_logging); if ($code_template_id > 0) { $code_template_model = JModelLegacy::getInstance('codetemplate', 'ComponentArchitectModel', array('ignore_request' => true)); $this->_code_template = $code_template_model->getItem($code_template_id); if ($this->_code_template === false) { $error = array('message' => JText::sprintf('COM_COMPONENTARCHITECT_GENERATE_ERROR_GEN0001_CANNOT_LOAD_COMPONENT', $code_template_id, $code_template_model->getError()), 'errorcode' => 'gen0001'); $this->_progress->outputError($this->_token, $error); $this->_progress->completeProgress($this->_token); return false; } // Double check that only limited punctuation is present in name as this may cause php code or sql problems $this->_code_template->template_component_name = preg_replace($this->_name_regex, '', $this->_code_template->template_component_name); $this->_code_template->template_object_name = preg_replace($this->_name_regex, '', $this->_code_template->template_object_name); } else { /* No code template id provided */ $error = array('message' => JText::_('COM_COMPONENTARCHITECT_GENERATE_ERROR_GEN0002_NO_CODE_TEMPLATE_SELECTED'), 'errorcode' => 'gen0002'); $this->_progress->outputError($this->_token, $error); $this->_progress->completeProgress($this->_token); return false; } if ($component_id > 0) { $component_model = JModelLegacy::getInstance('component', 'ComponentArchitectModel', array('ignore_request' => true)); $this->_component = $component_model->getItem($component_id); if ($this->_component === false) { $error = array('message' => JText::sprintf('COM_COMPONENTARCHITECT_GENERATE_ERROR_GEN0003_CANNOT_LOAD_COMPONENT', $component_id, $component_model->getError()), 'errorcode' => 'gen0003'); $this->_progress->outputError($this->_token, $error); $this->_progress->completeProgress($this->_token); return false; } // Double check that only limited punctuation is present in name as this may cause php code or sql problems $this->_component->name = preg_replace($this->_name_regex, '', $this->_component->name); $this->_component->set('search_replace_pairs', $this->_getComponentSearchPairs($this->_code_template->template_component_name, $this->_component)); } else { /* No component id provided */ $error = array('message' => JText::_('COM_COMPONENTARCHITECT_GENERATE_ERROR_GEN0004_NO_COMPONENT_SELECTED'), 'errorcode' => 'gen0004'); $this->_progress->outputError($this->_token, $error); $this->_progress->completeProgress($this->_token); return false; } // Initialise the Progress session data with the generate data $this->_progress->setInitialiseStage($this->_token, $logging, $this->_code_template->name, $this->_component->name); /* * Stage 1 - Analyse component */ $count_fields = (int) $this->_countFields($component_id); $this->_progress->setProgressStage($this->_token, 'stage_1', $count_fields); $this->_search_replace_helper->setTemplateComponentName(str_replace(" ", "", JString::strtolower($this->_code_template->template_component_name))); $this->_search_replace_helper->setTemplateObjectName(str_replace(" ", "", JString::strtolower($this->_code_template->template_object_name))); $this->_search_replace_helper->setMarkupPrefix($this->_code_template->template_markup_prefix); $this->_search_replace_helper->setMarkupSuffix($this->_code_template->template_markup_suffix); $this->_search_replace_helper->setComponentName(str_replace("_", "", str_replace(" ", "", JString::strtolower($this->_component->code_name)))); //Conditions are a generic set for the generate which may include other conditions besides Joomla! Features //Convert Joomla! Parts to conditions. $no_generate_array = array(); // 1st pass to find all high level conditions that are set to not generate foreach ($this->_component->get('joomla_parts') as $name => $value) { // Higher levels must be set to generate otherwise all levels below will need to be set to not generate if (($name == 'generate_admin' or $name == 'generate_site' or $name == 'generate_site_views' or $name == 'generate_categories' or $name == 'generate_plugins' or $name == 'generate_modules') and $value == '0') { $no_generate_array[] = $name; } } // 2nd pass to check each of the conditions against the no generate ones foreach ($this->_component->get('joomla_parts') as $name => $value) { if ($value == '1') { for ($i = 0; $i < count($no_generate_array); $i++) { if (JString::strpos($name, $no_generate_array[$i]) !== false) { $value = '0'; break; } } if ($value == '1' and (JString::strpos($name, 'generate_categories_site') !== false and in_array('generate_site', $no_generate_array) or JString::strpos($name, 'generate_site_layout') !== false and in_array('generate_site_views', $no_generate_array))) { $value = '0'; } } $this->_search_replace_helper->setComponentConditions($name, (int) $value); } //Convert Joomla! Features to conditions. foreach ($this->_component->get('joomla_features') as $name => $value) { $this->_search_replace_helper->setComponentConditions($name, (int) $value); } // Populate the Component Objects if (!$this->_getFieldTypes()) { $this->_progress->completeProgress($this->_token); return false; } $this->_component_objects = $this->_getComponentObjects($component_id, $this->_component->get('default_object_id'), $this->_code_template->template_component_name, $this->_code_template->template_object_name); if ($this->_component_objects === false) { /* Problem loading component objects */ $error = array('message' => JText::sprintf('COM_COMPONENTARCHITECT_GENERATE_ERROR_GEN0012_CANNOT_POPULATE_COMPONENT_OBJECTS', $this->_component->name), 'errorcode' => 'gen0012'); $this->_progress->outputError($this->_token, $error); $this->_progress->completeProgress($this->_token); return false; } $this->_search_replace_helper->setComponentObjects($this->_component_objects); $generic_language_vars = implode('', $this->_generic_values); // Save search replace pair for the all generic field values array_push($this->_component->search_replace_pairs, array('search' => $this->_markupText('COM_' . JString::strtoupper(str_replace(' ', '', $this->_code_template->template_component_name)) . '_GENERIC_FIELD_VALUES'), 'replace' => $generic_language_vars)); // Update Stage 1 progress as being complete if logging requested this will also create a log record $step = JText::_('COM_COMPONENTARCHITECT_GENERATE_END_STAGE_1'); $this->_progress->setProgress($this->_token, 'stage_1', $step, true); /* * Stage 2 - Create Files */ $this->_code_templates_root = JPATH_COMPONENT_ADMINISTRATOR . '/' . 'codetemplates'; $files_count = $this->_countFiles(JPath::clean($this->_code_templates_root . '/' . $this->_code_template->source_path)); $excluded_files_count = $this->_countExcludedFiles(JPath::clean($this->_code_templates_root . '/' . $this->_code_template->source_path)); $files_count = $files_count - $excluded_files_count; $this->_progress->setProgressStage($this->_token, 'stage_2', $files_count); $template_source_path = JPath::clean($this->_code_templates_root . '/' . $this->_code_template->source_path); $dir = opendir($template_source_path); while (false !== ($file = readdir($dir))) { if ($file != '.' and $file != '..' and !is_file($template_source_path . '/' . $file)) { $src_file = $file; $src_path = $template_source_path . '/' . $file; break; } } closedir($dir); $dst_file = str_replace(str_replace(" ", "", JString::strtolower($this->_code_template->template_component_name)), str_replace("_", "", str_replace(" ", "", JString::strtolower($this->_component->code_name))), $src_file); $dst_path = JPath::clean(JPATH_SITE . '/' . $output_path . '/' . $dst_file); // Call the main function to recursively make copies of the folders and files in the Code Template $this->_search_replace_helper->recursiveCopy($src_path, $dst_path); // Update Stage 2 progress as being complete if logging requested this will also create a log record $step = JText::_('COM_COMPONENTARCHITECT_GENERATE_END_STAGE_2'); $this->_progress->setProgress($this->_token, 'stage_2', $step, true); /* * Stage 3 - Search/Replace Markup */ $files_count = $this->_countFiles($dst_path); $this->_progress->setProgressStage($this->_token, 'stage_3', $files_count); // Initialise the search - replace parameters $this->_search_replace_helper->initialiseSearchReplace($this->_component->get('search_replace_pairs'), '', $dst_path); // Call the main search and replace function $this->_search_replace_helper->doSearchReplace(); // Finally need to copy icons for components and component object if ($this->_component->icon_16px != '') { copy(JPATH_SITE . '/' . $this->_component->icon_16px, $dst_path . '/media/images/' . str_replace("_", "", str_replace(" ", "", JString::strtolower($this->_component->code_name))) . '.png'); copy(JPATH_SITE . '/' . $this->_component->icon_16px, $dst_path . '/media/images/icon-16-' . str_replace("_", "", str_replace(" ", "", JString::strtolower($this->_component->code_name))) . '.png'); } if ($this->_component->icon_48px != '') { $image_name = str_replace("_", "", str_replace(" ", "", JString::strtolower($this->_component->code_name))) . '.png'; copy(JPATH_SITE . '/' . $this->_component->icon_48px, $dst_path . '/media/images/icon-48-' . $image_name); ComponentArchitectHelper::createThumb(JPATH_SITE . '/' . $this->_component->icon_48px, $dst_path . '/media/images/icon-32-' . $image_name, 32, 32); ComponentArchitectHelper::createThumb(JPATH_SITE . '/' . $this->_component->icon_48px, $dst_path . '/media/images/icon-24-' . $image_name, 24, 24); } // If component has to generate categories then include images for those in both admin assets and media (for auto menu items and Header images) if ($this->_search_replace_helper->getComponentConditions('generate_categories')) { if ($this->_component->categories_icon_16px != '') { copy(JPATH_SITE . '/' . $this->_component->categories_icon_16px, $dst_path . '/media/images/' . str_replace("_", "", JString::strtolower($this->_component->code_name)) . '-categories.png'); copy(JPATH_SITE . '/' . $this->_component->categories_icon_16px, $dst_path . '/media/images/icon-16-categories.png'); } if ($this->_component->categories_icon_48px != '') { copy(JPATH_SITE . '/' . $this->_component->categories_icon_48px, $dst_path . '/media/images/icon-48-categories.png'); ComponentArchitectHelper::createThumb(JPATH_SITE . '/' . $this->_component->categories_icon_48px, $dst_path . '/media/images/icon-32-categories.png', 32, 32); ComponentArchitectHelper::createThumb(JPATH_SITE . '/' . $this->_component->categories_icon_48px, $dst_path . '/media/images/icon-24-categories.png', 24, 24); } } foreach ($this->_component_objects as $component_object) { if ($component_object->icon_16px != '') { copy(JPATH_SITE . '/' . $component_object->icon_16px, $dst_path . '/media/images/' . str_replace("_", "", JString::strtolower($this->_component->code_name)) . '-' . str_replace("_", "", str_replace(" ", "", JString::strtolower($component_object->plural_code_name))) . '.png'); copy(JPATH_SITE . '/' . $component_object->icon_16px, $dst_path . '/media/images/icon-16-' . str_replace("_", "", str_replace(" ", "", JString::strtolower($component_object->plural_code_name))) . '.png'); } if ($component_object->icon_48px != '') { $image_name = str_replace("_", "", str_replace(" ", "", JString::strtolower($component_object->plural_code_name))) . '.png'; copy(JPATH_SITE . '/' . $component_object->icon_48px, $dst_path . '/media/images/icon-48-' . $image_name); ComponentArchitectHelper::createThumb(JPATH_SITE . '/' . $component_object->icon_48px, $dst_path . '/media/images/icon-32-' . $image_name, 32, 32); ComponentArchitectHelper::createThumb(JPATH_SITE . '/' . $component_object->icon_48px, $dst_path . '/media/images/icon-24-' . $image_name, 24, 24); } } // Update Stage 3 progress as being complete if logging requested this will also create a log record $step = JText::_('COM_COMPONENTARCHITECT_GENERATE_END_STAGE_3'); $this->_progress->setProgress($this->_token, 'stage_3', $step, true); $component_path = $output_path . '/' . $dst_file; $zip_file = $this->_zip_file; if ($zip_format != '') { jimport('joomla.filesystem.archive'); $zipFilesArray = array(); $dirs = JFolder::folders($dst_path, '.', true, true); array_push($dirs, $dst_path); foreach ($dirs as $dir) { $files = JFolder::files($dir, '.', false, true); foreach ($files as $file) { $data = JFile::read($file); $zipFilesArray[] = array('name' => str_replace($dst_path . '\\', '', str_replace($dst_path . '/', '', $file)), 'data' => $data); } } $zip = JArchive::getAdapter($zip_format); $zip->create(JPATH_SITE . '/' . $output_path . '/' . $dst_file . '.' . $zip_format, $zipFilesArray); $zip_file = $dst_file . '.' . $zip_format; $zip_path = JUri::root() . $output_path; } else { $zip_file = ''; $zip_path = ''; } $this->_progress->completeProgress($this->_token, $component_path, $zip_path, $zip_file); return true; }
/** * Method to display a view. * * @param boolean If true, the view output will be cached * @param array An array of safe url parameters and their variable types, for valid values see {@link JFilterInput::clean()}. * * @return JControllerLegacy This object to support chaining. * */ public function display($cachable = false, $url_params = false) { if (version_compare(JVERSION, '3.0', 'lt')) { $view = JRequest::getCmd('view', $this->default_view); $layout = JRequest::getCmd('layout', 'default'); $id = JRequest::getInt('id'); } else { $view = $this->input->get('view', $this->default_view); $layout = $this->input->get('layout', 'default'); $id = $this->input->getInt('id'); } // Load the submenu. ComponentArchitectHelper::addSubmenu($view); // Check for edit form. switch ($view) { case 'component': if ($layout == 'edit' and !$this->checkEditId('com_componentarchitect.edit.component', $id)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=com_componentarchitect&view=components', false)); return false; } break; case 'componentobject': if ($layout == 'edit' and !$this->checkEditId('com_componentarchitect.edit.componentobject', $id)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=com_componentarchitect&view=componentobjects', false)); return false; } break; case 'fieldset': if ($layout == 'edit' and !$this->checkEditId('com_componentarchitect.edit.fieldset', $id)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=com_componentarchitect&view=fieldsets', false)); return false; } break; case 'field': if ($layout == 'edit' and !$this->checkEditId('com_componentarchitect.edit.field', $id)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=com_componentarchitect&view=fields', false)); return false; } break; case 'fieldtype': if ($layout == 'edit' and !$this->checkEditId('com_componentarchitect.edit.fieldtype', $id)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=com_componentarchitect&view=fieldtypes', false)); return false; } break; case 'codetemplate': if ($layout == 'edit' and !$this->checkEditId('com_componentarchitect.edit.codetemplate', $id)) { // Somehow the person just went to the form - we don't allow that. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id)); $this->setMessage($this->getError(), 'error'); $this->setRedirect(JRoute::_('index.php?option=com_componentarchitect&view=codetemplates', false)); return false; } break; } parent::display(); return $this; }