This is an installment in an ongoing series of bi-weekly posts on ZF3 development status.

The highlights:

  • ~60 pull requests merged, and ~100 issues closed.
  • Another v3 release: zend-stdlib!
  • 16 components updated to zend-servicemanager/zend-eventmanager/zend-stdlib v3 changes, and tagged with stable releases.
  • 25 component releases.
  • Publication of documentation for 13 components to GitHub Pages.

New 3.0 versions

We released another component with version 3.0 stability, zend-stdlib. This release got the major version bump for a number of reasons:

  • Per version 2.7.0, the hydrator sub-component was deprecated (it has been moved into its own component, zend-hydrator). With the new major version, we were able to remove it.
  • A number of features existed as polyfills to provide forwards-compatibility support from PHP 5.3 or PHP 5.4 to later PHP versions. Since we now support only PHP 5.5+, we could remove these.

Unless a component depends specifically on the hydrators, it's essentially already forwards-compatible with the new version 3! As such, we'll be gradually updating components that depend on zend-stdlib to depend on ^2.7 || ^3.0.

Compatibility Migrations

The past two weeks have been heavily focused on preparing components to be forwards compatible with the version 3 releases of zend-stdlib, zend-eventmanager, and zend-servicemanager. We had several breakthroughs that are enabling these migrations.

First, we can test the different versions via additional Travis-CI jobs. As an example, consider these PHP 5.5 entries from the zend-cache test matrix:

matrix:
    include:
    - php: 5.5
        env:
        - EXECUTE_CS_CHECK=true
        - PECL_INSTALL_APCU='apcu-4.0.8'
    - php: 5.5
        env:
        - SERVICE_MANAGER_VERSION="^2.7.5"
        - EVENT_MANAGER_VERSION="^2.6.2"
        - PECL_INSTALL_APCU='apcu-4.0.8'

Note that in the second entry, we specify specific v2 versions of zend-eventmanager and zend-servicemanager to use.

Later, in our before_install section, we do the following:

before_install:
    - if [[ $SERVICE_MANAGER_VERSION != '' ]]; then composer require --no-update "zendframework/zend-servicemanager:$SERVICE_MANAGER_VERSION" ; fi
    - if [[ $SERVICE_MANAGER_VERSION == '' ]]; then composer require --no-update "zendframework/zend-servicemanager:^3.0.3" ; fi
    - if [[ $SERVICE_MANAGER_VERSION == '' ]]; then composer remove --dev --no-update zendframework/zend-session ; fi
    - if [[ $EVENT_MANAGER_VERSION != '' ]]; then composer require --no-update "zendframework/zend-eventmanager:$EVENT_MANAGER_VERSION" ; fi
    - if [[ $EVENT_MANAGER_VERSION == '' ]]; then composer require --no-update "zendframework/zend-eventmanager:^3.0" ; fi

Essentially, we have two builds. One against the v2 components, and one against the v3 components; the items above force one or the other for the particular build. This allows us to verify that the code works against both versions, and that any later changes require that both versions continue to work.

What about that line to remove dependencies, though?

The tricky part of migration has been unravelling dependencies. If a dependency of a component being migrated also depends on one of the updated components, we have to wait until the dependency is migrated. Or do we?

In many cases, these dependencies are marked as suggestions, and as development dependencies only; they are not hard requirements of the component. Realizing this, we discovered the following workflow:

  • We can remove dependencies when testing against v3 components if:
    • the dependency is not yet migrated
    • the dependency is optional (only listed in require-dev and/or suggest)
  • We can update the tests to skip tests that depend on those particular components if classes or interfaces from that component are missing.

This means that we're testing specifically that the current component is forwards-compatible with the new versions. Later, once those dependencies are updated, we can re-enable those tests.

Finally, a contributor wrote a trait that we can compose in plugin manager tests to verify that a plugin manager implementation is both v2 and v3 compatible. By adding these to components, we're able to verify with much more confidence that the code works on both versions.

With these findings and tools in place, we were able to complete migration of 16 components these past two weeks, tagging each with new stable versions! These include:

We've made every effort to ensure that these releases continue to work with existing version 2 functionality; however, occasionally, errors occur. If you notice such errors, please report them as soon as you can, with as many details as you can, so we can correct them. Additionally, please be aware that developers are fellow human beings, and be respectful in your communication. Nobody is intentionally trying to break your applications, and contributors desire a smooth migration for you as well.

At this point, we're about half-done with the migrations, and of the remaining half, around half have patches under review. If you want to assist, please review the migrations page to see which patches are need review, and where you might be able to help.

Documentation

As noted in our last update, Gary Hockin performed an automated migration of our documentation from our reStructuredText sources to per-component Markdown a few weeks ago, and opened issues against each component to guide review of the documentation before publication. We also mentioned a plan to host documentation via GitHub Pages.

As part of the migration process, we decided to review and ready documentation for publication for any component getting a new minor release. This has resulted in new documentation for the following 13 components!

We're very excited about the new documentation, particularly as it's mobile-friendly, and has in-site search!

Pull request and issue activity

Since the last update, we've merged around 60 pull requests, closing over 100 issues. (links require a GitHub account). Activity has been particularly high on documentation issues.

Component Releases

The following is a list of component releases since the last update, minus those noted in the migration section already. While not all releases are related to ZF3 specifically, this list is intended to detail activity within the organization.

  • zend-expressive-twigrenderer 1.1.1 updates the TwigExtension to implement Twig_Extension_GlobalsInterface, to ensure it is forwards-compatible with Twig v2.
  • zend-servicemanager 2.7.5 fixes the behavior of the InvokableFactory for situations when options are passed via a plugin manager, and provides tests for validating plugin managers are ready for both v2 and v3.
  • zend-servicemanager 3.0.3 provides a number of fixes:
    • cyclical alias detection and reporting.
    • skips alias resolution if no aliases are present.
    • adds tests to verify plugin managers are v3-ready.
    • publishes documentation to GitHub Pages.
  • ZendXml 1.0.2 updates the PHP dependency to ^5.3.3 || ^7.0, allowing it to work with any ZF component, in any supported PHP version. It also expands the test matrix to include PHP 7.
  • zend-i18n 2.6.0, while previously noted, also contained the following changes:
    • adds support for NumberFormatter text attributes when using the NumberFormat view helper.
    • provides updated postal code verifications for Mauritius and Serbia.
    • allows multiple invocations of the DateTime validator with different sets of input.
    • provides null checks on provided message strings.

Until next time

If you want to help:

Many thanks to all the contributors who have provided feedback, patches, reviews, or releases these past two weeks!

Source

This is an installment in an ongoing series of bi-weekly posts on ZF3 development status.

