2016-09-26 5 views
5

Gibt es einen Weg in Laravel, um Ihre eigenen benutzerdefinierten Modell-Modelle zusätzlich zu den eingebauten hinzuzufügen?Laravel benutzerdefinierte Modell wirft

Momentan kann ich Getter und Mutatoren verwenden, aber diese werden am Ende für viele Felder wiederholt.

+0

Haben Sie das sehen, und wenn ja, was ist es nicht für Ihre Bedürfnisse nicht funktioniert? https://laravel.com/docs/5.3/eloquent-mutators#attribute-casting – user3158900

+0

IMO die beste Lösung in diesem Fall ist die Verwendung von Traits. – Matheus

+0

können Sie das Modell erweitern und die Abgüsse anpassen oder eine Methode erstellen, um Abgüsse für ein bestimmtes Modell usw. festzulegen, wenn Sie das wirklich wollen. – lagbox

Antwort

6

Also ging ich die Traits-Route hinunter, um verschiedene Model-Methoden zu umgehen, dies stellt sich heraus, nicht für die Zartbesaiteten zu sein, da das Casting ziemlich tief in die Funktionsweise von Modellen eingebettet ist.

Um dies für den allgemeinsten Fall arbeiten zu lassen, d. H. In der Lage zu sein, einfach benutzerdefinierte Umwandlungen hinzuzufügen, würde eine größere Überarbeitung von Model erforderlich machen. Hier

ist die Trait Ich schrieb eine Zeit Guss hinzuzufügen:

<?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']); 
    } 
}