آرشیو دوم : دستورات و نکات مهم لاراول

در مقاله قبل آرشیوی از دستورات اولیه و مهم لاراول رو نوشتم تا هر موقع نیاز شد بازبینی داشته باشم. در آرشیو دوم سعی میکنم برخی مفاهیم جدید که یاد میگیرم را به اشتراک بذارم.

۱ – تفاوت بین PUT و PATCH  در فرم‌های لاراول :

وقتی یک فرم با متد post ارسال می‌شود یک resource  در سرور ایجاد می‌شود. اگر کاربر درخواست مشابهی رو دوبار وارد کند برای درخواست دوم resource جدید ایجاد می‌شود. در واقع ارسال فرم با متد post همان INSERT یک رکورد در دیتابیس است.

http post method is like a INSERT query in SQL which always creates a new record in database.

برای مثال ثبت یک مطلب، کاربر و سفارش در وبسایت همگی با متد post انجام می‌شود.

put و patch درخواست های http هستند که هر دوی آنها اطلاعات را بروزرسانی می‌کنند.

متد PUT :

ارسال فرم با متد put  به این صورت عمل می‌کند ابتدا با استفاده از شناسه ای که دریافت می‌کند ابتدا بررسی می‌کند تا از موجودیت رکورد مورد نظر در دیتابیس مطمئن شود اگر رکورد وجود داشت همان رکورد را بروزرسانی میکند و درواقع اطلاعات جدید ارسال شده کاملا جایگزین می‌شود ولی اگر بعد از بررسی دیتایی وجود نداشت در واقع آن یک resource جدید در سرور ایجاد می‌کند و اطلاعات را در دیتابیس ثبت میکند.

http put method is like a MERGE query in SQL which inserts or updates a record depending upon whether the given record exists.

در متد PUT اگر چند درخواست مشابه ارسال شود با توجه به شناسه ای که ارسال می‌شود همان resource که پیدا شده است بروز رسانی می‌شود و ‌resource جدیدی در سرور ایجاد نمی‌شود. در واقع در این متد شناسه ‌resource توسط کاربر ارسال می‌شود.

برای مثال وقتی سفارش مشتری، مطلب وبلاگ و یا کاربری که وجود دارد را بروزرسانی می‌کنیم.

متد PATCH :

از متد patch  برای بروزرسانی بخشی از یک  resource (داده، اطلاعات) استفاده می‌کنیم. در واقع در این متد همه اطلاعات ارسال نمی‌شود که کاملا جایگزین رکورد فعلی دیتابیس شود.

http patch method is like a UPDATE query in SQL which sets or updates selected columns only and not the whole row.

برای مثال وقتی وضعیت یک سفارش مشتری را تغییر میدهیم از این متد استفاده می‌کنیم. ( PATCH request requires less bandwidth. )

۲ – ست کردن Session  بعد از ریدایرکت :

وقتی رکوردی در دیتابیس اضافه می‌شود و یا تغییری اعمال می‌شود، ما یک session به صفحه ارسال می‌کنیم تا تغییر مورد نظر را تایید و یا رد کند. به صورت زیر این کار را انجام می‌دهیم:

 return redirect()->back()->with('success', ['your message,here']);   

برای نمایش پیام ست شده در blade  به صورت زیر عمل می‌کنیم :

@if (\Session::has('success'))
  <div class="alert alert-success">
    <ul>
       <li>{!! \Session::get('success') !!}</li>
    </ul>
  </div>
@endif

۳ – نکته ای در مورد migration :

در پروژه ای که انجام می‌دادم نیاز بود یکی از فیلدهای دیتابیس را از حالت UNIQUE خارج کنم. برای اینکار یک مایگریشن ایجاد کردم و به صورت زیر اجرا کردم.

public function up()
{
    Schema::table('users', function(Blueprint $table)
    {
        $table->dropUnique('email');
    });
}

پس از اجرای مایگریشن، متوجه شدم که به درستی اجرا نمیشه و عمل نمیکنه. نکته ای که وجود دارد این است که :

To drop an index you must specify the index’s name. Laravel assigns a reasonable name to the indexes by default. Simply concatenate the table name, the names of the column in the index, and the index type.

وقتی فیلد را UNIQUE  کردم ایندکس شد و برای اینکه از حالت UNIQUE خارجش کنم باید نام ایندکس آن را داخل مایگریشن قرار دهم به صورت زیر :

$table->dropUnique('users_email_unique');

