Multi session tables in Laravel - php

i have setup a Laravel project with two guards wach with Hi own users table. Now i want to save the sessions into the database instead in a file. The Problem is that I cant save the session in a single table, because the user ID is not unique.
How can I solve this problem? Thanks.

I tried this. This working, but it exists a default session driver, so a user has a session in the default table and in the admin_sessions table.
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
Administrator::class => UserPolicy::class,
];
public function boot()
{
$this->registerPolicies();
Auth::extend('admin_session', function ($app, $name, array $config) {
$provider = Auth::createUserProvider($config['provider']);
$guard = new SessionGuard($name, $provider, $app->session->driver('admin_database'));
if (method_exists($guard, 'setCookieJar')) {
$guard->setCookieJar($this->app['cookie']);
}
if (method_exists($guard, 'setDispatcher')) {
$guard->setDispatcher($this->app['events']);
}
if (method_exists($guard, 'setRequest')) {
$guard->setRequest($this->app->refresh('request', $guard, 'setRequest'));
}
return $guard;
}
}
class SessionServiceProvider extends ServiceProvider
{
/**
* Register the service provider.
*
* #return void
*/
public function register()
{
}
/**
* Perform post-registration booting of services.
*
* #return void
*/
public function boot()
{
$this->app->session->extend('admin_database', function ($app) {
$table = 'administrator_sessions';
// This is not workin, because I don't have the user her.
/*if (auth()->user() instanceof Customer) {
$table = 'customer_sessions';
}
else if (auth()->user() instanceof Administrator){
$table = 'administrator_sessions';
}*/
$lifetime = $app['config']['session.lifetime'];
$connection = $app['db']->connection($app['config']['session.connection']);
return new DatabaseSessionHandler($connection, $table, $lifetime, $app);
});
}
}

Related

Difference between boot and booted in laravel

I am trying to understand the usage and difference of boot and booted.
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected static function boot() {
parent::boot();
static::creating(function ($user) {
});
}
protected static function booted() {
parent::booted();
static::creating(function ($user) {
});
}
}
When and where should be this two function called?
Actually answer is in the Eloquent model itself:
protected function bootIfNotBooted()
{
if (! isset(static::$booted[static::class])) {
static::$booted[static::class] = true;
$this->fireModelEvent('booting', false);
static::booting();
static::boot();
static::booted();
$this->fireModelEvent('booted', false);
}
}
/**
* Perform any actions required before the model boots.
*
* #return void
*/
protected static function booting()
{
//
}
/**
* Bootstrap the model and its traits.
*
* #return void
*/
protected static function boot()
{
static::bootTraits();
}
/**
* Perform any actions required after the model boots.
*
* #return void
*/
protected static function booted()
{
//
}
I tried both, I think there are just the same; just that boot will run first and it requires to call extra parent::boot()
protected static function boot()
{
parent::boot();
self::creating(function (Outlet $outlet): void {
Log::debug("#boot");
$outlet->name = "boot";
});
}
protected static function booted()
{
self::creating(function (Outlet $outlet): void {
Log::debug("#booted");
$outlet->name = "booted";
});
}

Role based permission to Laravel

