How to update information without duplicating in the database - php

I'm still new to Laravel and I needed some help.
I have a job from a programming course that I'm stuck on, which is to import a .csv file like in the image: enter image description here
And I need to add it to the database without duplicating the CPF information as in the image:
enter image description here
*The information is merely illustrative.
So if anyone can help me I would appreciate it.
I can use updateOrCreate but it doesn't get the rest of the information.
Import:
public function collection(Collection $collection)
{
foreach ($collection as $row) {
Clientes::updateOrCreate(
[ 'cpf' => $row[1]],
[ 'nome' => $row[2],
'telefone1' => $row[0],
]
);
}
}
Controller:
public function import(Request $request)
{
$import = (new ImportTelefones(2));
Excel::import($import, $request->file);
return redirect()->back();
}

It looks like that you are trying to import an Excel or CSV file.
The easiest option for that is to use Laravel-Excel Package.
See here:
Installation: https://docs.laravel-excel.com/3.1/getting-started/installation.html
Import: https://docs.laravel-excel.com/3.1/imports/
With that you should be able to import your file and have the data in the database.
To prevent duplicates you can use the 'upsert' feature. It will update the entry on import instead of creating it, if the configured unique key exists.
https://docs.laravel-excel.com/3.1/imports/model.html#upserting-models
Best regards
Sergej

Related

How to properly Update in the papers and authors table

