Laravel 5.8 – From The Ground Up - Laravel 5.8 Tutorial From Scratch – e52 – Multi Image File Upload & Gallery

Education, Programming

Laravel 5.8 – From The Ground Up

52 Lessons

Laravel 5.8 Tutorial From Scratch – e52 – Multi Image File Upload & Gallery

welcome in this episode we're going to be tackling probably the most requested thing in coders tape and that is how to do multiple image upload and create a

gallery using level and view so let me show you what we're actually going to be building and this is it right here this is the finished product now the first thing you'll notice is just drop images

here now this is gonna allow us to grab some images here are some sample images that I have and simply just drag them into here and this will upload them for us automatically

now we'll also create a thumbnail for us so what we're actually seeing here is a thumbnail so 250 pixel by 250 pixel thumbnail if we click on the image then we do get the full resolution image so

that's pretty cool furthermore from that we can hit the delete button and that goes away and of course we are deleting the record from the database but we're also cleaning up

our files we're actually deleting the thumbnail and the original file with that single click so stick around we have a lot to cover and we're gonna do it from scratch

100% using level and view I'll see you on the other side [Music] okay so let's start from the very beginning

let's run laravel new image – upload so a completely fresh level installation so let's let it do its thing we'll be right back okay and now that's finished let's visit in the browser I

hit refresh and there we go so we have a fresh level installation okay a couple more setup things that we need to do so let me CD into our image of load

project and let's go ahead and run npm install of course we're gonna use view to make the drag-and-drop functionality work so let's go ahead and run all the npm installation and then we'll add drop

zone that's the package that's gonna let us drop files into the browser and upload them for us okay so now let's run npm i and the package that we're looking for is drop zone and let's go ahead and

save that to our dependencies so now we can run npm run watch and because this is the first time it's gonna need to install a couple more things all right so we are all compiled and ready to go

let me go ahead and open this up in phpstorm so now that it's open in phpstorm one thing i do want to note is that i'm going to try to use everything that

level ships with and nothing out of the ordinary that way the setup is very very simple and we're really focused around the functionality that we are trying to get so i will actually even reuse the

example component that ships with level so if we go inside resources j/s components here's the example component so of course we know that we're going to need that drop zone so let's go ahead

and delete everything from this component and let's go ahead and import that drop zone so right after the script tag will say import drop zone from drop zone so this will bring in this package

that we need so now when our component is mounted i want to go ahead and new up drop zone so – new up drop zone let's make a new data property so say data it's a function that returns an object

and instead of here let's have drop zone and initially we'll set that equal to null so again when the component is mounted let's go ahead and grab this dot drop

zone and then let's go ahead a new up drop zone now drop zone to new it up you're going to need two things the first thing is our drag and drop area the area that we want our application to

go ahead and designate as the drag and drop area so typically for this you could do it as an ID but the nice thing with using view is that we have this reference so let me show you how

something like that would work instead let's go ahead and create a div and inside the diff we'll add this ref attribute again ref is just a reference to a particular tag using view so let's

call it image upload so now how do we access this particular div well inside of here we can say this dot dollar sign refs as in references dot image upload so now we are passing this particular

div into our drop zone and like I said it needs a second thing and what that is is just simply an object that has some settings or options for this particular drop zone plugin now there are a ton of

setting but the only thing that is actually required is a URL and the URL that is required is the URL that it's actually going to send the pictures to now of course we don't have that yet but

let's go ahead and add one anyway we'll add it eventually but right now it doesn't exist yet so we'll say the URL is gonna be slash images so it's gonna perform

a post request to slash images and that's it that's really all we need I did forget the common air let's add it back in so now that we have this going that's basically it in terms of setup

for drop zone let's go ahead and style this a little bit so we can actually see what's inside of it so let's add some classes here now level of course ships with bootstrap so that's what we're

gonna be using for this so let's make this a row and we'll justified content Center a margin bottom of three so now inside of here let's add some instruction for our users so we'll add a

