Exemplo n.º 1
0
 /**
  * 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;
 }