# Laravel 製作套件 ###### tags: `Laravel`、`php` ## 環境 在 laravel 根目錄上建立 packages/venderName/packageName > src 目錄將包含所有 PHP 代碼 ``` root ├── packages │ └── gcreate │ └──line_notify │ ├── src ``` cd 進入 packages/gcreate/line_notify 下指令 composer init ```=json # 輸入套件命名 Package name (<vendor>/<name>) [user/test]: gcreate/line-notify # 輸入套件描述 Description []: use line notify plugin. # 輸入作者訊息 Author [gcreate <service@gcreate.com.tw>, n to skip]: # 輸入最低穩定版本,ex: stable, RC, beta, alpha, dev Minimum Stability []: dev # 輸入套件類型 Package Type (e.g. library, project, metapackage, composer-plugin) []: library # 輸入授權類型 License []: MIT Define your dependencies. # 是否需要定義依賴套件 Would you like to define your dependencies (require) interactively [yes]? yes # 以 php 為例 Search for a package: php Info from https://repo.packagist.org: #StandWithUkraine # 輸入此依賴套件最低需求版本(或留白取最新版本) Enter the version constraint to require (or leave blank to use the latest version): >=7.4.3 # 如需多個依賴則重複上述步驟 Search for a package: ...... # 是否需要定義 require-dev Would you like to define your dev dependencies (require-dev) interactively [yes]? no # 是否支援 PSR-4 自動載入(對應命名空間名稱與檔案目錄名稱) Add PSR-4 autoload mapping? Maps namespace "Packages\Test" to the entered relative path. [src/, n to skip]: { "name": "gcreate/line_notify", "description": "use line notify plugin", "type": "library", "license": "MIT", "autoload": { "psr-4": { "Gcreate\\LineNotify\\": "src/" } }, "authors": [ { "name": "gcreate", "email": "service@gcreate.com.tw" } ], "minimum-stability": "dev", "require": { "php": ">=7.4.3" }, "require-dev": { "gcreate/line-notify": "*" } } # 是否照以上資訊生成 composer.json Do you confirm generation [yes]? yes # 是否要現在安裝依賴套件 Would you like to install dependencies now [yes]? no PSR-4 autoloading configured. Use "namespace Gcreate\LineNotify;" in src/ Include the Composer autoloader with: require 'vendor/autoload.php'; ``` ## 建立 Provider 在 src 資料夾新增 Service Provider,可以使用 php artisan make:provider XXXServiceProvider 指令新增,並搬遷到我們預計要做的套件 src/ 底下 順便在***根目錄*** config/app 內,加入自己做的套件 ( Provider ) ```php! ... 'providers' => [ Gcreate\LineNotify\LineNotifyServiceProvider::class, ] ``` 因為我們要直接用,直接檢查會不會跑不用另外安裝下來做 在 root composer.json,psr-4 這個是 composer 會抓取路徑名稱要下好,完成後要把這裡修改 ```json! ... "autoload": { "psr-4": { ... "Gcreate\\LineNotify\\": "packages/gcreate/line_notify/src/" }, ... }, ... ``` 在根目錄上執行 `composer dump-autoload` 就可以直接操作 ### ServiceProvider 建立和專案 config 與 migration 複製或合併 需要把專案 users table 欄位調整和加入一個 config 檔案,這兩個檔是要使用者下指令產生 ``` root ├── packages │ └── gcreate │ └──line_notify │ ├── src │ │ ├── config │ │ │ └── line-notify.php │ │ ├── database │ │ │ └──add_line_token_column_and_line_state_column_to_users_table.php │ │ └── LineNotifyServiceProvider.php │ ├── vendor │ └── composer.json ``` ### src/LineNotifyServiceProvider.php ```=php <?php namespace Gcreate\LineNotify; // 這邊一定要寫好 use Illuminate\Support\ServiceProvider; class LineNotifyServiceProvider extends ServiceProvider { /** * Register services. * * @return void */ public function register() { // 如果 root 有 config 設定檔就合併,沒有就產生 config 設定檔,來源在 src/config $this->mergeConfigFrom( __DIR__ . '/config/line-notify.php', 'line-notify'); } /** * Bootstrap services. * * @return void */ public function boot(): void { // 發佈 config 設定檔 // php artisan vendor:publish --tag=line-notify-config $source = realpath($raw = __DIR__ . '/config/line-notify.php') ?: $raw; $this->publishes([ $source => config_path('line-notify.php'), ],'line-notify-config'); // 發佈 migration // php artisan vendor:publish --tag=line-notify-migration $timestamp = date('Y_m_d_His'); $this->publishes([ __DIR__.'/database/migrations/add_line_token_column_and_line_state_column_to_users_table.php' => database_path('migrations/'.$timestamp.'_add_line_token_column_and_line_state_token_to_users_table.php'), ],'line-notify-migration'); } } ``` #### src/config 建立檔案 line-notify.php 在 .env 上也需要有對應的 key ```php! <?php return [ 'client_id' => env('LineNotifyClientID'), 'client_secret' => env('LineNotifyClientSecret'), 'CALLBACK_URL' => env('LineNotifyCallbackUrl'), ]; ``` #### src/database/migrations 建立檔案 add_line_token_column_and_line_state_column_to_users_table.php 我們 provider 加入時間戳複製到 migration 就會和我們下 migration 是一樣的 > 這裡也是先下完 php artisan make:migration xxxxxx_tables 在搬遷到 src 底下作業 > 要注意去除時間戳 ```php! <?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class AddLineTokenColumnAndLineStateTokenToUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table('users', function (Blueprint $table) { $table->string('line_notify_access_token'); $table->string('line_notify_state'); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('users', function (Blueprint $table) { $table->dropColumn('line_notify_access_token'); $table->dropColumn('line_notify_state'); }); } } ``` ## Line Notify 需要有 controller、route ( callback 用 ) 資料夾格式如下 ``` root ├── packages │ └── gcreate │ └──line_notify │ ├── src │ │ ├── Controllers │ │ │ └── LineNotifyController.php │ │ ├── config │ │ │ └── line-notify.php │ │ ├── routes │ │ │ └── web.php │ │ ├── database │ │ │ └──add_line_token_column_and_line_state_column_to_users_table.php │ │ └── LineNotifyServiceProvider.php │ ├── vendor │ └── composer.json ``` ### src/Controllers/LineNotifyController.php ```php! <?php namespace Gcreate\LineNotify\Controllers; // 這裡很重要 use Illuminate\Http\Request; // 需要繼承原來 laravel 的方法 use App\Http\Controllers\Controller; class LineNotifyController extends Controller { // ... 需要的方法 } ``` ### src/routes/web.php ```php! <?php use Gcreate\LineNotify\Controllers\LineNotifyController; use Illuminate\Support\Facades\Route; // if env isn't setting callback URL, default is "line/callbackURL" Route::any( config('line-notify.CALLBACK_URL', 'line/callbackURL' ), [LineNotifyController::class, 'getAuthLineCallback'] ); ``` ## 上傳套件 ## 建立Git Hub 專案 ![](https://hackmd.io/_uploads/r1vK-IePn.png) > 注意 license 要 MIT > Add a README file 要勾 :::info 上傳的時候不要帶 vender ::: ### 以 Packagist 為例 (public) 到 Packagist 使用 GitHub 登入帳號,點擊 Submit,直接輸入 repository 的網址,然後 Submit Package 就完成了。 ### 連動 github Profile 有自己的 API TOKE 進入自己發布的 github 專案 > Settings > Webhooks > Edit ( 如果沒有 Add webhook ) > Secret > 填入自己的 API TOKE > 存檔