Publishing videos
Transcript was automatically generated and may be inaccurate.
-
–
We now want to be able to publish and un-publish videos. -
–
To achieve this, we'll add a new "status" column in the switch component to our -
–
videos listing table. -
–
In our video index view, let's add a new column for "status". -
–
And for each video, we will display a switch toggle to update the status of the video -
–
to publish and un-published. -
–
You can find a link for the mark-up for the component in the video resources. -
–
Pause the video now if you need to grab this. -
–
Copy the switch component mark-up and paste it into the "videos" table. -
–
Now if we take a look at the component, we can see it's just a simple Alpine.js -
–
component with a single "checked" property, -
–
which just toggles its value when the switch is checked. -
–
This isn't very helpful as it's not actually updating the video status. -
–
So let's flesh out this component. -
–
Open up your app.js file. -
–
We're going to create a new component called "updateVideoStatus". -
–
We'll define that "checked" property. -
–
But we're also going to specify some initial arguments the component needs. -
–
The "initialChecked" value. -
–
And the URL we should use to update the video status. -
–
When the switch is toggled, we want to update the video. -
–
If the switch's checked value is "true", that means the video is published and we -
–
want to make a request to un-publish it. -
–
If the checked value is "false", that means the video is not currently published -
–
and we want to publish it. -
–
On the button element, change the click handler. -
–
Instead of just simply toggling the checked property's value, we want to create -
–
a new "toggle" method. -
–
We should also change the component's x-data value to the name of the component -
–
we've just defined, which is "updateVideoStatus". -
–
Back in our app.js file. -
–
Let's create that "toggle" method. -
–
Before we continue, if we look at our Video model and "videos" table in the -
–
database, -
–
we'll see that we don't actually have a way of indicating if the video is -
–
published or not. -
–
We could add a simple "is_published" boolean column, but a better method is to -
–
instead store a timestamp of when the video was published. -
–
This is a approach Laravel uses itself. -
–
For example, specifying a "deleted_at" column instead of just "is_deleted" for -
–
soft deletes. -
–
It would also enable functionality such as a user being able to sort videos by -
–
published time and date, for example. -
–
We'll need to create a migration to modify our "videos" table. -
–
Create a new migration. -
–
Name it "add published at column to videos table". -
–
Let's set the "--table" argument to "videos". -
–
This just automatically sets the table argument to "videos" in the migration -
–
itself. -
–
In the "up" method, we want to create a new timestamp column called "published_at". -
–
It should be nullable by default. -
–
In the "down" method, we can just drop this column. -
–
Open our Video model. -
–
We now want to add this "published_at" column to our "fillable" array. -
–
And we also want to cast it as a "datetime". -
–
Since we've updated our database schema, we now need to migrate. -
–
In the terminal window, run "sail artisan migrate". -
–
We'll now create a new controller to handle the publishing and un-publishing of -
–
videos. -
–
Create a new singleton controller. -
–
And we'll call it "Admin\VideoPublishController". -
–
We can also set the parent to the Video model. -
–
Open it up. -
–
And remove all actions except the "store" action. -
–
And the "destroy" action. -
–
We can also remove this. -
–
We're going to use POST requests to the "store" action to publish the video and -
–
DELETE requests to the "destroy" action to un-publish the video. -
–
Open up your routes/web.php file. -
–
And we need to register the routes for that singleton resource. -
–
We add the "creatable" method as well to register a POST route as by default -
–
singleton resources don't register routes for creation of new singleton -
–
resources. -
–
If we run the route:list command, -
–
we should now see two new routes for publishing and un-publishing in videos. -
–
In our VideoPublishController, we simply want to set the "published_at" -
–
attribute of the Video model to the current date and time in the "store" action -
–
and set it to null in the "destroy" action. -
–
So let's do that. -
–
Go back to your app.js file. -
–
Let's make an Axios request in the "toggle" method we just created. -
–
[typing sounds] -
–
In the then callback, we don't need to do anything. In the catch callback, we -
–
need to reset the "checked" value back to the previous value if there was an -
–
error publishing or un-publishing in the video, and we can also display a -
–
JavaScript alert. -
–
We need to go back to our video index view and add the initial arguments for -
–
our component. -
–
By default we have two: we have the videos current published status and the URL -
–
for updating the video. -
–
[typing sounds] -
–
For the first argument, we check if the video's "published_at" attribute is not null. -
–
If it's not null, it means the video is published and "checked" should be true. -
–
For the second argument, we'll set it to the published store route. -
–
Let's go back to our VideoPublishController and update the return types of -
–
these methods. -
–
[typing sounds] -
–
Back in the browser, if we toggle a couple of these, we should see that they're -
–
now working. -
–
If we look in the database, we should see that some rows have "published_at" -
–
values now. -
–
This is all well and good, but we actually have an issue here. -
–
At the moment, we're currently able to publish videos that are in the process -
–
of being uploaded or that aren't ready yet. -
–
To fix this, we can add a guard to the "store" method in our VideoPublishController -
–
that aborts the request if the video is not ready for publishing. -
–
To be published, a video needs to meet the following criteria: it needs to have -
–
a description, the "upload_status" needs to be "complete", and the "mux_status" -
–
needs to be "ready". -
–
We can add a method to our Video model encapsulating this criteria. -
–
Open up your Video model and define a new "canBePublished" method that's -
–
going to return a boolean. -
–
In this method, we're simply going to return a boolean result of the above -
–
expression. -
–
[typing sounds] -
–
This method will return true if there's a description, if the "upload_status" -
–
equals "complete", and the "mux_status" equals "ready". -
–
If any of these are false, then the method will return false as well. Back in -
–
our publish controller, we can abort the request if that method returns false. -
–
[typing sounds] -
–
If the video cannot be published, then a 400 Bad Request response will be -
–
returned instead of the model being updated. -
–
We can test this in the browser by finding the video whose "upload_status" isn't -
–
"complete". If you try to publish, say, this video, we now get an error message -
–
and the toggle should go back to "off". -
–
And there we have it. We now have simple administration panel where we can -
–
upload videos, list videos, edit video details, and publish or un-publish -
–
videos. -
–
Now that we can actually publish videos, we'll look at displaying them in the -
–
front end of our application, and also playing uploaded videos in the browser.