【问题标题】:What is the best way to manage home page banners in Laravel?在 Laravel 中管理主页横幅的最佳方法是什么?
【发布时间】:2021-05-24 08:08:34
【问题描述】:

这是我在主页中的横幅结构:

如您所见,我有 4 个用于横幅的部分 - 小横幅 |中等横幅| 高分辨率照片| CLIPARTO新闻横幅|大横幅

我有一个名为 Banner 的模型,4 个控制器来管理这个横幅和 4 个表格来保存数据。

这是Banner 模型:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Banner extends Model
{
    protected $fillable = [
        'title', 'image', 'url', 'image_title', 'image_alt'
    ];
}

和控制器:

小控制器:

class SmallController extends Controller
{
    public function small_list()
    {
        $smallBanners = DB::table('small_banner')->get();
        return view('admin.banners.small.list', compact('smallBanners'));
    }

    public function small_create()
    {
        return view('admin.banners.small.add');
    }

    public function small_store(Request $request)
    {
        $data = $request->validate([
            'title' => 'required',
            'url' => 'required',
            'image' => 'required',
            'image_title' => 'max:255',
            'image_alt' => 'max:255'
        ]);
        DB::table('small_banner')->insert($data);
        return redirect(route('admin.banners.small.index'));
    }

    public function small_edit($id)
    {
        $small = DB::table('small_banner')->where('id', $id)->first();
        return view('admin.banners.small.edit', compact('small'));
    }

    public function small_update(Request $request, $id)
    {
        $small = DB::table('small_banner')->where('id', $id)->first();
        if ($request->has('image')) {
            if (file_exists($small->image)) {
                unlink($small->image);
            }
            DB::table('small_banner')->where('id', $id)->update([
                'image' => $request['image']
            ]);
        }
        DB::table('small_banner')->where('id', $id)->update([
            'title' => $request['title'],
            'url' => $request['url'],
            'image_title' => $request['image_title'],
            'image_alt' => $request['image_alt']
        ]);
        return redirect(route('admin.banners.small.index'));
    }

    public function small_delete($id)
    {
        $small = DB::table('small_banner')->where('id', $id)->first();
        DB::table('small_banner')->where('id', $id)->delete();
        if (file_exists($small->image)) {
        unlink($small->image);
        }
        return redirect(route('admin.banners.small.index'));
    }
}

其他控制器类似于 SmallController

这就是我展示横幅的方式:

@foreach($smallBanners as $small)
        <div class="col-6 col-lg-3">
             <div class="widget-banner card">
                  <a href="{{ $small->url }}" target="_blank" rel="noopener">
                     <img class="img-fluid w-100" loading="lazy"
                          src="{{ $small->image }}" title="{{ $small->title }}"
                          alt="{{ $small->image_alt }}" width="350" height="200">
                  </a>
              </div>
         </div>
@endforeach

其他视图,如小横幅。

但在这种情况下,例如在小横幅中,如果我们上传 5 张图片而不是 4 张图片,则结构会混乱。

管理此横幅和优化代码的最佳方法是什么?

【问题讨论】:

  • 如果您的横幅模板仅针对 4 个横幅进行了优化,您可以将服务器返回的数据列表限制为数据库中随机的 4 个横幅
  • 但我不想返回 4 个随机横幅,我需要正好 4 个横幅@AlzafanChristian

标签: php html laravel


【解决方案1】:

让我们回到这个概念,从减少表的使用开始,或者你可以坚持你的概念

让我们把结构改成下面

表:banners

列:

$table->increments('id');
$table->string('title');
$table->string('image');
$table->string('url');
$table->string('image_title')->nullable(); //guessing from validator that it can be null
$table->string('image_alt')->nullable();
//extra columns
$table->enums('banner_type', ['small', 'medium', 'large', 'news']);
//or
$table->string('banner_type');
$table->boolean('isActive')->default(0);

你有模型,但没有使用它

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Banner extends Model
{
    protected $table = 'banners'; //add this line to define table name, make sure you have set the database config in .env
    protected $fillable = [
        'title', 'image', 'url', 'image_title', 'image_alt', 'banner_type', 'isActive'
    ];
}

现在将用于管理横幅的控制器减少到只有 1 个控制器

use Banner;

class BannerController extends Controller
{
    public function index()
    {
        $banners = Banner::get();
        return view('admin.banners.index', compact('banners'));
    }

    public function create()
    {
        return view('admin.banners.create');
    }

