Laravel Tricks: 50 Thủ Thuật Laravel Siêu Hữu Ích

Laravel Tricks: 50 Thủ Thuật Laravel Siêu Hữu Ích. Xin chào các bạn. Đã lâu mình không có bài viết nào về Laravel. Sau bao ngày tổng hợp từ nhiều nguồn cũng như đúc kết bản thân. Hôm nay mình xin chia sẽ cho các bạn 50 bí kiếp Laravel bỏ túi dành cho developer. Các bạn hãy theo dõi ngay bên dưới nhé.

Laravel Tricks: 50 Thủ Thuật Laravel Siêu Hữu Ích
Laravel Tricks: 50 Thủ Thuật Laravel Siêu Hữu Ích



1. Automatic Model Validation

class Post extends Eloquent
{
    public staic $autoValidates = true;

    protected static $rules = [];

    protected static function boot()
    {
        parent::boot();

        // or static::creating, or static::updating
        static::saving(function($model)
        {
            if ($model::$autoValidates) {
                return $model->validate();
            }
        });
    }

    public function validate()
    {

    }
}

2. Prevent updating

class Post extends Eloquent
{
    protected static function boot()
    {
        parent::boot();

        static::updating(function($model)
        {
            return false;
        });
    }
}

3. Conditional Relationships

class myModel extends Model
{
    public function category()
    {
        return $this->belongsTo('myCategoryModel', 'categories_id')
            ->where('users_id', Auth::user()->id);
    }
}

4. Expressive “Where” Syntax

$products = Product::where('category', '=', 3)->get();

$products = Product::where('category', 3)->get();

$products = Product::whereCategory(3)->get();

5. Query Builder: Having Raw



SELECT *, COUNT(*) FROM products GROUP BY category_id HAVING count(*) > 1;

DB::table('products')
    ->select('*', DB::raw('COUNT(*) as products_count'))
    ->groupBy('category_id')
    ->having('products_count', '>', 1)
    ->get();

6. Simple Date Filtering

$q->whereDate('created_at', date('Y-m-d'));

$q->whereDay('created_at', date('d'));

$q->whereMonth('created_at', date('m'));

$q->whereYear('created_at', date('Y'));

7. Save Options

// src/Illuminate/Database/Eloquent/Model.php
public function save(array $options = [])

// src/Illuminate/Database/Eloquent/Model.php
protected function performUpdate(Builder $query, array $options=[])
{
    if ($this->timestamps && array_get($options, 'timestamps', true))
    {
        $this->updateTimestamps();
    }
}

$product = Product::find($id);
$product->updated_at = '2015-01-01 00:00:00';
$product->save(['timestamps'=>false]);

8. Multilanguage Support

//In config/app.php
'locales' => ['en' => 'English', 'sv' => 'Swedish']
'skip_locales' => ['admin','auth','etc'],

//In RouteServiceProvider.php

public function map(Router $router, Request $request)
{
    $locale = $request->segment(1);
    $this->app->setLocale($locale);
    $skipLocales = $this->app->config->get('app.skip_locales');  

    // If the locale is added to skip_locales array continue without locale
    if (in_array($locale, $skipLocales)) {
        $router->group(['namespace' => $this->namespace], function($router)
        {
            require app_path('Http/routes.php');
        });
    }
    else {
        $router->group(['namespace' => $this->namespace, 'prefix' => $locale], function($router) {
            require app_path('Http/routes.php');
        });
    }
}

// In Language Middleware

