# زبان های اسکریپتی > PHP > Laravel Framework >  آموزش Laravel 5

## hamedarian2009

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

کانال مرتبط با آموزش ها در تلگرام
https://telegram.me/learning_laravel

فهرست آموزش ها 
نصب و پیکربندی فریمورک لاراول ۵توضیحات بیشتر در مورد پیکربندی لاراولساختار برنامه Routing 
Middleware ها
_کار با کنترلرها__کار با view ها و ارسال داده به آنها__درخواست های HTTP__پاسخ های HTTP__کار با ‌‌_Blade و ایجاد layoutآشنایی با برخی توابع کمکیکار با session هااعتبارسنجی فرم هامطالب تکمیلی اعتبارسنجی فرم هاکار با دیتابیس به صورت پایهکار با دیتابیس با Query Builder کار با Query Builder - ادامهکار با EloquentRelationshipsصفحه بندی کردن (Pagination)کار با migrationکار با migration و schema builderHash کردناحراز هویت کاربران (Authentication)مثالی کاربردی از آپلود فایل مثالی کاربردی از ارسال ایمیلنحوه Reset کردن کلمه عبور کاربرافزودن کلاس و پکیج به لاراول مثالی کاربردی از چند زبانه کردن برنامهمثالی کاربردی از از AJAX افزودن کلاس های Html و Form و کار با آنهاCommand Schedulerکار با Captcha

----------


## hamedarian2009

*نصب فریمورک* 

قبل از اینکه بخواهید فریمورک لاراول ۵ رو نصب کنید باید مطمئن باشید که extension های زیر روی سرورتان نصب باشد و ورژن PHP سرور هم باید ۵٫۴ یا بیشتر باشد
McryptOpenSSLMbstringTokenizer 

برای اطلاع از فعال بودن این extension ها و همچنین نسخه php روی سیستم می تونید با استفاده از دستور phpinfo() به این اطلاعات دست پیدا کنید و در صورت عدم نصب هرکدام با توجه به سیستم عاملتون اقدام به نصب و فعال کردن آنها بکنید.

بهترین راه نصب لاراول ۵ استفاده از composer است که در صورت نصب نبودن روی سیستم تان می توانید از اینجا آن را دریافت و نصب کنید.

 ترمینال رو توی لینوکس یا cmd رو توی ویندوز باز کنید و ابتدا به دایرکتوری که میخواهید فریمورک رو داخلش نصب کنید (پوشه root نرم افزار شبیه ساز سروتان مثل xampp یا lamp و یا wamp) بروید مثلا با یکی از دستورات زیر که البته ممکن است مکان پوشه root در سیستم شما متفاوت باشد:

// for linux ubuntu
cd /var/www/html
 //for windows and xampp 
cd c:\xampp\htdocs
//for windows and wamp
cd c:\wamp\www

حالا می تونید با تایپ دستور زیر توی ترمینال آخرین نسخه لاراول رو دانلود و نصب کنید که یک پوشه به نام laravel ساخته میشود:

composer create-project laravel/laravel --prefer-dist

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

در صورتی که composer در سیستم شما نصب نمی شود یا مشکلی دارد میتوانید فایل های فریمورک لاراول را از آدرس زیر دریافت و در مسیر پوشه root سرورتان extract کنید:
http://fian.my.id/larapack/

*پیکربندی لاراول ۵

*توی پوشه اصلی لاراول یک فایل به نام env. وجود دارد که می توانید تنظیمات برنامه تان و دیتابیس پروژه را در اینجا تعیین کنید :*

APP_ENV=local
APP_DEBUG=true
APP_KEY=zGKCjTPbzET3WiHhKCxSpTBNCuUVWWLc

DB_HOST=localhost
DB_DATABASE=learninglaravel
DB_USERNAME=root
DB_PASSWORD=secret

*
به طور مثال اگر APP_DEBUG را روی true ست کنید خطاهای برنامه نویسی در هنگام کدنویسی برایتان قابل مشاهده خواهد بود و مناسب برای حالت development هست و در هنگام آپلود سایت روی هاست آن را fasle قرار دهید.
بهتره مقدار APP_KEY را هم با تایپ دستور زیر در ترمینال تغییر دهیم :
php artisan key:generate

سایر تنظیمات رو هم میتونید در پوشه config در فایل مورد نظرش اعمال کنید. به طور مثال می توانید در فایل app.php مقدار timezone رو به Asia/Tehran تغییر دهید.

----------


## hamedarian2009

*توضیحات بیشتر در مورد پیکربندی لاراول*

شما می توانید داخل فایل app.php در پوشه config تنظیمات برنامه را اعمال کنید. تنظیمات به صورت یک جفت کلید/مقدار هستند. بعضی از آیتم ها مقدار خودشان را ا توسط تابع کمکی env از فایل env. واقع در دابرکتوری root  پروژه که در پست قبلی توضیح دادم می گیرند به طور مثال :

'debug' => env('APP_DEBUG'),

'key' => env('APP_KEY', 'SomeRandomString'),

debug و key مقدار خودش رو از فایل env. می گیرند در صورتی که در فایل env. برایشان مقداری ست نکرده باشیم می توانیم به تابع ()env پارامتر دومی بدهیم که نشانگر مقدار آن هست. در مثال بالا key به این صورت است و اگر در فایل env. آن را حذف کنیم از این مقدار پیش فرض استفاده خواهد کرد.

در زیر توضیح مختصری برای هر آیتم آن میدهم :
*debug :*  اگر مقدار آن را true ست کنید برنامه در مد development خواهد بود و خطاهای برنامه نشان داده می شود و اگر false باشد در مد production می باشد و مناسب برای publish و استفاده نهایی برنامه هست.*url :* آدرس url پروژه را در اینجا ست میکنیم مثلا http://localhost/laravel/public*timezone :* موقعیت زمانی را مشخص می کنیم که برای مثال در کشور ایران Asia/Tehran ست می کنیم.*locale* *:* در مسیر resources/lang می توانیم یک پوشه دیگر به نام fa ایجاد کرده تا در آن پیغام ها و متون فارسی را تایپ کنیم تا در برنامه از آنها استفاده کنیم. به طور مثال یک کاربرد آن در فارسی سازی پیغام های اعتبارسنجی فرم ها می باشد. مقدار این آیتم را fa که همنام آن پوشه که ایجاد کردیم ست میکنیم.*fallback_locale :* در صورتی که locale موردنظر برای آن رشته موجود نبود از این locale استفاده شود.*key* : کلید برنامه که یک رشته تصادفی هست و در رمزنگاری های برنامه توسط لاراول مورد استفاده قرار می گیرد. نحوه ست کردن آن را در پست قبلی توضیح دادم.... 
سایر موارد را در جای مناسب خودش توضیح خواهم داد.


لاراول ۵ به طور پیش فرض از دایرکتوری app تحت  namespace ای به نام App استفاده میکند که هنگام ایجاد کلاس هایتان از آن استفاده میکنید که شما می توانید با استفاده از دستور زیر و تایپ در ترمینال آن فضای نام را به نام دلخواهتان تغییر دهید مثلا در مثال زیر من آن را به Hamo تغییر دادم:
php artisan app:name Hamo

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

*دسترسی به مقادیر پیکر بندی :*
با استفاده از کلاس Config هم می توانید مقادیر config رو با استفاده از متد get بدست بیارید یا مقدار جدیدی را با استفاده از متد set ست کنید به مثال های زیر توجه کنید:


$value = Config::get('app.timezone');

Config::set('app.timezone', 'Asia/Tehran');



همچنین می توانید از تابع کمکی config هم استفاده کنید: 
$value = config('app.timezone');

----------


## hamedarian2009

*ساختار برنامه در لاراول ۵*

در این قسمت قصد دارم در مورد ساختار دایرکتوری ها و فایل های موجود در فریمورک لاراول ۵ توضیجات مختصری رو ارائه کنم.
Screenshot from 2015-04-17 17:20:30.png
در بالا تصویری از دایرکتوری root لاراول قرار دادم. در زیر درمورد آنها توضیحاتی می دهم :
app : این دایرکتوری حاوی تمام کدهای برنامه تان از جمله کنترلرها و مدل های برنامه تان هست. با این دایرکتوری زیاد سروکار خواهیم داشت.bootstrap: این دایرکتوری حاوی یک سری فایل برای autoloading و راه اندازی فریمورک هست.config: حاوی تمام فایل های پیکربندی برنامه تان است.database : حاوی فایل های migration و seed است.public : فایل های استاتیک و front-end برنامه تان از قبیل javascript , css, images در اینجا قرار میگرند.resources: در این دایرکتوری فایل های view برنامه و  فایل های loacale و زبان در آن قرار می گیرند.storage: در این دایرکتوری فایل هایی که توسط موتور پوسته blade  کامپایل می شوند و همچنین مکان ذخیره سازی فایل های سشن و کش و سایر فایل هایی که توسط فریمورک ایجاد می شوند می باشد.test: حاوی فایل های تست خودکار برنامه است.vendor: حاوی تمام third-party ها و وابستگی هایی که توسط composer به برنامه اضافه می شوند هست. 

داخل دایرکتوری app می توانید مدل ها را ایجاد کنید و همچنین در مسیر app/Http/controllers می توانید کنترلرهای برنامه را ایجاد کنیم و همچنین فایل routes.php که در مسیر app/Http قرار دارد که مدیریت مسیرها از آن استفاده میکنیم ازجمله فایل ها و دایرکتوری های پرکاربرد ما در این فریمورک هستند.
فایل های view برنامه را هم در مسیر resources/views قرار می دهیم. در قسمت های بعدی نحوه مسیردهی و ایجاد کنترلر و ویو ها را خواهیم آموخت.
برای اطلاعات بیشتر می توانید به اینجا مراجعه کنید

----------


## hamedarian2009

*Routing در لاراول ۵*

از مزیت های فریمورک لاراول نسبت به سایر فریمورک های PHP مبحث Routing آن است که می توان مدیریت خوبی روی مسیرها داشت. در مسیر app/Http و فایل routes.php می توانیم تمامی مسیرهای برنامه را در آنجا تعریف و مدیریت کنیم.این فایل توسط کلاس App\Providers\RouteServiceProvider  بارگزاری میشود.

*یک مثال ساده* 
Route::get('/', function()
{
    return 'Hello World';
});

کلاس Route چند متد دارد که نوع درخواست http را مشخص میکند. در مثال بالا متد get فقط در خواست های GET به این مسیر را قبول میکند. سایر متدها که نوع درخواست http را مشخص میکنند post , put, patch, delete می باشند. این متد دوتا پارامتر می گیرد که اولی مسیری است که بعد از نام دامنه سایت می آید مثلا در آدرس http://www.example.com/about مسیری که وارد میکنیم about است. 
در پارامتر دومی هم می توانیم بدون استفاده از کنترلر و اکشن و با دادن یک تابع بی نام در همین روتر آن را مدیریت کنیم. 


کلاس Route دارای متد دیگری به نام match هست که می توانیم چند نوع درخواست http را به یک مسیر مجاز کنیم در مثال زیر مسیر هردونوع درخواست GET و POST را قبول می کند :
Route::match(['get', 'post'], '/', function()
{
    return 'Hello World';
}); 

در صورتی که بخواهیم مسیر همه در خواست ها را قبول کنید از متد any استفاده میکنیم مثلا آدرس http://www.example.com/foo هر درخواستی را قبول میکند :
Route::any('foo', function()
{
    return 'Hello World';
});

HTML درخواست های PUT , DELETE یا PATCH را پشتیبانی نمی کند برای اینکه یک فرم HTML را با این متدها تعریف کنیم کافیه یک تگ input از نوع hidden و با نام method_ تعریف میکنیم و به value آن یکی از مقادیر PUT, DELETE, PATCH را بدهید مثلا:
<form action="/foo/bar" method="POST">
    <input type="hidden" name="_method" value="PUT">
    <input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">
</form>
در مثال بالا آدرس http://www.example.com/foo/bar در روتر با متد put قابل دریافت است که می توانیم برای DELETE , PATCH هم به همین صورت عمل کنیم. کاربرد این متدها را در بخش کنترلر ها تشریح خواهم کرد. همچنین یک تگ از نوع مخفی به نام _token هم در فرم وجود دارد که در یک پست جداگانه در مورد فرم ها و کار با آنها توضیح خواهم داد.

*مسیر با پارامتر*
به همراه مسیر می توانیم هر تعداد پارامتر را هم ارسال کنیم فقط کافی است نام پارامترها را داخل آکولاد قرار دهیم. به مثال های زیر توجه کنید: 

Route::get('user/{id}', function($id)
{
    return 'User '.$id;
});

Route::get('user/{name?}', function($name = null)
{
    return $name;
});

Route::get('user/{name?}', function($name = 'John')
{
    return $name;
});


در مثال های بالا همانطور که مشاهده کردید می توانیم برای پارامترها یک مقدار پیش فرض یا null هم در نظر گرفت تا درصورت وارد نکردن مقداری برای پارامتر در url خطایی ایجاد نشود. همچنین باید جلوی نام پارامتر های اختیاری یک علامت ? قرار دهیم.

*افزودن عبارت منظم به پارامترها*
می توانیم با افزودن متد where به انتهای متد get برای هر پارامتر یک عبارت منظم هم تعریف کرد تا مثلا id فقط مقدار عدد مورد قبول باشد. در صورتی که چند پارامتر را بخواهیم برایش عبارت منظم تعریف کنیم آنها را داخل آرایه قرار می دهیم.
Route::get('user/{id}/{name}', function($id, $name)
{
    //
})
->where(['id' => '[0-9]+', 'name' => '[a-z]+'])

همچنین می توانیم برای یک پارامتر خاص در کل برنامه یک عبارت منظم عمومی تعریف کنیم به این صورت که در کلاس RouteServiceProvider در دایرکتوری app/Providers در متد boot این عبارت را قرار دهیم مثلا در مثال زیر کاربر در routing هرجایی از پارامتر id استفاده کرد فقط مجاز به دادن مقدار عددی به آن است و دیگر مانند بالا نیاز به تعریف متد where نیست :
$router->pattern('id', '[0-9]+');

*مسیردهی به یک کنترلر و اکشن* 
Route::get('user/{id}', 'UserController@showProfile');

در پارامتر دوم فقط کافی است بین نام کلاس کنترلر و اکشن یک علامت @ قرار دهیم.

*نامگزاری مسیر* 
با استفاده از کلمه as می توانیم برای مسیر یک نام هم تعریف کنیم و همچنین با استفاده از uses می توانیم آن را به اکشن و کنترلر خاصی هدایت کنیم.
Route::get('user/profile', [
    'as' => 'profile', 'uses' => 'UserController@showProfile'
]);
از کاربردهای نامگزاری مسیر برای ایجاد و ساختن url است که می توانیم با استفاده از تابع کمکی route نام مسیر را به آن بدهیم مثلا در مثال بالا با دادن نام profile آدرس http://www.example.com/user/profile ایجاد خواهد شد و همچنین برای ریدایرکت به یک مسیر هم کاربرد دارد.
$url = route('profile');

$redirect = redirect()->route('profile');

*مسیردهی گروهی*
در لاراول می توانیم یک دسته از مسیرها را که مثلا در یک قسمت از url خود مشترک هستند یا middleware مشترکی دارند و یا دارای یک namespace مشترک هستند را در یک گروه قرار دهیم. همجنین می توانیم sub-domain ها را از این طریق مدیریت کنیم.

Route::group(['prefix' => 'admin'], function()
{
    Route::get('users', function()
    {
        // Matches The "/admin/users" URL
    });
})

در مثال بالا تمامی مسیرهایی که با admin شروع می شوند را داخل این گروه قرار می دهیم.

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

----------


## Veteran

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

----------


## hamedarian2009

*Middleware ها در لاراول ۵*
middleware ها یک مکانیسم ساده ای را برای فیلتر کردن درخواست های http ورودی به برنامه تان تدارک می بیند. به طور مثال لاراول یک middleware (ترجمه فارسیش میشه میان افزار) برای احرازهویت کاربران دارد و در صورتی که کاربری Login نکرده باشد و احراز هویت نشده باشد میان افزار آن را به صفحه لاگین هدایت میکند  وگرنه میان افزار به درخواست اجازه ادامه کارش را میدهد.
middleware ها در دایرکتوری app/Http/Middleware قرار میگیرند.

*تعریف یک middleware 
* با تایپ دستور make:middleware در ترمینال می توانیم یک میان افزار جدید ایجاد کنیم. در مثال زیر میان افزار OldMiddleware را ایجاد کردیم‌.
php artisan make:middleware OldMiddleware

فایل ایجاد شده را باز میکنیم و در متد handle شرط زیر را قرار میدهیم به این صورت که درخواست ورودی به نام age اگر کوچکتر از ۲۰۰ بود به صفحه home ریدایرکت شود وگرنه به درخواست اجازه ادامه کار بدهد.

<?php namespace App\Http\Middleware;

class OldMiddleware {

    /**
     * Run the request filter.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($request->input('age') < 200)
        {
            return redirect('home');
        }

        return $next($request);
    }

}


اکنون برای اینکه بخواهیم از این میان افزار استفاده کنیم ابتدا باید آن را در فایل app/Http/Kernel.php ثبت کنیم. اگر می خواهید این میان افزار برای هر درخواست http برنامه تان اجرا شود آن را به آرایه middleware$ اضافه کنید که بعد از این هردرخواستی با این نام را فیلتر خواهد کرد.
اگر می خواهید میان افزار فقط به یک مسیر خاص اعمال شود ابتدا باید آن را به آرایه routeMiddleware$ اضافه کنید به این صورت که کلید آن در آرایه نام خلاصه آن برای استفاده در برنامه به کار می رود :
protected $routeMiddleware = [
        'auth' => 'App\Http\Middleware\Authenticate',
        'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicA  uth',
        'guest' => 'App\Http\Middleware\RedirectIfAuthenticated',
        'old' => 'App\Http\Middleware\OldMiddleware',
    ];

حالا می تونید میان افزار را به هر مسیری در فایل routing.php مانند مثال های زیر اضافه کنید که دوتا میان افزار old و auth را به مسیرهای موردنظرمان افزودیم :

Route::post('url/create', ['middleware' => 'old', 'uses'=>'UrlController@create']);

Route::get('admin/profile', ['middleware' => 'auth', function()
{
    //
}]);


*Before / After Middleware*
همچنین می توانیم میان افزارهای خاصی را ایجاد کنیم که قبل یا بعد از مدیریت درخواست توسط برنامه عملی را اجرا کنند.

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

----------


## hamedarian2009

> بنظرم تصویری کنید اموزش هارو خیلی بهتره.
> هم از نوشتن توی تاپیک خسته نمیشید هم کاربر بهتر یاد میگیره.


آموزش تصویری هم در نظر دارم بعد از این آموزش شروع کنم که انشالله در وبسایتم قرار میدم. فعلا میخوام خلاصه و ترجمه ای از داکیومنت لاراول ۵ رو داشته باشیم تا ببینیم فیدبک آن توسط کاربران چطور هست. مسلما هیچ اموزشی به صورت تصویری تاثیر نخواهد داشت.

----------


## meysam1366

سلام دوست عزیز

میخواستم بپرسم که کسانی که زیاد با لاراول کار نکردن بهتره مستقیما برن سراغ لاراول 5 یا همون 4 رو کار کنن؟

----------


## Mohammadsgh

برید سراغ لاراول5 که هستش خیلی بهتر شده.البته شاید یه خورده واستون سنگین باشه چون یادگیریش از لاراول4 یک خورده سختتر شده

----------


## hamedarian2009

> سلام دوست عزیز
> 
> میخواستم بپرسم که کسانی که زیاد با لاراول کار نکردن بهتره مستقیما برن سراغ لاراول 5 یا همون 4 رو کار کنن؟


الان ورژن جدید لاراول ۵ هست و اگه می خواهید تازه شروع به یادگیری کنید از ۵ شروع کنید و نیازی نیست حتما ۴ را هم کار کرده باشید

----------


## hamedarian2009

*کار با کنترلرها*

یکی از سه عنصر اصلی الگوی طراحی MVC کنترلرها هستند. در فایل routing.php می توانیم درخواست ها را به یک کنترلر و اکشن خاصی ارسال کنیم به طور مثال آدرس http://www.example.com/user/5
را در مثال زیر به کنترلر UserController و اکشن showProfile هدایت می کند.
Route::get('user/{id}', 'UserController@showProfile');

*تعریف کنترلر :* کترلر ها در مسیر دایرکتوری app/Http/Controllers قرار می گیرند. 

<?php namespace App\Http\Controllers;

use App\Http\Controllers\Controller;

class UserController extends Controller {

    /**
     * Show the profile for the given user.
     *
     * @param  int  $id
     * @return Response
     */
    public function showProfile($id)
    {
        return view('user.profile', ['user' => User::findOrFail($id)]);
    }

}


*کنترلرها و فضای نام (namespace)*
برای هرکلاس باید namespace آن را تعریف کنیم که این فضای نام در واقع مسیر قرارگیری کلاس از پوشه app می باشد و برای کنترلرها App\Http\Controllers تعریف می کنیم. در صورتی که داخل دایرکتوری Controllers یک دایرکتوری دیگر مثلا به نام Auth ایجاد کرده باشیم و کنترلری در آن تعریف کنیم فضای نام به صورت namespace App\Http\Controllers\Auth می باشد.

*نکته :* همیشه نام کلاس های کنترلر را به صورت PascalCase و در انتهای آن کلمه Controller را بیاورید. بهتر است اکشن ها را هم به صورت camelCase نامگزاری کنید.
البته من خودم همیشه عادت دارم کلاس های کنترلر و مدل را با ترمینال ایجاد کنم که شما هم می توانید با این دستور یک کنترلر بدون هیچ متدی ایجاد کنید :
 php artisan make:controller UserController --plain