در قسمت دیگری که مایگریشن را ایجاد می‌کردم، باید فیلد دیتابیسی که کلید خارجی بود را از حالت کلید بودن بر می‌داشتم برای اینکار باید dropForeign با سبکی نوشته میشد که مطابق قاعده مایگریشن ها باشد.

برای مثال وقتی در جدول boxes فیلدی به نام type_id داریم و کلید خارجی به جدول دیگری است

$table->integer('type_id')->unsigned();
$table->foreign('type_id')->references('id')->on('table');

باید برای  dropForeign آن به صورت زیر اقدام میکردم :

<table_name>_<column_name>_foreign

یعنی به صورت زیر :

$table->dropForeign('boxes_type_id_foreign');

۴ – دریافت اولین و آخرین مقدار Foreach در قالب Blade Laravel :

از نسخه لاراول ۵.۳+ متغیری به نام $loop داخل حلقه ها در دسترس است که میتوانیم کارهای زیر را انجام دهیم  :

شمارنده در هر اجرا : در لیست هایی که چاپ میکنیم میتوانیم شمارنده ای را با استفاده از این متغیر چاپ کنیم :

$loop->iteration 

دریافت اولین و آخرین مقدار یک آرایه :

@foreach ($menu as $item)
  <div @if ($loop->first) class="hidden" @endif>
    <h2>{{ $item->title }}</h2>
  </div>
@endforeach
@foreach ($menu as $item)
   <div @if ($loop->last) class="hidden" @endif>
     <h2>{{ $item->title }}</h2>
   </div>
@endforeach

۵ – فیلدهای دیتابیس از نوع JSON و نحوه Eloquent

وقتی داده‌هایی که در دیتابیس ذخیره می‌کنیم از نوع JSON باشند فقط یک مقدار را ندارد که به صورت روال قبل داده را دریافت کنیم و از آن در eloquent استفاده کنیم. مثلا داده های json زیر داخل یکی از فیلدهای دیتابیس به نام meta ذخیره شده است :

{
    "id": 1,
    "name": "Alphonse",
    "meta": {
        "wants_newsletter": true,
        "favorite_color": "red"
    }
}

برای اینکه چک کنیم در صورتیکه یکی از ویژگی‌های فیلد meta  مطابق چیزی است که ما میخواهیم یا خیر به صورت زیر اقدام میکنیم، مثلا میخواهیم در صورتیکه مقدار favoraite_color  اگر red بود داده را بگیریم :

$redLovers = DB::table('users')
    ->where('meta->favorite_color', 'red')
    ->get();

برای بروزرسانی هم به صورت زیر میتوانیم بنویسیم :

DB::table('users')
    ->where('id', 1)
    ->update(['meta->wants_newsletter' => false]);

نکته مهم : MariaDB در حال حاضر از فیلدهای دیتابیس با نوع JSON پشتیبانی نمی‌کند ولی PostgreSQL و MySQL 5.7+ از این نوع فیلد پشتیبانی می‌کنند.

۶ –  والیدیشن فیلد ایمیل ( یونیک بودن ایمیل )

در فرم‌هایی که ایجاد میکنیم، برای مثال وقتی که میخواهیم پروفایل کاربر را ادیت کنیم و در جدول کاربران فیلد ایمیل یا هر فیلد دیگری یونیک است در رکوستی که برای والیدیت ( Validation )  فیلدهای ارسالی مینویسیم به صورت زیر اقدام می‌کنیم :

$rules = [
'email'     => 'nullable|email|unique:users,email,' . $this->user,
]

فیلد ایمیل را nullable کردیم و آن را اختیاری قرار دادیم از طرفی می‌خواهیم این فیلد برای هر کاربر یونیک باشد پس آن را برای جدول users یونیک می کنیم.

وقتی ایمیل کاربر تغییر میکند، یونیک بودن را با سایر فیلدهای دیتابیس چک کند و این رکورد از دیتابیس را با بقیه مقایسه کند. ( در صورتیکه رکورد کاربر فعلی که ادیت می‌شود را مشخص نکنیم ( $this->user ) خطای تکراری بودن ایمیل باعث می‌شود نتوانیم کاربری را ویرایش کنیم. )

ساخت Helper کاستوم در لاراول

وقتی پروژه ای را پیاده سازی می‌کنیم بعد از پیاده سازی ساختار پروژه، به فایلهایی همچون config فکر می‌کنیم که در تمام بخش‌های پروژه فراخوانی شود و فایلی رو داشته باشیم که قبل از نمایش صفحه فانکشن‌هایی برای آن پروژه اجرا شود.