The highlights:

  • > 70 pull requests merged
  • 2 components updated to zend-servicemanager/zend-eventmanager v3 changes
  • 23 releases of components, including Expressive 1.0, and new maintenance releases of Apigility and the ZF2 package.
  • Kickstarting of the documentation migration

Expressive 1.0!

Following two final release candidates, and after three months in release candidate status, we've finally tagged Expressive 1.0 stable! Among other things, we've created a dedicated documentation site, which will update automatically as features are merged to the project.

We feel Expressive is the true cornerstone of the ZF3 initiative, and we look forward to seeing the middleware-based projects people develop using it!

ZF2 and Apigility

We noted that the zendframework/zendframework package, which since 2.5.0 has been a metapackage aggregating the various independent components, was using ~2.5.0 for component constraints. This is problematic, as many components have 2.6 and even 2.7 versions, and some of those contain security fixes. To fix this, we released version 2.5.3, which modifies the component constraints to ^2.5, allowing them to get the latest 2.X series of any given component.

We also released version 1.3.2 of Apigility, to bring in some changes merged many months ago to fix things like DB Autodiscovery, as well as to pick up the 2.5.3 version of ZF2.

Documentation

Gary Hockin generously donated some time and wrote scripts to automate translation of individual component documentation from the ZF2 reStructured Text sources to markdown, and submitted pull requests across all components, which we have now merged. These are incomplete; some syntax cannot be translated correctly, imports within files could not be automated, etc.

If you want to assist, we've labeled all documentation tasks (link requires github login); feel free to jump in on the effort!

We're also working on a plan to host the documentation via GitHub Pages, to allow constant, up-to-date documentation, based on the work we did for the Expressive documentation. Most of the tooling for this is now created, and we will be able to start pushing it out to components once their documentation is ready to publish.

Pull request activity

Since the last update, we've merged over 70 pull requests (link requires a GitHub account). Activity has been particularly high on Expressive and documentation issues.

Component Releases

The following is a list of component releasessince the last update, minus a number of Expressive releases leading to the stable release. While not all releases are related to ZF3 specifically, this list is intended to detail activity within the organization.

  • zend-view 2.5.3 adds support for the itemprop HTML attribute in the headLink() view helper, and updates PhpRenderer::render() to no longer lazy-instantiate a FilterChain if none is already present.
  • zend-servicemanager 2.7.4 fixed an issue with resolving aliases of aliases due to canonicalization changes in previous versions.
  • zend-servicemanager 3.0.1 removes the dependency on zend-stdlib by inlining the ArrayUtils::merge() routine into the Config class.
  • zend-expressive-twigrenderer 1.1.0 adds several new features:
    • url and absolute_url template functions for generating URL paths and absolute URIs.
    • New "globals" configuration for specifying variables to make available in all templates.
  • zend-servicemanager 3.0.2 fixes an issue whereby the creation context was not being passed correctly to abstract factories from plugin managers, and provides a performance boost for alias resolution.
  • zend-code 3.0.1 moves the phpcs dependency to the require-dev section, and ensures that the method name is required when adding a method to the class generator.
  • zend-apigility-admin 1.4.1 fixes an issue in the RpcServiceModel to ensure that a correct pattern is generated when fetching a service by name.
  • zend-apigility-admin-ui 1.2.2 fixes a number of issues discovered, including:
    • DB Autodiscovery was failing due to inability to properly select the DB adapter name.
    • Custom authentication adapters are now displayed.
    • The regex for validating custom content-types was fixed to ensure it only allows valid MIME type specifications.
    • Fixes validation for REST and RPC service names, raising a warning on invalid input.

ZF3 Refactors

Our refactoring effort has slowed due to our focus on getting Expressive stabilized, though we're starting to get a number of community contributions to aid the effort.

If you wish to assist, please read the ZF3 ServiceManager refactoring guide; be sure to edit the wiki to indicate when you're working on a component, as well as to indicate the relevant pull request.

Until next time

If you want to help:

Many thanks to all the contributors who have provided feedback, patches, reviews, or releases these past two weeks!

Source

The Zend Framework community is pleased to announce the immediate availability of Expressive 1.0.0 STABLE!

You can install it using Composer, via the create-project command:

$ composer create-project zendframework/zend-expressive-skeleton expressive

If you were using a release candidate, you can update your existing applications using:

$ composer require "zendframework/zend-expressive:^1.0"

What's new in the stable version?

Nothing!

Well, not "nothing". Since last week, we merged a few documentation fixes, but, more importantly, finalized our documentation. This included a few changes:

  • Some re-organization, to better categorize the documentation hierarchy.
  • Switching from bookdown to MkDocs as our build engine of choice. We'd already been using MkDocs to publish on ReadTheDocs, so this wasn't a huge change. The choice was made based on stability, maturity, and ecosystem; MkDocs has been around for quite some time, and enabled us to accomplish a number of ideas quite quickly.
  • Automated publishing to GitHub Pages, via Travis-CI. Any time we push to our master branch, the documentation will be updated.

We're quite proud of the results, and hope that the new documentation serves our users well.

What's to look forward to?

Shipping a stable version means that you can depend on the API going forward. As such, we're messaging that it's production ready; start building and shipping your applications on it today!

For the next feature version, we already have a few things scheduled:

Kudos

We wish to thank everyone who contributed to the Expressive project! (That previous sentence is a link for every one of our 11 Expressive repositories!)

Additionally, we thank everyone who has provided us feedback — whether in the form of questions, bug reports, or suggestions — these past few months; without the critical feedback, the project would not be where it is today.

A few folks stand out:

  • Enrico Zimuel, who started it all!
  • Geert Eltink, who did the hard work of making the installer work!
  • Hari K T, who nudged us to split the repository into discrete, single-purpose projects!
  • Michael Moussa, who suggested the idea that middleware specifications could be pipelines themselves — and then implemented the solution!

Write your next project Expressively!

Write your PSR-7 middleware today! Consult the documentation to get started!

Source

This is an installment in an ongoing series of bi-weekly posts on ZF3 development status.

The highlights:

  • 70 pull requests merged

  • 2 components updated to zend-servicemanager/zend-eventmanager v3 changes
  • 23 releases of components, including Expressive 1.0, and new maintenance releases of Apigility and the ZF2 package.
  • Kickstarting of the documentation migration

Expressive 1.0!

Following two final release candidates, and after three months in release candidate status, we've finally tagged Expressive 1.0 stable! Among other things, we've created a dedicated documentation site, which will update automatically as features are merged to the project.

We feel Expressive is the true cornerstone of the ZF3 initiative, and we look forward to seeing the middleware-based projects people develop using it!

ZF2 and Apigility

We noted that the zendframework/zendframework package, which since 2.5.0 has been a metapackage aggregating the various independent components, was using ~2.5.0 for component constraints. This is problematic, as many components have 2.6 and even 2.7 versions, and some of those contain security fixes. To fix this, we released version 2.5.3, which modifies the component constraints to ^2.5, allowing them to get the latest 2.X series of any given component.

