Attachment.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. <?php
  2. namespace Easemob;
  3. use Easemob\Http\Http;
  4. /**
  5. * \~chinese
  6. * Attachment 用来上传下载附件
  7. *
  8. * \~english
  9. * The `Attachment` is used to upload and download attachments
  10. */
  11. final class Attachment
  12. {
  13. /**
  14. * @ignore
  15. * @var Auth $auth 授权对象
  16. */
  17. private $auth;
  18. /// @cond
  19. public function __construct($auth)
  20. {
  21. $this->auth = $auth;
  22. }
  23. /// @endcond
  24. /**
  25. * \~chinese
  26. * \brief
  27. * 文件上传
  28. *
  29. * \details
  30. * - 上传文件的大小不能超过 10 M,超过会上传失败。
  31. * - 在上传文件的时候可以选择是否限制访问权限,如果选择限制的话,会在上传请求完成后返回一个 secret,只有知道这个 secret,并且是 app 的注册用户,才能够下载文件。如果选择不限制的话,则只要是 app 的注册用户就能够下载。
  32. * - 如选择加 secret 限制的话,消息回调(包含发送前回调和发送后回调)、历史消息这些功能中涉及下载文件时,都需要在下载 url 中拼接 secret,才能正常下载文件;
  33. * - 拼接规则如下:url?share-secret=secret
  34. *
  35. * @param string $fileName 上传的附件
  36. * @param boolean $restrictAccess 控制文件是否可以被任何人获取,这个值为 true,返回结果中会添加一个 share-secret 值。再次访问文件需要用到这个值。默认值:false
  37. * @return array 上传文件信息或者错误
  38. *
  39. * \~english
  40. * \brief
  41. * File upload
  42. *
  43. * \details
  44. * - The size of the uploaded file cannot exceed 10m. If it exceeds 10m, the upload will fail.
  45. * - When uploading files, you can choose whether to restrict access rights. If you choose to restrict, a secret will be returned after the upload request is completed. Only those who know the secret and are registered users of the app can download files. If you choose not to limit, you can download as long as you are a registered user of the app.
  46. * - If you choose to add the secret limit, the message callback (including the callback before sending and the callback after sending) and the historical message, which involve downloading files, need to splice the secret in the download URL to download files normally;
  47. * - The splicing rules are as follows: url?share-secret=secret
  48. *
  49. * @param string $fileName Uploaded attachments
  50. * @param boolean $restrictAccess Controls whether the file can be obtained by anyone. This value is true. A share secret value will be added to the returned result. This value is required to access the file again. Default: false
  51. * @return array Upload file information or error
  52. */
  53. public function uploadFile($fileName, $restrictAccess = false)
  54. {
  55. if (!trim($fileName)) {
  56. \Easemob\exception('Please pass in the attachment name');
  57. }
  58. $file = fopen($fileName, 'rb');
  59. if ($file === false) {
  60. \Easemob\exception('The attachment cannot be read');
  61. }
  62. $restrictAccess = (bool)$restrictAccess;
  63. $headers = $this->auth->headers();
  64. if ($restrictAccess) {
  65. $headers['restrict-access'] = $restrictAccess;
  66. }
  67. $stat = fstat($file);
  68. $size = $stat['size'];
  69. $data = fread($file, $size);
  70. fclose($file);
  71. $mimeType = mime_content_type($fileName) ? mime_content_type($fileName) : null;
  72. $uri = $this->auth->getBaseUri() . '/chatfiles';
  73. $resp = Http::multipartPost($uri, $fileName, $data, $mimeType, $headers);
  74. if (!$resp->ok()) {
  75. return \Easemob\error($resp);
  76. }
  77. $data = $resp->data();
  78. return $data['entities'][0];
  79. }
  80. /**
  81. * \~chinese
  82. * \brief
  83. * 下载附件
  84. *
  85. * \details
  86. * 这里需要注意的就是,如果上传文件时候选择了文件不共享,需要在请求头中带上上面返回的 share-secret 和当前登录用户的 token 才能够下载。
  87. *
  88. * @param string $fileName 下载的文件名
  89. * @param string $uuid 文件唯一 ID,文件上传成功后会返回
  90. * @param string $shareSecret share-secret,文件上传成功后会返回
  91. * @return int|array 下载文件的大小或者错误
  92. *
  93. * \~english
  94. * \brief
  95. * Download attachments
  96. *
  97. * \details
  98. * It should be noted here that if you choose not to share the file when uploading the file, you need to bring the share secret returned above and the token of the currently logged in user in the request header to download it.
  99. *
  100. * @param string $fileName Downloaded file name
  101. * @param string $uuid Unique ID of the file, which will be returned after the file is uploaded successfully
  102. * @param string $shareSecret share-secret,it will return after the file is uploaded successfully
  103. * @return int|array Download file size or error
  104. */
  105. public function downloadFile($fileName, $uuid, $shareSecret = '')
  106. {
  107. return $this->download($fileName, $uuid, $shareSecret);
  108. }
  109. /**
  110. * \~chinese
  111. * \brief
  112. * 下载缩略图
  113. *
  114. * \details
  115. * 在服务器端支持自动的创建图片的缩略图。可以先下载缩略图,当用户有需求的时候,再下载大图。 这里和下载大图唯一不同的就是 header 中多了一个“thumbnail: true”,当服务器看到过来的请求的 header 中包括这个的时候,就会返回缩略图,否则返回原始大图。
  116. *
  117. * @param string $fileName 下载缩略图的文件名
  118. * @param string $uuid 文件唯一 ID,文件上传成功后会返回
  119. * @param string $shareSecret share-secret,文件上传成功后会返回
  120. * @return int|array 下载缩略图的大小或者错误
  121. *
  122. * \~english
  123. * \brief
  124. * Download thumbnails
  125. *
  126. * \details
  127. * The server side supports the automatic creation of thumbnails of pictures. You can download thumbnails first, and then download large images when users need them. The only difference between this and downloading the big picture is that there is an "thumbnail: true" in the header. When the server sees that this is included in the header of the request, it will return the thumbnail, otherwise it will return the original big picture.
  128. *
  129. * @param string $fileName Download thumbnail file name
  130. * @param string $uuid Unique ID of the file, which will be returned after the file is uploaded successfully
  131. * @param string $shareSecret share-secret,it will return after the file is uploaded successfully
  132. * @return int|array Download file size or error
  133. */
  134. public function downloadThumb($fileName, $uuid, $shareSecret = '')
  135. {
  136. return $this->download($fileName, $uuid, $shareSecret, true);
  137. }
  138. /**
  139. * @ignore 下载附件
  140. * @param string $fileName 下载的文件名
  141. * @param string $uuid 文件唯一 ID,文件上传成功后会返回
  142. * @param string $shareSecret share-secret,文件上传成功后会返回
  143. * @param boolean $thumb 下载缩略图标识
  144. * @return int|array 下载文件的大小或者错误
  145. */
  146. private function download($fileName, $uuid, $shareSecret = '', $thumb = false)
  147. {
  148. $uri = $this->auth->getBaseUri() . '/chatfiles/' . $uuid;
  149. $headers = $this->auth->headers();
  150. if ($shareSecret) {
  151. $headers['share-secret'] = $shareSecret;
  152. }
  153. if ($thumb) {
  154. $headers['thumbnail'] = true;
  155. }
  156. $resp = Http::get($uri, $headers);
  157. if (!$resp->ok()) {
  158. return \Easemob\error($resp);
  159. }
  160. $dir = dirname($fileName);
  161. if (!file_exists($dir)) {
  162. mkdir($dir, 0755, true);
  163. }
  164. return file_put_contents($fileName, $resp->body);
  165. }
  166. }