#Lesson 4
- .env file is a place where you should keep your keys, API keys etc.
php artican migrate
runs all the migrations fromdatabase/migrations
creating all the necessary tables in configured schema. It also createsmigrations
table to keep records of all the runned migrations
#Lesson 5
- You can retrieve data passed do view via
<?= $name ?>
or{{ $name }}
- Pass data using second argument after view name or using
with(argument, value)
method - Passing data as second argument you can either create new array or use
compact(parameter1, parameter2)
function - In templates use blade directives (eg.
@foreach($tasks as $task) {{ $task }} @endforeach
) instead of php structures
#Lesson 6
- To display all the possible artisan commands use
php artisan
php artisan help [commands]
displays help- To create new migration use eg.
php artisan make:migration create_tasks_table
. It's not going to create new table - To create new table in migration add
--create=[tableName]
option - When you delete migration and receive an error try update the autoloader
composer dump-autoload
- Methods creating column names correspond to the data type. You can get more information from documentation or reading source code of
Illuminate\Database\Schema\Blueprint
- increments
- integer
- string
- text
- timestamps
- To run migrations use
php artisan migrate
. You can refresh them using subtask:refresh
- Returned entities are automatically converted into JSON response
dd($someVariable)
allows us to show the variable value
- You can pass parameters to url using eg.
Route::get('/tasks/{task}', function ($id)
- When
id
corresponds to some real entity you can populate it passing entity in method:Route::get('/tasks/{task}', function (Task $task)
- Create model with
php artisan make:model Task
-
To play with php and eloquent use
php artisan tinker
-
App\Task::all())
- get all entities -
You can use conditionals like
App\Task::where('id', '>', 2)->get();
-
If you don't use
get
method you'll receive `Illuminate\Database\Eloquent\Builder object -
To get only one field from all records use
App\Task::pluck('body')
-
The result is
Illuminate\Database\Eloquent\Collection
. It contains methods likefirst
-
Upon creating new entity via
$task = new App\Task;
and setting values using$task->body = 'Go to the market';
you can save it invoking$task->save();
-
php artisan migrate:reset
rolls back all the migrations -
To automatically create migration while creating model use
php artisan make:model Task --migration
-
If you want to specify default value for entity use
$table->boolean('completed')->default(false);
-
You can use static function to facilitate fetching data from database
public static function incomplete()
{
return static::where('completed', 0)->get();
}
- When we want to make constructions like
App\Task::incomplete()->get()->where('id', '>', 1)
we have to resort to local scopes like in
public function scopeIncomplete($query)
{
return $query->where('completed', 0);
}
- The method returning all the items is often called
index
- New controllers are created with
php artisan make:controller TasksController
- Route model binding is the ability to bind model when its id is passed in url. The route name must match parameter name. The laravel will perform
Task::find(id)
and use primary key to find entity
Route::get('/tasks/{task}', 'TasksController@show');
public function show (Task $task) {
return view('tasks.show', compact('task'));
}
- To specify place where content should be inserted use directive
@yield('content')
- Instead creating separately model, controller and migration, use
make:model
flags-m -c
- To use layout utilize
@section
and@extends
directives:
@extends('layout)
@section('content')
@endsection
- To include some content use
@include('layouts.nav')
- There is a convention to keep your layout partials in
layout
directory and name the main layout filemaster
-
GET /posts - displays all the posts
-
GET /posts/create - displays form for adding new form
-
POST /posts - adds new form
-
GET /posts/{id}/edit - displays form to edit post with specified id
-
GET /posts/{id} - shows the post
-
PATCH /posts/{id} - updated the post
-
DELETE /posts/{id} - deletes the post
-
When you generate controller add the flag
-r
to generate resourceful controller with all the necessary methods -
request()->all()
gives all the request parameters. You can get only one field withrequest('fieldName')
or selected fields withrequest(['title', 'body'])
-
Laravel generates a csrf token which has to be passed in field with
{{ csrf_field() }}
. The fields looks like this:"_token" => "RatQYPlj5RRjsWyqCiNhw0BcOcTTYz0QjeS55tTW"
- One way is to create entities using
$post = new Post;
$post->title = request('title');
$post->body = request('body');
$post->save();
- The other is to use:
Post::create([
'title' => request('title'),
'body' => request('body')
]);
- Remember to fill in fillable field to allow the second option:
class Post extends Model
{
protected $fillable = ['title', 'body'];
}
- The inverse of
$fillable
isprotected $guarded = ['user_id'];
. In specific cases it can be set to empty array - There is a technique to create your own Model to inherit from containing
$guarder
with empty array:
namespace App;
use Illuminate\Database\Eloquent\Model as Eloquent;
class Model extends Eloquent
{
protected $fillable = [];
}
- You can't rely only on validation on client side
- Use server side validation instead:
$this->validate(request(), [
'title' => 'required',
'body' => 'required'
]);
- It'll return to previous page with error fields. You can access them:
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
#Lesson 13
- You can utilize fields
created_at
andupdated_at
to get post creation and update date created_at
andupdated_at
are instances of carbon library and have many interesting methods- To get formatted date you can use
toFormattedDateString()
- The source code of query steps can be found in
Illuminate\Database\Query\Builder
- The modifier
latest()
works likeorderBy
with fieldcreated_at
#Lesson 14
- Laravel mix is a npm dependency
Comment::class
is equivalent of"\App\Comment"
- First side of one to many relationship is created using
hasMany
function
public function comments()
{
return $this->hasMany(Comment::class);
}
- The other side is created with
belongsTo
public function post()
{
return $this->belongsTo(Post::class);
}
- You can access each side via field:
\App\Post::find(1)->comments
- Don't nest your REST urls too much
- Use
back()
helper function to redirect to the previous page - While creating subentity you can:
- create it in controller
- create it in entity using
Subentity::create
- create it in entity using
$this->subentities()->create(['field' => 'value'])
php artisan make:auth
scaffolds basic authentication mechanism- It creates authentication routes in
web.php
(Auth::routes();
) - Configuration files in
config
directory reference.env
files which should not be commited into repository - Changing
DB_CONNECTION
you can change database driver used inconfig/database.php
configuration file. The unnecessary properties can be removed - The list of middleware run during every request is in
Kernel.php
file php artisan down
turns application down for maintanance. It is handled byCheckForMaintenanceMode
middleware- Route middleware can be assigned to route groups. It contains middlewares to restrict access to guests, authenticated users etc.
- Route middleware can be used in constructor of a router
- You can adapt autogenerated registration mechanism for your needs
- Instead of smpt mail driver you can use log and see the results in
storate/logs/laravel.log
#Lesson 18
- You can create new user with tinker
- Create new password using
$user->password = bcrypt('password');
- To access input data use
\Request::input
orrequest()->input
- To redirect to home you can use
return redirect('/')
orreturn redirect()->home()
. The latter method required naming the route `Route::get('/', 'PostsController@index')->name('home'); - When the field has corresponding field with suffix
confirmation
, the validationconfirmed
checks the fields' equality - Fetch user name with
Auth::user()->name
. You can chech whether the user is logged in withAuth::check()
- To prevent access to all the methods except some use
$this->middleware('auth')->except(['index', 'show']);
- Fetching user id can be done with
auth()->id()
- When you have relation to some entities you can use method save to add another entity:
$this->posts()->save($post);
. This will save theuser_id
for us - The method
attempt
attempts to authenticate user against the date in databaseauth()->attempt(request(['email', 'password']))
- To allow only guests using the methods use middleware
guest
:$this->middleware('guest')
- You can resort to mutator to automatically bcrypt password
- With eloquent you can create fairly complicated queries:
\App\Post::selectRaw('year(created_at) year, monthname(created_at) month, count(*) published')->groupBy('year', 'month')->get()->toArray()
- Use Carbon to convert month name to month number:
Carbon::parse($month)->month
- You can conditionally build eloquent query:
public function scopeFilter($query, $filters)
{
if ($month = $filters['month']) {
$query->whereMonth('created_at', Carbon::parse($month)->month);
}
if ($year = $filters['year']) {
$query->whereYear('created_at', $year);
}
}
- View composers can bind variables on views loading. You should add them in
AppServiceProvider->boot
method
view()->composer('layouts.sidebar', function($view) {
$view->with('archives', \App\Post::archives());
});
- Laravel has phpunit as a dependency. You can use it typing
phpunit
. Make sure you havevendor/bin
in yourPATH
variable - Database factories are made with
factory('App\User')->make()
. They are located indatabase/factories
directory - To persist them use
create()
method instead:factory('App\User')->create()
- You can take it further and create multiple entities at once:
factory('App\User', 50)->create()
- You can create your own factories:
$factory->define(App\Post::class, function (Faker\Generator $faker) {
static $password;
return [
'user_id' => function () {
return factory(App\User::class)->create()->id;
},
'title' => $faker->sentence,
'body' => $faker->paragraph
];
});
- You can overrite the default values passing an array in
make
/create
method:
$second = factory(Post::class)->create([
'created_at' => \Carbon\Carbon::now()->subMonth()
]);
- Assert count (
$this->assertCount(2, $posts);
) asserts the number of instances in collection - Environment variables overrides used with phpunit are located in
phpunit.xml
file. Eg.
<php>
<env name="APP_ENV" value="testing"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
<env name="DB_DATABASE" value="blog_testing"/>
</php>
- Use transaction to roll back the database after running test
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase
{
use DatabaseTransactions;
}
- Laravel provides dependency injection for constructor and every single action
- When we want to access View, Request or App facades, we can use
view()
,request()
andapp()
functions respectively - If we want to bind to the container we use
App::bind('App\Billing\Stripe', function () { ... })
, eg:
App::bind('App\Billing\Stripe', function () {
return new \App\Billing\Stripe(config('services.stripe.key'));
});
- To access config file you can use
config('configFileName.key.subKey)
- Resolving bound service can be done with
App::make
orresolve()
orapp()
:
$stripe = App::make('App\Billing\Stripe');
$stripe = resolve('App\Billing\Stripe');
$stripe = app('App\Billing\Stripe');
- You can register singleton with
App::singleton()
instead ofApp::bind()
:
App::singleton('App\Billing\Stripe', function () {
return new \App\Billing\Stripe(config('services.stripe.key'));
});
$stripe1 = App::make('App\Billing\Stripe');
$stripe2 = resolve('App\Billing\Stripe');
$stripe3 = app('App\Billing\Stripe');
dd($stripe1, $stripe2, $stripe3);
- With
App::instance()
you can swap existing instance with new one
- Add services registration in
AppServiceProvider
'sregister()
method AppServiceProvider
hasapp
property to bind services:$this->app->singleton()
- You can add
$app
as a function parameter when some dependencies are necessary:
$this->app->singleton(Stripe::class, function ($app) {
$app->make
return new Stripe(config('services.stripe.key'));
});
- Providers in
config/app/providers
are the building blocks of Laravel - Then the service is not required on every single page load we can defer loading it with field
protected $defer = true;
in ourServiceProvider
- If you have anything in your boot method, the
ServiceProvider
can't be deferred php artisan make:provider
will generate service provider for you
Lesson 26
- To prepare new email class use
php artisan make:mail
. Laravel will generateapp/Mail
folder and put new email there - Newly created email can be sent with
Mail::to($user)->send(new Welcome)
- Globally the field "from" comes from
mail.php
configuration file - When some fields in email class are public, they can be used in templates:
class Welcome extends Mailable
{
use Queueable, SerializesModels;
public $user;
public function __construct(User $user)
{
$this->user = $user;
}
public function build()
{
return $this->view('emails.welcome');
}
}
<!DOCTYPE html>
<html lang="{{ config('app.locale') }}">
<head>
<title>Laravel</title>
</head>
<body>
<h1>Welcome to Laracasts! {{ $user->name }}</h1>
</body>
</html>
- We can also pass some fields to the view using
with
method:return $this->view('emails.welcome')->with(...)
- When the emails should suppport markdown, provide
--markdown
flag when generating them:php artisan make:mail WelcomeAgain --markdown="emails.welcome-again"
. Such generated email class will reference markdown instead of view method - There are button components, panel component, table component etc.
- To extract any resources from vendor files use:
php artisan vendor:publish --tag=laravel-mail
.
Copied Directory [/vendor/laravel/framework/src/Illuminate/Mail/resources/views] To [/resources/views/vendor/mail]
Publishing complete.
- You can create multiple themes. Just create new css file and set the theme name in mail configuration file
- Request classes are made with
php artisan make:request RegistrationRequest
- The
rules
method performs validation:
public function rules()
{
return [
'name' => 'required',
'email' => 'required|email',
'password' => 'required|confirmed'
];
}
- The
authorize
methods determines if the user is authorized to make the request:
public function authorize()
{
return true;
}
- Every
request(['name', 'email', 'password'])
should be replaced with$this->only(['name', 'email', 'password'])
- We can access session using
session()
orrequest()->session()
- To retrieve some value, provide key and default value:
session('message', 'Here is a default message')
- To set some value, provide an array with new values:
session(['message' => 'Something custom']);
- You can flash something to the session. Such variable will be available for only one request:
session->flash()
. It can be useful for single use data (like error messages, notifications etc)
- To make combined primary key pass array to
primary
method of table blueprint:$table->primary(['post_id', 'tag_id'])
- To create many to many relationship use
$this->belongsToMany(Post::class);
- When we fetch all Posts using
App\Post::all()
none of the tags will be fetched. To do it useApp\Post::with('tags')->get()
instead - To attach entity to collection use attach method:
$post = App\Post::first();
$tag = App\Tag::where('name', 'personal')->first();
$post->tags()->attach($tag->id);
// or
$post->tags()->attach($tag);
- There is also a detach method:
$post->tags()->detach($tag)
- The method
getRouteKeyName
will perform where condition while binding entity on route name. It is used when the entity is injected into method. It matches the rout key to column name returned from the function
public function getRouteKeyName()
{
return 'name';
}
- Useful technique is to pluck some fields for the needs of composed view:
public function boot()
{
view()->composer('layouts.sidebar', function ($view) {
$view->with('tags', \App\Tag::pluck('name'));
});
}
- To fetch all the tags with some non empty collection use
\App\Tag::has('posts')
, eg:
\App\Tag::has('posts')->pluck('name')
php artisan make:event SomeEvent
creates new event class to be sent to the listenersphp artisan make:listener SendNotification --event="SomeEvent"
creates new listener- All the listenings have to be registered in
EventServiceProvider
i$listen
method - When we don't want to manually create all the events, listeners and register them. We can only add something in
$listen
method and runphp artisan event:generate
- To publish new event use
event
function:event(new \App\Events\ThreadCreated(['name' => 'Some new thread']))