The Zend Framework community is pleased to announce the immediate availability of Zend Framework 1.12.20! Packages and installation instructions are available at:

Changelog

This release includes a single security patch, reported as ZF2016-03, for SQL injection vulnerabilities in the Zend_Db_Select::order() and Zend_Db_Select::group() methods. If you use these, we recommend updating immedaitely.

To see the complete set of issues resolved for 1.12.20, please visit the changelog:

End of Life

As announced previously, Zend Framework 1 will reach its end of life on 28 September 2016, and only receive security fixes between now and that date. Past that point, we will offer custom bug and security fixes for Zend Framework 1 on-demand only to Enterprise users of Zend Server.

Thank You!

Many thanks to Enrico Zimuel for his efforts in developing the security patch for this release!

Source

ZF2016-03: Potential SQL injection in ORDER and GROUP functions of ZF1

The implementation of ORDER BY and GROUP BY in Zend_Db_Select remained prone to SQL injection when a combination of SQL expressions and comments were used. This security patch provides a comprehensive solution that identifies and removes comments prior to checking validity of the statement to ensure no SQLi vectors occur.

The implementation of ORDER BY and GROUP BY in Zend_Db_Select of ZF1 is vulnerable by the following SQL injection:

$db = Zend_Db::factory(/* options here */);
$select = new Zend_Db_Select($db);
$select->from('p');
$select->order("MD5(\"a(\");DELETE FROM p2; #)"); // same with group()

The above $select will render the following SQL statement:

SELECT `p`.* FROM `p` ORDER BY MD5("a(");DELETE FROM p2; #) ASC

instead of the correct one:

SELECT "p".* FROM "p" ORDER BY "MD5(""a("");DELETE FROM p2; #)" ASC

This security fix can be considered an improvement of the previous ZF2016-02 and ZF2014-04 advisories.

As a final consideration, we recommend developers either never use user input for these operations, or filter user input thoroughly prior to invoking Zend_Db. You can use the Zend_Db_Select::quoteInto() method to filter the input data, as shown in this example:

$db    = Zend_Db::factory(...);
$input = "MD5(\"a(\");DELETE FROM p2; #)"; // user input can be an attack
$order = $db->quoteInto("SQL statement for ORDER", $input);

$select = new Zend_Db_Select($db);
$select->from('p');
$select->order($order); // same with group()

Action Taken

We fixed the reported SQL injection by removing comments from the SQL statement before passing it to either the order() or group() methods; this patch effectively solves any comment-based SQLi vectors.

We used the following regex to remove comments from a SQL statement:

