Beispiel #1
0
 /**
  * Action to execute queries from sample data file
  *
  * @return  void
  */
 public function installDataAction()
 {
     try {
         // Create a backup of Joomla database
         $this->_backupDatabase();
         // Initialize variables
         $config = JFactory::getConfig();
         $tmpPath = $config->get('tmp_path');
         $xmlFiles = glob("{$tmpPath}/{$this->template['name']}_sampledata/*.xml");
         if (empty($xmlFiles)) {
             throw new Exception(JText::_('JSN_TPLFW_ERROR_CANNOT_EXTRACT_SAMPLE_DATA_PACKAGE'));
         }
         // Load XML document
         $xml = simplexml_load_file(current($xmlFiles));
         $version = (string) $xml['version'];
         $joomla_ver = (string) $xml['joomla-version'];
         // Compare versions
         $templateVersion = JSNTplHelper::getTemplateVersion($this->template['name']);
         $joomlaVersion = new JVersion();
         if (version_compare($templateVersion, $version, '<')) {
             throw new Exception(JText::sprintf('JSN_TPLFW_ERROR_SAMPLE_DATA_OUT_OF_DATED', $templateVersion), 99);
         }
         if (!empty($joomla_ver) and version_compare($joomlaVersion->getShortVersion(), $joomla_ver, '<')) {
             throw new Exception(JText::sprintf('JSN_TPLFW_ERROR_JOOMLA_OUT_OF_DATE', $joomlaVersion->getShortVersion()), 99);
         }
         $thirdComponents = array();
         $thirdComponentErrors = array();
         // Looping to each extension type=component to get information and dependencies
         foreach ($xml->xpath('//extension[@author="3rd_party"]') as $component) {
             if (isset($component['author']) && $component['author'] == '3rd_party') {
                 $attrs = (array) $component->attributes();
                 $attrs = $attrs['@attributes'];
                 $componentType = (string) $attrs['type'];
                 $namePrefix = array('component' => 'com_', 'module' => 'mod_');
                 $componentName = isset($namePrefix[(string) $attrs['type']]) ? $namePrefix[$componentType] . $attrs['name'] : (string) $attrs['name'];
                 $state = $this->_getExtensionState($componentName, (string) $attrs['version'], true);
                 $thirdComponents[] = array('id' => $attrs['name'], 'state' => $state, 'full_name' => (string) $attrs['full_name'], 'version' => (string) $attrs['version'], 'type' => $componentType);
             }
         }
         if (count($thirdComponents)) {
             foreach ($thirdComponents as $thirdComponent) {
                 if ($thirdComponent['state'] == 'install') {
                     $thirdComponentErrors[] = JText::sprintf('JSN_TPLFW_ERROR_THIRD_EXTENSION_NOT_INSTALLED', strtoupper($thirdComponent['full_name']) . ' ' . $thirdComponent['type'], $thirdComponent['version']);
                 } elseif ($thirdComponent['state'] == 'update') {
                     $thirdComponentErrors[] = JText::sprintf('JSN_TPLFW_ERROR_THIRD_EXTENSION_NEED_TO_INSTALLED', strtoupper($thirdComponent['full_name']) . ' ' . $thirdComponent['type'], $thirdComponent['version']);
                 } elseif ($thirdComponent['state'] == 'unsupported') {
                     $thirdComponentErrors[] = JText::sprintf('JSN_TPLFW_ERROR_THIRD_EXTENSION_NOT_SUPPORTED', strtoupper($thirdComponent['full_name']) . ' ' . $thirdComponent['type'], $thirdComponent['version']);
                 } else {
                     //do nothing
                 }
             }
         }
         if (count($thirdComponentErrors)) {
             $strThirdComponentError = '<ul>';
             foreach ($thirdComponentErrors as $thirdComponentError) {
                 $strThirdComponentError .= '<li>' . $thirdComponentError . '</li>';
             }
             $strThirdComponentError .= '</ul>';
             throw new Exception(JText::sprintf('JSN_TPLFW_ERROR_THIRD_EXTENSION', $strThirdComponentError), 99);
         }
         // Temporary backup data
         $this->_backupThirdPartyModules();
         $this->_backupThirdPartyAdminModules();
         $this->_backupThirdPartyMenus();
         // Start transaction before manipulate database
         $this->dbo->transactionStart();
         // Delete admin modules
         $this->_deleteThirdPartyAdminModules();
         // Disable execution timeout
         if (!JSNTplHelper::isDisabledFunction('set_time_limit')) {
             set_time_limit(0);
         }
         $attentions = array();
         // Loop each extension to execute queries
         foreach ($xml->xpath('//extension') as $extension) {
             if (isset($extension['author']) && $extension['author'] == 'joomlashine') {
                 $extensionType = (string) $extension['type'];
                 $namePrefix = array('component' => 'com_', 'module' => 'mod_');
                 $extensionName = isset($namePrefix[(string) $extension['type']]) ? $namePrefix[$extensionType] . $extension['name'] : (string) $extension['name'];
                 // Check if JoomlaShine extension is installed
                 $canInstall = JSNTplHelper::isInstalledExtension($extensionName);
                 if ($canInstall == false and $extensionType == 'component') {
                     // Add to attention list when extension is not installed
                     $attentions[] = array('id' => (string) $extension['name'], 'name' => (string) $extension['description'], 'url' => (string) $extension['producturl']);
                 }
             } else {
                 $canInstall = true;
                 $extensionName = 'com_' . (string) $extension['name'];
             }
             if ($canInstall === true) {
                 // Get sample data queries
                 if ($queries = $extension->xpath("task[@name=\"dbinstall\"]/parameters/parameter") and @count($queries)) {
                     // Execute sample data queries
                     foreach ($queries as $query) {
                         // Find remote assets then download to local system
                         if (preg_match_all('#(http://demo.joomlashine.com/[^\\s\\t\\r\\n]+/media/joomlashine/)[^\\s\\t\\r\\n]+\\.(js|css|bmp|gif|ico|jpg|png|svg|ttf|otf|eot|woff)#', $query, $matches, PREG_SET_ORDER)) {
                             foreach ($matches as $match) {
                                 $keepAsIs = false;
                                 if (!isset($this->mediaFolder)) {
                                     // Detect a writable folder to store demo assets
                                     foreach (array('media', 'cache', 'tmp') as $folder) {
                                         $folder = JPATH_ROOT . "/{$folder}";
                                         if (is_dir($folder) and is_writable($folder) and JFolder::create("{$folder}/joomlashine")) {
                                             $this->mediaFolder = "{$folder}/joomlashine";
                                             break;
                                         }
                                     }
                                 }
                                 if (isset($this->mediaFolder)) {
                                     // Generate path to store demo asset
                                     $mediaFile = str_replace($match[1], "{$this->mediaFolder}/", $match[0]);
                                     // Download demo asset only once
                                     if (!is_file($mediaFile)) {
                                         try {
                                             JSNTplHttpRequest::get($match[0], $mediaFile);
                                         } catch (Exception $e) {
                                             $keepAsIs = true;
                                         }
                                     }
                                     // Alter sample data query
                                     if (!$keepAsIs) {
                                         $query = str_replace($match[0], str_replace(JPATH_ROOT . '/', '', $mediaFile), $query);
                                     }
                                 }
                             }
                         }
                         // Execute query
                         $this->dbo->setQuery((string) $query);
                         if (!$this->dbo->{$this->queryMethod}()) {
                             throw new Exception($this->dbo->getErrorMsg());
                         }
                     }
                 }
             }
         }
         // Restore backed up data
         $this->_restoreThirdPartyData();
         $this->_rebuildMenus();
         // Disable default template
         $q = $this->dbo->getQuery(true);
         $q->update('#__template_styles');
         $q->set('home = 0');
         $q->where('client_id = 0');
         $q->where('home = 1');
         $this->dbo->setQuery($q);
         if (!$this->dbo->{$this->queryMethod}()) {
             throw new Exception($this->dbo->getErrorMsg());
         }
         // Set installed template the default one
         $q = $this->dbo->getQuery(true);
         $q->update('#__template_styles');
         $q->set('home = 1');
         $q->where('id = ' . (int) $this->request->getInt('styleId'));
         $this->dbo->setQuery($q);
         if (!$this->dbo->{$this->queryMethod}()) {
             throw new Exception($this->dbo->getErrorMsg());
         }
         // Commit database change
         $this->dbo->transactionCommit();
         // Clean up temporary data
         JInstallerHelper::cleanupInstall("{$tmpPath}/{$this->template['name']}_sampledata.zip", "{$tmpPath}/{$this->template['name']}_sampledata");
         // Clean up assets table for extension that is not installed
         if (count($attentions)) {
             foreach ($attentions as $attention) {
                 $this->_cleanExtensionAssets('com_' . $attention['id']);
             }
         }
         // Set final response
         $this->setResponse(array('attention' => $attentions));
     } catch (Exception $e) {
         throw $e;
     }
 }
