Database field to MySQL Query - php

I'm looking for a way to use a field in a database as a query. This is what I have:
Column Title: banemail
The contents of this field is updated using the vBulletin Settings page. It stores the email addresses I want to ban from registering. I need a query that will delete all users who are already registered and use a banned email. I want to retrieve the contents from the table, then use it a query of my own.
Query so far:
$datastoreemails = $vbulletin->db->query_read("SELECT data FROM ".TABLE_PREFIX."datastore WHERE title = 'banemail'");
while($content = $vbulletin->db->fetch_array($datastoreemails))
{
echo $content['data']."<br />";
}
This output is:
.cc .co hotmail
How can I then turn this output into a query to delete anyone in the database that has an email address containg the above?
This works when I run it manually but I have 20-30 banned email address and I would like to do it all in 1 query if possible.
DELETE FROM TABLE_PREFIX_user WHERE email LIKE '%.com%';
TIA

I've never used vbulletin so you may need ot adjust the below. I didn't know what the users table was for examples so I just entered "users".
$datastoreemails = $vbulletin->db->query_read("SELECT data FROM ".TABLE_PREFIX."datastore WHERE title = 'banemail'");
//Create an array of banned emails.
$bannedEmails = [];
while($content = $vbulletin->db->fetch_array($datastoreemails))
{
//Explode your data by a space to return an array of items you are looking for
$bannedEmails = array_merge($bannedEmails, explode(" ", $content['data']));
}
//check if there is anything in the banned Emails, if so build your "delete" query
if(is_array($bannedEmails) && count($bannedEmails) > 0) :
$deleteQuery = "DELETE FROM ".TABLE_PREFIX."users WHERE";
$deleteWhere = "";
//Loop through the array adding each email stub in to the query
foreach($bannedEmails as $email):
//If this is the second time through the loop add the AND clause
if($deleteWhere != "") $deleteWhere .= "OR ";
//Add in where email like %hotmail.com% to match anything that looks like it.
$deleteWhere .= " email like '%" .$email . "%' ";
endforeach;
//Add the where on the end of the query
$deleteQuery .= $deleteWhere;
//Now all you need to do is execute the delete, I'm just going to print it out so you can check the
//sql first!
echo $deleteQuery;
endif;
From your code it looks like there is a single text field which will hold the banned email addresses in your database. If that is the case then you might want to use "query_first" like this $vbulletin->db->query_first($query) as that will just pull one row out, and you won't have to loop through the results. I've written the code above in case there are multiple rows with banned emails in, which should work even if there is just one.

