PageRenderTime 39ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/magento/module-downloadable/Helper/Download.php

https://gitlab.com/yousafsyed/easternglamor
PHP | 287 lines | 138 code | 29 blank | 120 comment | 27 complexity | 5d34578d20336a21e1d16d341a57d7a8 MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright © 2016 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. // @codingStandardsIgnoreFile
  7. namespace Magento\Downloadable\Helper;
  8. use Magento\Framework\App\Filesystem\DirectoryList;
  9. use Magento\Framework\Filesystem;
  10. use Magento\Framework\Exception\LocalizedException as CoreException;
  11. /**
  12. * Downloadable Products Download Helper
  13. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  14. */
  15. class Download extends \Magento\Framework\App\Helper\AbstractHelper
  16. {
  17. /**
  18. * Link type url
  19. */
  20. const LINK_TYPE_URL = 'url';
  21. /**
  22. * Link type file
  23. */
  24. const LINK_TYPE_FILE = 'file';
  25. /**
  26. * Config path to content disposition
  27. */
  28. const XML_PATH_CONTENT_DISPOSITION = 'catalog/downloadable/content_disposition';
  29. /**
  30. * Type of link
  31. *
  32. * @var string
  33. */
  34. protected $_linkType = self::LINK_TYPE_FILE;
  35. /**
  36. * Resource file
  37. *
  38. * @var string
  39. */
  40. protected $_resourceFile = null;
  41. /**
  42. * Resource open handle
  43. *
  44. * @var \Magento\Framework\Filesystem\File\ReadInterface
  45. */
  46. protected $_handle = null;
  47. /**
  48. * Remote server headers
  49. *
  50. * @var array
  51. */
  52. protected $_urlHeaders = [];
  53. /**
  54. * MIME Content-type for a file
  55. *
  56. * @var string
  57. */
  58. protected $_contentType = 'application/octet-stream';
  59. /**
  60. * File name
  61. *
  62. * @var string
  63. */
  64. protected $_fileName = 'download';
  65. /**
  66. * Core file storage database
  67. *
  68. * @var \Magento\MediaStorage\Helper\File\Storage\Database
  69. */
  70. protected $_coreFileStorageDb;
  71. /**
  72. * Downloadable file
  73. *
  74. * @var \Magento\Downloadable\Helper\File
  75. */
  76. protected $_downloadableFile;
  77. /**
  78. * @var \Magento\Framework\Filesystem
  79. */
  80. protected $_filesystem;
  81. /** @var Filesystem\File\ReadFactory */
  82. protected $fileReadFactory;
  83. /**
  84. * Working Directory (valid for LINK_TYPE_FILE only).
  85. * @var \Magento\Framework\Filesystem\Directory\Read
  86. */
  87. protected $_workingDirectory;
  88. /**
  89. * @var \Magento\Framework\Session\SessionManagerInterface
  90. */
  91. protected $_session;
  92. /**
  93. * @param \Magento\Framework\App\Helper\Context $context
  94. * @param File $downloadableFile
  95. * @param \Magento\MediaStorage\Helper\File\Storage\Database $coreFileStorageDb
  96. * @param Filesystem $filesystem
  97. * @param \Magento\Framework\Session\SessionManagerInterface $session
  98. * @param Filesystem\File\ReadFactory $fileReadFactory
  99. */
  100. public function __construct(
  101. \Magento\Framework\App\Helper\Context $context,
  102. \Magento\Downloadable\Helper\File $downloadableFile,
  103. \Magento\MediaStorage\Helper\File\Storage\Database $coreFileStorageDb,
  104. \Magento\Framework\Filesystem $filesystem,
  105. \Magento\Framework\Session\SessionManagerInterface $session,
  106. \Magento\Framework\Filesystem\File\ReadFactory $fileReadFactory
  107. ) {
  108. parent::__construct($context);
  109. $this->_downloadableFile = $downloadableFile;
  110. $this->_coreFileStorageDb = $coreFileStorageDb;
  111. $this->_filesystem = $filesystem;
  112. $this->_session = $session;
  113. $this->fileReadFactory = $fileReadFactory;
  114. }
  115. /**
  116. * Retrieve Resource file handle (socket, file pointer etc)
  117. *
  118. * @return \Magento\Framework\Filesystem\File\ReadInterface
  119. * @throws CoreException|\Exception
  120. */
  121. protected function _getHandle()
  122. {
  123. if (!$this->_resourceFile) {
  124. throw new CoreException(__('Please set resource file and link type.'));
  125. }
  126. if (is_null($this->_handle)) {
  127. if ($this->_linkType == self::LINK_TYPE_URL) {
  128. $path = $this->_resourceFile;
  129. $protocol = strtolower(parse_url($path, PHP_URL_SCHEME));
  130. if ($protocol) {
  131. // Strip down protocol from path
  132. $path = preg_replace('#.+://#', '', $path);
  133. }
  134. $this->_handle = $this->fileReadFactory->create($path, $protocol);
  135. } elseif ($this->_linkType == self::LINK_TYPE_FILE) {
  136. $this->_workingDirectory = $this->_filesystem->getDirectoryRead(DirectoryList::MEDIA);
  137. $fileExists = $this->_downloadableFile->ensureFileInFilesystem($this->_resourceFile);
  138. if ($fileExists) {
  139. $this->_handle = $this->_workingDirectory->openFile($this->_resourceFile);
  140. } else {
  141. throw new CoreException(__('Invalid download link type.'));
  142. }
  143. } else {
  144. throw new CoreException(__('Invalid download link type.'));
  145. }
  146. }
  147. return $this->_handle;
  148. }
  149. /**
  150. * Retrieve file size in bytes
  151. *
  152. * @return int
  153. */
  154. public function getFileSize()
  155. {
  156. return $this->_getHandle()->stat($this->_resourceFile)['size'];
  157. }
  158. /**
  159. * Return MIME type of a file.
  160. *
  161. * @return string
  162. */
  163. public function getContentType()
  164. {
  165. $this->_getHandle();
  166. if ($this->_linkType == self::LINK_TYPE_FILE) {
  167. if (function_exists(
  168. 'mime_content_type'
  169. ) && ($contentType = mime_content_type(
  170. $this->_workingDirectory->getAbsolutePath($this->_resourceFile)
  171. ))
  172. ) {
  173. return $contentType;
  174. } else {
  175. return $this->_downloadableFile->getFileType($this->_resourceFile);
  176. }
  177. } elseif ($this->_linkType == self::LINK_TYPE_URL) {
  178. return $this->_handle->stat($this->_resourceFile)['type'];
  179. }
  180. return $this->_contentType;
  181. }
  182. /**
  183. * Return name of the file
  184. *
  185. * @return string
  186. */
  187. public function getFilename()
  188. {
  189. $this->_getHandle();
  190. if ($this->_linkType == self::LINK_TYPE_FILE) {
  191. return pathinfo($this->_resourceFile, PATHINFO_BASENAME);
  192. } elseif ($this->_linkType == self::LINK_TYPE_URL) {
  193. $stat = $this->_handle->stat($this->_resourceFile);
  194. if (isset($stat['disposition'])) {
  195. $contentDisposition = explode('; ', $stat['disposition']);
  196. if (!empty($contentDisposition[1]) && preg_match(
  197. '/filename=([^ ]+)/',
  198. $contentDisposition[1],
  199. $matches
  200. )
  201. ) {
  202. return $matches[1];
  203. }
  204. }
  205. $fileName = @pathinfo($this->_resourceFile, PATHINFO_BASENAME);
  206. if ($fileName) {
  207. return $fileName;
  208. }
  209. }
  210. return $this->_fileName;
  211. }
  212. /**
  213. * Set resource file for download
  214. *
  215. * @param string $resourceFile
  216. * @param string $linkType
  217. * @return $this
  218. * @throws \InvalidArgumentException
  219. */
  220. public function setResource($resourceFile, $linkType = self::LINK_TYPE_FILE)
  221. {
  222. if (self::LINK_TYPE_FILE == $linkType) {
  223. //check LFI protection
  224. if (preg_match('#\.\.[\\\/]#', $resourceFile)) {
  225. throw new \InvalidArgumentException(
  226. 'Requested file may not include parent directory traversal ("../", "..\\" notation)'
  227. );
  228. }
  229. }
  230. $this->_resourceFile = $resourceFile;
  231. $this->_linkType = $linkType;
  232. return $this;
  233. }
  234. /**
  235. * Output file contents
  236. *
  237. * @return void
  238. */
  239. public function output()
  240. {
  241. $handle = $this->_getHandle();
  242. $this->_session->writeClose();
  243. while (true == ($buffer = $handle->read(1024))) {
  244. echo $buffer;
  245. }
  246. }
  247. /**
  248. * Use Content-Disposition: attachment
  249. *
  250. * @param mixed $store
  251. * @return bool
  252. * @SuppressWarnings(PHPMD.BooleanGetMethodName)
  253. */
  254. public function getContentDisposition($store = null)
  255. {
  256. return $this->scopeConfig->getValue(self::XML_PATH_CONTENT_DISPOSITION, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store);
  257. }
  258. }