اخیرا در پروژه ای که با لاراول پیاده سازی شده بود، نیاز داشتم که یک فانکشن در تمام بخش‌های پنل کاربری اجرا شود. برای اینکار نیاز به یک فایل به نام Helper داشتم که قبل از اجرای صفحه لود شود و موارد موردنیازم را بررسی و اجرا نماید. پس فایل کاستوم Helper را ایجاد کردم.

مسیرهایی که برای این فایل در نظر گرفته می‌شود معمولا یکی از دو مورد زیر است :

  • app/helpers.php
  • app/Http/helpers.php

لازم است که این فایل را در کل پروژه فراخوانی کنیم.

require_once ROOT . '/helpers.php';

ولی در لاراول می‌توانیم از یک راه جذابتر استفاده کنیم و مسیر فایل Helper  را در فایل composer.json لاراول ( autoload ) تعریف کنیم.

"autoload": {
    "files": [
        "app/helpers.php"
    ],
    "classmap": [
        "database/seeds",
        "database/factories"
    ],
    "psr-4": {
        "App\\": "app/"
    }
},

بعد از اینکار کامند زیر را اجرا میکنیم :

composer dump-autoload

با اینکار فایل helper.php  در تمام کنترلرهایی که داریم در دسترس است و میتوانیم استفاده کنیم به این خاطر که وقتی مسیر فایل را در autoload کامپوزر لاراول قرار دادیم و چون autoload لاراول در مسیر public/index.php به صورت زیر قرار می‌گیرد پس فایل helper نیز در دسترس قرار می‌گیرد :

require __DIR__.'/../vendor/autoload.php';

بعد از ایجاد فایل Helper  لازم است به صورت زیر تابع‌هایی که نیاز داریم را تعریف کنیم :

if (! function_exists('function_name')) 
{
    function function_name($key, $default = null) 
{
        // ...
    }
}

 

آرشیو اول : دستورات و نکات مهم لاراول

همانطور که در اولین مطلب وبلاگم اشاره کردم بسیاری از مطالبی که در وبلاگم منتشر میکنم برای آرشیو کردن آن ها برای خودم است و امیدوارم  برای  برخی از دوستان هم کاربرد داشته باشه.

( لاراول ۵.۴ )

در این مطلب در رابطه با مواردی که در لاراول لازم میشه اشاره میکنم :

۱- ایجاد ارتباط بین فیلدهای جداول دیتابیس در migration :

وقتی فیلدی داریم که قصد داریم به عنوان کلید خارجی هم ازش استفاده کنیم، مثلا مقالاتی برای وبلاگ داریم که افرادی آنها را منتشر میکنند، پس برای هر مقاله فیلدی به نام user_id ذخیره میکنیم که شناسه کاربری که مقاله را منتشر کرده است در جدول مقالات ذخیره شود.

پس در migration مربوط به مقالات که نام مقاله و slug ، …. وجود داره یک فیلد به نام user_id وجود داره که به فیلد id موجود در جدول users اشاره میکنه. ( جدول users مشخصات کاربران را ذخیره میکند )

پس داخل فایل migration مربوط به مقالات به این صورت می نویسیم :

$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');

۲ –  گروه بندی مسیریابی Rout در فایل web.php

همانطور که میدونید برای اینکه مثلا لیست مقالات مربوط به وبسایت رو نمایش بدیم باید در فایل web.php که در فولدر rout است مسیردهی مورد نظر و کنترلر و تابع اون رو مشخص کنیم، برای مثال اگر قرار باشه با مسیر mekaeil.me/admin/articles لیست تمام مقالات را نمایش دهیم مسیردهی در فایل web.php به صورت زیر خواهد بود :

Route::get('/admin/articles', 'Admin\[email protected]')->name('admin.article.list');

که در اینجا با فراخوانی آدرس /admin/articles بعد از نام دامنه، کنترلر ArticlesController که در مسیر Http > Controllers > Admin > ArticlesController وجود دارد فراخوانی میشود و تابع list موجود در این فایل مدیریت نمایش لیست مقالات و ارسال اطلاعات به view را انجام خواهد داد.

نکته اینجاست که ما اگر کلی مسیردهی داشته باشیم برای آدرس های مختلف باید به تعداد آنها مسیریابی را داخل فایل web.php ایجاد کنیم، برای راحتی کار و خلاصه شدن کار میتوانیم از حالت گروه بندی استفاده کنیم به صورت زیر :

