I've stumbled upon an issue with my user to user block feature.
I don't know how to write my SELECT
to get the right results. When User1 blocks user2 both users can't see each others profiles but when I log in I can see my own account. I'm using a switch to do this.
My BLOCK
table consists of ID
, USER1_ID
, USER2_ID
and STATUS
. 0
being 'viewable' and 1
being 'blocked'.
Function.user
public function check_block($user1_id,$user2_id){
$check_sql= "SELECT ......";
$check_query = mysql_query($check_sql)or die(mysql_error());
$check_num = mysql_num_rows($check_query);
if($check_num>0){
$block = mysql_fetch_array($check_query);
return $block['status'];
}else{
return $check_num;
}
}
SWITCH
<?
$user1_id=$_SESSION['id'];
$user2_id=$data['id'];
$userblock = function_user_core::check_block($user1_id,$user2_id);
switch($userblock){
case 1:
echo'You Are Blocked From Viewing This Users Profile';
break;
}
?>
Field Blocked In User profile
<? if($userblock==1) { ?>
THIS USER HAS BLOCKED YOU FROM THEIR ACCOUNT
<? } ?>
It looks like you are asking for an example query.
It looks like you need a query that will test for the existence of a row in the block
table where the status
is set to "blocked" (1) for a given pair of users. From the wording of your question, it looks like the order of the user_id values doesn't matter. It doesn't matter (to this query) whether 'foo' blocked 'bar' or 'bar' blocked 'foo', or both. It looks like your code is going to execute the same exact path in all of those cases. (If I understood your question correctly.)
This query should get that:
SELECT b.status
FROM block b
WHERE ( b.status = 1 AND b.user1_id = 'foo' AND b.user2_id = 'bar' )
OR ( b.status = 1 AND b.user1_id = 'bar' AND b.user2_id = 'foo' )
LIMIT 1
NOTE: this query doesn't account for the corner case where user has blocked himself. See below for a query that also handles that condition.
I've used literals 'foo' and 'bar' in my example query, where you would of course substitute your (properly escaped) variables in the SQL text.
For this check query, it only needs to return a row if it finds a row that specifies that a given pair of users is "blocked". Otherwise, the query doesn't need to return any rows. With this query, your code can actually be a little simpler. Using this query, you could simply return the value from mysql_num_rows.
That is, you could replace this block:
$check_num = mysql_num_rows($check_query);
if($check_num>0){
$block = mysql_fetch_array($check_query);
return $block['status'];
}else{
return $check_num;
}
With this:
$check_num = mysql_num_rows($check_query);
return $check_num;
The query above doesn't account for the (unusual?) corner case, where a user has blocked himself.
If the table contains a row like this:
('foo','foo',1)
And you pass in values of 'foo' and 'foo' as user_1 and user_2, the query above will return a row. But you specified that a user should always be able to view their own profile.
So, if you want to ignore any rows that specify the condition where a user has "blocked" himself from his own profile, you can add another predicate in your query, to simply disregard any rows where the user_id values match:
SELECT 1 AS `status`
FROM block b
WHERE b.user1_id <> b.user2_id
AND b.status = 1
AND ( ( b.user1_id = 'foo' AND b.user2_id = 'bar' )
OR ( b.user2_id = 'foo' AND b.user1_id = 'bar' )
)
LIMIT 1
Also note that if there are conflicting rows in the table, that is, one raw that says the user pair is "blocked" and another row that says the pair is not blocked, the "blocked" status will take precedence.
Note that we don't even really need to return the status
column, we can return a literal value (with an appropriate alias to provide the result set metadata your code is expecting.)
It doesn't look like you have any problem in your code, though I likely would have coded it a bit differently. The important thing is that it is understandable, and that it works.
UPDATE:
Sorry it's not working for you. Here is a SQL Fiddle demonstration of the query I provided.
http://sqlfiddle.com/#!2/21120/2
It's most likely that I misunderstood what you were trying to accomplish with your query. What my query achieves is, if
then when passed in parameters of ('foo','bar')
or ('bar','foo')
(in either order), the query returns a row with status = 1.
Otherwise, that is, if neither user has 'blocked' the other, the query returns no rows.
It's important in the query that each of the two supplied "user_id" parameters be supplied twice, in the correct positions. (It's possible to rewrite the query so that each of the arguments only need to be supplied once, but that query isn't as easy (for me) to understand.)