* استفاده از middleware در کنترلر*
همانطور که در پست قبلی توضیح دادم می توانیم برای هر مسیر خاص یک کلاس میان افزار اضافه کنیم تا درخواست ها فیلتر شوند. مثلا در مثال زیر برای مسیر میان افزار auth را اضافه کردیم :
Route::get('profile', [
    'middleware' => 'auth',
    'uses' => 'UserController@showProfile'
]);
در مثال زیر همانطور که مشاهده می کنید سه مثال از استفاده از میان افزار در کنترلرها را آورده است که در متد سازنده کلاس هم قرار می گیرند :
class UserController extends Controller {

    /**
     * Instantiate a new UserController instance.
     */
    public function __construct()
    {
        $this->middleware('auth');

        $this->middleware('log', ['only' => ['fooAction', 'barAction']]);

        $this->middleware('subscribed', ['except' => ['fooAction', 'barAction']]);
    }

}
در مثال دوم میان افزار را با استفاده از کلمه only فقط به اکشن های fooAction و barAction محدود کردیم و فیلتر فقط به این اکشن ها اعمال شود و در مثال سوم با استفاده از کلمه except میان افزار به همه اکشن ها اعمال شود به جز اکشن های fooAction و barAction.

در لاراول همچنین می توانیم به مسیردهی به یک اکشن را به صورتی ساده تر هم انجام دهیم مثلا با تعریف مسیر به این صورت :
Route::controller('users', 'UserController');

با افزودن درخواست http به ابتدای نام اکشن با توجه به نوع درخواست به اکشن مورد نظر تحویل داده می شود :
class UserController extends BaseController {

    public function getIndex()
    {
        //
    }

    public function postProfile()
    {
        //
    }

    public function anyLogin()
    {
        //
    }

} 

*نکته :* اگر می خواهید برخی از مسیرها را نامگزاری کنید کافیست پارامتر سومی هم به صورت آرایه در نظر بگیرید و کلید آرایه نام اکشن و مقدار آن نام مسیر باشد:
Route::controller('users', 'UserController', [
    'anyLogin' => 'user.login',
]);

* کنترلرهای RESTful*

در لاراول می توانیم با دستور زیر در ترمینال کنترلرهایی با اکشن های خاصی ایجاد کنیم که هر اکشن یک مسیر و درخواست http را تحویل میگیرند. به طور مثال کنترلر PhotoController را ایجاد می کنیم:
php artisan make:controller PhotoController

مسیر را هم به این صورت در فایل routes.php تعریف می کنیم :
Route::resource('photo', 'PhotoController');
حالا اگر url را به صورت http://www.example.com/photo بنویسیم اکشن index درخواست را دریافت میکند. در تصویر زیر می توانید اطلاعات کاملی را از تمام اکشن ها داشته باشید. verb نوع درخواست http و path مسیری که در url وارد میکنیم و action اکشنی که این درخواست را دریافت میکند و route name هم نام مسیر می باشد.
Screenshot from 2015-04-19 13:08:32.png

همچنین می توانیم فقط اکشن های خاصی را به صورت RESTful تعریف کنیم :
Route::resource('photo', 'PhotoController',
                ['only' => ['index', 'show']]);

Route::resource('photo', 'PhotoController',
                ['except' => ['create', 'store', 'update', 'destroy']]);

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

----------


## hamedarian2009

*کار با view ها* 

view ها را در مسیر resources/views قرار می دهیم. شما می توانید آنها را با استفاده از موتور قالب Blade و یا به صورت معمولی ایجاد کنید. در مثال زیر فایل greeting.php را در مسیر ذکر شده قرار می دهیم و در آن دستورات زیر را قرار میدهیم :

<!-- View stored in resources/views/greeting.php -->

<html>
    <body>
        <h1>Hello, <?php echo $name; ?></h1>
    </body>
</html>


با استفاده از تابع کمکی view هم می توانیم فایل ویو را render کنیم. این تابع دو پارامتر می گیرد که اولی نام فایل ویو موردنظر بدون قرار دادن فرمت آن و دومین پارامتر آرایه ای از داده هایی هست که به فایل ویو می فرستیم.کلید آرایه در فایل ویو به صورت  نام متغیر قابل استفاده است. در مثال زیر کاربر با وارد کردن آدرس http://www.example.com به او Hello, James نمایش داده می شود.
Route::get('/', function()
{
    return view('greeting', ['name' => 'James']);
});

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

return view('admin.profile', $data);
در مثال فوق فایل ویو در مسیر resources/views/admin/profile.php قرار دارد.

همچنین به روش های زیر هم می توانیم داده را به ویو ارسال کنیم :
// Using conventional approach
$view = view('greeting')->with('name', 'Victoria');

// Using Magic Methods
$view = view('greeting')->withName('Victoria');
متد with دو پارامتر میگیرد که اولی نام متغیر و دومی مقدار آن هست. همچنین می توانید به روش دوم که در انتهای متد with نام متغیر را اضافه و مقدارش را به عنوان پارامتر به آن می دهیم.

*بررسی وجود فایل view* 
if (view()->exists('emails.customer'))
{
    //
}

*رندر کردن view از طریق مسیر فایل*
Route::get('/', function(){
    return view()->file('/var/www/html/laravel/public/greeting.php', ['name' => 'James']);
});

همانطور که می بنید کاربرد آن برای مواقعی است که شما فایل view که خارج از مسیر resourrces/views تعریف  کرده اید را بتوانید رندر کنید. در مثال بالا من فایل ویو را در پوشه public ایجاد کردم.

در قسمت های آینده در مورد  ایجاد layout و کار با موتور قالب blade مطالبی خواهیم داشت.

برای اطلاعات تکمیلی کار با view ها به اینجا مراجعه کنید

----------


## hamedarian2009

*درخواست های HTTP*

در لاراول درخواست های http که با متدهای GET , POST ,... ارسال می کنیم را می توانیم  مقادیر آنها را با استفاده از کلاس Request دریافت کنیم :
$name = Request::input('name');
*نکته :* برای استفاده از هر کلاسی در کلاس های کنترلر ابتدا باید آن کلاس را با استفاده از دستور use ایمپورت کنیم. در مثال بالا هم بایستی به این صورت قبل از تعریف کلاس کنترلر موردنظر کلاس Request را ایمپورت کنیم. 
use Request;

همچنین می توانیم به روش دیگری هم مقادیر را به دست بیاوریم. به این صورت که ابتدا کلاس Illuminate\Http\Request را به کنترلر مورد نظر ایمپورت می کنیم سپس دستور Request $request را به عنوان پارامتر به اکشن مورد نظر می دهیم. در طول برنامه داخل اکشن می توانیم  از متغیر request$ استفاده کنیم.

<?php namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;

class UserController extends Controller {

