eZ Components - ConsoleTools ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. contents:: Table of Contents Introduction ============ 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. Class overview ============== The ConsoleTools component offers several (mostly independent) classes to perform different tasks. The main classes are: ezcConsoleOutput ezcConsoleOutput is responsible for printing text to the console. It allows you to print text in different colors with different background colors. It can also apply other styling information to the text, making it bold or underlined for example. It can automatically wrap text after a certain number of characters are printed (keeping words intact) and handle output of different verbosity levels. ATTENTION: Windows does not support the styling of text. ezcConsoleInput Using this little tool, you can handle the options and arguments provided to your shell application. It is capable of handling and validating three types of option datatypes (string, int and none) and can handle optional and mandatory options as well as rules to define relations between them. Rules can include dependencies and exclusions between options. ezcConsoleProgressbar Most often you will use a console application in favor of a web application when it comes to processing time-consuming tasks. To indicate the current progress of a task, a kind of "status indicator" will be used, which is most commonly a progress bar. ezcConsoleProgressbar gives you an easy-to-use interface to display this. It will keep track of re-drawing the bar as needed, showing current and maximum values, as well as percentage completion. It is fully configurable regarding its visual appearance. ezcConsoleStatusbar ezcConsoleStatusbar is the "little brother" of ezcConsoleProgressbar. It also allows you to display the progress of a time-consuming action, but does not use a fixed bar-like appearance. Instead, it indicates successful and failed operations by displaying specific characters and keeps a count of successes and failures. This allows you to indicate the progress of a process where you don't initially know the number of actions to be performed. ezcConsoleProgressMonitor Sometimes you need to display the progress of several actions and don't want to use a progress bar to do so. In this case you need the status indicator. It allows you to display a status entry for each action and generates the percentage completion of the current step. ezcConsoleTable This class lets you easily create tables to be displayed on the console. It has a very convenient interface to create a table and manage the data it contains. It is highly configurable regarding the table's appearance (for example, different color and style information for content and borders on a per-cell basis, character selection for borders, variable width of the table and so on). ezcConsoleTable will also take care of measuring the best width for table columns (to make your content fit best), automatically wrapping content and aligning the content in the cells as indicated. ezcConsoleDialog This interface provides a common API for user interaction elements. A console dialog can request information from a user and react on this information interactively. For you as a user of ezcConsoleDialog, a dialog is displayed to the user and returns a result value to you, which was provided by the user of your application in some way. Currently 2 implementations of ezcConsoleDialog exist: ezcConsoleQuestionDialog is a dialog for asking a simply question and retrieving the answer from the user of an application. Instances of the ezcConsoleMenuDialog class display a menu to the user and retrieves his choice of a menu item. Usage ===== Printing text to the console ---------------------------- As mentioned, the class ezcConsoleOutput is used to print text to the console. Let's look at a basic example: .. include:: tutorial_example_01_output_basic.php :literal: 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: .. include:: tutorial_example_02_output_advanced.php :literal: 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: .. include:: tutorial_example_03_output_options.php :literal: autobreak Will wrap lines automatically after the set amount of characters, keeping word boundaries intact. verbosityLevel Allows you to specify a third parameter to ezcConsoleOutput::outputLine() and ezcConsoleOutput::outputText() to indicate a verbosity level for when the text should be printed. By setting the "verbosityLevel" option for ezcConsoleOutput, you define which texts will and will not be printed. 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. Mastering options and arguments ------------------------------- Below is a simple example for ezcConsoleInput: .. include:: tutorial_example_04_input_basic.php :literal: 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: .. include:: tutorial_example_05_input_advanced.php :literal: 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 [-o ] ] [[--] ] 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: .. include:: tutorial_example_12_input_arguments.php :literal: 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] [--] [] [] A simple text program -h / --help No help available. Arguments: The source directory. No help available. Number of iterations. For further information, please refer to the API documentation of ezcConsoleInput. Progress indication ------------------- This example defines a simple progress bar: .. include:: tutorial_example_06_progressbar_basic.php :literal: 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: .. image:: img/consoletools_tutorial_example_06.png The next example performs more customization on the progress bar appearance: .. include:: tutorial_example_07_progressbar_advanced.php :literal: 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: .. image:: img/consoletools_tutorial_example_07.png With ezcConsoleStatusbar, you can indicate the progress of a time-consuming action in a simpler way. Here is an example: .. include:: tutorial_example_08_statusbar.php :literal: 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: .. image:: img/consoletools_tutorial_example_08.png 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. .. include:: tutorial_example_11_progressmonitor.php :literal: 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. More information on these classes can be found in the API documentation of ezcConsoleProgressbar, ezcConsoleStatusbar and ezcConsoleProgressMonitor. Large data served in a table ---------------------------- This is the result of a table generated by ezcConsoleTable: .. image:: img/consoletools_tutorial_example_09.png Here is its corresponding source code: .. include:: tutorial_example_09_table_basic.php :literal: 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: - ezcConsoleTable::ALIGN_DEFAULT (inherit from parent) - ezcConsoleTable::ALIGN_LEFT - ezcConsoleTable::ALIGN_RIGHT - ezcConsoleTable::ALIGN_CENTER 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. .. _SPL: http://php.net/spl .. _ArrayAccess: http://www.php.net/~helly/php/ext/spl/interfaceArrayAccess.html Below is a more advanced (but in a way useless) example to show the handling of tables: .. include:: tutorial_example_10_table_advanced.php :literal: 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: .. image:: img/consoletools_tutorial_example_10.png More information on the handling of tables on the shell can be found in the API documentation of ezcConsoleTable, ezcConsoleTableRow and ezcConsoleTableCell. Interacting with the user ------------------------- 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. .. include:: tutorial_example_13_dialog_question.php :literal: 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! For the same dialog, a simple yes/no question, a convenience method exists so this can be created easier: .. include:: tutorial_example_14_dialog_yesnoquestion.php :literal: 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: .. include:: tutorial_example_15_dialog_menu.php :literal: 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 . 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: [0] 1 Performing some more actions... Please choose a possibility: 1) Perform some more actions 2) Perform another action 0) Quit Select: [0] 2 Performing some other actions! Please choose a possibility: 1) Perform some more actions 2) Perform another action 0) Quit Select: [0] 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. Further information about dialogs can be found in the API documentation of ezcConsoleDialog, ezcConsoleQuestionDialog and ezcConsoleMenuDialog. .. Local Variables: mode: rst fill-column: 79 End: vim: et syn=rst tw=79