FileFactory.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. <?php
  2. /**
  3. *
  4. * Copyright © Magento, Inc. All rights reserved.
  5. * See COPYING.txt for license details.
  6. */
  7. namespace Magento\Framework\App\Response\Http;
  8. use Magento\Framework\App\Filesystem\DirectoryList;
  9. class FileFactory
  10. {
  11. /**
  12. * @var \Magento\Framework\App\ResponseInterface
  13. */
  14. protected $_response;
  15. /**
  16. * @var \Magento\Framework\Filesystem
  17. */
  18. protected $_filesystem;
  19. /**
  20. * @param \Magento\Framework\App\ResponseInterface $response
  21. * @param \Magento\Framework\Filesystem $filesystem
  22. */
  23. public function __construct(
  24. \Magento\Framework\App\ResponseInterface $response,
  25. \Magento\Framework\Filesystem $filesystem
  26. ) {
  27. $this->_response = $response;
  28. $this->_filesystem = $filesystem;
  29. }
  30. /**
  31. * Declare headers and content file in response for file download
  32. *
  33. * @param string $fileName
  34. * @param string|array $content set to null to avoid starting output, $contentLength should be set explicitly in
  35. * that case
  36. * @param string $baseDir
  37. * @param string $contentType
  38. * @param int $contentLength explicit content length, if strlen($content) isn't applicable
  39. * @throws \Exception
  40. * @throws \InvalidArgumentException
  41. * @return \Magento\Framework\App\ResponseInterface
  42. *
  43. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  44. * @SuppressWarnings(PHPMD.NPathComplexity)
  45. * @SuppressWarnings(PHPMD.ExitExpression)
  46. */
  47. public function create(
  48. $fileName,
  49. $content,
  50. $baseDir = DirectoryList::ROOT,
  51. $contentType = 'application/octet-stream',
  52. $contentLength = null
  53. ) {
  54. $dir = $this->_filesystem->getDirectoryWrite($baseDir);
  55. $isFile = false;
  56. $file = null;
  57. $fileContent = $this->getFileContent($content);
  58. if (is_array($content)) {
  59. if (!isset($content['type']) || !isset($content['value'])) {
  60. throw new \InvalidArgumentException("Invalid arguments. Keys 'type' and 'value' are required.");
  61. }
  62. if ($content['type'] == 'filename') {
  63. $isFile = true;
  64. $file = $content['value'];
  65. if (!$dir->isFile($file)) {
  66. throw new \Exception((string)new \Magento\Framework\Phrase('File not found'));
  67. }
  68. $contentLength = $dir->stat($file)['size'];
  69. }
  70. }
  71. $this->_response->setHttpResponseCode(200)
  72. ->setHeader('Pragma', 'public', true)
  73. ->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0', true)
  74. ->setHeader('Content-type', $contentType, true)
  75. ->setHeader('Content-Length', $contentLength === null ? strlen($fileContent) : $contentLength, true)
  76. ->setHeader('Content-Disposition', 'attachment; filename="' . $fileName . '"', true)
  77. ->setHeader('Last-Modified', date('r'), true);
  78. if ($content !== null) {
  79. $this->_response->sendHeaders();
  80. if ($isFile) {
  81. $stream = $dir->openFile($file, 'r');
  82. while (!$stream->eof()) {
  83. echo $stream->read(1024);
  84. }
  85. } else {
  86. $dir->writeFile($fileName, $fileContent);
  87. $file = $fileName;
  88. $stream = $dir->openFile($fileName, 'r');
  89. while (!$stream->eof()) {
  90. echo $stream->read(1024);
  91. }
  92. }
  93. $stream->close();
  94. flush();
  95. if (!empty($content['rm'])) {
  96. $dir->delete($file);
  97. }
  98. }
  99. return $this->_response;
  100. }
  101. /**
  102. * Returns file content for writing.
  103. *
  104. * @param string|array $content
  105. * @return string|array
  106. */
  107. private function getFileContent($content)
  108. {
  109. if (isset($content['type']) && $content['type'] === 'string') {
  110. return $content['value'];
  111. }
  112. return $content;
  113. }
  114. }