Package Management

Flow is a package-based system. In fact, Flow itself is just a package as well - but obviously an important one. Packages act as a container for different matters: Most of them contain PHP code which adds certain functionality, others only contain documentation and yet other packages consist of templates, images or other resources.

Package Locations

Framework and Application Packages

Flow packages are located in a sub folder of the Packages/ directory. A typical application (such as Neos for example) will use the core packages which are bundled with Flow and use additional packages which are specific to the application. The framework packages are kept in a directory called Framework while the application specific packages reside in the Application directory. This leads to the following folder structure:

Configuration/

The global configuration folder

Data/

The various data folders, temporary as well as persistent

Packages/
Framework/

The Framework directory contains packages of the Flow distribution.

Application/

The Application directory contains your own / application specific packages.

Libraries/

The Libraries directory contains 3rd party packages.

Additional Package Locations

Apart from the Application, Framework and Libraries package directories you may define your very own additional package locations by just creating another directory in the application’s Packages directory. One example for this is the Neos distribution, which expects packages with website resources in a folder named Sites.

The location for Flow packages installed via Composer (as opposed to manually placing them in a Packages/ sub folder) is determined by looking at the package type in the manifest file. This would place a package into Packages/Acme:

"type": "neos-acme"

If you would like to use package:create to create packages of this type in Packages/Acme instead of the default location Packages/Application, add an entry in the Settings.yaml of the package that expects packages of that type:

Neos:
  Flow:
    package:
      packagesPathByType:
        'neos-acme': 'Acme'

Note

Packages where the type starts with typo3-flow- or neos- are considered Flow packages and will therefore be reflected and proxied by default. We recommend using only the neos- prefix for the type when creating new packages (but only from Flow 3.2 upwards) as the other is deprecated and will stop working in the next major.

Package Directory Layout

The Flow package directory structure follows a certain convention which has the advantage that you don’t need to care about any package-related configuration. If you put your files into the right directories, everything will just work.

The directory layout inside a Flow package is as follows:

Classes

This directory contains the actual source code for the package. Package authors are free to add (only!) class or interface files directly to this directory or add subdirectories to organize the content as necessary. All classes or interfaces below this directory are handled by the autoloading mechanism and will be registered at the object manager automatically (and will thus be considered “registered objects”).

One special file in here is the Package.php which contains the class with the package’s bootstrap code (if needed).

Configuration

All kinds of configuration which are delivered with the package reside in this directory. The configuration files are immutable and must not be changed by the user or administrator. The most prominent configuration files are the Objects.yaml file which may be used to configure the package’s objects and the Settings.yaml file which contains general user-level settings.

Documentation

Holds the package documentation. Please refer to the Documenter’s Guide for more details about the directories and files within this directory.

Resources

Contains static resources the package needs, such as library code, template files, graphics, … In general, there is a distinction between public and private resources.

Private

Contains private resources for the package. All files inside this directory will never be directly available from the web.

Installer/Distribution

The files in this directory are copied to the root of a Flow installation when the package is installed or updated via Composer. Anything in Defaults is copied only, if the target does not exist (files are not overwritten). Files in Essentials are overwritten and thus kept up-to-date with the package they come from.

Templates

Template files used by the package should go here. If a user wants to modify the template it will end up elsewhere and should be pointed to by some configuration setting.

PHP

Should hold any PHP code that is an external library which should not be handled by the object manager (at least not by default), is of procedural nature or doesn’t belong into the classes directory for any other reason.

Java

Should hold any Java code needed by the package. Repeat and rinse for Smalltalk, Modula, Pascal, … ;)

Public

Contains public resources for the package. All files in this directory will be mirrored into Flow’s Web directory by the ResourceManager (and therefore become accessible from the web). They will be delivered to the client directly without further processing.

Although it is up to the package author to name the directories, we suggest the following directories:

  • Images

  • Styles

  • Scripts

The general rule for this is: The folder uses the plural form of the resource type it contains.

Third party bundles that contain multiple resources such as jQuery UI or Twitter Bootstrap should reside in a sub directory Libraries.

Tests
Unit

Holds the unit tests for the package.

Functional

Holds the functional tests for the package.

