Laravel CheatSheet
Tags: laravel
Published: 2020-07-15 09:52:46

Valet set up on Mac: valet link target   -> where the public or public_html folder of the app that you would like to show is the target. To view the valet link type: valet links

to change your valet domain (.whateveryoulike) run: valet domain domainnameofyourchoosing

To get around the PHP memory error in PHP artisan tinker or in a PHP file type in the following:
ini_set('memory_limit', -1);
(though in production set it to a MB or GB like 512M in production e.g.ini_set('memory_limit', '-512M');)

App/resources/routes/web.php defines all of the routes for a webpage and can be used to load up views which are held in App/resources/views.

Upon a response to a patch request you can get the attributes before the patch submission by using the getOriginal() method.

To quickly view routes run php artisan route:list

The blade file naming e.g. welcome.blade.php allows you to reference the slug from the routes entry safely (helps stop hackers) and easily.

env file details all of the database configurations
php artisan shows all of the artisan commands within the Laravel environment.
php artisan tinker /*this is a php tinkering environment which also allows you to access the variables in Laravel*/
php artisan serve starts the development server
php artisan make:model NAMEOFMODEL -mc

-mc flag adds a migration and a controller to the eloquent model

Once the model is created you can edit the migration to create the table. To commit the migration you can run:
php artisan migrate

Once the table is create you can create a new entry by doing $newEntry = new NAMESPACE\NAMEOFMODEL;
$newEntry->COLUMNNAME = "First Entry";
$newEntry->save(); //This commits the change.

NAMESPACE\NAMEOFMODEL::all(); /*This shows you all of the entries in the model/database.*/

NAMESPACE\NAMEOFMODEL::where('completed',false)->get(); /*This shows all entries where false is shown in the completed column*/

Methods
Methods can be created in the Eloquent Model. A major purpose of the Eloquent Model is to create methods which can call on migrations (which make changes to database) or any other type of business logic. One you are in the correct namespace, they can be invoked using ->nameofmethod()

Namespaces
namespace App; //Changes the current namespace to App
echo __NAMESPACE__ //This echos the current namespace

<b>Making Components within Views of Laravel</b>
Put the following in your view blade view file

@extends('layout');
@section('content')
  <h1>Hello World</h1>
@endsection

You will then be able to reference this in a different php file called layout.blade.php in the same directory using @yield('content').

Laravel comes with WebPack support out of the box using Laravel Mix.

npm run dev //runs webpack - it compiles the scss file to css as per webpack.mix.js file. This also helps you run webpack on Vue files too. "npm run watch" can watch the associated files for changes and automatically recompile them. This includes react and less support. 

<b>Example Controller</b>

use App\Article;
use Illuminate\Http\Request;

class ArticlesController extends Controller
{
    public function show($id) {
        $article = Article::find($id);

        return view('articles.show', ['article' => $article]);
    }

    public function index() {
        $articles = Article::all();

        return view('articles.showall', ['articles' => $articles]);
    }
}

By convention use index() to use all rows in a table and show() to use a particular row in a table

To create a controller with all of the standard methods in type:
php artisan make:controller ProjectsController -r

<b>error 419</b>

This is usually due to a csrf error. Laravel does this to try and secure you as much as possible. Add the page that is receiving the error in the file:
VerifyCsrfToken.php
e.g.:
   protected $except = [
        'http://testproject.test/articles'
    ];

also put @csrf in the form that is posting the information.

<b>Lavarel Vapor</b>
https://devdojo.com/bobbyiliev/the-good-and-the-bad-of-using-vapor

<b>Other</b>
dd($value) would show the $value in browser.
To use Laravel PUT methods you need to put the following in the form:


![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/xrzochhk1cu1vy996vav.png)

NOTICE THAT THE FORM METHOD AT THE TOP IS STILL POST.

getRouteKeyName() -> changes the database search of the route auto binding.

The following will store in a SQL table if it does not exist already. It is similar to ->save() except it does not throw an error if it does not already exist:
``` ->sync($value, false) ```

The following blade directive includes a html section into another html document:
```
@include('NameOfHtml')
```

<b>Mass Assignment Error</b>
You have to be explicit in Laravel of the field names from the form that you want to search the database with. Putting the following in the Model will allow form items to do so:
protected $fillable = ['title', 'excerpt', 'body'];

