Yii Framework Forum: Yii Search With Multiple Condition, Please Help! - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Yii Search With Multiple Condition, Please Help! Thanks! Rate Topic: ***** 1 Votes

#1 User is offline   jiaming 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 262
  • Joined: 10-April 12

Posted 15 November 2012 - 11:11 PM

Dear all,

I have a friendship table to record users' friends.

I have the following columns : sender, receiver, accept.

E.g., If user 1 and user 10 are friends.

The table may be:
--------------------------
sender(1) receiver(10) accept(1)

Or

sender(10) receiver(1) accept(1)

--------------------------

I want to achieve the following effect, so the user can search all his friends, they may be in either sender or receiver field..

Here is what I have now

	public function search()
	{
		// Warning: Please modify the following code to remove attributes that
		// should not be searched.

		$criteria=new CDbCriteria;

                $criteria->with = array('senderx'); //my relations to the User model.
                $criteria->compare('username', $this->friend,true);

                $criteria->condition = '(receiver=:uId) OR (sender=:uId)';
                $criteria->params = array(    
                     ':uId' => Yii::app()->user->id,  
               );  


		return new CActiveDataProvider($this, array(
    'criteria'=>$criteria,
    'pagination'=>array(
        'pageSize'=>10,
    ),
		));
	}




<?php echo CHtml::link('Search Friends','#',array('class'=>'search-button btn btn-primary')); ?>
<div class="search-form" style="display:none">
<?php $form=$this->beginWidget('CActiveForm', array(
	'action'=>Yii::app()->createUrl($this->route),
	'method'=>'get',
)); ?>

	<div class="row">
		<?php echo $form->textField($search,'friend'); ?>
	</div>

	<div class="row buttons">
		<?php echo CHtml::submitButton('Search',array('class'=>'btn btn-success')); ?>
	</div>

<?php $this->endWidget(); ?>



All I want is .... a default page display user's friends(either in sender/receiver fields).

You can search the username of the sender/receiver and update the dataprovider....

Any ideas? Big thanks!


Right now it displays all the friends correctly, but the search function is totally useless...
0

#2 User is offline   Rajith R 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 879
  • Joined: 20-April 11
  • Location:India

Posted 16 November 2012 - 01:21 AM

now u r rendering with the
'criteria'=>$criteria 



what u actually want?
Rajith Ramachandran,
Wiwo inc.
| Mobile: 919995504508
0

#3 User is offline   KonApaz 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 1,323
  • Joined: 21-February 11
  • Location:Greece

Posted 16 November 2012 - 04:12 AM

Hi jiaming

the search() seems correct in general way.
Why didn't use the CGridView widget to test your issue? (or use in general way)
Yii is the best php framework in the world!
find our demo Yii extension on www.webkit.gr
Is it post useful? please v++ ;)
0

#4 User is offline   jiaming 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 262
  • Joined: 10-April 12

Posted 16 November 2012 - 03:46 PM

View PostKonApaz, on 16 November 2012 - 04:12 AM, said:

Hi jiaming

the search() seems correct in general way.
Why didn't you use the CGridView widget to test your issue? (or use in general way)



I tried but doesn't work....the search is not working at all : (

But if I delete the whole condition part, it works(through not my purpose)
0

#5 User is offline   jiaming 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 262
  • Joined: 10-April 12

Posted 16 November 2012 - 03:48 PM

View PostRajith R, on 16 November 2012 - 01:21 AM, said:

now u r rendering with the
'criteria'=>$criteria 



what u actually want?

I am not sure I understand your point...?Shouldn't I use
'criteria'=>$criteria 
?

Thanks
0

#6 User is offline   phtamas 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 529
  • Joined: 26-February 11
  • Location:Mezőtúr, Hungary

Posted 17 November 2012 - 07:14 AM

$criteria->condition = '(receiver=:uId) OR (sender=:uId)';
overwrites all conditions previously set by $criteria->compare(). Use CDbCriteria::addCondition() instead.
0

#7 User is offline   jiaming 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 262
  • Joined: 10-April 12

Posted 17 November 2012 - 12:03 PM

View Postphtamas, on 17 November 2012 - 07:14 AM, said:

$criteria->condition = '(receiver=:uId) OR (sender=:uId)';
overwrites all conditions previously set by $criteria->compare(). Use CDbCriteria::addCondition() instead.


Thanks for your help...Now the list is displaying properly. But the serach function is still not working...

I want the user search username of either receiver/sender and get the list....