I am trying to do a role based permission control in a Laravel application. I want to check what actions can some user do, but i can't figure out how to implement gates and policies in my model (the permission description is in the database and are booleans asociated to a table that stores the resource's ids).
This is the database model that im using:
I would like to know if laravel gates is useful in my case, and how can i implement it, if not, how to make a basic middleware that take care of permission control to protect routes (or controllers).
In the table resource i have a uuid that identifies the resources, the alias is the name of the resource and has dot notation values of actions or context of the resource (eg. 'mysystem.users.create', 'mysystem.roles.delete', 'mysystem.users.images.view'). The policy tables has a boolean 'allow' field that describes the permission of users.
Thanks in advance.
This is the way that I implement role based permissions in Laravel using Policies.
Users can have multiple roles.
Roles have associated permissions.
Each permission allows a specific action on a specific model.
Migrations
Roles table
class CreateRolesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->string('label');
$table->text('description');
$table->timestamps();
});
}
// rest of migration file
Permissions table
class CreatePermissionsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('permissions', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->string('label');
$table->text('description');
$table->timestamps();
});
}
// rest of migration file
Permission Role Pivot Table
class CreatePermissionRolePivotTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('permission_role', function (Blueprint $table) {
$table->integer('permission_id')->unsigned()->index();
$table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade');
$table->integer('role_id')->unsigned()->index();
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
$table->primary(['permission_id', 'role_id']);
});
}
// rest of migration file
Role User Pivot Table
class CreateRoleUserPivotTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('role_user', function (Blueprint $table) {
$table->integer('role_id')->unsigned()->index();
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
$table->integer('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->primary(['role_id', 'user_id']);
});
}
// rest of migration file
Models
User
public function roles()
{
return $this->belongsToMany(Role::class);
}
public function assignRole(Role $role)
{
return $this->roles()->save($role);
}
public function hasRole($role)
{
if (is_string($role)) {
return $this->roles->contains('name', $role);
}
return !! $role->intersect($this->roles)->count();
}
Role
class Role extends Model
{
protected $guarded = ['id'];
protected $fillable = array('name', 'label', 'description');
public function permissions()
{
return $this->belongsToMany(Permission::class);
}
public function givePermissionTo(Permission $permission)
{
return $this->permissions()->save($permission);
}
/**
* Determine if the user may perform the given permission.
*
* #param Permission $permission
* #return boolean
*/
public function hasPermission(Permission $permission, User $user)
{
return $this->hasRole($permission->roles);
}
/**
* Determine if the role has the given permission.
*
* #param mixed $permission
* #return boolean
*/
public function inRole($permission)
{
if (is_string($permission)) {
return $this->permissions->contains('name', $permission);
}
return !! $permission->intersect($this->permissions)->count();
}
}
Permission
class Permission extends Model
{
protected $guarded = ['id'];
protected $fillable = array('name', 'label', 'description');
public function roles()
{
return $this->belongsToMany(Role::class);
}
/**
* Determine if the permission belongs to the role.
*
* #param mixed $role
* #return boolean
*/
public function inRole($role)
{
if (is_string($role)) {
return $this->roles->contains('name', $role);
}
return !! $role->intersect($this->roles)->count();
}
}
Policies
A policy is required for each model. Here is an example policy for a model item. The policy defines the 'rules' for the four actions 'view, create, update, delete.
class ItemPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view the item.
*
* #param \App\User $user
* #return mixed
*/
public function view(User $user)
{
$permission = Permission::where('name', 'items-view')->first();
return $user->hasRole($permission->roles);
}
/**
* Determine whether the user can create items.
*
* #param \App\User $user
* #return mixed
*/
public function create(User $user)
{
$permission = Permission::where('name', 'items-create')->first();
return $user->hasRole($permission->roles);
}
/**
* Determine whether the user can update the item.
*
* #param \App\User $user
* #return mixed
*/
public function update(User $user)
{
$permission = Permission::where('name', 'items-update')->first();
return $user->hasRole($permission->roles);
}
/**
* Determine whether the user can delete the item.
*
* #param \App\User $user
* #return mixed
*/
public function delete(User $user)
{
$permission = Permission::where('name', 'items-delete')->first();
return $user->hasRole($permission->roles);
}
}
Register each policy in AuthServiceProvider.php
use App\Item;
use App\Policies\ItemPolicy;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* #var array
*/
protected $policies = [
Item::class => ItemPolicy::class,
];
// rest of file
Controllers
In each controller, refer to the corresponding authorisation action from the policy.
For example, in the index method of ItemController:
public function index()
{
$this->authorize('view', Item::class);
$items = Item::orderBy('name', 'asc')->get();
return view('items', ['items' => $items]);
}
Views
In your views, you can check if the user has a specific role:
#if (Auth::user()->hasRole('item-administrator'))
// do stuff
#endif
or if a specific permission is required:
#can('create', App\User::class)
// do stuff
#endcan
Answer for your Question:how to make a basic middleware that take care of permission control to protect routes (or controllers)?.
Just an Example:
Here is the simple role middleware for your routes
AdminRole
namespace App\Http\Middleware;
use Illuminate\Support\Facades\Auth;
use Closure;
class AdminRole
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if(Auth::user()->role->name!=="admin"){ //Check your users' role or permission, in my case only admin role for routes
return redirect('/access-denied');
}
return $next($request);
}
}
After defining this middleware
Update your kernel.php file as
protected $routeMiddleware = [
..............
'admin' =>\App\Http\Middleware\AdminRole::class,
...................
];
And to use this route middleware:
There are different way to use route middleware but following is one example
Route::group(['middleware' => ['auth','admin']], function () {
Route::get('/', 'AdminController#index')->name('admin');
});
Note: There are some tools and libraries for roles and permission on laravel but above is the example of creating basic route middle-ware.
Because the laravel model did not fit my database so much, I did almost everything again. This is a functional draft in which some functions are missing, the code is not optimized and it may be a bit dirty, but here it is:
proyect/app/Components/Contracts/Gate.php This interface is used to create singleton in AuthServiceProvider.
<?php
namespace App\Components\Contracts;
interface Gate
{
public function check($resources, $arguments = []);
public function authorize($resource, $arguments = []);
}
proyect/app/Components/Security/Gate.php This file loads the permissions from the database. This could be improved a lot :(
<?php
namespace App\Components\Security;
use App\Components\Contracts\Gate as GateContract;
use App\Models\Security\Resource;
use App\Models\Security\User;
use Illuminate\Auth\Access\HandlesAuthorization;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
class Gate implements GateContract
{
use HandlesAuthorization;
protected $container;
protected $userResolver;
protected $policies = [];
public function __construct(Container $container, callable $userResolver)
{
$this->container = $container;
$this->userResolver = $userResolver;
}
public function permissionsForUser(User $user)
{
$result = User::with(['roles.resources', 'groups.resources', 'policies'])->where('id', $user->id)->first();
$list = [];
//role-specific ... the order is important role < group < user permissions
foreach ($result->roles as $role) {
foreach ($role->resources as $permission) {
if (isset($list[$permission->uuid])) {
if ($list[$permission->uuid]['on'] == User::ROLE_POLICY) {
if ($permission->pivot->allow == false) {
$list[$permission->uuid]['allow'] = false;
}
} else {
$list[$permission->uuid]['allow'] = $permission->pivot->allow ? true : false;
$list[$permission->uuid]['on'] = User::ROLE_POLICY;
$list[$permission->uuid]['id'] = $role->id;
}
} else {
$list[$permission->uuid] = [
'allow' => ($permission->pivot->allow ? true : false),
'on' => User::ROLE_POLICY,
'id' => $role->id];
}
}
}
// group-specific
foreach ($result->groups as $group) {
foreach ($group->resources as $permission) {
if (isset($list[$permission->uuid])) {
if ($list[$permission->uuid]['on'] == User::GROUP_POLICY) {
if ($permission->pivot->allow == false) {
$list[$permission->uuid]['allow'] = false;
}
} else {
$list[$permission->uuid]['allow'] = $permission->pivot->allow ? true : false;
$list[$permission->uuid]['on'] = User::GROUP_POLICY;
$list[$permission->uuid]['id'] = $group->id;
}
} else {
$list[$permission->uuid] = [
'allow' => ($permission->pivot->allow ? true : false),
'on' => User::GROUP_POLICY,
'id' => $group->id];
}
}
}
// user-specific policies
foreach ($result->policies as $permission) {
if (isset($list[$permission->uuid])) {
if ($list[$permission->uuid]['on'] == User::USER_POLICY) {
if ($permission->pivot->allow == false) {
$list[$permission->uuid]['allow'] = false;
}
} else {
$list[$permission->uuid]['allow'] = $permission->pivot->allow ? true : false;
$list[$permission->uuid]['on'] = User::USER_POLICY;
$list[$permission->uuid]['id'] = $result->id;
}
} else {
$list[$permission->uuid] = [
'allow' => ($permission->pivot->allow ? true : false),
'on' => User::USER_POLICY,
'id' => $result->id,
];
}
}
return $list;
}
public function check($resources, $arguments = [])
{
$user = $this->resolveUser();
return collect($resources)->every(function ($resource) use ($user, $arguments) {
return $this->raw($user, $resource, $arguments);
});
}
protected function raw(User $user, $resource, $arguments = [])
{
$list = $user->getPermissionList();
if (!Resource::isUUID($resource)) {
if (empty($resource = Resource::byAlias($resource))) {
return false;
}
}
if (empty($list[$resource->uuid]['allow'])) {
return false;
} else {
return $list[$resource->uuid]['allow'];
}
}
public function authorize($resource, $arguments = [])
{
$theUser = $this->resolveUser();
return $this->raw($this->resolveUser(), $resource, $arguments) ? $this->allow() : $this->deny();
}
protected function resolveUser()
{
return call_user_func($this->userResolver);
}
}
proyect/app/Traits/Security/AuthorizesRequests.php This file is added to controller. Allows to use $this->authorize('stuff'); in a controller when is added.
<?php
namespace App\Traits\Security;
use App\Components\Contracts\Gate;
trait AuthorizesRequests
{
public function authorize($ability, $arguments = [])
{
list($ability, $arguments) = $this->parseAbilityAndArguments($ability, $arguments);
return app(Gate::class)->authorize($ability, $arguments);
}
}
proyect/app/Providers/AuthServiceProvider.php This file is the same that can be found on proyect/vendor/laravel/framework/src/Illuminate/Auth/AuthServiceProvider.php, but i changed some parts to add new classe. Here are the important methods:
<?php
namespace App\Providers;
use App\Components\Contracts\Gate as GateContract;
use App\Components\Security\Gate;
use Illuminate\Auth\AuthManager;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Support\ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/* function register() ... */
/* other methods () */
protected function registerAccessGate()
{
$this->app->singleton(GateContract::class, function ($app) {
return new Gate($app, function () use ($app) {
return call_user_func($app['auth']->userResolver());
});
});
}
/* ... */
}
proyect /app/Http/Middleware/AuthorizeRequest.php This file is used to allow add the 'can' middleware to routes, eg: Route::get('users/', 'Security\UserController#index')->name('users.index')->middleware('can:inet.user.list');
<?php
namespace App\Http\Middleware;
use App\Components\Contracts\Gate;
use Closure;
use Illuminate\Contracts\Auth\Factory as Auth;
class AuthorizeRequest
{
protected $auth;
protected $gate;
public function __construct(Auth $auth, Gate $gate)
{
$this->auth = $auth;
$this->gate = $gate;
}
public function handle($request, Closure $next, $resource, ...$params)
{
$this->auth->authenticate();
$this->gate->authorize($resource, $params);
return $next($request);
}
}
but you must overwrite the default value in proyect/app/Http/Kernel.php:
/* ... */
protected $routeMiddleware = [
'can' => \App\Http\Middleware\AuthorizeRequest::class,
/* ... */
];
To use #can('inet.user.list') in a blade template you have to add this lines to proyect/app/Providers/AppServiceProvider.php:
class AppServiceProvider extends ServiceProvider
{
public function boot()
Blade::if ('can', function ($resource, ...$params) {
return app(\App\Components\Contracts\Gate::class)->check($resource, $params);
});
}
/* ... */
User model at proyect/app/Models/Security/User.php
<?php
namespace App\Models\Security;
use App\Components\Contracts\Gate as GateContract;
use App\Models\Security\Group;
use App\Models\Security\Resource;
use App\Models\Security\Role;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Hash;
class User extends Authenticatable
{
use SoftDeletes;
use Notifiable;
public $table = 'user';
const CREATED_AT = 'created_at';
const UPDATED_AT = 'updated_at';
// tipos de politicas
const GROUP_POLICY = 'group_policy';
const ROLE_POLICY = 'role_policy';
const USER_POLICY = 'user_policy';
protected $dates = ['deleted_at'];
public $fillable = [
];
public function policies()
{
return $this->belongsToMany(Resource::class, 'user_policy', 'user_id', 'resource_id')
->whereNull('user_policy.deleted_at')
->withPivot('allow')
->withTimestamps();
}
public function groups()
{
return $this->belongsToMany(Group::class, 'user_group', 'user_id', 'group_id')
->whereNull('user_group.deleted_at')
->withTimestamps();
}
public function roles()
{
return $this->belongsToMany(Role::class, 'user_role', 'user_id', 'role_id')
->whereNull('user_role.deleted_at')
->withTimestamps();
}
public function getPermissionList()
{
return app(GateContract::class)->permissionsForUser($this);
}
}
Group model at proyect/app/Models/Security/Group.php THis is the same than Role, change only names
<?php
namespace App\Models\Security;
use App\Models\Security\Resource;
use App\Models\Security\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Group extends Model
{
use SoftDeletes;
public $table = 'group';
const CREATED_AT = 'created_at';
const UPDATED_AT = 'updated_at';
protected $dates = ['deleted_at'];
public $fillable = [
'name',
];
public static $rules = [
];
public function users()
{
return $this->hasMany(User::class);
}
public function resources()
{
return $this->belongsToMany(Resource::class, 'group_policy', 'group_id', 'resource_id')
->whereNull('group_policy.deleted_at')
->withPivot('allow')
->withTimestamps();
}
}
Resource Model proyect/app/Models/Security/Resource.php
<?php
namespace App\Models\Security;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Resource extends Model
{
use SoftDeletes;
public $table = 'resource';
const CREATED_AT = 'created_at';
const UPDATED_AT = 'updated_at';
protected $dates = ['deleted_at'];
public $fillable = [
'alias',
'uuid',
'type',
];
public static $rules = [
];
public static function isUUID($value)
{
$UUIDv4 = '/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i';
return preg_match($UUIDv4, $value);
}
public static function byAlias($value)
{
return Resource::where('alias', $value)->first();
}
}
There are a lot of things that I have not put here, but this is what I have so far
The problem i find with trying to combine permissions from a db with policies is when it comes to the ownership of a record.
Ultimately in our code we would like to check access to a resource using permission only. This is because as the list of roles grows we don't want to have to keep adding checks for these roles to the codebase.
If we have a users table we may want 'admin' (role) to be able to update all user records but a 'basic' user to only be able to update their own user record. We would like to be able to control this access SOLELY using the database.
However, if you have an 'update_user' permission then do you give it to both roles?
If you don't give it to the basic user role then the request won't get as far as the policy to check ownership.
Hence, you cannot revoke access for a basic user to update their record from the db alone.
Also the meaning of 'update_user' in the permissions table now implies the ability to update ANY user.
SOLUTION?
Add extra permissions to cater for the case where a user owns the record.
So you could have permissions to 'update_user' AND 'update_own_user'.
The 'admin' user would have the first permission whilst the 'basic' user would have the second one.
Then in the policy we check for the 'update_user' permission first and if it's not present we check for the 'update_own_user'.
If the 'update_own_user' permission is present then we check ownership. Otherwise we return false.
The solution will work but it seems ugly to have to have manage 'own' permissions in the db.

