How to cook and other inquiries about wolf hustlin'

download How to cook and other inquiries about wolf hustlin'

of 396

Transcript of How to cook and other inquiries about wolf hustlin'

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    1/395

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    2/395

    Laravel 4 Cookbook

    C h r i s to ph e r P i tt a n d T a y l o r O tw e l l

    T h i s b o o k i s f o r s a l e a t http://leanpub.com/laravel4cookbook

    Th i s ve rsi o n wa s pu bli sh e d o n 2 0 1 4 - 0 5 - 0 4

    T h i s i s a Leanpub bo o k. Le a npu b e mpo we rs a u t h o rs a nd pu bli sh e rs wi t h t h e Le a n Pu bli sh i ngprocess. Le a n Pu bli sh i ng i s t h e a c t o f p u b l i s h i n g a n i n - p r o g r e s s e b o o k u s i n g l i g h t w e i g h t t o o l s a n dm a n y i t e r a t i o n s t o g e t r e a d e r f e e d b a c k , p i v o t u n t i l y o u h a v e t h e r i g h t b o o k a n d b u i l d t r a c t i o n o n c e

    y o u d o .

    2 0 1 3 - 2 0 1 4 C h ri st o ph e r Pi t t

    http://leanpub.com/manifestohttp://leanpub.com/http://leanpub.com/laravel4cookbook
  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    3/395

    Tweet This Book!

    P l e a s e h e l p C h r i s t o p h e r P i t t a n d T a y l o r O t w e l l b y s p r e a d i n g t h e w o r d a b o u t t h i s b o o k o n Twitter!

    T h e s u g g e s t e d h a s h t a g f o r t h i s b o o k i s #laravel4cookbook.

    F i n d o u t w h a t o t h e r p e o p l e a r e s a y i n g a b o u t t h e b o o k b y c l i c k i n g o n t h i s l i n k t o s e a r c h f o r t h i sh a sh t a g o n Twi t t e r:

    https://twitter.com/search?q=#laravel4cookbook

    https://twitter.com/search?q=%23laravel4cookbookhttps://twitter.com/search?q=%23laravel4cookbookhttp://twitter.com/
  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    4/395

    Contents

    Dedication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i

    Forward . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ii

    What This Book Teaches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii

    Why Write This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv

    Installing Laravel 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v

    Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1Installing Laravel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1Configuring The Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

    Connection To The Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2Database Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3Elo quent Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4Creating A Migration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

    Creating A Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7Creating A Seeder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8Configuring Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10Logging In . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

    Creating A Layout View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11Creating A Login View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14Creating A Login Action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16Authenticating Users . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17Redirecting With Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20Authenticating Credentials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

    Resetting Passwords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

    Creating A Password Reset View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24Creating A Password Reset Action . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26Creating Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31Creating A Logout Action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

    Access Control List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35Managing Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    5/395

    C O NT E NT S

    Refactoring Migrations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35Listing Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39Adding Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42Editing Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

    Deleting Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53Adding Users And Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

    Adding Migrations, Models And Relationships . . . . . . . . . . . . . . . . . . . . . . 56Adding Views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61Seeding Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64Saving Relationships . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

    Advanced Routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

    Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72Dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72Environment Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

    Checking Environments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74Setting Environments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80Unsetting Environments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

    Asset Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87Combining Assets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90Minifying Assets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94Building Assets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97Watching Assets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99Resource Watcher Integration Bug . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

    Rsync . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104

    Distribute Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105Copying Files For Distribution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105Removing Development Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107Synchronising Files To A Remote Server . . . . . . . . . . . . . . . . . . . . . . . . . 109

    Command Portability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113Preprocessors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

    API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114Dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114Creating Resources With Artisan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

    Creating Resources With Generators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115Generating Migrations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115Generating Seeders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122Generating Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125Generating Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128

    Binding Models To Routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132Troublesho oting Aliases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    6/395

    C O NT E NT S

    Testing Endpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135Authenticating Requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136Using Accessors And Mutators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137Using Cache . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

    Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142Composer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142Dependency Injection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142Inversion Of Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146Service Providers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149Organising Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151Publishing Configuration Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169Creating Composer.json . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169Submitting A Package To Packagist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170Note On Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171

    Real Time Chat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172Dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172

    Bo otstrap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172EmberJS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172Ratchet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172

    ReactP H P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173Ratchet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173Creating An Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174

    Creating A View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174Creating An EmberJS App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177

    Creating A Service Provider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179Creating A Chat Handler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181Creating A Socket Wrapper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185

    Creating A Serve Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187Connecting To The Socket Ser ver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191

    Wiring Up The Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192Showing Chat Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193Sending Chat Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195Finishing Up The Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198

    Note On Nginx . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200

    Multisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201Note on Operating Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201Note on Server Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201Note on Dutch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201Virtual Hosts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201

    Adding Virtual Host Entries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    7/395

    C O NT E NT S

    Creating Apache 2 Virtual Hosts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203Creating Nginx Virtual Hosts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204

    Environments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205Note on Running Commands in Local Environment . . . . . . . . . . . . . . . . . . . 206

    Using Site-Spe cific Views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206Using Site-Spe cific Routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211

    Translation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212Using Language Lookups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212Using Language Lookups in Packages . . . . . . . . . . . . . . . . . . . . . . . . . . 215Caching Language Lookups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216

    Creating Multi-Language Routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219Creating Multi-Language Content . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221

    E-Commerce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226Note on Sanity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226

    Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226Installing Laravel 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227Installing Other Dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227

    AngularJS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227Bo otstrap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228DOMP DF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228Stripe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229Faker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230

    Creating Database Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230Creating Migrations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230

    Creating Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236Creating Seeders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240Creating AP I Endpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248

    Managing Categories And Products . . . . . . . . . . . . . . . . . . . . . . . . . . . 248Managing Accounts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250Managing Orders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251

    Creating The Site With AngularJS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253Creating The Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253Making The Interface Dynamic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259Completing Orders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271

    Accepting Payments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278

    Creating Orders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278Working The Ser vice Provider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281Making Payments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285

    Generating P DF Documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286

    Embedded Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293Gathering Parts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    8/395

    C O NT E NT S

    Installing Dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293Note About Errata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294Creating An Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294Creating A Socket Ser ver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296

    Connection To Arduino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303Spinning Up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309Adding A Webcam . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310

    Installing ImageSnap On OSX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310Installing Streamer On Ubuntu/Debian . . . . . . . . . . . . . . . . . . . . . . . . . . 310Displaying Photos In The Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311

    File-Based CMS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312Installing Dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312Rendering Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313Gathering Metadata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318

    Creating Layouts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321Creating Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340Displaying Content . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352Extending The CMS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356

    Controller Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357Installing Dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357Unit vs. Functional vs. Acceptance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358

    Unit Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358Functional Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358Acceptance Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359

    Am I Writing Unit Or Functional Tests? . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359Fat Controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359Service Providers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361Dependency Injection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366This Isnt Testing! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370The Rabbit Hole . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382Alternatives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    9/395

    DedicationI w o u l d l i k e t o t h a n k T a y l o r O t w e l l f o r t h e L a r a v e l f r a m e w o r k . H e m a y n o t h a v e w r i t t e n p a r t o f t h i s bo o k (i n t h e t ra di t i o na l se nse ), bu t wi t h o u t h i s t i re le ss de di c a t i o n t o La ra ve l; no ne o f t h i s wo u ldh a v e h a p p e n e d . I c o n s i d e r h i m a c o - d e v e l o p e r i n t h e c o d e I w r i t e d a i l y .

    I w o u l d l i k e t o t h a n k a l l o f m y f r i e n d s a s J o e P u b l i c . I h a v e n e v e r w o r k e d a n y w h e r e I l o v e m o r e .Y o u g i v e m e t h e f r e e d o m a n d e n c o u r a g e m e n t t o c r e a t e , l e a r n a n d h a v e f u n .

    I w o u l d l i k e t o t h a n k m y f a m i l y f o r t h e i r e n c o u r a g e m e n t , s u p p o r t a n d g e n e r a l a w e s o m e n e s s .

    I w ou ld l ik e t o t ha nk m y w if e a nd c hi ld re n f or b ei ng p at ie nt a nd l ov in g m e e ve n w he n I m n ot

    loveable.I w o u l d l i k e t o t h a n k J e s u s . I e n c o u r a g e y o u t o a s k m e w h y .

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    10/395

    ForwardH i , m y n a m e i s W a y n e A s h l e y B e r r y a n d I w o r k w i t h C h r i s a t J o e P u b l i c w h e r e w e w r i t e b u s i n e s sc r i t i c a l s o f t w a r e d a y i n a n d d a y o u t . I v e b e e n w r i t i n g s o f t w a r e p r o f e s s i o n a l l y f o r y e a r s C h r i s i st h e g u y I g o t o w h e n G o o g l e d o e s n t h a v e t h e a n s w e r s .

    W h a t I lo ve a bo u t C h ri s s wo rk e t h i c i s t h a t h e c o nt i nu a lly pu sh e s t h e li mi t s o f so ft wa re , fra me wo rksa n d l a n g u a g e s b u t t h e n m a n a g e s t o h o l d b a c k a n d u s e s i m p l e a n d u n d e r s t a n d a b l e c o n c e p t s .

    B . B . K i n g o n c e s a i d D o n t u s e t h e s o n g t o s h o w o f f y o u r s k i l l s , u s e y o u r s k i l l s t o s h o w o f f t h e s o n g . ,C h r i s i s l i k e t h a t J a z z m u s i c i a n w h o y o u k n o w c o u l d o u t - p l a y y o u w i t h o n e h a n d b u t f i n d s i m m e n s e

    joy in playing four chord pop tracks.

    E a c h c a s e s t u d y i n t h i s b o o k c o m e s f r o m h a r d e a r n e d e x p e r i e n c e . C o n s i d e r e a c h c h a p t e r y e a r s o f e x pe r ie n ce , s l ee p le s s n i gh t s a n d s t re s sf u l d e ad l in e s d i st i ll e d i n to a s e t o f b e st p r a ct i ce s , c o mm o nse nse a nd go o d a dvi c e .

    I f y o u r e l o o k i n g t o u s e L a r a v e l , o r e v e n j u s t P H P , f o r r e a l - w o r l d p r o j e c t s t h e n c o n s i d e r t h i s b o o kw o r t h m o r e t h a t i t s f i l e - s i z e i n g o l d .

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    11/395

    What This Book TeachesI m w r i t i n g t h i s b o o k ( a n d t h e t u t o r i a l s ) i n t h e h o p e t h a t p e o p l e c a n l e a r n t h e t h i n g s I h a v e a b o u tL ar av el 4 . I t s n ot m ea nt a s a r ep la ce me nt f or a ny o f t he g re at L ar av el b oo ks , b ut i ns te ad a s ac o mple me nt t o t h e re so u rc e s, do c u me nt a t i o n a nd fra me wo rk.

    T h i s b o o k t e a c h e s v a r i o u s a s p e c t s o f L a r a v e l 4 i m p l e m e n t a t i o n , c o n f i g u r a t i o n a n d u s a g e ; a s p a r t o f s e p a r a t e p r o j e c t s . T h e i d e a i s n o t t o d e m o n s t r a t e t h e o n l y o r b e s t w a y t o c r e a t e a n y o f t h e s e p r o j e c t s .I t s n o t t o s h o w t h e o n l y o r b e s t w a y t o u s e L a r a v e l 4 . I t s s i m p l y a d i f f e r e n t ( a n d s u b j e c t i v e ) k i n do f do c u me nt a t i o n t o t h e mo du la ri se d ve rsi o n fo u nd a t : http://laravel.com/docs

    W hi le t hi s b o ok t ou ch es o n i n t he i ns ta ll at io n a nd h os ti ng o f L ar av el a pp li ca ti on s; i t s n ot a n

    e xh au st iv e r ef er en ce f or h ow t o d o t he se t hi ng s. T he re a re s om e i ns tr uc ti on s ; w hi ch s ho ul d b ee no ug h t o g et y ou u p a nd r un ni ng , b ut i t a ss um es y ou a re f am il ia r w it h h ow t hi ng s l ik e L A MP( L i n u x , A p a c h e , M y S Q L a n d P H P ) w o r k a n d a r e c a p a b l e o f i n s t a l l i n g a n d m a i n t a i n i n g t h e m .

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    12/395

    Why Write This BookI w a s l e a r n i n g h o w t o u s e L a r a v e l 4 m o r e e f f e c t i v e l y , a n d f o u n d s o m e s u b j e c t s w h i c h I f e l t w e r ew o r t h s h a r i n g . I p i c k e d M e d i u m ( w h i c h l a t e r t u r n e d o u t t o b e a h u g e p a i n ) a n d s t a r t e d p u t t i n g at u t o r i a l t o g e t h e r . A f e w h o u r s l a t e r I h i t p u b l i s h

    T h e n @ l a r a v e l p h p r e t w e e t e d a l i n k t o t h e a r t i c l e . I t h i n k I s p e n t t h e r e s t o f t h e d a y j u s t w a t c h i n gs t a t s . T h e t u t o r i a l h i t M e d i u m s h o m e p a g e . I t t u r n s o u t t h e r e a r e a l o t o f p e o p l e w h o w a n t e d t o k n o wa b ou t A ut h en t ic a ti o n ( i n L a r av e l) , a n d j u st n e e de d t o b e e x po s ed t o t h e a r ti c le t h ro u gh @ l ar a ve l ph p spro mo t i o n o f i t .

    S i n c e t h e n ; I h a v e b e e n r e l e a s i n g a t u t o r i a l e v e r y t w o w e e k s .

    T he b o ok g re w o ut o f t he r ea li sa ti on t ha t; w hi le l oa d s o f p e op le w er e r ea di ng t he t ut or ia ls o nMe di u m, so me pe o ple we re n t h a ppy wi t h t h e pla t fo rm.

    T h e r e a r e m a n y c o m p e l l i n g r e a s o n s f o r m e t o k e e p o n u s i n g M e d i u m t o h o s t t h e t u t o r i a l s . I d o n tw a n t t o h o s t m y o w n t h i n g b e c a u s e u p t i m e i s i m p o r t a n t , a n d o u t a g e s i n t h e n i g h t a d d y e a r s o n t om y l i f e . T h e s i m p l e s t a t i s t i c s a n d t e x t f o r m a t t i n g a r e a l s o g r e a t .

    I w a n t t o s t a y o n M e d i u m , b u t I a l s o w a n t p e o p l e t o w a n t t o r e a d t h e t u t o r i a l s a n d l e a r n f r o m t h e mo n o t h e r p l a t f o r m s . T h e b o o k a l l o w s b o t h o f t h e s e t h i n g s , a s w e l l a s a n i m p o r t a n t t h i r d t h i n g

    T h e b o o k i s a l s o i n t e n d e d a s a m e a n s t o g i v e b a c k t o L a r a v e l ; i n p a r t i c u l a r t h e i n v a l u a b l e w o r k o f Ta y lo r O t we l l. To t h is e n d, I h a ve c o mm i tt e d t o g i ve h a lf o f a l l s a le s t o Ta y lo r. T h e t u t o ri a ls w i ll

    a l w a y s b e f r e e o n M e d i u m , a n d t h e i r c o n t e n t w i l l m i r r o r t h e c h a p t e r s o f t h i s b o o k ( w i t h o b v i o u sre pe t i t i o n o mi t t e d), bu t by pu rc h a si ng t h i s bo o k y o u a re h e lpi ng t o fu nd fu t u re La ra ve l de ve lo pme ntf r o m h i m a n d t u t o r i a l s f r o m m e .

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    13/395

    Installing Laravel 4L a ra v el 4 u s es C o mp o s er t o m a na g e i t s d e p en d en c ie s . Yo u c a n i n st a ll C o mp o s er b y f o ll o wi n g t h ei nst ru c t i o ns a thttp://getcomposer.org/doc/00-intro.md#installation-nix.

    O nc e y o u h a ve C o mpo se r wo rki ng, ma ke a ne w di re c t o ry o r na vi ga t i o n t o a n e xi st i ng di re c t o ry a ndi nst a ll La ra ve l 4 wi t h t h e fo llo wi ng c o mma nd:

    1 composer create-project laravel/laravel ./ --prefer-dist

    I f y o u c h o s e n o t t o i n s t a l l C o m p o s e r g l o b a l l y ( t h o u g h y o u r e a l l y s h o u l d ) , t h e n t h e c o m m a n d y o uu se sh o u ld re se mble t h e fo llo wi ng:

    1 php composer.phar create-project laravel/laravel ./ --prefer-dist

    B o t h o f t h e s e c o m m a n d s w i l l s t a r t t h e p r o c e s s o f i n s t a l l i n g L a r a v e l 4 . T h e r e a r e m a n y d e p e n d e n c i e st o b e s o u r c e d a n d d o w n l o a d e d ; s o t h i s p r o c e s s m a y t a k e s o m e t i m e t o f i n i s h .

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    14/395

    AuthenticationI f y o u r e a n y t h i n g l i k e m e ; y o u v e s p e n t a g r e a t d e a l o f t i m e b u i l d i n g p a s s w o r d - p r o t e c t e d s y s t e m s .I u s e d t o d r e a d t h e p o i n t a t w h i c h I h a d t o b o l t o n t h e a u t h e n t i c a t i o n s y s t e m t o a C M S o r s h o p p i n gc a r t . T h a t w a s u n t i l I l e a r n e d h o w e a s y i t w a s w i t h L a r a v e l 4 .

    Th e c ode fo r t his ch ap ter ca n be f ou nd a t https://github.com/formativ/tutorial-laravel-4-

    authentication.

    T hi s t ut or ia l r eq ui re s P H P 5 .4 o r g re at er a nd t he P DO /S QL it e e xt en si on . Yo u a ls o n ee d

    to have all of the requirements of Laravel 4 met. You can find a list of these at

    http://laravel.com/docs/installation#server-requirements.

    Installing Laravel

    L a ra v el 4 u s es C o mp o s er t o m a na g e i t s d e p en d en c ie s . Yo u c a n i n st a ll C o mp o s er b y f o ll o wi n g t h ei nst ru c t i o ns a thttp://getcomposer.org/doc/00-intro.md#installation-nix.

    O nc e y o u h a ve C o mpo se r wo rki ng, ma ke a ne w di re c t o ry o r na vi ga t i o n t o a n e xi st i ng di re c t o ry a ndi nst a ll La ra ve l wi t h t h e fo llo wi ng c o mma nd:

    1 composer create-project laravel/laravel .

    2

    3 Installing laravel/laravel (v4.1.27)

    4 ...

    I f y o u c h o s e n o t t o i n s t a l l C o m p o s e r g l o b a l l y ( t h o u g h y o u r e a l l y s h o u l d ) , t h e n t h e c o m m a n d y o uu se sh o u ld re se mble t h e fo llo wi ng:

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    15/395

    Authentication 2

    1 php composer.phar create-project laravel/laravel .

    2

    3 Installing laravel/laravel (v4.1.27)

    4 ...

    B o t h o f t h e s e c o m m a n d s w i l l s t a r t t h e p r o c e s s o f i n s t a l l i n g L a r a v e l 4 . T h e r e a r e m a n y d e p e n d e n c i e st o b e s o u r c e d a n d d o w n l o a d e d ; s o t h i s p r o c e s s m a y t a k e s o m e t i m e t o f i n i s h .

    T h e v e r s i o n o f L a r a v e l t h i s t u t o r i a l i s b a s e d o n i s 4.1.27. I t s p os s i b le that late r v e r s i ons of L ar av e l

    w i ll i ntr od u c e b r e ak i ng c hang e s to the c od e s how n he r e . I n that c as e , c lone the Gi thu b r e p os i tor y

    me nti one d ab ov e , and r u ncomposer install. The loc k f i le has b e e n i nc lu d e d s o that L ar av e l 4.1.27

    w i ll b e i ns talle d f or you .

    Configuring The Database

    O ne o f t he b es t w ay s t o m an ag e u se rs a nd a ut he nt ic at io n i s b y s to ri ng t he m i n a d at ab as e. T he d ef au ltL a r a v e l 4 a u t h e n t i c a t i o n c o m p o n e n t s a s s u m e y o u w i l l b e u s i n g s o m e f o r m o f d a t a b a s e s t o r a g e , a n dt h e y pro vi de t wo dri ve rs wi t h wh i c h t h e se da t a ba se u se rs c a n be re t ri e ve d a nd a u t h e nt i c a t e d.

    Connection To The Database

    To u se e it he r o f t he p ro vi de d d r iv er s, w e f ir s t n ee d a v al id c on ne ct io n t o t he d at ab as e. S et i t u pb y c o n f i g u r i n g a n d o f t h e s e c t i o n s i n t h e app/config/database.php f i l e . H e r e s a n e x a m p l e o f t h eS Q L i t e d a t a b a s e I u s e f o r t e s t i n g :

    1

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    16/395

    Authentication 3

    T h i s f i l e s h o u l d b e s a v e d a s app/config/database.php.

    I hav e r e mov e d c omme nts , e x tr ane ou s li ne s and s u p e r f lu ou s d r i v e r c onf i g u r ati on op ti ons .

    P r ev i ou s v er s io n s o f t h is t u to r ia l u s ed a M y SQ L d a ta b as e f o r u s er s t or a ge . I d e ci d ed t o s wi t ch

    t o S Q Li t e b e ca u se i t s s i mp l er t o i n st a ll a n d u s e, w h en d e mo n st r at i ng L a ra v el c o de . I f y o u r e

    u si ng m ig ra t io ns t h en t hi s s ho ul dn t a ff ec t y ou a t a ll . Yo u c an l ea rn m or e a bo ut S QL it e a t

    https://laracasts.com/lessons/maybe-you-should-use-sqlite.

    Database Driver

    T he f ir s t d r iv er w hi ch L ar av el 4 p ro vi de s i s a c al le ddatabase. A s t he n am e s ug ge st s; t hi s d r iv erq u er i es t h e d a ta b as e d i re c tl y, i n o r de r t o d e te r mi n e w h et h er u s er s m a tc h in g p r ov i de d c r ed e n ti a lse xi st , a nd wh e t h e r t h e a ppro pri a t e a u t h e nt i c a t i o n c re de nt i a ls h a ve be e n pro vi de d.

    I f t h i s i s t h e d r i v e r y o u w a n t t o u s e ; y o u w i l l n e e d t h e f o l l o w i n g d a t a b a s e t a b l e i n t h e d a t a b a s e y o uh a ve a lre a dy c o nfi gu re d:

    1 CREATE TABLE user (

    2 id integer PRIMARY KEY NOT null,

    3 username varchar NOT null,

    4 password varchar NOT null,

    5 email varchar NOT null,

    6 remember_token varchar NOT null,

    7 created_at datetime NOT null,

    8 updated_at datetime NOT null9 );

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    17/395

    Authentication 4

    H e r e , and f u r the r on, I d e v i ate f r om the s tand ar d of p lu r al d atab as e tab le name s . U s u ally, I w ou ld

    r e c omme nd s ti c k i ng w i th the s tand ar d , b u t thi s g av e me an op p or tu ni ty to d e mons tr ate how you

    c an c onf i g u r e d atab as e tab le name s i n b oth mi g r ati ons and mod e ls .

    Eloquent Driver

    Th e se c o nd dri ve r wh i c h La ra ve l pro vi de s i s c a lle d eloquent. E l o q u e n t i s a l s o t h e n a m e o f t h e O R Mw h i c h L a r a v e l p r o v i d e s , f o r a b s t r a c t i n g m o d e l d a t a . I t i s s i m i l a r i n t h a t i t w i l l u l t i m a t e l y q u e r y ad at ab as e t o d et er m in e w he th er a u se r i s a ut he nt ic , b ut t he i nt er fa ce w hi ch i t u se s t o m ak e t ha t

    de t e rmi na t i o n i s qu i t e di ffe re nt fro m di re c t da t a ba se qu e ri e s.If y o u re u si ng La ra ve l t o bu i ld me di u m- t o - la rge a ppli c a t i o ns, t h e n y o u st a nd a go o d c h a nc e o f u si ngE l o q u e n t m o d e l s t o r e p r e s e n t d a t a b a s e o b j e c t s . I t i s w i t h t h i s i n m i n d t h a t I w i l l s p e n d s o m e t i m ee la bo ra t i ng o n t h e i nvo lve me nt o f Elo qu e nt mo de ls i n t h e a u t h e nt i c a t i o n pro c e ss.

    I f y o u w a n t t o i gn o re a l l t h in g s E l o q ue n t; f e el f r ee t o s ki p t h e f o l l ow i ng s e ct i on s d e al i ng w it h

    models.

    Creating A Migration

    S i nc e w e r e u s in g E l oq u en t t o m a na ge h o w o u r a p pl i ca t io n c o mm u ni c at e s w i th t h e d a ta b as e ; w ema y a s we ll u se La ra ve l s da t a ba se t a ble ma ni pu la t i o n t o o ls.

    T o g e t s t a r t e d , n a v i g a t e t o t h e r o o t o f y o u r p r o j e c t a n d t y p e t h e f o l l o w i n g c o m m a n d :

    1 php artisan migrate:make --table="user" create_user_table

    2

    3 Created Migration: 2014_05_04_193719_create_user_table

    4 Generating optimized class loader

    5 Compiling common classes

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    18/395

    Authentication 5

    The--table f lag matc he s the$table p r o p e r t y w e w i l l d e f i n e i n t h eUser model.

    Th i s wi ll ge ne ra t e t h e sc a ffo ldi ng fo r t h e u se rs t a ble , wh i c h sh o u ld re se mble t h e fo llo wi ng:

    1

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    19/395

    Authentication 6

    1

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    20/395

    Authentication 7

    Creating A Model

    La ra ve l 4 pro vi de s a User mo de l, wi t h a ll t h e i nt e rfa c e me t h o ds i t re qu i re s. I h a ve mo di fi e d i t sli gh t ly ,b u t t h e b a s i c s a r e s t i l l t h e r e

    1

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    21/395

    Authentication 8

    39 {

    40 return $this->email;

    41 }

    42 }

    T h i s f i l e s h o u l d b e s a v e d a s app/models/User.php.

    Note the$table p r op e r ty w e hav e d e f i ne d . I t s hou ld matc h the tab le w e d e f i ne d i n ou r mi g r ati ons .

    The User mo de l e xt e nds Eloquent a n d i m p l e m e n t s t w o i n t e r f a c e s w h i c h e n s u r e t h e m o d e l i s v a l i df o r a u th e nt i ca t io n a n d r e mi n de r o p er a ti o ns . We l l l o ok a t t h e i n te r fa c es l a te r, b u t i t s i m po r ta n t t ono t e t h e me t h o ds t h e se i nt e rfa c e s re qu i re .

    L a r a v e l a l l o w s t h e u s e r o f e i t h e r e m a i l a d d r e s s o r u s e r n a m e w i t h w h i c h t o i d e n t i f y t h e u s e r , b u t i ti s a d i f f e r e n t f i e l d f r o m t h a t w h i c h t h e getAuthIdentifier() re t u rns. Th e UserInterface interfacedo e s spe c i fy t h e pa sswo rd fi e ld na me , bu t t h i s c a n be c h a nge d by o ve rri di ng t h e getAuthPassword()method.

    T h e r e m i n d e r t o k e n m e t h o d s a r e u s e d t o c r e a t e a n d v a l i d a t e a c c o u n t - s p e c i f i c s e c u r i t y t o k e n s . T h e

    f i n e r d e t a i l s a r e b e s t l e f t t o a n o t h e r l e s s o n

    The getReminderEmail() m e t h o d r e t u r n s a n e m a i l a d d r e s s w i t h w h i c h t o c o n t a c t t h e u s e r w i t h apa sswo rd re se t e ma i l, sh o u ld t h i s be re qu i re d.

    Y o u a r e o t h e r w i s e f r e e t o s p e c i f y a n y m o d e l c u s t o m i s a t i o n , w i t h o u t f e a r i t w i l l b r e a k t h e b u i l t - i nauthentication components.

    Creating A Seeder

    L ar av el 4 a ls o i nc lu de s s e ed in g s ys te m, w hi ch c an b e u se d t o a dd r ec or ds t o y ou r d at ab as e a ft er

    i n i t i a l m i g r a t i o n . T o a d d t h e i n i t i a l u s e r s t o m y p r o j e c t , I h a v e t h e f o l l o w i n g s e e d e r c l a s s :

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    22/395

    Authentication 9

    1

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    23/395

    Authentication 10

    T h i s f i l e s h o u l d b e s a v e d a s app/database/seeds/DatabaseSeeder.php.

    TheDatabaseSeeder c la ss wi ll se e d t h e u se rs t a ble wi t h my a c c o u nt wh e n i nvo ke d. If y o u ve a lre a dyse t u p y o u r mi gra t i o n a nd mo de l, a nd pro vi de d va li d da t a ba se c o nne c t i o n de t a i ls, t h e n t h e fo llo wi ngc o mma nds sh o u ld ge t e ve ry t h i ng u p a nd ru nni ng:

    1 composer dump-autoload

    2

    3 Generating autoload files

    4

    5 php artisan migrate

    67 Migrated: ****_**_**_******_create_user_table

    8

    9 php artisan db:seed

    10

    11 Seeded: UserSeeder

    T he f ir s t c om ma nd m ak es s ur e a ll t he n ew c la ss es w e ve c re at ed a re p ic ke d u p b y t he c la ss a ut ol oa de r.Th e se c o nd c re a t e s t h e da t a ba se t a ble s spe c i fi e d fo r t h e mi gra t i o n. Th e t h i rd se e ds t h e u se r da t a i nt ot h e u se rs t a ble .

    Configuring Authentication

    Th e c o nfi gu ra t i o n o pt i o ns fo r t h e a u t h e nt i c a t i o n c o mpo ne nt s a re spa rse , bu t t h e y do a llo w fo r so mecustomisation.

    1

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    24/395

    Authentication 11

    T h i s f i l e s h o u l d b e s a v e d a s app/config/auth.php.

    A l l o f t h es e s e tt i ng s a r e i m po r ta n t, a n d m o st a r e s e lf - ex p l an a to r y. T h e v i ew u s ed t o c o mp o se t h er e q u e s t e m a i l i s s p e c i f i e d w i t h t h e email k e y a n d t h e t i m e i n w h i c h t h e r e s e t t o k e n w i l l e x p i r e i sspe c i fi e d by t h eexpire key.

    Pa y particular att ention t o the view specified by the email k ey i t t el ls L ar av el

    to load the file app/views/email/request.blade.php i nstead of the default

    app/views/emails/auth/reminder.blade.php.

    Logging In

    T o a l l o w a u t h e n t i c u s e r s t o u s e o u r a p p l i c a t i o n , w e r e g o i n g t o b u i l d a l o g i n p a g e ; w h e r e u s e r s c a ne n t e r t h e i r l o g i n d e t a i l s . I f t h e i r d e t a i l s a r e v a l i d , t h e y w i l l b e r e d i r e c t e d t o t h e i r p r o f i l e p a g e .

    Creating A Layout View

    B e f o r e w e c r e a t e a n y o f t h e p a g e s f o r o u t a p p l i c a t i o n ; i t w o u l d b e w i s e t o a b s t r a c t a w a y a l l o f o u rl a y o u t m a r k u p a n d s t y l i n g . T o t h i s e n d ; w e w i l l c r e a t e a l a y o u t v i e w w i t h v a r i o u s i n c l u d e s , u s i n gt h e Bla de t e mpla t e e ngi ne .

    F i r s t o f f , w e n e e d t o c r e a t e t h e l a y o u t v i e w :

    1

    2

    3

    4

    5

    6 Tutorial

    7

    8

    9 @include("header")

    10

    11

    12 @yield("content")

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    25/395

    Authentication 12

    13

    14

    15 @include("footer")

    16

    17

    T h i s f i l e s h o u l d b e s a v e d a s app/views/layout.blade.php.

    T h e l a y o u t v i e w i s m o s t l y s t a n d a r d H T M L , w i t h t w o B l a d e - s p e c i f i c t a g s i n i t . T h e @include tagst el l L ar av el t o i nc lu de t he v ie ws ( na me d i n t ho se s tr in g s; a s header and footer) f r o m t h e v i e w sdirectory.

    No t i c e h o w we ve o mi t t e d t h e .blade.php e x t e n s i o n ? L a r a v e l a u t o m a t i c a l l y a d d s t h i s o n f o r u s . I ta l s o b i n d s t h e d a t a p r o v i d e d t o t h e l a y o u t v i e w t o b o t h i n c l u d e s .

    T he s e co nd B la de t ag i s @yield. T hi s t ag a cc ep ts a s ec ti on n am e, a nd o ut pu ts t he d at a s to re d i nt h a t s e c t i o n . T h e v i e w s i n o u r a p p l i c a t i o n w i l l e x t e n d t h i s l a y o u t v i e w ; w h i l e s p e c i f y i n g t h e i r o w ncontent s e c t i o n s s o t h a t t h e i r m a r k u p i s e m b e d d e d i n t h e m a r k u p o f t h e l a y o u t . Y o u l l s e e e x a c t l yh o w se c t i o ns a re de fi ne d sh o rt ly .

    1 @section("header")

    2

    3 4 Tutorial

    5

    6

    7 @show

    T h i s f i l e s h o u l d b e s a v e d a s app/views/header.blade.php.

    T h e h e a d e r i n c l u d e f i l e c o n t a i n s t w o b l a d e t a g s w h i c h , t o g e t h e r , i n s t r u c t B l a d e t o s t o r e t h e m a r k u pi n t h e n a m e d s e c t i o n , a n d r e n d e r i t i n t h e t e m p l a t e .

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    26/395

    Authentication 13

    1 @section("footer")

    2

    3

    4 Powered by Laravel

    5

    6

    7 @show

    T h i s f i l e s h o u l d b e s a v e d a s app/views/footer.blade.php.

    S i m i l a r l y , t h e f o o t e r i n c l u d e w r a p s i t s m a r k u p i n a n a m e d s e c t i o n a n d i m m e d i a t e l y r e n d e r s i t i n t h e

    template.

    Y o u m a y b e w o n d e r i n g w h y w e w o u l d n e e d t o w r a p t h e m a r k u p , i n t h e s e i n c l u d e f i l e s , i n s e c t i o n s .W e a r e r e n d e r i n g t h e m i m m e d i a t e l y , a f t e r a l l . D o i n g t h i s a l l o w s u s t o a l t e r t h e i r c o n t e n t s . W e w i l ls e e t h i s i n a c t i o n s o o n .

    1 body {

    2 margin : 0;

    3 padding : 0 0 50px 0;

    4 font-family : "Helvetica", "Arial";

    5 font-size : 14px;

    6 line-height : 18px;

    7 cursor : default;

    8 }

    9

    10 a {

    11 color : #ef7c61;

    12 }

    13

    14 .container {

    15 width : 960px;

    16 position : relative;17 margin : 0 auto;

    18 }

    19

    20 .header, .footer {

    21 background : #000;

    22 line-height : 50px;

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    27/395

    Authentication 14

    23 height : 50px;

    24 width : 100%;

    25 color : #fff;

    26 }

    27

    28 .header h1, .header a {

    29 display : inline-block;

    30 }

    31

    32 .header h1 {

    33 margin : 0;

    34 font-weight : normal;

    35 }

    36

    37 .footer {

    38 position : absolute;

    39 bottom : 0;

    40 }

    41

    42 .content {

    43 padding : 25px 0;

    44 }

    45

    46 label, input {

    47 clear : both;

    48 float : left;49 margin : 5px 0;

    50 }

    T h i s f i l e s h o u l d b e s a v e d a s public/css/layout.css.

    We f in is h b y a dd in g s om e b as ic s ty le s; w hi ch w e l in ke d t o i n t he head e l em e nt . T h es e a l te r t h e

    d e f a u l t f o n t s a n d l a y o u t . Y o u r a p p l i c a t i o n w o u l d s t i l l w o r k w i t h o u t t h e m , b u t i t w o u l d j u s t l o o k alittle messy.

    Creating A Login View

    T h e l o g i n v i e w i s e s s e n t i a l l y a f o r m ; i n w h i c h u s e r s e n t e r t h e i r c r e d e n t i a l s .

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    28/395

    Authentication 15

    1 @extends("layout")

    2 @section("content")

    3 {{ Form::open() }}

    4 {{ Form::label("username", "Username") }}

    5 {{ Form::text("username") }}

    6 {{ Form::label("password", "Password") }}

    7 {{ Form::password("password") }}

    8 {{ Form::submit("login") }}

    9 {{ Form::close() }}

    10 @stop

    T h i s f i l e s h o u l d b e s a v e d a s app/views/user/login.blade.php.

    The@extends t a g t e lls La ra ve l t h a t t h i s vi e w e xt e nds t h e la y o u t vi e w. Th e @section t a g t h e n t e l l s i tw h a t m a r k u p t o i n c l u d e i n t h e c o n t e n t s e c t i o n . T h e s e t a g s w i l l f o r m t h e b a s i s f o r a l l t h e v i e w s ( o t h e rt h a n l a y o u t ) w e w i l l b e c r e a t i n g .

    We t he n u se {{ and }} t o t e l l L a r a v e l w e w a n t t h e c o n t a i n e d c o d e t o b e r e n d e r e d , a s i f w e w e r eu si ng t h e echo s t a t e m e n t . W e o p e n t h e f o r m w i t h t h e Form::open() m e t h o d ; p r o v i d i n g a r o u t e f o rt h e f o r m t o p o s t t o , a n d o p t i o n a l p a r a m e t e r s i n t h e s e c o n d a r g u m e n t .

    W e t h e n d e f i n e t w o l a b e l s a n d t h r e e i n p u t s . T h e l a b e l s a c c e p t a n a m e a r g u m e n t , f o l l o w e d b y a t e x t

    a rg um en t. T he t ex t i np ut a cc ep ts a n am e a r gu me nt , a d ef au lt v al ue a r gu me nt a nd a nd o pt io na lp a r am e te r s. T h e p a ss w or d i n pu t a c ce p ts a n a me a r gu m en t a n d o p ti o na l p a ra m et e rs . L a st l y, t h es u b m i t i n p u t a c c e p t s a n a m e a r g u m e n t a n d a t e x t a r g u m e n t ( s i m i l a r t o l a b e l s ) .

    W e c l o s e o u t t h e f o r m w i t h a c a l l t o Form::close().

    Y o u c a n f i n d o u t m o r e a b o u t t h e Form me thod s L ar av e l of f e r s athttp://laravel.com/docs/html.

    O u r l o g i n v i ew i s n o w c o m p le t e, b u t b a s i ca l ly u s el e ss w i th o ut t h e s e r v e r- s id e c o de t o a c ce p t t h ei n p u t a n d r e t u r n a r e s u l t . L e t s g e t t h a t s o r t e d !

    P re vi ou s v er si on s o f t hi s t ut or ia l i nc lu de d s om e e xt ra i np ut a t tr ib ut es , a nd a r ef er en ce t o a

    JavaScript library that will help you support them. I have removed those attributes to simplify

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    29/395

    Authentication 16

    t h e t u t o r i a l , b u t y o u c a n f i n d t h a t s c r i p t a thttp://polyfill.io.

    Creating A Login Action

    T h e l o g i n a c t i o n i s w h a t g l u e s t h e a u t h e n t i c a t i o n l o g i c t o t h e v i e w s w e h a v e c r e a t e d . I f y o u h a v eb e e n f o l l o w i n g a l o n g , y o u m i g h t h a v e w o n d e r e d w h e n w e w e r e g o i n g t o t r y a n y o f t h i s s t u f f o u t i na b r o w s e r . U p t o t h i s p o i n t ; t h e r e w a s n o t h i n g t e l l i n g o u r a p p l i c a t i o n t o l o a d t h a t v i e w .

    T o b e g i n w i t h ; w e n e e d t o a d d a r o u t e f o r t h e l o g i n a c t i o n :

    1

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    30/395

    Authentication 17

    T h i s f i l e s h o u l d b e s a v e d a s app/controllers/UserController.php.

    W e de fi ne t h eUserController, wh i c h e xt e nds t h eController c la ss. W e ve a lso c re a t e d t h elogin()m e t h o d t h a t w e s p e c i f i e d i n t h e r o u t e s f i l e . A l l t h i s c u r r e n t l y d o e s i s r e n d e r t h e l o g i n v i e w t o t h eb r o w s e r , b u t i t s e n o u g h f o r u s t o b e a b l e t o s e e o u r p r o g r e s s !

    U n l e s s y o u v e g o t a p e r s o n a l w e b s e r v e r s e t u p , y o u l l p r o b a b l y w a n t t o u s e t h e b u i l t - i n w e b s e r v e rt h a t La ra ve l pro vi de s. Te c h ni c a lly i t s ju st bo o t st ra ppi ng t h e fra me wo rk o n t o p o f t h e pe rso na l we bs e r v e r t h a t c o m e s b u n d l e d w i t h P H P 5 . 3 , b u t w e s t i l l n e e d t o r u n t h e f o l l o w i n g c o m m a n d t o g e t i tworking:

    1 php artisan serve

    2

    3 Laravel development server started on http://localhost:8000

    W he n y ou o p en y ou r b ro ws er a thttp://localhost:8000, y o u s h o u l d s e e t h e l o g i n p a g e . I f i t s n o tt h e re , y o u ve pro ba bly o ve rlo o ke d so me t h i ng le a di ng u p t o t h i s po i nt .

    Authenticating Users

    R i g h t , s o w e v e g o t t h e f o r m a n d n o w w e n e e d t o t i e i t i n t o t h e d a t a b a s e s o w e c a n a u t h e n t i c a t eusers correctly.

    1

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    31/395

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    32/395

    Authentication 19

    S ome ti me s i t s b e tte r to s tor e the v ali d ati on log i c ou ts i d e of the c ontr olle r . I of te n p u t i t i n a mod e l,

    b u t you c ou ld als o c r e ate a c las s s p e c i f i c ally f or hand li ng and v ali d ati ng i np u t.

    I f y o u p o s t t h i s f o r m ; i t w i l l n o w t e l l y o u w h e t h e r t h e r e q u i r e d f i e l d s w e r e s u p p l i e d o r n o t , b u t t h e r ei s a m o r e e l e g a n t w a y t o d i s p l a y t h i s k i n d o f m e s s a g e

    1 public function login()

    2 {

    3 $data = [];

    4

    5 if ($this->isPostRequest()) {

    6 $validator = $this->getLoginValidator();7

    8 if ($validator->passes()) {

    9 echo "Validation passed!";

    10 } else {

    11 $data["error"] = "Username and/or password invalid.";

    12 }

    13 }

    14

    15 return View::make("user/login", $data);

    16 }

    Thi s w as e x tr ac te d f r om app/controllers/UserController.php.

    I n st e ad o f s h ow i ng i n di v id u al e r ro r m e ss a ge s f o r e i th e r u s er n am e o r p a s sw o rd ; w e r e s h ow i ng as i n g l e e r r o r m e s s a g e f o r b o t h . L o g i n f o r m s a r e a l i t t l e m o r e s e c u r e t h a t w a y !

    T o d i s p l a y t h i s e r r o r m e s s a g e , w e a l s o n e e d t o c h a n g e t h e l o g i n v i e w :

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    33/395

    Authentication 20

    1 @extends("layout")

    2 @section("content")

    3 {{ Form::open() }}

    4 @if (isset($error))

    5 {{ $error }}

    6 @endif

    7 {{ Form::label("username", "Username") }}

    8 {{ Form::text("username") }}

    9 {{ Form::label("password", "Password") }}

    10 {{ Form::password("password") }}

    11 {{ Form::submit("login") }}

    12 {{ Form::close() }}

    13 @stop

    T h i s f i l e s h o u l d b e s a v e d a s app/views/user/login.blade.php.

    A s y o u c a n p r o b a b l y s e e ; w e v e a d d e d a c h e c k f o r t h e e x i s t e n c e o f t h e e r r o r m e s s a g e , a n d r e n d e r e di t . I f v a l i d a t i o n f a i l s , y o u w i l l n o w s e e t h e e r r o r m e s s a g e a b o v e t h e u s e r n a m e f i e l d .

    Redirecting With Input

    O n e o f t h e c o m m o n p i t f a l l s o f f o r m s i s h o w r e f r e s h i n g t h e p a g e m o s t o f t e n r e - s u b m i t s t h e f o r m . W ec a n o v e r co m e t h i s w i th s o me L a ra v el m a gi c . W e l l s t o r e t h e p o s t e d f o r m d a ta i n t h e s e s s i on , a n dr e d i r e c t b a c k t o t h e l o g i n p a g e !

    1 public function login()

    2 {

    3 if ($this->isPostRequest()) {

    4 $validator = $this->getLoginValidator();

    5

    6 if ($validator->passes()) {

    7 echo "Validation passed!";8 } else {

    9 return Redirect::back()

    10 ->withInput()

    11 ->withErrors($validator);

    12 }

    13 }

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    34/395

    Authentication 21

    14

    15 return View::make("user/login");

    16 }

    Thi s w as e x tr ac te d f r om app/controllers/UserController.php.

    I ns te ad o f a ss ig ni ng e rr or s m es sa ge s t o t he v ie w, w e r ed ir ec t b ac k t o t he s am e p ag e, p as si ng t hep o s t e d i n p u t d a t a a n d t h e v a l i d a t o r e r r o r s . T h i s a l s o m e a n s w e w i l l n e e d t o c h a n g e o u r v i e w :

    1 @extends("layout")

    2 @section("content")

    3 {{ Form::open() }}

    4 {{ $errors->first("password") }}

    5 {{ Form::label("username", "Username") }}

    6 {{ Form::text("username", Input::old("username")) }}

    7 {{ Form::label("password", "Password") }}

    8 {{ Form::password("password") }}

    9 {{ Form::submit("login") }}

    10 {{ Form::close() }}

    11 @stop

    W e c a n n o w h i t t h a t r e f r e s h b u t t o n w i t h o u t i t a s k i n g u s f o r p e r m i s s i o n t o r e - s u b m i t d a t a .

    Authenticating Credentials

    T he l as t s te p i n a ut he nt ic at io n i s t o c he ck t he p ro vi de d f or m d at a a ga in s t t he d at ab as e. L ar av elh a n d l e s t h i s e a s i l y f o r u s :

    1

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    35/395

    Authentication 22

    11 if ($validator->passes()) {

    12 $credentials = $this->getLoginCredentials();

    13

    14 if (Auth::attempt($credentials)) {

    15 return Redirect::route("user/profile");

    16 }

    17

    18 return Redirect::back()->withErrors([

    19 "password" => ["Credentials invalid."]

    20 ]);

    21 } else {

    22 return Redirect::back()

    23 ->withInput()

    24 ->withErrors($validator);

    25 }

    26 }

    27

    28 return View::make("user/login");

    29 }

    30

    31 protected function isPostRequest()

    32 {

    33 return Input::server("REQUEST_METHOD") == "POST";

    34 }

    35

    36 protected function getLoginValidator()37 {

    38 return Validator::make(Input::all(), [

    39 "username" => "required",

    40 "password" => "required"

    41 ]);

    42 }

    43

    44 protected function getLoginCredentials()

    45 {

    46 return [

    47 "username" => Input::get("username"),

    48 "password" => Input::get("password")

    49 ];

    50 }

    51 }

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    36/395

    Authentication 23

    T h i s f i l e s h o u l d b e s a v e d a s app/controllers/UserController.php.

    W e s i m p l y n e e d t o p a s s t h e p o s t e d f o r m$credentials t o t h e Auth::attempt() m e t h o d a n d , i f t h eu s e r c r e d e n t i a l s a r e v a l i d , t h e u s e r w i l l b e l o g g e d i n . I f v a l i d , w e r e t u r n a r e d i r e c t t o t h e u s e r p r o f i l epage.

    L e t s s e t t h i s p a g e u p :

    1 @extends("layout")

    2 @section("content")

    3 Hello {{ Auth::user()->username }}

    4

    Welcome to your sparse profile page.

    5 @stop

    T h i s f i l e s h o u l d b e s a v e d a s app/views/user/profile.blade.php.

    1 Route::any("/profile", [

    2 "as" => "user/profile",

    3 "uses" => "UserController@profile"

    4 ]);

    Thi s w as e x tr ac te d f r om app/routes.php.

    1 public function profile()2 {

    3 return View::make("user/profile");

    4 }

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    37/395

    Authentication 24

    Thi s w as e x tr ac te d f r om app/controllers/UserController.php.

    O n c e t h e u s e r i s l o g g e d i n , w e c a n g e t a c c e s s t o t h e i r r e c o r d b y c a l l i n g t h e Auth::user() method.T h i s r e t u r n s a n i n s t a n c e o f t h e U s e r m o d e l ( i f w e r e u s i n g t h e E l o q u e n t a u t h d r i v e r , o r a p l a i n o l dP H P o b j e c t i f w e r e u s i n g t h e D a t a b a s e d r i v e r ) .

    Y o u c a n f i n d o u t m o r e a b o u t t h e A u t h c l a s s a t http://laravel.com/docs/security#authenticating-

    users.

    Resetting Passwords

    T h e p a s s w o r d r e s e t c o m p o n e n t s b u i l t i n t o L a r a v e l a r e g r e a t ! W e r e g o i n g t o s e t i t u p s o u s e r s c a nre se t t h e i r pa sswo rds ju st by pro vi di ng t h e i r e ma i l a ddre ss.

    Creating A Password Reset View

    W e n e e d t w o v i e w s f o r u s e r s t o b e a b l e t o r e s e t t h e i r p a s s w o r d s . W e n e e d a v i e w f o r t h e m t o e n t e rt h e i r e m a i l a d d r e s s s o t h e y c a n b e s e n t a r e s e t t o k e n , a n d w e n e e d a v i e w f o r t h e m t o e n t e r a n e w

    pa sswo rd fo r t h e i r a c c o u nt .

    1 @extends("layout")

    2 @section("content")

    3 {{ Form::open() }}

    4 {{ Form::label("email", "Email") }}

    5 {{ Form::text("email", Input::old("email")) }}

    6 {{ Form::submit("reset") }}

    7 {{ Form::close() }}

    8 @stop

    T h i s f i l e s h o u l d b e s a v e d a s app/views/user/request.blade.php.

    T h i s v i e w i s s i m i l a r t o t h e l o g i n v i e w , e x c e p t i t h a s a s i n g l e f i e l d f o r a n e m a i l a d d r e s s .

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    38/395

    Authentication 25

    1 @extends("layout")

    2 @section("content")

    3 {{ Form::open() }}

    4 {{ $errors->first("token") }}

    5 {{ Form::label("email", "Email") }}

    6 {{ Form::text("email", Input::get("email")) }}

    7 {{ $errors->first("email") }}

    8 {{ Form::label("password", "Password") }}

    9 {{ Form::password("password") }}

    10 {{ $errors->first("password") }}

    11 {{ Form::label("password_confirmation", "Confirm") }}

    12 {{ Form::password("password_confirmation") }}

    13 {{ $errors->first("password_confirmation") }}

    14 {{ Form::submit("reset") }}

    15 {{ Form::close() }}

    16 @stop

    T h i s f i l e s h o u l d b e s a v e d a s app/views/user/reset.blade.php.

    O k, y ou g et i t b y n ow. T he re s a f or m w it h s om e i np ut s a nd e rr or m es s ag es . I v e a ls o s li gh tl y m od if ie dt h e p a s s w o r d t o k e n r e q u e s t e m a i l , t h o u g h i t r e m a i n s m o s t l y t h e s a m e a s t h e d e f a u l t v i e w p r o v i d e d

    by ne w La ra ve l 4 i nst a lla t i o ns.

    1

    2

    3

    4

    5

    6

    7 Password Reset

    8 To reset your password, complete this form:

    9 {{ URL::route("user/reset", compact("token")) }}

    10

    11

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    39/395

    Authentication 26

    T h i s f i l e s h o u l d b e s a v e d a s app/views/email/request.blade.php.

    R em em be r w e c ha ng ed t he c on fi gu ra ti on o pt io ns f or e ma il in g t hi s v ie w f ro m t he d ef au lt

    app/views/emails/auth/reminder.blade.php.

    Creating A Password Reset Action

    I n o r d e r f o r t h e a c t i o n s t o b e a c c e s s i b l e ; w e n e e d t o a d d r o u t e s f o r t h e m .

    1 Route::any("/request", [

    2 "as" => "user/request",

    3 "uses" => "UserController@request"

    4 ]);

    5

    6 Route::any("/reset/{token}", [

    7 "as" => "user/reset",

    8 "uses" => "UserController@reset"

    9 ]);

    Thi s w as e x tr ac te d f r om app/routes.php.

    R em em be r; t he r eq ue st r ou te i s f or r eq ue st in g a r es et t ok en , a nd t he r es et r ou te i s f or r es et ti ng ap a s s w o r d . W e a l s o n e e d t o g e n e r a t e t h e p a s s w o r d r e s e t t o k e n s t a b l e ; u s i n g a r t i s a n .

    1 php artisan auth:reminders-table

    2

    3 Migration created successfully!

    4 Generating optimized class loader

    Th i s wi ll ge ne ra t e a mi gra t i o n t e mpla t e fo r t h e re mi nde r t a ble :

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    40/395

    Authentication 27

    1

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    41/395

    Authentication 28

    1 public function request()

    2 {

    3 if ($this->isPostRequest()) {

    4 $response = $this->getPasswordRemindResponse();

    5

    6 if ($this->isInvalidUser($response)) {

    7 return Redirect::back()

    8 ->withInput()

    9 ->with("error", Lang::get($response));

    10 }

    11

    12 return Redirect::back()

    13 ->with("status", Lang::get($response));

    14 }

    15

    16 return View::make("user/request");

    17 }

    18

    19 protected function getPasswordRemindResponse()

    20 {

    21 return Password::remind(Input::only("email"));

    22 }

    23

    24 protected function isInvalidUser($response)

    25 {

    26 return $response === Password::INVALID_USER;27 }

    Thi s w as e x tr ac te d f r om app/controllers/UserController.php.

    T h e m a i n m a g i c i n t h i s s e t o f m e t h o d s i s t h e c a l l t o t h ePassword::remind() me t h o d. Th i s me t h o dc h e c k s t h e d a t a b a s e f o r a m a t c h i n g u s e r . I f o n e i s f o u n d , a n e m a i l i s s e n t t o t h a t u s e r , o r e l s e a n e r r o r

    me ssa ge i s re t u rne d.

    W e s h o u l d a d j u s t t h e r e s e t v i e w t o a c c o m m o d a t e t h i s e r r o r m e s s a g e :

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    42/395

    Authentication 29

    1 @extends("layout")

    2 @section("content")

    3 {{ Form::open() }}

    4 @if (Session::get("error"))

    5 {{ Session::get("error") }}

    6 @endif

    7 @if (Session::get("status"))

    8 {{ Session::get("status") }}

    9 @endif

    10 {{ Form::label("email", "Email") }}

    11 {{ Form::text("email", Input::old("email")) }}

    12 {{ Form::submit("reset") }}

    13 {{ Form::close() }}

    14 @stop

    T h i s f i l e s h o u l d b e s a v e d a s app/views/user/request.blade.php.

    W he n n av ig at in g t o t hi s r ou te , y ou s ho ul d b e p re se nt ed w it h a f or m c on ta in in g a n e ma il a d dr es s f ie lda n d a s u b m i t b u t t o n . C o m p l e t i n g i t w i t h a n i n v a l i d e m a i l a d d r e s s s h o u l d r e n d e r a n e r r o r m e s s a g e ,w h i l e c o m p l e t i n g i t w i t h a v a l i d e m a i l a d d r e s s s h o u l d r e n d e r a s u c c e s s m e s s a g e . T h a t i s , p r o v i d e dt h e e m a i l i s s e n t

    L ar av e l i nc lu d e s a ton of c onf i g u r ati on op ti ons f or s e nd i ng e mai l. I w ou ld lov e to g o ov e r the m now ,

    b u t i n t h e i n t e r e s t s o f k e e p i n g t h i s t u t o r i a l f o c u s s e d , I l l s i m p l y s u g g e s t t h a t y o u s e t t h e pretend

    k e y t o t r u e , i n app/config/mail.php. T h i s w i l l a c t a s i f t h e a p p l i c a t i o n i s s e n d i n g e m a i l , t h o u g h i t

    just skips that step.

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    43/395

    Authentication 30

    1 public function reset($token)

    2 {

    3 if ($this->isPostRequest()) {

    4 $credentials = Input::only(

    5 "email",

    6 "password",

    7 "password_confirmation"

    8 ) + compact("token");

    9

    10 $response = $this->resetPassword($credentials);

    11

    12 if ($response === Password::PASSWORD_RESET) {

    13 return Redirect::route("user/profile");

    14 }

    15

    16 return Redirect::back()

    17 ->withInput()

    18 ->with("error", Lang::get($response));

    19 }

    20

    21 return View::make("user/reset", compact("token"));

    22 }

    23

    24 protected function resetPassword($credentials)

    25 {

    26 return Password::reset($credentials, function($user, $pass) {27 $user->password = Hash::make($pass);

    28 $user->save();

    29 });

    30 }

    Thi s w as e x tr ac te d f r om app/controllers/UserController.php.

    S i mi l ar t o t h ePassword::remind() me th o d, t h e Password::reset() m et h od a c ce p ts a n a r ra y o f u s e r - s p e c i f i c d a t a a n d d o e s a b u n c h o f m a g i c . T h a t m a g i c i n c l u d e s c h e c k i n g f o r a v a l i d u s e r a c c o u n ta nd c h a ngi ng t h e a sso c i a t e d pa sswo rd, o r re t u rni ng a n e rro r me ssa ge .

    W e n e e d t o c r e a t e t h e r e s e t v i e w , f o r t h i s :

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    44/395

    Authentication 31

    1 @extends("layout")

    2 @section("content")

    3 {{ Form::open() }}

    4 @if (Session::get("error"))

    5 {{ Session::get("error") }}

    6 @endif

    7 {{ Form::label("email", "Email") }}

    8 {{ Form::text("email", Input::old("email")) }}

    9 {{ $errors->first("email") }}

    10 {{ Form::label("password", "Password") }}

    11 {{ Form::password("password") }}

    12 {{ $errors->first("password") }}

    13 {{ Form::label("password_confirmation", "Confirm") }}

    14 {{ Form::password("password_confirmation") }}

    15 {{ $errors->first("password_confirmation") }}

    16 {{ Form::submit("reset") }}

    17 {{ Form::close() }}

    18 @stop

    T h i s f i l e s h o u l d b e s a v e d a s app/views/user/reset.blade.php.

    Tok e ns e x p i r e af te r 6 0 mi nu te s , as d e f i ne d i n app/config/auth.php.

    Creating Filters

    La ra ve l i nc lu de s a fi lt e rs fi le , i n wh i c h we c a n de fi ne fi lt e rs t o ru n fo r si ngle o r e ve n gro u ps o f ro u t e s.T h e m o s t b a s i c o n e w e r e g o i n g t o l o o k a t i s t h e a u t h f i l t e r :

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    45/395

    Authentication 32

    1

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    46/395

    Authentication 33

    T h i s f i l e s h o u l d b e s a v e d a s app/routes.php.

    Y o u ll no t i c e t h a t we ve wra ppe d t h e pro fi le ro u t e i n a c a llba c k, wh i c h e xe c u t e s t h e a u t h fi lt e r. Th i sme a ns t h e pro fi le ro u t e wi ll o nly be a c c e ssi ble t o a u t h e nt i c a t e d u se rs.

    Creating A Logout Action

    T o t e s t t h e s e n e w s e c u r i t y m e a s u r e s o u t , a n d t o r o u n d o f f t h e t u t o r i a l , w e n e e d t o c r e a t e a logout()m e t h o d a n d a d d l i n k s t o t h e h e a d e r s o t h a t u s e r s c a n l o g o u t .

    1 public function logout()

    2 {

    3 Auth::logout();

    4

    5 return Redirect::route("user/login");

    6 }

    Thi s w as e x tr ac te d f r om app/controllers/UserController.php.

    L o g g i n g a u s e r o u t i s a s s i m p l e a s c a l l i n g t h e Auth::logout() m e t h o d . I t d o e s n t c l e a r t h e s e s s i o n ,m i n d y o u , b u t i t w i l l m a k e s u r e o u r auth fi lt e r ki c ks i n

    T h i s i s w h a t t h e n e w h e a d e r i n c l u d e l o o k s l i k e :

    1 @section("header")

    2

    3

    4 Tutorial

    5 @if (Auth::check())

    6

    7 logout

    8 |

    9

    10 profile

    11

    12 @else

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    47/395

    Authentication 34

    13

    14 login

    15

    16 @endif

    17

    18

    19 @show

    T h i s f i l e s h o u l d b e s a v e d a s app/views/header.blade.php.

    L a s t l y , w e s h o u l d a d d a r o u t e t o t h e l o g o u t a c t i o n :

    1 Route::any("/logout", [

    2 "as" => "user/logout",

    3 "uses" => "UserController@logout"

    4 ]);

    Thi s w as e x tr ac te d f r om app/routes.php.

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    48/395

    Access Control ListP r e v i o u s l y w e l o o k e d a t h o w t o s e t u p a b a s i c a u t h e n t i c a t i o n s y s t e m . I n t h i s c h a p t e r ; w e r e g o i n g t oc o n t i n u e t o i m p r o v e t h e a u t h e n t i c a t i o n s y s t e m b y a d d i n g w h a t s c a l l e d A C L ( A c c e s s C o n t r o l L i s t )t o t h e a u t h e nt i c a t i o n la y e r.

    T h e c o d e f o r t h i s c h a p t e r c a n b e f o u n d a t : https://github.com/formativ/tutorial-laravel-4-acl

    Managing Groups

    W e re go i ng t o be c re a t i ng a n i nt e rfa c e fo r a ddi ng, mo di fy i ng a nd de le t i ng u se r gro u ps. Gro u ps wi llb e t h e c o n t a i n e r s t o w h i c h w e a d d v a r i o u s u s e r s a n d r e s o u r c e s . W e l l d o t h a t b y c r e a t e a m i g r a t i o na n d a m o d e l f o r g r o u p s , b u t w e r e a l s o g o i n g t o o p t i m i s e t h e w a y w e c r e a t e m i g r a t i o n s .

    Refactoring Migrations

    W e v e g o t a f e w m o r e m i g r a t i o n s t o c r e a t e i n t h i s t u t o r i a l ; s o i t s a g o o d t i m e f o r u s t o r e f a c t o r o u ra ppro a c h t o c re a t i ng t h e m

    1

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    49/395

    Ac c e s s C o n tro l L i s t 36

    16 }

    17

    18 return $this->table;

    19 }

    20

    21 public function setTable(Blueprint $table)

    22 {

    23 $this->table = $table;

    24 return $this;

    25 }

    26

    27 public function addNullable($type, $key)

    28 {

    29 $types = [

    30 "boolean",

    31 "dateTime",

    32 "integer",

    33 "string",

    34 "text"

    35 ];

    36

    37 if (in_array($type, $types))

    38 {

    39 $this->getTable()

    40 ->{$type}($key)

    41 ->nullable()42 ->default(null);

    43 }

    44

    45 return $this;

    46 }

    47

    48 public function addTimestamps()

    49 {

    50 $this->addNullable("dateTime", "created_at");

    51 $this->addNullable("dateTime", "updated_at");

    52 $this->addNullable("dateTime", "deleted_at");

    53 return $this;

    54 }

    55

    56 public function addPrimary()

    57 {

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    50/395

    Ac c e s s C o n tro l L i s t 37

    58 $this->getTable()->increments("id");

    59 return $this;

    60 }

    61

    62 public function addForeign($key)

    63 {

    64 $this->addNullable("integer", $key);

    65 $this->getTable()->index($key);

    66 return $this;

    67 }

    68

    69 public function addBoolean($key)

    70 {

    71 return $this->addNullable("boolean", $key);

    72 }

    73

    74 public function addDateTime($key)

    75 {

    76 return $this->addNullable("dateTime", $key);

    77 }

    78

    79 public function addInteger($key)

    80 {

    81 return $this->addNullable("integer", $key);

    82 }

    83

    84 public function addString($key)

    85 {

    86 return $this->addNullable("string", $key);

    87 }

    88

    89 public function addText($key)

    90 {

    91 return $this->addNullable("text", $key);

    92 }

    93 }

    T h i s f i l e s h o u l d b e s a v e d a sapp/database/migrations/BaseMigration.php.

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    51/395

    Ac c e s s C o n tro l L i s t 38

    W e r e g o i n g t o b a s e a l l o f o u r m o d e l s o f f o f a s i n g l e BaseModel c l a s s . T h i s w i l l m a k e i t p o s s i b l e f o ru s t o r e u s e a l o t o f t h e r e p e a t e d c o d e w e h a d b e f o r e .

    The BaseModel c l as s h as a s in gl e p ro te ct ed $table p r op e rt y, f o r s t or i ng t h e c u rr e nt Blueprint

    i ns ta nc e w e a re g iv in g i ns id e o ur m ig r at io n c al lb ac ks . We h av e a t yp ic al s et te r f or t hi s; a nd a na t y pi c a l ge t t e r (wh i c h t h ro ws a n e xc e pt i o n i f $this->table h a s n t b e e n s e t ) . W e d o t h i s a s w e n e e da w a y t o v a l i d a t e t h a t t h e m e t h o d s w h i c h r e q u i r e a v a l i d Blueprint i n s t a n c e h a v e o n e o r t h r o w a nexception.

    OurBaseMigration c l a s s a l s o h a s a f a c t o r y m e t h o d f o r c r e a t i n g f i e l d s o f v a r i o u s t y p e s . I f t h e t y p ep ro vi de d i s o ne o f t ho se d ef in ed ; a n ul la bl e f ie ld o f t ha t t yp e w il l b e c re at ed . T hi s s ig ni fi ca nt lys h o r t e n s t h e c o d e w e u s e d p r e v i o u s l y t o c r e a t e n u l l a b l e f i e l d s .

    F o ll o wi n g t h is ; w e h a ve addPrimary(), addForeign() and addTimestamps(). T h e addPrimary()me t h o d i s a bi t c le a re r t h a n t h e increments() me t h o d, t h e addForeign() me t h o d a dds bo t h a nu lla blei nt eg er f ie ld a nd a n i nd ex f or t he f or ei gn k ey. T he addTimestamps() m et ho d i s s im il ar t o t he

    Blueprintstimestamps() m e t h o d ; e x c e p t t h a t i t a l s o a d d s t h e deleted_at t i me st a mp fi e ld.F i n a l l y ; t h e r e a r e a h a n d f u l o f m e t h o d s w h i c h p r o x y t o t h e addNullable() method.

    U s in g t he se m et ho d s, t he a mo un t o f c od e r eq ui re d f or t he m ig ra ti on s w e w il l c re at e ( an d h av ea lre a dy c re a t e d) i s dra st i c a lly re du c e d.

    1

  • 8/10/2019 How to cook and other inquiries about wolf hustlin'

    52/395

    Ac c e s s C o n tro l L i s t 39

    23 }

    24 }

    Th is fi le sh oul d be sa ved a s app/database/migrations/0000_00_00_000000_CreateGroupT-

    able.php. Y ou r s may b e s li g htly d i f f e r e nt as the 0 s ar e r e p lac e d w i th othe r nu mb e r s .

    T he g r ou p t ab le h as a p r im ar y k ey, t im es ta mp f ie ld s ( in cl ud in g created_at, updated_at anddeleted_at) a s w e l l a s a n a m e f i e l d .

    I f y ou r e s k ip p in g m ig r at io ns ; t he f ol lo wi ng S QL s ho ul d c re at e t he s am e t ab le s tr uc tu re a s t hemigration:

    1 CREATE TABLE group` (

    2 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,

    3 `name` varchar(255) DEFAULT NULL,

    4 `created_at` datetime DEFAULT NULL,

    5 `updated_at` datetime DEFAULT NULL,

    6 deleted_at` datetime DEFAULT NULL,

    7 PRIMARY KEY (`id`)

    8 ) ENGINE=InnoDB CHARSET=utf8;

    Listing GroupsWe r e g o in g t o b e c r ea t in g v i ew s t o m a na g e g r o u p r e co r ds ; m o re c o mp r eh e ns i ve t h an t h os e w ec r e a t e d f o r u s e r s p r e v i o u s l y , b u t m u c h t h e s a m e i n t e r m s o f c o m p l e x i t y .

    1 @extends("layout")

    2 @section("content")