Is there a way to do so?

	public function search()
	{
		// Warning: Please modify the following code to remove attributes that
		// should not be searched.

		$criteria=new CDbCriteria;

                $criteria->with = array('senderx');
                $criteria->addCondition('username', $this->friend,true);

                $criteria->addCondition('receiver=:uId','OR');
                $criteria->addCondition('sender=:uId','OR');

                $criteria->params = array(    
                     ':uId' => Yii::app()->user->id,  
               );  

		return new CActiveDataProvider($this, array(
    'criteria'=>$criteria,
    'pagination'=>array(
        'pageSize'=>10,
    ),

		));
	}


<?php 
echo CHtml::link('Search Friends','#',array('class'=>'search-button btn btn-primary')); ?>
<div class="search-form" style="display:none">
<?php $form=$this->beginWidget('CActiveForm', array(
	'action'=>Yii::app()->createUrl($this->route),
	'method'=>'get',
)); ?>

	<div class="row">
		<?php echo $form->textField($search,'friend'); ?>
	</div>

	<div class="row buttons">
		<?php echo CHtml::submitButton('Search',array('class'=>'btn btn-success')); ?>
	</div>

<?php $this->endWidget(); 
?>



'friend' is only a property I initialized, not a column in database.

THank you!
0

#8 User is offline   jiaming 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 262
  • Joined: 10-April 12

Posted 18 November 2012 - 03:33 AM

View PostKonApaz, on 16 November 2012 - 04:12 AM, said:

Hi jiaming

the search() seems correct in general way.
Why didn't you use the CGridView widget to test your issue? (or use in general way)


Hi, thanks for your help...I just modified my code... Would you please have a look at it?

Even if I replace condition with addcondition, it still not works...
0

#9 User is offline   softark 

  • Keep It Simple
  • Yii
  • Group: Moderators
  • Posts: 2,082
  • Joined: 16-February 11
  • Location:Japan

Posted 18 November 2012 - 05:14 AM

                $criteria->addCondition('receiver=:uId OR sender=:uId2','AND');
                $criteria->params = array(    
                     ':uId' => Yii::app()->user->id,  
                     ':uId2' => Yii::app()->user->id,  
               );  

You have to use a different place holder for each condition, even if it is the same thing.

And I thought the following is not what you want:
                $criteria->addCondition('username', $this->friend,true);
                $criteria->addCondition('receiver=:uId','OR');
                $criteria->addCondition('sender=:uId2','OR');

This means:
(('username' = $this->friend) OR 'receiver' = user) or 'sender' = user


What you want should be:
('username' = $this->friend) AND ('receiver' = user or 'sender' = user)

0

#10 User is offline   jiaming 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 262
  • Joined: 10-April 12

Posted 18 November 2012 - 01:20 PM

View Postsoftark, on 18 November 2012 - 05:14 AM, said:

                $criteria->addCondition('receiver=:uId OR sender=:uId2','AND');
                $criteria->params = array(    
                     ':uId' => Yii::app()->user->id,  
                     ':uId2' => Yii::app()->user->id,  
               );  

You have to use a different place holder for each condition, even if it is the same thing.

And I thought the following is not what you want:
                $criteria->addCondition('username', $this->friend,true);
                $criteria->addCondition('receiver=:uId','OR');
                $criteria->addCondition('sender=:uId2','OR');

This means:
(('username' = $this->friend) OR 'receiver' = user) or 'sender' = user


What you want should be:
('username' = $this->friend) AND ('receiver' = user or 'sender' = user)



Thanks for your help...I revised my code like the following now:

	public function search()
	{
		// Warning: Please modify the following code to remove attributes that
		// should not be searched.

		$criteria=new CDbCriteria;

                $criteria->with = array('senderx');  
                $criteria->with = array('receiverx');

/*******this are codes in my relationships**********
          'senderx' => array(self::BELONGS_TO, 'Users', 'sender'),  
           'receiverx' => array(self::BELONGS_TO, 'Users', 'receiver'),
****************************************************/

                $criteria->compare('username', $this->friend,true);

                $criteria->addCondition('receiver=:uId1','OR');
                $criteria->addCondition('sender=:uId2','OR');

                $criteria->params = array(    
                     ':uId1' => Yii::app()->user->id,  
                     ':uId2' => Yii::app()->user->id,  
               );  

		return new CActiveDataProvider($this, array(
    'criteria'=>$criteria,
    'pagination'=>array(
        'pageSize'=>10,
    ),

		));
	}



