================== Package Management ================== .. sectionauthor:: Robert Lemke 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 .. 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: .. code-block:: bash $ ./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* :: 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: .. code-block:: bash $ ./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 :ref:`sect-enabling-non-flow-packages` ----- .. _Composer: https://getcomposer.org/ .. _Packagist: https://packagist.org/