PageRenderTime 48ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/libraries/joomla/installer/helper.php

https://github.com/FullService/joomla
PHP | 274 lines | 241 code | 7 blank | 26 comment | 3 complexity | f849bb3a988f1c1bb20df135a20ed2bd MD5 | raw file
  1. <?php
  2. /**
  3. * @version $Id$
  4. * @copyright Copyright (C) 2005 - 2010 Open Source Matters, Inc. All rights reserved.
  5. * @license GNU General Public License version 2 or later; see LICENSE.txt
  6. */
  7. // No direct access
  8. defined('JPATH_BASE') or die;
  9. jimport('joomla.filesystem.file');
  10. jimport('joomla.filesystem.folder');
  11. jimport('joomla.filesystem.archive');
  12. jimport('joomla.filesystem.path');
  13. /**
  14. * Installer helper class
  15. *
  16. * @static
  17. * @package Joomla.Framework
  18. * @subpackage Installer
  19. * @since 1.5
  20. */
  21. class JInstallerHelper
  22. {
  23. /**
  24. * Downloads a package
  25. *
  26. * @static
  27. * @param string URL of file to download
  28. * @param string Download target filename [optional]
  29. * @return mixed Path to downloaded package or boolean false on failure
  30. * @since 1.5
  31. */
  32. function downloadPackage($url, $target = false)
  33. {
  34. $config = JFactory::getConfig();
  35. // Capture PHP errors
  36. $php_errormsg = 'Error Unknown';
  37. $track_errors = ini_get('track_errors');
  38. ini_set('track_errors', true);
  39. // Set user agent
  40. jimport('joomla.version');
  41. $version = new JVersion();
  42. ini_set('user_agent', $version->getUserAgent('Installer'));
  43. // Open the remote server socket for reading
  44. $inputHandle = @ fopen($url, "r");
  45. $error = strstr($php_errormsg,'failed to open stream:');
  46. if (!$inputHandle) {
  47. JError::raiseWarning(42, JText::sprintf('JLIB_INSTALLER_ERROR_DOWNLOAD_SERVER_CONNECT', $error));
  48. return false;
  49. }
  50. $meta_data = stream_get_meta_data($inputHandle);
  51. foreach ($meta_data['wrapper_data'] as $wrapper_data)
  52. {
  53. if (substr($wrapper_data, 0, strlen("Content-Disposition")) == "Content-Disposition")
  54. {
  55. $contentfilename = explode ("\"", $wrapper_data);
  56. $target = $contentfilename[1];
  57. }
  58. }
  59. // Set the target path if not given
  60. if (!$target) {
  61. $target = $config->get('tmp_path').DS.JInstallerHelper::getFilenameFromURL($url);
  62. }
  63. else {
  64. $target = $config->get('tmp_path').DS.basename($target);
  65. }
  66. // Initialise contents buffer
  67. $contents = null;
  68. while (!feof($inputHandle))
  69. {
  70. $contents .= fread($inputHandle, 4096);
  71. if ($contents == false)
  72. {
  73. JError::raiseWarning(44, JText::sprintf('JLIB_INSTALLER_ERROR_FAILED_READING_NETWORK_RESOURCES', $php_errormsg));
  74. return false;
  75. }
  76. }
  77. // Write buffer to file
  78. JFile::write($target, $contents);
  79. // Close file pointer resource
  80. fclose($inputHandle);
  81. // restore error tracking to what it was before
  82. ini_set('track_errors',$track_errors);
  83. // Return the name of the downloaded package
  84. return basename($target);
  85. }
  86. /**
  87. * Unpacks a file and verifies it as a Joomla element package
  88. * Supports .gz .tar .tar.gz and .zip
  89. *
  90. * @static
  91. * @param string $p_filename The uploaded package filename or install directory
  92. * @return Array Two elements - extractdir and packagefile
  93. * @since 1.5
  94. */
  95. function unpack($p_filename)
  96. {
  97. // Path to the archive
  98. $archivename = $p_filename;
  99. // Temporary folder to extract the archive into
  100. $tmpdir = uniqid('install_');
  101. // Clean the paths to use for archive extraction
  102. $extractdir = JPath::clean(dirname($p_filename).DS.$tmpdir);
  103. $archivename = JPath::clean($archivename);
  104. // do the unpacking of the archive
  105. $result = JArchive::extract($archivename, $extractdir);
  106. if ($result === false) {
  107. return false;
  108. }
  109. /*
  110. * Lets set the extraction directory and package file in the result array so we can
  111. * cleanup everything properly later on.
  112. */
  113. $retval['extractdir'] = $extractdir;
  114. $retval['packagefile'] = $archivename;
  115. /*
  116. * Try to find the correct install directory. In case the package is inside a
  117. * subdirectory detect this and set the install directory to the correct path.
  118. *
  119. * List all the items in the installation directory. If there is only one, and
  120. * it is a folder, then we will set that folder to be the installation folder.
  121. */
  122. $dirList = array_merge(JFolder::files($extractdir, ''), JFolder::folders($extractdir, ''));
  123. if (count($dirList) == 1)
  124. {
  125. if (JFolder::exists($extractdir.DS.$dirList[0]))
  126. {
  127. $extractdir = JPath::clean($extractdir.DS.$dirList[0]);
  128. }
  129. }
  130. /*
  131. * We have found the install directory so lets set it and then move on
  132. * to detecting the extension type.
  133. */
  134. $retval['dir'] = $extractdir;
  135. /*
  136. * Get the extension type and return the directory/type array on success or
  137. * false on fail.
  138. */
  139. if ($retval['type'] = JInstallerHelper::detectType($extractdir)) {
  140. return $retval;
  141. }
  142. else {
  143. return false;
  144. }
  145. }
  146. /**
  147. * Method to detect the extension type from a package directory
  148. *
  149. * @static
  150. * @param string $p_dir Path to package directory
  151. * @return mixed Extension type string or boolean false on fail
  152. * @since 1.5
  153. */
  154. function detectType($p_dir)
  155. {
  156. // Search the install dir for an xml file
  157. $files = JFolder::files($p_dir, '\.xml$', 1, true);
  158. if ( ! count($files))
  159. {
  160. JError::raiseWarning(1, JText::_('JLIB_INSTALLER_ERROR_NOTFINDXMLSETUPFILE'));
  161. return false;
  162. }
  163. foreach ($files as $file)
  164. {
  165. if( ! $xml = JFactory::getXML($file))
  166. {
  167. continue;
  168. }
  169. if($xml->getName() != 'install' && $xml->getName() != 'extension')
  170. {
  171. unset($xml);
  172. continue;
  173. }
  174. $type = (string)$xml->attributes()->type;
  175. // Free up memory
  176. unset ($xml);
  177. return $type;
  178. }
  179. JError::raiseWarning(1, JText::_('JLIB_INSTALLER_ERROR_NOTFINDJOOMLAXMLSETUPFILE'));
  180. // Free up memory.
  181. unset ($xml);
  182. return false;
  183. }
  184. /**
  185. * Gets a file name out of a url
  186. *
  187. * @static
  188. * @param string $url URL to get name from
  189. * @return mixed String filename or boolean false if failed
  190. * @since 1.5
  191. */
  192. function getFilenameFromURL($url)
  193. {
  194. if (is_string($url))
  195. {
  196. $parts = explode('/', $url);
  197. return $parts[count($parts) - 1];
  198. }
  199. return false;
  200. }
  201. /**
  202. * Clean up temporary uploaded package and unpacked extension
  203. *
  204. * @static
  205. * @param string $package Path to the uploaded package file
  206. * @param string $resultdir Path to the unpacked extension
  207. * @return boolean True on success
  208. * @since 1.5
  209. */
  210. function cleanupInstall($package, $resultdir)
  211. {
  212. $config = JFactory::getConfig();
  213. // Does the unpacked extension directory exist?
  214. if (is_dir($resultdir)) {
  215. JFolder::delete($resultdir);
  216. }
  217. // Is the package file a valid file?
  218. if (is_file($package)) {
  219. JFile::delete($package);
  220. }
  221. elseif (is_file(JPath::clean($config->get('tmp_path').DS.$package)))
  222. {
  223. // It might also be just a base filename
  224. JFile::delete(JPath::clean($config->get('tmp_path').DS.$package));
  225. }
  226. }
  227. /**
  228. * Splits contents of a sql file into array of discreet queries
  229. * queries need to be delimited with end of statement marker ';'
  230. * @param string
  231. * @return array
  232. */
  233. function splitSql($sql)
  234. {
  235. $db = JFactory::getDbo();
  236. return $db->splitSql($sql);
  237. }
  238. }