We also released version 1.3.2 of Apigility, to bring in some changes merged many months ago to fix things like DB Autodiscovery, as well as to pick up the 2.5.3 version of ZF2.

Documentation

Gary Hockin generously donated some time and wrote scripts to automate translation of individual component documentation from the ZF2 reStructured Text sources to markdown, and submitted pull requests across all components, which we have now merged. These are incomplete; some syntax cannot be translated correctly, imports within files could not be automated, etc.

If you want to assist, we've labeled all documentation tasks (link requires github login); feel free to jump in on the effort!

We're also working on a plan to host the documentation via GitHub Pages, to allow constant, up-to-date documentation, based on the work we did for the Expressive documentation. Most of the tooling for this is now created, and we will be able to start pushing it out to components once their documentation is ready to publish.

Pull request activity

Since the last update, we've merged over 70 pull requests (link requires a GitHub account). Activity has been particularly high on Expressive and documentation issues.

Component Releases

The following is a list of component releasessince the last update, minus a number of Expressive releases leading to the stable release. While not all releases are related to ZF3 specifically, this list is intended to detail activity within the organization.

  • zend-view 2.5.3 adds support for the itemprop HTML attribute in the headLink() view helper, and updates PhpRenderer::render() to no longer lazy-instantiate a FilterChain if none is already present.
  • zend-servicemanager 2.7.4 fixed an issue with resolving aliases of aliases due to canonicalization changes in previous versions.
  • zend-servicemanager 3.0.1 removes the dependency on zend-stdlib by inlining the ArrayUtils::merge() routine into the Config class.
  • zend-expressive-twigrenderer 1.1.0 adds several new features:
    • url and absolute_url template functions for generating URL paths and absolute URIs.
    • New "globals" configuration for specifying variables to make available in all templates.
  • zend-servicemanager 3.0.2 fixes an issue whereby the creation context was not being passed correctly to abstract factories from plugin managers, and provides a performance boost for alias resolution.
  • zend-code 3.0.1 moves the phpcs dependency to the require-dev section, and ensures that the method name is required when adding a method to the class generator.
  • zend-apigility-admin 1.4.1 fixes an issue in the RpcServiceModel to ensure that a correct pattern is generated when fetching a service by name.
  • zend-apigility-admin-ui 1.2.2 fixes a number of issues discovered, including:
    • DB Autodiscovery was failing due to inability to properly select the DB adapter name.
    • Custom authentication adapters are now displayed.
    • The regex for validating custom content-types was fixed to ensure it only allows valid MIME type specifications.
    • Fixes validation for REST and RPC service names, raising a warning on invalid input.

ZF3 Refactors

Our refactoring effort has slowed due to our focus on getting Expressive stabilized, though we're starting to get a number of community contributions to aid the effort.

If you wish to assist, please read the ZF3 ServiceManager refactoring guide; be sure to edit the wiki to indicate when you're working on a component, as well as to indicate the relevant pull request.

Until next time

If you want to help:

Many thanks to all the contributors who have provided feedback, patches, reviews, or releases these past two weeks!

Source

The Zend Framework community is pleased to announce the immediate availability of Expressive 1.0.0 STABLE!

You can install it using Composer, via the create-project command:

$ composer create-project zendframework/zend-expressive-skeleton expressive

If you were using a release candidate, you can update your existing applications using:

$ composer require "zendframework/zend-expressive:^1.0"

What's new in the stable version?

Nothing!

Well, not "nothing". Since last week, we merged a few documentation fixes, but, more importantly, finalized our documentation. This included a few changes:

  • Some re-organization, to better categorize the documentation hierarchy.
  • Switching from bookdown to MkDocs as our build engine of choice. We'd already been using MkDocs to publish on ReadTheDocs, so this wasn't a huge change. The choice was made based on stability, maturity, and ecosystem; MkDocs has been around for quite some time, and enabled us to accomplish a number of ideas quite quickly.
  • Automated publishing to GitHub Pages, via Travis-CI. Any time we push to our master branch, the documentation will be updated.

We're quite proud of the results, and hope that the new documentation serves our users well.

What's to look forward to?

Shipping a stable version means that you can depend on the API going forward. As such, we're messaging that it's production ready; start building and shipping your applications on it today!

For the next feature version, we already have a few things scheduled:

Kudos

We wish to thank everyone who contributed to the Expressive project! (That previous sentence is a link for every one of our 11 Expressive repositories!)

Additionally, we thank everyone who has provided us feedback — whether in the form of questions, bug reports, or suggestions — these past few months; without the critical feedback, the project would not be where it is today.

A few folks stand out:

  • Enrico Zimuel, who started it all!
  • Geert Eltink, who did the hard work of making the installer work!
  • Hari K T, who nudged us to split the repository into discrete, single-purpose projects!
  • Michael Moussa, who suggested the idea that middleware specifications could be pipelines themselves — and then implemented the solution!

Write your next project Expressively!

Write your PSR-7 middleware today! Consult the documentation to get started!

Source

The Zend Framework community is pleased to announce the immediate availability of Expressive 1.0.0rc7 and the Expressive Skeleton and Installer 1.0.0rc8!

You can install the latest versions using Composer, via the create-project command:

$ composer create-project -s rc zendframework/zend-expressive-skeleton expressive

You can update your existing applications using:

$ composer update

This release candidate contains bug fixes for dispatching error middleware pipelines. Additionally, we've released a new version of our Twig integration, and detail those changes below.

Changes in zend-expressive RC7

RC6 updated the configuration for the middleware pipeline to make it a single pipeline. We recommended that developers make use of our middleware grouping feature, however, which allows you to specify not just a single, named middleware service, but an array of named middleware services. This feature is great for grouping middleware based on when it should execute, and makes ordering related middleware simpler.

Per our suggested, default configuration:

use Zend\Expressive\Container\ApplicationFactory;
use Zend\Expressive\Helper;