    /**
     * Store a new user.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        $name = $request->input('name');

        //
    }

}


 می توانیم برای یک ورودی مقداری پیش فرض هم تعیین کنیم تا در صورتی که مقداری برای آن ست نشده بود این مقدار جایگزین آن شود :
$name = Request::input('name', 'Sally');
با استفاده از متد has می توانیم بررسی کنیم که آیا ورودی با این مقدار وجود دارد یا خیر :
if (Request::has('name'))
{
    //
}
با استفاده از متد all می توانیم تمامی ورودی ها را دریافت کنیم.
$input = Request::all();

همچنین می توانیم فقط برخی ورودی ها یا همه ورودی ها به جز برخی را دریافت کنیم.
$input = Request::only('username', 'password');

$input = Request::except('credit_card');

هنگامی که مقدار ورودی یک آرایه باشد می توانیم با استفاده از نقظه به مقدار آیتم مورد نظر دست پیدا کرد :
$input = Request::input('products.0.name');

همچنین می توانیم به مقادیر flash که توسط سشن ایجاد می شوند و به صورتی هستند که فقط برای درخواست بعدی معتبر هستند و از بین می روند هم به صورت های زیر دسترسی داشته باشیم:

Request::flash();
Request::flashOnly('username', 'email');

Request::flashExcept('password');

در مثال دوم و سوم هم مثل قبل که دیدیم فقط یا به جز برخی موارد دسترسی داریم.

می توانیم مقادیر ورودی ها را دوباره با استفاده flash به صفحه قبلی یا صفحه دیگری ارسال کنیم :
return redirect('form')->withInput();
return redirect('form')->withInput(Request::except('password'));
کاربرد آن در فرم ها می باشد که اگر بعد از اعتبارسنجی ورودی ها دارای خطایی باشد و بخواهیم دوباره به صفحه فرم بازگردیم ورودی های فرم که کاربر نوشته از بین نروند. در مثال دوم به password اجازه 
حفظ شدن ندادیم.
برای چاپ مقادیر قبلی هم باید داخل تکست باکس های فرم مقدارش را به این صورت چاپ کنیم :
<input type="text" name="email" value="<?php echo old('name') ?>">

*کوکی ها*
می توانیم به مقدار یک کوکی هم به این صورت دسترسی داشته باشیم :
$value = Request::cookie('name');

*فایل ها*
فایلی که آپلود شده را می توانیم به این صورت اطلاعاتش دریافت کنیم. در مثال زیر نام فیلد فایل در فرم photo بوده است:
$file = Request::file('photo');

در مثال زیر بررسی می کند که آیا این فایل با این نام وجود دارد:
if (Request::hasFile('photo'))
{
    //
}


مقداری که متد file در کلاس Request به ما می دهد یک آبجکت از کلاس Symfony\Component\HttpFoundation\File\UploadedFile که می توانید با متدهای آن برای کار با فایل کار کنید.

if (Request::file('photo')->isValid())
{
    //
}
 
در مثال بالا بررسی می کند که آیا فایل آپلود شده صحیح و بدون خطا می باشد :

با استفاده از متد move می توانیم فایل را به مسیر مورد نظر که به عنوان پارامتر اول به آن می دهیم و همچنین نام فایل که اختیاری است ذخیره کنیم.

Request::file('photo')->move($destinationPath);

Request::file('photo')->move($destinationPath, $fileName);


در قسمت های آینده در مورد آپلود فایل و یک مثال کاربردی حتما مطلبی خواهیم داشت
سایر اطلاعات را می توانید در اینجا مشاهده کنید

----------


## hamedarian2009

*پاسخ های HTTP*

*پاسخ ساده*
بعد از دریافت درخواست و انجام عملیات مورد نظر باید پاسخی هم ایجاد کنیم. ساده ترین نوع پاسخ  return رشته هست که قبلا هم با آن آشنا شدیم :
Route::get('/', function()
{
    return 'Hello World';
});

*ایجاد پاسخ دلخواه*
با استفاده از کلاس Response یا تابع کمکی response می توانیم یک پاسخ دلخواه ایجاد کنیم مثلا مثال زیر را در نظر بگیرید :

return response($content, $status)
              ->header('Content-Type', $value);

محتویات را به عنوان پارامتر اول و status code را به عنوان پارامتر دوم به آن بدهیم و همچنین با استفاده از متد header نوع هدر را هم مشخص کنیم مثلا application/pdf.


همینطور که در مثال زیر می بینید می توانید یک فایل ویو و همچنین یک فایل کوکی را هم به عنوان پاسخ ارسال کنید و استفاده از متدها به صورت زنجیره ای امکان پذیر است.

return response()->view('hello')->header('Content-Type', $type)
                 ->withCookie(cookie('name', 'value'));
*Redirect*

با استفاده از تابع کمکی redirect و افزودن مسیر به آن می توانیم به مسیر مورد نظر هدایت شویم.
return redirect('user/login');

return redirect('user/login')->with('message', 'Login Failed');
همچنین می توانیم به همراه ریدایرکت کردن یک داده flash هم ارسال کنیم.

با استفاده از متد back می توانیم به مسیر قبلی که بودیم دوباره هدایت شویم.
return redirect()->back();

return redirect()->back()->withInput();
در مثال دومی می توانیم درخواست هایی که به این مسیر آمده را هم دوباره به مسیر قبلی ارسال کنیم که در پست قبلی نحوه کار با آنها را  مشاهده کردیم.

می توانیم با استفاده از نام مسیر که در فایل routes.php تعریف میکنیم هم ریدایرکت را با استفاده از متد route انجام دهیم.
return redirect()->route('login');

// For a route with the following URI: profile/{id}

return redirect()->route('profile', [1]);
همچنین می توانیم با استفاده از یک آرایه به عنوان پارامتر دوم متد route داده هم به آن ارسال کنیم.

می توانیم با استفاده از متد action به یک اکشن در کلاس کنترلر دیگری هدایت شویم که بایستی نام کلاس با فضای نام آن نوشته شود و همچنین در صورت وجود پارامتر به صورت آرایه به عنوان پارامتر دوم به آن اضافه میکنیم.
return redirect()->action('App\Http\Controllers\HomeController@index  ');

return redirect()->action('App\Http\Controllers\UserController@profi  le', ['user' => 1]);

*ایجاد پاسخ به صورت JSON*
با استفاده از متد json که یک آرایه را به عنوان پارامتر ورودی دریافت میکنید و خروجی آن به صورت JSON می باشد.
return response()->json(['name' => 'Abigail', 'state' => 'CA']);

*ایجاد پاسخ به صورت دانلود فایل*
با استفاده از متد download که مسیر فایل را به عنوان پارامتر می گیرد و دو پارامتر اختیاری دیگر که نام فایل و هدر های فایل هست را دریافت میکند.
return response()->download($pathToFile);

return response()->download($pathToFile, $name, $headers);

return response()->download($pathToFile)->deleteFileAfterSend(true);
در مثال سوم فایل بعد از دانلود حذف خواهد شد.

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

----------


## hamedarian2009

*کار با موتور قالب Blade و ایجاد Layout* 

توی این پست نحوه ایجاد فایل های view و نحوه render کردن اون توسط کنترلر و ارسال دیتا به اون رو کار کردیم. در  لاراول برای ایجاد ویو ها میتونید از موتور قالب Blade هم استفاده کنید که کارتون رو در ایجاد layout ها و کدنویسی خیلی آسون میکنه. شما می تونید بخش هایی از وبسایت از جمله هدر و فوتر و منو ها و ... که در تمام صفحات وبسایت یکی هستن را داخل یک فایل layout ایجاد کرده و در فایل های دیگر قابل ارث بردن هست. این فایل ها با فرمت blade.php. ایجاد می شوند.
*
تعریف یک Layout  ساده* 
در مسیر resources/views یک پوشه به نام layouts ایجاد کرده و فایل master.blade.php را داخل آن ایجاد کرده و کدهای زیر را داخل آن می نویسیم :

<!-- Stored in resources/views/layouts/master.blade.php -->

<html>
    <head>
        <title>App Name - @yield('title')</title>
    </head>
    <body>
        @section('sidebar')
            This is the master sidebar.
        @show

        <div class="container">
            @yield('content')
        </div>
    </body>
</html>


اکثر دستورات blade با علامت @ شروع می شوند. با استفاده از دستور yield می توانیم یک بخش را ایجاد کنیم که بعدا در فایل هایی که از آن ارث برده می شوند بتوانید محتوایی که در هر فایل متفاوت است را در ان قرار دهیم. نحوه استفاده از layout بالا را در فایلی دیگر مشاهده کنید :

@extends('layouts.master')

@section('title', 'Page Title')

@section('sidebar')
    @parent

    <p>This is appended to the master sidebar.</p>
@stop

@section('content')
    <p>This is my body content.</p>
@stop

همانطور که مشاهده کردید با استفاده از دستور extends می توانید فایل layout را به صفحه اضافه کنید. نحوه آدرس دهی هم به این صورت است که بین دایرکتوری و نام فایل ویو نقطه قرار می دهیم.
با استفاده از دستور section که نام yield مورد نظر را به آن می دهیم می توانیم محتوای جدید را داخل آن قرار دهیم. در پایان هم باید stop را بنویسیم. yield ها در فایل layout هیچ محتوایی ندارند اما اگر بخواهیم بخشی را تعریف کنیم که در فایل layout هم محتو ادشته باشند باید از section استفاده با این تفاوت که در layout باید در انتها show قرار دهیم. بخش ها در فایل به ارث برده شده override می شوند برای اینکه بتوانیم محتوای فایل والد رو هم داشته باشیم کافیه در ابتدا یا انتهای محتوای جدید دستور parent را اضافه کنیم. در مثال بالا بخش sidebar به این صورت است.

برای بخش yield می توانیم یک محتوای پیش فرض هم تعیین کنیم مثلا 
@yield('section', 'Default Content')

*چاپ داده یا متغیر ها  در blade*
با استفاده از بلاک های دو آکولاده می توانیم یک متغیر یا عبارت قابل چاپ را در صفحه چاپ کنیم.
Hello, {{ $name }}.

The current UNIX timestamp is {{ time() }}.
همچنین اگر متغیری با نام مورد نظر ست نشده بود یک مقدار پیش فرض برای چاپ در نظر بگیریم تا باعث ایجاد خطا در صفحه نشود.
{{ $name or 'Default' }}
دوآکولاد در blade تمامی دستورات html را escape میکند مانند دستور htmlentities در php عمل میکند. اگر نخواهیم داده ها escape شوند به این صورت انجام دهید :
Hello, {!! $name !!}.

دستورات شرطی و حلقه ها هم به صورت های زیر قابل نوشتن هستند :
@if (count($records) === 1)
    I have one record!
@elseif (count($records) > 1)
    I have multiple records!
@else
    I don't have any records!
@endif
@foreach ($users as $user)
    <p>This is user {{ $user->id }}</p>
@endforeach

برای دیدن مثال های بیشتر به اینجا مراجعه کنید

*اینکلود کردن فایل view در view دیگر*
مثلا در یک فایل ویو فرم لاگین را طراحی کرذه ایم و می خواهیم آن را در چند صفحه استفاده کنیم کافیست آن را مانند مثال زیر در فایل های مورد نظر اینکلود کنیم :
@include('view.name')

@include('view.name', ['some' => 'data'])


در مثال بالا view نام پوشه و name نام فایل ویو مورد نظر است. همچنین می توانیم دیتا هم به آن فایل ارسال کنیم.

*توضیحات در Blade*
برای نوشتن کامنت یا توضیحات می توانید به صورت زیر عمل کنید :
{{-- This comment will not be in the rendered HTML --}}

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

----------


## hamedarian2009

*توابع کمکی در لاراول ۵*

توابع کمکی یا helper بسایر زیادی در لاراول وجود دارند که در حین توسعه برنامه به کارتون میان و توی پست های قبلی هم از چندتا ازونا استفاده کردیم مثل تابع view .  برای کار با آرایه ها و مسیرها و ایجاد url و کار با رشته ها توابع بسیار خوبی دارد.توی این پست میخواستم چندتا از پرکاربردهاشو معرفی کنم.

افزودن به آرایه با تابع array_add
$array = ['foo' => 'bar'];

$array = array_add($array, 'key', 'value');

تقسیم آرایه به دو آرایه از کلیدها و مقادیر با تابع array_devide
$array = ['foo' => 'bar'];

list($keys, $values) = array_divide($array);

گرفتن مسیر فیزیکی دایرکتوری app و public با توابع  app_path و public_path
$path = app_path();

$path = public_path();

اجرای دستور htmlentities روی رشته با پشتیبانی از UTF-8 با تابع e
$entities = e('<html>foo</html>');

ایجاد یک رشته تصادفی به طول دلخواه با تابع str_random که مثلا مناسب برای ایجاد کلمه عبور است
$string = str_random(40);

ایجاد مسیر کامل با تابع url - پارامتر اولش مسیر نسبی هست و پارامتر دوم هم پارامترهای مسیر در صورت وجود است و پارامتر سوم اگر true باشد مسیر با پروتکل https ایجاد می شود
echo url('foo/bar', $parameters = [], $secure = null);

ایجاد یک توکن در فرم ها برای جلوگیری از حملات csrf با تابع csrf_token
$token = csrf_token();

تابع dd هم یک متغیر یا آبجکت یا آرایه را می گیرد و به صورتی شبیه var_dump نمایش می دهد و برای  debug کردن خیلی کاربردی هست
dd($value);

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

----------


## hamedarian2009

*کار با Session ها
*
در لاراول ۵ می توانیم از طریق کلاس Session و هم با استفاده از تابع کمکی session به مقادیر آنها دسترسی داشته باشیم.

ذخیره مقدار در یک سشن

در مثال زیر با هردو روش مقداری را در سشن ذخیره کرده ایم. key نام سشن و value مقدار آن است. برای تعریف چند سشن کلید و مقدار را داخل یک آرایه قرار دهید.
Session::put('key', 'value');

session(['key' => 'value']);
باید توجه داشته باشید که برای ست کردن یک  سشن هم  در تابع کمکی session باید آن را در آرایه قرار دهید.

افزودن  مقدار به یک سشن آرایه ای
Session::push('user.teams', 'developers');

بازیابی مقدار سشن با متد get امکانپذیر است.

$value = Session::get('key');

$value = session('key');


در صورتی که سشن مقداری نداشت می توانیم برای آن یک مقدار پیش فرض تعریف کنیم
$value = Session::get('key', 'default');

$value = Session::get('key', function() { return 'default'; });

گرفتن مقدار یک سشن و بلافاصله حذف آن با متد pull امکانپذیر است :
$value = Session::pull('key', 'default');

با متد all می توانیم به تمام مقادیر سشن ها را در یک آرایه بازیابی کنیم.
$data = Session::all();

برای حذف یک سشن خاص از متد forget که نام سشن را به آن می دهیم استفاده می کنیم. برای حذف تمامی سشن ها از flush استفاده میکنیم.
Session::forget('key');

Session::flush();

برای امنیت بیشتر سشن ها می توانید از متد regenerate برای تولید دوباره session id استفاده کنید :
Session::regenerate();

*داده های فلش*
سشن ها بعد از تولید تا وقتی که مرورگر بسته نشود از بین نمی روند. در لاراول سشن هایی به نام فلش وجود دارند که فقط برای یک درخواست معتبر هستند و بلافاصله در درخواست بعدی از بین میروند که مناسب برای ایجاد پیغام های خطا می باشند. مانند مثال زیر آنها را تولید می کنیم و به مانند سشن های دیگر بازیابی میکنیم.
Session::flash('key', 'value');

*ذخیره سشن ها در دیتابیس*

سشن ها به طور پیش فرض در فایل ذخیره می شوند. شما می توانید آنها در چند جای مختلف از جمله دیتابیس ذخیره کنید که هرکدام در کاربردهای خاصی استفاده می شوند.
 در صورتی که میخواهید سشن ها را در دیتابیس ذخیره کنید کافی است این سه دستور را به ترتیب در ترمنال تایپ و اجرا کنید :
php artisan session:table

composer dump-autoload

php artisan migrate

سپس در فایل env. مقدا*ر* SESSION_DRIVER را به database تغییر دهید. 

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

----------


## hamedarian2009

*اعتبار سنجی فرم ها*

توی این پست یک مثال کاربردی از اعتبار سنجی فرم ها رو خواهیم داشت. برای این منظور ابتدا  یک فرم رو در فایل view مثلا به نام form.blade.php در پوشه resources/views ایجاد می کنم و کدهای فرم را به این صورت می نویسم :

    <ul>
        @foreach($errors->all('<li>:message</li>') as $error)
            {!! $error !!}
        @endforeach
    </ul>
    <form action="{{ url('test') }}" method="post">
        <input type="hidden" name="_token" value="{{ csrf_token() }}">
        <label for="name">Name</label>
        <input type="text" name="name" id="name" value="{{ old('name') }}"><br>

        <label for="email">Email</label>
        <input type="text" name="email" id="email" value="{{ old('email') }}"><br>

        <label for="age">Age</label>
        <input type="text" name="age" id="age" value="{{ old('age') }}"><br>

        <input type="submit" value="Submit">
    </form>

همینطور که مشاهده میکنید اکشن فرم را به مسیر test تعیین کردم. برای فرم هایتان باید حتما یک توکن تعیین کنید که یک فیلد مخفی با نام token_ است و مقدار آن توسط تابع csrf_token ایجاد می شود و برای جلوگیری از حملات csrf به کار می رود. برای هر تکست باکس هم مقدار آن را با تابع کمکی old مقداردهی کردم تا در صورت ریدایرکت بک شدن درخواست مقادیر قبلی فرم حفظ شوند.

خب حالا باید  توی فایل routes.php دوتا مسیر تعریف کنیم. مسیر get  که فایل فرم را رندر میکند و در مرورگر نمایش می دهد و post هم که مقادیر بعد از سابمیت به آن ارسال می شوند. 

Route::get('test', function(){
    return view('form');
});

Route::post('test' , function(){

});

من برای طولانی نشدن مثال در همین فایل routes اعتبارسنجی رو انجام میدم اما شما بهتره برای رعایت اصول mvc این اعمال را داخل کنترلرها انجام بدین.

حالا اعتبارسنجی رو به این صورت انجام میدم :

Route::post('test' , function(){
    $validator = Validator::make(
        Request::all(),
        [
            'name' => 'required',
            'email' => 'required|email|unique:users',
            'age' => 'numeric',
        ]
    );

    if($validator->fails()){
        return redirect()->back()->withErrors($validator->errors())->withInput();
    }
});


همانطور که می بینید از کلاس Validator و متد make استفاده کردم. این متد دوتا پارامتر آرایه ای می گیرد که اولی آرایه ای از مقادیر هست که از فرم ارسال کرده ایم و دومی هم آرایه ای هست که قوانین اعتبارسنجی را برای هر فیلد تعریف می کنیم. چیزی که اینجا جدیده نحوه نوشتن قوانین اعتبار سنجی هست که یک آرایه هست که باید کلید آن نام اون فیلد فرم و مقدار اون قوانین اون فیلد باشد و هر قانون را هم با کاراکتر | از هم جدا میکنیم. required  یعنی الزامی بودن فرم و email یعنی یک آدرس ایمیل معتبر باشد یا numeric یعنی مقدار باید عددی باشد و ... . در اینجا از یک قانون به نام unique برای فیلد email قرار دادم که در جدول users بررسی می کند که مقدار ایمیل واردشده در جدول قبلا ثبت نشده باشد. البته باید نام ستون ایمیل در جدول با نام فیلد یکی باشد وگرنه باید نام ستون را هم جلوی قانون اضافه کنیم. 
این قوانین خیلی زیاد هستند که برای اطلاع از آنها و نحوه کارشون به اینجا مراجعه کنید
در نهایت با متد fails بررسی میکنیم اگر اعتبارسنجی دارای خطا بود به صفحه قبل ریدایرکت شود. پیغام های خطا و مقادیر قبلی فرم هم ارسال شوند.

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

public function store(Request $request)
{
    $this->validate($request, [
        'title' => 'required|unique|max:255',
        'body' => 'required',
    ]);

    //
}

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

همه برنامه نویسان حرفه ای بدنبال این هستند که همیشه حداقل کد رو بنویسن پس اگر توی کلاس کنترلر مورنظر چندین بار از اعتبارسنجی در اکشن های مختلف می خواهید استفاده کنید باز روش بهتری هست که قوانین رو در یک کلاس request ایجاد کنید. ابتدا با دستور زیر در ترمینال یک کلاس request با نام دلخواه ایجاد کنید :
php artisan make:request StoreBlogPostRequest
توجه داشته باشید این کلاس حتما باید از کلاس Request ارث برده شود. حالا توی متد rules اون کلاس قوانین رو تعریف کنیم :
public function rules()
{
    return [
        'title' => 'required|unique|max:255',
        'body' => 'required',
    ];
}
 کافیه تو هر اکشن کنترلری که می خواهیم اعتبارسنجی انجام شود از این کلاس استفاده کنیم. 
public function store(StoreBlogPostRequest $request)
{
    // The incoming request is valid...
}
درخواست ها ابتدا اعتبارسنجی می شوند در صورتی که بدون خطا باشند وارد اکشن می شوند وگرنه به طور اتوماتیک به صفحه قبلی ریدایرکت و پیغام های خطا هم قابل دسترسی هستند.

به علت طولانی بودن مطلب ادامه مطلب را در پست بعدی قرار می دهم.

----------


## hamedarian2009

*اعتبار سنجی فرم ها - ادامه*

*نمایش پیغام های خطا در view*

echo $errors->first('email');

foreach ($errors->all() as $error)
{
    //
}
در  صورتی که فقط خطای فیلد خاصی را بخواهیم نمایش دهیم مانند مثال اول و اگر  همه پیغام ها را نمایش دهیم به مانند مثال دوم عمل میکنیم.
همچنین می توانیم پیغام های خطا را در قالب یک تگ HTML نمایش دهیم که من در مثالم به این صورت عمل کردم‌:

    <ul>
        @foreach($errors->all('<li class="error">:message</li>') as $error)
            {!! $error !!}
        @endforeach
    </ul>


*ایجاد یک قانون اعتبار سنجی دلخواه*
اگر قانون مورد نظر شما در قوانین موجود لاراول وجود نداشت می توانید با استفاده از متد extend این قانون را ایجاد کنید :

Validator::extend('alpha_spaces', function($attribute, $value)
        {
            return preg_match('/^[\pL\s]+$/u', $value);
        });

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

*ایجاد پیغام خطای دلخواه برای قوانین اعتبارسنجی*

پیغام ها خطا به طور پیش فرض در مسیر resources/lang/en و فایل validation.php تعریف شده اند و به زبان انگلیسی هستند. ما می توانیم یک آرایه تعریف کنیم که کلید آن نام قانون و مقدار آن پیغام خطای مورد نظر شما می باشد و این آرایه را به عنوان پارامتر سوم به متد make بدهیم.
$messages = [
    'same'    => 'The :attribute and :other must match.',
    'size'    => 'The :attribute must be exactly :size.',
    'between' => 'The :attribute must be between :min - :max.',
    'in'      => 'The :attribute must be one of the following types: :values',
];

$validator = Validator::make($input, $rules, $messages);

البته راه بهتری پیشنهاد میکنم به جای اینکه در هر اکشن بخواهید این پیغام هارا ست کنید بهتر است داخل مسیر resources/lang یک پوشه به نام fa ایجاد کنیم و همه محتویات پوشه en را داخل آن کپی کنیم و سپس داخل فایل validation.php پیغام های خطای هر قانون را به فارسی و دلخواه خودتان ست کنید. همچنین  داخل آرایه attributes داخل همان فایل هم نام فیلدهای فرم که به ظور پیش فرض از خاصیت name هرتکست باکس گرفته می شود را به دلخواه خودتان تغییر دهید.
به مثال زیر توجه کنید :

"required"             => "فیلد :attribute پر کردن آن الزامی است.",

    'attributes' => [
        'name' => 'نام' ,
        'email' => 'آدرس ایمیل',
        'age' => 'سن',
    ],

برای قانون required یک پیغام دلخواه و نام دلخواهی برای فیلدها در نظر گرفتم.
برای استفاده از این پیغام های دلخواه چون من این پوشه را fa نامگزاری کردم باید داخل فایل app.php در پوشه config آیتم locale را به fa تغییر دهید.

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

----------


## meysam1366

سلام دوست عزیز

ممنون بابت آموزشهای خوبتون

ان شاالله کی فیلم آموزشی میسازید در قالب CMS ؟ چون به نظرم قابل فهم تره

بازم ممنون

----------


## hamedarian2009

> سلام دوست عزیز
> 
> ممنون بابت آموزشهای خوبتون
> 
> ان شاالله کی فیلم آموزشی میسازید در قالب CMS ؟ چون به نظرم قابل فهم تره
> 
> بازم ممنون


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

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

----------


## hamedarian2009

* مباحث پایه کار با دیتابیس*

یکی از مزیت های فریمورک لاراول کار با دیتابیس آن است که بسیار ساده است و متدهای زیادی برای عملیات های مختلف دارد. برای اعمال تنظیمات دیتابیس خود باید داخل فایل env. و همچنین در پوشه config و فایل database.php تنظیمات مورد نظر خود را اعمال کنید. به طور پیش فرض لاراول از mysql استفاده می کند اما از دیتابیس های MySQL , Postgres, SQLite و SQL Server هم پشتیبانی می کند و می توانیم از هر یک از انها استفاده کنیم.

*اجرای کوئری با کلاس* *DB*
در لاراول به سادگی می توانیم با استفاده از کلاس DB و نوشتن کوئری به صورت prepared statements عمل مورد نظرمان را انجام دهیم.


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

$results = DB::select('select * from users where id = ?', [1]);

$results = DB::select('select * from users where id = :id', ['id' => 1]);

*insert , update , delete*
برای درج در جدول  از متد insert و برای به روز رسانی از update و حذف از جدول  delete  را استفاده میکنیم :
DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']);

DB::update('update users set votes = 100 where name = ?', ['John']);

DB::delete('delete from users where id =:id', ['id' => 1]);
نکته : متدهای update  و delete  تعداد رکوردهایی که با این کوئری تغییر یافتند یا حذف شدند را برمیگرداند.

اگر کوئری غیر از ۴ عمل اصلی دیتابیس بود می توانیم از متد ststement استفاده کنیم :

DB::statement('drop table users');

برای تراکنش هم می توانید از متد transaction استفاده کنید و عملیات مورنظرتان را داخل تابع که به آن می دهیم را انجام دهیم. در صورتی که هریک از کوئری ها با خطایی مواجه شوند و اجرا نشوند به ظور اتوماتیک تمام کوئری های اجرا شده به عقب بر میگردند که مناسب برای عملیات های مالی می باشد.
DB::transaction(function()
{
    DB::table('users')->update(['votes' => 1]);

    DB::table('posts')->delete();
});  

در صورتی که در برنامه تان از چند اتصال به دیتابیس استفاده می کنید با استفاده از متد connection و دادن نام اتصال به آن به عنوان پارامتر از آن استفاده کنیم :
 $users = DB::connection('foo')->select(...); 

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

----------


## hamedarian2009

*کار با دیتابیس با Query Builder*

روش بهتر و آسانتر برای کار با دیتابیس در لاراول به جای نوشتن کامل کوئری استفاده از Query Builder است. شما می توانید اکثر عملیات های دیتابیس را در برنامه تان انجام بدهید و این کوئری ها در همه دیتابیس هایی که لاراول ساپورت می کند کار کند. در ضمن کوئری بیلدر لاراول از bind کردن پارامترها استفاده می کند که برنامه تان را در برابر حملات SQL Injection محافظت میکند.

*SELECT*
برای انتخاب تمامی رکوردهای یک جدول  ابتدا نام جدول موردنظر را به متد table و سپس با متد get رکوردها را واکشی میکنیم.

$users = DB::table('users')->get();

foreach ($users as $user)
{
    var_dump($user->name);
}


برای استفاده از شرط در کوئری از متد where استفاده می کنیم و این متد سه پارامتر میگیرد که اولی نام ستون موردنظر و دومی operator شرط (= , > , <, <= , ...) و سومین پارامتر هم مقدار موردنظر است. در صورتی که پارامتر دوم را ننویسیم به صورت پیش فرض عملگر =  در نظر گرفته می شود. متد  first  هم اولین رکورد که با شرط فوق همخوانی داشته باشد را برمیگرداند که برای بازیابی یک رکورد استفاده می شود. در صورتی که چند رکورد را بخواهیم بازیابی کنیم از متد get استفاده میکنیم.

$user = DB::table('users')->where('name', 'John')->first();

var_dump($user->name);$users = DB::table('users')->where('votes', '>', 100)->get();

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


$name = DB::table('users')->where('name', 'John')->pluck('name');

$roles = DB::table('roles')->lists('title');

$roles = DB::table('roles')->lists('title', 'name');


*استفاده از OR  یا AND برای جدا کردن شرط ها* 
برای این کار کافی است بعد از متد where که نوشتیم متد orWhere را استفاده کنیم :

$users = DB::table('users')
                    ->where('votes', '>', 100)
                    ->orWhere('name', 'John')
                    ->get();عبارت بالا معادل کوئری زیر است :
SELECT * FROM users WHERE votes > 100 OR name = 'john'

اگر دوباره از متد where استفاده کنیم معادل AND در نظر گرفته می شود.

متدهای بسیار زیادی وجود دارند که به علت طولانی شدن مبجث و وجود مثال ها به ظور واضح در داکیومنت برای اطلاعات بیشتر به اینجا مراجعه کنید


*استفاده از متدهای جادویی شرط* 
روش بهتر و با کدنویسی کمتر استفاده از متدهای جادویی هست. در مثال های زیر کوئری های معادل آنها را هم نوشته ام :

//SELECT * FROM users WHERE id=1 LIMIT 1;
$admin = DB::table('users')->whereId(1)->first(); 

//SELECT * FROM users WHERE id=2 AND email = 'john@doe.com' LIMIT 1;
$john = DB::table('users')
                    ->whereIdAndEmail(2, 'john@doe.com')
                    ->first(); //

//SELECT * FROM users WHERE name='Jane' OR age = 22 LIMIT 1;
$jane = DB::table('users')
                    ->whereNameOrAge('Jane', 22)
                    ->first();


* استفاده از Order By و Group By و Having با کوئری بیلدر*
$users = DB::table('users')
                    ->orderBy('name', 'desc')
                    ->groupBy('count')
                    ->having('count', '>', 100)
                    ->get();

همچنین می توانیم از LIMIT به همراه آفست در کوئری استفاده کنیم. 
$users = DB::table('users')->skip(10)->take(5)->get();
در مثال بالا کوئری میگوید که از رکورد دهم در جدول users راانتخاب کن و  تا ۵ رکورد را واکشی کن. (شماره گزاری رکوردها از صفر شروع میشود)

به علت طولانی بودن مطلب ادامه آن را در پست بعدی دنبال کنید.

----------


## hamedarian2009

*کار با دیتابیس با Query Builder - ادامه

** JOIN کردن* 
 با متد join می توانید دو یا چند جدول را باهم JOIN  کنید. این متد ۴ پارامتر می گیرد که اولی جدولی که میخواهیم به آن پیوند بزنیم و پارامترهای بعدی فیلدهایی که باید باهم مساوی باشند را قرار میدهیم.

DB::table('users')
            ->join('contacts', 'users.id', '=', 'contacts.user_id')
            ->join('orders', 'users.id', '=', 'orders.user_id')
            ->select('users.id', 'contacts.phone', 'orders.price')
            ->get(); 
در مثال بالا به سه جدول orders, users, contacts پیوند زده شده است.

با کوئری بیلدر می توانیم با توابع جمعی (count, max, min, ...)  تمام مقادیر اسکالر یک ستون را محاسبه کرده و مقداری اسکالر تولید می کند

$users = DB::table('users')->count();

$price = DB::table('orders')->max('price');

$price = DB::table('orders')->min('price');

$price = DB::table('orders')->avg('price');

$total = DB::table('users')->sum('votes');


*درج کردن (INSERT)*
با استفاده از متد insert می توانیم در جدول مورد نظر مقادیری را درج کنیم. مقادیر را در آرایه قرار می دهیم و به عنوان پارامتر به آن می دهیم. کلیدهای آرایه نام ستون جدول مورد نظر است.

DB::table('users')->insert(
    ['email' => 'john@example.com', 'votes' => 0]
);

$id = DB::table('users')->insertGetId(
    ['email' => 'john@example.com', 'votes' => 0]
);

DB::table('users')->insert([
    ['email' => 'taylor@example.com', 'votes' => 0],
    ['email' => 'dayle@example.com', 'votes' => 0]
]);

اگر در جدولتان فیلد id به صورت Auto-increment است می توانید از متد insertGetId استفاده کنید که بعد از درج  کوئری  id که تولید شده را به عنوان خروجی برمیگرداند. در مثال سوم در بالا هم همانظور که می بینید در صورتی که بخواهید چندین رکورد را باهم درج کنید کافیست رکوردها را به عنوان پارامتر به متد insert بدهیم و با ویرگول ازهم جدا کنیم.

*به روزرسانی  (UPDATE)* 
با استفاده از متد update که یک آرایه به ان میدهیم که کلید های آن نام ستون موردنظر در جدول و مقادیر آن هم مقدار جدید می باشد رکوردها را آپدیت کنیم.
DB::table('users')
            ->where('id', 1)
            ->update(['votes' => 1]);

همچنین می توانیم با متد increment مقدار ستونی را یک واحد افزایش دهیم یا با ذکر یک پارامتر دوم تعداد افزایش را به طور مثال در مثال زیر ۵ واحد مشخص کنیم. متد decrement هم مقدار را کاهش می دهد و مانند متد قبلی عمل میکند.

DB::table('users')->increment('votes');

DB::table('users')->increment('votes', 5);

DB::table('users')->decrement('votes');

DB::table('users')->decrement('votes', 5);
DB::table('users')->increment('votes', 1, ['name' => 'John']);
در مثال آخر هم همانظور که می بینید هم می توانیم عمل افزایش را انجام دهیم و هم آپدیت سایر مقادیر ستون های جدول را که به عنوان پارامتر سوم و از نوع آرایه به آن می دهیم.

*حذف کردن (Delete)*
با استفاده از متد delete می توانیم رکوردی یا همه رکوردهای جدول را حذف کنیم. اگر از شرط استفاده نکنیم همه رکوردهای جدول حذف می شوند. با استفاده از متد truncate هم می توانیم همه مقادیر یک جدول را حذف کنیم با این تفاوت که truncate هیچ شرطی نمیگیره و سریعتر از delete هست یا تفاوت دیگر آن این است که id های اختصاص داده شده به رکوردها را هم reset میکند ولی در delete اینگونه نیست.

DB::table('users')->where('votes', '<', 100)->delete();
DB::table('users')->delete();
DB::table('users')->truncate();

با استفاده از متد union می توانیم دو کوئری را باهم اجتماع کنیم :
$first = DB::table('users')->whereNull('first_name');

$users = DB::table('users')->whereNull('last_name')->union($first)->get();

*قفل کردن جدول هنگام اجرای عملیات*
در صورتی که قصد دارید در هنگام انجام عملیات SELECT جدول قفل شود میتوانیم به صورت زیر عمل کنیم :

DB::table('users')->where('votes', '>', 100)->sharedLock()->get();

DB::table('users')->where('votes', '>', 100)->lockForUpdate()->get();

با استفاده از متد sharedLock جدول را به ظور کامل قفل می کنیم و با متد lockForUpdate جدول را هنگام عملیات SELECT فقط برای به روزرسانی قفل می کنیم.

برای دیدن مثال های بیشتر به اینجا مراجعه کنید

----------


## hamedarian2009

*کار با دیتابیس و Eloquent* 
در لاراول می توانیم با استفاده از  Eloquent که پیاده سازی شده از الگوی طراحی ActiveRecord است خیلی ساده تر با دیتابیس کار کنیم. در این روش هر جدول در دیتا بیس با یک کلاس Model در ارتباط است.
برای شروع کار با Eloquent باید ابتدا یک کلاس مدل از جدول ایجاد کنیم. کلاس های مدل را داخل پوشه app قرار میدهیم. با تایپ این دستور در ترمینال می توانیم یک مدل ایجاد کنیم :
php artisan make:model User
نام مدل را همیشه به صورت PascalCase بنویسید. به طور پیش فرض مدل با جدولی که مشابه نام مدل است اما فقط یک s به آخر اضافه شده متناظر است. مثلا مدل User با جدول users در دیتابیس مرتبط است. کلاس ایجاد شده باید محتوای آن به شکل زیر باشد :

<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model {}

در صورتی که نام جدولی که با کلاس مدل از قانونی که در بالا گفتم تبعیت نمیکند میتوانید در کلاس با استفاده از پراپرتی table نام مورد نظر را ست کنیم.
class User extends Model {

    protected $table = 'my_users';

    public $timestamps = false;

}


همچنین در جداول باید دو ستون تاریخ و زمان به نام های created_at , updated_at وجود داشته باشند که هنگام ایجاد رکورد یا به روزرسانی آن مقداردهی می شوند اما شما می توانید با false قراردادن پراپرتی timestamps از ایجاد این ستون ها در جدول صرف نظر کنید.
حالا می توانیم به راحتی از کلاس مدل برای عملیات های دیتابیس استفاده کنیم. در Eloquent می توانیم از همه متدهای Query Builder استفاده کنیم.

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

$users = User::all();

رکوردی را با داشتن id آن می توانیم با متد find بازیابی کنیم :
$user = User::find(1);

var_dump($user->name);

درصورتی که  هنگام بازیابی رکوردها مقداری یافت شد و خواستیم یک خطای استثناء تولید شود کلمه OrFail را به انتهای متد موردنظر اضافه میکنیم:

$model = User::findOrFail(1);

$model = User::where('votes', '>', 100)->firstOrFail();


از تمام متدهایی که در Query  Builder یاد گرفتیم میتوانیم در Eloquent هم استفاده کنیم:

$users = User::where('votes', '>', 100)->take(10)->get();

foreach ($users as $user)
{
    var_dump($user->name);
}


*درج کردن با Eloquent* 
ابتدا یک شی از کلاس مدل ایجاد میکنیم و سپس با استفاده از شی ایجاد شده attribute های مدل که همان نام ستونهای جدول هستند را با مقدار جدید مقداردهی میکنیم و سپس با صدازدن متد save رکورد جدید را ایجاد میکنیم.
$user = new User;

$user->name = 'John';

$user->save();

$insertedId = $user->id;
بعد از درج هم میتوانیم به id اختصاص داده شده به این رکورد دسترسی داشته باشیم.

همچنین می توانیم با استفاده از متد create یک رکورد جدید را به جدول اضافه کنیم که به این روش mass-assignment گفته میشود که البته بایستی در کلاس مدل یک پراپرتی protected به نام guarded ایجاد کنیم که یک لیست سیاه می باشد و اجازه تغییر فیلدهای موردنظر را به کاربر نمیدهد. پراپرتی fillable برعکس guarded است و یک لیست سفید برای عملیات mass-assignment ایجاد میکند.

// Create a new user in the database...
$user = User::create(['name' => 'John']);

// Retrieve the user by the attributes, or create it if it doesn't exist...
$user = User::firstOrCreate(['name' => 'John']);

// Retrieve the user by the attributes, or instantiate a new instance...
$user = User::firstOrNew(['name' => 'John']);

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

*به روزرسانی رکوردها*
برای آپدیت هم مشابه درج کردن عمل میکنیم فقط با این تفاوت که به جای ایجاد شی از کلاس مدل باید رکورد مورد نظر را ابتدا بازیابی کنید. مثلا در مثال زیر رکورد با id برابر ۱ را بازیابی کرده و سپس فیلد email را با مقدار جدیدی آپدیت میکند :

$user = User::find(1);

$user->email = 'john@foo.com';
$user->save();


*حذف رکوردها*
با استفاده ازمتد delete می توانید رکورد بازیابی شده را به راحتی حذف کنید.

$user = User::find(1);

$user->delete();


همچنین روش آسانتر استفاده از متد destroy است که id رکورد را به ان میدهیم. در صورتی که تعداد id ها بیش از یکی بود هم می توانید در آرایه قرار دهید و به عنوان پارامتر به متد دهید و یا اینکه هرکدام را با ویرگول ازهم جدا کنید.

User::destroy(1);

User::destroy([1, 2, 3]);

User::destroy(1, 2, 3);


مباحث پایه کار با Eloquent را در این پست گفتم. سایر مباحث را انشالله در پست های بعدی ادامه خواهم داد
برای اطلاعات بیشتر به اینجا مراجعه کنید

----------


## hamedarian2009

*ارتباطات (Relationships)* 
تقریبا همه جداول موجود در دیتابیس بایکدیگر ارتباط دارند. ارتباطات می تواند از انواع یک به یک و یک به چند و چند به چند باشد. در لاراول با Eloquent به راحتی می توانید این ارتباط ها را مدیریت و با آنها کار کنید. در این پست دو نمونه رایج ارتباط یک به چند (One-to-Many) و چند به چند (Many-to-Many) که اکثر ارتباطها در جداول دیتابیس به این صورت است را مثال خواهیم زد.

*ارتباط One To Many*
برای مثال یک وبلاگ را در نظر بگیرید که دارای یک جدول به نام posts و یک جدول هم به نام comments هست. هر پست در بلاگ می تواند دارای چند کامنت و هرکامنت هم فقط به یک پست تعلق دارد پس این ارتباط یک به چند است. 
داخل کلاس مدل Post (که سمت یک ارتباط است) ابتدا ارتباط به مدل Comment را با افزودن یک متد همنام با جدول متناظرش مثلا به نام comments  به این صورت پیاده سازی میکنیم :

class Post extends Model {

    public function comments()
    {
        return $this->hasMany('App\Comment');
    }

}
با استفاده از متد hasMany کلاسی که با آن ارتباط چندی دارد را به عنوان پارامتر به آن میدهیم.

همچنین باید داخل کلاس مدل Comment هم متدی همنام کلاس متناظرش مثلا post ایجاد کرده و سپس با استفاده از متد belongsTo کلاس Post را به عنوان پارامتر به آن میدهیم.

class Comment extends Model {

    public function post()
    {
        return $this->belongsTo('App\Post');
    }

}


اکنون همانند مثال زیر می توانید تمام کامنت های پستی با id برابر ۱ را بازیابی کنید. همچنین می توانید از سایر متدها  همچون شرط هم استفاده کنید.
$comments = Post::find(1)->comments;

$comments = Post::find(1)->comments()->where('title', '=', 'foo')->first();

*نکته :* نام کلید خارجی باید به صورتی باشد که ابتدا نام جدولی که از آن ارجاع می شود بدون s و سپس کلمه id_ به انتهای آن افزوده شود مثلا برای مثال بالا کلید خارجی باید post_id باشد وگرنه باید در متد hasMany کلید خارجی را هم مشخص کنیم :
return $this->hasMany('App\Comment', 'foreign_key'); 

*ارتباط Many To Many*
برای پیاده سازی این نوع ارتباط فرض کنید یک جدول به نام users داریم و یک جدول هم به نام roles. هر کاربر می تواند چندین نقش داشته باشد و هر نقش هم میتواند به چندین کاربر تعلق داشته باشد. پس باید یک جدول واسط هم برای این دو جدول به نام role_user داشته باشیم. دقت کنید نام این جدول باید ترکیبی از نام دوجدول قبلی اما بدون s آخر آنها باشد که با _ ازهم جدا شده اند. سپس کلید های خارجی user_id و role_id هم در این جدول ایجاد می شوند.
در مدل User یک متد همنام جدولی که با آن ارتباط دارد ایجاد میکنیم و سپس با استفاده از متد belongsToMany کلاس مدل Role را به آن میدهیم.

class User extends Model {

    public function roles()
    {
        return $this->belongsToMany('App\Role');
    }

}


در کلاس مدل Role هم مانند بالا عمل میکنیم :

class Role extends Model {

    public function users()
    {
        return $this->belongsToMany('App\User');
    }

}


حالا به راحتی می توانیم تمامی نقش های یک کاربر را بازیابی کنیم :
$roles = User::find(1)->roles;

----------


## 1sarbaz

آقا حامد دستت واقعا درد نکنه ! آموزشها عالی هستند و نکات خیلی خوبی داشتند.

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

امیدوارم دلسرد نشین و همچنان قوی و با انرژی ادامه بدید.

----------


## hamedarian2009

*درج کردن در جدول رابطه دار*
فرض کنید می خواهیم یک کامنت را در جدولcomments درج کنیم. همانطور که قبلا مثال زدیم جدول posts با جدول comments  دارای ارتباط  یک به چند است و ستون post_id در جدول comment کلید خارجی است. همانند مثال زیر می توانید به روش mass-assignment رکوردی را در ج کنید به طوری که در فیلد post_id به طوراتوماتیک با توجه به پست مورد نظر id آن ثبت خواهد شد.

$comment = new Comment(['message' => 'A new comment.']);

$post = Post::find(1);

$comment = $post->comments()->save($comment);


*نکته :* در این روش درج باید حتما پراپرتی guarded$ را هم در کلاس مدل مورد نظر که میخواهید عمل درج را انجام دهید ست کنید تا ستون هایی که قرار نیست توسط کاربر درج شود محافظت شوند. به طور مثال در زیر من اینگونه آن را تعریف کردم :
public $guarded = ['id' , 'post_id'];

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

$comments = [
    new Comment(['message' => 'A new comment.']),
    new Comment(['message' => 'Another comment.']),
    new Comment(['message' => 'The latest comment.'])
];

$post = Post::find(1);

$post->comments()->saveMany($comments); 


بعضی مواقع نیاز داریم که هنگام select کردن رکوردها خروجی را در قالب آرایه یا JSON داشته باشیم که Eloquent دارای متدهایی برای این کار می باشد.
با استفاده از متد toArray می توانیم خروجی هر کوئری را به یک آرایه تبدیل کنیم
$user = User::with('roles')->first();

return $user->toArray();

با متد toJson هم خروجی را به JSON تبدیل می کنیم :

return User::find(1)->toJson();


Eloquent دارای مباحث بسیار زیادی می باشد که گنجاندن همه آنها در این آموزش میسر نمی باشد و من مباحث اصلی را ذکر کردم و برای  اطلاعات بیشتر  به اینجا مراجعه کنید

----------


## hamedarian2009

*صفحه بندی کردن (Pagination)*

هنگامی که تعداد رکوردهایی که می خواهید در یک صفحه وب  نمایش دهید زیاد می باشد بهترین روش برای مدیریت تعداد نمایش در هر صفحه صفحه بندی کردن است. در لاراول شما آسان تر از سایر فریمورک ها می توانید این کار را انجام دهید. کد HTML ای هم که برای نمایش صفحه بندی تولید می شود سازگار با Bootstrap Twitter می باشد.

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

$users = DB::table('users')->paginate(15);
$allUsers = User::paginate(15);

$someUsers = User::where('votes', '>', 100)->paginate(15);
در مثال های فوق هم با روش کوئری بیلدر و هم Eloquent اینکار را انجام داده ایم و تعداد آیتم ها را ۱۵ تعیین کردیم.

حالا فرض کنید تمام کاربران را از دیتابیس واکشی کردیم و به صفحه view با متغیری به نام users ارسال کردیم. داخل ویو موردنظر کدهای زیر را قرار می دهیم :

<div class="container">
    <?php foreach ($users as $user): ?>
        <?php echo $user->name; ?>
    <?php endforeach; ?>
</div>

<?php echo $users->render(); ?>


با استفاده از حلقه foreach نام کاربران را نمایش میدهیم. برای نمایش کد HTML مربوط به صفحه بندی هم از متد render استفاده میکنیم و آن را چاپ میکنیم. البته مثال بالا به روش php نوشته شده و شما بهتر است از موتور قالب Balde استفاده کنید. با CSS میتوانید قالب نمایش صفحه بندی را به دلخواه خودتان تغییر دهید.

غیر از متد render متدهای دیگر هم وجود دارند که می توانید اطلاعات بیشتری  را بدست آورید به طور مثال currentPage شماره صفحه جاری را نمایش می دهد و lastPage شماره آخرین صفحه و ... 

اگر فقط می خواهید   لینک Next و Previous نمایش داده شود و صفحه بندی ساده ای باشد از متد simplePaginate هنگام واکشی استفاده کنید. 

$someUsers = User::where('votes', '>', 100)->simplePaginate(15);


 به طور پیش فرض URL هنگام صفحه بندی مثلا به صورت 2=page? خواهد بود شما می توانید با متد setPath یک URL دلخواه هنگام نمایش صفحه بندی  ایجاد کنید :

$users = User::paginate();

$users->setPath('custom/url');

در مثال بالا آدرس URL به صورت http://example.com/custom/url?page=2  نمایش داده می شود.

به انتهای URL  می توانیم کوئری استرینگ هم اضافه کنیم. هنگام نمایش صفحه بندی با استفاده از متد append که داده های کوئری استرینگ را به عنوان آرایه به آن می دهیم :

<?php echo $users->appends(['sort' => 'votes'])->render(); ?>

در مثال بالا آدرس URL به صورت http://example.com/something?page=2&sort=votes  نمایش داده میشود.


همچنین می توانیم با متد fragment یک آدرس fragment را به انتهای URL اضافه کنیم.

<?php echo $users->fragment('foo')->render(); ?>

در مثال بالا URL به صورت http://example.com/something?page=2#foo نمایش داده می شود.

----------


## Vahid2016

با سلام ، از مدیر محترم بخش PHP تقاضا داریم با توجه به ماهیت این تاپیک و استقبالی که از آن شده این تاپیک را هم مث تاپیک آموزش Yii تاپیک اعلان بکنند ، با تشکر

----------


## hamedarian2009

*کار با Migration*
migration یک نوع  کنترل ورژن برای دیتابیس برنامه تان است. به تیم برنامه نویسی شما این اجازه رو مییدهد که شما (Schema) دیتابیس رو طراحی کنند و تغییر بدهند. با این ابزار شما می توانید نسخه های مختلفی از دیتابیس رو هم داشته باشین که با یکسری دستورات میتونید به نسخه های مختلف سوئیچ کنید. یکی از مزیت های دیگر آن مهم نبودن نوع دیتابیس است و دستورات شما با همه دیتابیس هایی که لاراول ساپورت میکند کار خواهد کرد. migration به طور معمول با استفاده از Schema Builder کار میکند.

*ایجاد یک migration*

با استفاده از دستور make:migration  و تایپ آن در ترمینال می توانیم یک migration جدید ایجاد کنیم:
php artisan make:migration create_users_table
migration  ایجاد شده در مسیر پوشه database/migrations قرار می گیرد. اکنون با استفاده از دستورات Schema Builder می توانیم schema جدول موردنظرمان را طراحی کنیم.


use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function(Blueprint $table)
        {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password', 60);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('users');
    }

}

همانطور که می بینید کلاس migration دارای دو متد به نام up و down می باشد. از up برای ایجاد جدول و افزودن یا تغییر ستون هاو از down برای عمل برعکس آن استفاده میکنیم مثلا اگر جدولی را ایجاد کرده ایم در متد down آن را حذف میکنیم. از کلاس Schema و متد create برای ایجاد جدول استفاده میکنیم که دو پارامتر می گیرد اولی نام جدول می باشد و دومی یک تابع بی نام می باشد که آبجکت table$ را به عنوان پارامتر میگیرد.داخل تابع ستون ها را تعریف میکنیم. به صورتی که  متدهای آبجکت table$ نوع ستون و پارامتر ورودی آنها نام ستون را مشخص میکند.
 مثلا متد increments نوع int و کلید اصلی به همراه AutoIncrement در نظر میگیرد.
 string نوع varchar در نظر گرفته می شود و پارامتر دومی هم میشود به آن داد که طول رشته را مشخص میکند.
unique ستون را به ایندکس unique تبدیل میکند.
timestamps فیلدهای زمانی created_at و updated_at را ایجاد میکند.
برای اطلاعات بیشتر در مورد نحوه ایجاد ستون ها به اینجا مراجعه کنید.

در تابع down هم با استفاده از متد drop مشخص کردیم جدول users حذف شود.
با استفاده از دستور زیر می توانید migration ایجاد شده را اجرا کنید:
php artisan migrate 
با اجرای دستور بالا جدول موردنظر در دیتابیس ایجاد خواهد شد. البته دستور بالا تمام migration هایی که اجرا نشده اند را اجرا میکند.

 و با استفاده از دستور زیر می توانید دستورات متد down را اجرا کنید و باتوجه به مثال بالا جدول users حذف می شود :
php artisan migrate:rollback

نکته : اگر در هنگام اجرای دستور migrate پیغام خطای "class not found" داد از دستور زیر قبل از دستور migrate در ترمینال استفاده کنید :
composer dump-autoload
مباحث بیشتر در مورد این موضوع را در پست بعدی خواهم گفت

----------


## hamedarian2009

*کار با  Schema Builder و  Migration*

در هنگام ایجاد migration می توانید نام جدول را هم در دستور مشخص کنید .
php artisan make:migration create_users_table --create=users
برای نامگزاری فایل migration معمولا از یک نام با مسما که نشانده عملیات موردنظرمان است استفاده میکنیم مثلا برای افزودن یک ستون جدید به نام votes در جدول users به این صورت فایل را نامگزاری و ایجاد میکنیم :
php artisan make:migration add_votes_to_users_table --table=users

بعضی از عملیات های دیتابیس ممکن است مخرب باشند و هنگامی در جداول دیتابیس داده ای وجود داشته باشد باعث از بین رفتن برخی داده ها شود برای محافظت از این خطرات از دستور migaret به صورت زیر استفاده کنید و در پایان آن force-- را قرار دهید :
php artisan migrate --force

همانطور که در پست قبل دیدید از دستور rollback استفاده کردیم که این دستور روی آخرین عملیات migration عمل میکند. برای اینکه همه عملیات ها را rollback کنیم از دستور migrate:reset استفاده میکنیم و در صورتی که بخواهیم همه عملیات ها rollback و سپس دوباره اجرا شوند از migrate:refresh استفاده میکنیم.

php artisan migrate:resetphp artisan migrate:refresh

فرض کنید میخواهیم ستون ایمیل را به جدول users اضافه کنیم ابتدا فایل migration ای ایجاد و سپس در متد up آن دستور زیر را می نویسیم :
Schema::table('users', function($table)
{
    $table->string('email');

//$table->string('name')->after('email');});
در متد down هم دستورات زیر را قرار میدهیم :

Schema::table('users', function($table)
{
    $table->dropColumn('email');

});

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

برای تغییر نام جدول از متد rename از کلاس Schema مانند مثال اول در زیر استفاده کنید. با استفاده drop هم می توانیم جدولی را حذف کنیم و dropIfExists هم ابتدا بررسی میکند اگر جدول وجود داشت آن را حذف میکند.

Schema::rename($from, $to);
Schema::drop('users');

Schema::dropIfExists('users');


برای ویرایش یک ستون ابتدا بایستی مطمئن شوید که وابستگی doctrine/dbal روی فریمورک نصب شده باشد در غیر اینصورت مانند زیر عمل کنید:
 در بخش require فایل composer.json آن را اضافه کرده :

    "require": {
        "laravel/framework": "5.0.*",
        "illuminate/html": "~5.0",
        "doctrine/dbal": "2.5.*",
    },

سپس از دستور  composer update در ترمینال برای نصب این وابستگی استفاده کنید.

همانند مثال زیر می توانیم یک ستون را ویرایش کنیم. در مثال زیر طول ستون name را به ۵۰ کاراکتر تغییر داده و آن را قابل NULL بودن تعریف میکنیم:
Schema::table('users', function($table)
{
    $table->string('name', 50)->nullable()->change();
});

برای افزودن کلید خارجی به یک جدول هم به این صورت عمل میکنیم :
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');

ابتدا یک ستون unsigned عددی به نام user_id ایجاد کردیم و سپس در پایین آن را کلید خارجی تعریف کردیم و گفتیم که مرجعی از ستون id از جدول users می باشد.
همچنین می توانیم خاصیت onDelete آن راهم تعیین کنیم :
$table->foreign('user_id')
      ->references('id')->on('users')
      ->onDelete('cascade');

برای حذف کلید خارجی هم همانند مثال زیر عمل میکنیم :
$table->dropForeign('posts_user_id_foreign');



با استفاده از متد hasTable می توانیم بررسی کنیم آیا جدول موردنظر وجود دارد یا خیر و یا با استفاده از متد hasColumn بررسی کنیم در جدول موردنظر ستون های موردنظرمان وجود دارد یا خیر:
if (Schema::hasTable('users'))
{
    //
}

if (Schema::hasColumn('users', 'email'))
{
    //
}

برای افزودن و حذف ایندکس می توانیم همانند مثال های زیر عمل کنیم :

$table->string('email')->unique();
$table->dropUnique('email');


برای حذف ستونهای زمانی هم مانند مثال های زیر عمل کنید:

$table->dropTimestamps();
$table->dropSoftDeletes();

همچنین می توانیم موتور ذخیره سازی دیتابیس را هم مشخص کنیم :
$table->engine = 'InnoDB';

----------


## hamedarian2009

*Hash کردن*
در لاراول با استفاده از کلاس Hash می توانیم یک رشته را به صورت هش در بیاوریم که مناسب برای هش کردن کلمه عبور کاربران برای ذخیره در دیتابیس می باشد.

از متد make برای هش کردن کلمه عبور استفاده میکنیم و کلمه عبور هش شده را در دیتابیس ذخیره کنیم :
$password = Hash::make('secret');
همچنین می توانیم از تابع کمکی bcrypt نیز استفاده کنیم:
$password = bcrypt('secret');

همچنین برای بررسی صحت کلمه عبور وارد شده توسط کاربر با کلمه عبور هش شده ذخیره در دیتابیس به این صورت عمل میکنیم :
if (Hash::check('secret', $hashedPassword))
{
    // The passwords match...
}

----------


## hamedarian2009

*احراز هویت کاربران (Authentication)*

پیاده سازی احراز هویت در لاراول بسیار ساده ساده است. تنظیمات مربوط به احرازهویت در پوشه config و فایل auth.php قرار دارد. در این فایل می توانید درایور را eloquent تعیین کنید و کلاس مدلی که به جدول کاربران دسترسی دارد را مشخص کنید و همچنین در بخش table نام جدولی که اطلاعات کاربران در ان ذخیره می شود را مشخص کنید.
به طور پیش فرض در پوشه app یک مدل به نام User وجود دارد که با استفاده از eloquent لاراول یک سیستم احرازهویت را پیاده سازی کرده است که شما می توانید از آن استفاده کنید. در مسیر app/Http/Controllers/Auth دوکنترلر برای استفاده در سیستم احرازهویت استفاده می شوند که AuthController برای ایجاد کاربر جدید یا لاگین کردن و PasswordController برای ریست کردن کلمه عبور کاربرانی که آن را فراموش کرده اند به کار می رود. تمام view های مربوطه هم در پوشه resources/views/auth قرار دارند و شما می توانید آنها را به دلخواه خودتان ویرایش کنید.
همچنین اگر نیاز دارید تغییراتی در فرم ثبت نام کاربر جدید بدهید کافی است در مسیر App\Services در فایل Registrar.php تغییرات موردنظر را اعمال کنید. در متد validator می توانید قوانین اعتبارسنجی فیلدها و در متد create نیز مقادیر فیلدهارا در دیتابیس و جدول users درج کنید. شما به راحتی می توانید از این سیستم احراز هویت پیش فرض لاراول استفاده کنید.
خود لاراول یک middleware به نام Authenticate ایجاد کرده که در متد handle آن ابتدا بررسی میکند آیا کاربر لاگین کرده یا خیر و در غیر اینصورت آن را به صفحه login هدایت میکند. شما با استفاده از این middleware در سازنده کلاس کنترلری که میخواهید فقط کاربران احرازهویت شده دسترسی داشته باشند به صورت زیر عمل کنیم. به طور مثال در کلاس کنترلر HomeController به همین صورت عمل شده است  :

    public function __construct()
    {
        $this->middleware('auth');
    }


در صورتی که نمیخواهید از این سیستم احرازهویت تهیه شده توسط لاراول استفاده کنید نگران نباشید. خودتان هم می توانید به سادگی آن را پیاده سازی کنید.
برای اینکار باید کلاس Auth را به کنترلر ایمپورت کنید و سپس با استفاده از متد attempt به عنوان پارامتر یک آرایه دریافت می کند و کلیدهای این آرایه نام ستون های موردنظر در دیتابیس و جدول users و مقادیر آن هم مقداروارد شده توسط کاربر است صحت اطلاعات کاربر را بررسی کنید. متد attempt در صورتی که احراز هویت با موفقیت انجام شود true وگرنه false برمیگرداند.

<?php namespace App\Http\Controllers;

use Auth;
use Illuminate\Routing\Controller;

class AuthController extends Controller {

    /**
     * Handle an authentication attempt.
     *
     * @return Response
     */
    public function authenticate()
    {
        if (Auth::attempt(['email' => $email, 'password' => $password]))
        {
            return redirect()->intended('dashboard');
        }
    }

}