    public function store_count($request, $type)
    {
        //using array limit
        return Banner::where('banner_type', $type)
        ->where('isActive', 1)->count() < $this->limits[$type] && $request->isActive == 1;
    }

    public function update_count($banner, $type)
    {
        return Banner::whereNotIn('id', [$banner->id])
        ->where('isActive', 1)
        ->where('type', $banner->banner_type)->count() < $this->limits[$type] && $banner->isActive == 1;
    }

    public function store(Request $request)
    {
        //validating form data
        $data = $request->validate([
            'title' => "required",
            'url' => "required",
            'image' => "required",
            'image_title' => "max:255",
            'image_alt' => "max:255",
            'banner_type' => "required|in:small,medium,large,news",
            'isActive' => "nullable|in:0,1" //active or not
        ]);

        //validating images active count
        if (!$this->store_count($request, $request->banner_type)) {
        return redirect()->back()->withInput($request->all())
            ->withErrors(['isActive' => ' نمیتوان بیشتر از ' . $this->limits[$request['banner_type']] . ' عکس برای این بنر آپلود کرد! ']);
    }

        Banner::create($data);
        return redirect(route('admin.banners.index'));
    }

    public function show($id)
    {
        $banner = Banner::findOrFail($id);
        return view('admin.banners.edit', compact('banner'));
    }

    public function update(Request $request, $id)
    {
        $banner = Banner::findOrFail($id);
        //validate update form data here
        //your validation
        //validating images active count
        if(!$this->update_count($banner, $request->banner_type)){
            return redirect()->back()
           ->withInput($request->all())
           ->withErrors(['isActive' => 'There cant be more than '.$this->limits[$request['banner_type']].' images active');
        }
        $banner = $banner->fill([
            'title' => $request['title'],
            'url' => $request['url'],
            'image_title' => $request['image_title'],
            'image_alt' => $request['image_alt'],
            'banner_type' => $request['banner_type'],
            'isActive' => $request['isActive'] ?? 0
        ]);
        if ($request->has('image')) {
            if (file_exists($banner->image)) {
                unlink($banner->image);
            }
            $banner->image = $request['image'];
        }
        $banner->update();
        return redirect(route('admin.banners.index'));
    }

    public function delete($id)
    {
        $banner = Banner::findOrFail($id);
        if (file_exists($banner->image)) {
           unlink($banner->image);
        }
        $banner->delete();

        return redirect(route('admin.banners.index'));
    }
}

现在我们设置代码来选择哪些图像是活动的,你可以使用 ajax 方法或使用上面的控制器

public function set_active($id)
{
     $banner = Banner::findOrFail($id);
     $this->validate_count((new Request([])), $banner->banner_type);
     $banner->update(['isActive' => 1]);
     return redirect(route('admin.banners.index'));
}

//you can use array if want to set different limit of banner type, put it as public variable inside controller class
public $limits = [
    'small' => 4,
    'medium' => 4,
    'large' => 4,
    'news' => 4
];

将数据资源加载到视图中

public class home()
{
    $small = Banner::where('banner_type', 'small')
    ->where('isActive', 1)->get();
    $medium = Banner::where('banner_type', 'medium')
    ->where('isActive', 1)->get();
    $large = Banner::where('banner_type', 'large')
    ->where('isActive', 1)->get();
    $news = Banner::where('banner_type', 'news')
    ->where('isActive', 1)->get();
   return view('home', compact('small', 'medium', 'large', 'news'));
}

【讨论】:

  • 我忘了添加额外的filable 我会更新它,祝你编码愉快@Waltun
  • 我使用的是数组限制,但是这个部分 -> $limit = $this->limits[$type]; if($total > $limit){ return redirect()->back() ->withInput($request->all()) ->withErrors(['isActive' => "不能超过 {$limit}图像活动"]); } 不起作用
  • 你把public $limits放在控制器上面了吗?
  • 是的,当我检查 $limit 和 $total 时,这没关系,当我在 if($total > $limit) 中 dd(...) 时没关系,但返回重定向没有t 工作和横幅将添加@AlzafanChristian
  • 对不起,我不知道我的完整代码会被使用,我的答案更新了,也许你可以再检查一下结果:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-11
  • 1970-01-01
  • 2015-11-19
  • 1970-01-01
  • 1970-01-01
  • 2020-05-23
  • 2021-08-31
相关资源
最近更新 更多