آموزش ساخت اپلیکیشن مدیریت وظایف با لاراول : قسمت پنجم

دسته بندی: برنامه نویسی
سطح مقاله: متوسط
زمان مطالعه: ۱۶ دقیقه
۲۸ خرداد ۱۳۹۸

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

آموزش ساخت یک برنامه مدیریت وظیفه با لاراول

آموزش لاراول

در این بخش به پیاده سازی عملیات CRUD وظایف می پردازیم. ابتدا ویوی مربوط به وظایف رابا استفاده از موتور قالب Blade برای ارتباط با کنترلر آماده سازی می کنیم. سپس به تکمیل متدهای کنترلر Task می پردازیم. به این ترتیب رفته رفته به انتهای پروژه اپلیکیشن مدیریت وظایف نزدیک می شویم.

نمایش Task ها

در ابتدای کار باید مدل Task را برای ارتباط با دیتابیس آماده کنیم. برای این پروژه خاص کاری با مدل Task نداریم جز اینکه باید آن را برای عملیات Mass Assignment در لاراول آماده کنیم. پس به مسیر App رفته و فایل Task.php را که قبلا به همراه RESTful Controller ساخته شده بود باز کنید. اگر با عملیات Mass Assignment آشنایی ندارید حتما مقاله ما با عنوان "" را مطالعه کنید. در کلاس Task در فایل Task.php کد زیر را وارد کنید:

protected $guarded = [];

این کد به لاراول می گوید که نیازی نیست از فیلدی در مقابل عملیات Mass Assignment مراقبت کند. به مسیر App>http>controllers رفته و فایل TaskController.php را باز کنید. در متد index() کد زیر را وارد کنید:

$tasks = Task::latest()->get();
return view('app' , compact('tasks'));

در خط اول کد، تمام رکورد های مدل Task بر اساس تاریخ و به صورت نزولی مرتب سازی و دریافت شده و در متغیر $tasks  قرار می گیرند. در خط دوم هم متغیر $tasks با استفاده از متد compact() و با نام tasks به ویو app.blade.php پاس داده می شود. البته فراموش نکنید که حتما با استفاده از دستور زیر، مدل Task را در کنترلر TaskController فراخوانی کنید:

use App\Task;

سپس به فایل wep.php در مسیر routes رفته و خط کد زیر را در آن وارد کنید تا به لاراول بگوییم که در صورت فراخوانی URL اصلی سایت، باید متد index() از کلاس TaskController فراخوانی شود:

Route::get('/', 'TaskController@index');

حال به مسیر resources>views رفته و فایل app.blade.php را باز کنید. تگ ul مربوط به نمایش لیست task ها را بین دو دستور زیر قرار دهید:

@if(count($tasks))
...
@endif

این دستور در یک شرط ساده بررسی می کند که تنها در صورت خالی نبودن آرایه $tasks تگ ul را به نمایش در بیاورد. تمام تگ های li درون تگ ul را به جز تگ اول پاک کنید. سپس تنها تگ li باقی مانده را بین دو دستور زیر قرار دهید:

@foreach ($tasks as $task)
...
@endforeach

این دستور باعث می شود که تگ های li به تعداد رکوردهای مدل Task تکرار شوند. از اینجا به بعد باید اطلاعات هر تسک را که در داخل حلقه بالا با نام $task شناخته می شود در تگ های li نمایش دهیم. همانطور که در کد HTML مشاهده می کنید در هر تگ li، یک div با کلاس panel وجود دارد. هر panel یک کلاس اضافی مخصوص تعیین رنگ می گیرد که ما به این ترتیب از آن ها استفاده می کنیم:

  • Panel-primary با رنگ آبی مخصوص تسک های Undone
  • Panel-success با رنگ سبز مخصوص تسک های Done
  • Panel-danger با رنگ قرمز مخصوص تسک های Cancel
  • Panel-warning با رنگ زرد مخصوص تسک های Migrated

برای ایجاد اتوماتیک این رنگ بندی می توانیم به راحتی از دستور switch بر اساس status هر تسک استفاده کنیم. بنابراین کلاس panel-info را پاک کرده و به جای آن کد زیر را وارد می کنیم:

@php
    switch ($task->status) {
        case 'Undone':
            echo 'panel-primary';
            break;
        case 'Done':
            echo 'panel-success';
            break;
        case 'Cancel':
            echo 'panel-danger';
            break;
        default:
            echo 'panel-warning';
            break;
    }
@endphp

نوشته درون تگ h3 با کلاس panel-title را پاک کرده و به جای آن کد زیر را وارد کنید تا اتریبیوت title از هر رکورد تسک را چاپ کند:

{{ $task->title }}

محتویات div با کلاس panel-content را پاک کرده و به جای آن کد زیر را وارد کنید تا بتوانید description هر تسک را نمایش دهید:

{{ $task->description }}

در پایان کار باید تگ ul شما به شکل زیر در آمده باشد:

@if(count($tasks))
    <ul class="tasks">
    @foreach ($tasks as $task)
    <li class="task">
        <div class="panel
        @php
            switch ($task->status) {
                case 'Undone':
                    echo 'panel-primary';
                    break;
                case 'Done':
                    echo 'panel-success';
                    break;
                case 'Cancel':
                    echo 'panel-danger';
                    break;
                default:
                    echo 'panel-warning';
                    break;
            }
        @endphp
        ">
        <div class="panel-heading">
            <h3 class="panel-title">{{ $task->title }}</h3>
        </div>
        <div class="panel-body">
            <div class="panel-content">
                {{ $task->description }}
            </div>
            <form action="" class="form-horizontal hidden-form">
                <div class="form-group">
                    <div class="col-md-12">
                        <input type="text" class="form-control hidden-title" value="وظیفه مهم اول" placeholder="نام تسک را وارد کنید"/>
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-md-12">
                        <textarea name="" class="form-control hidden-description" cols="30" rows="5" placeholder="توضیحات تسک را وارد کنید">لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد. کتابهای زیادی در شصت و سه درصد گذشته، حال و آینده شناخت فراوان جامعه و متخصصان را می طلبد تا با نرم افزارها شناخت بیشتری را برای طراحان رایانه ای علی الخصوص طراحان خلاقی و فرهنگ پیشرو در زبان فارسی ایجاد کرد. در این صورت می توان امید داشت که تمام و دشواری موجود در ارائه راهکارها و شرایط سخت تایپ به پایان رسد وزمان مورد نیاز شامل حروفچینی دستاوردهای اصلی و جوابگوی سوالات پیوسته اهل دنیای موجود طراحی اساسا مورد استفاده قرار گیرد.</textarea>
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-md-12">
                        <button class="btn btn-primary" id="edit-btn" type="submit">ذخیره کردن</button>
                    </div>
                </div>
            </form>
        </div>
        <div class="panel-footer task-links">
            <form action="">
                وضعیت:
                <span class="task-status undone">انجام نشده</span> /
                <span class="edit">ویرایش</span> /
                <button type="submit" class="remove">حذف</button>
            </form>
        </div>
    </div>
    </li>
    @endforeach
    </ul>
@endif

در استک PHP خود MySQL را فعال کنید. ما در این آموزش از استک XAMPP استفاده می کنیم. صفحه را رفرش کنید. همانطور که می بینید در صورتی که دیتابیس خود را پر نکرده باشید هیچ تسکی در لیست دیده نمی شود. برای امتحان به phpmyadmin رفته و یک رکورد جدید را در جدول tasks وارد کنید. دوباره صفحه را رفرش کنید. در صورتی که تمام مراحل را به درستی انجام داده باشید اکنون رکورد جدید جدول tasks در لیست وظایف پیش روی شما است!

اضافه کردن Task

به مسیر resources>views رفته و فایل app.blade.php را باز کنید. همانطور که مشاهده می کنید، بخش HTML ابتدای کد به فرم مربوط به اضافه کردن Task اختصاص دارد:

<form action=”” method="POST" class="form-horizontal">
        <div class="form-group">
            <div class="col-md-12">
                <input type="text" id="title" name="title" class="form-control" placeholder="نام تسک را وارد کنید"/>
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-12">
                <textarea id="description" name="description" class="form-control" cols="30" rows="5" placeholder="توضیحات تسک را وارد کنید"></textarea>
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-12">
                <button class="btn btn-primary" id="add-btn" type="submit">ذخیره کردن</button>
            </div>
        </div>
    </form>