همچنین می توانیم در متد attempt اطلاعات بیشتری را بررسی کنیم.مثلا در مثال زیر علاوه بر ایمیل و کلمه عبور باید کاربر فیلد تایید آن در دیتابیس هم ۱ باشد :
if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1]))
{
    // The user is active, not suspended, and exists.
}

در هر قسمت از برنامه هم که نیاز دارید بررسی کنید کاربر جاری احراز هویت شده است یا خیر کافی است از متد check اینکار را انجام دهید :
if (Auth::check())
{
    // The user is logged in...
}

برای logout کردن از برنامه هم از متد logout استفاده میکنیم :
Auth::logout();

بعداز اینکه کاربر احرازهویت شد به راحتی با استفاده از متد user میتوانید یک آبجکت از کاربر جاری ایجاد کنید :

$user = Auth::user();
 echo $user->name;

در مثال همانطور که مشاهده کردید به راحتی توانستم به نام کاربر دسترسی داشته و آن را چاپ کنم.

در کنترلر به این صورت هم می توان به روش های زیر یک آبجکت از کاربر ایجاد کنیم :
public function updateProfile(Request $request)
    {
        if ($request->user())
        {
            // $request->user() returns an instance of the authenticated user...
        }
    }
//×××××××××××××××××××××××××  ××××××××××××××××××××××
public function updateProfile(Authenticatable $user)
    {
        // $user is an instance of the authenticated user...
    }