const REGEX_SQL_COMMENTS = '@
    (([\'"]).*?[^\\\]\2) # $1 : Skip single & double quoted expressions
    |(                   # $3 : Match comments
        (?:\#|--).*?$    # - Single line comments
        |                # - Multi line (nested) comments
         /\*             #   . comment open marker
            (?: [^/*]    #   . non comment-marker characters
                |/(?!\*) #   . ! not a comment open
                |\*(?!/) #   . ! not a comment close
                |(?R)    #   . recursive case
            )*           #   . repeat eventually
        \*\/             #   . comment close marker
    )\s*                 # Trim after comments
    |(?<=;)\s+           # Trim after semi-colon
    @msx';

The patch is available starting in Zend Framework 1.12.20.

Other Information

This SQL injection attack does not affect Zend Framework 2 and 3 versions because the implementations of Zend\Db\Sql\Select::order() and Zend\Db\Sql\Select::group() do not manage parenthetical expressions.

Acknowledgments

The Zend Framework team thanks the following for identifying the issues and working with us to help protect its users:

  • Hiroshi Tokumaru (HASH Consulting Corp.), who discovered the issue;
  • Masanobu Katagi (Japan Computer Emergency Response Team Coordination Center), who reported the issue;
  • Enrico Zimuel, who provided the patch.

Source

Recently, we released zend-crypt 3.1.0, the cryptographic component from Zend Framework. This last version includes a hybrid cryptosystem, a feature that can be used to implement end-to-end encryption schema in PHP.

A hybrid cryptosystem is a cryptographic mechanism that uses symmetric encyption (e.g. AES) to encrypt a message, and public-key cryptography (e.g. RSA) to protect the encryption key. This methodology guarantee two advantages: the speed of a symmetric algorithm and the security of public-key cryptography.

Before we talk about the PHP implementation, let's explore the hybrid mechanism in more detail. Below is a diagram demonstrating a hybrid encryption schema:

Encryption schema

A user (the sender) wants to send a protected message to another user (the receiver). He/she generates a random session key (one-time pad) and uses this key with a symmetric algorithm to encrypt the message (in the figure, Block cipher represents an authenticated encryption algorithm). At the same time, the sender encrypts the session key using the public key of the receiver. This operation is done using a public-key algorithm, e.g., RSA. Once the encryption is done, the sender can send the encrypted session key along with the encrypted message to the receiver. The receiver can decrypt the session key using his/her private key, and consequently decrypt the message.

This idea of combining together symmetric and asymmetric (public-key) encryption can be used to implement end-to-end encryption (E2EE). An E2EE is a communication system that encrypts messages exchanged by two users with the property that only the two users can decrypt the message. End-to-end encryption has become quite popular in the last years with the usage in popular software, and particularly messaging systems, such as WhatsApp. More generally, when you have a software used by many users, end-to-end encryption can be used to protect information exchanged by users. Only the users can access (decrypt) exchanged information; even the administrator of the system is not able to access this data.

Build end-to-end encryption in PHP

We want to implement end-to-end encryption for a web application with user authentication. We will use zend-crypt 3.1.0 to implement our cryptographic schemas. This component of Zend Framework uses the OpenSSL extension for PHP for its cryptographic primitives.

The first step is to create public and private keys for each users. Typically, this step can be done when the user credentials are created. To generare the pairs of keys, we can use Zend\Crypt\PublicKey\RsaOptions. Below is an example demonstrating how to generate public and private keys to store in the filesystem:

use Zend\Crypt\PublicKey\RsaOptions;
use Zend\Crypt\BlockCipher;

$username = 'alice';
$password = 'test'; // user's password

// Generate public and private key
$rsaOptions = new RsaOptions();
$rsaOptions->generateKeys([
    'private_key_bits' => 2048
]);
$publicKey  = $rsaOptions->getPublicKey()->toString();
$privateKey = $rsaOptions->getPrivateKey()->toString();

// store the public key in a .pub file
file_put_contents($username . '.pub', $publicKey);

// encrypt and store the private key in a file
$blockCipher = BlockCipher::factory('openssl', array('algo' => 'aes'));
$blockCipher->setKey($password);
file_put_contents($username, $blockCipher->encrypt($privateKey));

In the above example, we generated a private key of 2048 bits. If you are wondering why not 4096 bits, this is questionable and depends on the real use case. For the majority of applications, 2048 is still a good key size, at least until 2030. If you want more security and you don't care about the additional CPU time, you can increase the key size to 4096. We suggest reading the following blog posts for more information on key key size:

We did not generate the private key using a passphrase; this is because the OpenSSL extension of PHP does not support AEAD (Authenticated Encrypt with Associated Data) mode yet; AEAD mode will be supported starting in PHP 7.1, which should release this autumn.

The default passphrase encryption algorithm for OpenSSL is des-ede3-cbc using PBKDF2 with 2048 iterations for generating the encryption key from the user's password. Even if this encryption algorithm is quite good, the number of iterations of PBKDF2 is not optimal; zend-crypt improves on this in a variety of ways, out-of-the-box. As demonstrated above, we use Zend\Crypt\BlockCipher to encrypt the private key; this class provides encrypt-then-authenticate using the AES-256 algorithm for encryption and HMAC-SHA-256 for authentication. Moreover, BlockCipher uses the PBKDF2 algorithm to derivate the encryption key from the user's key (password). The default number of iterations for PBKDF2 is 5000, and you can increase it using the BlockCipher::setKeyIteration() method.

In the example, we stored the public and private keys in two files named, respectively, $username.pub and $username. Because the private file is encrypted, using the user's password, it can be access only by the user. This is a very important aspect for the security of the entire system (we take for granted that the web application stores the hashes of the user's passwords using a secure algorithm such as bcrypt).

Once we have the public and private keys for the users, we can start using the hybrid cryptosystem provided by zend-crypt. For instance, imagine Alice wants to send an encrypted message to Bob:

use Zend\Crypt\Hybrid;
use Zend\Crypt\BlockCipher;

$sender   = 'alice';
$receiver = 'bob';
$password = 'test'; // bob's password

$msg = sprintf('A secret message from %s!', $sender);

// encrypt the message using the public key of the receiver
$publicKey  = file_get_contents($receiver . '.pub');
$hybrid     = new Hybrid();
$ciphertext = $hybrid->encrypt($msg, $publicKey);

// send the ciphertext to the receiver

// decrypt the private key of bob
$blockCipher = BlockCipher::factory('openssl', ['algo' => 'aes']);
$blockCipher->setKey($password);
$privateKey = $blockCipher->decrypt(file_get_contents($receiver));

$plaintext = $hybrid->decrypt($ciphertext, $privateKey);

printf("%s\n", $msg === $plaintext ? "The message is: $msg" : 'Error!');

The above example demonstrates encrypting information between two users. Of course, in this case, the sender (Alice) knows the message because she wrote it. More in general, if we need to store a secret between multiple users, we need to specify the public keys to be used for encryption.

The hybrid component of zend-crypt supports encrypting messages for multiple recipients. To do so, pass an array of public keys in the $publicKey parameter of Zend\Crypt\Hybrid::encrypt($data, $publicKey).

Below demonstrates encrypting a file for two users, Alice and Bob.

use Zend\Crypt\Hybrid;
use Zend\Crypt\BlockCipher;

$data    = file_get_contents('path/to/file/to/protect');
$pubKeys = [
  'alice' => file_get_contents('alice.pub'),
  'bob'   => file_get_contents('bob.pub')
];

$hybrid     = new Hybrid();

// Encrypt using the public keys of both alice and bob
$ciphertext = $hybrid->encrypt($data, $pubKeys);

file_put_contents('file.enc', $ciphertext);

$blockCipher = BlockCipher::factory('openssl', ['algo' => 'aes']);

$passwords = [
  'alice' => 'password of Alice',
  'bob'   => 'password of Bob'
];

// decrypt using the private keys of alice and bob, one at time
foreach ($passwords as $id => $pass) {
  $blockCipher->setKey($pass);
  $privateKey = $blockCipher->decrypt(file_get_contents($id));
  $plaintext  = $hybrid->decrypt($ciphertext, $privateKey, null, $id);
  printf("%s for %s\n", $data === $plaintext ? 'Decryption ok' : 'Error', $id);
}

For decryption, we used a hard coded password for the users. Usually, the user's password is provided during the login process of a web application and should not be stored as permanent data; for instance, the user's password can be saved in a PHP session variable for temporary usage. If you use sessions to save the user's password, ensure that data is protected; the PHP-Secure-Session library or the Suhosin PHP extension will help you do so.

To decrypt the file we used the Zend\Crypt\Hybrid::decrypt() function, where we specified the $privateKey, a null passphrase, and finally the $id of the privateKey. This parameters are necessary to find the correct key to use in the header of the encrypted message.

Source

We are pleased to announce the immediate availability of Apigility 1.4.0!

This is our first minor release in over a year, and our largest, feature-wise, to date!

Zend Framework 3 Support

Six weeks ago, we announce Zend Framework 3 availablility. Our efforts since then have been focused on making all Apigility modules forwards compatible with version 3 releases of Zend Framework components. This touched on every Apigility component, and required the addition of a couple new components as well to help with migration.

This update also means that Apigility has adopted the same minimum supported PHP version as Zend Framework itself: 5.6. If you are using an earlier version of PHP, we recommend updating as soon as possible, as earlier versions are no longer supported by the PHP project.

The main takeaway to know is: you can upgrade your existing Apigility applications now, and they will continue to work, albeit with a number of bugfixes and new features!

Upgrade script

Additionally, once you've verified your application is working, we have provided a script to update your application to take advantage of Zend Framework v3 components and reduce the overall dependency footprint of your application!

$ ./vendor/bin/apigility-upgrade-to-1.5

(The 1.5 here refers to the internal version of the zf-apigility-admin module, in which this script is defined.)

Once you've run that script, you will be pinned to version 3 Zend Framework component releases, and no longer have a dependency on the full ZF metapackage.

There are other things you can do as well to modernize your application, and we have created a comprehensive migration document for 1.4 detailing the changes.

New Apigility skeleton

We decided to mondernize the Apigility skeleton in the same way that we updated the Zend Framework skeleton application. In particular:

  • Adopting PSR-4 directory structure for the shipped Application module.
  • Providing unit tests for the shipped Application module.
  • Removal of i18n features.
  • Enabling PSR-4 Apigility module structure by default.
  • Enabling usage of short array syntax in Apigility-generated configuration files by default.
  • Enabling usage of ::class notation in Apigility-generated configuration files by default.
  • Usage of zfcampus/zf-asset-manager for asset management by default.
  • Addition of zfcampus/zf-composer-autoloading as a development requirement, to facilitate enabling Composer-based autoloading of your Apigility (or Zend Framework) modules.
  • Addition of zendframework/zend-component-installer, to automate registration of ZF components and modules with Apigility applications.
  • Addition of several Composer scripts for working with development mode, serving your application via the PHP built-in web server, and running QA tools.
  • New vagrant and docker-compose configuration based on Ubuntu 16.04 and PHP 7.

The new skeleton updates Apigility applications to use modern approaches to PHP application structure, and provides better tooling around usage of virtual machines and containers in the development workflow.

Improvements

This release wraps new releases of every Apigility module. Notable features of these modules include:

  • zf-apigility
    • Support in ZF\Apigility\Application for handling PHP 7 Throwables.
  • zf-apigility-admin
    • Extracts all factories defined in the Module class to their own classes.
    • Extracts all listeners defined in the Module class to their own classes.
    • Adds a patchList() stub to the REST resource class template, so that it is present by default.
    • Adds support for working with modules using PSR-4 directory format, and the ability to generate PSR-4-style modules.
    • Adds a vendor script, apigility-upgrade-to-1.5, for upgrading an existing Apigility application so that it may use Zend Framework component v3 releases.
    • Adds the ability to generate all configuration files using short array syntax and ::class notation.
    • Adds a new API endpoint for reporting the current Apigility skeleton version.
  • zf-apigility-admin-ui
    • Displays the current Apigility skeleton version as returned by the zf-apigility-admin API.
    • Uses full controller service names when interacting with the zf-apigility-admin API; this resolves some lingering UI issues due to version mismatch.
    • Adds a "field type" input to new field entries, allowing you to provide this information via the UI (previously the information could only be provided by manually updating configuration files). This allows communicating field type information to documentation systems such as Swagger.
    • Numerous UI fixes, particularly with regards to sidebar behavior.
  • zf-apigility-documentation
    • Adds support for displaying documentation of APIs in nested PHP namespaces.
    • Adds support for transforming Markdown documentation to HTML, and enables it by default.
    • Displays field types, if provided, by default.
  • zf-apigility-provider
    • Deprecates the Module class. You no longer need to list the ZF\Apigility\Provider module in your application module configuration.
  • zf-configuration
    • Adds a new configuration switch, zf-configuration.class_name_scalars, allowing you to configure whether or not generated configuration will use ::class notation.
  • zf-console
    • Adds the ability to substitute your own dispatcher via the ZF\Console\DispatcherInterface
    • Adds the ability to disable output of the application banner.
    • Adds the ability to compose a container-interop container with the dispatcher, which allows providing service names as console handlers.
    • The exception handler now catches PHP 7 Throwable instances as well.
  • zf-content-validation
    • Adds support for mapping input filters to GET requests. This feature is not yet supported in the admin UI, however.
  • zf-hal
    • Adds an interface, concrete classes, and configuration for allowing alternate "self" and generic link generation strategies. As such, usage of the server url and url helpers with the Hal plugin is now deprecated.
    • Adds service factories for the two link extraction services, allowing the ability to provide alternate facilities if needed.
    • Adds a new method to the Hal plugin, resetEntityHashStack(); this can be used when rendering multiple responses or payloads within the same request cycle to allow re-use of the same entity instances.
  • zf-http-cache
    • Adds ETag support, with configurable hashing.
    • Adds more capabilities aroudn matching routed controllers.
  • zf-oauth2
    • Adds support for the ext/mongodb extension.
    • Adds token revocation suport.

New modules

Two new modules were added to Apigility:

  • zfcampus/zf-asset-manager uses configuration from rwoverdijk/assetmanager to expose asset directories in the document root of your application. It acts as a Composer plugin, and copies configured asset directories under your public/ directory, adding an entry to that directory's .gitignore file to prevent checking those files into version control. Updates to modules are honored, and removal of a module will remove the files from your source tree.
  • zfcampus/zf-composer-autoloading will add an autoloading entry to your Composer configuration for the module you specify, and then update autoloading rules locally. This package can be used with any Zend Framework application!

Doctrine support

At this time, Doctrine support for Apigility has not yet been updated. Contributors and collaborators are working with the Doctrine team to ensure the various Zend Framework modules they maintain are updated to work with Zend Framework component v3 releases, while working in parallel on zf-apigility-doctrine and zf-doctrine-querybuilder. We hope to announce support for these in the next few weeks.

Upgrading to the latest versions of Apigility modules, however, should allow you to continue using Doctrine features; you will simply be constrained to Zend Framework component v2 releases.

Thank You!

We had a number of contributors to this release, but wish to call out two individuals in particular:

  • Adam Grabek provided the initial pull requests implementing Zend Framework v3 support for around a half-dozen or more modules, and maintained a checklist monitoring progress.
  • Michal (webimpress) Bundyra provided a number of compatibility patches, bugfixes, features, and, most notably, innumerable hours of testing and collaboration towards finalizing the skeleton changes.

To everyone who has contributed patches, features, feedback, and documentation: thank you!

Source

The Zend Framework community is pleased to announce the immediate availability of Zend Framework 1.12.19! Packages and installation instructions are available at:

Changelog

This release includes a single security patch, reported as ZF2016-02, for SQL injection vulnerabilities in the Zend_Db_Select::order() and Zend_Db_Select::group() methods. If you use these, we recommend updating immedaitely.

To see the complete set of issues resolved for 1.12.2, please visit the changelog:

Thank You!

Many thanks to all contributors to this release!

Source

ZF2016-02: Potential SQL injection in ORDER and GROUP statements of Zend_Db_Select

The implementation of ORDER BY and GROUP BY in Zend_Db_Select of ZF1 is vulnerable by the following SQL injection:

$db = Zend_Db::factory(/* options here */);
$select = new Zend_Db_Select($db);
$select->from('p');
$select->order("MD5(\"(\");DELETE FROM p2; #)"); // same with group()

The above $select will render the following SQL statement:

SELECT `p`.* FROM `p` ORDER BY MD5("");DELETE FROM p2; #) ASC

instead of the correct one:

SELECT `p`.* FROM `p` ORDER BY "MD5("""");DELETE FROM p2; #)" ASC

This security fix can be considered as an improvement of the previous ZF2014-04.

Action Taken

We fixed the reported SQL injection using two regular expressions for the order() and the group() methods in Zend_Db_Select, created as the class constants REGEX_COLUMN_EXPR_ORDER and REGEX_COLUMN_EXPR_GROUP, respectively. These are defined as:

/^([\w]+\s*\(([^\(\)]|(?1))*\))$/

This regexp is different from the previous REGEX_COLUMN_EXPR, which used the character patterm [\w]*; we now require at least one word boundary ([\w]+).

The patch is available starting in Zend Framework 1.12.19.

Other Information

This SQL injection attack does not affect Zend Framework 2 and 3 versions because the implementations of Zend\Db\Sql\Select::order() and Zend\Db\Sql\Select::group() do not manage parenthetical expressions.

Acknowledgments

The Zend Framework team thanks the following for identifying the issues and working with us to help protect its users:

  • Peter O'Callaghan, who discovered and reported the issue;
  • Enrico Zimuel, who provided the patch.

Source

After 17 months of effort, hundreds of releases, tens of thousands of commits by hundreds of contributors, and millions of installs, we're pleased to announce the immediate availability of Zend Framework 3.

What is Zend Framework 3?

For Zend Framework 2 MVC users, the differences are subtle:

  • Increased performance; we've measured up to 4X faster applications under PHP 5, and even better performance under PHP 7!
  • PHP 7 support.
  • A focus on de-coupling packages, to allow re-use in a greater number of contexts. In some cases, this has meant the creation of new packages that either split concerns, or provide integration between multiple components.
  • A focus on documentation. Documentation is now included within each component repository, allowing us to block contributions for lack of documentation, as well as automate deployment of documentation. See our new documentation site for the results.

Migration from version 2 to version 3 was at the top of our minds, and we have provided a number of forwards compatibility features over the course of ZF3 development, and written migration guides to help you navigate the changes.

If you are already familiar with our MVC, or want to get started with it, we have created a new version of the skeleton application that ships with minimal dependencies, and provides a number of convenience features including the ability to select optional packages at installation, as well as auto-register components and modules when adding them to your application. Read more about the skeleton in the documentation.

For newcomers to the framework, we have been working on our package architecture, and attempting to make each package installable with a minimal amount of dependencies, to allow usage in any project, from Zend Framework MVC applications to other popular frameworks such as Laravel and Symfony. All components are now developed independently, with their own release schedules, allowing us to ship bugfixes and new features more frequently. This change has allowed us to tag multiple hundreds of releases in the past year!

The Zend Framework 3 initiatives also included a number of new features, primarily around PSR-7 (HTTP Message interfaces) support. These include:

Yes, you read that correctly: Zend Framework now ships with a microframework as a parallel offering to its MVC full-stack framework! For users new to Zend Framework who are looking for a place to dive in, we recommend Expressive, as we feel PSR-7 middleware represents the future of PHP application development.

The release today is a new beginning for the framework, returning to its original mission: a strong component library, with opt-in MVC features.

Join our community today; we're available on the #zftalk Freenode IRC channel, and via our component repositories (for discussing issues and development).

— The Zend Framework Team —

Look for follow-up posts on this blog soon, detailing some of the new features!

Source

With the release of Zend Framework 3, it's time to halt development on Zend Framework 1. As such, we hereby announce that Zend Framework 1 reaches its End of Life (EOL) three months from today, on 28 September 2016.

Between now and then, we will only provide security fixes, if any security reports are made in that time frame. Past that point, we will offer custom bug and security fixes for Zend Framework 1 on-demand only to Enterprise users of Zend Server.

Additionally, as of today, access to our legacy subversion server is disabled. If you were using svn:externals to incorporate Zend Framework into your application, please download the relevant package as listed in our Zend Framework packages archives instead, or update your application to use Composer.

If you need assistance migrating your Zend Framework 1 application to Zend Framework 2/3 or Expressive, Zend offers architecture migration services.

If you are in need of Zend Framework 2/3 training, Zend offers both a Zend Framework 2 Fundamentals course and a Zend Framework 2 Advanced Concepts course.

Source

This is an installment in an ongoing series of posts on ZF3 development status. Since the last status update:

  • ~130 pull requests merged, and ~100 issues closed.
  • Over 30 component releases.
  • Completion of the component documentation migration.
  • Tagging of zend-mvc 3.0.
  • Completion of the new skeleton application and related installers.

Documentation

Since the last update, we managed to complete the migration of documentation to components, as well as publish documentation for all components!

You can view a list of all documented components via GitHub Pages:

Each component contains a link in the topnav to scroll in the component list, allowing you to navigate to other components.

Please help us thank Frank Brückner for the enormous amount of assistance he provided driving this milestone to completion!

zend-mvc 3.0 stability

After copious testing with the skeleton application (more on that below), and prepping components such as zend-test to work with it, we decided that zend-mvc was ready to tag with a 3.0 stable version!

For those not following previous updates, the main goals of the zend-mvc v3 effort were:

  • De-couple from other components. Many components were listed as development requirements and suggestions due to the fact that zend-mvc contained zend-servicemanager integrations for them. We have moved those integrations into the components themselves.
  • Reduce dependencies to exactly what's needed for a basic zend-mvc application:
    • EventManager
    • HTTP
    • ModuleManager
    • Router
    • ServiceManager
    • Standard Library
    • View
  • Split optional integrations into their own packages. These included:
    • Console integration (now provided via zend-mvc-console)
    • i18n integration (now provided via zend-mvc-i18n)
    • Several plugins had requirements on additional libraries, including:
      • PRG (uses zend-session)
      • FilePRG (uses zend-form and zend-session)
      • FlashMessenger (uses zend-session)
      • Identity (uses zend-authentication)

During the process, we were able to remove around 75% of the code, making the component much smaller, more maintainable, and more focused.

Once zend-mvc was tagged 3.0, we quickly followed up with a zend-test 3.0 release, and stable releases of zend-mvc-console, zend-mvc-i18n, and the various zend-mvc-plugin packages.

Skeleton application

We'd begun refactoring the skeleton application previously, and were able to complete the work in the past couple weeks. The new skeleton:

  • Migrates to PSR-4 directory layout for the shipped Application module.
  • Relies on Composer for all autoloading, including the Application module.
  • Removes all translations. These were of dubious use, and were quite difficult to maintain.
  • Depends only on zend-mvc, zend-component-installer (which automates injecting components and modules into application configuration during installation), and zend-skeleton-installer (more on this below).
  • We removed almost 8000 lines of code, adding only 800!

zend-skeleton-installer is a new Composer plugin that prompts the user during installation to:

  • Decide if they want a minimal install, or want to add optional packages.
  • Prompts for a number of common optional packages, including caching, logging, console integration, i18n, etc.
  • When installation is complete, it removes itself from the project!

Matthew plans to blog on the code behind zend-skeleton-installer in the near future.

You can test out the new skeleton using the following:

$ composer create-project "zendframework/skeleton-application:dev-develop" zend-project

The above will use the new develop branch, and create a project in the directory zend-project.

Finally, we added both an updated Vagrantfile and Docker support to the skeleton, allowing you to start developing in a consistent, de-coupled environment immediately.

For Vagrant, after you've installed, execute:

$ vagrant up

For Docker, you will need to use docker-compose; once you have that available, execute:

$ docker-compose up -d --build

With each, we bind your host port 8080 to the container's port 80, allowing you to visit it at http://localhost:8080/

We're excited about the new skeleton, and look forward to getting your feedback on it!

Final milestones

We have a few last milestones before we're ready to announce the completion of the Zend Framework 3 initiatives.

First, because PHP 5.5 support ends at the end of June, we will be releasing a new minor version of all components setting the minimum supported PHP version to 5.6. (Many already have such versions in place.)

Second, now that the skeleton application is ready, we will be migrating our tutorials to a new repository, converting them to Markdown and MkDocs, and updating them to follow the new skeleton and component changes.

Finally, we will be deciding what the zendframework/zendframework package will look like for a version 3 tag. In large part, it becomes unnecessary, as we can ship even the skeleton with a minimal set of components; however, for those who want "everything at once", keeping it around as a metapackage may have value. We'll be announcing the plans for it soon.

Until next time

If you want to help:

  • Test the new skeleton (see the directions above) and provide feedback.
  • Search for help wanted or EasyFix issues (most of the latter are documentation).

Many thanks to all the contributors who have provided feedback, patches, reviews, or releases since the last update!

Source

This is an installment in an ongoing series of posts on ZF3 development status. Since the last status update:

  • ~130 pull requests merged, and ~100 issues closed.
  • Over 30 component releases.
  • Completion of the component documentation migration.
  • Tagging of zend-mvc 3.0.
  • Completion of the new skeleton application and related installers.

Documentation

Since the last update, we managed to complete the migration of documentation to components, as well as publish documentation for all components!

You can view a list of all documented components via GitHub Pages:

Each component contains a link in the topnav to scroll in the component list, allowing you to navigate to other components.

Please help us thank Frank Brückner for the enormous amount of assistance he provided driving this milestone to completion!

zend-mvc 3.0 stability

After copious testing with the skeleton application (more on that below), and prepping components such as zend-test to work with it, we decided that zend-mvc was ready to tag with a 3.0 stable version!

For those not following previous updates, the main goals of the zend-mvc v3 effort were:

  • De-couple from other components. Many components were listed as development requirements and suggestions due to the fact that zend-mvc contained zend-servicemanager integrations for them. We have moved those integrations into the components themselves.
  • Reduce dependencies to exactly what's needed for a basic zend-mvc application:
    • EventManager
    • HTTP
    • ModuleManager
    • Router
    • ServiceManager
    • Standard Library
    • View
  • Split optional integrations into their own packages. These included:
    • Console integration (now provided via zend-mvc-console)
    • i18n integration (now provided via zend-mvc-i18n)
    • Several plugins had requirements on additional libraries, including:
      • PRG (uses zend-session)
      • FilePRG (uses zend-form and zend-session)
      • FlashMessenger (uses zend-session)
      • Identity (uses zend-authentication)

During the process, we were able to remove around 75% of the code, making the component much smaller, more maintainable, and more focused.

Once zend-mvc was tagged 3.0, we quickly followed up with a zend-test 3.0 release, and stable releases of zend-mvc-console, zend-mvc-i18n, and the various zend-mvc-plugin packages.

Skeleton application

We'd begun refactoring the skeleton application previously, and were able to complete the work in the past couple weeks. The new skeleton:

  • Migrates to PSR-4 directory layout for the shipped Application module.
  • Relies on Composer for all autoloading, including the Application module.
  • Removes all translations. These were of dubious use, and were quite difficult to maintain.
  • Depends only on zend-mvc, zend-component-installer (which automates injecting components and modules into application configuration during installation), and zend-skeleton-installer (more on this below).
  • We removed almost 8000 lines of code, adding only 800!

zend-skeleton-installer is a new Composer plugin that prompts the user during installation to:

  • Decide if they want a minimal install, or want to add optional packages.
  • Prompts for a number of common optional packages, including caching, logging, console integration, i18n, etc.
  • When installation is complete, it removes itself from the project!

Matthew plans to blog on the code behind zend-skeleton-installer in the near future.

You can test out the new skeleton using the following:

$ composer create-project "zendframework/skeleton-application:dev-develop" zend-project

The above will use the new develop branch, and create a project in the directory zend-project.

Finally, we added both an updated Vagrantfile and Docker support to the skeleton, allowing you to start developing in a consistent, de-coupled environment immediately.

For Vagrant, after you've installed, execute:

$ vagrant up

For Docker, you will need to use docker-compose; once you have that available, execute:

$ docker-compose up -d --build

With each, we bind your host port 8080 to the container's port 80, allowing you to visit it at http://localhost:8080/

We're excited about the new skeleton, and look forward to getting your feedback on it!

Final milestones

We have a few last milestones before we're ready to announce the completion of the Zend Framework 3 initiatives.

First, because PHP 5.5 support ends at the end of June, we will be releasing a new minor version of all components setting the minimum supported PHP version to 5.6. (Many already have such versions in place.)

Second, now that the skeleton application is ready, we will be migrating our tutorials to a new repository, converting them to Markdown and MkDocs, and updating them to follow the new skeleton and component changes.

Finally, we will be deciding what the zendframework/zendframework package will look like for a version 3 tag. In large part, it becomes unnecessary, as we can ship even the skeleton with a minimal set of components; however, for those who want "everything at once", keeping it around as a metapackage may have value. We'll be announcing the plans for it soon.

Until next time

If you want to help:

  • Test the new skeleton (see the directions above) and provide feedback.
  • Search for help wanted or EasyFix issues (most of the latter are documentation).

Many thanks to all the contributors who have provided feedback, patches, reviews, or releases since the last update!

Source