3

I have a trait called Multilingual which uses the model its lang and translation_of attributes (also see https://stackoverflow.com/a/7299777/1453912) to provide multiple translations of an entity.

Now I want to hide the translation_of field from the model when $model->toArray() is called, which is - most easily - done through adding it to the $hidden attribute. Like this:

class Model {
    use Multilingual;

    protected $hidden = ['translation_of'];
}

But to keep the original model clean, I want to add the hidden field via the used trait.

I have tried:

  1. Adding protected $hidden = ['translation_of']; to the trait, which is not allowed: Undefined: trait declaration of property 'hidden' is incompatible with previous declaration

    And also not very extensible (It will be overridden by the $hidden property of the class, I think..)

  2. Adding a boot method to the trait:

    static function bootMultilingual() {
        static::$hidden[] = 'translation_of';
    }
    

    Which (as I suspected) is also not allowed, because of the scope.

Any ideas for a clean way to do this?

Please help!


NOTE: To keep it dynamic, I figured it can be done in two ways:

  1. Internally: $this->hidden[] = 'translation_of';
  2. Externally: $model->setHidden(array_merge($model->getHidden(), ['translation_of']));
Community
  • 1
  • 1
mauvm
  • 3,586
  • 3
  • 18
  • 19

1 Answers1

6

You could override the method where $this->hidden is actually used. And that's getArrayableItems

trait Multilingual {

    protected function getArrayableItems(array $values)
    {
        if(!in_array('translation_of', $this->hidden)){
            $this->hidden[] = 'translation_of';
        }
        return parent::getArrayableItems($values);
    }
}
lukasgeiter
  • 147,337
  • 26
  • 332
  • 270