عرض مشاركة واحدة
قديم 23-02-2019, 05:10 PM   #1
تاريخ التسجيل: Feb 2019
المشاركات: 1,010
التقييم: 10
تاريخ التسجيل: Feb 2019
المشاركات: 1,010
التقييم: 10
افتراضي laravel5 todo إنشاء تطبيق Todo List بسيط باستخدام Laravel 5 - الجزء الأول

يعتبر Laravel أشهر إطار ويب بلغة PHP، ولقد شهد إصداره الخامس العديد من التغييرات وتمت إضافة الكثير من المميزات الجديدة، ولذلك لتعلم أساسيات هذا الإطار سوف نقوم بإنشاء تطبيق Todo List، وسوف نتعلم من خلال هذا التطبيق الكثير من المفاهيم والطرق البرمجية حتى نتمكن من التعامل والتوسع مع إطار Laravel 5.قبل أن نبدأ
أهم المصطلحات التي ستصادفنا في هذه الدروس:
التهجير migration: نظام لإدارة قواعد البيانات، فهو يسمح للفريق بتعديل مخطط قواعد البيانات لجميع الأعضاء.
البذر seeding: يقصد بها إدخال البيانات الأولية لتجربة التطبيق، أي أنه سيقوم بإدخال بيانات لمساعدتك على التطوير واكتشاف الأخطاء.

هدف المشروع
سوف يتكون تطبيقنا من مشروع أو أكثر، كل واحد لديه قائمة مهام خاصة به، وسوف تتمكن من إنشاء وعرض وتعديل وحذف المهام والمشاريع.
في هذا الدرس سوف نقوم بـ:

إعداد وتنصيب Laravel.
تركيب حزم إضافية لتسهيل عملية التطوير.
استخدام التهجير migration والبذر seeds.
تعلم كيفية استخدام متحكِّمات الموارد resourceful controllers.
تعلم كيفية استخدام العروض views. (بما في ذلك نظام blade ومخططات المحتوى)قاعدة البيانات

سوف نحتاج إلى قاعدة بيانات، لذلك سنقوم بعمل واحدة ثم سنقوم بنسخ .env.example إلى .env وتحديث البيانات على الشكل التالي:

DB_HOST=localhost
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
في النهاية إذا لم تكن تستخدم MySQL فقُم بفتح config/database.php/ ثم قٌم بتغيير السطر الافتراضي:

'default' => 'mysql'خطواتنا الأولى
كما ذكرنا في الأعلى، سوف يتكون تطبيق قائمة المهام على مشروع أو أكثر كل واحد مع قائمة المهام الخاصة به، ولذلك سوف نحتاج إلى مشروع، نماذج مهام، متحكِّمات، عروض views، التهجير migration، البذور seeds والطرق routes، ولقد قمنا بشرح بعض هذه المصطلحات في بداية الدرس.
لنبدأ بالتعامل معهم كل واحد على حدة.

التهجير migration

أولا نريد أن نرى مخطط جدولنا، سوف يبدو مثل هذا:

Projects
+------------+------------------+------+-----+
| Field | Type | Null | Key |
+------------+------------------+------+-----+
| id | int(10) unsigned | NO | PRI |
| name | varchar(255) | NO | |
| slug | varchar(255) | NO | |
| created_at | timestamp | NO | |
| updated_at | timestamp | NO | |
+------------+------------------+------+-----+

Tasks
+-------------+------------------+------+-----+
| Field | Type | Null | Key |
+-------------+------------------+------+-----+
| id | int(10) unsigned | NO | PRI |
| project_id | int(10) unsigned | NO | MUL |
| name | varchar(255) | NO | |
| slug | varchar(255) | NO | |
| completed | tinyint(1) | NO | |
| description | text | NO | |
| created_at | timestamp | NO | |
| updated_at | timestamp | NO | |
+-------------+------------------+------+-----+
ثم سوف نقوم بعمل التهجير migration:

php artisan make:migration create_projects_and_tasks_tables --create="projects"
سوف نقوم بعمل كِلا الجدولين بتهجير migration واحد حتى نتمكن من حذفها بترتيب عكسي لتجنب سلامة خرق القيد/database/migrations/createprojectsandtasks_tables.php
وقُم بتحديث المعلومات حسب الآتي:

<?php

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