return [
    'dependencies' => [
        'factories' => [
            Helper\ServerUrlMiddleware::class => Helper\ServerUrlMiddlewareFactory::class,
            Helper\UrlHelperMiddleware::class => Helper\UrlHelperMiddlewareFactory::class,
        ],
    ],
    // This can be used to seed pre- and/or post-routing middleware
    'middleware_pipeline' => [
        // An array of middleware to register. Each item is of the following
        // specification:
        //
        // [
        //  Required:
        //     'middleware' => 'Name or array of names of middleware services and/or callables',
        //  Optional:
        //     'path'     => '/path/to/match', // string; literal path prefix to match
        //                                     // middleware will not execute
        //                                     // if path does not match!
        //     'error'    => true, // boolean; true for error middleware
        //     'priority' => 1, // int; higher values == register early;
        //                      // lower/negative == register last;
        //                      // default is 1, if none is provided.
        // ],
        //
        // While the ApplicationFactory ignores the keys associated with
        // specifications, they can be used to allow merging related values
        // defined in multiple configuration files/locations. This file defines
        // some conventional keys for middleware to execute early, routing
        // middleware, and error middleware.
        'always' => [
            'middleware' => [
                // Add more middleware here that you want to execute on
                // every request:
                // - bootstrapping
                // - pre-conditions
                // - modifications to outgoing responses
                Helper\ServerUrlMiddleware::class,
            ],
            'priority' => 10000,
        ],

        'routing' => [
            'middleware' => [
                ApplicationFactory::ROUTING_MIDDLEWARE,
                Helper\UrlHelperMiddleware::class,
                // Add more middleware here that needs to introspect the routing
                // results; this might include:
                // - route-based authentication
                // - route-based validation
                // - etc.
                ApplicationFactory::DISPATCH_MIDDLEWARE,
            ],
            'priority' => 1,
        ],

        'error' => [
            'middleware' => [
                // Add error middleware here.
            ],
            'priority' => -10000,
            'error' => true,
        ],
    ],
];

Unfortunately, for error middleware, this was not working correctly.

Internally, when we encounter an array of middleware, we create a Zend\Stratigility\MiddlewarePipe instance, and pipe each middleware service to it in order. The problem is that MiddlewarePipe does not implement the error middleware signature — which meant that error middleware pipelines were completely skipped!

To make this work, we introduced a proxy class, Zend\Expressive\ErrorMiddlewarePipe, which wraps a MiddlewarePipe, and exposes the error middleware signature. This is now used internally whenever an error middleware pipeline needs to be created.

Changes in zend-expressive-skeleton RC8

When we created the new default middleware pipeline configuration for RC6/RC7, we forgot one important detail: the error middleware group was missing its error key, meaning it wasn't attempting to create error middleware at all! We've fixed this in RC8.

If you upgraded to RC6/RC7 earlier this week, make sure you add that error key, as detailed in the above example.

Twig integration updates

Today we released version 1.0.1 of our Twig integration. This includes a few new features:

  • It adds a dependency on zend-expressive-helpers and, if the UrlHelper and ServerUrlHelper services are registered, makes new url and absolute_url template functions available.
  • It adds a new "globals" configuration sub-section for registering variables to pass to all templates.

You can read more in the Twig integration documentation.

Many thanks to Geert Eltink for these new features!

Future

Code is stabilizing, and we're seeing fewer issues hitting our issue tracker. We hope that in a week or two we can release a stable version.

If you are testing Expressive — whether for the first time, or updating an existing application — please help us prepare it for general availability!

Source

The Zend Framework community is pleased to announce the immediate availability of Expressive 1.0.0rc7 and the Expressive Skeleton and Installer 1.0.0rc8!

You can install the latest versions using Composer, via the create-project command:

$ composer create-project -s rc zendframework/zend-expressive-skeleton expressive

You can update your existing applications using:

$ composer update

This release candidate contains bug fixes for dispatching error middleware pipelines. Additionally, we've released a new version of our Twig integration, and detail those changes below.

Changes in zend-expressive RC7

RC6 updated the configuration for the middleware pipeline to make it a single pipeline. We recommended that developers make use of our middleware grouping feature, however, which allows you to specify not just a single, named middleware service, but an array of named middleware services. This feature is great for grouping middleware based on when it should execute, and makes ordering related middleware simpler.

Per our suggested, default configuration:

use Zend\Expressive\Container\ApplicationFactory;
use Zend\Expressive\Helper;

return [
    'dependencies' => [
        'factories' => [
            Helper\ServerUrlMiddleware::class => Helper\ServerUrlMiddlewareFactory::class,
            Helper\UrlHelperMiddleware::class => Helper\UrlHelperMiddlewareFactory::class,
        ],
    ],
    // This can be used to seed pre- and/or post-routing middleware
    'middleware_pipeline' => [
        // An array of middleware to register. Each item is of the following
        // specification:
        //
        // [
        //  Required:
        //     'middleware' => 'Name or array of names of middleware services and/or callables',
        //  Optional:
        //     'path'     => '/path/to/match', // string; literal path prefix to match
        //                                     // middleware will not execute
        //                                     // if path does not match!
        //     'error'    => true, // boolean; true for error middleware
        //     'priority' => 1, // int; higher values == register early;
        //                      // lower/negative == register last;
        //                      // default is 1, if none is provided.
        // ],
        //
        // While the ApplicationFactory ignores the keys associated with
        // specifications, they can be used to allow merging related values
        // defined in multiple configuration files/locations. This file defines
        // some conventional keys for middleware to execute early, routing
        // middleware, and error middleware.
        'always' => [
            'middleware' => [
                // Add more middleware here that you want to execute on
                // every request:
                // - bootstrapping
                // - pre-conditions
                // - modifications to outgoing responses
                Helper\ServerUrlMiddleware::class,
            ],
            'priority' => 10000,
        ],

        'routing' => [
            'middleware' => [
                ApplicationFactory::ROUTING_MIDDLEWARE,
                Helper\UrlHelperMiddleware::class,
                // Add more middleware here that needs to introspect the routing
                // results; this might include:
                // - route-based authentication
                // - route-based validation
                // - etc.
                ApplicationFactory::DISPATCH_MIDDLEWARE,
            ],
            'priority' => 1,
        ],

        'error' => [
            'middleware' => [
                // Add error middleware here.
            ],
            'priority' => -10000,
            'error' => true,
        ],
    ],
];

Unfortunately, for error middleware, this was not working correctly.

Internally, when we encounter an array of middleware, we create a Zend\Stratigility\MiddlewarePipe instance, and pipe each middleware service to it in order. The problem is that MiddlewarePipe does not implement the error middleware signature — which meant that error middleware pipelines were completely skipped!

To make this work, we introduced a proxy class, Zend\Expressive\ErrorMiddlewarePipe, which wraps a MiddlewarePipe, and exposes the error middleware signature. This is now used internally whenever an error middleware pipeline needs to be created.

Changes in zend-expressive-skeleton RC8

When we created the new default middleware pipeline configuration for RC6/RC7, we forgot one important detail: the error middleware group was missing its error key, meaning it wasn't attempting to create error middleware at all! We've fixed this in RC8.

If you upgraded to RC6/RC7 earlier this week, make sure you add that error key, as detailed in the above example.

Twig integration updates

Today we released version 1.0.1 of our Twig integration. This includes a few new features:

  • It adds a dependency on zend-expressive-helpers and, if the UrlHelper and ServerUrlHelper services are registered, makes new url and absolute_url template functions available.
  • It adds a new "globals" configuration sub-section for registering variables to pass to all templates.

You can read more in the Twig integration documentation.

