a536baabd6
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>
128 lines
3.3 KiB
Markdown
128 lines
3.3 KiB
Markdown
# Entity Reference
|
|
|
|
Detailed patterns for Oro entity work.
|
|
|
|
## Full Entity Example
|
|
|
|
```php
|
|
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)
|
|
|
|
```php
|
|
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
|
|
|
|
```bash
|
|
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:
|
|
|
|
```php
|
|
$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:
|
|
|
|
```php
|
|
$entity->getMyCustomField();
|
|
$entity->setMyCustomField($value);
|
|
```
|