Modeling a nested domain hierarchy

Hi guys

I have got trouble in modeling the domain hierarchy of my application. Here are the basics:

The AbstractParty is an abstract entity. Is is implemented by either of the two entities Person and Organisation.
The person holds some basic properties like name, date of birth, nationality and so on. A person may now be extended by two different entities: SoccerPlayer and HockeyPlayer.

The problem now is: Every Person may be

  • Only a Person
  • A Person and a SoccerPlayer
  • A Person and a HockeyPlayer
  • A Person and a SoccerPlayer and a HockeyPlayer

How should I define my model? Currently the AbstractParty (at the top of the inheritance mapping) is annotated as follows:

/**
 * A party
 *
 * @Flow\Entity
 * @ORM\InheritanceType("JOINED")
 */
abstract class AbstractParty { ... }

When I use the provided PartyService of the Neos.Party package i can successfully retrieve the Person entity related with the authenticated Account. This entity does NOT hold any information about the player specific data.

The primary question is: How can I access the HockeyPlayer or SoccerPlayers data from the “parent entity” Person?

Any hints and tips are very welcome :slight_smile:

Kind regards,
Peter

Hi Peter,

I don’t speak on behalf of the core team but my personal opinion is: Don’t use the Party package for this but create a model tailored to your needs.

For example you could have a User model instead of the Person as simple as:

<?php

/**
 * @Flow\Entity
 */
class User
{
    /**
     * @var Account
     * @Flow\Validate(type="NotEmpty")
     * @ORM\ManyToOne
     */
    protected $account;

    /**
     * @var string
     */
    protected $givenName;

    /**
     * @var string
     */
    protected $familyName;

    /**
     * @param Account $account
     * @param string $givenName
     * @param string $familyName
     */
    public function __construct(Account $account, string $givenName, string $familyName)
    {
        $this->account = $account;
        $this->givenName = $givenName;
        $this->familyName = $familyName;
    }

    // ...
}

If hockey and soccer player are just used for classification of the user, you can add simple flags for those – or even roles on the related Account.
If they have their own custom properties (like player number) though, I’d model them explicitly:

<?php

/**
 * @Flow\Entity
 */
class HockeyPlayer
{
    /**
     * @var User
     * @Flow\Validate(type="NotEmpty")
     * @ORM\ManyToOne
     */
    protected $user;

    /**
     * @var int
     */
    protected $playerNumber;

    /**
     * @param User $user
     * @param int $playerNumber
     */
    public function __construct(User $user, int $playerNumber)
    {
        $this->user = $user;
        $this->playerNumber = $playerNumber;
    }

    // ...

}

Hi Bastian

Thanks a lot for your reply!
In fact I’m really using the AbstractParty since it may represent either a Person or an Organisation. They have some common properties like accounts or addresses. The Person instances will be used in the frontend while Organisation instances will be allowed to consume an API.

Apart from that, you were right about implementing the two player types as separate entities. The both have distinct properties.

I’d prefer some mechanism to “autoload” the available player properties into the Person object upon creation (say: retrieval from the repos). How could this be achieved?