I'm trying to extend a trait. By that I mean create a trait that redefines a couple methods for a different trait.
This is my code (PHP 5.6 and Laravel 5.4):
namespace App\Traits;
use Illuminate\Database\Eloquent\Concerns\HasTimestamps;
trait ExtendHasTimestamps
{
use HasTimestamps {
HasTimestamps::setCreatedAt as parentSetCreatedAt;
HasTimestamps::setUpdatedAt as parentSetUpdatedAt;
}
public function setCreatedAt($value) {
if ($value !== '') return $this;
return $this->parentSetCreatedAt($value);
}
public function setUpdatedAt($value) {
if ($value !== '') return $this;
return $this->parentSetUpdatedAt($value);
}
}
The issue comes in when I use ExtendHasTimestamps
in a Model, it conflicts with HasTimestamps
because Eloquent\Model
has use HasTimestamps
. Before PHP 7, traits throw a fatal error if you try to define the same property twice. So since I'm defining $timestamps
both in HasTimestamps
and again through ExtendHasTimestamps
by virtue of use HasTimestamps
, it breaks.
In short:
trait HasTimestamps {
protected $timestamps = true; //problematic property
}
trait ExtendHasTimestamps {
use HasTimestamps;
// add validation then call HasTimestamps method
}
class Model {
use HasTimestamps;
}
class MyModel extends Model {
use ExtendHasTimestamps; //everything breaks
}
Is there a way to either convince PHP that it is really the same thing and it can stop conflicting with itself, or to inform the class I'm working with (an extension of Eloquent\Model
) to stop using HasTimestamps
in favor of my trait?
This question does not answer mine because I'm trying to use a trait to overwrite another trait rather than just adding methods to each class where I need to use this code.