update table with csv using laravel - laravel

I'm trying to update a table using Maatwebsite/Laravel-Excel.
public function import(Request $request)
{
if($request->file('imported-file'))
{
$path = $request->file('imported-file')->getRealPath();
$data = Excel::load($path, function($reader)
{
})->get();
if(!empty($data) && $data->count())
{
foreach ($data->toArray() as $row)
{
if(!empty($row))
{
$dataArray[] =
[
//'name' => $row['name'],
'age' => $row['age'],
'phone' => $row['phone'],
//'created_at' => $row['created_at']
];
}
if(!empty($dataArray))
{
//Item::insert($dataArray);
DB::table('items')
->where('name', $row['name'])->update($dataArray);
return view('imported')->with('success', 'Course updated');
}
}
}
}
}
But its giving error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column '0' in 'field list' (SQL: update items set 0 = 20 where name = james
Here's my csv
name,age,phone
James,20,888839939
Joseph,54,3444444
Hanson,30,99999999
The above is the csv file i'm trying to update.

The problem is that $dataArray is an array of arrays, so to make it work you have to loop each one:
if(!empty($dataArray)) {
foreach ($dataArray as $array) {
DB::table('items')
->where('name', $row['name'])
->update($array);
}
return view('imported')->with('success', 'Course updated');
}
But this wouldn't make much sense, because every time it would be updating the row with name = $row['name'], so you probbaly need to update the line where you set a value to the $dataArray from $dataArray[] = ... to $dataArray = ...*, so it could have a single value.

In case any body comes across this, this is how i solved it.
public function import(Request $request)
{
if($request->file('imported-file'))
{
$path = $request->file('imported-file')->getRealPath();
Excel::load($path)->each(function (Collection $csvLine) {
DB::table('items')
->where('id', $csvLine->get('id'))
->update(['name' => $csvLine->get('name'),'phone' => $csvLine->get('phone'),'age' => $csvLine->get('age')]);
});
return view('imported')->with('success', 'Course updated');
}
}
I used the each() collection method to loop through the csv file and it won the battle.

Related

Call to a member function pro_events() on null

Hello I'm trying to fix this issue where the error
Call to a member function pro_events() on null
would not happen all the time. I'm not sure what's causing this.
Any idea how to prevent this error in case it would appear again? We just saw this error in the log but can't duplicate the issue. Thanks!
Organizer.php model
class Organiser extends MyBaseModel
{
protected $rules = [
'org_name' => ['required', 'unique:organisers,name'],
'email' => ['required', 'email', 'unique:organisers'],
'organiser_logo' => ['mimes:jpeg,jpg,png', 'max:10000'],
'terms_agreed' => ['required'],
'org_tags' => ['required'],
];
protected $messages = [
'org_name.required' => 'You must at least give a name for the event organiser.',
'org_name.unique' => 'Your desired organisation name is already taken.',
'organiser_logo.max' => 'Please upload an image smaller than 10Mb',
'organiser_logo.size' => 'Please upload an image smaller than 10Mb',
'organiser_logo.mimes' => 'Please select a valid image type (jpeg, jpg, png)',
];
public function pro_events() {
return $this->hasMany(\App\Models\ProEvent::class)->orderBy('event_date', 'asc');
}
SomeController.php
public function showPackageHome($organiser_id, $event_dummy = null, $event_id = null, $the_country = null, $package_type_id = null, $package_category_id = null)
{
date_default_timezone_set('Europe/London');
$now = Carbon::now();
$cacheKey = md5(vsprintf('%s.%s', [
$organiser_id,
'organiser_cache'
]));
$organiser = Cache::remember($cacheKey, 10, function() use ($organiser_id) {
return Organiser::find($organiser_id);
});
$cacheKey = md5(vsprintf('%s', [
'event_list_cache'
]));
$events = Cache::remember($cacheKey, 1, function() use ($organiser, $now) {
return $organiser->pro_events()
->where("event_status", "live")
->whereDate('event_date', '>=', $now->format("Y-m-d"))
->orderBy('event_date', 'asc')
->get();
});
ProEvent.php model
class ProEvent extends MyBaseModel
{
use SoftDeletes;
protected $table = 'pro_events';
You must go up in the call stack to find where the organizer_id comes from. A possible reason would be that the admin/loggedIn person may change the route manually and try to load an organizer that doesn't exist.
If you have a route like /organizer/{organizer_id}, then you must make sure that the provided ID actually exists in db. One way to do it would be to use findOrFail instead of find and to catch the thrown exception in case the organizer doesn't exist.
public function showPackageHome($organiser_id, $event_dummy = null, $event_id = null, $the_country = null, $package_type_id = null, $package_category_id = null)
{
date_default_timezone_set('Europe/London');
$now = Carbon::now();
$cacheKey = md5(vsprintf('%s.%s', [
$organiser_id,
'organiser_cache'
]));
$organiser = Cache::remember($cacheKey, 10, function() use ($organiser_id) {
return Organiser::findOrFail($organiser_id);
});
$cacheKey = md5(vsprintf('%s', [
'event_list_cache'
]));
$events = Cache::remember($cacheKey, 1, function() use ($organiser, $now) {
return $organiser->pro_events()
->where("event_status", "live")
->whereDate('event_date', '>=', $now->format("Y-m-d"))
->orderBy('event_date', 'asc')
->get();
});
}
In your controller method you can actually catch the exception and display something to the user:
public function yourControllerMethod(Illuminate\Http\Request $request)
{
// something more here
try {
$events = $this->showPackageHome($request->get('organizer_id'), /* the other parameters */);
return $this->view(..., ['events' => $events]);
} catch (Illuminate\Database\Eloquent\ModelNotFoundException $ex) {
// The organizer couldn't be found
return redirect()->back()->withErrors(['organizer-not-found' => 'The organizer could not be found'])
}
}
i think it's because the instance of Organizer where you called pro_events() function was null.

Is there any efficient method on how to get id of object to my create method

I am creating a web module, and want to get ID of table licensing level two parse into my create method. Hence each ID of level will have a task and the ID need to be stored within my licensing table as a foreign key which reflects ID in Level Two table. How could I solve this, anyone can give me a good suggestion or way on doing this
public function add_show($id)
{
$level = PreLicensingLevelTwo::where('id', $id)->first();
$level->prelicensingtask = PreLicensingTask::where('pre_licensing_level_two_id', $level->id)->with('staff', 'statusdesc', 'prelicensingtaskstaff')->get();
return view('staff.regulatory.statutory.approval.display',compact('level'));
}
public function create()
{
$staff = Staff::pluck('staff_name');
$status = PreLicensingStatus::pluck('status_description', 'id');
return view('staff.regulatory.statutory.approval.create', compact('staff','status'));
}
public function show($id)
{
$one = PreLicensingLevelOne::where('pre_licensing_main_id', $id)->get();
foreach ($one as $key => $license)
{
$license->two = PreLicensingLevelTwo::where('pre_licensing_level_one_id', $license->id)->get();
}
$rendered = view('staff.regulatory.statutory.approval.show')->with('one', $one)->render();
return response()->json(array('status' => 1, 'tableData' => $rendered));
}
With help from my working collegue this is how i able to solve the question i asked
public function store(Request $request)
{
$this->validate($request, [
'task_title' => 'required',
'task_description' => 'required',
'task_due_date' => 'required',
]);
$leveltwo = PreLicensingLevelTwo::find($request->input('pre_licensing_level_two_id'));
$prelicensingtask = new PreLicensingTask;
$prelicensingtask->task_title =$request->input('task_title');
$prelicensingtask->task_description =$request->input('task_description');
$prelicensingtask->task_due_date =$request->input('task_due_date');
$prelicensingtask->created_by_staff_id = Auth::user()->ref_user->staff_id;
$prelicensingtask->status = $request->input('status');
$prelicensingtask->pre_licensing_level_two_id = $leveltwo->id;
$prelicensingtask->pre_licensing_level_one_id = $leveltwo->pre_licensing_level_one_id;
$prelicensingtask->pre_licensing_main_id = $leveltwo->pre_licensing_main_id;
$prelicensingtask->centre_id = Auth::user()->ref_user->centre_id;
$prelicensingtask->save();
return redirect()->back();
}

how to filter with two or more combinations in laravel

enter code hereMy question about the combination filters in laravel by using eloquent.
I am trying to filter with a combination of the following:
username
Category
Sub_category
started_at
created_at
status
I use where conditions but it not working as required.
public function filter(Request $request, User $user)
{
$user = $user->newQuery();
// Search for a user based on their name.
if ($request->has('username')) {
$user->where('name', $request->input('username'));
}
// Search for a user based on their Category.
if ($request->has('Category')) {
$user->where('Category', $request->input('Category'));
}
// Search for a user based on their Sub_category.
if ($request->has('Sub_category')) {
$user->where('Sub_category', $request->input('Sub_category'));
}
// Search for a user based on their started_at.
if ($request->has('started_at')) {
$user->where('started_at', $request->input('started_at'));
}
// Search for a user based on their status.
if ($request->has('status')) {
$user->where('status', $request->input('status'));
}
// Continue for all of the filters.
// Get the results and return them.
return $user->get();
}
You should save your where conditions to the $user variable.
$user = $user->where($dbField, $request->input($requestParam));
For improved readability, I'd suggest using a loop with all of your filtering cases.
public function filter(Request $request)
{
$users = User::query();
$filters = [
'username' => 'name',
'Category' => 'Category',
'Sub_category' => 'Sub_category',
'started_at' => 'started_at',
'status' => 'status'
];
foreach ($filters as $requestParam => $dbField){
if ($request->has($requestParam)) {
$users = $users->where($dbField, $request->input($requestParam));
}
}
return $users->get();
}
Bear in mind $request->has does not check whether the parameter value is empty, use $request->filled if you wish so.
This is My examle refer this
public function filter(Request $request)
{
$q = User::query();
$email = $request->input('email');
$username= $request->input('username');
$q->when($email,function ($query) use ($email){
$query->where('email',$email);
});
$q->when($username,function ($query) use ($username){
$query->where('username',$username);
});
$results = $q->get();
//code
}

Figure what fields `save()` acted on if any (detecting changes)

Doing ->save() and ->update() only updates when changes made, I think, is this true?
Here's the relevant part of code in Illuminate\Database\Eloquent\Model#performUpdate:
protected function performUpdate(Builder $query, array $options = [])
{
$dirty = $this->getDirty();
if (count($dirty) > 0)
{
// runs update query
}
return true;
}
I typically update like this:
public function update(Requests\UpdatePetRequest $request, Pet $pet)
{
$pet->update($request->all());
return $pet;
}
I want to figure from ->save and from ->update if what field names were updated? Along with what was the old value and the new value.
I currently manually do this like this:
public function update(Requests\UpdatePetRequest $request, Pet $pet)
{
$changes = [];
if ($request->exists('name') && $request->name != $pet->name) {
$changes['name'] = array([
'old' => $pet->name,
'new' => $request->name
]);
}
if ($request->exists('avatar') && $request->avatar != $pet->avatar) {
$changes['avatar'] = array([
'old' => $pet->avatar,
'new' => $request->avatar
]);
}
if (!count($changes)) {
return response()->json(['error'=>'No properties changed'], 422);
}
$pet->update($request->all());
$body = json_encode($changes);
$message = new Message(['body' => $body, 'kind' => 'PET_UPDATE']);
}
Is there an automated way to do this?
You can't do that with update(), but you can use getDirty() before save():
$model = Model::find($id);
$model->fill($request->all());
$cahnges = $model->getDirty();
$model->save();
getDirty() will return you an array with changed columns only, for example:
['name' => 'New Name', 'address' => 'New Street, 12']

Laravel Excel - Select columns to export

I'm using Laravel Excel from maatwebsite but i have a problem with export data to xls file. I have this query but i don't need to show all columns in the xls file but i need to select all this columns to do operations before download the file. In my select i have 8 columns but in my headers i just have 7 to show but this doesn't work because the 8ª column appears too.
MY FUNCTION:
public function toExcel($id) { $b = Budget::find($id);
$budget = Budget_Item::join('budgets', 'budget__items.id_budget', '=', 'budgets.id')
->join('items_sizes', 'budget__items.id_itemSize', '=', 'items_sizes.id')
->join('items', 'items_sizes.id_item', '=', 'items.id')
->join('material_types', 'items_sizes.id_materialType', '=', 'material_types.id')
->select('items.reference AS Referência', 'items.name AS Descrição', 'items_sizes.size AS Tamanho', 'material_types.material_type AS Material', 'budget__items.amount AS Quantidade', 'items_sizes.unit_price AS Val.Unitário', 'budget__items.price AS Val.Total', 'budget__items.purchasePrice')
->where('id_budget', '=', $id)
->get();
$budgetUpdate = [];
$budgetUpdate[] = ['Referência', 'Descrição', 'Tamanho', 'Material', 'Quantidade', 'Val.Unitário', 'Val.Total'];
foreach ($budget as $key)
{
if ($key->purchasePrice > 0)
{
$key->unit_price = $key->purchasePrice;
}
$budgetUpdated[] = $key->toArray();
}
Excel::create('Proposta_'.$b->reference, function($excel) use($budgetUpdated)
{
// Set the title
$excel->setTitle('Proposta');
$excel->sheet('Sheetname', function($sheet) use($budgetUpdated)
{
$sheet->fromArray($budgetUpdated, null, 'A1', false, true);
});
})->download('xls');}
How can i solve that?
Thank's
Tested on Laravel excel 3.1 docs
on controller
public function exportAsCsv()
{
return Excel::download(new MyExport, 'invoices.xlsx');
}
on MyExport, look at the map function
class MyExport implements FromCollection, WithHeadings, WithMapping{
public function collection(){
return MyTable:all();
}
// here you select the row that you want in the file
public function map($row): array{
$fields = [
$row->myfield2,
$row->myfield1,
];
return fields;
}
}
also check this
For what its worth I ran into a similar issue and didnt find much in terms of a fix so heres my solution.
1. I query the DB in the callback and get all the data I need.
2. I then go over the collection and create a new array on each iteration and assign a value & header. Works great for picking out columns from a model
Excel::create('User List Export', function($excel) {
$excel->sheet('Users', function($sheet) {
$email = yourModelGoesHere::all();
foreach ($email as $key => $value) {
$payload[] = array('email' => $value['email'], 'name' => $value['name']);
}
$sheet->fromArray($payload);
});
})->download('xls');
You can try this way.
$user_id = Auth::user()->id
Excel::create('User', function($excel) use ($user_id){
$excel->sheet('Sheet', function($sheet) use($user_id){
$user = User::where('user_id', $user_id)->select('name', 'email', 'role', 'address')->get();
});
})->export('xls');
return redirect('your route');

Resources