In the previous chapter, we have created a script, that can download all the photos from any Tumblr blog. But it is not very convenient to use.
The path to a folder for saved photos and the blog itself are hardcoded in the index.php file. It will be more usefulto use this script as
a console app and pass the blog with the folder for saving files as the params to it:
Create An Entry Point
It can be done with the help of the Symfony Components. There is a bunch of different usefulcomponents, but
we need only one of them: Console component.
In the next step, we need to create an executable php script. For this purpose let’s create a file tumblr-downloaderwithout any extension with the following content:
This file should be in the root folder of our project, not in the src directory. It will be the enter point to our application. Lets make it executable and then run it:
Now our console application entry point is ready.
Next step is to create a command for grabbing photos. Let’s create a class SaveCommand in the src folder. To use it as a command
we need it to extend Symfony’s Console Component Command class. Command class basically has two methods: config to set some
command settings and execute to process the entire logic:
First of all we configure out command. We set its name and description, then we add a required argument blog to it.
Next we implement execute method. Now it is very simple, and does nothing useful. Now it is used only to check, if
our command works fine and recieves an argument.
Then we need to add our SaveCommand to the console application in the tumblr-downloader file:
Now, if we run it, we will see the following output:
It means that our command works fine and it is time to implement the main saving logic. Our application logic is implemented in the
Downloader class, so we need to get access to it in out command. To achieve this, we use dependency injection via constructor:
We build an instance of the Downloader class like we did it in the previous chapter and then pass as an argument to the
SaveCommand constructor. To make it work, we also need to modify SaveCommand itself. We change the constructor
to get an instance of the Downloader class and save it then protected property $downloader. Then in the execute method
we use it and call its photos method with the passed to our command argument blog:
Let’s try it:
Now out command is almost ready. We can add one more feature to it, to make it more convenient in use - progress bar. And again we will
use one of the Symfony Console Components called Progress Bar.
To show a progress bar we need to know the total amount of posts. So we need to add a method to Downloader class, that returns total number of
posts of a blog:
We use already familiar method getBlogPosts to get total posts with photos. Then we need to modify Downloader class and add support to call
a closure on every saved post. We will use this closure to output the progress:
$progressCallback can be a closure. An it accepts current saving post as an arguent.
When we are ready with Downloader class, then we need to instantiate an instance of the ProgressBar and create a closure to pass it to the Downloader.
It can be done in the execute method of our SaveCommand:
And that is all. Now our console command looks much better. It accepts blog name as an argument and outputs a process of the downloading photos.
At last we can add a counter for saved photos. And after saving has been completed, we can show the total number of the saved photos:
The final output of our command in action:
@ 2018. All rights reserved.
If you've got any feedback, comments or just want to chat you can get in
touch via Twitter or email.