# 套件說明 Flash Message Step 0.安裝套件 composer require laracasts/flash Step 1.在要顯示訊息的視圖上加上Bootstrap樣式,一般放在<head>標籤內,如下: <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> Step 2.在要顯示訊息的視圖上載入JS,一般放在</body>之前 <!-- Flash Message Overlay會用到,需保留 --> $('#flash-overlay-modal').modal(); <!-- Flash Message 3秒之後消失,非必須 --> $('div.alert').delay(3000).fadeOut(350); Step 3.在視圖上要顯示訊息的位置加入以下程式碼 @include('flash::message') 使用Flash Message //app/Http/Controllers/OrderController.php public function store(){ //儲存訂單到資料庫 flash('訂單建立完成!!')->success(); //綠色框 flash('訂單建立失敗!!')->error(); //紅色框 flash('請向客服確認此訂單!!')->warning(); //橘色框 flash('訂單建立完成!!')->overlay(); //跳出視窗 flash()->overlay('Modal Message', 'Modal Title'); //跳出帶標題視窗 flash('訂單建立完成')->important(); //加上關閉功能 flash('Message')->error()->important(); //結合外框與關閉功能 return redirect('/'); } 如果需要顯示多個訊息,可多次呼叫flash() 進階技巧 讓訊息顯示3秒後自動消失 <script> $('div.alert').not('.alert-important').delay(3000).fadeOut(350); </script> 複寫訊息的視圖 開啟Terminal,輸入以下指令 php artisan vendor:publish --provider="Laracasts\Flash\FlashServiceProvider" 也可以不指定provider,只輸入vendor:publish,從選項去選也是一樣的 訊息沒有顯示的可能原因 我曾出現因為Session內容結構改變(flash_notification型別為集合而非預設的物件,可能是因為做了多次的flash())導致Blade判斷時認為沒有訊息需要顯示 解決方案: Step 1.執行以下指令 php artisan vendor:publish --provider=“Laracasts\Flash\FlashServiceProvider” Step 2.修改 resources/views/vendor/flash/message.blade.php成以下內容 @if (Session::has('flash_notification')) @if (Session::has('flash_notification.overlay')) @include('flash::modal', ['modalClass' => 'flash-modal', 'title' => Session::get('flash_notification.title'), 'body' => Session::get('flash_notification.message')]) @else @foreach (Session::get('flash_notification') as $item) @if (Session::has('flash_notification.important')) <div class="alert alert-important alert-{{ $item->level }}"> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> {{ $item->message }} </div> @else <div class="alert alert-{{ $item->level }}"> {{ $item->message }} </div> @endif @endforeach @endif @endif 購物車 安裝套件 Step 1.開啟Terminal,輸入以下指令 composer require "darryldecode/cart:~4.0" 安裝套件時如果出現記憶體不足的錯誤,可開啟Apache伺服器>config>php.ini,找到裏頭的一行設定"memory_limit",將其值改成-1,即可不限定伺服器的記憶體空間 Step 2.(非必須)修改config/app.php,加入 provider與 alias 加入以下到Service Provider陣列 Darryldecode\Cart\CartServiceProvider::class 加入以下到Alias陣列 'Cart' => Darryldecode\Cart\Facades\CartFacade::class 常用變數內容 $item = \App\Item::find(商品主鍵); $rowId = 商品主鍵 $userID = Auth::user()->id; 基礎用法 使用Cart Facade前,記得加上use Cart; 將商品加入購物車 \\app\Http\Controllers\ShopController.php public function addItem(Item $item){ $data = [ 'id' =>$item->id, 'name' => $item->title, 'price' => $item->price, 'quantity' => 1, 'attributes' => [], //額外屬性 'associatedModel' => $item //商品模型物件 ]; Cart::session($userID)->add($data); } 測試路由 Route::get('/shops/additem/{item}','App\Http\Controllers\ShopController@addItem'); 變更購物車裏頭的商品 這個方法並非設定商品的屬性,而是增加。比方說 quantity => 1 ,表示數量加1的意思 \\app\Http\Controllers\ShopController.php public function updateItem(Item $item,$qty){ \Cart::session($userID)->update($item->id,[ 'quantity' => $qty ]); } 測試路由 Route::get('/shops/updateitem/{item}/{qty}','App\Http\Controllers\ShopController@updateItem'); 刪除購物車中的商品 \\app\Http\Controllers\ShopController.php public function removeItem(Item $item){ \Cart::session($userID)->remove($item->id); } 測試路由 Route::get('/shops/removeitem/{item}','App\Http\Controllers\ShopController@removeItem'); 取得購物車的內容 \\app\Http\Controllers\ShopController.php public function getContent(){ $cartContent = \Cart::session($userID)->getContent(); dd($cartContent); } 測試路由 Route::get('/shops/getcontent','App\Http\Controllers\ShopController@getContent'); 進階用法 清空購物車 \\app\Http\Controllers\ShopController.php public function clear(){ \Cart::session($userID)->clear(); } 測試路由 Route::get('/shops/clear','App\Http\Controllers\ShopController@clear'); 確認購物車是否為空 \\app\Http\Controllers\ShopController.php public function checkEmpty(){ $isEmpty = \Cart::session($userID)->isEmpty(); dd($isEmpty); } } 測試路由 Route::get('/shops/checkempty','App\Http\Controllers\ShopController@checkEmpty'); 確認購物車商品總數 \\app\Http\Controllers\ShopController.php public function getTotalQuantity(){ $qty = \Cart::session($userID)->getTotalQuantity(); return $qty; } 測試路由 Route::get('/shops/gettotalquantity','App\Http\Controllers\ShopController@getTotalQuantity'); 取得小計與總計 \\app\Http\Controllers\ShopController.php public function getTotal(){ $subtotal = \Cart::session($userID)->getSubTotal(); $total = \Cart::session($userID)->getTotal(); return '小計:' . $subtotal . ',總計:' . $total; } 測試路由 Route::get('/shops/gettotal','App\Http\Controllers\ShopController@getTotal'); 自定義功能頁面(非必須) 開啟Terminal,輸入以下指令 php artisan vendor:publish --provider="Darryldecode\Cart\CartServiceProvider" --tag=“config" 多語系支持 mcamara / laravel-localization 說明如何使用 mcamara ,來達成讓應用能夠透過路徑,同時支援多個語系,比如/en/shop 抑或是/zh_tw/shop,還支援 session 和 cookie 等機制記憶。 mcamara官網說明 知識點 0.使用套件簡易步驟 Step 1.用compoer安裝套件 Step 2.(可選)如果是Laravel5.5以前的版本,需要註冊provider和alias Step 3.用vendor:publish生成設定檔laravellocalization.php Step 4.修改laravellocalization.php設定檔的supportedLocales Step 5.修改web.php,新增套件路由群組,並移入需要支援翻譯的路由 Step 6.(可選)如需使用更多的中介層功能,需在App\Http\Kernal.php的$routeMiddleware陣列進行註冊 知識點 1.如何安裝套件 可開啟Terminal命令列,透過composer來安裝: composer require mcamara/laravel-localization 在Laravel 5.5,service provider(服務供應器)和facade將會自動地被註冊。但對於較早的框架版本,請跟隨以下的步驟來註冊: Step 1.在 config/app.php 註冊service provider 'providers' => [ //... Mcamara\LaravelLocalization\LaravelLocalizationServiceProvider::class, ], Step 2.同樣地,在 config/app.php 註冊LaravelLocalization facade: 'aliases' => [ //... 'LaravelLocalization' => Mcamara\LaravelLocalization\Facades\LaravelLocalization::class, ], 知識點 2.設定套件 設定檔案 Config Files 為了能編輯此套件的預設設定檔,你需要執行以下命令: php artisan vendor:publish --provider="Mcamara\LaravelLocalization\LaravelLocalizationServiceProvider" 完成後,config/laravellocalization.php將會被建立。在這檔案內,你將找到所有套件能夠被編輯的設定。編輯laravellocalization.php,主要修改supportedLocales,移除所需要支持語系的註解。 'useAcceptLanguageHeader' => false, //設定當網址沒有語系路徑段時,是否取用瀏覽器Accept-Language header的設定,若否則取自app.php的設定 'hideDefaultLocaleInURL' => true, //設定是否隱藏預設的語系路徑段 'urlsIgnored' => [], //設定哪些路徑要排除,不進行翻譯轉址 服務供應器 Service Providers 否則,你能夠使用 ConfigServiceProviders (檢查此檔案來得到更多資訊) 例如,編輯預設 config service provider ,該檔會在安裝後被Laravel載入。這個檔案位在app/providers/ConfigServicePovider.php,內容如下: <?php namespace App\Providers; use Illuminate\Support\ServiceProvider; class ConfigServiceProvider extends ServiceProvider { public function register() { config([ 'laravellocalization.supportedLocales' => [ 'ace' => array( 'name' => 'Achinese', 'script' => 'Latn', 'native' => 'Aceh' ), 'ca' => array( 'name' => 'Catalan', 'script' => 'Latn', 'native' => 'català' ), 'en' => array( 'name' => 'English', 'script' => 'Latn', 'native' => 'English' ), ], 'laravellocalization.useAcceptLanguageHeader' => true, 'laravellocalization.hideDefaultLocaleInURL' => true ]); } } 這個設定檔加入Catalan 和 Achinese作為語系,並且覆蓋套件內任何其他支持語系和設定。 你能夠建立你自己的config providers並把他們加入你的應用設定檔,可檢查在config/app.php檔案內的 providers 陣列。 知識點 3.如何使用此套件? Laravel 本地化使用請求的網址來判斷適合的語系。為了達到這個目的,一個路由群組應該要加到 route.php 檔裡頭。它需要過濾所有必須本地化的頁面。 // routes/web.php //要被本地化的頁面 Route::group(['prefix' => LaravelLocalization::setLocale()], function() { /** ADD ALL LOCALIZED ROUTES INSIDE THIS GROUP **/ Route::get('/', function() { return View::make('hello'); }); Route::get('test',function(){ return View::make('test'); }); }); /* 剩下不要被本地化的頁面 */ 一旦這個路由群組被加入路由檔內,使用者能夠取用所有被加入 supportedLocales 設定的語系。(預設是en和es,可到config區塊來改變選項。)例如,使用者現在能取用兩個不同的語系。透過請求以下網址: http://url-to-laravel/en http://url-to-laravel/es 假如語系並未出現在網址上,如下例,又或者是並未被定義在 supportedLocales 之內,系統將使用應用的預設語系,又或者是使用者瀏覽器的預設語系(定義在config檔內)。 http://url-to-laravel 當語系定義完,語系變數將會被存在session裡面(假如中介層有啟用),所以在語系定義過後就不需要在網址內加入/lang/這段路徑,因為將會讓該使用者對應最後已知語系。假如使用者取用不同的語系,該語系變數就會被改變,使用最新的語系變數來翻譯其他新拜訪頁面。 版型檔和所有語系檔應該要跟隨Lang類別。 知識點 4.此套件的中介層負責什麼工作? 這個套件包含一個中介層物件來轉址所有非本地化路由到對應的本地化路由。所以,假如使用者訪問 http://url-to-laravel/test ,那麼系統發現這個中介層是啟用的,並且使用者的當前語系是’en’,它將會自動地把使用者導到 http://url-to-laravel/en/test。這主要是用來避免不同網址卻回傳相同內容的問題以優化SEO。 為此,你必須註冊這個中介層到 app/Http/Kernal.php 檔案內,像這樣: <?php namespace App\Http; use Illuminate\Foundation\Http\Kernel as HttpKernel; class Kernel extends HttpKernel { /** * The application's route middleware. * * @var array */ protected $routeMiddleware = [ /**** 其他中介層 ****/ 'localize' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class, 'localizationRedirect' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class, 'localeSessionRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class, 'localeViewPath' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationViewPath::class // REDIRECTION MIDDLEWARE ]; } // app/Http/routes.php Route::group( [ 'prefix' => LaravelLocalization::setLocale(), 'middleware' => [ 'localeSessionRedirect', 'localizationRedirect', 'localeViewPath' ] ], function() { /** 加入所有本地化路由到這個群組之內 **/ Route::get('/', function() { return View::make('hello'); }); Route::get('test',function(){ return View::make('test'); }); }); /** 其他不應該被本地化的頁面 **/ 為了要啟用,你只需加入這個中介層到想要取用本地化的路由裡頭。另外,假如你想要隱藏預設語系但永遠顯示其他路由到網址上,把 hideDefaultLocaleInURL 設定值改為true。設好之後,假如預設語系是en,那所有包含/en/語系路徑的網址將會被轉址到相同但是去掉/en/這個語系路徑的網址,而且語系仍舊是en,也就是English。 當 hideDefaultLocaleInURL 和 useAcceptLanguageHeader 都設為true,那語言協商使用 Accept-Language 標頭將只會發生在 session('locale)為空的時候。在協商之後,session('locale)將被對應設定而且將不會再被呼叫。 透過view-base-path設定當前語系 為了設定當前語系作為 view-base-path,只需要註冊 localeViewPath-middlware 到Kernal.php,就像之前描述的那樣。現在你能夠把你的視圖打包進以語系分類的資料夾內,就如同翻譯檔的架構那樣,如下所示。 resources/views/en/, resources/views/fr, … 知識點 5.能夠自訂語系路徑區塊? 你能夠修改 supportedLocales 透過重新命名他們的 key,使用字串 uk 而非 en-GB 來提供自訂語系路徑區塊是可能的。當然,你需要避免重複使用已經存在的 key,並盡可能服從慣例。但假使你正在使用自訂 key,你需要將它存在 localesMapping 陣列內。這個 localesMapping 陣列是需要被用來啟用 LanguageNegotiator 從而能根據 HTTP Accept Language Header 來正確分配希望的語系。這是一個將 HTTP Accept Language Header 對應到語系路徑區塊’uk’的例子: // config/laravellocalization.php 'localesMapping' => [ 'en-GB' => 'uk' ], 知識點 6.幫助函式? 此套件提供了一些有幫助的函式,像這些: 取得指定語系的網址 public function getLocalizedURL($locale = null, $url = null, $attributes = array()) //如要在視圖內使用,可以像這樣呼叫,它將會回傳需求語系的本地化後網址: {{ LaravelLocalization::getLocalizedURL(optional string $locale, optional string $url, optional array $attributes) }} Route Model Binding?放心,當生成本地化路徑時route model binding是有被支援的。 取得乾淨的路由 public function getNonLocalizedURL($url = null) //如要在視圖內使用,可以像這樣呼叫,它將會回傳任何本地化網址的乾淨網址 {{ LaravelLocalization::getNonLocalizedURL(optional string $url) }} 取得網址的語系key public function getURLFromRouteNameTranslated($locale, $transKeyName, $attributes = array()) //如要在視圖內使用,可以像這樣呼叫,它將會回傳一個路由,根據傳入語系來進行本地化。假如該翻譯 key 並未存在於語系內,此函式將會回傳 false {{ LaravelLocalization::getURLFromRouteNameTranslated(string $locale, optional array $transKeyNames, optional array $attributes) }} 取得支持語系列表 public function getSupportedLocales() //如要在視圖內使用,可以像這樣呼叫,此函式將會回傳所有支持語系與其屬性,型態為陣列。 {{ LaravelLocalization::getSupportedLocales() }} 取得支持語系列表,以指定的順序 public function getLocalesOrder() //如要在視圖內使用,可以像這樣呼叫,此函式將回傳所有支持語系但根據設定檔所指定的路徑。你能夠使用這個函式來印出語言選擇器。 {{ LaravelLocalization::getLocalesOrder() }} 取得支持語系Keys public function getSupportedLanguagesKeys() //如要在視圖內使用,可以像這樣呼叫,這個函式將回傳支持語系的對應key,型態為陣列。 {{ LaravelLocalization::getSupportedLanguagesKeys() }} 設定語系 public function setLocale($locale = null) //如要在視圖內使用,可以像這樣呼叫,這個函式將改變應用的當前語系。假如語系沒被傳入,語系將會透過 cookie . session (假如先前有存入) . 瀏覽器Accept-Language header ,又或是預設應用語系來決定,根據你的設定檔。這個函式應該被任何要被翻譯的路由之prefix所呼叫,請見 Filters 區塊來取得更多資訊。 {{ LaravelLocalization::setLocale(optional string $locale) }} 取得當前語系 public function getCurrentLocale() //如要在視圖內使用,可以像這樣呼叫,此函式將回傳當前語系的key {{ LaravelLocalization::getCurrentLocale() }} 取得當前語系名稱 public function getCurrentLocaleName() //如要在視圖內使用,可以像這樣呼叫,此函式將回傳當前語系的名稱,型態為字串,如English/Spanish/Arabic/ ..etc。 {{ LaravelLocalization::getCurrentLocaleName() }} 取得當前語系方向 public function getCurrentLocaleDirection() //如要在視圖內使用,可以像這樣呼叫,此函式將回傳當前語系的方向,型態為字串,如ltr/rtl。 {{ LaravelLocalization::getCurrentLocaleDirection() }} 取得當前語系腳本 public function getCurrentLocaleScript() //如要在視圖內使用,可以像這樣呼叫,此函式將以 ISO 15924 編碼回傳當前語系腳本,型態為字串,如"Latn", "Cyrl", "Arab", etc。 {{ LaravelLocalization::getCurrentLocaleScript() }} 知識點 7.創造語言選擇器 假如你想在你的專案上支持多語系,你也許想要提供使用者一個管道得以改變語言。以下是一個簡單的 blade 範本碼例子,讓你得以建立自己的語言選擇器。 <ul> @foreach(LaravelLocalization::getSupportedLocales() as $localeCode => $properties) <li> <a rel="alternate" hreflang="{{ $localeCode }}" href="{{ LaravelLocalization::getLocalizedURL($localeCode, null, [], true) }}"> {{ $properties['native'] }} </a> </li> @endforeach </ul> 這裡預設語言將會在 getLocalizedURL() 被強迫顯示在網址上,哪怕 hideDefaultLocaleInURL 為 true,而且 Route Model Binding 是有支持的。 知識點 8.翻譯路由 你能夠根據你想要顯示的語言來修改你的網址。比如 http://url/en/about 和 http://url/es/acerca(acerca是about的spanish版本),又或是 http://url/en/view/5 和 http://url/es/ver/5 (var 是 view 的 spanish 版本),都將被轉址到相同的控制器使用合適的過濾器和設定以下翻譯: 因為它是中介層,首先你必須註冊它到 app/Http/Kernel.php 檔案裡頭,像這樣: <?php namespace App\Http; use Illuminate\Foundation\Http\Kernel as HttpKernel; class Kernel extends HttpKernel { /** * The application's route middleware. * * @var array */ protected $routeMiddleware = [ /**** OTHER MIDDLEWARE ****/ 'localize' => 'Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes', // TRANSLATE ROUTES MIDDLEWARE ]; } // app/Http/routes.php Route::group( [ 'prefix' => LaravelLocalization::setLocale(), 'middleware' => [ 'localize' ] // Route translate middleware ], function() { /** ADD ALL LOCALIZED ROUTES INSIDE THIS GROUP **/ Route::get('/', function() { // This routes is useless to translate return View::make('hello'); }); Route::get(LaravelLocalization::transRoute('routes.about'), function() { return View::make('about'); }); Route::get(LaravelLocalization::transRoute('routes.view'), function($id) { return View::make('view',['id'=>$id]); }); }); /** OTHER PAGES THAT SHOULD NOT BE LOCALIZED **/ 在路由檔你只需要加入 LaravelLocalizationRoutes 過濾器和 LaravelLocalization::transRoute函式到每一個你想要使用翻譯key的路由。 然後你必須創造翻譯檔並加入每一個你想要翻譯的key。我建議建立一個route.php檔案到你的 resources/lang/language_abbreviation 資料夾。對之前的例子,我建立兩個翻譯檔案,它們長得像這樣: // resources/lang/en/routes.php return [ "about" => "about", "view" => "view/{id}", //we add a route parameter // other translated routes ]; // resources/lang/es/routes.php return [ "about" => "acerca", "view" => "ver/{id}", //we add a route parameter // other translated routes ]; 當檔案被儲存後,你能夠正常的取用 http://url/en/about , http://url/es/acerca , http://url/en/view/5 和 http://url/es/ver/5,沒有任何問題。 知識點 9.事件 你能夠在翻譯時捕捉網址參數,假如你也想要翻譯它們的話。為達此,只需要為路由創造一個事件偵聽器,翻譯事件像這樣: Event::listen('routes.translation', function($locale, $attributes) { // 作你的操作 return $attributes; }); 知識點 10.問題排除 如果出現以下錯誤,表示Middleware尚未進行註冊,請參考知識點4來進行設定 ReflectionException (-1) Class localeSessionRedirect does not exist LaraStreamer 這個套件是用來實作串流影片功能 安裝流程 Step 1.透過composer下載套件 composer require rajurayhan/larastreamer Step 2.出版設定檔 php artisan vendor:publish --tag=larastreamer 使用方法 此套件已經內建了以下的串流路由 Route::get('/stream/{filename}', 'Raju\Streamer\Controllers\StreamController@stream')->name('stream'); 只需要使用像這樣的網址就能夠進行訪問,其中test.mp4為影片檔案名稱 http://teststream.test/stream/test.mp4 所有的影片檔案預設需放至於storage/app/uploads資料夾內,可以到config/larastreamer.php進行變更,如下所示: return [ 'basepath' => storage_path('app/uploads/'), ]; 效果示例 Laravel Excel 官方網站 安裝套件 開啟Terminal,輸入以下指令 composer require maatwebsite/excel 5分鐘簡易匯入Excel Step 1.生成Import類別 可透過以下指令來生成此類別,生成的類別位在app/Imports資料夾內 php artisan make:import UsersImport --model=User . ├── app │ ├── Imports │ │ ├── UsersImport.php │ └── composer.json 或者你可以自己撰寫,格式如下: <?php namespace App\Imports; use App\User; use Illuminate\Support\Facades\Hash; use Maatwebsite\Excel\Concerns\ToModel; class UsersImport implements ToModel { /** * @param array $row * * @return User|null */ public function model(array $row) { //可設定如果沒有某欄位,該行就不要匯入 if(!isset($row[0])){ return null; } return new User([ //設定欄位對應,第一欄對應name欄位,第二欄對應email欄位 'name' => $row[0], 'email' => $row[1], 'password' => Hash::make($row[2]), ]); } } Step 2.在控制器使用Import類別來進行載入 use App\Imports\UsersImport; use Maatwebsite\Excel\Facades\Excel; use App\Http\Controllers\Controller; class UsersController extends Controller { public function import() { Excel::import(new UsersImport, 'users.xlsx'); return redirect('/')->with('success', 'All good!'); } } 如果有多個Sheet,只需要匯入某個Sheet… Step 1.在Import類別導入類別並實作 <?php namespace App\Imports; ... use Maatwebsite\Excel\Concerns\WithMultipleSheets; ... class UserImport implements ToModel,WithMultipleSheets Step 2.在Import類別加入以下函式 下列程式表示只匯入第一個sheet public function sheets(): array { return [ 0 => $this, ]; } 從Sheet的第幾行開始讀 Step 1.在Import類別導入類別並實作 <?php namespace App\Imports; ... use Maatwebsite\Excel\Concerns\WithStartRow; ... class UserImport implements ToModel,WithStartRow Step 2.在Import類別加入以下程式碼 public function startRow(): int { return 4; //從第4行開始讀 } 匯入時進行欄位驗證 Step 1.在Import類別導入類別並實作 <?php namespace App\Imports; ... use Maatwebsite\Excel\Concerns\WithValidation; ... class UserImport implements ToModel,WithValidation Step 2.在Import類別加入以下程式碼 //匯入時的驗證規則 public function rules(): array { return [ '0' => 'required|string', '1' => 'required|email', ]; } //驗證訊息使用的欄位名稱 public function customValidationAttributes() { return [ '0' => '姓名', '1' => 'Email', ]; } 發表於 HackMD 338 讚賞 收藏 訂閱