Route::namespace('Admin')->prefix('admin')->group(function(){

$this->get('/articles', '[email protected]')->name('admin.article.list');

// Another rout here ...
});

۳ – ایجاد کنترلرها و متدهای مربوط به آن ( CRUD )

هنگام ایجاد اپلیکیشن ها و برنامه ها، متدهای Create , Read, Update, Delete , Store  در کنترلرهای مربوط به مدیریت برنامه استفاده میشود، برای ایجاد کنترلر و متدهای مربوط به آن، بعد از اینکه مدل مورد نظر را ایجاد کردیم میتوانیم با استفاده از دستور زیر به صورت Resource کنترلر موردنظر را ایجاد کنیم در حالتی که شامل متدهای مورد نظر هستند‌:

php artisan make:controller PhotoController -r

CRUD

در حالت فوق متدهای show , edit و … مقداری به نام $id را به عنوان ورودی متد دریافت میکنند تا عملیات مورد نظر انجام شود :‌

Rout model binding in laravel

حالا با تغییر دستور ترمینال به صورت زیر، میتوان با استفاده از rout model binding دسترسی و ارتباط میان کنترلرها و مدلها را برقرار کرد :

 php artisan make:controller ArticleController -r --model=Article

۴ –  insert داده های اولیه ( پیشفرض ) به جداول دیتابیس

من برای پروژه ای که داشتم باید هنگام راه اندازی پروژه یکسری داده ها به صورت پیشفرض به جداول دیتابیس اضافه میشد تا بتوانن هنگام برنامه نویسی هم از آنها استفاده کرد. برای مثال دسته بندی به نام “پیشفرض” به جداول دسته بندی ها اضافه کردم تا وقتی اگر یک مقاله ای آپلود و منتشر شد در صورتیکه دسته بندیی وجود نداشت و یا انتخاب نشد به صورت اتوماتیک این دسته بندی انتخاب شود و یا اگر یک دسته بندی حذف شد، تمام مقالات مربوط به آن دسته بندی به جای حذف به آن دسته بندی نسبت داده شوند.

برای ایجاد این داده های پیشفرض، من داخل فایل migration مربوط به جدول مورد نظر داده ها را اضافه کردم به صورت زیر :

    public function up()
    {
        Schema::create('articlecats', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('slug')->nullable();
            $table->timestamps();
        });

        // Insert Default Data
        DB::table('articlecats')->insert(
            array(
                'id'            => '1',
                'name'      => 'پیشفرض',
                'slug'          => 'default',
                'created_at'    => '1991-07-14',
                'updated_at'    => '1991-07-14'
            )
        );    
    }

۵ – افزودن کاربر به دیتابیس به صورت دستی

گاهی وقت ها هنگام ایجاد پروژه در بخش هایی که هنوز به بخش سطوح دسترسی و احزارهویت کاربران نرسیدیم و لازم است یکسری دیتا را ایجاد کنیم، برای ایجاد این دیتاها از سمت برنامه باید کاربر لاگین کرده باشد و برای لاگین بودن کاربر باید کاربری وجود داشته باشد! پس به صورت دستی یا از سمت phpmyadmin کاربری را ایجاد میکنیم و یا با استفاده از کدنویسی و قراردادن در یکی از فانکشن های کنترلر کاربر را ایجاد میکنیم و سپس کد را حذف میکنیم، که من شخصا راه دوم رو با استفاده از کد زیر انجام میدم.

return User::create([
'name' => 'Mekaeil Andisheh',
'level' => 'admin',
'email'=> '[email protected]',
'password'  => bcrypt('123456')
 ]);  

۶ – دریافت رکوردهای یک جدول به صورت آرایه

برای برخی بخش‌‌ها که اطلاعات کلی نمایش داده می‌شود برای مثال تنظیمات کلی یک بخش یا متن‌های استاتیک یک صفحه میتوان راهکارهای مختلفی را پیش گرفت که بهترین این راهکارها ایجاد بخشی به نام settings است که مدل خود را داشته باشد و حتی بعدا بتوان تابعی را داخل Helper آن نوشت که به راحتی برای بخش های مختلف آن به آن دسترسی داشت.

برای اینکار می‌توانید متن این لینک را مطالعه نمائید : Save laravel app settings in database

برای بخشی از یک پروژه که فقط یک بخش ساده داشت که حدود ۱۰ تا رکورد جاهای مختلف از دیتابیس فراخوانی بشه انجام اینکار هم زمانبر بود و هم چون نیازی بو توسعه بعدها نداشت انگیزه ای برای انجام کار به سبک فوق نبود. راهکاری که به نظرم آمد دریافت همه رکوردها و تبدیل به آرایه و ارسال به صفحه مورد نظر بود.

