/app/Models/Export.php
https://gitlab.com/besingamkb/rtwc · PHP · 231 lines · 94 code · 38 blank · 99 comment · 7 complexity · 7ce13dd275722742fec34befafbafd1d MD5 · raw file
- <?php
- namespace App\Models;
- use Storage;
- class Export
- {
- /**
- * Whether the CSV has been saved or still needs building.
- *
- * @var $saved
- */
- protected $saved = false;
- /**
- * Set the export type.
- *
- * @var $type
- */
- protected $exportType = '';
- /**
- * Store the raw data.
- *
- * @var $rawData
- */
- protected $rawData = [];
- /**
- * Store the header row data.
- *
- * @var $headerRow
- */
- protected $headerRow = [];
- /**
- * Store the row data.
- *
- * @var $dataRows
- */
- protected $dataRows = [];
- /**
- * Set the default CSV directory.
- *
- * @var string
- */
- protected $csvDirectory = 'exports/default';
- /**
- * Set the default CSV file name.
- *
- * @var string
- */
- protected $csvFileName = 'default.csv';
- /**
- * Set the default CSV path from the storage directory.
- *
- * @var string
- */
- protected $csvPath = '';
- /**
- * Set the default CSV absolute path from server root.
- *
- * @var string
- */
- protected $csvAbsPath = '';
- /**
- * Export constructor.
- */
- public function __construct()
- {
- $this->csvFileName = time() . '.csv';
- $this->csvPath = $this->csvDirectory . '/' . $this->csvFileName;
- $this->csvAbsPath = storage_path('app/' . $this->csvDirectory . '/' . $this->csvFileName);
- }
- /**
- * Build the CSV from the header row and data rows.
- *
- * @param array $data
- * @return Export|bool
- */
- protected function build(array $data)
- {
- // Check if the CSV exists.
- if (file_exists($this->csvPath)) {
- $this->saved = true;
- return $this;
- }
- // Set the data into the raw data.
- $this->rawData = $data;
- // Create a blank file using the Laravel Storage library.
- // Used just in case directory does not exist.
- Storage::disk()->put($this->csvPath, '');
- // Open the filestream for the CSV.
- $file = fopen($this->csvAbsPath, 'w');
- // Only set a header row if there is more than 1 column
- if (count(array_keys($data[0])) > 1) {
- $this->setHeaderRow(array_keys($data[0]));
- }
- // Set the data rows.
- $this->setDataRows($data);
- // Concatenate the header row and data rows.
- $concatenatedRows = $this->dataRows;
- array_unshift($concatenatedRows, $this->headerRow);
- // Add rows to the filestream.
- foreach ($concatenatedRows as $row) {
- fputcsv($file, $row);
- }
- // Close the filestream.
- $saved = fclose($file);
- // Upload to remote storage.
- Storage::cloud()->put($this->csvPath, Storage::disk()->get($this->csvPath));
- // Check if the file has been saved.
- if (!$saved) {
- return false;
- }
- // Set CSV saved to true.
- $this->saved = true;
- return $this;
- }
- /**
- * Set an array of data rows.
- *
- * @param $rows
- * @return Export
- */
- protected function setDataRows($rows)
- {
- foreach ($rows as $row) {
- $this->setDataRow($row);
- }
- return $this;
- }
- /**
- * Set a single data row.
- *
- * @param $row
- * @return Export
- */
- protected function setDataRow($row)
- {
- array_push($this->dataRows, $row);
- return $this;
- }
- /**
- * Set the CSV header row.
- *
- * @param $row
- * @return Export
- */
- protected function setHeaderRow($row)
- {
- $this->headerRow = $row;
- return $this;
- }
- /**
- * Sets the export type.
- *
- * @param $type
- * @return Export
- */
- public function setType($type)
- {
- $this->exportType = $type;
- return $this;
- }
- /**
- * Return the CSV as a filestream.
- *
- * @return boolean|string
- */
- public function get()
- {
- // Check if the CSV has been built yet and build it if not.
- if ($this->saved == false) {
- if (!count($this->rawData)) {
- $this->build($this->rawData);
- }
- return false;
- }
- // Check if the CSV exists in storage.
- if (!Storage::cloud()->exists($this->csvPath)) {
- return false;
- }
- // Return the CSV as filestream.
- $client = Storage::cloud()->getDriver()->getAdapter()->getClient();
- $command = $client->getCommand(
- 'GetObject',
- [
- 'Bucket' => Storage::cloud()->getDriver()->getAdapter()->getBucket(),
- 'Key' => $this->csvPath,
- 'ResponseContentType' => 'application/octet-stream',
- 'ResponseContentDisposition' => 'attachment; filename="' . $this->csvFileName . '"',
- ]
- );
- $request = $client->createPresignedRequest($command, '+5 minute');
- $presignedUrl = (string)$request->getUri();
- return $presignedUrl;
- }
- }