I am trying to make soft deletes in my DB tables but it fails in one table. I made same things with other tables but only in one it dosen't work. When i click delete in view it deletes row in data base. I will show code of soft delete for this table and have hope that you will help me.
This is my migration for it:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class Invoices extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('invoices', function (Blueprint $table) {
$table->increments('id');
$table->string('invoicenumber')->nullable();
$table->date('invoicedate')->nullable();
$table->date('selldate')->nullable();
$table->integer('user_id')->unsigned()->nullable();
$table->integer('form_id')->unsigned()->nullable();
$table->integer('currency_id')->unsigned()->nullable();
$table->integer('proform_id')->unsigned()->nullable();
$table->string('paymentmethod')->nullable();
$table->date('paymentdate')->nullable();
$table->string('status')->nullable();
$table->string('comments')->nullable();
$table->string('city')->nullable();
$table->string('paid')->nullable();
$table->string('autonumber')->nullable();
$table->string('automonth')->nullable();
$table->string('autoyear')->nullable();
$table->string('name')->nullable();
$table->string('PKWIU')->nullable();
$table->string('quantity')->nullable();
$table->string('unit')->nullable();
$table->string('netunit')->nullable();
$table->string('nettotal')->nullable();
$table->string('VATrate')->nullable();
$table->string('grossunit')->nullable();
$table->string('grosstotal')->nullable();
$table->timestamps();
$table->time('deleted_at')->nullable();
});
Schema::table('invoices', function (Blueprint $table){
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
$table->foreign('form_id')
->references('id')
->on('forms')
->onDelete('cascade');
$table->foreign('currency_id')
->references('id')
->on('currencys')
->onDelete('cascade');
$table->foreign('proform_id')
->references('id')
->on('proforms')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('invoices');
}
}
This is model for invoice. Invoice.php
<?php
namespace App;
use Kyslik\ColumnSortable\Sortable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Invoice extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
use SoftDeletes;
use Sortable;
protected $table = 'invoices';
protected $fillable = [
'invoicenumber', 'invoicedate', 'id', 'selldate', 'user_id', 'paymentmethod',
'paymentdate', 'status', 'comments', 'city', 'paid', 'autonumber', 'automonth', 'autoyear', 'name',
'PKWIU', 'quantity', 'unit', 'netunit', 'nettotal',
'VATrate', 'grossunit', 'grosstotal', 'form_id', 'currency_id',
];
public $sortable = [ 'invoicenumber', 'invoicedate', 'id', 'selldate',
'user_id', 'paymentmethod', 'paymentdate', 'status', 'comments', 'grosstotal', 'nettotal', 'form_id', 'currency_id',];
protected $dates = ['deleted_at'];
public $primaryKey = 'id';
public function user()
{
return $this->belongsTo('App\User');
}
public function form()
{
return $this->hasOne('App\Form');
}
public function currency()
{
return $this->hasOne('App\Currency');
}
public function proform()
{
return $this->belongsTo('App\Proform');
}
}
InvoiceController.php
<?php
namespace App\Http\Controllers;
use Kyslik\ColumnSortable\Sortable;
use App\Invoice;
use Illuminate\Http\Request;
use App\User;
use App\Proform;
use App\Form;
use App\Currency;
use DB;
class InvoiceController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
function __construct()
{
$this->middleware('permission:product-list|product-create|product-edit|product-delete', ['only' => ['index','show']]);
$this->middleware('permission:product-create', ['only' => ['create','store']]);
$this->middleware('permission:product-edit', ['only' => ['edit','update']]);
$this->middleware('permission:product-delete', ['only' => ['destroy']]);
}
public function search4(Request $request)
{
$user = User::all('showname','id');
$invoices = Invoice::sortable()->paginate(5);
$query = DB::table('users')
->join('invoices', 'users.id', '=', 'invoices.user_id');
$search = $request->get('search');
$requestData = ['showname'];
/* $query = Proform::query(); */
foreach ($requestData as $field){
$query->orWhere($field, 'like', '%'.$search.'%');
}
$data2=$query->paginate(5);
return view('invoices.index', ['invoices' => $data2, 'user'=> $user])->with('i', ($request->input('page', 1) - 1) * 5);
}
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$user = User::all('showname','id');
$invoices = Invoice::sortable()->paginate(5);
return view('invoices.index',compact('invoices', 'user'))
->with('i', (request()->input('page', 1) - 1) * 5);
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{ $users = User::all('showname','id');
$forms = Form::all('id', 'form');
$currencys = Currency::all('id', 'currency', 'course');
return view('invoices.create')->with('users', $users, 'forms', 'currencys');
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
request()->validate([
'invoicedate' => 'required',
'user_id' => 'required',
'selldate' => 'required',
'paymentdate' => 'required',
'paymentmethod' => 'required',
'status' => 'required',
'comments' => 'nullable',
'city' => 'nullable',
'paid' => 'nullable',
'name' => 'required',
'PKWIU' => 'nullable',
'quantity' => 'required',
'unit' => 'required',
'netunit' => 'required',
'nettotal' => 'required',
'VATrate' => 'required',
'grossunit' => 'required',
'grosstotal' => 'required',
]);
Invoice::create($request->all());
return redirect()->route('invoices.index')
->with('success','Invoice created successfully.');
}
/**
* Display the specified resource.
*
* #param \App\Product $product
* #return \Illuminate\Http\Response
*/
public function show(Invoice $invoice)
{
return view('invoices.show',compact('invoice'));
}
/**
* Show the form for editing the specified resource.
*
* #param \App\Product $product
* #return \Illuminate\Http\Response
*/
public function edit(Invoice $invoice)
{
$users = User::all('showname','id');
$forms = Form::all('id', 'form');
$currencys = Currency::all('id', 'currency', 'course');
return view('invoices.edit',compact('invoice', 'users', 'forms', 'currencys'));
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param \App\Product $product
* #return \Illuminate\Http\Response
*/
public function update(Request $request, Invoice $invoice)
{
request()->validate([
'invoicedate' => 'required',
'user_id' => 'required',
'selldate' => 'required',
'paymentdate' => 'required',
'paymentmethod' => 'required',
'status' => 'required',
'comments' => 'nullable',
'city' => 'nullable',
'paid' => 'nullable',
'name' => 'required',
'PKWIU' => 'nullable',
'quantity' => 'required',
'unit' => 'required',
'netunit' => 'required',
'nettotal' => 'required',
'VATrate' => 'required',
'grossunit' => 'required',
'grosstotal' => 'required',
]);
$invoice->update($request->all());
return redirect()->route('invoices.index')
->with('success','Invoice updated successfully');
}
/**
* Remove the specified resource from storage.
*
* #param \App\Product $product
* #return \Illuminate\Http\Response
*/
public function destroy(Invoice $invoice)
{
$invoice->delete();
return redirect()->route('invoices.index')
->with('success','Invoice deleted successfully');
}
}
Routes:
<?php
use Illuminate\Support\Facades\Route;
Route::get('/', function(){
return view('welcome');
});
Route::get('home');
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
Route::group(['middleware' => ['auth']], function () {
Route::get('/search', 'UserController#search');
Route::get('/search2', 'ProductController#search2');
Route::get('/search3', 'ProformController#search3');
Route::get('/search4', 'InvoiceController#search4');
Route::post('/duplicate', 'ProformController#duplicate')->name('proforms.duplicate');
Route::get('data', 'UserController#index');
Route::get('posts', 'PostController#index');
Route::get('/prodview', 'TestController#prodfunct');
Route::resource('roles', 'RoleController');
Route::resource('users', 'UserController');
Route::resource('permissions', 'PermissionController');
Route::resource('products', 'ProductController');
Route::resource('invoices', 'InvoiceController');
Route::resource('category', 'CategoryController');
Route::resource('invoices', 'InvoiceController');
Route::resource('proforms', 'ProformController');
});
View:
#extends('layouts.app')
#section('content')
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2>Zarządzanie fakturami</h2>
</div>
<div class="col-md-4">
<form action="/search4" method="get">
<div class="input-group">
<input type="search" name="search" class="form-control">
<span class="input-group-prepend">
<button type="submit" class="btn btn-primary">Wyszukaj</button>
</span>
</div>
</form>
</div>
<div class="pull-right">
#can('product-create')
<a class="btn btn-success" href="{{ route('invoices.create') }}"> Utwórz nową fakturę</a>
#endcan
</div>
</div>
</div>
#if ($message = Session::get('success'))
<div class="alert alert-success">
<p>{{ $message }}</p>
</div>
#endif
<table class="table table-bordered">
<tr>
<th scope="col">#sortablelink('id', 'Numer')</th>
<th scope="col">#sortablelink('invoicnumber', 'Numer faktury')</th>
<th scope="col">#sortablelink('invoicedate', 'Data wystawienia')</th>
<th scope="col">#sortablelink('user_id', 'Kontrachent')</th>
<th scope="col">#sortablelink('selldate', 'Data sprzedaży')</th>
<th scope="col">#sortablelink('paymentdate', 'Termin płatności')</th>
<th scope="col">#sortablelink('status', 'Status')</th>
<th scope="col">#sortablelink('nettotal', 'Netto razem')</th>
<th scope="col">#sortablelink('grosstotal', 'Brutto razem')</th>
<th width="280px">Akcja</th>
</tr>
#foreach ($invoices as $invoice)
<tr>
<td>{{ ++$i }}</td>
<td>{{ $invoice->invoicenumber }}</td>
<td>{{ $invoice->invoicedate }}</td>
<td>{{ $invoice->user->showname ?? $invoice->showname }}</td>
<td>{{ $invoice->selldate }}</td>
<td>{{ $invoice->paymentdate }}</td>
<td>{{ $invoice->status }}</td>
<td>{{ $invoice->nettotal }}</td>
<td>{{ $invoice->grosstotal }}</td>
<td>
<form action="{{ route('invoices.destroy',$invoice->id) }}" method="POST">
<a class="btn btn-info" href="{{ route('invoices.show',$invoice->id) }}">Więcej</a>
#can('product-edit')
<a class="btn btn-primary" href="{{ route('invoices.edit',$invoice->id) }}">Edytuj</a>
#endcan
#csrf
#method('DELETE')
#can('product-delete')
<button type="submit" class="btn btn-danger">Usuń</button>
#endcan
</form>
</td>
</tr>
#endforeach
</table>
{!! $invoices ?? ''->appends(request()->except('page'))->render() !!}
<p class="text-center text-primary"><small>ARTplus 2020</small></p>
#endsection
You must to use $table->softDeletes(); instead of $table->time('deleted_at')->nullable();.
softDeletes() method used timestamp instead of time format date. Maybe it will solve your problem;
Related
I have three tables: Users, Videogames and videogames_users . How can I display the videogames selected by the users?
This is what I need to achieve (picture 1) but what I’m getting is this (picture 2)
Picture 1
Picture 2
Controller
public function users()
{
$videogamesBuilder = VideoGames::with(['plataforma', 'generos', 'categoria', 'numJugadores', 'users']);
$users = DB::table(users)->select('user_id', 'nombre', 'email','rol_usuario')->get();
$videogames = $videogamesBuilder->paginate(4)->withQueryString();
return view('admin.videojuegos.users', [
'videogames' => $videogames,
'users' => $users,
]);
}
Model
class User extends User
{
use HasApiTokens, Notifiable;
protected $table = 'users';
protected $primaryKey = 'user_id';
protected $fillable = [ 'email', 'nombre', 'password', 'rol_usuario'];
protected $hidden = ['password', 'remember_token'];
public const VALIDATE_RULES = [
'email' => 'required',
'nombre' => 'required|min:5',
'password' => 'required|numeric|min:0',
'rol_usuario' => 'required',
];
}
Migration Videogame
class CreateVideojuegosTable extends Migration
{
public function up()
{
Schema::create('videogames', function (Blueprint $table) {
$table->id('videogame_id');
$table->string('titulo', 300);
$table->text('subtitulo');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('videogames');
}
}
Migration Users
return new class extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id('user_id');
$table->string('email')->unique();
$table->string('nombre');
$table->string('password');
$table->string('rol_usuario');
$table->rememberToken();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('users');
}
};
Migration Videogames selected by users
return new class extends Migration
{
public function up()
{
Schema::create('videojuegos_tienen_usuarios', function (Blueprint $table) {
$table->foreignId('videogames_id')->constrained('videogames', 'videogames_id');
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('user_id')->on('users');
$table->primary(['videogames_id', 'user_id']);
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('videojuegos_tienen_usuarios');
}
};
Sedeer
class VideojuegosTienenUsuariosSeeder extends Seeder
{
public function run()
{
\DB::table('videojuegos_tienen_usuarios')->insert([
[
'videojgame_id' => 1,
'user_id' => 1,
'created_at' => now(),
'updated_at' => now(),
],
[
'videojgame_id' => 2,
'user_id' => 1,
'created_at' => now(),
'updated_at' => now(),
],
[
'videojgame_id' => 2,
'user_id' => 2,
'created_at' => now(),
'updated_at' => now(),
],
[
'videojgame_id' => 2,
'user_id' => 3,
'created_at' => now(),
'updated_at' => now(),
],
[
'videojgame_id' => 3,
'user_id' => 1,
'created_at' => now(),
'updated_at' => now(),
]
]);
}
}
view
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>ID</th>
<th>Nombre de usuario</th>
<th>Email Usuario</th>
<th>Rol del Usuario</th>
</tr>
</thead>
<tbody>
#foreach($users as $user)
<tr>
<td>{{ $user->user_id }}</td>
<td>{{ $user->nombre }}</td>
<td>{{ $user->email }}</td>
<td>{{ $user->rol_usuario }}</td>
#endforeach
</tr>
</tbody>
</table>
Your trying to implement a many-to-many relationship, please check: https://laravel.com/docs/9.x/eloquent-relationships#many-to-many
Just follow the table naming structure and add this method to your User model:
public function videogames()
{
return $this->belongsToMany(VideoGame::class);
}
Afterwards you can query the videogames of an user in your view for each user like:
#foreach($users as $user)
<tr>
<td>{{ $user->user_id }}</td>
<td>{{ $user->nombre }}</td>
<td>{{ $user->email }}</td>
<td>{{ $user->rol_usuario }}</td>
<td>
#foreach($user->videogames as $game)
{{ $game->titulo }},
#endforeach
</td>
#endforeach
I am pretty new to Laravel, and I am facing an issue.
I creating a website where users can upload products (modules) to the site and for their product they have to choose a category aswell as subcategory.
Now, I want to create a view.blade which automatically displays all the uploaded products with their corresponding subcategory. So on the roof page I want to display all the uploaded modules with subcategory roof.
However, the view page is loaded but no data is displayed...
I have created a ModulesController:
{ class ModulesController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function create()
{
return view('modules/create');
}
public function store()
{
$data = request()->validate([
'title' => ['required', 'string', 'max:50'],
'description' => ['required', 'string', 'max:255'],
'price' => ['required', 'string'],
'category' => ['required', 'string'],
'subcategory' => ['required', 'string'],
'image' => ['required', 'image'],
]);
#dd($data);
$imagePath = request('image')->store('uploads', 'public');
$image = Image::make(public_path("storage/{$imagePath}"))->fit(1200, 1200);
$image->save();
auth()->user()->modules()->create([
'title' => $data['title'],
'description' => $data['description'],
'price' => $data['price'],
'category' => $data['category'],
'subcategory' => $data['subcategory'],
'image' => $imagePath,
]);
return redirect('/profile/' . auth()->user()->id);
}
public function show(\App\Models\Module $module)
{
return view('modules.show', compact('module'));
A corresponding model:
class Module extends Model
{
protected $fillable =[
'title',
'description',
'price',
'category',
'subcategory',
'image',
];
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}
A Module migration database:
class CreateModulesTable extends Migration
{
public function up()
{
Schema::create('modules', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->string('title');
$table->text('description');
$table->string('price');
$table->string('category');
$table->string('subcategory');
$table->string('image');
$table->timestamps();
$table->index('user_id');
});
}
And I am trying to pass it to this view where I want to show all the images.
I have tried to use this loop but I can't make it work....
#section('content')
<div class="container">
<div class="flex justify-center pt-8 sm:justify-start
sm:pt-0">
<h1>All modules with corresponding subcategory</h1>
#if ( $module["subcategory"] == "dak" )
#foreach ($modules as $module)
<a href="/module/{{ $module->id }}">
<img src="/storage/{{$module->image}}"
class="w-100" alt=""/>
<a/>
#endforeach
#endif
</div>
</div>
#endsection
If anyone can help this would be much appreciated.
P.S. "dak" is a subcategory and means "roof".
A user have many products and product have own id
2)And A product have many projects
I have trouble to make ProjectController
Note: if you need more details you can ask.
This is my user model user.php
public function Products(){
return $this->hasMany('App\Models\Product');
}
public function Project(){
return $this->hasMany('App\Models\Project');
}
This is my Product model product.php
public function User(){
return $this->belongsTo(User::class);
}
public function Project(){
return $this->hasMany('App\Models\Project');
}
This is my project model project.php
public function User(){
return $this->belongsTo(User::class);
}
public function Product(){
return $this->belongsTo(Product::class);
}
Here product table have user_id as forignId and project table have user_id and product_id as forign key
This is project table project.php
$table->unsignedBigInteger ('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreignId('product_id')->nullable();
This is here I have troubles in ProjectController.php
class ProjectController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
// $projects = Project::where('user_id',auth()->user()->id)->latest()->paginate(20);
$projects = Project::where('user_id',auth()->user()->id)->where('product_id')->latest()->paginate(20);
return view('projects.index', compact('projects'))
->with('i', (request()->input('page', 1) - 1) * 5);
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
return view('projects.create');
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request,$id)
{
$request->validate([
'chapter_name' => 'required',
'sub_section_name' => 'required',
'title_1' => 'required',
'description_1' => 'required',
'image_1' => 'required',
'image_2' => 'required',
'image_3' => 'required',
'title_2' => 'required',
'description_2' => 'required',
'title_3' => 'required',
'description_3' => 'required',
'video_1' => 'required',
'video_2' => 'required',
'video_3' => 'required',
]);
// $input = $request->all();
$input['user_id'] = auth()->user()->id;
$input['product_id'] = $id;
Project::create($input);
return redirect()->route('project.index')
->with('success','Product created successfully.');
}
/**
* Display the specified resource.
*
* #param \App\Models\Project $project
* #return \Illuminate\Http\Response
*/
public function show(Project $project)
{
// $category = $project->category;
return view('projects.show', compact('project'));
}
/**
* Show the form for editing the specified resource.
*
* #param \App\Models\Project $project
* #return \Illuminate\Http\Response
*/
public function edit(Project $project)
{
return view('projects.edit', compact('project'));
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param \App\Models\Project $project
* #return \Illuminate\Http\Response
*/
public function update(Request $request, Project $project)
{
// $user_id = Auth::user()->id ;
$request->validate([
'chapter_name' => 'required',
'sub_section_name' => 'required',
'title_1' => 'required',
'description_1' => 'required',
'image_1' => 'required',
'image_2' => 'required',
'image_3' => 'required',
'title_2' => 'required',
'description_2' => 'required',
'title_3' => 'required',
'description_3' => 'required',
'video_1' => 'required',
'video_2' => 'required',
'video_3' => 'required',
]);
$input = $request->all();
$project->update($input);
return redirect()->route('project.index')
->with('success','Product updated successfully');
}
/**
* Remove the specified resource from storage.
*
* #param \App\Models\Project $project
* #return \Illuminate\Http\Response
*/
public function destroy(Project $project)
{
$project->delete();
return redirect()->route('projects.index')
->with('success', 'Project deleted successfully');
}
public function importProject()
{
Excel::import(new ProjectsImport, request()->file('file'));
return back()->with('success','Project created successfully.');
}
public function export()
{
return Excel::download(new UsersExport, 'projects.xlsx');
}
}
This is user table user.php
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->foreignId('current_team_id')->nullable();
$table->text('profile_photo_path')->nullable();
$table->timestamps();
});
This is products table products.php
Schema::create('products', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->text('detail');
$table->string('color');
$table->string('image');
$table->string('logo');
$table->unsignedBigInteger('user_id');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
This is project table project.php
Schema::create('projects', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('chapter_name', 255)->nullable();
$table->string('sub_section_name', 500)->nullable();
$table->string('title_1', 255)->nullable();
$table->string('description_1', 5000)->nullable();
$table->string('image_1', 255)->nullable();
$table->string('image_2', 255)->nullable();
$table->string('image_3', 255)->nullable();
$table->string('title_2', 255)->nullable();
$table->string('description_2', 5000)->nullable();
$table->string('title_3', 255)->nullable();
$table->string('description_3', 255)->nullable();
$table->string('video_1', 255)->nullable();
$table->string('video_2', 255)->nullable();
$table->string('video_3', 255)->nullable();
$table->unsignedBigInteger ('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
// $table->foreignId('product_id')->nullable();
$table->unsignedBigInteger('product_id')->references('id')->on('products')->onDelete('cascade');
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->nullable();
});
Thanks for help
Below are 2 possible causes of your error.
The uploaded file request()->file('file') lucks a column with header name id.
If this is the case you may wish to perform some sort of header validation during the import process. i.e:
<?php
namespace App\Imports;
use App\Models\Project;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\Importable;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
class ProjectsImport implements ToCollection, WithHeadingRow
{
use Importable;
private const HEADING_NAMES = [
'chapter_name',
'sub_section_name',
'title_1',
'description_1',
'image_1',
'image_2',
'image_3',
'title_2',
'description_2',
'title_3',
'description_3',
'video_1',
'video_2',
'video_3',
'id'
];
private const HEADING_ROW = 0;
public function collection(Collection $rows)
{
if (
(count($columnHeadings = array_keys($rows[self::HEADING_ROW])) == count(self::HEADING_NAMES))
&& (array_diff($columnHeadings, self::HEADING_NAMES) === array_diff(self::HEADING_NAMES, $columnHeadings))
) {
redirect()
->back()
->withErrors([
"import" => "Incorrect excel sheet headers."
. " "
. "Expected:"
. " " . json_encode(self::HEADING_NAMES)
]);
}
// If validation fails, it won't reach the next statement.
foreach ($rows as $row) {
Project::create([
'chapter_name' => $row['chapter_name'],
// ...
]);
}
}
public function headingRow(): int
{
return self::HEADING_ROW;
}
}
You're using header names to access the data yet by default $row indexes are used instead. i.e: $row[0] instead of $row['chapter_name'].
If this is the case you may wish to implement the WithHeadingRow concern.
Laravel Excel | Heading Row
In case your file contains a heading row (a row in which each cells
indicates the purpose of that column) and you want to use those names
as array keys of each row, you can implement the WithHeadingRow
concern.
i.e:
<?php
use App\Models\Project;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
class ProjectsImport implements ToModel, WithHeadingRow
{
public function model(array $row)
{
return new Project([
'chapter_name' => $row['chapter_name'],
// ...
]);
}
}
Addendum
If the uploaded file doesn't have the actual 'product_id's but instead has the product names, you could perform some sort of preprocessing to replace product names with their respective 'product_id's.
In addition, you could use some row validation to ensure that the product names exist in the database.
A. Validate product names making sure that they exist.
Laravel Excel | Row Validation without ToModel
<?php
namespace App\Imports;
use App\Models\Project;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\Importable;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
class ProjectsImport implements ToCollection, WithHeadingRow
{
use Importable;
public function collection(Collection $rows)
{
Validator::make($rows->toArray(), [
// Table Name: 'products'. Table Column Name: 'name'. Excel Sheet Header Name: 'product_name'.
'*.product_name' => ['required', 'exists:products,name'],
])->validate();
// If validation fails, it won't reach the next statement.
foreach ($rows as $row) {
Project::create([
'chapter_name' => $row['chapter_name'],
// ...
]);
}
}
}
B. Perform some sort of preprocessing to replace product names with their respective 'product_id's
Laravel Excel | Mapping rows
By adding WithMapping you map the data that needs to be added as
row. This way you have control over the actual source for each column.
i.e:
<?php
namespace App\Imports;
use App\Models\Project;
use App\Models\Product;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\Importable;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithMapping;
class ProjectsImport implements ToCollection, WithHeadingRow, WithMapping
{
use Importable;
public function collection(Collection $rows)
{
Validator::make($rows->toArray(), [
'*.chapter_name' => 'required',
'*.sub_section_name' => 'required',
'*.title_1' => 'required',
'*.description_1' => 'required',
'*.image_1' => 'required',
'*.image_2' => 'required',
'*.image_3' => 'required',
'*.title_2' => 'required',
'*.description_2' => 'required',
'*.title_3' => 'required',
'*.description_3' => 'required',
'*.video_1' => 'required',
'*.video_2' => 'required',
'*.video_3' => 'required',
'*.product_name' => ['required', 'exists:products,name'],
'*.product_id' => ['required', 'numeric', 'exists:products,id'],
])->validate();
foreach ($rows as $row) {
Project::create([
'chapter_name' => $row['chapter_name'],
'product_id' => $row['product_id']
// ...
]);
}
}
public function map($row): array
{
$mappedRow = $row;
$mappedRow['product_id'] = (isset($row['product_name'])
&& ($product = Product::firstWhere('name', $row['product_name'])))
? $product->id
: null;
return $mappedRow;
// From this point, your rules() and model() functions can access the 'product_id'
}
}
Addendum 2
It appears that your second where clause in index method is lucking (ProjectController).
// ...
public function index()
{
// $projects = Project::where('user_id',auth()->user()->id)->latest()->paginate(20);
$projects = Project::where('user_id',auth()->user()->id)->where('product_id')->latest()->paginate(20); ❌
return view('projects.index', compact('projects'))
->with('i', (request()->input('page', 1) - 1) * 5);
}
// ...
A where clause requires at least 2 parameters. One 'product_id' parameter is passed for your case.
I have a problem with the validation of images or mimes overall.
This is my code:
$this->validate($request, [
'title' => 'required|max:50',
'content' => 'required|min:20',
'description' => 'required|max:140',
'file' => 'image'
]);
When I try to upload any file I get the error:
The file failed to upload.
When I dont have the image flag, everthing just works fine.
I can put things like required or max:5000.
I looked at the documentation and it should work, but it doesn't.
So what am I doing wrong?
EDIT:
Added form:
{!! Form::open(['method' => 'POST', 'action' => 'PostController#store', 'files' => 'true' ]) !!}
<div class="form-group">
{!! Form::label('title', 'Title:') !!}<br>
{!! Form::text('title', null, ['class' => 'form-control']) !!}
<small>Max 50 characters</small>
<br>
{!! Form::label('description', 'Description:') !!}<br>
{!! Form::textarea('description', null, ['class' => 'form-control', 'rows' => 2, 'cols' => 50]) !!}
<small>Max 140 characters</small>
<br>
{!! Form::label('content', 'Content:') !!}<br>
{!! Form::textarea('content', null, ['class' => 'form-control', 'id' =>'content', 'rows' => 8, 'cols' => 50]) !!}
<br>
{!! Form::label('file', 'Upload a thumbnail here:') !!} <br>
{!! Form::file('file', null, ['class' => 'form-control']) !!} <br>
<small>Only jpeg, png, bmp, gif, or svg</small>
</div>
{!! Form::submit(null, ['class' => 'btn btn-primary']) !!}
{!! Form::close() !!}
EDIT 2:
added html:
<form method="POST" action="https://blog.luukwuijster.eu" accept-charset="UTF-8" enctype="multipart/form-data"><input name="_token" type="hidden" value="N72xyc8mmbdFGrS78sdhIqh25awN30AboL9ecqGm">
<div class="form-group">
<label for="title">Title:</label><br>
<input class="form-control" name="title" type="text" id="title">
<small>Max 50 characters</small>
<br>
<label for="description">Description:</label><br>
<textarea class="form-control" rows="2" cols="50" name="description" id="description"></textarea>
<small>Max 140 characters</small>
<br>
<label for="content">Content:</label><br>
<textarea class="form-control" id="content" rows="8" cols="50" name="content" style="display: none;"></textarea>
<br>
<label for="file">Upload a thumbnail here:</label> <br>
<input name="file" type="file" id="file"> <br>
<small>Only jpeg, png, bmp, gif, or svg</small>
</div>
<input class="btn btn-primary" type="submit">
</form>
EDIT 3:
added the controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Post;
use App\User;
use Illuminate\Support\Facades\Auth;
use GrahamCampbell\Markdown\Facades\Markdown;
class PostController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function __construct()
{
$this->middleware('auth')->except('index', 'show');
}
public function index()
{
$posts = Post::latest()->get();
return view('welcome', compact('posts'));
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
return view('create');
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$input = $request->all();
$file = $request->file('file');
if($file){
$name = rand(1, 1000000000).'_'.$file->getClientOriginalName();
$file->move('images', $name);
$input['thumbnail'] = $name;
}else{
$input['thumbnail'] = "No_Image.png";
}
//TODO: validatie voor de thumbnails.
$this->validate($request->all(), [
'title' => 'required|max:50',
'content' => 'required|min:20',
'description' => 'required|max:140',
'file' => 'image'
]);
Auth::user()->post()->create($input);
return redirect('/');
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($id)
{
$post = Post::findOrFail($id);
$content = Markdown::convertToHtml($post->content);
return view('post', compact('post', 'content'));
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function edit($id)
{
$post = Auth::user()->post()->findOrFail($id);
return view('edit', compact('post'));
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$input = $request->all();
$file = $request->file('file');
if($file){
$name = rand(1, 1000000000).'_'.$file->getClientOriginalName();
$file->move('images', $name);
$input['thumbnail'] = $name;
}
//TODO: validatie voor de thumbnails.
$this->validate($request, [
'title' => 'required|max:50',
'content' => 'required|min:20',
'description' => 'required|max:140',
'file' => 'image'
]);
Auth::user()->post()->findOrFail($id)->update($input);
return redirect('/home');
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy($id)
{
Auth::user()->post()->withTrashed()->findOrFail($id)->forceDelete();
return redirect('/recyclebin');
}
public function restore($id)
{
Auth::user()->post()->withTrashed()->findOrFail($id)->restore();
return redirect('/home');
}
public function recyclebin()
{
$posts = Post::onlyTrashed()->get();
return view('recyclebin', compact('posts'));
}
public function remove($id){
//Post::findOrFail($id)->delete();
Auth::user()->post()->findOrFail($id)->delete();
return redirect('/home');
}
}
In your opening form tag add this:
enctype="multipart/form-data"
and in the file input(where you actually upload it), add this:
multiple="multiple"
Edit:
In every form you should use the csrf_field() method. add also just befor the openning form tag.
2019 update:
You can add the #csrf directive instead of csrf_field() method. It's the same, just more convenient for some people.
Hope this helps you.
Try changing you controller like this --
public function store(Request $request) {
$this->validate($request, [
'title' => 'required|max:50',
'content' => 'required|min:20',
'description' => 'required|max:140',
'file' => 'image'
]);
$input = $request->all();
$file = $request->file('file');
if($request->hasFile('file')){
$name = rand(1, 1000000000).'_'.$file->getClientOriginalName();
$file->move('images', $name);
$input['thumbnail'] = $name;
}else{
$input['thumbnail'] = "No_Image.png";
}
Auth::user()->post()->create($input);
return redirect('/');
}
And changing 'files' => 'true' to 'files' => true
This is my code
$validator = Validator::make($input, [
'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048'
])
if ($validator - > fails()) {
return $this - > sendError('Validation Error.', $validator - > errors());
}
i'm doing a ecommerce, i created a resource controller for ORDERS. But i have some problem to get information about the products. i would like show all items orders with information about the products buyed, like name, price, category. Each order item have a "product_id" relation.
i have this tables migration:
Orders
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateOrdersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('orders', function (Blueprint $table) {
$table->increments('id');
$table->decimal('subtotal', 5, 2);
$table->decimal('shipping', 5,2);
$table->text('method');
$table->text('status');
$table->text('order_code');
$table->text('fullname_ship');
$table->text('address_ship');
$table->text('app_ship');
$table->text('province_ship');
$table->text('country_ship');
$table->text('email_ship');
$table->text('phone_ship');
$table->text('fullname_bill');
$table->text('address_bill');
$table->text('app_bill');
$table->text('province_bill');
$table->text('country_bill');
$table->text('email_bill');
$table->text('phone_bill');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('orders');
}
}
Orders items
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateOrderItemsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('orders_items', function (Blueprint $table) {
$table->increments('id');
$table->decimal('price', 5, 2);
$table->integer('quantity')->unsigned();
$table->integer('product_id')->unsigned();
$table->foreign('product_id')
->references('id')
->on('products')
->onDelete('cascade');
$table->integer('order_id')->unsigned();
$table->foreign('order_id')
->references('id')
->on('orders')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('order_items');
}
}
Products table
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateProductsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
//Up creare table
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->string('name', 255);
$table->string('slug');
$table->text('description');
$table->string('extract', 300);
$table->decimal('price', 5, 2);
$table->string('image', 300);
$table->boolean('visible');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
$table->integer('category_id')->unsigned();
// relazioni
$table->foreign('category_id')
->references('id')
->on('categories')
->onDelete('cascade');
//crea // Ogni prodotto ha un autore( artista)
// ----//
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
//eliminare table
public function down()
{
Schema::drop('products');
}
}
My OrderController.php
<?php
namespace dixard\Http\Controllers\Admin;
use Illuminate\Http\Request;
use dixard\Http\Requests;
use dixard\Http\Controllers\Controller;
use dixard\Order;
use dixard\OrderItem;
use dixard\Product;
use dixard\Category;
use Validator;
class OrderController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$orders = Order::orderBy('id')->paginate(15);
return view('admin.order.index', compact('orders'));
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
return view ('admin.order.create');
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$rules = [
'status' => 'required',
'method' => 'required',
'order_code' => 'required',
'fullname_ship' => 'required',
'address_ship' => 'required',
'app_ship' => 'required',
'province_ship' => 'required',
'country_ship' => 'required',
'email_ship' => 'required',
'phone_ship' => 'required',
];
$messages = [
'status.required' => 'Status ordine richiesto',
'method.required' => 'Metodo di pagamento richiesto',
'order_code.required' => 'Codice ordine richiesto',
'fullname_ship.required' => 'Nome e cognome richiesto',
'address_ship.required' => 'Indirizzo spedizione richiesto',
'app_ship.required' => 'App/Interno richiesto',
'province_ship.required' => 'Città/Provincia di spedizione richiesto',
'country_ship.required' => 'Paese di spedizione richiesto',
'email_ship.required' => 'Email campo richiesto',
'phone_ship.required' => 'Cellulare/spedizione richiesto',
];
$validator = Validator::make($request->all(), $rules, $messages);
if ($validator->fails()){
return redirect('admin/order/create')->withErrors($validator);
}else {
$data = [
'status' => $request->get('status'),
'method' => $request->get('method'),
'order_code' => $request->get('order_code'),
'shipping' => $request->get('shipping'),
'subtotal' => $request->get('subtotal'),
'fullname_ship' => $request->get('fullname_ship'),
'address_ship' => $request->get('address_ship'),
'app_ship' => $request->get('app_ship'),
'province_ship' => $request->get('province_ship'),
'country_ship' => $request->get('country_ship'),
'email_ship' => $request->get('email_ship'),
'phone_ship' => $request->get('phone_ship'),
'fullname_bill' => $request->get('fullname_bill'),
'address_bill' => $request->get('address_bill'),
'app_bill' => $request->get('app_bill'),
'province_bill' => $request->get('province_bill'),
'country_bill' => $request->get('country_bill'),
'email_bill' => $request->get('email_bill'),
'phone_bill' => $request->get('phone_bill'),
];
$order = Order::create($data);
return redirect('admin/order')->with('message', 'Ordine creato!');
}
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show(Order $order)
{
$items = OrderItem::orderBy('id', 'desc')->paginate(20);
$items_product_id = $items->product_id;
$items_products=Product::with('items_product_id')->get();
//$products = Product::where('id', $items->product_id)->orderBy('id', 'desc');
return view('admin.order.show', compact('items','items_products'));
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function edit(Order $order)
{
return View('admin.order.edit', compact('order'));
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, Order $order)
{
$id= $order->id;
$rules = [
'status' => 'required',
'order_code' => 'required',
'shipping' => 'required',
'subtotal' => 'required',
'fullname_ship' => 'required',
'address_ship' => 'required',
'app_ship' => 'required',
'province_ship' => 'required',
'country_ship' => 'required',
'email_ship' => 'required',
'phone_ship' => 'required',
];
$messages = [
'status.required' => 'Status ordine richiesto',
'order_code.required' => 'Codice ordine richiesto',
'shipping.required' => 'Costo spedizione richiesto',
'subtotal.required' => 'Totale costo prodotti - SUBTOTAL richiesto',
'fullname_ship.required' => 'Nome e cognome richiesto',
'address_ship.required' => 'Indirizzo spedizione richiesto',
'app_ship.required' => 'App/Interno richiesto',
'province_ship.required' => 'Città/Provincia di spedizione richiesto',
'country_ship.required' => 'Paese di spedizione richiesto',
'email_ship.required' => 'Email campo richiesto',
'phone_ship.required' => 'Cellulare/spedizione richiesto',
];
$validator = Validator::make($request->all(), $rules, $messages);
if ($validator->fails()){
return redirect()->route('admin.order.edit', $id)->withErrors($validator)->withInput();
}
// if there is not any error go to update
else{
// if email id different by input, so if email input update also email
$s = new Order;
$data = array(
'status' => $request->get('status'),
'method' => $request->get('method'),
'order_code' => $request->get('order_code'),
'shipping' => $request->get('shipping'),
'subtotal' => $request->get('subtotal'),
'fullname_ship' => $request->get('fullname_ship'),
'address_ship' => $request->get('address_ship'),
'app_ship' => $request->get('app_ship'),
'province_ship' => $request->get('province_ship'),
'country_ship' => $request->get('country_ship'),
'email_ship' => $request->get('email_ship'),
'phone_ship' => $request->get('phone_ship'),
'fullname_bill' => $request->get('fullname_bill'),
'address_bill' => $request->get('address_bill'),
'app_bill' => $request->get('app_bill'),
'province_bill' => $request->get('province_bill'),
'country_bill' => $request->get('country_bill'),
'email_bill' => $request->get('email_bill'),
'phone_bill' => $request->get('phone_bill'),
);
$s->where('id', '=', $request->get('id'))->update($data);
return redirect('admin/order')->with('message', 'Ordine aggiornato con successo!');
}
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy(Order $order)
{
$deleted=$order->delete();
if(isset($deleted))
{
return redirect('admin/order')->with('message', 'Ordine eliminato con successo!');
} else {
return redirect('admin/order')->with('message-error', 'Ordine non eliminato');
}
}
}
I created the view show.blade.php to show all items ordered, i would like show all items with information about the products, like name, price, category. Each order item have a "product_id" relation.
i'm trying so in show.blade.php:
#foreach($items as $item)
<tr class="even pointer">
<td class=" ">{{ $item->id }}</td>
<td class=" ">{{ $item->product_id }}</td>
<td class=" ">{{ $item->quantity }}</td>
<td class=" ">€{{ $item->order_id }}</td>
</td>
</td>
</tr>
#endforeach
#foreach($items_products as $items_product)
<tr class="even pointer">
<td class=" ">{{ $items_product->id }}</td>
<td class=" ">{{ $items_product->name }}</td>
<td class=" ">{{ $items_product->price }}</td>
<td class=" ">€{{ $items_product->description }}</td>
</td>
</td>
</tr>
#endforeach
But it doesnt work. Thank you for your help! if you need models:
Product MODEL
namespace dixard;
use Illuminate\Database\Eloquent\Model;
use dixard\User;
use dixard\Category;
use dixard\OrderItem;
class Product extends Model
{
protected $table = 'products';
protected $fillable =
[
'name',
'slug',
'description',
'extract',
'image',
'visible',
'price',
'category_id',
'user_id'
];
public function user() {
return $this->belongsTo('dixard\User');
}
public function category() {
return $this->belongsTo('dixard\Category');
}
public function OrderItem() {
return $this->belongsTo('dixard\OrderItem');
}
}
Order items MODEL
<?php
namespace dixard;
use Illuminate\Database\Eloquent\Model;
use dixard\Product;
class OrderItem extends Model
{
// DIrgli che ci lascia scrivere
protected $table = 'orders_items';
protected $fillable = [
'price',
'quantity',
'product_id',
'order_id'
];
public $timestamps = false;
public function product()
{
return $this->hasMany('dixard\Product');
}
}
Order MODEL
<?php
namespace dixard;
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
// DIrgli che ci lascia scrivere
protected $table = 'orders';
// gli dico che voglio scrivere questo campi
protected $fillable = [
'subtotal',
'shipping',
'method',
'status',
'order_code',
'fullname_ship',
'address_ship',
'app_ship',
'province_ship',
'country_ship',
'email_ship',
'phone_ship',
'fullname_bill',
'address_bill',
'app_bill',
'province_bill',
'country_bill',
'email_bill',
'phone_bill',
];
}