2016-09-26 21 views
5

是否有Laravel方式來增加自己的定製機型除了投射到內置的呢?Laravel定製機型蒙上

目前我可以使用getter和改變者,但這些最終得到重複很多領域。

+0

你看到這一點,如果你做了,它什麼也沒有爲你的工作需要? https://laravel.com/docs/5.3/eloquent-mutators#attribute-casting – user3158900

+0

IMO在這種情況下的最佳解決方案是使用特質。 – Matheus

+0

如果你真的想要,你可以擴展模型並調整演員陣容,或創建一種方法來爲特定模型設置演員等。 – lagbox

回答

6

所以我最終漲難跌的特徵路線覆蓋各種型號的方法,事實證明這不是爲懦弱者準備的屬性鑄造相當深深嵌入的方式模型的工作。

爲了使這項工作爲最一般的情況下,即能方便地添加自定義蒙上,將要求模型相當重大改寫。

這裏是我寫的添加時間投特質:

<?php 

namespace App\Models; 

use Carbon\Carbon; 

trait CustomCasts 
{ 
    /** 
    * Cast an attribute to a native PHP type. 
    * 
    * @param string $key 
    * @param mixed $value 
    * @return mixed 
    */ 
    protected function castAttribute($key, $value) 
    { 
     if (is_null($value)) { 
      return $value; 
     } 

     switch ($this->getCastType($key)) { 
      case 'int': 
      case 'integer': 
       return (int) $value; 
      case 'real': 
      case 'float': 
      case 'double': 
       return (float) $value; 
      case 'string': 
       return (string) $value; 
      case 'bool': 
      case 'boolean': 
       return (bool) $value; 
      case 'object': 
       return $this->fromJson($value, true); 
      case 'array': 
      case 'json': 
       return $this->fromJson($value); 
      case 'collection': 
       return new BaseCollection($this->fromJson($value)); 
      case 'date': 
      case 'datetime': 
       return $this->asDateTime($value); 
      case 'timestamp': 
       return $this->asTimeStamp($value); 
      case 'time': 
       return $this->asTime($value); 
      default: 
       return $value; 
     } 
    } 

    protected function asTime($value) 
    { 
     // If this value is already a Carbon instance, we shall just return it as is. 
     // This prevents us having to re-instantiate a Carbon instance when we know 
     // it already is one, which wouldn't be fulfilled by the DateTime check. 
     if ($value instanceof Carbon) { 
      return $value; 
     } 

     // If the value is already a DateTime instance, we will just skip the rest of 
     // these checks since they will be a waste of time, and hinder performance 
     // when checking the field. We will just return the DateTime right away. 
     if ($value instanceof DateTimeInterface) { 
      return new Carbon(
       $value->format('Y-m-d H:i:s.u'), $value->getTimeZone() 
      ); 
     } 

     // If this value is an integer, we will assume it is a UNIX timestamp's value 
     // and format a Carbon object from this timestamp. This allows flexibility 
     // when defining your date fields as they might be UNIX timestamps here. 
     if (is_numeric($value)) { 
      return Carbon::createFromTimestamp($value); 
     } 

     // If the value is in simply year, month, day format, we will instantiate the 
     // Carbon instances from that format. Again, this provides for simple date 
     // fields on the database, while still supporting Carbonized conversion. 
     if (preg_match('/^(\d{1,2}):(\d{2}):(\d{2})$/', $value)) { 
      return Carbon::createFromFormat('h:i:s', $value); 
     } 

     var_dump($value); 

     // Finally, we will just assume this date is in the format used by default on 
     // the database connection and use that format to create the Carbon object 
     // that is returned back out to the developers after we convert it here. 
     return Carbon::createFromFormat($this->getTimeFormat(), $value); 
    } 

    /** 
    * Get the format for database stored dates. 
    * 
    * @return string 
    */ 
    protected function getTimeFormat() 
    { 
     //return $this->timeFormat ?: $this->getConnection()->getQueryGrammar()->getTimeFormat(); 
     return $this->timeFormat ?: 'h:i:s'; 
    } 

    /** 
    * Set a given attribute on the model. 
    * 
    * @param string $key 
    * @param mixed $value 
    * @return $this 
    */ 
    public function setAttribute($key, $value) 
    { 
     // First we will check for the presence of a mutator for the set operation 
     // which simply lets the developers tweak the attribute as it is set on 
     // the model, such as "json_encoding" an listing of data for storage. 
     if ($this->hasSetMutator($key)) { 
      $method = 'set'.Str::studly($key).'Attribute'; 

      return $this->{$method}($value); 
     } 

     // If an attribute is listed as a "date", we'll convert it from a DateTime 
     // instance into a form proper for storage on the database tables using 
     // the connection grammar's date format. We will auto set the values. 
     elseif ($value && (in_array($key, $this->getDates()) || $this->isDateCastable($key))) { 
      $value = $this->fromDateTime($value); 
     } 

     elseif ($value && ($this->isTimeCastable($key))) { 
      $value = $this->fromTime($value); 
     } 

     if ($this->isJsonCastable($key) && ! is_null($value)) { 
      $value = $this->asJson($value); 
     } 

     $this->attributes[$key] = $value; 

     return $this; 
    } 

    /** 
    * Convert a Carbon Time to a storable string. 
    * 
    * @param \Carbon\Carbon|int $value 
    * @return string 
    */ 
    public function fromTime($value) 
    { 
     $format = $this->getTimeFormat(); 

     $value = $this->asTime($value); 

     return $value->format($format); 
    } 

    /** 
    * Determine whether a value is Date/DateTime castable for inbound manipulation. 
    * 
    * @param string $key 
    * @return bool 
    */ 
    protected function isTimeCastable($key) 
    { 
     return $this->hasCast($key, ['time']); 
    } 
}