you could use the reult of select fro delete directly
assuming you have
SELECT data FROM ".TABLE_PREFIX."datastore WHERE title = 'banemail'"
then you could
("DELETE
FROM " .TABLE_PREFIX ."user
WHERE email in ( SELECT data
FROM " .TABLE_PREFIX."datastore
WHERE title = 'banemail'" );

Related

Creating a dynamic search query with PHP and MySQL

I'm trying to create a dynamic search query, based on the user input.
Requirements:
A user could fill in none, some, or all fields.
The query searches in a table for a record that matches all the requirements.
Now I have done my research, and I found out multiple ways on doing this. But none of them work, and if they do, they are far from practical.
Attempt:
At the moment I'm creating a query like this:
SELECT *
FROM assignments
WHERE (id = $id OR id = '')
AND (field1 = $field1 OR field1 = '')
This query works, but only if you fill in all the fields.
I got this from a stackoverflow article, that I can't find anymore, that said:
If the user has filled in an input field it will check the first rule
"id = $input"
and if the user hasn't specified any input it will check for "id = '' " and when it
checks for that, it will just return everything. Because it escapes the empty search rule.
But as you might already know, it doesnt work..
How would you suggest me to approach this?
Try getting all of the post vars and looping through them to see if they are valid, and then build your query
<?php
$id = $_POST[id];
$field1 = $_POST[field1];
$field2 = $_POST[field2];
$field3 = $_POST[field3];
$whereArr = array();
if($id != "") $whereArr[] = "id = {$id}";
if($field1 != "") $whereArr[] = "field1 = {$field1}";
if($field2 != "") $whereArr[] = "field2 = {$field2}";
if($field3 != "") $whereArr[] = "field3 = {$field3}";
$whereStr = implode(" AND ", $whereArr);
$query = "Select * from assignments WHERE {$whereStr}";
Something like that should handle what you need
You should start with a string like yours up to the WHERE statement, then after that you loop through all the fields the user wants to search with and add them to an array, then use the PHP function "implode" to glue the fields together with an AND statement as "glue".
Now add on the glued string to the startquery and voila!
I'd give example but on phone atm!
Building the query dynamically based on the responses is definitely a must. But another nice feature that allows users to find results based on even partial responses is using a MySQL REGEXP query. So for instance, if they wanted to find "maverick" in a Top Gun database, a query REGEXP = 'mav' | 'rick' would return results. This brings your search much closer to the search engine functionality that users are accustomed to.
Here's a REGEXP example, simplified.

column of table cells text to links

I'm creating a table dynamically from a mysql database that gets fields name, email, city. The email column has emails that I'd like to have as "mailto:" links. Currently they display the email without the hyperlink. There's a 'filter' form on the page as well that when submitted will display only results that correspond with a name specified in the form textbox by the user.
I'm very novice at creating anything dynamic. What's the easiest way to display the email column as hyperlinks? I was thinking about using javascript to do a getElementByID loop for the second td of every tr and amend a "mailto:" the beginning using string manipulation. Maybe this is more practically done in PHP instead?
edit:
I realized the obvious solution to my question. I simply concatenated the a href mailto: before the echo of the php command that gets my email field from the sql db and displays it in the table.
This is, indeed, more practically done in PHP. You can use something like the following, assuming that $result contains the result of a MySQL SELECT statement which fetches the users.
while ($u = $result->fetch_assoc()) {
// Output other data
// ...
echo '' . $u['email'] . '';
// ...
}
If you're still using mysql instead of mysqli (which you shouldn't really be doing), then replace
while ($u = $result->fetch_assoc()) {
with
while ($u = mysql_fetch_assoc($result)) {
$db = new PDO(//your dsn, host and password);
$query = $db->prepare('SELECT name,email from users');
$query->execute(); while($row = $query->fetch(PDO::FETCH_ASSOC))
{
echo ''.$row['name'].'';
}

Check if username exists, if so, increment by one

When a username is inserted into my database, such as:
John_Smith
I need to check if there is already a John_Smith present. If so, increment it by 1 to become John_Smith_1
So if the following usernames already exist:
John_Smith
John_Smith_1
John_Smith_2
John_Smith_3
....up to John_Smith_10
I need the next John_Smith inserted to be incremented to John_Smith_11.
So far, I have searched and come up with this:
$preferredname= "John_Smith"
//check for duplicate user names
$duplicate= check_for_duplicate_username($preferredname);
//if duplicate, increment the preferredname
if ($duplicate)
{
$parts = explode("_",$preferredname);
if (isset($parts[1]))
$preferredname = $parts[0]."_".$parts[1]."_".($parts[2]+1);
else $preferredname = $parts[0]."_".$parts[1]."_1";
}
This, I believe would work for only the first matching usernames. My problem is checking the database for the version of the name with the highest number.. This is my sql:
function check_for_duplicate_username($name)
{
// check if username already exists
$sql = "SELECT * FROM users WHERE user_username=$name";
//then return duplicates
You can use this query:
$sql = 'SELECT * FROM users WHERE user_username LIKE ' . $name . '_%';
the above will query for rows in which user_username have value similar to John_Smith_* ( where * is any valid character including number, which you have to check later )
you can use this php statement for getting user's suffix number:
preg_match( '/([0-9]+)$/', 'John_smith_10', $matches );
$user_number = $matches[0];
While this may not be the best solution in the grand scheme of things, here is an answer that addresses what you were specifically trying to do. The following query returns the number of users with either $name or $name_123 SELECT COUNT(*) FROM users WHERE user_username REGEXP '$name[_0-9]*$'; So if the value is 0 you can simply use $name by itself, otherwise you can use $name."_". + the number returned by the query.
But as many people have mentioned, prly not the best idea to autoassign usernames (very web 1.0 :P ). I'd recommend email addresses. Another option is to use whatever userid the social app uses along with another field identifying the social app (if you have multiple), and then using an autoincremented id field as the unique primary key..
I had a similar problem I was trying to solve today and did it like this. In my case I needed to store/create a unique directory name based on the users first initial/last name:
$username = "bjones";
$usersql = "SELECT * FROM users WHERE username LIKE '$username%'";
$usercnt = mysqli_num_rows(mysqli_query($con,$usersql));
// If bjones, bjones1, bjones2, etc already exists
if ($usercnt >= 1) {
$num = ++$usercnt; // Increment $usercnt by 1
$username = $username . $num; // Add number to username
}
Assuming bjones, bjones1, bjones2 already exists, I would end up with bjones3.

PHP check if variable exists in all rows returned

i want to do a check if a user id exists in all of the table rows i search for.
edit sorry i was missleading i think.
I want to check if the user has read all of the articles in a category, i have a forum front end displaying the categories and within the categories are the articles.
On the categories screen i want to display an image ALL ARTICLES READ or NOT ALL ARTICLES READ, so some how i need to loop through all of the articles per category which is what the example query below is doing and check if user id exists in ALL returned rows if yes then then all articles have been read if there are some rows missing the users id then some articles have not been read
This is my sql query
$colname_readposts = "-1";
if (isset($_GET['Thread_Category_Article_id'])) {
$colname_readposts = $_GET['Thread_Category_Article_id'];
}
mysql_select_db($database_test, $test);
$query_readposts = sprintf("SELECT Thread_Article_User_Read FROM Thread_Articles WHERE Thread_Category_Article_id = %s", GetSQLValueString($colname_readposts, "int"));
$readposts = mysql_query($query_readposts, $cutthroats) or die(mysql_error());
$row_readposts = mysql_fetch_assoc($readposts);
$totalRows_readposts = mysql_num_rows($readposts);
How can i check if all of the rows returned contain the users id?
The idea is to check to see if user has read all the articles if yes show READ if no show UNREAD.
The results per row are like so 0,15,20,37 these are id's entered when a user views a post.
i have managed to get this check for a single article to show if the user has read a specific article but unsure how i would check multiple:
here is my single article check:
<?php
$userid = $_SESSION['loggedin_id'];
$userreadlist = $row_readposts['Thread_Article_User_Read'];
$myarray = (explode(',',$userreadlist));
if (in_array($userid,$myarray )){
?>
html image READ
<?php } else { ?>
html image UNREAD
<?php } ?>
Any help would be appreciated.
Carl
First up, forget the mysql_* functions; ext/mysql is a deprecated API as of PHP 5.5 - so it's a really good idea to use mysqli or PDO.
From what I gather you're actually trying to see if any of those results contain a specific user's id? If so, do this in the SQL query:
SELECT Thread_Article_User_Read FROM Thread_Articles WHERE
Thread_Category_Article_id = %s AND UserID = %s
And supply this the User's ID as a second argument. (Syntax may not be 100% correct, but it should prove a point)
If you mean you want to check there there is any user's ID - then once again; do this in SQL:
SELECT Thread_Article_User_Read FROM Thread_Articles WHERE
Thread_Category_Article_id = %s AND UserID IS NOT NULL
This will ensure there is a valid value for 'UserID'.
Naturally replace 'UserID' with your column name if you base your solution on one of these examples.
However, if you're dumping out ALL the results from a table - and you need to see if your user's ID is present in a certain column (like you do!); then you can actually just adapt the logic that you're using on your single article page. Which should give you something like this...
$userid = $_SESSION['loggedin_id'];
$colname_readposts = "-1";
if (isset($_GET['Thread_Category_Article_id'])) {
$colname_readposts = $_GET['Thread_Category_Article_id'];
}
/* connect to db and run query; CHANGE ME TO SOMETHING NOT DEPRECATED */
mysql_select_db($database_test, $test);
$query_readposts =
sprintf("SELECT Thread_Article_User_Read FROM Thread_Articles WHERE
Thread_Category_Article_id = %s", GetSQLValueString($colname_readposts, "int"));
$readposts = mysql_query($query_readposts, $cutthroats) or die(mysql_error());
/* loop through all returned items */
while($row = mysql_fetch_assoc($readposts)) {
/* repeat the check you used on an individual
row on the single article page. i.e: */
$userreadlist = $row['Thread_Article_User_Read'];
$myarray = (explode(',',$userreadlist));
if (in_array($userid,$myarray )){
/* user has read */
} else {
/* user hasn't read */
}
}
If that code you worked for a single page then it should work in the above; as for every iteration of the loop you're working on a single row - just as you were on the single page. If the data is coming from the same table then the column names etc match up and it will work.
Or, if you just want to know if there are any unread posts at all, replace the loop with this one...
/* loop through all returned items */
$read = true;
while($row = mysql_fetch_assoc($readposts)) {
/* repeat the check you used on an individual
row on the single article page. i.e: */
$userreadlist = $row['Thread_Article_User_Read'];
$myarray = (explode(',',$userreadlist));
if (! in_array($userid,$myarray )){
$read = false;
break;
}
}
if( $read ){
/* all pages are read */
} else {
/* there are unread pages */
}

Combine isset() with a mysql query to create dynamic queries

I have done some looking but to be honest I just dont know what exactly to search. What I am trying to do is create a dynamic query as the tittle says. That is, one where I query only the variables that are sent to the php file. For example if I want to look up users but I only know their last name and username however for another user I know his firstname and email. I want to give the search form many fields and create a query based on what fields were entered.
Build up a list of WHERE clauses first and then add these into your query. For example:
$where = "";
if (isset($firstname) {
$firstname = mysql_real_escape_string($firstname);
$where .= "AND firstname='$firstname'";
}
if (isset($lastname) {
$firstname = mysql_real_escape_string($lastname);
$where .= "AND lastname='$lastname'";
}
mysql_query("SELECT * FROM users WHERE 1 ".$whereClause);
Of course you will need to change the table/row/etc names and add extra if (isset sections for each attribute.

Categories