new div and we'll say drop image and then we'll put an S in parenthesis here so drop your images right here and this one let's also a little bit so we'll give it a glass of

cold 12 that way it takes up the whole entire screen I will say BG dark so we give it a nice dark background with some white text so text white rounded corners let's give it some top and bottom

padding of three as well as some margin top and bottom of two that way it gets separated and finally let's go ahead and Center this text so now through all of this we are actually not using this

component so let's jump to the Welcome that blade that PHP file I'll delete all these styles here as we don't really need them but what I do need to do is go ahead and import our compiled file so to

do that let's add a new link and the href is gonna be using mix so we will say slash CSS slash app that CSS again this is all set up stuff level related not quite related to this particular

lesson but it's always good to review all of the steps necessary all right so let me go ahead and clear all of this out I don't need any of it and so inside of here this is where we're actually

gonna use our component so let's go ahead and use example component now this comes registered for us right out of the box so this will really just work but the last thing I do need to do is go

ahead and add a reference to our actual JavaScript file so to do that we'll say script and script will have a source of we could use mix again and we could say alright mix grab our /j s slash app dot

j s and finally because we are using view of course we need to designate this as an ID of app so we'll say ID okay so with any luck this should all be working in Chrome I'll hit refresh and there we

go so we have our drop images here and we are basically done for the JavaScript side of this so let me actually pull open the network tab so notice how there is no network activity right now so

let's go ahead and drop some images in here and let's see what kind of activity we get in the network tab so I actually have some sample images that we can use to drop in this area and checking out

the network tab again I want to show you what it surely does so let me get out a full-screen mode and down here there it is so these are

the sample images that I have to work with they're just simple images you can use any images you can google for some images or take your own images alright so I will drag just the first one and

drop it in there and the first thing you'll notice is we do get a preview as well as how big it is and the name of the file but over here on the network tab we see this images and of course

it's red because level actually said not found HTTP exception so it actually did try to add that image using that post route so let's go ahead and make that actually work so let's take the fastest

path there I'll close everything up and let's open up web dot PHP so we know that we are hitting a post route of slash images and then this needs to go to some sort of controller so let's go

ahead and create and uploads controller and what is the correct action for this well we are going to be storing so let's hit the store method so let's jump back to the terminal and let me open up a new

tab and CD into that same project so it's called image upload and then let's go ahead and run PHP artisan make controller uploads controller and let's go ahead and visit that in phpstorm

so back to PHP uploads controller and let's go ahead and create that store method okay so inside this store method what do we actually need to do well if you actually watch the lesson on how to

upload a single image this is actually going to be very very similar but of course we're going to be handling multiple images so let's go ahead and grab all of our images so how do we do

that reach into the request and then we can use this file method that level provides for us and then all we have to pass in is the key and the key that dropzone actually uses is simply just a

file so this images now contains all the images that were dropped into drop zone and what they are wrapped around is an upload file so let me go ahead and just

die and dump images just to show you what is actually being saved under images because I think it's important for you to see that so I will go ahead and refresh this page so

everything clears out and let me drop that same file back in there and now this time when I go over here we see that we get an error of CSRF token mismatch all right so this is going to

be something that you're going to run into as you're doing a lot of level development so you've got two choices here you can either go ahead and submit a full form where you can actually pass

in a CSRF token or you can use the API instead because we really don't need a CSRF token for this particular example so the easiest fix for this would be to actually go to my web dot PHP file and

grab this route out of here and let's actually put it in the API route so if you ever run into this issue of a CSRF token that's because we're trying to submit really an API call but using the

web so now that we've changed this any routes inside of API as you may know actually get a prefix of API so we're going to have to change our example component and now our address is not

gonna be slash images but it's gonna be slash API slash images okay so with that change let's go ahead and do this one more time I'll grab the same one drop it in and now under images we get this

uploaded file class which is really what we were looking for from the beginning now because our file is wrapped up in this upload file we've got some leverage in terms of how to move the file and

