Files
pictureFrame/.claude/skills/oro-backend-dev/reference-entities.md
T
football2801 a536baabd6 feat: initial commit — BMAD tooling, Claude memories, firmware scaffold
Adds the complete project foundation:
- BMAD BMM workflow tooling (_bmad/)
- Claude slash commands, skills, and project memories (.claude/)
- ESP32 firmware scaffold (PlatformIO + Waveshare e-ink driver)
- .gitignore excluding _bmad-output/ and .pio/ build artifacts

Planning artifacts (PRD, architecture, epics) are intentionally not
tracked — they live in _bmad-output/ per project convention.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 15:38:46 -04:00

3.3 KiB

Entity Reference

Detailed patterns for Oro entity work.

Full Entity Example

namespace Acme\Bundle\ExampleBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Oro\Bundle\EntityConfigBundle\Metadata\Attribute\Config;
use Oro\Bundle\EntityConfigBundle\Metadata\Attribute\ConfigField;
use Oro\Bundle\EntityExtendBundle\Entity\ExtendEntityInterface;
use Oro\Bundle\EntityExtendBundle\Entity\ExtendEntityTrait;

#[ORM\Entity]
#[ORM\Table(name: 'acme_example')]
#[ORM\HasLifecycleCallbacks]
#[Config(
    routeName: 'acme_example_index',
    routeView: 'acme_example_view',
    defaultValues: [
        'entity' => ['icon' => 'fa-cube'],
        'security' => ['type' => 'ACL', 'group_name' => ''],
        'ownership' => [
            'owner_type' => 'USER',
            'owner_field_name' => 'owner',
            'owner_column_name' => 'user_owner_id',
            'organization_field_name' => 'organization',
            'organization_column_name' => 'organization_id',
        ],
    ]
)]
class Example implements ExtendEntityInterface
{
    use ExtendEntityTrait;

    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    private ?int $id = null;

    #[ORM\Column(type: 'string', length: 255)]
    #[ConfigField(defaultValues: ['dataaudit' => ['auditable' => true]])]
    private string $name = '';

    #[ORM\Column(type: 'datetime')]
    private ?\DateTimeInterface $createdAt = null;

    #[ORM\Column(type: 'datetime')]
    private ?\DateTimeInterface $updatedAt = null;

    #[ORM\PrePersist]
    public function prePersist(): void
    {
        $this->createdAt = new \DateTime('now', new \DateTimeZone('UTC'));
        $this->updatedAt = clone $this->createdAt;
    }

    #[ORM\PreUpdate]
    public function preUpdate(): void
    {
        $this->updatedAt = new \DateTime('now', new \DateTimeZone('UTC'));
    }

    // getters/setters...
}

Migration Example (Installation)

namespace Acme\Bundle\ExampleBundle\Migrations\Schema;

use Doctrine\DBAL\Schema\Schema;
use Oro\Bundle\MigrationBundle\Migration\Installation;
use Oro\Bundle\MigrationBundle\Migration\QueryBag;

class AcmeExampleBundleInstaller implements Installation
{
    public function getMigrationVersion(): string
    {
        return 'v1_0';
    }

    public function up(Schema $schema, QueryBag $queries): void
    {
        $table = $schema->createTable('acme_example');
        $table->addColumn('id', 'integer', ['autoincrement' => true]);
        $table->addColumn('name', 'string', ['length' => 255]);
        $table->addColumn('created_at', 'datetime');
        $table->addColumn('updated_at', 'datetime');
        $table->setPrimaryKey(['id']);
    }
}

Extend Entity Commands

php bin/console oro:entity-extend:cache:clear
php bin/console oro:entity-extend:cache:warmup
php bin/console oro:entity-extend:update-schema
php bin/console oro:entity-extend:update-schema --dry-run

Enum/Option Set Fields

For select/multi-select fields, use the enum pattern:

$table->addColumn('status_id', 'string', [
    'oro_options' => [
        'extend' => ['is_extend' => true, 'owner' => ExtendScope::OWNER_SYSTEM],
        'enum' => ['enum_code' => 'example_status'],
    ]
]);

Extended Field Access

Extended fields are accessed via magic methods generated at cache warmup:

$entity->getMyCustomField();
$entity->setMyCustomField($value);