برای مسیرها هم می توانیم middleware احرازهویت را تعریف کنیم تا دسترسی به مسیر فقط برای کاربران احرازهویت شده میسر باشد.
Route::get('profile', ['middleware' => 'auth', 'uses' => 'ProfileController@show']);


مباحث اصلی را ذکر کردم و برای اطلاعات بیشتر می توانید  به اینجا مراجعه کنید

----------


## hamedarian2009

*یک مثال کاربردی  آپلود فایل* 
حالا نوبت این است که با یک مثال کاربردی  نحوه آپلود فایل در لاراول رو کار کنیم. فرض کنید می خواهیم در جدول posts یک مطلب جدید را اضافه کنیم که این مطلب دارای یک تصویر هم می باشد که قرار است آن را در مسیر public/uploads ذخیره کنیم. فرض میکنیم در جدول posts ستونهای (id, title, body, pic_name) وجود دارد.
یک فایل view به نام form.blade.php در مسیر resources/views ایجاد کنید و کدهای زیر را داخل آن قرار دهید :


```
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form validation</title>
    <style type="text/css">
        .error {
            color: red;
            font-weight: bold;
        }
        .success {
            color: green;
            font-weight: bold;
        }
    </style>
</head>
<body>
    <form action="{{ url('add-post') }}" method="post" enctype="multipart/form-data">
        <input type="hidden" name="_token" value="{{ csrf_token() }}">
        <label for="title">Title</label>
        <input type="text" name="title" id="title" value="{{ old('title') }}">
        <span class="error">{{ $errors->first('title') }}</span><br>

        <label for="post">Post</label>
        <textarea name="post" id="post">{{ old('post') }}</textarea>
        <span class="error">{{ $errors->first('post') }}</span><br>

        <label for="photo">Select an Image:</label>
        <input type="file" name="photo" id="photo">
        <span class="error">{{ $errors->first('photo') }}</span><br>

        <input type="submit" value="Submit">
    </form>
    <p class="success">{{ session('message') }}</p>
    <p class="error">{{ session('error') }}</p>
</body>
</html>
```

اکنون مسیر های زیر را در فایل routes.php تعریف میکنیم :

Route::get('add-post', 'PostController@getAddPost');

Route::post('add-post', 'PostController@postAddPost');


همانطور که می بینید باید یک کنترلر به نام PostController  داشته باشیم و متدهای getAddPost و postAddPost را داخل آن تعریف کنیم.
ابتدا برای رندر کردن فایل ویو متد getAddPost را به صورت زیر بنویسید :

    public function getAddPost()
    {
        return view('form');
    }


کد های زیر را هم در متد postAddPost قرار دهید :

    public function postAddPost(Request $request)
    {
        $rules = [
            'title' => 'required|max:255|unique:posts',
            'post' => 'required',
            'photo' => 'required|image|max:1024',
        ];
        $v = Validator::make($request->all(), $rules);
        if($v->fails()){

            return redirect()->back()->withErrors($v->errors())->withInput($request->except('photo'));
        
        } else {
            
            $file = $request->file('photo');
            if($file->isValid()){
                $fileName = time().'_'.$file->getClientOriginalName();
                $destinationPath = public_path().'/uploads';
                $file->move($destinationPath, $fileName);
                $post = new Post;
                $post->title = $request->input('title');
                $post->body = $request->input('post');
                $post->pic_name = $fileName;
                $post->save();

                return redirect()->back()->with('message', 'The post successfully inserted.');
            } else {
                return redirect()->back()->with('error', 'uploaded file is not valid.');
            }
        }
    }


همانطور که که می بینید ابتدا مقادیر فرم را اعتبارسنجی کردیم. برای فایل هم با قانون max مشخص کردم که فایل فقط می تواند ۱۰۲۴ کیلوبایت سایز داشته باشد و همچنین با قانون image مشخص میکنیم که فایل از نوع تصویر باشد فقط mime type های (jpeg, png, bmp, gif, or svg) را قبول میکند. در صورتی که می خواهید محدودیت بیشتری برای mime type فایل در نظر بگیرید یا اصلا فایل شما تصویر نیست می توانید با استفاده از قانون mime نوع فایل را مشخص کنید. در صورتی که اعتبارسنجی دارای خطا باشد به فرم برگشته و خطاها نمایش داده می شوند. 
سپس اطلاعات فایل رو در متغیر file$ قرار دادم و با استفاده از متدهای کلاس UploadedFile می توانیم به اطلاعات فایل دسترسی داشته باشیم. نام فایل را تلفیقی از timestamp جاری و نام اصلی فایل تعیین کردم تا احتمال اینکه نام فایل تکراری باشد وجود نداشته باشد و داخل متغیر fileName$ قرار دادم. مسیر آپلود فایل را در destinationPath$ قرار دادم و با استفاده از متد move فایل را آپلود میکنیم. این متد مسیر آپلود و نام فایل را به عنوان پارامتر میگیرد.
در نهایت سایر مقادیر فرم به همراه نام فایل را در جدول posts درج میکنیم. در صورت موفقیت یا عدم موفقیت نیز پیغام های خطایی را ست و در ویو چاپ میکنیم.

اکنون هرقسمت از وبسایت که می خواهیم پست ها را نمایش دهیم به راحتی می توانیم تصویر را هم با استفاده از نام آن نمایش دهیم:
    <img src="{{ asset('uploads/'.$post->pic_name) }}" alt="{{ $post->pic_name }}" >

----------


## hamedarian2009

*ارسال ایمیل* 

در لاراول ۵ شما به راحتی می توانید با استفاده از کلاس Facade Mail یک ایمیل را ارسال کنید. توی این بخش هم میخوام به صورت کاربردی نحوه ارسال ایمیل را برایتان توضیح بدهم. فرض میکنیم یک فرم تماس با ما داریم که میخواهیم بعد از تکمیل ان توسط کاربر به ایمیل مدیر سایت ارسال شود. 
ابتدا باید در فایل env. تنظیمات مربوط به ایمیل هاست خود را ست کنید. در این مثال من تنظیمات جیمیل خودم را قرار دادم :

MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=**********@gmail.com
MAIL_PASSWORD=************


همچنین در پوشه config و فایل mail.php هم می توانید تنطیمات بیشتری را اعمال کنید.

حالا دوتا مسیر توی فایل routes.php ایجاد میکنیم :

Route::get('contact-me', ['as' => 'contact', 'uses' => 'ContactController@contactForm']);

Route::post('contact-me', ['as' => 'contact_send', 'uses' => 'ContactController@contactSend']);


همانطور که مشاهده میکنید برای هر مسیر یک نام انتخاب کردم و همچنین به کنترلر ContactController و اکشن contactForm برای درخواست های GET و اکشن contactSend برای درخواست های POST نیاز داریم.  متد contactForm را به این صورت می نویسیم :

public function contactForm()
    {
        return view('emails.contact');
    }

همانطور که مشخص کردیم باید فرم تماس با ما را در پوشه emails و فایل contact.blade.php در مسیر resources/views ذخیره میکنیم و کدهای زیر را داخل آن قرار می دهیم:


```
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Contact</title>
</head>
<body>
<h1>Contact Me</h1>
<form action="{{ route('contact_send') }}" method="POST">
    <input type="hidden" value="{{ csrf_token() }}" name="_token">

    <label for="name">Your Name: </label>
    <input type="text" name="name" id="name" value="{{ old('name') }}"> <span class="error">{{ $errors->first('name') }}</span> <br>

    <label for="email">Your Email: </label>
    <input type="email" name="email" id="email" value="{{ old('email') }}"> <span class="error">{{ $errors->first('email') }}</span> <br>

    <label for="message">Message:</label>
    <textarea name="message" id="message">{{ old('message') }}</textarea> <span class="error">{{ $errors->first('message') }}</span> <br>
    
    <input type="submit" value="Send">
</form>  

@if (Session::has('message'))
  {{ Session::get('message') }}
@endif
</body>
</html>
```

توی این مثال از ویژگی کلاس  Request هم برای اعتبارسنجی استفاده میکنیم. پس با دستور زیر یک کلاس Request ایجاد میکنیم :
php artisan make:request ContactFormRequest

این کلاس در مسیر app/Http/Requests ایجاد می شود. آن را باز کرده و در متد rules آن قوانین اعتبارسنجی فرمتان را تعیین کنید.

public function rules()
{
  return [
    'name' => 'required',
    'email' => 'required|email',
    'message' => 'required',
  ];
}
همچنین متد authorize را که به طور پیش فرض false برمیگرداند true کنید چون نیازی به اهراز هویت در این درخواست نداریم. خب با این کار دیگه نیازی نیست تو کنترلر اعتبارسنجی انجام بدیم فقط کافیه این کلاسی که ساختیم رو به عنوان پارامتر به متد contactSend بدهیم :


public function contactSend(ContactFormRequest $request)
    {
        extract($request->all());

        Mail::send('emails.email',
            array(
                'name' => $name,
                'email' => $email,
                'content' => $message
            ), function($message) use($email, $name) {

                $message->from($email, $name);
                $message->to('example@gmail.com')->subject('Test Email');
        });

              return Redirect::route('contact')->with('message', 'Thanks for contacting us!');
    }


به این متد فقط درخواست های اعتبارسنجی شده وارد می شوند و اعتبارسنجی داخل کلاس ContactFormRequest انجام می شود. ابتدا همه داده های فرم که به صورت آرایه هست را با دستور extract تبدیل به متغیر کردم و با استفاده از کلاس Mail و متد send ایمیل را ارسال میکنیم. متد send سه تا پارامتر میگیره که اولی یک فایل وبو هست که داخل آن محتویات html برای ارسال فرم را تولید میکنیم و پارامتر دوم داده هایی که نیاز داریم به آن فابل ویو ارسال کنیم را در قالب آرایه میفرستیم و در پارامتر سوم هم یک تابع بی نام ایجاد کرده و اطلاعات فرستنده و گیرنده نامه را تعیین میکنیم. در متد from نام و ایمیل فرستنده و در متد to ایمیل گیرنده نامه و در متد subject موضوع نامه را تعیین میکنیم. 
در نهایت به صفحه تماس با ما ریدایرکت میکنیم و پیغامی را هم ارسال و چاپ میکنیم. 
همچنین باید یک فایل ویو که در متد send آن را به عنوان پارامتر اول دادیم هم در پوشه emails ایجاد کنیم. پس نام آن را email.blade.php قرار می دهیم و محتویات زیر را داخل آن می نویسیم :


```
You received a message from hamo.ir:

<p>
Name: {{ $name }}
</p>

<p>
Email address :{{ $email }}
</p>

<p>
    {{ $content }}
</p>
```

امیدوارم که این مثال برایتان مفید بوده باشد.

----------


## relaxdevil

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

----------


## hamedarian2009

> مرسی بسیار عالی همینطور پیش برو داداش
> یه سوال کاربری اگه رمز عبور خودشو یادش بره بخواد بهش رمز جدیدی ایمیل بشه چی ؟
> رمز جدید تصادفی چطور ایجاد کنیم مرسی اگه راه حل یا براش یه آموزش بگی بهمون


با تشکر
در لاراول ۵ یک سیستم احراز هویت پیش فرض پیاده سازی شده که اگه به آدرس http://example.com/auth/login بروید یک لینک در زیر فرم لاگین قرار داره که شمارو به صفحه ای میبره که ازتون ایمیلتون رو میخاد و بعد از دریافت ایمیل یک لینک به ایمیل شما ارسال میکنه و شما با کلیک روی اون لینک به صفحه ریست کردن پسورد می روید و میتونید پسورد جدیدی برای خودتان ست کنید.
بازهم برای درک بیشتر امروز حتما یک آموزش در این زمینه خواهم داشت

----------


## hamedarian2009

*RESET کردن کلمه عبورکاربر*
توی این پست به درخواست یکی از دوستان نحوه ریست کردن کلمه عبور کاربران رو باهم کار میکنیم. ابتدا در مسیر app/Http/Controllers/Auth کلاس PasswordController را باز کنید و به آن متد  getEmail را اضافه کنید :

public function getEmail()
    {
        return view('auth.password');
    }

پس بایستی یک فایل view در پوشه auth به نام password.blade.php داشته باشیم که فرم ریست کردن کلمه عبور در آن قرار دارد. محتویات این فایل شبیه زیر است :


```
@extends('app')

@section('content')
<div class="container-fluid">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-default">
                <div class="panel-heading">Reset Password</div>
                <div class="panel-body">
                    @if (session('status'))
                        <div class="alert alert-success">
                            {{ session('status') }}
                        </div>
                    @endif

                    @if (count($errors) > 0)
                        <div class="alert alert-danger">
                            <strong>Whoops!</strong> There were some problems with your input.<br><br>
                            <ul>
                                @foreach ($errors->all() as $error)
                                    <li>{{ $error }}</li>
                                @endforeach
                            </ul>
                        </div>
                    @endif

                    <form class="form-horizontal" role="form" method="POST" action="{{ url('/password/email') }}">
                        <input type="hidden" name="_token" value="{{ csrf_token() }}">

                        <div class="form-group">
                            <label class="col-md-4 control-label">E-Mail Address</label>
                            <div class="col-md-6">
                                <input type="email" class="form-control" name="email" value="{{ old('email') }}">
                            </div>
                        </div>

                        <div class="form-group">
                            <div class="col-md-6 col-md-offset-4">
                                <button type="submit" class="btn btn-primary">
                                    Send Password Reset Link
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

```

این فایل از layout ای که لاراول به طور پیش فرض در پوشه views قرار داده به نام app.blade.php ارث برده می شود که از  bootstrap هم استفاده میکند.

در کلاس PasswordController یک متد به نام postEmail هم برای دریافت ایمیل کاربر بعد از ارسال توسط این فرم باید ایجاد کنیم :

 public function postEmail(Request $request)
    {
        $v = Validator::make($request->all(), [
            'email' => 'required|email|exists:users',
        ]);

        if ($v->fails())
        {
            return redirect()->back()->withErrors($v->errors());
        } else {
            $response = $this->passwords->sendResetLink($request->only('email'), function($m)
            {
                $m->subject($this->getEmailSubject());
            });

            switch ($response)
            {
                case PasswordBroker::RESET_LINK_SENT:
                    return redirect()->back()->with('status', trans($response));

                case PasswordBroker::INVALID_USER:
                    return redirect()->back()->withErrors(['email' => trans($response)]);
            }

        }
    }

*نکته :* ابتدای کلاس کنترلر این کلاس ها را ایمپورت کنید چون در بدنه کلاس از آنها استفاده میکنیم:
use Illuminate\Http\Request;
use Validator;

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

حالا وارد ایمیل خودتان بشوید و بر روی لینکی که برایتان ارسال شده است کلیک کنید. این لینک حاوی یک توکن است که آن توکن دوباره در کنترلر بررسی میشود و اگر درست بود  وارد صفحه ای می شوید که می توانید کلمه عبور خودتان را ریست کنید. فایل view آن در همان پوشه views/auth و به نام reset.blade.php است و حاوی کدهای زیر است :


```
@extends('app')

@section('content')
<div class="container-fluid">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-default">
                <div class="panel-heading">Reset Password</div>
                <div class="panel-body">
                    @if (count($errors) > 0)
                        <div class="alert alert-danger">
                            <strong>Whoops!</strong> There were some problems with your input.<br><br>
                            <ul>
                                @foreach ($errors->all() as $error)
                                    <li>{{ $error }}</li>
                                @endforeach
                            </ul>
                        </div>
                    @endif

                    <form class="form-horizontal" role="form" method="POST" action="{{ url('/password/reset') }}">
                        <input type="hidden" name="_token" value="{{ csrf_token() }}">
                        <input type="hidden" name="token" value="{{ $token }}">

                        <div class="form-group">
                            <label class="col-md-4 control-label">E-Mail Address</label>
                            <div class="col-md-6">
                                <input type="email" class="form-control" name="email" value="{{ old('email') }}">
                            </div>
                        </div>

                        <div class="form-group">
                            <label class="col-md-4 control-label">Password</label>
                            <div class="col-md-6">
                                <input type="password" class="form-control" name="password">
                            </div>
                        </div>

                        <div class="form-group">
                            <label class="col-md-4 control-label">Confirm Password</label>
                            <div class="col-md-6">
                                <input type="password" class="form-control" name="password_confirmation">
                            </div>
                        </div>

                        <div class="form-group">
                            <div class="col-md-6 col-md-offset-4">
                                <button type="submit" class="btn btn-primary">
                                    Reset Password
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

```

بعد از اینکه کلمه عبور را تغییر دهید به طور اتوماتیک به صفحه کاربری خود ریدایرکت می شوید که این صفحه در لاراول home می باشد که می توانید با استفاده از پراپرتی redirectTo آن را تغییر دهید :

    protected $redirectTo = '/dashboard';

در مثال بالا آن را به مسیر dashboard تغییر دادم.

در پایان باید یادتان باشد که تنظیمات مربوط به ایمیل برنامه تان را در فابل env. و config/mail.php به درستی اعمال کنید وگرنه ممکن است در ارسال ایمیل دچار خطا شوید.

----------


## behvandi

آقا خسته نباشی ، فیلم لاراول در قالب پروژه رو اگه آماده کنی و بذاری خیلی خیلی ممنون میشم

----------


## hamedarian2009

> آقا خسته نباشی ، فیلم لاراول در قالب پروژه رو اگه آماده کنی و بذاری خیلی خیلی ممنون میشم


انشالله تا یکی دوماه آینده سعی مکینم آماده کنم و لینک آن را در همین جا قرار میدم

----------


## hamedarian2009

*افزودن کلاس و پکیج به لاراول ۵*

ممکن است شما کلاسی رو خودتون نوشته باشید و قصد دارین از اون توی فریمورک لاراول استفاده کنید. توی لاراول ۵ به راحتی میتونید از کلاستون استفاده کنید. یک پوشه توی پوشه app به نام Classes ایجاد میکنیم و یک فایل مثلا به نام Common.php ایجاد میکنیم و کلاس Common  رو داخلش تعریف میکنیم :

<?php namespace App\Classes;

class Common
{