Many thanks to Geert Eltink for these new features!

Future

Code is stabilizing, and we're seeing fewer issues hitting our issue tracker. We hope that in a week or two we can release a stable version.

If you are testing Expressive — whether for the first time, or updating an existing application — please help us prepare it for general availability!

Source

The Zend Framework community is pleased to announce the immediate availability of Expressive 1.0.0rc6 and 1.0.0rc7!

You can install the latest versions using Composer, via the create-project command:

$ composer create-project -s rc zendframework/zend-expressive-skeleton expressive

You can update your existing applications using:

$ composer update

Unfortunately, zend-expressive RC6 introduces some breaking changes. Several issues were raised that could not be handled in a fully backwards compatible fashion, and we felt they were important enough to introduce before a stable release is made. We continue to honor previous application configuration; however, deprecation notices will be raised, and the code for parsing the old configuration will be removed for the 1.1 release.

We also released zend-expressive-skeleton RC7 quick on the heels of RC6 in order to correct an issue with installation whereby the development dependencies at time of invocation were installed, rather than the rewritten ones. This affected only the skeleton, which is why we're announcing RC6 and RC7 releases.

See below for full details on what has changed.

Changes in zend-expressive RC6

Like RC5, the bulk of the changes merged for RC6 were documentation, including:

Unlike RC5, however, we introduced a significant code change, prompted by user feedback. In particular, we saw each of the following reported multiple times:

  • confusion over the pre_routing and post_routing middleware pipeline keys, and how they relate to routed middleware.
  • requests to split the routing middleware into two distinct responsibilities: routing middleware, and dispatch middleware.
  • requests to allow dispatching middleware when triggering route result observers.

On analysis, and in discussions with users, we decided to make the following changes.

Splitting the routing middleware

We split the routing middleware into two discrete methods: routing and dispatch. This solved multiple problems, and enables a number of interesting workflows.

In particular, it allows you to define middleware that can act on the routing results in order to satisify pre-conditions in an automated way.

As an example, let's say you have a workflow where you want to:

  • Authenticate a user
  • Authorize the user
  • Perform content negotiation
  • Validate incoming body parameters

However, you don't want to perform these actions for every request, only specific routes.

Previously, you would need to define an array of middleware for each route that needs this set of responsibilities:

[
    'routes' => [
        'api.ping' => [
            'path' => '/api/ping',
            'middleware' => [
                AuthenticationMiddleware::class,
                AuthorizationMiddleware::class,
                ContentNegotiationMiddleware::class,
                BodyValidationMiddleware::class,
                PingMiddleware::class,
            ],
            'allowed_methods' => ['GET'],
        ],
        'api.books' => [
            'path' => '/api/books[/{id:[a-f0-9]{8}}]',
            'middleware' => [
                AuthenticationMiddleware::class,
                AuthorizationMiddleware::class,
                ContentNegotiationMiddleware::class,
                BodyValidationMiddleware::class,
                BooksMiddleware::class,
            ],
        ],
        /* etc. */
    ],
]

This is repetitive, and prone to error: any change in the workflow requires propagation to every route.

Splitting the routing and dispatch middleware allows you to pipe middleware between the two actions, allowing you to register such workflows once. The middleware could then introspect the route results to determine if they have work to do.

This means you can now write middleware like this:

use Zend\Expressive\Router\RouteResult;

$authenticationMiddleware = function ($request, $response, $next) use ($map, $authenticate) {
    $routeResult = $request->getAttribute(RouteResult::class, false);
    if (! $routeResult instanceof RouteResult) {
        return $next($request, $response);
    }

    if (! in_array($routeResult->getMatchedRouteName(), $map)) {
        return $next($request, $response);
    }

    $authenticationResult = $authenticate($request);
    if (! $authenticationResult->isSuccess()) {
        // ERROR!
        return new AuthenticationErrorResponse();
    }

    return $next(
        $request->withAttribute($authenticationResult->getIdentity()),
        $response
    );
}

You would then sandwich it between the routing and dispatch middleware. Programmatically, that looks like:

$app->pipeRoutingMiddleware();
$app->pipe($authenticationMiddleware);
$app->pipeDispatchMiddleware();

We'll look at configuration later, as it changes more dramatically.

No more auto-registration of the routing middleware

Prior to RC6, the routing middleware was auto-registered when:

  • any call to route() was made, including those via the methods that proxy to it (get(), post(), any(), etc.).
  • as soon as the Application instance was invoked as middleware (i.e., by calling $app($request, $response) or calling $app->run()).

You could also always register it manually when creating your application pipeline using the pipeRoutingMiddleware() method.

Because routing was split into two distinct actions, and one primary purpose for doing so was to allow registering middleware between those actions, we felt that auto-registration was not only no longer useful, but a liability.

As such, when creating your application programmatically, there is now exactly one workflow to use to enable the routing and dispatch middleware: each must be piped explicitly into the pipeline:

$app->pipe(ServerUrlMiddleware::class);
$app->pipe(BaseParamsMiddleware::class);
$app->pipeRoutingMiddleware();
$app->pipe(UrlHelperMiddleware::class);
$app->pipeDispatchMiddleware();

If you are building your application programmatically, you must update it to pipe the routing and dispatch middleware in order for it to continue to work.

We'll look at configuration for the ApplicationFactory later, as it changes as well.

No more route result observers

Another consequence of splitting the routing middleware in two was a pleasant discovery: there was no longer any need for the route result observer system!

The route result observer system was added in RC3 to allow the application to notify interested observers of the results of routing, as there was no other way to trigger functionality between the act of routing and when the matched middleware was dispatched (if any was actually matched!).

Several developers complained that they couldn't return a response from these observers when they detected an error condition, nor could they introspect the request in such situations.

With the routing middleware split, there's an answer to those questions, and the observer system is no longer needed; just place middleware between the routing and dispatch middleware, and have it act on the RouteResult instance (which the routing middleware injects as a request attribute). In fact, we've already demonstrated this above!

For RC6, we removed the RouteResultSubjectInterface implementation from the Application instance, while keeping the original methods defined in that interface; these methods now trigger deprecation notices. If you were using observers previously, and keep your existing RC5 configuration, we also inject a special "route result observer middleware" between the routing and dispatch middleware that will notify the observers. The deprecation messages will prompt you to update your code, and provide a link to the migration guide to help you.

A new minor version of zend-expressive-router was released, v1.2.0, marking each of the RouteResultSubjectInterface and RouteResultObserverInterface as deprecated.

A new major version of zend-expressive-helpers was released, v2.0.0, that removes the RouteResultObserverInterface implementation from the UrlHelper, and updates its related middleware to act between the routing and dispatch middleware.

Simplified configuration

We've alluded to configuration changes several times; it's now time to detail those.

