Setup MySQL connection in Laravel env
nano .env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=DBNAME
DB_USERNAME=DBUSER
DB_PASSWORD=DBPASSWORD
Setup authentication
php artisan make:auth
php artisan migrate
This overwrites HomeController.php if already exist so execute at beginning stage of development
Create your database tables, Controller & Model
#Create database table example: cards & notes
php artisan make:migration create_cards_table --create=cards
php artisan make:migration create_notes_table --create=notes
#Refer to below link for database columns
https://laravel.com/docs/5.3/migrations#creating-columns
#migrate (lose data)
php artisan migrate
php artisan migrate:refresh
php artisan migrate:reset
#Make controller
php artisan make:controller CardsController
php artisan make:controller NotesController
#Make model
php artisan make:model Card
php artisan make:model Note
# listen to sql query
DB::listen(function($query) {var_dump($query->sql);});
Test your app on terminal first
php artisan tinker
#query table cards
DB::table('cards')->get();
#test model
App\Card::all();
App\Card::first();
App\Note::all();
#test model User (new, save, update, delete)
$user = new App\User;
$user->name = "My Name";
$user->email = "whatever";
$user->save();
$user->name = "My new Name";
$user->update();
$user->delete();
Setup your home routes at /routes/web.php
Route::auth();
Route::get('/', 'CardsController@home';);
CardsController class
use App\Card;
class CardsController extends Controller{
public function home(){
$cards = Card::all();
return view('card.cards', ['cards' => $cards]);
}
}...
hasMany() Model relationship (example Card has many notes)
hasMany()
class Card extends Model
{
protected $table = 'cards';
protected $primaryKey = 'id';
public function getNotes(){
return $this->hasMany(Note::class, 'card_id', $this->primaryKey);
}
}
HasMany () format
return $this->hasMany('App\Note', 'foreign_key_on_another_table', 'local_key_PK');
Test Card hasMany() Note:class relationship
php artisan tinker
#query first Card
$card = App\Card::first();
#query all the Card's notes
$card->getNotes->all();
$card->getNotes()->get();
$card->getNotes
#query the Card's first note
$card->getNotes->first();
#Same as above but more efficient (doesn't query all notes on the database)
$card->getNotes()->first();
#Attempt saving a note to this card
$card = App\Card::first();
$note = new App\Note;
$card->notes()->save($note);
#refresh
$card = $card->fresh();
#test
$card->getForeignKey()
$card->getQuery()
$card->touch()
belongsTo() Model relationship (example Note belongs to Card)
belongsTo()
class Note extends Model
{
protected $table = 'notes';
protected $primaryKey = 'nid';
public function belongsToCard(){
return $this->belongsTo(Card::class, 'card_id', 'cid');
}
}
belongsTo format
return $this->belongsTo('App\Card', 'foreign_key_on_local', 'other_key_PK_of_another_table');
Test Note belongsTo() Card::class relationship
php artisan tinker
#query first Note
$note = App\Card::first();
#query this note belongsTo which card
$note->belongsToCard
#query using your methods
$note->belongsToCard->getNotes->first()->belongsToCard
Laravel API
Layout using blade
<!doctype html>
<html>
<head>
@include('includes.head')
@yield('title')
</head>
<body>
<div class="container">
<div class="row">
@include('includes.header')
</div>
<div id="main" class="row">
@yield('content')
</div>
<footer class="row">
@include('includes.footer')
</footer>
</div>
</body>
</html>
Head
Bootstrap in your head section
<meta charset="UTF-8">
<!-- If IE use the latest rendering engine -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- Set the page to the width of the device and set the zoon level -->
<meta name="viewport" content="width = device-width, initial-scale = 1">
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
Get the latest CSS Bootstrap version at:http://getbootstrap.com/getting-started/ or https://www.bootstrapcdn.com/
Footer
Provide jQuery before loading bootstrap.min.js
<!-- jquery -->
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<!-- bootstrap.min.js-->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
Get the latest jquery version at:http://jquery.com/download/#other-cdns or https://cdnjs.com/libraries/jquery/
Get the latest bootstrap.min.js at: https://www.bootstrapcdn.com/
Form with csrf
<form method="POST" action="/card/addNote">
<textarea class="form-control" name="body"></textarea>
<input type="submit" value="Add note" class="btn btn-default">
{{ csrf_field() }}
</form>
MassAssignmentException
Declare $fillable to fix Mass Assignment Exception on your class
class Note extends Model
{
protected $table = 'notes';
protected $primaryKey = 'nid';
protected $fillable = ['body', 'abc', 'zyx'];
...
Add validation to your form
Cleaner to put on contoller
public function addNote(Request $request, int $cid){
$this->validate($request, ['body' => 'required | min:10']);
...
}
If you wish to use Input::all() you may need to use below on your controller
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Redirect;
...
public function firstloginhtmlSubmit(Request $request){
$rules = [ 'name' => 'required',
'email' => 'required|email',
'password' => 'required|confirmed' ];
$validator = Validator::make(Input::all(), $rules);
...
}
...
Display validation error on your view
@if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
Give back old user input data that was cleared due to validation error on the form {{ old(‘body’) }}
Display all validation error
{{print_r($errors)}}
@if(Session::get('errors'))
<div class="alert alert-danger alert-dismissable">
@foreach($errors->all() as $msg)
<li> {{ $msg }} </li>
@endforeach
</div>
@endif
Display validation error with Bootstrap
Chose from has-error
has-warning
has-success
<form method="POST" class="form-group">
<div class="@if($errors->has('body'))has-error
@endif">
<textarea class="form-control" name="body">{{$note->body}}</textarea>
</div>
...
</form>
Display custom validation error with Bootstrap
<form method="POST" class="form-group">
<div class="@if($errors->has('body')) has-error @endif">
@if ($errors->has('body'))
<p class="help-block">Please enter your message</p>
@endif
<textarea class="form-control" name="body">{{$note->body}}</textarea>
</div>
...
</form>
Refer to bootstrap for more options: http://getbootstrap.com/css/?#forms-help-text
Pagination
class CardsController extends Controller
{
public function home(){
$cards = Card::paginate(25);
return view('card.cards', ['cards' => $cards]);
}
Display pagination on view
{{ $cards->links() }}
Configure mail
For gmail, port 465 (with SSL) and port 587 (with TLS)
.env
MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=465
MAIL_USERNAME=xyz@gmail.com
MAIL_PASSWORD=pass
MAIL_ENCRYPTION=ssl
/config/mail.php
'driver' => env('MAIL_DRIVER', 'smtp'),
'host' => env('MAIL_HOST', 'smtp.gmail.com'),
'port' => env('MAIL_PORT', 587),
'from' => ['address' => 'xyz@abc.com', 'name' => 'xyz'],
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
'sendmail' => '/usr/sbin/sendmail -bs',
Clear cache
php artisan config:cache
php artisan config:clear
Disable gmail security (DisplayUnlockCaptcha)
https://accounts.google.com/b/0/DisplayUnlockCaptcha
Disable gmail security
https://www.google.com/settings/security/lesssecureapps
Enable 2 factor authentication if you do not wish to disable google security
http://www.google.com/landing/2step/
Generate apppasswords
https://security.google.com/settings/security/apppasswords
Admin.google.com
Step1. Go to admin.google.com
Step2. Select “Security” -> “Basic settings” -> “Less secure apps”
Step3. Go to settings for less secure apps -> Check the radio button “Allow users to manage their access to less secure apps”
Step4. Save the changes
Step5. Open this link being sign in as the super administrator https://www.google.com/settings/security/lesssecureapps
Step7. Check the radio button Turn On the access for less secure apps
Step8. Unlock Captcha using this link https://accounts.google.com/DisplayUnlockCaptcha
Make middleware
php artisan make:middleware AdminOnly
Assign Middleware To Routes
# app/Http/Kernel.php
...
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'AdminOnly' => \App\Http\Middleware\AdminOnly::class,
];