things like that so this is actually something that level does for us out of the box and it makes it very simple to handle file uploads so back in my uploads controller all we really need to

do is grab each one and move them into place now this right here is really going to be returning either a single item or an array of items so what I can actually do is go ahead and wrap the

whole thing in a collection as a side note if you are not familiar with collections definitely check out the whole series that we have here on coders tape in collections they are extremely

powerful you're going to get to see a little bit of that right now so I will actually do the following there's a collection method and that's inside illuminate support

collection notice that it got imported up here at the top and there is a wrap method inside of them and what rap actually does is it will wrap anything that you put in a collection now if that

item is already a collection then it doesn't re rap it it's smart enough to know not to do that but now images is actually a collection and this is gonna allow us to do something like this

collections have special methods and one of them is each and each is very useful whenever you need to iterate through each of the items and perform certain actions so this will accept a callback

and in each one will have a particular image so instead of having a collection of images inside of this callback will actually have one single image and now the fastest path to get this working is

just just simply take our image and then move it and where we're gonna move it to what if we just move it to our public path just straight into the public path we can change this but for now that will

work so let me go ahead and just give it some sort of name here we'll just say ABC and then we need the extension of our file so I know in this particular case is going to be a JPEG file but we

don't know that so how can we possibly get that well because it is wrapped in a file upload class we actually have access to a very cool method which gives us the extension of the file that the

user uploaded so in the case they uploaded a PNG or a JPEG or any other format that we accept this will still work it doesn't matter what the format is and that method is the following so

let's go ahead and put a period at the end of this and then let's go ahead and concatenate the following we'll say image get clients original extension I know that that's quite a big method name

but it really does explain what it actually does it simply returns the original extension that the client provided for us so with that we are basically good to go at this point we've

moved our file into the right place so let me go ahead and open up my public directory and as you see here these are the files that are currently less sit in there so with any luck if we run

chrome now I'll refresh I'll move this file in here and then let's go ahead and go back to phpstorm and now if we come back here it should have appeared here under public we must

have made a mistake here on the code so what it is is oh I see it so one of these parentheses actually have to be right after this so public path is a single and then as a second argument

then we pass that it all right no big deal let's go ahead and try this one more time I'll pull that in and now we'll head back to phpstorm there we go ABC dot jpg was saved and there is our

actual image so just like that technically we are good to go that would work now of course you probably wouldn't want to put them straight into the public path so why don't we create our

own directory now you can create a directory on the fly but I'm going to show you the more dynamic way of doing it the thing about move is that the directory has to already exist you can't

just simply designate a directory name and not have a directory name it will fail so you need to create the directory but then there's another problem if the directory already exists then you can't

create the same directory with the same name that will also give you an error so we actually have to check does this directory exist and then if it doesn't then we create it otherwise we can move

on so we can say that quite simply what have we said if so there is a PHP function called is underscore dir for it is directory but we don't want to find out if it is a directory we want to find

out if it's not so we can negate that with just an exclamation so what is the path that we are looking for well we know we're going to be looking inside public path and how about if we save all

of our images in a subdirectory of images so if that is not a directory then let's go ahead and use mkdir to actually make this directory so we'll go back into our public path and we'll make

that directory now for permissions on this let's go ahead and give it a permission of 0 7 7 7 that way we can save into that same directory that we just created if you don't put that mode

in there you won't have read right access into this new created directory so it's important that you put the mode of zero seven seven seven so now let's go ahead and do the exact same

thing but of course I don't want to just go to slash public path I actually want to go to images all right so let's give that a go now back to Chrome hit refresh one more time we'll drop that image in

back to phpstorm and sure enough now we have this new images directory and inside of there we have ABC dot jpg okay so so far so good but of course what would happen if we put two files right

now well they would have the same name and so they would basically replace each other so that's definitely not what we want to do we don't want a hard code ABC but rather we actually want to have a

unique name now we can't trust a user's name of the actual file as a unique name because well we don't know what they're actually going to name their and the odds of two people naming two