Authentication laravel 4.2 cannot work

Authentication laravel can't work on my program. I have googled but not solve this. My program is
LoginController#auth
public function auth()
{
$username = Input::get('username');
$password = Input::get('pass');
if(Auth::attempt(array('id' => $username, 'password' => $password)))
{
echo "Work";
}
else
{
echo "Bad";
}
}
Authtable.php
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class Authtable extends Eloquent implements UserInterface, RemindableInterface
{
protected $table = 'authtable';
protected $hidden = array('password');
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* Get the e-mail address where password reminders are sent.
*
* #return string
*/
public function getReminderEmail()
{
return $this->email;
}
public function getRememberToken()
{
return $this->remember_token;
}
public function setRememberToken($value)
{
$this->remember_token = $value;
}
public function getRememberTokenName()
{
return 'remember_token';
}
}
auth.php
'driver' => 'eloquent',
'model' => 'Authtable',
'table' => 'authtable',
And nullable remember_token(varchar(100)), password(varchar(60)) but still not work. Please give some solution.
I had a bad experience about that.
Composer dump-autoload to make sure model name is working.
Check that model name has no conflicts
Check 'authtable' column names. Is that columns include what you Input?'id' => $username, 'password' => $password

Laravel authentication fails to the Hash result refreshing each time