As already mentioned, all classes which are found in the Classes directory will be detected and registered. However, this only works if you follow the naming rules equally for the class name as well as the filename. An example for a valid class name is \MyCompany\MyPackage\Controller\StandardController while the file containing this class would be named StandardController.php and is expected to be in a directory MyCompany.MyPackage/Classes/MyCompany/MyPackage/Controller.

All details about naming files, classes, methods and variables correctly can be found in the Flow Coding Guidelines. You’re highly encouraged to read (and follow) them.

Package Keys

Package keys are used to uniquely identify packages and provide them with a namespace for different purposes. They save you from conflicts between packages which were provided by different parties.

We use vendor namespaces for package keys, i.e. all packages which are released and maintained by the Neos and Flow core teams start with Neos.* (for historical reasons) or Neos.*. In your company we suggest that you use your company name as vendor namespace.

To define the package key for your package we recommend you set the “extra.neos.package-key” option in your composer.json as in the following example:

composer.json:

"extra": {
    "neos": {
        "package-key": "Vendor.PackageKey"
    }
}

Loading Order

The loading order of packages follows the dependency chain as defined in the composer manifests involved, solely taking the “require” part into consideration. Additionally you can configure packages that should be loaded before by adding an array of composer package names to “extra.neos.loading-order.after” as in this example:

composer.json:

"extra": {
    "neos": {
        "loading-order": {
            "after": [
                 "some/package"
            ]
        }
    }
}

Installing a Package

There are various ways of installing packages. They can just be copied to a folder in Packages/, either manually or by some tool, or by keeping them in your project’s VCS tool (directly or indirectly, via git submodules or svn:externals).

The true power of dependency management comes with the use of Composer, though. Installing a package through composer allows to install dependencies of that package automatically as well. That is why we suggest only using composer to install packages.

If a package you would like to add is available on Packagist it can be installed by running:

composer require <vendor/package>

Note

If you need to install Composer first, read the installation instructions

In case a package is not available through Packagist, you can still install via Composer as it supports direct fetching from popular SCM system. For this, define a repository entry in your manifest to be able to use the package name as usual in the dependencies.

composer.json:

"repositories": [
    {
        "type": "git",
        "url": "git://github.com/acme/demo.git"
    },
    
],

"require": {
    ,
    "acme/demo": "dev-master"
}

Creating a New Package

Use the package:create command to create a new package:

$ ./flow package:create Acme.Demo

This will create the package in Packages/Application. After that, adjust composer.json to your needs. Apart from that no further steps are necessary.

Updating Packages

The packages installed via Composer can be updated with the command:

composer update

Package Meta Information

All packages need to provide some meta information to Flow. The data is split in two files, depending on primary use.

composer.json

The Composer manifest. It declares metadata like the name of a package as well as dependencies, like needed PHP extensions, version constraints and other packages. For details on the format and possibilities of that file, have a look at the Composer documentation.

Classes/Package.php

This file contains bootstrap code for the package. If no bootstrap code is needed, it does not need to exist.

Example: Minimal Package.php

<?php
namespace Acme\Demo;

use Neos\Flow\Package\Package as BasePackage;

/**
 * The Acme.Demo Package
 *
 */
class Package extends BasePackage {

        /**
        * Invokes custom PHP code directly after the package manager has been initialized.
        *
        * @param \Neos\Flow\Core\Bootstrap $bootstrap The current bootstrap
        * @return void
        */
        public function boot(\Neos\Flow\Core\Bootstrap $bootstrap) {
                $bootstrap->registerRequestHandler(new \Acme\Demo\Quux\RequestHandler($bootstrap));

                $dispatcher = $bootstrap->getSignalSlotDispatcher();
                $dispatcher->connect(\Neos\Flow\Mvc\Dispatcher::class, 'afterControllerInvocation', \Acme\Demo\Baz::class, 'fooBar');
        }
}
?>

The bootstrap code can be used to wire some signal to a slot or to register request handlers (as shown above), or anything else that can must be done early the bootstrap stage.

After creating a new Package.php in your package you need to execute:

$ ./flow flow:package:rescan

Otherwise the Package.php will not be found.

Using Third Party Packages

When using 3rd party packages via Composer everything should work as expected. Flow uses the Composer autoloader to load code. Third party packages will not have any Flow “magic” enabled by default. That means no AOP will work on classes from third party packages. If you need this see Enabling Other Package Classes For Object Management