different files the exact same name aren't actually quite high so we don't want to run into any issues with duplicate names because that would replace images so all of a sudden John's

images are the same as Mary's images so we don't want that to happen so to do that let's go ahead and establish a base name so we'll say alright my base name is gonna be we're gonna use STR let's

eliminate support STR random and then let's just go ahead and keep the defaults for random now do note that STR did get imported up here at the top alright so we have a base name and then

to this base name let's go ahead and create our actual name original and this is gonna be the file name that we're going to use so let's start with base name and then we'll go ahead and add the

period so we need a period that way we can actually add the images original client name so this will basically give us a random name with the correct extension so now the second parameter

here we can replace that with simply original alright so let's give that another go hit refresh drop the same image in back to phpstorm now notice that we have a random name

with JPEG and of course our image is still inside so pretty cool so now we're actually uploaded bunch of images and the names won't actually conflict so you may have already been thinking it

doesn't matter how many images we upload if we don't keep track of that in our database then it's gonna be hard for us to create any sort of gallery so let's go ahead and take care of that very

simple to do let's go ahead and create a model and a migration so we'll say PHP artisan make model we'll call it image upload and go ahead and give me a migration at the same time so back to

phpstorm so let's go ahead and find that create image uploads table and let's add a new field here as a string and this is gonna be for original that way we can actually

save the original file name so that'll work for now but as I've done many times before I want to go ahead and turn off mass assignment so we'll say guarded equals an empty array and if you add

this line again that turns off mass assignment because I just want to create a record so right after we move the file let's go ahead and call that image upload and then let's go ahead and

create a new record and the record is gonna be something like original and that's gonna be set equal to original now notice that image upload did get imported up here at the top very

important otherwise it won't find that class all right so let's go ahead and set up a very quick database so to do that I'm gonna use SQLite so we can do touch database directory database dot

SQLite but if you are in Windows this is not gonna work so don't use touch instead you can use something like vim or VI or anything like that we just need to create an empty file called database

dot SQLite inside the database directory so I'll actually use vim and I'm not gonna type anything I'm just gonna hit escape : WQ and now that file is created for us so back in phpstorm the only

thing we need to do is go ahead and change our environment so that instead of using MySQL we're gonna use SQLite and then we'll delete everything else from there and now let's run PHP artisan

migrate and there we go we have a database in place so let me jump over into PHP artisan tinker and right now if we pull open image upload all nothing there

totally empty all right so I'm gonna exit out of that let's go back to Chrome and let's upload our image one more time I'll drop it in there and now let's go back in to tinker again and let's run

the same command and now we do have an image so pretty cool so now we have an original name right here but we know that this is only the name of the file it is still inside our images directory

so I do like to save those sub directories inside the database so simple fix for that all we need to do is make sure that when we save our original we actually do tag on this images so

we'll say images and then original and we will need a slash right there so that way now we have a nice full path that we can use to retrieve these images so this is it I mean this is the basic

implementation of doing that if you wanted to add multiple images at the same time let's go ahead and grab five of these images I'll drop them all in at the same time notice that they all

showed up and now we go back to phpstorm notice that all of my images are there and of course in tinker if we do that one more time we've got all of our images in there so this is it this is

the basic implementation of how to actually get multiple images uploaded at the same time now if you stick around with me for a little longer we're gonna take this to the next level and kind of

turn it into a very simple gallery so let's go ahead and tackle that now the first thing about galleries is of course we're going to need to resize these images we're going to need to create

thumbnails so we can do all that on the fly but we're going to need a special library now the library that I like to use is intervention image library and it is fantastic I've actually talked about

it already during the other image uploading lesson that we did so let's go ahead and just use it again if you want a little bit more review on this particular topic definitely check out

that other lesson because we go into a lot of details of the intervention image package but to pull it in all we need to do is go ahead and run composer require intervention slash image and this is the

