Learninglaravel5 5thedition
Learninglaravel5 5thedition
of
Contents
Part
1
About
This
Book 1.1
Requirements 1.1.1
What
You
Will
Get 1.1.2
Book
Structure 1.1.3
Feedback 1.1.4
Translation 1.1.5
Book
Status,
Changelog
and
Contributors 1.1.6
Changelog 1.1.7
Part
2
Chapter
1
-
Installing
Laravel 2.1
Introducing
CLI
(Command
Line
Interface) 2.1.1
CLI
for
MAC
OSX 2.1.1.1
CLI
for
Windows 2.1.1.2
CLI
for
Linux 2.1.1.3
Installing
Laravel
Using
Homestead 2.1.2
What
is
Homestead? 2.1.2.1
How
to
install
Homestead? 2.1.2.2
Configure
Homestead 2.1.2.3
Launching
Homestead 2.1.2.4
Installing
Laravel 2.1.2.5
Checking
Laravel
version 2.1.2.6
Updating
Homestead
box 2.1.3
2
Updating
Homestead
using
Git 2.1.4
Generate
new
application
key 2.1.5
Part
3
Chapter
2:
Building
Our
First
Website 3.1
Exploring
Laravel
structure 3.1.1
Understand
the
routes
directory 3.1.2
Changing
Laravel
home
page 3.1.3
Adding
more
pages
to
our
first
website 3.1.4
Create
our
first
controller 3.1.4.1
Using
our
first
controlle 3.1.4.2
Create
other
pages 3.1.4.3
Integrating
Twitter
Bootstrap 3.1.5
Using
Bootstrap
CDN 3.1.5.1
Using
Precompiled
Bootstrap
Files 3.1.5.2
Using
Bootstrap
Source
Code
(Sass
or
Less) 3.1.5.3
Introducing
Laravel
Mix 3.1.5.4
Adding
Twitter
Bootstrap
components 3.1.6
Learning
Blade
templates 3.1.7
Creating
a
master
layout 3.1.7.1
Extending
the
master
layout 3.1.7.2
Using
other
Bootstrap
themes 3.1.8
Refine
our
website
layouts 3.1.9
Changing
the
navbar 3.1.10
Changing
the
home
page 3.1.11
Chapter
2
Summary 3.1.12
Chapter
2
Source
Code 3.1.13
3
Part
4
Chapter
3
-
Building
A
Support
Ticket
System 4.1
What
do
we
need
to
get
started? 4.1.1
What
will
we
build? 4.1.2
Laravel
Database
Configuration 4.1.3
Create
a
database 4.1.4
Default
database
information 4.1.4.1
Create
a
database
using
the
CLI 4.1.4.2
Create
a
database
on
Mac 4.1.4.3
Create
a
database
on
Windows 4.1.4.4
Using
Migrations 4.1.5
Meet
Laravel
Artisan 4.1.5.1
Understand
Schema
to
write
migrations 4.1.5.2
Create
a
new
Eloquent
model 4.1.6
Create
a
page
to
submit
tickets 4.1.7
Create
a
view
to
display
the
submit
ticket
form 4.1.7.1
Create
a
new
controller
for
the
tickets 4.1.8
Introducing
HTTP
Requests 4.1.9
Install
Laravel
Collective
packages 4.1.10
Install
a
package
using
Composer 4.1.10.1
Create
a
service
provider
and
aliases 4.1.10.2
How
to
use
HTML
package 4.1.11
Submit
the
form
data 4.1.12
Using
.env
file 4.1.13
What
is
the
.env
file? 4.1.13.1
How
to
edit
it? 4.1.13.2
Insert
data
into
the
database 4.1.14
View
all
tickets 4.1.15
4
View
a
single
ticket 4.1.16
Using
a
helper
function 4.1.17
Edit
a
ticket 4.1.18
Delete
a
ticket 4.1.19
Sending
an
email 4.1.20
Sending
emails
using
Gmail 4.1.20.1
Sending
emails
using
Sendinblue 4.1.20.2
Sending
a
test
email 4.1.20.3
Sending
an
email
when
there
is
a
new
ticket 4.1.20.4
Reply
to
a
ticket 4.1.21
Create
a
new
comments
table 4.1.21.1
Introducing
Eloquent:
Relationships 4.1.21.2
Create
a
new
Comment
model 4.1.21.3
Create
a
new
comments
controller 4.1.21.4
Create
a
new
CommentFormRequest 4.1.21.5
Create
a
new
reply
form 4.1.21.6
Display
the
comments 4.1.21.7
Chapter
3
Summary 4.1.22
Chapter
3
Source
Code 4.1.23
Part
5
Chapter
4
-
Building
A
Blog
Application 5.1
What
do
we
need
to
get
started? 5.1.1
What
will
we
build? 5.1.1.1
Building
a
user
registration
page 5.1.1.2
Creating
a
login
page 5.1.1.3
Add
authentication
throttling
to
your
application 5.1.1.4
Building
an
Admin
area 5.1.2
5
List
all
users 5.1.2.1
Using
named
route 5.1.3
All
about
Middleware 5.1.4
Creating
a
new
middleware 5.1.5
Adding
roles
and
permission
to
our
app
using
laravel-permission 5.1.6
Create
a
new
role 5.1.6.1
Assign
roles
to
users 5.1.6.2
Restrict
access
to
Manager
users 5.1.7
Create
an
admin
dashboard
page 5.1.8
Create
a
new
post 5.1.9
Create
a
Many-to-Many
relation 5.1.10
Create
and
view
categories 5.1.10.1
Select
categories
when
creating
a
post 5.1.10.2
View
and
edit
posts 5.1.11
Display
all
posts 5.1.11.1
Edit
a
post 5.1.11.2
Display
all
blog
posts 5.1.12
Display
a
single
blog
post 5.1.13
Using
Polymorphic
Relations 5.1.13.1
Seeding
our
database 5.1.14
Localization 5.1.15
Chapter
4
Summary 5.1.16
Part
6
Chapter
5
-
Deploying
Our
Laravel
Applications 6.1
Deploying
your
apps
on
shared
hosting
services 6.1.1
Deploying
on
Godaddy
shared
hosting 6.1.1.1
Deploying
your
apps
using
DigitalOcean 6.1.2
6
Deploy
a
new
Ubuntu
server 6.1.2.1
Install
MySQL
Server 6.1.2.2
Install
Nginx,
PHP
and
other
packages 6.1.2.3
Install
Laravel 6.1.2.4
Possible
Errors 6.1.2.5
Take
a
snapshot
of
your
application 6.1.2.6
Little
tips 6.1.2.7
Chapter
5
Summary 6.1.3
7
About
This
Book
About
This
Book
Learning
Laravel
5:
Building
Practical
Applications
is
the
easiest
way
to
learn
web
development
using
Laravel.
Throughout
5
chapters,
instructor
Nathan
Wu
will
teach
you
how
to
build
many
real-world
applications
from
scratch.
This
bestseller
is
also
completely
about
you.
It
has
been
structured
very
carefully,
teaching
you
all
you
need
to
know
from
installing
your
Laravel
5
app
to
deploying
it
to
a
live
server.
When
you
have
completed
this
book
you
will
have
created
a
dynamic
website
and
have
a
good
knowledge
to
become
a
good
web
developer.
We
first
start
with
the
basics.
You
will
learn
some
main
concepts
and
create
a
simple
website.
After
that
we
progress
to
building
more
advanced
web
applications.
Learn
by
doing!
If
you
are
looking
for
a
genuinely
effective
book
that
helps
you
to
build
your
next
amazing
applications,
this
is
the
number
one
book
for
you.
Requirements
The
projects
in
this
book
are
intended
to
help
people
who
have
grasped
the
basics
of
PHP
and
HTML
to
move
forward,
developing
more
complex
projects,
using
Laravel
advanced
techniques.
The
fundamentals
of
the
PHP
are
not
covered,
you
will
need
to:
Have
a
basic
knowledge
of
PHP,
HTML,
CSS.
Love
Laravel,
like
we
do.
What
You
Will
Get
Lifetime
access
to
the
online
book.
(Read
70%
of
the
book
for
FREE!)
Digital
books:
PDF,
MOBI,
EPUB
(Premium
Only)
Full
source
code
(Premium
Only)
8
About
This
Book
Access
new
chapters
of
the
book
while
it's
being
written
(Premium
Only)
A
community
of
80000+
students
learning
together.
Amazing
bundles
and
freebies
to
help
you
become
a
successful
developer.
iPhone,
iPad
and
Android
Accessibility.
Book
Structure
Chapter
1
-
Installing
Laravel
There
are
many
ways
to
install
Laravel.
In
this
chapter,
you
will
learn
how
to
setup
Laravel
Homestead
(a
Vagrant-based
virtual
machine),
and
run
your
Laravel
projects
on
it.
Chapter
2
-
Building
Our
First
Website
This
book
is
meant
to
help
you
build
the
skills
to
create
web
applications
as
quickly
and
reliably
as
possible.
We
present
you
with
four
projects
in
various
states
of
completion
to
explain
and
practice
the
various
concepts
being
presented.
Our
first
app,
which
is
a
simple
website,
will
walk
you
through
the
structure
of
a
Laravel
app,
and
show
some
main
concepts
of
Laravel.
You
will
also
create
a
good
template
for
our
next
applications.
Chapter
3
-
Building
A
Support
Ticket
System
After
having
a
good
template,
we
will
start
building
a
support
ticket
system
to
learn
some
Laravel
features,
such
as
Eloquent
ORM,
Eloquent
Relationships,
Migrations,
Requests,
Laravel
Collective,
sending
emails,
etc.
While
the
project
design
is
simple,
it
provides
an
excellent
way
to
explore
Laravel.
You
will
also
know
how
to
construct
your
app
structure
the
right
way.
Chapter
4
-
Building
A
Blog
Application
9
About
This
Book
Throughout
the
projects
in
this
book
up
to
this
point,
we've
learned
many
things.
It's
time
to
use
our
skills
to
build
a
complete
blog
system.
You
will
learn
to
make
an
admin
control
panel
to
create
and
manage
your
posts,
users,
roles,
permissions,
etc.
Chapter
5
-
Deploying
Our
Laravel
Applications
Finally,
we
learn
how
to
create
our
own
web
server
and
deploy
our
Laravel
app
to
it.
Launching
your
first
Laravel
5
application
is
that
easy!
Feedback
Feedback
from
our
readers
is
always
welcome.
Let
us
know
what
you
liked
or
may
have
disliked.
Simply
send
an
email
to
support@learninglaravel.net.
We're
always
here.
Translation
We're
also
looking
for
translators
who
can
help
to
translate
our
book
to
other
languages.
Feel
free
to
contact
us
at
support@learninglaravel.net.
Here
is
a
list
of
our
current
translators:
List
of
Translators
Book
Status,
Changelog
and
Contributors
You
can
always
check
the
book
status,
changelog
and
view
the
list
of
contributors
at:
Book
Status
Changelog
10
About
This
Book
Contributors
Translators
Changelog
Current
Version
Latest
version
the
book:
Version:
5.0
(5th
Edition)
Status:
Complete.
The
book
now
supports
Laravel
5.6
Updated:
May
8,
2018
11
Chapter
1
-
Installing
Laravel
Chapter
1
-
Installing
Laravel
There
are
many
ways
to
install
Laravel.
We
can
install
Laravel
directly
on
our
main
machine,
or
we
can
use
all-in-one
server
stacks
such
as
MAMP,
XAMPP,
etc.
We
have
a
huge
selection
of
ways
to
choose.
In
this
book,
I
will
show
you
the
most
popular
one:
Laravel
Homestead.
Introducing
CLI
(Command
Line
Interface)
If
you
haven't
heard
about
CLI,
Terminal
or
Git,
this
section
is
for
you.
If
you
know
how
to
use
the
CLI
already,
you
may
skip
this
section.
Working
with
Laravel
requires
a
lot
of
interactions
with
the
CLI,
thus
you
will
need
to
know
how
to
use
it.
CLI
for
MAC
OSX
Luckily,
on
Mac,
you
can
find
a
good
CLI
called
Terminal
at
/Applications/Utilities.
Most
of
what
you
do
in
the
Terminal
is
enter
specific
text
strings,
then
press
Return
to
execute
them.
Alternatively,
you
can
use
iTerms
2.
CLI
for
Windows
Unfortunately,
the
default
CLI
for
Windows
(cmd.exe)
is
not
good,
you
may
need
another
one.
The
most
popular
one
called
Git
Bash.
You
can
download
and
install
it
here:
http://msysgit.github.io
Most
of
what
you
do
in
Git
Bash
is
enter
specific
text
strings,
then
press
Enter
to
execute
them.
Alternatively,
you
may
use
Cygwin.
12
Chapter
1
-
Installing
Laravel
CLI
for
Linux
On
Linux,
the
CLI
is
called
Terminal
or
Konsole.
If
you
know
how
to
install
and
use
Linux,
I
guess
you've
known
how
to
use
the
CLI
already.
Installing
Laravel
Using
Homestead
What
is
Homestead?
Nowadays,
many
developers
are
using
a
virtual
machine
(VM)
to
develop
dynamic
websites
and
applications.
You
can
run
a
web
server,
a
database
server
and
all
your
scripts
on
that
virtual
machine.
You
can
create
many
VM
instances
and
work
on
various
projects.
If
you
don't
want
any
VM
anymore,
you
can
safely
delete
it
without
affecting
anything.
You
can
even
re-create
the
VM
in
minutes!
We
call
this:
"Virtualization."
There
are
many
options
for
virtualization,
but
the
most
popular
one
is
VirtualBox
from
Oracle.
VirtualBox
will
help
us
to
install
and
run
many
virtual
machines
as
we
like
on
our
Windows,
Mac,
Linux
or
Solaris
operating
systems.
After
that,
we
will
use
a
tool
called
Vagrant
to
manage
and
configure
our
virtual
development
environments.
In
2014,
Taylor
Otwell
-
the
creator
of
Laravel
-
has
introduced
Homestead.
Homestead
is
a
Vagrant
based
Virtual
Machine
(VM)
and
it
is
based
on
Ubuntu.
It
includes
everything
we
need
to
start
developing
Laravel
applications.
That
means,
when
we
install
Homestead,
we
have
a
virtual
server
that
has
PHP,
Nginx,
databases
and
other
packages.
We
can
start
creating
our
Laravel
application
right
away.
Here
is
a
list
of
included
software:
Ubuntu
16.04
Git
PHP
7.1
Nginx
MySQL
MariaDB
13
Chapter
1
-
Installing
Laravel
Sqlite3
Postgres
Composer
Node
(With
Yarn,
Bower,
Grunt,
and
Gulp)
Redis
Memcached
Beanstalkd
Mailhog
ngrok
You
may
check
out
the
Homestead
Documentation
at:
https://laravel.com/docs/master/homestead
How
to
install
Homestead?
In
May
2015,
the
Laravel
official
documentation
has
been
updated.
The
recommended
way
to
install
Homestead
is
using
Git.
There
are
three
steps
to
install
Homestead
using
this
method.
Step
1:
Install
VirtualBox
Step
2:
Install
Vagrant
Step
3:
Install
Homestead
Let's
start
by
installing
VirtualBox
and
Vagrant
first.
Step
1
-
Installing
VirtualBox
First,
we
need
to
go
to:
https://www.virtualbox.org/wiki/Downloads
Choose
a
VirtualBox
for
your
platform
and
install
it.
Make
sure
that
you
download
the
correct
version
for
your
operating
system.
The
stable
release
is
version
5.1.4.
You
can
use
a
newer
version
if
you
want,
but
if
you
have
any
problems,
try
to
use
this
version.
14
Chapter
1
-
Installing
Laravel
If
you're
using
Windows,
double
click
the
.exe
setup
file
to
install
VirtualBox.
If
you're
using
Mac,
simply
open
the
VirtualBox
.dmg
file
and
click
on
the
.pkg
file
to
install.
Step
2
-
Installing
Vagrant
The
next
step
is
to
install
Vagrant.
Please
go
to:
http://www.vagrantup.com/downloads.html
Note:
The
stable
release
is
version
1.9.2,
which
can
be
found
at
https://releases.hashicorp.com/vagrant/1.9.2/.
You
may
use
a
newer
version,
but
if
you
encounter
any
error,
try
to
reinstall
version
1.9.2.
If
you're
using
Mac,
download
the
.dmg
file
->
Open
the
downloaded
file
->
Click
on
the
Vagrant.pkg
file
to
install
it.
15
Chapter
1
-
Installing
Laravel
If
you
still
don't
know
how
to
install,
there
is
an
official
guide
on
Vagrant
website:
http://docs.vagrantup.com/v2/installation
Step
3
-
Install
Homestead
(Using
Git
Clone)
You
can
install
Homestead
just
by
cloning
the
Homestead
Repository.
You
will
need
to
install
Git
first
if
you
don't
have
it
on
your
system.
Note:
if
you
don't
know
how
to
run
a
command,
please
read
Introducing
CLI
(Command
Line
Interface)
section.
Install
Git
on
Mac
The
easiest
way
is
to
install
the
Xcode
Command
Line
Tools.
You
can
do
this
by
simply
running
this
command:
xcode-select --install
Click
Install
to
download
Command
Line
Tools
package.
16
Chapter
1
-
Installing
Laravel
Alternatively,
you
can
also
find
the
OSX
Git
installer
at
this
website:
http://git-scm.com/download/mac
Install
Git
on
Windows
You
can
download
GitHub
for
Windows
to
install
Git:
https://windows.github.com
Install
Git
on
Linux/Unix
You
can
install
Git
by
running
this
command:
If
you’re
on
a
Debian-based
distribution,
use
this:
For
more
information
and
other
methods,
you
can
see
this
guide:
https://git-scm.com/book/en/v2/Getting-Started-Installing-Git
When
you
have
Git
installed.
Enter
the
following
command
to
your
Terminal
(or
Git
Bash):
Once
downloaded,
go
to
the
Homestead
directory
by
using
cd
command:
cd Homestead
Run
this
command
to
create
Homestead.yaml
file:
17
Chapter
1
-
Installing
Laravel
bash init.sh
The
Homestead.yaml
file
will
be
placed
in
the
Homestead
directory.
Open
it
with
a
text
editor
to
edit
it.
Note:
In
older
versions
of
Homestead,
the
Homestead.yaml
file
will
be
placed
in
your
~/.homestead
directory.
Please
note
that
the
~/.homestead
directory
is
hidden
by
default,
make
sure
that
you
can
see
hidden
files.
If
you
know
how
to
use
VI
or
VIM,
use
this
command
to
edit
the
file:
18
Chapter
1
-
Installing
Laravel
vi ~/Homestead/Homestead.yaml
Alternatively,
you
can
use
this
command
to
open
the
file
with
your
text
editor:
open ~/Homestead/Homestead.yaml
Note:
Your
system
path
may
be
different.
Try
to
find
Homestead.yaml.
Configure
Homestead
The
structure
of
the
Homestead.yaml
is
simple.
There
are
7
sections.
Let's
see
what
they
do.
First
section
-
Configure
VM
ip: "192.168.10.10"
memory: 2048
cpus: 1
provider: virtualbox
As
you
can
see,
we
can
configure
the
IP
address,
memory,
cpus
and
provider
of
our
VM.
This
section
is
not
important,
so
we
can
just
leave
it
as
it
is.
Second
and
third
section
-
Configure
SSH
authorize: ~/.ssh/id_rsa.pub
keys:
- ~/.ssh/id_rsa
Basically,
we
need
to
generate
an
SSH
key
for
Homestead
to
authenticate
the
user
and
connect
to
the
VM.
If
you're
working
with
Git,
you
may
have
an
SSH
key
already.
If
you
don't
have
it,
simply
run
this
command
to
generate
it:
19
Chapter
1
-
Installing
Laravel
The
command
will
generate
an
SSH
key
for
you
and
put
it
in
the
~/.ssh
directory
automatically,
you
don't
need
to
do
anything
else.
Fourth
section
-
Configure
shared
folder
We
use
folders
section
to
specify
the
directory
that
we
want
to
share
with
our
Homestead
environment.
If
we
add,
edit
or
change
any
files
on
our
local
machine,
the
files
will
be
updated
automatically
on
our
Homestead
VM.
folders:
- map: ~/Code
to: /home/vagrant/Code
We
can
see
that
the
~/Code
directory
has
been
put
there
by
default.
This
is
where
we
put
all
the
files,
scripts
on
our
local
machine.
Feel
free
to
change
the
link
if
you
want
to
put
your
codes
elsewhere.
The
/home/vagrant/Code
is
a
path
to
the
Code
directory
on
our
VM.
Usually,
we
don't
need
to
change
it.
Fifth
section
-
Map
a
domain
sites:
- map: homestead.test
to: /home/vagrant/Code/Laravel/public
This
section
allows
us
to
map
a
domain
to
a
folder
on
our
VM.
For
example,
we
can
map
homestead.test
to
the
public
folder
of
our
Laravel
project,
and
then
we
can
easily
access
our
Laravel
app
via
this
address:
"http://homestead.test".
Note:
You
can
use
the
.app
extension
if
you
like
(For
example,
http://homestead.app).
However,
if
you're
using
the
latest
version
of
Google
Chrome,
you
should
change
the
.app
extension
to
.test
extension.
Remember
that,
when
we
add
any
domain,
we
must
edit
the
hosts
file
on
our
local
machine
to
redirect
requests
to
our
Homestead
environment.
On
Linux
or
Mac,
you
can
find
the
hosts
file
at
etc/hosts
or
/private/etc/hosts .
You
can
edit
the
hosts
file
using
this
command:
20
Chapter
1
-
Installing
Laravel
If
you
know
how
to
use
VI
or
VIM,
use
this
command
to
edit
the
file:
On
Windows,
you
can
find
the
hosts
file
at
C:\Windows\System32\drivers\etc\hosts.
After
opening
the
file,
you
need
to
add
this
line
at
the
end
of
the
file:
192.168.10.10 homestead.test
Done!
When
we
launch
Homestead,
we
can
access
the
site
via
this
address.
http://homestead.test
Please
note
that
we
can
change
the
address
( homestead.test )
to
whatever
we
like.
All
sites
will
be
accessible
by
HTTP
via
port
8000
and
HTTPS
via
port
44300
by
default
(Homestead
port).
Sixth
section
-
Configure
database
databases:
- homestead
This
is
the
database
name
of
our
VM.
As
usual,
we
just
leave
it
as
it
is.
Seventh
section
-
Add
custom
variables
variables:
- key: APP_ENV
value: local
If
we
want
to
add
some
custom
variables
to
our
VM,
we
can
add
them
here.
It's
not
important,
so
let's
move
to
the
next
fun
part.
21
Chapter
1
-
Installing
Laravel
Launching
Homestead
Once
we
have
edited
Homestead.yaml
file,
cd
to
the
Homestead
directory,
run
this
command
to
boot
our
virtual
machine:
vagrant up
It
may
take
a
few
minutes...
If
you
see
this
error:
It
means
that
you
don't
have
Code
directory
on
your
main
machine.
You
can
create
one,
or
change
the
link
to
any
folder
that
you
like.
Executing
this
command
to
create
a
new
Code
folder:
To
prevent
possible
errors
when
creating
Laravel,
try
to
set
right
permissions
for
the
Code
folder
by
running:
If
everything
is
going
fine,
we
should
see:
22
Chapter
1
-
Installing
Laravel
Now
we
can
access
our
VM
using:
vagrant ssh
Note:
If
it
asks
for
a
password,
type
vagrant .
To
make
sure
that
everything
is
ok,
run
ls
command:
If
you
can
see
the
Code
directory
there,
you
have
Homestead
installed
correctly!
Excellent!
Let's
start
installing
Laravel!
Installing
Laravel
When
you
have
installed
Homestead,
create
a
new
Laravel
app
is
so
easy!
As
I've
mentioned
before,
the
Code
directory
is
where
we
will
put
our
Laravel
apps.
Let's
go
there!
cd Code
You
should
notice
that
the
directory
is
empty.
There
are
two
methods
to
install
Laravel.
Install
Laravel
Via
Laravel
Installer
23
Chapter
1
-
Installing
Laravel
This
method
is
recommended.
It's
newer
and
faster.
You
should
use
this
method
to
create
your
Laravel
application.
First,
we
need
to
use
Composer
to
download
the
Laravel
installer.
Once
downloaded,
you
can
create
a
new
Laravel
project
by
using
this
command:
Laravel
Installer
will
download
the
latest
Laravel
version
and
install
it.
To
install
a
specific
Laravel
version,
you
may
use
this
command
instead:
This
command
is
used
to
download
Laravel
5.6.
Note:
If
the
latest
version
of
Laravel
is
5.6,
you
can't
run
this
command.
You
may
install
Laravel
5.5
instead
by
using
the
--5.5
flag.
It
is
recommended
to
use
Laravel
5.6
to
learn
the
basics
of
Laravel
Framework.
You
can
upgrade
to
a
newer
version
later.
24
Chapter
1
-
Installing
Laravel
You're
free
to
change
the
nameOfYourSite
to
whatever
you
like,
but
remember
to
edit
the
sites
section
of
Homestead.yaml
to
match
your
site's
name.
For
instance,
in
Homestead.yaml,
we
specify
the
name
of
our
app
is
Laravel
sites:
- map: homestead.test
to: /home/vagrant/Code/Laravel/public
We
will
need
to
run
this
command
to
create
a
new
Laravel
site
You
should
see
this:
If
you
see
this
error
when
using
the
laravel new
command:
We
have
to
edit
the
.bashrc
file,
type:
nano ~/.bashrc
Add
this
line
at
end
of
the
file:
alias laravel='~/.config/composer/vendor/bin/laravel'
Press
Ctrl + X ,
then
Y ,
then
Enter
to
exit
and
save
the
file.
Lastly,
run
this
command:
source ~/.bashrc
25
Chapter
1
-
Installing
Laravel
Now
you
should
be
able
to
create
a
new
Laravel
app
using:
You
should
see
this:
Next,
open
your
web
browser
and
go
to:
http://homestead.test
Congratulations!
You've
installed
Laravel!
It's
time
to
create
something
amazing!
Install
Laravel
using
composer
create-project
If
you
don't
like
to
use
Laravel
Installer,
or
you
have
any
problems
with
it,
feel
free
to
use
composer create-project
to
create
a
new
Laravel
app:
This
command
is
used
to
download
Laravel
5.6.15,
which
is
a
stable
version.
If
you
want
to
use
the
latest
version,
use:
26
Chapter
1
-
Installing
Laravel
Note:
It
is
recommended
to
use
Laravel
5.6
to
learn
the
basics
of
Laravel
Framework.
You
can
upgrade
to
a
newer
version
later.
You're
free
to
change
the
nameOfYourSite
to
whatever
you
like,
but
remember
to
edit
the
sites
section
of
Homestead.yaml
to
match
your
site's
name.
For
instance,
in
Homestead.yaml,
we
specify
the
name
of
our
app
is
Laravel
sites:
- map: homestead.test
to: /home/vagrant/Code/Laravel/public
We
will
need
to
run
this
command
to
create
Laravel
site
Alternatively,
we
can
create
a
new
Laravel
folder,
cd
to
it,
and
create
our
Laravel
app
there:
mkdir Laravel
cd Laravel
composer create-project laravel/laravel --prefer-dist
You
should
see
this:
Open
your
web
browser,
go
to:
http://homestead.test
27
Chapter
1
-
Installing
Laravel
Note:
if
you
cannot
access
the
site,
try
to
add
the
port
into
the
URL:
http://homestead.test:8000.
Congratulations!
You've
installed
Laravel!
It's
time
to
create
something
amazing!
Checking
Laravel
version
We
can
check
what
version
of
Laravel
that
we've
installed
by
simply
running
this
command
at
the
root
of
our
application:
A
line
will
be
printed
out:
As
you
see,
I'm
using
Laravel
5.6.15.
Important
note:
If
you're
not
using
Laravel
5.6,
please
download
and
install
Laravel
5.6
to
avoid
possible
errors.
28
Chapter
1
-
Installing
Laravel
Updating
Homestead
box
Sometimes,
when
we
run
the
vagrant up
command,
we
might
see
this
message:
As
you
may
have
noticed,
this
means
a
newer
version
of
Homestead
box
is
available.
We
can
update
the
box
by
running
this
command:
You'll
see
something
like
this:
Note:
Be
sure
to
backup
your
files
and
databases
first.
It
may
take
a
long
time
to
complete.
After
that,
vagrant ssh
into
your
Homestead
and
run:
If
it
asks
anything,
type
y .
Please
note
that
the
master
branch
(the
latest
version)
may
not
always
be
stable.
If
your
app
is
running
fine,
you
don't
have
to
update
Homestead.
Updating
Homestead
using
Git
29
Chapter
1
-
Installing
Laravel
If
you
want
to
upgrade
your
Homestead
to
the
latest
version
or
use
another
version
of
Homestead,
you
may
use
this
method.
First,
please
backup
the
Homestead.yaml
file
and
your
database
first
to
ensure
that
you
won't
lose
any
data.
Go
to
your
homestead
root
directory:
cd Homestead
Note:
Your
path
could
be
different.
Next,
run
this
command
to
get
a
list
of
Homestead
versions:
You'll
see
something
like
this:
After
that,
pick
the
version
that
you
like.
Currently,
the
newest
stable
version
is
v7.0.0 .
Run
these
commands
to
destroy
and
update
your
vagrant:
vagrant destroy
rm -rf .vagrant
vagrant up
Note:
You
might
need
to
download
and
install
the
latest
version
of
Vagrant.
30
Chapter
1
-
Installing
Laravel
Done!
You're
good
to
go!
Note:
In
this
book,
we'll
be
using
Homestead
v7.0.0
(which
is
a
stable
version),
so
please
use
the
same
version
to
avoid
possible
errors.
Generate
new
application
key
Sometimes,
you
might
see
this
error
when
generating
a
new
application:
To
fix
this,
you
just
need
to
update
the
Laravel
Installer
by
running
this
command:
After
that,
simply
generate
a
new
application
key:
This
should
fix
the
bug.
31
Chapter
2:
Building
Our
First
Website
Chapter
2:
Building
Our
First
Website
Now
that
we
know
how
to
install
Laravel,
let's
start
working
our
way
into
our
first
Laravel
website.
In
this
chapter,
you
will
learn
about
Laravel
structure,
routes,
Controllers,
Blade
templates,
Artisan
commands,
Elixir
and
many
basic
features
that
will
come
handy
when
building
Laravel
applications.
Exploring
Laravel
structure
I
assume
that
you've
installed
Laravel
at
~/Code/Laravel.
Let's
go
there
and
open
the
Laravel
directory.
32
Chapter
2:
Building
Our
First
Website
To
build
applications
using
Laravel,
you
will
need
to
understand
truly
Laravel.
Laravel
follows
MVC
(Model
View
Controller)
pattern,
so
if
you've
already
known
about
MVC,
everything
will
be
simple.
Don't
worry
if
you
don't
know
what
MVC
is,
you
will
get
to
know
soon.
As
you
may
have
seen,
every
time
you
visit
a
Laravel
app,
you'll
see
these
folders.
1.
app
2.
bootstrap
3.
config
4.
database
5.
public
6.
resources
33
Chapter
2:
Building
Our
First
Website
7.
routes
8.
storage
9.
tests
10.
vendor
I'm
not
going
to
tell
you
everything
about
them
right
now
because
I
know
that
it's
boring.
Trust
me.
But
we
have
to
take
a
quick
look
at
them
to
know
what
they
are,
anyway.
App
This
directory
holds
all
our
application's
logic.
We
will
put
our
controllers,
services,
filters,
commands
and
many
other
custom
classes
here.
Bootstrap
This
folder
has
some
files
that
are
used
to
bootstrap
Laravel.
The
cache
folder
is
also
placed
here.
Config
When
we
want
to
configure
our
application,
check
out
this
folder.
We
will
configure
database,
mail,
session,
etc.
here.
Database
As
the
name
implies,
this
folder
contains
our
database
migrations
and
database
seeders.
Public
The
public
folder
contains
the
application's
images,
CSS,
JS
and
other
public
files.
Resources
We
should
put
our
views
(.blade.php
files),
raw
files
and
other
localization
files
here.
Routes
All
our
route
files
will
be
stored
here.
We'll
learn
about
this
routes
directory
in
the
next
section.
34
Chapter
2:
Building
Our
First
Website
Storage
Laravel
will
use
this
folder
to
store
sessions,
caches,
templates,
logs,
etc.
Tests
This
folder
contains
the
test
files,
such
as
PHPUnit
files.
Vendor
Composer
dependencies
(such
as
Symfony
classes,
PHPUnit
classes,
etc.)
are
placed
here.
To
understand
more
about
Laravel
structure,
you
can
read
the
official
documentation
here:
https://laravel.com/docs/master/structure
Understand
the
routes
directory
One
of
the
most
important
features
of
Laravel
is
"routing".
What
does
it
mean?
Routing
means
that
you
will
tell
Laravel
to
get
URL
requests
and
assign
them
to
specific
actions
that
you
want.
For
instance,
when
someone
visits
homestead.test,
which
is
the
home
page
of
our
current
application,
Laravel
will
think:
"Oh,
this
guy
is
going
to
the
home
page,
I
need
to
display
something!"
We
usually
register
all
routes
in
the
routes.php
file,
but
since
Laravel
5.3,
the
routes.php
file
has
been
moved
to
the
new
routes
directory.
We
now
have
three
files:
web.php,
console.php
and
api.php.
Changing
Laravel
home
page
To
change
Laravel
home
page,
we
need
to
edit
the
web.php
file.
Let's
see
what's
inside
the
file.
routes/web.php
35
Chapter
2:
Building
Our
First
Website
Route::get('/', function () {
return view('welcome');
});
We
have
only
one
route
by
default.
This
route
tells
Laravel
to
return
the
welcome
view
when
someone
make
a
GET
request
to
our
root
URL
(which
represents
by
the
/).
So
if
we
want
to
edit
the
home
page,
we
need
to
modify
the
welcome
view.
What
is
view
and
where
is
the
welcome
view?
Views
contain
the
HTML
served
by
our
application.
A
simple
view
may
look
like
a
simple
HTML
file:
<html>
<body>
<p> A simple view </p>
</body
</html>
All
views
are
stored
at
the
resources/views
directory.
Go
to
the
views
folder,
find
a
file
called
welcome.blade.php.
It's
the
welcome
view.
Open
it:
resources/views/welcome.blade.php
<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
36
Chapter
2:
Building
Our
First
Website
background-color: #fff;
color: #636b6f;
font-family: 'Raleway', sans-serif;
font-weight: 100;
height: 100vh;
margin: 0;
}
.full-height {
height: 100vh;
}
.flex-center {
align-items: center;
display: flex;
justify-content: center;
}
.position-ref {
position: relative;
}
.top-right {
position: absolute;
right: 10px;
top: 18px;
}
.content {
text-align: center;
}
.title {
font-size: 84px;
}
.links > a {
color: #636b6f;
padding: 0 25px;
font-size: 12px;
font-weight: 600;
letter-spacing: .1rem;
text-decoration: none;
text-transform: uppercase;
}
.m-b-md {
margin-bottom: 30px;
}
</style>
</head>
<body>
<div class="flex-center position-ref full-height">
37
Chapter
2:
Building
Our
First
Website
@if (Route::has('login'))
<div class="top-right links">
@auth
<a href="{{ url('/home') }}">Home</a>
@else
<a href="{{ route('login') }}">Login</a>
<a href="{{ route('register') }}">Register</a>
@endauth
</div>
@endif
<div class="content">
<div class="title m-b-md">
Laravel
</div>
<div class="links">
<a href="https://laravel.com/docs">Documentation</a>
<a href="https://laracasts.com">Laracasts</a>
<a href="https://laravel-news.com">News</a>
<a href="https://forge.laravel.com">Forge</a>
<a href="https://github.com/laravel/laravel">GitHub</a>
</div>
</div>
</div>
</body>
</html>
This
welcome
view
is
used
to
display
the
home
page.
It
just
looks
like
a
basic
HTML
file!
I
assume
that
you've
already
known
HTML,
so
you
should
understand
the
content
of
this
file
clearly.
Tip:
If
you
don't,
w3schools
is
a
good
place
to
learn
HTML
and
PHP:
http://www.w3schools.com/html
It's
time
to
modify
the
home
page!
What
should
we
do?...
How
about
display
a
custom
quote?
Let's
replace
these
lines:
<div class="links">
<a href="https://laravel.com/docs">Documentation</a>
<a href="https://laracasts.com">Laracasts</a>
<a href="https://laravel-news.com">News</a>
38
Chapter
2:
Building
Our
First
Website
<a href="https://forge.laravel.com">Forge</a>
<a href="https://github.com/laravel/laravel">GitHub</a>
</div>
with:
Our
new
welcome
view
should
look
like
this:
<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
.full-height {
height: 100vh;
}
.flex-center {
align-items: center;
display: flex;
justify-content: center;
}
.position-ref {
position: relative;
}
.top-right {
39
Chapter
2:
Building
Our
First
Website
position: absolute;
right: 10px;
top: 18px;
}
.content {
text-align: center;
}
.title {
font-size: 84px;
}
.links > a {
color: #636b6f;
padding: 0 25px;
font-size: 12px;
font-weight: 600;
letter-spacing: .1rem;
text-decoration: none;
text-transform: uppercase;
}
.m-b-md {
margin-bottom: 30px;
}
</style>
</head>
<body>
<div class="flex-center position-ref full-height">
@if (Route::has('login'))
<div class="top-right links">
@auth
<a href="{{ url('/home') }}">Home</a>
@else
<a href="{{ route('login') }}">Login</a>
<a href="{{ route('register') }}">Register</a>
@endauth
</div>
@endif
<div class="content">
<div class="title m-b-md">
Laravel
</div>
</div>
</div>
</body>
</html>
40
Chapter
2:
Building
Our
First
Website
Note:
Laravel
welcome
view
is
changed
frequently.
If
your
view
is
different,
just
copy
the
code
above
to
create
a
new
welcome
view.
Save
the
file,
head
over
to
your
browser
and
run
homestead.test.
Awesome!
We
have
just
changed
our
home
page
by
changing
the
welcome.blade.php
template!
In
fact,
we
may
change
any
page
without
returning
a
view:
Modify
the
first
route:
routes/web.php
Route::get('/', function () {
return view('welcome');
});
to
Route::get('/', function()
{
return 'Welcome to our home page!';
});
41
Chapter
2:
Building
Our
First
Website
Amazing!
Right?
We
have
just
used
a
anonymous
function
to
change
our
home
page.
In
PHP,
we
called
this
function:
"Closure".
A
Closure
is
a
function
that
doesn't
have
a
name.
We
use
Closure
to
handle
"routing"
in
small
applications.
In
large
applications,
we
use
Controllers.
You
can
find
Controllers
documentation
here:
http://laravel.com/docs/master/controllers
It's
recommended
that
you
should
always
use
Controllers
because
Controllers
help
to
structure
your
code
easier.
For
instance,
you
may
group
all
user
actions
into
UserController,
all
post
actions
into
PostsController.
The
disadvantage
of
Controllers
is,
you
will
need
to
create
a
file
for
each
Controller,
thus
it
takes
a
bit
more
time.
42
Chapter
2:
Building
Our
First
Website
To
understand
what
Controllers
is,
we
will
be
creating
some
pages
using
Controllers.
Adding
more
pages
to
our
first
website
When
we
have
a
basic
understanding
of
how
we
can
edit
the
home
page,
adding
more
pages
is
easy.
Imagine
that
we're
going
to
build
a
website
to
introduce
the
Learning
Laravel
book.
Our
website
will
have
three
pages:
1.
Home
page.
2.
About
page.
3.
Contact
page.
Because
we
have
many
pages,
and
we
might
add
more
pages
to
our
website,
we
should
organize
all
our
pages
in
PagesController.
As
you've
noticed,
we
don't
have
the
PagesController
yet,
thus
we're
going
to
create
it.
Create
our
first
controller
There
are
two
methods
to
create
a
controller:
Create
a
controller
manually
To
start
off
with
things,
create
a
new
file
called
PagesController.php
with
your
favorite
text
editor
(PHPStorm,
Sublime
Text,
etc.).
Place
the
file
in
app/Http/Controllers/
directory.
Update
the
PagesController.php
file
to
look
like
this:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
43
Chapter
2:
Building
Our
First
Website
{
public function home()
{
return view('welcome');
}
}
Good
job!
You
now
have
PagesController
with
a
home
action.
You
may
notice
that
the
home
action
tells
Laravel
to
"return
the
welcome
view":
return view('welcome');
Create
a
controller
by
using
Artisan
Rather
than
manually
creating
a
controller,
we
can
use
Artisan
to
generate
it
automatically.
Artisan
is
Laravel
command
line
tool
that
helps
us
to
perform
tasks
that
we
hate
to
do
manually.
Using
Artisan,
we
can
create
models,
views,
controllers,
migrations
and
many
other
things.
You
have
known
how
to
use
Terminal
or
Git
Bash,
let's
create
a
controller
by
running
this
command:
Note:
vagrant
ssh
to
your
VM,
cd
to
Laravel
folder,
and
use
the
command
there.
Delete
the
old
controller
if
you've
created
it.
You'll
see:
By
default,
Laravel
creates
a
plain
controller:
44
Chapter
2:
Building
Our
First
Website
app/Http/Controllers/PagesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
Next,
let's
add
a
new
a
home
action:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
Alternatively,
you
can
use
this
command
to
generate
a
new
RESTful
PagesController:
Good
job!
You
now
have
PagesController
with
the
home
action.
You
may
notice
that
the
home
action
tells
Laravel
to
"return
the
welcome
view":
return view('welcome');
Using
our
first
controller
Cool!
When
you
have
PagesController,
the
next
thing
to
do
is
modifying
our
routes!
45
Chapter
2:
Building
Our
First
Website
Open
the
web.php
file.
Change
the
default
route
to:
routes/web.php
Route::get('/', 'PagesController@home');
This
route
tells
Laravel
to
execute
the
home
action
(which
can
be
found
in
PagesController)
when
someone
makes
a
GET
request
to
our
root
URL
(which
represents
by
the
/).
Well
done!
You've
just
displayed
the
front
page
using
your
own
controller!
Create
other
pages
Now
that
we
have
PagesController
class.
Adding
more
pages
is
not
difficult.
Suggestion:
How
about
trying
to
add
the
about
and
contact
page
yourself?
Edit
the
web.php
file.
Add
the
following
lines:
Route::get('/about', 'PagesController@about');
Route::get('/contact', 'PagesController@contact');
Open
PagesController,
add:
46
Chapter
2:
Building
Our
First
Website
Here
is
the
updated
PagesController.php
file:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
Next
you
will
want
to
create
about
view
and
contact
view.
Create
two
new
files
in
the
resources/views
directory
named
about.blade.php
and
contact.blade.php.
Finally,
add
the
following
contents
(copy
from
the
welcome
view)
to
each
file:
resources/views/about.blade.php
<html>
<head>
<title>About Page</title>
47
Chapter
2:
Building
Our
First
Website
text/css'>
<style>
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
color: #B0BEC5;
display: table;
font-weight: 100;
font-family: 'Lato';
}
.container {
text-align: center;
display: table-cell;
vertical-align: middle;
}
.content {
text-align: center;
display: inline-block;
}
.title {
font-size: 96px;
margin-bottom: 40px;
}
.quote {
font-size: 24px;
}
</style>
</head>
<body>
<div class="container">
<div class="content">
<div class="title">About Page</div>
<div class="quote">Our about page!</div>
</div>
</div>
</body>
</html>
resources/views/contact.blade.php
<html>
<head>
<title>Contact Page</title>
48
Chapter
2:
Building
Our
First
Website
<style>
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
color: #B0BEC5;
display: table;
font-weight: 100;
font-family: 'Lato';
}
.container {
text-align: center;
display: table-cell;
vertical-align: middle;
}
.content {
text-align: center;
display: inline-block;
}
.title {
font-size: 96px;
margin-bottom: 40px;
}
.quote {
font-size: 24px;
}
</style>
</head>
<body>
<div class="container">
<div class="content">
<div class="title">Contact Page</div>
<div class="quote">Our contact page!</div>
</div>
</div>
</body>
</html>
Save
these
changes,
go
to
homestead.test/about
and
homestead.test/contact:
49
Chapter
2:
Building
Our
First
Website
50
Chapter
2:
Building
Our
First
Website
Yayyyy!
We
have
created
the
about
and
contact
page
with
just
a
few
lines
of
code!
Now,
let's
create
a
home
view
for
our
homepage,
and
change
the
PagesController
to
use
it:
resources/views/home.blade.php
<html>
<head>
<title>Home Page</title>
<style>
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
color: #B0BEC5;
display: table;
font-weight: 100;
font-family: 'Lato';
51
Chapter
2:
Building
Our
First
Website
.container {
text-align: center;
display: table-cell;
vertical-align: middle;
}
.content {
text-align: center;
display: inline-block;
}
.title {
font-size: 96px;
margin-bottom: 40px;
}
.quote {
font-size: 24px;
}
</style>
</head>
<body>
<div class="container">
<div class="content">
<div class="title">Home Page</div>
<div class="quote">Our Home page!</div>
</div>
</div>
</body>
</html>
PagesControllers
Find:
Replace
with:
52
Chapter
2:
Building
Our
First
Website
Integrating
Twitter
Bootstrap
Nowadays,
the
most
popular
front-end
framework
is
Twitter
Bootstrap.
It's
free,
open
source
and
has
a
large
active
community.
I've
been
using
Bootstrap
for
all
projects.
Using
Twitter
Bootstrap,
we
can
quickly
develop
responsive,
mobile-ready
web
applications.
Millions
of
beautiful
and
popular
sites
across
the
world
are
built
with
Bootstrap.
In
this
section,
we
will
learn
how
to
integrate
Twitter
Bootstrap
into
our
Laravel
application.
You
can
get
Bootstrap
and
read
its
official
documentation
here:
https://getbootstrap.com/docs/3.3/getting-started/
Note:
We're
using
Bootstrap
3
in
this
book.
Bootstrap
4
is
just
released,
and
it's
not
stable
yet.
We
will
update
the
book
when
Bootstrap
4
is
stable.
Be
sure
to
subscribe
to
our
newsletter
to
get
the
latest
news.
There
are
many
ways
to
integrate
Twitter
Bootstrap.
You
can
install
it
using
Bootstrap
CDN,
Bower,
npm,
etc.
I'll
show
you
the
most
three
popular
methods:
1.
Using
Bootstrap
CDN
2.
Using
Precompiled
Bootstrap
Files
3.
Using
Bootstrap
Source
Code
(Sass
or
Less)
Using
Bootstrap
CDN
The
fastest
way
to
integrate
Twitter
Bootstrap
is
using
CDN.
Open
home.blade.php,
place
these
links
inside
the
head
tag
53
Chapter
2:
Building
Our
First
Website
<script src="//code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></sc
ript>
Done!
You
now
have
fully
integrated
Twitter
Bootstrap
into
our
website!
You
may
notice
that
we've
added
some
CSS
styles
and
Lato
font
into
our
home.blade.php
file
before.
Remove
those:
<style>
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
color: #B0BEC5;
display: table;
font-weight: 100;
font-family: 'Lato';
}
.container {
text-align: center;
display: table-cell;
vertical-align: middle;
}
.content {
text-align: center;
display: inline-block;
}
.title {
font-size: 96px;
margin-bottom: 40px;
}
.quote {
font-size: 24px;
}
</style>
and
54
Chapter
2:
Building
Our
First
Website
Here
is
our
new
home.blade.php:
<html>
<head>
<title>Home Page</title>
<script src="//code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js">
</script>
</head>
<body>
<div class="container">
<div class="content">
<div class="title">Home Page</div>
<div class="quote">Our Home page!</div>
</div>
</div>
</body>
</html>
Note:
The
bootstrap-theme.min.css
is
optional.
Using
Precompiled
Bootstrap
Files
Twitter
Bootstrap
is
built
using
Less
-
a
CSS
pre-processor.
Less
allows
us
to
use
variables,
mixins,
functions
and
other
techniques
to
enhance
CSS.
You
can
learn
more
about
Less
here:
http://lesscss.org
Unfortunately,
browsers
don't
understand
Less.
You
must
compile
all
Less
files
using
Less
compiler
to
produce
CSS
files.
Of
course,
you
have
to
learn
Less.
Luckily,
Bootstrap
has
provided
compiled
CSS,
JS
and
fonts
for
us.
We
can
download
and
use
them
without
worrying
about
the
Less
files.
Go
to:
https://getbootstrap.com/docs/3.3/getting-started/
Click
Download
Bootstrap
to
download
latest
compiled
Bootstrap
files.
55
Chapter
2:
Building
Our
First
Website
Uncompress
the
downloaded
.zip
file.
We
have
three
folders:
1.
css
2.
js
3.
fonts
Put
them
all
into
the
public
folder
of
your
app.
(~/Code/Laravel/public).
Note:
By
default,
Laravel
has
created
css
and
fonts
folder
for
us.
The
fonts
folder
also
contains
all
the
glyphicons
fonts.
When
you
visit
your
public
folder,
it
should
look
like
this:
To
load
Twitter
Bootstrap
framework
for
styling
our
home
page,
open
home.blade.php
and
place
these
links
inside
the
head
tag
56
Chapter
2:
Building
Our
First
Website
Twitter
Bootstrap
requires
jQuery
to
work
properly,
you
can
download
jQuery
here:
https://jquery.com/download
Put
the
jQuery
file
into
the
public
directory
as
well,
then
use
the
following
code
to
reference
it:
Or
you
can
just
use
jQuery
CDN
without
downloading
the
jQuery
file:
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
Note:
Your
jQuery
version
may
be
different.
Full
code:
Done!
You
now
have
fully
integrated
Twitter
Bootstrap
into
our
website!
We've
used
asset
function
to
link
CSS
and
JS
files
to
our
app.
You
can
also
use
the
asset
function
to
link
images,
fonts
and
other
public
files.
If
you
don't
want
to
use
asset
function,
you
can
use
relative
links
instead:
<script src="/js/jquery-3.2.1.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
You
may
notice
that
we've
added
some
CSS
styles
and
Lato
font
into
our
home.blade.php
file
before.
Remove
those:
<style>
body {
margin: 0;
padding: 0;
57
Chapter
2:
Building
Our
First
Website
width: 100%;
height: 100%;
color: #B0BEC5;
display: table;
font-weight: 100;
font-family: 'Lato';
}
.container {
text-align: center;
display: table-cell;
vertical-align: middle;
}
.content {
text-align: center;
display: inline-block;
}
.title {
font-size: 96px;
margin-bottom: 40px;
}
.quote {
font-size: 24px;
}
</style>
and
Here
is
our
new
home.blade.php:
<html>
<head>
<title>Home Page</title>
<script src="/js/jquery-3.2.1.min.js"></script>
<script src="{!! asset('js/bootstrap.min.js') !!}"></script>
</head>
<body>
<div class="container">
<div class="content">
<div class="title">Home Page</div>
58
Chapter
2:
Building
Our
First
Website
Note:
The
bootstrap-theme.min.css
file
is
optional.
Using
Bootstrap
Source
Code
(Sass
or
Less)
The
good
news
is,
Laravel
5.5
has
officially
supported
Sass.
Sass
files
are
placed
at
resources/assets/sass.
We'll
use
Laravel
Mix
to
automatically
compile
Sass
files
to
app.css
file.
To
load
Twitter
Bootstrap
framework
for
styling
our
home
page,
open
home.blade.php
and
place
these
links
inside
the
head
tag:
Done!
You
now
have
fully
integrated
Twitter
Bootstrap
into
your
website!
You
may
notice
that
we've
added
some
CSS
styles
and
Lato
font
into
our
home.blade.php
file
before.
Remove
those:
<style>
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
color: #B0BEC5;
display: table;
font-weight: 100;
font-family: 'Lato';
}
.container {
text-align: center;
display: table-cell;
vertical-align: middle;
}
.content {
59
Chapter
2:
Building
Our
First
Website
text-align: center;
display: inline-block;
}
.title {
font-size: 96px;
margin-bottom: 40px;
}
.quote {
font-size: 24px;
}
</style>
and
Here
is
our
new
home.blade.php:
<html>
<head>
<title>Home Page</title>
<link rel="stylesheet" href="/css/app.css">
<script src="/js/app.js"></script>
</head>
<body>
<div class="container">
<div class="content">
<div class="title">Home Page</div>
<div class="quote">Our Home page!</div>
</div>
</div>
</body>
</html>
Oh,
I've
mentioned
Laravel
Mix,
what
is
it?
Introducing
Laravel
Mix
One
of
the
best
Laravel
5
new
features
is
Laravel
Mix.
We
can
use
Laravel
Mix
to
compile
Sass
files,
Coffee
Scripts
or
automate
other
manual
tasks.
60
Chapter
2:
Building
Our
First
Website
Note:
Laravel
Mix
is
a
new
feature
of
Laravel
5.4+.
In
older
versions
of
Laravel,
we
have
Elixir,
which
is
pretty
similar.
Laravel
Mix
official
documentation
Basically,
Elixir
is
based
on
Webpack.
If
you
don't
know
about
Webpack
yet,
you
can
find
more
information
about
it
here:
Webpack
Official
Home
Page
To
use
Laravel
Mix,
we
must
have
NPM(Node
Package
Manager)
and
Node.js
installed.
Luckily,
Homestead
has
NPM
and
Node.js
by
default,
we
can
use
Laravel
Mix
right
away.
If
you
don't
use
Homestead,
you
have
to
install
Node.js
and
NPM.
Tip:
Actually,
you
should
run
Node.js/Laravel
Mix
directly
on
your
local
machine
(Windows,
Mac,
etc.).
It's
faster
and
less
buggy.
To
install
Node.js,
visit:
https://nodejs.org
Note:
Be
sure
to
use
Node.js
v7.5.0
or
newer.
The
direct
download
links
can
also
be
found
at:
https://nodejs.org/en/blog/release/v7.5.0
Follow
instructions
on
the
site,
you
should
have
installed
Node.js
easily.
You
may
check
the
version
of
Node.js
by
running:
node -v
You
may
check
the
version
of
NPM
by
running:
npm -v
The
last
step
is
to
install
Laravel
Mix.
Laravel
5
has
included
a
file
called
package.json.
You
use
this
file
to
install
Node
modules.
Open
the
file,
you
should
see:
package.json
61
Chapter
2:
Building
Our
First
Website
{
"private": true,
"scripts": {
"dev": "npm run development",
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpac
k.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.
js",
"watch": "npm run development -- --watch",
"watch-poll": "npm run watch -- --watch-poll",
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/web
pack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.conf
ig.js",
"prod": "npm run production",
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.
js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config
.js"
},
"devDependencies": {
"axios": "^0.18",
"bootstrap": "^4.0.0",
"popper.js": "^1.12",
"cross-env": "^5.1",
"jquery": "^3.2",
"laravel-mix": "^2.0",
"lodash": "^4.17.4",
"vue": "^2.5.7"
}
}
Do
you
see
the
laravel-mix
there?
Good!
Navigate
to
our
app
root
(~/Code/Laravel),
run
this
command
to
install
Laravel
Mix:
npm install
Note:
If
you
install
Node.js
on
your
local
machine,
you
should
run
this
command
directly
on
your
machine
(Windows,
macOS,
etc.).
Windows
system
users
may
need
to
run
this
command
instead:
Mac
Users
may
need
to
run
this
command
instead
(if
the
above
command
doesn't
work):
62
Chapter
2:
Building
Our
First
Website
It
may
take
a
while
to
download.
Be
patient.
63
Chapter
2:
Building
Our
First
Website
Once
complete,
there
is
a
new
folder
called
node_modules
in
our
app.
You
can
find
Laravel
Mix
and
other
Node.js
packages
here.
Running
first
Laravel
Mix
task
You
can
write
a
new
Mix
task
in
webpack.mix.js.
By
default,
you
can
find
a
Mix
task
that
compiles
app.sass
file
into
app.css,
and
bundles
all
JS
files
there:
mix.js('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css');
Feel
free
to
add
more
tasks
by
reading
the
official
Laravel
Mix
documentation:
https://laravel.com/docs/master/mix
To
execute
your
Mix
task,
run
this
command:
By
running
the
task,
Laravel
will
automatically
compile
the
app.sass
file
and
bundle
all
JS
files.
The
output
files
can
be
found
in
your
public
directory.
Adding
Twitter
Bootstrap
components
Cool!
Now
we
can
add
Twitter
Bootstrap
components
into
our
website.
There
are
many
reusable
Bootstrap
components
built
to
provide
navbars,
labels,
dropdowns,
panels,
etc.
You
can
see
a
full
list
of
components
here:
https://getbootstrap.com/docs/3.3/components/
64
Chapter
2:
Building
Our
First
Website
To
use
the
components,
you
can
copy
the
example
codes,
and
paste
them
into
your
application.
For
instance,
we
can
add
Twitter
Bootstrap
navbar
to
our
app
by
adding
these
codes
to
home.blade.php:
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link <span class="sr-only">(current)</span></a>
</li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" ari
a-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Separated link</a></li>
<li class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left" role="search">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" ari
a-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
65
Chapter
2:
Building
Our
First
Website
Here
is
our
new
home.blade.php
after
adding
the
navbar:
home.blade.php
<html>
<head>
<title>Home Page</title>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js">
</script>
</head>
<body>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link <span class="sr-only">(current)</s
pan></a></li>
<li><a href="#">Link</a></li>
66
Chapter
2:
Building
Our
First
Website
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="b
utton" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Separated link</a></li>
<li class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left" role="search">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="b
utton" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="container">
<div class="content">
<div class="title">Home Page</div>
<div class="quote">Our Home page!</div>
</div>
</div>
</body>
</html>
It's
time
to
refresh
our
browser:
67
Chapter
2:
Building
Our
First
Website
Responsive
meta
tag
To
make
our
site
more
responsive
to
display
well
across
all
devices,
we
should
put
a
responsive
meta
tag
in
the
head
section
of
our
template:
Find:
<head>
Add
below:
Note:
this
step
is
optional,
but
it's
recommended
to
include
the
tag
when
using
Bootstrap.
68
Chapter
2:
Building
Our
First
Website
Learning
Blade
templates
It's
time
to
learn
about
Blade!
Blade
is
an
official
Laravel's
templating
engine.
It's
very
powerful,
but
it
has
very
simple
syntax.
We
use
Blade
to
build
layouts
for
our
Laravel
applications.
Blade
view
files
have
.blade.php
file
extension.
The
home
view
and
other
views
that
we've
been
using
are
Blade
templates.
Usually,
we
put
all
Blade
templates
in
resources/views
directory.
The
great
thing
is,
we
can
use
plain
PHP
code
in
a
Blade
view.
All
Blade
expressions
begin
with
@ .
For
example:
@section ,
@if ,
@for ,
etc.
Blade
also
supports
all
PHP
loops
and
conditions:
@if ,
@elseif ,
@else ,
@for ,
@foreach ,
@while ,
etc.
For
instance,
you
can
write
a
if else
statement
in
Blade
like
this:
@if ($product == 1)
{!! $product->name !!}
@else
There is no product!
@endif
Equivalent
PHP
code:
if ($product ==1) {
echo $product->name;
} else {
echo("There is no product!");
}
To
understand
Blade's
features,
we
will
use
Blade
to
build
our
first
website's
layout.
Creating
a
master
layout
The
typical
web
application
has
a
master
layout.
The
layout
consists
header,
footer,
sidebar,
etc.
Using
a
master
layout,
we
can
easily
place
one
element
on
every
view.
For
instance,
we
can
use
the
same
header
and
footer
for
all
pages.
It
helps
to
make
our
code
look
clearer
and
save
our
time
a
lot.
69
Chapter
2:
Building
Our
First
Website
To
get
started,
we
will
create
a
master
layout
called
master.blade.php
resources/views/master.blade.php
<html>
<head>
<title> @yield('title') </title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/b
ootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/b
ootstrap-theme.min.css">
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js">
</script>
</head>
<body>
@include('shared.navbar')
@yield('content')
</body>
</html>
This
view
look
likes
the
home
view,
but
we've
changed
something.
Let's
see
the
code
line
by
line.
Instead
of
putting
a
title
here,
we
use
@yield
directive
to
get
the
title
from
another
section.
@include('shared.navbar')
We
use
@include
directive
to
include
other
Blade
views.
You
may
notice
that
we've
embedded
a
view
called
navbar
here.
However,
we
don't
have
the
navbar
view
yet,
let's
create
a
shared
directory
and
put
navbar.blade.php
there.
Copy
the
Twitter
Bootstrap
navbar
and
put
it
into
the
navbar.blade.php:
resources/views/shared/navbar.blade.php
70
Chapter
2:
Building
Our
First
Website
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link <span class="sr-only">(current)</s
pan></a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="b
utton" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Separated link</a></li>
<li class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left" role="search">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="b
utton" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</li>
71
Chapter
2:
Building
Our
First
Website
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
Note:
You
may
change
the
shared
folder
name
to
partials,
embed
or
whatever
you
like.
@yield('content')
As
you
see
it's
really
convenient
for
us
to
not
display
the
content
of
any
pages
here.
We
simply
use
@yield
directive
to
embed
a
section
called
content
from
other
views.
Great!
You've
just
created
a
master
layout!
Extending
the
master
layout
Now
we
can
change
the
home
view
to
extend
our
master
layout.
resources/views/home.blade.php
@extends('master')
@section('title', 'Home')
@section('content')
<div class="container">
<div class="content">
<div class="title">Home Page</div>
<div class="quote">Our Home page!</div>
</div>
</div>
@endsection
As
you
can
observe
we
use
@extends
directive
to
inherit
our
master
layout.
To
set
the
title
for
our
home
page,
we
use
@section
directive.
@section('title', 'Home')
It's
the
"short
way".
If
we
have
a
long
content,
we
can
use
@section
and
@endsection
to
inject
our
content
into
the
master
layout.
72
Chapter
2:
Building
Our
First
Website
@section('content')
<div class="container">
<div class="content">
<div class="title">Home Page</div>
<div class="quote">Our Home page!</div>
</div>
</div>
@endsection
Refresh
your
browser,
you
should
see
the
same
home
page,
but
this
time
our
code
look
much
cleaner.
Using
the
same
technique,
we
can
easily
change
the
about
and
contact
page:
about.blade.php
@extends('master')
@section('title', 'About')
@section('content')
<div class="container">
<div class="content">
<div class="title">About Page</div>
73
Chapter
2:
Building
Our
First
Website
contact.blade.php
@extends('master')
@section('title', 'Contact')
@section('content')
<div class="container">
<div class="content">
<div class="title">Contact Page</div>
<div class="quote">Our contact page!</div>
</div>
</div>
@endsection
Using
other
Bootstrap
themes
74
Chapter
2:
Building
Our
First
Website
The
best
thing
about
Twitter
Bootstrap
is,
it
has
many
themes
for
you
to
"switch".
If
you
don't
like
the
default
Bootstrap
theme,
you
can
easily
find
another
one
to
use.
Here
are
some
popular
themes
for
Bootstrap:
1.
http://bootswatch.com
2.
http://fezvrasta.github.io/bootstrap-material-design
3.
http://designmodo.github.io/Flat-UI
In
this
section,
we're
going
to
apply
Bootstrap
Material
Design
theme
for
our
website.
This
Bootstrap
theme
will
"provide
an
easy
way
to
use
the
new
Material
Design
guidelines
by
Google".
If
you're
using
an
Android
phone,
you
may
have
seen
Material
Design
already.
You
can
find
out
more
about
Material
Design
here:
http://www.google.com/design/spec/material-design/introduction.html
This
section
is
designed
to
test
your
knowledge
of
the
Laravel
5
structure
and
views.
I'll
additionally
show
you
how
to
manage
your
assets.
Feel
free
to
use
other
themes
if
you
want.
We
also
build
a
good
template
to
use
for
all
applications
of
this
book.
First,
head
over
to:
https://github.com/FezVrasta/bootstrap-material-design/archive/v0.5.10.zip
Note:
All
releases
can
be
found
at:
https://github.com/FezVrasta/bootstrap-
material-design/releases
Download
the
zip
file.
Uncompressed
it.
Go
to
the
dist
directory.
If
you're
using
version
0.5.10,
you
should
only
see
two
folders:
1.
css
2.
js
Copy
css
and
js
directory
to
our
Laravel
public
folder.
(~/Code/Laravel/public).
Open
master.blade.php,
modify
its
content
to
look
like
this:
<html>
<head>
<title> @yield('title') </title>
75
Chapter
2:
Building
Our
First
Website
</head>
<body>
@include('shared.navbar')
@yield('content')
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></sc
ript>
<script src="/js/ripples.min.js"></script>
<script src="/js/material.min.js"></script>
<script>
$(document).ready(function() {
// This command is used to initialize some elements and make them work properly
$.material.init();
});
</script>
</body>
</html>
Congratulations!
You
now
have
a
beautiful
Material
Design
website!
76
Chapter
2:
Building
Our
First
Website
Refine
our
website
layouts
Currently,
the
site
looks
messy.
We're
going
to
change
a
few
things
and
re-design
all
views
to
make
our
application
look
better
and
professional.
Changing
the
navbar
Open
navbar.blade.php,
and
update
it:
77
Chapter
2:
Building
Our
First
Website
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">Learning Laravel</a>
</div>
78
Chapter
2:
Building
Our
First
Website
Changing
the
home
page
Open
home.blade.php,
and
update
it:
@extends('master')
@section('title', 'Home')
@section('content')
<div class="container">
<div class="row banner">
<div class="col-md-12">
<div class="text-center">
<img src="https://learninglaravel.net/img/LearningLaravel5_cover0.
79
Chapter
2:
Building
Our
First
Website
</div>
</div>
</div>
@endsection
We
now
have
a
cool
responsive
home
page.
80
Chapter
2:
Building
Our
First
Website
81
Chapter
2:
Building
Our
First
Website
You
may
try
to
navigate
to
the
about
and
contact
page
to
see
if
everything
is
working
correctly.
Feel
free
to
change
minor
things
like
images,
contents,
colors,
and
fonts
to
your
liking.
Chapter
2
Summary
Good
job!
We
now
have
a
fully
responsive
template!
We
will
use
this
template
to
build
other
applications
to
learn
more
about
Laravel.
In
this
chapter,
you've
learned
many
things:
1.
You've
known
about
Laravel
structure,
how
Laravel
works
and
where
to
put
the
files.
2.
You've
learned
about
Laravel
routes.
3.
You've
learned
Controllers.
Now
you
can
be
able
to
create
web
pages
using
Controllers.
4.
You've
known
what
Blade
is.
It's
easy
to
create
Blade
templates
for
your
next
amazing
applications.
5.
You've
known
how
to
integrate
Twitter
Bootstrap,
CSS,
JS
and
apply
different
Bootstrap
themes.
6.
You've
known
Laravel
Mix,
how
to
install
Node.js
and
how
to
create
a
basic
Mix
task.
In
the
next
chapter,
we
will
learn
how
to
create
a
basic
CRUD
(Create,
Read,
Update,
Delete)
application
to
learn
more
about
Laravel's
features.
Chapter
2
Source
Code
You
can
view
and
download
the
source
code
at:
Learning
Laravel
5
Book:
Chapter
2
Source
Code
82
Chapter
2:
Building
Our
First
Website
83
Chapter
3
-
Building
A
Support
Ticket
System
Chapter
3:
Building
A
Support
Ticket
System
In
this
chapter,
we
will
build
a
support
ticket
system
to
learn
about
Laravel
main
features,
such
as
Eloquent
ORM,
Eloquent
Relationships,
Migrations,
Requests,
Laravel
Collective,
sending
emails,
etc.
While
the
project
design
is
simple,
it
provides
an
excellent
way
to
learn
Laravel.
What
do
we
need
to
get
started?
I
assume
that
you
have
followed
the
instructions
provided
in
the
previous
chapter
and
you've
created
a
basic
website.
You
will
need
that
basic
application
to
start
building
the
support
ticket
system.
What
will
we
build?
We'll
start
by
laying
down
the
basic
principle
behind
the
application's
creation,
and
a
summary
of
how
it
works.
Our
ticket
system
is
simple:
When
users
visit
the
contact
page,
they
will
be
able
to
submit
a
ticket
to
contact
us.
Once
they've
created
a
ticket,
the
system
will
send
us
an
email
to
let
us
know
that
there
is
a
new
ticket.
The
ticket
system
automatically
generates
a
unique
link
to
let
us
access
the
ticket.
We
can
view
all
the
tickets.
We
can
be
able
to
reply,
edit,
change
tickets'
status
or
delete
them.
Let's
start
building
things!
84
Chapter
3
-
Building
A
Support
Ticket
System
Laravel
Database
Configuration
Our
application
requires
a
database
to
work.
Laravel
supports
many
database
platforms,
including:
1.
MySQL
2.
SQLite
3.
PostgreSQL
4.
SQL
Server
5.
MariaDB
Note:
A
database
is
a
collection
of
data.
We
use
database
to
store,
manage
and
update
our
data
easier.
The
great
thing
is,
we
can
choose
any
of
them
to
develop
our
applications.
In
this
book,
we
will
use
MySQL.
You
can
configure
databases
using
database.php
file,
which
is
placed
in
the
config
directory.
config/database.php
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/
/*
|--------------------------------------------------------------------------
| Database Connections
|--------------------------------------------------------------------------
|
| Here are each of the database connections setup for your application.
| Of course, examples of configuring each database platform that is
85
Chapter
3
-
Building
A
Support
Ticket
System
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
],
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
'pgsql' => [
'driver' => 'pgsql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
'sslmode' => 'prefer',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '1433'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
86
Chapter
3
-
Building
A
Support
Ticket
System
],
/*
|--------------------------------------------------------------------------
| Migration Repository Table
|--------------------------------------------------------------------------
|
| This table keeps track of all the migrations that have already run for
| your application. Using this information, we can determine which of
| the migrations on disk haven't actually been run in the database.
|
*/
/*
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer set of commands than a typical key-value systems
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/
'redis' => [
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
],
];
Try
to
read
the
comments
to
understand
how
to
use
this
file.
The
most
two
important
settings
are:
1.
default:
You
can
set
the
type
of
database
you
would
like
to
use
here.
By
default,
it
is
mysql.
If
you
want
to
use
a
different
database,
you
can
set
it
to:
pgsql,
sqlite.
87
Chapter
3
-
Building
A
Support
Ticket
System
2.
connections:
Fill
your
database
authentication
credentials
here.
The
env()
function
is
used
to
retrieve
configuration
variables
(DB_HOST,
DB_DATABASE,
DB_USERNAME,
DB_PASSWORD)
from
.env
file.
If
it
can't
find
any
variables,
it
will
use
the
value
of
the
function's
second
parameter
(localhost,
forge).
If
you
use
Homestead,
Laravel
has
created
a
homestead
database
for
you
already.
If
you
don't
use
Homestead,
you
will
need
to
create
a
database
manually.
Laravel
uses
PHP
Data
Objects
(PDO).
When
we
execute
a
Laravel
SQL
query,
rows
are
returned
in
a
form
of
a
stdClass
object.
For
instance,
we
may
access
our
data
using:
$user->name
MySQL
Strict
Mode
In
new
versions
of
Laravel,
MySQL
Strict
Mode
is
enabled
by
default.
Information:
If
you
want
to
know
what
Strict
Mode
is,
check
out
this
article:
Upgrading
to
MySQL
5.7?
Beware
of
the
new
STRICT
mode
In
some
cases,
you
might
want
to
turn
the
Strict
Mode
off .
Here's
how
we
can
do
it:
Find:
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
Change
strict
from
true
to
false :
88
Chapter
3
-
Building
A
Support
Ticket
System
Note:
If
you
encounter
some
database
errors,
be
sure
to
try
to
turn
the
Strict
Mode
off
first.
It's
still
safe
to
turn
the
Strict
Mode
off.
Create
a
database
Note:
You
need
a
basic
understanding
of
SQL
to
develop
Laravel
applications.
At
least,
you
should
know
how
to
read,
update,
modify
and
delete
a
database
and
its
tables.
If
you
don't
know
anything
about
database,
a
good
place
to
learn
is:
http://www.w3schools.com/sql
To
develop
multiple
applications,
we
will
need
multiple
databases.
In
this
section,
we
will
learn
how
to
create
a
database.
Default
database
information
Laravel
has
created
a
homestead
database
for
us.
To
connect
to
MySQL
or
Postgres
database,
you
can
use
these
settings:
host:
127.0.0.1
database:
homestead
username:
homestead
password:
secret
port:
33060
(MySQL)
or
54320
(Postgres)
Create
a
database
using
the
CLI
You
can
easily
create
a
new
database
via
the
command
line.
First,
vagrant
ssh
to
your
Homestead.
Use
this
command
to
connect
to
MySQL:
mysql -u homestead -p
When
it
asks
for
the
password,
use
secret.
89
Chapter
3
-
Building
A
Support
Ticket
System
To
create
a
new
database,
use
this
command:
Feel
free
to
change
your_database_name
to
your
liking.
To
see
all
databases,
run
this
command:
show databases;
Finally,
you
may
leave
MySQL
using
this
command:
exit
Even
though
we
can
easily
create
a
new
database
via
the
CLI,
we
should
use
a
Graphical
User
Interface
(GUI)
to
manage
databases
easily.
Create
a
database
on
Mac
On
Mac,
the
most
popular
GUI
to
manage
databases
is
Sequel
Pro.
It's
free,
fast
and
very
easy
to
use.
You
can
download
it
here:
www.sequelpro.com
After
that,
you
can
connect
to
MySQL
or
Postgres
database
using
database
credentials
in
the
Default
database
information
section.
90
Chapter
3
-
Building
A
Support
Ticket
System
Once
connected,
you
can
easily
create
a
new
database
by
clicking
Choose
Database...
and
then
Add
Database.
Alternatively,
you
may
use
Navicat.
Create
a
database
on
Windows
On
Windows,
three
popular
GUIs
for
managing
databases
are:
SQLYog
(Free)
https://www.webyog.com/product/sqlyog
SQLYog
has
a
free
open-source
version.
You
can
download
it
here:
https://github.com/webyog/sqlyog-community
Click
the
Download
SQLyog
Community
Version
to
download.
HeidiSQL
(Free)
http://www.heidisql.com
91
Chapter
3
-
Building
A
Support
Ticket
System
Navicat
http://www.navicat.com
Feel
free
to
choose
to
use
any
GUI
that
you
like.
After
that,
you
can
connect
to
MySQL
or
Postgres
database
using
database
credentials
in
the
Default
database
information
section.
Using
Migrations
One
of
the
best
features
of
Laravel
is
Migrations.
Whether
you're
working
with
a
team
or
alone,
you
may
need
to
find
a
way
to
keep
track
your
database
schema.
Laravel
Migrations
is
the
right
way
to
go.
Laravel
uses
migration
files
to
know
what
we
change
in
our
database.
The
great
thing
is,
you
can
easily
revert
or
apply
changes
to
your
applications
by
just
running
a
command.
For
example,
we
can
use
this
command
to
reset
the
database:
It's
easy,
right?
This
feature
is
very
useful.
You
should
always
use
Migrations
to
build
your
application's
database
schema.
You
can
find
Migrations
documentation
at:
http://laravel.com/docs/master/migrations
Meet
Laravel
Artisan
Artisan
is
Laravel's
CLI
(Command
Line
Interface).
We
often
use
Artisan
commands
to
develop
our
Laravel
applications.
For
instance,
we
use
Artisan
commands
to
generate
migration
files,
seed
our
database,
see
the
application
namespace,
etc.
You've
used
Artisan
before!
In
the
last
chapter,
we've
used
Artisan
to
generate
controllers:
92
Chapter
3
-
Building
A
Support
Ticket
System
Artisan
official
docs:
http://laravel.com/docs/master/artisan
To
see
a
list
of
available
Artisan
commands,
go
to
your
application's
root,
run:
You
should
see
all
commands:
Usage:
command [options] [arguments]
Options:
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
--env[=ENV] The environment the command should run under
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for
more verbose output and 3 for debug
Available commands:
clear-compiled Remove the compiled class file
down Put the application into maintenance mode
env Display the current framework environment
help Displays help for a command
inspire Display an inspiring quote
list Lists commands
migrate Run the database migrations
optimize Optimize the framework for better performance
serve Serve the application on the PHP development server
tinker Interact with your application
up Bring the application out of maintenance mode
app
app:name Set the application namespace
auth
auth:clear-resets Flush expired password reset tokens
cache
cache:clear Flush the application cache
cache:forget Remove an item from the cache
cache:table Create a migration for the cache database table
config
config:cache Create a cache file for faster configuration loading
config:clear Remove the configuration cache file
db
93
Chapter
3
-
Building
A
Support
Ticket
System
94
Chapter
3
-
Building
A
Support
Ticket
System
view
view:clear Clear all compiled view files
Create
a
new
migration
file
Now,
let's
try
to
generate
a
new
migration
file!
We're
going
to
create
a
tickets
table.
Go
to
your
application
root
(~/Code/Laravel),
execute
this
command:
You'll
see:
Laravel
will
create
a
new
migration
template
and
place
it
in
your
database/migrations
directory.
The
name
of
the
new
migration
template
is:
create_tickets_table.
You
can
name
it
whatever
you
want.
Check
the
migrations
directory,
you'll
find
a
file
look
like
this:
2017_02_08_003609_create_tickets_table
You
may
notice
that
Laravel
put
a
timestamp
before
the
name
of
the
file,
it
helps
to
determine
the
order
of
the
migrations.
Open
the
file:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
95
Chapter
3
-
Building
A
Support
Ticket
System
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('tickets');
}
}
Basically,
a
migration
is
just
a
standard
class.
There
are
two
important
methods:
1.
up
method:
you
use
this
method
to
add
new
tables,
column
to
the
database.
2.
down
method:
well,
you
might
have
guessed
already,
this
method
is
used
to
reverse
what
you've
created.
It's
time
to
create
our
tickets
table
by
filling
the
up
method!
But...
WAIT!
We
have
a
faster
way
to
create
the
tickets
table:
using
--create
option.
Delete
the
migration
file
that
you've
just
created.
Once
deleted,
run
this
command:
By
using
the
--create
option,
Laravel
automatically
generates
the
codes
to
create
the
tickets
table
for
you.
96
Chapter
3
-
Building
A
Support
Ticket
System
If
you
see
this
error:
[ErrorException]
include(/home/vagrant/Code/Laravel/database/migrations/2016_09_09_193947_create_
tickets_table.php):
failed to open stream: No such file or directory
You
will
need
to
run
this
command
to
regenerate
the
list
of
all
classes
that
need
to
be
included
in
your
app:
composer dump-autoload -o
Tip:
In
the
future,
if
you
see
this
error
again,
you
can
run
the
command
above
to
fix
it.
If
you
see
this
error:
You
may
be
running
a
version
of
MySQL
older
than
the
5.7.7
release.
To
fix
the
bug,
you
need
to
edit
the
AppServiceProvider.php
file,
and
set
a
default
string
length
inside
the
boot
method:
use Illuminate\Support\Facades\Schema;
Note:
You
can
read
more
about
this
issue
at
https://laravel.com/docs/master/migrations#creating-indexes
Understand
Schema
to
write
migrations
Schema
is
a
class
that
we
can
use
to
define
and
manipulate
tables.
We
use
Schema::create
method
to
create
the
tickets
table:
97
Chapter
3
-
Building
A
Support
Ticket
System
Schema::create
method
has
two
parameters.
The
first
one
is
the
name
of
the
table.
The
second
one
is
a
Closure.
The
Closure
has
one
parameter:
$table.
You
can
name
the
parameter
whatever
you
like.
We
use
the
$table
parameter
to
create
database
columns,
such
as
id,
name,
date,
etc.
$table->increments('id');
$table->timestamps();
increments('id')
command
is
used
to
create
id
column
and
defines
it
to
be
an
auto-
increment
primary
key
field
in
the
tickets
table.
timestamps
is
a
special
method
of
Laravel.
It
creates
updated_at
and
created_at
column.
Laravel
uses
these
columns
to
know
when
a
row
is
created
or
changed.
To
see
a
full
list
of
Schema
methods
and
column
type,
check
out
the
official
docs:
https://laravel.com/docs/master/migrations
You
don't
need
to
remember
them
all.
We
will
learn
some
of
them
by
creating
some
migrations
in
this
book.
Our
tickets
will
have
these
columns:
id
title
content
slug:
URL
friendly
version
of
the
ticket
title
status:
current
status
of
the
ticket
(answered
or
pending)
user_id:
who
created
the
ticket
Here's
how
we
can
write
our
first
migrations:
create_tickets_table.php
98
Chapter
3
-
Building
A
Support
Ticket
System
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('tickets');
}
}
Finally,
run
this
command
to
create
the
tickets
table
and
its
columns:
99
Chapter
3
-
Building
A
Support
Ticket
System
The
first
time
you
run
this
command,
Laravel
will
create
a
migration
table
to
keep
track
of
what
migrations
you've
created.
By
default,
Laravel
also
creates
create_users_table
migration
and
create_password_resets_table
migration
for
us.
These
migrations
will
create
users
and
password_resets
tables.
If
you
want
to
implement
the
default
authentication,
leave
the
files
there.
Otherwise,
you
can
just
delete
them,
or
run
php
artisan
fresh
command
to
completely
remove
the
default
authentication
feature.
Well,
I
guess
it
worked!
It
looks
like
the
tables
have
been
created.
Let's
check
the
homestead
database:
Note:
I
use
the
homestead
database.
If
you
like
to
use
another
one,
feel
free
to
change
it
using
the
.env
file.
Well
done!
You've
just
created
a
new
tickets
table
to
store
our
data.
Create
a
new
Eloquent
model
Laravel
has
a
very
nice
feature:
Eloquent
ORM.
100
Chapter
3
-
Building
A
Support
Ticket
System
Eloquent
provides
a
simple
way
to
use
ActiveRecord
pattern
when
working
with
databases.
By
using
this
technique,
we
can
wrap
our
database
into
objects.
What
does
it
mean?
In
Object
Oriented
Programming
(OOP),
we
usually
create
multiple
objects.
Objects
can
be
anything
that
has
properties
and
actions.
For
example,
a
mobile
phone
can
be
an
object.
Each
model
of
a
phone
has
its
own
blueprint.
You
can
buy
a
new
case
for
your
phone,
or
you
can
change
its
home
screen.
But
no
matter
you
customize
it,
it's
still
based
on
the
blueprint
that
was
created
by
the
manufacturer.
We
call
that
blueprint:
model.
Basically,
model's
just
a
class.
Each
model
has
its
own
variables
(features
of
each
mobile
phone)
and
methods
(actions
that
you
take
to
customize
the
phone).
Model
is
known
as
the
M
in
the
MVC
system
(Model-View-Controller).
Now
let's
get
back
to
our
tickets
table.
If
we
can
turn
the
tickets
table
to
be
a
model,
we
can
then
easily
access
and
manage
it.
Eloquent
helps
us
to
do
the
magic.
We
may
use
Eloquent
ORM
to
create,
edit,
manipulate,
deletes
our
tickets
without
writing
a
single
line
of
SQL!
To
get
started,
let's
create
our
first
Ticket
model
by
running
this
Artisan
command:
Note:
a
model
name
should
be
singular,
and
a
table
name
should
be
plural.
Yes!
It's
that
simple!
You've
created
a
model!
You
can
find
the
Ticket
model
(Ticket.php)
in
the
app
directory.
Here
is
a
new
tip.
You
can
also
generate
the
tickets
migration
at
the
same
time
by
adding
the
-m
option:
Cool?
Ok,
let's
open
our
new
Ticket
model:
101
Chapter
3
-
Building
A
Support
Ticket
System
app/Ticket.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
As
you
may
notice,
the
Ticket
model
is
just
a
PHP
class
that
extends
the
Model
class.
Now
we
can
use
this
file
to
tell
Laravel
about
its
relationships.
For
instance,
each
ticket
is
created
by
a
user,
we
can
tell
tickets
belongs
to
users
by
writing
like
this:
We
also
can
be
able
to
use
this
model
to
access
any
tickets'
data,
such
as:
title,
content,
etc.
Eloquent
is
clever.
It
automatically
finds
and
connects
our
models
with
our
database
tables
if
you
name
them
correctly
(Ticket
model
and
tickets
table,
in
this
case).
For
some
reasons,
if
you
want
to
use
a
different
name,
you
can
let
Eloquent
know
that
by
defining
a
table
property
like
this:
Read
more
about
Eloquent
here:
102
Chapter
3
-
Building
A
Support
Ticket
System
http://laravel.com/docs/master/eloquent
Once
we
have
the
Ticket
model,
we
can
build
a
form
to
let
the
users
create
a
new
ticket!
Create
a
page
to
submit
tickets
Now
as
we
have
the
Ticket
model,
let's
write
the
code
for
creating
new
tickets.
To
create
a
new
ticket,
we
will
need
to
use
Controller
action
(also
known
as
Controller
method)
and
view
to
display
the
new
ticket
form.
Create
a
view
to
display
the
submit
ticket
form
Go
to
our
views
directory,
create
a
new
directory
called
tickets.
Because
we
will
have
many
ticket
views
(such
as:
create
ticket
view,
edit
ticket
view,
delete
ticket
view,
etc.),
we
should
store
all
the
views
in
the
tickets
directory.
Next,
create
a
new
Blade
template
called
create.blade.php
views/tickets/create.blade.php
@extends('master')
@section('title', 'Contact')
@section('content')
<div class="container col-md-8 col-md-offset-2">
<div class="well well bs-component">
<form class="form-horizontal">
<fieldset>
<legend>Submit a new ticket</legend>
<div class="form-group">
<label for="title" class="col-lg-2 control-label">Title</label>
<div class="col-lg-10">
<input type="text" class="form-control" id="title" placeho
lder="Title">
</div>
</div>
<div class="form-group">
<label for="content" class="col-lg-2 control-label">Content</l
abel>
<div class="col-lg-10">
<textarea class="form-control" rows="3" id="content"></tex
103
Chapter
3
-
Building
A
Support
Ticket
System
tarea>
<span class="help-block">Feel free to ask us any question.
</span>
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button class="btn btn-default">Cancel</button>
<button type="submit" class="btn btn-primary">Submit</butt
on>
</div>
</div>
</fieldset>
</form>
</div>
</div>
@endsection
Unfortunately,
we
can't
see
this
view
yet,
we
have
to
use
a
Controller
action
to
display
it.
Open
PagesController.php,
edit:
to:
Instead
of
displaying
the
contact
view,
we
redirect
users
to
tickets.create
view.
After
saving
these
changes,
we
should
see
a
new
responsive
submit
ticket
form
when
visiting
the
contact
page:
104
Chapter
3
-
Building
A
Support
Ticket
System
Create
a
new
controller
for
the
tickets
Even
though
we
can
use
PagesController
to
manage
all
the
pages,
we
should
create
TicketsController
to
manage
our
tickets.
TicketsController
will
be
responsible
for
creating,
editing
and
deleting
tickets.
It
will
help
to
organize
and
maintain
our
application
much
easier.
You
have
known
how
to
create
a
controller,
let's
create
the
TicketsController
by
running
this
command:
As
mentioned
before,
by
using
the
--resource
flag,
Laravel
creates
some
RESTful
actions
(create,
edit,
update,
etc.)
for
us.
Update
the
create
action
as
follows:
105
Chapter
3
-
Building
A
Support
Ticket
System
And
don't
forget
to
update
the
web.php
file:
Route::get('/contact', 'TicketsController@create');
Great!
You
now
have
the
TicketsController.
Pretty
simple,
right?
Introducing
HTTP
Requests
In
previous
versions
of
Laravel,
developers
usually
place
validation
anywhere
they
want.
That
is
not
a
good
practice.
Luckily,
Laravel
5
has
a
new
feature
called
Requests
(aka
HTTP
Requests
or
Form
Requests).
When
users
send
a
request
(submit
a
ticket,
for
example),
we
can
use
the
new
Request
class
to
define
some
rules
and
validate
the
request.
If
the
validator
passes,
then
everything
will
be
executed
as
normal.
Otherwise,
the
user
will
be
automatically
redirected
back
to
where
they
are.
As
you
can
see,
it's
really
convenient
for
us
to
validate
our
application's
forms.
We
will
use
Request
to
validate
the
create
ticket
form.
To
create
a
new
Request,
simply
run
this
Artisan
command:
A
new
TicketFormRequest
will
be
generated!
You
can
find
it
in
the
app/Http/Requests
directory.
Open
the
file,
you
can
see
that
there
are
two
methods:
authorize
and
rules.
authorize()
method
106
Chapter
3
-
Building
A
Support
Ticket
System
By
default,
it
returns
false.
That
means
no
one
can
be
able
to
perform
the
request.
To
be
able
to
submit
the
tickets,
we
have
to
turn
it
to
true
rules()
method
We
use
this
method
to
define
our
validation
rules.
Currently,
our
create
ticket
form
has
two
fields:
title
and
content,
we
can
set
the
following
rules:
required|min:3
validation
rule
means
that
the
users
must
fill
the
title
field,
and
the
title
should
have
a
minimum
three
character
length.
There
are
many
validation
rules,
you
can
see
a
list
of
available
rules
at:
http://laravel.com/docs/master/validation#available-validation-rules
107
Chapter
3
-
Building
A
Support
Ticket
System
Install
Laravel
Collective
packages
Note:
This
is
an
optional
section,
you
may
SKIP
THIS
SECTION.
The
package
might
not
support
the
latest
version
of
Laravel
yet.
Since
Laravel
5,
some
Laravel
components
have
been
removed
from
the
core
framework.
If
you've
used
older
versions
of
Laravel
before,
you
may
love
these
features:
HTML:
HTML
helpers
for
creating
common
HTML
and
form
elements
Annotations:
route
and
events
annotations.
Remote:
a
simple
way
to
SSH
into
remote
servers
and
run
commands.
Fortunately,
bringing
all
these
features
back
is
very
easy.
You
just
need
to
install
LaravelCollective
package!
https://laravelcollective.com
Don't
know
how
to
install
the
package?
Let
me
show
you.
Install
a
package
using
Composer
First,
you
need
to
open
your
composer.json
file,
which
is
placed
in
your
application
root.
composer.json
{
"name": "laravel/laravel",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"type": "project",
"require": {
"php": ">=7.0.0",
"fideloper/proxy": "~3.3",
"laravel/framework": "5.5.*",
"laravel/tinker": "~1.0"
},
"require-dev": {
"filp/whoops": "~2.0",
"fzaninotto/faker": "~1.4",
"mockery/mockery": "0.9.*",
108
Chapter
3
-
Building
A
Support
Ticket
System
"phpunit/phpunit": "~6.0"
},
"autoload": {
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"extra": {
"laravel": {
"dont-discover": [
]
}
},
"scripts": {
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate"
],
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover"
]
},
"config": {
"preferred-install": "dist",
"sort-packages": true,
"optimize-autoloader": true
}
}
This
is
a
JSON
(Javascript
Object
Notation)
file.
We
use
JSON
to
store
and
exchange
data.
JSON
is
very
easy
to
read.
If
you
can
read
HTML
or
XML,
I'm
sure
that
you
can
read
JSON.
If
you
can't
read
it,
learn
more
about
JSON
here:
https://w3schools.com/json
109
Chapter
3
-
Building
A
Support
Ticket
System
In
this
section,
we
will
add
the
HTML
package
to
our
app.
The
instructions
can
be
found
here:
https://laravelcollective.com/docs/master/html
To
install
a
Laravel
package
using
Composer,
you
just
need
to
add
the
following
code:
find:
"require": {
"php": ">=5.6.4",
"laravel/framework": "5.5.*",
"laravel/tinker": "~1.0"
},
add:
"require": {
"php": ">=5.6.4",
"laravel/framework": "5.5.*",
"laravel/tinker": "~1.0",
"laravelcollective/html": "5.5.*"
},
Note:
Your
version
could
be
different.
For
example,
if
you're
using
Laravel
5.6,
the
code
should
be
"laravelcollective/html":
"5.6.*".
Check
for
the
latest
version
here.
Save
the
file
and
run
this
command
at
your
application
root:
composer update
Done!
You've
just
installed
LaravelCollective/HTML
package!
Create
a
service
provider
and
aliases
After
installing
the
HTML
package
via
Composer.
You
need
to
follow
some
extra
steps
to
let
Laravel
know
where
to
find
the
package
and
use
it.
To
use
the
package,
you
have
to
add
a
service
provider
to
the
providers
array
of
the
config/app.php.
110
Chapter
3
-
Building
A
Support
Ticket
System
Find:
'providers' => [
/*
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class,
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
Illuminate\Cookie\CookieServiceProvider::class,
Illuminate\Database\DatabaseServiceProvider::class,
Illuminate\Encryption\EncryptionServiceProvider::class,
Illuminate\Filesystem\FilesystemServiceProvider::class,
Illuminate\Foundation\Providers\FoundationServiceProvider::class,
Illuminate\Hashing\HashServiceProvider::class,
Illuminate\Mail\MailServiceProvider::class,
Illuminate\Notifications\NotificationServiceProvider::class,
Illuminate\Pagination\PaginationServiceProvider::class,
Illuminate\Pipeline\PipelineServiceProvider::class,
Illuminate\Queue\QueueServiceProvider::class,
Illuminate\Redis\RedisServiceProvider::class,
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
Illuminate\Session\SessionServiceProvider::class,
Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
/*
* Package Service Providers...
*/
Laravel\Tinker\TinkerServiceProvider::class,
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
],
Add
the
following
line
to
the
$provider
array:
Collective\Html\HtmlServiceProvider::class,
111
Chapter
3
-
Building
A
Support
Ticket
System
Your
$provider
array
should
look
like
this:
'providers' => [
/*
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class,
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
Illuminate\Cookie\CookieServiceProvider::class,
Illuminate\Database\DatabaseServiceProvider::class,
Illuminate\Encryption\EncryptionServiceProvider::class,
Illuminate\Filesystem\FilesystemServiceProvider::class,
Illuminate\Foundation\Providers\FoundationServiceProvider::class,
Illuminate\Hashing\HashServiceProvider::class,
Illuminate\Mail\MailServiceProvider::class,
Illuminate\Notifications\NotificationServiceProvider::class,
Illuminate\Pagination\PaginationServiceProvider::class,
Illuminate\Pipeline\PipelineServiceProvider::class,
Illuminate\Queue\QueueServiceProvider::class,
Illuminate\Redis\RedisServiceProvider::class,
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
Illuminate\Session\SessionServiceProvider::class,
Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
/*
* Package Service Providers...
*/
Laravel\Tinker\TinkerServiceProvider::class,
Collective\Html\HtmlServiceProvider::class,
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
],
Then
find
the
aliases
array:
'aliases' => [
112
Chapter
3
-
Building
A
Support
Ticket
System
],
add
these
two
aliases
to
the
aliases
array:
You
should
have:
'aliases' => [
113
Chapter
3
-
Building
A
Support
Ticket
System
Now
you
can
use
the
LaravelCollective/HTML
package!
How
to
use
HTML
package
The
HTML
package
helps
us
to
build
forms
easier
and
faster.
Let's
see
an
example:
Normal
HTML
code:
<form action="contact">
<label>First name:</label>
<input type="text" name="firstname" value="Enter your first name">
<br />
<label>Last name:</label>
<input type="text" name="lastname" value="Enter your last name">
114
Chapter
3
-
Building
A
Support
Ticket
System
<br />
<input type="submit" value="Submit">
</form>
Using
HTML
package:
As
you
see,
we
use
Form::open()
to
create
our
opening
form
tag
and
Form::close()
to
close
the
form.
Text
fields
and
labels
can
be
generated
using
Form::text
and
Form::label
method.
You
can
learn
more
about
how
to
use
HTML
package
by
reading
Laravel
4
official
docs:
http://laravel.com/docs/4.2/html
If
you
don't
like
to
take
advantage
of
the
HTML
package
to
build
your
forms,
you
don't
have
to
use
it.
I
just
want
you
to
understand
its
syntax
because
many
Laravel
developers
are
using
it
these
days.
It
would
be
better
if
you
know
both
methods.
Submit
the
form
data
Having
learned
about
Requests,
working
with
Controllers
and
View
to
build
the
create
ticket
form,
now
you're
ready
to
process
the
submitted
data.
if
you
click
the
submit
button
now,
nothing
happens.
We
need
to
use
other
HTTP
method
to
submit
the
form.
Two
commonly
used
HTTP
methods
for
a
client
to
communicate
with
a
server
are:
GET
and
POST.
We've
used
GET
to
display
the
form:
115
Chapter
3
-
Building
A
Support
Ticket
System
Route::get('/contact', 'TicketsController@create');
But
we
won't
use
GET
to
submit
data.
GET
requests
should
only
be
used
to
retrieve
data.
We
always
use
POST
method
to
handle
the
form
submissions
endpoints.
When
we
use
POST,
requests
are
never
cached,
parameters
are
not
saved
in
users'
browser
history.
Therefore,
POST
is
safer
than
GET.
Let's
open
the
web.php
file,
add:
Route::post('/contact', 'TicketsController@store');
Good!
Now
when
users
make
a
POST
request
to
the
contact
page,
this
route
tells
Laravel
to
execute
the
TicketsController's
store
action.
The
store
action
is
still
empty.
You
can
update
it
to
display
the
form
data:
TicketsController.php
We
use
the
TicketFormRequest
as
a
parameter
of
the
store
action
here
to
tell
Laravel
that
we
want
to
apply
validation
to
the
store
action.
Laravel
requires
us
to
type-hint
the
Illuminate\Http\Request
class
on
our
controller
constructor
to
obtain
an
instance
of
the
current
HTTP
request.
Simply
put,
we
need
to
add
this
line
at
the
top
of
the
TicketsController.php
file:
use App\Http\Requests\TicketFormRequest;
find:
add
above:
116
Chapter
3
-
Building
A
Support
Ticket
System
use App\Http\Requests\TicketFormRequest;
class TicketsController extends Controller
{
One
more
step,
you
need
to
update
the
ticket
form
to
send
POST
requests.
Open
tickets/create.blade.php.
Find:
<form class="form-horizontal">
Update
to:
You
also
need
to
tell
Laravel
the
name
of
the
fields:
Find:
update
to:
Now,
try
to
click
the
submit
button!
117
Chapter
3
-
Building
A
Support
Ticket
System
Oops!
There
is
an
error
-
known
as
TokenMismatchException.
What
is
it?
For
security
purposes,
Laravel
requires
a
token
to
be
sent
when
using
the
POST
method.
If
you
don't
send
any
token,
it
will
throw
an
error.
To
fix
this,
you
need
to
add
a
hidden
token
field
below
your
form
opening
tag:
Good!
Refresh
your
browser,
fill
the
form
and
hit
submit
again,
you'll
see:
118
Chapter
3
-
Building
A
Support
Ticket
System
Yayyy!
We
can
see
the
ticket
data!
Everything
is
working!
Note:
If
the
page
is
refreshed
and
you
don't
see
the
ticket
data,
that
means
the
validation
rules
are
working.
You
have
to
follow
the
rules
and
fill
the
title
and
the
content
correctly.
One
last
step
is
to
display
the
errors
when
the
users
don't
fill
the
form
or
the
form
is
not
valid.
Find:
add
below:
119
Chapter
3
-
Building
A
Support
Ticket
System
Basically,
if
the
validator
fails,
Laravel
will
store
all
errors
in
the
session.
We
can
easily
access
the
errors
via
$errors
object.
Now,
let's
go
back
to
the
form,
don't
fill
anything
and
hit
the
submit
button:
Here
is
the
new
tickets/create.blade.php
file:
@extends('master')
@section('title', 'Create a new ticket')
@section('content')
<div class="container col-md-8 col-md-offset-2">
<div class="well well bs-component">
<fieldset>
120
Chapter
3
-
Building
A
Support
Ticket
System
<div class="col-lg-10">
<input type="title" class="form-control" id="title" placeh
older="Title" name="title">
</div>
</div>
<div class="form-group">
<label for="content" class="col-lg-2 control-label">Content</l
abel>
<div class="col-lg-10">
<textarea class="form-control" rows="3" id="content" name="
content"></textarea>
<span class="help-block">Feel free to ask us any question.
</span>
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button class="btn btn-default">Cancel</button>
<button type="submit" class="btn btn-primary">Submit</butt
on>
</div>
</div>
</fieldset>
</form>
</div>
</div>
@endsection
Using
.env
file
In
the
next
section,
we
will
learn
how
to
insert
data
into
the
database.
Before
working
with
databases,
you
should
understand
.env
file
first.
What
is
the
.env
file?
Our
applications
usually
run
in
different
environments.
For
example,
we
develop
our
apps
on
a
local
server,
and
deploy
it
on
a
production
server.
The
database
settings
and
server
credentials
of
each
environment
might
be
different.
Laravel
5
provides
121
Chapter
3
-
Building
A
Support
Ticket
System
us
an
easy
way
to
handle
different
configuration
settings
by
simply
editing
the
.env
file.
The
.env
file
helps
us
to
load
custom
configurations
variables
without
editing
.htaccess
files
or
virtual
hosts,
and
keep
our
sensitive
credentials
more
secure.
Learn
more
about
.env
file
here:
https://github.com/vlucas/phpdotenv
How
to
edit
it?
The
.env
file
is
very
easy
to
configure.
Let's
open
it:
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:7u+kwBbWsJ+izfVohtJcXjdFm2JaGtD/V6PgCoJCwYc=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
SESSION_LIFETIME=120
QUEUE_DRIVER=sync
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
122
Chapter
3
-
Building
A
Support
Ticket
System
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
As
you
see,
the
file
is
very
clear.
Let's
try
to
edit
a
few
settings.
Currently,
you're
using
the
default
homestead
database.
If
you've
created
a
different
database
and
you
want
to
use
it
instead,
edit
this
line:
DB_DATABASE=homestead
to
DB_DATABASE=yourCustomDatabaseName
If
you
don't
want
to
display
full
error
messages,
turn
the
APP_DEBUG
to
false.
If
you're
using
Sendinblue
to
send
emails,
replace
these
lines
with
your
Sendinblue
credentials:
MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
For
example:
MAIL_DRIVER=smtp
MAIL_HOST=smtp-relay.sendinblue.com
MAIL_PORT=587
MAIL_USERNAME=learninglaravel
MAIL_PASSWORD=secret
Now,
let's
move
to
the
fun
part!
Insert
data
into
the
database
123
Chapter
3
-
Building
A
Support
Ticket
System
In
the
previous
section,
you've
learned
how
to
receive
and
validate
the
users'
requests.
Once
you
have
the
submitted
form
data,
inserting
the
data
into
the
database
is
pretty
easy.
First,
let's
begin
by
putting
this
line
at
the
top
of
your
TicketsController
file:
use App\Ticket;
Be
sure
to
put
it
above
the
class
name:
use App\Ticket;
class TicketsController extends Controller
{
This
tells
Laravel
that
you
want
to
use
your
Ticket
model
in
this
class.
Now
you
can
use
Ticket
model
to
store
the
form
data.
Update
the
store
action
as
follows:
$ticket->save();
Let's
see
the
code
line
by
line:
$slug = uniqid();
We
use
the
uniqid()
function
to
generate
a
unique
ID
based
on
the
microtime.
You
may
use
md5()
function
to
generate
the
slugs
or
create
your
custom
slugs.
124
Chapter
3
-
Building
A
Support
Ticket
System
This
is
the
ticket's
unique
ID.
Next,
we
create
a
new
Ticket
model
instance,
set
attributes
on
the
model.
$ticket->save();
Then
we
call
the
save
method
to
save
the
data
to
our
database.
Once
the
ticket
has
been
saved,
we
redirect
users
to
the
contact
page
with
a
message.
Finally,
try
to
create
a
new
ticket
and
submit
it.
Oh
no!
There
is
an
error:
"MassAssignmentException"
Don't
worry,
it's
a
Laravel
feature
that
protect
against
mass-assignment.
What
is
mass-assignment?
According
to
the
Laravel
official
docs:
125
Chapter
3
-
Building
A
Support
Ticket
System
"mass-assignment
vulnerability
occurs
when
user's
pass
unexpected
HTTP
parameters
through
a
request,
and
then
that
parameter
changes
a
column
in
your
database
you
did
not
expect.
For
example,
a
malicious
user
might
send
an
is_admin
parameter
through
an
HTTP
request,
which
is
then
mapped
onto
your
model's
create
method,
allowing
the
user
to
escalate
themselves
to
an
administrator"
Read
more
about
it
here:
https://laravel.com/docs/master/eloquent#mass-assignment
To
save
the
ticket,
open
the
Ticket
model.
(Ticket.php
file)
Then
place
the
following
contents
into
the
Ticket
Model:
The
$fillable
property
make
the
columns
mass
assignable.
Alternatively,
you
may
use
the
$guarded
property
to
make
all
attributes
mass
assignable
except
for
your
chosen
attributes.
For
example,
I
use
the
id
column
here:
Note:
You
must
use
either
$fillable
or
$guarded.
One
more
thing
to
do,
we
need
to
update
the
tickets/create.blade.php
view
to
display
the
status
message:
Find:
Add
Below:
126
Chapter
3
-
Building
A
Support
Ticket
System
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
Good!
Try
to
create
a
new
ticket
again.
Well
done!
You've
just
saved
a
new
ticket
to
the
database!
Be
sure
to
check
your
application
database,
you
should
see
some
new
records
in
the
tickets
table:
View
all
tickets
127
Chapter
3
-
Building
A
Support
Ticket
System
As
you
continue
developing
the
app,
you'll
find
that
you
need
a
way
to
display
all
tickets,
so
you
can
be
able
to
view,
modify
or
delete
them
easily.
The
following
are
the
steps
to
list
all
tickets:
First,
we'll
modify
the
web.php
file:
Route::get('/tickets', 'TicketsController@index');
When
users
access
homestead.test/tickets,
we
use
TicketsController
to
execute
the
index
action.
Feel
free
to
change
the
link
path
or
the
action's
name
to
whatever
you
like.
Then,
open
the
TicketsController
file,
and
update
the
index
action:
We
use
Ticket::all()
to
get
all
tickets
in
our
database
and
store
them
in
the
$tickets
variable.
Before
we
return
the
tickets.index
view,
we
use
the
compact()
method
to
convert
the
result
to
an
array,
and
pass
it
to
the
view.
Alternatively,
you
can
use:
or
Those
three
methods
are
the
same.
Finally,
create
a
new
view
called
index.blade.php
and
place
it
in
the
tickets
directory:
views/tickets/index.blade.php
128
Chapter
3
-
Building
A
Support
Ticket
System
@extends('master')
@section('title', 'View all tickets')
@section('content')
@endsection
We
perform
the
following
steps
to
load
the
tickets:
@if ($tickets->isEmpty())
<p> There is no ticket.</p>
@else
First,
we
check
if
the
$tickets
variable
is
empty
or
not.
If
it's
empty,
then
we
display
a
message
to
our
users.
@else
129
Chapter
3
-
Building
A
Support
Ticket
System
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Status</th>
</tr>
</thead>
<tbody>
@foreach($tickets as $ticket)
<tr>
<td>{!! $ticket->id !!} </td>
<td>{!! $ticket->title !!}</td>
<td>{!! $ticket->status ? 'Pending' : 'Answered' !!}</td>
</tr>
@endforeach
</tbody>
</table>
@endif
If
the
$tickets
is
not
empty,
we
use
foreach()
loop
to
display
all
tickets.
Here
is
how
we
can
write
the
if
else
statement
in
a
short
way.
If
the
ticket's
status
is
1,
we
say
that
it's
pending.
If
the
ticket's
status
is
0,
we
say
that
it's
answered.
Feel
free
to
change
the
name
of
the
status
to
your
liking.
Go
to
homestead.test/tickets,
you
should
be
able
to
view
all
tickets
that
you've
created!
130
Chapter
3
-
Building
A
Support
Ticket
System
View
a
single
ticket
At
this
point,
viewing
a
ticket
is
much
easier.
When
we
click
on
the
title
of
the
ticket,
we
want
to
display
its
content
and
status.
As
usual,
open
web.php
file,
and
add:
Route::get('/ticket/{slug?}', 'TicketsController@show');
You
should
notice
that
we
use
a
special
route
(/ticket/{slug?})
here.
By
doing
this,
we
tell
Laravel
that
any
route
parameter
named
slug
will
be
bound
to
the
show
action
of
our
TicketsController.
Simply
put,
when
we
visit
ticket/558467e731bb8,
Laravel
automatically
detects
the
slug
(which
is
558467e731bb8)
and
pass
it
to
the
action.
Note:
you
can
change
{slug?}
to
{slug}
or
whatever
you
like.
Be
sure
to
put
your
custom
name
in
the
{
}
brackets.
131
Chapter
3
-
Building
A
Support
Ticket
System
Next,
open
TicketsController,
update
the
show
action
as
follows:
We
pass
the
slug
of
the
ticket
we
want
to
display
in
the
show
action.
Then
we
can
use
this
slug
to
find
the
correct
ticket
via
our
Ticket
model's
firstOrFail
method.
The
firstOrFail
method
will
retrieve
the
first
result
of
the
query.
If
there
is
no
result,
it
will
throw
a
ModelNotFoundException.
If
you
don't
want
to
throw
an
exception,
you
can
use
the
first()
method.
$ticket = Ticket::whereSlug($slug)->first();
Finally,
we
return
the
tickets.show
view
with
the
ticket.
We
don't
have
the
show
view
yet.
Let's
create
it:
views/tickets/show.blade.php
@extends('master')
@section('title', 'View a ticket')
@section('content')
@endsection
Pretty
simple,
right?
132
Chapter
3
-
Building
A
Support
Ticket
System
We
just
display
the
ticket's
title,
status
and
content.
We
also
add
the
edit
and
delete
button
here
to
easily
edit
and
remove
the
ticket.
Now
if
you
access
http://homestead.test/ticket/yourSlug,
you'll
see:
Note:
your
ticket's
slug
may
be
different.
Be
sure
to
use
a
correct
slug
to
view
the
ticket.
Using
a
helper
function
Laravel
has
many
helper
functions.
These
PHP
functions
are
really
useful.
We
can
use
helper
functions
to
manage
paths,
modify
strings,
configure
our
application,
etc.
You
can
find
them
here:
https://laravel.com/docs/master/helpers
133
Chapter
3
-
Building
A
Support
Ticket
System
Now,
as
we
have
a
view
to
display
all
the
tickets,
let's
explore
how
we
can
link
the
title
of
the
ticket
to
the
TicketController's
show
action.
Open
tickets/index.blade.php.
Find:
@foreach($tickets as $ticket)
<tr>
<td>{!! $ticket->id !!} </td>
<td>{!! $ticket->title !!}</td>
<td>{!! $ticket->status ? 'Pending' : 'Answered' !!}</td>
</tr>
@endforeach
Update
to:
@foreach($tickets as $ticket)
<tr>
<td>{!! $ticket->id !!}</td>
<td>
<a href="{!! action('TicketsController@show', $ticket->slug) !!}">{!! $tic
ket->title !!} </a>
</td>
<td>{!! $ticket->status ? 'Pending' : 'Answered' !!}</td>
</tr>
@endforeach
Here,
we
use
action
function
to
generate
a
URL
for
the
TicketsController's
show
action:
action('TicketsController@show', $ticket->slug)
The
second
argument
is
a
route
parameter.
We
use
slug
to
find
the
ticket,
so
we
put
the
ticket's
slug
here.
Alternatively,
you
can
write
the
code
like
this:
Now,
when
you
access
homestead.test/tickets,
you
can
click
on
the
title
to
view
the
ticket.
134
Chapter
3
-
Building
A
Support
Ticket
System
Edit
a
ticket
It's
time
to
move
on
to
create
our
ticket
edit
form.
Open
web.php,
add
this
route:
Route::get('/ticket/{slug?}/edit','TicketsController@edit');
When
users
go
to
/ticket/{slug?}/edit,
we
redirect
them
to
the
TicketsController's
edit
action.
Let's
modify
the
edit
action:
135
Chapter
3
-
Building
A
Support
Ticket
System
We
find
the
ticket
using
its
slug,
then
we
use
the
tickets.edit
view
to
display
the
edit
form.
Let's
create
our
edit
view
at
resouces/views/tickets/edit.blade.php:
@extends('master')
@section('title', 'Edit a ticket')
@section('content')
<div class="container col-md-8 col-md-offset-2">
<div class="well well bs-component">
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
<fieldset>
<legend>Edit ticket</legend>
<div class="form-group">
<label for="title" class="col-lg-2 control-label">Title</label>
<div class="col-lg-10">
<input type="text" class="form-control" id="title" name="t
itle" value="{!! $ticket->title !!}">
</div>
</div>
<div class="form-group">
<label for="content" class="col-lg-2 control-label">Content</l
abel>
<div class="col-lg-10">
<textarea class="form-control" rows="3" id="content" name="
content">{!! $ticket->content !!}</textarea>
</div>
</div>
<div class="form-group">
<label>
<input type="checkbox" name="status" {!! $ticket->status?""
:"checked"!!} > Close this ticket?
</label>
</div>
136
Chapter
3
-
Building
A
Support
Ticket
System
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button class="btn btn-default">Cancel</button>
<button type="submit" class="btn btn-primary">Update</butt
on>
</div>
</div>
</fieldset>
</form>
</div>
</div>
@endsection
This
view
is
very
similar
to
the
create
view,
but
we
add
a
new
checkbox
to
modify
ticket's
status.
<div class="form-group">
<label>
<input type="checkbox" name="status" {!! $ticket->status?"":"checked"!!} > Clo
se this ticket?
</label>
</div>
Try
to
understand
this
line:
{!! $ticket->status?"":"checked"!!}
If
the
status
is
1
(pending),
we
display
nothing,
the
checkbox
is
not
checked.
If
the
status
is
0
(answered)
,
we
display
a
checked
attribute,
the
checkbox
is
checked.
Good!
Now,
let's
open
the
show
view,
update
the
edit
button
as
follows:
Find:
Update
to:
137
Chapter
3
-
Building
A
Support
Ticket
System
We
use
the
action
helper
again!
When
you
click
on
the
edit
button,
you
should
be
able
to
access
the
edit
form:
Unfortunately,
we
can't
update
the
ticket
yet.
Remember
what
you've
done
to
create
a
new
ticket?
We
need
to
use
POST
method
to
submit
the
form.
Open
web.php,
add:
Route::post('/ticket/{slug?}/edit','TicketsController@update');
Then
use
update
action
to
handle
the
submission
and
store
the
changes.
138
Chapter
3
-
Building
A
Support
Ticket
System
} else {
$ticket->status = 1;
}
$ticket->save();
return redirect(action('TicketsController@edit', $ticket->slug))->with('status', '
The ticket '.$slug.' has been updated!');
As
you
notice,
you
can
save
the
ticket
by
using
the
following
code:
$ticket = Ticket::whereSlug($slug)->firstOrFail();
$ticket->title = $request->get('title');
$ticket->content = $request->get('content');
if($request->get('status') != null) {
$ticket->status = 0;
} else {
$ticket->status = 1;
}
$ticket->save();
This
is
how
we
can
check
if
the
users
select
the
status
checkbox
or
not:
if($request->get('status') != null) {
$ticket->status = 0;
} else {
$ticket->status = 1;
}
Finally,
we
redirect
users
to
the
ticket
page
with
a
status
message:
Try
to
edit
the
ticket
now
and
hit
the
update
button!
139
Chapter
3
-
Building
A
Support
Ticket
System
Amazing!
The
ticket
has
been
updated!
Delete
a
ticket
You've
learned
how
to
create,
read
and
update
a
ticket.
Next,
you
will
learn
how
to
delete
it.
By
the
end
of
this
section,
you'll
have
a
nice
CRUD
application!
First
step,
let's
open
the
web.php
file
and
add
a
new
route:
Route::post('/ticket/{slug?}/delete','TicketsController@destroy');
When
we
send
a
POST
request
to
this
route,
Laravel
will
take
the
slug
and
execute
the
TicketsController's
destroy
action.
Note:
You
may
use
the
GET
method
here.
Open
TicketsController
and
update
the
destroy
action:
140
Chapter
3
-
Building
A
Support
Ticket
System
{
$ticket = Ticket::whereSlug($slug)->firstOrFail();
$ticket->delete();
return redirect('/tickets')->with('status', 'The ticket '.$slug.' has been deleted
!');
}
We
find
the
ticket
using
the
provided
slug.
After
that,
we
use
$ticket->delete()
method
to
delete
the
ticket.
As
always,
we
then
redirect
users
to
the
all
tickets
page.
Let's
update
the
index.blade.php
to
display
the
status
message:
Find:
<div class="panel-heading">
<h2> Tickets </h2>
</div>
Add
below:
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
Finally,
in
order
to
remove
the
ticket,
all
we
need
to
do
is
create
a
form
to
submit
a
delete
request.
Open
show.blade.php
and
find:
Update
to:
141
Chapter
3
-
Building
A
Support
Ticket
System
<div class="clearfix"></div>
The
code
above
creates
a
nice
delete
form
for
you.
When
you
view
a
ticket,
you
should
see
a
different
delete
button:
Now,
click
the
delete
button,
you
should
be
able
to
remove
the
ticket!
142
Chapter
3
-
Building
A
Support
Ticket
System
You've
just
deleted
a
ticket!
Congratulations!
You
now
have
a
CRUD
(Create,
Read,
Update,
Delete)
application!
Sending
an
email
When
users
submit
a
ticket,
we
may
want
to
receive
an
email
to
get
notified.
In
this
section,
you
will
learn
how
to
send
emails
using
Laravel.
Laravel
provides
many
methods
to
send
emails.
You
may
use
a
plain
PHP
method
to
send
emails,
or
you
may
use
some
email
service
providers
such
as
Mailgun,
Sendinblue,
Sendgrid,
Mandrill,
Amazon
SES,
etc.
To
send
emails
on
a
production
server,
simply
edit
the
mail.php
configuration
file,
which
is
placed
in
the
config
directory.
Here
is
the
file
without
comments:
143
Chapter
3
-
Building
A
Support
Ticket
System
return [
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
'name' => env('MAIL_FROM_NAME', 'Example'),
],
'markdown' => [
'theme' => 'default',
'paths' => [
resource_path('views/vendor/mail'),
],
],
];
To
send
emails
on
a
local
development
server
(Homestead),
simply
edit
the
.env
file.
MAIL_DRIVER=mail
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
As
usual,
you
may
learn
how
to
use
Mailgun,
Mandrill
and
SES
drivers
at
the
official
docs:
https://laravel.com/docs/master/mail
Because
working
on
Homestead,
we
will
learn
how
to
send
emails
on
Homestead
using
Gmail
and
Sendinblue
for
FREE!!!!!
144
Chapter
3
-
Building
A
Support
Ticket
System
Sending
emails
using
Gmail
Note:
Even
though
we
can
use
Gmail,
it's
recommended
to
use
a
transactional
email
service
(Sendinblue,
Mandrill,
etc.)
to
send
emails.
You
may
SKIP
THIS
SECTION.
If
you
have
a
Gmail
account,
it's
very
easy
to
send
emails
using
Laravel
5!
First,
go
to:
https://myaccount.google.com/security#connectedapps
Take
a
look
at
the
Sign-in
&
security
->
Connected
apps
&
sites
->
Allow
less
secure
apps
settings.
You
must
turn
the
option
"Allow
less
secure
apps"
ON.
145
Chapter
3
-
Building
A
Support
Ticket
System
Once
complete,
edit
the
.env
file:
MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=yourEmail
MAIL_PASSWORD=yourPassword
MAIL_ENCRYPTION=tls
Well
done!
You're
now
ready
to
send
emails
using
Gmail!
If
you
get
this
error
when
sending
email:
"Failed
to
authenticate
on
SMTP
server
with
username
"youremail@gmail.com"
using
3
possible
authenticators"
You
may
try
one
of
these
methods:
146
Chapter
3
-
Building
A
Support
Ticket
System
Go
to
https://accounts.google.com/UnlockCaptcha,
click
continue
and
unlock
your
account
for
access
through
other
media/sites.
Using
a
double
quote
password:
"your
password"
Try
to
use
only
your
Gmail
username:
yourGmailUsername
Sending
emails
using
Sendinblue
Go
to
Sendinblue,
register
a
new
account:
https://www.sendinblue.com/?ae=484
When
your
account
is
activated,
edit
the
.env
file:
MAIL_DRIVER=smtp
MAIL_HOST=smtp-relay.sendinblue.com
MAIL_PORT=587
MAIL_USERNAME=yourSendinblueUsername
MAIL_PASSWORD=yourPassword
Good
job!
You're
now
ready
to
send
emails
using
Sendinblue!
Sending
a
test
email
To
send
a
test
email,
open
web.php
file
and
add
this
route:
Route::get('sendemail', function () {
$data = array(
'name' => "Learning Laravel",
);
});
});
147
Chapter
3
-
Building
A
Support
Ticket
System
As
you
see,
we
use
the
send
method
on
the
Mail
facade.
There
are
three
arguments:
1.
The
name
of
the
view
that
we
use
to
send
emails.
2.
An
array
of
data
that
we
want
to
pass
to
the
email.
3.
A
closure
that
we
can
use
to
customize
our
email
subjects,
sender,
recipients,
etc.
When
you
visit
http://homestead.test/sendemail,
Laravel
will
try
to
send
an
email.
If
the
email
is
sent
successfully,
Laravel
will
display
a
message.
Note:
Be
sure
to
replace
yourEmail@domain.com
with
your
real
email
address.
Finally,
we
don't
have
the
welcome.blade.php
view
yet,
let's
create
it
and
put
it
in
the
emails
directory.
views/emails/welcome.blade.php
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
</head>
<body>
<h2>Learning Laravel!</h2>
<div>
Welcome to {!! $name !!} website!
</div>
</body>
</html>
Because
we've
passed
an
array
containing
the
$name
key
in
the
above
route,
we
could
display
the
name
within
this
welcome
view
using:
or
148
Chapter
3
-
Building
A
Support
Ticket
System
Done!
Now
go
to
http://homestead.test/sendemail,
you
should
see:
Check
your
inbox,
you
should
receive
a
new
email!
Feel
free
to
customize
your
email
address,
recipients,
subjects,
etc.
Sending
an
email
when
there
is
a
new
ticket
Now
that
we
have
set
up
everything,
let's
send
an
email
when
users
create
a
new
ticket!
Open
TicketsController.php
and
update
the
store
action.
Find:
Add
above:
149
Chapter
3
-
Building
A
Support
Ticket
System
$data = array(
'ticket' => $slug,
);
Note:
Be
sure
to
replace
yourEmail@domain.com
with
your
real
email
address.
Don't
add
the
code
above
if
you
don't
want
to
send
an
email.
And
don't
forget
to
tell
Laravel
that
you
want
to
use
the
Mail
facade
here:
Find:
Add
above:
use Illuminate\Support\Facades\Mail;
As
you
may
notice,
we
don't
have
the
emails/ticket.blade.php
view
yet.
Let's
create
it!
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
</head>
<body>
<h2>Learning Laravel!</h2>
<div>
You have a new ticket. The ticket id is {!! $ticket !!}!
</div>
</body>
</html>
It's
time
to
create
a
new
ticket!
150
Chapter
3
-
Building
A
Support
Ticket
System
If
everything
works
out
well,
you
should
see
a
new
email
in
your
inbox!
Here
is
the
email's
content:
Laravel
5.6
allows
us
to
send
emails
using
Markdown.
If
you
love
Markdown,
you
may
read
the
documentation
to
learn
how
to
use
this
feature:
https://laravel.com/docs/master/mail#markdown-mailables
Reply
to
a
ticket
Welcome
to
the
last
section!
In
this
section,
we
will
learn
how
to
create
a
form
for
users
to
post
a
reply.
Create
a
new
comments
table
First,
we
need
a
table
to
store
all
the
ticket
responses.
I
name
this
table
comments.
Let's
run
this
migration
command:
Then,
open
yourTimestamps_create_comments_table.php,
use
Schema
to
create
some
columns:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
151
Chapter
3
-
Building
A
Support
Ticket
System
* @return void
*/
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->increments('id');
$table->text('content');
$table->integer('post_id');
$table->integer('user_id')->nullable();
$table->tinyInteger('status')->default(1);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('comments');
}
}
You
should
know
how
to
read
this
file
by
now.
Let's
run
the
migrate
command
to
create
the
comments
table
and
its
columns:
Great!
Check
your
database
now
to
make
sure
that
you
have
created
the
comments
table.
152
Chapter
3
-
Building
A
Support
Ticket
System
Introducing
Eloquent:
Relationships
In
Laravel,
you
can
maintain
a
relationship
between
tables
easily
using
Eloquent.
Here
are
the
relationships
that
Eloquent
supports:
One
to
One
One
to
Many
Many
to
Many
Has
Many
Through
Polymorphic
Relations
Many
To
Many
Polymorphic
Relations
What
is
a
relationship?
Usually,
tables
are
related
to
each
other.
For
instance,
our
tickets
may
have
many
comments
(ticket
responses).
That
is
One
to
Many
relationship.
Once
we've
defined
a
One
to
Many
relationship
between
tickets
and
comments
table,
we
can
easily
access
and
list
all
comments
or
any
related
records.
Learn
more
about
Eloquent
relationships
here:
https://laravel.com/docs/master/eloquent-relationships
153
Chapter
3
-
Building
A
Support
Ticket
System
Create
a
new
Comment
model
As
you
know,
we
need
a
Comment
model!
Run
this
command
to
create
it:
Once
completed,
open
it
and
add
this
relationship:
In
addition,
we
may
want
to
make
all
columns
mass
assignable
except
the
id
column:
Instead
of
using
the
$fillable
property,
we
use
the
$guarded
property
here.
You
now
have:
app/Comment.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
By
doing
this,
we
let
Eloquent
know
that
this
Comment
model
belongs
to
the
Ticket
model.
154
Chapter
3
-
Building
A
Support
Ticket
System
Next,
open
the
Ticket
model
and
add:
You
now
have:
app/Ticket.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
As
you
may
have
guessed,
we
tell
that
the
Ticket
model
has
many
comments
and
Eloquent
can
use
the
post_id
(ticket
id)
to
find
all
related
comments.
That's
it!
You've
defined
a
One
to
Many
relationship
between
two
tables.
Create
a
new
comments
controller
With
the
relation
defined,
we
will
create
a
new
CommentsController
to
handle
form
submissions
and
save
comments
to
our
database.
Before
doing
that,
let's
modify
our
web.php
first:
Route::post('/comment', 'CommentsController@newComment');
When
we
send
a
POST
request
to
this
route,
Laravel
will
execute
the
CommentsController's
newComment
action.
155
Chapter
3
-
Building
A
Support
Ticket
System
It's
time
to
run
this
command
to
generate
our
controller:
Open
the
new
CommentsController
and
add
a
new
action:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\CommentFormRequest;
use App\Comment;
$comment->save();
Don't
forget
to
add:
use App\Http\Requests\CommentFormRequest;
use App\Comment;
Here
is
a
little
tip,
you
can
use
redirect()->back()
to
redirect
users
back
to
the
previous
page!
As
you
see,
we
still
use
Request
here
for
the
validation.
Create
a
new
CommentFormRequest
We
don't
have
the
CommentFormRequest
yet,
so
let's
create
it
as
well:
156
Chapter
3
-
Building
A
Support
Ticket
System
Now,
define
our
rules:
app/Requests/CommentFormRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'content'=> 'required|min:3',
];
}
}
Note:
Check
the
authorize()
function,
don't
forget
to
update
it
to
return
true
Create
a
new
reply
form
157
Chapter
3
-
Building
A
Support
Ticket
System
Good
job!
Now
open
the
tickets.show
view
and
add
this
form:
@foreach($errors->all() as $error)
<p class="alert alert-danger">{{ $error }}</p>
@endforeach
@if(session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
<fieldset>
<legend>Reply</legend>
<div class="form-group">
<div class="col-lg-12">
<textarea class="form-control" rows="3" id="content" name="content"
></textarea>
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button type="reset" class="btn btn-default">Cancel</button>
<button type="submit" class="btn btn-primary">Post</button>
</div>
</div>
</fieldset>
</form>
</div>
Here
is
the
new
tickets.show
view:
@extends('master')
@section('title', 'View a ticket')
@section('content')
158
Chapter
3
-
Building
A
Support
Ticket
System
<div class="clearfix"></div>
</div>
@foreach($errors->all() as $error)
<p class="alert alert-danger">{{ $error }}</p>
@endforeach
@if(session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
<fieldset>
<legend>Reply</legend>
<div class="form-group">
<div class="col-lg-12">
<textarea class="form-control" rows="3" id="content" name="
content"></textarea>
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button type="reset" class="btn btn-default">Cancel</button
>
<button type="submit" class="btn btn-primary">Post</button>
</div>
</div>
</fieldset>
</form>
</div>
159
Chapter
3
-
Building
A
Support
Ticket
System
</div>
@endsection
This
form
is
very
similar
to
the
create
ticket
form,
we
just
need
to
add
a
new
hidden
input
to
submit
the
ticket
id
(post_id)
as
well.
When
you
have
the
form,
let's
try
to
reply
to
a
ticket.
Yes!
You've
created
a
new
response!
Display
the
comments
One
last
step,
we're
going
to
modify
the
show
action
of
our
TicketsController
to
list
all
ticket's
comments
and
pass
them
to
the
view.
Open
TicketsController.
The
changes
in
the
show
action
are
listed
as
follows:
160
Chapter
3
-
Building
A
Support
Ticket
System
As
you
may
see
in
the
code
above,
we
just
need
to
use
this
line
to
list
all
comments:
$comments = $ticket->comments()->get();
Amazing,
right?
You
don't
even
use
a
single
SQL
code!
Now,
open
the
show.blade.php
view,
and
add
this
code
above
the
reply
form:
@foreach($comments as $comment)
<div class="well well bs-component">
<div class="content">
{!! $comment->content !!}
</div>
</div>
@endforeach
Here
is
the
new
show.blade.php:
views/tickets/show.blade.php
@extends('master')
@section('title', 'View a ticket')
@section('content')
161
Chapter
3
-
Building
A
Support
Ticket
System
<div class="clearfix"></div>
</div>
@foreach($comments as $comment)
<div class="well well bs-component">
<div class="content">
{!! $comment->content !!}
</div>
</div>
@endforeach
@foreach($errors->all() as $error)
<p class="alert alert-danger">{{ $error }}</p>
@endforeach
@if(session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
<fieldset>
<legend>Reply</legend>
<div class="form-group">
<div class="col-lg-12">
<textarea class="form-control" rows="3" id="content" name="
content"></textarea>
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button type="reset" class="btn btn-default">Cancel</button
>
<button type="submit" class="btn btn-primary">Post</button>
</div>
</div>
</fieldset>
</form>
</div>
</div>
162
Chapter
3
-
Building
A
Support
Ticket
System
@endsection
Refresh
your
browser
now!
To
make
sure
that
everything
is
working,
reply
again!
163
Chapter
3
-
Building
A
Support
Ticket
System
Congratulations!
You
now
have
a
fully
working
support
ticket
system!
Chapter
3
Summary
In
this
chapter,
you've
gone
through
the
different
steps
involved
in
creating
a
ticket
support
system.
Even
though
the
app
is
simple,
it
provides
us
many
things
to
learn:
You've
known
how
to
create
databases.
You've
learned
one
of
the
most
important
Laravel
features:
migrations.
Now
you
can
create
any
database
structures
that
you
want.
You've
understood
how
to
use
Request
to
validate
forms.
If
you
want
to
use
different
packages,
you've
known
how
to
install
them.
164
Chapter
3
-
Building
A
Support
Ticket
System
You've
learned
about
Laravel's
helper
functions.
Sending
emails
using
Gmail
and
Sendinblue
is
easy,
right?
You've
known
how
to
define
Eloquent
Relationships
and
work
with
those
relationships
easily.
Basically,
you
may
now
be
able
to
create
a
simple
blog
system.
Feel
free
to
build
a
different
application
or
customize
this
application
to
meet
your
needs.
The
next
chapter
is
where
all
the
fun
begin!
You
will
learn
to
create
a
complete
blog
application
that
has
an
admin
control
panel.
You
may
use
this
application
to
write
your
blog
posts
or
you
may
use
it
as
a
starter
template
for
all
your
amazing
applications.
Chapter
3
Source
Code
You
can
view
and
download
the
source
code
at:
Learning
Laravel
5
Book:
Chapter
3
Source
Code
165
Chapter
4
-
Building
A
Blog
Application
Chapter
4:
Building
A
Blog
Application
Up
to
this
point,
we
have
used
many
Laravel
features
to
build
our
applications.
In
this
chapter,
we're
going
to
build
a
blog
application.
By
doing
this,
we
will
learn
about
Laravel
Authentication,
Seeding,
Localization,
Middleware
and
many
useful
features
that
can
help
us
to
have
a
solid
understanding
of
Laravel
5.
For
our
purposes,
it's
always
best
to
think
about
how
our
blog
application
works
first.
What
do
we
need
to
get
started?
I
assume
that
you
have
followed
the
instructions
provided
in
the
previous
chapter
and
you've
created
a
support
ticket
system.
We
will
use
the
previous
application
as
our
template.
What
will
we
build?
Our
simple
blog
application
will
have
these
features:
Users
can
be
able
to
register
and
login.
Admin
can
write
posts.
Users
can
be
able
to
comment
on
the
posts.
There
is
an
admin
control
panel
to
manage
users,
posts
(create,
update,
delete)
Permissions
and
roles
system.
Admin
can
create/remove/edit
categories.
Let's
get
started!
Building
a
user
registration
page
166
Chapter
4
-
Building
A
Blog
Application
Since
Laravel
5,
implementing
authentication
has
become
very
easy,
Laravel
has
provided
almost
everything
for
us.
In
this
section,
you
will
learn
how
to
create
a
simple
registration
page.
By
default,
Laravel
has
created
some
authentication
controllers
for
us:
RegisterController:
handles
new
user
registration.
LoginController:
handles
authentication
(login).
ForgotPasswordController:
sends
emails
to
users
with
a
link
to
reset
their
password.
ResetPasswordController:
reset
users'
password.
You
can
find
them
in
the
app/Http/Controllers/Auth
directory.
Note:
If
you
don't
see
these
controllers,
you
may
use
a
different
version
of
Laravel.
In
Laravel
5.1
and
5.2,
we
only
have
one
controller
(the
AuthController)
that
handles
all
the
functionalities.
First,
let's
take
a
look
at
our
database,
we
should
see
that
the
users
table
has
been
created.
As
mentioned
before,
Laravel
comes
with
a
default
user
migration,
which
is
placed
in
the
database/migrations
directory:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
167
Chapter
4
-
Building
A
Blog
Application
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('users');
}
}
If
you
want
to
customize
your
users
table,
you
can
modify
this
migration.
We
also
have
the
User
model
(app/User.php)
already.
Since
Laravel
5.2,
we
can
generate
all
routes
and
views
for
our
authentication
system
using
Laravel
Auth
Scaffold.
We
just
need
to
run
this
command:
However,
for
learning
purposes,
we
will
create
our
routes
and
views
manually
to
understand
how
the
system
works.
Once
you
know
how
the
system
works,
you
can
easily
customize
it
to
meet
your
needs.
Next,
we
would
need
some
routes
for
our
registration
form.
We
can
open
web.php
and
add
these
routes:
Route::get('users/register', 'Auth\RegisterController@showRegistrationForm');
Route::post('users/register', 'Auth\RegisterController@register');
The
first
route
will
provide
the
registration
form.
The
second
route
will
process
the
form.
Both
routes
are
handled
by
the
RegisterController's
actions:
showRegistrationForm
and
register.
Let's
open
the
RegisterController
and
take
a
look
at:
168
Chapter
4
-
Building
A
Blog
Application
As
you
may
notice,
there
are
three
fields
here:
name,
email
and
password.
When
users
visit
users/register,
this
RegisterController
will
render
a
registration
view,
which
contains
a
registration
form.
Unfortunately,
Laravel
doesn't
create
the
registration
view
for
us,
we
have
to
create
it
manually.
The
registration
views
should
be
placed
at
resources/views/auth/register.blade.php.
Here
is
the
code:
resources/views/auth/register.blade.php
@extends('master')
@section('name', 'Register')
@section('content')
<div class="container col-md-6 col-md-offset-3">
<div class="well well bs-component">
<fieldset>
<legend>Register an account</legend>
<div class="form-group">
<label for="name" class="col-lg-2 control-label">Name</label>
<div class="col-lg-10">
<input type="text" class="form-control" id="name" placehol
der="Name" name="name" value="{{ old('name') }}">
</div>
</div>
<div class="form-group">
169
Chapter
4
-
Building
A
Blog
Application
<div class="col-lg-10">
<input type="email" class="form-control" id="email" placeh
older="Email" name="email" value="{{ old('email') }}">
</div>
</div>
<div class="form-group">
<label for="password" class="col-lg-2 control-label">Password</
label>
<div class="col-lg-10">
<input type="password" class="form-control" name="password
">
</div>
</div>
<div class="form-group">
<label for="password" class="col-lg-2 control-label">Confirm p
assword</label>
<div class="col-lg-10">
<input type="password" class="form-control" name="passwor
d_confirmation">
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button type="reset" class="btn btn-default">Cancel</button
>
<button type="submit" class="btn btn-primary">Submit</butt
on>
</div>
</div>
</fieldset>
</form>
</div>
</div>
@endsection
You've
created
many
forms
in
the
previous
chapters,
so
I
guess
you
should
understand
this
file
clearly.
Here
is
a
new
tip.
Instead
of
using
this
line
to
generate
a
new
CSRF
token:
You
can
simply
use
this
helper
function
to
generate
the
token!
170
Chapter
4
-
Building
A
Blog
Application
You
also
may
notice
that
there
is
a
new
old()
method.
When
the
form's
validation
fails,
the
users
will
be
redirected
back
to
the
form.
We
use
this
method
to
display
the
old
users'
input,
so
they
don't
have
to
fill
in
all
the
fields
again.
Now,
go
to
http://homestead.test/users/register,
you
should
see
a
nice
user
registration
form.
Fill
in
all
the
fields,
and
hit
submit!
You've
registered
a
new
user!
Check
your
database
now,
you
should
see:
171
Chapter
4
-
Building
A
Blog
Application
By
default,
Laravel
automatically
redirects
you
to
the
/home
URI.
If
you
see
this
error
when
you're
at
http://homestead.test/home:
or
Sorry, the page you are looking for could not be found.
Then
that
means
your
web.php
file
doesn't
have
the
home
route:
Route::get('home', 'PagesController@home');
You
can
fix
the
error
by
adding
the
home
route
into
your
app
or
you
can
open
the
RegisterController
and
take
a
look
at:
/**
* Where to redirect users after login / registration.
*
* @var string
172
Chapter
4
-
Building
A
Blog
Application
*/
protected $redirectTo = '/home';
When
users
register
for
a
new
account,
Laravel
will
validate
the
registration
form.
If
the
validation
rules
pass,
Laravel
will
save
data
to
the
database,
log
the
users
in
and
redirect
them
to
the
/home
URI
of
our
application
(home
page).
You
may
notice
that
when
you
go
to
the
registration
page,
Laravel
will
automatically
redirect
you
back
to
the
home
page
because
you're
now
logged
in.
To
redirect
users
to
other
locations,
we
simply
change
this
$redirectTo
variable:
Creating
a
logout
functionality
We
don't
have
the
logout
functionality
yet,
but
don't
worry,
it's
very
easy
to
implement.
Open
the
shared/navbar.blade.php
view,
find:
<li><a href="/users/register">Register</a></li>
<li><a href="/users/login">Login</a></li>
Replace
with
the
following
code:
@if (Auth::check())
<li><a href="/users/logout">Logout</a></li>
@else
<li><a href="/users/register">Register</a></li>
<li><a href="/users/login">Login</a></li>
@endif
To
check
whether
a
user
is
logged
in,
we
can
use
the
Auth::check()
method.
In
the
code
above,
if
users
are
logged
in,
we
will
display
a
logout
link.
173
Chapter
4
-
Building
A
Blog
Application
To
make
the
link
work,
open
web.php,
add:
Route::get('users/logout', 'Auth\LoginController@logout');
As
you
see,
when
users
visit
the
users/logout
link,
we
will
use
LoginController's
getLogout
action
to
log
the
users
out.
174
Chapter
4
-
Building
A
Blog
Application
Try
to
test
the
functionality
yourself!
Now
you
can
be
able
to
log
out!
Creating
a
login
page
It's
time
to
create
our
login
form.
As
always,
we're
going
to
define
two
different
actions
on
the
users/login
route:
Route::get('users/login', 'Auth\LoginController@showLoginForm');
Route::post('users/login', 'Auth\LoginController@login');
The
GET
route
will
display
the
login
form,
the
POST
route
will
process
the
form.
As
you
may
have
guessed,
you
should
create
a
login
view
now.
The
view
should
be
placed
at
views/auth/login.blade.php.
175
Chapter
4
-
Building
A
Blog
Application
@extends('master')
@section('name', 'Login')
@section('content')
<div class="container col-md-6 col-md-offset-3">
<div class="well well bs-component">
<fieldset>
<legend>Login</legend>
<div class="form-group">
<label for="email" class="col-lg-2 control-label">Email</label>
<div class="col-lg-10">
<input type="email" class="form-control" id="email" name="
email" value="{{ old('email') }}">
</div>
</div>
<div class="form-group">
<label for="password" class="col-lg-2 control-label">Password</
label>
<div class="col-lg-10">
<input type="password" class="form-control" name="password
">
</div>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="remember" > Remember Me?
</label>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button type="submit" class="btn btn-primary">Login</button
>
</div>
</div>
</fieldset>
</form>
</div>
</div>
176
Chapter
4
-
Building
A
Blog
Application
@endsection
Our
login
form
is
simple,
it
has
two
fields:
email
and
password.
Users
have
to
enter
the
correct
email
and
password
here
to
login.
Laravel
also
provides
the
remember
me
functionality
out
of
the
box.
We
can
implement
it
by
simply
creating
a
remember
checkbox.
Note:
The
name
of
the
checkbox
should
be
"remember".
One
last
step,
don't
forget
to
open
the
LoginController
and
change
the
$redirectTo
variable:
Now
everything
should
be
working
fine.
Let's
go
to
http://homestead.test/users/login
and
try
to
login
with
your
email
and
password!
177
Chapter
4
-
Building
A
Blog
Application
If
you
try
to
login
with
wrong
credentials,
you
should
see
this
message:
178
Chapter
4
-
Building
A
Blog
Application
Add
authentication
throttling
to
your
application
Since
Laravel
5.1.4,
we
have
had
a
new
feature:
"Authentication
Throttling".
This
feature
is
used
to
throttle
login
attempts
to
your
application.
If
users
try
to
login
many
times,
they
can't
be
able
to
login
for
one
minute.
Because
we're
using
Laravel
5.6
and
the
Laravel's
built-in
LoginController
class
for
authentication,
this
feature
has
been
implemented
already.
Now,
let's
try
to
login
with
wrong
credentials:
179
Chapter
4
-
Building
A
Blog
Application
When
you
try
to
login
many
times,
an
error
message
would
appear:
180
Chapter
4
-
Building
A
Blog
Application
Documentation:
Learn
more
about
Login
Throttling
at
https://laravel.com/docs/master/authentication#login-throttling.
Building
an
admin
area
Imagine
that
our
application
will
have
an
administration
section
and
a
front
end
section,
there
would
be
many
routes.
We
need
to
find
a
way
to
organize
all
the
routes.
Additionally,
we
may
want
to
allow
only
administrators
to
access
our
admin
area.
Fortunately,
Laravel
helps
us
to
do
that
easily.
Let's
open
web.php
file
and
add:
181
Chapter
4
-
Building
A
Blog
Application
By
using
Route::group
we
can
group
all
related
routes
together
and
apply
some
specific
rules
for
them.
We
use
the
prefix
attribute
to
prefix
each
route
in
the
route
group
with
a
URI
(admin).
In
this
case,
when
we
go
to
http://homestead.test/admin
or
any
routes
that
contain
the
admin
prefix,
Laravel
will
understand
that
we
want
to
access
the
admin
area.
Laravel
5.6
uses
PSR-4
autoloading
standard,
which
is
a
coding
style.
Your
applications
controllers,
models
and
other
classes
must
be
namespaced.
What
are
namespaces?
According
to
PHP
docs:
"namespaces
are
designed
to
solve
two
problems
that
authors
of
libraries
and
applications
encounter
when
creating
re-
usable
code
elements
such
as
classes
or
functions.".
Simply
put,
let's
think
namespaces
as
the
last
names
of
persons.
When
many
persons
have
the
same
name,
we
will
use
their
last
name
to
distinguish
them
apart.
To
namespace
a
class,
we
can
use
the
namespace
keyword
and
declare
the
namespace
at
the
top
of
the
file
before
any
other
code.
For
instance,
let's
open
RegisterController.php
class,
you
should
see
its
namespace:
<?php
namespace App\Http\Controllers\Auth;
You
can
learn
more
about
Namespace
here:
http://php.net/manual/en/language.namespaces.rationale.php
As
you
may
have
seen,
I
have
defined
a
namespace
called
Admin
for
our
routes:
If
we
have
a
class
that
has
a
namespace
like
this:
<?php
namespace App\Http\Controllers\Admin;
182
Chapter
4
-
Building
A
Blog
Application
Laravel
will
know
exactly
which
class
that
we
want
to
load
and
where
to
find
it.
Laravel
5
also
has
a
new
feature
called
HTTP
Middleware
(or
simply
Middleware).
Basically,
we
use
it
to
filter
our
applications'
HTTP
requests.
For
example,
I
use:
That
means
I
want
to
use
the
auth
middleware
for
this
route
group.
Only
authenticated
users
can
access
these
routes.
We'll
learn
more
about
Middleware
soon.
List
all
users
We
now
have
a
route
group
for
our
admin
control
panel.
Let's
list
all
the
users
so
that
we
can
view
and
manage
them
easier.
As
you
know,
we
have
defined
a
route
here:
Route::get('users', 'UsersController@index');
We
don't
have
the
UsersController
yet,
let's
use
PHP
Artisan
to
create
it:
This
time,
our
code
is
a
little
bit
different.
It
has
/Admin
before
the
controller's
name.
Laravel
is
clever.
When
we
code
like
this,
it
will
automatically
create
a
directory
called
Admin,
and
put
the
UsersController
file
into
the
Admin
directory
for
you.
More
than
that,
our
controller
has
been
namespaced!
183
Chapter
4
-
Building
A
Blog
Application
At
this
point,
I
think
that
you've
known
how
to
list
all
the
users.
Basically,
the
process
is
very
similar
to
what
we've
done
to
list
all
the
tickets
in
Chapter
3.
First,
we
tell
Laravel
that
we
want
to
use
the
User
model:
Find:
use App\Http\Controllers\Controller;
Add
below:
use App\User;
Now,
add
a
new
index()
action
as
follows:
As
you
may
have
guessed,
we
will
put
all
the
administration
views
in
the
backend
directory.
We're
going
to
create
a
new
view
called
index.blade.php
to
display
all
the
users.
Let's
create
a
new
users
directory
as
well
and
put
the
index
view
inside.
So
the
index
view
will
be
placed
at
views/backend/users/index.blade.php.
Here
is
the
code:
@extends('master')
@section('title', 'All users')
@section('content')
184
Chapter
4
-
Building
A
Blog
Application
@endif
@if ($users->isEmpty())
<p> There is no user.</p>
@else
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Joined at</th>
</tr>
</thead>
<tbody>
@foreach($users as $user)
<tr>
<td>{!! $user->id !!}</td>
<td>
<a href="#">{!! $user->name !!} </a>
</td>
<td>{!! $user->email !!}</td>
<td>{!! $user->created_at !!}</td>
</tr>
@endforeach
</tbody>
</table>
@endif
</div>
</div>
@endsection
Now,
be
sure
to
login
to
our
application
and
visit
http://homestead.test/admin/users
185
Chapter
4
-
Building
A
Blog
Application
Cool!
We
can
be
able
to
view
all
the
users!
If
you
don't
log
in
and
visit
the
page,
you
will
get
an
error:
You
may
notice
that
you're
redirected
to
http://homestead.test/login.
Don't
worry,
it's
because
our
middleware
is
working
fine.
To
fix
this
issue,
we'll
use
named
route.
Using
named
route
In
Laravel
5,
we
can
use
the
named
route
feature
to
generate
URLs
or
redirects
for
specific
routes.
Simply
put,
we
can
name
a
route
by
just
using
the
name
method:
Route::get('yourRoute', 'yourController@yourAction')->name('yourCustomNamedRoute');
186
Chapter
4
-
Building
A
Blog
Application
To
fix
the
login
issue,
we
just
need
to
open
routes/web.php:
Find:
Route::get('users/login', 'Auth\LoginController@showLoginForm')
Replace
with:
Route::get('users/login', 'Auth\LoginController@showLoginForm')->name('login');
Everything
should
be
good
to
go.
Why?
Because
if
you
try
to
access
the
admin
routes
when
you're
not
authenticated,
you
will
be
redirected
to
the
login
route.
However,
we
use
users/login
route
to
access
our
login
page.
That's
why
Laravel
doesn't
understand
where
the
login
route
is,
and
it
throws
an
error.
To
fix
the
bug,
we
just
need
to
update
the
route
and
tell
Laravel
that
the
login
route
is
now
/users/login .
Simple,
isn't
it?
Documentation:
Learn
more
about
named
routes
at
https://laravel.com/docs/5.6/routing#named-routes
In
the
next
section,
we
will
learn
how
to
use
Middleware.
All
about
Middleware
One
of
the
best
new
features
of
Laravel
5
is
Middleware
(aka
HTTP
Middleware).
Imagine
that
you
have
a
layer
between
all
requests
and
responses.
That
layer
will
help
to
handle
all
requests
and
return
proper
responses,
even
before
the
requests/responses
are
processed.
We
call
the
layer:
"Middleware".
Take
a
look
at
the
docs
to
learn
more
about
it:
https://laravel.com/docs/master/middleware
We
can
use
middleware
to
do
many
things.
For
example,
middleware
can
help
to
authenticate
users,
log
data
for
analytics,
add
CSRF
protection,
etc.
187
Chapter
4
-
Building
A
Blog
Application
You
can
find
some
middleware
in
the
app/Http/Middleware
directory.
Open
the
directory,
you'll
see
these
middleware:
1.
EncryptCookies
middleware:
Used
to
encrypt
the
application's
cookies.
2.
RedirectIfAuthenticated
middleware:
Redirect
users
to
a
page
if
they're
not
authenticated.
3.
VerifyCsrfToken
middleware:
Used
to
manage
RSRF
tokens.
4.
TrimStrings
middleware:
Used
to
automatically
trim
all
the
request
data.
5.
TrustProxies
middleware:
Used
to
quickly
customize
the
load
balancers
or
proxies
that
should
be
trusted
by
our
application.
Note:
Since
Laravel
5.4,
the
Authenticated
middleware
has
been
removed.
This
middleware
is
responsible
for
authenticating
users.
If
users
are
not
logged
in,
they
are
redirected
to
the
login
page.
Let's
open
the
RedirectIfAuthenticated
middleware:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/home');
}
return $next($request);
}
}
188
Chapter
4
-
Building
A
Blog
Application
As
you
see,
this
RedirectIfAuthenticated
middleware
is
just
a
class.
We
use
the
handle
method
to
process
all
requests
and
define
request
filters.
By
default,
if
users
are
not
authenticated,
the
middleware
automatically
redirects
users
to
the
/home
URI:
return redirect('/home');
Now
let's
say
that
we
wanted
to
use
a
new
middleware
called
Manager
to
make
sure
that
only
administrators
can
access
the
admin
area.
Creating
a
new
middleware
Creating
a
new
middleware
is
easy,
simply
run
this
Artisan
command:
A
new
middleware
called
Manager
will
be
created.
You
can
find
it
in
the
Middleware
directory.
<?php
namespace App\Http\Middleware;
use Closure;
class Manager
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
return $next($request);
}
}
One
more
step
to
do,
we
need
to
register
the
Manager
middleware.
Let's
open
the
Kernel.php
file,
which
can
be
found
in
the
Http
directory.
189
Chapter
4
-
Building
A
Blog
Application
app/Http/Kernel.php
<?php
namespace App\Http;
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
190
Chapter
4
-
Building
A
Blog
Application
* @var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
}
There
are
three
properties:
$middleware,
$middlewareGroups
and
$routeMiddleware.
If
you
want
to
enable
a
middleware
for
every
route,
you
can
append
it
to
the
$middleware
property.
For
example,
you
may
add
the
Manager
class
like
this:
protected $middleware = [
\App\Http\Middleware\Manager::class,
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\TrustProxies::class,
];
If
you
want
to
enable
a
middleware
for
just
the
web
group
(the
routes/web.php),
you
can
append
it
to
the
$middlewareGroups
property:
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\Manager::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
191
Chapter
4
-
Building
A
Blog
Application
];
However,
we
just
want
to
assign
the
Manager
middleware
to
our
admin
route
group.
Therefore,
all
we
need
to
do
is
append
the
Manager
middleware
to
the
$routeMiddleware
property.
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'manager' => \App\Http\Middleware\Manager::class,
];
We
can
use
manager
as
a
short-hand
key
to
reference
the
Manager
middleware.
Note::
Don't
append
the
Manager
middleware
to
the
$middleware
property
or
the
$middlewareGroups
property.
Only
append
the
middleware
to
the
$routeMiddleware
property,
because
we
only
want
to
use
it
for
our
admin
route
group.
Next,
open
web.php
and
modify
the
admin
route
group
to
enable
the
Manager
middleware:
Change
to:
Well
done!
Our
Manager
middleware
is
now
active.
192
Chapter
4
-
Building
A
Blog
Application
You've
got
a
solid
foundation
of
Middleware.
Keep
in
mind
that
you
can
use
Middleware
to
do
many
things.
Even
though
our
Manager
middleware
is
working
properly,
we
can't
see
any
difference.
The
reason
is,
we
don't
create
any
request
filters
yet.
If
we
want
to
restrict
access
to
the
admin
area,
we
need
to
add
roles
or
permissions
to
our
users.
Fortunately,
Laravel
has
many
packages
that
we
can
use
to
implement
the
features
easily:
Entrust:
This
is
the
most
popular
package
for
adding
Role-based
Permissions
to
Laravel
5.
However,
it's
not
updated
frequently.
laravel-permission:
This
is
a
new
package
but
it's
powerful
and
very
easy
to
use.
It
is
built
upon
Laravel's
authorization
functionality.
Because
laravel-permission
is
well
maintained,
we'll
be
using
it.
Note:
If
you
want
to
learn
more
about
Entrust,
please
read
the
first
edition
of
the
Learning
Laravel
5
book.
Adding
roles
and
permission
to
our
app
using
laravel-permission
You
can
install
laravel-permission
by
running
this
command:
Note:
vagrant ssh
to
your
Homestead,
go
to
the
root
directory
of
your
application
and
run
the
command
there.
193
Chapter
4
-
Building
A
Blog
Application
In
Laravel
5.5
or
higher,
the
service
provider
will
automatically
get
registered.
If
you're
using
an
older
version
of
Laravel,
you
might
need
to
open
the
config/app.php
file
and
find
the
providers
array,
add:
'providers' => [
...
Spatie\Permission\PermissionServiceProvider::class,
];
Note:
that
means
you
can
skip
the
step
above
because
we're
using
Laravel
5.6.
Next,
we
can
publish
the
migration
using
this
command:
A
new
timestamp_create_permission_tables
migration
file
will
be
created.
Note:
If
your
users
table
is
different,
you
have
to
manually
update
the
migration
file.
After
that,
we
can
create
the
role
and
permission
tables
using:
Check
your
database,
you
should
see
some
new
tables.
194
Chapter
4
-
Building
A
Blog
Application
We
can
publish
laravel-permission's
config
file
by
running
this
command:
A
new
permission.php
file
will
be
created
in
the
config
directory.
Last
step,
open
our
User
model
(app/User.php)
and
update
as
follows:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
}
Good
job!
You've
installed
laravel-permission!
Create
a
new
role
Once
installed,
we
can
be
able
to
create
user
roles.
Let's
say
we
will
have
two
roles:
manager
and
member.
195
Chapter
4
-
Building
A
Blog
Application
As
an
exercise
let's
create
a
simple
role
creation
form:
First,
edit
the
web.php
file
and
update
the
admin
route
group
as
follows:
We
define
routes
to
view
all
roles
and
create
a
new
role.
Again,
create
RolesController
by
running
this
command:
Open
RolesController,
add
a
new
create
action
as
follows:
Create
a
new
roles
directory,
place
it
inside
the
views/backend
directory.
Then
create
a
new
view
called
create:
views/backend/roles/create.blade.php
@extends('master')
@section('title', 'Create A New Role')
@section('content')
<div class="container col-md-8 col-md-offset-2">
<div class="well well bs-component">
196
Chapter
4
-
Building
A
Blog
Application
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
<fieldset>
<legend>Create a new role</legend>
<div class="form-group">
<label for="name" class="col-lg-2 control-label">Name</label>
<div class="col-lg-10">
<input type="text" class="form-control" id="name" name="na
me">
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button type="reset" class="btn btn-default">Cancel</button
>
<button type="submit" class="btn btn-primary">Submit</butt
on>
</div>
</div>
</fieldset>
</form>
</div>
</div>
@endsection
We
should
have
a
nice
role
creation
form
at
http://homestead.test/admin/roles/create.
197
Chapter
4
-
Building
A
Blog
Application
Next,
let's
add
a
new
store
action
into
the
RolesController
to
save
the
data:
We
use
RoleFormRequest
here
to
validate
the
form,
but
we
don't
have
the
request
file
yet.
Let's
create
it:
Open
it
and
find:
Update
to:
Here
is
the
rule:
We
only
need
to
require
users
to
enter
the
role's
name.
Be
sure
that
you
have
told
Laravel
that
you
want
to
use
Role,
Permission
and
RoleFormRequest
in
the
RolesController:
198
Chapter
4
-
Building
A
Blog
Application
app/Http/Controllers/Admin/RolesController
<?php
namespace App\Http\Controllers\Admin;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Requests\RoleFormRequest;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
Now,
go
to
http://homestead.test/admin/roles/create
and
create
two
new
roles:
manager
and
member.
Note:
Please
note
that
names
are
case-sensitive,
which
means
that
you
have
to
use
"manager"
instead
of
"Manager".
To
view
all
roles,
add
a
new
index
action
of
our
RolesController
as
follows:
Then
create
a
new
index
view
at
views/backend/roles/index.blade.php:
views/backend/roles/index.blade.php
199
Chapter
4
-
Building
A
Blog
Application
@extends('master')
@section('title', 'All roles')
@section('content')
@endsection
Go
to
http://homestead.test/admin/roles.
You
should
see
a
list
of
roles.
200
Chapter
4
-
Building
A
Blog
Application
Assign
roles
to
users
In
this
section,
we
will
learn
how
to
edit
users
and
assign
roles
to
them.
Let's
start
by
adding
these
routes
to
our
admin
route
group:
Route::get('users/{id?}/edit', 'UsersController@edit');
Route::post('users/{id?}/edit','UsersController@update');
Next,
open
users/index
view
and
find:
Update
the
link
to:
Open
Admin/UsersController,
add
a
new
edit
action:
201
Chapter
4
-
Building
A
Blog
Application
All
we
need
to
do
is
find
a
correct
user
using
the
user
id
and
list
all
the
roles
for
users
to
select.
The
$selectedRoles
is
an
array
that
holds
the
current
role's
names
of
users.
As
you
see,
we
use
the
Role
model
here.
Don't
forget
to
add
this
line
at
the
top
of
the
UsersController:
use Spatie\Permission\Models\Role;
Here
is
the
users/edit
view:
views/backend/users/edit.blade.php
@extends('master')
@section('name', 'Edit a user')
@section('content')
<div class="container col-md-6 col-md-offset-3">
<div class="well well bs-component">
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
<fieldset>
<legend>Edit user</legend>
<div class="form-group">
<label for="name" class="col-lg-2 control-label">Name</label>
<div class="col-lg-10">
<input type="text" class="form-control" id="name" placehol
der="Name" name="name"
value="{{ $user->name }}">
</div>
</div>
<div class="form-group">
<label for="email" class="col-lg-2 control-label">Email</label>
202
Chapter
4
-
Building
A
Blog
Application
<div class="col-lg-10">
<input type="email" class="form-control" id="email" placeh
older="Email" name="email"
value="{{ $user->email }}">
</div>
</div>
<div class="form-group">
<label for="select" class="col-lg-2 control-label">Role</label>
<div class="col-lg-10">
<select class="form-control" id="role" name="role[]" multi
ple>
@foreach($roles as $role)
<option value="{!! $role->name !!}" @if(in_array(
$role->name, $selectedRoles))
selected="selected" @endif >{!! $role->name !!}
</option>
@endforeach
</select>
</div>
</div>
<div class="form-group">
<label for="password" class="col-lg-2 control-label">Password</
label>
<div class="col-lg-10">
<input type="password" class="form-control" name="password"
>
</div>
</div>
<div class="form-group">
<label for="password" class="col-lg-2 control-label">Confirm p
assword</label>
<div class="col-lg-10">
<input type="password" class="form-control" name="password
_confirmation">
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button type="reset" class="btn btn-default">Cancel</button
>
<button type="submit" class="btn btn-primary">Submit</butt
on>
</div>
203
Chapter
4
-
Building
A
Blog
Application
</div>
</fieldset>
</form>
</div>
</div>
@endsection
Let's
look
at
this
code:
This
will
display
a
multiple
select
box
for
us.
We
use
@foreach
to
iterate
over
$roles
and
display
the
select
options.
To
display
which
option
is
selected,
we
use
in_array
function
to
check
if
$selectedRoles
array
contains
the
role's
name.
Save
the
changes
and
go
to
http://homestead.test/admin/users.
Click
on
the
name
of
a
user
that
you
want
to
edit.
204
Chapter
4
-
Building
A
Blog
Application
If
you
click
the
Submit
button
now,
nothing
will
happen.
We
have
to
add
a
new
UsersController's
update
action
to
save
data
to
our
database:
$user->syncRoles($request->get('role'));
We
use
user's
id
to
find
the
user
and
then
save
the
changes
to
the
database
using
$user->save()
method.
Notice
how
we
handle
the
password:
$password = $request->get('password');
if($password != "") {
205
Chapter
4
-
Building
A
Blog
Application
$user->password = Hash::make($password);
}
First,
we
check
if
the
password
is
empty.
We
only
save
the
password
when
users
enter
a
new
one,
using:
$user->password = Hash::make($password);
This
will
create
a
hashed
password.
Before
saving
a
password
to
the
database,
remember
that
you
must
hash
it
using
the
Hash::make()
method.
For
more
information,
visit:
https://laravel.com/docs/master/hashing#introduction
We'll
need
to
include
the
Hash
facade
and
UserEditFormRequest
as
well.
Find:
Add
above:
use App\Http\Requests\UserEditFormRequest;
use Illuminate\Support\Facades\Hash;
You
may
notice
that
there
is
a
new
syncRoles()
method
here:
$user->syncRoles($request->get('role'));
syncRoles
is
a
laravel-permission
method
that
we
can
use
to
automatically
sync
(attach
and
detach)
multiple
roles.
Basically,
this
method
will
retrieve
the
$role
array,
which
contains
roles'
ID,
and
attach
the
appropriate
roles
to
the
user.
If
there
is
no
role,
it
will
detach
the
role
from
the
user.
Here
is
our
updated
UsersController
file:
<?php
namespace App\Http\Controllers\Admin;
206
Chapter
4
-
Building
A
Blog
Application
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\User;
use Spatie\Permission\Models\Role;
use App\Http\Requests\UserEditFormRequest;
use Illuminate\Support\Facades\Hash;
$user->syncRoles($request->get('role'));
As
always,
generate
the
UserEditFormRequest
by
running
this
command:
Be
sure
to
change
return
false
to
true.
Here
are
the
rules:
UserEditFormRequest.php
207
Chapter
4
-
Building
A
Blog
Application
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required',
'email'=> 'required',
'role'=> 'required',
];
}
}
Sweet!
Now
let's
try
to
assign
a
role
to
a
user!
208
Chapter
4
-
Building
A
Blog
Application
Note:
If
you
see
any
error,
make
sure
that
laravel-permission
is
installed
properly,
and
you've
added
the
HasRoles
trait
to
your
User
model.
Restrict
access
to
Manager
users
Absolutely,
we
don't
want
anyone
to
access
the
admin
area,
except
our
Manager
users.
Open
our
Manager
middleware:
As
you
see,
there
is
no
filter
here,
everyone
can
access
the
admin
area.
There
are
many
ways
to
restrict
access,
but
the
easiest
way
is
using
the
Auth
facade:
Middleware/Manager.php
<?php
namespace App\Http\Middleware;
209
Chapter
4
-
Building
A
Blog
Application
use Closure;
use Illuminate\Support\Facades\Auth;
class Manager
{
public function handle($request, Closure $next)
{
if(!Auth::check()) {
return redirect('users/login');
} else {
$user = Auth::user();
if($user->hasRole('manager'))
{
return $next($request);
} else {
return redirect('/');
}
}
}
}
Let's
see
the
code
line
by
line.
First,
we
tell
Laravel
that
we
want
to
use
the
Auth
facade:
use Illuminate\Support\Facades\Auth;
Then
we
use
Auth:check()
method
to
check
if
the
user
is
logged
in.
If
not,
then
the
user
is
redirected
to
the
login
page.
if(!Auth::check()) {
return redirect('users/login');
} else {
Otherwise,
we
use
Auth::user()
method
to
retrieve
the
authenticated
user.
This
way,
we
can
check
if
the
user
has
the
manager
role.
If
not,
the
user
is
redirected
back
to
the
home
page.
$user = Auth::user();
if($user->hasRole('manager'))
{
return $next($request);
} else {
return redirect('/');
}
210
Chapter
4
-
Building
A
Blog
Application
Now,
try
to
access
the
admin
area
to
test
our
Manager
middleware.
If
you
don't
sign
in
and
you're
not
a
manager,
you
can't
access
any
routes
of
the
admin
route
group.
Tip:
If
you
can't
access
http://homestead.test/admin/users
anymore,
you
can
open
the
web.php
file,
remove
the
manager
middleware
or
change
it
to
auth.
When
the
manager
middleware
is
active,
only
managers
(users
who
have
the
manager
role)
can
be
able
to
access
the
admin
routes.
Create
an
admin
dashboard
page
Since
we
haven't
created
the
admin
home
page,
when
we
access
http://homestead.test/admin,
there
is
an
error:
Note:
You
may
see
a
different
error
message
if
you're
using
a
different
Laravel
version.
It's
normal.
Let's
move
onto
creating
the
admin
home
page
now
so
that
we
can
access
the
admin
area
easily.
Update
our
web.php
file,
add
this
route
into
the
admin
route
group:
Route::get('/', 'PagesController@home');
Next,
create
the
Admin/PagesController:
211
Chapter
4
-
Building
A
Blog
Application
Admin/PagesController.php
file
will
be
created.
Let's
add
a
new
home
action:
Admin/PagesController.php
<?php
namespace App\Http\Controllers\Admin;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
Finally,
create
a
new
home
view
in
the
backend
directory:
views/backend/home.blade.php
@extends('master')
@section('title', 'Admin Control Panel')
@section('content')
<div class="container">
<div class="row banner">
<div class="col-md-12">
<div class="list-group">
<div class="list-group-item">
<div class="row-action-primary">
<i class="material-icons">face</i>
</div>
<div class="row-content">
<div class="action-secondary"><i class="material-icons">ac
count_box</i></div>
<h4 class="list-group-item-heading">Manage User</h4>
<a href="/admin/users" class="btn btn-default btn-raised">
All Users</a>
</div>
</div>
<div class="list-group-separator"></div>
<div class="list-group-item">
<div class="row-action-primary">
<i class="material-icons">supervisor_account</i>
212
Chapter
4
-
Building
A
Blog
Application
</div>
<div class="row-content">
<div class="action-secondary"><i class="material-icons">ac
cessibility</i></div>
<h4 class="list-group-item-heading">Manage Roles</h4>
<a href="/admin/roles" class="btn btn-default btn-raised">
All Roles</a>
<a href="/admin/roles/create" class="btn btn-primary btn-r
aised">Create A Role</a>
</div>
</div>
<div class="list-group-separator"></div>
<div class="list-group-item">
<div class="row-action-primary">
<i class="material-icons">content_copy</i>
</div>
<div class="row-content">
<div class="action-secondary"><i class="material-icons">bo
rder_color</i></div>
<h4 class="list-group-item-heading">Manage Posts</h4>
<a href="/admin/posts" class="btn btn-default btn-raised">
All Posts</a>
<a href="/admin/posts/create" class="btn btn-primary btn-r
aised">Create A Post</a>
</div>
</div>
<div class="list-group-separator"></div>
</div>
</div>
</div>
</div>
@endsection
213
Chapter
4
-
Building
A
Blog
Application
I
just
add
some
buttons
to
access
other
admin
pages
here.
Feel
free
to
change
the
layout
to
your
liking.
One
more
thing,
how
about
adding
a
link
to
our
navigation
bar
to
access
the
admin
area
easier?
Open
the
shared/navbar
view
and
find:
@if (Auth::check())
<li><a href="/users/logout">Logout</a></li>
@else
Update
to:
@if (Auth::check())
@role('manager')
<li><a href="/admin">Admin</a></li>
@endrole
<li><a href="/users/logout">Logout</a></li>
@else
As
you
see,
we
can
use
the
@role
Blade
directive
to
check
if
the
user
is
a
manager
in
views
as
well.
214
Chapter
4
-
Building
A
Blog
Application
Create
a
new
post
Now
that
we
have
everything
in
order,
we're
going
to
build
a
form
to
create
blog
posts
in
this
section.
Actually,
the
process
is
very
similar
to
what
we've
done
to
create
users,
tickets,
and
roles.
To
get
started,
let's
create
a
new
Post
model
and
its
migration:
215
Chapter
4
-
Building
A
Blog
Application
You
can
also
generate
the
post's
migration
at
the
same
time
by
adding
the
-m
option.
Open
timestamp_create_posts_table.php,
which
can
be
found
in
the
migrations
directory.
Update
the
up
method
as
follows:
Don't
forget
to
run
the
migrate
command
to
add
a
new
posts
table
and
its
columns
into
our
database:
Open
web.php,
add
these
routes
to
the
admin
route
group:
Route::get('posts', 'PostsController@index');
Route::get('posts/create', 'PostsController@create');
Route::post('posts/create', 'PostsController@store');
Route::get('posts/{id?}/edit', 'PostsController@edit');
Route::post('posts/{id?}/edit','PostsController@update');
Create
a
new
Admin/PostsController
by
running
this
command:
Open
Admin/PostsController,
update
the
create
action
as
follows:
216
Chapter
4
-
Building
A
Blog
Application
Create
a
new
posts
folder
in
the
backend
directory.
Place
a
new
create
view
there:
views/backend/posts/create.blade.php
@extends('master')
@section('title', 'Create A New Post')
@section('content')
<div class="container col-md-8 col-md-offset-2">
<div class="well well bs-component">
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
<fieldset>
<legend>Create a new post</legend>
<div class="form-group">
<label for="title" class="col-lg-2 control-label">Title</label>
<div class="col-lg-10">
<input type="text" class="form-control" id="title" placeho
lder="Title" name="title">
</div>
</div>
<div class="form-group">
<label for="content" class="col-lg-2 control-label">Content</l
abel>
<div class="col-lg-10">
<textarea class="form-control" rows="3" id="content" name="
content"></textarea>
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button type="reset" class="btn btn-default">Cancel</button
>
<button type="submit" class="btn btn-primary">Submit</butt
on>
</div>
</div>
217
Chapter
4
-
Building
A
Blog
Application
</fieldset>
</form>
</div>
</div>
@endsection
When
we
visit
http://homestead.test/admin/posts/create,
we
can
see
a
new
post
creation
form.
However,
we
also
need
to
create
Post
Categories.
The
Post
Categories
allow
the
users
to
select
a
category
for
the
post
they
are
creating.
Run
this
command
to
create
a
new
Category
model
and
its
migration:
218
Chapter
4
-
Building
A
Blog
Application
Next,
open
the
timestamp_create_categories_table.php
and
update
the
up
method
as
follows:
This
will
create
a
new
column
called
name
to
store
categories'
name.
Create
a
Many-to-Many
relation
As
you
know,
a
post
may
have
multiple
categories,
and
a
category
may
be
associated
with
many
posts.
This
is
a
many-to-many
relation.
Many-to-many
relations
need
an
intermediate
table
(aka
pivot
table)
to
work.
The
table
will
have
two
columns,
that
store
the
foreign
keys
of
two
related
models.
For
example,
the
role_user
table
is
a
pivot
table,
which
consists
the
users_id
and
role_id.
The
pivot
table
of
posts
and
categories
will
be
called
category_post
table
(alphabetical
order).
We
have
to
create
our
category_post
manually.
Run
this
Artisan
command
to
generate
the
category_post
migration:
Next,
open
the
new
timestamp_create_category_post_table
migration
file
and
modify
the
up
method:
$table->foreign('category_id')
->references('id')->on('categories')
219
Chapter
4
-
Building
A
Blog
Application
->onUpdate('cascade')
->onDelete('cascade');
$table->foreign('post_id')
->references('id')->on('posts')
->onUpdate('cascade')
->onDelete('cascade');
});
}
Save
the
changes
and
run
the
migrate
command:
Check
your
database
to
make
sure
that
you
have
all
these
tables:
posts,
categories
and
category_post.
Alternatively,
you
can
use
Laravel
5
Extended
Generators
package
to
generate
the
pivot
table
faster:
220
Chapter
4
-
Building
A
Blog
Application
https://github.com/laracasts/Laravel-5-Generators-Extended
Great!
Now
open
our
Post
model
and
update
it
to
look
like
this:
app/Post.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
We
use
$guarded
property
to
make
all
columns
mass
assignable,
except
the
id
column.
The
belongsToMany
method
is
used
to
let
Laravel
know
that
this
model
has
many-
to-many
relation.
Open
our
Category
model
and
update
it
to
look
like
this:
app/Category.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
221
Chapter
4
-
Building
A
Blog
Application
You've
successfully
defined
a
many-to-many
relation.
Create
and
view
categories
Let's
make
a
form
to
create
categories.
Open
web.php,
add
these
routes
to
the
admin
route
group:
Route::get('categories', 'CategoriesController@index');
Route::get('categories/create', 'CategoriesController@create');
Route::post('categories/create', 'CategoriesController@store');
Generate
a
new
CategoriesController
by
running
this
command:
Open
the
newly
created
CategoriesController
and
update
the
create
action:
As
usual,
create
a
new
categories
folder
inside
the
backend
directory.
Put
a
new
create
view
in
the
categories
directory:
@extends('master')
@section('title', 'Create A New Category')
@section('content')
<div class="container col-md-8 col-md-offset-2">
<div class="well well bs-component">
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
222
Chapter
4
-
Building
A
Blog
Application
<fieldset>
<legend>Create a new category</legend>
<div class="form-group">
<label for="name" class="col-lg-2 control-label">Name</label>
<div class="col-lg-10">
<input type="text" class="form-control" id="name" name="na
me">
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button type="reset" class="btn btn-default">Cancel</button
>
<button type="submit" class="btn btn-primary">Submit</butt
on>
</div>
</div>
</fieldset>
</form>
</div>
</div>
@endsection
Visit
http://homestead.test/admin/categories/create,
you
should
have
a
form
to
create
a
new
category:
223
Chapter
4
-
Building
A
Blog
Application
Good
job!
Now
open
the
CategoriesController
again,
update
the
store
action
as
follows:
$category->save();
Tell
Laravel
that
you
want
to
use
the
CategoryFormRequest
and
the
Category
model:
224
Chapter
4
-
Building
A
Blog
Application
use App\Category;
use App\Http\Requests\CategoryFormRequest;
Generate
a
new
CategoryFormRequest
file
by
running
this:
Modify
the
authorize
method
and
the
rules
method
to
look
like
this:
Here
is
the
updated
CategoryFormRequest:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
225
Chapter
4
-
Building
A
Blog
Application
{
return [
'name'=> 'required|min:3',
];
}
}
Save
the
changes
and
visit
the
category
form
again.
Create
some
categories
(News,
Laravel,
Announcement,
etc.)
:
To
view
all
categories,
open
CategoriesController
again,
update
the
index
action:
226
Chapter
4
-
Building
A
Blog
Application
Create
a
new
index
view
and
place
it
in
the
categories
directory:
@extends('master')
@section('title', 'All categories')
@section('content')
@endsection
Now
you
can
be
able
to
view
all
categories
at
http://homestead.test/admin/categories.
227
Chapter
4
-
Building
A
Blog
Application
Let's
update
the
admin
home
page
(dashboard)
to
include
the
category
links
there.
Open
the
backend/home
view:
Find
(at
the
end
of
the
file):
Add
below:
<div class="list-group-item">
<div class="row-action-primary">
<i class="material-icons">format_list_bulleted</i>
</div>
<div class="row-content">
<div class="action-secondary"><i class="material-icons">format_list_bulleted</i
></div>
<h4 class="list-group-item-heading">Manage Categories</h4>
<a href="/admin/categories" class="btn btn-default btn-raised">All Categories</
a>
<a href="/admin/categories/create" class="btn btn-primary btn-raised">New Cate
gory</a>
</div>
</div>
<div class="list-group-separator"></div>
Here
is
our
new
admin
home
page:
228
Chapter
4
-
Building
A
Blog
Application
Select
categories
when
creating
a
post
Now
we
can
create
a
new
post
with
categories.
Open
PostsController
and
find:
Add
above:
use App\Category;
use App\Post;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Auth;
Update
the
create
action
as
follows:
Next,
open
the
posts/create
view
and
find:
<div class="form-group">
<label for="content" class="col-lg-2 control-label">Content</label>
<div class="col-lg-10">
<textarea class="form-control" rows="3" id="content" name="content"></textarea>
</div>
</div>
Add
this
code
below
to
allow
users
to
select
the
categories:
<div class="form-group">
<label for="categories" class="col-lg-2 control-label">Categories</label>
<div class="col-lg-10">
<select class="form-control" id="category" name="categories[]" multiple>
@foreach($categories as $category)
<option value="{!! $category->id !!}">
{!! $category->name !!}
229
Chapter
4
-
Building
A
Blog
Application
</option>
@endforeach
</select>
</div>
</div>
Here
is
the
updated
create
view:
posts/create.blade.php
@extends('master')
@section('title', 'Create A New Post')
@section('content')
<div class="container col-md-8 col-md-offset-2">
<div class="well well bs-component">
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
<fieldset>
<legend>Create a new post</legend>
<div class="form-group">
<label for="title" class="col-lg-2 control-label">Title</label>
<div class="col-lg-10">
<input type="text" class="form-control" id="title" placeho
lder="Title" name="title">
</div>
</div>
<div class="form-group">
<label for="content" class="col-lg-2 control-label">Content</l
abel>
<div class="col-lg-10">
<textarea class="form-control" rows="3" id="content" name="
content"></textarea>
</div>
</div>
<div class="form-group">
<label for="categories" class="col-lg-2 control-label">Categor
230
Chapter
4
-
Building
A
Blog
Application
ies</label>
<div class="col-lg-10">
<select class="form-control" id="category" name="categorie
s[]" multiple>
@foreach($categories as $category)
<option value="{!! $category->id !!}">
{!! $category->name !!}
</option>
@endforeach
</select>
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button type="reset" class="btn btn-default">Cancel</button
>
<button type="submit" class="btn btn-primary">Submit</butt
on>
</div>
</div>
</fieldset>
</form>
</div>
</div>
@endsection
231
Chapter
4
-
Building
A
Blog
Application
We
now
have
a
new
nice
post
creation
form!
Now
let's
create
the
PostFormRequest
first:
Modify
the
authorize
method
and
the
rules
method
of
the
PostFormRequest
to
look
like
this:
232
Chapter
4
-
Building
A
Blog
Application
return [
'title' => 'required',
'content'=> 'required',
'categories' => 'required',
];
}
Finally,
open
the
PostsController
again,
and
find:
Add
this
code
above
to
use
PostFormRequest
in
this
controller:
use App\Http\Requests\PostFormRequest;
Next,
update
the
store
action:
$post->save();
$post->categories()->sync($request->get('categories'));
To
create
the
post's
slug,
we
can
use
Str::slug
method
to
automatically
generate
a
friendly
slug
from
the
given
post's
title.
As
you
see,
we
also
use
the
Auth
facade
to
get
the
current
user
id.
After
saving
the
post
to
the
database
using
$post->save,
we
can
use:
$post->categories()->sync($request->get('categories'));
233
Chapter
4
-
Building
A
Blog
Application
to
attach
the
selected
categories
to
the
post.
Try
to
create
a
new
post
now.
Congratulations!
You've
just
created
your
first
blog
post!
View
and
edit
posts
Now
that
you
know
how
to
create
a
post,
let's
next
create
pages
to
view
all
the
posts
and
edit
them.
Display
all
posts
As
a
reminder,
we've
already
defined
this
route
in
the
previous
section:
Route::get('posts', 'PostsController@index');
234
Chapter
4
-
Building
A
Blog
Application
We
can
update
the
index
action
of
the
PostsController
as
follows:
Next,
create
a
new
index
view
at
backend/posts/index.blade.php:
backend/posts/index.blade.php
@extends('master')
@section('title', 'All posts')
@section('content')
</tr>
</thead>
<tbody>
@foreach($posts as $post)
<tr>
<td>{!! $post->id !!}</td>
<td>
<a href="#">{!! $post->title !!} </a>
</td>
<td>{!! $post->slug !!}</td>
<td>{!! $post->created_at !!}</td>
<td>{!! $post->updated_at !!}</td>
235
Chapter
4
-
Building
A
Blog
Application
</tr>
@endforeach
</tbody>
</table>
@endif
</div>
</div>
@endsection
Go
to
http://homestead.test/admin/posts
to
view
all
the
posts.
Edit
a
post
We
also
have
defined
these
routes:
Route::get('posts/{id?}/edit', 'PostsController@edit');
Route::post('posts/{id?}/edit','PostsController@update');
Let's
modify
the
edit
action
to
display
a
post
edit
form:
Create
a
new
edit
view
at
backend/posts/edit.blade.php:
backend/posts/edit.blade.php
@extends('master')
@section('title', 'Edit A Post')
@section('content')
<div class="container col-md-8 col-md-offset-2">
<div class="well well bs-component">
236
Chapter
4
-
Building
A
Blog
Application
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
<fieldset>
<legend>Edit a post</legend>
<div class="form-group">
<label for="title" class="col-lg-2 control-label">Title</label>
<div class="col-lg-10">
<input type="text" class="form-control" id="title" placeho
lder="Title" name="title" value="{{ $post->title }}">
</div>
</div>
<div class="form-group">
<label for="content" class="col-lg-2 control-label">Content</l
abel>
<div class="col-lg-10">
<textarea class="form-control" rows="3" id="content" name="
content">{!! $post->content !!}</textarea>
</div>
</div>
<div class="form-group">
<label for="select" class="col-lg-2 control-label">Categories</
label>
<div class="col-lg-10">
<select class="form-control" id="categories" name="categor
ies[]" multiple>
@foreach($categories as $category)
<option value="{!! $category->id !!}" @if(in_array
($category->id, $selectedCategories))
selected="selected" @endif >{!! $category->
name !!}
</option>
@endforeach
</select>
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button type="reset" class="btn btn-default">Cancel</button
>
<button type="submit" class="btn btn-primary">Submit</butt
on>
</div>
237
Chapter
4
-
Building
A
Blog
Application
</div>
</fieldset>
</form>
</div>
</div>
@endsection
After
creating
the
form,
you'll
need
to
modify
the
posts/index
view
to
add
links
to
the
posts.
Find:
Edit
to:
Go
to
http://homestead.test/admin/posts
and
click
on
the
post
title,
you
should
be
able
to
see
a
post
edit
form:
238
Chapter
4
-
Building
A
Blog
Application
As
always,
create
a
new
PostEditFormRequest
by
running
this
command:
Modify
the
authorize
method
and
the
rules
method
to
look
like
this:
239
Chapter
4
-
Building
A
Blog
Application
Once
the
file
is
saved,
open
PostsController
and
find:
Add
above:
use App\Http\Requests\PostEditFormRequest;
Finally,
update
the
update
method
to
save
the
changes
to
our
database:
$post->save();
$post->categories()->sync($request->get('categories'));
Instead
of
creating
a
new
saveCategories
method
(similar
to
the
saveRoles
method),
we
can
sync
the
categories
like
this:
$post->categories()->sync($request->get('categories'));
Now
try
to
edit
a
post
and
submit
the
changes.
240
Chapter
4
-
Building
A
Blog
Application
Well
done!
Once
submitted,
you
should
be
able
to
update
a
post!
Display
all
blog
posts
In
this
section,
we
will
create
a
blog
page
that
lists
all
blog
posts.
This
page
is
public.
Everyone
can
access
it
and
read
the
posts.
Let's
register
a
blog
route
by
adding
the
following
code
to
web.php:
Route::get('/blog', 'BlogController@index');
We
would
need
to
create
the
BlogController:
241
Chapter
4
-
Building
A
Blog
Application
Insert
the
following
code
into
it:
Find:
Tell
Laravel
that
you
want
to
use
the
Post
model
in
this
controller.
Add
above:
use App\Post;
Now,
update
the
index
action:
Create
a
new
index
view
at
views/blog
directory.
The
following
are
the
contents
of
the
views/blog/index.blade.php
file:
views/blog/index.blade.php
@extends('master')
@section('title', 'Blog')
@section('content')
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
@if ($posts->isEmpty())
<p> There is no post.</p>
@else
@foreach ($posts as $post)
<div class="panel panel-default">
<div class="panel-heading">{!! $post->title !!}</div>
<div class="panel-body">
{!! mb_substr($post->content,0,500) !!}
</div>
242
Chapter
4
-
Building
A
Blog
Application
</div>
@endforeach
@endif
</div>
@endsection
We
use
mb_substr
(Multibyte
String)
function
to
display
only
500
characters
of
the
post.
Tip:
If
you
want
to
learn
more
about
the
function,
visit
http://php.net/manual/en/function.mb-substr.php
We
should
add
a
blog
link
to
our
navigation
bar
to
access
the
blog
page
faster.
Open
shared/navbar.blade.php
and
find:
<li><a href="/about">About</a></li>
Add
above:
<li><a href="/blog">Blog</a></li>
Head
over
to
your
browser
and
visit
the
blog
page.
243
Chapter
4
-
Building
A
Blog
Application
Now,
everyone
can
see
all
your
blog
posts!
Display
a
single
blog
post
When
we
click
on
the
post's
title,
we
should
see
the
full
post.
Open
web.php,
register
this
route:
Route::get('/blog/{slug?}', 'BlogController@show');
Before
updating
the
show
method,
let's
think
about
how
we
can
implement
the
blog
post
comment
feature.
Note:
I
assume
that
you've
created
a
Comment
model.
If
not,
please
read
Chapter
3
to
know
how
to
implement
the
comment
feature.
244
Chapter
4
-
Building
A
Blog
Application
Normally,
we
have
to
create
a
different
Comment
model
(PostComment,
for
example)
to
list
a
post's
comments.
That
means
we
have
two
columns:
comments
and
postcomments.
Fortunately,
by
defining
Polymorphic
Relations,
we
can
store
comments
for
our
tickets
and
for
our
posts
using
only
a
single
comments
table!
Using
Polymorphic
Relations
You
can
read
about
this
relationship
here:
http://laravel.com/docs/master/eloquent-relationships#many-to-many-
polymorphic-relations
To
build
this
relationship,
our
comments
table
must
have
two
columns:
post_id
and
post_type.
The
post_id
column
contains
the
ID
of
the
tickets
or
the
posts,
while
the
post_type
contains
the
class
name
of
the
owning
model
(App\Ticket
or
App\Post).
Currently,
the
comments
table
has
the
post_id
column
but
it
doesn't
have
the
post_type
column
yet.
Let's
create
a
migration
to
add
the
column
into
our
comments
table:
This
will
create
a
new
file
called
timestamp_add_post_type_to_comments_table.php
in
your
migrations
directory.
Open
the
file
and
modify
it
to
look
like
this:
} else {
Schema::table('comments', function (Blueprint $table) {
$table->string('post_type')->nullable();
});
}
}
245
Chapter
4
-
Building
A
Blog
Application
We
check
if
the
comments
table
has
the
post_type
column.
If
not,
we
add
the
post_type
column
into
the
table.
Don't
forget
to
run
the
migrate
command:
Now
our
comments
table
should
have
the
post_type
column.
It's
time
to
build
the
Polymorphic
relationship.
Open
the
Comment
model,
update
it
as
follows:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
246
Chapter
4
-
Building
A
Blog
Application
return $this->morphTo();
}
}
The
post()
method
will
get
all
of
the
owning
models.
Open
the
Ticket
model,
update
the
comments()
method
to:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
Open
the
Post
model,
update
it
as
follows:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
The
comments()
method
will
be
used
to
get
all
post's
comments.
247
Chapter
4
-
Building
A
Blog
Application
Done!
You've
defined
Polymorphic
relations.
Now,
open
BlogController
and
update
the
show
method:
Here
is
the
blog/show
view:
views/blog/show.blade.php
@extends('master')
@section('title', 'View a post')
@section('content')
@foreach($comments as $comment)
<div class="well well bs-component">
<div class="content">
{!! $comment->content !!}
</div>
</div>
@endforeach
@foreach($errors->all() as $error)
<p class="alert alert-danger">{{ $error }}</p>
@endforeach
@if(session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
248
Chapter
4
-
Building
A
Blog
Application
<fieldset>
<legend>Comment</legend>
<div class="form-group">
<div class="col-lg-12">
<textarea class="form-control" rows="3" id="content" n
ame="content"></textarea>
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button type="reset" class="btn btn-default">Cancel</b
utton>
<button type="submit" class="btn btn-primary">Post</bu
tton>
</div>
</div>
</fieldset>
</form>
</div>
</div>
@endsection
Notice
that
we've
added
a
new
hidden
field
called
post_type.
Because
this
is
the
post's
comment,
the
value
of
the
field
is:
"App\Post"
(class
name).
Open
CommentsController
and
find:
Add
post_type
to
save
its
value
into
the
database:
Finally,
open
the
ticket/show
view
and
find:
249
Chapter
4
-
Building
A
Blog
Application
Add
below:
We
add
a
new
hidden
field
called
post_type,
which
has
the
"App\Ticket"
value,
to
let
Laravel
know
that
the
comments
of
this
view
belong
to
the
Ticket
model.
One
more
thing
to
do,
open
the
blog/index
view
and
find:
Modify
to:
Now,
go
to
your
browser
and
view
a
post.
Try
to
post
a
comment
as
well.
250
Chapter
4
-
Building
A
Blog
Application
Let's
check
the
database
to
see
how
things
work:
As
you
see,
even
though
the
comments
have
the
same
post_id
(which
is
2),
their
post_type
values
are
different.
The
ORM
uses
the
post_type
column
to
determine
which
model
is
related
to
the
comments.
It's
a
bit
confusing.
However,
if
you
know
how
to
use
Polymorphic
Relations,
you
will
gain
many
benefits.
251
Chapter
4
-
Building
A
Blog
Application
Seeding
our
database
Instead
of
creating
test
data
manually,
we
can
use
Laravel's
Seeder
class
to
populating
our
database.
In
this
section,
we
will
learn
how
to
use
Seeder
by
creating
sample
users
for
our
application.
To
create
a
seeder,
run
this
command:
This
will
create
a
class
called
UserTableSeeder,
which
is
placed
in
database/seeds
directory.
Update
the
run()
method
as
follows:
],
[
'name' => 'Lisa',
'email' => str_random(12).'@email.com',
'password' => bcrypt('yourPassword'),
'created_at' => new DateTime,
'updated_at' => new DateTime,
],
]);
}
Within
the
run
method,
we
use
database
query
builder
to
create
dummy
user
data.
Keep
in
mind
that
we
can
also
load
data
from
a
JSON
or
CSV
file.
252
Chapter
4
-
Building
A
Blog
Application
Instead
of
using
the
Hash
facade
to
hash
the
password,
you
can
also
use
the
bcrypt()
helper
function
to
do
that.
Read
more
about
Database
Query
Builder
here:
https://laravel.com/docs/master/queries
You
may
also
want
to
try
Faker,
which
is
a
popular
PHP
package
that
helps
to
create
fake
data
effectively.
https://github.com/fzaninotto/Faker
Note:
If
you're
using
Laravel
5.1
or
newer,
the
Faker
library
has
been
already
installed
by
default.
After
writing
the
seeder
class,
open
database/seeds/DatabaseSeeder.php.
Normally,
we
would
create
many
seeder
classes
to
seed
different
dummy
data.
For
example,
UserTableSeeder
is
used
to
create
fake
users,
PostTableSeeder
is
used
to
create
dummy
posts,
etc.
We
use
the
DatabaseSeeder
file
to
control
the
order
of
seeder
classes.
In
this
case,
we
only
have
one
UserTableSeeder
class,
so
let's
write
like
this:
To
seed
data,
run
this
Artisan
command:
This
will
execute
the
run
method
of
the
UserTableSeed
class
and
insert
data
into
our
database.
253
Chapter
4
-
Building
A
Blog
Application
Now
check
your
database
or
visit
http://homestead.test/admin/users,
there
are
some
new
users:
Seeding
is
very
useful.
You
may
try
to
use
this
feature
to
create
posts,
tickets
and
other
data
to
test
your
application!
Localization
You
can
easily
translate
strings
to
multiple
languages
using
Laravel
localization
feature.
All
language
files
are
stored
in
the
resources/lang
directory.
254
Chapter
4
-
Building
A
Blog
Application
By
default,
there
is
an
en
(English)
directory,
which
contains
English
strings.
If
you
want
to
support
other
languages,
create
a
new
directory
at
the
same
level
as
the
en
directory.
Please
note
that
all
language
directories
should
be
named
using
ISO
639-
1
Code.
Read
more
about
ISO
639-1
Code
here:
http://www.loc.gov/standards/iso639-2/php/code_list.php
Open
en/passwords.php
file:
<?php
return [
/*
|--------------------------------------------------------------------------
| Password Reset Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are the default lines which match reasons
| that are given by the password broker for a password update attempt
| has failed, such as for an invalid token or invalid new password.
|
*/
'password' => 'Passwords must be at least six characters and match the confirmatio
n.',
'reset' => 'Your password has been reset!',
'sent' => 'We have e-mailed your password reset link!',
'token' => 'This password reset token is invalid.',
'user' => "We can't find a user with that e-mail address.",
];
As
you
see,
a
language
file
simply
returns
an
array
that
contains
translated
strings.
You
can
change
the
default
language
by
editing
this:
The
line
can
be
found
in
the
config/app.php
configuration
file.
Let's
create
a
new
language
file
to
translate
our
application!
255
Chapter
4
-
Building
A
Blog
Application
Go
to
resources/lang/en
directory,
create
a
new
file
called
main.php,
which
looks
like
this:
resources/lang/en/main.php
<?php
return [
];
Next,
open
the
home
view
and
find:
views/home.blade.php
Change
to:
Head
over
to
your
browser:
256
Chapter
4
-
Building
A
Blog
Application
The
trans
helper
function
is
used
to
retrieve
lines
from
language
files:
main
is
the
name
of
the
language
file
(main.php).
subtitle
is
the
key
of
the
language
line.
As
you
notice,
we
may
use
the
localization
feature
to
manage
strings
as
well.
For
example,
put
all
your
application's
strings
into
the
main.php
file;
when
you
want
to
edit
a
string,
you
can
find
it
easily.
Don't
forget
to
read
the
docs
to
learn
more
about
localization:
https://laravel.com/docs/master/localization
Chapter
4
Summary
257
Chapter
4
-
Building
A
Blog
Application
Congratulations!
You've
built
a
complete
blog
application!
Our
application
is
not
perfect
yet,
but
you
may
use
it
as
a
starter
template
and
apply
some
concepts
that
you've
known
to
build
a
larger
application.
Towards
the
end
of
this
chapter,
let's
review
what
we
have
learned:
You've
known
how
to
authenticate
users
and
add
login
throttling
to
your
app.
You
now
understand
more
about
routes
and
route
group.
Using
Middleware,
you
can
handle
requests/responses
effectively.
Many
Laravel
applications
are
using
laravel-permission,
it's
one
of
the
best
packages
to
manage
roles
and
permissions.
We
only
use
the
"roles"
feature
in
this
book.
Try
to
create
some
permissions
to
secure
your
apps
better.
Understanding
Many-to-Many
Relations
and
Polymorphic
Relations
is
hard
at
first,
but
you'll
gain
many
benefits
later.
Now
you
can
be
able
to
seed
your
database!
Seeding
is
easy.
Right?
The
Laravel
localization
feature
is
simple,
but
it's
very
helpful
and
powerful.
Try
to
use
it
in
all
your
applications
to
manage
all
the
strings.
Remember
that,
this
is
just
a
beginning,
there
is
still
so
much
more
to
learn.
Hopefully,
you
will
have
a
successful
application
someday!
Enjoy
the
journey!
If
you
wish
to
learn
more
about
Laravel,
check
our
Laravel
5
Cookbook,
Laravel
Angular
book
and
Vue.js
Book
out!
Note:
If
you
would
like
to
give
feedback,
report
bugs,
translate
the
book,
or
ask
any
questions,
please
email
us
at
support@learninglaravel.net.
Thank
you.
Chapter
4
Source
Code
You
can
view
and
download
the
source
code
at:
Learning
Laravel
5
Book:
Chapter
4
Source
Code
258
Chapter
4
-
Building
A
Blog
Application
259
Chapter
5
-
Deploying
Our
Laravel
Applications
Chapter
5:
Deploying
Our
Laravel
Applications
Currently,
we're
just
working
locally
on
our
personal
computers.
We
will
have
to
deploy
our
applications
to
some
hosting
services
or
servers
so
that
everyone
can
access
it.
There
are
many
ways
to
make
your
application
visible
to
the
rest
of
the
world!
In
this
chapter,
I
will
show
you
how
to
deploy
your
Laravel
applications
using
these
popular
methods:
1.
Deploying
your
apps
on
shared
hosting
services
2.
Deploying
your
apps
using
DigitalOcean
If
you
find
out
some
better
solutions,
feel
free
to
contact
us.
I'll
update
the
book
to
talk
about
other
approaches.
To
deploy
a
Laravel
application,
you
may
have
to
follow
these
steps:
Create
a
different
directory
structure.
(If
you're
using
shared
hosting)
Setup
your
web
server
(If
you're
using
servers
or
cloud
services,
such
as
DigitalOcean,
Linode,
etc.)
Upload
your
applications
to
your
host/server.
Give
proper
permissions
to
your
files.
Create
a
database
for
your
application.
Deploying
your
apps
on
shared
hosting
services
Basically,
your
Laravel
applications
are
just
PHP
applications,
which
means
you
can
upload
them
directly
to
any
supported
shared
hostings,
and
they
may
work
just
fine.
260
Chapter
5
-
Deploying
Our
Laravel
Applications
However,
Laravel
is
not
designed
to
work
on
shared
hosting
services.
Therefore,
you
will
need
to
do
some
extra
configurations.
I
don't
recommend
to
use
this
approach,
but
the
choice
is
yours.
Here
are
some
popular
web
hosting
services
that
you
can
use:
Host
Gator
GoDaddy
Blue
Host
Please
note
that
each
web
hosting
service
requires
a
different
configuration,
so
bear
in
mind
that
you
need
to
find
a
way
and
spend
extra
time
to
make
your
Laravel
applications
work
properly.
Deploying
on
Godaddy
shared
hosting
First,
let's
assume
that
you
have
a
new
Laravel
application
and
your
home
directory
is:
/home/content/learninglaravel/public_html
Now,
follow
these
steps:
You
will
need
to
create
a
directory
on
the
same
level
as
the
public_html
directory.
This
directory
will
hold
your
Laravel
application.
Because
it's
on
the
same
level
as
your
public_html
directory,
others
cannot
access
it.
This
makes
the
application
more
secure.
Upload
your
Laravel
application
to
the
new
directory
using
an
FTP
client
(such
as
Filezilla,
Transmit,
CuteFTP,
etc.),
except
the
public
folder.
Upload
the
public
folder
to
the
public_html
directory.
Good
job!
Now
open
the
index.php
file
and
change
two
paths:
require __DIR__.'/../bootstrap/autoload.php';
and
261
Chapter
5
-
Deploying
Our
Laravel
Applications
Last
step,
go
to
the
public_html
directory
and
modify
the
.htaccess
file
(If
you
don't
have
one,
create
a
new
file):
RewriteEngine On
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]
Well
done,
now
it's
time
to
visit
your
website
URL!
(www.yourdomain.com).
You
should
see
the
Laravel
welcome
screen.
You've
just
deployed
your
Laravel
app!
Note:
Please
note
that
your
application
may
not
work
properly
on
shared
hosting
and
there
is
a
security
risk.
Laravel
is
not
designed
to
work
on
a
shared
host.
Deploying
your
apps
using
DigitalOcean
262
Chapter
5
-
Deploying
Our
Laravel
Applications
DigitalOcean
is
one
of
the
best
cloud
server
providers
that
you
can
find
around
the
world.
You
can
get
their
cheapest
SSD
Cloud
Server
for
just
$5
a
month.
More
than
450,000
developers
have
been
using
DigitalOcean
to
deploy
their
applications!
263
Chapter
5
-
Deploying
Our
Laravel
Applications
DigitalOcean
is
also
my
best
favorite
hosting
solution.
The
performance
is
really
amazing!
In
this
section,
I'll
show
you
how
to
install
Laravel
with
Nginx
on
a
Ubuntu
16.04.1
LTS
VPS.
(Ubuntu
16.04.1
Long
Term
Support
Virtual
Private
Server)
Why
do
I
choose
Ubuntu
16.04.1?
There
are
some
newer
versions
of
Ubuntu,
but
the
16.04.1
is
an
LTS
version,
which
means
we
will
receive
updates
and
support
for
at
least
five
years.
Alternatively,
you
can
use
Laravel
Forge
to
install
the
VPS
and
configure
everything
for
you.
However,
you
will
have
to
pay
$10/month
or
more.
Deploy
a
new
Ubuntu
server
First,
you
will
need
to
register
a
new
account
at
DigitalOcean.
You
can
use
this
link
to
get
$10
for
free,
that
means
you
can
use
their
$5
cloud
server
for
two
months.
https://www.digitalocean.com/?refcode=5f7e95cb014e
Note:
You
will
need
to
provide
your
credit
card
information
or
Paypal
to
activate
your
account.
After
your
account
has
been
activated.
You
will
need
to
create
a
"droplet",
which
is
a
cloud
server.
Click
on
the
Create
Droplet
button
or
go
to:
https://cloud.digitalocean.com/droplets/new
264
Chapter
5
-
Deploying
Our
Laravel
Applications
Note:
The
layout
could
be
different.
Follow
these
steps:
At
the
Choose
an
Image
section,
be
sure
to
choose
Ubuntu
16.04.1
x64.
Select
your
droplet
size
and
region
that
you
like.
$5/mo
or
$10/mo
is
fine.
You
may
skip
other
settings.
Give
your
Droplet
a
name
(For
example,
learninglaravel).
Click
"Create
Droplet"
to
create
your
first
cloud
server!
Wait
for
a
few
seconds
and...
Congratulations!
You
just
have
a
new
Ubuntu
VPS!
Check
your
email
to
get
the
username
and
password,
you
will
need
to
use
them
to
access
your
server.
265
Chapter
5
-
Deploying
Our
Laravel
Applications
Great!
Now
you
can
access
the
new
server
via
Terminal
or
Git
Bash
by
using
this
command:
ssh root@139.59.245.162
Note:
Your
IP
Address
should
be
different
Type
yes
if
it
asks
if
you
want
to
continue
connecting.
The
first
time
you
log
in,
it
will
ask
you
to
change
the
password.
Enter
the
current
Unix
password
again,
and
then
enter
your
new
password
to
change
it.
Finally,
run
this
command
to
check
and
update
all
current
packages
to
the
latest
version:
266
Chapter
5
-
Deploying
Our
Laravel
Applications
We're
now
ready
to
install
PHP
7,
Nginx
and
other
packages!
Install
MySQL
Server
Note:
We're
using
MySQL
in
this
book,
so
I
will
install
MySQL,
you
can
install
other
databases
if
you
like.
To
get
started,
we
need
to
install
MySQL
to
store
our
data.
Run
this
command:
Say
Y
to
everything.
If
you're
asked
to
enter
a
new
password
for
the
MySQL
root
user,
give
it
a
password.
Good
job!
You've
installed
MySQL.
We
will
install
PHP
in
the
next
section.
Install
Nginx,
PHP
and
other
packages
267
Chapter
5
-
Deploying
Our
Laravel
Applications
First
of
all,
we
need
to
add
Ondrej's
PPA
to
the
system's
Apt
sources
by
running
this
command:
Note:
A
PPA
(Personal
Package
Archive)
is
an
Apt
repository
hosted
on
Launchpad.
Third-party
developers
can
distribute
their
custom
PPA
packages
for
Ubuntu
outside
of
the
official
channels.
We
have
to
add
the
Ondrej's
PPA
because
it
supports
PHP
7.0
for
Ubuntu.
Press
Enter
(or
Return)
to
continue
if
it
asks
you
anything.
Run
this
command
again
to
update
our
local
packages:
Next,
run
this
command
to
install
Nginx,
PHP
7,
PHP7.0-FPM,
PHP-MySQL,
PHP7.0-Zip,
Curl,
phpredis,
xdebug
and
other
useful
packages.
apt-get -y install nginx php7.0 php7.0-fpm php7.0-mysql php7.0-curl php7.0-xml git php
7.0-zip php-redis php-xdebug php7.0-mcrypt
php-mbstring php7.0-mbstring php-gettext php7.0-gd
Alternatively,
you
may
use
this
command
to
install
more
packages:
You
may
use
this
command
to
see
all
the
PHP
7
packages:
Available
packages:
268
Chapter
5
-
Deploying
Our
Laravel
Applications
269
Chapter
5
-
Deploying
Our
Laravel
Applications
Note:
You
may
remove
some
packages
that
you
don't
use
and
install
them
later
when
you
need.
Done!
You
can
now
visit
your
Nginx
server
via
the
IP
address:
http://139.59.245.162
Note:
Your
IP
address
must
be
different.
We
can
check
the
installed
version
of
PHP
by
using
this
command:
php -v
After
that,
we
need
to
edit
the
server
block
(aka
virtual
hosts)
file.
Open
it:
270
Chapter
5
-
Deploying
Our
Laravel
Applications
Find:
root /var/www/html;
This
is
the
path
to
your
Laravel
application,
we
don't
have
a
Laravel
application
yet,
but
let's
change
it
to:
root /var/www/learninglaravel.net/html;
Note:
You
may
use
a
different
address
(change
learninglaravel.net
to
your
website's
address)
if
you
want.
Be
sure
to
replace
all
the
addresses.
Find:
Change
to:
Find:
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
Change
to:
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri/ $uri /index.php?$query_string;
}
Add
below:
271
Chapter
5
-
Deploying
Our
Laravel
Applications
location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
Save
the
file
and
exit.
In
nano,
you
can
do
this
by
pressing
Ctrl-X
to
exit,
then
press
y
to
confirm,
and
Enter
to
overwrite
the
file.
As
you
know,
we
don't
have
the
/var/www/learninglaravel.net/html
directory
yet,
let's
create
it.
Be
sure
to
give
it
a
proper
permission:
Next,
let's
make
a
test
file
called
index.html
to
test
our
configurations:
Here
is
the
content
of
the
index.html
file:
<html>
<head>
<title>Learning Laravel</title>
</head>
<body>
<h1>Learning Laravel test page. PHP 7 and Nginx</h1>
</body>
</html>
Finally,
restart
PHP
and
Nginx
by
running
the
following:
272
Chapter
5
-
Deploying
Our
Laravel
Applications
Now
when
you
visit
your
website
via
its
IP
address,
you
should
see:
Well
done!
You
now
have
a
working
PHP
7
installation.
Install
Laravel
Now
that
we
have
everything
in
order,
we
will
be
going
to
install
Composer
and
use
it
to
install
Laravel!
If
you're
installing
Laravel
on
a
512MB
droplet,
you
must
add
a
swapfile
to
Ubuntu
to
prevent
it
from
running
out
of
memory.
You
can
add
a
swapfile
easily
by
running
these
commands:
Note:
If
your
server
is
restarted,
you
have
to
add
the
swapfile
again.
Run
this
simple
command
to
install
Composer:
Once
installed,
run
this
command
to
move
composer.phar
to
a
directory
that
is
in
your
path,
so
that
you
can
access
it
globally:
mv composer.phar /usr/local/bin/composer
Next,
we
will
use
Composer
to
download
the
Laravel
Installer:
273
Chapter
5
-
Deploying
Our
Laravel
Applications
Once
finished,
we're
finally
at
the
part
that
we've
been
waiting
for:
Installing
Laravel!
We
will
put
our
Laravel
application
at
/var/www/learninglaravel.net/.
Type
the
following
to
get
there:
cd /var/www/learninglaravel.net/
It's
time
to
install
Laravel.
Run
this
command:
274
Chapter
5
-
Deploying
Our
Laravel
Applications
If
you
see
this
error
when
using
the
laravel
new
command:
We
have
to
edit
the
.bashrc
file,
type:
nano ~/.bashrc
Add
this
line
at
end
of
the
file:
alias laravel='~/.config/composer/vendor/bin/laravel'
Press
Ctrl
+
X,
then
Y,
then
Enter
to
exit
and
save
the
file.
Lastly,
run
this
command:
source ~/.bashrc
Now
you
should
be
able
to
create
a
new
Laravel
app
using:
Note:
This
is
a
pretty
standard
process.
I
hope
you
understand
what
we've
done.
If
you
don't,
please
read
chapter
1
again.
By
now,
we
should
have
our
Laravel
app
installed
at
/var/www/learninglaravel.net/laravel.
Once
that
step
is
done,
we
must
give
the
directories
proper
permissions:
These
commands
should
do
the
trick.
One
last
step,
edit
the
server
block
file
again:
275
Chapter
5
-
Deploying
Our
Laravel
Applications
Find:
root /var/www/learninglaravel.net/html;
Change
to:
root /var/www/learninglaravel.net/laravel/public;
Save
the
file
and
exit.
Finally,
restart
Nginx:
Go
ahead
and
visit
your
Laravel
app
in
browser:
Your
application
is
now
ready
to
rock
the
world!
Possible
Errors
276
Chapter
5
-
Deploying
Our
Laravel
Applications
If
you
see
this
error:
No supported encrypter found. The cipher and / or key length are invalid.
This
is
a
Laravel
5
bug.
Sometimes,
your
app
doesn't
have
a
correct
application
key
(this
key
is
generated
automatically
when
installing
Laravel)
You
need
to
run
these
commands
to
fix
this
bug:
Finally,
restart
your
Nginx
server:
Take
a
snapshot
of
your
application
I
know
that
the
process
is
a
bit
complicated.
The
great
thing
is,
you
can
take
a
snapshot
of
your
VPS,
and
then
you
can
restore
it
later.
When
you
have
new
projects,
you
don't
have
to
start
over
again!
Everything
can
be
done
by
two
clicks!
To
take
a
snapshot,
shutdown
your
server
first:
shutdown -h now
Now,
go
to
DigitalOcean
Control
Panel.
Go
to
your
droplet.
Click
on
the
Snapshots
button
to
view
the
Snapshots
section.
277
Chapter
5
-
Deploying
Our
Laravel
Applications
Enter
a
name
and
then
take
a
snapshot!
You
may
use
this
snapshot
to
restore
your
VPS
later
by
using
the
Restore
from
Snapshot
functionality.
Little
tips
Tip
1:
If
you
have
a
domain
and
you
want
to
connect
it
to
your
site,
open
the
server
block
file,
and
edit
this
line:
server_name localhost;
Modify
to:
server_name yourDomain.com;
Now
you
can
be
able
to
access
your
site
via
your
domain.
Tip
2:
You
can
access
your
server
using
FTP
as
well
(to
upload,
download
files,
etc.),
use
this
information:
278
Chapter
5
-
Deploying
Our
Laravel
Applications
User: root
Port: 22
Chapter
5
Summary
Congratulations!
You
now
know
how
to
deploy
your
Laravel
applications!
I
hope
you
like
this
chapter.
If
you
wish
to
learn
more
about
Laravel,
check
our
Laravel
5
Cookbook,
Laravel
Angular
book
and
Vue.js
Book
out!
Thank
you
again
for
your
support!
Have
a
great
time!
279