I have a problem that whenever I update a paper it will always error out Unknown variable [Fname]
This is the update function in my controller
public function update(Request $request, $PaperID)
{
$request->validate([
'PaperTitle' => 'required',
'PaperType' => 'required',
'file' => [
'required',
File::types('pdf')
->max(12 * 1024),
],
]);
$paper=Papers::find($PaperID);
$file=$request->file;
$filename=time().'.'.$file->getClientOriginalExtension();
$request->file->move('assets', $filename);
$paper->file=$filename;
$paper->PaperTitle=$request->PaperTitle;
$paper->PaperType=$request->PaperType;
$paper->College=$request->College;
$paper->DateCompleted=$request->DateCompleted;
$paper->ContentAdviser=$request->ContentAdviser;
$paper->update();
$input = $request->all();
if(count($input['Fname']) > 0){
for($i = 0 ; $i < count($input['Fname']) ; $i++){
$author->Fname = $input['Fname'][$i];
$author->Lname = $input['Lname'][$i];
$author->update();
}
}
return redirect()->back()->with('success','File has been updated.');
}
the storing works fine but update doesn't how to fix this? I want that both papers and authors table will update the papers updates fine but the author does not
Solution
Use $paper->save() — update expects different params.
Try this for updating:
$paper->update($request->validated()->except('file'))
// or
`$paper->update($request->validated()->only(['field1', 'field2', 'etc'))`
(of course, you'll want to add validation for all Model attributes)
Extra credit (PR Review Learning Comments)
1. Code Readability
First, add spaces around your = & after your if's. Better yet, use a library (like php-cs-fixer) to automatically format your code.
2. Use a custom UpdatePaperRequest
Using a custom Request rather than using $request->validate() helps organize your code. Laravel delegates validation to requests. You can then test the Request separately, create reusable/shared functionality (Traits/Concernst), etc... it's just better trust me :)

Maatwerk Excel Laravel how to set CSV EXPORT delimeter?

Hi i'm using Maatwerk Excel laravel package to export data to XLSX and CSV.
In 2 instances a comma is good.
But now i need to make a CSV where the delimeter is not a comma but something different (a tab or pipe symbol).
I cannot find where to set this.
I tried:
Config::set('Excel::csv.delimeter','|');
Excel::create('CSV Products', function($excel) use ($exports_arr) {
$excel->setTitle('Products');
$excel->setCreator('Me')->setCompany('My company');
$excel->setDescription('Products');
$excel->sheet('sheet1', function($sheet) use ($exports_arr) {
$sheet->fromArray($exports_arr, null, 'A1', false, false);
});
})->download('csv');
But if i look in the config/Excel.php file the comments suggest that this delimeter is only for reading.
Is it even possible to change the Delimeter for EXPORTING CSV files?
Thanks in advance.
The comment states that excel.csv.delimiter is used for reading out a csv file, but in Writers/LaravelExcelWriter.php (line 578) the CSV delimiter is taken from the config, and set as , by default:
$this->writer->setDelimiter(config('excel.csv.delimiter', ','));
Are you sure the Config::set statement works properly?
Try to use:
Config::set('excel.csv.delimeter','|');
and check the value with
Config::get('excel.csv.delimeter');
UPDATE:
As mentioned in this answer, the service provider is registered before the request takes place. Updating the config key during the request won't affect the value that is read earlier by Maatwerk/Excel. A solution is given in the answer, by creating a deferred provider.
I know this is a bit outdated but I was having the same problem recently.
In order to set a custom delimiter while exporting multiple CSV files, you can create a new instance of the use Maatwebsite\Excel\Excel class without using the facade.
Try this:
use Maatwebsite\Excel\Excel;
use Maatwebsite\Excel\Writer;
use Maatwebsite\Excel\QueuedWriter;
use Maatwebsite\Excel\Reader;
...
$reader = new Reader(app()->make('filesystem'));
$writer = new Writer;
$queued_writer = new QueuedWriter($writer);
$writer->setDelimiter('|');
$excel = new Excel($writer, $queued_writer, $reader, app()->make('filesystem'));
$excel->create( ... );
An update on this question: If you are using Laravel Excel 3, you can set it in the config/excel.php file:
return [
'exports' => [
'csv' => [
'delimiter' => '|',
]
]
]
Or if you want to set it dynamically:
\Config::set('excel.exports.csv.delimiter', '|');
use Maatwebsite\Excel\Concerns\WithCustomCsvSettings;
use Maatwebsite\Excel\Concerns\WithCustomQuerySize;
class MyExportClass implements FromView, WithCustomQuerySize, WithCustomCsvSettings
{
use Exportable;
public string $filePath;
public string $disk;
public function getCsvSettings(): array
{
return [
'delimiter' => ",",
];
}
....
}
From documentation:
enter link description here

Laravel Public url for storage files

I want to retrieve public url for all the files stored using
storage::putFile('public/spares');
So, this is the issue I'm using
storage::files('public/spares');
but it provides this output from laravel storage directory
public/spares/image1.jpg
public/spares/image2.jpg
public/spares/image3.jpg
how can I get the public link for the above
http://localhost/laravel/public/storage/spares/image1.jpg
http://localhost/laravel/public/storage/spares/image2.jpg
http://localhost/laravel/public/storage/spares/image3.jpg
**Edit **
Sending last modified data of files to view
$docs = File::files('storage/document');
$lastmodified = [];
foreach ($docs as $key => $value) {
$docs[$key] = asset($value);
$lastmodified[$key] = File::lastmodified($value);
}
return view('stock.document',compact('docs','lastmodified'));
Is this correct
First you have to create the symbolic link from your public/storage directory to your storage/app/public directory so you can access the files. You can do that with:
php artisan storage:link
So then you can store your documents with:
Storage::putFile('spares', $file);
And access them as an asset with:
asset('storage/spares/filename.ext');
Check out the documentation on the public disk
What about Storage::url? It works even for local storage.
You can find more here: https://laravel.com/docs/5.4/filesystem#file-urls
If you want to return all files' urls from the directory, you can do something like this:
return collect(Storage::files($directory))->map(function($file) {
return Storage::url($file);
})
Don't forget to inject the \Illuminate\Filesystem\FilesystemManager instead of the Storage facade if you are looking for a not-facade way.
Edit:
There are 2 (or more) ways how you can deal with modified date:
Pass files to the view.
|ou can pass your Storage::files($directory) directly to the view and then in your template use following:
// controller:
return view('view', ['files' => Storage::files($directory)]);
// template:
#foreach($files as $file)
{{ Storage::url($file) }} - {{ $file->lastModified }} // I'm not sure about lastModified property, but you get the point
#endforeach
Return an array:
return collect(Storage::files($directory))->map(function($file) {
return [
'file' => Storage::url($file),
'modified' => $file->lastModified // or something like this
]
})->toArray()
I know this question is quite old, but i am putting this answer for anyone still having this issue from laravel 5.5+
To solve the issue update your filesystem's configuration by adding the 'url' key like below:
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
Hope it helps :)
Well I figured out the solution, instead of searching the storage
$docs = Storage:files('public/spares');
we can search the symbolic link
$docs = File:files('storage/spares');
then run it through the asset() function to get the public URL. Is there a better solution?
$file = Storage::disk('public')->put($folder, request()->file($key), 'public');
$file = Storage::url($file);

