جشنواره فطر سون لرن

آموزش اضافه کردن نمونه کار (portfolio) در لاراول - آموزش طراحی سایت شخصی با لاراول قسمت دوم

دسته بندی: لاراول
زمان مطالعه: 21 دقیقه
۰۲ فروردین ۱۳۹۹

در قسمت اول آموزش طراحی سایت شخصی با لاراول ما مراحل اولیه شامل نصب پروژه، اتصال به دیتابیس، احراز هویت، پنل مدیریت، مدل نمونه کار و همچنین ظاهر لیست مدل نمونه کار را ساختیم.

برای هر مدل و بخش‌هایی که نیاز داریم در سایت نمایش داده شوند ما به چهار عملیات نیاز داریم که به اصطلاح به آن CRUD گفته می‌شود.

CRUD مخفف کلمات Create, Retrieve, Update, Delete هستند. برای ساخت هر قسمت نیاز داریم یک فایل ویو، یک آدرس و یک تابع در کنترلر مربوطه ایجاد کنیم

ایجاد کردن نمونه کار:

ایجاد فایل ویو:

برای ایجاد کردن نمونه کار در اولین مرحله به یک فایل ویو برای نمایش فیلدهای اطلاعات هر نمونه کار نیاز داریم.

در مسیر resoursec/views/admin/portfolios یک فایل با نام add.blade.php بسازید و کدهای زیر را در آن قرار دهید.

@extends('admin.layouts.panel')

@section('content')
    <div class="card">
        <div class="card-header">Add Portfolio</div>

        <div class="card-body">
            @if (session('status'))
                <div class="alert alert-success" role="alert">
                    {{ session('status') }}
                </div>
            @endif

            <form>
                <div class="form-group">
                    <label for="title">Title</label>
                    <input type="text" class="form-control" id="title" name="title" aria-describedby="titleHelp">
                    <small id="titleHelp" class="form-text text-muted">Choose a title for your portfolio</small>
                </div>
                <div class="custom-file">
                    <input type="file" class="custom-file-input" id="image" name="image">
                    <label class="custom-file-label" for="image">Choose image</label>
                </div>
                <div class="form-group">
                    <label for="description">Description</label>
                    <textarea class="form-control" id="description" name="description" rows="3"></textarea>
                </div>
                <div class="form-group">
                    <label for="rank">Rank</label>
                    <select class="custom-select" id="rank" name="rank">
                        <option value="1">1</option>
                        <option value="2">2</option>
                        <option value="3">3</option>
                        <option value="4">4</option>
                        <option value="5">5</option>
                    </select>
                </div>
                <div class="form-group">
                    <label for="client">Client</label>
                    <input type="text" class="form-control" id="client" name="client">
                </div>
                <div class="form-group">
                    <label for="link">Link</label>
                    <input type="text" class="form-control" id="link" name="link" aria-describedby="linkHelp">
                    <small id="linkHelp" class="form-text text-muted">Enter project link like: https://7learn.com</small>
                </div>
                <div class="form-group">
                    <label for="completion_date">Completion Date</label>
                    <input type="text" class="form-control" id="completion_date" name="completion_date" aria-describedby="completion_dateHelp">
                    <small id="completion_dateHelp" class="form-text text-muted">Attention just enter like: 1398/12/02</small>
                </div>
                <div class="form-group">
                    <label for="content">Content</label>
                    <textarea class="form-control" id="content" name="content" rows="10"></textarea>
                </div>
                <button type="submit" class="btn btn-primary">Submit</button>
            </form>
        </div>
    </div>
@stop

 

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

 

ایجاد آدرس:

در فایل routes/web.php درست بعد از آدرسی که برای صفحه‌ی لیست نمونه کارها درست کردیم، کد زیر را قرار دهید.

Route::get('/add', 'PortfolioController@view_add')->name('viewAddPortfolio');

در کد بالا ما یک آدرس برای نمایش صفحه‌ی اضافه کردن نمونه کار ایجاد کردیم و آن را به تابع view_add در فایل کنترلر PortfolioController وصل کردیم. دقت کنید ما فایل PortfolioController را در مسیر app/Http/Controllers/Admin ایجاد نکرده‌ایم.

برای ایجاد فایل بالا می‌توانیم از دستور زیر استفاده کنیم.

php artisan make:controller Admin/PortfolioController

این دستور فایل کنترلر نمونه کار را در مسیر Admin می‌سازد.

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