همانطور که می دانید برای ارسال درخواست های از نوع POST، PATCH و DELETE در لاراول، احتیاج دارید که یک توکن CSRF را به همراه header ارسال کنید. برای این کار سه راه دارید:

می توانید مقدار توکن را از لاراول گرفته و در یک فیلد hidden ارسال کنید:

<input type="hidden" name="_token" value="{{ csrf_token() }}">

و یا از متد آماده لاراول برای تولید فیلد CSRF استفاده کنید تا همه کارها را به طور اتوماتیک انجام دهد:

{{ csrf_field() }}

و یا از دستور آماده یا directive آماده Blade استفاده کنید:

@csrf

هرکدام از این روش ها را که انتخاب کنید نتیجه یکی است. به هر حال فیلد CSRF را درون فرم ایجاد تسک جای دهید. پس از آن باید یک URL را به عنوان action فرم وارد کنیم. در این آموزش از متد route لاراول برای تولید URL استفاده می کنیم. کافی است name مربوط به route مورد نظرمان را به این متد بدهیم:

{{ route('Task.store') }}

 البته در صورت نیاز می توانیم اطلاعات اضافی request مانند id را نیز به عنوان آرگومان به این متد بدهیم تا URL را به صورت اتوماتیک تولید کند. برای پیدا کردن نام route های resource پروژه همانطور که قبلا هم گفتیم کافی است دستور زیر را در خط فرمان وارد کنید:

php artisan route:list

حالا تنها کاری که لازم است انجام دهیم ایجاد راهی برای نمایش ارورهای فرم است. در مسیر resources>views>section یک فایل جدید با نام error.blade.php ایجاد کرده و کد زیر را در آن وارد کنید:

@if(count($errors) > 0)
    <div class="alert alert-danger">
        <ul>
            @foreach($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

همانطور که با خواندن این قطعه کد متوجه می شوید، ابتدا با استفاده از متد count بررسی می شود که آبجکت کالکشن $errors خالی است یا خیر. اگر خالی نبود، با استفاده از شمارنده foreach تمام ارورهای موجود در آن در یک تگ ul چاپ می شود. در ضمن متد all() آرایه موجود در آبجکت کالکشن را بیرون می کشد و باعث می شود تا بتوانیم با $errors->all()  مانند یک آرایه رفتار کنیم. حالا کافی است فایل error.blade.php را در فرم ایجاد تسک فراخوانی کنیم:

@include('section.error')

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

<form action="{{ route('Task.store') }}" method="POST" class="form-horizontal">
    {{ csrf_field() }}
    @include('section.error')
        <div class="form-group">
            <div class="col-md-12">
                <input type="text" id="title" name="title" class="form-control" placeholder="نام تسک را وارد کنید"/>
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-12">
                <textarea id="description" name="description" class="form-control" cols="30" rows="5" placeholder="توضیحات تسک را وارد کنید"></textarea>
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-12">
                <button class="btn btn-primary" id="add-btn" type="submit">ذخیره کردن</button>
            </div>
        </div>
    </form>

حالا به TaskController.php بروید و متد store() آن را به شکل زیر در آورید:

public function store(Request $request)
{
    Task::create($request->all());
    return redirect()->back();
}

در خط اول کد متد با استفاده از متد create() و با روش Mass Assignment یک رکورد جدید در مدل Task ایجاد می کنیم. برای به دست آوردن اتریبیوت های موجود در Request کافی است از متد all() از کلاس Request استفاده کرده و آن را به عنوان آرگومان به متد create() بدهیم. در پایان با استفاده از متد back() و redirect() کاربر را به صفحه قبل یا همان صفحه درخواست دهنده برگشت می دهیم. با این کار کاربر پس از ایجاد تسک جدید دوباره به صفحه خانه که فرم را در آنجا پر کرده بود برگشت داده می شود.

اما مشکلی که در اینجا وجود دارد این است که متد create() هر تسکی را بدون بررسی درستی اطلاعات آن که از طرف کاربر ارسال شده ایجاد می کند. در واقع هیج اعتبار سنجی روی اطلاعات تسک ها انجام نمی شود. برای اعتبار سنجی اتوماتیک اطلاعات فرم ایجاد تسک کافی است یک Request دیگر مخصوص تسک ها بسازیم و درخواست های مربوط به آن را به طور اختصاصی اعتبار سنجی کنیم. به خط فرمان پروژه رفته و دستور زیر را در آن وارد کنید:

Php artisan make:request TaskRequest

حالا به مسیر App>Http>Requests بروید. همانطور که مشاهده می کنید یک فایل جدید با نام TaskRequest.php در آن ایجاد شده است. آن را باز کنید.  کلاس TaskRequest دارای دو متد به نام های authorize() و rules() است. متد authorize() تنظیمات دسترسی را برای هر درخواست بررسی می کند. شما می توانید به راحتی با استفاده از تعریف میدلورها (Middleware) دسترسی های و تنظیمات دلخواهتان را روی Request اعمال کنید.

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

public function authorize()
{
    return true;
}

حال باید قوانینی را برای تایید درخواست تعیین کنیم. برای این کار از متد rules استفاده می کنیم. کد زیر را در متد rules()  وارد کنید:

public function rules()
{
    if($this->method() == 'POST') {
        return [
            'title' => 'required|max:250',
            'description' => 'required',
        ];
    }
    return [
        'title' => 'required|max:250',
        'description' => 'required',
        'status' => 'in:Undone,Done,Cancel,Migrated'
    ];
}

در این متد ابتدا بررسی می کنیم که درخواست ارسال شده از چه نوعی است. اگر از نوع POST باشد یعنی درخواست ایجاد تسک است و در غیر این صورت درخواست مربوط به ویرایش تسک است. برای دسترسی به درخواست هم کافی است از طریق کی ورد $this به شی ساخته شده از نوع TaskRequest دسترسی پیدا کنیم.

در صورتی که درخواست از نوع ایجاد بود احتیاجی به بررسی status نداریم. چرا که status دارای یک مقدار پیشفرض Undone است و فقط در درخواست های ویرایش تغییر داده می شود. همینطور مشخص می کنیم که ورود فیلد title ضروری است و طول آن باید حتما زیر 250 کاراکتر باشد. فیلد description هم یک فیلد ضروری است بنابراین با استفاده از کی ورد required آن را به عنوان یک فیلد اجباری برای Request معرفی می کنیم.

در مورد درخواست های ویرایش هم تنها قانون اضافی این است که فیلد status باید حتما یکی از مقادیر Undone، Done، Cancel و Migrated را داشته باشد. هر status غیر از این مقدار باعث می شود که Request از اعتبار خارج شود. Request جدید ما آماده است اما هنوز درخواست های ایجاد تسک به آن ارتباطی ندارند!

برای اینکه درخواست های ایجاد تسک بتوانند از این Request جدید به جای Request های معمول استفاده کنند کافی است پارامتر متد store() در TaskController را به این شکل تغییر دهید تا درخواست ها اشیایی از کلاس TaskRequest باشند:

public function store(TaskRequest $request)
{
    Task::create($request->all());
    return redirect()->back();
}

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

جمع بندی

در این قسمت از سری آموزشی " آموزش ساخت اپلیکیشن مدیریت وظیفه با لاراول" عملیات نمایش و ایجاد تسک ها را تکمیل کردیم. یعنی بخش C و R از عملیات CRUD! برای تکمیل بخش U و D یعنی ویرایش و حذف تسک ها منتظر قسمت بعدی این سری آموزشی باشید. آیا در اجرای کدهای این بخش از آموزش با مشکل مواجه شدید؟ ما همیشه پاسخگوی سوالات شما در بخش نظرات هستیم!

بیشتر مطالعه کنید : 

نویسنده

نظرات کاربران

Uniqueweb Ir

سایت فوق العاده ای
درمان یبوست

امین

سلام
در ابتدای مطلب نوشتید :»
حتما مقاله ما با عنوان “” را مطالعه کنید.
مطلب رو نذاشتین و
کد زیر هم غلط نوشتاری داره:»
تصحیح کنید.
ممنون

//این نوشتید
@if(count($errors) > )
// درستش اینه دیگه؟
@if(count($errors) >0 )
ارسال دیدگاه
خوشحال میشیم دیدگاه و یا تجربیات خودتون رو با ما در میون بذارید :

 
گزارش مشکل