Skip to content

A 'virtual properties' attribute#3

Open
gwillz wants to merge 25 commits intomasterfrom
feat/virtual-attributes
Open

A 'virtual properties' attribute#3
gwillz wants to merge 25 commits intomasterfrom
feat/virtual-attributes

Conversation

@gwillz
Copy link
Copy Markdown
Collaborator

@gwillz gwillz commented Nov 2, 2022

We already have a very handy UpdateVirtualTrait that lets us apply functions whenever updating data via constructor or update(). This lets us normalise or parse complex data. However, it's a little cumbersome (and broken for strong types).

Attributes

Declare an attribute for properties to define how it should be marshalled into the correct type.

There are three attributes:

  • VirtualProperty - this defines a method to call when updating this property.
  • VirtualObject - this converts arrays into objects using configurable logic.
  • VirtualArray - for create object arrays, same configurable logic.

Such as:

class MyModel extends DataObject
{
   use UpdateTrait;
   use AttributesVirtualTrait;

   #[VirtualProperty('setComplex')]
   public $complex;

   #[VirtualObject(OtherModel::class)]
   public $object;
   
   public function setComplex($value)
   {
      this->complex = new Complex($value);
   }
}

Strong Types

This introduces the UpdateVirtualInterface with a setVirtual() method to replace the wonky applyVirtual() approach.

Where instead of modifying types in-place on the object (which doesn't work with strong types), instead we convert and apply virtual properties first.

The relevant update traits are updated to use the new interface. This is technically a breaking change.

Important considerations

Something like this feels redundant, and you would be right.

#[VirtualObject(SomeModel::class)
public SomeModel $object;

The target object is right there and we could simply use that instead of the attribute. However this scenario is also common:

#[VirtualObject(SomeModel::class)
public BaseModel $object;

Where BaseModel is abstract or an interface.

@gwillz gwillz force-pushed the feat/virtual-attributes branch 3 times, most recently from 22b31e4 to e7247c0 Compare November 7, 2022 05:25
gwillz added 22 commits April 9, 2026 20:08
This adds VirtualObject for shorthand goodness using the
Configure helper. However, this doesn't gel so well with
strict property types introduced in PHP 7.4.

We'll likely need to rework how update() and applyVirtual() works.
…ely.

This permits 'strict' updates to report errors for bad types.
Lots of complexity and we don't need doc tags.
Why when attributes are always superior?
This trait only exists for backward compat.
@gwillz gwillz force-pushed the feat/virtual-attributes branch from c0dd6df to 09442b9 Compare April 9, 2026 11:03
@gwillz gwillz marked this pull request as ready for review April 9, 2026 11:27
gwillz added 2 commits April 10, 2026 15:05
Where the virtual trait is used without the interface.
Common if using DataObject instead of Collection as the base class.
UpdateVirtualTrait was already opt-in. So now it simply overrides
the default (attributes) behaviour.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant