Lightna uses Data Objects to access data in templates and beyond.
The simplest Data Object is an array-like structure where values are accessed using ->key
instead of ["key"]
, making it more intuitive and convenient for working with data.
Data Objects provide the following benefits:
Data Object example:
<?php declare(strict_types=1); namespace MyProject\MyModule\App\Data; use Lightna\Engine\App\Context;use Lightna\Engine\Data\DataA;use MyProject\MyModule\App\Data\Config\Currency;use MyProject\MyModule\App\Data\Config\Favicon;use MyProject\MyModule\App\Data\Config\Logo; /** * @method string copyright(string $escapeMethod = null) * @method string property1(string $escapeMethod = null) * @method string property2(string $escapeMethod = null) * @method string property3(string $escapeMethod = null) */class Config extends DataA{ /** * Public data section */ public Currency $currency; public Favicon $favicon; public Locale $locale; public Logo $logo; public string $copyright; public string $property1; public string $property2 = ''; public ?string $property3 = null; /** * Dependencies section */ protected Context $context; /** * Internal properties section */ protected array $internalProperty1; protected array $internalProperty2; public function getContextField(): string { return $this->context->getField(); } // ...}
Where:
* @method string property1 |
Declares an escaping method for correct IDE suggestions |
DataA |
Base Data Object class |
public Currency $currency; |
Declares the currency property with its own structure |
public string $property1 |
Declares a required property1 property of type string |
public string $property2 = ''; |
Declares an optional property2 property with a default empty value |
protected Context $context; |
Declares a required typed context property with lazy initialization |
public function getContextField() |
Custom method to retrieve data from the Context dependency |
If a Data Object represents an indexed entity, initialize it with the entity data.
When the same Data instance is required during page rendering, such as configuration or the current
product on a product page, initialize the data using the init
method:
protected function init(array $data = []): void { $entity = getobj(MyEntity::class); $data = $entity->get(1); parent::init($data); }
Where:
@AppConfig(entity/my_entity/entity) |
Loads the config value entity/my_entity/entity into $myEntityClass
|
getobj(MyEntity::class) |
Calls the Object Manager to create the entity object |
$entity->get(1) |
Loads the entity with id=1 , which is always 1 for global entities within a scope,
such as configuration
|
parent::init($data) |
Populates the object with the entity data |
When unique instances of a Data Object are required during page rendering, initialize data using the Object Manager:
/** @noinspection PhpUnused */ protected function defineRelatedProducts(): void { $this->relatedProducts = []; foreach ($this->productEntity->getList($this->relatedIds) as $data) { $this->relatedProducts[] = newobj(ProductData::class, $data); } }
Where:
defineRelatedProducts |
Magic Lightna method to define the relatedProducts property |
newobj(ProductData::class, $data) |
Creates a new instance of ProductData and passes $data into its
init method
|
To avoid Class::property must not be accessed before initialization
errors, especially
during backward-compatible deployments when a property is declared but missing in the index — define
default values for new properties, for example public array $items = [];
.
This will not be required in future releases — see Planned section.
Avoid using null
as a default value — it helps keep the code cleaner and avoids unnecessary
conditions. Use an empty array or an empty string instead, depending on the property type.
In a future release, uninitialized properties in Data Objects will be set automatically based on their type — no need to define a default unless a custom value is required.