عرض مشاركة واحدة
قديم 23-02-2019, 04:03 PM   #1
تاريخ التسجيل: Feb 2019
المشاركات: 1,010
التقييم: 10
تاريخ التسجيل: Feb 2019
المشاركات: 1,010
التقييم: 10
افتراضي دليل مطوّري PHP للبدء في بناء تطبيقات Laravel - الجزء الأوّل

استخدام النماذج عند الحديث عن تعريف مسارات Routes التطبيق.

ملحوظة: عند الاستعلام عن بيانات من قاعدة بيانات MySQL في PHP فإن نوع البيانات المتحصَّل عليه هو دائما string (سلسلة محارف). استخدمنا في النموذج أعلاه المصفوفة casts للتأكيد على أن الخاصية user_id في الصنف Task يجب أن تكون من النوع int. سنتمكّن بهذه الطريقة من استخدام المعامل === (المساواة التامة، في القيمة ونوع البيانات).

علاقات Eloquent
عرفنا في الفقرتين السابقتين النموذجيْن User وTask؛ المستخدم والمهمة على التوالي، يجب الآن تعريف العلاقة التي تربط بين الاثنين. يمكن لمستخدم إنشاء أكثر من مهمّة، لكنّ مهمّة محدّدة لا يمكن أن تُسنَد سوى لمستخدم واحد فقط. يمكّن تعريف العلاقات بين النماذج من الحصول بسهولة على البيانات الطلوبة. مثلا؛ يمكن، بعد تعريف العلاقة بين المستخدم والمهام، إيجادُ مهامّ المستخدم ذي المعرّف 1 على النحو التالي:

$user = App\User::find(1);

foreach ($user->tasks as $task) {
echo $task->name;
}
علاقة المستخدم بالمهام
نحدّد أولا طبيعة العلاقة بين المستخدم والمهامّ. تعرَّف العلاقات في Eloquent بدوالّ في النموذج. تحدّد الدوال طبيعة العلاقة بين النموذجين. يمكن أن يكون للمستخدم، كما أسلفنا، أكثرُ من مهمة، تُسمّى هذه العلاقة في Eloquent بـhasMany، وتعرَّف بإضافة دالة tasks على النحو التالي إلى النموذج User:

<?php

namespace App;


class User extends Authenticatable
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];

/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* Get all of the tasks for the user.
*/
public function tasks()
{
return $this->hasMany(Task::class);
}
}
علاقة المهمّة بالمستخدم
نعرفّ، في الجانب الآخر، على مستوى النموذج Task، طبيعة العلاقة التي تربط المهمة بالمستخدم. نعرّف، كما فعلنا عند تعريف علاقة المستخدم بالمهامّ، دالةً مع تحديد طبيعة العلاقة التي هي في هذه الحالة belongsTo. بمعنى أن المهمة تتبع للمستخدم؛ أي أنه لا يمكن أن تتبع نفس المهمة لأكثر من مستخدم.

يمكن تقريب الفكرة بالقول إن الناظر للعلاقة من جهة المهمة يرى أنه تسير في اتجاه واحد belongsTo (مستخدم واحد)؛ أما الناظر إليها من جهة المستخدم فيرى أنها يمكن أن تسير في عدّة اتجاهات hasMany (مهامّ متعدّدة):

<?php

namespace App;

use App\User;

class Task extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['name'];

/**
* Get the user that owns the task.
*/
public function user()
{
return $this->belongsTo(User::class);
}
}
التوجيه
تُستخدَم المسارات Routes لتوجيه الروابط URL إلى متحكّم أو دالة تُنفَّذ عند زيارة رابط محدَّد. تُعرَّف المسارات مبدئيا في Laravel ضمن الملفّتيح المتحكمات التعامل مع طلبات Http بتوزيعها بين ملفات مختلفة من أجل تنظيم أفضل وصيانة أسهل.

إظهار عرض
سيكون لدينا مسار / تظهر للزائر عند طلبه صفحة ترحيبية. تنتُج الصفحة الترحيبية عن معالجة قالب HTML. مبدئيا؛ يُخزّن Laravel جميع قوالب HTML في المجلّد resources

ستجد عند فتح الملفّ routes.php أنه يحوي الدالة التالية:

Route::get('/', function () {
return view('welcome');
});
تستقبل هذه الدالة الطالبات الواردة على المسار /وتقدّم إليها العرض welcome.blade.php باستخدام الدالة المساعدة view. لاحظ أننا لم نحدّد امتداد الملفّ في الدالة، اسم العرض (welcome) يكفي. سنعرّف العرض في ما بعد.