class CreateProjectsAndTasksTables extends Migration {

/**
* Run the migrations.
*
* @return void
*/

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

Schema::create('tasks', function(Blueprint $table) {
$table->increments('id');
$table->integer('project_id')->unsigned()->default(0);
$table->foreign('project_id')->references('id')->on('projects')->onDelete('cascade');
$table->string('name')->default('');
$table->string('slug')->default('');
$table->boolean('completed')->default(false);
$table->text('description')->default('');
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/

public function down()
{
Schema::drop('tasks');
Schema::drop('projects');
}

}
قم بتنفيذ الهجرة migration:

php artisan migrate
إذا قمت الآن بمراجعة قاعدة البيانات، يجب أن تكون الجداول مكتملة.

البذور Seeds

سوف نحتاج إلى بذر المشاريع/المهام ليكون لديك شيء للعمل معه عندما نصل إلى المتصفح، لذلك قم بإنشاء:

/database/seeds/ProjectsTableSeeder.php و TasksTableSeeder.php
كالتالي:

// /database/migrations/seeds/ProjectsTableSeeder.php
<?php

use Illuminate\Database\Seeder;

class ProjectsTableSeeder extends Seeder {

public function run()
{
// Uncomment the below to wipe the table clean before populating
DB::table('projects')->delete();

$projects = array(
['id' => 1,
'name' => 'Project 1',
'slug' => 'project-1',
'created_at' => new DateTime,
'updated_at' => new DateTime],
['id' => 2,
'name' => 'Project 2',
'slug' => 'project-2',
'created_at' => new DateTime,
'updated_at' => new DateTime],
['id' => 3,
'name' => 'Project 3',
'slug' => 'project-3',
'created_at' => new DateTime,
'updated_at' => new DateTime],
);

// Uncomment the below to run the seeder
DB::table('projects')->insert($projects);
}

}

// /database/migrations/seeds/TasksTableSeeder.php
<?php

use Illuminate\Database\Seeder;

class TasksTableSeeder extends Seeder {

public function run()
{
// Uncomment the below to wipe the table clean before populating
DB::table('tasks')->delete();

$tasks = array(
['id' => 1,
'name' => 'Task 1',
'slug' => 'task-1',
'project_id' => 1,
'completed' => false,
'description' => 'My first task',
'created_at' => new DateTime,
'updated_at' => new DateTime],

['id' => 2,
'name' => 'Task 2',
'slug' => 'task-2',
'project_id' => 1,
'completed' => false,
'description' => 'My first task',
'created_at' => new DateTime,
'updated_at' => new DateTime],

['id' => 3,
'name' => 'Task 3',
'slug' => 'task-3',
'project_id' => 1,
'completed' => false,
'description' => 'My first task',
'created_at' => new DateTime,
'updated_at' => new DateTime],

['id' => 4,
'name' => 'Task 4',
'slug' => 'task-4',
'project_id' => 1,
'completed' => true,
'description' => 'My second task',
'created_at' => new DateTime,
'updated_at' => new DateTime],

['id' => 5,
'name' => 'Task 5',
'slug' => 'task-5',
'project_id' => 1,
'completed' => true,
'description' => 'My third task',
'created_at' => new DateTime,
'updated_at' => new DateTime],

['id' => 6,
'name' => 'Task 6',
'slug' => 'task-6',
'project_id' => 2,
'completed' => true,
'description' => 'My fourth task',
'created_at' => new DateTime,
'updated_at' => new DateTime],

['id' => 7,
'name' => 'Task 7',
'slug' => 'task-7',
'project_id' => 2,
'completed' => false,
'description' => 'My fifth task',
'created_at' => new DateTime,
'updated_at' => new DateTime],
);

//// Uncomment the below to run the seeder
DB::table('tasks')->insert($tasks);
}

}
ولا تنسَ إضافة أصناف البذور(seed classes) إلى database/seeds/DatabaseSeeder.php/ :

use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;

class DatabaseSeeder extends Seeder {

/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Model::unguard();

$this->call('ProjectsTableSeeder');
$this->call('TasksTableSeeder');
}

}
الآن نقوم بالبذر:

composer dump-autoload
ثم:

php artisan db:seed
# أو
php artisan migrate:refresh --seed
يجب الآن أن تكون قاعدة البيانات قد تم بذرها.

mysql> select * from projects;
+----+-----------+-----------+---------------------+---------------------+
| id | name | slug | created_at | updated_at |
+----+-----------+-----------+---------------------+---------------------+
| 1 | Project 1 | project-1 | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 |
| 2 | Project 2 | project-2 | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 |
| 3 | Project 3 | project-3 | 2015-02-05 01:25:43 | 2015-02-05 01:25:43 |
+----+-----------+-----------+---------------------+---------------------+

mysql> select * from tasks;
+----+------------+--------+--------+-----------+----------------+---------------------+---------------+
| id | project_id | name | slug | completed | description | created_at | updated_at |
+----+------------+--------+--------+-----------+----------------+---------------------+---------------+
| 1 | 1 | Task 1 | task-1 | 0 | My first task | 2015-02-05 01:25:43 | 2015-02-05 01:25:43
| 2 | 1 | Task 2 | task-2 | 0 | My first task | 2015-02-05 01:25:43 | 2015-02-05 01:25:43
| 3 | 1 | Task 3 | task-3 | 0 | My first task | 2015-02-05 01:25:43 | 2015-02-05 01:25:43
| 4 | 1 | Task 4 | task-4 | 1 | My second task | 2015-02-05 01:25:43 | 2015-02-05 01:25:43
| 5 | 1 | Task 5 | task-5 | 1 | My third task | 2015-02-05 01:25:43 | 2015-02-05 01:25:43
| 6 | 2 | Task 6 | task-6 | 1 | My fourth task | 2015-02-05 01:25:43 | 2015-02-05 01:25:43
| 7 | 2 | Task 7 | task-7 | 0 | My fifth task | 2015-02-05 01:25:43 | 2015-02-05 01:25:43
+----+------------+--------+--------+-----------+----------------+---------------------+---------------+
النماذج Models

للعمل مع جداول المشاريع والمهام نحتاج إلى نماذج مماثلة، سوف نقوم بإنشائها الآن:

php artisan make:model Project
php artisan make:model Task
كان هذا سهلا :)