de-facto PHP package for image manipulation I think just about everybody uses the same package and now it is complete so let's jump back to phpstorm and so yes we're

going to move our file but before we do that let's go ahead and create a thumbnail so the first thing we're going to need is of course we're gonna need a name for our thumbnail now I do want to

reuse our base name so I will actually copy this line and let's go ahead and call this thumbnail and we'll still use our base name but let's go ahead and slap on underscore some that way the

images get sorted equally but we have this underscore thumb and the original file so we'll have both files in place so to use the image intervention package we're going to go ahead and call image

now this is the one that you want you want intervention image façades so that's the one that you're looking for now that did get imported up here at the top right here so make sure that that

line is up there otherwise again it won't find the image library so using the image library let's go ahead and make an image and so what is the data for our image well of course our actual

image so we can take the entire image and just pass it straight into image so then to create our thumbnail I like to use the method fit now there are literally about 50 or so methods that

you can use but fit will actually crop and resize at the same time it's quite useful for things like thumbnails because you're gonna want to make probably a square image and in this case

we're gonna make a square image that's 250 pixels by 250 pixels now I don't care what aspect ratio my user uploaded I still want it to be a perfect square so fit is perfect for that

so we'll say fit and as a first argument will be the width and as a second argument would be the height so 250 and 250 as I said and then we'll go ahead and save this new image so let's go

ahead and save it to our public path again under slash images slash and then our thumbnail so as you may have noticed we've reused this slash images quite a bit at times so good refactor here would

be to extract this into its own variable a little bit outside of the scope of this particular tutorial but definitely a good thing to note so that way when you're actually doing

for a production code make sure you don't repeat this over and over but rather extract it to its own variable we'll leave it like that for now that way it's really explicit so that's it

now we're gonna make two images whenever we upload so I'll actually do is I will go ahead and delete all of these images from my images directory and then on top of that we now need to save this new

thumbnail into our database so back in the migration we're going to have this original strength but let's also create a new one for thumbnail so now that we have that of course our migration is out

of sync with the database so let's go ahead and flush our entire database right now we can do that by saying PHP artisan migrate fresh so that will drop all the tables and then migrate the

database for us so now we can go back to phpstorm and we need to add that into our actual create function so we're gonna have the original but on top of that of course we're gonna have the

thumbnail so that way they're both saved alright let's give this a go I will hit refresh here I'll throw in two images this time throw both of those in and now let's visit tinker again and then let's

run the same command again and there we go so now we've got our original image and then we've got the thumbnail which has the same file name except that it ends in underscore thumb now let's check

out this file that way you see what fit did for us back to phpstorm open images so we have our original file which looks like this and then we have our thumbnail so our thumbnail is perfectly square and

it's 250 pixels by 250 pixels so it's perfect for us to actually show this as a gallery so let's take care of that right now let's go back to the Welcome and we're going to need our actual

images so up until this point welcome actually gets loaded automatically if we go to the web dot PHP file notice how a view is simply returned out of here but we do have this uploads controller so

what are we reuse all of that so what I'll actually want to do is instead of a call back let's go ahead and use the uploads controller and then let's hit the index method so in my uploads

controller let's add a new function public function index and so we need to fetch all of our images at this point so say images equals image upload but what I want here

is I want them to be in reverse chronological order that way the latest upload is up front so to do that we can call latest and then we can call get so this will get us

all of the images available in our database so then all we need to do is return the same view that's gonna be the welcome view but now we do need to pass in this data we need images to be in

there so let's go ahead and pass in images as a data property so now if we go back to Chrome and we refresh everything should work exactly the same because we haven't made any changes but

now in our welcome view we now have access to all of our images so we can say for each images as image and then we'll say end for each so for each of these images of course I'm going to want

to have an image tag so let me actually wrap all of this inside of a row that way they're nice and grouped together and then each of the images will be a column of two so we'll add a new div

with column of two and this is given some margin bottom of four just to separate them a little bit so inside of here we'll have our image and the source is going to be image thumbnail and then

