2019年6月3日月曜日

laravel type hintでobjとれない件

以下のrouting定義がある。
Route::resource('tokus', 'TokuController')

controllerで下記のtype hintがあるが、dd($toku)であるはずのobjがとれない。
public function show(Toku $toku)
    {
        return view('tokus.show', compact('toku'));
    }

route:listで確認したところ、show actionのURIは、tokes/{tokes}になっている。
type hintの引数は{tokes}と一致しないといけないため、public function show(Toku $tokus)に変更したら解決できた。それが嫌なら、引数を指定できる。

Route::resource('tokus', 'TokuController')->parameters([
    'tokus' => 'toku'
]);

参考:https://laracasts.com/discuss/channels/laravel/controller-method-with-type-hinting-give-empty-eloquent-object

2019年5月30日木曜日

laravel middleware

Controllers also allow you to register middleware using a Closure. This provides a convenient way to define a middleware for a single controller without defining an entire middleware class:

$this->middleware(function ($request, $next) {
    // ...

    return $next($request);
});

resource controller

php artisan make:controller PhotoController --resource
Route::resource('photos', 'PhotoController');
Route::resources([
    'photos' => 'PhotoController',
    'posts' => 'PostController'
]);

Partial Resource Routes

Route::resource('photos', 'PhotoController')->only([
    'index', 'show'
]);

Route::resource('photos', 'PhotoController')->except([
    'create', 'store', 'update', 'destroy'
]);

Route::apiResources([
    'photos' => 'PhotoController',
    'posts' => 'PostController'
]);

If you need to add additional routes to a resource controller beyond the default set of resource routes, you should define those routes before your call to Route::resource

Route::get('photos/popular', 'PhotoController@method');
Route::resource('photos', 'PhotoController');

You may even restrict the middleware to only certain methods on the controller class:

public function __construct()
    {
        $this->middleware('auth');

        $this->middleware('log')->only('index');

        $this->middleware('subscribed')->except('store');
    }

// 一覧
GET /projects (index)

// 新規ページ
GET /projects/create (create)

// 保存
POST /projects (store)

// show project
GET /projects/{id}

// 編集ページ
GET /projects/{id}/edit (edit)

// 更新
PATCH /projects/{id} (update)

// 削除
DELETE /projects/{id} (destroy)

Dependency Injection & Controllers

Injectionの場所は2つある
1)Constructor Injection
class UserController extends Controller
{
    /**
     * The user repository instance.
     */
    protected $users;

    /**
     * Create a new controller instance.
     *
     * @param  UserRepository  $users
     * @return void
     */
    public function __construct(UserRepository $users)
    {
        $this->users = $users;
    }
}

2)Method Injection
class UserController extends Controller
{
    /**
     * Store a new user.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        $name = $request->name;

        //
    }
}

laravel Authorization

Gates provide a simple, Closure based approach to authorization while policies, like controllers, group their logic around a particular model or resource.
Gates are most applicable to actions which are not related to any model or resource, such as viewing an administrator dashboard. In contrast, policies should be used when you wish to authorize an action for a particular model or resource.

Gates are Closures that determine if a user is authorized to perform a given action and are typically defined in the App\Providers\AuthServiceProvider class using the Gate facade. Gates always receive a user instance as their first argument, and may optionally receive additional arguments such as a relevant Eloquent model:

public function boot()
{
    $this->registerPolicies();

    Gate::define('update-post', function ($user, $post) {
        return $user->id == $post->user_id;
    });

    Gate::define('update-post', 'App\Policies\PostPolicy@update');
}

Authorizing Actions

To authorize an action using gates, you should use the allows or denies methods. Note that you are not required to pass the currently authenticated user to these methods. Laravel will automatically take care of passing the user into the gate Closure:

if (Gate::allows('update-post', $post)) {
    // The current user can update the post...
}

if (Gate::denies('update-post', $post)) {
    // The current user can't update the post...
}

If you would like to determine if a particular user is authorized to perform an action, you may use the forUser method on the Gate facade:

if (Gate::forUser($user)->allows('update-post', $post)) {
    // The user can update the post...
}

if (Gate::forUser($user)->denies('update-post', $post)) {
    // The user can't update the post...
}

You may use the before method to define a callback that is run before all other authorization checks:

boot function中で下記追加

Gate::before(function ($user, $ability) {
    if ($user->isSuperAdmin()) {
        return true;
    }
});
If the before callback returns a non-null result that result will be considered the result of the check.

You may use the after method to define a callback to be executed after all other authorization checks:

Gate::after(function ($user, $ability, $result, $arguments) {
    if ($user->isSuperAdmin()) {
        return true;
    }
});

Generating Policies

php artisan make:policy PostPolicy
php artisan make:policy PostPolicy --model=Post

Registering Policies

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        Post::class => PostPolicy::class,
    ];

Policy Auto-Discovery
Laravel can auto-discover policies as long as the model and policy follow standard Laravel naming conventions.

Any policies that are explicitly mapped in your AuthServiceProvider will take precedence over any potential auto-discovered policies.

class PostPolicy
{
    /**
     * Determine if the given post can be updated by the user.
     *
     * @param  \App\User  $user
     * @param  \App\Post  $post
     * @return bool
     */
    public function update(User $user, Post $post)
    {
        return $user->id === $post->user_id;
    }
}

