Last active
May 23, 2023 19:35
-
-
Save dwaard/bb068c55a3a5a601f8061d8edf07fb7b to your computer and use it in GitHub Desktop.
Csv Readable Trait for Laravel Seeders. Including an example seeder file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Database\Seeders; | |
use Illuminate\Support\Facades\Storage; | |
/** | |
* Trait that enables Seeder classes to easily read CSV formatted files and seed Models with its data. The | |
* | |
* User: waar0003 | |
* Date: 11-4-2018 | |
* Time: 13:42 | |
*/ | |
trait CsvReadable | |
{ | |
/* | |
* Full path of the file (normally relative to storage/app) to import | |
*/ | |
public $path = ""; | |
/* | |
* The delimiter | |
*/ | |
public $delimiter = ','; | |
/* | |
* the row number of the header to read. Default = null | |
* | |
* If $header_row is set to null, no header data is read, and the $header attribute is used to determine the | |
* columns to import. If the file contains a header row, but is not conform the column names in the model, | |
* you should set the $header attribute. | |
*/ | |
public $header_row = null; | |
/* | |
* The first row to import. Default set to 0 (first row) | |
*/ | |
public $start_row = 0; | |
/* | |
* Array with the Model's column names that should be available in the csv file. | |
* | |
* Set this attribute if the file has no headers or the header row is not conform the column names of the | |
* model. | |
*/ | |
public $header = null; | |
/** | |
* Reads the CSV data and calls the `$callback` function for each row. | |
* | |
* @param $callback | |
* @return void | |
*/ | |
public function readCsvData($callback) | |
{ | |
$contents = collect(explode("\n", Storage::get($this->path))); | |
// Removes any \r | |
$contents = $contents->map(function ($item) { | |
// remove any remaining CR (\r) and all other non characters | |
return str_replace("\r", "", preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $item)); | |
}); | |
// Set the keyset when no header row is specified | |
if (!$this->header_row) { | |
$keyset = collect($this->header); | |
} | |
$current_row = 0; | |
foreach ($contents as $raw) { | |
$row = explode($this->delimiter, $raw); | |
if ($current_row == $this->header_row) { | |
$keyset = collect($row); | |
} | |
if ($current_row >= $this->start_row) { | |
$item_count = count($row); | |
if ($item_count == $keyset->count()) { | |
// combine header and row into an Associative Array (key=>value) | |
$importData = $keyset->combine($row)->all(); | |
// call the callback function | |
$callback($importData); | |
} elseif ($row != [""]) { | |
$msg = implode(', ', $row); | |
$this->command->error("CANNOT IMPORT: [$msg]; Size doesn't match"); | |
} | |
} | |
$current_row++; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Database\Seeders; | |
use Illuminate\Database\Seeder; | |
use App\Models\Result; | |
class ResultSeeder extends Seeder | |
{ | |
use CsvReadable; | |
/** | |
* Construct a new ResultSeeder | |
*/ | |
public function __construct() | |
{ | |
$this->path = "seed_files/results.csv"; | |
$this->delimiter = ";"; | |
$this->header_row = 0; | |
$this->start_row = 1; | |
} | |
/** | |
* Run the database seeds. | |
* | |
* @return void | |
*/ | |
public function run() | |
{ | |
$this->readCsvData(function ($data) { | |
// Parse the date (eg. 05-02-2019) to an importable object | |
$data['date'] = \Carbon\Carbon::createFromFormat('d-m-Y', $data['date']); | |
// Parse the time (eg. 19.15) to an importable object | |
$data['time'] = \Carbon\Carbon::createFromFormat('G:i', $data['time']); | |
// You might want to do some validation here | |
Result::create($data); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment