PHPackages                             romaricdrigon/orchestra-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. romaricdrigon/orchestra-bundle

ActiveSymfony-bundle[Framework](/categories/framework)

romaricdrigon/orchestra-bundle
==============================

Naked Object framework build on top of Symfony2

0.8.1(11y ago)4221[7 issues](https://github.com/romaricdrigon/OrchestraBundle/issues)MITPHPPHP ~5.4

Since Nov 30Pushed 11y ago1 watchersCompare

[ Source](https://github.com/romaricdrigon/OrchestraBundle)[ Packagist](https://packagist.org/packages/romaricdrigon/orchestra-bundle)[ RSS](/packages/romaricdrigon-orchestra-bundle/feed)WikiDiscussions master Synced 3w ago

READMEChangelogDependencies (13)Versions (3)Used By (0)

Orchestra Bundle
================

[](#orchestra-bundle)

Orchestra is a Naked Object implementation on top of Symfony2 Available as a Symfony2 Bundle

[![Latest Stable Version](https://camo.githubusercontent.com/f489b697ca8d4a9cc734e81aaf4675ec3df48c61ef4f7db985e6799f83c9b669/68747470733a2f2f706f7365722e707567782e6f72672f726f6d61726963647269676f6e2f6f72636865737472612d62756e646c652f762f737461626c652e737667)](https://packagist.org/packages/romaricdrigon/orchestra-bundle)[![License](https://camo.githubusercontent.com/26cddc8403bc5358e44470f08466f7406404d344bb148d7daaeff6542b60c953/68747470733a2f2f706f7365722e707567782e6f72672f726f6d61726963647269676f6e2f6f72636865737472612d62756e646c652f6c6963656e73652e737667)](https://packagist.org/packages/romaricdrigon/orchestra-bundle)[![SensioLabsInsight](https://camo.githubusercontent.com/a829093b7b0ae9c26f9bf2498940b7794c7fae13d9f05d4b944e3737fcfc4001/68747470733a2f2f696e73696768742e73656e73696f6c6162732e636f6d2f70726f6a656374732f36396134376234332d653730312d343339662d626331332d6434363535383238366635342f6d696e692e706e67)](https://insight.sensiolabs.com/projects/69a47b43-e701-439f-bc13-d46558286f54)[![Build Status](https://camo.githubusercontent.com/85662b7da2025f0e5a63cfd588a242cbb387eaf093d9183033ffef9aa3b35006/68747470733a2f2f7472617669732d63692e6f72672f726f6d61726963647269676f6e2f4f726368657374726142756e646c652e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/romaricdrigon/OrchestraBundle)

Why Orchestra?
--------------

[](#why-orchestra)

[Naked Object](http://en.wikipedia.org/wiki/Naked_objects) is a powerful pattern first described by Richard Pawson.
It states that business objects, if correctly modelled, are sufficient to create an application, the technical code being generic enough to be automatically generated.

Orchestra aims to be such an admin generator: a library that helps you focusing on modelling the Domain right, and do all the "boring code" for you.

Maybe you will want to personalize it further, then it's ok, Orchestra is not about restraining you but helping you quickly create a starter application, that may be used as a prototype, a proof-of-concept, or for discussions with business experts... Note that Orchestra application are made to be production-ready, safe to use, and to offer decent performances. Everything is done by reflection (eventually cached), no direct code generation in here.

Roadmap / version
-----------------

[](#roadmap--version)

Roadmap:

- **0.8** (current): functional but still **beta** version. Using is OK, but extending may change
- 0.9 : production-ready. Several code optimizations are needed
- 1.0 : first stable version. Some refactors have to occur before, but not after before a 2.0 version.

Installation
------------

[](#installation)

Install bundle using composer: `composer require romaricdrigon/orchestra-bundle`

Register the bundle and the vendor we use in `app/AppKernel.php`:

```
class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            // ...

            new RomaricDrigon\OrchestraBundle\RomaricDrigonOrchestraBundle(),
            new Knp\Bundle\MenuBundle\KnpMenuBundle(),
        );
```

Import our routes (both the XML and our custom type):

```
# app/config/routing.yml
orchestra_routing:
    resource: '@RomaricDrigonOrchestraBundle/Resources/config/routing.xml'
    prefix: /admin

orchestra_generated:
    prefix: /admin
    resource: .
    type: orchestra
```

Getting started
---------------

[](#getting-started)

With Orchestra admin generator you will have to focus only on 2 objects: `Entities` and `Repositories`. All those objects must be placed within a valid Symfony2 bundle.

**TL;DR:** you can find a working example at [Orchestra-example](https://github.com/romaricdrigon/Orchestra-example)

### Entities

[](#entities)

`Entities` are the basic Domain objects of your application. Even if we will see later that they are persisted, they may be differ than Doctrine entities.

#### Basic entity

[](#basic-entity)

By convention, place those in your bundle `Entity` folder.

They must implement `RomaricDrigon\OrchestraBundle\Domain\Entity\EntityInterface`: Orchestra must be able to get a unique ID for each entity instance.

```
use RomaricDrigon\OrchestraBundle\Domain\Entity\EntityInterface;

class SomeEntity implements EntityInterface
{
    public function getId()
    {
        return ...
```

Naked Object follow a DDD mindset. We strike not to have an [Anemic Domain Model](http://www.martinfowler.com/bliki/AnemicDomainModel.html). A few guidelines and advices:

- entities properties are private or protected, *not public*,, in compliance with encapsulation
- entities must have public getters for the properties you will want to expose, for example in the views
- they expose methods corresponding to actions on the objects, leading to modification of its internal state, but **not public setters**
- you may want to add *private* setters, in order to achieve self-encapsulation, it's up to you

#### Displaying the entity in listing

[](#displaying-the-entity-in-listing)

If you want your entity to be displayed in the default listing page, it must implement `ListableEntityInterface`:

```
use RomaricDrigon\OrchestraBundle\Domain\Entity\EntityInterface;
use RomaricDrigon\OrchestraBundle\Domain\Entity\ListableEntityInterface;

class SomeEntity implements EntityInterface, ListableEntityInterface
{
    public function viewListing()
    {
        return ['some data', 'some more', '...'];
    }
```

The data returned by `viewListing` will be displayed in the same order in each listing row. It can be an array or a `QueryInterface` object. You will learn more about queries in the next sections.

#### Command and queries

[](#command-and-queries)

Entities apply the [Command-Query Separation principle](http://martinfowler.com/bliki/CommandQuerySeparation.html).

##### Query

[](#query)

Any entity method can return an array (simpler, preferred) or an object implementing `QueryInterface`. Orchestra will generate from it an action, a web page displaying the data from the returned object.

*Note*: `QueryInterface` extends `\Traversable`. It means that a Query will have to either extend [`\Iterator`](http://php.net/manual/en/class.iterator.php) or [`IteratorAggregate`](http://php.net/manual/en/class.iteratoraggregate.php)Watch out, as of PHP 5.4.30, interface implementation order counts, you must implement one those 2 interfaces before implementing `QueryInterface`.

##### Command

[](#command)

Any entity method can accept an object implementing `CommandInterface`. Such method will be transformed into a web page with a Form.

A `Command` is typically a simple data container, with public properties. Those public properties will be mapped to Orchestra-generated Form.

*Note*: A Command will be called either by calling its constructor (in that case it should receive no argument), either you can designate a factory method on the entity. In that case, use the `CommandFactory` annotation on your Command class.

#### Persisting

[](#persisting)

Usually, they are persisted. Orchestra supports Doctrine ORM through its Symfony2 bridge. You will have to do their mapping, using Doctrine annotations, YAML (advised) or XML as you want. For this part, please refer to [Symfony documentation](http://symfony.com/doc/2.4/book/doctrine.html).

#### Events

[](#events)

Events are objects implementing `EventInterface`. An Entity can emit Events.

A method emitting en Event must return either an Event or `null` (in that case nothing will happen). The `Event` will be passed to the corresponding Repository `receive` method (*it must implement `ReceiveEventInterface`*). You can then decide what to do.

### Repositories

[](#repositories)

Those are NOT Doctrine repositories! We stick to the original Repository pattern (Fowler, 2002), "a collection-like interface for accessing domain objects".

Their name will be the name of the `Entity` suffixed by `Repository` but you're free to do otherwise.

**Each `Repository` must have a corresponding `Entity`, with the same slug (lowercase name without suffix): for a `FooBar` entity, you must have a `FoobarRepository`, or `FooBarRepository` or `FooBar` (though this last is less readable).**

#### Basic repository

[](#basic-repository)

We advise you to place those, by convention, in your bundle within a `Repository` folder.

They must implement `RomaricDrigon\OrchestraBundle\Domain\Repository\RepositoryInterface`:

```
use RomaricDrigon\OrchestraBundle\Domain\Repository\RepositoryInterface;
use RomaricDrigon\OrchestraBundle\Annotation\Name;

class MyRepository implements RepositoryInterface
{
```

They must be declared as services, tagged with `orchestra.repository` and **indicating the corresponding entity class**:

```

        ...
```

#### Fetching Doctrine repository

[](#fetching-doctrine-repository)

An Orchestra Repository is a Symfony2 service, so you can inject it dependencies.

Orchestra can automatically resolve and inject to your service the corresponding Doctrine repository. They will also receive a copy of Orchestra `ObjectManager`. To benefit from this, just implement `RomaricDrigon\OrchestraBundle\Domain\Doctrine\DoctrineAwareInterface`.

For simplicity, you can extends the provided `BaseRepository` class. You will then have access to the corresponding Doctrine repository, and we provide a generic `listing` method.

```
use RomaricDrigon\OrchestraBundle\Domain\Doctrine\BaseRepository;
use RomaricDrigon\OrchestraBundle\Annotation\Name;

class MyRepository implements BaseRepository
{
    public function someMethod()
    {
        $objectManager = $this->objectManager;

        $doctrineRepository = $this->doctrineRepository;

        ...
```

#### Customize displayed name

[](#customize-displayed-name)

The name displayed for the Repository can be automatically generated, from the class name, or optionally personalized using the `@Name` annotation.

```
use RomaricDrigon\OrchestraBundle\Domain\Repository\RepositoryInterface;
use RomaricDrigon\OrchestraBundle\Annotation as Orchestra;

/**
 * @Orchestra\Name("CustomName")
 */
class MyRepository implements RepositoryInterface
{
```

Hiding a method
---------------

[](#hiding-a-method)

You can add an Entity or Repository method from the menu by adding it a `@Hidden` annotation.

```
use RomaricDrigon\OrchestraBundle\Domain\Repository\RepositoryInterface;
use RomaricDrigon\OrchestraBundle\Annotation as Orchestra;

class MyRepository implements RepositoryInterface
{
    /**
     * @Orchestra\Hidden
     */
    public function hiddenMethod()
    {
```

Note this does not work on interface, only child classes.

Security
--------

[](#security)

Orchestra fully integrates with Symfony2 Security component, and does not try to interfere with it.

As a convenience, you can add `@Security` annotations to an Entity or Repository method to restrict access to the corresponding page. The content of this annotation is a valid Symfony2 Expression, identical to those used by the [SensioFrameworkExtraBundle](http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/security.html)

Moreover you can access Orchestra objects, such as `repository`, `entity` which an `EntityReflection` or `object` the eventual current `EntityInterface` (but not the `Request` object directly).

Configuration
-------------

[](#configuration)

You can configure the Bundle by putting those settings in your `config.yml`:

```
# app/config/config.yml
romaric_drigon_orchestra:
    app_title: Orchestra # default. Will be used as title (prefix) for pages
```

Misc
----

[](#misc)

IE8 is not supported by provided templates. Twitter Bootstrap is missing its JS polyfills, and we are using jQuery 2.0

Thanks
------

[](#thanks)

Twitter Bootstrap integration have been realized using templates from [Braincrafted Bootstrap bundle](https://github.com/braincrafted/bootstrap-bundle)

Security annotation are supported in a very similar way to [SensioFrameworkExtraBundle](https://github.com/sensiolabs/SensioFrameworkExtraBundle)

###  Health Score

20

—

LowBetter than 13% of packages

Maintenance0

Infrequent updates — may be unmaintained

Popularity12

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~26 days

Total

2

Last Release

4204d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/919405?v=4)[Romaric Drigon](/maintainers/romaricdrigon)[@romaricdrigon](https://github.com/romaricdrigon)

---

Top Contributors

[![romaricdrigon](https://avatars.githubusercontent.com/u/919405?v=4)](https://github.com/romaricdrigon "romaricdrigon (339 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/romaricdrigon-orchestra-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/romaricdrigon-orchestra-bundle/health.svg)](https://phpackages.com/packages/romaricdrigon-orchestra-bundle)
```

###  Alternatives

[rcsofttech/audit-trail-bundle

Enterprise-grade, high-performance Symfony audit trail bundle. Automatically track Doctrine entity changes with split-phase architecture, multiple transports (HTTP, Queue, Doctrine), and sensitive data masking.

1189.8k](/packages/rcsofttech-audit-trail-bundle)[easycorp/easyadmin-bundle

Admin generator for Symfony applications

4.3k17.9M387](/packages/easycorp-easyadmin-bundle)[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.5k5.9M728](/packages/sylius-sylius)[oro/platform

Business Application Platform (BAP)

645143.5k114](/packages/oro-platform)[contao/core-bundle

Contao Open Source CMS

1231.6M2.7k](/packages/contao-core-bundle)[kimai/kimai

Kimai - Time Tracking

4.8k9.0k1](/packages/kimai-kimai)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
