Table of Contents
The ConsoleTools component provides several useful tools to build applications that run on a computer console (sometimes also called shell or command line). For example, eZ Publish includes several shell scripts that perform tasks like clearing caches.
From version 1.5.2 on, all necessary string operations in ConsoleTools are performed using ext/iconv. This makes the component binary safe and allows you to use arbitrary unicode characters in your texts. Please make sure to convert your text to UTF-8 before submitting it to a method in ConsoleTools, if you use a different, non ASCII-compatible encoding.
The ConsoleTools component offers several (mostly independent) classes to perform different tasks. The main classes are:
As mentioned, the class ezcConsoleOutput is used to print text to the console. Let's look at a basic example:
The ezcConsoleOutput object is simply instantiated. You can optionally submit options and predefined formatting options to its constructor, but this can also be done later.
In line 7, you can see how format is defined. Formats are created on the fly, as soon as you access them (for reading or writing) through the $output->formats attribute. There, we create a format called "info" and assign the color value "blue" to it. This will make all text printed with this format blue. In line 9, you can see how the format is applied to some text at printing time.
The second example shows some more advanced code:
In this example, two more formats are defined: "error" and "fatal". These formats have an additional style attribute set, which makes them both appear bold. The "fatal" format will also underline the text and give it a black background color.
The difference between ezcConsoleOutput->outputText() and ezcConsoleOutput->outputLine() is that the latter automatically adds a newline value to your text. The newline sequence used here is adjusted based on the operating system. The use of ezcConsoleOutput->outputLine() is recommended over the direct output of, for example, "n".
If you leave the second parameter of ezcConsoleOutput::outputText() and ezcConsoleOutput::outputLine() out, the "default" format is used. The default is set to your console's default setting, but you can also change this as for any other format you define. A third variant to format text is ezcConsoleOutput->formatText(), which returns the formatted string instead of printing it.
This example shows some of the options ezcConsoleOutput supports:
In our example, the call on line 23 would not print out text with the "verbosityLevel" option set to 3, but the call on line 25 would.
The last example shows how to change the target of a format, which allows you to print text e.g. to STDERR.
The error message 'Unable to connect to database' will be printed in bold, with a red foreground color to STDOUT. The default target is ezcConsoleOutput::TARGET_OUTPUT, which prints to STDOUT and has standar output buffering in place. If you want to switch out the standard output bufferung, use ezcConsoleOutput::TARGET_STDOUT.
Although this feature was originally not designed for that purpose, you can also use any other arbitrary PHP stream definition as a target. For example 'file:///var/log/my.log' to get the messages redirected to a log file instead of displaying them.
Below is a simple example for ezcConsoleInput:
After instantiating a new ezcConsoleInput object to handle the options, an option is registered on lines 7-12. This option will be available as "-h" and "--help". The ezcConsoleInput->process() call makes ezcConsoleInput respond to the options submitted by the user. If any error occurs with the submitted user data, the method will throw an exception of type ezcConsoleOptionException. By default, all options are registered with the value type ezcConsoleInput::TYPE_NONE, which indicates that they don't expect a value from the user. If a value is submitted anyway, ezcConsoleInput->process() will throw a ezcConsoleOptionTypeViolationException.
On line 23, a check is performed to see whether an option was submitted. If an option was not submitted, its $value property will contain bool false. Depending on the $type set, it can contain different value types if it was submitted. If you use the (not shown here) ezcConsoleOption->$multiple property, the value will be an array containing the specified value types.
The next example is more advanced:
Two options are registered here: "-i" / "--input" and "-o" / "--output". For the first one, additional properties for the ezcConsoleOption object are submitted through the constructor. For the second ezcConsoleOption object, you see how to provide additional properties after construction. We change the type of both options to expect a string value from the user (lines 13 and 20).
In lines 25 and 28 we make both parameters depend on each other. If one of them is submitted without the other, ezcConsoleInput->process() will throw an ezcConsoleOptionDependencyViolationException. Aside from dependency rules, you can also define exclusion rules using ezcConsoleOption->addExclusion().
On line 43, the method ezcConsoleInput->getSynopsis() is used to retrieve a synopsis string for the program. The synopsis for our example would look like this:
$ ./tutorial_example_05_input_advanced.php [-h] [-i <string> [-o <string>] ] [[--] <args>]
The synopsis will indicate the option value types, whether they are optional, the inter-option dependencies and default values (if set). On line 46, the property ezcConsoleOption->$shorthelp is accessed, where you can store some short help information. It has a reasonable default value set.
On line 49, the submission of the "-o" option is checked. Because this has a dependency on the "-i" option, a check for that is not necessary. Line 52 shows how you can access the arguments submitted to the program. ezcConsoleInput->getArguments() always returns an array (which is empty if no arguments are submitted). A more advanced way of handling arguments is explained further below.
Here is an example of how the defined program would be called:
$ ./tutorial_example_05_input_advanced.php -i /var/www -o /tmp foo bar
The program would respond by printing the following:
Input: /var/www, Output: /tmp Arguments: foo, bar
As you can see, this example does not define, which arguments are expected and therefore, the program simply accepts any number of arguments and provides them through the ezcConsoleInput->getArguments() method. The following example shows, how specific arguments can be defined:
As seen before, a help option is registered. In addition, 3 arguments are registered: The first one with the name "source" is a standard argument. It is mandatory for the user to submit a value here. The second argument, "destination" is optional and a default value is assigned, which will be used, if the user does not provide a value for it.
The third one ("iterations") is not of type string, but an integer. Because the second argument is optional, this third one is automatically optional, too. Since no default value is assigned, it will be null, if the user does not submit it. If a value is provided, it must be an integer.
Argument definitions are processed as usual inside the ezcConsoleInput->process() method, but will throw an ezcConsoleArgumentException if something goes wrong. If desired, exceptions about options and arguments can be caught together using ezcConsoleException or be handled on their own.
The value of an argument can be fetched from its definition, using its value property. As can be seen at the very end of the example, for reading purpose, arguments can be accessed by their name. This does not work for writing purpose, since a specific order must be given there.
If the --help option is set, mandatory arguments don't need to be submitted and are silently ignored. The help text generated by ezcConsoleInput for this example looks like this:
Usage: $ tutorial_example_12_input_arguments.php [-h] [--] <string:source> [<string:destination>] [<int:iterations>] A simple text program -h / --help No help available. Arguments: <string:source> The source directory. <string:destination> No help available. <int:iterations> Number of iterations.
For further information, please refer to the API documentation of ezcConsoleInput.
This example defines a simple progress bar:
The created progressbar will count to a maximum value of 15, submitted to ezcConsoleProgressbar->__construct() in line 7. ezcConsoleProgressbar utilizes ezcConsoleOutput to print the generated progress bar. The call to ezcConsoleProgressbar->advance() pushes the progress bar one step further on each call and redraws it (line 11). Calling ezcConsoleProgressbar->finish() will set the progress bar to 100% immediately.
The progress bar generated by the example will look like this:
The next example performs more customization on the progress bar appearance:
The defined options array demonstrates only a small subset of options. For detailed information, see the API documentation on ezcConsoleProgressbarOptions. The "emptyChar" value defines the character to prefill the bar, the "barChar" option defines the character to fill the bar with when calling ezcConsoleProgressbar->advance(). Using the "formatString" option, you define the appearance of the whole bar. Here the substitution of several placeholders (like "%fraction%" and "%bar%") is permitted. "formatString" must contain the "%bar%" placeholder, while all other values are optional. Any other printable character is permitted. Formatting options are allowed in the "formatString" option, but not in any other option. "redrawFrequency" defines how often the progressbar will be redrawn. In the example this will be every 50th call to ezcConsoleProgressbar->advance().
The resulting progress bar looks like this:
With ezcConsoleStatusbar, you can indicate the progress of a time-consuming action in a simpler way. Here is an example:
This variant of indicating progress only displays success or failure indicators for an action and allows you to run any number of actions, without specifying in advance how many you will perform. The "successChar" and "failureChar" options indicate which string to print on a successful or failed action. Lines 11 and 12 format these strings.
Indicating a status is done using ezcConsoleStatusbar->add(), which expects true for a succeeded action and false for a failed one (line 20). You can access the number of successes and failures through ezcConsoleStatusbar->getSuccessCount() and ezcConsoleStatusbar->getFailureCount(). To make ezcConsoleStatusbar wrap a line after a certain amount of statuses, you can use ezcConsoleOutput->$autobreak.
Here the result of the example:
Finally, ezcConsoleProgressMonitor can indicate progress, but does not use a bar-like interface. It simply prints status information about each action you perform and shows the current progress as a percentage value in relation to the number of actions you plan to perform overall.
Line 7 creates a new status indicator, which will iterate over 7 actions. Inside the while loop, we simulate some actions. The call to $status->addEntry() adds a status entry and causes the indicator to print the entry. Every entry consists of a tag (first parameter) and a message.
The result of the example is as follows:
14.3% ACTION Performed action #1. 28.6% ACTION Performed action #2. 42.9% ACTION Performed action #3. 57.1% ACTION Performed action #4. 71.4% ACTION Performed action #5. 85.7% ACTION Performed action #6. 100.0% ACTION Performed action #7.
This is the result of a table generated by ezcConsoleTable:
Here is its corresponding source code:
ezcConsoleTable (like ezcConsoleStatusbar and ezcConsoleProgressbar) uses the ezcConsoleOutput class to print to the console. To create a table, you just need to submit the maximum width of the table to its constructor: ezcConsoleTable->__construct(). Options for table formatting are inherited from the table itself to the table rows and from there to the table cells. On each inheritance level, options can be overridden individually. The "defaultBorderFormat" option sets the global format value for all borders (line 24). This is overridden in line 26 for the first row of the table.
Table rows are accessed like an array in PHP (this is achieved by implementing the ArrayAccess interface from SPL). ezcConsoleTable implements the Iterator interface (SPL, too) to allow iteration over table rows using foreach. Each table row is represented by an object of type ezcConsoleTableRow, which also implements the ArrayAccess and Iterator interfaces to access cells contained in the rows in the same way. Each of the named classes allows the access of its properties as usual, in addition to access to its contained objects through the array interface.
ezcConsoleTableRow and ezcConsoleTableCell have a $format setting to define the format of the contained text. All cells (as described above) will inherit the setting of their parent ezcConsoleTableRow, as long as this has not been explicitly overridden. The same applies to ezcConsoleTableRow->$align and ezcConsoleTableCell->$align. Possible align values are:
The content of a cell is stored in the ezcConsoleTableCell->$content property (line 34). The usage of formatted text in a cell is possible, but not recommended. If you want to define the format of cell content, use the ezcConsoleTableCell->$format property.
Below is a more advanced (but in a way useless) example to show the handling of tables:
The "corner", "lineHorizontal" and "lineVertical" options define which characters to use for the borders of the table. These options must be exactly one character long and cannot contain formatting information. To style the borders, use the ezcConsoleTable->$defaultBorderFormat and ezcConsoleTableRow->$borderFormat properties.
The random format and alignment options selected above create the following table:
Implementations of the interface ezcConsoleDialog are generic building blocks, which allow to interact with the user of a shell application using STDIN. A dialog is initialized, displayed and will return a value provided by the user. What exactly happens inside a specific dialog may vary. Commonly, the dialog validates and possibly manipulates the provided value before returning it.
The most basic dialog is the ezcConsoleQuestionDialog, which prints out some text and retrieves a single value back.
Every dialog expects an instance of ezcConsoleOutput which is used to display it. The question dialog here will display the text "Do you want to proceed?" and expects an answer from the user. The $showResults option indicates, that the possible values the user may provide will be indicated, as well as the default value, if one is set.
The mechanism for validating the answer is defined by an instance of ezcConsoleQuestionDialogValidator. In the example, a collection validator is used, which defines a collection of valid values. Beside that, it performs a case conversion on the user provided result before validating it, if desired.
Displaying a dialog can either be done directly, by calling ezcConsoleDialog->display(), or the more convenient way, shown in the example. The ezcConsoleDialogViewer::displayDialog() method displays the dialog in a loop, until the user provided a valid value, so that the program can rely on this. In the example, the user is asked after every performed action, if he still wants to proceed. If the answer is "n" or "N", the program stops.
An example run of this application could look like this:
Some action performed... Do you want to proceed? (y/n) [y] y Some action performed... Do you want to proceed? (y/n) [y] Some action performed... Do you want to proceed? (y/n) [y] n Goodbye!
A very similar yes/no question can be created through convenience method very easily:
The created yes/no question dialog contains a custom question and defaults to "y", if nothing is selected. In contrast to the last example, the dialog created here also accepts "yes" and "no" as answers. Both phrases can be used in any typing, e.g. like "yEs" or "NO". This is made possibly by the ezcConsoleQuestionDialogMappingValidator, which extends ezcConsoleQuestionDialogCollectionValidator. The mapping validator allows to define an arbitrary mapping between the user typed answers and expected ones. Therefore the dialog still only returns either "y" or "n".
The second dialog type, provided with ConsoleTools, is the ezcConsoleMenuDialog. Similar to the ezcConsoleQuestionDialog, it displays a list of menu items to the user and requires him to choose one of these. An example for this class looks like this:
Again the dialog is instantiated and some options are tweaked to get the desired behaviour. The validator in this case receives an array of possible menu items, while the key represents the identifier and the value contains the text to be displayed for the item. The second argument is the default value, chosen if the user simply presses <return>.
An example run of this program could look like this:
Please choose a possibility: 1) Perform some more actions 2) Perform another action 0) Quit Select:  1 Performing some more actions... Please choose a possibility: 1) Perform some more actions 2) Perform another action 0) Quit Select:  2 Performing some other actions! Please choose a possibility: 1) Perform some more actions 2) Perform another action 0) Quit Select: 
The character used to divide the identifier and text, as well as the text indicating that a selection must be done, can be tweaked, too.