laravel 8 store() & index() functions doesn't work - php

Salam i am new in laravel i try to show & store data and index() and store() functions doesn't work!!
its display as result
500 | SERVER ERROR
this is the controller code:
namespace App\Http\Controllers;
use App\Models\Enseignant;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class EnseignantController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
return response()->json(Enseignant::all(),200);
}
public function store(Request $request)
{
try{
$enseigante = Enseignant::create($request->all());
return response($enseigante,201);
}catch(Throwable $e){
report($e);
return false;
}
}

In order to use the create method in the controller, you need to make sure that the fillable things are mentioned in the model.
protected $fillable = [
'name',
'email',
'password',
];
And to retrieve the data you can use.
public function index()
{
$admins = admin::all();
return view('totalUser', compact('admins'));
}
To show the data on your view you can do this:
#foreach($admins as $admin)
<p>{{$admin->name}}</p>
#endforeach

What's the error we cannot understand just by the status code share the actual error

Related

How can I use the show method of my resource controller on a soft deleted model?

So I have a resource controller called ProjectController and I added soft delete and use it as an archive.
Route::get('project/archive', 'ProjectController#trash')->name('project.archive');
Route::resource('project', 'ProjectController');
In this archive, I have a list of the projects.
public function trash()
{
$projects = Project::onlyTrashed()->get();
return view('projects.archive', compact('projects'));
}
Now I want to use the show method to view these projects.
In my \App\Providers\RouteServiceProvider I added:
Route::bind('project', function ($value) {
return \App\Project::withTrashed()->find($value);
});
But this way, I am able to edit the project.
I tried to bind project/show, project/{project}/show, but that does not work.
How can I use the show method of my resource controller on a trashed project?
My complete ProjectController looks like:
<?php
namespace App\Http\Controllers;
use App\Http\Requests\ProjectRequest;
use App\Project;
class ProjectController extends Controller
{
public function index()
{
$projects = Project::all();
return view('project.index', compact('projects'));
}
public function create()
{
return view('project.create');
}
public function store(ProjectRequest $request)
{
Project::create($request->all());
return redirect()->route('project.index');
}
public function show(Project $project)
{
return view('project.show', compact('project'));
}
public function edit(Project $project)
{
return view('project.edit', compact('project'));
}
public function update(ProjectRequest $request, Project $project)
{
$project->update($request->all());
return redirect()->route('project.index');
}
public function destroy(Project $project)
{
$project->delete();
return redirect()->route('project.archive');
}
public function trash()
{
$projects = Project::onlyTrashed()->get();
return view('project.archive', compact('projects'));
}
}
By adding a check in the \App\Providers\RouteServiceProvider.
Route::bind('project', function ($value) {
if (Route::currentRouteName() === 'project.show') {
return \App\Project::withTrashed()->find($value);
}
return \App\Project::find($value);
});
Hopefully this will help others.
I may be completely misunderstood the problem, but as far as I understood:
You can exclude some functions of a controller, such as;
Route::resource('photos', 'PhotoController')->only([
'index', 'show'
]);
Route::resource('photos', 'PhotoController')->except([
'create', 'store', 'update', 'destroy'
]);
More detailed information on https://laravel.com/docs/5.7/controllers#restful-partial-resource-routes
Additionally, if you want to implement a resource controller that uses only trashed projects -rather than a regular laravel model- as a resource you have to generate a new controller via something like
php artisan make:controller -r ProjectArchiveController
and customize the functions of it accordingly. For more options on make:controller command, you can use;
php artisan help make:controller
Hope this all helps.
New addition:
Route::get('project/{id}', 'ProjectController#trash')->name('project.archive');
Route::resource('project', 'ProjectController');
and declaration of the function trash,
public function trash(int $id)
You can add a withTrashed() method to the routes file. From the laravel docs https://laravel.com/docs/8.x/routing#implicit-soft-deleted-models
use App\Models\User;
Route::get('/users/{user}', function (User $user) {
return $user->email;
})->withTrashed();
I also posted on laracasts.com, where I partly borrowed from OP's answer.
I use this not for an archive of soft-deleted models, but for a restore route. But the problem is the same: route model binding only works for non-trashed models. I wanted a solution that:
works on all models which use the SoftDeletes trait;
only works on routes which are specifically meant for restoring soft-deleted models;
only works on models which are actually soft-deleted;
Therefore, I utilized the resolveRouteBinding() method (originally in \Illuminate\Database\Eloquent\Model), creating a more generic solution:
\App\Models\Traits\SoftDeletes:
<?php
namespace App\Models\Traits;
use Illuminate\Database\Eloquent\SoftDeletes as EloquentSoftDeletes;
use Illuminate\Support\Facades\Route;
trait SoftDeletes {
use EloquentSoftDeletes;
/**
* Retrieve the model for a bound value.
*
* Modified from \Illuminate\Database\Eloquent\Model::resolveRouteBinding()
*
* #param mixed $value
* #param string|null $field
* #return \Illuminate\Database\Eloquent\Model|null
*/
public function resolveRouteBinding($value, $field = null) {
$route_name_parts = explode(".", Route::currentRouteName());
if (end($route_name_parts) === 'restore') {
return $this->onlyTrashed()->where($field ?? $this->getRouteKeyName(), $value)->first();
}
return $this->where($field ?? $this->getRouteKeyName(), $value)->first();
}
}
For OP's archive, just add another check on the route name in that if-statement.
On the model, I swap the Eloquent version of SoftDeletes for this one. Now I can just define a route as:
Route::patch(
'/projects/{project}/restore',
[ProjectController::class, 'restore']
)->name('projects.restore');
Thus only routes with a name ending in 'restore' will work on a trashed model, all other routes only work on non-trashed models.
Note
With this, the restore routes exclusively work with trashed models. If you want them to work with non-trashed models as well (but why?), just replace the onlyTrashed() method with the withTrashed() method.