   public static function pre($array)
   {
            echo '<pre>' . print_r($array, true) . '</pre>';
   }




همانطور که مشاهده میکنید ایتدا یک namespace برای کلاس تعریف کردم و برای مثال داخل کلاس متدی استاتیک به نام pre تعریف کردم. حالا هرجای پروژه به راحتی می تونید به این صورت با این متد کار کنید :
$cars = ['volvo', 'toyota', 'bmw'];
        \App\Classes\Common::pre($cars);

یا مثلا در کنترلر بهتره اونو use کنیم و اینجوری استفاده کنیم :

use App\Classes\Common;

class SiteController extends Controller
{
    public function index()
    {
        $cars = ['volvo', 'toyota', 'bmw'];
        return Common::pre($cars);
    }
//×××××××××××××××××××××××××  ××××


*افزودن پکیج به لاراول* 
برای لاراول پکیج های زیادی نوشته میشه که شما میتونید با مراجعه به این آدرس پکیج مورد نظرتون سرچ کنید و اونو معمولا با composer به فریمورک اضافه کنید:
http://packalyst.com/

مثلا یکی از پکیج های خوبش اینه که کار با تصویر رو براتون آسون میکنه http://packalyst.com/packages/packag...rvention/image
یا پکیج debug-bar لاراول که خیلی کاربردیه http://packalyst.com/packages/packag...ravel-debugbar

----------


## imohammad

چجوری میشه پکیج ساخت و منتشرش کرد؟

----------


## hamedarian2009

> چجوری میشه پکیج ساخت و منتشرش کرد؟


اینجارو بخونید
http://prosperotemuyiwa.com/2015/05/...vel-5-package/

----------


## relaxdevil

خیلی عالی استاد
من می خوام یه برنامه سمپل ساده بنویسم به عنوان تمرین
که سایت 2 زبانه پیاده کنم
تمرینی که تو ذهنمه اینه
یه سایت داریم که تو جدول دیتابیسش
فیلدهای زیرو داریم 
1-id
2-titel_fa
3-titel_en
4-bodyNews_fa
5-bodyNews_en
میخوام اطلاعات و تویه یک صفحه نشون بدم و 2تا لینک بزارم(برای تعین زبان) بازدن لینکها همون صفحه منوها و چیزهای ثابت سایت فارسی بشه و اطلاعات خونده شده از دیتا بیس هم به اون زبان در بیاد 
میشه این تمرینو انجام بدید چون شنیدم دو زبانه کردن تویه لارول خیلی خوبه
من سعی میکنم انجامش بدم

----------


## hamedarian2009

بله چند زبانه کردن در لاراول خیلی ساده است و سعی میکنم فردا آموزشی در این زمنیه بزارم
آموزش ها دیگه تموم شده و ازین ببعد با توجه به پرسش های دوستان مطالبی رو تهیه و در این تاپیک قرار میدهم اگر هم دوستانی از بخش های قبلی بخشی را متوجه نشدن مطرح کنند تا بیشتر توضیح بدم به بقیه دوستان هم پیشنهاد میکنم یک پروژه تمرینی ساده رو انجام بدن چون تمرین است که باعث یادگیری خواهد شد نه فقط خواندن آموزشها

----------


## tresa022

سلام اگه میشه نقش های کاربری رو بیشتر توضیح بدید ؟مثلا علاوه بر guest ,manager چند نوع کاربر دیگه هم داشته باشیم چطر از اکستنشن یا وخودمون انجام بدیم؟ چه راه و روشی پیشنهاد میکنید؟خودتون چی استفاده میکنید؟

----------


## hamedarian2009

*چند زبانه کردن برنامه 
*
به طور پیش فرض در مسیر resources/lang یک پوشه به نام en وجود دارد که فایل های زبانی انگلیسی در آن قرار دارند. برای چند زبانی کردن کافی است به ازای هرتعداد زبان یک پوشه ایجاد کرده و دقیقا فایل های موجود در پوشه en را در آن هم کپی کنیم. هر فایل زبانی یک آرایه را return میکند که اندیس ها در همه فایل ها باید به انگلیسی باشند اما مقادیر آنها باتوجه زبان موردنظر مقداردهی می شوند. ما در این مثال قصد داریم یک برنامه  ساده دوزبانه فارسی و انگلیسی را پیاده سازی کنیم پس با من همراه باشید. 
ابتدا دوتا پوشه fa و en در پوشه resources/lang ایجاد کنید و فایل messages.php را ایجاد کنید به این صورت :

/resources
    /lang
        /en
            messages.php
        /fa
            messages.php

محتویات فایل های messages.php را هم به این صورت تغییر دهید :

//برای فایل انگلیسی
<?php

return [
    'welcome' => 'Welcome to our application',
    'text'     =>     'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
                tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
                quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
                consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
                cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
                proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
];

//برای فایل فارسی

return [
    'welcome' => 'به برنامه ما خوش آمدید',
    'text'    => '

لورم ایپسوم یا طرح‌نما (به انگلیسی: Lorem ipsum) به متنی آزمایشی و بی‌معنی در صنعت چاپ، صفحه‌آرایی 
و طراحی گرافیک گفته می‌شود. طراح گرافیک از این متن به عنوان عنصری از ترکیب بندی برای پر کردن صفحه
 و ارایه اولیه شکل ظاهری و کلی طرح سفارش گرفته شده استفاده می نماید، تا از نظر گرافیکی نشانگر
 چگونگی نوع و اندازه فونت و ظاهر متن باشد. معمولا طراحان گرافیک برای صفحه‌آرایی، نخست از متن‌های
  آزمایشی و بی‌معنی استفاده می‌کنند تا صرفا به مشتری یا صاحب کار خود نشان دهند که صفحه طراحی یا
   صفحه بندی شده بعد از اینکه متن در آن قرار گیرد چگونه به نظر می‌رسد و قلم‌ها و اندازه‌بندی‌ها
    چگونه در نظر گرفته شده‌است. از آنجایی که طراحان عموما نویسنده متن نیستند و وظیفه رعایت حق 
    تکثیر متون را ندارند و در همان حال کار آنها به نوعی وابسته به متن می‌باشد آنها با استفاده 
    از محتویات ساختگی، صفحه گرافیکی خود را صفحه‌آرایی می‌کنند تا مرحله طراحی و صفحه‌بندی را به 
    پایان برند.',
 ];

حالا یک فایل view به نام test.blade.php هم ایجاد کنید و کدهای زیر را در آن قرار دهید :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Multi Languages-Hamo</title>
</head>
<body>

    <a href="{{ url('/language') }}">{{ Session::get('locale', 'fa') == 'fa' ? 'English' : 'فارسی' }}</a>
    <h1>{{ trans('messages.welcome') }}</h1>
    <p>{{ trans('messages.text') }}</p>

</body>
</html>

با استفاده از تابع کمکی trans متن موردنظرمان را چاپ میکنیم. مقداری که این تابع میگرد به این صورت است که ابتدا نام فایل بعد یک نقطه و سپس اندیس آرایه را به آن میدهیم و مقدار ان براساس locale برنامه چاپ می شود مثلا اگر زبان برنامه fa باشد welcome و text فارسی وگرنه انگلیسی نمایش داده خواهد شد. یک لینک هم برای تغییر زبان تعریف کردم که با یک سشن به نام locale که جلوتر تعریف میکنیم  زبان جاری را در آن قرار می دهیم و مقدار لینک بر اساس نوع زبان جاری تعیین می شود مثلا اگر زبان فارسی بود لینک زبان انگلیسی نمایش داده می شود و بالعکس این لینک را میتوانید در منوی وبسایت و در قالب اصلی آن قراردهید که بستگی به سلیقه خودتان دارد. این لینک به مسیر language هدایت میشود پس مسیر را در فایل routes.php تعریف میکنیم :

//language
Route::get('/language', 'WelcomeController@language');
 
مسیر را به کنترلر WelcomeController و اکشن language ارسال کردیم. پس اکشن language را در کلاس کنترلر موردنظر ایجاد میکنیم :

public function language(ChangeLocaleCommand $ChangeLocaleCommand)
    {
        $this->dispatch($ChangeLocaleCommand);
        return redirect()->back();
    }


همانطور که می بینید از یک کلاس command استفاده کردیم که در این کلاس نوع زبان را در سشن تغییر می دهیم. یادتان باشد برای استفاده از هرکلاسی در کنترلر باید ابتدا آن را با namespace آن ایمپورت کنید پس ایتدای کلاس این عبارت را ااضفه کنید :

use App\Commands\ChangeLocaleCommand;

  اکنون با دستور زیر کلاس ChangeLocaleCommand را ایجاد کنید :

php artisan make:command ChangeLocaleCommand


 در مسیر app/commands کلاس ایجاد شده را باز کنید و متد handle را به این صورت تغییر دهید :

<?php namespace App\Commands;

use App\Commands\Command;

use Illuminate\Contracts\Bus\SelfHandling;

class ChangeLocaleCommand extends Command implements SelfHandling {

    /**
     * Execute the command.
     *
     * @return void
     */
    public function handle()
    {
        session()->set('locale', session('locale') == 'fa' ? 'en' : 'fa');
    }

}


همانطور که می بینید در کلاس بالا مقدار سشن اگر fa بود به en یا بالعکس تغییر میدهیم.

حالا باید یک کلاس command دیگر برای ست کردن locale برنامه ایجاد کنیم پس با دستور زیر آن را ایجاد میکنیم :

php artisan make:command SetLocaleCommand

حالا فایل آن را بازکنید و به این صورت تغییر دهید :

<?php namespace App\Commands;

use App\Commands\Command;
use Request;
use Illuminate\Contracts\Bus\SelfHandling;

class SetLocaleCommand extends Command implements SelfHandling {

    /**
     * The availables languages.
     *
     * @array $languages
     */
    protected $languages = ['en','fa'];

    /**
     * Execute the command.
     *
     * @return void
     */
    public function handle()
    {
        if(!session()->has('locale'))
        {
            session()->put('locale', Request::getPreferredLanguage($this->languages));
        }

        app()->setLocale(session('locale'));
    }

}



 همانطور که مشاهده میکنید در کلاس بالا locale برنامه را با توجه مقدار سشن تغییر می دهیم اگر مقدار سشن fa بود پس locale برنامه هم fa و یا بالعکس شود. در صورتی که سشن ست نشده بود با استفاده از متد getPreferredLanguage و پراپرتی languages که زبان های موردنظرمان را در ان ست کردیم آن را مقداردهی میکنیم.

حالا بایستی از این کلاس command استفاده کنیم پس یک middleware هم در مسیر app/Http/Middleware به نام App ایجاد میکنیم با دستور زیر :
php artisan make:middleware App

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

<?php namespace App\Http\Middleware;

use Closure;

use App\Commands\SetLocaleCommand;

use Illuminate\Bus\Dispatcher as BusDispatcher;

class App {

    /**
     * The command bus.
     *
     * @array $bus
     */
    protected $bus;

    /**
     * The command bus.
     *
     * @array $bus
     */
    protected $setLocaleCommand;

    /**
     * Create a new App instance.
     *
     * @param  Illuminate\Bus\Dispatcher $bus
     * @param  App\Commands\SetLocaleCommand $setLocaleCommand
     * @return void
    */
    public function __construct(
        BusDispatcher $bus,
        SetLocaleCommand $setLocaleCommand)
    {
        $this->bus = $bus;
        $this->setLocaleCommand = $setLocaleCommand;
    }

    /**
     * Handle an incoming request.
     *
     * @param  Illuminate\Http\Request  $request
     * @param  Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $this->bus->dispatch($this->setLocaleCommand);

        return $next($request);
    }

}


در سازنده کلاس دوتا پراپرتی bus$  و  setLocalCommand$ را با نمونه از کلاس های BusDispatcher و SetLocaleCommand مقداردهی کردیم و در متد handle کلاس SetLocaleCommand را برای اجرای فرمان به bus  میدهیم. 
در پایان باید این middleware را به فریمورک معرفی کنیم همانظور که در بخش موردنظرش هم توضیح دادم چون میخواهم این middleware عمومی باشد و در کل برنامه اجرا شود پس در فایل Kernel.php در مسیر app/Http به پراپرتی middleware$ که مقدارش آرایه است این middleware را هم اضافه کنید.

    protected $middleware = [
        'Illuminate\Foundation\Http\Middleware\CheckForMai  ntenanceMode',
        'Illuminate\Cookie\Middleware\EncryptCookies',
        'Illuminate\Cookie\Middleware\AddQueuedCookiesToRe  sponse',
        'Illuminate\Session\Middleware\StartSession',
        'Illuminate\View\Middleware\ShareErrorsFromSession  ',
        'App\Http\Middleware\VerifyCsrfToken',
        'App\Http\Middleware\App',
    ];


اگر فایل test.blade.php را رندر کنید  به راحتی با کلیک کردن بر لینک تغییر زبان می توانید زبان برنامه را تغییر دهید. امیدوارم که مطلب برایتان مفید باشد.

----------


## hamedarian2009

> سلام اگه میشه نقش های کاربری رو بیشتر توضیح بدید ؟مثلا علاوه بر guest ,manager چند نوع کاربر دیگه هم داشته باشیم چطر از اکستنشن یا وخودمون انجام بدیم؟ چه راه و روشی پیشنهاد میکنید؟خودتون چی استفاده میکنید؟


ببینید دوست گرامی هر امکاناتی که میخواهید به برنامه تان اضافه کنید بهتره اول سرچ بکنید ببینید آیا پکیج مناسب کارتون وجود داره یا نه که در 95 درصد موارد هم وجود داره شما از فریمورک استفاده میکنید تا نیازی به نوشتن کدهای تکراری نداشته باشید برای ایجاد نقش هم توی همین بخش لاراول یکی از کاربران یکیشو معرفی کرد این لینکو ببینید
https://github.com/Zizaco/entrust/tree/laravel-5

----------


## moalla

احسنت به همت شما
اگر امکان داره در مورد استفاده از ایجکس بفرمایید

----------


## hamedarian2009

*مثالی کاربردی از AJAX در لاراول*

امروز با توجه به درخواست یکی از  دوستان یک مثال کاربردی با AJAX را کار خواهیم کرد. برای کار با AJAX شما  ابتدا باید با جاوااسکریپت و یا یکی از کتابخانه های جاوااسکریپت آشنایی  داشته باشید. من در  این مثال از jQuery برای کار با AJAX استفاده میکنم.
ابتدا دوتا route در فایل routes.php ایجاد میکنیم :

Route::get('ajax-form', 'WelcomeController@ajaxForm');
Route::post('ajax-form', 'WelcomeController@postAjaxForm');


داخل  کلاس WelcomeController متدهای ajaxForm برای درخواست های GET و متد  postAjaxForm را برای درخواست های POST ایجاد میکنیم. متد ajaxForm فرم را  به این صورت می نویسیم :

public function ajaxForm()
    {
        return  view('ajax');
    }

حالا یک فایل ویو به نام ajax.blade.php در مسیر resources/views ایجاد میکنیم و کدهای زیر را در آن قرار دهید :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>AJAX Example</title>
    <style type="text/css">
        .error {
            color: red;
            font-weight: bold;
        }

        .success {
            color: green;
            font-weight: bold;
        }
    </style>
</head>
<body>
<form action="{{ url('/ajax-form') }}" method="post" id="form1">
    <input type="hidden" name="_token" value="{{ csrf_token() }}">
    Your Name:<input type="text" name="name"> <span class="error" id="name"></span> <br>
    Your Email:<input type="text" name="email"> <span class="error" id="email"></span> <br>
    Your Website:<input type="text" name="website"> <span class="error" id="website"></span><br>
    <input type="submit" value="Submit">
</form>    
<div id="results" class="success"></div>

<script src="{{ asset('js/jquery.js') }}"></script>
<script type="text/javascript">
    $(document).ready(function (){
        $("#form1").submit(function (event){
            event.preventDefault();
            var $this = $(this);
            var url = $this.attr('action');

            $.ajax({
                url: url,
                type: 'POST',
                dataType: 'JSON',
                data: $this.serialize(),
            })
            .done(function( response ) {
                $('span').empty();
                $("div#results").empty();
                $.each(response, function(index, val) {
                     /* iterate through array or object */
                     switch(index){
                         case "name":
                             $('span#name').html(val);
                             break;
                         case "email":
                             $("span#email").html(val);
                            break;
                        case "website":
                             $("span#website").html(val);
                            break;
                        case "success":
                            $("div#results").html(val);
                            break;                      
                     }
                });
            })
            .fail(function() {
                 console.log('error');
            });

        });
    });
</script>
</body>
</html>


همانطور که مشاهده می کنید ابتدا در css دوتا کلاس error و sucess برای نمایش زیباتر پاسخ و پیغام های خطا تعریف کردم. فرم موردنظرمان را ایجاد کردیم و کتابخانه جی کوئری را به صفحه ضمیمه کرده و در نهایت کد  AJAX را نوشتم . در کد ای جکس متد درخواست یا همون پارامتر type رو POST قراردادم و همچنین نوع داده ای که می خواهیم دریافت کنیم رو JSON گزاشتم چون قرار است پاسخ ما از نوع json باشد. url آن راهم به صورت داینامیک نعریف کردم و از خصوصیت action فرم گرفتم که شما می توانید به صورت دستی هم مقدار بدهید چون من میخواهم این کد ای جکسم قابل استفاده مجدد در هرپروژه دیگر باشد اینکار را کردم. همه داده های فرم راهم به صورت سریالایز فرستادم که بازهم شما می توانید به صورت دستی اینکار را بکنید. متد done هم اگر درخواست ای جکس با موفقیت به پایان برسد پاسخ دریافتی رو دریافت میکنیم و متد fail هم در صورتی که کد ای جکس دارای خطا باشد عملیات موردنظرمان را در آن می نویسیم.

قبل اینکه کدهای داخل متد done رو توضیح بدم بریم اکشن postAjaxForm در کنترلر WelcomeController رو مشاهده کنیم :

   public function postAjaxForm(Request $request)
    {
        if($request->ajax()){
            //validation 
            $rules = [
                'name' => 'required|min:3|max:100',
                'email' => 'required|email',
                'website' => 'url'
            ];

            $v = Validator::make($request->all(), $rules);
            if($v->fails()){
                return Response::json($v->errors());
            } else {
                $html = '<p>Your name: '. $request->input('name') .'</p>';
                $html .= '<p>Your email: '. $request->input('email') .'</p>';
                $html .= '<p>Your website: '. $request->input('website') .'</p>';
                return Response::json(['success'=> $html]);
            }
        } else {
            return 'Request invalid!';
        }
    }


ابتدا بررسی کردیم اگر نوع درخواست ajax بود ادامه کار را انجام دهیم و سپس داده های فرم را اعتبارسنجی کردیم و اگر اعتبار سنجی دارای خطا بود خطا ها را با استفاده از کلاس Response و متد json به صورت JSON تولید میکنیم. خطاها را به عنوان آرگومان به این متد می دهیم. اندیس ها نام فیلد فرم و مقدار آن پیغام خطای مورد نظر است.
در صورتی که اعتبارسنجی بدون خطا باشد یک پاسخ در قالب json برای تست ایجاد کردم به این صورت که آرایه ای که به متد json دادم اندیس آن را success قرار دادم که به این اندیس ها در کد ای جکس نیاز پیدا میکنیم.
حالا یکبار دیگه داخل کد AJAX متد done رو نگاه کنید :

.done(function( response ) {
                $('span').empty();
                $("div#results").empty();                 
                $.each(response, function(index, val) {
                     /* iterate through array or object */
                     switch(index){
                         case "name":
                             $('span#name').html(val);
                             break;
                         case "email":
                             $("span#email").html(val);
                            break;
                        case "website":
                             $("span#website").html(val);
                            break;
                        case "success":
                            $("div#results").html(val);
                            break;                      
                     }
                });
            })

همانطور که می بینید response ای که دریافت کردیم را به راحتی میتوانیم مدیریت کنیم. ابتدا مقدار span ها و تگ با آیدی results را در هربار که درخواست ای جکس ارسال میکنیم خالی میکنیم تا پیغام های  درخواست قبلی پاک شوند سپس همانند دستور foreach در php با استفاده از دستور each می توانیم به اندیس ها و مقادیر هر آیتم دسترسی داشته باشیم. من در این مثال از switch استفاده کردم تا هر اندیسی که به عنوان پاسخ برایمان ارسال شده را در جای مناسب خودش نمایش بدهم. index همان اندیس مورنظرمان و val هم مقدار آن می باشد.

بعضی مواقع شما درخواست های ای جکس را بدون استفاده از فرم ارسال میکنید در نتیجه چون توکنی ارسال نمیکنید middleware عمومی که توکن را بررسی میکند درخواست را reject میکند برای حل این مشکل کافی است توکن را مثلا در تگ meta تولید کرده سپس و با استفاده از ajaxSetup توکن را به هدر اضافه کنید:


```
<meta name="csrf-token" content="{{ csrf_token() }}" />

$.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });
```

برای درک بیشتر همانطور که گفتم باید با جاوااسکریپت و جی کوئری آشنایی نسبی داشته باشید. امیدورام که این مثال هم برایتان مفید باشد.

----------


## hamedarian2009

*کار با کلاس های Html و Form*
دو تا کلاس در لاراول ۴ بودند که کار رو برای نوشتن کدهای تکراری HTML برایمان آسان تر میکردن که در لاراول ۵ به طور پیش فرض وجود ندارد و باید به آن اضافه کنیم. چون در خیلی از مثال های موجود در وب از این کلاس ها استفاده شده لازم دیدم این کلاس ها را معرفی کنم. ابتدا نحوه افزودن آن به لاراول ۵ رو توضیح میدم.
در پوشه اصلی لاراول ۵ یک فایل به نام composer.json را باز کرده و خط "illuminate/html": "5.*" به بخش *require* اضافه کنید به این صورت :

"require": {
        "illuminate/html": "5.*",
        "laravel/framework": "5.0.*"
    },
سپس در ترمینال به پوشه پروژه خود رفته و دستور زیر را اجرا کنید :

composer update

سپس فایل app.php در پوشه config را باز کنید و به انتهای آرایه providers مقدار 'Illuminate\Html\HtmlServiceProvider' را اضافه کنید به این صورت :

