1. Automatic Model Validation
[precode]php[noidung1]
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()
{
}
}
[/noidung1][/precode]
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)
{{ $item->title }}
@endforeach // apply CSS to last item only @foreach ($menu as $item)
{{ $item->title }}
@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) Recently Favorited By @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']); }); Login
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 // .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
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 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é.