Dashboard sipadu mbip
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DataPart.php 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Mime\Part;
  11. use Symfony\Component\Mime\Exception\InvalidArgumentException;
  12. use Symfony\Component\Mime\Header\Headers;
  13. use Symfony\Component\Mime\MimeTypes;
  14. /**
  15. * @author Fabien Potencier <fabien@symfony.com>
  16. *
  17. * @experimental in 4.3
  18. */
  19. class DataPart extends TextPart
  20. {
  21. private static $mimeTypes;
  22. private $filename;
  23. private $mediaType;
  24. private $cid;
  25. private $handle;
  26. /**
  27. * @param resource|string $body
  28. */
  29. public function __construct($body, string $filename = null, string $contentType = null, string $encoding = null)
  30. {
  31. if (null === $contentType) {
  32. $contentType = 'application/octet-stream';
  33. }
  34. list($this->mediaType, $subtype) = explode('/', $contentType);
  35. parent::__construct($body, null, $subtype, $encoding);
  36. $this->filename = $filename;
  37. $this->setName($filename);
  38. $this->setDisposition('attachment');
  39. }
  40. public static function fromPath(string $path, string $name = null, string $contentType = null): self
  41. {
  42. // FIXME: if file is not readable, exception?
  43. if (null === $contentType) {
  44. $ext = strtolower(substr($path, strrpos($path, '.') + 1));
  45. if (null === self::$mimeTypes) {
  46. self::$mimeTypes = new MimeTypes();
  47. }
  48. $contentType = self::$mimeTypes->getMimeTypes($ext)[0] ?? 'application/octet-stream';
  49. }
  50. if (false === $handle = @fopen($path, 'r', false)) {
  51. throw new InvalidArgumentException(sprintf('Unable to open path "%s"', $path));
  52. }
  53. $p = new self($handle, $name ?: basename($path), $contentType);
  54. $p->handle = $handle;
  55. return $p;
  56. }
  57. /**
  58. * @return $this
  59. */
  60. public function asInline()
  61. {
  62. return $this->setDisposition('inline');
  63. }
  64. public function getContentId(): string
  65. {
  66. return $this->cid ?: $this->cid = $this->generateContentId();
  67. }
  68. public function hasContentId(): bool
  69. {
  70. return null !== $this->cid;
  71. }
  72. public function getMediaType(): string
  73. {
  74. return $this->mediaType;
  75. }
  76. public function getPreparedHeaders(): Headers
  77. {
  78. $headers = parent::getPreparedHeaders();
  79. if (null !== $this->cid) {
  80. $headers->setHeaderBody('Id', 'Content-ID', $this->cid);
  81. }
  82. if (null !== $this->filename) {
  83. $headers->setHeaderParameter('Content-Disposition', 'filename', $this->filename);
  84. }
  85. return $headers;
  86. }
  87. private function generateContentId(): string
  88. {
  89. return bin2hex(random_bytes(16)).'@symfony';
  90. }
  91. public function __destruct()
  92. {
  93. if (null !== $this->handle && \is_resource($this->handle)) {
  94. fclose($this->handle);
  95. }
  96. }
  97. public function __sleep()
  98. {
  99. // converts the body to a string
  100. parent::__sleep();
  101. $this->_parent = [];
  102. foreach (['body', 'charset', 'subtype', 'disposition', 'name', 'encoding'] as $name) {
  103. $r = new \ReflectionProperty(TextPart::class, $name);
  104. $r->setAccessible(true);
  105. $this->_parent[$name] = $r->getValue($this);
  106. }
  107. $this->_headers = $this->getHeaders();
  108. return ['_headers', '_parent', 'filename', 'mediaType'];
  109. }
  110. public function __wakeup()
  111. {
  112. $r = new \ReflectionProperty(AbstractPart::class, 'headers');
  113. $r->setAccessible(true);
  114. $r->setValue($this, $this->_headers);
  115. unset($this->_headers);
  116. foreach (['body', 'charset', 'subtype', 'disposition', 'name', 'encoding'] as $name) {
  117. $r = new \ReflectionProperty(TextPart::class, $name);
  118. $r->setAccessible(true);
  119. $r->setValue($this, $this->_parent[$name]);
  120. }
  121. unset($this->_parent);
  122. }
  123. }