Laravel - как избежать дублирования кода в моделях - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть метод для сохранения некоторых файлов в моих моделях, и я больше не хочу его дублировать, что является лучшим способом избежать этого дублирования кода в Laravel?

Ниже вы можете увидеть некоторые примерыдублирование, вот оно, Модель Продукта и Статьи, оба имеют метод saveFile.

Как я могу изолировать этот код и использовать его повторно?

// App/Article.php
class Product extends Model {
    protected static $storageFolders = "public/products";

    public static function saveFile($file, Array $options = []) {
        $filename = "";
        if (isset($options["name"])) {
            $filename .= $options["name"];
        }
        if ($options["unique"]) {
            $filename .= "-" . time();
        }
        $picture_path = "";
        if ($filename) {
            $extension = $file->getClientOriginalExtension();
            $filename .= ".$extension";
            $picture_path = $file->storeAs(SELF::$storageFolders, $filename);
        } else {
            $picture_path = $file->store(SELF::$storageFolders);
        }
        $storage_url = Storage::url($picture_path);
        return $storage_url;
    }
}

// App/Article.php
class Article extends Model {
    protected static $storageFolders = "public/articles";

    public static function saveFile($file, Array $options = []) {
        $filename = "";
        if (isset($options["name"])) {
            $filename .= $options["name"];
        }
        if ($options["unique"]) {
            $filename .= "-" . time();
        }
        $picture_path = "";
        if ($filename) {
            $extension = $file->getClientOriginalExtension();
            $filename .= ".$extension";
            $picture_path = $file->storeAs(SELF::$storageFolders, $filename);
        } else {
            $picture_path = $file->store(SELF::$storageFolders);
        }
        $storage_url = Storage::url($picture_path);
        return $storage_url;
    }

}

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

Вы можете использовать Сервис или Черту.(вы никогда не вызываете метод из одного контроллера в другой контроллер).

    <?php


    namespace App\Services;

    class FileService
    {

        public function saveFile($file, Array $options = []) {
            $filename = "";
            if (isset($options["name"])) {
                $filename .= $options["name"];
            }
            if ($options["unique"]) {
                $filename .= "-" . time();
            }

            $picture_path = "";    

            if ($filename) {
                $extension = $file->getClientOriginalExtension();
                $filename .= ".$extension";
                $picture_path = $file->storeAs(SELF::$storageFolders, $filename);
            } else {
                $picture_path = $file->store(SELF::$storageFolders);
            }
            $storage_url = Storage::url($picture_path);

        return $storage_url;
       }
}

Затем в любом другом классе вы просто инициализируете его в конструкторе и используете.

// App/Article.php
class Product extends Model {
    protected static $storageFolders = "public/products";  
    protected $fileService;

    public function __construct(FileService $fileService) 
    {
         $this->fileService = $fileService;
    }

    public function saveFile ($file, Array $options = [] ) {
        this->fileService->saveFile($file,$options);
    }
0 голосов
/ 11 декабря 2018

Черты позволяют вам разделять методы между различными классами.Если вы поместите этот метод в черту и оба класса будут его использовать, это должно достичь того, что вы хотите.

Например:

trait SavesFiles
{
    public static function saveFile($file, Array $options = []) {
        $filename = "";
        if (isset($options["name"])) {
            $filename .= $options["name"];
        }
        if ($options["unique"]) {
            $filename .= "-" . time();
        }
        $picture_path = "";
        if ($filename) {
            $extension = $file->getClientOriginalExtension();
            $filename .= ".$extension";
            $picture_path = $file->storeAs(SELF::$storageFolders, $filename);
        } else {
            $picture_path = $file->store(SELF::$storageFolders);
        }
        $storage_url = Storage::url($picture_path);
        return $storage_url;
    }
}

Тогда ваши модели могут использовать его следующим образом:

class Product extends Model
{
    use SavesFiles;
    ...
}

Все, что отличается между моделями, например, папка, может быть определено в классе, например, public $folder = 'products';, а затем использовано в признаке, например, $this->folder.

Или, вы можете создать класс абстрактной модели с этим методом, и обе модели наследуются от него.Но черты были бы моим первым выбором.

...