PDA

View Full Version : شجره نامه با Yii



Amir_f
شنبه 23 فروردین 1393, 09:29 صبح
من دارم برای خودم یک شجره نامه می سازم
امکانات فعلی که داره فعلا در همین حد هست که یک کاربر می تونه : 1-پدر 2- مادر 3-همسر 4- فرزندانش رو ببینه
جدول کاربران به شکل زیر است ( شاید نوع فیلد ها رو درست تعیین نکرده باشم )

<?php
class m140411_160139_create_tbl_user extends CDbMigration
{
public function up()
{
$this->createTable('tbl_user',
array(
'id'=>'pk',
'name'=>'string',
'family'=>'string',
'shsh'=>'string', // shomare shenasname
'tt'=>'datetime',
'vazeiyat'=>'int(2)',
'sex'=>'int(2)',
'hamsar_id'=>'int(11)',
'father_id'=>'int(11)',
'mother_id'=>'int(11)',

), 'ENGINE=InnoDB'
);

$this->addForeignKey("hamsar", "tbl_user", "hamsar_id", "tbl_user", "id", "CASCADE", "CASCADE");
$this->addForeignKey("father", "tbl_user", "father_id", "tbl_user", "id", "CASCADE", "CASCADE");
$this->addForeignKey("mother", "tbl_user", "mother_id", "tbl_user", "id", "CASCADE", "CASCADE");
}

public function down()
{
$this->dropForeignKey("hamsar", "tbl_user");
$this->dropForeignKey("father", "tbl_user");
$this->dropForeignKey("mother", "tbl_user");
$this->dropTable('tbl_user');
}

}

اینم کدم برای نمایش توی index.php



<?php

$user =USER::model()->find('id=?',array($_GET["uid"]));
?>
<?php if ($user->vazeiyat !== 0 ): ?>
<div class="bb">
<img src="<?php echo 'http://localhost/tree/images/'.$user->id.'.png' ?>"/>
<?php if ($user->hamsar !== null): ?> <!-- ازدواج کرده -->
<img src="<?php echo 'http://localhost/tree/images/'.$user->hamsar->id.'.png' ?>"/>
<?php endif ; ?>
</div>
<?php
if ($user->sex == 1 ) { // گاربر مرداست
$childs = USER::model()->findAll('father_id=?', array($_GET["uid"]));
} else { // کاربر زن است
$childs = USER::model()->findAll('mother_id=?', array($_GET["uid"]));
}
?>
<?php foreach ($childs as $chi): ?> <!-- فرزندان در صورت داشتن فرزند -->
<div class="bb chi">
<img src="<?php echo 'http://localhost/tree/images/'.$chi->id.'.png' ?>" />
<?php if ($chi->hamsar !== null): ?> <!-- فرزنذ ازدواج کرده -->
<img src="<?php echo 'http://localhost/tree/images/'.$chi->hamsar->id.'.png' ?>" />
<br/>
<?php endif; ?>
<?php
if ($chi->sex == 1 ) { // فرزند پسر است
$nave = USER::model()->findAll('father_id=?', array($chi->id));
} else { // فرزند دختر است
$nave = USER::model()->findAll('mother_id=?', array($chi->id));
}
?>
<br/>
<?php foreach ($nave as $navee): ?> <!-- نوه !!!!! -->

<img src="<?php echo 'http://localhost/tree/images/'.$navee->id.'.png' ?>" />
<?php if ($navee->hamsar !== null): ?>
<img src="<?php echo 'http://localhost/tree/images/'.$navee->hamsar->id.'.png' ?>" />
<?php endif; ?>
<?php endforeach; ?>

</div>
<?php endforeach; ?>

<?php endif ?>