Update two models using yii x-editable

So, I'm using this extension: x-editable for yii.
And I'm currently trying to update two models in update() function.
I have two models:
Realisasi.php
RealisasiDeadline.php.
So when a cell is updated on table Realisasi.php (one value in column t1701 in this case), I want the function to update the corresponding value in column t1701 of table RealisasiDeadline, using column no as the foreign key.
Since I haven't found any example on Google, I made it up myself:
public function actionSimpanEdit($kode) {
Yii::import('editable.EditableSaver');
$es = new EditableSaver($_GET['model']); // 'modelName' is classname of model to be updated
$es->update();
$es2 = RealisasiDeadline::model()->findByPk($kode);//this is where I'm stuck
$es2['t1701'] = '1991-11-19';//this too
$es->update();//and this
}
This is the view.php:
array(
'name' => 't1701',
'value' => 'CHtml::value($data,"hubtarget.t1701")=== "0"?"Target Nol":$data->t1701',
'header' => 'Bkl Selatan',
'class' => 'editable.EditableColumn',
'editable' => array(
'url' => $this->createUrl('simpanEdit', array('model' => 'Realisasi', 'kode'=>'$data->no')),
)
),
What have I missed? Is it possible at all to do? If not, is there another solution?
UPDATE
It's not showing any error. But the value in table RealisasiDeadline doesn't change, only the one in Realisasi does.
Added some comments to original function so you can improve upon it. Biggest issue with this code is that looking at it I have no idea what it does.
public function actionSimpanEdit($kode) {
Yii::import('editable.EditableSaver'); // Should be at the top of the file
// For the love of god use descriptive variable names
$es = new EditableSaver($_GET['model']); // Would prefer to have model as actions argument
$es->update();
$es2 = RealisasiDeadline::model()->findByPk($kode); // no idea what this model is responsible for
$es2['t1701'] = '1991-11-19'; // no idea what attribute t1701 is, use descriptive names
$es->update();
}
I have refactored it a bit. Still have no idea what it does ;/
public function actionSimpanEdit($id, $model) {
$editableSaver = new EditableSaver($model);
$editableSaver->update();
$deadline = RealisasiDeadline::model()->findByPk($id);
if($deadline instanceof RealisasiDeadline) {
$deadline->t1701 = '1991-11-19';
if(!$deadline->update()) {
// something went wrong
}
} else {
// not found
}
}
Going back to your problem. It is probably caused by RealisasiDeadline model being not found or some behavior or event preventing it from update.

Import utf-8 headings Maatwebsite Laravel

I'm using Maatwebsite in Laravel and it's very good option for excel works but I have one problem .. I have excel sheet with arabic heading, so when I import it , it converted to understand-less english character to fit array key .. So What is the solution for my problem?
I know it's too late, but for someone else that may have the same problem, you should change the value of "heading" key to "original" in "import" array of config/excel.php file..
'import' => [
...
'heading' => 'original',
],
http://www.maatwebsite.nl/laravel-excel/docs/import
Look up the header about import encoding.
From thoose pages:
// When utilising a closure, you can pass the input encoding as third parameter.
Excel::load('filename.csv', function($reader) {
}, 'UTF-8');
// or without a closure, you can use it as second parameter.
Excel::load('filename.csv', 'UTF-8');
Does that solve the issue?
You can implements the Interface of WithCustomCsvSettings, in your class import
Example:
<?php
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithCustomCsvSettings;
class ArticlesImport implements ToCollection, WithCustomCsvSettings
{
public function collection(Collection $rows)
{
// do something
}
public function getCsvSettings(): array
{
# Define your custom import settings for only this class
return [
'input_encoding' => 'UTF-8',
'delimiter' => ";"
];
}
}
I'm too late but this workerd for me, instead of a modifying import.php, in your controller add this
config(['excel.import.heading' => 'original' ]);

Categories