as a class let's go ahead and just give it a class of width of 100 so with 100 that way it gets resized perfectly to our browser okay back to Chrome hit refresh and there we

go so we have our nice gallery going on let me go ahead and close this so notice that everything is bumped to the left that's because this needs to be wrapped in a container

this is bootstrap stuff nothing to do with this actual project but now you see that our images are inside if we were to upload some more images I'm gonna add this one I'll hit refresh and there we

go so we have our images the nice thing would be if we can click them and view the full resolution file so we could do that by just wrapping all this in another anchor tag so say anchor and

where are we going to go let's just go to image original and then inside of here we'll actually have the image so now we can click on them and sure we can go to each one now of course you

can get super fancy with this and have some sort of modal that way the image doesn't leave the page but again we're focused around just uploading images resizing them and getting them into a

gallery style so this is pretty much working at this stage just as a finishing touch I want to add a delete button I want a way for us to actually delete each of these images now to

delete our images we cannot simply just create a link and the reason for this is because due to restful controllers we actually need to submit a delete request to our server

that way we can reuse that same exact you arrived but to do that we actually need to submit a form so let's go ahead and create a form and the action is going to be to slash emerges and then

the method is going to be post but we're going to override that because we actually want the method to be a delete request so if you've been around kotor state long enough you know at this stage

that you can only submit and get or post requests so a delete request actually needs to be faked it's not part of the spec so we're gonna actually submit a post request but if we add this method

of delete in that case letter what's gonna know that this is a delete request the other thing we're going to need is of course a CSRF token because we're not hitting that API so let's go ahead and

use that CSRF token and then let's add a button my button will say delete and for classes on this one as you say it's small it's gonna be a button with a button outline of danger all right let's

see what that looks like there we go yeah it's gonna need a little bit of margin let's try margin top two there we go so when we hit our button of course I want to delete the image but I also want

to delete the thumbnail the original and everything from our database so it is a little bit more involved in just deleting the record from the database so whenever this happens of course we're

going to need that route so back in my web dot PHP I'll create a new delete route for slash images and this is gonna hit the uploads controller at the destroy method alright so let's go to

the uploads controller and then down here at the very end I actually don't want to die and dump that anymore that's from a previous section go ahead and delete that and let's add a new

public function here for destroy so how do we destroy all of this well it would be a lot simpler if we actually had our image which we can so let me show you how instead of just hitting slash images

let's actually hit slash images slash and then the ID that we're trying to delete so we can grab that by saying image ID and then on top of that in our routes of course we are not just slash

images but we are slash images and then in curly brackets we'll say image upload this is route model binding it's one of those magical things with level that I use all the time so now simply by type

hinting image upload in our controller Lehrer will actually give us the instance of image upload so we'll go into the database and fetch the correct image upload for us and give it to us

right inside this we don't have to fetch anything it's all done for us magically pretty awesome stuff so now what do we need to do in here sometimes when I'm not sure exactly how

the code is gonna go a good place to go is to go ahead and add comments for each of the steps that you need to do so the first step is we know we need to delete the files write both the original and

the thumbnail then we know we're going to need to delete the record from the database and lastly we're gonna need to redirect we need to send the user back somewhere so the redirect part that's

actually quite simple because all we need to do is return a redirect and let's just send them back to our home page so this will actually work at this point if we hit refresh

here and I just hit delete notice that it actually goes but it comes right back because of course we're not deleting the record but at least we know that that last step is done that's the easy one so

how do we delete the files well we can use the file facade so we'll say file that's going to be under illuminate support facades and make sure that that gets imported up here at the top and

here it is make sure you add that line to your code otherwise file will not be found so we add that line and then we can say delete and to delete we can actually pass an array of files

that we're looking to delete we're luckily for us we can use public path again and then the first public path is going to be image upload at original and then the same thing but it's gonna be

thumbnail okay so that takes care of our files and finally we need to delete the record from the database so that's simple enough as well we just say image upload delete and that would

