PDO UNION function only processes first SELECT statement - mysql

Okay so I have three different types of users (Developers, Designers & Employers) all of whom have different database tables. I have successfully developed a script that can log in a user from any of the three user tables using UNION. However I have now introduced email verification on sign up so I need to test whether the 'confirmed' field (in each table) has a value of '1' to process a successful login (if the value is 0, the user will not be able to log in).
public function email_confirmed($email) {
$query = $this->db->prepare("SELECT
COUNT(developers.id) FROM " . DB_NAME . ".developers WHERE developers.email= ? AND developers.confirmed = ?
UNION SELECT COUNT(designers.id) FROM " . DB_NAME . ".designers WHERE designers.email = ? AND designers.confirmed = ?
UNION SELECT COUNT(employers.id) FROM " . DB_NAME . ".employers WHERE employers.email = ? AND employers.confirmed = ?
");
$query->bindValue(1, $email);
$query->bindValue(2, 1);
$query->bindValue(3, $email);
$query->bindValue(4, 1);
$query->bindValue(5, $email);
$query->bindValue(6, 1);
try{
$query->execute();
$rows = $query->fetchColumn();
if($rows == 1){
return true;
}else{
return false;
}
} catch(PDOException $e){
die($e->getMessage());
}
}
At the moment however (using the function below), only a developer can log in. If you attempt to log in using a designer or an employer account, the error below shows. Any ideas why this is happening?
if ($users->email_confirmed($email) === false) {
$errors[] = 'Sorry, but you need to activate your account. Please check your emails.';
} else // carry on logging in user

This is your query:
SELECT COUNT(developers.id)
FROM " . DB_NAME . ".developers
WHERE developers.email= ? AND developers.confirmed = ?
UNION
SELECT COUNT(designers.id)
FROM " . DB_NAME . ".designers
WHERE designers.email = ? AND designers.confirmed = ?
UNION
SELECT COUNT(employers.id)
FROM " . DB_NAME . ".employers
WHERE employers.email = ? AND employers.confirmed = ?
It is fetching three rows, then removing duplicates, and ordering them arbitrarily. You are then reading the value (the count) from one of these rows.
Taking the approach you are taking, I think you want:
select COUNT(*)
from ((select 1
from " . DB_NAME . ".developers
where developers.email= ? AND developers.confirmed = ?
) union all
(select 1
from " . DB_NAME . ".designers
where designers.email = ? AND designers.confirmed = ?
) union all
(select 1
from " . DB_NAME . ".employers
where employers.email = ? AND employers.confirmed = ?
)
) t

Related

how i insert 1 data with 2 string? and insert into database?

i was doing a insert statement and i want 2 username become 1 data and insert into database. i no sure how to do it.
here is my php and mysql
$target = $_GET['user'];
$id = $_SESSION['id'];
$targetusername = mysqli_query($connection,"SELECT username FROM user WHERE id='$target' ")or die(mysqli_error($connection));
$username= mysqli_query($connection,"SELECT username FROM user WHERE id='$id'") or die(mysqli_error($connection));
$direct_message_room_name ="INSERT INTO direct_message_room(`direct_message_room_name`,`user_1_id`,`user_2_id`) VALUES (('$targetusername' + ' and ' + '$username'),'$id','$target')";
In order to have two variables in one column, you can serialize an array, though this is generally frowned upon unless it's for a good reason.
$array = array('username'=>'user1','username2'=>'user2');
$serialize = serialize($array);
Gives you:
a:2:{s:8:"username";s:5:"user1";s:9:"username2";s:5:"user2";}
Use the unserialize() function to return it to an array. Wordpress is one notable web application that stores arrays in such a way.
On a side note, you need to use bind parameter to avoid injectable sql queries:
// Do not do this
$target = $_GET['user'];
mysqli_query($connection,"SELECT username FROM user WHERE id='$target' ")
Here is a reference:
What does bind_param accomplish?
You can concat two strings in php like so:
$StringAB = $StringA . " something " . $StringB;
$target = $_GET['user'];
$id = $_SESSION['id'];
$targetusername = mysqli_query($connection,"SELECT username FROM user WHERE id='$target' ")or die(mysqli_error($connection));
$username= mysqli_query($connection,"SELECT username FROM user WHERE id='$id'") or die(mysqli_error($connection));
$rowUserName = mysql_fetch_array($username);
$rowTargetUserName = mysql_fetch_array($targetusername );
$room_name = $rowUserName["username"] . ' and ' . $rowTargetUserName["username"]; // Create room name (assuming both exist)
$direct_message_room_name ="INSERT INTO direct_message_room(`direct_message_room_name`,`user_1_id`,`user_2_id`) VALUES ('$room_name','$id','$target')";

Trying to sum MySQL value

I'm trying to sum my MySQL column value with number, here is my php script, i dont think im doing in right way. I was searching in stackoweflow but i havent found how to sum with specific number, not with other column.
<?php
$currentUser = isset($_POST['currentUser']) ? $_POST['currentUser'] : '';
$currentTasken = isset($_POST['currentTasken']) ? $_POST['currentTasken'] : '';
$con = mysql_connect("localhost", "root", "") or die(mysql_error());
if(!$con)
die('Could not connectzzz: ' . mysql_error());
mysql_select_db("foxi" , $con) or die ("could not load the database" . mysql_error());
$check = mysql_query("SELECT * FROM dotp_task_log");
$numrows = mysql_num_rows($check);
if($numrows >= 1)
{
//$pass = md5($pass);
$ins = mysql_query("INSERT INTO dotp_task_log (task_log_creator, task_log_Task) VALUES ('$currentUser' , '$currentTasken')" ) ;
if($ins)
$check = mysql_query("SELECT * FROM dotp_task WHERE task_id='$currentTasken'");
$numrows = mysql_num_rows($check);
if($numrows == 1)
{
//$pass = md5($pass);
$ins = mysql_query("SELECT (SELECT SUM(task_percent_complete) FROM dotp_task WHERE task_id='$currentTasken') FirstSum, (SELECT SUM(5)), SecondSum ");
if($ins)
die("Succesfully summed!");
else
die("ERROR");
}
else
{
die("Cant sum!");
}
die("Succesfully Created Log!");
else
die("ERROR");
}
else
{
die("Log already exists!");
}
?>
Your query is not written properly. Try to run this query from MySQL command line or from PHPMyAdmin. It will give you an idea what the error is. My best guess is that the first part of the query is not complete.
This is what it will resolve to
SELECT n FirstSum, 5, SecondSum
Where n is the value returned from the subquery. This is a syntax error. Try to remove the last comma before SecondSum.
This is what your query should be:
SELECT (SELECT Sum(task_percent_complete)
FROM dotp_task
WHERE task_id = '$currentTasken') FirstSum,
(SELECT Sum(5)) SecondSum
remove
(select sum(5))
and replace it with
(select 5)

MYSQL query with variables that may not be set

I have a PHP file which is taking in seven variables like so:
$name=$_REQUEST['membername'];
$email=$_REQUEST['email'];
$dob=$_REQUEST['dob'];
$gender=$_REQUEST['gender'];
$phone=$_REQUEST['phone'];
$county=$_REQUEST['county'];
$IP=$_REQUEST['IP'];
Some of these will not be set. What I want to do is construct a query which will search the members table such that if only $email and $dob are set it will only search by $email and $dob, ignoring the others. Or if only $phone, $name, and $gender are set, it will search those three columns only.
Is there an easier method than constructing a big block of if isset functions covering all possible permutations?
If you don't want to search on a field, pass NULL for the parameter and structure your WHERE clause something like...
WHERE
( (#parameter1 IS NULL) OR (column1 = #parameter1) )
AND
( (#parameter2 IS NULL) OR (column2 = #parameter2) )
I don't spend much time in MYSQL so the syntax is probably a bit off but you get the idea.
Presuming that you use parameters to push values into the query...
SELECT *
FROM MyTable
WHERE name = COALESCE(#p1, name)
OR email = COALESCE(#p2, email)
OR dob = COALESCE(#p3, dob)
...
...
If you construct a query string in PHP you can, instead, take another tack:
function AddWhere(&$where, $dbFieldName, $fieldValue)
{
if ($fieldValue <> "")
{
if (strlen($fieldName) > 0)
$fieldName .= " AND ";
$fieldname .= '(' + $dbFieldName + ' = \'' + $fieldValue + '\')'
}
}
Then, when you're retrived the variables, build a SQL statement thusly
$whereClause = ''
AddWhere($whereClause, 'name', $name)
AddWhere($whereClause, 'email', $email)
AddWhere($whereClause, 'dob', $dob)
...
IF (strlen($whereClause) > 0)
{
$sql = 'SELECT * FROM MyTable WHERE ' + $whereClause
... etc
}
(I'm not great at PHP, so the syntax may be somewhat screwed up).

joomla database select and insert query

i am trying to insert another info to joomla (2.5.7) database after user is registered. The user chooses his usergroup and I want the insertion to happen only when the user is in a specific group. So I am trying to use this code to get the group data from the databse first to be used in the insert query. Now it is just a testing ground, later this retrieved value be used in if statement.
This is the code:
function onUserAfterSave($user, $isnew, $success, $msg)
{
if ($isnew && $success) {
$db = &JFactory::getDBO();
$query = "SELECT #__k2_users.group FROM #__k2_users WHERE userID = ".$user['id'];
$db->setQuery($query);
$group = $db->loadResult();
$db->setQuery( 'INSERT INTO #__user_profiles (ordering) VALUES ('.$group.')' );
$db->query();
if (!$db->query())
{
throw new Exception($db->getErrorMsg());
}
}
return $this->onAfterStoreUser($user, $isnew, $success, $msg);
}
and this is the error I am getting upon the failed registration:
Column count doesn't match value count at row 1 SQL=INSERT INTO std13_user_profiles (ordering) VALUES ()
If I read it correctly, it means that the select statement is not returning anything but why? Thank you for your help.
UPDATE:
if ($isnew && $success) {
$db = &JFactory::getDBO();
$userId = JArrayHelper::getValue($user, 'id', 0, 'int');
$query = "SELECT #__k2_users.group FROM #__k2_users WHERE userID = ".$userId;
$db->setQuery($query);
$group = $db->loadResult();
$query2 = "INSERT INTO #__user_profiles (ordering) VALUES ('".$group."')";
$db->setQuery($query2);
$db->query();
if (!$db->query())
{
throw new Exception($db->getErrorMsg());
}
}
with this code, I don't get any errors and the user is registered and the values are inserted. However the $group is always 0 and based on the value is only 1 or 3 in k2_users table, I am guessing that it returns nothing. I think it may be because the registered user is not stored in the databse yet and it doesn't have his ID yet to look for the group?
UPDATE2:
if ($isnew && $success) {
$count = JRequest::getVar('gender');
if($count == 3) {
$db = &JFactory::getDBO();
$alias = $user['name'];
$table = array(
' '=>'-', 'Š'=>'S', 'š'=>'s', 'Ð'=>'Dj', 'Ž'=>'Z', 'ž'=>'z', 'C'=>'C', 'c'=>'c', 'C'=>'C', 'c'=>'c',
'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 'Å'=>'A', 'Æ'=>'A', 'Ç'=>'C', 'È'=>'E', 'É'=>'E',
'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I', 'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O',
'Õ'=>'O', 'Ö'=>'O', 'ě'=>'e', 'Ù'=>'U', 'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y', 'Þ'=>'B', 'ß'=>'Ss',
'à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'a', 'ç'=>'c', 'è'=>'e', 'é'=>'e',
'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ð'=>'o', 'ñ'=>'n', 'ò'=>'o', 'ó'=>'o',
'ô'=>'o', 'õ'=>'o', 'ö'=>'o', 'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b',
'ÿ'=>'y', 'R'=>'R', 'r'=>'r', " "=>'-', '"'=>'-'
);
$string = strtr($alias, $table);
$alias_low = strtolower($string);
$query = "INSERT INTO #__menu (menutype, title, alias, path, link, type, published, level, component_id, access) VALUES ('stavebnici','".$user['name']."','".$alias_low."','".$alias_low."',
'index.php?option=com_k2&view=itemlist&layout=user&id=".$user['id']."&task=user','component',1,1,10012,1)";
$db->setQuery($query);
$db->query();
if (!$db->query())
{
throw new Exception($db->getErrorMsg());
}
}
}
OKAY! I got it working so now I can insert new menu every time a user is created, however th activation link is not created and the registration says that it failed. This is the error:
Duplicate entry '0-1-vojtech-plesner-' for key 'idx_client_id_parent_id_alias_language' SQL=INSERT INTO std13_menu (menutype, title, alias, path, link, type, published, level, component_id, access) VALUES ('stavebnici','Vojtěch Plešner','vojtech-plesner','vojtech-plesner', 'index.php?option=com_k2&view=itemlist&layout=user&id=2789&task=user','component',1,1,10012,1)
The client_id, parent_id and language have values of 1,1 and * abd they are in all the rows so why is it saying it is duplicate?
You need to update that query to 2.5 style.
http://www.theartofjoomla.com/home/9-developer/135-database-upgrades-in-joomla-16.html
is a good article.
You definitely seem to be missing
$query = $db->getQuery(true);
not to mention that you are using & for an object. That usage will generate strict errors.
You can do it with one query:
$query = "
INSERT INTO #__user_profiles (ordering)
SELECT #__k2_users.group
FROM #__k2_users
WHERE userID = " . user['id']
";
But doesn't #__user_profiles have other columns like the user id?
Also You can do it with one query:
$query = "
INSERT INTO #__user_profiles (ordering)
SELECT "YOURJOOMLADBPREFIX"_k2_users.group
FROM "YOURJOOMLADBPREFIX"_k2_users
WHERE userID = " . user['id']
";

mySQL breaks when adding a var

I'm attempting to modify a mySQL query (that works) to return a more specific result. I've added a variable to the statement so that it looks for jobID AND UserName. Adding the $userName to the statement breaks it.
I've included the code below with the three variations of the SQL statement for comparison. I'm sure it's something obvious - to everyone but me...
Thanks in advance!
DB
// get all applicants from a User
public function GetAllMyApplications($from=false, $to=false, $user_name)
{
global $db;
$applicants = array();
if ($from >= 0 && $to > 0)
{
$sql_limit = ' LIMIT ' . $from .', ' . $to;
}
else
{
$sql_limit = '';
}
$user_name = "Bob Bobberton"; // reset this var for testing
$sql = 'SELECT * FROM '.DB_PREFIX.'job_applications WHERE job_id = '. $this->mJobId . ' ORDER BY name ASC ' . $sql_limit; // This was the original SQL that worked
$sql = 'SELECT * FROM '.DB_PREFIX.'job_applications WHERE job_id = '. $this->mJobId . ' AND name = ' . $user_name . ' ORDER BY name ASC ' . $sql_limit; // Added "and" $user_name - it breaks
$sql = 'SELECT * FROM '.DB_PREFIX.'job_applications WHERE job_id = '. $this->mJobId . ' AND name = "Bob Bobberton" ORDER BY name ASC ' . $sql_limit; // Replace var with value "Bob Bobberton" and it works
$result = $db->query($sql);
while ($row = $result->fetch_assoc())
{
$applicants[] = array('id' => $row['id'],
'job_id' => $row['job_id'],
'name' => $row['name'],
'email_address' => $row['email_address'],
'message' => str_replace(array("\r\n", "\r", "\n"), "<br />", $row['message']),
'resume_path' => base64_encode($row['resume_path']),
'created_on' => $row['created_on'],
'ip' => $row['ip']);
}
if (isset($applicants))
{
return $applicants;
}else{
return("");
}
}
change this
' AND name = ' . $user_name . ' ORDER BY name ASC '
to
" AND name = '" . $user_name . "' ORDER BY name ASC "
and it will work
The solution provided by Satya is not enough. You should escape your inputs properly.
Assume your $username contains a " character. That will break your SQL statement. So you should use prepared statements or, at least, use the function mysql_real_string_escape().