$products = $art->products->skip(0)->take(10)->get(); //get first 10 rows $products = $art->products->skip(10)->take(10)->get(); //get next 10 rows
$products = $art->products->skip(0)->take(10)->get(); //get first 10 rows $products = $art->products->skip(10)->take(10)->get(); //get next 10 rows
Ví dụ: muốn sắp xếp tăng dần theo cột id
->orderBy('id', 'DESC');
->leftJoin('task', 'task.id', '=', 'event.task_id')->select('event.*', 'event.id as eventID', 'event.description as eventDescription', 'task.*')
->whereYear('date', '=', $year)->whereMonth('date', $month)
->where('name', 'like', '%abc%')
DB::table('users')->where(function ($query) use ($activated) { $query->where('activated', '=', $activated); })->get(); /* 1. Viết một function trong where hoặc orWhere 2. Nếu cần sử dụng biến trong function sử dụng thêm từ khóa use sau đó là tên biến */
$dataQuery = AnyEloquent::query(); $dataQuery->where(....); $dataQuery->orWhere(....); $dataQuery->get(); /* 1. Dùng eloquent trỏ đến phương thức query() 2. Sử dụng theo cấu trúc eloquent như bình thường */
Sử dụng hàm save() để lưu vào CSDL.
public function themBoMon($request) { $kt = new BomonModel(); $kt->MaBoMon = $$request->maBoMon; $kt->TenBoMon = $$request->tenBoMon; $kt->save(); return true; }
Lấy đối tượng đó ra, rồi update dữ liệu trường thay đổi. Sử dụng save() để lưu vào CSDL.
public function suaBoMon($maBM, $request) { $kt = BomonModel::where('MaBoMon', '=', $maBM)->first(); $kt->TenBoMon = $request->tenBoMon; $kt->save(); }
Sử dụng hàm delete() để xóa CSDL.
public function xoaBoMon($maBM) { $kt = new BomonModel(); $kt->where('MaBoMon', '=', $maBM)->delete(); }
Khi Select dữ liệu nên chuyển sang dạng mảng để dễ xử lý, và khi trả về mảng bạn lưu ý phải thêm vị trí của phần tử cần lấy vì nó trả về mảng 2 chiều.
//sau khi select nhớ toArray $data = $this->user->where('email', '=', $email)->get()->toArray(); //láy tên của phần tử đầu tiên $khach->setData($data[0]["hoTen"],
Kết các bảng lại với nhau:
$kt = new CoVanModel(); $kq = $kt->join('bomon', 'bomon.MaBoMon', '=', 'CoVanHocTap.MaBoMon')->select('MaCV','HoTen_CV','SDT_CV','TenBoMon')->get()->toArray(); /* Kết bảng CoVanHocTap với Bảng bomon qua trường MaBoMon */
try { //code return true; } catch(\Illuminate\Database\QueryException $ex){ //code return false; }
Nhiều khi Eloquent lỗi insert, update, dữ liệu. (như illegal offset type chẳng hạn). Có thể do bảng có 2 khóa chính,… Thay vì ngồi sửa thì hãy sử dụng lớp DB có sẵn của Laravel.
Đầu tiên import này vào
use Illuminate\Support\Facades\DB;
DB::table('users')->insert( ['email' => 'john@example.com', 'votes' => 0] );
Tham khảo thêm tại: https://laravel.com/docs/8.x/queries
public function tonTai($maBm) { $kt = new BomonModel(); $kq = $kt->where('MaBoMon', '=', $maBm)->get()->count(); if($kq>0) return true; else return false; }
public function getIDByCode($code) { $item = Order::where("code", "=", $code)->get()->toArray(); if(count($item) > 0) return $item[0]["id"]; else return -1; }
public function getAllLopAndInfo() { $kt = new LopModel(); $kq = $kt->join('bomon', 'bomon.MaBoMon', '=', 'lop.MaBoMon')->join('covanhoctap', 'covanhoctap.MaCV', '=', 'lop.MaCV')->get()->toArray(); return $kq; } public function getAllThongTinLop() { $kt = new LopModel(); $kq = $kt->join('bomon', 'bomon.MaBoMon', '=', 'lop.MaBoMon')->join('covanhoctap', 'covanhoctap.MaCV', '=', 'lop.MaCV')->select('MaLop', 'TenLop', 'EmailLop', 'HoTen_CV', 'SDT_CV', 'Email_CV', 'TenBoMon')->get()->toArray(); return $kq; }
$validation = Validator::make( $request->all(), [ 'title' => 'required|string|max:50', ], [ 'title.required' => trans('validation.required_custom', ['attribute' => trans('table.room.title')]), 'title.max' => trans('validation.max.string', ['attribute' => trans('table.room.title')]), ] ); $validation->after( //Check accept is_accept_policy function ($validation) use ($request) { if ($request->title === 'Test') { $validation->errors()->add('title', trans('validation.title_equal_test')); } } ); if ($validation->fails()) { return $this->jsonValidate($validation->errors()); }
Tôi bị lỗi này suốt mấy tháng mà không tìm ra, giờ chia sẻ lại cho các bạn kinh nghiệm.
$this->$thuocTinh; //sai $this->thuoctinh; //đúng
//không được class GuestController extends Controller { private $thongbao_table = new ThongBaoModel(); } //thì làm như thế này class GuestController extends Controller { private $thongbao_table; public function __construct() { $this->thongbao_table = new ThongBaoModel(); } }
strpos($chuoi, $tuCanTim) //syntax strpos(string, find, start) //string: Required. Specifies the string to search //find: Required. Specifies the string to find //start: Optional. Specifies where to begin the search. If start is a negative number, it counts from the end of the string. //Returns the position of the first occurrence of a string inside another string, //or FALSE if the string is not found. Note: String positions start at 0, and not 1.
public function __construct() { parent::__construct(); }
//$info là biến của php //Cần đổ dữ liệu $info sang javascript làm như bên dưới @if( isset($info) ) <script> alert("{{ $info }}"); </script> @endif
Các phần phải có trong model. Biến $fillable là các trường được phép chỉnh sửa dữ liệu.
class ThongBaoModel extends Model { protected $table = 'thong-bao'; protected $fillable = ['img', 'title', 'content', 'quote']; public $timestamps = false; }
Nếu bảng khóa chính không phải là id
protected $primaryKey = "MaBoMon"; //trường khóa chính protected $keyType = 'string'; //kieur dữ liệu của trường đó
Hãy sử dụng compact thì khi truyền sang tên biến sẽ không bị thay đổi tên. Tức là truyền qua tên nào thì ở view lấy tên đó xài luôn. Và nó có thể truyền nhiều biến nữa.
$ds = new DanhSachController(); $data = $ds->getDanhSach(); $bm = new BomonModel(); $boMon = $bm->getAllBoMon(); $lp = new LopModel(); $lop = $lp->getAllLop(); return view('admin.trang-chu')->with( compact('data', 'boMon', 'lop') );
class AdminMiddleware { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { if($request->session()->has('user') && $request->session()->get('user') == 'admin') { return $next($request); } else return redirect("/2"); } }
Đăng ký Kernel
protected $routeMiddleware = [ //'auth' => \App\Http\Middleware\Authenticate::class, //'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, //'can' => \Illuminate\Foundation\Http\Middleware\Authorize::class, //'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, //'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'admin' => \App\Http\Middleware\AdminMiddleware::class, ];
Có bao nhiêu bảng thì tạo bấy nhiêu cái DB::table(”)->insert();
use DB; class DatabaseSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { DB::table('bomon')->insert([ array('MaBoMon'=>'BM01','TenBoMon'=>'Xây dựng'), array('MaBoMon'=>'BM02','TenBoMon'=>'Công nghệ thông tin'), array('MaBoMon'=>'BM03','TenBoMon'=>'Điện - Điện tử'), array('MaBoMon'=>'BM04','TenBoMon'=>'Cơ khí động lực'), ]); DB::table('user')->insert([ array('username'=>'admin','password'=>'123456') ]); } }
DB::table('phieucham')->insert([ array('maPhieuCham' => '01', 'diem' => 10, 'ngayCham' => '2018-09-05', 'nhanXet' => 'Hoàn thành tốt, có trách nhiệm'), ]); // 'năm-tháng-ngày'
php artisan make:factory TenFactory // ví dụ php artisan make:factory PostFactory
<?php /** @var \Illuminate\Database\Eloquent\Factory $factory */ use App\Post; use Faker\Generator as Faker; $factory->define(Post::class, function (Faker $faker) { return [ 'title' => $faker->sentence(3), 'content' => $faker->paragraphs(10, true), 'lead' => $faker->text(200), 'topic_id' => random_int(1, 20), 'author_id' => random_int(1, 20), ]; });
<?php use Illuminate\Database\Seeder; use App\Post; class DatabaseSeeder extends Seeder { /** * Seed the application's database. * * @return void */ public function run() { factory(Post::class, 20)->create(); } }
Migration sẽ chạy theo thứ tự tạo, nên cái nào không có khóa ngoại tạo trước, cái nào có khóa ngoại tạo sau nha.
Nếu đã lỡ xa chân vào lỗi không thực hiện như trên thì.
Nếu vẫn chưa được chạy cmd: composer dump-autoload
Do khóa ngoại sẽ tham chiếu đến khóa chính. Nên bảng cần tham chiếu khóa chính nên thêm thuộc tính unique().
Schema::create('hocvi', function (Blueprint $table) { $table->bigInteger('maHocVi')->unique(); $table->string('tenHocVi'); $table->timestamps(); });
public function up() { Schema::create('lop', function(Blueprint $table) { //$table->String('MaLop', 10)->unique(); //$table->String('TenLop', 70); //$table->String('EmailLop', 30); //$table->String('MaBoMon', 10); //$table->String('MaCV', 10); $table->foreign('MaBoMon')->references('MaBoMon')->on('bomon')->onDelete('cascade'); }); } //$table->foreign('CotBangHienTai')->references('CotBangForeign')->on('TenBangForeign')->onDelete('cascade');
Nên tạo bằng câu lệnh này để nó tạo luôn khai báo tên bảng
php artisan make:migration Ten_Migration --create=ten_bang
public function up() { Schema::create('lop', function(Blueprint $table) { $table->String('MaLop', 10)->unique(); $table->String('TenLop', 70); $table->String('EmailLop', 30); $table->String('MaBoMon', 10); $table->String('MaCV', 10); }); }
public function down() { Schema::dropIfExists('lop'); }
Hàm Schema
//tạo bảng Schema::create('categories', function (Blueprint $table) { // } //sửa bảng Schema::table('categories', function (Blueprint $table) { // } //đổi tên bảng Schema::rename('category', 'categories'); //Xóa bảng Schema::dropIfExists('categories');
Nếu khóa chính là kiểu String thì phải khai báo độ dài cho khóa chính và cho cả các khóa ngoại tham chiếu tới nó.
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class AddForeignKeysToPostsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('posts', function (Blueprint $table) { $table->unsignedBigInteger('topic_id')->index()->nullable(); $table->foreign('topic_id')->references('id')->on('topics'); $table->unsignedBigInteger('author_id')->index()->nullable(); $table->foreign('author_id')->references('id')->on('users'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('posts', function (Blueprint $table) { $table->dropForeign(['topic_id']); $table->dropColumn('topic_id'); $table->dropForeign(['author_id']); $table->dropColumn('author_id'); }); } }
Ở thư mục gốc => cmd
php artisan tinker
Nhập câu lệnh và sẽ trả kết quả về cho bạn
Request gửi tới nhưng bạn không muốn xử lý tại function đó mà muốn chuyển request đó sang funtion khác để xử lý thì làm như bên dưới nhé! Request bỏ zô một biến rồi truyền sang.
<?php public function veryComplexMethod(Request $request) { $data = $request->all(); return $this->veryComplexMethodProcessing($data); } public function veryComplexMethodProcessing($data) { //process data.... return $answer; }
$fileName = ""; $fileSize = ""; if ($rq->hasFile('fileToUpload')) { $file = $rq->fileToUpload; //Lấy Tên files $fileName = $file->getClientOriginalName(); //Lấy kích cỡ của file đơn vị tính theo bytes $fileSize = $file->getSize(); } if($fileName != "" && $fileSize < 10485760) { $file = $rq->fileToUpload; $fileName = url("public/img/upload/".$fileName); $file->move("public/img/upload", $file->getClientOriginalName()); //tham số đầu tiên là đường dẫn thư mục server, lưu ý không sử dụng asset ở đây } else { //code }
Tham khảo thêm tại: https://www.techblog.vn/bai-19-upload-files-trong-laravel
<form action=" {{ asset('thong-tin-can-bo') }}/{{ $email }}" method="post">
Bài viết này https://agitech.com.vn/vn/bai-viet/website/77-lap-trinh-laravel-dang-nhap-va-phan-quyen có trình bày rõ về cách hoạt động và code của Authentication Laravel. Các bạn xem và tham khảo nó nhé.
Ví dụ: Chuỗi “25122020” => “2020-12-25”
private function convertDate($date) { $date_return = substr($date,4,4); $date_return .= substr($date,2,2); $date_return .= substr($date,0,2); return date("Y-m-d", strtotime($date_return)); }
Route::group([ 'prefix' => 'bao-hiem-vien-phi', 'namespace'=>'Api' ], function () { Route::post('/add', 'BaoHiemVienPhiController@themBaoHiemVienPhi'); Route::post('/addPerson', 'BaoHiemVienPhiController@themNguoiDuocBaoHiemVienPhi'); Route::put('/edit', 'BaoHiemVienPhiController@editBaoHiemVienPhi'); Route::get('/cal-fee/{type}/{data}', 'BaoHiemVienPhiController@tinhPhi'); });
Thêm vào namespace
Route::group([ 'prefix' => 'bao-hiem-vien-phi', 'namespace'=>'Api' ], function () { Route::post('/add', 'BaoHiemVienPhiController@themBaoHiemVienPhi'); Route::post('/addPerson', 'BaoHiemVienPhiController@themNguoiDuocBaoHiemVienPhi'); Route::put('/edit', 'BaoHiemVienPhiController@editBaoHiemVienPhi'); Route::get('/cal-fee/{type}/{data}', 'BaoHiemVienPhiController@tinhPhi'); });
Route::namespace('App\Http\Controllers\api')->group(function () { Route::group(['middleware' => 'auth:sanctum'], function() { Route::post('create-event', 'CalendarController@createEvent'); Route::delete('delete-event/{id}', 'CalendarController@deleteEvent'); Route::get('event/{date}', 'CalendarController@getEvent'); Route::get('event-single/{id}', 'CalendarController@getSingleEvent'); Route::post('update-event/{id}', 'CalendarController@updateEvent'); Route::post('create-task', 'TaskController@createTask'); Route::post('change-color-task/{id}', 'TaskController@updateColorTask'); Route::delete('delete-task/{id}', 'TaskController@deleteTask'); Route::get('task', 'TaskController@getAllTask'); }); Route::post('login', 'UserController@login'); });
Route::group(['prefix'=>'admin', 'middleware' => 'admin'], function () { Route::get('home/{id?}', 'AdminController@getTrangChu'); });
const mix = require('laravel-mix'); /* |-------------------------------------------------------------------------- | Mix Asset Management |-------------------------------------------------------------------------- | | Mix provides a clean, fluent API for defining some Webpack build steps | for your Laravel applications. By default, we are compiling the CSS | file for the application as well as bundling up all the JS files. | */ mix.js('resources/js/app.js', 'public/js').vue() .sass('resources/css/app.scss', 'public/css');
<!doctype html> <html lang="{{ app()->getLocale() }}"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="{{ asset('/img/calendar_logo_icon.ico') }}"> <link rel="stylesheet" href="{{ asset('/css/reset.css') }}"> <link rel="stylesheet" href="{{ asset('/css/app.css') }}"> <!-- <link rel="stylesheet" href="./css/bootstrap.min.css"> --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" /> <title>Calendar</title> </head> <body> <div id="app"> </div> <script> window.Laravel = <?php echo json_encode([ 'csrfToken' => csrf_token(), ]); ?> </script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="{{ mix('js/app.js') }}"></script> </body> </html>
npm install --save vue vue-router
npm install laravel-mix@latest --save-dev
import Vue from 'vue' import App from './App.vue' Vue.config.productionTip = false; new Vue({ render: h => h(App) }).$mount('#app')
<template> <div> abc </div> </template> <script> export default { name: 'App' } </script>
Chạy lệnh:
npm run watch
Trường hợp gặp lỗi:
Cannot find module ‘webpack/lib/rules/DescriptionDataMatcherRulePlugin’ Require stack:
Hãy chạy lệnh dưới
npm update vue-loader // nếu chưa install chạy lệnh dưới npm i vue-loader
Nếu gặp lỗi hãy thay phần script ở file package.json:
// before "scripts": { "dev": "npm run development", "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", "watch": "npm run development -- --watch", "watch-poll": "npm run watch -- --watch-poll", "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --disable-host-check --config=node_modules/laravel-mix/setup/webpack.config.js", "prod": "npm run production", "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" }, // after "scripts": { "dev": "npm run development", "development": "mix", "watch": "mix watch", "watch-poll": "mix watch -- --watch-options-poll=1000", "hot": "mix watch --hot", "prod": "npm run production", "production": "mix --production" },
php artisan vue-i18n:generate
Tạo API và Authenticate nhanh chóng với package Laravel Sanctum
//import hash use Illuminate\Support\Facades\Hash; //hash Hash::make('chuoiPassword'); //check Hash::check('chuoiPassword', 'Chuoi hash lưu trong database')
Mặc định laravel sẽ run project ở cổng 8000.
Để run mặc định bạn chạy lệnh sau:
php artisan serve
Để thay đổi cổng theo ý muốn bạn sử dụng lệnh sau:
php artisan serve --port=... // ... thay thanh port (8001, 8002, ...)
$membe = Member::->where('winner', 1)->orderBy('created_at', 'DESC')->paginate(10);
<div class="ot-pagination clearfix"> <div class="text-center"> <!-- Previous Page Link --> <a href="{{$memberExams->onFirstPage() ? 'javascript:void(0)' : $memberExams->previousPageUrl()}}" rel="prev"><strong class="prev active"></strong></a> <!-- Element Page Link --> @for($page = 1; $page <= $memberExams->lastPage(); $page++) @if(($memberExams->currentPage() == 1 && $page <= $memberExams->currentPage() + 4) || ($memberExams->currentPage() == 2 && $page <= $memberExams->currentPage() + 3) || (($memberExams->currentPage() == $memberExams->lastPage() || $memberExams->currentPage() == $memberExams->lastPage() - 1) && ($page - 3 >= 1 || $page - 4 >= 1)) || ($page >= $memberExams->currentPage() - 2 && $page <= $memberExams->currentPage() + 2)) <strong> <a href="{{$memberExams->url($page)}}" class="page-link {{$page == $memberExams->currentPage() ? 'active' : ''}}"> <span>{{$page}}</span> </a> </strong> @endif @endfor <!-- Next Page Link --> <a href="{{$memberExams->hasMorePages() ? $memberExams->nextPageUrl() : 'javascript:void(0)'}}" rel="next"><strong class="next active"></strong></a> </div> </div>
use Illuminate\Pagination\Paginator; use Illuminate\Support\Collection; use Illuminate\Pagination\LengthAwarePaginator;
$member = Member::->where('winner', 1)->orderBy('created_at', 'DESC')->get();
public function paginate($items, $perPage = 5, $page = null, $options = []) { $page = $page ?: (Paginator::resolveCurrentPage() ?: 1); $items = $items instanceof Collection ? $items : Collection::make($items); return new LengthAwarePaginator($items->forPage($page, $perPage), $items->count(), $perPage, $page, ['path'=>url('thi-thu-nhan-qua')]); }
<input type="text" name="username" value="{{ old('username') }}">
public function post(Request $request) { return back()->withInput( $request->only('username') ); }
Tham khảo: https://viblo.asia/p/tap-16-request-laravel-aWj534Y8K6m mục 8c
'phone' => ['required', 'max:191', 'regex:((09|03|07|08|05)+([0-9]{8})\b)'],
//https://regex101.com/r/cD8nG4/1 $content = preg_replace( "/<a[\S\s]+?<\/a>(*SKIP)(*FAIL)|<img[\S\s]+?\>(*SKIP)(*FAIL)|($keyword)/i", $linkReplace, $content, $limit - $keywordLinkCount, $count );
Giả sử, bảng User có field first_name và last_name.
Bên ngoài hiển thị cần hiển thị dạng full_name (first_name + space + last_name).
Trong Model User viết hàm như sau:
public function getFullNameAttribute() // get[property_name]Attribute { return $this->first_name . " " . $this->last_name; }
Khi cần sử dụng full_name, thì sử dụng nó như thuộc tính bình thường
$data = \App\Models\User::all(); foreach($data as $item) { echo $item->full_name . "<br />"; // get full_name như thuộc tính }
Giả sử, bảng User có field first_name và last_name.
Khi insert hoặc update vào database thì in hoa first_name rồi mới insert vào.
Trong model User:
public function setCompanyNameAttribute($value) // camelCase => function set[property_name]Attribute { $this->attributes['company_name'] = strtoupper($value); }
Khi đó, insert và update như bình thường, nó sẽ apply function đó vào thuộc tính first_name.
$item = new \App\Models\User(); $item->first_name = "Do"; // => Database sẽ lưu => DO $item->last_name = "Hao"; $item->save();
Apply cho toàn bộ query của eloquent.
Giả sử, bảng User có field role.
Khi truy vấn bạn muốn toàn bộ query không lấy giá trị null của role
Trong model User:
// nhớ import Builder use Illuminate\Database\Eloquent\Builder; ... protected static function booted() { static::addGlobalScope('filterRole', function (Builder $builder) { // filterRole => ten global scope $builder->whereNotNull('role'); // thay thành câu điều kiện cho toàn bộ truy vấn }); }
Nếu một truy vấn nào đó không muốn apply global scope vào
// Xóa một global scope User::withoutGlobalScope('role')->get(); // thay role thành tên global scope cần xóa // Xóa nhiều global scope // Xóa toàn bộ User::withoutGlobalScopes()->get(); // Xóa một vài global scope User::withoutGlobalScopes([ FirstScope::class, SecondScope::class ])->get();
Apply cho một query nào đó của eloquent.
Giả sử, bảng User có field role.
Câu truy vấn bạn muốn query lấy role >= 2 (Và câu điều kiện này sử dụng ở nhiều nơi)
Trong model User:
public function scopeActive($query) // scope[scopeName] { return $query->where('role', '>=', 2); }
Khi sử dụng.
$data = \App\Models\User::active()->get(); // gọi scopeName
Giả sử bạn muốn truyền tham số để query role, có thể thay đổi linh hoạt hơn.
Trong User model:
public function scopeActive($query, $roleUp) // Thêm param sau $query để sử dụng { return $query->where('role', '>=', $roleUp); }
Khi sử dụng:
$data = \App\Models\User::active(3)->get(); // truyển param vào scopeName
Lưu ý:
+ Relationship dựa trên tên model
+ Khóa ngoại được xác định bằng cách: ten_model_id (tên model dạng snakeCase).
+ Nếu khóa ngoại không như cấu trúc trên, sử dụng tham số thứ 2 sau hasOne để xác định khóa ngoại của bảng cần tham chiếu
+ Tương tự khóa chính là id, nếu khác sử dụng tham số thứ 2 để xác định id của bảng cần tham chiếu
Vd1: Bảng posts (Model: Post) và comments (Model: Comment).
Post hasOne Comment => function sẽ có s phía sau tên (tên function là tên model liên kết dạng snakeCase) comments
Comment belongTo => function sẽ không có s phía sau tên (tên function là tên model liên kết dạng snakeCase) post
Lưu ý: Relationship chỉ dựa vào tên model.
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Post extends Model { /** * Get the comments for the blog post. */ public function comments() { return $this->hasMany('App\Comment'); } }
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Comment extends Model { /** * Get the post that owns the comment. */ public function post() { return $this->belongsTo('App\Post'); } }
Ví dụ 2: cho bảng có tên dài. Có bảng
mail_templates => Model: MailTemplate
và bảng
sendmail_cv_settings => Model: SendmailCvSetting
Lưu ý: Relationship chỉ dựa vào tên model.
MailTemplate hasOne SendmailCvSetting=> function sẽ có s phía sau tên (tên function là tên model liên kết dạng snakeCase) sendmailCvSettings
SendmailCvSetting belongTo => function sẽ không có s phía sau tên (tên function là tên model liên kết dạng snakeCase) mailTemplate
class MailTemplate extends BaseModel { //Declare table name protected $table = 'mail_templates'; use SoftDeletes; protected $fillable = ['id']; public function sendmailCvSettings() { return $this->hasMany(\App\Models\SendmailCvSetting::class, 'mail_template_id'); } }
class SendmailCvSetting extends BaseModel { //Declare table name protected $table = 'sendmail_cv_settings'; use SoftDeletes; protected $fillable = ['id']; public function mailTemplate() { return $this->belongsTo(\App\Models\MailTemplate::class); } }
$sendmailCvData = SendmailCvSetting::query(); $sendmailCvData->with('mailTemplate'); // sử dụng with, param là tên model tham chiếu. //=> data khi query sẽ có mục relation chứa data tham chiếu.
let param = { YOUR_EMAIL: 'your@gmail.com', YOUR_PASS: 'apppassword', ADDRESS_FROM_USER_SEE: 'your@gmail.com', NAME_USER_SEE: 'your name', TEMPLATE_MAIL: 'emails.create-job', // file blade trong resource/view SUBJECT_TEXT: 'Send mail from ....', EMAIL_SEND: [ 'abc@gmail.com' ] }; console.log('Cấu hình .env'); let data = ` MAIL_DRIVER=smtp MAIL_HOST=smtp.gmail.com MAIL_PORT=587 MAIL_USERNAME=YOUR_EMAIL MAIL_PASSWORD=YOUR_PASS MAIL_ENCRYPTION=tls MAIL_FROM_ADDRESS=ADDRESS_FROM_USER_SEE MAIL_FROM_NAME="NAME_USER_SEE" `; data = data.replaceAll('YOUR_EMAIL', param.YOUR_EMAIL); data = data.replaceAll('YOUR_PASS', param.YOUR_PASS); data = data.replaceAll('ADDRESS_FROM_USER_SEE', param.ADDRESS_FROM_USER_SEE); data = data.replaceAll('NAME_USER_SEE', param.NAME_USER_SEE); console.log(data); console.log('Tại nơi cần xử lý gửi mail'); console.log('use Mail;'); data = ` Mail::send('TEMPLATE_MAIL', [ // 'name' => 'admin', // 'clientJob' => $clientJob, // 'clientUser' => $clientUser, // 'client' => $client, // 'dataJoin' => (object) $dataJoin // add variable vào để sử dụng trong view ], function($message) /* use ($clientJob, $clientUser) => Phần này khai báo các biến sử dụng cho function ở dưới*/ {` param.EMAIL_SEND.forEach( (item) => { data += ` $message->to('${item}')->subject('SUBJECT_TEXT');`; }); data += ` }); `; data = data.replaceAll('TEMPLATE_MAIL', param.TEMPLATE_MAIL); data = data.replaceAll('SUBJECT_TEXT', param.SUBJECT_TEXT); console.log(data);
Xem thêm: https://viblo.asia/p/huong-dan-gui-mail-voi-laravel-5-XQZkxZEbGwA
// $item->thumbnail: File upload gửi lên server $pathImage = 'uploads/cv-sample/images'; $resourceType = imagecreatefrompng($item->thumbnail); $sourceProperties = getimagesize($item->thumbnail); $sourceImageWidth = $sourceProperties[0]; $sourceImageHeight = $sourceProperties[1]; $newWidth = 224; $newHeight = 316; $imageLayer = ImageService::resizeImage($resourceType, $sourceImageWidth, $sourceImageHeight, $newWidth, $newHeight); imagepng($imageLayer, $pathImage . '/' . $newSample->id . '.png');
public static function resizeImage($resourceType, $image_width, $image_height, $resizeWidth, $resizeHeight) { // $resizeWidth = 100; // $resizeHeight = 100; $imageLayer = imagecreatetruecolor($resizeWidth, $resizeHeight); imagecopyresampled($imageLayer, $resourceType, 0, 0, 0, 0, $resizeWidth, $resizeHeight, $image_width, $image_height); return $imageLayer; } // hàm này t bỏ vô ImageService.php file
Tham khảo: https://www.devopsschool.com/blog/how-to-upload-and-resize-an-image-using-php/
https://tailwindcss.com/docs/guides/laravel
// Run lệnh npm install -D tailwindcss postcss autoprefixer // sau đó npm run dev
1. Vào file webpack.frontend.mix 2. Change png|jpe?g|gif|webp => png|jpe?g|gif|webp|avif 3. Chạy lại thử
Thêm dòng bên dưới ở trên console.log // eslint-disable-next-line no-console
//==== Reset database ==== // 1. Backup db // 2. Migrate php artisan migrate // 3. Seeding php artisan db:seed // 4. delete table delete table generates, auth_clients // 5. import table từ db cũ import table generates cũ qua mới import table auth_clients cũ qua mới
use Illuminate\Support\Facades\Crypt; Crypt::encryptString($encryptKey); Crypt::decryptString($encryptKey);
Còn nhiều kinh nghiệm ở các bài viết khác: