> For the complete documentation index, see [llms.txt](https://dustinsimon.gitbook.io/encapsulation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dustinsimon.gitbook.io/encapsulation/v1.2/getting-started/advanced.md).

# Advanced

In most projects you need to define own encapsulation classes for representing different data and/or add more methods. You can inherit from an encapsulation class and modify behavior at some points.

## Allow specific fields only

Extending from `Dustin\Encapsulation\ArrayEncapsulation` allows you to define a specific set of fields which are allowed in objects of your class. For example it does not make sense to store a price in a customer object. This prevents inserting unsolicited data which can cause errors.

```php
use Dustin\Encapsulation\ArrayEncapsulation;

class Product extends ArrayEncapsulation {
    
    public function getAllowedFields(): ?array {
        return ['name', 'stock', 'price', 'description'];
    }
    
}
```

Our product can now only hold values for the fields *name*, *stock*, *price* and *description*. The following example will cause an error when trying to set another field.

```php
$product = new Product();

$product->set('price', 12.34); 
// Field 'price' is allowed

$product->set('metaTitle', 'My cool product'); 
// Will throw a NotAllowedFieldException since the field 'metaTitle' is not allowed.
```

## Nest encapsulations

In some scenarios - for example serialization - it's a good choice to prevent an encapsulation holding other objects which are not encapsulations. The `NestedEncapsulation` will only hold scalar values, arrays or other `NestedEncapsulations`. There is no way to insert other objects.

```php
use Dustin\Encapsulation\NestedEncapsulation;

$encapsulation = new NestedEncapsulation([
    'foo' => 'foo',
    'bar' => 123
]);

$encapsulation->set('otherObject', new MyObject()); 
// will throw an exception since MyObject does not inherit from NestedEncapsulation
```

## Allow objects only in containers

You can inherit from `Container` and restrict it's elements to objects of a given class. These objects are not limited to encapsulations. You can use any class you want.

```php
use Dustin\Encapsulation\Container;

class ProductContainer extends Container {

    protected function getAllowedClass(): ?string {
        return Product::class;
    }
    
}
```

Now trying to add an element to a `ProductContainer` which is not a `Product` will cause an exception:

```php
$container = new ProductContainer();

$container->add(new Customer()); // will throw an exception
```
