File Manager

Current Directory: /home/astoriaah/www/old15/administrator/components/com_akeeba/models
Viewing File: /home/astoriaah/www/old15/administrator/components/com_akeeba/models/installer.php
<?php /** * @package AkeebaBackup * @copyright Copyright (c)2009-2014 Nicholas K. Dionysopoulos * @license GNU General Public License version 3, or later * * @since 3.3 */ defined('_JEXEC') or die(''); JLoader::import('joomla.application.component.model'); JLoader::import('joomla.installer.installer'); JLoader::import('joomla.installer.helper'); require_once F0FTemplateUtils::parsePath('admin://components/com_installer/models/install.php', true); /** * Class AkeebaModelInstaller extends the core com_installer InstallerModelInstall model, * adding the brains which decide how to perform the SRP backup in each case. */ class AkeebaModelInstaller extends InstallerModelInstall { /** * Fetches a package from the upload form and saves it to the temporary directory * * @return boolean True if the upload is successful */ public function upload() { // Get the uploaded file information $userfile = JRequest::getVar('install_package', null, 'files', 'array'); // Make sure that file uploads are enabled in php if (!(bool)ini_get('file_uploads')) { JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLFILE')); return false; } // Make sure that zlib is loaded so that the package can be unpacked if (!extension_loaded('zlib')) { JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLZLIB')); return false; } // If there is no uploaded file, we have a problem... if (!is_array($userfile)) { JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_NO_FILE_SELECTED')); return false; } // Check if there was a problem uploading the file. if ($userfile['error'] || $userfile['size'] < 1) { JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR')); return false; } // Build the appropriate paths $config = JFactory::getConfig(); $tmp_dest = $config->get('tmp_path') . '/' . $userfile['name']; $tmp_src = $userfile['tmp_name']; // Move uploaded file JLoader::import('joomla.filesystem.file'); $uploaded = JFile::upload($tmp_src, $tmp_dest); if (!$uploaded) { JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_WARNINSTALLUPLOADERROR')); return false; } // Store the uploaded package's location $session = JFactory::getSession(); $session->set('compressed_package', $tmp_dest, 'akeeba'); return true; } /** * Downloads a package from a URL and saves it to the temporary directory * * @return boolean True is the download was successful */ public function download() { $input = JFactory::getApplication()->input; // Get the URL of the package to install $url = $input->getString('install_url'); // Did you give us a URL? if (!$url) { JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_ENTER_A_URL')); return false; } // Handle updater XML file case: if (preg_match('/\.xml\s*$/', $url)) { jimport('joomla.updater.update'); $update = new JUpdate; $update->loadFromXML($url); $package_url = trim($update->get('downloadurl', false)->_data); if ($package_url) { $url = $package_url; } unset($update); } // Download the package at the URL given $p_file = JInstallerHelper::downloadPackage($url); // Was the package downloaded? if (!$p_file) { JError::raiseWarning('', JText::_('COM_INSTALLER_MSG_INSTALL_INVALID_URL')); return false; } $config = JFactory::getConfig(); $tmp_dest = $config->get('tmp_path'); // Store the uploaded package's location $session = JFactory::getSession(); $session->set('compressed_package', $tmp_dest . '/' . $p_file, 'akeeba'); return true; } /** * Extracts a package archive to the temporary directory. The package information is * saved in the session. * * @return boolean True if the extraction was successful */ function extract() { $session = JFactory::getSession(); $compressed_package = $session->get('compressed_package', null, 'akeeba'); // Do we have a compressed package? if (is_null($compressed_package)) { JError::raiseWarning('', 'No package specified'); return false; } // Extract the package $package = JInstallerHelper::unpack($compressed_package); $session->set('package', $package, 'akeeba'); return true; } /** * Gets the package information from an (already extracted) package in a directory, * then saves the package information in the session. * * @param string $folder (optional) Which directory to look into. * * @return boolean Always true */ public function fromDirectory($folder = null) { if (!empty($folder)) { $input = JFactory::getApplication()->input; $input->set('install_directory', $folder); } $package = $this->_getPackageFromFolder(); $session = JFactory::getSession(); $session->set('package', $package, 'akeeba'); return true; } /** * Cleans up any remaining files after the installation is over (successful or not) * * @return boolean True on success */ function cleanUp() { $session = JFactory::getSession(); $package = $session->get('package', '', 'akeeba'); // Was the package unpacked? if (!$package || empty($package)) { return false; } // Cleanup the install files if (!is_file($package['packagefile'])) { $config = JFactory::getConfig(); $package['packagefile'] = $config->get('tmp_path') . '/' . $package['packagefile']; } JInstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']); return true; } /** * Identifies the extension whose package is extracted in $p_dir. It returns an array with * the extension type, name and group (folder for plugins, admin/site section for modules, * etc) * * @param string $p_dir The directory containing the extracted package * * @return array|bool Hashed array on success, boolean false on failure */ public function getExtensionName($p_dir) { // Search the install dir for an XML file JLoader::import('joomla.filesystem.folder'); $files = JFolder::files($p_dir, '\.xml$', 1, true); if (!count($files)) { JError::raiseWarning(1, JText::_('JLIB_INSTALLER_ERROR_NOTFINDXMLSETUPFILE')); return false; } foreach ($files as $file) { try { $xml = new SimpleXMLElement($file, LIBXML_NONET, true); } catch (Exception $e) { continue; } if (($xml->getName() != 'install') && ($xml->getName() != 'extension') && ($xml->getName() != 'akeebabackup')) { unset($xml); continue; } $type = (string)$xml->attributes()->type; list($name, $cname, $group) = $this->extractName($xml, $type); if (empty($name)) { $name = false; } if ($name !== false) { $info = array('name' => $name, 'cname' => $cname, 'group' => $group); if (!$this->isInstalled($xml, $type, $info)) { $name = false; } } else { return false; } // Free up memory from SimpleXML parser unset ($xml); if ($name === false) { return false; } // Return the name return array( 'name' => $name, 'client' => $cname, 'group' => $group ); } return false; } /** * Returns the URL used to take a System Restore Point backup for the current extension. * If the extension is not already installed it will return boolean false. * * @return bool|string URL on success, false if the extension is not already installed */ public function getSrpUrl() { $session = JFactory::getSession(); $package = $session->get('package', array(), 'akeeba'); $name = $this->getExtensionName($package['dir']); if ($name !== false) { // If SRPs are supported, get the SRP URL $type = $package['type']; $url = 'index.php?option=com_akeeba&view=backup&tag=restorepoint&type=' . $type . '&name=' . urlencode($name['name']); switch ($type) { case 'component': break; case 'file': break; case 'library': break; case 'module': $url .= '&group=' . $name['client']; break; case 'package': break; case 'plugin': $url .= '&group=' . $name['group']; break; case 'template': $url .= '&group=' . $name['client']; break; default: return false; break; } $url .= '&returnurl=' . urlencode('index.php?option=com_installer&view=install&task=install.akrealinstall'); $token = JSession::getFormToken(); $url .= '&' . $token . '=1'; // Force the profile $profile = 1; if (!class_exists('JPluginHelper')) { JLoader::import('joomla.plugin.helper'); JLoader::import('cms.plugin.helper'); } $plugin = JPluginHelper::getPlugin('system', 'srp'); if (!empty($plugin)) { $plugin = (array)$plugin; if (array_key_exists('params', $plugin)) { $params = new JRegistry($plugin['params']); $profile = $params->get('profileid', 1); } } JFactory::getSession()->set('profile', $profile, 'akeeba'); // Return the SRP URL return $url; } else { // If SRPs are not supported, return false return false; } } /** * Downloads an update package given an update record ID ($uid). The package is downloaded * and its location recorded in the session. * * @param integer $uid The update record ID * * @return True on success */ public function downloadUpdate($uid) { // Unset the compressed_package session variable $session = JFactory::getSession(); $session->set('compressed_package', null, 'akeeba'); // Find the download location from the XML update stream jimport('joomla.updater.update'); $update = new JUpdate; $instance = JTable::getInstance('update'); $instance->load($uid); $update->loadFromXML($instance->detailsurl); if (isset($update->get('downloadurl')->_data)) { $url = $update->downloadurl->_data; } else { JError::raiseWarning('', JText::_('COM_INSTALLER_INVALID_EXTENSION_UPDATE')); return false; } // Sadly JInstallerHelper will only add any extra query param firing installer plugins, it won't check // the update_sites table, so we have to that manually if (version_compare(JVERSION, '3.2.0', 'ge')) { $db = JFactory::getDbo(); // There is no JTable for update_sites, so I have to do that manually... $query = $db->getQuery(true) ->select($db->qn('extra_query')) ->from($db->qn('#__update_sites')) ->where($db->qn('update_site_id') . ' = ' . $db->q($instance->update_site_id)); try { $extra = $db->setQuery($query)->loadResult(); if ($extra) { $url .= '&' . $extra; } } catch (Exception $e) { // Simply do nothing, we'll cross our fingers } } // Download the package $p_file = JInstallerHelper::downloadPackage($url); // Was the package downloaded? if (!$p_file) { JError::raiseWarning('', JText::sprintf('COM_INSTALLER_PACKAGE_DOWNLOAD_FAILED', $url)); return false; } // Store the uploaded package's location $config = JFactory::getConfig(); $tmp_dest = $config->get('tmp_path'); $session->set('compressed_package', $tmp_dest . '/' . $p_file, 'akeeba'); return true; } /** * Searches inside the manifest file for the extension name * * @param SimpleXMLElement $xml XML instance of the manifest file * @param string $type Extension type * * @return array */ private function extractName(SimpleXMLElement $xml, $type) { $name = false; $cname = ''; $group = ''; switch ($type) { case 'component' : case 'file' : case 'library' : case 'package' : case 'template' : $name = (string)$xml->name; if (version_compare(JVERSION, '3.2.0', 'ge')) { $jfilter = new JFilterInput(); $name = $jfilter->clean($name, 'cmd'); } else { $name = JFilterInput::clean($name, 'cmd'); } if ($type == 'template') { $cname = (string)$xml->attributes()->client; } break; case 'module': case 'plugin': $cname = (string)$xml->attributes()->client; $group = (string)$xml->attributes()->group; $element = $xml->files; if (($element instanceof SimpleXMLElement) && $element->count()) { foreach ($element->children() as $file) { if ($file->attributes()->$type) { $name = (string)$file->attributes()->$type; break; } } } break; } return array($name, $cname, $group); } /** * Is the selected extension installed? * * @param SimpleXMLElement $xml XML instance of the manifest file * @param string $type Extension type * @param array $info Indexed array that hold extension information: name, client and group * * @return bool */ private function isInstalled(SimpleXMLElement $xml, $type, $info) { // Make sure the extension is already installed - otherwise there is no point! JLoader::import('joomla.filesystem.file'); JLoader::import('joomla.filesystem.folder'); $db = JFactory::getDbo(); switch ($type) { case 'component': $info['name'] = strtolower($info['name']); if (strpos($info['name'], 'com_') === false) { $info['name'] = 'com_' . $info['name']; } $query = $db->getQuery(true) ->select('COUNT(*)') ->from($db->qn('#__extensions')) ->where($db->qn('element') . ' = ' . $db->q($info['name'])) ->where($db->qn('type') . ' = ' . $db->q('component')); return (bool)$db->setQuery($query)->loadResult(); break; case 'file'; $query = $db->getQuery(true) ->select('COUNT(*)') ->from($db->qn('#__extensions')) ->where($db->qn('element') . ' = ' . $db->q($info['name'])) ->where($db->qn('type') . ' = ' . $db->q('file')); return (bool)$db->setQuery($query)->loadResult(); break; case 'library'; $query = $db->getQuery(true) ->select('COUNT(*)') ->from($db->qn('#__extensions')) ->where($db->qn('element') . ' = ' . $db->q($info['name'])) ->where($db->qn('type') . ' = ' . $db->q('library')); return (bool)$db->setQuery($query)->loadResult(); break; case 'module': $client = $info['cname'] == 'site' ? 1 : 0; $query = $db->getQuery(true) ->select('COUNT(*)') ->from($db->qn('#__extensions')) ->where($db->qn('element') . ' = ' . $db->q($info['name'])) ->where($db->qn('client_id') . ' = ' . $db->q($client)) ->where($db->qn('type') . ' = ' . $db->q('module')); return (bool)$db->setQuery($query)->loadResult(); break; case 'package' : // Package manifest files are a "little" undocumented, so let's try to create // a function that is flexible as much as possible $element = $info['name']; if (strpos($info['name'], 'pkg_') === false) { $element = 'pkg_' . $element; } $query = $db->getQuery(true) ->select('COUNT(*)') ->from($db->qn('#__extensions')) ->where($db->qn('element') . ' = ' . $db->q($element)) ->where($db->qn('type') . ' = ' . $db->q('package')); if ($db->setQuery($query)->loadResult()) { return true; } // No luck with the original name, let's try with the element "packagename" $element = (string)$xml->packagename; if (strpos($info['name'], 'pkg_') === false) { $element = 'pkg_' . $element; } $query->clear('where') ->where($db->qn('element') . ' = ' . $db->q($element)) ->where($db->qn('type') . ' = ' . $db->q('package')); if ($db->setQuery($query)->loadResult()) { return true; } // Still nothing? Ok, maybe it's really not installed return false; break; case 'plugin': $query = $db->getQuery(true) ->select('COUNT(*)') ->from($db->qn('#__extensions')) ->where($db->qn('element') . ' = ' . $db->q($info['name'])) ->where($db->qn('folder') . ' = ' . $db->q($info['group'])) ->where($db->qn('type') . ' = ' . $db->q('plugin')); return (bool)$db->setQuery($query)->loadResult(); break; case 'template': $client = $info['cname'] == 'site' ? 1 : 0; $query = $db->getQuery(true) ->select('COUNT(*)') ->from($db->qn('#__extensions')) ->where($db->qn('element') . ' = ' . $db->q($info['name'])) ->where($db->qn('client_id') . ' = ' . $db->q($client)) ->where($db->qn('type') . ' = ' . $db->q('template')); return (bool)$db->setQuery($query)->loadResult(); break; default: return false; break; } } }