بسم الله الرحمن الرحيم
السلام عليكم ورحمة الله وبركاته
أعلم أنه قد تم التطرق إلى هذا الأمر عدة مرات وبأساليب مختلفة، ولم أر ضيراً في الإدلاء بدلو صغير جداً في الموضوع، فعسى أن لا يضيق خادم الموقع ولا قلوب كاتبيه الكبيرة عن مثل هذه المشاركة.
الكلام عن الأقسام المتفرعة بغير تناه يكون على ثلاثة مقامات:
الأول بنية الجداول في قاعدة البيانات، وهذه قد استقر القول فيها على الاكتفاء بجدول واحد له بنية مشابهة للتالي:
وكما نرى فإن الحقول الثلاثة المذكورة هي أهم ما هنالك، ويمكن أن تزيد عليها ما يحتاجه برنامجك كوصف للقسم أو تاريخ إضافة ونحو ذلك.كود:CREATE TABLE `cats` ( `id` int(11) NOT NULL auto_increment, `name` varchar(50) NOT NULL default '', `parent` int(11) NOT NULL default '0', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=cp1256 AUTO_INCREMENT=9 ;
الثاني قراءة الأقسام من الجداول وتنظيمها في الذاكرة، وهنا كان أكثر الاختلاف في الخوارزميات التي قرأتها في هذا الموقع الجميل، وفيما يلي الطريقة التي أفضلها:
الصف (Class) الرئيس هو Cat ويعرف على النحو التالي:
ويستخدم هذا الصف من داخل البرنامج على النحو التالي:كود PHP:class Cat {
var $id;
var $name;
var $parentid;
var $children;
function Cat($i, $n, $p) {
}
function addChild(&$child) {
}
function display() {
}
}
وطبعاً يدور في خلد البعض سؤال ملح وهو: ما ذا يوجد داخل صناديق الدوال المشار إليها أعلاه؟كود PHP:if (!isset($catid)) $catid=0;
$cats = new Cat(0, 'All categories', -1);
$catQ = array();
$sel_stmnt = "SELECT id, name, parent FROM $cats_table";
$results= mysql_query($sel_stmnt);
while ($record = mysql_fetch_row($results)) {
list($cid, $cname, $cparent) = $record;
if (! $cats->addChild($child=new Cat($cid, $cname, $cparent)))
array_push($catQ, $child);
}
while (count($catQ)>0)
if (! $cats->addChild($child=array_shift($catQ)))
array_push($catQ, $child);
والجواب كالتالي:
دالة البناء:
دالة الإضافة:كود PHP:function Cat($i, $n, $p) {
$this->id=$i;
$this->name=$n;
$this->parentid=$p;
$this->children = array();
}
أود التنبيه إلى أن المتغيرين $parentsbag و $childrenbag ليسا أساسيين في الطريقة المقترحة لكنهما يوفران أداتين مفيدتين جداً يمكن استخدامهما في مواضع أخرى من البرنامج، كما في طريقة العرض الشجرية مثلاً، وعلى العموم، في حال استخدامها يجب التصريح عنهما قبل تعريف الصف.كود PHP:function addChild(&$child) {
global $catid, $childrenbag, $parentsbag;
if ($added=($child->parentid==$this->id))
$this->children[$child->id]=$child;
else foreach ($this->children as $cid => $cchild)
if ($added = $this->children[$cid]->addChild($child)) break;
if ($added) {
if ($this->id == $catid) $childrenbag[] = $child->id;
if ($child->id == $catid) $parentsbag[]=$this->id;
}
return $added;
}
المقام الثالث: هو عرض الأقسام، وهو أمر سهل ميسور بعد أن أصبحت الأقسام وتفريعاتها موجودة عندنا مرتبة، فيمكن أن تختار طريقة العرض الشجرية أو طريقة القائمة المنسدلة، أيهما أنسب لك، وذلك باستدعاء:
على سبيل المثال، هذا التعريف لدالة display يعرض الأقسام على شكل تفريع شجري شهير، ويستخدم ثلاثة صور لتمثيل العقد: واحدة لتمييز القسم المختار، وأخرى لتمييز أبناء هذا القسم وإن دنوا، والثالثة لتمييز آبائه وإن علوا، وصوراً أخرى للمسارات والخطوط.كود PHP:echo $cats->display();
وهذا أوان الإمساك عن فضول الكلام، ففيما تقدم الكفاية، والمرجو من القراء الكرام المسامحة على ما زاد عن الحد.كود PHP:function display() {
global $catid, $catchildren, $childrenbag, $parentsbag, $treestring;
if ($A=($this->id==$catid)) $catchildren =true;
if ((in_array($this->id, $parentsbag)) || ($A) || (in_array($this->id, $childrenbag))) {
$treestring .= '<table class="treeview" cellpadding="0" cellspacing="0" ><tr><td><img src="'.(($A)?'c':(($catchildren)?'o':'p')).'folder.gif" alt="" /></td>';
$treestring .= '<td> <span class="linkcat" onClick="loadCat('.($this->id).')">'.($this->name).'</span></td></tr>';
if (count($this->children)>0) {
foreach ($this->children as $key=>$catchild) {
if ((in_array($catchild->id, $parentsbag)) || ($catchild->id==$catid) || (in_array($catchild->id, $childrenbag))) {
$treestring .= '<tr><td'.(($key==max(array_keys($this->children))|| ($catchild->id==$catid) || (in_array($catchild->id,$parentsbag)))?'><img src="imgs/tvln':' class="tvnlastnode"><img src="tvnln').'.gif" alt="" /></td><td>';
$catchild->display();
$treestring .= '</td></tr>';
}
}
}
$treestring .= '</table>';
}
if ($this->id ==0) return $treestring;
}
}
والله تعالى أعلم.
أخوكم : أحمد


رد مع اقتباس

