PageRenderTime 23ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/joomla/installer/helper.php

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