'providers' => [
   /* more already here */
   'Illuminate\Html\HtmlServiceProvider',

همچنین دو خط زیر را هم به انتهای آرایه aliases اضافه کنید به این صورت :

'aliases' => [
   /* more already here */
    'Html' => 'Illuminate\Html\HtmlFacade',
    'Form' => 'Illuminate\Html\FormFacade',
 ],
اکنون می توانید از این کلاس ها در برنامه خودتان در view ها استفاده کنید. از هرکدام چند تا از کاربردی هایش را مثال خواهم زد.

*کلاس Html*
ایجاد تگ script: از متد script استفاده میکنید و پارامتر اولی مسیر اسکریپت و پارامتر دوم هم که  به صورت آرایه هست شامل attribute های تگ می باشد 

{!! Html::script('js/jquery.js', ['type' => 'text/javascript']) !!}
//output: <script type="text/javascript" src="http://laravel.dev/js/jquery.js"></script> 


ایجاد تگ link : مشابه دستور بالا است و تگ لینک را ایجاد میکند

{!! Html::style('css/style.css') !!}
//output:  <link media="all" type="text/css" rel="stylesheet" href="http://laravel.dev/css/style.css"> 


ایجاد تگ image : با استفاده از متد image و پارامتر اول مسیر تصویر و پارامتر دوم متن جایگزین و پارامتر سوم هم attribute ها می باشند.

{!! Html::image('images/1.jpg' , 'alternate', ['class' => 'img'])!!}
//output:  <img src="http://laravel.dev/images/1.jpg" class="img" alt="alternate"> 


ایجاد تگ a : با استفاده از متد link و پارامتر اول url مورد نظر و پارامتر دوم عنوان تگ که اگر null قرار دهیم همان url عنوان در نظر گرفته می شود و پارامتر سوم هم attribute های تگ می باشند.

{!! Html::link('user/profile', 'Go User Profile', ['calss' => 'btn btn-primary']) !!}
//output: <a href="http://laravel.dev/user/profile" calss="btn btn-primary">Go User Profile</a>  


ایجاد تگ ul: با استفاده از متد ul و پارامتر اول آرایه ای از لیست ها و پارامتر دوم هم آرایه ای از attribute ها می باشد.

{!! Html::ul(['Item1', 'Item2', 'Item3'], ['calss' => 'nav']) !!}
//output:  <ul calss="nav"><li>Item1</li><li>Item2</li><li>Item3</li></ul>  

برای آشنایی با سایر متدها به اینجا مراجعه کنید

*کلاس Form*
ایجاد تگ شروع و پایان form : با استفاده از متد open و یک پارامتر آرایه ای میگیرد که attribute ها را در آن ست میکنیم. url همان اکشن فرم را مقداردهی میکند و همچنین files اگر true قرار دهیم فرم برای آپلود فایل مناسب می باشد. این متد فیلد توکن را هم ایجاد میکند. متد close هم تگ فرم را می بندد.

{!! Form::open(['url' => 'conatct', 'id'=>'form1', 'files'=> true]) !!}
//output:  <form method="POST" action="http://laravel.dev/conatct" accept-charset="UTF-8" id="form1" enctype="multipart/form-data"><input name="_token" type="hidden" value="FzsNKPfXXLbuD1YoMCfgJXbEsYW7Z2CTAohEyiG0">

{!! Form::close() !!}


ایجاد تگ label و input از نوع text : در متد label پارامتر اول نام فیلدی است که میخواهیم برای آن لیبل تعریف کنیم و پارامتر دوم مقدار لیبل است و پارامتر سوم هم آرایه ای از attribute ها می باشد. در صورتی که خصوصیت id برای فیلد متناظر تگ label تعریف نکرده باشیم به طور خودکار  id با مقدار هم نام با فیلد input متناظرش ایجاد خواهد کرد. در متد text هم یک input از نوع text ایجاد کرده که پارامتر اول آن نام آن و پارامتر دوم مقدار آن و پارامتر سوم هم آرایه ای از attribute ها  می باشد.

{!! Form::label('name', 'Your Name', ['class' => 'label']) !!}
//output: <label class="label" for="name">Your Name</label>
{!! Form::text('name', null, ['calss' => 'test']) !!}
//output: <input id="name" type="text" name="name" calss="test">

نحوه تعریف متدهای hidden, email, url, textarea, number هم مشابه متد text می باشد.

ایجاد input از نوع file : پارامتر اول آن نام فیلد و پارامتر دوم هم آرایه ای از attribute ها است.

{!! Form::file('photo') !!}
//output: <input type="file" name="photo">


ایجاد input از نوع submit: پارامتر اول آن مقدار فیلد و پارامتر دوم آرایه ای از attribute ها است.

{!! Form::submit('Register' , ['calss' => 'btn btn-primary']) !!}
//output: <input type="submit" value="Register" calss="btn btn-primary">

برای اطلاعات بیشتر  و آشنایی با سایر متدها به اینجا مراجعه کنید

----------


## MeSaeid

سلام
میشه در رابطه با قسمت لاگین و رجیستر لاراول 5 یه کم توضیح بدین 
.../Http/Controllers/Auth
و قسمت روتش

Route::controllers([
   'auth' => 'Auth\AuthController',
   'password' => 'Auth\PasswordController',
]);

----------


## hamedarian2009

> سلام
> میشه در رابطه با قسمت لاگین و رجیستر لاراول 5 یه کم توضیح بدین 
> .../Http/Controllers/Auth
> و قسمت روتش
> 
> Route::controllers([
>    'auth' => 'Auth\AuthController',
>    'password' => 'Auth\PasswordController',
> ]);


تو بخش کنترلرها گفتم که یک نوع routing در لاراول داریم که تلویجی یا ضمنی هست به اینجا نگاه کنید 

Route::controller('users', 'UserController');

//کلاس کنترلر
class UserController extends BaseController {

    public function getIndex()
    {
        //
    }

    public function postProfile()
    {
        //
    }

    public function anyLogin()
    {
        //
    }

}

هنگام تعریف route فقط مسیر و نام کنترلر رو بهش میدیم و بعد اکشن هایی که تعریف میکنیم کافیه با توجه به نوع درخواست http ای که می خواهیم قبول کنند مثل get , post, any , ... اونو پیشوند نام اکشن قرار میدیم به طور مثال آدرس http://example.com/users/login همه نوع درخواستی رو قبول میکنه چون پیشوند any براش گزاشتیم. خب تا اینجا که مشکلی نیست؟

حالا اگه بخواهیم چندتا route به صورت بالا تعریف کنیم دیگه نیازی نیست هربار بیایم اون کدو تکرار کنیم بلکه از متد controllers به جای controller استفاده میکنیم و مسیر ها رو داخل آرایه قرار میدیم

کنترلر های AuthController و PasswordController هم دقیقا اکشن هاش به همین صورت تعریف میشن مثلا getLogin یا postRegister , ...
وقتی هم url را به این صورت می نویسیم میبینیم http://example.com/auth/login اکشن getLogin فراخوانی میشه
منتها لاراول قبلا اومده اینهارو توی یک trait در مسیر Illuminate\Foundation\Auth\AuthenticatesAndRegiste  rsUsers پیاده سازی کرده اما اگه بخواهیم تو اکشن ها تغییری بدیم کافیه تو همون کنترلر خودش اکشن رو دوباره بازنویسی کنیم و کدهای خودمون رو داخلش بنویسیم مثلا ببین من متد getLogin رو توی کلاس AuthController بازنویسی کردم:

public function getLogin()
{
        return view('site.login');
}

فایل ویو رو که از پوشه auth/login.blade.php رندر میشه رو به مسیر site/login.blade.php در پوشه views تغییر دادم. 
فکرکنم توضیحات کامله دیگه قسمت لاگین و رجیستر  میخواهید دقیقا کجاشو توضیح بدم؟

----------


## MeSaeid

> فکرکنم توضیحات کامله دیگه قسمت لاگین و رجیستر  میخواهید دقیقا کجاشو توضیح بدم؟


ممنون از شما بسیار کامل,  فقط میشه در مورد این قسمت یکم توضیح بدین

public function __construct(Guard $auth, Registrar $registrar)
{
   $this->auth = $auth;
   $this->registrar = $registrar;

   $this->middleware('guest', ['except' => 'getLogout']);
}

----------


## hamedarian2009

> ممنون از شما بسیار کامل,  فقط میشه در مورد این قسمت یکم توضیح بدین
> 
> public function __construct(Guard $auth, Registrar $registrar)
> {
>    $this->auth = $auth;
>    $this->registrar = $registrar;
> 
>    $this->middleware('guest', ['except' => 'getLogout']);
> }


از trait ای به نام AuthenticatesAndRegistersUsers توی کنترلر استفاده شده که دوتا پراپرتی داره به روش type-hint اومده  دوتا نمونه از رابط های Guard و Registrar ایجاد کرده و به این دو پراپرتی داده تا توی برنامه از متداشون استفاده بشه. Guard برای عملیات های مربوط به لاگین و Registrar برای ثبت نام کاربر پیاده شده.

سومی هم که یک middleware ای تعریف شده به نام guest که درخواست های ورودی به کنترلر AuthController رو فیلتر میکنه که این middleware درمسیر app\Http\Middleware به نام RedirectIfAuthenticated  می باشد که میاد هردرخواستی رو اگه کاربر لاگین کرده بود ریدایرکت میکنه به صفحه شخصی کاربر هدایت میکنه مثلا اگه کاربری لاگین باشه دیگه صفحه http://example.com/auth/login براش باز نمیشه و میره به صفحه home . اون except هم که میگه این middleware به همه اکشن ها اعمال بشه به جز اکشن getLogout

----------


## MeSaeid

سلام 
برای نماش Title و آپشن های دیگه توی ویو باید اطلاعات رو زمانی که قالب رو رندر می کنیم بش بدیم خب این کار خسته کننده ای هست که برای نمایش هر ویو این همه اطلاعات رو بنویسیم 
چه راهی پیشنهاد می کنید ؟ خب من میخواستم اطلاعات مربوط به سایت رو از دیتابیس بخونم بعد تو یک آرایه Options$ بفرستم .

----------


## hamedarian2009

توی پست مربوط به blade هم گفتم دیگه شما یه قالب تعریف کنید و بخش هایی که تو همه صفحات تکرار میشه رو اونجا یکبار بنویسید و فقط بخش هایی که تو هر صفحه محتویات متفاوتی خواهد داشت رو براش yield تعریف کنید مثلا فرض کن تو پوشه resources/views/layouts یک فایل به نام master.blade.php ایجاد کنیم به این صورت :


```
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>@yield('title', 'Blog Title')</title>
    <link rel="stylesheet" type="text/css" href="{{ asset('css/style.css') }}">
    @yield('head')
</head>
<body>
    <div class="container">
        @yield('content')
    </div>

    <script type="text/javascript" src="{{ asset('js/jquery.js') }}"></script>

    @yield('js')
</body>
</html>
```

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


```
@extends('layouts.master')

@section('title', 'Home')

@section('content')
    <p>new content</p>
    <p class="test"></p>
@stop

@section('js')
    <script type="text/javascript">
        document.getElementsByClassName("test").innerHTML = "another content";
    </script>
@stop
```

چیز تکراری دیگه نداریم که هربار بخواهید بنویسید نیازی به دیتابیس هم نیست

----------


## MeSaeid

> توی پست مربوط به blade هم گفتم دیگه شما یه قالب تعریف کنید و بخش هایی که تو همه صفحات تکرار میشه رو اونجا یکبار بنویسید و فقط بخش هایی که تو هر صفحه محتویات متفاوتی خواهد داشت رو براش yield تعریف کنید مثلا فرض کن تو پوشه resources/views/layouts یک فایل به نام master.blade.php ایجاد کنیم به این صورت :
> 
> 
> ```
> <!DOCTYPE html>
> <html lang="en">
> <head>
>     <meta charset="UTF-8">
>     <title>@yield('title', 'Blog Title')</title>
> ...


ممنون از شما
فرض کنید یوزر بخواد عنوان سایت رو تغییر بده ( از پنل ) یا مثلا یک سری اطلاعات مربوط به آمار سایت  ( که در تمام قسمت های سایت وجود داره )و از این چیزا بخواد لود بشه اینها تغییر می کنن و نمیشه از این روش رفت 
بنده میخوام یه سری اطلاعات بدون اینکه من به ویو بدم خودش لود کنه مثل از این چیزا که گفتم

----------


## hamedarian2009

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

----------


## MeSaeid

> هرچیزی میخواد توی همه صفحات نشون داده بشه اعم از امار سایت و ... تو قالب اصلی و هرچیزی که تو هر صفحه جدیده توی همون view قرار میگیره  حالا میخاد از دیتابیس خونده بشه یا هرجای دیگه اون بستگی به برنامتون داره هدف اینه که شما دیگه هربار داده تکراری به ویو نفرستین


بله حرف شما درسته 
بنده دنبال اینها بودم View Composers و View Share که مشکلم حل شد

----------


## MeSaeid

سلام
میشه در رابطه با Scheduling یه کم توضح بدین مثلا 
$schedule->call(function() {
    // Do stuff
})->everyFiveMinutes();
خب چطور این رو فعال کنیم ؟ php artisan schedule:run این دستور رو اجرا کردم ولی گفت چیزی برای اجرا شدن پیدا نشد

----------


## hamedarian2009

> سلام
> میشه در رابطه با Scheduling یه کم توضح بدین مثلا 
> $schedule->call(function() {
>     // Do stuff
> })->everyFiveMinutes();
> خب چطور این رو فعال کنیم ؟ php artisan schedule:run این دستور رو اجرا کردم ولی گفت چیزی برای اجرا شدن پیدا نشد


تو این چیزی ننوشتید که بخواد اجرا بشه 

مواقعی هست که می خواهید  یک دستور در زمان های مشخصی به طور اتوماتیک اجرا شود با استفاده از command scheduler این کار رو به راحتی میتونید انجام دهید. برای اینکار کافیه توی مسیر app/Console فایل Kernel.php را باز کنید و داخل متد schedule دستور مورد نظرتون رو بنویسید. مثلا در مثالی که اشاره کنید میتونید به طور مستقیم یک عملیاتی را داخل closure تعریف کنید و متد بعدی آن هم برنامه زمانی اجرای آن را مشخص میکند که در مثالی که ذکر کردین هر ۵ ذقیقه یک بار است. به چندتا مثال زیر توجه کنید:
protected function schedule(Schedule $schedule)
    {
        $schedule->command('inspire')->hourly();
        
        $schedule->command('cache:clear')->hourly();
                    
        $schedule->call(function()
        {
            \DB::delete("DELETE * FROM accounts WHERE expire = ?", [0]);

        })->dailyAt('24:00');
    }


از آخر توضیح میدم ببینید  به متد call یک closure یا تابع بی نام  داده ایم که به طور مستقیم یک دستور SQL رو نوشتم که هر روز سر ساعت 24:00 میاد و حساب های کاربری که  انقضا آنها صفر شده است را حذف میکند

در مثال وسطی به متد cammand میشه یک فرمان CLI یا همون Artisan Command Line که وجود داره رو به طور مستقیم بهش داد که در اینجا دستور clear:cache رو بهش دادیم و گفتیم که هر یک ساعت یکبار cache رو پاک کند

همچنین می توانیم یک فرمان جدید Artisan ایجاد کنیم مثال اولی هم یک فرمان جدید Artisan رو به نام inspire ایجاد کرده و ابتدا آن را  به پراپرتی commands$ که یک آرایه هست اضافه کرده و سپس در متد schedule از آن استفاده کرده. کلاس این فرمان در مسیر app/Console/Commands قرار دارد.
protected $commands = [
        'App\Console\Commands\Inspire',
    ];
فرمان inspire که به صورت php artisan inspire در ترمینال قابل اجرا هست هم هر یک ساعت یکبار اجرا خواهد شد. در صورتی که میخواهید با نحوه ایجاد یک فرمان Artisan آشنا شوید این لینک خیلی واضح توضیح داده است

در انتها اگر دستور زیر را به cron job هاست خود بدهید هر یک دقیقه یک بار این دستور را اجرا میکند و اگر job ای وجود داشت اجرا میکند 
* * * * * php /var/www/html/laravel/artisan schedule:run 1>> /dev/null 2>&1
دقت کنید بعد از دستور php باید مسیر فیزیکی فابل artisan که در پوشه اصلی فریمورک قرار داره رو بنویسید

همچنین اینجا فقط دوتا متد hourly و dailyAt  رو مثال زدم ولی کلی متد دیگه هم هست که در زیر براتون لیست میکنم و میتونید از هرکدوم استفاده کنید :

->hourly()
->daily()
->at($time) // 24 hour time
->dailyAt($time)
->twiceDaily()
->weekdays()
->mondays()
->tuesdays()
->wednesdays()
->thursdays()
->fridays()
->saturdays()
->sundays()
->weekly()
->weeklyOn($day, $time)
->monthly()
->yearly()
->everyFiveMinutes()
->everyTenMinutes()
->everyThirtyMinutes()
->days() // Days of the week

----------


## 1sarbaz

آقا حامد دستت درد نکنه بابت زحمتت.

ما اگر توی جدول چندین ارتباط one 2 one داشته باشیم یا حتی سایر ارتباطات فرض کنید من یک جدول محصولات .
و بعد این جدول با جداول 

تگ های کالا
دسته بندی های کالا
ویژگیهای کالا (دوربین فلان ، بلوتوث فلان ، اندروید فلان و ...)  
نوع کار ( رنگ و سایز ..)
جدول کاربران ( برای پیدا کردن نوسنده )
دیدگاهها و بررسی ها ی کاربران

و یا حتی چند مورد دیگه 

ارتباط داشته باشه برای هر جدول کوئری زده میشه دیگه درسته ، خوب اینها همه قراره توی یک صفحه نمایش داده بشه به نظر شما این خیلی سنگین نمیکنه کوئری ها رو و فشار نمیاره  ؟ راه اصولیش چیه ؟

آیا استاندارد و تعداد خاصی جدول مشخص رو باید برای ارتباطات به کار ببرم یا محدودیتی نداره ؟ چون ما اگر بخوایم نرمال کنیم جداولمون رو خود به خود جداولمون تعدادش بالا میره.

----------


## hamedarian2009

> آقا حامد دستت درد نکنه بابت زحمتت.
> 
> ما اگر توی جدول چندین ارتباط one 2 one داشته باشیم یا حتی سایر ارتباطات فرض کنید من یک جدول محصولات .
> و بعد این جدول با جداول 
> 
> تگ های کالا
> دسته بندی های کالا
> ویژگیهای کالا (دوربین فلان ، بلوتوث فلان ، اندروید فلان و ...)  
> نوع کار ( رنگ و سایز ..)
> ...


بهتر بود سوالتون رو در بخش دیتابیس می پرسیدید ولی خب اگه شما همه اینها رو در یک جدول هم به کار ببرید باعث افزونگی و آنومالی در دیتابیس خواهد شد و ناگزیر هستید حداقل تا سطح 3NF نرمالسازی را انجام دهید 
در کل این کوئری که استفاده میکنید باید بهینه ترین کوئری بسته به نتیجه ای که از آن انتظار دارید باشد که همه اینها نیاز به داشتن تجربه و تسلط به مباحث پایگاه داده می باشد

----------


## relaxdevil

سلام آقا حامد عزیز .ممنون از آموزشهای خوب و کامل شما
2 تا سوال دارم !
1-برای اینکه از بوت استرپ استفاده کنیم فایلهای بوت استرپ دانلود کردم از سایت بوت استرپ بریزیم تویه پوشه public ؟

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

----------


## hamedarian2009

> سلام آقا حامد عزیز .ممنون از آموزشهای خوب و کامل شما
> 2 تا سوال دارم !
> 1-برای اینکه از بوت استرپ استفاده کنیم فایلهای بوت استرپ دانلود کردم از سایت بوت استرپ بریزیم تویه پوشه public ؟
> 
> 2-میشه یه آموزش درباره کد کپچا بدی موقع لاگین کردن ؟ آیا لاراول برای کار با کدهای کپچا راه حل خاصی دارد یا نه ؟


1- میتونید فایل app.blade.css رو تو پوشه views بگیرید و برای قالب مستر خودتون ویرایش کنید این قالب به صورت بوت استرپ هست و فایل های مربوط به auth ازش استفاده کردن ولی در کل بله فایل های css و js و تصاویر رو تو پوشه public  قرار دهید و هنگام استفاده به این صورت هم آدرس دهی کنید:


```
<link rel="stylesheet" type="text/css" href="{{ asset('bootstrap/css/bootstrap.min.css') }}">
```

2- به طور پیش فرض لاراول هیچ کلاسی برای کپچا قرار نداده و باید بهش اضافه کنید که میتونید reCaptcha و botDetect و ... رو بهش اضافه کنید که حتما فردا یک آموزش در همین زمینه قرار خواهم داد.

----------


## hamedarian2009

*افزودن Captcha و کار با آن*

برای کار با کپچا شما می توانید از کپچاهای معروف زیادی همچون reCaptcha استفاده کنید اما من از یک کپچای خوب که کار با آن آسان است در این آموزش استفاده خواهم کرد. 
ابتدا با ترمنیال به مسیر پروژه لاراول بروید و دستور زیر را تایپ و اجرا کنید:
composer require mews/captcha

سپس در فایل config/app.php بخش providers خط زیر را به انتهای آن اضافه کنید :
        'Mews\Captcha\CaptchaServiceProvider',
همچنین خط زیر را هم به انتهای بخش aliases اضافه کنید :
'Captcha' => 'Mews\Captcha\Facades\Captcha',
در پایان هم دستور زیر را احرا کنید :
php artisan vendor:publish 

اکنون می توانیم از کپچا در فرم ها استفاده کنیم. با یک مثال کاربردی نحوه استفاده از آن را توضیح خواهم داد. طبق خواسته یکی از کاربران این مثال را در فرم لاگین انجام می دهم.
ابتدا فایل login.blade.php در مسیر resources/views/auth رو به این صورت ویرایش میکنیم :


```
<form class="form-horizontal" role="form" method="POST" action="{{ url('/auth/login') }}">
                        <input type="hidden" name="_token" value="{{ csrf_token() }}">

                        <div class="form-group">
                            <label class="col-md-4 control-label">E-Mail Address</label>
                            <div class="col-md-6">
                                <input type="email" class="form-control" name="email" value="{{ old('email') }}">
                            </div>
                        </div>

                        <div class="form-group">
                            <label class="col-md-4 control-label">Password</label>
                            <div class="col-md-6">
                                <input type="password" class="form-control" name="password">
                            </div>
                        </div>

                        <div class="form-group">
                            <label class="col-md-4 control-label">Captcha Code</label>
                            <div class="col-md-6">
                                {!! Captcha::img('flat') !!}
                                <input type="text" class="form-control" name="captcha">
                            </div>
                        </div>

                        <div class="form-group">
                            <div class="col-md-6 col-md-offset-4">
                                <div class="checkbox">
                                    <label>
                                        <input type="checkbox" name="remember"> Remember Me
                                    </label>
                                </div>
                            </div>
                        </div>

                        <div class="form-group">
                            <div class="col-md-6 col-md-offset-4">
                                <button type="submit" class="btn btn-primary">Login</button>

                                <a class="btn btn-link" href="{{ url('/password/email') }}">Forgot Your Password?</a>
                            </div>
                        </div>
                    </form>
```

همانطور که مشاهده می کنید با دستور Captcha::img('flat') تصویر کپچا نمایش داده می شود و من چون می خواستم ابعاد تصویر کمی بزرگتر باشد از flat استفاده کردم که می توانید در فایل config/captcha.php تنظیمات مربوط به ابعاد و رنگ ها را به دلخواه خودتان تغییر دهید.

حالا یک کلاس Request هم برای اعتبار سنجی با استفاده از دستور زیر ایجاد میکنیم:
php artisan make:request LoginRequest
قوانین اعتبار سنجی را در متد rules قرار می دهیم و متد authorize را هم true می کنیم چون نیازی به احراز هویت در این درخواست نمی باشد. کلاس LoginRequest در مسیر app/Http/Requests باید مشابه مثال زیر ویرایش شود :

<?php namespace App\Http\Requests;

use App\Http\Requests\Request;

class LoginRequest extends Request {

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'email'    => 'required|email',
            'password' => 'required|min:3|max:17',
            'captcha'  => 'required|captcha',
        ];
    }

}



همانطور که می بینید برای فیلد captcha یک قانون اعتبارسنجی جدید به نام captcha قرار دادیم که میاد ورودی کاربر را با کد داخل تصویر مطابقت میده و در صورتی که مغایرت داشته باشد خطایی صادر میکند. پس باید داخل مسیر resources/lang/en فایل validation.php را باز کنیم و برای آن یک پیغام مناسب ست میکنیم. پس خط زیر را به آن اضافه کنید :
"captcha"               => "The :attribute field entered is wrong",

در ادامه باید در کنترلر AuthController در مسیر app/Http/Controllers/Auth متد postLogin را بازنویسی کنیم. ابتدا به کنترلر  کلاس های زیر را ایمپورت می کنیم:

use App\Http\Requests\LoginRequest;
use Request;
use Auth;


حالا متد postLogin را به این صورت اضافه کنید :

public function postLogin(LoginRequest $request)
    {
        $credentials = Request::only('email', 'password');

        if(Auth::attempt($credentials)){

            return redirect()->intended('/home');

        } else {

            return redirect()->back()->withErrors(['invalid' => 'The username or email invalid!']);
        }
    }

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


```
 <img src="{{ asset('img/refresh.svg') }}" alt="refresh" id="refresh" width="50" height="50">
```

در انتها هم دستورات jquery  زیر را به صفحه اضافه کردم تا با هربار کلیک روی تصویر رفرش کپچا تغییر کند.

<script type="text/javascript">
    $('document').ready(function(){
        $('#refresh').click(function(){
            var src = "{{ Captcha::src() }}";
            var timestamp = new Date().getTime();
            $("img[alt=captcha]").attr("src", src + '?' +timestamp);
        });
    });
</script>


تصویر زیر نتیجه کار را نشان می دهد. امیدوارم که این مطلب هم برایتان مفید بوده باشد.
captcha.png

----------


## imohammad

ممنون از زحمتی که میکشی
خیلی عالیه
چجوری میشه rule های خودمون رو به validator اضافه کنیم؟ مثلا یه متد داریم که ساختار کد ملی رو چک میکنه و با true یا false جواب میده، اینو چطور میشه بعنوان rule شناسوند؟

----------


## hamedarian2009

> ممنون از زحمتی که میکشی
> خیلی عالیه
> چجوری میشه rule های خودمون رو به validator اضافه کنیم؟ مثلا یه متد داریم که ساختار کد ملی رو چک میکنه و با true یا false جواب میده، اینو چطور میشه بعنوان rule شناسوند؟


ببینید میتونید از قانون regex استفاده کنید و برای فیلد موردنظرتون یک عبارت منظم مناسب کارتون بنویسید و از آن استفاده کنید مثلا برای کد ملی به این صورت :

'codemelli' => 'required|regex:#^[0-9]{10}$#',

 و میتونید براش یک پیام هم ست کنید و به عنوان پارامتر سوم به متد make بدهید:

$messages = [
    'regex' => 'فیلد کدملی را به درستی وارد نمایید.',
];

$validator = Validator::make($input, $rules, $messages);


همچنین اگه به پستی که در مورد اعتبارسنجی توضیح دادم مراجعه کنید نحوه ایجاد یک rule دلخواه رو هم گفتم که قبل اعتبارسنجی باید آن را تعریف کنید مثلا من یک rule به نام alpha_spaces تعریف کردم که حروف الفبا به اضافه فاصله را قبول میک ند و مثل بالا و یا در فایل validation.php  پیغام مناسبی هم براش ست کنید.

Validator::extend('alpha_spaces', function($attribute, $value)
{
    return preg_match('#^[a-zA-Z ]+$#', $value);
});

 شاید شما برای کد ملی بخواهید صحت کد ملی رو هم بررسی کنید که استفاده از متد extend بهتر به کارتون میاد که در تابع بی نام عملیات موردنظرتونو میونیسید و در پایان هم میتونید false یا true را return کنید.

----------


## relaxdevil

مرسی از سرعت عمل بالا کارت حرف نداره مهندس  :تشویق: 
استاد یه در خواست دارم میشه هر آموزشی که میدی پروژه لاراول شو آپلود کنی جایی لینک بدی بهمون ؟

----------


## hamedarian2009

> مرسی از سرعت عمل بالا کارت حرف نداره مهندس 
> استاد یه در خواست دارم میشه هر آموزشی که میدی پروژه لاراول شو آپلود کنی جایی لینک بدی بهمون ؟


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

----------


## 1sarbaz

سلام مجدد خدمت آقا حامد عزیز

فرض کنید ما یک سیستم وبلاگدهی رو میخوایم بنویسیم .

خوب سابدمین روتینگ که راحت میشه با این روش پیاده کرد.
http://laravel.com/docs/4.2/routing#sub-domain-routing

اما حالا اگر هر وبلاگ نویس خواست دامنه اختصاصی خودش رو به وبلاگش وصل کنه ما باید چطور روتها رو درست کنیم ؟

خیلی جستجو کردم اما به نتیجه نرسیدم . خودم شخصا به این نتیجه رسیدم که دستی با 

Request::getHost()

و ایجاد شرط و این مسائل در همون فایل route مدیریتش کنم اما خیلی به نظر غیر اصولی میاد و کثیف کاری میشه. پیشنهاد شما چیه ؟

----------


## rahahost

سلام .

واقعا آموزش های مفید و جامعی بود :)
متشکرم ازتون .

لطفا اگر امکانش هست ، کمی در مورد " کش " در لاراول توضیح بدید و یه مثال کاربردی براش بزنید .

متشکرم .

----------


## hamedarian2009

سلام دوستان
من به علت مشغله ای کاری که برام پیش اومده فعلا نمیتونم در خدمت شما دوستان باشم و خیلی زود  با مباحث جدیدتر و پاسخگویی به سوالات شما برخواهم گشت

----------


## stackprogramer

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

----------


## tuytoosh

با وجود CSRF ، آیا نیازی به کپچا هست؟

----------


## 2undercover

> با وجود CSRF ، آیا نیازی به کپچا هست؟


CSRF که خودش اسم یک نوع حمله است Cross-Site Request Forgery این چیزی که ازش در مقابل این حمله استفاده میشه CSRF Token هست که کارش این هست که ما اطمینان حاصل می کنیم که درخواستی که به سایت برای یک کار ارسال شده از طریق خود سایت هست نه از جای دیگه ای.

حمله CSRF رو با توجه به چیزی که من فکر می کنم میشه با Captcha هم خنثی اش کرد ولی خوب دلیلی نداره مثلا برای اضافه کردن یک کالا به سبد خرید کاربر ازش درخواست کنیم Captcha رو وارد بکنه پس همون CSRF Token کافی هست. ولی چیزی که شما گفتید که با وجود CSRF Token دیگه نیازی به Captcha نباشه خوب اشتباه هست؛ چون کاربرد Captcha اصلا متفاوت به حمله CSRF هست. Captcha برای این استفاده میشه که مطمئن بشیم که درخواست ارسال شده توسط یک انسان هست و کار یک ربات نیست که مثلا می خواد از طریق Brute Force به نتیجه ای برسه یا فرضا بخواد با تعداد زیادی درخواست نامربوط (فرضا درخواست ثبت نام) برنامه رو دچار اختلال بکنه.

پس من فکر می کنم CSRF رو میشه با Captcha خنثی کرد ولی اطمینان از فرستاده شدن درخواست توسط انسان از طریق CSRF Token ممکن نیست.

----------


## captain_hamid

استفاده از میان افزار رو درک نکردم میشه توضیح بدین مقدار پارامترها رو از کجا دریافت میکنه؟ چطوری بهش پاس میدیم؟
مثل همین age<200 که نوشتین؟ این مقدار age رو کجا بهش پاس بدیم؟ میشه تو url هم اینکارو کرد؟؟
ممنون

----------


## captain_hamid

راهنمایی . لطفا جواب سوال بالا؟

----------


## hamedarian2009

> راهنمایی . لطفا جواب سوال بالا؟


شما مبحث درخواست ها یا Request رو مطالعه کردین؟
کلا Middleware ها   کارشون فیلتر درخواست ها هست یعنی قبل اینکه بخواد درخواست وارد یک کنترلر بشه میتونید بررسی کنید اگه شرایطی رو که مد نظر داشتین رو اون درخواست داشت بهش اجازه ادامه عملیات و ورود به کنترلر موردنظرشو بدهید مثلا یک نمونه از همون middleware ها auth می باشد که اگه به کنترلری اونو بدیم فقط درخواست های کاربران احراز هویت شده قابل پذیرش هست وگرنه به صفحه لاگین ریدایرکت خواهد شد.
 توی هر درخواستی ممکنه شما data هم داشته باشید حالا ممکنه از طریق ارسال فرم باشه یا از طریق URL اگه مبحث درخواست ها رو بخونید میتونید به داده ها به این صورت دسترسی داشته باشید:

$request->input('name');


توی مثالی که داشتیم age هم به همین صورت هست. چیز زیاد سختی نیست شما چند بار اگر عملی کار کنید متوجه میشین

----------


## kmbahmanzadeh

سلام با تشکر از آموزشتون من هنگام نصب با این مشکل مواجه می شم!!!http://uupload.ir/files/w24w_capture.png

----------


## hamedarian2009

با Composer در ویندوز ممکنه به چنین خظاهایی بخورید میتونید از لینک زیر فایل های لاراول ۵ رو مستقیما دانلود کنید
http://fian.my.id/larapack/

----------


## dezchilds

سلام ، با تشکر از آموزش های مفصلتون ...
صفحه اول تاپیکو خوندم ولی از اونجایی که متوجه نشدم آخرش چطوری باید استارت کار رو بزنم اومدم سوال کنم .
اولین باره که میخوام از فریمورک استفاده کنم  . 
لطفاً فقط به ترجمه داکیومنت های سایت لاراول بسنده نکنید و برای قابل لمس تر شدن پیاده سازی این داکیومنت ها چندتا Sample ساده از صفر تا 100 ساخت یه سایت رو توضیح بدید ممنون میشم چون برای من که تا حالا Core کار کردم و میخوام سویچ کنم تو فاز فریمورک یکم قضایا نامفهومه . 
بازم تشکر از آموزش های عالیتون  :قلب:

----------


## vioming

با سلام

واقعا آقا حامد بابت آموزش های خوب و روانتون کمال تشکر رو از جناب عالی دارم

ولی من نیاز به راهنمایی دارم در زمینه ی facades ها , service container ها و contract ها و service provider ها

من رفتم به ترتیب در خود سایت لاراول 
http://laravel.com/docs/5.1/providers
http://laravel.com/docs/5.1/container
http://laravel.com/docs/5.1/contracts
http://laravel.com/docs/5.1/facades
رو خوندم ولی چیزه زیادی دستگیرم نشد و یک درک کمی تونستم ازش پیدا کنم
به همین جهت تقاضا داشتم که درباره ی موارد بالا که عرض کردم توضیحی مختصر همراه با مثال بدید تا متوجه بشم که مبانی معماری لاراول به چه صورته ....
بنده خودم با لاراول کار میکنم ولی با اینکه از موارد گفته شده در بالا استفاده می کنم ولی متاسفانه درک کمی ازشون دارم , بازم از شما و همه ی دوستانی که دارن دانش خودشون رو به اشتراک میذارن متشکرم

----------


## vahidmahmoudi

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



;(Route::_model_(*'tasks'*, *'Task*

}(Route::_bind_(*'tasks'*, *function*($value, $route 
  {;()*return* App\Task::_whereSlug_($value)->first

----------


## m_e_h_d_i

> اینجارو بخونید
> http://prosperotemuyiwa.com/2015/05/...vel-5-package/


متاسفانه لینک کار نمیکنه.

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

----------


## m_e_h_d_i

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

لاراول نسخه ۵.۱ با php 5.5+ کار میکنه که سرور جدید این مشکل را داشت.

----------


## hamedarian2009

> سلام ...ممنون از اموزش خوبتون ...لطفا یه توضیحی هم در مورد این ادرس دهی که پایین نوشتم بدهید ...ممنون میشم
> 
> 
> 
> ;(Route::_model_(*'tasks'*, *'Task*
> 
> }(Route::_bind_(*'tasks'*, *function*($value, $route 
>   {;()*return* App\Task::_whereSlug_($value)->first


تو لاراول می تونیم یک مدل را داخل route معرفی کنیم و با استفاده از Method Injection از مدل  داخل اکشن یا Closure به روش Type-Hint یک شی از آن ایجاد کنیم و  دیگه نیازی به بازیابی اطلاعات کاربر نداریم مثلا مثال زیر رو در نظر بگیرید:

Route::model('user', 'User');

Route::get('profile/{user}', function(App\User $user)
{
    return $user->email;
});

جای user باید id کاربر رو بهش پاس بدیم مثلا اگر ادرس profile/1 رو در مرورگر باز کنید ایمیل کاربر با id برابر 1  رو بهتون نشون میده

اما در حالت عادی باید اینکارو می کردیم:

Route::get('profile/{id}', function($id)
{
    $user = App\User::find($id);
    return $user->email;
});


حالا می تونیم رفتار کوئری رو با bind تغییر بدهیم مثلا :

Route::bind('user', function($value, $route)
{
    return App\User::where('name', $value)->first();
});

الان براساس نام کاربر اطلاعاتشو بهتون میده مثلا اگر profile/admin را بازکنید ایمیل admin را نمایش خواهد داد

----------


## tux-world

> با سلام
> 
> واقعا آقا حامد بابت آموزش های خوب و روانتون کمال تشکر رو از جناب عالی دارم
> 
> ولی من نیاز به راهنمایی دارم در زمینه ی facades ها , service container ها و contract ها و service provider ها
> 
> من رفتم به ترتیب در خود سایت لاراول 
> http://laravel.com/docs/5.1/providers
> http://laravel.com/docs/5.1/container
> ...


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

----------


## perkas

*آقا حامد آموزش  خیلی مفید هست
اگه pdf این آموزش رو بسازین یه کتاب خیلی خوب میشه*

----------


## hamedarian2009

با تشکر از دوستان مدتی است آموزش هام رو در انجمن دیگری شروع کردم که این سری آموزش ها پروژه محور است چون اون انجمن در این فروم سانسور هست اگر "آموزش گام به گام laravel" رو جستجو کنید در انجمن n+c+i+s آموزش های جدیدم را می توانید دنبال کنید

PDF هم ندارم چون مستقیما در همینجا تایپ میکنم و اگر کسی دوست داره میتونه زحمتشو بکشه

----------


## hamedarian2009

دوستان در تلگرام گروهی به منظور بحث و بررسی و پرسش و پاسخ در مورد فریمورک laravel راه اندازی شده است که در صورتی که علاقمند به حضور در این گروه می باشید می تونید پیغام خصوصی بکنید تا براتون لینک گروه رو ارسال کنم

----------


## nrezvani

تو قسمت کلید خارجی من کد رو میذارم اما متاسفانه کلید خارجی در دیتابیس من اضافه نمیشه ولی اروری هم نمیگیره از کدم 
بصورت manually کلید خارجی رو در دیتابیس میزارم اضافه هم میشه کار میکنه اما با کد لاراول اضافه نمیشه میشه راهنمایی کنید؟

----------


## ashapple

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

----------


## medisapps

> تو این چیزی ننوشتید که بخواد اجرا بشه 
> 
> مواقعی هست که می خواهید  یک دستور در زمان های مشخصی به طور اتوماتیک اجرا شود با استفاده از command scheduler این کار رو به راحتی میتونید انجام دهید. برای اینکار کافیه توی مسیر app/Console فایل Kernel.php را باز کنید و داخل متد schedule دستور مورد نظرتون رو بنویسید. مثلا در مثالی که اشاره کنید میتونید به طور مستقیم یک عملیاتی را داخل closure تعریف کنید و متد بعدی آن هم برنامه زمانی اجرای آن را مشخص میکند که در مثالی که ذکر کردین هر ۵ ذقیقه یک بار است. به چندتا مثال زیر توجه کنید:
> protected function schedule(Schedule $schedule)
>     {
>         $schedule->command('inspire')->hourly();
>         
>         $schedule->command('cache:clear')->hourly();
>                     
> ...



سلام
عذر میخوام من در خط زیر مشکل داشتم

در انتها اگر دستور زیر را به cron job هاست خود بدهید هر یک دقیقه یک بار   این دستور را اجرا میکند و اگر job ای وجود داشت اجرا میکند 


```
* * * * *php /var/www/html/laravel/artisan schedule:run 1>> /dev/null 2>&1
```

چطور باید به کرون جاب هاستمون این دستور خط بالا رو بدیم ؟

----------


## hamedarian2009

> سلام
> عذر میخوام من در خط زیر مشکل داشتم
> 
> در انتها اگر دستور زیر را به cron job هاست خود بدهید هر یک دقیقه یک بار   این دستور را اجرا میکند و اگر job ای وجود داشت اجرا میکند 
> 
> 
> ```
> * * * * *php /var/www/html/laravel/artisan schedule:run 1>> /dev/null 2>&1
> ```
> ...


سلام. معمولا تو  سی پنل یا دایرکت ادمین هاست تون باید یک گزینه به اسم cron jobs وجود داشته باشه که داخلش هم یک نمونه مثال از نحوه استفاده ازش هم وجود داره اگر هم وجود نداره باید به پشتیبانی هاست تیکت بزنید تا فعال کنند

----------


## behzadamin12

با سلام خدمت تمام دوستان عزیز در این مطلب برای old value laravel مثال کاملی ندیدم مثلا نوع input, textarea, checkbox, select که یه مثال براتون پیدا کردم به صورت کامل 

*laravel show old value form*

----------


## behzadamin12

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

https://jobteam.ir/ProductUser/74-la...multi-language

----------


## behzadamin12

چند روزیه چشمم به این آموزش از لاراول میفته 
حیفم میاد تکمیلترش نکنم
یه بحثی که زیاد مهمه ایجاد لینک های موقت و امن (محافظت شده) در لاراول هستش که مثلا 24 ساعت برای یک کاربر درخواست دهنده اعتبار داشته باشه *تولید لینک موقت در لاراول* با استفاده از Signed Route ایجاد میشه
آموزش خیلی کابردی برای کسایی هستش که میخان یک فایل رو فقط فردی که خریده بتونه دانلود کنه و اگه لینک رو به کاربر دیگه داد نتونه دانلود کنده

https://jobteam.ir/ProductUser/81-La...y-Signed-Route

----------


## behzadamin12

دوستان عزیز و اساتید گرامی موضوع بعدی و پایه در آموزش *لاراول middleware*ها هستند و باید به درستی درک شده و در پروژه ها مورد استفاده قرار بگیرند

https://jobteam.ir/ProductUser/82-Laravel-Middleware

----------


## behzadamin12

سلام مقوله این دو باهم فرق داره
حتما یک سر بزنید و مفهوم *CSRF لاراول* رو مطالعه کنید

----------


## behzadamin12

برای تکمیل آموزش های پایه لاراول در این قسمت در مورد *درخواست های http در لاراول* توضیحات کامل رو ارائه دادیم درخواست های http همان *laravel request* می باشد

----------


## behzadamin12

با سلام خدمت دوستان عزیز قسمت بعدی که باید بعد از درخواست های http در لاراول مطالعه کنید *پاسخ (Response) های Http در لاراول* می باشد

----------


## m.alinejad

این هم یه دوره آموزشی خوب و رایگان
*Lynda - Laravel 5 Essential Training*

----------

