الجدول الثاني tasks
بسم الله الرحمن الرحيم،
كل عام وأنتم بخير وتقبل الله طاعتكم. مر وقت طويل منذ آخر تدوينة في سلسلة الكيك ولكن يجب أن نكمل السلسلة قبل أن تبرد الهمم. فالنسيان آفة العلم والزمن سبب للنسيان.
أولاً دعونا نتذكر مامر بنا من أحداث في مشروع قائمة المهام:
في بداية الأمر وفي بداية كل مشروع يجب أن نضع الأهداف من وراء هذا المشروع وهذا مافعلناه في تحديد الأهداف. بعد ذلك لابد من تحديد الشريحة المستهدفة من الناس في هذا المشروع، كي نركز عليهم في تصميم الموقع وسهوليته والدعاية له وتسويقه، وناقشنا هذا الأمر في تحديد الشرائح المستهدفة. ثم وبناء على الأهداف والشرائح المستهدفة قمنا بوضع الميزات لهذا المشروع. هذه الخطوات الثلاث تندرج تحت تصنيف تحليل المشروع.
بعد ذلك أنقصنا خطوة ولكن يجب أن تضعها ببالك وهي وضع سكيتش للمشروع أي ترسم شكل الموقع الذي في مخيلتك على الورق وتقوم بترتيبه بالشكل الذي يحلو لك والتعديل عليه وفقاً لما تراه مناسباً أكثر، هكذا ستوفر على نفسك الكثير من العناء أثناء تصميم الموقع.
ثم بدأنا بالعمل الحقيقي وهو التطوير، حددنا التقنيات التي يجب استخدامها، ثم قمنا بتصميم قاعدة البيانات، وبعدها بدأنا بالبرمجة وبالتحديد برمجة الكيك. في بداية الأمر قمنا بمناقشة تحميل وتثبيت الكيك، بدأنا بأول متحكم وهو groups، وبعد ذلك أكملنا به وتناقشنا بمفهوم MVC.
هذا كل ماجرى باختصار وإذا نسيت بعض الخطوات فعد إليها وستلاحظ أنك ستستغرق وقتاً أقل من المرة الأولى لفهمها وسترى أشياء جديدة لم ترها أول مرة وهذا هو حال الكيك. في كل مرة تبرمج به تشاهد فيه ميزات جديدة أو تفهم بعضاً مما خفي عليك في السابق.
أظن أننا طبقنا كل ماورد في التدوينة السابقة، إذاً لدينا الآن صفحة بقوائم المهام وصفحة لإضافة قائمة جديدة. الآن نريد أن نضيف على القوائم المهمات التي تندرج تحت كل قائمة، فمثلاً في قائمة العيد لدي المهمات: شراء ملابس جديدة، زيارة الأهل والأقارب والخروج مع الأصدقاء.
الآن سنكرر بعض الخطوات التي شاهدناها في التدوينة السابقة، وهي إنشاء الطبقات الثلاثة للمهمات (Model, Controller, View)، في البداية سنقوم بإنشاء Model، سندخل إلى مجلد models وننشأ الملف: task.php وبالتأكيد نذكر بأن اسم الموديل هو نفس اسم الجدول في قاعدة البيانات ولكن بالمفرد (اسم الجدول هنا هو tasks فاسم الملف يكون task.php).
وكالعادة نقوم بكتابة الكليشه المعهودة:
<?php
class Task extends AppModel {
var $name = 'Task';
}
?>
وسنضيف عليه التالي ليصبح:
<?php
class Task extends AppModel {
var $name = 'Task';
var $belongsTo = array(
'Group' => array(
'classname' => 'Group'
)
);
}
?>
سنتوقف وقفة قصيرة لنشاهد ماحدث، سأشرح قليلاً عن أنواع العلاقات بين الجداول في قواعد البيانات وهي ثلاث:
- one-to-one: من اسمها علاقة رأس لرأس كما تسمى وكمثال عليها المستخدم و IP فلكل مستخدم IP واحد وله فقط.
- one-to-many: علاقة رأس لأطراف، وكمثال عليها مشروعنا الحالي فلكل قائمة مهام عدة مهام تندرج تحتها، وهذه العلاقة تقريباً هي أكثر العلاقات شيوعاً فالأمثلة عليها كثيرة في واقعنا لذلك يكثر استخدامها.
- many-to-many: علاقة معقدة ومثال عليها الطالب، فالطالب لديه عدد من المواد وكل مادة فيها عدد من الطلاب.
الآن عرفنا بأن مشروعنا بتطلب علاقة رأس لأطراف ولكي نخبر الكيك عنها استخدمنا متحول belongsTo المحجوز لهذه العلاقة بالذات (رأس لأطراف) وهو عبارة عن مصفوفة نكتب فيها اسم الموديل التي نريد الارتباط معها. وبالتأكيد من اسم المتحول نلاحظ بأن الرأس هو موديل القوائم (يتبع لـ Group) والأطراف هي المهمات.
انتهينا الآن من موديل المهمات، لاحظتم كم هي سهلة! فقط وضعنا نوع العلاقة ولكن يجب أيضاً أن نضع العلاقة في الموديل الآخرى وهي موديل Gruop، حرر ملف group.php داخل مجلد models ليصبح:
<?php
class Group extends AppModel {
var $name = 'Group';
var $hasMany = array(
'Task' => array(
'classname' => 'Task'
)
);
}
?>
لاحظ متحول hasmany الذي يدل الكيك على أن القائمة تتبع لها العديد من المهمات وهذا كل شيء، الكيك سيقوم بالباقي … لا عبارات where أو join أبداً كل هذا العمل التكراري سنتركه للكيك.
الآن سنقوم بإنشاء ملف المتحكم الخاص بالمهمات، ادخل إلى مجلد controllers وأنشأ الملف tasks_controller.php لاحظ أنه نفس اسم الجدول ولكن أضفنا بعده الشحطة (_) وكلمة controller وفعلنا المثل بالمتحكم السابق. حرر الملف واكتب داخله الكليشه المعهودة أيضاً:
<?php
class TasksController extends AppController {
var $name = 'Tasks';
}
?>
وبعد ذلك أضف التابع (الدالة) التالية:
<?php
class TasksController extends AppController {
var $name = 'Tasks';
function index() {
$this->set('tasks', $this->Task->find('all'));
}
}
?>
تابع index داخله سطر وحيد يقوم بجلب كل المهمات (سنتخلى عنه في نهاية المشروع لأننا لانود أن نعرض لكل مستخدم المهمات كلها، أي مهماته ومهمات باقي المستخدمين لكننا سنستخدمها في الوقت الحالي للتأكد من عملنا.
هذا السطر يأخذ وسيطين، الوسيط الأول اسم المصفوفة التي سيتم تخزين البيانات التي ستجلب فيها والتي (المصفوفة) بدورها سنقوم بعرضها في view ولذلك لم نستخدم الإسناد العادي (var = val) لأن هذا التابع (set) يقوم بنقل المصفوفة إلى العرض (view) بيمنا الإسناد العادي تذهب قيمة متحوله عندما نخرج من الملف، والوسيط الثاني هو البيانات التي نريد جلبها وفي حالتنا نريد جلب (find) كل البيانات (all) من موديل (Task)، هل فهمتموها؟ أظن انها سهلة بهذا التفصيل.
انتهينا من طبقة المتحكم وبقي لنا طبقة العرض، بدون أن تكملوا القراءة هل تعرفون كم ملف نحتاجه للعرض؟
سنحتاج لملف واحد في طبقة العرض لأننا كتبنا تابعاً واحداً (index) في المتحكم، فالقاعدة هي لكل تابع في المتحكم ملف في العرض، طبعاً لهذه القاعدة شواذ لن نتعرض لها الآن.
توجه لمجلد views وأنشأ مجلداً باسم tasks ومن ثم أنشأ ملفاً اسمه index.ctp، وضع به التالي:
<div id="tasks"> <div class="title">المهمات</div> <?php if(empty($tasks)): ?> <p class="notasks">لايوجد لديك مهام بعد!</p> <?php else: ?> <ul class="taskslist"> <?php foreach ($tasks as $task): ?> <li> <?php echo $$task['Task']['title']; ?> </li> <?php endforeach; ?> </ul> <?php endif; ?> </div>
وضعنا في البداية جملة شرطية (if) لفحص مصفوفة tasks (التي جاءتنا من المتحكم وبالتحديد من الوسيط الأول في تابع set)، فإذا كانت فارغة (أي لايوجد مهام في جدول المهمات) فسنعرض رسالة بأنه لايوجد مهمات بعد، وإذا لم تكن فارغة فسنقوم بالدوران على قيمها باستخدام (foreach) التي تريحنا أكثر من (for)، والـ foreach باختصار تأخذ متحولين الأول هو المصفوفة والثاني متحول فارغ تقوم بتعبئته في كل دورة بعنصر من عناصر المصفوفة. وداخل الحلقة قمنا بطباعة اسم المهمة وبالتأكيد يمكنكم طباعة بقية الحقول لكن سنقوم بذلك في آخر المشروع (ذكروني إن نسيت
).
لحد الآن أظن أننا انتهينا من تدوينة اليوم ولكن هل لاحظتم شيئاً ناقصاً؟ نعم أين تابع إضافة مهمة. لدينا تابع وملف لعرض المهمات لكن لم نضف مهمة ونعرضها بعد. وحتى التدوينة القادمة انتظروا هذا ومن يود التعلم فعلاً فلبقم بها لوحده اعتماداً على معلومات التدوينة السابقة حيث وضعنا تابع لإضافة قائمة، ويبقى الجزء الصعب وهو إضافة المهمة وتحديد القائمة التي تنتمي لها
أعتقد أنكم ستحلوها بالطريقة البسيطة أي بدون تحديد قائمة.












وأخيراً، الله يبارك فيك لا تتأخر علينا بعد ^^.
.
تراني ما عندي مصدر غيرك
هناك نقص:
ماذا نضع؟؟
لامؤاخذة تمت الإضافة وتوقعتك تحل تابع الإضافة؟
[...] خلال التدوينة السابقة في سلسلة الكيك لم أرى أي تفاعل (عدا بعض التفاعل البسيط من الأخ عمر) [...]
السلام عليكم و رحمة الله و بركاته.
الحمد لله, لقد قمت بما أرشدت إليه أخي خالد.
كما قمت بإضافة دالة add في صنف TasksController على نفس وتيرة GroupsController. هذا بالنسبة لطبقة التحكم أما في طبقة العرض فكما أشرت تماما في الدروس السابقة أضفت ملف add.ctp و نسخ نفس محتوى نظيرة هذه الدالة بالنسبة لل Group مع تغيير بعض أسماء المتغيرات مثل title…
بالطبع فالطريقة المثلى المتبعة دائما بالنسبة للمبتدئيين هي (نسخ و لصق).
بانتظار حل مسألة ربط الجداول مع بعضهم البعض. بحيث كل مهمة تكون تابعة للقائمة التي تنتمي إليها.
ملاحظة : إعترضتني بعض المشاكل الغير منطقية و تبين أن سببها بيئة العمل Xampp مما اضطرني إلى إعادة تشغيل الحاسوب؟. و إعادة إنجاز بعض المراحل.
ممتاز جداً أخي عبد الولي … بالنسبة للمشاكل انحلت ولا لأ؟
نعم لقد إنحلت المشاكل و لله الحمد.
والله يا إخوان ترى الموضوع مهم جداً لكن رائع لقد أنتهيت من الأمر المطلوب