public function __construct(Application $app, Redirector $redirector, Request $request)
    {
        $this->app = $app;
        $this->redirector = $redirector;
        $this->request = $request;
    }

    /**
     * Handle an incoming request.
     *
     * @param \Illuminate\Http\Request $request            
     * @param \Closure $next            
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        // Make sure the current local exists
        $locale = $request->segment(1);

        // If the locale is added to to skip_locales array continue without locale
        if (in_array($locale, $this->app->config->get('app.skip_locales'))) {
            return $next($request);
        } else {
            // If the locale does not exist in the locales array continue with the fallback_locale
            if (! array_key_exists($locale, $this->app->config->get('app.locales'))) {
                $segments = $request->segments();
                array_unshift($segments, $this->app->config->get('app.fallback_locale'));
                // $segments[0] = $this->app->config->get('app.fallback_locale');
                return $this->redirector->to(implode('/', $segments));
            }
        }
        $this->app->setLocale($locale);

        return $next($request);
    }

9. Retrieve Random Rows

$questions = Question::orderByRaw('RAND()')->take(10)->get();

10. UUID Model Primary Key

use Ramsey\Uuid\Uuid;

trait UUIDModel
{
    public $incrementing = false;

    protected static function boot()
    {
        parent::boot();

        static::creating(function ($model)
        {
            $key = $model->getKeyName();

            if (empty($model->{$key})) {
                $model->{$key} = (string) $model->generateNewUuid();
            }
        });
    }

    public function generateNewUuid()
    {
        return Uuid::uuid4();
    }
}

11. Ordered Relationships



class Category extends Model
{
    public function products()
    {
        return $this->hasMany('App\Product')->orderBy('name');
    }
}

12. Simple Incrementing & Decrementing

$customer = Customer::find($customer_id);
$loyalty_points = $customer->loyalty_points + 50;
$customer->update(['loyalty_points' => $loyalty_points]);

// adds one loyalty point
Customer::find($customer_id)->increment('loyalty_points', 50);

// subtracts one loyalty point
Customer::find($customer_id)->decrement('loyalty_points', 50);

13. Lists with Mutations

$employees = Employee::where('branch_id', 9)->lists('name', 'id');
return view('customers.create', compact('employees'));

{!! Form::select('employee_id', $employees, '') !!}


public function getFullNameAttribute()
{
    return $this->name . ' ' . $this->surname;
}

[2015-07-19 21:47:19] local.ERROR: exception 'PDOException'...Column not found:...'full_name'

$employees = Employee::where('branch_id', 9)->get()->lists('full_name', 'id');

14. Appending Mutated Properties

function getFullNameAttribute() 
{
    return $this->first_name . ' ' . $this->last_name;
}

class User extends Model
{
    protected $appends = ['full_name'];
}

15. Filter only rows with child rows

class Category extends Model
{
    public function products()
    {
        return $this->hasMany('App\Product');
    }
}

public function getIndex()
{
    $categories = Category::with('products')->has('products')->get();
    return view('categories.index', compact('categories'));
}

16. Return relations on model save

public function store()
{
    $post = new Post;
    $post->fill(Input::all());
    $post->user_id = Auth::user()->user_id;

    $post->user;

    return $post->save();
}

Blade

17. Dynamic With

// eloquent
Post::whereSlug('slug')->get();

// instead of
View::make('posts.index')->with('posts', $posts);

// do this
View::make('posts.index')->withPosts($posts);

18. First/Last Array Element

// hide all but the first item
@foreach ($menu as $item)
    

<div @if ($item != reset($menu)) class="hidden" @endif>

<h2>{{ $item->title }}</h2>


    </div>


@endforeach

// apply CSS to last item only
@foreach ($menu as $item)
    

<div @if ($item == end($menu)) class="no_margin" @endif>

<h2>{{ $item->title }}</h2>


    </div>


@endforeach

Collections

19. Arrays as Collections

$devs = [
    ['name' => 'Anouar Abdessalam', 'email' => 'dtekind@gmail.com'],
    ['name' => 'Bilal Ararou', 'email' => 'have@noIdea.com'],
];

$devs = new \Illuminate\Support\Collection($devs);

20. Collection Filters

Keeps the item only if the closure returns true

$customers = Customer::all();

$us_customers = $customers->filter(function($customer)
{
    return $customer->country == 'United States';
});

21. find()

// returns a single row as a collection
$collection = Person::find([1]);

// returns multiple rows as a collection
$collection = Person::find([1, 2, 3]);

22. where()



$collection = Person::all();

$programmers = $collection->where('type', 'programmer');

23. implode()

$collection = Person::all();

$names = $collection->implode('first_name', ',');

24. where() & list()


// returns a collection of first names
$collection = Person::all()->where('type', 'engineer')->lists('first_name');

// returns all meta records for user 1
$collection = WP_Meta::whereUserId(1)->get();

// returns first name meta values
$first_name = $collection->where('meta_key', 'first_name')->lists('value')[0];

25. Order belongsToMany by Pivot Table value


class Link extends Model
{
    public function users()
    {
        return $this->belongsToMany('Phpleaks\User')->withTimestamps();
    }
}

@if ($link->users->count() > 0)
    <strong>Recently Favorited By</strong>
    @foreach ($link->users()->orderBy('link_user.created_at', 'desc')->take(15)->get() as $user)
        ...
    @endforeach
@endif

26. Sorting with closures

$sorted = $collection->sortBy(function($product, $key)
{
    return array_search($product['name'], [1=>'Bookcase', 2=>'Desk', 3=>'Chair']);
});

27. Keying arrays

Defines the ‘key’ for an array-as-collection (for use with e.g. ->contains)


$library = $books->keyBy('title');

28. Grouped Collections


$collection = Person::all();

$grouped = $collection->groupBy('type');

29. Collection Unions


// the point is to actually combine results from different models
$collection = new Collection;

$all = $collection->merge($programmers)->merge($critics)->merge($engineers);

30. Collection Lookaheads


$collection = collect([1=>11, 5=>13, 12=>14, 21=>15])->getCachingIterator();

foreach ($collection as $key=>$value)
{
    dump ($collection->current() . ':' . $collection->getInnerIterator()->current());
}

Routing

31. Nested Route Groups


Route::group(['prefix'=> => 'account', 'as' => 'account.'], function()
{
    Route::get('login', ['as' => 'login', 'uses' => AccountController::Class.'@getLogin']);
});

<a href="{{ route('account.login') }}">Login</a>

32. Catch-all View Route


// app/Http/routes.php
Route::group(['middleware' => 'auth'], function()
{
    Route::get('{view}', function($view)
    {
        try {
            return view($view);
        } catch (\Exception $e) {
            abort(404);
        }
    })->where('view', '.*');
});

33. Internal Dispatch




// api controller
public funciton show(Car $car)
{
    if (Input::has('fields')) {
        // do something
    }
}

// internal request to api - fields are lost
$request = Request::create('/api/cars/' . $id . '?fields=id,color', 'GET');
$response = json_decode(Route::dispatch($request)->getContent());

// internal request to api - with fields
$originalInput = Request::input();
$request = Request::create('/api/cars' . $id . '?fields=id,color', 'GET');
Request::replace($request->input());
$response = json_decode(Route::dispatch($request)->getContent());
Request::replace($originalInput);
Testing

34. Environmental Variables


// phpunit.xml
<php
    <env name="APP_ENV" value="testing" />
</php>

// .env.test - add to .gitignore
TWILIO_ACCOUNT_SID=blank

// within createApplication() method of TestCase.php
if (file_exists(dirname(__DIR__) . '/.env.test')) {
    Dotenv::load(dirname(__DIR__), '.env.test');
}

35. Run tests automatically


// gulpfile.js
var elixir = require('laravel-elixir');

mix.phpUnit();

$ gulp tdd
Miscellaneous

36. Share Cookies Between Domains


// app/Http/Middleware/EncryptCookies.php
protected $except = [
    'shared_cookie',
];

Cookie::queue('shared_cookie', 'my_shared_value', 10080, null, '.example.com');

37. Easy Model & Migration Stubs


$ artisan make:model Books -m

38. Add Spark to an Existing Project


Notes: Do not run spark:install, backup /resources/views/home.blade.php before running

$ composer require genealabs/laravel-sparkinstaller --dev

$ php artisan spark:upgrade

$ php artisan vendor:publish --tag=spark-full
// config/app.php
Laravel\Spark\Providers\SparkServiceProvider::class,
GeneaLabs\LaravelSparkInstaller\Providers\LaravelSparkInstallerServiceProvider::class,

39. Customize the Default Error Page


<?php namespace App\Exceptions; use Exception; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Symfony\Component\Debug\ExceptionHandler as SymfonyDisplayer; class Handler extends ExceptionHandler { protected function convertExceptionToResponse(Exception $e) { $debug = config('app.debug', false); return $debug ? (new SymfonyDisplayer($debug))->createResponse($e)
            : response()->view('errors.default', ['exception' => $e], 500);
    }
}

40. Conditional Service Providers


// app/Providers/AppServiceProvider.php
public function register()
{
    $this->app->bind(
        \Illuminate\Contracts\Auth\Registrar::class,
        \App\Services\Registrar::class
    );

    if ($this->app->environment('production')) {
        $this->app->register(\App\Providers\ProductionErrorHandlerServiceProvider::class);
    }
    else {
        $this->app->register(\App\Providers\VerboseErrorHandlerServiceProvider::class);
    }
}

41. Change a Column Name in Migration


$ composer require doctrine/dbal

public function up()
{
    Schema::table('users', function ($table)
    {
        $table->string('name', 50)->change();
    });
}

42. Checking if a View Exists


if (view()->exists("emails.{$template}")) {
    // ...sending an email to the customer
}

43. Extending the Application




// bootstrap/app.php
// replace this:
$app = new \Illuminate\Foundation\Application( realpath(__DIR__.'/../'));

// with this:
$app = new \Fantabulous\Application( realpath(__DIR__.'/../'));

// and add
<?php namespace Fantabulous; class Application extends \Illuminate\Foundation\Application { public function storagePath() { return $this->basePath.'/FantabulousStorage';
    }
}

44. Simple Caching Microservice


class fakeApiCaller
{
    public function getResultsForPath($path)
    {
        return [
            'status' => 200,
            'body' => json_encode([
                'title' => "Results for path [$path]"
            ]),
            'headers' => [
                "Content-Type" => "application/json",
            ]
        ];
    }
}

$app->get('{path?}', function($path)
{
    $result = Cache::remember($path, 60, function() use ($path)
    {
        return (new fakeApiCaller)->getResultsForPath($path);
    });

    return response($result['body'], $result['status'], array_only(
        $result['headers'], ['Content-Type', 'X-Pagination']
    ));
})->where('path', '.*');

45. Use Bleeding Edge Version


$ composer create-project laravel/laravel your-project-name dev-develop

// composer.json
{
    "require": {
        "php": ">=5.5.9",
        "laravel/framework": "5.2.*"
    },
    "minimum-stability": "dev"
}

46. Capture Queries


Event::listen('illuminate.query', function($query)
{
    var_dump($query);
});

\DB::listen(function($query, $bindings, $time)
{
    var_dump( $query, $bindings, $time);

});

47. Authorization Without Models


// app/Policies/AdminPolicy.php
class AdminPolicy
{
    public function managePages($user)
    {
        return $user->hasRole(['Administrator', 'Content Editor']);
    }
}

// app/Providers/AuthServiceProvider.php
public function boot( \Illuminate\Contracts\Auth\Access\GateContract $gate)
{
    foreach (get_class_methods(new \App\Policies\AdminPolicy) as $method) {
        $gate->define($method, \App\Policies\AdminPolicy::class . "@{$method}");
    }
    $this->registerPolicies($gate);
}

$this->authorize('managePages'); // in Controllers
@can('managePages') // in Blade
$user->can('managePages'); // via Eloquent

48. Efficient File Transfers with Streams


$disk = Storage::disk('s3');
$disk->put($targetFile, file_get_contents($sourceFile));

$disk = Storage::disk('s3');
$disk->put($targetFile, fopen($sourceFile, 'r+'));

$disk = Storage::disk('s3');
$stream = $disk->getDriver()->readStream($sourceFileOnS3);
file_put_contents($targetFile, stream_get_contents($stream), FILE_APPEND);

$stream = Storage::disk('s3')->getDriver()->readStream($sourceFile);
Storage::disk('sftp')->put($targetFile, $stream);

49. Avoid Overflowing Log Files


$schedule->call(function()
{
    Storage::delete($logfile);
})->weekly();

50. Pipeline



$result = (new \Illuminate\Pipeline\Pipeline($container))
    ->send($something)
    ->through('ClassOne', 'ClassTwo', 'ClassThree')
    ->then(function ($something)
    {
        return 'foo';
    });

50 ví dụ này chỉ là một lựa chọn nhỏ mà Laravel cung cấp. Tôi khuyến khích bạn làm quen với tất cả những gì hiện có và bắt đầu triển khai chúng vào trong chính project của bạn. Chúc các bạn thành công. Nếu thấy hay và có ích hãy share cho bạn bè nhé.







Bài viết được viết bởi Codevivu.com. Các bạn yêu thích muốn trích dẫn vui lòng ghi rõ nguồn từ Codevivu.com nhé!.