حال فایل web.php باید شبیه به زیر باشد.

 

ایجاد کنترلر:

در مرحله قبل ما آدرس مربوط به اضافه کردن نمونه کار را به یک تابع در فایل PortfolioController متصل کردیم. این یعنی هربار که آدرس اضافه کردن نمونه کار را باز کنید تابع view_add در کنترلر مربوطه اجرا می‌شود.

نیاز داریم که در این کنترلر تابع view_add را ایجاد کنیم و در آن فایل ویو که برای فرم اضافه کردن نمونه کار قبل‌تر ساختیم را فراخوانی کنیم.فایل PortfolioController باید به شکل زیر باشد.

<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class PortfolioController extends Controller
{
    //

    public function portfolios()
    {
        return view('admin.portfolios.list');
    }

    public function view_add()
    {
        return view('admin.portfolios.add');
    }
}

 

حالا اگر آدرس https://127.0.0.1:8000/admin/portfolios/add را در مرورگر وارد کنید باید با صفحه‌ی زیر مواجه شوید.

 

قبل از هرکاری باید یک لینک برای این آدرس ایجاد کنیم که وقتی روی آن کلیک شد به صفحه‌ی اضافه کردن نمونه کار برود. به این منظور در صفحه لیست نمونه کارها یک دکمه (Button) قرار می‌دهیم.

در فایل ویو مربوط به لیست نمونه کار در مسیر resources/views/admin/portfolios یک دکمه به شکل زیر قرار دهید.

<a href="{{ route('viewAddPortfolio') }}" class="btn btn-outline-primary">Add</a>

کد مربوط به یک لینک است و زمانی که روی آن کلیک شود آدرس صفحه اضافه کردن نمونه کار باز خواهد شد.

در کد بالا ما از تابعی در لاراول به اسم route، استفاده کرده‌ایم. ورودی این تابع نام route‌های پروژه است و مسیر هر route را برمی‌گرداند.

در اینجا ما routeصفحه‌ی اضافه کردن نمونه کار را به آن دادیم که برای ما آدرس https://127.0.0.1:8000/admin/portfolios/add را چاپ می‌کند. این لینک را در هرجایی که دوست دارید قرار دهید.

ذخیره‌ی اطلاعات:

وقتی صفحه اضافه کردن نمونه کار باز می‌شود، می‌توانید اطلاعات را وارد کنید ولی برای ذخیره‌ی آن اگر روی دکمه Submit کلیک کنید، اتفاقی نمی‌افتد. برای ذخیره‌ی اطلاعات باید چند مرحله را پیش بگیریم.

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

برای اطلاعات بیشتر در مورد تفاوت این دو متد می‌توانید به این لینک مراجعه کنید.

ما در این پروژه برای ارسال اطلاعات از Post استفاده می‌کنیم. باید یک Route در فایل web.php به صورت زیر تعریف کنیم.

Route::post('/add', 'PortfolioController@add')->name('addPortfolio');

در کد بالا ما یک آدرس با مسیر add و متد post ساختیم که به تابع add در فایل PortfolioController متصل شده است و اسم آن addPortfolio می‌باشد.

برای اینکه اطلاعات فرم اضافه کردن نمونه کار به این آدرس فرستاده شوند همان‌طور که می‌دانید باید به تگ form در صفحه مورد نظر یک attribute به نام action بدهیم و آدرس را در آن قرار دهیم. تگ شروع form را در صفحه add.blade.php در مسیر resources/views/admin/portfolios به صورت زیر تغییر دهید.

<form action="{{ route('addPortfolio') }}" method="post" enctype="multipart/form-data">

 

در بالا ما آدرس ارسال اطلاعات فرم را به آدرسی که در بالا تعریف کردیم تغییر دادیم. همچنین متد ارسال اطلاعات را به post تغییر دادیم.

ما در فرم اضافه کردن نمونه کار تصویر نیز داریم و این یعنی در ارسال اطلاعات فایل‌ها نیز باشند به این منظور در بالا از ویژگی‌ای به نام enctype استفاده کردیم و مقدار آن را multipart/form-data قرار دادیم.

اگر در حال حاظر ما فرم را ثبت کنیم با خطای ۴۱۹ مواجه می‌شویم و این یعنی فرم ما معتبر نیست. برای اعتبار دادن به فرم در لاراول نیاز است یک مقدار به اسم csrf token را در فرم قرار دهیم. در بدنه‌ی فرم و در اولین خط مقدار زیر را قرار دهید.