In the view:
<?php echo CHtml::link('Search Friends','#',array('class'=>'search-button btn btn-primary')); ?>
<div class="search-form" style="display:none">
<?php $form=$this->beginWidget('CActiveForm', array(
	'action'=>Yii::app()->createUrl($this->route),
	'method'=>'get',
)); ?>

	<div class="row">
		<?php echo $form->textField($search,'friend'); ?>
	</div>

	<div class="row buttons">
		<?php echo CHtml::submitButton('Search',array('class'=>'btn btn-success')); ?>
	</div>

<?php $this->endWidget(); ?>


However, The search function is not working at all. No matter what I Input ,the dataprovider will not be updated AFTER I ADD ANY CONDITIONS in search();

Any ideas?

Thank you very much for your help!! I really appreciate it!!
0

#11 User is offline   softark 

  • Keep It Simple
  • Yii
  • Group: Moderators
  • Posts: 2,082
  • Joined: 16-February 11
  • Location:Japan

Posted 18 November 2012 - 07:02 PM

Ah, I'm very sorry. I was wrong.
Would you please try this one?
               $criteria->compare('username', $this->friend,true);

                $criteria->addCondition('receiver=:uId1','OR');
                $criteria->addCondition('sender=:uId2','OR');

                $criteria->params[':uId1'] = Yii::app()->user->id,  
                $criteria->params[':uId2'] = Yii::app()->user->id,  

'$criteria->compare()' will set an item in $criteria->params for it, and we should not overwrite it.
0

#12 User is offline   jiaming 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 262
  • Joined: 10-April 12

Posted 18 November 2012 - 07:07 PM

View Postsoftark, on 18 November 2012 - 07:02 PM, said:

Ah, I'm very sorry. I was wrong.
Would you please try this one?
               $criteria->compare('username', $this->friend,true);

                $criteria->addCondition('receiver=:uId1','OR');
                $criteria->addCondition('sender=:uId2','OR');

                $criteria->params[':uId1'] = Yii::app()->user->id,  
                $criteria->params[':uId2'] = Yii::app()->user->id,  

'$criteria->compare()' will set an item in $criteria->params for it, and we should not overwrite it.


Hi, thanks so much for your help!

I tried but still, the list is still not updating at all. no matter what i input in the search field. I want the user input the username so it updated the list...

I believe the problem is the "friend" property.. Can I really get username from either receiverx or senders(my 2 relations) in this way?

Here is my complete code now.

		$criteria=new CDbCriteria;

                $criteria->with = array('senderx');
                $criteria->with = array('receiverx');

                $criteria->compare('username', $this->friend,true);

                $criteria->addCondition('receiver=:uId1','OR');
                $criteria->addCondition('sender=:uId2','OR');

                $criteria->params[':uId1'] = Yii::app()->user->id;  
                $criteria->params[':uId2'] = Yii::app()->user->id;  



	public function relations()
	{
		// NOTE: you may need to adjust the relation name and the related
		// class name for the relations automatically generated below.
		return array(
               'senderx' => array(self::BELONGS_TO, 'Users', 'sender'),
               'receiverx' => array(self::BELONGS_TO, 'Users', 'receiver'),
		);
	}


Thanks !!
0

#13 User is offline   softark 

  • Keep It Simple
  • Yii
  • Group: Moderators
  • Posts: 2,082
  • Joined: 16-February 11
  • Location:Japan

Posted 18 November 2012 - 07:15 PM

It might be because you are combining the conditions with 'OR'.
Your current code means:
(('username' = $this->friend) OR 'receiver' = user) or 'sender' = user

So I guess this is what you want.
                $criteria->compare('username', $this->friend,true);
                $criteria->addCondition('receiver=:uId1 OR sender=:uId2','AND');
                $criteria->params[':uId1'] = Yii::app()->user->id;  
                $criteria->params[':uId2'] = Yii::app()->user->id;

This means:
('username' = $this->friend) AND ('receiver' = user or 'sender' = user)

0

#14 User is offline   jiaming 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 262
  • Joined: 10-April 12

Posted 18 November 2012 - 07:25 PM

View Postsoftark, on 18 November 2012 - 07:15 PM, said:

It might be because you are combining the conditions with 'OR'.
Your current code means:
(('username' = $this->friend) OR 'receiver' = user) or 'sender' = user

So I guess this is what you want.
                $criteria->compare('username', $this->friend,true);
                $criteria->addCondition('receiver=:uId1 OR sender=:uId2','AND');
                $criteria->params[':uId1'] = Yii::app()->user->id;  
                $criteria->params[':uId2'] = Yii::app()->user->id;