برای دریافت مقادیر از دستور زیر میتوان استفاده کرد.

$homeItems = Home::where('status', 1)->get();

که دیتاها به صورت زیر دریافت می‌شوند :

که با تغییر کد فوق به صورت زیر با استفاده از key مورد نظرم دیتاها را به صورت یک لیستی از آرایه دریافت می‌کنم.

$homeItems = Home::where('status', 1)->get()->keyBy('section');

که با این تغییر داده ها را به صورت زیر دریافت میکنم :

برای استفاده از این داده ها در جاهای مختلف قالب به صورت زیر عمل میکنم.

{{ $sections['section-1']['title'] }}

۷ – قراردادن url اصلی پروژه در قالب blade

وقتی که قالب اصلی پروژه را روی لاراول پیاده سازی می‌کنیم بعضی وقتها مثلا داخل فوتر یا یک جاهایی که لوگو قرار دارد میخواهیم که به صفحه اصلی لینک شود، میتوانیم به صورت کاستوم آدرس url پروژه را داخل href بذاریم اما شیوه درستتر این ست که Route قرار دهیم که با تغییر دامنه این بخش نیز تغییر پیدا کند.

$url = URL::to("/");
print_r($url);

$url2 = url('/');
print_r($url2);

۸ –  دریافت مقدار Route Name

در برخی قسمتهای برنامه لازم است Route فعلی صفحه جاری را چک کنیم، در صورتیکه به این کار نیاز شد با استفاده از دستور زیر میتوانید Route  صفحه جاری را دریافت نمائید :

Route::currentRouteName()

در صورتیکه نیاز به دریافت نام اکشن شد میتوانیم به صورت زیر اقدام کنیم :

Route::getCurrentRoute()->getActionName();

در صورتیکه نیاز به دریافت url کامل شد به صورت زیر اقدام کنیم :

$url = $request->url();

رفع مشکل Migration , Doctrine DBAL

یکی از جذابترین قسمت های لاراول مدیریت دیتابیس و migration ها است. وقتی بخواهیم فیلدهای دیتابیس را تغییر دهیم و در کل برای ایجاد هر تغییر در دیتابیس لازمه که یک migration ایجاد بشه که دیتاهای قبلی که در طول پروژه وارد شدند حفظ بشن و از طرفی وقتی به صورت تیمی کاری انجام میشه هم اعضای تیم در جریان روند تغییرات باشند و هم در هنگام استفاده از گیت ، اگر لازم شد rollback کنیم به تغییرات قبلی، اینکار انجام شدنی و راحت باشه.

