/app/Models/Export.php

https://gitlab.com/besingamkb/rtwc · PHP · 231 lines · 94 code · 38 blank · 99 comment · 7 complexity · 7ce13dd275722742fec34befafbafd1d MD5 · raw file

  1. <?php
  2. namespace App\Models;
  3. use Storage;
  4. class Export
  5. {
  6. /**
  7. * Whether the CSV has been saved or still needs building.
  8. *
  9. * @var $saved
  10. */
  11. protected $saved = false;
  12. /**
  13. * Set the export type.
  14. *
  15. * @var $type
  16. */
  17. protected $exportType = '';
  18. /**
  19. * Store the raw data.
  20. *
  21. * @var $rawData
  22. */
  23. protected $rawData = [];
  24. /**
  25. * Store the header row data.
  26. *
  27. * @var $headerRow
  28. */
  29. protected $headerRow = [];
  30. /**
  31. * Store the row data.
  32. *
  33. * @var $dataRows
  34. */
  35. protected $dataRows = [];
  36. /**
  37. * Set the default CSV directory.
  38. *
  39. * @var string
  40. */
  41. protected $csvDirectory = 'exports/default';
  42. /**
  43. * Set the default CSV file name.
  44. *
  45. * @var string
  46. */
  47. protected $csvFileName = 'default.csv';
  48. /**
  49. * Set the default CSV path from the storage directory.
  50. *
  51. * @var string
  52. */
  53. protected $csvPath = '';
  54. /**
  55. * Set the default CSV absolute path from server root.
  56. *
  57. * @var string
  58. */
  59. protected $csvAbsPath = '';
  60. /**
  61. * Export constructor.
  62. */
  63. public function __construct()
  64. {
  65. $this->csvFileName = time() . '.csv';
  66. $this->csvPath = $this->csvDirectory . '/' . $this->csvFileName;
  67. $this->csvAbsPath = storage_path('app/' . $this->csvDirectory . '/' . $this->csvFileName);
  68. }
  69. /**
  70. * Build the CSV from the header row and data rows.
  71. *
  72. * @param array $data
  73. * @return Export|bool
  74. */
  75. protected function build(array $data)
  76. {
  77. // Check if the CSV exists.
  78. if (file_exists($this->csvPath)) {
  79. $this->saved = true;
  80. return $this;
  81. }
  82. // Set the data into the raw data.
  83. $this->rawData = $data;
  84. // Create a blank file using the Laravel Storage library.
  85. // Used just in case directory does not exist.
  86. Storage::disk()->put($this->csvPath, '');
  87. // Open the filestream for the CSV.
  88. $file = fopen($this->csvAbsPath, 'w');
  89. // Only set a header row if there is more than 1 column
  90. if (count(array_keys($data[0])) > 1) {
  91. $this->setHeaderRow(array_keys($data[0]));
  92. }
  93. // Set the data rows.
  94. $this->setDataRows($data);
  95. // Concatenate the header row and data rows.
  96. $concatenatedRows = $this->dataRows;
  97. array_unshift($concatenatedRows, $this->headerRow);
  98. // Add rows to the filestream.
  99. foreach ($concatenatedRows as $row) {
  100. fputcsv($file, $row);
  101. }
  102. // Close the filestream.
  103. $saved = fclose($file);
  104. // Upload to remote storage.
  105. Storage::cloud()->put($this->csvPath, Storage::disk()->get($this->csvPath));
  106. // Check if the file has been saved.
  107. if (!$saved) {
  108. return false;
  109. }
  110. // Set CSV saved to true.
  111. $this->saved = true;
  112. return $this;
  113. }
  114. /**
  115. * Set an array of data rows.
  116. *
  117. * @param $rows
  118. * @return Export
  119. */
  120. protected function setDataRows($rows)
  121. {
  122. foreach ($rows as $row) {
  123. $this->setDataRow($row);
  124. }
  125. return $this;
  126. }
  127. /**
  128. * Set a single data row.
  129. *
  130. * @param $row
  131. * @return Export
  132. */
  133. protected function setDataRow($row)
  134. {
  135. array_push($this->dataRows, $row);
  136. return $this;
  137. }
  138. /**
  139. * Set the CSV header row.
  140. *
  141. * @param $row
  142. * @return Export
  143. */
  144. protected function setHeaderRow($row)
  145. {
  146. $this->headerRow = $row;
  147. return $this;
  148. }
  149. /**
  150. * Sets the export type.
  151. *
  152. * @param $type
  153. * @return Export
  154. */
  155. public function setType($type)
  156. {
  157. $this->exportType = $type;
  158. return $this;
  159. }
  160. /**
  161. * Return the CSV as a filestream.
  162. *
  163. * @return boolean|string
  164. */
  165. public function get()
  166. {
  167. // Check if the CSV has been built yet and build it if not.
  168. if ($this->saved == false) {
  169. if (!count($this->rawData)) {
  170. $this->build($this->rawData);
  171. }
  172. return false;
  173. }
  174. // Check if the CSV exists in storage.
  175. if (!Storage::cloud()->exists($this->csvPath)) {
  176. return false;
  177. }
  178. // Return the CSV as filestream.
  179. $client = Storage::cloud()->getDriver()->getAdapter()->getClient();
  180. $command = $client->getCommand(
  181. 'GetObject',
  182. [
  183. 'Bucket' => Storage::cloud()->getDriver()->getAdapter()->getBucket(),
  184. 'Key' => $this->csvPath,
  185. 'ResponseContentType' => 'application/octet-stream',
  186. 'ResponseContentDisposition' => 'attachment; filename="' . $this->csvFileName . '"',
  187. ]
  188. );
  189. $request = $client->createPresignedRequest($command, '+5 minute');
  190. $presignedUrl = (string)$request->getUri();
  191. return $presignedUrl;
  192. }
  193. }