A Framework for Building Modern PHP Apps
Constant width
Constant width bold
Constant width italic
From the very beginning of Laravel, I’ve had this idea that all people want to feel like they are part of something. It’s a natural human instinct to want to belong and be accepted into a group of other like-minded people. So, by injecting personality into a web framework and being really active with the community, that type of feeling can grow in the community.
Taylor Otwell, Product and Support interview
// File: routes/web.php
<?
php
Route
::
get
(
'/'
,
function
()
{
return
'Hello, World!'
;
});
// File: routes/web.php
<?
php
Route
::
get
(
'/'
,
'WelcomeController@index'
);
// File: app/Http/Controllers/WelcomeController.php
<?
php
namespace
app\Http\Controllers
;
class
WelcomeController
{
public
function
index
()
{
return
'Hello, World!'
;
}
}
// File: routes/web.php
<?
php
Route
::
get
(
'/'
,
function
()
{
return
Greeting
::
first
()
->
body
;
});
// File: app/Greeting.php
<?
php
use
Illuminate\Database\Eloquent\Model
;
class
Greeting
extends
Model
{}
// File: database/migrations/2015_07_19_010000_create_greetings_table.php
<?
php
use
Illuminate\Database\Migrations\Migration
;
use
Illuminate\Database\Schema\Blueprint
;
class
CreateGreetingsTable
extends
Migration
{
public
function
up
()
{
Schema
::
create
(
'greetings'
,
function
(
Blueprint
$table
)
{
$table
->
increments
(
'id'
);
$table
->
string
(
'body'
);
$table
->
timestamps
();
});
}
public
function
down
()
{
Schema
::
drop
(
'greetings'
);
}
}
git clone https://github.com/laravel/homestead.git ~/Homestead
bash ~/Homestead/init.sh
ip
:
"192.168.10.10"
memory
:
2048
cpus
:
1
provider
:
virtualbox
authorize
:
~/.ssh/id_rsa.pub
keys
:
-
~/.ssh/id_rsa
folders
:
-
map
:
~/Code
to
:
/home/vagrant/Code
sites
:
-
map
:
homestead.app
to
:
/home/vagrant/Code/Laravel/public
databases
:
-
homestead
# blackfire:
# - id: foo
# token: bar
# client-id: foo
# client-token: bar
# ports:
# - send: 50000
# to: 5000
# - send: 7777
# to: 777
# protocol: udp
folders
:
-
map
:
~/Sites
to
:
/home/vagrant/Sites
sites
:
-
map
:
projectName.app
to
:
/home/vagrant/Sites/projectName/public
192.168.10.10 projectName.app
databases
:
-
projectname
cd
~/Homestead
vagrant up
composer global require "laravel/installer=~1.1"
laravel new projectName
composer create-project laravel/laravel projectName --prefer-dist
app/ bootstrap/ config/ database/ public/ resources/ routes/ storage/ tests/ vendor/ .env .env.example .gitattributes .gitignore artisan composer.json composer.lock gulpfile.js package.json phpunit.xml readme.md server.php
// config/services.php
return
[
'sparkpost'
=>
[
'secret'
=>
'abcdefg'
]
];
// config/services.php
return
[
'bugsnag'
=>
[
'api_key'
=>
env
(
'BUGSNAG_API_KEY'
)
]
];
BUGSNAG_API_KEY=oinfp9813410942
laravel new myProject && cd myProject && valet open
laravel new myProject cd myProject git init git add . git commit -m "Initial commit"
// routes/web.php
Route
::
get
(
'/'
,
function
()
{
return
'Hello, World!'
;
});
Route
::
get
(
'/'
,
function
()
{
return
view
(
'welcome'
);
});
Route
::
get
(
'about'
,
function
()
{
return
view
(
'about'
);
});
Route
::
get
(
'products'
,
function
()
{
return
view
(
'products'
);
});
Route
::
get
(
'services'
,
function
()
{
return
view
(
'services'
);
});
$router
->
get
(
'/'
,
function
()
{
return
'Hello, World!'
;
});
Route
::
get
(
'/'
,
function
()
{
return
'Hello, World!'
;
});
Route
::
post
(
'/'
,
function
()
{});
Route
::
put
(
'/'
,
function
()
{});
Route
::
delete
(
'/'
,
function
()
{});
Route
::
any
(
'/'
,
function
()
{});
Route
::
match
([
'get'
,
'post'
],
'/'
,
function
()
{});
Route
::
get
(
'/'
,
'WelcomeController@index'
);
Route
::
get
(
'users/{id}/friends'
,
function
(
$id
)
{
//
});
Route
::
get
(
'users/{id?}'
,
function
(
$id
=
'fallbackId'
)
{
//
});
Route
::
get
(
'users/{id}'
,
function
(
$id
)
{
//
})
->
where
(
'id'
,
'[0-9]+'
);
Route
::
get
(
'users/{username}'
,
function
(
$username
)
{
//
})
->
where
(
'username'
,
'[A-Za-z]+'
);
Route
::
get
(
'posts/{id}/{slug}'
,
function
(
$id
,
$slug
)
{
//
})
->
where
([
'id'
=>
'[0-9]+'
,
'slug'
=>
'[A-Za-z]+'
]);
<
a
href
=
"<?php echo url('/'); ?>"
>
// outputs <a href="http://myapp.com/">
// Defining a route with name in routes/web.php:
Route
::
get
(
'members/{id}'
,
'MembersController@show'
)
->
name
(
'members.show'
);
// Link the route in a view using the route() helper
<
a
href
=
"<?php echo route('members.show', ['id' => 14]); ?>"
>
Route
::
get
(
'members/{id}'
,
[
'as'
=>
'members.show'
,
'uses'
=>
'MembersController@show'
]);
Route
::
group
([],
function
()
{
Route
::
get
(
'hello'
,
function
()
{
return
'Hello'
;
});
Route
::
get
(
'world'
,
function
()
{
return
'World'
;
});
});
Route
::
group
([
'middleware'
=>
'auth'
],
function
()
{
Route
::
get
(
'dashboard'
,
function
()
{
return
view
(
'dashboard'
);
});
Route
::
get
(
'account'
,
function
()
{
return
view
(
'account'
);
});
});
class
DashboardController
extends
Controller
{
public
function
__construct
()
{
$this
->
middleware
(
'auth'
);
$this
->
middleware
(
'admin-auth'
)
->
only
(
'admin'
);
$this
->
middleware
(
'team-member'
)
->
except
(
'admin'
);
}
}
Route
::
group
([
'prefix'
=>
'api'
],
function
()
{
Route
::
get
(
'/'
,
function
()
{
// Handles the path /api
});
Route
::
get
(
'users'
,
function
()
{
// Handles the path /api/users
});
});
Route
::
group
([
'domain'
=>
'api.myapp.com'
],
function
()
{
Route
::
get
(
'/'
,
function
()
{
//
});
});
Route
::
group
([
'domain'
=>
'{account}.myapp.com'
],
function
()
{
Route
::
get
(
'/'
,
function
(
$account
)
{
//
});
Route
::
get
(
'users/{id}'
,
function
(
$account
,
$id
)
{
//
});
});
// App\Http\Controllers\ControllerA
Route
::
get
(
'/'
,
'ControllerA@index'
);
Route
::
group
([
'namespace'
=>
'API'
],
function
()
{
// App\Http\Controllers\API\ControllerB
Route
::
get
(
'api/'
,
'ControllerB@index'
);
});
Route
::
group
([
'as'
=>
'users.'
,
'prefix'
=>
'users'
],
function
()
{
Route
::
group
([
'as'
=>
'comments.'
,
'prefix'
=>
'comments'
],
function
()
{
// Route name will be users.comments.show
Route
::
get
(
'{id}'
,
function
()
{
//
})
->
name
(
'show'
);
});
});
Route
::
get
(
'/'
,
function
()
{
return
view
(
'home'
);
});
Route
::
get
(
'tasks'
,
function
()
{
return
view
(
'tasks.index'
)
->
with
(
'tasks'
,
Task
::
all
());
});
view
()
->
share
(
'variableName'
,
'variableValue'
);
php artisan make:controller TasksController
<?
php
namespace
App\Http\Controllers
;
use
Illuminate\Http\Request
;
use
App\Http\Requests
;
class
TasksController
extends
Controller
{
}
<?
php
use
App\Http\Controllers\Controller
;
class
TasksController
extends
Controller
{
public
function
home
()
{
return
'Hello, World!'
;
}
}
// routes/web.php
<?
php
Route
::
get
(
'/'
,
'TasksController@home'
);
// TasksController.php
...
public
function
index
()
{
return
view
(
'tasks.index'
)
->
with
(
'tasks'
,
Task
::
all
());
}
php artisan make:controller TasksController --resource
// routes/web.php
Route
::
get
(
'tasks/create'
,
'TasksController@create'
);
Route
::
post
(
'tasks'
,
'TasksController@store'
);
// TasksController.php
...
public
function
store
()
{
$task
=
new
Task
;
$task
->
title
=
Input
::
get
(
'title'
);
$task
->
description
=
Input
::
get
(
'description'
);
$task
->
save
();
return
redirect
(
'tasks'
);
}
<?
php
namespace
App\Http\Controllers
;
use
Illuminate\Support\facades\Input
;
class
TasksController
{
public
function
store
()
{
$task
=
new
Task
;
$task
->
title
=
Input
::
get
(
'title'
);
$task
->
description
=
Input
::
get
(
'description'
);
$task
->
save
();
return
redirect
(
'tasks'
);
}
// TasksController.php
...
public
function
store
(
\Illuminate\Http\Request
$request
)
{
$task
=
new
Task
;
$task
->
title
=
$request
->
input
(
'title'
);
$task
->
description
=
$request
->
input
(
'description'
);
$task
->
save
();
return
redirect
(
'tasks'
);
}
php artisan make:controller MySampleResourceController --resource
Verb | URL | Controller method | Name | Description |
---|---|---|---|---|
// routes/web.php
Route
::
resource
(
'tasks'
,
'TasksController'
);
Route
::
get
(
'conferences/{id}'
,
function
(
$id
)
{
$conference
=
Conference
::
findOrFail
(
$id
);
});
Route
::
get
(
'conferences/{conference}'
,
function
(
Conference
$conference
)
{
return
view
(
'conferences.show'
)
->
with
(
'conference'
,
$conference
);
});
public
function
getRouteKeyName
()
{
return
'slug'
;
}
public
function
boot
(
Router
$router
)
{
// Just allows the parent's boot() method to still run
parent
::
boot
(
$router
);
// Perform the binding
$router
->
model
(
'event'
,
Conference
::
class
);
}
Route
::
get
(
'events/{event}'
,
function
(
Conference
$event
)
{
return
view
(
'events.show'
)
->
with
(
'event'
,
$event
);
});
<form
action=
"/tasks/5"
method=
"POST"
>
<input
type=
"hidden"
name=
"_method"
value=
"DELETE"
>
</form>
<form
action=
"/tasks/5"
method=
"POST"
>
<?php echo csrf_field(); ?>
<!-- or: -->
<input
type=
"hidden"
name=
"_token"
value=
"<?php echo csrf_token(); ?>"
>
</form>
<
meta
name
=
"csrf-token"
content
=
"<?php echo csrf_token(); ?>"
id
=
"token"
>
// in jQuery:
$
.
ajaxSetup
({
headers
:
{
'X-CSRF-TOKEN'
:
$
(
'meta[name="csrf-token"]'
).
attr
(
'content'
)
}
});
// in Vue:
Vue
.
http
.
interceptors
.
push
((
request
,
next
)
=>
{
request
.
headers
[
'X-CSRF-TOKEN'
]
=
document
.
querySelector
(
'#token'
).
getAttribute
(
'content'
);
next
();
});
// Using the global helper to generate a redirect response
Route
::
get
(
'redirect-with-helper'
,
function
()
{
return
redirect
()
->
to
(
'login'
);
});
// Using the global helper shortcut
Route
::
get
(
'redirect-with-helper-shortcut'
,
function
()
{
return
redirect
(
'login'
);
});
// Using the facade to generate a redirect response
Route
::
get
(
'redirect-with-facade'
,
function
()
{
return
Redirect
::
to
(
'login'
);
});
function
to
(
$to
=
null
,
$status
=
302
,
$headers
=
[],
$secure
=
null
)
Route
::
get
(
'redirect'
,
function
()
{
return
redirect
()
->
to
(
'home'
);
// or same, using the shortcut:
return
redirect
(
'home'
);
});
Route
::
get
(
'redirect'
,
function
()
{
return
redirect
()
->
route
(
'conferences.index'
);
});
function
route
(
$to
=
null
,
$parameters
=
[],
$status
=
302
,
$headers
=
[])
Route
::
get
(
'redirect'
,
function
()
{
return
redirect
()
->
route
(
'conferences.show'
,
[
'conference'
=>
99
]);
});
Route
::
get
(
'redirect-with-key-value'
,
function
()
{
return
redirect
(
'dashboard'
)
->
with
(
'error'
,
true
);
});
Route
::
get
(
'redirect-with-array'
,
function
()
{
return
redirect
(
'dashboard'
)
->
with
([
'error'
=>
true
,
'message'
=>
'Whoops!'
]);
});
Route
::
get
(
'form'
,
function
()
{
return
view
(
'form'
);
});
Route
::
post
(
'form'
,
function
()
{
return
redirect
(
'form'
)
->
withInput
()
->
with
([
'error'
=>
true
,
'message'
=>
'Whoops!'
]);
});
<input
name=
"username"
value=
"<?=
old('username', 'Default username instructions here');
?>"
>
Route
::
post
(
'form'
,
function
()
{
$validator
=
Validator
::
make
(
$request
->
all
()),
$this
->
validationRules
);
if
(
$validator
->
fails
())
{
return
redirect
(
'form'
)
->
withErrors
(
$validator
)
->
withInput
();
}
});
Route
::
post
(
'something-you-cant-do'
,
function
(
Illuminate\Http\Request
)
{
abort
(
403
,
'You cannot do that!'
);
abort_unless
(
$request
->
has
(
'magicToken'
),
403
);
abort_if
(
$request
->
user
()
->
isBanned
,
403
);
});
// AssignmentTest.php
public
function
test_post_creates_new_assignment
()
{
$this
->
post
(
'/assignments'
,
[
'title'
=>
'My great assignment'
]);
$this
->
seeInDatabase
(
'assignments'
,
[
'title'
=>
'My great assignment'
]);
}
// AssignmentTest.php
public
function
test_list_page_shows_all_assignments
()
{
$assignment
=
Assignment
::
create
([
'title'
=>
'My great assignment'
]);
$this
->
visit
(
'assignments'
)
->
see
([
'My great assignment'
]);
}
<
h1
>
{{
$group
->
title
}}
</
h1
>
{
!!
$group
->
heroImageHtml
()
!!
}
@
forelse
(
$users
as
$user
)
•
{{
$user
->
first_name
}}
{{
$user
->
last_name
}}
<
br
>
@
empty
No
users
in
this
group
.
@
endforelse
@
if
(
count
(
$talks
)
===
1
)
There
is
one
talk
at
this
time
period
.
@
elseif
(
count
(
$talks
)
===
0
)
There
are
no
talks
at
this
time
period
.
@
else
There
are
{{
count
(
$talks
)
}}
talks
at
this
time
period
.
@
endif
@
unless
(
$user
->
hasPaid
())
You
can
complete
your
payment
by
switching
to
the
payment
tab
.
@
endunless
@
for
(
$i
=
0
;
$i
<
$talk
->
slotsCount
();
$i
++
)
The
number
is
{{
$i
}}
<
br
>
@
endfor
@
foreach
(
$talks
as
$talk
)
•
{{
$talk
->
title
}}
({{
$talk
->
length
}}
minutes
)
<
br
>
@
endforeach
@
while
(
$item
=
array_pop
(
$items
))
{{
$item
->
orSomething
()
}}
<
br
>
@
endwhile
@
forelse
(
$talks
as
$talk
)
•
{{
$talk
->
title
}}
({{
$talk
->
length
}}
minutes
)
<
br
>
@
empty
No
talks
this
day
.
@
endforelse
index
iteration
remaining
count
first
last
depth
parent
<
ul
>
@
foreach
(
$pages
as
$page
)
<
li
>
{{
$loop
->
iteration
}}
:
{{
$page
->
title
}}
@
if
(
$page
->
hasChildren
())
<
ul
>
@
foreach
(
$page
->
children
()
as
$child
)
<
li
>
{{
$loop
->
parent
->
iteration
}}
.
{{
$loop
->
iteration
}}
:
{{
$child
->
title
}}
</
li
>
@
endforeach
</
ul
>
@
endif
</
li
>
@
endforeach
</
ul
>
<!-- resources/views/layouts/master.blade.php -->
<html>
<head>
<title>
My Site | @yield('title', 'Home Page')</title>
</head>
<body>
<div
class=
"container"
>
@yield('content')</div>
@section('footerScripts')<script
src=
"app.js"
></script>
@show</body>
</html>
<!-- resources/views/dashboard.blade.php -->
@extends('layouts.master') @section('title', 'Dashboard') @section('content') Welcome to your application dashboard! @endsection @section('footerScripts') @parent<script
src=
"dashboard.js"
></script>
@endsection
<!-- resources/views/home.blade.php -->
<div
class=
"content"
data-page-name=
"{{ $pageName }}"
>
<p>
Here's why you should sign up for our app:<strong>
It's Great.</strong></p>
@include('sign-up-button', ['text' => 'See just how great it is'])</div>
<!-- resources/views/sign-up-button.blade.php -->
<a
class=
"button button--callout"
data-page-name=
"{{ $pageName }}"
>
<i
class=
"exclamation-icon"
></i>
{{ $text }}</a>
<!-- resources/views/sidebar.blade.php -->
<div
class=
"sidebar"
>
@each('partials.module', $modules, 'module', 'partials.empty-module')</div>
<!-- resources/views/partials/module.blade.php -->
<div
class=
"sidebar-module"
>
<h1>
{{ $module->title }}</h1>
</div>
<!-- resources/views/partials/empty-module.blade.php -->
<div
class=
"sidebar-module"
>
No modules :(</div>
Route
::
get
(
'passing-data-to-views'
,
function
()
{
return
view
(
'dashboard'
)
->
with
(
'key'
,
'value'
);
});
Route
::
get
(
'home'
,
function
()
{
return
view
(
'home'
)
->
with
(
'posts'
,
Post
::
recent
());
});
Route
::
get
(
'about'
,
function
()
{
return
view
(
'about'
)
->
with
(
'posts'
,
Post
::
recent
());
});
// Some service provider
public
function
boot
()
{
...
view
()
->
share
(
'posts'
,
Post
::
recent
());
}
view
()
->
composer
(
'partials.sidebar'
,
function
(
$view
)
{
$view
->
with
(
'posts'
,
Post
::
recent
());
});
view
()
->
composer
(
[
'partials.header'
,
'partials.footer'
],
function
()
{
$view
->
with
(
'posts'
,
Post
::
recent
());
}
);
view
()
->
composer
(
'partials.*'
,
function
()
{
$view
->
with
(
'posts'
,
Post
::
recent
());
});
<?
php
namespace
App\Http\ViewComposers
;
use
App\Post
;
use
Illuminate\Contracts\View\View
;
class
RecentPostsComposer
{
private
$posts
;
public
function
__construct
(
Post
$posts
)
{
$this
->
posts
=
$posts
;
}
public
function
compose
(
View
$view
)
{
$view
->
with
(
'posts'
,
$this
->
posts
->
recent
());
}
}
// AppServiceProvider
public
function
boot
()
{
...
view
()
->
composer
(
'partials.sidebar'
,
\App\Http\ViewComposers\RecentPostsComposer
::
class
);
}
Route
::
get
(
'backend/sales'
,
function
(
AnalyticsService
$analytics
)
{
return
view
(
'backend.sales-graphs'
)
->
with
(
'analytics'
,
$analytics
);
});
<
div
class
=
"finances-display"
>
{{
$analytics
->
getBalance
()
}}
/
{{
$analytics
->
getBudget
()
}}
</
div
>
@
inject
(
'analytics'
,
'App\Services\Analytics'
)
<
div
class
=
"finances-display"
>
{{
$analytics
->
getBalance
()
}}
/
{{
$analytics
->
getBudget
()
}}
</
div
>
// AppServiceProvider
public
function
boot
()
{
Blade
::
directive
(
'ifGuest'
,
function
()
{
return
"<?php if (auth()->guest()): ?>"
;
});
}
Blade
::
directive
(
'ifGuest'
,
function
()
{
// Antipattern! Do not copy.
$ifGuest
=
auth
()
->
guest
();
return
"<?php if (
{
$ifGuest
}
): ?>"
;
});
// Binding
Blade
::
directive
(
'newlinesToBr'
,
function
(
$expression
)
{
return
"<?php echo nl2br(
{
$expression
}
); ?>"
;
});
// In use
<
p
>@
newlinesToBr
(
$message
->
body
)
</
p
>
@
if
(
app
(
'context'
)
->
isPublic
())
&
copy
;
Copyright
MyApp
LLC
@
else
&
copy
;
Copyright
{{
app
(
'context'
)
->
client
->
name
}}
@
endif
// Binding
Blade
::
directive
(
'ifPublic'
,
function
()
{
return
"<?php if (app('context')->isPublic()): ?>"
;
});
// In use
@
ifPublic
&
copy
;
Copyright
MyApp
LLC
@
else
&
copy
;
Copyright
{{
app
(
'context'
)
->
client
->
name
}}
@
endif
// EventsTest.php
public
function
test_list_page_shows_all_events
()
{
$event1
=
factory
(
Event
::
class
)
->
create
();
$event2
=
factory
(
Event
::
class
)
->
create
();
$this
->
visit
(
'events'
)
->
see
(
$event1
->
title
)
->
see
(
$event2
->
title
);
}
// EventsTest.php
public
function
test_list_page_shows_all_events
()
{
$event1
=
factory
(
Event
::
class
)
->
create
();
$event2
=
factory
(
Event
::
class
)
->
create
();
$this
->
visit
(
'events'
);
$this
->
assertViewHas
(
'events'
,
Event
::
all
());
$this
->
assertViewHasAll
([
'events'
=>
Event
::
all
(),
'title'
=>
'Events Page'
]);
$this
->
assertViewMissing
(
'dogs'
);
}
// EventsTest.php
public
function
test_list_page_shows_all_events
()
{
$event1
=
factory
(
Event
::
class
)
->
create
();
$this
->
visit
(
'events/'
.
$event1
->
id
);
$this
->
assertViewHas
(
'event'
,
function
(
$event
)
use
(
$event1
)
{
return
$event
->
id
===
$event1
->
id
;
});
}
var
gulp
=
require
(
'gulp'
),
sass
=
require
(
'gulp-ruby-sass'
),
autoprefixer
=
require
(
'gulp-autoprefixer'
),
rename
=
require
(
'gulp-rename'
),
notify
=
require
(
'gulp-notify'
),
livereload
=
require
(
'gulp-livereload'
),
lr
=
require
(
'tiny-lr'
),
server
=
lr
();
gulp
.
task
(
'sass'
,
function
()
{
return
gulp
.
src
(
'resources/assets/sass/app.scss'
)
.
pipe
(
sass
({
style
:
'compressed'
,
sourcemap
:
true
}))
.
pipe
(
autoprefixer
(
'last 2 version'
,
'ie 9'
,
'ios 6'
))
.
pipe
(
gulp
.
dest
(
'public/css'
))
.
pipe
(
rename
({
suffix
:
'.min'
}))
.
pipe
(
livereload
(
server
))
.
pipe
(
notify
({
title
:
"Karani"
,
message
:
"Styles task complete."
}));
});
var
elixir
=
require
(
'laravel-elixir'
);
elixir
(
function
(
mix
)
{
mix
.
sass
(
'app.scss'
);
});
const
elixir
=
require
(
'laravel-elixir'
);
elixir
(
mix
=>
{
mix
.
sass
(
'app.scss'
)
});
$
gulp --production
const
elixir
=
require
(
'laravel-elixir'
);
elixir
(
mix
=>
{
mix
.
sass
([
'app.scss'
,
'public.scss'
]);
});
const
elixir
=
require
(
'laravel-elixir'
);
elixir
.
config
.
sourcemaps
=
false
;
elixir
(
mix
=>
{
mix
.
sass
(
'app.scss'
);
});
const
elixir
=
require
(
'laravel-elixir'
);
elixir
(
mix
=>
{
// Combines all files from resources/assets/css and subfolders
mix
.
styles
();
// Combines files from resources/assets/css
mix
.
styles
([
'normalize.css'
,
'app.css'
]);
// Combines all styles from other directory
mix
.
stylesIn
(
'resources/some/other/css/directory'
);
// Combines given styles from resources/assets/css
// and outputs to a custom directory
mix
.
styles
([
'normalize.css'
,
'app.css'
],
'public/other/css/output.css'
);
// Combines given styles from custom directory
// and outputs to a custom directory
mix
.
styles
([
'normalize.css'
,
'app.css'
],
'public/other/css/output.css'
,
'resources/some/other/css/directory'
);
});
const
elixir
=
require
(
'laravel-elixir'
);
elixir
(
mix
=>
{
// Combines files from resources/assets/js
mix
.
scripts
([
'jquery.js'
,
'app.js'
]);
// Combines all scripts from other directory
mix
.
scriptsIn
(
'resources/some/other/js/directory'
);
// Combines given scripts from resources/assets/js
// and outputs to a custom directory
mix
.
scripts
([
'jquery.js'
,
'app.js'
],
'public/other/js/output.js'
);
// Combines given scripts from custom directory
// and outputs to a custom directory
mix
.
scripts
([
'jquery.js'
,
'app.js'
],
'public/other/js/output.js'
,
'resources/some/other/js/directory'
);
});
elixir
(
function
(
mix
)
{
mix
.
webpack
(
'app.js'
);
// or
mix
.
rollup
(
'app.js'
);
});
const
elixir
=
require
(
'laravel-elixir'
);
elixir
(
mix
=>
{
mix
.
version
(
'public/css/all.css'
);
});
<
link
rel
=
"stylesheet"
href
=
"{{ elixir("
css
/
all
.
css
") }}"
>
// will output something like:
<
link
rel
=
"stylesheet"
href
=
"/build/css/all-84fa1258.css"
>
// Define the task
gulp
.
task
(
"log"
,
function
()
{
var
message
=
"Something happened"
;
gulp
.
src
(
""
).
pipe
(
shell
(
'echo "'
+
message
+
'" >> file.log'
));
});
elixir
(
mix
=>
{
// Use the task in Elixir
mix
.
task
(
'log'
);
// Bind the task to run every time certain files are changed
mix
.
task
(
'log'
,
'resources/somefiles/to/watch/**/*'
)
});
// Either in gulpfile.js, or in an external file and required in gulpfile.js
var
gulp
=
require
(
"gulp"
),
shell
=
require
(
"gulp-shell"
),
elixir
=
require
(
"laravel-elixir"
);
elixir
.
extend
(
"log"
,
function
(
message
)
{
new
Task
(
'log'
,
function
()
{
return
gulp
.
src
(
''
).
pipe
(
shell
(
'echo "'
+
message
+
'" >> file.log'
));
})
.
watch
(
'./resources/some/files/**/*'
);
});
// PostsController
public
function
index
()
{
return
view
(
'posts.index'
,
[
'posts'
=>
DB
::
table
(
'posts'
)
->
paginate
(
20
)]);
}
// posts/index.blade.php
<
table
>
@
foreach
(
$posts
as
$post
)
<
tr
><
td
>
{{
$post
->
title
}}
</
td
></
tr
>
@
endforeach
</
table
>
{{
$posts
->
links
()
}}
// By defaut, $posts->links() will output something like this:
<
ul
class
=
"pagination"
>
<
li
class
=
"disabled"
><
span
>&
laquo
;
</
span
></
li
>
<
li
class
=
"active"
><
span
>
1
</
span
></
li
>
<
li
><
a
href
=
"http://myapp.com/posts?page=2"
>
2
</
a
></
li
>
<
li
><
a
href
=
"http://myapp.com/posts?page=3"
>
3
</
a
></
li
>
<
li
><
a
href
=
"http://myapp.com/posts?page=2"
rel
=
"next"
>&
raquo
;
</
a
></
li
>
</
ul
>
use
Illuminate\Http\Request
;
use
Illuminate\Pagination\Paginator
;
Route
::
get
(
'people'
,
function
(
Request
$request
)
{
$people
=
[
...
];
// huge list of people
$perPage
=
15
;
$offsetPages
=
$request
->
input
(
'page'
,
1
)
-
1
;
// The Paginator will not slice your array for you
$people
=
array_slice
(
$people
,
$offsetPages
*
$perPage
,
$perPage
);
return
new
Paginator
(
$people
,
$perPage
);
});
$messages
=
[
'errors'
=>
[
'Something went wrong with edit 1!'
],
'messages'
=>
[
'Edit 2 was successful.'
]
];
$messagebag
=
new
\Illuminate\Support\MessageBag
(
$messages
);
// Check for errors; if there are any, decorate and echo
if
(
$messagebag
->
has
(
'errors'
))
{
echo
'<ul id="errors">'
;
foreach
(
$messagebag
->
get
(
'errors'
,
'<li><b>:message</b></li>'
)
as
$error
)
{
echo
$error
;
}
echo
'</ul>'
;
}
// partials/errors.blade.php
@
if
(
$errors
->
any
())
<
div
class
=
"alert alert-danger"
>
<
ul
>
@
foreach
(
$errors
as
$error
)
<
li
>
{{
$error
}}
</
li
>
@
endforeach
</
ul
>
</
div
>
@
endif
e
starts_with
, ends_with
, str_contains
str_is
str_slug
str_plural
(word
, num
), str_singular
// Normal PHP <?php echo trans('navigation.back'); ?> // Blade {{ trans('navigation.back') }} // Blade directive @lang('navigation.back')
// resources/lang/es/navigation.php
return
[
'back'
=>
'Volver al panel'
];
// routes/web.php
Route
::
get
(
'/es/contacts/show/:id'
,
function
()
{
// Setting it manually, for this example, instead of in a service provider
App
::
setLocale
(
'es'
);
return
view
(
'contacts.show'
);
});
// resources/views/contacts/show.blade.php
<
a
href
=
"/contacts"
>
{{
trans
(
'navigation.back'
)
}}
</
a
>
// resources/lang/en/navigation.php
return
[
'back'
=>
'Back to :section dashboard'
];
// resources/views/contacts/show.blade.php
{{
trans
(
'navigation.back'
,
[
'section'
=>
'contacts'
])
}}
// resources/lang/en/messages.php
return
[
'task-deletion'
=>
'You have deleted a task|You have successfully deleted tasks'
];
// resources/views/dashboard.blade.php
@
if
(
$numTasksDeleted
>
0
)
{{
trans_choice
(
'messages.task-deletion'
,
$numTasksDeleted
)
}}
@
endif
// resources/lang/es/messages.php
return
[
'task-deletion'
=>
"{0} You didn't manage to delete any tasks.|"
.
"[1,4] You deleted a few tasks.|"
.
"[5,Inf] You deleted a whole ton of tasks."
];
public
function
test_missing_email_field_errors
()
{
$this
->
post
(
'person/create'
,
[
'name'
=>
'Japheth'
]);
$this
->
assertSessionHasErrors
([
'email'
]);
}
Route
::
post
(
'form'
,
function
(
Illuminate\Http\Request
$request
)
{
// $request->etc()
});
<!-- GET route form view at /get-route -->
<form
method=
"post"
action=
"/post-route?utm=12345"
>
{{ csrf_field() }}<input
type=
"text"
name=
"firstName"
>
<input
type=
"submit"
>
</form>
Route
::
post
(
'/post-route'
,
function
(
Request
$request
)
{
var_dump
(
$request
->
all
());
});
// Outputs:
/**
* [
* '_token' => 'CSRF token here',
* 'firstName' => 'value',
* 'utm' => 12345
* ]
*/
Route
::
post
(
'/post-route'
,
function
(
Request
$request
)
{
var_dump
(
$request
->
except
(
'_token'
));
});
// Outputs:
/**
* [
* 'firstName' => 'value',
* 'utm' => 12345
* ]
*/
Route
::
post
(
'/post-route'
,
function
(
Request
$request
)
{
var_dump
(
$request
->
only
([
'firstName'
,
'utm'
]));
});
// Outputs:
/**
* [
* 'firstName' => 'value',
* 'utm' => 12345
* ]
*/
// POST route at /post-route
if
(
$request
->
has
(
'utm'
))
{
// Do some analytics work
}
Route
::
post
(
'/post-route'
,
function
(
Request
$request
)
{
$userName
=
$request
->
input
(
'name'
,
'(anonymous)'
);
});
<!-- GET route form view at /get-route -->
<form
method=
"post"
action=
"/post-route"
>
{{ csrf_field() }}<input
type=
"text"
name=
"employees[0][firstName]"
>
<input
type=
"text"
name=
"employees[0][lastName]"
>
<input
type=
"text"
name=
"employees[1][firstName]"
>
<input
type=
"text"
name=
"employees[1][lastName]"
>
<input
type=
"submit"
>
</form>
// POST route at /post-route
Route
::
post
(
'/post-route'
,
function
(
Request
$request
)
{
$employeeZeroFirstName
=
$request
->
input
(
'employees.0.firstName'
);
$allLastNames
=
$request
->
input
(
'employees.*.lastName'
);
$employeeOne
=
$request
->
input
(
'employees.1'
);
});
// If forms filled out as "Jim" "Smith" "Bob" "Jones":
// $employeeZeroFirstName = 'Jim';
// $allLastNames = ['Smith', 'Jones'];
// $employeeOne = ['firstName' => 'Bob', 'lastName' => 'Jones']
POST
/post-route
HTTP
/
1.1
Content-Type
:
application/json
{
"firstName"
:
"Joe"
,
"lastName"
:
"Schmoe"
,
"spouse"
:
{
"firstName"
:
"Jill"
,
"lastName"
:
"Schmoe"
}
}
// post-route
Route
::
post
(
'post-route'
,
function
(
Request
$request
)
{
$firstName
=
$request
->
input
(
'firstName'
);
$spouseFirstname
=
$request
->
input
(
'spouse.firstName'
);
});
// routes/web.php
Route
::
get
(
'users/{id}'
,
function
(
$id
)
{
// If the user visits myapp.com/users/15/, $id will equal 15
});
<form
method=
"post"
enctype=
"multipart/form-data"
>
{{ csrf_field() }}<input
type=
"text"
name=
"name"
>
<input
type=
"file"
name=
"profile_picture"
>
<input
type=
"submit"
>
</form>
Route
::
post
(
'form'
,
function
(
Request
$request
)
{
var_dump
(
$request
->
all
());
});
// Output:
// [
// "_token" => "token here"
// "name" => "asdf"
// "profile_picture" => UploadedFile {}
// ]
Route
::
post
(
'form'
,
function
(
Request
$request
)
{
if
(
$request
->
hasFile
(
'profile_picture'
))
{
var_dump
(
$request
->
file
(
'profile_picture'
));
}
});
// Output:
// UploadedFile (details)
if
(
$request
->
hasFile
(
'profile_picture'
))
{
$path
=
$request
->
profile_picture
->
store
(
'profiles'
,
's3'
);
auth
()
->
user
()
->
profile_picture
=
$path
;
auth
()
->
user
()
->
save
();
}
<form
method=
"post"
enctype=
"multipart/form-data"
>
// routes/web.php
Route
::
get
(
'recipes/create'
,
'RecipesController@create'
);
Route
::
post
(
'recipes'
,
'RecipesController@store'
);
// app/Http/Controllers/RecipesController.php
<?
php
namespace
App\Http\Controllers
;
use
Illuminate\Http\Request
;
class
RecipesController
extends
Controller
{
public
function
create
()
{
return
view
(
'recipes.create'
);
}
public
function
store
(
Request
$request
)
{
$this
->
validate
(
$request
,
[
'title'
=>
'required|unique:recipes|max:125'
,
'body'
=>
'required'
]);
// Recipe is valid; proceed to save it
}
}
Route
::
get
(
'recipes/create'
,
function
()
{
return
view
(
'recipes.create'
);
});
Route
::
post
(
'recipes'
,
function
(
Illuminate\Http\Request
$request
)
{
$validator
=
Validator
::
make
(
$request
->
all
(),
[
'title'
=>
'required|unique:recipes|max:125'
,
'body'
=>
'required'
]);
if
(
$validator
->
fails
())
{
return
redirect
(
'recipes/create'
)
->
withErrors
(
$validator
)
->
withInput
();
}
// Recipe is valid; proceed to save it
});
@if ($errors->any())<ul
id=
"errors"
>
@foreach ($errors->all() as $error)<li>
{{ $error }}</li>
@endforeach</ul>
@endif
php artisan make:request CreateCommentRequest
<?
php
namespace
App\Http\Requests
;
use
App\BlogPost
;
use
App\Http\Requests\Request
;
class
CreateCommentRequest
extends
Request
{
public
function
rules
()
{
return
[
'body'
=>
'required|max:1000'
];
}
public
function
authorize
()
{
$blogPostId
=
$this
->
route
(
'blogPost'
);
return
auth
()
->
check
()
&&
BlogPost
::
where
(
'id'
,
$blogPostId
)
->
where
(
'user_id'
,
auth
()
->
user
()
->
id
)
->
exists
();
}
}
Route
::
post
(
'comments'
,
function
(
App\Http\Requests\CreateCommentRequest
$request
)
{
// Store comment
});
Route
::
post
(
'posts'
,
function
(
Request
$request
)
{
$newPost
=
Post
::
create
(
$request
->
all
());
});
<?
php
namespace
App
;
use
Illuminate\Database\Eloquent\Model
;
class
Post
extends
Model
{
// Disable mass assignment on the author_id field
protected
$guarded
=
[
'author_id'
];
}
Route
::
post
(
'posts'
,
function
(
Request
$request
)
{
$newPost
=
Post
::
create
(
$request
->
only
([
'title'
,
'body'
]));
});
public
function
test_input_missing_a_title_is_rejected
()
{
$this
->
post
(
'posts'
,
[
'body'
=>
'This is the body of my post'
]);
$this
->
assertRedirectedTo
(
'posts/create'
);
$this
->
assertSessionHasErrors
();
$this
->
assertHasOldInput
();
}
public
function
test_valid_input_should_create_a_post_in_the_database
()
{
$this
->
post
(
'posts'
,
[
'title'
=>
'Post Title'
,
'body'
=>
'This is the body'
]);
$this
->
seeInDatabase
([
'title'
=>
'Post Title'
]);
}
php artisan make:controller PostsController
app
auth
cache
config
db
event
key
make
migrate
notifications
queue
route
schedule
* * * * * php /home/myapp.com/artisan schedule:run >> /dev/null 2>&
1
session
storage
vendor
view
php artisan make:console WelcomeNewUsers --command=
email:newusers
<?
php
namespace
App\Console\Commands
;
use
Illuminate\Console\Command
;
class
WelcomeNewUsers
extends
Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected
$signature
=
'email:newusers'
;
/**
* The console command description.
*
* @var string
*/
protected
$description
=
'Command description'
;
/**
* Create a new command instance.
*
* @return void
*/
public
function
__construct
()
{
parent
::
__construct
();
}
/**
* Execute the console command.
*
* @return mixed
*/
public
function
handle
()
{
//
}
}
class
Kernel
extends
ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected
$commands
=
[
\App\Console\Commands\WelcomeNewUsers
::
class
,
];
// routes/console.php
Artisan
::
command
(
'password:reset {userId} {--sendEmail}'
,
function
(
$userId
,
$sendEmail
)
{
// do something...
}
);
...
class
WelcomeNewUsers
extends
Command
{
public
function
handle
()
{
User
::
signedUpThisWeek
()
->
each
(
function
(
$user
)
{
::
send
(
'emails.welcome'
,
[
'name'
=>
$user
->
name
],
function
(
$m
)
use
(
$user
)
{
$m
->
to
(
$user
->
)
->
subject
(
'Welcome!'
);
}
);
});
}
...
class
WelcomeNewUsers
extends
Command
{
public
function
__construct
(
UserMailer
$userMailer
)
{
parent
::
__construct
();
$this
->
userMailer
=
$userMailer
}
public
function
handle
()
{
$this
->
userMailer
->
welcomeNewUsers
();
}
protected
$signature
=
'password:reset {userId} {--sendEmail}'
;
password:reset {userId}
password:reset {userId?}
password:reset {userId=1}
password:reset {userId} {--sendEmail}
password:reset {userId} {--password=}
password:reset {userId} {--queue=default}
password:reset {userIds*} password:reset {--ids=*}
// Argument php artisan password:reset 1 2 3 // Option php artisan password:reset --ids=1 --ids=2 --ids=3
protected
$signature
=
'password:reset
{userId : The ID of the user}
{--sendEmail : Whether to send user an email}'
;
// with definition "password:reset {userId}":
php
artisan
password
:
reset
5
// $this->argument() returns this array
[
"command"
:
"password:reset"
,
"userId': "
5
",
]
//
$this->argument
('userId') returns this string
"
5
"
// with definition "password:reset {--userId=}":
php
artisan
password
:
reset
--
userId
=
5
// $this->option() returns this array
[
"userId"
=>
"5"
"help"
=>
false
"quiet"
=>
false
"verbose"
=>
false
"version"
=>
false
"ansi"
=>
false
"no-ansi"
=>
false
"no-interaction"
=>
false
"env"
=>
null
]
// $this->option('userId') returns this string
"5"
public
function
handle
()
{
// All arguments, including the command name
$arguments
=
$this
->
argument
();
// Just the 'userId' argument
$userid
=
$this
->
argument
(
'userId'
);
// All options, including some defaults like 'no-interaction' and 'env'
$options
=
$this
->
option
();
// Just the 'sendEmail' option
$sendEmail
=
$this
->
option
(
'sendEmail'
);
}
ask()
=
$this
->
ask
(
'What is your email address?'
);
secret()
$password
=
$this
->
secret
(
'What is the DB password?'
);
confirm()
if
(
$this
->
confirm
(
'Do you want to truncate the tables?'
))
{
//
}
anticipate()
$album
=
$this
->
anticipate
(
'What is the best album ever?'
,
[
"The Joshua Tree"
,
"Pet Sounds"
,
"What's Going On"
]);
choice()
$winner
=
$this
->
choice
(
'Who is the best football team?'
,
[
'Gators'
,
'Wolverines'
],
0
);
$winner
=
$this
->
choice
(
'Who is the best football team?'
,
[
'gators'
=>
'Gators'
,
'wolverines'
=>
'Wolverines'
],
'gators'
);
$this
->
info
(
'Your command has run successfully.'
);
$headers
=
[
'Name'
,
'Email'
];
$data
=
[
[
'Dhriti'
,
'dhriti@amrit.com'
],
[
'Moses'
,
'moses@gutierez.com'
]
];
// Or, you could get similar data from the database:
// $data = App\User::all(['name', 'email'])->toArray();
$this
->
table
(
$headers
,
$data
);
+---------+--------------------+ | Name | Email | +---------+--------------------+ | Dhriti | dhriti@amrit.com | | Moses | moses@gutierez.com | +---------+--------------------+
$totalUnits
=
10
;
$this
->
output
->
progressStart
(
$totalUnits
);
for
(
$i
=
0
;
$i
<
$totalUnits
;
$i
++
)
{
sleep
(
1
);
$this
->
output
->
progressAdvance
();
}
$this
->
output
->
progressFinish
();
Route
::
get
(
'test-artisan'
,
function
()
{
$exitCode
=
Artisan
::
call
(
'password:reset'
,
[
'userId'
=>
15
,
'--sendEmail'
=>
true
]);
});
public
function
handle
()
{
$this
->
callSilent
(
'password:reset'
,
[
'userId'
=>
15
]);
}
php artisan tinker
>>> $user = new App\User; => App\User: {} >>> $user->email = 'matt@mattstauffer.co'; => "matt@mattstauffer.co" >>> $user->password = bcrypt('superSecret'); => "$2y$10$TWPGBC7e8d1bvJ1q5kv.VDUGfYDnE9gANl4mleuB3htIY2dxcQfQ5" >>> $user->save(); => true
public
function
test_empty_log_command_empties_logs_table
()
{
DB
::
table
(
'logs'
)
->
insert
([
'message'
=>
'Did something'
]);
Artisan
::
call
(
'logs:empty'
);
$this
->
assertCount
(
0
,
DB
::
table
(
'logs'
)
->
get
());
}
use
Illuminate\Contracts\Console\Kernel
;
...
class
NightlyCleanup
extends
Job
{
...
public
function
handle
(
Kernel
$kernel
)
{
// ... do other stuff
$kernel
->
call
(
'logs:empty'
);
}
'connections'
=>
[
'sqlite'
=>
[
'driver'
=>
'sqlite'
,
'database'
=>
database_path
(
'database.sqlite'
),
'prefix'
=>
''
,
],
'mysql'
=>
[
'driver'
=>
'mysql'
,
'host'
=>
env
(
'DB_HOST'
,
'localhost'
),
'database'
=>
env
(
'DB_DATABASE'
,
'forge'
),
'username'
=>
env
(
'DB_USERNAME'
,
'forge'
),
'password'
=>
env
(
'DB_PASSWORD'
,
''
),
'charset'
=>
'utf8'
,
'collation'
=>
'utf8_unicode_ci'
,
'prefix'
=>
''
,
'strict'
=>
false
,
'engine'
=>
null
,
],
'pgsql'
=>
[
'driver'
=>
'pgsql'
,
'host'
=>
env
(
'DB_HOST'
,
'localhost'
),
'database'
=>
env
(
'DB_DATABASE'
,
'forge'
),
'username'
=>
env
(
'DB_USERNAME'
,
'forge'
),
'password'
=>
env
(
'DB_PASSWORD'
,
''
),
'charset'
=>
'utf8'
,
'prefix'
=>
''
,
'schema'
=>
'public'
,
],
'sqlsrv'
=>
[
'driver'
=>
'sqlsrv'
,
'host'
=>
env
(
'DB_HOST'
,
'localhost'
),
'database'
=>
env
(
'DB_DATABASE'
,
'forge'
),
'username'
=>
env
(
'DB_USERNAME'
,
'forge'
),
'password'
=>
env
(
'DB_PASSWORD'
,
''
),
'charset'
=>
'utf8'
,
'prefix'
=>
''
,
],
]
$users
=
DB
::
connection
(
'secondary'
)
->
select
(
'select * from users'
);
<?
php
use
Illuminate\Database\Schema\Blueprint
;
use
Illuminate\Database\Migrations\Migration
;
class
CreateUsersTable
extends
Migration
{
/**
* Run the migrations.
*
* @return void
*/
public
function
up
()
{
Schema
::
create
(
'users'
,
function
(
Blueprint
$table
)
{
$table
->
increments
(
'id'
);
$table
->
string
(
'name'
);
$table
->
string
(
'email'
)
->
unique
();
$table
->
string
(
'password'
,
60
);
$table
->
rememberToken
();
$table
->
timestamps
();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public
function
down
()
{
Schema
::
drop
(
'users'
);
}
}
php
artisan
make
:
migration
create_users_table
php
artisan
make
:
migration
add_votes_to_users_table
--
table
=
users
php
artisan
make
:
migration
create_users_table
--
create
=
users
Schema
::
create
(
'tablename'
,
function
(
Blueprint
$table
)
{
// Create columns here
});
Schema
::
create
(
'users'
,
function
(
Blueprint
$table
)
{
$table
->
string
(
'name'
);
});
integer(colName)
, tinyInteger(colName)
, smallInteger(colName)
, medium
Integer(colName)
, bigInteger(colName)
string(colName, OPTIONAL length)
binary(colName)
boolean(colName)
char(colName, length)
datetime(colName)
decimal(colName, precision, scale)
double(colName, total digits, digits after decimal)
enum(colName, [choiceOne, choiceTwo])
float(colName)
json(colName)
and jsonb(colName)
text(colName)
, mediumText(colName)
, longText(colName)
time(colName)
timestamp(colName)
uuid(colName)
Schema
::
drop
(
'contacts'
);
Schema
::
table
(
'users'
,
function
(
$table
)
{
$table
->
string
(
'name'
,
100
)
->
change
();
});
Schema
::
table
(
'contacts'
,
function
(
$table
)
{
$table
->
string
(
'deleted_at'
)
->
nullable
()
->
change
();
});
Schema
::
table
(
'contacts'
,
function
(
$table
)
{
$table
->
renameColumn
(
'promoted'
,
'is_promoted'
);
});
Schema
::
table
(
'contacts'
,
function
(
$table
)
{
$table
->
dropColumn
(
'votes'
);
});
public
function
up
()
{
Schema
::
table
(
'contacts'
,
function
(
Blueprint
$table
)
{
$table
->
dropColumn
(
'is_promoted'
);
});
Schema
::
table
(
'contacts'
,
function
(
Blueprint
$table
)
{
$table
->
dropColumn
(
'alternate_email'
);
});
}
// after columns are created...
$table
->
primary
(
'primary_id'
);
// Primary key; unnecessary if used increments()
$table
->
primary
([
'first_name'
,
'last_name'
]);
// Composite keys
$table
->
unique
(
'email'
);
// Unique index
$table
->
unique
(
'email'
,
'optional_custom_index_name'
);
// Unique index
$table
->
index
(
'amount'
);
// Basic index
$table
->
index
(
'amount'
,
'optional_custom_index_name'
);
// Basic index
$table
->
dropPrimary
(
'contacts_id_primary'
);
$table
->
dropUnique
(
'contacts_email_unique'
);
$table
->
dropIndex
(
'optional_custom_index_name'
);
// If you pass an array of column names to dropIndex, it will
// guess the index names for you based on the generation rules
$table
->
dropIndex
([
'email'
,
'amount'
]);
$table
->
foreign
(
'user_id'
)
->
references
(
'id'
)
->
on
(
'users'
);
$table
->
foreign
(
'user_id'
)
->
references
(
'id'
)
->
on
(
'users'
)
->
onDelete
(
'cascade'
);
$table
->
dropForeign
(
'contacts_user_id_foreign'
);
$table
->
dropForeign
([
'user_id'
]);
php artisan migrate
php artisan migrate --seed
php
artisan
migrate
--
seed
php
artisan
migrate
:
refresh
--
seed
php
artisan
db
:
seed
php
artisan
db
:
seed
--
class
=
VotesTableSeeder
php
artisan
make
:
seeder
ContactsTableSeeder
// database/seeds/DatabaseSeeder.php
...
public
function
run
()
{
$this
->
call
(
ContactsTableSeeder
::
class
);
}
<?
php
use
Illuminate\Database\Seeder
;
use
Illuminate\Database\Eloquent\Model
;
class
ContactsTableSeeder
extends
Seeder
{
public
function
run
()
{
DB
::
table
(
'contacts'
)
->
insert
([
'name'
=>
'Lupita Smith'
'email'
=>
'lupita@gmail.com'
,
]);
}
}
$factory
->
define
(
User
::
class
,
function
(
Faker\Generator
$faker
)
{
return
[
'name'
=>
$faker
->
name
,
];
});
$factory
->
define
(
'users'
,
function
(
Faker\Generator
$faker
)
{
return
[
'name'
=>
$faker
->
name
,
];
});
$factory
->
define
(
Contact
::
class
,
function
(
Faker\Generator
$faker
)
{
return
[
'name'
=>
'Lupita Smith'
,
'email'
=>
'lupita@gmail.com'
,
];
});
// Create one
$contact
=
factory
(
Contact
::
class
)
->
create
();
// Create many
factory
(
Contact
::
class
,
20
)
->
create
();
$factory
->
define
(
Contact
::
class
,
function
(
Faker\Generator
$faker
)
{
return
[
'name'
=>
$faker
->
name
,
'email'
=>
$faker
->
,
];
});
factory
(
Post
::
class
)
->
create
([
'title'
=>
'My greatest post ever'
]);
factory
(
User
::
class
,
20
)
->
create
()
->
each
(
function
(
$u
)
use
(
$post
)
{
$post
->
comments
()
->
save
(
factory
(
Comment
::
class
)
->
make
([
'user_id'
=>
$u
->
id
]));
});
$factory
->
define
(
Contact
::
class
,
function
(
Faker\Generator
$faker
)
{
return
[
'name'
=>
$faker
->
name
,
'email'
=>
$faker
->
,
];
});
$factory
->
define
(
Contact
::
class
,
function
(
Faker\Generator
$faker
)
{
return
[
'name'
=>
$faker
->
name
,
'email'
=>
$faker
->
,
];
});
$factory
->
defineAs
(
Contact
::
class
,
'vip'
,
function
(
Faker\Generator
$faker
)
{
return
[
'name'
=>
$faker
->
name
,
'email'
=>
$faker
->
,
'vip'
=>
true
,
];
});
$factory
->
define
(
Contact
::
class
,
function
(
Faker\Generator
$faker
)
{
return
[
'name'
=>
$faker
->
name
,
'email'
=>
$faker
->
,
];
});
$factory
->
defineAs
(
Contact
::
class
,
'vip'
,
function
(
Faker\Generator
$faker
)
use
(
$factory
)
{
$contact
=
$factory
->
raw
(
Contact
::
class
);
return
array_merge
(
$contact
,
[
'vip'
=>
true
]);
});
$vip
=
factory
(
Contact
::
class
,
'vip'
)
->
create
();
$vips
=
factory
(
Contact
::
class
,
'vip'
,
3
)
->
create
();
// basic statement
DB
::
statement
(
'drop table users'
)
// raw select, and parameter binding
DB
::
select
(
'select * from contacts where validated = ?'
,
[
true
]);
// select using the fluent builder
$users
=
DB
::
table
(
'users'
)
->
get
();
// joins and other complex calls
DB
::
table
(
'users'
)
->
join
(
'contacts'
,
function
(
$join
)
{
$join
->
on
(
'users.id'
,
'='
,
'contacts.user_id'
)
->
where
(
'contacts.type'
,
'donor'
);
})
->
get
();
$users
=
DB
::
select
(
'select * from users'
);
$usersOfType
=
DB
::
select
(
'select * from users where type = ?'
,
[
$type
]
);
$usersOfType
=
DB
::
select
(
'select * from users where type = :type'
,
[
'type'
=>
$userType
]
);
DB
::
insert
(
'insert into contacts (name, email) values (?, ?)'
,
[
'sally'
,
'sally@me.com'
]
);
$countUpdated
=
DB
::
update
(
'update contacts set status = ? where id = ?'
,
[
'donor'
,
$id
]
);
$countDeleted
=
DB
::
delete
(
'delete from contacts where archived = ?'
,
[
true
]
);
$usersOfType
=
DB
::
table
(
'users'
)
->
where
(
'type'
,
$type
)
->
get
();
select()
$emails
=
DB
::
table
(
'contacts'
)
->
select
(
'email'
,
'email2 as second_email'
)
->
get
();
// Or
$emails
=
DB
::
table
(
'contacts'
)
->
select
(
'email'
)
->
addSelect
(
'email2 as second_email'
)
->
get
();
where()
$newContacts
=
DB
::
table
(
'contact'
)
->
where
(
'created_at'
,
'>'
,
Carbon
::
now
()
->
subDay
())
->
get
();
$newVips
=
DB
::
table
(
'contacts'
)
->
where
(
'vip'
,
true
)
->
where
(
'created_at'
,
'>'
,
Carbon
::
now
()
->
subDay
());
// Or
$newVips
=
DB
::
table
(
'contacts'
)
->
where
([
[
'vip'
,
true
],
[
'created_at'
,
'>'
,
Carbon
::
now
()
->
subDay
()],
]);
orWhere()
$priorityContacts
=
DB
::
table
(
'contacts'
)
->
where
(
'vip'
,
true
)
->
orWhere
(
'created_at'
,
'>'
,
Carbon
::
now
()
->
subDay
())
->
get
();
$contacts
=
DB
::
table
(
'contacts'
)
->
where
(
'vip'
,
true
)
->
orWhere
(
function
(
$query
)
{
$query
->
where
(
'created_at'
,
'>'
,
Carbon
::
now
()
->
subDay
())
->
where
(
'trial'
,
false
);
})
->
get
();
$canEdit
=
DB
::
table
(
'users'
)
->
where
(
'admin'
,
true
)
->
orWhere
(
'plan'
,
'premium'
)
->
where
(
'is_plan_owner'
,
true
)
->
get
();
SELECT
*
FROM
users
WHERE
admin
=
1
OR
plan
=
'premium'
AND
is_plan_owner
=
1
;
$canEdit
=
DB
::
table
(
'users'
)
->
where
(
'admin'
,
true
)
->
orWhere
(
function
(
$query
)
{
$query
->
where
(
'plan'
,
'premium'
)
->
where
(
'is_plan_owner'
,
true
);
})
->
get
();
SELECT
*
FROM
users
WHERE
admin
=
1
OR
(
plan
=
'premium'
AND
is_plan_owner
=
1
);
whereBetween(colName, [low, high])
$mediumDrinks
=
DB
::
table
(
'drinks'
)
->
whereBetween
(
'size'
,
[
6
,
12
])
->
get
();
whereIn(colName, [1, 2, 3])
$closeBy
=
DB
::
table
(
'contacts'
)
->
whereIn
(
'state'
,
[
'FL'
,
'GA'
,
'AL'
])
->
get
();
whereNull(colName)
and whereNotNull(colName)
whereRaw()
whereExists()
$commenters
=
DB
::
table
(
'users'
)
->
whereExists
(
function
(
$query
)
{
$query
->
select
(
'id'
)
->
from
(
'comments'
)
->
whereRaw
(
'comments.user_id = users.id'
);
})
->
get
();
distinct()
orderBy(colName, direction)
$contacts
=
DB
::
table
(
'contacts'
)
->
orderBy
(
'last_name'
,
'asc'
)
->
get
();
groupBy()
and having()
or havingRaw()
$populousCities
=
DB
::
table
(
'contacts'
)
->
groupBy
(
'city'
)
->
havingRaw
(
'count(contact_id) > 30'
)
->
get
();
skip()
and take()
$page4
=
DB
::
table
(
'contacts'
)
->
skip
(
30
)
->
take
(
10
)
->
get
();
latest(colName)
and oldest(colName)
inRandomOrder()
get()
$contacts
=
DB
::
table
(
'contacts'
)
->
get
();
$vipContacts
=
DB
::
table
(
'contacts'
)
->
where
(
'vip'
,
true
)
->
get
();
first()
and firstOrFail()
$newestContact
=
DB
::
table
(
'contacts'
)
->
orderBy
(
'created_at'
,
'desc'
)
->
first
();
first()
find(id)
and findOrFail(id)
$contactFive
=
DB
::
table
(
'contacts'
)
->
find
(
5
);
value()
$newestContactEmail
=
DB
::
table
(
'contacts'
)
->
orderBy
(
'created_at'
,
'desc'
)
->
value
(
'email'
);
count()
$countVips
=
DB
::
table
(
'contacts'
)
->
where
(
'vip'
,
true
)
->
count
();
min()
and max()
$highestCost
=
DB
::
table
(
'orders'
)
->
max
(
'amount'
);
sum()
and avg()
$averageCost
=
DB
::
table
(
'orders'
)
->
where
(
'status'
,
'completed'
)
->
avg
(
'amount'
);
$contacts
=
DB
::
table
(
'contacts'
)
->
select
(
DB
::
raw
(
'*, (score * 100) AS integer_score'
))
->
get
();
$users
=
DB
::
table
(
'users'
)
->
join
(
'contacts'
,
'users.id'
,
'='
,
'contacts.user_id'
)
->
select
(
'users.*'
,
'contacts.name'
,
'contacts.status'
)
->
get
();
DB
::
table
(
'users'
)
->
join
(
'contacts'
,
function
(
$join
)
{
$join
->
on
(
'users.id'
,
'='
,
'contacts.user_id'
)
->
orOn
(
'users.id'
,
'='
,
'contacts.proxy_user_id'
);
})
->
get
();
$first
=
DB
::
table
(
'contacts'
)
->
whereNull
(
'first_name'
);
$contacts
=
DB
::
table
(
'contacts'
)
->
whereNull
(
'last_name'
)
->
union
(
$first
)
->
get
();
$id
=
DB
::
table
(
'contacts'
)
->
insertGetId
([
'name'
=>
'Abe Thomas'
,
'email'
=>
'athomas1987@gmail.com'
,
]);
DB
::
table
(
'contacts'
)
->
insert
([
[
'name'
=>
'Tamika Johnson'
,
'email'
=>
'tamikaj@gmail.com'
],
[
'name'
=>
'Jim Patterson'
,
'email'
=>
'james.patterson@hotmail.com'
],
]);
DB
::
table
(
'contacts'
)
->
where
(
'points'
,
'>'
,
100
)
->
update
([
'status'
=>
'vip'
]);
DB
::
table
(
'contacts'
)
->
increment
(
'tokens'
,
5
);
DB
::
table
(
'contacts'
)
->
decrement
(
'tokens'
);
DB
::
table
(
'users'
)
->
where
(
'last_login'
,
'<'
,
Carbon
::
now
()
->
subYear
())
->
delete
();
DB
::
table
(
'contacts'
)
->
truncate
();
// Select all records where the "isAdmin" property of the "options"
// JSON column is set to true
DB
::
table
(
'users'
)
->
where
(
'options->isAdmin'
,
true
)
->
get
();
// Update all records, setting the "verified" property
// of the "options" JSON column to true
DB
::
table
(
'users'
)
->
update
([
'options->isVerified'
,
true
]);
DB
::
transaction
(
function
()
use
(
$userId
,
$numVotes
)
{
// Possibly failing DB query
DB
::
table
(
'users'
)
->
where
(
'id'
,
$userId
)
->
update
([
'votes'
=>
$numVotes
]);
// Caching query that we don't want to run if the above query fails
DB
::
table
(
'votes'
)
->
where
(
'user_id'
,
$userId
)
->
delete
();
});
<?
php
use
Illuminate\Database\Eloquent\Model
;
class
Contact
extends
Model
{}
public
function
save
(
Request
$request
)
{
// Create and save a new contact from user input
$contact
=
new
Contact
();
$contact
->
first_name
=
$request
->
input
(
'first_name'
);
$contact
->
last_name
=
$request
->
input
(
'last_name'
);
$contact
->
=
$request
->
input
(
'email'
);
$contact
->
save
();
return
redirect
(
'contacts'
);
}
public
function
show
(
$contactId
)
{
// Return a JSON representation of a Contact based on a URL segment;
// if the contact doesn't exist, throw an exception
return
Contact
::
findOrFail
(
$contactId
);
}
public
function
vips
()
{
// Unnecessarily complex example, but still possible with basic Eloquent
// class; adds a "formalName" property to every VIP entry
return
Contact
::
where
(
'vip'
,
true
)
->
get
()
->
map
(
function
(
$contact
)
{
$contact
->
formalName
=
"The exalted
{
$contact
->
first_name
}
of the
{
$contact
->
last_name
}
s"
;
return
$contact
;
});
}
php artisan make:model Contact
<?
php
namespace
App
;
use
Illuminate\Database\Eloquent\Model
;
class
Contact
extends
Model
{
//
}
php
artisan
make
:
model
Contact
--
migration
protected
$table
=
'contacts_secondary'
;
protected
$primaryKey
=
'contact_id'
;
public
$incrementing
=
false
;
public
$timestamps
=
false
;
protected
$dateFormat
=
'U'
;
$allContacts
=
Contact
::
all
();
$vipContacts
=
Contact
::
where
(
'vip'
,
true
)
->
get
();
$newestContacts
=
Contact
::
orderBy
(
'created_at'
,
'desc'
)
->
take
(
10
)
->
get
();
// ContactController
public
function
show
(
$contactId
)
{
return
view
(
'contacts.show'
)
->
with
(
'contact'
,
Contact
::
findOrFail
(
$contactId
));
}
$vipContacts
=
Contact
::
where
(
'vip'
,
true
)
->
get
();
$contacts
=
Contact
::
all
();
Contact
::
chunk
(
100
,
function
(
$contacts
)
{
foreach
(
$contacts
as
$contact
)
{
// Do something with $contact
}
});
$countVips
=
Contact
::
where
(
'vip'
,
true
)
->
count
();
$sumVotes
=
Contact
::
sum
(
'votes'
);
$averageSkill
=
User
::
avg
(
'skill_level'
);
$contact
=
new
Contact
;
$contact
->
name
=
'Ken Hirata'
;
$contact
->
=
'ken@hirata.com'
;
$contact
->
save
();
// or
$contact
=
new
Contact
([
'name'
=>
'Ken Hirata'
,
'email'
=>
'ken@hirata.com'
]);
$contact
->
save
();
$contact
=
Contact
::
create
([
'name'
=>
'Keahi Hale'
,
'email'
=>
'halek481@yahoo.com'
]);
$contact
=
Contact
::
find
(
1
);
$contact
->
=
'natalie@parkfamily.com'
;
$contact
->
save
();
Contact
::
where
(
'created_at'
,
'<'
,
Carbon
::
now
()
->
subYear
())
->
update
([
'longevity'
=>
'ancient'
]);
// or
$contact
=
Contact
::
find
(
1
);
$contact
->
update
([
'longevity'
=>
'ancient'
]);
// ContactController
public
function
update
(
Contact
$contact
,
Request
$request
)
{
$contact
->
update
(
$request
->
all
());
}
class
Contact
{
protected
$fillable
=
[
'name'
,
'email'
];
// or
protected
$guarded
=
[
'id'
,
'created_at'
,
'updated_at'
,
'owner_id'
];
}
Contact
::
create
(
$request
->
only
(
'name'
,
'email'
));
$contact
=
Contact
::
firstOrCreate
([
'email'
=>
'luis.ramos@myacme.com'
]);
$contact
=
Contact
::
find
(
5
);
$contact
->
delete
();
Contact
::
destroy
(
1
);
// or
Contact
::
destroy
([
1
,
5
,
7
]);
Contact
::
where
(
'updated_at'
,
'<'
,
Carbon
::
now
()
->
subYear
())
->
delete
();
Schema
::
table
(
'contacts'
,
function
(
Blueprint
$table
)
{
$table
->
softDeletes
();
});
<?
php
use
Illuminate\Database\Eloquent\Model
;
use
Illuminate\Database\Eloquent\SoftDeletes
;
class
Contact
extends
Model
{
use
SoftDeletes
;
// use the trait
protected
$dates
=
[
'deleted_at'
];
// mark this column as a date
}
$allHistoricContacts
=
Contact
::
withTrashed
()
->
get
();
if
(
$contact
->
trashed
())
{
// do something
}
$deletedContacts
=
Contact
::
onlyTrashed
()
->
get
();
$contact
->
restore
();
// or
Contact
::
onlyTrashed
()
->
where
(
'vip'
,
true
)
->
restore
();
$contact
->
forceDelete
();
// or
Contact
::
onlyTrashed
()
->
forceDelete
();
$activeVips
=
Contact
::
where
(
'vip'
,
true
)
->
where
(
'trial'
,
false
)
->
get
();
$activeVips
=
Contact
::
activeVips
()
->
get
();
class
Contact
{
public
function
scopeActiveVips
(
$query
)
{
return
$query
->
where
(
'vip'
,
true
)
->
where
(
'trial'
,
false
);
}
class
Contact
{
public
function
scopeStatus
(
$query
,
$status
)
{
return
$query
->
where
(
'status'
,
$status
);
}
$friends
=
Contact
::
status
(
'friend'
)
->
get
();
...
class
Contact
extends
Model
{
protected
static
function
boot
()
{
parent
::
boot
();
static
::
addGlobalScope
(
'active'
,
function
(
Builder
$builder
)
{
$builder
->
where
(
'active'
,
true
);
});
}
<?
php
namespace
App\Scopes
;
use
Illuminate\Database\Eloquent\Scope
;
use
Illuminate\Database\Eloquent\Model
;
use
Illuminate\Database\Eloquent\Builder
;
class
ActiveScope
implements
Scope
{
public
function
apply
(
Builder
$builder
,
Model
$model
)
{
return
$builder
->
where
(
'active'
,
true
);
}
}
<?
php
use
App\Scopes\ActiveScope
;
use
Illuminate\Database\Eloquent\Model
;
class
Contact
extends
Model
{
protected
static
function
boot
()
{
parent
::
boot
();
static
::
addGlobalScope
(
new
ActiveScope
);
}
}
$allContacts
=
Contact
::
withoutGlobalScope
(
'active'
)
->
get
();
Contact
::
withoutGlobalScope
(
ActiveScope
::
class
)
->
get
();
Contact
::
withoutGlobalScopes
([
ActiveScope
::
class
,
VipScope
::
class
])
->
get
();
Contact
::
withoutGlobalScopes
()
->
get
();
// Model definition:
class
Contact
extends
Model
{
public
function
getNameAttribute
(
$value
)
{
return
$value
?:
'(No name provided)'
;
}
}
// Accessor usage:
$name
=
$contact
->
name
;
// Model definition:
class
Contact
extends
Model
{
public
function
getFullNameAttribute
()
{
return
$this
->
first_name
.
' '
.
$this
->
last_name
;
}
}
// Accessor usage:
$fullName
=
$contact
->
full_name
;
// Defining the mutator
class
Order
extends
Model
{
public
function
setAmountAttribute
(
$value
)
{
$this
->
attributes
[
'amount'
]
=
$value
>
0
?
$value
:
0
;
}
}
// Using the mutator
$order
->
amount
=
'15'
;
// Defining the mutator
class
Order
extends
Model
{
public
function
setWorkgroupNameAttribute
(
$workgroupName
)
{
$this
->
attributes
[
'email'
]
=
"
{
$workgroupName
}
@ourcompany.com"
;
}
}
// Using the mutator
$order
->
workgroup_name
=
'jstott'
;
Type | Description |
---|---|
class
Contact
{
protected
$casts
=
[
'vip'
=>
'boolean'
,
'children_names'
=>
'array'
,
'birthday'
=>
'date'
,
];
}
class
Contact
{
protected
$dates
=
[
'met_at'
];
}
$collection
=
collect
([
1
,
2
,
3
]);
$odds
=
$collection
->
reject
(
function
(
$item
)
{
return
$item
%
2
===
0
;
});
$multiplied
=
$collection
->
map
(
function
(
$item
)
{
return
$item
*
10
;
});
$sum
=
$collection
->
filter
(
function
(
$item
)
{
return
$item
%
2
==
0
;
})
->
map
(
function
(
$item
)
{
return
$item
*
10
;
})
->
sum
();
...
class
OrderCollection
extends
Collection
{
public
function
sumBillableAmount
()
{
return
$this
->
reduce
(
function
(
$carry
,
$order
)
{
return
$carry
+
(
$order
->
billable
?
$order
->
amount
:
0
);
},
0
);
}
}
...
class
Order
extends
Model
{
public
function
newCollection
(
array
$models
=
[])
{
return
new
OrderCollection
(
$models
);
}
$orders
=
Order
::
all
();
$billableAmount
=
$orders
->
sumBillableAmount
();
$contactArray
=
Contact
::
first
()
->
toArray
();
$contactJson
=
Contact
::
first
()
->
toJson
();
$contactsArray
=
Contact
::
all
()
->
toArray
();
$contactsJson
=
Contact
::
all
()
->
toJson
();
// routes/web.php
Route
::
get
(
'api/contacts'
,
function
()
{
return
Contact
::
all
();
});
Route
::
get
(
'api/contacts/{id}'
,
function
(
$id
)
{
return
Contact
::
findOrFail
(
$id
);
});
class
Contact
extends
Model
{
public
$hidden
=
[
'password'
,
'remember_token'
];
class
Contact
extends
Model
{
public
$visible
=
[
'name'
,
'email'
,
'status'
];
class
User
extends
Model
{
public
$hidden
=
[
'contacts'
];
public
function
contacts
()
{
return
$this
->
hasMany
(
Contact
::
class
);
}
$user
=
User
::
with
(
'contacts'
)
->
first
();
$array
=
$user
->
makeVisible
(
'remember_token'
)
->
toArray
();
class
Contact
extends
Model
{
protected
$appends
=
[
'full_name'
];
public
function
getFullNameAttribute
()
{
return
"
{
$this
->
first_name
}
{
$this
->
last_name
}
"
;
class
Contact
extends
Model
{
public
function
phoneNumber
()
{
return
$this
->
hasOne
(
PhoneNumber
::
class
);
}
return
$this
->
hasOne
(
PhoneNumber
::
class
,
'owner_id'
);
$contact
=
Contact
::
first
();
$contactPhone
=
$contact
->
phoneNumber
;
class
PhoneNumber
extends
Model
{
public
function
contact
()
{
return
$this
->
belongsTo
(
Contact
::
class
);
}
$contact
=
$phoneNumber
->
contact
;
$contact
=
Contact
::
first
();
$phoneNumber
=
new
PhoneNumber
;
$phoneNumber
->
number
=
8008675309
;
$contact
->
phoneNumbers
()
->
save
(
$phoneNumber
);
// or
$contact
->
phoneNumbers
()
->
saveMany
([
PhoneNumber
::
find
(
1
),
PhoneNumber
::
find
(
2
),
]);
// or
$contact
->
phoneNumbers
()
->
create
([
'number'
=>
'+13138675309'
]);
class
User
extends
Model
{
public
function
contacts
()
{
return
$this
->
hasMany
(
Contact
::
class
);
}
$user
=
User
::
first
();
$usersContacts
=
$user
->
contacts
;
$donors
=
$user
->
contacts
->
filter
(
function
(
$contact
)
{
return
$contact
->
status
==
'donor'
;
});
$lifetimeValue
=
$contact
->
orders
->
reduce
(
function
(
$carry
,
$order
)
{
return
$carry
+
$order
->
amount
;
},
0
);
class
Contact
extends
Model
{
public
function
user
()
{
return
$this
->
belongsTo
(
User
::
class
);
}
$userName
=
$contact
->
user
->
name
;
$contact
=
Contact
::
first
();
$contact
->
user
()
->
associate
(
User
::
first
());
$contact
->
save
();
// and later
$contact
->
user
()
->
dissociate
();
$contact
->
save
();
$donors
=
$user
->
contacts
()
->
where
(
'status'
,
'donor'
)
->
get
();
$postsWithComments
=
Post
::
has
(
'comments'
)
->
get
();
$postsWithManyComments
=
Post
::
has
(
'comments'
,
'>='
,
5
)
->
get
();
$usersWithPhoneBooks
=
User
::
has
(
'contacts.phoneNumbers'
)
->
get
();
// Gets all contacts with a phone number containing the string "867-5309"
$jennyIGotYourNumber
=
Contact
::
whereHas
(
'phoneNumbers'
,
function
(
$query
)
{
$query
->
where
(
'number'
,
'like'
,
'%867-5309%'
);
});
class
User
extends
Model
{
public
function
phoneNumbers
()
{
return
$this
->
hasManyThrough
(
PhoneNumber
::
class
,
Contact
::
class
);
}
class
User
extends
Model
{
public
function
contacts
()
{
return
$this
->
belongsToMany
(
Contact
::
class
);
}
}
class
Contact
extends
Model
{
public
function
users
()
{
return
$this
->
belongsToMany
(
User
::
class
);
}
}
$user
=
User
::
first
();
$user
->
contacts
->
each
(
function
(
$contact
)
{
// do something
});
$contact
=
Contact
::
first
();
$contact
->
users
->
each
(
function
(
$user
)
{
// do something
});
$donors
=
$user
->
contacts
()
->
where
(
'status'
,
'donor'
)
->
get
();
public
function
contacts
()
{
return
$this
->
belongsToMany
(
Contact
::
class
)
->
withTimestamps
()
->
withPivot
(
'status'
,
'preferred_greeting'
);
}
$user
=
User
::
first
();
$user
->
contacts
->
each
(
function
(
$contact
)
{
echo
sprintf
(
'Contact associated with this user at: %s'
,
$contact
->
pivot
->
created_at
);
});
class
Star
extends
Model
{
public
function
starrable
()
{
return
$this
->
morphsTo
();
}
}
class
Contact
extends
Model
{
public
function
stars
()
{
return
$this
->
morphMany
(
Star
::
class
,
'starrable'
);
}
}
class
Event
extends
Model
{
public
function
stars
()
{
return
$this
->
morphMany
(
Star
::
class
,
'starrable'
);
}
}
$contact
=
Contact
::
first
();
$contact
->
stars
()
->
create
();
$contact
=
Contact
::
first
();
$contact
->
stars
->
each
(
function
(
$star
)
{
// Do stuff
});
$stars
=
Star
::
all
();
$stars
->
each
(
function
(
$star
)
{
var_dump
(
$star
->
starrable
);
// An instance of Contact or Event
});
class
Star
extends
Model
{
public
function
starrable
()
{
return
$this
->
morphsTo
;
}
public
function
user
()
{
return
$this
->
belongsTo
(
User
::
class
);
}
}
class
User
extends
Model
{
public
function
stars
()
{
return
$this
->
hasMany
(
Star
::
class
);
}
}
$user
=
User
::
first
();
$event
=
Event
::
first
();
$event
->
stars
()
->
create
([
'user_id'
=>
$user
->
id
]);
class
Contact
extends
Model
{
public
function
tags
()
{
return
$this
->
morphToMany
(
Tag
::
class
,
'taggable'
);
}
}
class
Event
extends
Model
{
public
function
tags
()
{
return
$this
->
morphToMany
(
Tag
::
class
,
'taggable'
);
}
}
class
Tag
extends
Model
{
public
function
contacts
()
{
return
$this
->
morphedByMany
(
Contact
::
class
,
'taggable'
);
}
public
function
events
()
{
return
$this
->
morphedByMany
(
Event
::
class
,
'taggable'
);
}
}
$tag
=
Tag
::
firstOrCreate
([
'name'
=>
'likes-cheese'
]);
$contact
=
Contact
::
first
();
$contact
->
tags
()
->
attach
(
$tag
->
id
);
$contact
=
Contact
::
first
();
$contact
->
tags
->
each
(
function
(
$tag
)
{
// Do stuff
});
$tag
=
Tag
::
first
();
$tag
->
contacts
->
each
(
function
(
$contact
)
{
// Do stuff
});
class
PhoneNumber
extends
Model
{
protected
$touches
=
[
'contact'
];
public
function
contact
()
{
return
$this
->
belongsTo
(
Contact
::
class
);
}
$contacts
=
Contact
::
all
();
foreach
(
$contacts
as
$contact
)
{
foreach
(
$contact
->
phone_numbers
as
$phone_number
)
{
echo
$phone_number
->
number
;
}
}
$contacts
=
Contact
::
with
(
'phoneNumbers'
)
->
get
();
$contacts
=
Contact
::
with
(
'phoneNumbers'
,
'addresses'
)
->
get
();
$authors
=
Author
::
with
(
'posts.comments'
)
->
get
();
$contacts
=
Contact
::
with
([
'addresses'
=>
function
(
$query
)
{
$query
->
where
(
'mailable'
,
true
);
}])
->
get
();
$contacts
=
Contact
::
all
();
if
(
$showPhoneNumbers
)
{
$contacts
->
load
(
'phoneNumbers'
);
}
$authors
=
Author
::
withCount
(
'posts'
)
->
get
();
// adds a "posts_count" integer to each Author with a count of that
// Author's number of related posts
class
AppServiceProvider
extends
ServiceProvider
{
public
function
boot
()
{
$thirdPartyService
=
new
SomeThirdPartyService
;
Contact
::
creating
(
function
(
$contact
)
use
(
$thirdPartyService
)
{
try
{
$thirdPartyService
->
addContact
(
$contact
);
}
catch
(
Exception
$e
)
{
Log
::
error
(
'Failed adding contact to ThirdPartyService; cancelled.'
);
return
false
;
}
});
}
public
function
test_active_page_shows_active_and_not_inactive_contacts
()
{
$activeContact
=
factory
(
Contact
::
class
,
'active'
)
->
create
();
$inactiveContact
=
factory
(
Contact
::
class
,
'inactive'
)
->
create
();
$this
->
visit
(
'active-contacts'
)
->
see
(
$activeContact
->
name
)
->
dontSee
(
$inactiveContact
->
name
);
}
public
function
test_contact_creation_works
()
{
$this
->
post
(
'contacts'
,
[
'email'
=>
'jim@bo.com'
]);
$this
->
seeInDatabase
(
'contacts'
,
[
'email'
=>
'jim@bo.com'
]);
}
public
function
test_full_name_accessor_works
()
{
$contact
=
factory
(
Contact
::
class
)
->
make
([
'first_name'
=>
'Alphonse'
,
'last_name'
=>
'Cumberbund'
]);
$this
->
assertEquals
(
'Alphonse Cumberbund'
,
$contact
->
fullName
);
}
public
function
test_vip_scope_filters_out_non_vips
()
{
$vip
=
factory
(
Contact
::
class
,
'vip'
)
->
create
();
$nonVip
=
factory
(
Contact
::
class
)
->
create
();
$vips
=
Contact
::
vips
()
->
get
();
$this
->
assertTrue
(
$vips
->
contains
([
'id'
=>
$vip
->
id
]));
$this
->
assertFalse
(
$vips
->
contains
([
'id'
=>
$nonVip
->
id
]));
}
Schema
::
create
(
'users'
,
function
(
Blueprint
$table
)
{
$table
->
increments
(
'id'
);
$table
->
string
(
'name'
);
$table
->
string
(
'email'
)
->
unique
();
$table
->
string
(
'password'
);
$table
->
rememberToken
();
$table
->
timestamps
();
});
<?
php
// App\User
namespace
App
;
use
Illuminate\Notifications\Notifiable
;
use
Illuminate\Foundation\Auth\User
as
Authenticatable
;
class
User
extends
Authenticatable
{
use
Notifiable
;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected
$fillable
=
[
'name'
,
'email'
,
'password'
,
];
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected
$hidden
=
[
'password'
,
'remember_token'
,
];
}
<?
php
// Illuminate\Foundation\Auth\User
namespace
Illuminate\Foundation\Auth
;
use
Illuminate\Auth\Authenticatable
;
use
Illuminate\Database\Eloquent\Model
;
use
Illuminate\Auth\Passwords\CanResetPassword
;
use
Illuminate\Foundation\Auth\Access\Authorizable
;
use
Illuminate\Contracts\Auth\Authenticatable
as
AuthenticatableContract
;
use
Illuminate\Contracts\Auth\Access\Authorizable
as
AuthorizableContract
;
use
Illuminate\Contracts\Auth\CanResetPassword
as
CanResetPasswordContract
;
class
User
extends
Model
implements
AuthenticatableContract
,
AuthorizableContract
,
CanResetPasswordContract
{
use
Authenticatable
,
Authorizable
,
CanResetPassword
;
}
public
function
dashboard
()
{
if
(
auth
()
->
guest
())
{
return
redirect
(
'sign-up'
);
}
return
view
(
'dashboard'
)
->
with
(
'user'
,
auth
()
->
user
());
}
...
class
RegisterController
extends
Controller
{
use
RegistersUsers
;
protected
$redirectTo
=
'/home'
;
...
protected
function
validator
(
array
$data
)
{
return
Validator
::
make
(
$data
,
[
'name'
=>
'required|max:255'
,
'email'
=>
'required|email|max:255|unique:users'
,
'password'
=>
'required|min:6|confirmed'
,
]);
}
protected
function
create
(
array
$data
)
{
return
User
::
create
([
'name'
=>
$data
[
'name'
],
'email'
=>
$data
[
'email'
],
'password'
=>
bcrypt
(
$data
[
'password'
]),
]);
}
}
// routes/web.php
Auth
::
routes
();
// Authentication Routes
$this
->
get
(
'login'
,
'Auth\LoginController@showLoginForm'
);
$this
->
post
(
'login'
,
'Auth\LoginController@login'
);
$this
->
post
(
'logout'
,
'Auth\LoginController@logout'
);
// Registration Routes
$this
->
get
(
'register'
,
'Auth\RegisterController@showRegistrationForm'
);
$this
->
post
(
'register'
,
'Auth\RegisterController@register'
);
// Password Reset Routes
$this
->
get
(
'password/reset'
,
'Auth\ForgotPasswordController@showLinkRequestForm'
);
$this
->
post
(
'password/email'
,
'Auth\ForgotPasswordController@sendResetLinkEmail'
);
$this
->
get
(
'password/reset/{token}'
,
'Auth\ResetPasswordController@showResetForm'
);
$this
->
post
(
'password/reset'
,
'Auth\ResetPasswordController@reset'
);
app/Http/Controllers/HomeController.php resources/views/auth/login.blade.php resources/views/auth/register.blade.php resources/views/auth/passwords/email.blade.php resources/views/auth/passwords/reset.blade.php resources/views/layouts/app.blade.php resources/views/home.blade.php
laravel new MyApp cd MyApp php artisan make:auth php artisan migrate
if
(
auth
()
->
attempt
([
'email'
=>
request
()
->
input
(
'email'
),
'password'
=>
request
()
->
input
(
'password'
)
]))
{
// Handle the successful login
}
if
(
auth
()
->
attempt
([
'email'
=>
request
()
->
input
(
'email'
),
'password'
=>
request
()
->
input
(
'password'
)
]),
request
()
->
has
(
'remember'
))
{
// Handle the successful login
}
auth
()
->
loginUsingId
(
5
);
auth
()
->
login
(
$user
);
protected
$routeMiddleware
=
[
'auth'
=>
\Illuminate\Auth\Middleware\Authenticate
::
class
,
'auth.basic'
=>
\Illuminate\Auth\Middleware\AuthenticateWithBasicAuth
::
class
,
'bindings'
=>
\Illuminate\Routing\Middleware\SubstituteBindings
::
class
,
'can'
=>
\Illuminate\Auth\Middleware\Authorize
::
class
,
'guest'
=>
\App\Http\Middleware\RedirectIfAuthenticated
::
class
,
'throttle'
=>
\Illuminate\Routing\Middleware\ThrottleRequests
::
class
,
];
Route
::
group
([
'middleware'
=>
'auth'
],
function
()
{
Route
::
get
(
'account'
,
'AccountController@dashboard'
);
});
Route
::
get
(
'login'
,
'Auth\LoginController@getLogin'
)
->
middleware
(
'guest'
);
'defaults'
=>
[
'guard'
=>
'web'
,
// Change the default here
'passwords'
=>
'users'
,
],
$apiUser
=
auth
()
->
guard
(
'api'
)
->
user
();
'guards'
=>
[
'trainees'
=>
[
'driver'
=>
'session'
,
'provider'
=>
'trainees'
,
],
],
'providers'
=>
[
'users'
=>
[
'driver'
=>
'eloquent'
,
'model'
=>
App\User
::
class
,
],
'trainees'
=>
[
'driver'
=>
'eloquent'
,
'model'
=>
App\Trainee
::
class
,
],
],
Route
::
group
([
'middleware'
=>
'auth:trainees'
],
function
()
{
// Trainee-only routes here
});
auth
()
->
provider
(
'riak'
,
function
(
$app
,
array
$config
)
{
// Return an instance of Illuminate\Contracts\Auth\UserProvider...
return
new
RiakUserProvider
(
$app
[
'riak.connection'
]);
});
protected
$listen
=
[
'Illuminate\Auth\Events\Attempting'
=>
[],
'Illuminate\Auth\Events\Login'
=>
[],
'Illuminate\Auth\Events\Logout'
=>
[],
'Illuminate\Auth\Events\Lockout'
=>
[],
];
if
(
Gate
::
denies
(
'edit'
,
$contact
))
{
abort
(
403
);
}
if
(
!
Gate
::
check
(
'create'
,
Contact
::
class
))
{
abort
(
403
);
}
class
AuthServiceProvider
extends
ServiceProvider
{
public
function
boot
(
GateContract
$gate
)
{
$this
->
registerPolicies
(
$gate
);
$gate
->
define
(
'update-contact'
,
function
(
$user
,
$contact
)
{
return
$user
->
id
===
$contact
->
user_id
;
});
}
}
$gate
->
define
(
'update-contact'
,
'ContactACLChecker@updateContact'
);
if
(
Gate
::
allows
(
'update-contact'
,
$contact
))
{
// Update contact
}
// or...
if
(
Gate
::
denies
(
'update-contact'
,
$contact
))
{
abort
(
403
);
}
// Definition
$gate
->
define
(
'add-contact-to-group'
,
function
(
$user
,
$contact
,
$group
)
{
return
$user
->
id
===
$contact
->
user_id
&&
$user
->
id
===
$group
->
user_id
;
});
// Usage
if
(
Gate
::
denies
(
'add-contact-to-group'
,
[
$contact
,
$group
]))
{
abort
(
403
);
}
if
(
Gate
::
forUser
(
$user
)
->
denies
(
'create-contact'
))
{
abort
(
403
);
}
Route
::
get
(
'people/create'
,
function
()
{
// Create person...
})
->
middleware
(
'can:create-person'
);
Route
::
get
(
'people/{person}/edit'
,
function
()
{
// Create person...
})
->
middleware
(
'can:create,person'
);
// From this:
public
function
show
(
$contactId
)
{
$contact
=
Contact
::
findOrFail
(
$contactId
);
if
(
Gate
::
cannot
(
'update-contact'
,
$contact
))
{
abort
(
403
);
}
}
// To this:
public
function
show
(
$contactId
)
{
$contact
=
Contact
::
findOrFail
(
$contactId
);
$this
->
authorize
(
'update-contact'
,
$contact
);
}
$this
->
authorizeForUser
(
$user
,
'update-contact'
,
$contact
);
...
class
ContactsController
extends
Controller
{
public
function
__construct
()
{
// This call does everything you see in the methods below.
// If you put this here, you can remove all authorize
// calls in the individual resource methods here.
$this
->
authorizeResource
(
Contact
::
class
);
}
public
function
index
()
{
$this
->
authorize
(
'view'
,
Contact
::
class
);
}
public
function
create
()
{
$this
->
authorize
(
'create'
,
Contact
::
class
);
}
public
function
store
(
Request
$request
)
{
$this
->
authorize
(
'create'
,
Contact
::
class
);
}
public
function
show
(
Contact
$contact
)
{
$this
->
authorize
(
'view'
,
$contact
);
}
public
function
edit
(
Contact
$contact
)
{
$this
->
authorize
(
'update'
,
$contact
);
}
public
function
update
(
Request
$request
,
Contact
$contact
)
{
$this
->
authorize
(
'update'
,
$contact
);
}
public
function
destroy
(
Contact
$contact
)
{
$this
->
authorize
(
'delete'
,
$contact
);
}
}
$user
=
User
::
find
(
1
);
if
(
$user
->
can
(
'create-contact'
))
{
// do something
}
<nav>
<a
href=
"/"
>
Home</a>
@can('edit-contact', $contact)<a
href=
"{{ route('contacts.edit', [$contact->id]) }}"
>
Edit This Contact</a>
@endcan</nav>
<h1>
{{ $contact->name }}</h1>
@cannot('edit-contact', $contact) LOCKED @endcannot
$gate
->
before
(
function
(
$user
,
$ability
)
{
if
(
$user
->
isOwner
())
{
return
true
;
}
});
php artisan make:policy ContactPolicy
class
AuthServiceProvider
extends
ServiceProvider
{
protected
$policies
=
[
Contact
::
class
=>
ContactPolicy
::
class
,
]
<?
php
namespace
App\Policies
;
class
ContactPolicy
{
public
function
update
(
$user
,
$contact
)
{
return
$user
->
id
===
$contact
->
user_id
;
}
}
...
class
ContactPolicy
{
public
function
createAny
(
$user
)
{
return
$user
->
canCreateContacts
();
}
// Gate
if
(
Gate
::
denies
(
'update'
,
$contact
))
{
abort
(
403
);
}
// Gate if you don't have an explicit instance
if
(
!
Gate
::
check
(
'create'
,
Contact
::
class
))
{
abort
(
403
);
}
// User
if
(
$user
->
can
(
'update'
,
$contact
))
{
// Do stuff
}
// Blade
@
can
(
'update'
,
$contact
)
<!--
show
stuff
-->
@
endcan
if
(
policy
(
$contact
)
->
update
(
$user
,
$contact
))
{
// Do stuff
}
public
function
before
(
$user
,
$ability
)
{
if
(
$user
->
isAdmin
())
{
return
true
;
}
}
public
function
test_it_creates_a_new_contact
()
{
$user
=
factory
(
User
::
class
)
->
create
();
$this
->
be
(
$user
);
$this
->
post
(
'contacts'
,
[
'email'
=>
'my@email.com'
]);
$this
->
seeInDatabase
(
'contacts'
,
[
'email'
=>
'my@email.com'
,
'user_id'
=>
$user
->
id
,
]);
}
public
function
test_non_admins_cant_create_users
()
{
$user
=
factory
(
User
::
class
)
->
create
([
'admin'
=>
false
]);
$this
->
be
(
$user
);
$this
->
post
(
'users'
,
[
'email'
=>
'my@email.com'
]);
$this
->
dontSeeInDatabase
(
'users'
,
[
'email'
=>
'my@email.com'
]);
}
public
function
test_non_admins_cant_create_users
()
{
$user
=
factory
(
User
::
class
)
->
create
([
'admin'
=>
false
]);
$this
->
be
(
$user
);
$this
->
post
(
'users'
,
[
'email'
=>
'my@email.com'
]);
$this
->
assertResponseStatus
(
403
);
}
public
function
test_users_can_register
()
{
$this
->
post
(
'register'
,
[
'name'
=>
'Sal Leibowitz'
,
'email'
=>
'sal@leibs.net'
,
'password'
=>
'abcdefg123'
,
'password_confirmation'
=>
'abcdefg123'
,
]);
$this
->
followRedirects
()
->
assertResponseOk
();
$this
->
seeInDatabase
(
'users'
,
[
'name'
=>
'Sal Leibowitz'
,
'email'
=>
'sal@leibs.net'
,
]);
}
public
function
test_users_can_log_in
()
{
$user
=
factory
(
User
::
class
)
->
create
([
'password'
=>
bcrypt
(
'abcdefg123'
)
]);
$this
->
post
(
'login'
,
[
'email'
=>
$user
->
,
'password'
=>
'abcdefg123'
,
]);
$this
->
followRedirects
()
->
assertResponseOk
();
$this
->
assertTrue
(
auth
()
->
check
());
}
...
class
GitHubServiceProvider
extends
ServiceProvider
{
protected
$defer
=
true
;
public
function
provides
()
{
return
[
GitHubClient
::
class
];
}
$request
=
Illuminate\Http\Request
::
capture
();
...
use
Illuminate\Http\Request
;
class
PeopleController
extends
Controller
{
public
function
index
(
Request
$request
)
{
$allInput
=
$request
->
all
();
}
$request
=
request
();
$allInput
=
request
()
->
all
();
$request
=
app
(
Illuminate\Http\Request
::
class
);
$request
=
app
(
'request'
);
// form<form
method=
"POST"
action=
"/form"
>
{{ csrf_field() }}<input
name=
"name"
>
Name<br>
<input
type=
"submit"
>
</form>
// route receiving the form
Route
::
post
(
'form'
,
function
(
Request
$request
)
{
echo
'name is '
.
$request
->
input
(
'name'
);
echo
'all input is '
.
print_r
(
$request
->
all
());
echo
'user provided email address: '
.
$request
->
has
(
'email'
)
?
'true'
:
'false'
;
});
Route
::
get
(
'route'
,
function
()
{
return
new
Illuminate\Http\Response
(
'Hello!'
);
});
// Same, using global function:
Route
::
get
(
'route'
,
function
()
{
return
response
(
'Hello!'
);
});
Route
::
get
(
'route'
,
function
()
{
return
response
(
'Error!'
,
400
)
->
header
(
'X-Header-Name'
,
'header-value'
)
->
cookie
(
'cookie-name'
,
'cookie-value'
);
});
return
response
(
$content
)
->
cookie
(
'signup_dismissed'
,
true
);
Route
::
get
(
'/'
,
function
(
XmlGetterService
$xml
)
{
$data
=
$xml
->
get
();
return
response
()
->
view
(
'xml-structure'
,
$data
)
->
header
(
'Content-Type'
,
'text/xml'
);
});
public
function
export
()
{
return
response
()
->
download
(
'file.csv'
,
'export.csv'
,
[
'header'
=>
'value'
]);
}
public
function
otherExport
()
{
return
response
()
->
download
(
'file.pdf'
);
}
public
function
invoice
(
$id
)
{
return
response
()
->
file
(
"./invoices/
{
$id
}
.pdf"
,
[
'header'
=>
'value'
]);
}
public
function
contacts
()
{
return
response
()
->
json
(
Contact
::
all
());
}
public
function
jsonpContacts
(
Request
$request
)
{
return
response
()
->
json
(
Contact
::
all
())
->
setCallback
(
$request
->
input
(
'callback'
));
}
public
function
nonEloquentContacts
()
{
return
response
()
->
json
([
'Tom'
,
'Jerry'
]);
}
return
redirect
(
'account/payment'
);
return
redirect
()
->
to
(
'account/payment'
);
return
redirect
()
->
route
(
'account.payment'
);
return
redirect
()
->
action
(
'AccountController@showPayment'
);
// If named route or controller needs parameters:
return
redirect
()
->
route
(
'contacts.edit'
,
[
'id'
=>
15
]);
return
redirect
()
->
action
(
'ContactsController@edit'
,
[
'id'
=>
15
]);
public
function
store
()
{
// If validation fails...
return
back
()
->
withInput
();
}
Route
::
post
(
'contacts'
,
function
()
{
// store the contact...
return
redirect
(
'dashboard'
)
->
with
(
'message'
,
'Contact created!'
);
});
Route
::
get
(
'dashboard'
,
function
()
{
// Get the flashed data from session--usually handled in Blade template
echo
session
(
'message'
);
});
...
class
AppServiceProvider
{
public
function
boot
()
{
Response
::
macro
(
'myJson'
,
function
(
$content
)
{
return
response
(
json_encode
(
$content
))
->
headers
([
'Content-Type'
=>
'application/json'
]);
});
}
return
response
()
->
myJson
([
'name'
=>
'Sangeetha'
]);
php artisan make:middleware BanDeleteMethod
...
class
BanDeleteMethod
{
public
function
handle
(
$request
,
Closure
$next
)
{
return
$next
(
$request
);
}
}
...
class
BanDeleteMethod
{
public
function
handle
(
$request
,
Closure
$next
)
{
// At this point, $request is the raw request from the user.
// Let's do something with it, just for fun.
if
(
$request
->
ip
()
===
'192.168.1.1'
)
{
return
response
(
'BANNED IP ADDRESS!'
,
403
);
}
// Now we've decided to accept it. Let's pass it on to the next
// middleware in the stack. We pass it to $next(), and what is
// returned is the response after the $request has been passed
// down the stack of middleware to the application and the
// application's response has been passed back up the stack.
$response
=
$next
(
$request
);
// At this point, we can once again interact with the response
// just before it is returned to the user
$response
->
cookie
(
'visited-our-site'
,
true
);
// Finally, we can release this response to the end user
return
$response
;
}
}
...
class
BanDeleteMethod
{
public
function
handle
(
$request
,
Closure
$next
)
{
// Test for the DELETE method
if
(
$request
->
method
()
===
'DELETE'
)
{
return
response
(
"Get out of here with that delete method"
,
405
);
}
$response
=
$next
(
$request
);
// Assign cookie
$response
->
cookie
(
'visited-our-site'
,
true
);
// Return response
return
$response
;
}
}
// app/Http/Kernel.php
protected
$middleware
=
[
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode
::
class
,
\App\Http\Middleware\BanDeleteMethod
::
class
,
];
// app/Http/Kernel.php
protected
$routeMiddleware
=
[
'auth'
=>
\App\Http\Middleware\Authenticate
::
class
,
...
'nodelete'
=>
\App\Http\Middleware\BanDeleteMethod
::
class
,
];
// Doesn't make much sense for our current example...
Route
::
get
(
'contacts'
,
[
'middleware'
=>
'nodelete'
,
'uses'
=>
'ContactsController@index'
]);
// Makes more sense for our current example...
Route
::
group
([
'prefix'
=>
'api'
,
'middleware'
=>
'nodelete'
],
function
()
{
// All routes related to an API
});
Route
::
get
(
'/'
,
'HomeController@index'
)
->
middleware
(
'web'
);
// App\Providers\RouteServiceProvider
public
function
map
()
{
$this
->
mapApiRoutes
();
$this
->
mapWebRoutes
();
}
protected
function
mapApiRoutes
()
{
Route
::
group
([
'middleware'
=>
'api'
,
'namespace'
=>
$this
->
namespace
,
'prefix'
=>
'api'
,
],
function
(
$router
)
{
require
base_path
(
'routes/api.php'
);
});
}
protected
function
mapWebRoutes
()
{
Route
::
group
([
'middleware'
=>
'web'
,
'namespace'
=>
$this
->
namespace
,
],
function
(
$router
)
{
require
base_path
(
'routes/web.php'
);
});
}
Route
::
get
(
'company'
,
function
()
{
return
view
(
'company.admin'
);
})
->
middleware
(
'auth:owner'
);
public
function
handle
(
$request
,
$next
,
$role
)
{
if
(
auth
()
->
check
()
&&
auth
()
->
user
()
->
hasRole
(
$role
))
{
return
$next
(
$request
);
}
return
redirect
(
'login'
);
}
Route
::
get
(
'company'
,
function
()
{
return
view
(
'company.admin'
);
})
->
middleware
(
'auth:owner,view'
);
$request
=
new
Illuminate\Http\Request
(
$query
,
// GET array
$request
,
// POST array
$attributes
,
// "attributes" array; empty is fine
$cookies
,
// cookies array
$files
,
// files array
$server
,
// servers array
$content
// raw body data
);
$response
=
new
Illuminate\Http\Response
(
$content
,
// response content
$status
,
// HTTP status, default 200
$headers
// array headers array
);
<?
php
class
UserMailer
{
protected
$mailer
;
public
function
__construct
(
Mailer
$mailer
)
{
$this
->
mailer
=
$mailer
;
}
public
function
welcome
(
$user
)
{
return
$this
->
mailer
->
(
$user
->
,
'Welcome!'
);
}
}
$mailer
=
new
MailgunMailer
(
$mailgunKey
,
$mailgunSecret
,
$mailgunOptions
);
$userMailer
=
new
UserMailer
(
$mailer
);
$userMailer
->
welcome
(
$user
);
$mailer
=
new
MailgunMailer
(
$mailgunKey
,
$mailgunSecret
,
$mailgunOptions
);
$logger
=
new
Logger
(
$logPath
,
$minimumLogLevel
);
$slack
=
new
Slack
(
$slackKey
,
$slackSecret
,
$channelName
,
$channelIcon
);
$userMailer
=
new
UserMailer
(
$mailer
,
$logger
,
$slack
);
$userMailer
->
welcome
(
$user
);
$logger
=
app
(
Logger
::
class
);
class
Bar
{
public
function
__construct
()
{}
}
class
Baz
{
public
function
__construct
()
{}
}
class
Foo
{
public
function
__construct
(
Bar
$bar
,
Baz
$baz
)
{}
}
$foo
=
app
(
Foo
::
class
);
public
function
__construct
(
Logger
$logger
)
{}
// In service provider
public
function
register
()
{
$this
->
app
->
bind
(
Logger
::
class
,
function
(
$app
)
{
return
new
Logger
(
'\log\path\here'
,
'error'
);
});
}
$this
->
app
->
bind
(
UserMailer
::
class
,
function
(
$app
)
{
return
new
UserMailer
(
$app
->
make
(
Mailer
::
class
),
$app
->
make
(
Logger
::
class
),
$app
->
make
(
Slack
::
class
)
);
});
public
function
register
()
{
$this
->
app
->
singleton
(
Logger
::
class
,
function
()
{
return
new
Logger
(
'\log\path\here'
,
'error'
);
});
}
public
function
register
()
{
$logger
=
new
Logger
(
'\log\path\here'
,
'error'
);
$this
->
app
->
instance
(
Logger
::
class
,
$logger
);
}
$this
->
bind
(
Logger
::
class
,
FirstLogger
::
class
);
// or
$this
->
bind
(
'log'
,
FirstLogger
::
class
);
// or
$this
->
bind
(
FirstLogger
::
class
,
'log'
);
...
use
Interfaces\Mailer
;
class
UserMailer
{
protected
$mailer
;
public
function
__construct
(
Mailer
$mailer
)
{
$this
->
mailer
=
$mailer
;
}
}
// service provider
public
function
register
()
{
$this
->
app
->
bind
(
\Interfaces\Mailer
::
class
,
function
()
{
return
new
MailgunMailer
(
...
);
});
}
// In a service provider
public
function
register
()
{
$this
->
app
->
when
(
FileWrangler
::
class
)
->
needs
(
Interfaces\Logger
::
class
)
->
give
(
Loggers\Syslog
::
class
);
$this
->
app
->
when
(
Jobs\SendWelcomeEmail
::
class
)
->
needs
(
Interfaces\Logger
::
class
)
->
give
(
Loggers\PaperTrail
::
class
);
}
...
class
MyController
extends
Controller
{
protected
$logger
;
public
function
__construct
(
Logger
$logger
)
{
$this
->
logger
=
$logger
;
}
public
function
index
()
{
// Do something
$this
->
logger
->
error
(
'Something happened'
);
}
}
...
class
MyController
extends
Controller
{
// Method dependencies can come after or before route parameters
public
function
show
(
Logger
$logger
,
$id
)
{
// Do something
$logger
->
error
(
'Something happened'
);
}
}
class
Foo
{
public
function
bar
(
$parameter1
)
{}
}
$foo
=
new
Foo
;
// Calls the 'bar' method on $foo with a first parameter of "value"
app
()
->
call
(
$foo
,
'bar'
,
[
'parameter1'
=>
'value'
]);
Log
::
alert
(
'Something has gone wrong!'
);
$logger
=
app
(
'log'
);
$logger
->
alert
(
'Something has gone wrong!'
);
...
use
Illuminate\Support\Facades\Log
;
class
Controller
extends
Controller
{
public
function
index
()
{
// ...
Log
::
error
(
'Something went wrong!'
);
}
<?
php
namespace
Illuminate\Support\Facades
;
class
Log
extends
facade
{
protected
static
function
getFacadeAccessor
()
{
return
'log'
;
}
}
Log
::
error
(
'Help!'
);
// is the same as...
app
(
'log'
)
->
error
(
'Help!'
);
Facade | Class | Service Container Binding |
---|---|---|
public
function
test_it_does_something
()
{
app
()
->
bind
(
Interfaces\Logger
,
function
()
{
return
new
DevNullLogger
;
});
// do stuff
}
class
TestCase
extends
\Illuminate\Foundation\Testing\TestCase
{
public
function
setUp
()
{
parent
::
setUp
();
app
()
->
bind
(
'whatever'
,
'whatever else'
);
}
}
<?
php
use
Illuminate\Foundation\Testing\WithoutMiddleware
;
use
Illuminate\Foundation\Testing\DatabaseMigrations
;
use
Illuminate\Foundation\Testing\DatabaseTransactions
;
class
ExampleTest
extends
TestCase
{
/**
* A basic functional test example.
*
* @return void
*/
public
function
testBasicExample
()
{
$this
->
visit
(
'/'
)
->
see
(
'Laravel'
);
}
}
PHPUnit 5.5.2 by Sebastian Bergmann and contributors. . Time:139
ms, Memory: 12.00Mb OK(
1
test
,2
assertions)
public
function
testBasicExample
()
{
$this
->
visit
(
'/'
)
->
see
(
'Applesauce'
);
}
PHPUnit 5.5.2 by Sebastian Bergmann and contributors. F Time: 115 ms, Memory: 12.00Mb There was 1 failure: 1) ExampleTest::testBasicExample <source of page here> Failed asserting that the page contains the HTML [Applesauce]. Please check the content above. /path-to-your-app/vendor/.../Foundation/Testing/Constraints/PageConstraint.php:90 /path-to-your-app/vendor/.../Foundation/Testing/Concerns/InteractsWithPages.php:271 /path-to-your-app/vendor/.../Foundation/Testing/Concerns/InteractsWithPages.php:287 /path-to-your-app/tests/ExampleTest.php:21 FAILURES! Tests: 1, Assertions: 2, Failures: 1.
class
Naming
{
public
function
test_it_names_things_well
()
{
// Runs as "test it names things well"
}
public
function
testItNamesThingsWell
()
{
// Runs as "It names things well"
}
/** @test */
public
function
it_names_things_well
()
{
// Runs as "it names things well"
}
public
function
it_names_things_well
()
{
// Doesn't run
}
}
$this->visit($uri)
$this->call(
$method
, $uri
, $params = []
, $cookies = []
, $files = []
, $server = []
, $content = null)
$this->get($uri, $headers = [])
, ->post(
$uri, $data = []
, $headers = []
), ->put($uri, $data = []
, $headers = [])
, ->patch()
, and ->delete()
$this->json(
$method
, $uri
, $data = []
, $headers = [])
$this->followRedirects()
$this->assertPageLoaded()
$this->see()
and ->dontSee()
$this->seeLink()
and ->dontSeeLink()
$this->seeHeader()
$this->seeCookie()
$this->seeInField()
and ->dontSeeInField()
$this->seeIsChecked()
and ->dontSeeIsChecked()
$this->seeIsSelected()
and ->dontSeeIsSelected()
$this->seePageIs()
$this->seeInDatabase()
and ->dontSeeInDatabase()
public
function
test_database_has_user_after_registration
()
{
$this
->
visit
(
'register'
)
->
fillForm
([
'email'
=>
'matt@mattstauffer.co'
])
->
submitForm
();
$this
->
seeInDatabase
(
'emails'
,
[
'email'
=>
'matt@mattstauffer.co'
]);
}
$this->seeJson()
, ->dontSeeJson()
, ->seeJsonEquals()
public
function
test_api_returns_certain_json
()
{
$this
->
json
(
'get'
,
'users'
);
$this
->
seeJson
([
'username'
=>
'mattstauffer'
]);
}
$this->assertResponseOK()
and ->assertResponseStatus($status)
public
function
test_pages_load_the_way_we_want
()
{
$this
->
get
(
'people'
);
$this
->
assertResponseOK
();
$this
->
call
(
'post'
,
'owners'
);
$this
->
assertResponseStatus
(
405
);
// Method not allowed
}
$this->assertViewHas($key, $value = null)
, ->assertViewHasAll(array $bindings)
, ->assertViewMissing($key)
// Route
Route
::
get
(
'test'
,
function
()
{
return
view
(
'test'
)
->
with
(
'foo'
,
'bar'
);
});
// Test
public
function
test_view_gets_data
()
{
$this
->
get
(
'test'
);
$this
->
assertViewHas
(
'foo'
);
// true
$this
->
assertViewHas
(
'foo'
,
'bar'
);
// true
$this
->
assertViewHas
(
'foo'
,
'baz'
);
// false
}
// Route
Route
::
get
(
'test'
,
function
()
{
return
view
(
'test'
)
->
with
(
'foo'
,
'bar'
)
->
with
(
'baz'
,
'qux'
);
});
// Test
public
function
test_view_gets_data
()
{
$this
->
get
(
'test'
);
$this
->
assertViewHasAll
([
'foo'
=>
'bar'
,
'baz'
=>
'qux'
]);
// true
}
public
function
test_events_are_owned_by_user_1
()
{
$this
->
get
(
'events'
);
$this
->
assertViewHas
(
'events'
,
function
(
$events
)
{
return
$events
->
reject
(
function
(
$event
)
{
return
$event
->
user_id
===
1
;
})
->
isEmpty
();
});
}
$this->assertRedirectedTo()
, ->assertRedirectedToRoute()
, ->assertRedirectedToAction()
// Route
Route
::
get
(
'redirector'
,
function
()
{
return
redirect
(
'/'
);
});
Route
::
get
(
'/'
,
'HomeController@index'
)
->
name
(
'home'
);
// Test
public
function
test_redirector_works
()
{
$this
->
get
(
'redirector'
);
$this
->
assertRedirectedTo
(
'/'
);
$this
->
assertRedirectedToRoute
(
'home'
);
$this
->
assertRedirectedToAction
(
'HomeController@index'
);
}
$this->assertSessionHas($key, $value = '')
, ->assertSessionHasAll($bindings)
, ->assertSessionHasErrors($bindings = []
, $format = null)
, ->assertHasOldInput()
public
function
test_session_has_stuff
()
{
Session
::
put
(
'foo'
,
'bar'
);
Session
::
put
(
'baz'
,
'qux'
);
$this
->
assertSessionHas
(
'foo'
);
$this
->
assertSessionHas
(
'foo'
,
'bar'
);
$this
->
assertSessionHasAll
([
'foo'
=>
'bar'
,
'baz'
=>
'qux'
]);
}
public
function
test_posting_empty_errors_out
()
{
// assuming the "/form" route requires an email field, and we're
// posting an empty form to it to trigger the error
$this
->
post
(
'form'
,
[]);
$this
->
assertSessionHasErrors
();
$this
->
assertSessionHasErrors
([
'email'
=>
'The email field is required.'
]);
$this
->
assertSessionHasErrors
(
[
'email'
=>
'<p>The email field is required.</p>'
],
'<p>:message</p>'
);
}
$this->click($name)
$this->type($text, $element)
$this->check($element)
$this->uncheck($element)
$this->select($option, $element)
$this->attach($filePath, $element)
$this->press($buttonText)
$this->submitForm($buttonText
, $inputs = []
, $uploads = [])
$this->fillForm($buttonText, $inputs = [])
$this->clearInputs()
$this->expectsEvents($eventClassName)
public
function
test_usersubscribed_event_fires_when_subscribing
()
{
$this
->
expectsEvents
(
App\Events\UserSubscribed
::
class
);
$this
->
visit
(
'subscribe'
)
->
type
(
'me@me.com'
,
'email'
)
->
press
(
'Subscribe'
);
}
$this->withoutEvents()
$this->expectsJobs()
public
function
test_number_of_subscriptions_crunches_reports
()
{
$this
->
expectsJobs
(
App\Jobs\CrunchReports
::
class
);
$this
->
visit
(
'subscribe'
)
->
type
(
'me@me.com'
,
'email'
)
->
press
(
'Subscribe'
);
}
$this->session(['key' => 'value'])
$this->flushSession()
$this->be($authenticatable)
public
function
test_members_cant_see_admin_dashboard
()
{
$member
=
factory
(
\App\User
::
class
,
'member'
)
->
create
();
$this
->
be
(
$member
);
$this
->
get
(
'admin-dashboard'
);
$this
->
assertResponseStatus
(
403
);
}
public
function
test_admins_can_see_admin_dashboard
()
{
$admin
=
factory
(
\App\User
::
class
,
'admin'
)
->
create
();
$this
->
be
(
$admin
);
$this
->
get
(
'admin-dashboard'
);
$this
->
assertResponseOK
();
}
$this->artisan($command, $parameters = [])
public
function
test_returns_certain_code
()
{
$this
->
artisan
(
'do:thing'
,
[
'--flagOfSomeSort'
=>
true
]);
$this
->
assertEquals
(
0
,
$this
->
code
);
// 0 means "no errors were returned"
}
$this->seed($seederClassName = 'DatabaseSeeder')
// app/SlackClient.php
class
SlackClient
{
...
public
function
send
(
$message
,
$channel
)
{
// Actually sends a message to Slack
}
}
// app/Notifier.php
class
Notifier
{
private
$slack
;
public
function
__construct
(
SlackClient
$slack
)
{
$this
->
slack
=
$slack
;
}
public
function
notifyAdmins
(
$message
)
{
$this
->
slack
->
send
(
$message
,
'admins'
);
}
}
// tests/NotifierTest.php
public
function
test_notifier_notifies_admins
()
{
$slackMock
=
Mockery
::
mock
(
SlackClient
::
class
)
->
shouldIgnoreMissing
();
$notifier
=
new
Notifier
(
$slackMock
);
$notifier
->
notifyAdmins
(
'Test message'
);
}
$slackMock
=
Mockery
::
mock
(
SlackClient
::
class
)
-
shouldIgnoreMissing
();
public
function
test_notifier_notifies_admins
()
{
$slackMock
=
Mockery
::
mock
(
SlackClient
::
class
);
$slackMock
->
shouldReceive
(
'send'
)
->
once
();
$notifier
=
new
Notifier
(
$slackMock
);
$notifier
->
notifyAdmins
(
'Test message'
);
}
public
function
test_notifier_notifies_admins
()
{
$slackMock
=
Mockery
::
mock
(
SlackClient
::
class
);
$slackMock
->
shouldReceive
(
'send'
)
->
once
();
app
()
->
instance
(
SlackClient
::
class
,
$slackMock
);
$notifier
=
app
(
Notifier
::
class
);
$notifier
->
notifyAdmins
(
'Test message'
);
}
// PeopleController
public
function
index
()
{
return
Cache
::
remember
(
'people'
,
function
()
{
return
Person
::
all
();
});
}
// PeopleTest
public
function
test_all_people_route_should_be_cached
()
{
$person
=
factory
(
Person
::
class
)
->
make
();
Cache
::
shouldReceive
(
'remember'
)
->
once
()
->
andReturn
(
collect
([
$person
]));
$this
->
visit
(
'people'
)
->
seeJson
([
'name'
=>
$person
->
name
]);
}
public
function
test_queue_job_should_be_pushed_after_regisration
()
{
Cache
::
spy
();
$this
->
post
(
'register'
,
[
'email'
=>
'joaquin@me.com'
]);
Cache
::
shouldHaveReceived
(
'push'
)
->
with
(
SendWelcomeEmail
::
class
,
[
'email'
=>
'joaquin@me.com'
]);
}
GET
/
api
/
cats
[
{
id
:
1
,
name
:
'Fluffy'
},
{
id
:
2
,
name
:
'Killer'
}
]
GET
/
api
/
cats
/
2
{
id
:
2
,
name
:
'Killer'
}
DELETE
/
api
/
cats
/
2
deletes
cat
POST
/
api
/
cats
with
body
:
{
name
:
'Mr Bigglesworth'
}
(
creates
new
cat
)
PATCH
/
api
/
cats
/
3
with
body
:
{
name
:
'Mr. Bigglesworth'
}
(
updates
cat
)
php
artisan
make
:
controller
Api
/
\DogsController
--
resource
<?
php
namespace
App\Http\Controllers\Api
;
use
Illuminate\Http\Request
;
use
App\Http\Requests
;
use
App\Http\Controllers\Controller
;
class
DogsController
extends
Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public
function
index
()
{}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public
function
create
()
{}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public
function
store
(
Request
$request
)
{}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public
function
show
(
$id
)
{}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public
function
edit
(
$id
)
{}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public
function
update
(
Request
$request
,
$id
)
{}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public
function
destroy
(
$id
)
{}
}
php
artisan
make
:
model
Dog
--
migration
php
artisan
migrate
...
class
DogsController
extends
Controller
{
public
function
index
()
{
return
Dog
::
all
();
}
public
function
store
(
Request
$request
)
{
Dog
::
create
(
$request
->
all
());
}
public
function
show
(
$id
)
{
return
Dog
::
findOrFail
(
$id
);
}
public
function
update
(
Request
$request
,
$id
)
{
$dog
=
Dog
::
findOrFail
(
$id
);
$dog
->
update
(
$request
->
all
());
}
public
function
destroy
(
$id
)
{
$dog
=
Dog
::
findOrFail
(
$id
);
$dog
->
delete
();
}
}
// Routes.php
Route
::
group
([
'prefix'
=>
'api'
,
'namespace'
=>
'Api'
],
function
()
{
Route
::
resource
(
'dogs'
,
'DogsController'
);
});
X-RateLimit-Limit: 5000 X-RateLimit-Remaining: 4987 X-RateLimit-Reset: 1350085394
HTTP/1.1 200 OK Server: nginx Date: Fri, 12 Oct 2012 23:33:14 GMT Content-Type: application/json; charset=utf-8 Connection: keep-alive Status: 200 OK ETag: "a00049ba79152d03380c34652f2cb612" X-GitHub-Media-Type: github.v3 X-RateLimit-Limit: 5000 X-RateLimit-Remaining: 4987 X-RateLimit-Reset: 1350085394 Content-Length: 5 Cache-Control: max-age=0, private, must-revalidate X-Content-Type-Options: nosniff
Accept: application/vnd.github.v3+json
Route
::
get
(
'dogs'
,
function
()
{
return
response
(
Dog
::
all
())
->
header
(
'X-Greatness-Index'
,
9
);
});
Route
::
get
(
'dogs'
,
function
(
Request
$request
)
{
echo
$request
->
header
(
'Accept'
);
});
Pagination is one of the first places where most APIs need to consider special instructions. Eloquent comes out of the box with a pagination system that hooks directly into the query parameters of any page request. We already covered the paginator component a bit in Chapter 5, but here’s a quick refresher.
Route
::
get
(
'dogs'
,
function
()
{
return
Dog
::
paginate
(
20
);
});
GET
/
dogs
-
Return
results
1
-
20
GET
/
dogs
?
page
=
1
-
Return
results
1
-
20
GET
/
dogs
?
page
=
2
-
Return
results
21
-
40
Route
::
get
(
'dogs'
,
function
()
{
return
DB
::
table
(
'dogs'
)
->
paginate
(
20
);
});
{
"total"
:
50
,
"per_page"
:
3
,
"current_page"
:
1
,
"last_page"
:
17
,
"next_page_url"
:
"http://myapp.com/api/dogs?page=2"
,
"prev_page_url"
:
null
,
"from"
:
1
,
"to"
:
3
,
"data"
:
[
{
'name'
:
'Fido'
},
{
'name'
:
'Pickles'
},
{
'name'
:
'Spot'
}
]
}
// Handles /dogs?sort=name
Route
::
get
(
'dogs'
,
function
(
Request
$request
)
{
// Get the sort query parameter (or fall back to default sort "name")
$sortCol
=
$request
->
input
(
'sort'
,
'name'
);
return
Dog
::
orderBy
(
$sortCol
)
->
paginate
(
20
);
});
// Handles /dogs?sort=name and /dogs?sort=-name
Route
::
get
(
'dogs'
,
function
(
Request
$request
)
{
// Get the sort query parameter (or fall back to default sort "name")
$sortCol
=
$request
->
input
(
'sort'
,
'name'
);
// Set the sort direction based on whether the key starts with -
// using Laravel's starts_with() helper function
$sortDir
=
starts_with
(
$sortCol
,
'-'
)
?
'desc'
:
'asc'
;
$sortCol
=
ltrim
(
$sort
,
'-'
);
return
Dog
::
orderBy
(
$sortCol
,
$sortDir
)
->
paginate
(
20
);
});
// Handles ?sort=name,-weight
Route
::
get
(
'dogs'
,
function
(
Request
$request
)
{
// Grab the query parameter and turn it into an array exploded by ,
$sorts
=
explode
(
','
,
$request
->
input
(
'sort'
,
''
));
// Create a query
$query
=
Dog
::
query
();
// Add the sorts one by one
foreach
(
$sorts
as
$sortCol
)
{
$sortDir
=
starts_with
(
$sortCol
,
'-'
)
?
'desc'
:
'asc'
;
$sortCol
=
ltrim
(
$sort
,
'-'
);
$query
->
orderBy
(
$sortCol
,
$sortDir
);
}
// Return
return
$query
->
paginate
(
20
);
});
Route
::
get
(
'dogs'
,
function
(
Request
$request
)
{
$query
=
Dog
::
query
();
if
(
$request
->
has
(
'filter'
))
{
list
(
$criteria
,
$value
)
=
explode
(
':'
,
$request
->
input
(
'filter'
));
$query
->
where
(
$criteria
,
$value
);
}
return
$query
->
paginate
(
20
);
});
Route
::
get
(
'dogs'
,
function
(
Request
$request
)
{
$query
=
Dog
::
query
();
if
(
$request
->
has
(
'filter'
))
{
$filters
=
explode
(
','
,
$request
->
input
(
'filter'
));
foreach
(
$filters
as
$filter
)
{
list
(
$criteria
,
$value
)
=
explode
(
':'
,
$filter
);
$query
->
where
(
$criteria
,
$value
);
}
}
return
$query
->
paginate
(
20
);
});
Route
::
get
(
'users/{id}'
,
function
(
$userId
)
{
return
(
new
UserTransformer
(
User
::
findOrFail
(
$userId
)));
});
class
UserTransformer
{
protected
$user
;
public
function
__construct
(
$user
)
{
$this
->
user
=
$user
;
}
public
function
toArray
()
{
return
[
'id'
=>
$this
->
user
->
id
,
'name'
=>
sprintf
(
"%s %s"
,
$this
->
user
->
first_name
,
$this
->
user
->
last_name
),
'friendsCount'
=>
$this
->
user
->
friends
->
count
()
];
}
public
function
toJson
()
{
return
json_encode
(
$this
->
toArray
());
}
public
function
__toString
()
{
return
$this
->
toJson
();
}
}
Route
::
get
(
'users/{id}'
,
function
(
$userId
,
Request
$request
)
{
// Get the embeds query parameter and split by commas
$embeds
=
explode
(
','
,
$request
->
input
(
'embed'
,
''
));
// Pass both user and embeds to the user transformer
return
(
new
UserTransformer
(
User
::
findOrFail
(
$userId
),
$embeds
));
});
class
UserTransformer
{
protected
$user
;
protected
$embeds
;
public
function
__construct
(
$user
,
$embeds
=
[])
{
$this
->
user
=
$user
;
$this
->
embeds
=
$embeds
;
}
public
function
toArray
()
{
$append
=
[];
if
(
in_array
(
'friends'
,
$this
->
embeds
))
{
// If you have more than one embed, you'll want to generalize this
$append
[
'friends'
]
=
$this
->
user
->
friends
->
map
(
function
(
$friend
)
{
return
(
new
FriendTransformer
(
$friend
))
->
toArray
();
});
}
return
array_merge
([
'id'
=>
$this
->
user
->
id
,
'name'
=>
sprintf
(
"%s %s"
,
$this
->
user
->
first_name
,
$this
->
user
->
last_name
)
],
$append
);
}
...
composer require laravel/passport
// routes/api.php
Route
::
get
(
'/user'
,
function
(
Request
$request
)
{
return
$request
->
user
();
})
->
middleware
(
'auth:api'
);
$http
=
new
GuzzleHttp\Client
;
$response
=
$http
->
request
(
'GET'
,
'http://speakr.dev/api/user'
,
[
'headers'
=>
[
'Accept'
=>
'application/json'
,
'Authorization'
=>
'Bearer '
.
$accessToken
,
],
]);
php
artisan
passport:client
--password
What
should
we
name
the
password
grant
client?
[
My
Application
Password
Grant
Client
]
:
>
SpaceBook_internal
Password
grant
client
created
successfully.
// Assuming SpaceBook is not an external app, but actually
// a trusted internal app... this is SpaceBook's routes/web.php
Route
::
get
(
'speakr/password-grant-auth'
,
function
()
{
$http
=
new
GuzzleHttp\Client
;
$response
=
$http
->
post
(
'http://speakr.dev/oauth/token'
,
[
'form_params'
=>
[
'grant_type'
=>
'password'
,
'client_id'
=>
config
(
'speakr.id'
),
'client_secret'
=>
config
(
'speakr.secret'
),
'username'
=>
'matt@mattstauffer.co'
,
'password'
=>
'my-speakr-password'
,
],
]);
$thisUsersTokens
=
json_decode
((
string
)
$response
->
getBody
(),
true
);
// do stuff with the tokens
});
php artisan passport:client Which user ID should the client be assigned to?: > 1 What should we name the client?: > SpaceBook Where should we redirect the request after authorization? [http://passport.dev/auth/callback]: > http://spacebook.dev/auth/callback New client created successfully. Client ID: 3 Client secret: RiQstsWDqd9SqQY3lQhiZF50ulKdw4iPhPAdkeO3
Every client needs to be assigned to a user in your app. Imagine Jill, user #1, is writing SpaceBook; she’ll be the “owner” of this client we’re creating.
// In SpaceBook's routes/web.php:
Route
::
get
(
'speakr/redirect'
,
function
()
{
$query
=
http_build_query
([
'client_id'
=>
config
(
'speakr.id'
),
'redirect_uri'
=>
url
(
'speakr/callback'
),
'response_type'
=>
'code'
,
]);
// Builds a string like:
// client_id={$client_id}&redirect_uri={$redirect_uri}&response_type=code
return
redirect
(
'http://speakr.dev/oauth/authorize?'
.
$query
);
});
php artisan vendor:publish --tag=
passport-views
// In SpaceBook's routes/web.php:
Route
::
get
(
'speakr/callback'
,
function
(
Request
$request
)
{
if
(
$request
->
has
(
'error'
))
{
// handle error condition
}
$http
=
new
GuzzleHttp\Client
;
$response
=
$http
->
post
(
'http://speakr.dev/oauth/token'
,
[
'form_params'
=>
[
'grant_type'
=>
'authorization_code'
,
'client_id'
=>
config
(
'speakr.id'
),
'client_secret'
=>
config
(
'speakr.secret'
),
'redirect_uri'
=>
url
(
'speakr/callback'
),
'code'
=>
$request
->
code
,
],
]);
$thisUsersTokens
=
json_decode
((
string
)
$response
->
getBody
(),
true
);
// do stuff with the tokens
});
php
artisan
passport:client
--personal
What
should
we
name
the
password
grant
client?
[
My
Application
Personal
Access
Client
]
:
>
My
Application
Personal
Access
Client
Personal
access
client
created
successfully.
// Creating a token without scopes
$token
=
$user
->
createToken
(
'Token Name'
)
->
accessToken
;
// Creating a token with scopes...
$token
=
$user
->
createToken
(
'My Token'
,
[
'place-orders'
])
->
accessToken
;
$
.
ajaxSetup
({
headers
:
{
'X-CSRF-TOKEN'
:
"{{ csrf_token() }}"
}
});
/
oauth
/
clients
(
GET
,
POST
)
/
oauth
/
clients
/
{
id
}
(
DELETE
,
PUT
)
/
oauth
/
personal
-
access
-
tokens
(
GET
,
POST
)
/
oauth
/
personal
-
access
-
tokens
/
{
id
}
(
DELETE
)
/
oauth
/
scopes
(
GET
)
/
oauth
/
tokens
(
GET
)
/
oauth
/
tokens
/
{
id
}
(
DELETE
)
php artisan vendor:publish --tag=
passport-components
require
(
'./bootstrap'
);
Vue
.
component
(
'passport-clients'
,
require
(
'./components/passport/Clients.vue'
)
);
Vue
.
component
(
'passport-authorized-clients'
,
require
(
'./components/passport/AuthorizedClients.vue'
)
);
Vue
.
component
(
'passport-personal-access-tokens'
,
require
(
'./components/passport/PersonalAccessTokens.vue'
)
);
const
app
=
new
Vue
({
el
:
'body'
});
<passport-clients></passport-clients> <passport-authorized-clients></passport-authorized-clients> <passport-personal-access-tokens></passport-personal-access-tokens>
// AuthServiceProvider
use
Laravel\Passport\Passport
;
...
public
function
boot
()
{
...
Passport
::
tokensCan
([
'list-clips'
=>
'List sound clips'
,
'add-delete-clips'
=>
'Add new and delete old sound clips'
,
'admin-account'
=>
'Administer account details'
,
]);
}
// In SpaceBook's routes/web.php:
Route
::
get
(
'speakr/redirect'
,
function
()
{
$query
=
http_build_query
([
'client_id'
=>
config
(
'speakr.id'
),
'redirect_uri'
=>
url
(
'speakr/callback'
),
'response_type'
=>
'code'
,
'scope'
=>
'list-clips add-delete-clips'
]);
return
redirect
(
'http://speakr.dev/oauth/authorize?'
.
$query
);
});
Route
::
get
(
'/events'
,
function
()
{
if
(
auth
()
->
user
()
->
tokenCan
(
'add-delete-clips'
))
{
//
}
});
'scopes'
=>
\Laravel\Passport\Http\Middleware\CheckScopes
::
class
,
'scope'
=>
\Laravel\Passport\Http\Middleware\CheckForAnyScope
::
class
,
// routes/api.php
Route
::
get
(
'clips'
,
function
()
{
// Access token has both the "list-clips" and "add-delete-clips" scopes
})
->
middleware
(
'scopes:list-clips,add-delete-clips'
);
// or
Route
::
get
(
'clips'
,
function
()
{
// Access token has at least one of the listed scopes
})
->
middleware
(
'scope:list-clips,add-delete-clips'
)
$table
->
string
(
'api_token'
,
60
)
->
unique
();
Route
::
group
([
'prefix'
=>
'api'
,
'middleware'
=>
'auth:api'
],
function
()
{
//
});
$user
=
auth
()
->
guard
(
'api'
)
->
user
();
...
class
DogsApiTest
extends
TestCase
{
use
WithoutMiddleware
,
DatabaseMigrations
;
public
function
test_it_gets_all_dogs
()
{
$this
->
be
(
factory
(
User
::
class
)
->
create
());
$dog1
=
factory
(
Dog
::
class
)
->
create
();
$dog2
=
factory
(
Dog
::
class
)
->
create
();
$this
->
visit
(
'api/dogs'
);
$this
->
seeJson
([
'name'
=>
$dog1
->
name
]);
$this
->
seeJson
([
'name'
=>
$dog2
->
name
]);
}
}
...
'disks'
=>
[
'local'
=>
[
'driver'
=>
'local'
,
'root'
=>
storage_path
(
'app'
),
],
'public'
=>
[
'driver'
=>
'local'
,
'root'
=>
storage_path
(
'app/public'
),
'visibility'
=>
'public'
,
],
's3'
=>
[
'driver'
=>
's3'
,
'key'
=>
'your-key'
,
'secret'
=>
'your-secret'
,
'region'
=>
'your-region'
,
'bucket'
=>
'your-bucket'
,
],
],
# Maps public/storage to serve the files from storage/app/public
php artisan storage:link
Storage
::
disk
(
's3'
)
->
get
(
'file.jpg'
);
get('file.jpg')
put('file.jpg', $contentsOrStream)
putFile('myDir', $file)
exists('file.jpg')
copy('file.jpg', 'newfile.jpg')
move('file.jpg', 'newfile.jpg')
prepend('my.log', 'log text')
append('my.log', 'log text')
delete('file.jpg')
deleteDirectory('myDir')
size('file.jpg')
lastModified('file.jpg')
files('myDir')
allFiles('myDir')
directories('myDir')
allDirectories('myDir')
// Some service provider
public
function
boot
()
{
Storage
::
extend
(
'dropbox'
,
function
(
$app
,
$config
)
{
$client
=
new
DropboxClient
(
$config
[
'accessToken'
],
$config
[
'clientIdentifier'
]
);
return
new
Filesystem
(
new
DropboxAdapter
(
$client
));
});
}
...
class
DogsController
{
public
function
updatePicture
(
Request
$request
,
Dog
$dog
)
{
Storage
::
put
(
'dogs/'
.
$dog
->
id
,
file_get_contents
(
$request
->
file
(
'picture'
)
->
getRealPath
())
);
}
...
class
DogsController
{
public
function
updatePicture
(
Request
$request
,
Dog
$dog
)
{
$original
=
$request
->
file
(
'picture'
);
// Resize image to max width 150
$image
=
Image
::
make
(
$original
)
->
resize
(
150
,
null
,
function
(
$constraint
)
{
$constraint
->
aspectRatio
();
})
->
encode
(
'jpg'
,
75
);
Storage
::
put
(
'dogs/thumbs/'
.
$dog
->
id
,
$image
->
getEncoded
()
);
}
// get
$value
=
session
()
->
get
(
'key'
);
$value
=
session
(
'key'
);
// put
session
()
->
put
(
'key'
,
'value'
);
session
([
'key'
,
'value'
]);
Route
::
get
(
'dashboard'
,
function
(
Request
$request
)
{
$request
->
session
()
->
get
(
'user_id'
);
});
Route
::
get
(
'dashboard'
,
function
(
Illuminate\Session\Store
$session
)
{
return
$session
->
get
(
'user_id'
);
});
Session
::
get
(
'user_id'
);
session()->get($key, $fallbackValue)
$points
=
session
()
->
get
(
'points'
);
$points
=
session
()
->
get
(
'points'
,
0
);
$points
=
session
()
->
get
(
'points'
,
function
()
{
return
(
new
PointGetterService
)
->
getPoints
();
});
session()->put($key, $value)
session
()
->
put
(
'points'
,
45
);
$points
=
session
()
->
get
(
'points'
);
session()->push($key, $value)
session
()
->
put
(
'friends'
,
[
'Saúl'
,
'Quang'
,
'Mechteld'
]);
session
()
->
push
(
'friends'
,
'Javier'
);
session()->has($key)
if
(
session
()
->
has
(
'points'
))
{
// do something
}
session()->all()
session()->forget($key)
and session()->flush()
session
()
->
put
(
'a'
,
'awesome'
);
session
()
->
put
(
'b'
,
'bodacious'
);
session
()
->
forget
(
'a'
);
// a is no longer set, b is still set
session
()
->
flush
();
// session is now empty
session()->pull($key, $fallbackValue)
session()->regenerate()
session()->flash($key, $value)
session()->reflash()
and session()->keep($key)
$users
=
Cache
::
get
(
'users'
);
Route
::
get
(
'users'
,
function
(
Illuminate\Contracts\Cache\Repository
$cache
)
{
return
$cache
->
get
(
'users'
);
});
// get from cache
$users
=
cache
(
'key'
,
'default value'
);
$users
=
cache
()
->
get
(
'key'
,
'default value'
);
// put for $minutes duration
$users
=
cache
([
'key'
=>
'value'
],
$minutes
);
$users
=
cache
()
->
put
(
'key'
,
'value'
,
$minutes
);
cache()->get($key, $fallbackValue)
and cache()->pull($key, $fallbackValue)
cache()->put($key, $value, $minutesOrExpiration)
cache
()
->
put
(
'key'
,
'value'
,
Carbon
::
now
()
->
addDay
());
cache()->add($key, $value)
$someDate
=
Carbon
::
now
();
cache
()
->
add
(
'someDate'
,
$someDate
);
// returns true
$someOtherDate
=
Carbon
::
now
()
->
addHour
();
cache
()
->
add
(
'someDate'
,
$someOtherDate
);
// returns false
cache()->forever($key, $value)
cache()->has($key)
cache()->remember($key, $minutes, $closure)
and cache()->rememberForever($key, $closure)
// Either returns the value cached at "users" or gets "User::all()",
// caches it at "users", and returns it
$users
=
cache
()
->
remember
(
'users'
,
120
,
function
()
{
return
User
::
all
();
});
cache()->increment($key, $amount)
and cache()->decrement($key, $amount)
cache()->forget($key)
and cache()->flush()
Cookie::get($key)
Cookie::has($key)
Cookie::make(...params)
Cookie::make()
Cookie::queue(Cookie || ...params)
Cookie
::
queue
(
'dismissed-popup'
,
true
,
15
);
$cookie
=
cookie
(
'dismissed-popup'
,
true
,
15
);
Route
::
get
(
'dashboard'
,
function
(
Illuminate\Http\Request
$request
)
{
$userDismissedPopup
=
$request
->
cookie
(
'dismissed-popup'
,
false
);
});
Route
::
get
(
'dashboard'
,
function
()
{
$cookie
=
cookie
(
'saw-dashboard'
,
true
);
return
Response
::
view
(
'dashboard'
)
->
cookie
(
$cookie
);
});
composer require laravel/scout
composer require algolia/algoliasearch-client-php
Review
::
search
(
'Llew'
)
->
get
();
// Get all records from the Review that match the term "Llew",
// limited to 20 per page and reading the page query parameter,
// just like Eloquent pagination
Review
::
search
(
'Llew'
)
->
paginate
(
20
);
// Get all records from the Review that match the term "Llew"
// and have the account_id field set to 2
Review
::
search
(
'Llew'
)
->
where
(
'account_id'
,
2
)
->
get
();
Review
::
withoutSyncingToSearch
(
function
()
{
// make a bunch of reviews, e.g.
factory
(
Review
::
class
,
10
)
->
create
();
});
Review
::
all
()
->
searchable
();
$user
->
reviews
()
->
searchable
();
Review
::
where
(
'sucky'
,
true
)
->
unsearchable
();
php artisan scout:import App\\Review
public
function
test_file_should_be_stored
()
{
$path
=
storage_path
(
'tests/for-tests.jpg'
);
$file
=
new
UploadedFile
(
$path
,
// file path
'for-tests.jpg'
,
// original file name
'image/jpg'
,
// MIME type
filesize
(
$path
),
// file size; best to get once & hardcode into your test,
null
,
// error code
true
// whether we're in test mode
);
$this
->
call
(
'post'
,
'upload-route'
,
[],
[],
[
'upload'
=>
$file
]);
$this
->
assertResponseOk
();
}
$factory
->
define
(
User
::
class
,
function
(
Faker\Generator
$faker
)
{
return
[
'picture'
=>
$faker
->
file
(
storage_path
(
'tests'
),
// source directory
storage_path
(
'app'
),
// target directory
false
// return just filename, not full path
),
'name'
=>
$faker
->
name
,
];
});
public
function
test_user_profile_picture_echoes_correctly
()
{
$user
=
factory
(
User
::
class
)
->
create
();
$this
->
visit
(
"users/
{
$user
->
id
}
"
);
$this
->
see
(
$user
->
picture
);
}
assertSessionHas($key, $value = null)
public
function
test_some_thing
()
{
// do stuff
$this
->
assertSessionHas
(
'key'
,
'value'
);
}
assertSessionHasAll(array $bindings)
$check
=
[
'has'
,
'hasWithThisValue'
=>
'thisValue'
,
]
$this
->
assertSessionHasAll
(
$check
);
assertSessionMissing($key)
assertSessionHasErrors($bindings = [], $format = null)
$this
->
post
(
'test-route'
,
[
'failing'
=>
'data'
]);
$this
->
assertSessionHasErrors
([
'name'
,
'email'
]);
$this
->
post
(
'test-route'
,
[
'failing'
=>
'data'
]);
$this
->
assertSessionHasErrors
([
'email'
=>
'<strong>The email field is required.</strong>'
],
'<strong>:message</strong>'
);
assertHasOldInput()
$this
->
post
(
'test-route'
,
[
'failing'
=>
'data'
]);
$this
->
assertHasOldInput
();
Cache
::
put
(
'key'
,
'value'
,
15
);
$this
->
assertEquals
(
'value'
,
Cache
::
get
(
'key'
));
use
Illuminate\Cookie\Middleware\EncryptCookies
;
...
$this
->
app
->
resolving
(
EncryptCookies
::
class
,
function
(
$object
)
{
$object
->
disableFor
(
'cookie-name'
);
}
);
// ...run test
public
function
test_cookie
()
{
$this
->
app
->
resolving
(
EncryptCookies
::
class
,
function
(
$object
)
{
$object
->
disableFor
(
'my-cookie'
);
});
$this
->
call
(
'get'
,
'route-echoing-my-cookie-value'
,
[],
[
'my-cookie'
=>
'baz'
]);
$this
->
see
(
'baz'
);
}
use
Illuminate\Contracts\Encryption\Encrypter
;
...
public
function
test_cookie
()
{
$encryptedBaz
=
app
(
Encrypter
::
class
)
->
encrypt
(
'baz'
);
$this
->
call
(
'get'
,
'route-echoing-my-cookie-value'
,
[],
[
'my-cookie'
=>
$encryptedBaz
]
);
$this
->
see
(
'baz'
);
}
$this
->
visit
(
'cookie-setting-route'
);
$this
->
seeCookie
(
'cookie-name'
);
composer require guzzlehttp/guzzle:"~5.3|~6.0"
composer require aws/aws-sdk-php:~3.0
::
send
(
'emails.assignment'
,
[
'trainer'
=>
$trainer
,
'trainee'
=>
$trainee
],
function
(
$m
)
use
(
$trainer
,
$trainee
)
{
$m
->
from
(
$trainer
->
,
$trainer
->
name
);
$m
->
to
(
$trainee
->
,
$trainee
->
name
)
->
subject
(
'A New Assignment!'
);
}
);
php artisan make:mail Assignment
<?
php
namespace
App\Mail
;
use
Illuminate\Bus\Queueable
;
use
Illuminate\Mail\Mailable
;
use
Illuminate\Queue\SerializesModels
;
use
Illuminate\Contracts\Queue\ShouldQueue
;
class
Assignment
extends
Mailable
{
use
Queueable
,
SerializesModels
;
/**
* Create a new message instance.
*
* @return void
*/
public
function
__construct
()
{
//
}
/**
* Build the message.
*
* @return $this
*/
public
function
build
()
{
return
$this
->
view
(
'view.name'
);
}
}
<?
php
namespace
App\Mail
;
use
Illuminate\Bus\Queueable
;
use
Illuminate\Mail\Mailable
;
use
Illuminate\Queue\SerializesModels
;
use
Illuminate\Contracts\Queue\ShouldQueue
;
class
Assignment
extends
Mailable
{
use
Queueable
,
SerializesModels
;
public
$trainer
;
public
$trainee
;
public
function
__construct
(
$trainer
,
$trainee
)
{
$this
->
trainer
=
$trainer
;
$this
->
trainee
=
$trainee
;
}
public
function
build
()
{
return
$this
->
subject
(
'New assignment from '
.
$this
->
trainer
->
name
)
->
view
(
'emails.assignment'
);
}
}
// Simple send
::
to
(
$user
)
->
send
(
new
Assignment
(
$trainer
,
$trainee
));
// With CC/BCC/etc.
::
to
(
$user1
))
->
cc
(
$user2
)
->
bcc
(
$user3
)
->
send
(
new
Assignment
(
$trainer
,
$trainee
));
// With collections
::
to
(
'me@app.com'
)
->
bcc
(
User
::
all
())
->
send
(
new
Assignment
(
$trainer
,
$trainee
))
<!-- resources/views/emails/assignment.blade.php -->
<p>
Hey {{ $trainee->name }}!</p>
<p>
You have received a new training assignment from<b>
{{ $trainer->name }}</b>
. Check out your<a
href=
"{{ route('training-dashboard') }}"
>
training dashboard</a>
now!</p>
public
function
build
()
{
return
$this
->
subject
(
'You have a new assignment!'
)
->
view
(
'emails.assignment'
)
->
with
([
'assignment'
=>
$this
->
event
->
name
]);
}
public
function
build
()
{
return
$this
->
view
(
'emails.reminder'
)
->
text
(
'emails.reminder_plain'
);
}
from($address, $name = null)
subject($subject)
attach($pathToFile, array $options = [])
attachData($data, $name, array $options = [])
priority($priority)
public
function
build
()
{
return
$this
->
subject
(
'Howdy!'
)
->
withSwiftMessage
(
function
(
$swift
)
{
$swift
->
setReplyTo
(
'noreply@email.com'
);
})
->
view
(
'emails.howdy'
);
}
// Attach a file using the local filename
public
function
build
()
{
return
$this
->
subject
(
'Your whitepaper download'
)
->
attach
(
storage_path
(
'pdfs/whitepaper.pdf'
),
[
'mime'
=>
'application/pdf'
,
// Optional
'as'
=>
'whitepaper-barasa.pdf'
// Optional
])
->
view
(
'emails.whitepaper'
);
}
// Attach a file passing the raw data
public
function
build
()
{
return
$this
->
subject
(
'Your whitepaper download'
)
->
attachData
(
file_get_contents
(
storage_path
(
'pdfs/whitepaper.pdf'
)),
'whitepaper-barasa.pdf'
,
[
'mime'
=>
'application/pdf'
// Optional
]
)
->
view
(
'emails.whitepaper'
);
}
<!--
emails
/
image
.
blade
.
php
--!>
Here
is
an
image
:
<
img loading="lazy"
src
=
"{{
$message->embed
(storage_path('embed.jpg')) }}"
>
Or
,
the
same
image
embedding
the
data
:
<
img loading="lazy"
src
=
"{{
$message->embedData
(
file_get_contents(storage_path('embed.jpg')), 'embed.jpg'
) }}"
>
::
queue
(
new
Assignment
(
$trainer
,
$trainee
));
$when
=
Carbon
::
now
()
->
addMinutes
(
30
);
::
later
(
$when
,
new
Assignment
(
$trainer
,
$trainee
));
$message
=
(
new
Assignment
(
$trainer
,
$trainee
))
->
onConnection
(
'sqs'
)
->
onQueue
(
'emails'
);
::
to
(
$user
)
->
queue
(
$message
);
Message-ID: <04ee2e97289c68f0c9191f4b04fc0de1@localhost> Date: Tue, 17 May 2016 02:52:46 +0000 Subject: Welcome to our app! From: Matt Stauffer <matt@mattstauffer.co> To: freja@jensen.no MIME-Version: 1.0 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable Welcome to our app!
MAIL_DRIVER=smtp MAIL_HOST=mailtrap.io MAIL_PORT=2525 MAIL_USERNAME=your_username_from_mailtrap_here MAIL_PASSWORD=your_password_from_mailtrap_here MAIL_ENCRYPTION=null
'to'
=>
[
'address'
=>
'matt@mattstauffer.co'
,
'name'
=>
'Matt Testing My Application'
],
php artisan make:notification WorkoutAvailable
<?
php
namespace
App\Notifications
;
use
Illuminate\Bus\Queueable
;
use
Illuminate\Notifications\Notification
;
use
Illuminate\Contracts\Queue\ShouldQueue
;
use
Illuminate\Notifications\Messages\MailMessage
;
class
WorkoutAvailable
extends
Notification
{
use
Queueable
;
/**
* Create a new notification instance.
*
* @return void
*/
public
function
__construct
()
{
//
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public
function
via
(
$notifiable
)
{
return
[
'mail'
];
}
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public
function
toMail
(
$notifiable
)
{
return
(
new
MailMessage
)
->
line
(
'The introduction to the notification.'
)
->
action
(
'Notification Action'
,
'https://laravel.com'
)
->
line
(
'Thank you for using our application!'
);
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
* @return array
*/
public
function
toArray
(
$notifiable
)
{
return
[
//
];
}
}
...
class
WorkoutAvailable
extends
Notification
{
use
Queueable
;
public
$workout
;
public
function
__construct
(
$workout
)
{
$this
->
workout
=
$workout
;
}
public
function
via
(
$notifiable
)
{
// This method doesn't exist on the User... we're going to make it up
return
$notifiable
->
preferredNotificationChannels
();
}
public
function
toMail
(
$notifiable
)
{
return
(
new
MailMessage
)
->
line
(
'You have a new workout available!'
)
->
action
(
'Check it out now'
,
route
(
'workout'
,
[
$this
->
workout
]))
->
line
(
'Thank you for training with us!'
);
}
public
function
toArray
(
$notifiable
)
{
return
[];
}
}
public
function
via
(
$notifiable
)
{
return
'nexmo'
;
}
public
function
via
(
$notifiable
)
{
return
$notifiable
->
preferred_notification_channel
;
}
use
App\Notifications\WorkoutAvailable
;
...
$user
->
notify
(
new
WorkoutAvailable
(
$workout
));
use
App\Notifications\WorkoutAvailable
;
...
Notification
::
send
(
User
::
all
(),
new
WorkoutAvailable
(
$workout
));
$delayUntil
=
Carbon
::
now
()
->
addMinutes
(
15
);
$user
->
notify
((
new
WorkoutAvailable
(
$workout
))
->
delay
(
$delayUntil
));
public
function
toMail
(
$notifiable
)
{
return
(
new
MailMessage
)
->
line
(
'You have a new workout available!'
)
->
action
(
'Check it out now'
,
route
(
'workout'
,
[
$this
->
workout
]))
->
line
(
'Thank you for training with us!'
);
}
php artisan vendor:publish --tag=laravel-notifications
User
::
first
()
->
notifications
->
each
(
function
(
$notification
)
{
// do something
});
User
::
first
()
->
unreadNotifications
->
each
(
function
(
$notification
)
{
// do something
});
// Individual
User
::
first
()
->
notifications
->
each
(
function
(
$notification
)
{
if
(
$condition
)
{
$notification
->
markAsRead
();
}
});
// All
User
::
first
()
->
unreadNotifications
->
markAsRead
();
composer require tightenco/mailthief --dev
public
function
test_signup_triggers_welcome_email
()
{
...
::
assertSent
(
WelcomeEmail
::
class
,
function
(
$e
)
{
return
$e
->
subject
==
'Welcome!'
;
});
// You can also use assertSentTo() to explicitly test the recipients
}
public
function
test_new_signups_triggers_admin_notification
()
{
...
Notification
::
assertSentTo
(
$user
,
NewUsersSignedup
::
class
,
function
(
$n
,
$channels
)
{
return
$n
->
user
->
==
'user-who-signed-up@gmail.com'
&&
$channels
==
[
'mail'
];
});
// You can also use assertNotSentTo()
}
php
artisan
make
:
job
CrunchReports
<?
php
use
Illuminate\Bus\Queueable
;
use
Illuminate\Queue\SerializesModels
;
use
Illuminate\Queue\InteractsWithQueue
;
use
Illuminate\Contracts\Queue\ShouldQueue
;
class
CrunchReports
implements
ShouldQueue
{
use
InteractsWithQueue
,
Queueable
,
SerializesModels
;
/**
* Create a new job instance.
*
* @return void
*/
public
function
__construct
()
{
//
}
/**
* Execute the job.
*
* @return void
*/
public
function
handle
()
{
//
}
}
...
use
App\ReportGenerator
;
use
Illuminate\Log\Writer
as
Logger
;
class
CrunchReports
implements
ShouldQueue
{
use
InteractsWithQueue
,
SerializesModels
;
protected
$user
;
public
function
__construct
(
$user
)
{
$this
->
user
=
$user
;
}
public
function
handle
(
ReportGenerator
$generator
,
Logger
$logger
)
{
$generator
->
generateReportsForUser
(
$this
->
user
);
$logger
->
info
(
'Generated reports.'
);
}
}
// In a controller
public
function
index
()
{
$user
=
auth
()
->
user
();
$this
->
dispatch
(
new
\App\Jobs\CrunchReports
(
$user
));
}
// Elsewhere
dispatch
(
new
\App\Jobs\CrunchReports
(
$user
));
dispatch
((
new
DoThingJob
)
->
onConnection
(
'redis'
));
dispatch
((
new
DoThingJob
)
->
onQueue
(
'high'
));
// Delays one minute before releasing the job to queue workers
dispatch
((
new
DoThingJob
)
->
delay
(
60
));
php
artisan
queue
:
work
php
artisan
queue
:
work
redis
--
timeout
=
60
--
sleep
=
15
--
tries
=
3
--
queue
=
high
,
medium
php artisan queue:listen --tries=
3
public
function
handle
()
{
...
if
(
$this
->
attempts
()
>
3
)
{
//
}
}
php
artisan
queue
:
failed
-
table
php
artisan
migrate
...
class
CrunchReports
implements
ShouldQueue
{
...
public
function
failed
()
{
// Do whatever you want
}
}
// Some service provider
use
Illuminate\Support\Facades\Queue
;
...
public
function
boot
()
{
Queue
::
failing
(
function
(
$connection
,
$job
,
$data
)
{
// Do whatever you want
});
}
php artisan queue:failed
+----+------------+---------+----------------------+---------------------+ | ID | Connection | Queue | Class | Failed At | +----+------------+---------+----------------------+---------------------+ | 9 | database | default | App/Jobs/AlwaysFails | 2016-01-26 03:42:55 | +----+------------+---------+----------------------+---------------------+
php artisan queue:retry 9
php artisan queue:retry all
php artisan queue:forget 5
php
artisan
queue
:
flush
public
function
handle
()
{
...
if
(
condition
)
{
$this
->
release
(
$numberOfSecondsToDelayBeforeRetrying
);
}
}
public
function
handle
()
{
...
if
(
$jobShouldBeDeleted
)
{
return
;
}
}
Event
::
fire
(
new
UserSubscribed
(
$user
,
$plan
));
// or
$dispatcher
=
app
(
Illuminate\Contracts\Events\Dispatcher
);
$dispatcher
->
fire
(
new
UserSubscribed
(
$user
,
$plan
));
// or
event
(
new
UserSubscribed
(
$user
,
$plan
));
php
artisan
make
:
event
UserSubscribed
<?
php
namespace
App\Events
;
use
Illuminate\Broadcasting\Channel
;
use
Illuminate\Queue\SerializesModels
;
use
Illuminate\Broadcasting\PrivateChannel
;
use
Illuminate\Broadcasting\PresenceChannel
;
use
Illuminate\Broadcasting\InteractsWithSockets
;
use
Illuminate\Contracts\Broadcasting\ShouldBroadcast
;
class
UserSubscribed
{
use
InteractsWithSockets
,
SerializesModels
;
/**
* Create a new event instance.
*
* @return void
*/
public
function
__construct
()
{
//
}
/**
* Get the channels the event should be broadcast on.
*
* @return Channel|array
*/
public
function
broadcastOn
()
{
return
new
PrivateChannel
(
'channel-name'
);
}
}
...
class
UserSubscribed
{
use
InteractsWithSockets
,
SerializesModels
;
public
$user
;
public
$plan
;
public
function
__construct
(
$user
,
$plan
)
{
$this
->
user
=
$user
;
$this
->
plan
=
$plan
;
}
}
php
artisan
make
:
listener
EmailOwnerAboutSubscription
--
event
=
UserSubscribed
<?
php
namespace
App\Listeners
;
use
App\Events\UserSubscribed
;
use
Illuminate\Queue\InteractsWithQueue
;
use
Illuminate\Contracts\Queue\ShouldQueue
;
class
EmailOwnerAboutSubscription
{
/**
* Create the event listener.
*
* @return void
*/
public
function
__construct
()
{
//
}
/**
* Handle the event.
*
* @param UserSubscribed $event
* @return void
*/
public
function
handle
(
UserSubscribed
$event
)
{
//
}
}
...
use
Illuminate\Contracts\Mail\Mailer
;
class
EmailOwnerAboutSubscription
{
protected
$mailer
;
public
function
__construct
(
Mailer
$mailer
)
{
$this
->
mailer
=
$mailer
;
}
public
function
handle
(
UserSubscribed
$event
)
{
$this
->
mailer
->
send
(
new
OwnerSubscriptionEmail
(
$event
->
user
,
$event
->
plan
)
);
}
}
class
EventServiceProvider
extends
ServiceProvider
{
protected
$listen
=
[
\App\Events\UserSubscribed
::
class
=>
[
\App\Listeners\EmailOwnerAboutSubscription
::
class
,
],
];
<?
php
namespace
App\Listeners
;
class
UserEventSubscriber
{
public
function
onUserSubscription
(
$event
)
{
// Handles the UserSubscribed event
}
public
function
onUserCancellation
(
$event
)
{
// Handles the UserCancelled event
}
public
function
subscribe
(
$events
)
{
$events
->
listen
(
\App\Events\UserSubscribed
::
class
,
'App\Listeners\UserEventSubscriber@onUserSubscription'
);
$events
->
listen
(
\App\Events\UserCancelled
::
class
,
'App\Listeners\UserEventSubscriber@onUserCancellation'
);
}
}
...
class
EventServiceProvider
extends
ServiceProvider
{
...
protected
$subscribe
=
[
\App\Listeners\UserEventSubscriber
::
class
];
}
...
use
Illuminate\Contracts\Broadcasting\ShouldBroadcast
;
class
UserSubscribed
extends
Event
implements
ShouldBroadcast
{
use
InteractsWithSockets
,
SerializesModels
;
public
$user
;
public
$plan
;
public
function
__construct
(
$user
,
$plan
)
{
$this
->
user
=
$user
;
$this
->
plan
=
$plan
;
}
public
function
broadcastOn
()
{
// String syntax
return
[
'users.'
.
$this
->
user
->
id
,
'admins'
];
// Channel object syntax
return
[
new
Channel
(
'users.'
.
$this
->
user
->
id
),
new
Channel
(
'admins'
),
// If it were a private channel: new PrivateChannel('admins'),
// If it were a presence channel: new PresenceChannel('admins'),
];
}
}
{
'user'
:
{
'id'
:
5
,
'name'
:
'Fred McFeely'
,
...
},
'plan'
:
'silver'
}
public
function
broadcastWith
()
{
return
[
'userId'
=>
$this
->
user
->
id
,
'plan'
=>
$this
->
plan
];
}
public
function
onQueue
()
{
return
'websockets-for-faster-processing'
}
...<script
src=
"https://js.pusher.com/3.1/pusher.min.js"
></script>
<script>
// Globally, perhaps; just a sample of how to get data in
var
App
=
{
'userId'
:
5
,
'pusherKey'
:
'your-pusher-api-key-here'
};
// Locally
var
pusher
=
new
Pusher
(
App
.
pusherKey
);
var
pusherChannel
=
pusher
.
subscribe
(
'users.'
+
App
.
userId
);
pusherChannel
.
bind
(
'App\\Events\\UserSubscribed'
,
(
data
)
=>
{
console
.
log
(
data
.
user
,
data
.
plan
);
});
</script>
// Run this right after you initialize echo
// Vue
Vue
.
http
.
interceptors
.
push
((
request
,
next
)
=>
{
request
.
headers
[
'X-Socket-Id'
]
=
Echo
.
socketId
();
next
();
});
// jQuery
$
.
ajaxSetup
({
headers
:
{
'X-Socket-Id'
:
Echo
.
socketId
()
}
});
broadcast
(
new
UserSubscribed
(
$user
,
$plan
))
->
toOthers
();
...
class
BroadcastServiceProvider
extends
ServiceProvider
{
public
function
boot
()
{
...
// Define how to authenticate a private channel
Broadcast
::
channel
(
'teams.*'
,
function
(
$user
,
$teamId
)
{
return
$user
->
team_id
==
$teamId
;
});
// Define how to authenticate a presence channel; return any data
// you want the app to have about the user in the channel
Broadcast
::
channel
(
'rooms.*'
,
function
(
$user
,
$roomId
)
{
if
(
$user
->
rooms
->
contains
(
$roomId
))
{
return
[
'name'
=>
$user
->
name
];
}
});
var
pusher
=
new
Pusher
(
App
.
pusherKey
,
{
authEndpoint
:
'/broadcasting/auth'
});
...
<
script
src
=
"https://js.pusher.com/3.1/pusher.min.js"
></
script
>
<
script
>
// Globally, perhaps; just a sample of how to get data in
var
App
=
{
'userId'
:
{{
auth
()
->
user
()
->
id
}},
'pusherKey'
:
'your pusher key here'
};
// Locally
var
pusher
=
new
Pusher
(
App
.
pusherKey
,
{
authEndpoint
:
'/broadcasting/auth'
});
// Private channel
var
privateChannel
=
pusher
.
subscribe
(
'private-teams.1'
);
privateChannel
.
bind
(
'App\\Events\\UserSubscribed'
,
(
data
)
=>
{
console
.
log
(
data
.
user
,
data
.
plan
);
});
// Presence channel
var
presenceChannel
=
pusher
.
subscribe
(
'presence-rooms.5'
);
console
.
log
(
presenceChannel
.
members
);
</
script
>
npm install pusher-js --save npm install laravel-echo --save
const
elixir
=
require
(
'laravel-elixir'
);
elixir
(
mix
=>
{
mix
.
webpack
(
'app.js'
);
});
import
Echo
from
"laravel-echo"
window
.
Echo
=
new
Echo
({
broadcaster
:
'pusher'
,
key
:
'your-pusher-key'
});
// Add your Echo bindings here
<meta
name=
"csrf-token"
content=
"{{ csrf_token() }}"
>
<script
src=
"/js/app.js"
></script>
var
currentTeamId
=
5
;
// Likely set elsewhere
Echo
.
channel
(
'teams.'
+
currentTeamId
)
.
listen
(
'UserSubscribed'
,
(
data
)
=>
{
console
.
log
(
data
);
});
Echo
.
channel
(
'teams.'
+
currentTeamId
)
.
listen
(
'UserSubscribed'
,
(
data
)
=>
{
console
.
log
(
data
);
})
.
listen
(
'UserCanceled'
,
(
data
)
=>
{
console
.
log
(
data
);
});
var
currentTeamId
=
5
;
// Likely set elsewhere
Echo
.
private
(
'teams.'
+
currentTeamId
)
.
listen
(
'UserSubscribed'
,
(
data
)
=>
{
console
.
log
(
data
);
});
var
currentTeamId
=
5
;
// Likely set elsewhere
Echo
.
join
(
'teams.'
+
currentTeamId
)
.
here
((
members
)
=>
{
console
.
log
(
members
);
});
var
currentTeamId
=
5
;
// Likely set elsewhere
Echo
.
join
(
'teams.'
+
currentTeamId
)
.
then
((
members
)
=>
{
// runs when you join
console
.
table
(
members
);
})
.
joining
((
joiningMember
,
members
)
=>
{
// runs when another member joins
console
.
table
(
joiningMember
);
})
.
leaving
((
leavingMember
,
members
)
=>
{
// runs when another member leaves
console
.
table
(
leavingMember
);
});
Echo
.
private
(
'App.User.'
+
userId
)
.
notification
((
notification
)
=>
{
console
.
log
(
notification
.
type
);
});
* * * * * php /home/myapp.com/artisan schedule:run >> /dev/null 2>&
1
// app/Consoles/Kernel.php
public
function
schedule
(
$schedule
)
{
$schedule
->
call
(
function
()
{
dispatch
(
new
CalculateTotals
);
})
->
everyMinute
();
}
$schedule
->
command
(
'scores:tally --reset-cache'
)
->
everyMinute
();
$schedule
->
exec
(
'/home/myapp.com/bin/build.sh'
)
->
everyMinute
();
$schedule
->
call
(
function
()
{
// Runs once a week on Sunday at 23:50
})
->
weekly
()
->
sundays
()
->
at
(
'23:50'
);
Command | Description |
---|---|
// Both run weekly on Sunday at 23:50
$schedule
->
command
(
'do:thing'
)
->
weeklyOn
(
0
,
'23:50'
);
$schedule
->
command
(
'do:thing'
)
->
weekly
()
->
sundays
()
->
at
(
'23:50'
);
// Run once per hour, weekdays, 8am-5pm
$schedule
->
command
(
'do:thing'
)
->
weekdays
()
->
hourly
()
->
when
(
function
()
{
return
date
(
'H'
)
>=
8
&&
date
(
'H'
)
<=
17
;
});
// Run once per hour, weekdays, 8am-5pm using new Laravel 5.3 "between"
$schedule
->
command
(
'do:thing'
)
->
weekdays
()
->
hourly
()
->
between
(
'8:00'
,
'17:00'
);
$schedule
->
command
(
'do:thing'
)
->
everyThirtyMinutes
()
->
skip
(
function
()
{
return
app
(
'SkipDetector'
)
->
shouldSkip
();
});
$schedule
->
command
(
'do:thing'
)
->
everyMinute
()
->
withoutOverlapping
();
$schedule
->
command
(
'do:thing'
)
->
daily
()
->
sendOutputTo
(
$filePath
);
$schedule
->
command
(
'do:thing'
)
->
daily
()
->
appendOutputTo
(
$filePath
);
$schedule
->
command
(
'do:thing'
)
->
daily
()
->
sendOutputTo
(
$filePath
)
->
emailOutputTo
(
'me@myapp.com'
);
$schedule
->
command
(
'do:thing'
)
->
daily
()
->
pingBefore
(
$beforeUrl
)
->
thenPing
(
$afterUrl
);
$schedule
->
command
(
'do_thing'
)
->
daily
()
->
before
(
function
()
{
// Prepare
})
->
after
(
function
()
{
// Cleanup
});
public
function
test_changing_number_of_subscriptions_crunches_reports
()
{
$this
->
expectsJobs
(
App\Jobs\CrunchReports
::
class
);
...
}
use
Illuminate\
public
function
test_changing_subscriptions_triggers_crunch_job
()
{
...
Bus
::
assertDispatched
(
CrunchReports
::
class
,
function
(
$e
)
{
return
$e
->
subscriptions
->
contains
(
5
);
});
// Also can use assertNotDispatched
}
public
function
test_usersubscribed_event_fires
()
{
$this
->
expectsEvents
(
App\Events\UserSubscribed
::
class
);
...
}
public
function
test_usersubscribed_event_fires
()
{
...
Event
::
assertFired
(
UserSubscribed
::
class
,
function
(
$e
)
{
return
$e
->
user
->
=
'user-who-subscribed@mail.com'
;
});
// Also can use assertNotFired()
}
public
function
test_something_subscription_related
()
{
$this
->
withoutEvents
();
...
}
array_first($array, $closure, $default = null)
$people
=
[
[
'email'
=>
'm@me.com'
,
'name'
=>
'Malcolm Me'
],
[
'email'
=>
'j@jo.com'
,
'name'
=>
'James Jo'
]
];
$value
=
array_first
(
$people
,
function
(
$key
,
$person
)
{
return
$person
[
'email'
]
==
'j@jo.com'
;
});
array_get($array, $key, $default = null)
$array
=
[
'owner'
=>
[
'address'
=>
[
'line1'
=>
'123 Main St.'
]]];
$line1
=
array_get
(
$array
,
'owner.address.line1'
,
'No address'
);
$line2
=
array_get
(
$array
,
'owner.address.line2'
);
array_has($array, $key)
$array
=
[
'owner'
=>
[
'address'
=>
[
'line1'
=>
'123 Main St.'
]]];
if
(
array_has
(
$array
,
'owner.address.line2'
))
{
// Do stuff
}
array_pluck($array, $key, $indexKey)
$array
=
[
[
'owner'
=>
[
'id'
=>
4
,
'name'
=>
'Tricia'
]],
[
'owner'
=>
[
'id'
=>
7
,
'name'
=>
'Kimberly'
]],
];
$array
=
array_pluck
(
$array
,
'owner.name'
);
// Returns ['Tricia', 'Kimberly'];
$array
=
array_pluck
(
$array
,
'owner.name'
,
'owner.id'
);
// Returns [4 => 'Tricia', 7 => 'Kimberly'];
e($string)
e
(
'<script>do something nefarious</script>'
);
// Returns <script>do something nefarious</script>
starts_with($haystack, $needle)
, ends_with($haystack, $needle)
, and str_contains($haystack, $needle)
if
(
starts_with
(
$url
,
'https'
))
{
// Do something
}
if
(
ends_with
(
$abstract
,
'...'
))
{
// Do something
}
if
(
str_contains
(
$description
,
'1337 h4x0r'
))
{
// Run away
}
str_limit($string, $numCharacters, $concatenationString = '...')
$abstract
=
str_limit
(
$loremIpsum
,
30
);
// Returns "Lorem ipsum dolor sit amet, co..."
$abstract
=
str_limit
(
$loremIpsum
,
30
,
"…"
);
// Returns "Lorem ipsum dolor sit amet, co…"
str_is($pattern, $string)
str_is
(
'*.dev'
,
'myapp.dev'
);
// true
str_is
(
'*.dev'
,
'myapp.dev.co.uk'
);
// false
str_is
(
'*dev*'
,
'myapp.dev'
);
// true
str_is
(
'*myapp*'
,
'www.myapp.dev'
);
// true
str_is
(
'my*app'
,
'myfantasticapp'
);
// true
str_is
(
'my*app'
,
'myapp'
);
// true
public
function
is
(
$pattern
,
$value
)
{
if
(
$pattern
==
$value
)
return
true
;
$pattern
=
preg_quote
(
$pattern
,
'#'
);
$pattern
=
str_replace
(
'\*'
,
'.*'
,
$pattern
);
return
(
bool
)
preg_match
(
'#^'
.
$pattern
.
'\z#u'
,
$value
);
}
str_random($length)
$hash
=
str_random
(
64
);
// Sample: J40uNWAvY60wE4BPEWxu7BZFQEmxEHmGiLmQncj0ThMGJK7O5Kfgptyb9ulwspmh
str_slug($string, $separator = '-')
str_slug
(
'How to Win Friends and Influence People'
);
// Returns 'how-to-win-friends-and-influence-people'
app_path($append = '')
app_path
();
// Returns /home/forge/myapp.com/app
base_path($append = '')
base_path
();
// Returns /home/forge/myapp.com
config_path($append = '')
config_path
();
// Returns /home/forge/myapp.com/config
database_path($append = '')
database_path
();
// Returns /home/forge/myapp.com/database
storage_path($append = '')
storage_path
();
// Returns /home/forge/myapp.com/storage
action('Controller@method’, $params = [], $absolute = true)
<
a
href
=
"{{ action('PeopleController@index' }}"
>
See
all
People
</
a
>
// Returns <a href="http://myapp.com/people">See all People</a>
<
a
href
=
"{{ action('PeopleController@show', ['id' => 3] }}"
>
See
Person
#3</a>
// or
<
a
href
=
"{{ action('PeopleController@show', [3] }}"
>
See
Person
#3</a>
// Returns <a href="http://myapp.com/people/3">See Person #3</a>
route($routeName, $params = [], $absolute = true)
<
a
href
=
"{{ route('people.show', ['id' => 3]) }}"
>
See
Person
#3</a>
// or
<
a
href
=
"{{ route('people.show', [3]) }}"
>
See
Person
#3</a>
<
a
href
=
"{{ action('people.show', ['id' => 3]) }}"
>
See
Person
#3</a>
// or
<
a
href
=
"{{ action('people.show', [3]) }}"
>
See
Person
#3</a>
// Returns <a href="http://myapp.com/people/3">See Person #3</a>
url($string)
and secure_url($string)
url
(
'people/3'
);
// Returns http://myapp.com/people/3
url
()
->
current
();
// Returns http://myapp.com/abc
url
()
->
full
();
// Returns http://myapp.com/abc?order=reverse
url
()
->
previous
();
// Returns http://myapp.com/login
// And many more methods available on the UrlGenerator...
elixir($filePath)
<
link
rel
=
"stylesheet"
href
=
"{{ elixir('css/app.css') }}"
>
// Returns something like /build/css/app-eb555e38.css
abort($code, $message, $headers)
, abort_unless($boolean, $code, $message, $headers)
, and abort_if($boolean, $code, $message, $headers)
public
function
controllerMethod
(
Request
$request
)
{
abort
(
403
,
'You shall not pass'
);
abort_unless
(
$request
->
has
(
'magicToken'
),
403
);
abort_if
(
$request
->
user
()
->
isBanned
,
403
);
}
auth()
$user
=
auth
()
->
user
();
if
(
auth
()
->
check
())
{
// Do something
}
back()
Route
::
get
(
'post'
,
function
()
{
...
if
(
$condition
)
{
return
back
();
}
});
collect($array)
$collection
=
collect
([
'Rachel'
,
'Hototo'
]);
config($key)
$defaultDbConnection
=
config
(
'database.default'
);
csrf_field()
and csrf_token()
<form>
{{ csrf_field() }}</form>
// or<form>
<input
type=
"hidden"
name=
"_token"
value=
"{{ csrf_token() }}"
>
</form>
dd($variable...)
...
dd
(
$var1
,
$var2
,
$state
);
// Why is this not working???
env($key, $default = null)
$key
=
env
(
'API_KEY'
,
''
);
// config/services.php
return
[
'bugsnag'
=>
[
'key'
=>
env
(
'BUGSNAG_API_KEY'
)
]
];
// in controller, or whatever
$bugsnag
=
new
Bugsnag
(
config
(
'services.bugsnag.key'
));
dispatch($job)
dispatch
(
new
EmailAdminAboutNewUser
(
$user
));
event($event)
event
(
new
ContactAdded
(
$contact
));
factory($entityClass)
$contact
=
factory
(
App\Contact
::
class
)
->
make
();
old($key, $default = null)
<
input
name
=
"name"
value
=
"{{ old('value', 'Your name here') }}"
redirect($path)
Route
::
get
(
'post'
,
function
()
{
...
return
redirect
(
'home'
);
});
response($body, $status, $headers)
return
response
(
'OK'
,
200
,
[
'X-Header-Greatness'
=>
'Super great'
]);
return
response
()
->
json
([
'status'
=>
'success'
],
200
);
view($viewPath)
Route
::
get
(
'home'
,
function
()
{
return
view
(
'home'
);
// Gets /resources/views/home.blade.php
});
$users
=
[
...
];
$admins
=
[];
foreach
(
$users
as
$user
)
{
if
(
$user
[
'status'
]
==
'admin'
)
{
$user
[
'name'
]
=
$user
[
'first'
]
.
' '
.
$user
[
'last'
];
$admins
[]
=
$user
;
}
}
return
$admins
;
$users
=
[
...
];
return
array_map
(
function
(
$user
)
{
$user
[
'name'
]
=
$user
[
'first'
]
.
' '
.
$user
[
'last'
];
return
$user
;
},
array_filter
(
$users
,
function
(
$user
)
{
return
$user
[
'status'
]
==
'admin'
;
}));
$users
=
collect
([
...
]);
return
$users
->
filter
(
function
(
$user
)
{
return
$user
[
'status'
]
==
'admin'
;
})
->
map
(
function
(
$user
)
{
$user
[
'name'
]
=
$user
[
'first'
]
.
' '
.
$user
[
'last'
];
return
$user
;
});
$users
=
[
...
]
$countAdmins
=
collect
(
$users
)
->
filter
(
function
(
$user
)
{
return
$user
[
'status'
]
==
'admin'
})
->
count
();
$users
=
[
...
];
$greenTeamPoints
=
collect
(
$users
)
->
filter
(
function
(
$user
)
{
return
$user
->
team
==
'green'
;
})
->
sum
(
'points'
);
all()
and toArray()
$users
=
User
::
all
();
$users
->
toArray
();
/* Returns
[
['id' => '1', 'name' => 'Agouhanna'],
...
]
*/
$users
->
all
();
/* Returns
[
Eloquent Object { id : 1, name: 'Agouhanna' },
...
]
*/
filter()
and reject()
$users
=
collect
([
...
]);
$admins
=
$users
->
filter
(
function
(
$user
)
{
return
$user
->
isAdmin
;
});
$paidUsers
=
$user
->
reject
(
function
(
$user
)
{
return
$user
->
isTrial
;
});
where()
$users
=
collect
([
...
]);
$admins
=
$users
->
where
(
'role'
,
'admin'
);
first()
and last()
$users
=
collect
([
...
]);
$owner
=
$users
->
first
(
function
(
$user
)
{
return
$user
->
isOwner
;
});
$firstUser
=
$users
->
first
();
$lastUser
=
$users
->
last
();
each()
$users
=
collect
([
...
]);
$users
->
each
(
function
(
$user
)
{
dispatch
(
new
EmailUserAThing
(
$user
));
});
map()
$users
=
collect
([
...
]);
$users
=
$users
->
map
(
function
(
$user
)
{
return
[
'name'
=>
$user
[
'first'
]
.
' '
.
$user
[
'last'
],
'email'
=>
$user
[
'email'
]
];
});
reduce()
$users
=
collect
([
...
]);
$points
=
$users
->
reduce
(
function
(
$carry
,
$user
)
{
return
$carry
+
$user
[
'points'
]
},
0
);
// Start with a carry of 0
pluck()
$users
=
collect
([
...
]);
$emails
=
$users
->
pluck
(
'email'
)
->
toArray
();
chunk()
and take()
$users
=
collect
([
...
]);
$rowsOfUsers
=
$users
->
chunk
(
3
);
// Separates into groups of 3
$topThree
=
$users
->
take
(
3
);
// Pulls the first 3
groupBy()
$users
=
collect
([
...
]);
$usersByRole
=
$users
->
groupBy
(
'role'
);
/* Returns:
[
'member' => [...],
'admin' => [...]
]
*/
$heroes
=
collect
([
...
]);
$heroesByAbilityType
=
$heroes
->
groupBy
(
function
(
$hero
)
{
if
(
$hero
->
canFly
()
&&
$hero
->
isInvulnerable
())
{
return
'Kryptonian'
;
}
if
(
$hero
->
bitByARadioactiveSpider
())
{
return
'Spidermanesque'
;
}
if
(
$hero
->
color
===
'green'
&&
$hero
->
likesSmashing
())
{
return
'Hulk-like'
;
}
return
'Generic'
;
});
reverse()
and shuffle()
$numbers
=
collect
([
1
,
2
,
3
]);
$numbers
->
reverse
()
->
toArray
();
// [3, 2, 1]
$numbers
->
shuffle
()
->
toArray
();
// [2, 3, 1]
sort()
, sortBy()
, and sortByDesc()
$sortedNumbers
=
collect
([
1
,
7
,
6
,
4
])
->
sort
()
->
toArray
();
// [1, 4, 6, 7]
$users
=
collect
([
...
]);
// Sort an array of users by their 'email' property
$users
->
sortBy
(
'email'
);
// Sort an array of users by their 'email' property
$users
->
sortBy
(
function
(
$user
,
$key
)
{
return
$user
[
'email'
];
});
count()
and isEmpty()
$numbers
=
collect
([
1
,
2
,
3
]);
$numbers
->
count
();
// 3
$numbers
->
isEmpty
();
// false
avg()
and sum()
collect
([
1
,
2
,
3
])
->
sum
();
// 6
collect
([
1
,
2
,
3
])
->
avg
();
// 2
$users
=
collect
([
...
]);
$sumPoints
=
$users
->
sum
(
'points'
);
$avgPoints
=
$users
->
avg
(
'points'
);