برای یکی از فیلدها مجبور شدم که type فیلد رو از string به text تغییر بدم که migration را به صورت زیر ایجاد کردم :

    public function up()
    {
        Schema::table('articles', function (Blueprint $table) {
            $table->text('FeatureImage')->nullable()->change();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('articles', function (Blueprint $table) {
            $table->string('FeatureImage')->nullable()->change();
        });
    }

بعد از اینکه با اجرای دستور php artisan migrate با خطای زیر مواجه شدم :

doctrine/dbal laravel5.4

برای رفع مشکل نیاز داریم که با استفاده از composer موارد لازم را نصب کنیم :

composer require doctrine/dbal

با اجرای دستور فوق ( به احتمال خیلی زیاد باید فیلترشکن فعال باشه تا بتونید نصب کنید ) مشکل رفع میشه و مجددا عملیات migrate را انجام دهیم به خوبی کار انجام میشه :

update and install composer

( لاراول ۵.۴ )

دستورات اولیه و مهم لاراول

در این مقاله قصد دارم دستورات مهم و کاربردی که در محیط ترمینال و controller , route و Model کاربرد دارند و معمولا باید بدونیم رو بنویسم که به صورت یک مطلب روی وبلاگم داشته باشم.

( لاراول ۵.۴ )

۱ – رفع باگ migration در لاراول ۵.۴

وقتی لاراول رو نصب میکنیم و فیلدهای دیتابیس رو از طریق migration ایجاد میکنیم، بعد از اینکه migrate کنیم با خطایی روبرو میشیم که تصویر خطا رو به صورت زیر میبینیم :

syntax-error-laravel

که برای رفع این مشکل در فایل AppServiceProvider.php در مسیر app > providers کد زیر را اضافه می کنیم :

public function boot()
{
Schema::defaultStringLength(191);
}

۲ – نمایش لیست Route های موجود پروژه در ترمینال

برای نمایش لیست Route های موجود در پروژه و جزئیات آنها از دستور زیر در ترمینال استفاده میکنیم

php artisan route:list

route-list

۳ –  اعتبارسنجی فرم ها و ایجاد Request

برای اعتبارسنجی فرم ها هم میتوان بعد از ارسال مقدار فیلدها، داخل متد کنترلر اعتبارسنجی رو انجام داد و هم اینکه با استفاده از محیط ترمینال یک Request برای فرم مورد نظر ایجاد کرد و اعتبارسنجی همه فرم های پروژه رو داخل فایلهای مربوط به هر فرم ایجاد نمود. برای ایجاد Request داخل ترمینال دستور زیر را وارد میکنیم :

php artisan make:request ArticleValidate

بعد از اینکار وارد فولدر Http > Request میشیم و فایل ArticleValidate را میبینیم که میتوانیم موارد مربوط به اعتبارسنجی را داخل آن وارد کنیم، اولین کار اینه که متد authorize() را از حالت false به true تغییر دهیم و سپس داخل متد rules() اعتبارسنجی را انجام دهیم.

    public function rules()
    {
        return [
            'ArticleTitle'      => 'required',
            'MetaDescriptions'  => 'required',
            'body'              => 'required'
        ];
    }

بعد از نوشتن فیلدهایی که باید اعتبار سنجی شوند باید داخل متد کنترلر که فرم به آن ارسال میشود نام این request را به عنوان آرگومان ورودی ارسال کنیم.

  public function saveArticle(ArticleValidate $request){
 //....
 }

که برای نمایش Error ها، داخل فایلی که فرم ارسال میشود میتوان آنها را نمایش داد.

۴ – فارسی سازی خطاهای نمایش داده شده به کاربر

برای فارسی سازی خطاهایی که مثلا هنگام ارسال فرم نمایش داده میشود، وارد فولدر resource > lang میشیم، در این فولدر یک فولدر به نام en وجود دارد که یک کپی از آن میگیریم و به fa تغییرش میدیم و وارد فایلهای فولدر میشیم و به فارسی تغییر میدیم ( البته فایل فارسی شده آن توسط بقیه دوستان برای دانلود روی گیت هاب وجود داره ) سپس وارد فولدر config و فایل app.php میشیم و کد ‘locale’ => ‘en’  را به ‘locale’ => ‘fa’ تغییر می دهیم.

دانلود فایل فارسی شده

Locale-laravel-to-farsi

۵ – تغییر مکان قرارگیری فایلهای مدل و کنترلر و مرتب سازی آنها

وقتی پروژه خود را با لاراول استارت میزنید، به صورت اتوماتیک یکسری از کنترلرها و مدلها ساخته میشود، من شخصا برای پروژه دوست دارم که فایلهای کنترلر و مدل را تفکیک کنم مثلا همه مدل ها را داخل فولدری به نام Models قرار دهم که با اینکار باید namespace و مسیر دسترسی به مدل را داخل کنترلر ادیت کنم. همچنین مدل User.php را نیز به فولدر Models انتقال میدم که با خطای زیر مواجه میشم :

Fatal error access model user in laravel

برای رفع این خطا و دسترسی کنترلر به مدل وارد فایل config/auth.php میشم و مسیر دسترسی به مدل را ویرایش میکنم :

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\Models\User::class,
    ],

همچنین داخل مدل User قسمت namespace را نیز به App\Models تغییر میدم.

۶ –  رفع خطای Mass Assignment در لاراول

وقتی میخواهیم با استفاده از متدهایی همچون create مقاله ای ، …  را اضافه کنیم و نیاز داریم که فیلدهای دیتابیس را تغییر دهیم با اجرای متد با خطایی به نام Mass Assignment روبرو میشیم که اجازه تغییر فیلدها دیتابیس را به کاربر نمیده، برای اینکار در فایل مدل مربوطه باید مشخص کنیم که کاربر اجازه تغییر کدام یک از فیلدها را خواهد داشت، که برای اینکار مثلا برای مقالات ما اگر بخواهیم فقط اجازه تغییر مقادیر تایتل و متن توضیحات رو به کاربر بدیم به صورت زیر اقدام میکنیم :

    protected $fillable = ['title' , 'body' ];

و اگر بخواهیم به همه فیلدها به جز یک فیلد یا تعداد کمتری اجازه تغییر دهیم، به جای ذکر همه فیلدها با استفاده از متد فوق میتوان به صورت زیر عمل کرد : ( اگر به همه فیلدها اجازه تغییر دهیم برای حالت زیر یک آرایه خالی قرار میدهیم )

  protected $guarded = ['price'];

۷ – رفع مشکل composer autoload

گاهی وقت ها مجبور میشیم که فایل کنترلر را حذف و مجددا بسازیم که در این حالت به دلیل باقی ماندن فایل در دایرکتوری composer با خطای زیر مواجه میشیم :

composer autoload

با اجرای کد زیر در ترمینال میتوان مشکل مورد نظر را حل و کنترلر را ایجاد کرد.

composer dumpautoload

۸ – ایجاد بخش لاگین و ثبت نام کاربر

php artisan make:auth

با استفاده از دستور فوق بخش های مربوط به لاگین و ثبت نام کاربران در پروژه لاراولی ایجاد میشود. ( مانند route ها و view ها )

 

معرفی پکیج sluggable برای لاراول

( لاراول ۵.۴ )

برای هر محتوا یا بخشی از پروژه لاراول قطعا یکی از بخش های مهم لینک همان بخش است که جنریت می شود تا لینک درست و مناسبی تولید شود، برای مثال همین مقاله ای که الان مشاهده میکنید اگر دقت کنید بین کلماتی که فاصله وجود دارد خط تیره گذاشته میشود تا لینک خواناتر و قابل فهم تر باشد.

برای مثال به جای اینکه لینک به صورت زیر باشد :

http://example.com/post/My+Dinner+With+Andr%C3%A9+%26+Fran%C3%A7ois

به صورت زیر نمایش داده می شود :

http://example.com/post/my-dinner-with-andre-francois

برای مدیریت این موضوع در لاراول پکیج های مختلفی تولید شده اند که بهترینشون تا به امروز پکیج Eloquent-Sluggable است که خیلی عالی لینک ها رو مدیریت و تولید میکنه.

برای نصب کافیه وارد مسیر پروژه بشید و به صورت زیر اقدام نمائید :

قدم اول : نصب پکیج با استفاده از کامپوزر :

 composer require cviebrock/eloquent-sluggable

قدم دوم : وارد فایل config/app.php میشیم و کد زیر را به providers اضافه میکنیم :

'providers' => [
      Cviebrock\EloquentSluggable\ServiceProvider::class     
];

قدم سوم : کد زیر را داخل ترمینال اجرا میکنیم :

php artisan vendor:publish

با اجرای این کد، فایلهایی که مورد نیاز است داخل پروژه قرار داده می شوند که مهمترینشون فایل sluggable.php داخل فولدر config است که میتوان تنظیمات slug را تغییر داد.

قدم چهارم :  وارد فایل مدل می شویم و پکیج را use میکنیم و کد زیر را بهش اضافه میکنیم :

use Cviebrock\EloquentSluggable\Sluggable;
    use Sluggable;

    /**
     * Return the sluggable configuration array for this model.
     *
     * @return array
     */
    public function sluggable()
    {
        return [
            'slug' => [
                'source' => 'title'
            ]
        ];
    }

تا به اینجای کار پکیج نصب شده و قابل استفاده ست فقط باید دقت کنیم که فیلدی که داخل دیتابیس داریم باید هم اسم فیلدی باشد که با استفاده از پکیج لینک جنریت میشود و داخل آن ذخیره می شود (slug).

اگر بخواهیم بگیم چطور قابل استفاده است با کد نمونه زیر در زمانی که پست ایجاد میشود قابل درک است :

$post = new Post([
    'title' => 'My Awesome Blog Post',
]);

$post->save();
// $post->slug is "my-awesome-blog-post"

اگر احیانا مقاله جدیدی با لینک یکی از مقالات یکی باشد اعدادی را به ترتیب به آخر لینک اضافه میکند و در واقع مقدار slug یونیک است.
$newPost = $post->replicate();
// $newPost->slug is "my-awesome-blog-post-1"

برای اینکه بخواهیم یکسری تغییرات دیگه ایجاد کنیم و یا تنظیمات بیشتری را روی پکیج اعمال کنیم توصیه میکنم لینک مربوط به پکیج را که در بالا اشاره شد مطالعه نمایید.

اگر بخواهیم لینک های دیگری ( مثلا برای نویسنده های مقالات ) تولید کنیم میتوانیم به صورت زیر کد فوق را که به مدل اضافه کردیم توسعه دهیم :

public function sluggable()
{
    return [
        'title-slug' => [
            'source' => 'title'
        ],
        'author-slug' => [
            'source' => ['author.firstname', 'author.lastname']
        ],
    ];
}

این پلاگین حروف فارسی را پشتیبانی نمیکنه برای اینکه این پشتیبانی صورت بگیره لازمه وارد فولدر config و فایل sluggable بشید و تابع زیر را برای method قرار دهید :

    'method' => function($string, $separator = '-') {
        $_transliteration = ["/ö|œ/" => "e",
            "/ü/" => "e",
            "/Ä/" => "e",
            "/Ü/" => "e",
            "/Ö/" => "e",
            "/À|Á|Â|Ã|Å|Ǻ|Ā|Ă|Ą|Ǎ/" => "",
            "/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª/" => "",
            "/Ç|Ć|Ĉ|Ċ|Č/" => "",
            "/ç|ć|ĉ|ċ|č/" => "",
            "/Ð|Ď|Đ/" => "",
            "/ð|ď|đ/" => "",
            "/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě/" => "",
            "/è|é|ê|ë|ē|ĕ|ė|ę|ě/" => "",
            "/Ĝ|Ğ|Ġ|Ģ/" => "",
            "/ĝ|ğ|ġ|ģ/" => "",
            "/Ĥ|Ħ/" => "",
            "/ĥ|ħ/" => "",
            "/Ì|Í|Î|Ï|Ĩ|Ī| Ĭ|Ǐ|Į|İ/" => "",
            "/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı/" => "",
            "/Ĵ/" => "",
            "/ĵ/" => "",
            "/Ķ/" => "",
            "/ķ/" => "",
            "/Ĺ|Ļ|Ľ|Ŀ|Ł/" => "",
            "/ĺ|ļ|ľ|ŀ|ł/" => "",
            "/Ñ|Ń|Ņ|Ň/" => "",
            "/ñ|ń|ņ|ň|ʼn/" => "",
            "/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ/" => "",
            "/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º/" => "",
            "/Ŕ|Ŗ|Ř/" => "",
            "/ŕ|ŗ|ř/" => "",
            "/Ś|Ŝ|Ş|Ș|Š/" => "",
            "/ś|ŝ|ş|ș|š|ſ/" => "",
            "/Ţ|Ț|Ť|Ŧ/" => "",
            "/ţ|ț|ť|ŧ/" => "",
            "/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ/" => "",
            "/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ/" => "",
            "/Ý|Ÿ|Ŷ/" => "",
            "/ý|ÿ|ŷ/" => "",
            "/Ŵ/" => "",
            "/ŵ/" => "",
            "/Ź|Ż|Ž/" => "",
            "/ź|ż|ž/" => "",
            "/Æ|Ǽ/" => "E",
            "/ß/" => "s",
            "/IJ/" => "J",
            "/ij/" => "j",
            "/Œ/" => "E",
            "/ƒ/" => ""];
        $quotedReplacement = preg_quote($separator, '/');
        $merge = [
            '/[^\s\p{Zs}\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]/mu' => ' ',
            '/[\s\p{Zs}]+/mu' => $separator,
            sprintf('/^[%s]+|[%s]+$/', $quotedReplacement, $quotedReplacement) => '',
        ];
        $map = $_transliteration + $merge;
        unset($_transliteration);
        return preg_replace(array_keys($map), array_values($map), $string);
    },

که خروجی و نتیجه به صورت زیر خواهد بود :

sluggable farsi

پ. ن :‌این تابع رو از وب سایت  morilog.ir برداشتم 🙂

پکیج تاریخ شمسی برای لاراول ۵

یکی از نیازهای برنامه‌نویسای ایرانی هنگام توسعه وب‌سایت‌ها و اپلیکیشن‌ها، تبدیل تاریخ میلادی و شمسی و بالعکسه… که مرتضی پروینی عزیز پکیجی رو برای این کار نوشته که در گیت هاب شخصی ایشون میتونید جزئیاتش رو ببینید و نصب و استفاده نمائید. ( همچنین در سایت packalyst میتوانید پکیج های مختلفی رو برای اینکار پیدا کنید که بازخوبترینش همین پکیجه تا به امروز. )

پ.ن : در نهایت تاکید میکنم که این مقالاتی که توی وبلاگم منتشر میکنم صرفا برای آرشیو کردن تجربیات خودم برای خودم است که در آینده نیز شاید دوباره برایم کاربرد داشته باشه اگر برای دوستان نیز کاربرد داشت که خوشحال خواهم شد.

شاد و موفق باشید.