@csrf

با این کار در فایل‌های Blade به صورت خودکار یک Input پنهان ایجاد می‌شود و یک مقدار معتبر را درون فرم قرار می‌دهد که لاراول فرم ما را می‌شناسد.

در مرحله بعد باید تابع ذخیره‌ی اطلاعات ارسالی از سمت فرم را در کنترلر بنویسیم. در بالا ما آدرس ارسال اطلاعات را به تابع add در کنترلر PortfolioController متصل کردیم پس باید در این کنترلر تابع زیر را بنویسیم.

public function add(Request $request)
    {
        $request->validate([
            'title' => 'required',
            'image' => 'required',
            'description' => 'required',
            'rank' => ['required' , Rule::in(['1','2','3','4','5'])],
            'client' => 'required',
            'link' => 'required',
            'completion_date' => 'required',
            'content' => 'required',
        ]);

        $portfolio = Portfolio::query()->create([
            'title' => $request->title,
            'image' => 'test',
            'description' => $request->description,
            'rank' => $request->rank,
            'client' => $request->client,
            'link' => $request->link,
            'completion_date' => Jalalian::fromFormat('Y/m/d',$request->completion_date)->toCarbon(),
            'content' => \request('content'),
        ]);

        $image = $request->file('image');
        $filename = $portfolio->id .'_'. time() .'.'. $image->getClientOriginalExtension();
        $image->move('portfolios', $filename);
        $portfolio->image = $filename;
        $portfolio->save();

        session()->put('status', 'Portfolio created successfully !');
        return redirect(route('viewAddPortfolio'));
    }

 

در اولین مرحله یک اعتبارسنجی برای اطلاعات ارسالی قرار دادیم که در آن گفتیم همه فیلدها اجباری هستن و فیلد rank می‌تواند یکی از مقادیر ذکر شده را بپذیرد. برای این کار از کلاس Rule و متد in استفاده کردیم که ورودی آن مقادیری که قابل پذیرش هستند قرار می‌گیرد.

بعد از آن، از مدل Portfolio یک ردیف در جدول نمونه کارها ساختیم و از متد create استفاده کردیم. این متد ورودی آرایه را می‌پذیرد و در آن فیلدها و مقادیر قرار می‌گیرند. زمانی که یک نمونه کار می‌سازیم در اولین مرحله یک مقدار پیش‌فرض برای تصویر قرار می‌دهیم چون ما باید اول تصویر را از اطلاعات ارسالی دریافت کنیم و آن را در جایی از پروژه ذخیره کنیم و همچنین نامی برای آن قرار دهیم و بعد نام مورد نظر را در ستون جدول ذخیره کنیم. در ادامه بیشتر توضیح خواهم داد.

برای تاریخ ارسالی از فرم، ما از پکیج morilog/jalali استفاده کردیم، که می‌توانید با دستور زیر آن را نصب کنید.

composer require morilog/jalali

این پکیج امکانات زیادی در تبدیل تاریخ میلادی به شمسی و برعکس آن، در دسترس شما قرار می‌دهد. ما برای ذخیره‌ی تاریخ، زمانی که فیلد جدول دیتابیس به عنوان timestamp است، باید تاریخ را به مدل Carbon تبدیل کنیم و بعد آن را در دیتابیس ذخیره کنیم.

در کد بالا با استفاده از پکیج جلالی تاریخ تکمیل پروژه را به تاریخ میلادی و مدل Carbon تبدیل کردیم تا برای ذخیره در دیتابیس مشکلی پیش نیاید. دقت کنید تاریخ را باید به صورت ۱۳۹۹/۰۱/۰۲ وارد کنید زیرا به تابع جلالی گفته‌ایم تاریخ به این صورت وارد خواهد شد.

در خط بعد ما از تابع کمک کننده (Helper Function) به اسم request استفاده کرده‌ایم چون خود کلاس Request یک متد به نام content دارد و این با فیلد ما تداخل دارد.

توجه: این تابع نیز همانند کلاس Request عمل می‌کند و برای استخراج اطلاعات از فرم استفاده می‌شود.

در مرحله‌ی بعد ما تصویر را که با کلید image برای ما ارسال شده است، در یک متغیر ذخیره کردیم و بعد از آن نامی که شامل id نمونه کار ساخته شده در خط‌های بالاتر به اضافه زمان حالا و همچنین پسوند فایل ارسال شده، برای تصویر خود انتخاب کردیم.