Beispiel #2
0
 /**
  * Clean up junk data related to the missing component.
  *
  * @param   string  $name     The component name.
  * @param   array   $modules  Additional modules to be removed.
  * @param   array   $plugins  Additional plugins to be removed.
  *
  * @return  void
  */
 private function _cleanJunkData($name, $modules = null, $plugins = null)
 {
     // Only clean-up junk data if component is really missing.
     if (!JSNTplHelper::isInstalledExtension($name)) {
         // Get all menu items associated with the missing component.
         $q = $this->dbo->getQuery(true);
         $q->select('id')->from('#__menu')->where("type = 'component'");
         $q->where("link LIKE '%option=" . $name . "%'");
         $this->dbo->setQuery($q);
         $items = $this->dbo->loadColumn();
         if (count($items)) {
             // Get all modules associated with all menu items of the missing component.
             $q = $this->dbo->getQuery(true);
             $q->select('moduleid')->from('#__modules_menu')->where('menuid IN (' . implode(', ', $items) . ')');
             $this->dbo->setQuery($q);
             $mods = $this->dbo->loadColumn();
             // Clean up menu table.
             $q = $this->dbo->getQuery(true);
             $q->delete('#__menu')->where('id IN (' . implode(', ', $items) . ')');
             $this->dbo->setQuery($q);
             if (!$this->dbo->{$this->queryMethod}()) {
                 throw new Exception($this->dbo->getErrorMsg());
             }
             // Clean up menu item alias also.
             $q = $this->dbo->getQuery(true);
             $q->delete('#__menu')->where("type = 'alias'")->where('(params LIKE \'%"aliasoptions":"' . implode('"%\' OR params LIKE \'%"aliasoptions":"', $items) . '"%\')');
             $this->dbo->setQuery($q);
             if (!$this->dbo->{$this->queryMethod}()) {
                 throw new Exception($this->dbo->getErrorMsg());
             }
             // Clean up module menu mapping table.
             $q = $this->dbo->getQuery(true);
             $q->delete('#__modules_menu')->where('menuid IN (' . implode(', ', $items) . ')');
             $this->dbo->setQuery($q);
             if (!$this->dbo->{$this->queryMethod}()) {
                 throw new Exception($this->dbo->getErrorMsg());
             }
         }
         if (isset($mods) && count($mods)) {
             // Make sure queried modules does not associate with menu items of other component.
             $q = $this->dbo->getQuery(true);
             $q->select('moduleid')->from('#__modules_menu')->where('moduleid IN (' . implode(', ', $mods) . ')');
             $this->dbo->setQuery($q);
             if ($items = $this->dbo->loadColumn()) {
                 $mods = array_diff($mods, $items);
             }
             // Clean up modules table.
             if (count($mods)) {
                 $q = $this->dbo->getQuery(true);
                 $q->delete('#__modules')->where('id IN (' . implode(', ', $mods) . ')');
                 $this->dbo->setQuery($q);
                 if (!$this->dbo->{$this->queryMethod}()) {
                     throw new Exception($this->dbo->getErrorMsg());
                 }
             }
         }
         // Clean up modules associated with the missing component but not associated with its menu items.
         $q = $this->dbo->getQuery(true);
         $q->delete('#__modules')->where("params LIKE '%\"moduleclass_sfx\":\"%jsn-demo-module-for-{$name}\"%'");
         $this->dbo->setQuery($q);
         if (!$this->dbo->{$this->queryMethod}()) {
             throw new Exception($this->dbo->getErrorMsg());
         }
         // Clean up assets table.
         $q = $this->dbo->getQuery(true);
         $q->delete('#__assets')->where('name = ' . $q->quote($name));
         $this->dbo->setQuery($q);
         if (!$this->dbo->{$this->queryMethod}()) {
             throw new Exception($this->dbo->getErrorMsg());
         }
         // Clean up extensions table.
         $q = $this->dbo->getQuery(true);
         $q->delete('#__extensions')->where('element = ' . $q->quote($name));
         $this->dbo->setQuery($q);
         if (!$this->dbo->{$this->queryMethod}()) {
             throw new Exception($this->dbo->getErrorMsg());
         }
     }
     // Clean up additional modules if specified.
     if ($modules && @count($modules)) {
         foreach ($modules as $module) {
             // Only clean-up junk data if module is really missing.
             if (!@is_dir(JPATH_ROOT . '/modules/' . (string) $module)) {
                 // Clean up modules table.
                 $q = $this->dbo->getQuery(true);
                 $q->delete('#__modules')->where('module = ' . $q->quote((string) $module));
                 $this->dbo->setQuery($q);
                 if (!$this->dbo->{$this->queryMethod}()) {
                     throw new Exception($this->dbo->getErrorMsg());
                 }
                 // Clean up extensions table.
                 $q = $this->dbo->getQuery(true);
                 $q->delete('#__extensions')->where("type = 'module'");
                 $q->where('element = ' . $q->quote((string) $module));
                 $this->dbo->setQuery($q);
                 if (!$this->dbo->{$this->queryMethod}()) {
                     throw new Exception($this->dbo->getErrorMsg());
                 }
             }
         }
     }
     // Clean up additional plugins if specified.
     if ($plugins && @count($plugins)) {
         foreach ($plugins as $plugin) {
             // Only clean-up junk data if plugin is really missing.
             if (!@is_dir(JPATH_ROOT . '/plugins/' . (string) $plugin['group'] . '/' . (string) $plugin)) {
                 // Clean up extensions table.
                 $q = $this->dbo->getQuery(true);
                 $q->delete('#__extensions')->where("type = 'plugin'");
                 $q->where('folder = ' . $q->quote((string) $plugin['group']));
                 $q->where('element = ' . $q->quote((string) $plugin));
                 $this->dbo->setQuery($q);
                 if (!$this->dbo->{$this->queryMethod}()) {
                     throw new Exception($this->dbo->getErrorMsg());
                 }
             }
         }
     }
 }