# 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 專案

> 注意 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 > 存檔