در خط بعد فایل ارسال شده را به مسیر public/portfolios با نامی که بالاتر انتخاب کردیم، انتقال دادیم. بعد از آن، نام فایل را در دیتابیس و برای نمونه کار ساخته شده قرار دادیم و نمونه کار را دوباره ذخیره کردیم.

از تابع سشن (session) برای نمایش یک پیغام جهت موفقیت آمیز بودن ایجاد نمونه کار به کاربر، استفاده کردیم و یک پیغام را در کلید status قرار دادیم.

از کلید status استفاده کردیم زیرا قبل‌تر این کلید را در صورت وجود، در فایل‌های ویو قرار داده‌ایم.

در آخر صفحه را دوباره به صفحه‌ی ایجاد نمونه کار منتقل کردیم.

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

 

اعتبارسنجی مقادیر ارسالی:

در قسمت اول تابع ایجاد نمونه کار از یک متد برای اعتبارسنجی استفاده کردیم ولی برای اینکه این اعتبارسنجی درصورت خطا به ما خطاها را نمایش دهد نیاز داریم تا کد زیر را فایل ویو ایجاد کردن نمونه کار در مسیر resources/views/admin/portfolios قرار دهیم.

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

زمانی که اعتبارسنجی خطایی را تشخیص می‌دهد، خطاها را در متغیر errors قرار می‌دهد. ما در کد بالا گفتیم، زمانی که مقدار errors خالی نباشد یک لیست بساز و هر آیتم که شامل هر خطا است را نمایش بده. اگر فرم ایجاد کردن نمونه کار را بدون هیچ مقداری ثبت کنید باید با تصویر زیر رو به رو شوید.

 

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

در قسمت قبل ما یک آدرس برای نمایش لیستی از نمونه کارها ایجاد کردیم. در این قسمت حالا که ما می‌توانیم نمونه کارها را ایجاد کنیم باید لیست را تغییر داده و نمونه کارهای موجود در سیستم را نمایش دهیم.

برای این کار تابع portfolios در Admin/PortfoliosController را به صورت زیر تغییر می‌دهیم.

public function portfolios()
    {
        $portfolios = Portfolio::query()->orderBy('created_at', 'desc')->get();
        return view('admin.portfolios.list', ['portfolios' => $portfolios]);
    }

در کد بالا ما اول تمامی نمونه کارها را بر اساس created_at به صورت نزولی در یک متغیر قرار می‌دهیم و در خط بعد هنگامی که یک ویو را برمی‌گردانیم متغیر portfolios را به عنوان portfolios به صفحه ویو می‌فرستیم.

 

نمایش نمونه کارها در ویو:

حال باید در فایل ویو خود اطلاعاتی که در مرحله‌ی قبل فرستادیم را نمایش دهیم. در فایل ویو لیست نمونه کارها در مسیر resources/views/admin/portfolios را به صورت زیر تغییر می‌دهیم.

@extends('admin.layouts.panel')

@section('content')
    <div class="card">
        <div class="card-header">Portfolios</div>

        <div class="card-body">
            @if (session('status'))
                <div class="alert alert-success" role="alert">
                    {{ session('status') }}
                </div>
            @endif

            <a href="{{ route('viewAddPortfolio') }}" class="btn btn-outline-primary">Add</a>

            <table class="table table-hover">
                <thead class="thead-dark">
                <tr>
                    <th scope="col">id</th>
                    <th width="20px" scope="col">Image</th>
                    <th scope="col">Title</th>
                    <th scope="col">Description</th>
                    <th scope="col">Client</th>
                    <th scope="col">Created At</th>
                </tr>
                </thead>
                <tbody>
                @foreach($portfolios as $portfolio)
                    <tr>
                        <th scope="row">{{ $portfolio->id }}</th>
                        <td><img src="{{ asset('portfolios/'.$portfolio->image) }}" alt="Portfolio" class="img-fluid"></td>
                        <td>{{ $portfolio->title }}</td>
                        <td>{{ substr($portfolio->description, 60) }}</td>
                        <td>{{ $portfolio->client }}</td>
                        <td>{{ jdate($portfolio->created_at)->format('Y/m/d') }}</td>
                    </tr>
                @endforeach
                </tbody>
            </table>
        </div>
    </div>
@stop

 

