PageRenderTime 25ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

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

https://gitlab.com/LisovyiEvhenii/ismextensions
PHP | 317 lines | 192 code | 28 blank | 97 comment | 54 complexity | 3c298ba201ccc8d74bc52c2e49390af8 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@magento.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.magento.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Downloadable
  23. * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.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. /**
  87. * Validate URL
  88. */
  89. $urlProp = parse_url($this->_resourceFile);
  90. if (!isset($urlProp['scheme'])
  91. || strtolower($urlProp['scheme'] != 'http') && strtolower($urlProp['scheme'] != 'https')) {
  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. switch ($urlProp['scheme']) {
  98. case 'https':
  99. $scheme = 'ssl://';
  100. $port = 443;
  101. break;
  102. case 'http':
  103. default:
  104. $scheme = '';
  105. $port = 80;
  106. }
  107. $hostname = $scheme . $urlProp['host'];
  108. if (isset($urlProp['port'])) {
  109. $port = (int)$urlProp['port'];
  110. }
  111. $path = '/';
  112. if (isset($urlProp['path'])) {
  113. $path = $urlProp['path'];
  114. }
  115. $query = '';
  116. if (isset($urlProp['query'])) {
  117. $query = '?' . $urlProp['query'];
  118. }
  119. try {
  120. $this->_handle = fsockopen($hostname, $port, $errno, $errstr);
  121. }
  122. catch (Exception $e) {
  123. throw $e;
  124. }
  125. if ($this->_handle === false) {
  126. Mage::throwException(Mage::helper('downloadable')->__('Cannot connect to remote host, error: %s.', $errstr));
  127. }
  128. $headers = 'GET ' . $path . $query . ' HTTP/1.0' . "\r\n"
  129. . 'Host: ' . $urlProp['host'] . "\r\n"
  130. . 'User-Agent: Magento ver/' . Mage::getVersion() . "\r\n"
  131. . 'Connection: close' . "\r\n"
  132. . "\r\n";
  133. fwrite($this->_handle, $headers);
  134. while (!feof($this->_handle)) {
  135. $str = fgets($this->_handle, 1024);
  136. if ($str == "\r\n") {
  137. break;
  138. }
  139. $match = array();
  140. if (preg_match('#^([^:]+): (.*)\s+$#', $str, $match)) {
  141. $k = strtolower($match[1]);
  142. if ($k == 'set-cookie') {
  143. continue;
  144. }
  145. else {
  146. $this->_urlHeaders[$k] = trim($match[2]);
  147. }
  148. }
  149. elseif (preg_match('#^HTTP/[0-9\.]+ (\d+) (.*)\s$#', $str, $match)) {
  150. $this->_urlHeaders['code'] = $match[1];
  151. $this->_urlHeaders['code-string'] = trim($match[2]);
  152. }
  153. }
  154. if (!isset($this->_urlHeaders['code']) || $this->_urlHeaders['code'] != 200) {
  155. Mage::throwException(Mage::helper('downloadable')->__('An error occurred while getting the requested content. Please contact the store owner.'));
  156. }
  157. }
  158. elseif ($this->_linkType == self::LINK_TYPE_FILE) {
  159. $this->_handle = new Varien_Io_File();
  160. if (!is_file($this->_resourceFile)) {
  161. Mage::helper('core/file_storage_database')->saveFileToFilesystem($this->_resourceFile);
  162. }
  163. $this->_handle->open(array('path'=>Mage::getBaseDir('var')));
  164. if (!$this->_handle->fileExists($this->_resourceFile, true)) {
  165. Mage::throwException(Mage::helper('downloadable')->__('The file does not exist.'));
  166. }
  167. $this->_handle->streamOpen($this->_resourceFile, 'r');
  168. }
  169. else {
  170. Mage::throwException(Mage::helper('downloadable')->__('Invalid download link type.'));
  171. }
  172. }
  173. return $this->_handle;
  174. }
  175. /**
  176. * Retrieve file size in bytes
  177. */
  178. public function getFilesize()
  179. {
  180. $handle = $this->_getHandle();
  181. if ($this->_linkType == self::LINK_TYPE_FILE) {
  182. return $handle->streamStat('size');
  183. }
  184. elseif ($this->_linkType == self::LINK_TYPE_URL) {
  185. if (isset($this->_urlHeaders['content-length'])) {
  186. return $this->_urlHeaders['content-length'];
  187. }
  188. }
  189. return null;
  190. }
  191. public function getContentType()
  192. {
  193. $handle = $this->_getHandle();
  194. if ($this->_linkType == self::LINK_TYPE_FILE) {
  195. if (function_exists('mime_content_type') && ($contentType = mime_content_type($this->_resourceFile))) {
  196. return $contentType;
  197. } else {
  198. return Mage::helper('downloadable/file')->getFileType($this->_resourceFile);
  199. }
  200. }
  201. elseif ($this->_linkType == self::LINK_TYPE_URL) {
  202. if (isset($this->_urlHeaders['content-type'])) {
  203. $contentType = explode('; ', $this->_urlHeaders['content-type']);
  204. return $contentType[0];
  205. }
  206. }
  207. return $this->_contentType;
  208. }
  209. public function getFilename()
  210. {
  211. $handle = $this->_getHandle();
  212. if ($this->_linkType == self::LINK_TYPE_FILE) {
  213. return pathinfo($this->_resourceFile, PATHINFO_BASENAME);
  214. }
  215. elseif ($this->_linkType == self::LINK_TYPE_URL) {
  216. if (isset($this->_urlHeaders['content-disposition'])) {
  217. $contentDisposition = explode('; ', $this->_urlHeaders['content-disposition']);
  218. if (!empty($contentDisposition[1]) && strpos($contentDisposition[1], 'filename=') !== false) {
  219. return substr($contentDisposition[1], 9);
  220. }
  221. }
  222. if ($fileName = @pathinfo($this->_resourceFile, PATHINFO_BASENAME)) {
  223. return $fileName;
  224. }
  225. }
  226. return $this->_fileName;
  227. }
  228. /**
  229. * Set resource file for download
  230. *
  231. * @param string $resourceFile
  232. * @param string $linkType
  233. * @return Mage_Downloadable_Helper_Download
  234. */
  235. public function setResource($resourceFile, $linkType = self::LINK_TYPE_FILE)
  236. {
  237. if (self::LINK_TYPE_FILE == $linkType) {
  238. //check LFI protection
  239. /** @var $helper Mage_Core_Helper_Data */
  240. $helper = Mage::helper('core');
  241. $helper->checkLfiProtection($resourceFile);
  242. }
  243. $this->_resourceFile = $resourceFile;
  244. $this->_linkType = $linkType;
  245. return $this;
  246. }
  247. /**
  248. * Retrieve Http Request Object
  249. *
  250. * @return Mage_Core_Controller_Request_Http
  251. */
  252. public function getHttpRequest()
  253. {
  254. return Mage::app()->getFrontController()->getRequest();
  255. }
  256. /**
  257. * Retrieve Http Response Object
  258. *
  259. * @return Mage_Core_Controller_Response_Http
  260. */
  261. public function getHttpResponse()
  262. {
  263. return Mage::app()->getFrontController()->getResponse();
  264. }
  265. public function output()
  266. {
  267. $handle = $this->_getHandle();
  268. if ($this->_linkType == self::LINK_TYPE_FILE) {
  269. while ($buffer = $handle->streamRead()) {
  270. print $buffer;
  271. }
  272. }
  273. elseif ($this->_linkType == self::LINK_TYPE_URL) {
  274. while (!feof($handle)) {
  275. print fgets($handle, 1024);
  276. }
  277. }
  278. }
  279. /**
  280. * Use Content-Disposition: attachment
  281. *
  282. * @param mixed $store
  283. * @return bool
  284. */
  285. public function getContentDisposition($store = null)
  286. {
  287. return Mage::getStoreConfig(self::XML_PATH_CONTENT_DISPOSITION, $store);
  288. }
  289. }