Guest Users

By default, all gates and policies automatically return false if the incoming HTTP request was not initiated by an authenticated user. However, you may allow these authorization checks to pass through to your gates and policies by declaring an "optional" type-hint or supplying a  null default value for the user argument definition:
public function update(?User $user, Post $post)
    {
        return $user->id === $post->user_id;
    }

For certain users, you may wish to authorize all actions within a given policy. To accomplish this, define a before method on the policy. The before method will be executed before any other methods on the policy

public function before($user, $ability)
{
    if ($user->isSuperAdmin()) {
        return true;
    }
}
If you would like to deny all authorizations for a user you should return false from the before method. If null is returned, the authorization will fall through to the policy method.
The before method of a policy class will not be called if the class doesn't contain a method with a name matching the name of the ability being checked.

Authorizing Actions Using Policies

if ($user->can('update', $post)) {
    // Via The User Model
}

use App\Post;
if ($user->can('create', Post::class)) {
    // Executes the "create" method on the relevant policy...
}

Laravel includes a middleware that can authorize actions before the incoming request even reaches your routes or controllers.
Route::put('/post/{post}', function (Post $post) {
    // The current user may update the post...
})->middleware('can:update,post');
we're passing the can middleware two arguments. The first is the name of the action we wish to authorize and the second is the route parameter we wish to pass to the policy method.
Actions That Don't Require Model Instance
Route::post('/post', function () {
    // The current user may create posts...
})->middleware('can:create,App\Post');

Via Controller Helpers

public function update(Request $request, Post $post)
    {
        $this->authorize('update', $post);

        // The current user can update the blog post...
    }

Via Blade Templates

@can('update', $post)
    <!-- The Current User Can Update The Post -->
@elsecan('create', App\Post::class)
    <!-- The Current User Can Create New Post -->
@endcan

@cannot('update', $post)
    <!-- The Current User Can't Update The Post -->
@elsecannot('create', App\Post::class)
    <!-- The Current User Can't Create New Post -->
@endcannot

2019年5月29日水曜日

laravelのdata_setでarrayの値をobjに代入

validationが通らない場合、row objの値を入力値にしたい

 $row = new \App\Model();
 if ($request->old()) {
        foreach (old() as $key => $value) {
            data_set($row, $key, $value);
        }
    }

2019年5月28日火曜日

laravel session

Retrieving Data

There are two primary ways of working with session data in Laravel: the global session helper and via a Request instance.
$value = $request->session()->get('key');
$value = $request->session()->get('key', 'default');
$value = $request->session()->get('key', function () {
    return 'default';
});

// Retrieve a piece of data from the session...
    $value = session('key');

    // Specifying a default value...
    $value = session('key', 'default');

$data = $request->session()->all();

The has method returns true if the item is present and is not null
if ($request->session()->has('users')) {
    //
}

The exists method returns true if the item is present, even if its value is null:
if ($request->session()->exists('users')) {
    //
}

Storing Data

// Via a request instance...
$request->session()->put('key', 'value');

// Via the global helper...
session(['key' => 'value']);

Pushing To Array Session Values

The push method may be used to push a new value onto a session value that is an array. For example, if the user.teams key contains an array of team names, you may push a new value onto the array like so:

$request->session()->push('user.teams', 'developers');

Retrieving & Deleting An Item

The pull method will retrieve and delete an item from the session in a single statement:

$value = $request->session()->pull('key', 'default');

Flash Data

store items in the session only for the next request
$request->session()->flash('status', 'Task was successful!');

If you need to keep your flash data around for several requests, you may use the reflash method, which will keep all of the flash data for an additional request. If you only need to keep specific flash data, you may use the keep method:

$request->session()->reflash();

$request->session()->keep(['username', 'email']);

Deleting Data

The forget method will remove a piece of data from the session. If you would like to remove all data from the session, you may use the flush method:

// Forget a single key...
$request->session()->forget('key');

// Forget multiple keys...
$request->session()->forget(['key1', 'key2']);

$request->session()->flush();

2019年5月27日月曜日

laravel paginate

$users = DB::table('users')->paginate(15);
$users = App\User::paginate(15);

"Simple Pagination"

If you only need to display simple "Next" and "Previous" links in your pagination view, you may use the simplePaginate method to perform a more efficient query.
$users = DB::table('users')->simplePaginate(15);
$users = User::where('votes', '>', 100)->simplePaginate(15);

Displaying Pagination Results

<div class="container">
    @foreach ($users as $user)
        {{ $user->name }}
    @endforeach
</div>

{{ $users->links() }} // ?page=N

Adjusting The Pagination Link Window
You may control how many additional links are displayed on each side of the paginator's URL "window". By default, three links are displayed on each side of the primary paginator links. However, you may control this number using the onEachSide method:

{{ $users->onEachSide(5)->links() }}

Customizing The Pagination View

{{ $paginator->links('view.name') }}

// Passing data to the view...
{{ $paginator->links('view.name', ['foo' => 'bar']) }}