PageRenderTime 55ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/app/code/core/Mage/Downloadable/Helper/Download.php

https://bitbucket.org/dnejedly/eaparts
PHP | 307 lines | 182 code | 28 blank | 97 comment | 51 complexity | c6ad88b41b37b8fc8a1c843769420178 MD5 | raw file
  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magentocommerce.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magentocommerce.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Downloadable
  23. * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * Downloadable Products Download Helper
  28. *
  29. * @category Mage
  30. * @package Mage_Downloadable
  31. * @author Magento Core Team <core@magentocommerce.com>
  32. */
  33. class Mage_Downloadable_Helper_Download extends Mage_Core_Helper_Abstract
  34. {
  35. const LINK_TYPE_URL = 'url';
  36. const LINK_TYPE_FILE = 'file';
  37. const XML_PATH_CONTENT_DISPOSITION = 'catalog/downloadable/content_disposition';
  38. /**
  39. * Type of link
  40. *
  41. * @var string
  42. */
  43. protected $_linkType = self::LINK_TYPE_FILE;
  44. /**
  45. * Resource file
  46. *
  47. * @var string
  48. */
  49. protected $_resourceFile = null;
  50. /**
  51. * Resource open handle
  52. *
  53. * @var resource
  54. */
  55. protected $_handle = null;
  56. /**
  57. * Remote server headers
  58. *
  59. * @var array
  60. */
  61. protected $_urlHeaders = array();
  62. /**
  63. * MIME Content-type for a file
  64. *
  65. * @var string
  66. */
  67. protected $_contentType = 'application/octet-stream';
  68. /**
  69. * File name
  70. *
  71. * @var string
  72. */
  73. protected $_fileName = 'download';
  74. /**
  75. * Retrieve Resource file handle (socket, file pointer etc)
  76. *
  77. * @return resource
  78. */
  79. protected function _getHandle()
  80. {
  81. if (!$this->_resourceFile) {
  82. Mage::throwException(Mage::helper('downloadable')->__('Please set resource file and link type.'));
  83. }
  84. if (is_null($this->_handle)) {
  85. if ($this->_linkType == self::LINK_TYPE_URL) {
  86. $port = 80;
  87. /**
  88. * Validate URL
  89. */
  90. $urlProp = parse_url($this->_resourceFile);
  91. if (!isset($urlProp['scheme']) || strtolower($urlProp['scheme'] != 'http')) {
  92. Mage::throwException(Mage::helper('downloadable')->__('Invalid download URL scheme.'));
  93. }
  94. if (!isset($urlProp['host'])) {
  95. Mage::throwException(Mage::helper('downloadable')->__('Invalid download URL host.'));
  96. }
  97. $hostname = $urlProp['host'];
  98. if (isset($urlProp['port'])) {
  99. $port = (int)$urlProp['port'];
  100. }
  101. $path = '/';
  102. if (isset($urlProp['path'])) {
  103. $path = $urlProp['path'];
  104. }
  105. $query = '';
  106. if (isset($urlProp['query'])) {
  107. $query = '?' . $urlProp['query'];
  108. }
  109. try {
  110. $this->_handle = fsockopen($hostname, $port, $errno, $errstr);
  111. }
  112. catch (Exception $e) {
  113. throw $e;
  114. }
  115. if ($this->_handle === false) {
  116. Mage::throwException(Mage::helper('downloadable')->__('Cannot connect to remote host, error: %s.', $errstr));
  117. }
  118. $headers = 'GET ' . $path . $query . ' HTTP/1.0' . "\r\n"
  119. . 'Host: ' . $hostname . "\r\n"
  120. . 'User-Agent: Magento ver/' . Mage::getVersion() . "\r\n"
  121. . 'Connection: close' . "\r\n"
  122. . "\r\n";
  123. fwrite($this->_handle, $headers);
  124. while (!feof($this->_handle)) {
  125. $str = fgets($this->_handle, 1024);
  126. if ($str == "\r\n") {
  127. break;
  128. }
  129. $match = array();
  130. if (preg_match('#^([^:]+): (.*)\s+$#', $str, $match)) {
  131. $k = strtolower($match[1]);
  132. if ($k == 'set-cookie') {
  133. continue;
  134. }
  135. else {
  136. $this->_urlHeaders[$k] = trim($match[2]);
  137. }
  138. }
  139. elseif (preg_match('#^HTTP/[0-9\.]+ (\d+) (.*)\s$#', $str, $match)) {
  140. $this->_urlHeaders['code'] = $match[1];
  141. $this->_urlHeaders['code-string'] = trim($match[2]);
  142. }
  143. }
  144. if (!isset($this->_urlHeaders['code']) || $this->_urlHeaders['code'] != 200) {
  145. Mage::throwException(Mage::helper('downloadable')->__('An error occurred while getting the requested content. Please contact the store owner.'));
  146. }
  147. }
  148. elseif ($this->_linkType == self::LINK_TYPE_FILE) {
  149. $this->_handle = new Varien_Io_File();
  150. if (!is_file($this->_resourceFile)) {
  151. Mage::helper('core/file_storage_database')->saveFileToFilesystem($this->_resourceFile);
  152. }
  153. $this->_handle->open(array('path'=>Mage::getBaseDir('var')));
  154. if (!$this->_handle->fileExists($this->_resourceFile, true)) {
  155. Mage::throwException(Mage::helper('downloadable')->__('The file does not exist.'));
  156. }
  157. $this->_handle->streamOpen($this->_resourceFile, 'r');
  158. }
  159. else {
  160. Mage::throwException(Mage::helper('downloadable')->__('Invalid download link type.'));
  161. }
  162. }
  163. return $this->_handle;
  164. }
  165. /**
  166. * Retrieve file size in bytes
  167. */
  168. public function getFilesize()
  169. {
  170. $handle = $this->_getHandle();
  171. if ($this->_linkType == self::LINK_TYPE_FILE) {
  172. return $handle->streamStat('size');
  173. }
  174. elseif ($this->_linkType == self::LINK_TYPE_URL) {
  175. if (isset($this->_urlHeaders['content-length'])) {
  176. return $this->_urlHeaders['content-length'];
  177. }
  178. }
  179. return null;
  180. }
  181. public function getContentType()
  182. {
  183. $handle = $this->_getHandle();
  184. if ($this->_linkType == self::LINK_TYPE_FILE) {
  185. if (function_exists('mime_content_type') && ($contentType = mime_content_type($this->_resourceFile))) {
  186. return $contentType;
  187. } else {
  188. return Mage::helper('downloadable/file')->getFileType($this->_resourceFile);
  189. }
  190. }
  191. elseif ($this->_linkType == self::LINK_TYPE_URL) {
  192. if (isset($this->_urlHeaders['content-type'])) {
  193. $contentType = explode('; ', $this->_urlHeaders['content-type']);
  194. return $contentType[0];
  195. }
  196. }
  197. return $this->_contentType;
  198. }
  199. public function getFilename()
  200. {
  201. $handle = $this->_getHandle();
  202. if ($this->_linkType == self::LINK_TYPE_FILE) {
  203. return pathinfo($this->_resourceFile, PATHINFO_BASENAME);
  204. }
  205. elseif ($this->_linkType == self::LINK_TYPE_URL) {
  206. if (isset($this->_urlHeaders['content-disposition'])) {
  207. $contentDisposition = explode('; ', $this->_urlHeaders['content-disposition']);
  208. if (!empty($contentDisposition[1]) && strpos($contentDisposition[1], 'filename=') !== false) {
  209. return substr($contentDisposition[1], 9);
  210. }
  211. }
  212. if ($fileName = @pathinfo($this->_resourceFile, PATHINFO_BASENAME)) {
  213. return $fileName;
  214. }
  215. }
  216. return $this->_fileName;
  217. }
  218. /**
  219. * Set resource file for download
  220. *
  221. * @param string $resourceFile
  222. * @param string $linkType
  223. * @return Mage_Downloadable_Helper_Download
  224. */
  225. public function setResource($resourceFile, $linkType = self::LINK_TYPE_FILE)
  226. {
  227. if (self::LINK_TYPE_FILE == $linkType) {
  228. //check LFI protection
  229. /** @var $helper Mage_Core_Helper_Data */
  230. $helper = Mage::helper('core');
  231. $helper->checkLfiProtection($resourceFile);
  232. }
  233. $this->_resourceFile = $resourceFile;
  234. $this->_linkType = $linkType;
  235. return $this;
  236. }
  237. /**
  238. * Retrieve Http Request Object
  239. *
  240. * @return Mage_Core_Controller_Request_Http
  241. */
  242. public function getHttpRequest()
  243. {
  244. return Mage::app()->getFrontController()->getRequest();
  245. }
  246. /**
  247. * Retrieve Http Response Object
  248. *
  249. * @return Mage_Core_Controller_Response_Http
  250. */
  251. public function getHttpResponse()
  252. {
  253. return Mage::app()->getFrontController()->getResponse();
  254. }
  255. public function output()
  256. {
  257. $handle = $this->_getHandle();
  258. if ($this->_linkType == self::LINK_TYPE_FILE) {
  259. while ($buffer = $handle->streamRead()) {
  260. print $buffer;
  261. }
  262. }
  263. elseif ($this->_linkType == self::LINK_TYPE_URL) {
  264. while (!feof($handle)) {
  265. print fgets($handle, 1024);
  266. }
  267. }
  268. }
  269. /**
  270. * Use Content-Disposition: attachment
  271. *
  272. * @param mixed $store
  273. * @return bool
  274. */
  275. public function getContentDisposition($store = null)
  276. {
  277. return Mage::getStoreConfig(self::XML_PATH_CONTENT_DISPOSITION, $store);
  278. }
  279. }