One common confusion that arose was around the pre_routing and post_routing names. Many assumed that pre_routing meant that the middleware listed only operated before routing — and did not realize that such middleware could also post-process responses. Similarly, many assumed that post_routing middleware was executed after routed middleware, even when the routed middleware returned a response (it was only executed if the routed middleware called $next() or if an error occurred).

We wanted to clarify how the middleware pipeline worked, and with the switch to split the routing and dispatch middleware, and a desire to allow injecting middleware between routing and dispatch, we had an opportunity to positiveily change the configuration to make it more clear.

Enrico suggested that instead of segregating into pre/post, we have a single pipeline. This would require defining entries for the routing and dispatch middleware as part of the pipeline, but you would then be able to see the exact workflow.

One counter-argument, however, is when merging configuration, which is done by default in the skeleton, and which is a recommended practice to keep configuration for related functionality in discrete places. How would order be preserved?

We decided to introduce a priority key into our middleware configuration specifications. This works with SplPriorityQueue: higher values are piped earlier and execute earlier, while lower/negative values are piped later. This provides the ability to define the pipeline across multiple files, merge it, and get a predictable order.

Additionally, we realized we could lever another existing feature: middleware specifications used by the pipeline configuration allow you to specify lists of middleware to execute, not just individual middleware. This means that you can group middleware under the same priority, in the order you want it to execute. This is a great technique for segregating configuration.

What we came up with ends up looking like this when you start out with the new skeleton:

use Zend\Expressive\Container\ApplicationFactory;
use Zend\Expressive\Helper;

return [
    'dependencies' => [
        'factories' => [
            Helper\ServerUrlMiddleware::class => Helper\ServerUrlMiddlewareFactory::class,
            Helper\UrlHelperMiddleware::class => Helper\UrlHelperMiddlewareFactory::class,
        ],
    ],
    // This can be used to seed pre- and/or post-routing middleware
    'middleware_pipeline' => [
        // An array of middleware to register. Each item is of the following
        // specification:
        //
        // [
        //  Required:
        //     'middleware' => 'Name or array of names of middleware services and/or callables',
        //  Optional:
        //     'path'     => '/path/to/match', // string; literal path prefix to match
        //                                     // middleware will not execute
        //                                     // if path does not match!
        //     'error'    => true, // boolean; true for error middleware
        //     'priority' => 1, // int; higher values == register early;
        //                      // lower/negative == register last;
        //                      // default is 1, if none is provided.
        // ],
        //
        // While the ApplicationFactory ignores the keys associated with
        // specifications, they can be used to allow merging related values
        // defined in multiple configuration files/locations. This file defines
        // some conventional keys for middleware to execute early, routing
        // middleware, and error middleware.
        'always' => [
            'middleware' => [
                // Add more middleware here that you want to execute on
                // every request:
                // - bootstrapping
                // - pre-conditions
                // - modifications to outgoing responses
                Helper\ServerUrlMiddleware::class,
            ],
            'priority' => 10000,
        ],

        'routing' => [
            'middleware' => [
                ApplicationFactory::ROUTING_MIDDLEWARE,
                Helper\UrlHelperMiddleware::class,
                // Add more middleware here that needs to introspect the routing
                // results; this might include:
                // - route-based authentication
                // - route-based validation
                // - etc.
                ApplicationFactory::DISPATCH_MIDDLEWARE,
            ],
            'priority' => 1,
        ],

        'error' => [
            'middleware' => [
                // Add error middleware here.
            ],
            'priority' => -10000,
        ],
    ],
];

For existing users:

  • Existing RC5 and earlier configuration is still honored, but will emit deprecation notices, prompting you to update; these notices include links to the migration guide.
  • To update, you'll need to:
    • update your zend-expressive-helpers version constraint to ^2.0.
    • update your configuration, using the above as a guide.

We're excited about this change, as we feel it simplifies the configuration, adds flexibility, and provides predictability in the system. While it is a large change for a release candidate, we also felt it was important enough to warrant introducing before the stable release.

Full migration details

The above narrative is use-case-centered. We have, however, published a full migration guide as part of the release to give exact details on changes you will need to make.

Future

At this point, we feel that the code has stabilized significantly, and that the improvements in these latest releases have provided important simplicity and flexibility to make the system robust. We'll be waiting a week or two to see how you, our users, respond, and hopefully be able to tag a stable release shortly!

If you are testing Expressive — whether for the first time, or updating an existing application — please help us prepare it for general availability!

Source

The Zend Framework community is pleased to announce the immediate availability of Expressive 1.0.0rc6 and 1.0.0rc7!

You can install the latest versions using Composer, via the create-project command:

$ composer create-project -s rc zendframework/zend-expressive-skeleton expressive

You can update your existing applications using:

$ composer update

Unfortunately, zend-expressive RC6 introduces some breaking changes. Several issues were raised that could not be handled in a fully backwards compatible fashion, and we felt they were important enough to introduce before a stable release is made. We continue to honor previous application configuration; however, deprecation notices will be raised, and the code for parsing the old configuration will be removed for the 1.1 release.

We also released zend-expressive-skeleton RC7 quick on the heels of RC6 in order to correct an issue with installation whereby the development dependencies at time of invocation were installed, rather than the rewritten ones. This affected only the skeleton, which is why we're announcing RC6 and RC7 releases.

See below for full details on what has changed.

Changes in zend-expressive RC6

Like RC5, the bulk of the changes merged for RC6 were documentation, including:

Unlike RC5, however, we introduced a significant code change, prompted by user feedback. In particular, we saw each of the following reported multiple times:

  • confusion over the pre_routing and post_routing middleware pipeline keys, and how they relate to routed middleware.
  • requests to split the routing middleware into two distinct responsibilities: routing middleware, and dispatch middleware.
  • requests to allow dispatching middleware when triggering route result observers.

On analysis, and in discussions with users, we decided to make the following changes.

Splitting the routing middleware

We split the routing middleware into two discrete methods: routing and dispatch. This solved multiple problems, and enables a number of interesting workflows.

In particular, it allows you to define middleware that can act on the routing results in order to satisify pre-conditions in an automated way.

As an example, let's say you have a workflow where you want to:

  • Authenticate a user
  • Authorize the user
  • Perform content negotiation
  • Validate incoming body parameters

However, you don't want to perform these actions for every request, only specific routes.

Previously, you would need to define an array of middleware for each route that needs this set of responsibilities:

[
    'routes' => [
        'api.ping' => [
            'path' => '/api/ping',
            'middleware' => [
                AuthenticationMiddleware::class,
                AuthorizationMiddleware::class,
                ContentNegotiationMiddleware::class,
                BodyValidationMiddleware::class,
                PingMiddleware::class,
            ],
            'allowed_methods' => ['GET'],
        ],
        'api.books' => [
            'path' => '/api/books[/{id:[a-f0-9]{8}}]',
            'middleware' => [
                AuthenticationMiddleware::class,
                AuthorizationMiddleware::class,
                ContentNegotiationMiddleware::class,
                BodyValidationMiddleware::class,
                BooksMiddleware::class,
            ],
        ],
        /* etc. */
    ],
]