استخدام Artisan – Tinker

الآن لدينا المعلومات في قاعدة البيانات وسيكون من الرائع أن نتعلم حول واحدة من أهم ميزات artisan وهي Tinker الذي يوفر لك سطر أوامر للتعامل مع Laravel، وكمثال، لنستخدمه في معرفة عدد المشاريع في قاعدة البيانات الحالية:

$ php artisan tinker
> App\Project::count();
3
> App\Task::count();
7
وكما ترى يمكن أن يكون Tinker مفيدا للغاية، لذلك سوف نستخدمه عدة مرات في هذه السّلسلة.

المُتحكِّمات Controllers

الآن وصلنا إلى النقطة التي سوف نبدأ بعرض ما صنعناه على المتصفح، وسوف نحتاج إلى إنشاء بعض المتحكِّمات Controllers والطرق Routes. سنبدأ أولا بالمتحكِّمات:

php artisan make:controller ProjectsController
php artisan make:controller TasksController
الموارد المُضمّنة

نبدأ بإضافة موارد Project و Task إلى app/Http/routes.php/ :

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

//Route::get('home', 'HomeController@index');
//
//Route::controllers([
// 'auth' => 'Auth\AuthController',
// 'password' => 'Auth\PasswordController',
//]);

Route::resource('projects', 'ProjectsController');Route::resource('tasks', 'TasksController');
والآن دعونا نرى إحدى مميزات artisan والمُتمثّلة في route:list، في سطر الأوامر أكتب التالي:

php artisan route:list
لتكون النّتيجة

+--------+----------+--------------------------+------------------+-------------------------------------------------+------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+--------------------------+------------------+-------------------------------------------------+------------+
| | GET|HEAD | / | | App\Http\Controllers\WelcomeController@index | |
| | GET|HEAD | projects | projects.index | App\Http\Controllers\ProjectsController@index | |
| | GET|HEAD | projects/create | projects.create | App\Http\Controllers\ProjectsController@create | |
| | POST | projects | projects.store | App\Http\Controllers\ProjectsController@store | |
| | GET|HEAD | projects/{projects} | projects.show | App\Http\Controllers\ProjectsController@show | |
| | GET|HEAD | projects/{projects}/edit | projects.edit | App\Http\Controllers\ProjectsController@edit | |
| | PUT | projects/{projects} | projects.update | App\Http\Controllers\ProjectsController@update | |
| | PATCH | projects/{projects} | | App\Http\Controllers\ProjectsController@update | |
| | DELETE | projects/{projects} | projects.destroy | App\Http\Controllers\ProjectsController@destroy | |
| | GET|HEAD | tasks | tasks.index | App\Http\Controllers\TasksController@index | |
| | GET|HEAD | tasks/create | tasks.create | App\Http\Controllers\TasksController@create | |
| | POST | tasks | tasks.store | App\Http\Controllers\TasksController@store | |
| | GET|HEAD | tasks/{tasks} | tasks.show | App\Http\Controllers\TasksController@show | |
| | GET|HEAD | tasks/{tasks}/edit | tasks.edit | App\Http\Controllers\TasksController@edit | |
| | PUT | tasks/{tasks} | tasks.update | App\Http\Controllers\TasksController@update | |
| | PATCH | tasks/{tasks} | | App\Http\Controllers\TasksController@update | |
| | DELETE | tasks/{tasks} | tasks.destroy | App\Http\Controllers\TasksController@destroy | |
+--------+----------+--------------------------+------------------+-------------------------------------------------+------------+
ستلاحظ أن كل من projects و tasks هي روابط ذات مستوى عالي، وفي تطبيقنا، المهام تتبع المشاريع، لذلك سيكون من الأفضل للروابط أن تكون مُضمّنة مثل /projects/1/tasks/3 بدلا من /tasks/، وهذا يمكن فعله باستخدام شيء اسمه الموارد المُضمّنة nested resources، وكما هو الحال مع أغلب الأشياء في Laravel، التعديل المطلوب سريع وبسيط، فقط قٌم بفتح /app/Http/routes.php وقٌم بالتعديلات التالية:

// Route::resource('tasks', 'TasksController');
Route::resource('projects.tasks', 'TasksController');
هذا كل شيء، قُم بكتابة php artisan route:list لنعلم ماذا لدينا لحد الآن:

php artisan route:list
+--------+----------+----------------------------------------+------------------------+-------------------------------------------------+------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+----------------------------------------+------------------------+-------------------------------------------------+------------+
| | GET|HEAD | / | | App\Http\Controllers\WelcomeController@index | |
| | GET|HEAD | projects | projects.index | App\Http\Controllers\ProjectsController@index | |
| | GET|HEAD | projects/create | projects.create | App\Http\Controllers\ProjectsController@create | |
| | POST | projects | projects.store | App\Http\Controllers\ProjectsController@store | |
| | GET|HEAD | projects/{projects} | projects.show | App\Http\Controllers\ProjectsController@show | |
| | GET|HEAD | projects/{projects}/edit | projects.edit | App\Http\Controllers\ProjectsController@edit | |
| | PUT | projects/{projects} | projects.update | App\Http\Controllers\ProjectsController@update | |
| | PATCH | projects/{projects} | | App\Http\Controllers\ProjectsController@update | |
| | DELETE | projects/{projects} | projects.destroy | App\Http\Controllers\ProjectsController@destroy | |
| | GET|HEAD | projects/{projects}/tasks | projects.tasks.index | App\Http\Controllers\TasksController@index | |
| | GET|HEAD | projects/{projects}/tasks/create | projects.tasks.create | App\Http\Controllers\TasksController@create | |
| | POST | projects/{projects}/tasks | projects.tasks.store | App\Http\Controllers\TasksController@store | |
| | GET|HEAD | projects/{projects}/tasks/{tasks} | projects.tasks.show | App\Http\Controllers\TasksController@show | |
| | GET|HEAD | projects/{projects}/tasks/{tasks}/edit | projects.tasks.edit | App\Http\Controllers\TasksController@edit | |
| | PUT | projects/{projects}/tasks/{tasks} | projects.tasks.update | App\Http\Controllers\TasksController@update | |
| | PATCH | projects/{projects}/tasks/{tasks} | | App\Http\Controllers\TasksController@update | |
| | DELETE | projects/{projects}/tasks/{tasks} | projects.tasks.destroy | App\Http\Controllers\TasksController@destroy | |
+--------+----------+----------------------------------------+------------------------+-------------------------------------------------+------------+
جعل روابط ذات اسم لطيف

الطرق routes الحالية ممتازة لكنها ذات عناوين يمكن تحسينها، مثل هذا العنوان /projects/1/tasks/2، فسيكون من الرائع للزوار أن يتم تغيير المعرف الرقمي ID بالاسم اللطيف للحقول، فمثلا سوف نحصل على /projects/my-first-project/tasks/buy-milk بدلا من /projects/1/tasks/2.

قم بفتح ملف /app/Http/routes.php وضع به التالي:

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

Route::bind('projects', function($value, $route) {
return App\Project::whereSlug($value)->first();
});
هذه الشيفرة سوف تغير السلوك الافتراضي لـ tasks و projects في artisan routes وجعل الروابط ذات إسم لطيف slug.

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