Putting the following in your Model will stop having to list it out explicitly:
protected $guarded = [];

The following command will list all of the registered routes
php artisan route:list

<b>Auth</b>
To get an out of the box Laravel application with user authentication already built in run the following commands:

php artisan ui vue --auth
npm install && npm run dev

Once the database is created in MySQL and the .env file is updated you can use either of the following two commands to access the user's name within your home.blade.php file.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0kuzvv986kbgzsy41emb.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/pnfp2ohgsi9vhtmxk1ep.png)

To check whether a user is authenticated before rendering a user specific object use one of the following techniques:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7nbnu527hvmh2e8d9ybf.png)
Or use Laveral's @auth which does the exact same thing:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/hetjcuenupwu0xlmyiyc.png)

You can use the following to only render a object which is specific to when the user is logged in:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/2l0g7nfo4ooasams15c6.png)

Out of the box Laravel also provides a reset password mechanism via mail. To enable this ensure that your MAIL_ fields in your .env are set up. You can set your MAIL_MAILER to log. This will out put the body of the mail (it won't actually send the mail) to storage/logs/laravel.log -> this is useful for testing.

<b>Collections</b>

To create a collection run the following command: ```create([1,2,3,4]); ```

To view all collection methods go to vendor/laravel/framework/src/Illuminate/Support/Collection.php

Create a new model instance with $newModelInstance = new App/MODELNAME;

An example is ->flatten which turns collections of collections in to one collection
Another is ->map which maps a function over the collection and returns a new collection.
```$shortCode = District::where('id',271)->pluck('short_code');```
The following finds the model instance where the primary key is 1, which is normally the id:
```District::find(1)```
To delete a property from an object class do: ```unset($object[$key])```
You can use ->fill() to update a model instance with new attributes. This will overwrite old attributes too. e.g:
lets say that $new has the following output PHP artisan tinker:
```
=> App\User {#3859
     id: 4,
     name: "ds",
     email: "ds",
     admin: 0,
   }
```
To replace a new attribute, e.g. the name you could do the follow:
```
$attr = [name => 'huh']
$new->fill($attr)
```
This would then output:
```
=> App\User {#3859
     id: 4,
     name: "huh",
     email: "ds",
     admin: 0,
     updated_at: "2020-08-04 05:48:03",
     created_at: "2020-08-04 05:48:03",

```
<b> CSRF protection </b>
Another site can affect the state of your site without you even knowing. Laravel protects you against this.

<b> Error Codes </b>
A list of all error codes is in response.php

<b> Facades </b>
View::make('welcome')
which is the same as view('welcome') but using Facade.
View the @see in the facade to view all of the facade's methods.
<b>Sending a mail</b>
Use mail trap to set up your .env file for testing.
You can use the Mail Facade to send emails. e.g:
```
Mail::raw('it works!', function ($message){$message->to("emailaddressgoeshere@gmail.com")->subject('Hello there');});
```

To create a html message you can run the following to create a new mailer which can return whatever html view you want;
```
php artisan make:mail EmailMe -m 'insert_email_view_here'
```

To use a Laravel formatted HTML mail out of the box use the following the view:
```
@component('mail::message')
# A Heading
The body of the email
@component('mail::button', [ "url" => "website.com"])
Visit My Website
@endcomponent
@endcomponent
```

You can also get a boilerplate for this out of the box if you run:
```php artisan make:mail EmailMe -m```

To edit this template run:
```php artisan vendor:publish --tag=laravel-mail```
This will copy the templates to a new view directory called vendor. If you edit the html/css in the these view the email will be updated with the new style. i.e. Laravel know to look in this directory rather than the vendor directory. You can also change the default.css in this vendor directory but changing the Markdown Mail settings in the config/mail.php file -> you would need to change the change from default in the markdown theme section.

Then in the controller method you can put 
```
Mail::to('insert_email_address_here')
            ->send(new ContactMe());
```
Where ContactMe() is the Mail:: class created.

<b>Flash Message</b>
For example to create a flash message put the following in the controller to send the message:
```
...
return redirect('/contact')
->with('message','Email sent!');
```
You will then be able to put the following in the view:
```
@if(session('message'))
   <div>{{session('message')}}</div>
@endif
```

<b> Notifications </b>
If auth() is used you can do the following to create an email or text etc:
```
use Illuminate\Support\Facades\Notification;
Notification::send(request()->user(), new InsertNotificationClassExtensionHere());
```

Create the Notification Class Extension using:
```
php artisan make:notification InsertNotificationClassExtensionNameHere
```

To also send the notification information to the database for traceability you can do the following to create the table:

```php artisan notifications:table```
You can then edit the notification class extension to state:
```
    public function via($notifiable)
    {
        return ['mail', 'database'];
    }
```
And fill in the array (which will be visible in the data column of your database) e.g.:
```
 public function toArray($notifiable)
    {
        return [
            'amount' => $this->amount
        ];
    }
```
<b>Contructs</b>

These allow you to utilise the variables passed to your class. e.g.
If you call a class from the Contoller and pass an object to it:
```
request()->user()->notify(new PaymentRecieved(900));
```
You will then be able to use this variable or object such as shown below:
```
class PaymentRecieved extends Notification {
    public function __construct($amount)
    {
        $this->amount = $amount;
    }

    public function toArray()
    {
        return [
            'amount' => $this->amount;
        ];
    }
}
```
<b> ForElse Block </b>
A forelse block in a blade.php view in Laravel allows is similar to the foreach block but you are allowed to submit something when the if statement returns false. e.g:
```
    <div class="container">
        Show all user notifications
        <ul>
        @forelse($notifications as $notification)
            @if($notification->type == 'App\Notifications\PaymentRecieved')
                <li>We have recieved a payment of {{$notification->data['amount']}} from you</li>
            @endif
            @empty
            <li>You have no unread notifications.</li>
        @endforelse

        </ul>
    </div>
```
<b> Sending SMS messages </b>
You can use the following link to find out how this works with Laravel (using Vonage https://dashboard.nexmo.com/sign-in).
https://laravel.com/docs/7.x/notifications#sms-notifications

<b> Listeners and Events </b>

You can create events which can be dispatched. You can also add listeners which create an action once the event is dispatched. The events and listeners need to be linked using the EventServicesProvider.php file.
e.g 
Create an event:
```
php artisan make:event ProductPurchased
```
To view this event type in:
```
php artisan event:list
```
Create a new listener:
```
php artisan make:event SendShareableCoupon -e ProductPurchased
```
Tie them together in the EventServicesProvider.php, change the listen array:
```
    protected $listen = [
        Registered::class => [
            SendEmailVerificationNotification::class,
        ],
        ProductPurchased::class => [
            SendShareableCoupon::class,
        ]
    ];
```
Or to avoid tieing events and listeners manually together all of the time then put the following in the EventServicesProvider.php file:
```
    public function shouldDiscoverEvents()
    {
        return true;
    }
```

<b>Limit Access to Authorized Users</b>
For example lets say that in your users SQL table you have a "admin" column, values -> 1 if the user is an admin, otherwise 0. You can use the blade directive @can in the view in conjunction with an edit in the authServiceProvider.php to filter what this admin can view.
Do the following in the authServiceProvider.php, amend the boot function and import the classes:
```
use App\User;
use Illuminate\Support\Facades\Gate;
    public function boot()
    {
        $this->registerPolicies();

        Gate::define('admin', function() {
            if(Auth::user()->admin) {
                return true;
            };
        });
    }
```
Then the view can look like this with the blade directive:
                    @can ('admin')
                        <div>You are a admin</div>
                    @endcan

Then if you are a admin will only be visible if you are labelled as an admin.
In a controller you can you use the helper function authorize() instead, which if you look under the hood just uses the Gate:: facade anyway.
Other Gate:: commands are allow() or denies() -> which act it the authServiceProvider allows or denies an action.

You can login as a particular user for testing using:
auth()->loginUsingId(INSERT ID HERE);
<b> Laravel Policies </b>
This is for organisational purposes and it is a place where you can detail what users are allowed to do on each model.

php artisan make:policy AdminPolicy --model=authtesting

<b> Tinker Well </b>
This is basically php artisan tinker but on steroids.

<b> SQL Logger </b>
In php artisan tinker or tinkerwell:
DB::enableQueryLog();
DB::getQueryLog();
This will show the SQL queries made under the hood, including the time it took and the bindings.