This is repetitive, and prone to error: any change in the workflow requires propagation to every route.

Splitting the routing and dispatch middleware allows you to pipe middleware between the two actions, allowing you to register such workflows once. The middleware could then introspect the route results to determine if they have work to do.

This means you can now write middleware like this:

use Zend\Expressive\Router\RouteResult;

$authenticationMiddleware = function ($request, $response, $next) use ($map, $authenticate) {
    $routeResult = $request->getAttribute(RouteResult::class, false);
    if (! $routeResult instanceof RouteResult) {
        return $next($request, $response);
    }

    if (! in_array($routeResult->getMatchedRouteName(), $map)) {
        return $next($request, $response);
    }

    $authenticationResult = $authenticate($request);
    if (! $authenticationResult->isSuccess()) {
        // ERROR!
        return new AuthenticationErrorResponse();
    }

    return $next(
        $request->withAttribute($authenticationResult->getIdentity()),
        $response
    );
}

You would then sandwich it between the routing and dispatch middleware. Programmatically, that looks like:

$app->pipeRoutingMiddleware();
$app->pipe($authenticationMiddleware);
$app->pipeDispatchMiddleware();

We'll look at configuration later, as it changes more dramatically.

No more auto-registration of the routing middleware

Prior to RC6, the routing middleware was auto-registered when:

  • any call to route() was made, including those via the methods that proxy to it (get(), post(), any(), etc.).
  • as soon as the Application instance was invoked as middleware (i.e., by calling $app($request, $response) or calling $app->run()).

You could also always register it manually when creating your application pipeline using the pipeRoutingMiddleware() method.

Because routing was split into two distinct actions, and one primary purpose for doing so was to allow registering middleware between those actions, we felt that auto-registration was not only no longer useful, but a liability.

As such, when creating your application programmatically, there is now exactly one workflow to use to enable the routing and dispatch middleware: each must be piped explicitly into the pipeline:

$app->pipe(ServerUrlMiddleware::class);
$app->pipe(BaseParamsMiddleware::class);
$app->pipeRoutingMiddleware();
$app->pipe(UrlHelperMiddleware::class);
$app->pipeDispatchMiddleware();

If you are building your application programmatically, you must update it to pipe the routing and dispatch middleware in order for it to continue to work.

We'll look at configuration for the ApplicationFactory later, as it changes as well.

No more route result observers

Another consequence of splitting the routing middleware in two was a pleasant discovery: there was no longer any need for the route result observer system!

The route result observer system was added in RC3 to allow the application to notify interested observers of the results of routing, as there was no other way to trigger functionality between the act of routing and when the matched middleware was dispatched (if any was actually matched!).

Several developers complained that they couldn't return a response from these observers when they detected an error condition, nor could they introspect the request in such situations.

With the routing middleware split, there's an answer to those questions, and the observer system is no longer needed; just place middleware between the routing and dispatch middleware, and have it act on the RouteResult instance (which the routing middleware injects as a request attribute). In fact, we've already demonstrated this above!

For RC6, we removed the RouteResultSubjectInterface implementation from the Application instance, while keeping the original methods defined in that interface; these methods now trigger deprecation notices. If you were using observers previously, and keep your existing RC5 configuration, we also inject a special "route result observer middleware" between the routing and dispatch middleware that will notify the observers. The deprecation messages will prompt you to update your code, and provide a link to the migration guide to help you.

A new minor version of zend-expressive-router was released, v1.2.0, marking each of the RouteResultSubjectInterface and RouteResultObserverInterface as deprecated.

A new major version of zend-expressive-helpers was released, v2.0.0, that removes the RouteResultObserverInterface implementation from the UrlHelper, and updates its related middleware to act between the routing and dispatch middleware.

Simplified configuration

We've alluded to configuration changes several times; it's now time to detail those.

One common confusion that arose was around the pre_routing and post_routing names. Many assumed that pre_routing meant that the middleware listed only operated before routing — and did not realize that such middleware could also post-process responses. Similarly, many assumed that post_routing middleware was executed after routed middleware, even when the routed middleware returned a response (it was only executed if the routed middleware called $next() or if an error occurred).

We wanted to clarify how the middleware pipeline worked, and with the switch to split the routing and dispatch middleware, and a desire to allow injecting middleware between routing and dispatch, we had an opportunity to positiveily change the configuration to make it more clear.

Enrico suggested that instead of segregating into pre/post, we have a single pipeline. This would require defining entries for the routing and dispatch middleware as part of the pipeline, but you would then be able to see the exact workflow.

One counter-argument, however, is when merging configuration, which is done by default in the skeleton, and which is a recommended practice to keep configuration for related functionality in discrete places. How would order be preserved?

We decided to introduce a priority key into our middleware configuration specifications. This works with SplPriorityQueue: higher values are piped earlier and execute earlier, while lower/negative values are piped later. This provides the ability to define the pipeline across multiple files, merge it, and get a predictable order.

Additionally, we realized we could lever another existing feature: middleware specifications used by the pipeline configuration allow you to specify lists of middleware to execute, not just individual middleware. This means that you can group middleware under the same priority, in the order you want it to execute. This is a great technique for segregating configuration.

What we came up with ends up looking like this when you start out with the new skeleton:

use Zend\Expressive\Container\ApplicationFactory;
use Zend\Expressive\Helper;

return [
    'dependencies' => [
        'factories' => [
            Helper\ServerUrlMiddleware::class => Helper\ServerUrlMiddlewareFactory::class,
            Helper\UrlHelperMiddleware::class => Helper\UrlHelperMiddlewareFactory::class,
        ],
    ],
    // This can be used to seed pre- and/or post-routing middleware
    'middleware_pipeline' => [
        // An array of middleware to register. Each item is of the following
        // specification:
        //
        // [
        //  Required:
        //     'middleware' => 'Name or array of names of middleware services and/or callables',
        //  Optional:
        //     'path'     => '/path/to/match', // string; literal path prefix to match
        //                                     // middleware will not execute
        //                                     // if path does not match!
        //     'error'    => true, // boolean; true for error middleware
        //     'priority' => 1, // int; higher values == register early;
        //                      // lower/negative == register last;
        //                      // default is 1, if none is provided.
        // ],
        //
        // While the ApplicationFactory ignores the keys associated with
        // specifications, they can be used to allow merging related values
        // defined in multiple configuration files/locations. This file defines
        // some conventional keys for middleware to execute early, routing
        // middleware, and error middleware.
        'always' => [
            'middleware' => [
                // Add more middleware here that you want to execute on
                // every request:
                // - bootstrapping
                // - pre-conditions
                // - modifications to outgoing responses
                Helper\ServerUrlMiddleware::class,
            ],
            'priority' => 10000,
        ],

        'routing' => [
            'middleware' => [
                ApplicationFactory::ROUTING_MIDDLEWARE,
                Helper\UrlHelperMiddleware::class,
                // Add more middleware here that needs to introspect the routing
                // results; this might include:
                // - route-based authentication
                // - route-based validation
                // - etc.
                ApplicationFactory::DISPATCH_MIDDLEWARE,
            ],
            'priority' => 1,
        ],

        'error' => [
            'middleware' => [
                // Add error middleware here.
            ],
            'priority' => -10000,
        ],
    ],
];

