Xem xét mối quan hệ giữa table cusc_sanpham và cusc_hinhanh
Thiết kế của table cusc_hinhanh
Do table cusc_hinhanh sử dụng cặp khóa chính gồm 2 cột (columns) là sp_ma và ha_stt nên chúng ta cần hiệu chỉnh model HinhAnh để có thể đáp ứng được việc lưu trữ cặp khóa chính thông qua Laravel như sau:
Step 1: Hiệu chỉnh file model app\HinhAnh.php , bổ sung các hàm xử lý với trường hợp sử dụng cặp khóa chính (Multi PrimaryKey) model HinhAnh:
<?php
namespace App;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
class HinhAnh extends Model
{
public $timestamps = false; //created_at, updated_at
protected $table = 'cusc_hinhanh';
protected $fillable = ['ha_ten'];
protected $guarded = ['sp_ma', 'ha_stt'];
protected $primaryKey = ['sp_ma', 'ha_stt'];
public $incrementing = false;
/**
* Set the keys for a save update query.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function setKeysForSaveQuery(Builder $query)
{
$keys = $this->getKeyName();
if(!is_array($keys)){
return parent::setKeysForSaveQuery($query);
}
foreach($keys as $keyName){
$query->where($keyName, '=', $this->getKeyForSaveQuery($keyName));
}
return $query;
}
/**
* Get the primary key value for a save query.
*
* @param mixed $keyName
* @return mixed
*/
protected function getKeyForSaveQuery($keyName = null)
{
if(is_null($keyName)){
$keyName = $this->getKeyName();
}
if (isset($this->original[$keyName])) {
return $this->original[$keyName];
}
return $this->getAttribute($keyName);
}
}
Step 2: Thêm các hàm lấy danh sách Hình ảnh liên quan trong Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;
class SanPham extends Model
{
const CREATED_AT = 'sp_taoMoi';
const UPDATED_AT = 'sp_capNhat';
protected $table = 'cusc_sanpham';
protected $fillable = ['sp_ten', 'sp_giaGoc', 'sp_giaBan', 'sp_hinh', 'sp_thongTin', 'sp_danhGia', 'sp_taoMoi', 'sp_capNhat', 'sp_trangThai', 'l_ma'];
protected $guarded = ['sp_ma'];
protected $primaryKey = 'sp_ma';
protected $dates = ['sp_taoMoi', 'sp_capNhat'];
protected $dateFormat = 'Y-m-d H:i:s';
public function loaisanpham()
{
return $this->belongsTo('App\Loai', 'l_ma', 'l_ma');
}
public function hinhanhlienquan()
{
return $this->hasMany('App\HinhAnh', 'sp_ma', 'sp_ma');
}
}
Step 3: Hiệu chỉnh chức năng Thêm mới Sản phẩm (create), bổ sung thêm ô chọn file cho phép người dùng upload cùng lúc nhiều hình ảnh
- Hiệu chỉnh view:
resources/views/backend/sanpham/create.blade.php
@extends('backend.layouts.master')
@section('title')
Thêm mới sản phẩm
@endsection
@section('custom-css')
<!-- Các css dành cho thư viện bootstrap-fileinput -->
<link href="{{ asset('vendor/bootstrap-fileinput/css/fileinput.css') }}" media="all" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" crossorigin="anonymous">
<link href="{{ asset('vendor/bootstrap-fileinput/themes/explorer-fas/theme.css') }}" media="all" rel="stylesheet" type="text/css" />
@endsection
@section('content')
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form method="post" action="{{ route('admin.sanpham.store') }}" enctype="multipart/form-data">
{{ csrf_field() }}
<div class="form-group">
<label for="l_ma">Loại sản phẩm</label>
<select name="l_ma" class="form-control">
@foreach($danhsachloai as $loai)
@if(old('l_ma') == $loai->l_ma)
<option value="{{ $loai->l_ma }}" selected>{{ $loai->l_ten }}</option>
@else
<option value="{{ $loai->l_ma }}">{{ $loai->l_ten }}</option>
@endif
@endforeach
</select>
</div>
<div class="form-group">
<label for="sp_ten">Tên sản phẩm</label>
<input type="text" class="form-control" id="sp_ten" name="sp_ten" value="{{ old('sp_ten') }}">
</div>
<div class="form-group">
<label for="sp_giaGoc">Giá gốc</label>
<input type="text" class="form-control" id="sp_giaGoc" name="sp_giaGoc" value="{{ old('sp_giaGoc') }}">
</div>
<div class="form-group">
<label for="sp_giaGoc">Giá bán</label>
<input type="text" class="form-control" id="sp_giaBan" name="sp_giaBan" value="{{ old('sp_giaBan') }}">
</div>
<div class="form-group">
<div class="file-loading">
<label>Hình đại diện</label>
<input id="sp_hinh" type="file" name="sp_hinh">
</div>
</div>
<div class="form-group">
<label for="sp_thongTin">Thông tin</label>
<input type="text" class="form-control" id="sp_thongTin" name="sp_thongTin" value="{{ old('sp_thongTin') }}">
</div>
<div class="form-group">
<label for="sp_danhGia">Đánh giá</label>
<input type="text" class="form-control" id="sp_danhGia" name="sp_danhGia" value="{{ old('sp_danhGia') }}">
</div>
<div class="form-group">
<label for="sp_taoMoi">Ngày tạo mới</label>
<input type="text" class="form-control" id="sp_taoMoi" name="sp_taoMoi" value="{{ old('sp_taoMoi') }}">
</div>
<div class="form-group">
<label for="sp_capNhat">Ngày cập nhật</label>
<input type="text" class="form-control" id="sp_capNhat" name="sp_capNhat" value="{{ old('sp_capNhat') }}">
</div>
<div class="form-group">
<label for="sp_trangThai">Trạng thái</label>
<select name="sp_trangThai" class="form-control">
<option value="1" {{ old('sp_trangThai') == 1 ? "selected" : "" }}>Khóa</option>
<option value="2" {{ old('sp_trangThai') == 2 ? "selected" : "" }}>Khả dụng</option>
</select>
</div>
<div class="form-group">
<div class="file-loading">
<label>Hình ảnh liên quan sản phẩm</label>
<input id="sp_hinhanhlienquan" type="file" name="sp_hinhanhlienquan[]" multiple>
</div>
</div>
<button type="submit" class="btn btn-primary">Lưu</button>
</form>
@endsection
@section('custom-scripts')
<!-- Các script dành cho thư viện bootstrap-fileinput -->
<script src="{{ asset('vendor/bootstrap-fileinput/js/plugins/sortable.js') }}" type="text/javascript"></script>
<script src="{{ asset('vendor/bootstrap-fileinput/js/fileinput.js') }}" type="text/javascript"></script>
<script src="{{ asset('vendor/bootstrap-fileinput/js/locales/fr.js') }}" type="text/javascript"></script>
<script src="{{ asset('vendor/bootstrap-fileinput/themes/fas/theme.js') }}" type="text/javascript"></script>
<script src="{{ asset('vendor/bootstrap-fileinput/themes/explorer-fas/theme.js') }}" type="text/javascript"></script>
<script>
$(document).ready(function() {
$("#sp_hinh").fileinput({
theme: 'fas',
showUpload: false,
showCaption: false,
browseClass: "btn btn-primary btn-lg",
fileType: "any",
previewFileIcon: "<i class='glyphicon glyphicon-king'></i>",
overwriteInitial: false
});
// Ô nhập liệu cho phép chọn nhiều hình ảnh cùng lúc (các hình ảnh liên quan đến sản phẩm)
$("#sp_hinhanhlienquan").fileinput({
theme: 'fas',
showUpload: false,
showCaption: false,
browseClass: "btn btn-primary btn-lg",
fileType: "any",
previewFileIcon: "<i class='glyphicon glyphicon-king'></i>",
overwriteInitial: false,
allowedFileExtensions: ["jpg", "gif", "png", "txt"]
});
});
</script>
<!-- Các script dành cho thư viện Mặt nạ nhập liệu InputMask -->
<script src="{{ asset('vendor/input-mask/jquery.inputmask.min.js') }}"></script>
<script src="{{ asset('vendor/input-mask/bindings/inputmask.binding.js') }}"></script>
<script>
$(document).ready(function() {
// Gắn mặt nạ nhập liệu cho các ô nhập liệu Giá gốc
$('#sp_giaGoc').inputmask({
alias: 'currency',
positionCaretOnClick: "radixFocus",
radixPoint: ".",
_radixDance: true,
numericInput: true,
groupSeparator: ",",
suffix: ' vnđ',
min: 0, // 0 ngàn
max: 100000000, // 1 trăm triệu
autoUnmask: true,
removeMaskOnSubmit: true,
unmaskAsNumber: true,
inputtype: 'text',
placeholder: "0",
definitions: {
"0": {
validator: "[0-9\uFF11-\uFF19]"
}
}
});
// Gắn mặt nạ nhập liệu cho các ô nhập liệu Giá bán
$('#sp_giaBan').inputmask({
alias: 'currency',
positionCaretOnClick: "radixFocus",
radixPoint: ".",
_radixDance: true,
numericInput: true,
groupSeparator: ",",
suffix: ' vnđ',
min: 0, // 0 ngàn
max: 100000000, // 1 trăm triệu
autoUnmask: true,
removeMaskOnSubmit: true,
unmaskAsNumber: true,
inputtype: 'text',
placeholder: "0",
definitions: {
"0": {
validator: "[0-9\uFF11-\uFF19]"
}
}
});
// Gắn mặt nạ nhập liệu cho các ô nhập liệu Ngày tạo mới
$('#sp_taoMoi').inputmask({
alias: 'datetime',
inputFormat: 'yyyy-mm-dd' // Định dạng Năm-Tháng-Ngày
});
// Gắn mặt nạ nhập liệu cho các ô nhập liệu Ngày cập nhật
$('#sp_capNhat').inputmask({
alias: 'datetime',
inputFormat: 'yyyy-mm-dd' // Định dạng Năm-Tháng-Ngày
});
});
</script>
@endsection
Step 4: hiệu chỉnh action store của Backend\SanPhamController
Bổ sung chức năng Lưu trữ cùng lúc nhiều hình ảnh
use App\HinhAnh; // Chúng ta cần sử dụng model HinhAnh để truy vấn dữ liệu
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
// Bổ sung ràng buộc Validate
$validation = $request->validate([
'sp_hinh' => 'required|file|image|mimes:jpeg,png,gif,webp|max:2048',
// Cú pháp dùng upload nhiều file
'sp_hinhanhlienquan.*' => 'file|image|mimes:jpeg,png,gif,webp|max:2048'
]);
// Tạo mới object SanPham
$sp = new SanPham();
$sp->sp_ten = $request->sp_ten;
$sp->sp_giaGoc = $request->sp_giaGoc;
$sp->sp_giaBan = $request->sp_giaBan;
$sp->sp_thongTin = $request->sp_thongTin;
$sp->sp_danhGia = $request->sp_danhGia;
$sp->sp_taoMoi = $request->sp_taoMoi;
$sp->sp_capNhat = $request->sp_capNhat;
$sp->sp_trangThai = $request->sp_trangThai;
$sp->l_ma = $request->l_ma;
// Kiểm tra xem người dùng có upload hình ảnh Đại diện hay không?
if ($request->hasFile('sp_hinh')) {
$file = $request->sp_hinh;
// Lưu tên hình vào column sp_hinh
$sp->sp_hinh = $file->getClientOriginalName();
// Chép file vào thư mục "storate/public/photos"
$fileSaved = $file->storeAs('public/photos', $sp->sp_hinh);
}
$sp->save();
// Lưu hình ảnh liên quan
if($request->hasFile('sp_hinhanhlienquan')) {
$files = $request->sp_hinhanhlienquan;
// duyệt từng ảnh và thực hiện lưu
foreach ($request->sp_hinhanhlienquan as $index => $file) {
$file->storeAs('public/photos', $file->getClientOriginalName());
// Tạo đối tưọng HinhAnh
$hinhAnh = new HinhAnh();
$hinhAnh->sp_ma = $sp->sp_ma;
$hinhAnh->ha_stt = ($index + 1);
$hinhAnh->ha_ten = $file->getClientOriginalName();
$hinhAnh->save();
}
}
// Hiển thị câu thông báo 1 lần (Flash session)
Session::flash('alert-info', 'Them moi thanh cong ^^~!!!');
// Điều hướng về route index
return redirect()->route('admin.sanpham.index');
}
Step 5: Hiệu chỉnh chức năng Sửa Sản phẩm (edit), bổ sung thêm ô chọn file cho phép người dùng upload cùng lúc nhiều hình ảnh
- Hiệu chỉnh view:
resources/views/backend/sanpham/edit.blade.php
@extends('backend.layouts.master')
@section('title')
Hiệu chỉnh sản phẩm
@endsection
@section('custom-css')
<!-- Các css dành cho thư viện bootstrap-fileinput -->
<link href="{{ asset('vendor/bootstrap-fileinput/css/fileinput.css') }}" media="all" rel="stylesheet" type="text/css"/>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" crossorigin="anonymous">
<link href="{{ asset('vendor/bootstrap-fileinput/themes/explorer-fas/theme.css') }}" media="all" rel="stylesheet" type="text/css"/>
@endsection
@section('content')
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form method="post" action="{{ route('admin.sanpham.update', ['id' => $sp->sp_ma]) }}" enctype="multipart/form-data">
<input type="hidden" name="_method" value="PUT" />
{{ csrf_field() }}
<div class="form-group">
<label for="l_ma">Loại sản phẩm</label>
<select name="l_ma" class="form-control">
@foreach($danhsachloai as $loai)
@if($loai->l_ma == $sp->l_ma)
<option value="{{ $loai->l_ma }}" selected>{{ $loai->l_ten }}</option>
@else
<option value="{{ $loai->l_ma }}">{{ $loai->l_ten }}</option>
@endif
@endforeach
</select>
</div>
<div class="form-group">
<label for="sp_ten">Tên sản phẩm</label>
<input type="text" class="form-control" id="sp_ten" name="sp_ten" value="{{ old('sp_ten', $sp->sp_ten) }}">
</div>
<div class="form-group">
<label for="sp_giaGoc">Giá gốc</label>
<input type="text" class="form-control" id="sp_giaGoc" name="sp_giaGoc" value="{{ old('sp_giaGoc', $sp->sp_giaGoc) }}">
</div>
<div class="form-group">
<label for="sp_giaGoc">Giá bán</label>
<input type="text" class="form-control" id="sp_giaBan" name="sp_giaBan" value="{{ old('sp_giaBan', $sp->sp_giaBan) }}">
</div>
<div class="form-group">
<div class="file-loading">
<label>Hình đại diện</label>
<input id="sp_hinh" type="file" name="sp_hinh">
</div>
</div>
<div class="form-group">
<label for="sp_thongTin">Thông tin</label>
<input type="text" class="form-control" id="sp_thongTin" name="sp_thongTin" value="{{ old('sp_thongTin', $sp->sp_thongTin) }}">
</div>
<div class="form-group">
<label for="sp_danhGia">Đánh giá</label>
<input type="text" class="form-control" id="sp_danhGia" name="sp_danhGia" value="{{ old('sp_danhGia', $sp->sp_danhGia) }}">
</div>
<div class="form-group">
<label for="sp_taoMoi">Ngày tạo mới</label>
<input type="text" class="form-control" id="sp_taoMoi" name="sp_taoMoi" value="{{ old('sp_taoMoi', $sp->sp_taoMoi) }}" data-mask-datetime>
</div>
<div class="form-group">
<label for="sp_capNhat">Ngày cập nhật</label>
<input type="text" class="form-control" id="sp_capNhat" name="sp_capNhat" value="{{ old('sp_capNhat', $sp->sp_capNhat) }}" data-mask-datetime>
</div>
<div class="form-group">
<label for="sp_trangThai">Trạng thái</label>
<select name="sp_trangThai" class="form-control">
<option value="1" {{ old('sp_trangThai', $sp->sp_trangThai) == 1 ? "selected" : "" }}>Khóa</option>
<option value="2" {{ old('sp_trangThai', $sp->sp_trangThai) == 2 ? "selected" : "" }}>Khả dụng</option>
</select>
</div>
<div class="form-group">
<div class="file-loading">
<label>Hình ảnh liên quan sản phẩm</label>
<input id="sp_hinhanhlienquan" type="file" name="sp_hinhanhlienquan[]" multiple>
</div>
</div>
<button type="submit" class="btn btn-primary">Lưu</button>
</form>
@endsection
@section('custom-scripts')
<!-- Các script dành cho thư viện bootstrap-fileinput -->
<script src="{{ asset('vendor/bootstrap-fileinput/js/plugins/sortable.js') }}" type="text/javascript"></script>
<script src="{{ asset('vendor/bootstrap-fileinput/js/fileinput.js') }}" type="text/javascript"></script>
<script src="{{ asset('vendor/bootstrap-fileinput/js/locales/fr.js') }}" type="text/javascript"></script>
<script src="{{ asset('vendor/bootstrap-fileinput/themes/fas/theme.js') }}" type="text/javascript"></script>
<script src="{{ asset('vendor/bootstrap-fileinput/themes/explorer-fas/theme.js') }}" type="text/javascript"></script>
<script>
$(document).ready(function() {
$("#sp_hinh").fileinput({
theme: 'fas',
showUpload: false,
showCaption: false,
browseClass: "btn btn-primary btn-lg",
fileType: "any",
append: false,
showRemove: false,
autoReplace: true,
previewFileIcon: "<i class='glyphicon glyphicon-king'></i>",
overwriteInitial: false,
initialPreviewShowDelete: false,
initialPreviewAsData: true,
initialPreview: [
"{{ asset('storage/photos/' . $sp->sp_hinh) }}"
],
initialPreviewConfig: [
{
caption: "{{ $sp->sp_hinh }}",
size: {{ Storage::exists('public/photos/' . $sp->sp_hinh) ? Storage::size('public/photos/' . $sp->sp_hinh) : 0 }},
width: "120px",
url: "{$url}",
key: 1
},
]
});
// Ô nhập liệu cho phép chọn nhiều hình ảnh cùng lúc (các hình ảnh liên quan đến sản phẩm)
$("#sp_hinhanhlienquan").fileinput({
theme: 'fas',
showUpload: false,
showCaption: false,
browseClass: "btn btn-primary btn-lg",
fileType: "any",
append: false,
showRemove: false,
autoReplace: true,
previewFileIcon: "<i class='glyphicon glyphicon-king'></i>",
overwriteInitial: false,
allowedFileExtensions: ["jpg", "gif", "png", "txt"],
initialPreviewShowDelete: false,
initialPreviewAsData: true,
initialPreview: [
@foreach($sp->hinhanhlienquan()->get() as $hinhAnh)
"{{ asset('storage/photos/' . $hinhAnh->ha_ten) }}",
@endforeach
],
initialPreviewConfig: [
@foreach($sp->hinhanhlienquan()->get() as $index=>$hinhAnh)
{
caption: "{{ $hinhAnh->ha_ten }}",
size: {{ Storage::exists('public/photos/' . $hinhAnh->ha_ten) ? Storage::size('public/photos/' . $hinhAnh->ha_ten) : 0 }},
width: "120px",
url: "{$url}",
key: {{ ($index + 1) }}
},
@endforeach
]
});
});
</script>
<!-- Các script dành cho thư viện Mặt nạ nhập liệu InputMask -->
<script src="{{ asset('vendor/input-mask/jquery.inputmask.min.js') }}"></script>
<script src="{{ asset('vendor/input-mask/bindings/inputmask.binding.js') }}"></script>
<script>
$(document).ready(function() {
// Gắn mặt nạ nhập liệu cho các ô nhập liệu Giá gốc
$('#sp_giaGoc').inputmask({
alias: 'currency',
positionCaretOnClick: "radixFocus",
radixPoint: ".",
_radixDance: true,
numericInput: true,
groupSeparator: ",",
suffix: ' vnđ',
min: 0, // 0 ngàn
max: 100000000, // 1 trăm triệu
autoUnmask: true,
removeMaskOnSubmit: true,
unmaskAsNumber: true,
inputtype: 'text',
placeholder: "0",
definitions: {
"0": {
validator: "[0-9\uFF11-\uFF19]"
}
}
});
// Gắn mặt nạ nhập liệu cho các ô nhập liệu Giá bán
$('#sp_giaBan').inputmask({
alias: 'currency',
positionCaretOnClick: "radixFocus",
radixPoint: ".",
_radixDance: true,
numericInput: true,
groupSeparator: ",",
suffix: ' vnđ',
min: 0, // 0 ngàn
max: 100000000, // 1 trăm triệu
autoUnmask: true,
removeMaskOnSubmit: true,
unmaskAsNumber: true,
inputtype: 'text',
placeholder: "0",
definitions: {
"0": {
validator: "[0-9\uFF11-\uFF19]"
}
}
});
// Gắn mặt nạ nhập liệu cho các ô nhập liệu Ngày tạo mới
$('#sp_taoMoi').inputmask({
alias: 'datetime',
inputFormat: 'yyyy-mm-dd' // Định dạng Năm-Tháng-Ngày
});
// Gắn mặt nạ nhập liệu cho các ô nhập liệu Ngày cập nhật
$('#sp_capNhat').inputmask({
alias: 'datetime',
inputFormat: 'yyyy-mm-dd' // Định dạng Năm-Tháng-Ngày
});
});
</script>
@endsection
Step 6: hiệu chỉnh action update của Backend\SanPhamController
Bổ sung chức năng Lưu trữ cùng lúc nhiều hình ảnh
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
// Bổ sung ràng buộc Validate
$validation = $request->validate([
'sp_hinh' => 'file|image|mimes:jpeg,png,gif,webp|max:2048',
// Cú pháp dùng upload nhiều file
'sp_hinhanhlienquan.*' => 'image|mimes:jpeg,png,gif,webp|max:2048'
]);
// Tìm object Sản phẩm theo khóa chính
$sp = SanPham::where("sp_ma", $id)->first();
$sp->sp_ten = $request->sp_ten;
$sp->sp_giaGoc = $request->sp_giaGoc;
$sp->sp_giaBan = $request->sp_giaBan;
$sp->sp_thongTin = $request->sp_thongTin;
$sp->sp_danhGia = $request->sp_danhGia;
$sp->sp_taoMoi = $request->sp_taoMoi;
$sp->sp_capNhat = $request->sp_capNhat;
$sp->sp_trangThai = $request->sp_trangThai;
$sp->l_ma = $request->l_ma;
// Kiểm tra xem người dùng có upload hình ảnh Đại diện hay không?
if ($request->hasFile('sp_hinh')) {
// Xóa hình cũ để tránh rác
Storage::delete('public/photos/' . $sp->sp_hinh);
// Upload hình mới
// Lưu tên hình vào column sp_hinh
$file = $request->sp_hinh;
$sp->sp_hinh = $file->getClientOriginalName();
// Chép file vào thư mục "photos"
$fileSaved = $file->storeAs('public/photos', $sp->sp_hinh);
}
// Lưu hình ảnh liên quan
if ($request->hasFile('sp_hinhanhlienquan')) {
// DELETE các dòng liên quan trong table `HinhAnh`
foreach ($sp->hinhanhlienquan()->get() as $hinhAnh) {
// Xóa hình cũ để tránh rác
Storage::delete('public/photos/' . $hinhAnh->ha_ten);
// Xóa record
$hinhAnh->delete();
}
$files = $request->sp_hinhanhlienquan;
// duyệt từng ảnh và thực hiện lưu
foreach ($request->sp_hinhanhlienquan as $index => $file) {
$file->storeAs('public/photos', $file->getClientOriginalName());
// Tạo đối tưọng HinhAnh
$hinhAnh = new HinhAnh();
$hinhAnh->sp_ma = $sp->sp_ma;
$hinhAnh->ha_stt = ($index + 1);
$hinhAnh->ha_ten = $file->getClientOriginalName();
$hinhAnh->save();
}
}
$sp->save();
// Hiển thị câu thông báo 1 lần (Flash session)
Session::flash('alert-info', 'Cập nhật thành công ^^~!!!');
// Điều hướng về trang index
return redirect()->route('admin.sanpham.index');
}
Step 7: hiệu chỉnh action despoy của Backend\SanPhamController
Bổ sung chức năng Xóa cùng lúc nhiều hình ảnh
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
// Tìm object Sản phẩm theo khóa chính
$sp = SanPham::where("sp_ma", $id)->first();
// Nếu tìm thấy được sản phẩm thì tiến hành thao tác DELETE
if (empty($sp) == false) {
// DELETE các dòng liên quan trong table `HinhAnh`
foreach ($sp->hinhanhlienquan()->get() as $hinhAnh) {
// Xóa hình cũ để tránh rác
Storage::delete('public/photos/' . $hinhAnh->ha_ten);
// Xóa record
$hinhAnh->delete();
}
// Xóa hình cũ để tránh rác
Storage::delete('public/photos/' . $sp->sp_hinh);
}
$sp->delete();
// Hiển thị câu thông báo 1 lần (Flash session)
Session::flash('alert-info', 'Xóa sản phẩm thành công ^^~!!!');
// Điều hướng về trang index
return redirect()->route('admin.sanpham.index');
}
|