2011-09-26 Dev status update
Zend Framework status update for the weeks of 13 - 26 September 2011.
2011-09-14 IRC Meeting
We held our third IRC meeting on Wednesday, 14 September 2011. On the agenda were:
- RFC on configuration
- Where components falling outside the standard distribution should live if incomplete
- Goals of the Module Manager
- Directory structure for modules
Configuration
Between the competing RFCs on configuration, the IRC discussion, and some back-and-forth following the meeting, the following summarizes the current consensus on how ZF2 will deal with component configuration:
- Hard dependencies that do not have sane defaults would be in the constructor signature
- The last argument in the constructor signature would be optional, and expect an instance of the component's Options class
- If a dependency has a sane default, we would not include an argument in the constructor, but would allow setter injection (which could be automated by the DI container)
- The component's Options class would handle optional configuration arguments, and provide validation for those arguments.
- The component would directly access optional arguments from the Options instance it composes
Note the word "Options". In discussions, we decided we should call this
functionality "Options" as it denotes that the values are optional, and also to
prevent nomenclature conflicts with the already existing Zend\Config
component. We will be producing a poll on the wiki to do a final vote very soon.
Unfinished "Extras" components
The discussion centered around whether or not we would remove unrefactored components that fall outside the standard distribution -- things like service components that have not been converted to namespaces, updated to latest exceptions practices, and not refactored to use the new HTTP functionality.
Only slight debate erupted -- the decision is:
- Keep this functionality in the master branch
- Add an annotation such as "@incomplete" to the file and/or class-level docblocks.
-
Add the "@incomplete" annotation to related test classes, and add a rule to
phpunit.xmlto skip such tests. - Comment out sections in the manual referring to these components.
We will then add rules to packaging to omit such classes and resources.
Module Manager Goals
The Module Manager is a component for scanning and initializing modules during application bootstrapping. As such, it's fairly central to the new MVC approach, and we wanted to be sure we captured its goals. A sizable list of goals was presented, and we voted on each. There are too many to relate here, so instead I'll simply link you to the summary.
Most items were straight-forward, but there are a few conflicting ideas about what the scope of the manager; should it simply act as a kernel for bootstrapping, or have deep ties within the application?
Current development of this tool has taken the former approach, but has exposed
a number of useful features that allow a ton of flexibility for a variety of
approaches. One, in particular, is a method getLoadedModules(), which returns
an associative array of module name/module objects. With this, I was able to do
such things as loop through modules, check for the existence of specific
methods, and then call them to do things such as event listener registration.
Module Directory Structure
By the time of the meeting, we already had a couple different module directory structures floating around, and the discussion centered on which one to use. Except that several people brought up one very, very good point: with a well-known class (the module's "Module" class) that we're querying, the structure doesn't matter, and does not need to be enforced.
As such, our decision was that we should have a recommended structure that satisfies the various use cases we originally brainstormed. Among these:
- Ability to serve multiple namespaces (if desired)
- Separation of code from non-code assets, if provided (such as CSS, JS, HTML)
- Separation of view templates, if provided, from code
- Separation of configuration, if provided, from code
As such, the following structure was generally agreed upon as a recommendation:
modules/
SpinDoctor/
Module.php
autoload_classmap.php
autoload_function.php
autoload_register.php
configs/
module.config.php
routes.config.ini
public/
images/
css/
spin-doctor.css
js/
spin-doctor.js
src/
SpinDoctor/
Controller/
SpinDoctorController.php
DiscJockeyController.php
Form/
Request.php
tests/
bootstrap.php
phpunit.xml
SpinDoctor/
Controller/
SpinDoctorControllerTest.php
DiscJockeyControllerTest.php
views/
spin-doctor/
album.phtml
disc-jockey/
turntable.phtml
Public assets such as images, CSS, and JS could either be symlinked into the public tree, copied, or managed by an asset manager such as Assetic.
Regarding the various autoload_*.php files, these were brought up in a
post from Ralph,
based on discussions he and I have had. The idea behind these is that we can
satisfy several typical use cases for modules:
-
Download and use: simply
require 'autoload_register.php';and start using classes. -
Use with custom registration:
spl_autoload_register(include 'autoload_function.php');, which allows you to specify tospl_autoload_registerwhether or not to append or prepend the function to your autoloader stack. -
Custom autoloading class map: aggregate the returns of
autoload_classmap.phpinto a single classmap for your application.
There's still some discussion going around these files, but they've been adopted in the prototypes at this time.
MVC Prototype Status
The MVC prototype has grown tremendously, in large part due to the efforts of Evan Coury and his work on the Module Manager. The module manager now does the following:
-
Aggregates configuration from all modules
- Including modules provided as phars!
- Provides introspection and access to discovered modules
- Optionally allows configuration caching
The MVC prototype has also grown. Based on a suggestion from Greg N. on the mailing lists, the EventManager was refactored slightly to do the following:
- Removed references to "handlers" in favor of "listeners" to provide a consistent terminology (both internally as well as with other systems of similar design)
-
triggernow allows passing anEventobject for any one of its required arguments. This allows creation of customEventobjects, as well as re-use of them. -
triggerwas modified to allow an optional final argument, either the fourth argument or an argument following anEventobject: a callback that indicates whether or not to halt execution. This largely eliminates the need fortriggerUntilat this time. -
Locally attached listeners are now combined with static listeners into a
single priority queue when
triggeris called. This provides a consistent expectation, and allows you to register static listeners that can be called prior to those attached locally.
What the above allowed was the ability to move routing and dispatching into
listeners within Zend\Mvc\Application, using a custom MvcEvent object. The
upshot is:
- Simpler code
-
Accessors for well-known (and/or expected) objects (e.g.,
getRequest(),getRouteMatch(),getResult()) - Events are registered with priority in order to shape the execution workflow
- The ability to replace the default routing and dispatch listeners with custom listeners.
This last point allowed me to prototype a ZF1-emulation layer in the new ZF2 paradigm. This effort was surprisingly easy, and helped illustrate how flexible the prototype can be.
Additional work on the MVC centered around error handling, and providing a
simple mechanism for discovering and handling errors. The
zf-quickstart example
showed that this largely eliminates the need for an ErrorController.
At this time, we're quickly closing in on what the MVC will likely look like for
ZF2, and hope to merge the ZendMvc and ZendModule modules into the library
very soon.
DI Annotation Support
Ralph has been refactoring the Reflection, CodeGenerator, and Code\Scanner
components to follow a consistent API, and to live under a common tree,
Zend\Code. Part of this work is to also provide a parser/tokenizer for PHP
docblocks, with the goal of providing annotation support to components that need
it. In particular, this could assist the Dependency Injection component,
allowing more intelligent hinting as to what setters are required and/or the
specific arguments to inject. Another potential use might be with modules, to
indicate what they provide and/or methods that should be called at
initialization.
This work should hit master this week, and will be compatible with the docblock extension.
Cloud Infrastructure
Enrico has been working on updating the Amazon, Rackspace, and GoGrid services to use the new HTTP functionality. In doing so, he's discovered areas where the HTTP component needed improvement, as well as places he could better test. At this time, all changes he's done are incorporated in the master branch, with the exception of some tests for GoGrid.
This work has helped round out a new offering in Zend Framework, as well as to test recent development work and ideas such as the HTTP component and the Options proposal.
The Future
There are new RFCs and discussions erupting regularly on the mailing list and in the #zftalk.2 IRC channel on Freenode; I encourage you to subscribe to the former and join in the latter so that you can participate.
Also, we have an IRC meeting this week, 28 September 2011 at 17:00 UTC. The agenda is online, but could potentially use some more topics and votes. Talk to you Wednesday!
blog comments powered by Disqus