Console application

In Chapter 2, Making a Custom Application with Yii 2, we set up the entity we called console runner in the form of the PHP script called yii in the root of the code base and skipped the explanations about what it really is. Starting then, we extensively used two particular command-line invocations, which used the scripts ./yii migrate/create and ./yii migrate. Also, we used the ./yii asset invocations in Chapter 8, Overall Behavior, to prepare our compiled assets. Now it's time to explain the value and possibilities of this entity.

Apart from the yiiwebApplication class, which represents the web application we were building in the previous 11 chapters (Chapter 1, Getting Started, was excluded), the Yii 2 framework includes the yiiconsoleApplication class, which represents the console application. This kind of application conceptually is exactly the same as a web application in the sense that it is a module supporting MVC, too. Specifics of the console application lie in the fact that it must render the results of its work to the console, and it needs to receive input parameters from the command line. Apart from that, the console application uses the same concept of controllers (which should be descendants of the yiiconsoleController, though) and is configured and created in the same way, which is obvious when you compare the contents of the yii and web/index.php scripts.

In essence, to reach the controller action using the console application, you make the following command-line invocation:

./yii controllerid/actionid param1value param2value --property1=value1

The details should be read from the framework documentation (http://www.yiiframework.com/doc-2.0/guide-tutorial-console.html). Note that the controller action parameters are passed as unnamed command-line arguments, and the values for controller properties are passed as named ones.

Unless you are exactly making the console application using the Yii framework, it's hard to justify the need to group the console controllers using modules. However, as the console application is still a module and uses the same routing mechanics as a web application, you can use the /moduleid/.../moduleid/controllerid/actionid routes as well.

As talking about console controllers is somewhat cumbersome, we'll refer to them as console commands, as Yii 1.x did, but what we really mean is the controller classes inheriting yiiconsoleController. You get the set of console commands built into the framework, like yiiconsolecontrollersMigrateController. They are listed in the yiiconsoleApplication::coreCommands() method, and you are encouraged to read through their classes' documentation. These commands are always accessible from the console application unless you override this method (and why should you do it at all?). We will not discuss them in detail as apart from the migrate and asset commands, all other are somewhat too specific.

You can declare and use custom properties on the console controllers. How to pass values to them at the time of calling a controller action will be discussed in the next section. How to set up values for them in the console application configuration will be explained in the next major section, which will deal with the database migrations specifically.

Custom console commands

Let's make some custom console command. We'll do a little hacking for developers to be able to custom-craft the user records directly in the database.

As you remember from Chapter 5, User Authentication, we store user passwords hashed using the Yii framework built-in helper classes. This hinders the ability of developers to make the user records manually using direct access to the database. As we can imagine and use some plaintext password easily, we need to store it in database hashed, and this hash needs to be computed somehow, which is basically impossible to do with pen and paper. More than that, we don't want to know exactly which methods of hashing were used at all.

So, let's make the console command which, given some string, computes and shows its hashed value in the same way our appmodelsuserUserRecord::beforeSave() method does.

As console controllers are controller classes, the Yii framework requires them all to be in the same directory. We arbitrarily decided that it was going to be the commands subdirectory under the root of the code base. According to PSR-4 rules and Yii framework conventions, this directory represents the appcommands namespace; so let's wire this namespace to our console application right now. Open the config/overrides/console_base.php file, and insert the controllerNamespace setting there:

return [
    'id' => 'crmapp-console',
    'controllerNamespace' => 'appcommands',
];

Let our new command be named hash, so it will be invocable by the ./yii hash command. We need the HashController class, the Controller suffix being mandatory, inside the commands directory, with the following boilerplate code in it:

namespace appcommands;
use yiiconsoleController;
class HashController extends Controller
{
    public function actionIndex()
    {
        // don't know what to do yet
    }
}

You should already know how to declare new controllers, so the namespace and use clauses are most important pieces here. It's really important that we remember that we create the console controller and not a web one, as they run actions differently. The default action is index, as in web controllers.

Instead of using the echo PHP built-in to output to the console, we'll utilize the yiihelpersConsole helper class from the Yii 2 framework. It has the output() method that will handle the newlines automatically, as appending them each time always was a hassle. Here is what we need to insert in order to satisfy our needs:

    public function actionIndex($string)
    {
        yiihelpersConsole::output(Yii::$app->security->generatePasswordHash($string));    }

The call to Security::generatePasswordHash() is exactly how we generate hash for the passwords inside our user records. Here is what you should get after calling ./yii hash 1234, to see the hash of a really dumb user password:

Custom console commands

You can also call this command ./yii hash/index 1234. The hash will be different, of course, but it will be the same action being run nevertheless.

Note that the arguments of the controller action are passed as unnamed command-line arguments. This means, among other things, that you should pass strings containing special characters enclosed in quotes to the console commands of Yii. To help visualize what we are really hashing, let's output the string to be hashed as well. However, it's pretty nice that our initial command conforms to the Unix way of doing things of our initial command (that is, the fact that it emits results directly to standard output without any additional information). We'll utilize the built-in flag of the console controller to check whether we really need to output this additional data. Add the following two lines at the beginning of the actionIndex() method:

        if ($this->interactive)
            Console::output(sprintf('Input string was: %s', $string));

The $this->interactive property being referenced is the yiiconsoleController::$interactive one, available in all console commands. As was said before, you can set the values of such properties using named parameters. In our case, this means we need to pass --interactive=0 to the ./yii hash 1234 call to suppress the debug output. Otherwise, we'll get a helpful reminder:

Custom console commands

This will help to resolve silly mistakes when handcrafting reasonably complex passwords, as otherwise you would not know what you are really hashing. Note which string was passed to our controller action in the first case, when we haven't escaped the input string.

To pass false to the controller properties, use any string that parses to the false-like value, like empty string or zero. The string null or false will be treated as a non-empty string and as such will be treated as a true Boolean value. So --interactive=false will not work as intended, but --interactive= will.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.139.169