I have made a Laravel Authentication system. It worked, but after updating laravel from 4.1.2.5 to 4.1.2.6 it stopped working. And I found out the problem, when the user tries to login, it fails since
Auth::attemp(array("user"=>$username, "password"=>$password))
regenrated the password Hashes and thus does not match against the one generated in time of registration.
Here is my User model:
class User extends Eloquent implements UserInterface, RemindableInterface {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password');
public function getRememberToken()
{
return $this->remember_token;
}
public function setRememberToken($value)
{
$this->remember_token = $value;
}
public function getRememberTokenName()
{
return 'remember_token';
}
public function getAuthPassword(){
}
public function getAuthIdentifier(){
}
function getReminderEmail (){
}
}
Here is my Login attempt:
Auth::attempt(array("email"=>$data['email'], 'password'=>$data['password']))
There's a breaking change between 4.1.25 and 4.1.26. Please check the upgrade section here

Laravel 4 - Trouble overriding model's save method

I'm trying to override my Post class's save() method so that I can validate some of the fields that will be saved to the record:
// User.php
<?php
class Post extends Eloquent
{
public function save()
{
// code before save
parent::save();
//code after save
}
}
When I try and run a this method in my unit testing I get the following error:
..{"error":{"type":"ErrorException","message":"Declaration of Post::save() should be compatible with that of Illuminate\\Database\\Eloquent\\Model::save()","file":"\/var\/www\/laravel\/app\/models\/Post.php","line":4}}
Create Model.php class which you will extend in another self-validating models
app/models/Model.php
class Model extends Eloquent {
/**
* Error message bag
*
* #var Illuminate\Support\MessageBag
*/
protected $errors;
/**
* Validation rules
*
* #var Array
*/
protected static $rules = array();
/**
* Validator instance
*
* #var Illuminate\Validation\Validators
*/
protected $validator;
public function __construct(array $attributes = array(), Validator $validator = null)
{
parent::__construct($attributes);
$this->validator = $validator ?: \App::make('validator');
}
/**
* Listen for save event
*/
protected static function boot()
{
parent::boot();
static::saving(function($model)
{
return $model->validate();
});
}
/**
* Validates current attributes against rules
*/
public function validate()
{
$v = $this->validator->make($this->attributes, static::$rules);
if ($v->passes())
{
return true;
}
$this->setErrors($v->messages());
return false;
}
/**
* Set error message bag
*
* #var Illuminate\Support\MessageBag
*/
protected function setErrors($errors)
{
$this->errors = $errors;
}
/**
* Retrieve error message bag
*/
public function getErrors()
{
return $this->errors;
}
/**
* Inverse of wasSaved
*/
public function hasErrors()
{
return ! empty($this->errors);
}
}
Then, adjust your Post model.
Also, you need to define validation rules for this model.
app/models/Post.php
class Post extends Model
{
// validation rules
protected static $rules = [
'name' => 'required'
];
}
Controller method
Thanks to Model class, Post model is automaticaly validated on every call to save() method
public function store()
{
$post = new Post(Input::all());
if ($post->save())
{
return Redirect::route('posts.index');
}
return Redirect::back()->withInput()->withErrors($post->getErrors());
}
This answer is strongly based on Jeffrey Way's Laravel Model Validation package for Laravel 4.
All credits to this man!
How to override Model::save() in Laravel 4.1
public function save(array $options = array())
{
parent::save($options);
}
If you want to overwrite the save() method, it must be identical to the save() method in Model:
<?php
public function save(array $options = array()) {}
And; you can also hook in the save() call with the Model Events:
http://laravel.com/docs/eloquent#model-events

Categories