This means:
('username' = $this->friend) AND ('receiver' = user or 'sender' = user)




I revised the code to

                $criteria->compare('username', $this->friend,true);
                $criteria->addCondition('receiver=:uId1 OR sender=:uId2','AND');
                $criteria->params[':uId1'] = Yii::app()->user->id;  
                $criteria->params[':uId2'] = Yii::app()->user->id;


However, if i use
 $criteria->compare('username', $this->friend,true);
, and "friend" property in the view page, the list is still not updating.

If I change "friend" to "sender", it works, but of course it's not going to achieve my goal (because the user may type in the receiver too. since receiver is also your friends)..

THANK YOU!
0

#15 User is offline   softark 

  • Keep It Simple
  • Yii
  • Group: Moderators
  • Posts: 2,082
  • Joined: 16-February 11
  • Location:Japan

Posted 18 November 2012 - 08:28 PM

I don't understand what $this->friend is for ... do you want to search friends by their name?

               $criteria->compare('username', $this->friend,true);

What the above means is that you are comparing "friend" with the user's own name ... It's very natural that you get no results (zero records) when you input some name other than the user's own name.
0

#16 User is offline   jiaming 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 262
  • Joined: 10-April 12

Posted 18 November 2012 - 08:32 PM

View Postsoftark, on 18 November 2012 - 08:28 PM, said:

I don't understand what $this->friend is for ... do you want to search friends by their name?

               $criteria->compare('username', $this->friend,true);

What the above means is that you are comparing "friend" with the user's own name ... It's very natural that you get no results (zero records) when you input some name other than the user's own name.


I want the user input either sender or receiver's name in the field, basically, the user input a name in the field, I determine that among all friends of the users,(receiver/sender = :uid), whose username is the user's input.

For example, in my database:

sender:1 receiver:2

sender:5 receiver:1

For user1, his friends are 2 and 5. I want him enter a name and find 2 or 5...


I can't have 2 fields and let user input your friend is receiver or sender...I want the server to decide...

friend is simply a property i declared in my model, its not a column of my table... And now i get ALL results no matter what i input for the friends field. not zero...

Thanks so much again for your help! I really appreciate it.
0

#17 User is offline   softark 

  • Keep It Simple
  • Yii
  • Group: Moderators
  • Posts: 2,082
  • Joined: 16-February 11
  • Location:Japan

Posted 18 November 2012 - 09:16 PM

I see.
Then you have to compare $this->friend with 'senderx.username' or 'receiverx.username', assuming that 'senderx' and 'receiverx' has an attribute of 'username'.

It's a little complicated ...
$criteria = new CDbCriteria();
$criteria->with = array('senderx', 'receiverx');
$criteria->compare('t.sender', Yii::app()->user->id);
$criteria->compare('t.receiver', Yii::app()->user->id, false, 'OR');
if ($this->friend != '')
{
	$criteria2 = new CDbCriteria();
	$criteria2->compare('senderx.username', $this->friend, true);
	$criteria2->compare('receiverx.username', $this->friend, true, 'OR');
	$criteria->mergeWith($criteria2);
}

By using 'compare', you can forget the params of the criteria. Of course you can use addCondition method instead.
Sometimes you have to merge multiple criteria when your conditions involve complicated 'AND's and 'OR's.
Please look up 'compare', 'mergeWith' in the reference for details.
0

#18 User is offline   jiaming 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 262
  • Joined: 10-April 12

Posted 18 November 2012 - 10:57 PM

View Postsoftark, on 18 November 2012 - 09:16 PM, said:

I see.
Then you have to compare $this->friend with 'senderx.username' or 'receiverx.username', assuming that 'senderx' and 'receiverx' has an attribute of 'username'.

It's a little complicated ...
$criteria = new CDbCriteria();
$criteria->with = array('senderx', 'receiverx');
$criteria->compare('t.sender', Yii::app()->user->id);
$criteria->compare('t.receiver', Yii::app()->user->id, false, 'OR');
if ($this->friend != '')
{
	$criteria2 = new CDbCriteria();
	$criteria2->compare('senderx.username', $this->friend, true);
	$criteria2->compare('receiverx.username', $this->friend, true, 'OR');
	$criteria->mergeWith($criteria2);
}

By using 'compare', you can forget the params of the criteria. Of course you can use addCondition method instead.
Sometimes you have to merge multiple criteria when your conditions involve complicated 'AND's and 'OR's.
Please look up 'compare', 'mergeWith' in the reference for details.


Thank you very much...It works like a charm now... : ]

Thanks again for your help! I really appreciate this!
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users