در کد بالا ما آرایه‌ای از نمونه کارها که در کنترلر ما ارسال می‌شود را درون یک foreach قرار می‌دهیم و هر نمونه کار را در یک سطر از جدول چاپ می‌کنیم. برای تصویر نمونه کار از تابع asset، که قبلا در مورد آن صحبت کردیم، استفاده کردیم و مسیر public/portfolios به اضافه اسم فایل که در دیتابیس ذخیره شده است را به عنوان ورودی به آن دادیم.

در قسمت توضیحات از تابع substr به منظور نمایش فقط ۶۰ کلمه اول توضیحات کوتاه هر نمونه کار، استفاده کردیم. همچنین برای تاریخ ایجاد نمونه کار از تابع jdate مربوط به پکیج morilog/jalali برای تبدیل تاریخ میلادی به شمسی در فرمت Y/m/d استفاده کردیم.

حالا اگر آدرس https://127.0.0.1:8000/admin/portfolios را در مرورگر باز کنیم باید با تصویری شبیه به زیر مواجه شویم.

 

جمع‌بندی:

ما مدل نمونه کار را به صورت سیستمی پیاده سازی کردیم یعنی می‌توانیم با استفاده از پنل مدیریت یک نمونه کار ایجاد کنیم و همچنین لیستی از نمونه کارها را مشاهده کنیم. از پکیج morilog/jalali برای تبدیل تاریخ به شمسی استفاده کردیم که می‌توانید برای اطلاعات بیشتر به صفحه پکیج در گیتهاب مراجعه کنید. به صورت کلی بیشتر بخش‌های سایت به همین صورت خواهند بود و فقط تغییر مدل و اسم آن است وگرنه کاری که باید انجام شود شباهت بسیاری به کاری که ما در این جلسه انجام دادیم دارد.

در قسمت بعد ویرایش و حذف نمونه کار را آموزش می‌دهیم و بعد به سراغ بقیه قسمت‌های سایت می‌رویم. با ما همراه باشید.

چه امتیازی به این مقاله می دید؟
نویسنده وحید حسنی
از دوست داران دنیای تکنولوژی مخصوصا دنیای وب از توسعه دهندگان وب مخصوصا بک اند از عاشقان پی اچ پی مخصوصا لاراول از دیوانگان کار کردن مخصوصا در آی ویرا ;-)

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

مهدی احمدی

ببخشید چرا میگه که قسمت اول یافت نشد
not found نشون میده

وحید حسنی

منظورتون از قسمت اول چیه؟؟
اگر not found دارید یعنی route شما به درستی تعریف نشده و یه چیزی رو دارید اشتباه وارد میکنید.

مهدی احمدی

سلام استاد
امید وار هستم که حالتون خوب باشه
ببخشید من داخل یه پروژه لاراول یه مشکلی پیدا کردم اگر لطف کنید کمکم کنید یه دنیا از شما سپاسگذار میشم
من یه سایت اموزشی با لاراول ساختم خب
حالا میخوام بخش پنل کاربری رو به سایتم اضافه کنم
نمیدونم چیکار کنم
یعنی این که من برای جدول user فیلدهای زیادی رو تعریف کردم مثل عکس-ادرس و موارد دیگه و این فیلد ها رو nullable گرفتم که کاربر اگر دلش خواست بعدا اونا رو اضافه کنه یا اونا رو ویرایش کنه
مشکل من همین هست
ایا برای چنین مسله ایی باید روت resource تعریف کرد یا نه؟
و از طرف دیگه اگه روت ریسورس تعریف کنم باید کدوم function ها رو استفاده کنم
چون که من نمیخوام بخش حذف و از این موارد رو داشته باشه
فقط میخوام که ویرایش فیلد های قبلی رو داشته باشه
خیلی ممنون میشم اگه یه مقدار بیشتر راهنمایی کنید
یک دنیا سپاس

وحید حسنی

سلام
خیلی ممنونم از شما دوست عزیز امیدوارم حال شما هم خوب باشه.
اگر منظورتون اینه که می‌خواین بخش ویرایش پروفایل کاربری درست کنید خب منطقا باید یه ویو بسازید و فقط فیلدهایی که نیاز دارید کاربر خودش بتونه تغییر بده رو قرار بدین بعدشم حتما از احراز هویت استفاده کنید.
امیدوارم کمکی کرده باشم…موفق باشین

ارسال دیدگاه
خوشحال میشیم دیدگاه و یا تجربیات خودتون رو با ما در میون بذارید :