الاستيثاق
ذكرنا في تقديم المشروع الذي نودّ بناءه أننا نريد أن يتمكّن المستخدمون من إنشاء حسابات والولوج بها إلى التطبيق؛ أي أننا سنحتاج لآلية للاستيثاق. قد يتطلّب إنشاء آلية للاستيثاق الكثير من الجهد والوقت؛ إلا أن Laravel يحاول جعل هذه العمليّة أسهل ما يمكن.

أولا؛ تمكن ملاحظة وجود المتحكّم AuthController في المجلد app/Http/Controllers/Auth. يستخدم هذا المتحكّم السمة AuthenticatesAndRegistersUsers التي تحوي الدوال المطلوبة لإنشاء المستخدمين والاستيثاق منهم.

مسارات الاستيثاق وعروضه
الأساسيات المطلوبة لإنشاء مستخدمين والاستيثاق منهم موجودة مبدئيا كما أسلفنا؛ ولكن يبقى تعريف قوالب (عروض) التسجيل والاستيثاق، والمسارات التي تشير إلى متحكّم الاستيثاق. يمكننا باستخدام artisan تعريفُ القوالب بسهولة:


php artisan make:auth
لاحظ مخرجات الأمر والعروض التي أضافها للمشروع. تمكن أيضا ملاحظة أن الأمر أضاف المسارات التالية إلى ملفّ المسارات:

Route::auth();

تسجّل الدالة auth من الصّنف Route جميع المسارات التي نحتاجها لتسجيل حسابات جديدة للمستخدمين، ولوج مستخدمين مسجَّلين وإعادة تعيين كلمة السّر.

يعرّف الأمر في المسار الثاني الرابط home/ الذي تتعامل معه الدالة index في المتحكم HomeController الذي أنشأه الأمر السابق. إن فتحت ملفّ المتحكم HomeController فستجد أن الدالة index تطلُب إظهار العرض home.

ملحوظة: إن كنت ترغب في الاطّلاع على الشفرة المصدرية الكاملة للعروض فهي متوفّرة ضمن شفرة المشروع على GitHub.

افتح ملفّ المتحكّم AuthController (في المجلّد app/Http/Controllers/Auth) وغيّر قيمة redirectTo$ كالتالي:


protected $redirectTo = '/tasks';
تحدّد هذه الخاصّيّة المسار الذي يُوجَّه الزائر إليه بعد الاستيثاق من بياناته. يجب أيضا التعديل على ليرجع نفس المسار بعد ولوج الزائر:


return redirect('/tasks');
المتحكم في المهام
ننشئ متحكّما جديدا خاصّا بالعمليات على المهامّ، مثل العثور على المهامّ المخزّنة وتخزين مهامّ جديدة. سنستخدم - كالعادة - أداة artisan لهذا الغرض:


php artisan make:controller TaskController
ثم نعدّل ملفّ المسارات بإضافة المسارات التالية:

سنستخدم المسار tasks/ مع الإجراء get للعثور على مهامّ مستخدِم، المسار task/ مع الإجراء post لإضافة مهمة جديدة والمسار {task/{task مع الإجراء delete لحذف مهمّة؛ حيثُ {task} معرّف المهمة.

الاستيثاق من جميع مسارات المهامّ
نريد لجميع المسارات المتعلّقة بالمهامّ أن تكون محميّة؛ بمعنى أن المستخدمين لا يمكنهم رؤيتها إلا بعد الولوج إلى التطبيق. من السهل تنفيذ هذا الأمر في Laravel، وذلك باستخدام صنف وسيط Middleware.

يمكن، بإضافة نداء لصنف الاستيثاق الوسيط auth داخل مشيّد Constructor المتحكّم TaskController، جعلُ جميع الإجراءات في المتحكّم تستدعي الاستيثاق من المستخدم (أن يكون مسجّلَ الدّخول). يعرّف الملف app/Http/Kernel.php جميع الأصناف الوسيطة الممكن تطبيقها على المسارات. يصبح المتحكم TaskController بعد إضافة الوسيط إلى المشيّد كما يلي:

<?php

namespace App\Http\Controllers;

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

{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
}
إنشاء القوالب والعروض
يتضمّن الجزء الأساسي من التطبيق الذي نعملُ عليه عرضا واحدا توجد به استمارة لإضافة مهامّ جديدة، كما تظهر لائحة بالمهامّ الموجودة سلفا. في ما يلي لقطة من التطبيق المكتمل:

01_application_layout.png

تعريف مخطّط العرض
تستخدم غالبية تطبيقات الوِب نفس المخطّط في كلّ الصفحات. بالنسبة للتطبيق الذي نعمل عليه فهو يحتوي على شريط تصفّح علوي يوجد في جميع الصفحات (في حال وجود أكثر من صفحة). تسهّل قوالب Blade تشارك العناصر بين الصفحات.

يحتفظ Laravel بجميع العروض ضمن المجلّد resources/views. سنعرّف قالبا جديدا لعروض Blade في الملفّ resources/views/layouts/app.blade.php. يستخدم Laravel نظام القوالب Blade لمعالجة الملفات التي تنتهي بالامتداد blade.php.. يمكن استخدام قوالب PHP تقليدية لتقديم العروض، إلا أن نظام Blade يوفّر قوالب مختصرة ومحكمة.


<!-- resources/views/layouts/app.blade.php -->

<!DOCTYPE html>
<html lang="en">
<head>
<title>Laravel Quickstart - Intermediate</title>

<!-- شفرات CSS و JavaScript -->
</head>

<body>
<div class="container">
<nav class="navbar navbar-default">
<!-- محتوى شريط التصفح Navbar -->
</nav>
</div>

@yield('content')
</body>
</html>
تحدّد التعليمة ('yield('content@ مكان الصفحات التي ستمدّد المخطّط الرئيس وتضيف محتوى خاصّا بها. راجع توريث القوالب في Laravel للمزيد من التفصيل. سننتقل الآن لتعريف العرض الإبن الذي سيستخدم المخطّط ويعرّف داخله محتوى خاصّا به.

تعريف العرض المُمدِّد للمخطَّط
سنحتاج لتعريف عرض يحوي استمارة لإنشاء مهمة جديدة وجدولا لعرض المهامّ الموجودة. ننشئ لهذا الغرض عرضا على المسار

سنركّز في ما يلي على التعليمات المتعلّقة بـBlade ونتجاوز شفرة Bootstrap CSS (يمكن الحصول على الشفرة كاملة من مستودع المشروع على GitHub:


<!-- resources/views/tasks/index.blade.php -->

@extends('layouts.app')

@section('content')

<div class="container">
<div class="col-sm-offset-2 col-sm-8">
<div class="panel panel-default">
<div class="panel-heading">
New Task
</div>

<div class="panel-body">
<!-- إظهار أخطاء التحقّق -->
@include('common.errors')

<!-- استمارة إنشاء مهمة -->
<form action="{{ url('task') }}" method="POST" class="form-horizontal">
{{ csrf_field() }}

<!-- اسم المهمة -->
<div class="form-group">
<label for="task-name" class="col-sm-3 control-label">Task</label>

<div class="col-sm-6">
<input type="text" name="name" id="task-name" class="form-control">
</div>
</div>

<!-- زرّ إضافة مهمة -->
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6">
<button type="submit" class="btn btn-default">
<i class="fa fa-plus"></i> Add Task
</button>
</div>
</div>
</form>
</div>
</div>

<!-- سنضع هنا الشفرة الخاصة بعرض المهام التي أنشأها المستخدم -->
@endsection
تُخبر التعليمة extends@ نظام القوالب Blade أننا في طور استخدام المخطّط المعرَّف في الملفّ resources/views/layouts/app.blade.php. يضع نظامُ القوالب جميعَ المحتوى الموجود بين التعليمتيْن ('section('content@ وendsection@ مكان التعليمة ('yield('content@ في المخطّط app.blade.php.

تحمّل التعليمة ('include('common.errors@ القالب resources/views/common/errors.blade.php. هذا القالب غير معرَّف لحد الساعة، ولكن سنعرّفه بعد قليل.

نعود للمتحكّم TaskController ونضيف الدالة index التي تطلُب تقديم العرض resources/views/tasks/index.blade.php الذي أنشأناه للتو:

/**
* Display a list of all of the user's task.
*
* @param Request $request
* @return Response
*/
public function index(Request $request)
{
return view('tasks.index');
}
يشير الاسم tasks.index إلى أن المطلوب هو إظهار العرض index.blade.php الموجود في المجلد tasks الذي يوجد بدوره في مجلد العروض (أي resources/view).

أصبحت أغلب عناصر التطبيق جاهزة. سنكمل في الجزء الثاني لهذا المقال بقية العناصر التي ستمكّن من إضافة مهامّ جديدة، عرض مهام موجودة أو حذفها

الفارس غير متواجد حالياً   اقتباس