How to use modelfactory in seeder in Laravel 5.4

I am using model factories in NewsTableSeeder, but I get this error when I entered db:seed.
I want to know why I can't use create() in my seeder.
Here is my News model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class News extends Model
{
protected $table = 'news';
protected $primaryKey = 'id';
public function home_news_lists() {
return $this->select('id', 'news_title', 'news_update')
->orderBy('news_update', 'DESC')
->limit(5)
->get();
}
public function lists() {
return News::all();
}
}
Model Factories:
$factory->define(App\Models\News::class, function (Faker\Generator $faker)
{
static $password;
$faker = $faker->create('zh_TW');
return [
'news_title' => $faker->sentence(),
'news_content' => $faker->paragraph(),
'news_author' => $faker->name(),
'news_pageviews' => $faker->numberBetween(1, 100),
'news_file' => ' ',
'news_img' => $faker->imageUrl($width, $height, 'business'),
'created_at' => $faker->dateTimeBetween('2012', 'now', 'zh_TW'),
'updated_at' => $faker->dateTimeBetween('2015', 'now', 'zh_TW')
];
});
NewsTableSeeder :
<?php
use Illuminate\Database\Seeder;
class NewsTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
factory(App\Models\News::class, 50)->create();
}
}
I can't tell 100% without seeing exactly the error you got, but I do believe there is no create() method on the $faker object.
I believe what you mean to do is:
$factory->define(App\Models\News::class, function (Faker\Generator $faker)
{
static $password;
$faker = \Faker\Factory::create('zh_TW'); // change to this
return [
...
];
}
I would just create a new faker generator (\Faker\Generator) that gets returned from calling \Faker\Factory::create($locale) and use that instead. Otherwise, I believe your next best option is to override wherever Laravel instantiates the \Faker\Generator $faker object that gets passed into the callback, but that may get hacky if Laravel doesn't provide a clean way to do it.
The create() method is a static call on the \Faker\Factory method. It accepts a locale as the parameter and uses en_US as the default locale.
$faker = $faker->create('zh_TW');
The error message said this code is wrong.
What is your purpose to use this code?

How add a request item to Backpack-Laravel?

I have to pass the secret author_id of the user when he edit for example an Article and memorize that into the Database in Backpack-Laravel.
How can do that?
I be able to do just this, the value appears in the $request array (I use dd($request) for know that) but isn't stored on the database.
AuthorCrudController.php
public function update(UpdateArticleRequest $request)
{
//dd($request); <-- author_id = Auth::id()
return parent::updateCrud();
}
UpdateArticleRequest.php
public function rules()
{
$this->request->add(['author_id'=> Auth::id()]);
return [
'title' => 'required|min:5|max:255',
'author_id' => 'numeric'
];
}
99 times out of 100, when the value isn't stored it's because that column hasn't been mentioned in your model's $fillable property. Is this it?
Sidenote: Adding the author_id like this works, but if you're using this approach for multiple models, I recommend coding it once for all your models. I use a trait for this. That way, any time an entry is created, the author is saved and you have the have all the methods for getting it in one place, the trait ($this->creator(), this->updator).
My approach to this is this:
1) I have two new columns in my database created_by and updated_by
2) I use a trait like this:
<?php namespace App\Models\Traits;
use Illuminate\Database\Eloquent\Model;
trait CreatedByTrait {
/**
* Stores the user id at each create & update.
*/
public function save(array $options = [])
{
if (\Auth::check())
{
if (!isset($this->created_by) || $this->created_by=='') {
$this->created_by = \Auth::user()->id;
}
$this->updated_by = \Auth::user()->id;
}
parent::save();
}
/*
|--------------------------------------------------------------------------
| RELATIONS
|--------------------------------------------------------------------------
*/
public function creator()
{
return $this->belongsTo('App\User', 'created_by');
}
public function updator()
{
return $this->belongsTo('App\User', 'updated_by');
}
}
3) Whenever I want a model to have this feature, i just need to:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Backpack\CRUD\CrudTrait;
class Car extends Model
{
use CrudTrait;
use CreatedByTrait; // <---- add this line
Hope it helps.
The update function in my backpack setup has $request passed in updateCrud function. The one that you have mentioned does not have the request passed into the parent function.
public function update(UpdateRequest $request)
{
// your additional operations before save here
$redirect_location = parent::updateCrud($request);
return $redirect_location;
}

Laravel 5 - why is input empty when returning with errors?

I have a form that submits to a controller, which validates the data. If the validation fails it redirects back with the input and the errors. This is the method that deals with the form submission:
<?php namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
class UserController extends Controller {
/**
* Create a new user.
*
* #param Reqeust $request
*
* #return Void
*/
public function postCreate(Request $request)
{
$user = new User;
$rules = $user->rules();
$rules['password'] = 'required|confirmed|min:8';
$v = \Validator::make($request->except('_token', 'roles'), $rules);
if ($v->fails())
{
return redirect()->back()->withInput($request->except('_token', 'password', 'password_confirmation'))->withErrors($v);
}
$user->fill($request->except('_token', 'password', 'password_confirmation'));
$user->password = \Hash::make($request->input('password'));
$user->save();
return redirect()->route('webmanAccounts')->with('messages', [['text' => 'User account created', 'class' => 'alert-success']]);
}
On the page that displays the form I check to see if name, one of the fields, is present and if so populate a User object with the data. The problem is input is always empty.
<?php namespace BackEnd;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Request as RequestFacade;
use App\Http\Controllers\Controller;
use App\Models\Role;
use App\Models\User;
class UserController extends Controller {
public function __construct(Request $request)
{
if ( ! $request->user()->can('accounts'))
{
return abort(403, 'You do not have permission to access this page.');
}
}
/**
* Display the create new user form and process any error messages.
*
* #param Reqeust $request
*
* #return View
*/
public function create(Request $request)
{
$user = new User;
dump(RequestFacade::all());
if (RequestFacade::has('name'))
{
$user->fill(RequestFacade::except('_token', 'roles'));
foreach (RequestFacade::only('roles') as $role)
{
$user->roles()->add($role);
}
}
return view('backend.user.create', ['title' => 'Website Manager :: Create New Account', 'user' => $user, 'roles' => Role::all()]);
}
I have tried RequestFacade, $request and Input, all show as empty. Why isn't the data being passed back?
To add to the strangeness of this, I have another project that uses almost identical code and that works perfectly fine. Why would it work fine for one project but not for another!?
When you use the withInput() method, the data is flashed to the session as "old" data.
$request->old() should give you an array of all the "old" data.
$request->old('name') should give you the "old" name data.

Laravel 5 return JSON or View depends if ajax or not

I would like to know if there is a magic method to use this scenario :
If I call a page via an AJAX request the controller returns a JSON object, otherwise it returns a view, i'm trying to do this on all my controllers without changin each method.
for example i know that i can do this :
if (Request::ajax()) return compact($object1, $object2);
else return view('template', compact($object, $object2));
but I have a lot of controllers/methods, and I prefer to change the basic behavior instead of spending my time to change all of them. any Idea ?
The easiest way would be to make a method that is shared between all of your controllers.
Example:
This is your controller class that all other controllers extend:
<?php namespace App\Http\Controllers;
use Illuminate\Routing\Controller as BaseController;
abstract class Controller extends BaseController
{
protected function makeResponse($template, $objects = [])
{
if (\Request::ajax()) {
return json_encode($objects);
}
return view($template, $objects);
}
}
And this is one of the controllers extending it:
<?php namespace App\Http\Controllers;
class MyController extends Controller
{
public function index()
{
$object = new Object1;
$object2 = new Object2;
return $this->makeResponse($template, compact($object, $object2));
}
}
Update for Laravel 5+
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
protected function makeResponse($request, $template, $data = [])
{
if ($request->ajax()) {
return response()->json($data);
}
return view($template, $data);
}
}
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class MyController extends Controller
{
public function index(Request $request)
{
$object = new Object1;
$object2 = new Object2;
return $this->makeResponse($request, $template, compact($object, $object2));
}
}
There is no magic but you can easily override ViewService in 3 steps:
1.create your view factory (your_project_path/app/MyViewFactory.php)
<?php
/**
* Created by PhpStorm.
* User: panos
* Date: 5/2/15
* Time: 1:35 AM
*/
namespace App;
use Illuminate\View\Factory;
class MyViewFactory extends Factory {
public function make($view, $data = array(), $mergeData = array())
{
if (\Request::ajax()) {
return $data;
}
return parent::make($view, $data, $mergeData);
}
}
2.create your view service provider (your_project_path/app/providers/MyViewProvider.php)
<?php namespace App\Providers;
use App\MyViewFactory;
use Illuminate\View\ViewServiceProvider;
class MyViewProvider extends ViewServiceProvider {
/**
* Register the application services.
*
* #return void
*/
public function register()
{
parent::register();
}
/**
* Overwrite original so we can register MyViewFactory
*
* #return void
*/
public function registerFactory()
{
$this->app->singleton('view', function($app)
{
// Next we need to grab the engine resolver instance that will be used by the
// environment. The resolver will be used by an environment to get each of
// the various engine implementations such as plain PHP or Blade engine.
$resolver = $app['view.engine.resolver'];
$finder = $app['view.finder'];
// IMPORTANT in next line you should use your ViewFactory
$env = new MyViewFactory($resolver, $finder, $app['events']);
// We will also set the container instance on this view environment since the
// view composers may be classes registered in the container, which allows
// for great testable, flexible composers for the application developer.
$env->setContainer($app);
$env->share('app', $app);
return $env;
});
}
}
3.in your_project_path/config/app.php:
change 'Illuminate\View\ViewServiceProvider',
to 'App\Providers\MyViewProvider',
What this do:
it tells your application to use another view provider which will register your view factory
$env = new MyViewFactory($resolver, $finder, $app['events']);
in line 33 of MyViewProvider.php which will check if request is AJAX and return if true or continue with original behavior
return parent::make($view, $data, $mergeData);
in MyViewFactory.php line 19
Hope this help you,
In laravel 5.1, this is the best way:
if (\Illuminate\Support\Facades\Request::ajax())
return response()->json(compact($object1, $object2));
else
return view('template', compact($object, $object2));
The solution suggested by #ryanwinchester is really good. I, however, wanted to use it for the responses from update() and delete(), and there naturally return view() at the end doesn't make a lot of sense as you mostly want to use return redirect()->route('whatever.your.route.is'). I thus came up with that idea:
// App\Controller.php
/**
* Checks whether request is ajax or not and returns accordingly
*
* #param array $data
* #return mixed
*/
protected function forAjax($data = [])
{
if (request()->ajax()) {
return response()->json($data);
}
return false;
}
// any other controller, e.g. PostController.php
public function destroy(Post $post)
{
// all stuff that you need until delete, e.g. permission check
$comment->delete();
$r = ['success' => 'Wohoo! You deleted that post!']; // if necessary
// checks whether AJAX response is required and if not returns a redirect
return $this->forAjax($r) ?: redirect()->route('...')->with($r);
}

Categories