This RFC is dealing with the CLI components of the Zend Framework 2 and should discuss:
- the need for CLI component(s)
- various use cases
- possible, but not final, implementations
This RFC is planned to be discussed on the next ZF2 IRC meeting, which will be held on November 9th (1)
It is based on a few mailing list threads - (2), (3), (4), (5) - and 2 CLI prototypes by Matt Cockayne and Robert Basic.
The goal is to have two separate components, Zend\Console and Zend\Cli (naming of these components is open to discussion). In context, “CLI components” refers to both Zend\Console and Zend\Cli.
Zend\Console should deal with “low level” problems, like, console argument parsing and outputting to STDOUT\STDERR, similar to what Zend\Console\Getopt is now. At most, it should rely only on the Zend\Stdlib component, on classes and interfaces defined in it. This would assure that this component can be used outside of Zend Framework as a standalone component for writing CLI scripts.
Zend\Cli should deal with “higher level” problems, like writing complete CLI modules and applications. Zend\Cli should utilise Zend\Console and follow as close as possible and necessary the Zend\Mvc component. Basically, it would offer a command line entry point to an MVC style application.
To ease creating of CLI scripts, modules and applications, and, most likely, other ZF2 components like Zend\Tool.
The biggest use case so far is the Module Installation and Distribution (6) which should be the main driving force behind these CLI components, in both the requirements and the deadline for these CLI components to provide something usable and useful.
Other uses cases include cron scripts, scrapers, development modules and tools, which could help with project management (for example, Zend\Tool)...
Zend\Console must provide the functionality of parsing console arguments passed to the called script. This parser should put the parsed arguments in a container of sorts, which must implement the Zend\Stdlib\ParametersDescription interface. This would make easier to work with these parameters, as it would be, if not the same, then very similar, as how we are already used to work with $_GET, $_POST... parameters in an HTTP environment.
Zend\Console must provide the functionality of working with interactive input. A valid use case for this is (8). A possible implementation for this could be (9), need to ask around/investigate more on this.
Zend\Console must provide the functionality of outputting responses to STDOUT|STDERR. It should provide different output decorators, which, if needed, could be applied to the output. An example set of these decorators can be found in the Zend\Tool component (7).
Zend\Cli should provide functionality which would make it possible to write CLI based applications and/or modules, or to add CLI functionality to already written MVC modules. For these reasons, this component should follow as closely as possible the Zend\Mvc component.
Zend\Cli must have a bootstrap process which will, similar to the MVC bootstrap, initialize the application.
Zend\Cli must have an application object, which will handle the incoming CLI request, by using the Zend\Console components. Also, any output which needs to be sent to the terminal, should be done by the application, again, by using the Zend\Console components.
Zend\Cli should have a request and a response object.
Zend\Cli should have a router and the possibility to define routes. This would allow us to, for example, call module Foo, controller Bar, action Baz, by simply invoking:
It should be possible to define a help message on any “level” of commands. For example, if we have the following commands:
we should be able to call help on both fetch and update, and on module too:
The matched route must call a module/controller/action combination, defined with the route. The controller must be dispatchable and locator aware.
We should consider and discuss the possibility of making it possible to access a controller both from an HTTP request and from an CLI request. The pro of this is reusability. The con is possible reduced security. Take just for an example an action which is run by cron to do some maintanance on the database/filesystem; making this accessible via HTTP can impose a security issue. There is also an option of adding a flag of some sort to the controller, which would be off by default and would mark the controller accessible only from HTTP or CLI. Setting the flag to on would make the controller accessible from both environments.
(1) 2011-11-09 Meeting Agenda
(6) RFC - Module Installation and Distribution