Bundle Standards
Perhaps unlike many other community bundles, each individual CMF bundle is part of a larger project, the CMF. As such, stable bundles should adhere to a core set of standards and goals in addition to the suggested bundle best practices.
All CMF bundles MUST meet the requirements set out in the following list in order for them to be classified as stable:
- General Bundle Standards;
- Meta: README, CHANGELOG, etc;
- Persistence;
- Configuration, Files and Formats;
- Base and Standard Implementations;
- Standard CMF Features;
- Testing Component Integration.
The rest of this document will explain each of the above requirements in detail.
General Bundle Standards
Class File Naming
Composite class names SHOULD place the subject first:
Bad | Good |
---|---|
FoobarMenuNode | MenuNodeFoobar |
AllFeaturesSimpleBlock | SimpleBlockAllFeatures |
Configuration File Naming
Configuration files for services SHOULD copy structure of the namespace up to the level of abstraction required. Each element of a namespace MAY also be compressed (e.g. event-listener => event).
A suffix may be added to allow different variations of the same configuration file.
Examples:
event-imagine-phpcr.xml
andevent-imagine-orm.xml
for an event subscriber with namespace[BundleName]\EventListener\ImagineCacheInvalidatorSubscriber
doctrine-phpcr.xml
for all classes in the[BundleName]\Doctrine\Phpcr
- namespace.
admin-imagine.xml
for classes in the[BundleName]\Admin\Imagine
namespace.
Interface Naming
Interfaces which exist to provide getters MUST be suffixed with "ReadInterface".
Interfaces which exist to provide setters MUST be suffixed with "WriteInterface".
"Read/Write" Interfaces, which provide both getters and setters, MUST not have an additional suffix and MUST extend the "Read" and "Write" interfaces IF either exists.
If either or both "Read" and "Write" interfaces do not exist, then the "Read/Write" interface MUST incorporate the methods required to fulfill the "Read/Write" contract:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
<?php
interface FoobarInterface extends FoobarReadInterface, FoobarWriteInterface
{
}
// or
interface FoobarInterface extends FoobarReadInterface
{
public function setFoobar($foobar);
}
// or
interface FoobarInterface
{
public function getFoobar();
public function setFoobar($foobar);
}
Dependency Container Configuration
Refer to the service naming conventions in the Symfony documentation.
Meta: README, CHANGELOG, etc
Bundles MUST have the following meta files:
1 2 3 4
./README.md
./CHANGELOG.md
./CONTRIBUTING.md
./Resources/meta/LICENSE
See the following templates:
- README: README template on wiki;
- CHANGELOG: CHANGELOG template on wiki;
- CONTRIBUTING: CONTRIBUTING file from CoreBundle (this should be copied verbatim);
- LICENSE: LICENSE template on wiki (this should be copied verbatim).
Persistence
All CMF bundles:
- MUST support PHPCR-ODM for persistence;
- MAY support other persistence layers like Doctrine ORM;
- MUST follow the following structure to enable future or current support of other persistence systems:
- MUST create implementation specific models in addition to
those in
/Model
(even if they are empty). SeeBlog.php
andPost.php
below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
./Model
./Blog.php
./Post.php
./Doctrine
./Phpcr
./Blog.php
./Post.php
./PostRepository.php
./PostListener.php
./Orm
./Resources/
./config
./doctrine-phpcr
./Blog.phpcr.xml
See the Mapping Model Classes chapter of the Symfony Cookbook for more information.
Base and Standard Implementations
The CMF offers various features which add functionality beyond the basic use case of some classes. Examples of these features include multi-language and publish workflow support, but the potential list of features is unbounded.
Bundles should offer ready-to-use and fully integrated implementations in addition to enabling the user to use only what they need.
To facilitate this, when applicable, there should be two implementations, the base implementation and the standard implementation.
- base implementation: This class should be suffixed with Base, e.g.
MenuNodeBase
and it MUST be an implementation with an absolute minimum of logic needed for it to work, it SHOULD NOT have external dependencies; - standard implementation: This class has no additional prefix/suffix, e.g.
MenuNode
. This implementation MUST implement the standard CMF feature set. This class MAY have external dependencies.
The user can then extend the base implementation, adding any functionality they want, using the standard implementation as a reference.
Standard CMF Features
CMF Bundles MUST (where applicable) implement the following features:
- PublishWorkflow;
- Translatable support.
Configuration, Files and Formats
Core configuration files MUST be in XML, this includes:
- Routing;
- Service definitions;
- Doctrine mappings;
- Translations (XLIFF format).
In other cases XML should be preferred over other configuration formats where there is a choice.
Bundles MUST adhere to the following directory and file name schema as applicable:
1 2 3 4 5 6 7 8 9
./Resources/
./config/
./schema/
./bundlename-1.0.xsd
./routing
./my_service.xml
./admin.xml # all sonata-admin stuff
./validation.xml # all validation
./my-related-services.xml # semantically named file for specific services
Bundles MUST define a Configuration
class:
1 2 3
./DependencyInjection
./Configuration.php
./MyBundleExtension.php
Bundles SHOULD provide an XML schema for their configuration, as provided by
Configuration::getXsdValidationBasePath
.
Bundles MUST use their own XML namespace, The XML namespace is
http://cmf.symfony.com/schema/dic/bundle_name
with bundle_name
being the
DI alias of the bundle.
Bundles MUST support XML in the configuration class.
Testing Component Integration
All bundles MUST implement the CMF Testing component.