For existing users:

  • Existing RC5 and earlier configuration is still honored, but will emit deprecation notices, prompting you to update; these notices include links to the migration guide.
  • To update, you'll need to:
    • update your zend-expressive-helpers version constraint to ^2.0.
    • update your configuration, using the above as a guide.

We're excited about this change, as we feel it simplifies the configuration, adds flexibility, and provides predictability in the system. While it is a large change for a release candidate, we also felt it was important enough to warrant introducing before the stable release.

Full migration details

The above narrative is use-case-centered. We have, however, published a full migration guide as part of the release to give exact details on changes you will need to make.

Future

At this point, we feel that the code has stabilized significantly, and that the improvements in these latest releases have provided important simplicity and flexibility to make the system robust. We'll be waiting a week or two to see how you, our users, respond, and hopefully be able to tag a stable release shortly!

If you are testing Expressive — whether for the first time, or updating an existing application — please help us prepare it for general availability!

Source

This is an installment in an ongoing series of bi-weekly posts on ZF3 development status.

Following a roughly two week hiatus at the end of the year, we've picked up where we left off and continued the momentum towards the ZF3 initiatives.

The highlights:

  • 48 pull requests merged
  • 11 releases of components, including 3 3.0 releases in 3 days!
  • 6 components updated to zend-servicemanager/zend-eventmanager v3 changes
  • Major updates for an upcoming Expressive RC6

3.0 Releases!

A number of components reached stability in the past few weeks, and this week we did a spree of three 3.0 releases in three days:

  • zend-servicemanager 3.0.0 is the first 3.0 release of any ZF components, and features a complete rewrite of the internals to provide up to 4x faster performance! We have been careful to retain as much backwards compatibility as possible, and the v2.7.0 release provides features that make migration between versions seamless for users. A migration guide is available.
  • zend-eventmanager 3.0.0 is our second 3.0 release of a ZF component, and features a complete rewrite of the internals of the EventManager implementation to provide up to 4X faster performance. By following the migration guide, you can update your v2 code to work on both v2 and v3.
  • zend-code 3.0.0 is our third 3.0 release of a ZF component, and features updates to allow usage with PHP 5.5, 5.6, and PHP 7, and, specifically, scalar typehints, return typehints, generators, and variadics.

Be aware that you cannot make use of these new 3.0 versions within existing ZF2 applications quite yet; we are still in the process of updating components to work with these releases. However, they can be used standalone, or within projects based on Expressive!

Pull request activity

Since the last update, we've merged 48 pull requests (link requires a GitHub account). Activity has been particularly high on Expressive, zend-servicemanager, and components refactoring to the latest zend-servicemanager and zend-eventmanager updates.

Component Releases

The following is a list of component releases (other than the 3.0 releases listed above) since the last update. While not all releases are related to ZF3 specifically, this list is intended to detail activity within the organization.

  • zend-expressive-helpers 1.4.0 adds base path support to the UrlHelper.
  • Diactoros 1.3.3 fixes an issue in ServerRequestFactory::marshalHeaders() whereby we were explicitly omitting cookie headers; they are now aggregated.
  • zend-expressive-zendrouter 1.0.1 fixes an issue whereby appending a trailing slash when requesting a route that did not define one resulted in a 405 instead of a 404 error.
  • zend-servicemanager 2.7.0, zend-servicemanager 2.7.1, zend-servicemanager 2.7.2, and zend-servicemanager 2.7.3 are forwards-compatibility releases, providing several features that allow users to update their code to work with both the v2 and v3 series of the service manager.
  • zend-eventmanager 2.6.2 introduces a trait, EventListenerIntrospectionTrait, for use with PHPUnit test cases. It provides a consistent API for introspecting what events and listeners are attached to an EventManager instance, and provides a custom assertion for validating that a given listener is registered at a given priority on a given event. This trait can be used to write assertions for validating listener attachment in a way that will be forwards compatible with version 3.

ZF3 Refactors

Since the last update, the following components have been refactored to work with the planned v3 versions of zend-servicemanager and zend-eventmanager. Please note that no new versions have been released at this time; all work remains either in pull requests or in the develop branches of each component.

Additionally, we have created pull requests for several components to work with the forwards compatibility releases of zend-servicemanager and zend-eventmanager. These will allow us to release 2.x versions of these components that can be used by code consuming the v3 versions of those two components.

Expressive

We've had quite a number of people testing Expressive heavily, and pointing out both its strengths and weaknesses. This has resulted in a ton of additional tests, bringing coverage to 100% in some cases, as well as copious amounts of new documentation.

After several issue threads and IRC conversations, we've decided to release an additional RC, RC6, to accomplish the following:

  • Simplification of the middleware pipeline; we will be doing away with the pre_routing and post_routing keys, and allowing a single pipeline representing the entire application lifecycle.
  • Splitting of the routing middleware into separate routing and dispatch middleware. This allows developers to tie into the application lifecycle using middleware between routing and dispatch, facilitating such things as route-based authentication, validation, etc.
  • Removal of auto-registration of the routing middleware; this is done to allow substituting alternative routing middleware and/or dispatch middleware.
  • Deprecation of the route result observer system. The same functionality can now be accomplished with middleware that acts between routing and dispatch.

We've attempted to preserve backwards compatibility for existing applications, but have marked deprecated features for removal with 1.1. A migration guide will assist our early adopters in updating their applications.

Until next time

If you want to help:

Many thanks to all the contributors who have provided feedback, patches, reviews, or releases! In particular, I want to call out:

  • Marco Pivetta for his work on updating zend-code to work with PHP 7 (and PHP 5.5, and PHP 5.6) features.
  • Michaël Gallego for his work on the zend-servicemanager and zend-eventmanager refactors, and his relentless pursuit of performance increases.
  • Enrico Zimuel for his work on the zend-eventmanager refactor, and taking on the drudgery of updating components to the new zend-eventmanager and zend-servicemanager changes.
  • Ralf Eggert and Daniel Gimenes for the constant stream of questions and suggestions for Expressive; their feedback is changing it for the better!

Source