phplaraveleloquentmutators

Laravel 6 mutator not converting null into empty string


I'm running an integration test and am getting the following error:

array:5 [
  "message" => "Argument 1 passed to App\Models\Order::getPhoneAttribute() must be of the type string, null given, called in /Users/bigweld/Sites/restaurantbe/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php on line 454"
  "exception" => "Symfony\Component\Debug\Exception\FatalThrowableError"
  "file" => "/Users/bigweld/Sites/restaurantbe/app/Models/Order.php"
  "line" => 87
  "trace" => array:44 [

So it seems to be related to my mutators, which are:

public function setPhoneAttribute(string $phone) : void
{
    $this->attributes[self::ORDER_PHONE] = empty($phone) ? "" : preg_replace("/[^A-Za-z0-9 ]/", '', $phone);
}

public function getPhoneAttribute(string $phone) : string
{
    return is_null($phone) ? "": preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~',
            '($1)-$2-$3', $phone);
}

my test is not passing Order::ORDER_PHONE meaning that an empty string should be stored in the database. If I declare the field in the data array along with the other fields even if empty (ie: [ Order::ORDER_PHONE => "" ]) then this error is not coming up.

Any ideas why?


Solution

  • The only way I was able to make it work without removing my type hint was making the parameter optional:

    public function getPhoneAttribute(?string $phone) : string
        {
            return preg_replace('~.*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4}).*~',
                '($1)-$2-$3', $phone);
        }