من الان برای هر نسل نمیتونم از تابع برگشتی استفاده کنم که به کمکش اگه کاربری چند نسل از مشخصات اعضای خانوادش در دیتابیس بود بتونه تصاویر همه شون رو ببینه ، یعنی هر نسل رو توی یک ردیف . ( اگه امکانش هست راهنماییم کنید ) به عنوان مثال کاربر 1 اگه پدر بزرگ کاربر 5 باشه مشکلی نداره (عکس خودش 1 و همسرش 2 نمایش داده میشه در خط بعدی عکس پسرش 3 و همسر پسرش 4 نمایش داده میشه و در ردیف بعدی هم عکس نوه اش که 5 هست ولی دیگه از اینجا نسل بعدی رو در صورت وجود داشتن نمیشه برای کاربر 1 نمایش داد
فعلا فقط می خوام به صورت یک درخت اعضای خانواده رو نشون بدم . و بعد مشخصاتی رو اضافه می کنم ( از قبیل تاریخ تولد ، نماد سال تولد و ... )

بنظرتون رابطه رو توی جدول درست تعریف کردم ؟

MMSHFE
شنبه 23 فروردین 1393, 13:16 عصر
قبل از اینکه راه حل مشکلتون رو بگم، یک مسئله رو درمورد قیدهایی که ساختین یادآوری کنم:
بهتره از CASCADE در اینجا برای عمل Delete استفاده نکنید (پارامتر اول از دو پارامتر آخری) چون اگه فرضاً رکورد همسر حذف بشه، باعث میشه کاربر مربوطه هم حذف بشه. بهتره بجاش از SET NULL استفاده کنید یعنی اگه یکی همسرش از سیستم حذف شد (مثلاً فوت کرد)، برگرده به جامعه مجردها !
ضمناً بهتره مدلها رو توی کنترلر فراخوانی کنید یا ترجیحاً از relationها استفاده کنید:
فایل Migration :

<?php
class m140411_160139_create_tbl_user extends CDbMigration
{
public function up()
{
$this->createTable('tbl_user',
array (
'id'=>'pk',
'name'=>'string',
'family'=>'string',
'shsh'=>'string',
'tt'=>'datetime',
'vazeiyat'=>'int(2)',
'sex'=>'int(2)',
'hamsar_id'=>'int(11)',
'father_id'=>'int(11)',
'mother_id'=>'int(11)',
), 'ENGINE=InnoDB'
);

$this->addForeignKey('hamsar', 'tbl_user', 'hamsar_id', 'tbl_user', 'id', 'SET NULL', 'CASCADE');
$this->addForeignKey('father', 'tbl_user', 'father_id', 'tbl_user', 'id', 'SET NULL', 'CASCADE');
$this->addForeignKey('mother', 'tbl_user', 'mother_id', 'tbl_user', 'id', 'SET NULL', 'CASCADE');
}

public function down()
{
$this->dropForeignKey('hamsar', 'tbl_user');
$this->dropForeignKey('father', 'tbl_user');
$this->dropForeignKey('mother', 'tbl_user');
$this->dropTable('tbl_user');
}
}
متد relations در فایل مدل User :

public function relations() {
return array(
'hamsar' => array(self::HAS_ONE, 'User', 'hamsar_id'),
'father' => array(self::BELONGS_TO, 'User', 'father_id'),
'mother' => array(self::BELONGS_TO, 'User', 'mother_id'),
'childrenOfMale' => array(self::HAS_MANY, 'User', 'father_id'),
'childrenOfFemale' => array(self::HAS_MANY, 'User', 'father_id'),
);
}
فایل view :

<?php if ($user->vazeiyat) : ?>
<div class="bb">
<img src="<?php echo Yii::app()->homeUrl . '/images/' . $user->id . '.png'; ?>" />
<?php if ($user->hamsar) : ?>
<img src="<?php echo Yii::app()->homeUrl . '/images/' . $user->hamsar->id . '.png'; ?>" />
<?php endif ; ?>
</div>
<?php foreach ($children as $child) : ?>
<div class="bb chi">
<img src="<?php echo Yii::app()->homeUrl . '/images/' . $child->id . '.png'; ?>" />
<?php if ($child->hamsar) : ?>
<img src="<?php echo Yii::app()->homeUrl . '/images/' . $child->hamsar->id . '.png'; ?>" />
<?php endif; ?>
<?php $grandChildren = ($child->sex ? $child->childrenOfMale : $child->childrenOfFemale);
<?php foreach ($grandChildren as $grandChild) : ?>
<img src="<?php echo Yii::app()->homeUrl . '/images/' . $grandChild->id . '.png'; ?>" />
<?php if ($grandChild->hamsar) : ?>
<img src="<?php echo Yii::app()->homeUrl . '/images/' . $grandChild->hamsar->id . '.png'; ?>" />
<?php endif; ?>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
<?php endif; ?>


<?php
public function actionIndex($uid) {
$user = User::model()->findByPk($uid);
if(!$user) {
throw new CHttpException(404, 'User not found.');
}
$this->render('index', array(
'user' => $user,
'children' => ($user->sex ? $user->childrenOfMale : $user->childrenOfFemale);
));
}
نحوه صدا زدن ویو در کنترلر:

public function actionIndex($uid) {
$user = User::model()->findByPk($uid);
if(!$user) {
throw new CHttpException(404, 'User not found.');
}
$this->render('index', array(
'user' => $user,
'children' => ($user->sex ? $user->childrenOfMale : $user->childrenOfFemale);
));
}

Amir_f
شنبه 23 فروردین 1393, 17:41 عصر
بابت راهنمایی تون ممنون
الان این مشکل هم حل میشه ؟ یعنی کاربری که نوه و نتیجه هم داره میتونه اونها رو هم ببینه ؟ یا فقط تا نوه هاشو میتونه ببینه ( یعنی کاربر 1 کاربر 10 رو میبینه یا فقط تا کاربر 9 رو میبینه)
117888
منظورم اینه مثل عکس بالا کاربر با ای دی 1 میتونه نتیجه خودش رو هم ببینه با کدی که الان داریم یا باید تغییر کنه کدمون .
حالا اگه کاربر چند نسل بعد خودش هم داخل سایت بود یعنی مثلا نوه ی ، نتیجه اش ! آیا اونم میتونه ببینه یا باید تابع بازگشتی نوشته بشه

ممنون

tux-world
شنبه 23 فروردین 1393, 20:38 عصر
یه سوال خارج از بحث. جرا اینقدر تگ php رو باز و بسته کردید؟ خیلی خیلی شلوغ کرده. وقتی خط پایین هم دارید از php استفاده میکنید دیگه نیازی نیست که ببندید و هی باز کنید. انقدر شلوغه حوصلم نکشید کدتون رو بخونم

Amir_f
شنبه 23 فروردین 1393, 21:13 عصر
یه سوال خارج از بحث. جرا اینقدر تگ php رو باز و بسته کردید؟ خیلی خیلی شلوغ کرده. وقتی خط پایین هم دارید از php استفاده میکنید دیگه نیازی نیست که ببندید و هی باز کنید. انقدر شلوغه حوصلم نکشید کدتون رو بخونم

دقیقا کجا دوست عزیز ؟
من واسه اینکه تگ ها html رو راحت بزنم اینطوری زدم و دیگه نیومدم از echo استفاده کنم و تگ های img رو توی php بنویسم که نمایش بده

tux-world
یک شنبه 24 فروردین 1393, 01:20 صبح
مثلا:


<?php endif; ?>
<?php $grandChildren = ($child->sex ? $child->childrenOfMale : $child->childrenOfFemale);
<?php foreach ($grandChildren as $grandChild) : ?>

Amir_f
یک شنبه 24 فروردین 1393, 10:32 صبح
مثلا:


<?php endif; ?>
<?php $grandChildren = ($child->sex ? $child->childrenOfMale : $child->childrenOfFemale);
<?php foreach ($grandChildren as $grandChild) : ?>


بخاطر اینکه if رو به شکل زیر باز کردیم




<?php if ($child->hamsar) : ?>
باید این طوری ببندیمش




<?php endif; ?>

tux-world
یک شنبه 24 فروردین 1393, 10:53 صبح
البته توصیه من اینه که از براکتها استفاده کنید. خانایی کدتون رو خیلی میبره بالا مخصوصا وقتی که از IDE استفاده میکنید میتونین بفهمین کجا باز شده کجا بسته.

Amir_f
یک شنبه 24 فروردین 1393, 13:00 عصر
بابت راهنمایی تون ممنون
الان این مشکل هم حل میشه ؟ یعنی کاربری که نوه و نتیجه هم داره میتونه اونها رو هم ببینه ؟ یا فقط تا نوه هاشو میتونه ببینه ( یعنی کاربر 1 کاربر 10 رو میبینه یا فقط تا کاربر 9 رو میبینه)
117888
منظورم اینه مثل عکس بالا کاربر با ای دی 1 میتونه نتیجه خودش رو هم ببینه با کدی که الان داریم یا باید تغییر کنه کدمون .
حالا اگه کاربر چند نسل بعد خودش هم داخل سایت بود یعنی مثلا نوه ی ، نتیجه اش ! آیا اونم میتونه ببینه یا باید تابع بازگشتی نوشته بشه

ممنون

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

MMSHFE
یک شنبه 24 فروردین 1393, 13:16 عصر
اگه تعداد سطح ها نامحدوده، بله باید بازگشتی کار کنید. الآن کدی که من نوشتم فقط تا نوه رو نشون میده (9 در تصویری که گذاشتین).