delete that record from the database so alright so take a look down here obviously we have six images three originals and three thumbnails so let me go into Chrome and I will delete this

last one right here I'll hit the delete button notice that it went completely away and then if we check back to phpstorm now we're down to just four images let's go ahead and delete another

one and if we come back here we're down to just the thumbnail and the original file but of course all the other functionality still works let me bring in a couple more images bring all these

drop them in there so we have all of these images now if we check back with phpstorm check out the list over here everything's working and of course we can delete and then we can click on one

image and actually check out the full resolution image so that's it that's going to complete this lesson I know it's a little bit lengthy but good job sticking around because now you know

exactly how to make a gallery from scratch using view and levo great job I'll catch you on the next one

As one of the most requested tutorials, in this lesson, we are tackling an example of multiple image uploads. We will also resize them to generate thumbnails and build a very basic image gallery where you can preview the full resolution images.

For the best experience, follow along in our interactive school at https://www.coderstape.com

Other Related Video

DigitalOcean Referral
https://m.do.co/c/7dce5364ef4d

Hit us up on Twitter with any questions or comments @codertape (https://twitter.com/CodersTape)

About This Course

Ready to get started on your path to Laravel Artisan? In this series, we are breaking down all of the basics of Laravel to get you comfortable using the world’s most popular PHP framework. Let’s get started!

    add to database laravel admin laravel artisan Artisan Command artisan commend create artisan console artisan laravel command authentication in laravel belongsto belongsto laravel example coding tutorials create artisan command create command artisan create new command artisan Create your own crud laravel crud laravel tutorial crud resource laravel crud with file upload custom artisan commands custom artisan commands laravel custom laravel database configuration laravel database relationship digital ocean dotenv eager loading eager loading in laravel eager loading vs lazy loading laravel eloquent eloquent accessors eloquent mutators eloquent orm feature testing laravel fetching data in laravel filesystem laravel form requests full stack vue gate and policy laravel google optimize hasmany hasmany laravel hasmany laravel example hasmany relationship in laravel hasone hasone relationship in laravel How to create how to queue email how to use queue installing laravel intervention image laravel laravel 5 laravel 5 auth laravel 5.4 queue laravel 5.5 queue laravel 5.8 laravel 5.8 artisan command laravel 5.8 artisan console laravel 5.8 auth tutorial laravel 5.8 authentication laravel 5.8 commands laravel 5.8 crud laravel 5.8 crud example laravel 5.8 custom middleware laravel 5.8 deprecations laravel 5.8 eager loading laravel 5.8 elixir laravel 5.8 event listeners laravel 5.8 events laravel 5.8 feature laravel 5.8 features laravel 5.8 global middleware laravel 5.8 install laravel 5.8 lazy loading laravel 5.8 listeners laravel 5.8 middleware laravel 5.8 multi auth laravel 5.8 named resource routes laravel 5.8 named routes laravel 5.8 new feature laravel 5.8 own artisan command laravel 5.8 queue laravel 5.8 queues laravel 5.8 routing laravel 5.8 telescope laravel 5.8 tutorial laravel 5.8 user auth laravel 5.8 user authentication laravel 5.8 what's new laravel 5.9 laravel admin permissions laravel api laravel artisan command laravel artisan console laravel assets laravel auth laravel auth role laravel authentication laravel authorization laravel axios post example laravel background process laravel background task laravel background worker laravel beginner to master laravel belongsto laravel belongsto vs hasone laravel belongstomany laravel best packages laravel best practices laravel best tutorial laravel bootstrap laravel command laravel command line laravel commands tutorial laravel composer install laravel connect db laravel console command laravel console testing laravel contact form send email laravel controllers laravel create laravel crud laravel crud policy laravel custom command laravel custom middleware laravel database laravel database configuration laravel database relationships laravel database seeder laravel database settings laravel db seed laravel db settings laravel debugging laravel deploy aws laravel deploy digital ocean laravel deploy on digitalocean laravel deploy on server laravel deploy to production laravel deployment laravel digitalocean laravel drag and drop file upload laravel dropzone file upload laravel dropzone image upload laravel e-commerce laravel eager loading laravel eager loading tutorial laravel eager loading with condition laravel elixir laravel eloquent laravel eloquent belongsto laravel eloquent crud laravel eloquent hasmany laravel eloquent where laravel eloquest tutorial laravel events and queue laravel events tutorial laravel factory laravel feature test laravel feature testing laravel fetching data from database laravel file storage laravel fillable example laravel flash message notification laravel for beginners laravel form validation laravel forms laravel forms bootstrap snippets laravel from scratch laravel from the ground up laravel front end laravel frontend tutorial laravel gate and policy tutorial laravel global middleware laravel hasmany laravel hasone laravel i18n laravel installation laravel installation mac laravel intervention image tutorial laravel javascript tutorial laravel jobs queue laravel language laravel language switcher laravel language tutorial laravel languages laravel lazy loading laravel listener event laravel listeners laravel localization laravel login laravel mailable tutorial laravel many to many relationship example laravel markdown email laravel markdown mail laravel mass assignment laravel middleware laravel migrate fresh laravel mix laravel mix 5.8 laravel mix vue laravel model factory tutorial laravel multiple language laravel mysql json laravel named resource routes laravel named routes laravel new features laravel news laravel nginx laravel node modules laravel npm install laravel npm run watch error laravel one to one laravel paginate laravel paginate link laravel pagination laravel pagination 5.8 laravel pagination links laravel pagination tutorial laravel phpunit laravel phpunit testing laravel pivot table example laravel policy laravel preview laravel query optimization laravel queue laravel queue event listener laravel react laravel register user laravel registration laravel registration validation laravel relationships laravel reset password laravel role middleware laravel role permission laravel roles laravel route group middleware laravel routes laravel routing laravel routing with parameters laravel sass laravel save file to database laravel scopes laravel seo tutorial laravel server laravel session data laravel ssl laravel supervisor laravel tailwind css laravel tailwind setup laravel tdd laravel tdd tutorial laravel telescope laravel telescope installation laravel telescope tutorial laravel test driven development laravel test workflow laravel testing laravel testing controllers laravel testing tutorial laravel tools laravel translation laravel tutorial laravel tutorial for beginners laravel ubuntu server laravel ubuntu tutorial laravel unit testing controllers laravel upload file laravel upload image to storage laravel upload multiple files at once laravel upload multiple image to database laravel upload multiple images laravel url slug laravel vue laravel vue js crud laravel vue setup laravel vue tutorial laravel vue.js laravel webpack error laravel webpack tutorial lazy loading lazy loading laravel lazy loading vs eager loading learn laravel learn laravel framework step by step localization in laravel localization laravel many to many laravel mvc tutorial for beginners in php mvc tutorial laravel mysql mysql relational database mysql relationship n + 1 problem n + 1 problem laravel new artisan command npm install npm run dev npm run watch laravel one to many one to one one to one laravel own artisan command pagination pagination bootstrap pagination bootstrap php mysql pagination laravel pagination laravel bootstrap pagination links pagination php php php artisan php carbon immutable php framework php framework 2019 php what's new 2019 phpunit phpunit laravel phpunit testing pivot laravel policy laravel polymorphic relationships queue and events queue email queue for laravel queue jobs queue laravel 5.8 registration form relationship laravel eloquent relationship mysql restful controller role permission in laravel roles laravel route model binding laravel routing in laravel save image to database seo friendly seo friendly content writing seo friendly website seo laravel seo optimization simple pagination laravel slugify sqlite relational database sqlite relationships between tables symfony command console symfony laravel tailwind css tailwind laravel mix telescope laravel tutorial laravel unit testing unit testing laravel upload file laravel upload file php upload image laravel upload image to database php upload images laravel upload multiple files in php url slug laravel url slug php vue vue.js vuejs laravel why use laravel queue why use queue