یکی از مهمترین بخشهای آموزش فریم ورک لاراول این است که بتوانید، اقدام به پکیج نویسی در آن کنید، در واقع پکیج ها امکاناتی هستند که شما با استفاده از آنها میتوانید، قابلیتهای جدیدی را به سایت خود اضافه کنید، پکیجها میتوانند، در هر جایی از برنامه که باعث بهبود روند برنامه نویسی و راحت شدن کار برنامه نویسان شود، به کار گرفته شوند.
پکیجها دارای انواع مختلفی همچون پکیجهای مستقلی که قابل استفاده در تمام فریم ورکهای زبان PHP هستند (پکیجهای Carbon و Behat)، پکیجهای مخصوص لاراول و سایر پکیجها میباشند. در ادامهی این مطلب نکاتی مهم درباره پکیج نویسی در لاراول را بررسی خواهیم کرد، تا پس از مطالعهی کامل این مطلب بتوانید، اقدام به ساخت پکیج در لاراول کنید، و پکیجهای مورد نظر خود را برای این فریم ورک محبوب و قدرتمند طراحی کنید، تا سایر افراد و برنامه نویسان نیز بتوانند، از پکیجهای شما استفاده کنند.
هنگام نوشتن یک برنامهی Laravel، فرقی نمیکند که از Contractها یا Facadeها استفاده کنید، زیرا هر دو سطح تستپذیری یا testability یکسانی دارند. با این حال هنگام نوشتن Package ها، Package شما به همهی helperهای تست کردن ( testing helperهای لاراول ) دسترسی ندارد. در این صورت اگر میخواهید خودتان testهای پکیجتان را بنویسید، میتوانید از پکیج Orchstral Testbench استفاده کنید.
Package Discovery
در فایل config/app.php در درون یک برنامهی Laravel، لیستی از Service Provider هایی که باید توسط برنامه load شوند، در بخش providers، به شکل زیر قرار دارد. هنگامی که شخصی Package شما را نصب میکند، میخواهید Service Provider خودتان در این لیست گنجانده شود.
شما میتوانید به جای اینکه کاربران را مجبور به اضافه کردن Service Provider خودتان به لیست کنید، در قسمت extra از فایل composer.json موجود در Package خودتان، Provider را تعریف کنید. همچنین علاوهبر Service Providerها ،میتوانید Facade هایی را که میخواهید register کنید نیز ذکر کنید.
"extra": {
"laravel": {
"providers": [
"Barryvdh\\Debugbar\\ServiceProvider"
],
"aliases": {
"Debugbar": "Barryvdh\\Debugbar\\Facade"
}
}
},
هنگامی که پکیج شما برای discovery پیکربندی شد، Laravel به طور خودکار Service Providerها و Facadeهای خود را هنگام نصب register میکند، و یک نصب آسان و سریع را برای کاربرانی که میخواهند، از پکیج شما استفاده کنند، به ارمغان میآورد.
جلوگیری کردن از Package Discovery
اگر شما مصرف کننده یک Package هستید، و میخواهید Package Discovery را غیرفعال کنید، میتوانید نام Package را در بخش extra از فایل composer.json برنامهی خود قرار دهید.
"extra": {
"laravel": {
"dont-discover": [
"barryvdh/laravel-debugbar"
]
}
},
همچنین اگر بخواهید Package Discovery را برای همهی Packageها غیرفعال کنید، میتوانید از علامت * به شکل زیر استفاده کنید.
"extra": {
"laravel": {
"dont-discover": [
"*"
]
}
},
Service Providers
Service Providerها در واقع یک پل ارتباطی بین اپلیکیشن شما و پکیج مورد نظرتان میباشد، یکی از مهمترین عملکردهای Service Provider این است، که منابع پکیجها، Viewها و فایلهای تنظیمات را برای شما load میکند، تا به راحتی بتوانید از آنها استفاده کنید.
و Service Providerها از کلاس Illuminate\Support\ServiceProvider ارثبری میکنند و دارای دو متد اصلی boot و register که بیشتر عملیاتها را انجام میدهند، میباشند. همچنین لازم به ذکر است که کلاس پایهی Service Provider در illuminate/support قرار دارد، که باید آن را به dependeciyهای پکیج خودمان اضافه کنیم.
Configuration
شما باید به طور معمول، فایل configuration پکیج خود را در directory به نام config در برنامهی خود قرار دهید. این کار باعث میشود، که کاربرانی که از پکیج شما استفاده میکنند، بتوانند به راحتی تنظیمات پیشفرض configuration پکیجتان را، مطابق با خواسته و میل خود تغییر دهند.
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->publishes([
__DIR__.'/path/to/config/courier.php' => config_path('courier.php'),
]);
}
حال هنگامی که کاربران Package شما، vendor لاراول را اجرا میکنند، یا یک command را publish میکنند، فایل شما به سرعت در مکان Publish کپی میشود. پس از انتشار Configuration شما، میتوانید به مقادیر یا Valueهای آن مانند هر فایل Configuration دیگری، دسترسی پیدا کنید.
$value = config('courier.option');
کانفیگهای پیش فرض Package ها
شما میتوانید فایل Configuration پکیج خود را با یک کپی از برنامهی Publish شده، به راحتی ادغام کنید. شما با این کار به کاربران اجازه میدهید، که در کپی Publish شده از فایل کانفیگ، تنظیماتی را که خودشان میخواهند، تعریف کنند. همچنین میتوانید برای ادغام Configuration ها، از متد mergeConfigFrom در درون متد register از Service Provider استفاده کنید.
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->mergeConfigFrom(
__DIR__.'/path/to/config/courier.php', 'courier'
);
}
[titles]Routes
اگر Package شما حاوی یک یا چند Route باشد، میتوانید آنها را با استفاده از متد loadRoutesFrom بارگذاری (load) کنید. در صورتی که Routeهای برنامه Cache شده باشند، و نتوانید Routeها را load کنید، این متد بهصورت خودکار اجرا میشود.
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->loadRoutesFrom(__DIR__.'/routes.php');
}
Migrations
اگر Package شما حاوی یک یا چند Migration باشد، میتوانید آنها را با استفاده از متد loadMigrationsFrom به Laravel معرفی کنید تا بتوانید، آنها را بارگذاری (load) کنید. متد loadMigrationsFrom مسیر Migrationهای پکیج را به عنوان تنها آرگومان خود میپذیرد.
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->loadMigrationsFrom(__DIR__.'/path/to/migrations');
}
پس از register یا ثبت Migrationهای Package شما، هنگامی که دستور php artisan migrate اجرا شود، بهطور خودکار تمام Migrationها نیز اجرا میشود.
Factories
اگر Package شما حاوی یک یا چند Factory باشد، میتوانید آنها را با استفاده از متد loadFactoriesFrom به Laravel معرفی کنید، تا بتوانید آنها را بارگذاری (load) کنید. متد loadFactoriesFrom مسیر Factoryهای پکیج را به عنوان تنها آرگومان خود میپذیرد.
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->loadFactoriesFrom(__DIR__.'/path/to/factories');
}
پس از register یا ثبت Factoryهای Package شما، میتوانید آنها را در برنامهی خود استفاده کنید.
factory(Package\Namespace\Model::class)->create();
Translations
اگر Package شما حاوی یک یا چند فایل Translation باشد، میتوانید آنها را با استفاده از متد loadTranslationsFrom به Laravel معرفی کنید، تا بتوانید آنها را بارگذاری (load) کنید. بهطور مثال، اگر نام Package شما courier باشد، میتوانید به شکل زیر عمل کنید.
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier');
}
شما میتوانید پکیج courier و دستور welcome آن را بهصورت زیر load کنید.
echo trans('courier::messages.welcome');
Publishing Translations (انتشار ترجمه ها)
اگر میخواهید Translationهای پکیج خود را در directory یا بخش resources/lang/vendor برنامهی خود Publish کنید، میتوانید از متد publishes در Service Provider استفاده کنید. متد publishes آرایهای از مسیرهای Package و مکانهای Publish دلخواه آن را میپذیرد. بهطور مثال، برای Publish کردن فایلهای Translation پکیج courier میتوانید به شکل زیر عمل کنید.
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->loadTranslationsFrom(__DIR__.'/path/to/translations', 'courier');
$this->publishes([
__DIR__.'/path/to/translations' => resource_path('lang/vendor/courier'),
]);
}
حال هنگامی که کاربران Package شما، vendor لاراول را اجرا میکنند یا یک Artisan command را publish میکنند، Translation پکیج شما در یک مکان Publish خاص، منتشر (Publish) میشود.
Views
برای register کردن Viewهای پکیج خود، باید به Laravel بگویید، که Viewها در کجا واقع شدهاند. شما میتوانید این کار را با استفاده از متد loadViewsFrom در Service Provider انجام دهید. متد loadViewsFrom دو آرگومان مسیر Viewها و نام پکیج را میپذیرد. بهطور مثال، اگر نام پکیج شما courier باشد، میتوانید کدهایی مانند کدهای زیر را در متد boot از Service Provider وارد کنید.
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
}
هنگامی که مسیر View شما در Service Provider ثبت یا همان register شد، میتوانید View دلخواه خود، مانند admin را به شکل زیر از courier بارگذاری (load) کنید.
Route::get('admin', function () {
return view('courier::admin');
});
بازنویسی Viewهای پکیج
در بازنویسی یا Override کردن Viewهای یک پکیج، در واقع وقتی از متد loadViewsFrom استفاده میکنید، لاراول دو location، یعنی پوشه resources/views/vendor برنامه و directory که خودمان مشخص کردیم، را برای Viewهای شما ثبت (register) میکند. بنابراین، فرض کنید در این مثال هم میخواهیم از courier استفاده کنیم، ابتدا Laravel بررسی میکند، که آیا نسخهی سفارشی View، توسط توسعه دهنده در resources/views/vendor/courier ارائه شده است یا خیر.
سپس، اگر نسخهی سفارشی View وجود نداشت، لاراول directory یا مکان View را که در همان متد call ،loadViewsFrom کردیم، جستجو میکند. این کارها باعث میشود، تا کاربرانی که از پکیج شما استفاده میکنند، بتوانند به راحتی همانگونه که میخواهند، Viewهای پکیج شما را سفارشیسازی کنند.
Publish کردن View ها
اگر بخواهید، Viewها قابلیت Publish شدن در directory یا قسمت resources/views/vendor را داشته باشد، میتوانید از متد publishes در Service Provider استفاده کنید. این متد یک آرایه که شامل مسیرهای View پکیج و مکانهای Publish دلخواه است، را میپذیرد.
پ/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
$this->publishes([
__DIR__.'/path/to/views' => resource_path('views/vendor/courier'),
]);
}
حال هنگامی که کاربران Package شما، vendor:publish را اجرا میکنند، Viewهای پکیج شما به سرعت در مکان Publish، کپی میشود.
View Components
اگر Package شما حاوی یک یا چند View Component باشد، میتوانید آنها را با استفاده از متد loadViewComponentsAs به Laravel معرفی کنید، تا بتوانید، آنها را بارگذاری (load) کنید. متد loadViewComponentsAs دو آرگومان tag prefix برای View Componentها و آرایهای از کلاسهای View Componentها را میپذیرد.
بهطور مثال، اگر Prefix پکیج شما courier باشد، و یک Alert و یک دکمه View Components داشته باشید، میتوانید، کدهایی مانند کدهای زیر را در متد boot از Service Provider وارد کنید.
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->loadViewComponentsAs('courier', [
Alert::class,
Button::class,
]);
}
هنگامی که View Componentها در Service Providerهای شما Register شد، میتوانید از آنها به شکل زیر در Viewها استفاده کنید.
<x-courier-alert />
<x-courier-button />
Commands
برای register کردن دستورهای پکیج خود با لاراول، میتوانید از تابع Commands استفاده کنید. این تابع یک آرایه از نامهای کلاس فرمان (command class names) را به عنوان ورودی میگیرد. وقتی فرمانها برای بار اول ثبت میشوند، میتوانید آنها را با استفاده از CLI اجرا کنید:
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
if ($this->app->runningInConsole()) {
$this->commands([
FooCommand::class,
BarCommand::class,
]);
}
}
Public Assets
Package شما ممکن است دارای Asset هایی مانند JavaScript ،CSS و تصاویر باشد. برای Publish کردن این Asset ها در پوشه Public برنامه، میتوانید از متد publishes در Service Provider استفاده کنید. در مثال زیر، به اصطلاح یک Public Asset Group Tag به متد publishes اضافه میکنیم.
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->publishes([
__DIR__.'/path/to/assets' => public_path('vendor/courier'),
], 'public');
}
حال هنگامی که کاربران Package شما، vendor:publish را اجرا میکنند، Assetهای پکیج شما به سرعت در مکان Publish، کپی میشود. از آنجا که بهطور معمول، با هر بار بروزرسانی Package نیاز به Overwrite یا بازنویسی Assetها دارید، میتوانید از force– در انتهای دستورتان استفاده کنید.
php artisan vendor:publish --tag=public --force
Publishing File Groups
گاهی اوقات ممکن است بخواهید، گروههایی از Public Assetهای یک پکیج و منابع یا Resourceها را بهطور جداگانه Publish کنید. بهطور مثال، ممکن است بخواهید به کاربران خود اجازه دهید، تا Configurationهای پکیجتان را Publish کنند، بدون اینکه مجبور باشند، Assetهای آن را Publish کنند. شما میتوانید این کار را با tag کردن آنها هنگام call کردن متد publishesh از Service Provider پکیج انجام دهید.
بهطور مثال، فرض کنید میخواهید از tagها برای تعریف کردن دو Publish Group در متد boot از Service Provider پکیج استفاده کنید.
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->publishes([
__DIR__.'/../config/package.php' => config_path('package.php')
], 'config');
$this->publishes([
__DIR__.'/../database/migrations/' => database_path('migrations')
], 'migrations');
}
اکنون کاربرانی که از پکیج شما استفاده میکنند، میتوانند این گروهها را بهصورت جداگانه با استفاده از tagهای آن، هنگامی که vendor:publish را اجرا میکنند Publish کنند.
php artisan vendor:publish --tag=config
جمعبندی:
یادگیری پکیج نویسی در لاراول حرفهای میتواند، یکی از بزرگترین نیازهای هر برنامه نویس لاراول باشد. امروزه بسیاری از برنامه نوسان برای ارتقا کیفیت برنامههای خود به جای آنکه کدهایی را خودشان از اول بنویسند، از پکیجهای آماده استفاده میکنند. قطعا پکیجهایی که دارای Bugهای مختلف امنیتی یا هر نوع Bug دیگری باشند، کمتر مورد استفاده قرار میگیرند، و شاید طی گذشت چند ماه با روی کار آمدن یک پکیج دیگر با همان امکانات ولی با Bugهای کمتر، پکیج شما بهطور کلی دیگر مورد استفادهی هیچ برنامه نویسی قرار نگیرد. پکیجهایی که شما میسازید، یکی از بزرگترین نقاط قوت رزومه شما چه برای استخدام در ایران و چه برای استخدام در هر کشور دیگری هستند.