I'm seeking for the best method to implement the column visibility in users profile.
Imagine the following scenario:
Name : stackoverflow | [checkbox] visible = 1
Address: New York | [checkbox] visible = 0
Phone : 312 021 11 | [checkbox] visible = 1
Email : stack#stack.com | [checkbox] visible = 1
With this, I have two tables: profile and profile_visibility
profile
ID
ID_User (joins with the User table)
Address
Phone
Email
profile_visibility
ID
ID_User (joins with the User table)
Address
Phone
Email
The fields of profile_visibility are all (except id_user and id) of tinyint data.
Now, I would like to make a loop to all columns to check if that column is visibile or not, instead of making conditions (because I have more than that columns). Something like:
$profile = $this->profile($id); // gets the info (as array) of profile
$visibility = $this->profile_visibility($id); // gets the visibility of fields
for($i = 0; $i <= sizeof($profile) - 1; $i++){
/* I can't match $profile with $visibility because the values are different..
$profile[$i]['name'] == $visibility[$i]['name']
$profile[$i]['name'] > it's equal to: 'stackoverflow'
$visibility[$i]['name'] > it's equal to: '1'
*/
}
EDIT: Solved -> But it's not the best solution, see #niyou solution.
foreach($visibility as $key => $val) {
if($val == 1){
if(array_key_exists($key, $profile)){
$content .= "<tr>
<td class='text-align-right'>
<b>" . ucfirst($key) . "</b>:
</td>
<td class='width-100'>" . $profile[$key] . "</td>
<td>
</td>
</tr>";
}
}
}
I think its a matter of your design:
I would create a table profile_fields where i define my possible data fields
profile_fields: field_id,field_name,field_position,...
My other Table holds the information whether a field ist visible or not for a user - named user_fields
user_fields: user_field_id, user_id, field_id, visible
Now you can easily query only those fields which are visible for a user:
SELECT field_id, field_name
FROM profile_fields
LEFT JOIN user_fields USING (field_id)
WHERE user_id=$user_id AND visible=true
Related
I am busy making a multi-shop shopping site like amazon.com, ebay, carousell.com etc...
Now when users create a listing I made a custom fields system that get the custom fields from a mysql table then outputs them into the form.
The Code:
Okay so first this is the listings table:
ID
list_title
list_brand
seller_id
1
Two sticks
Mr Sticks
1012
Then we have listings_meta which is where I store the custom fields like for a pillow it would be type of filling or for a stick it would be color of stick:
ID
listing_id
meta_key
meta_value
1
1
stick_color
brown
Now the meta key comes from a database table called [form_fields] which is linked the the categories like this
[form_fields]:
ID
meta_key
type
meta_link
1
stick_color
select
0
2
stick_length
input
0
3
rock_weight
input
0
4
brown
option
1
5
blue
option
1
And the category table[cats]:
ID
category
4
Sticks
5
Stones
Link custom fields and categories[cat_meta]:
ID
meta_id
cat_id
1
1
4
2
2
4
3
3
5
So now that you know how the items link with each other lets dive into the PHP code:
Now fist when a user clicks create product that will be given a popup asking which category they want to list the product thats done with a simple select query then they will be redirected to a new page called new_product.php?cat=[id of category from database ID]
new_product.php?cat=4
Now some of the fields are the same for all products they are the ones in listings table
But for custom fields its a bit more complex
:
<input type="text" name="list_title " placeholder="Title">
</br>
<input type="text" name="list_brand " placeholder="Brand">
</br>
<?php //get custom fields from custom_inputs table
//query the database for fields id and
$stmt = $conn->prepare("SELECT `meta_id ` FROM `cat_meta` WHERE `cat_id` = ?");
$stmt->bind_param("i", $_GET['cat']);
$stmt->execute();
$stmt_results = $stmt->get_result(); // get result
while($row_get = $stmt_results->fetch_assoc()){
$field_id[] = $row_get['meta_id ']; //store all id's in array
}
if(empty($field_id)){ //no custom field found in database
return 0;
}else{
foreach($field_id as $field_id){ //loop ID's to get multiple
$stmt = $conn->prepare("SELECT `meta_key `, `type ` FROM `form_fields` WHERE `ID` = ?");
$stmt->bind_param("i", $field_id);
$stmt->execute();
$stmt_results = $stmt->get_result(); // get result
while($row = $stmt_results->fetch_assoc()){
$field_name[] = $row['meta_key']; //get key aka title
$field_type[] = $row['type']; //get the type of input
}
}
}
foreach ($field_name as $index => $field) { //combine the type and meta key
$type = $field_type[$index];
if($type === "select"){ //field type is a select
echo '</br><select name="body['.$field.']">';
echo '<option selected Disabled value="">Select Option</option>';
//get options from `form_fields` linked to this meta_id
$stmt = $conn->prepare("SELECT `meta_key` FROM `form_fields` WHERE `meta_linked` = ? AND `field_type` = 'option'");
$stmt->bind_param("s", $field);
$stmt->execute();
$stmt_results = $stmt->get_result(); // get result
while($row = $stmt_results->fetch_assoc()){
echo '<option value='.$row['meta_key '].'>'.$row['meta_key'].'</option>';
}
echo '</select>';
}
if($type === "input"){ //field type is a user input
echo "<input name='body[$field]' placeholder='$field'>";
}
}
?>
Yes I know the code is very messy but I will clean it up before it is pushed but my issue is I feel like this seems over-complex/not efficient, Can anyone recommend a better way to build custom fields based on the category that was selected.
Also i do not include a lot of html and other php processing code as i dont think it needs to be included but if you need more info i will give it :)
I have a database like this :
ID | Name | Model | Type
1 | Car | 4 | C
2 | Bar | 2 | B
3 | Car | 4 | D
4 | Car | 3 | D
And a form like this :
Name :
Model :
Type :
Now, I would like to search only the name, for example "Car" and it returns lines 1, 3, 4. (I left Model and Type empty)
If I search "Car" in Name and 4 in Model, it returns lines 1, 3. (I left Type empty)
And if I search "Car" in Name and "D" in Type, it returns line 3, 4 (I left Model empty)
Is it possible to do this in one query ?
This is what I had :
SELECT *
FROM items
WHERE (:name IS NOT NULL AND name = :name)
AND (:model IS NOT NULL AND model = :model)
AND (:type IS NOT NULL AND type = :type)
But it doesn't work.
I would like to fill only 2 on 3 fields and the the "WHERE" adapts and ignore the blank field.
EDIT 1 : It is a little hard to explain but I have a form. I want to have only one required field, the two others are optional but if I also fill the one other or two others fields, they act like a filter.
So the name field is required (in the form). If I fill only the name field, it will select only where name = :name.
If I fill name + model, it will select where name = :name AND model = :model.
and so on...
Thank you for your help.
I'm not sure what you mean by "blank", but assuming you mean NULL, you can do something like this:
SELECT *
FROM items
WHERE (:name IS NULL OR name = :name) AND
(:model IS NULL OR model = :model) AND
(:type IS NULL OR type = :type);
That problem with this query is that it is very hard for MySQL to use indexes for it, because of the or conditions. If you have a large amount of data, and want to use indexes, then you should construct the where clauses based on the parameters that actually have data.
Here's an alternative approach using PHP. You'll need to update the variables.
<?php
$query = 'SELECT *
FROM items
WHERE 1 = 1 ';
//below used for testing can be remove
//$_GET['name'] = 'test';
//$_GET['car'] = 'test2';
//$_GET['type'] = 'test3';
if(!empty($_GET['name'])) {
$query .= ' and name = ? ';
$params[] = $_GET['name'];
}
if(!empty($_GET['car'])) {
$query .= ' and car = ? ';
$params[] = $_GET['car'];
}
if(!empty($_GET['type'])) {
$query .= ' and type = ? ';
$params[] = $_GET['type'];
}
if(!empty($params)) {
$dbh->prepare($query);
$sth->execute($params);
//fetch
} else {
echo 'Missing Values';
}
The 1=1 is so you can append and search field for each field with a value otherwise you'd need to see if it'd already been set.
This question already has answers here:
Rank function in MySQL
(13 answers)
Closed 8 years ago.
I have a text based mafia game and I am selected some GameRecords. The game records are all defined in the "users" table. For this example I am using "totalcrimes". I need to select all the rows from the users table and order it by totalcrimes and then find out which row each specific user is that is viewing the page.
If I was the user that was "ranked" 30th it would echo "30". The code I use to find the top 5 is here however I need to expand on it:
<?php
$i = 0;
$FindCrimes = mysql_query("SELECT * FROM players WHERE status='Alive' AND robot = 0 ORDER BY `totalcrimes` DESC LIMIT 5");
while($Row = mysql_fetch_assoc($FindCrimes)){
$Username = $Row['playername'];
$TotalCrimes = number_format($Row['totalcrimes']);
$i++;
echo "
<tr>
<td bgcolor='#111111' width='5%'>$i</td>
<td bgcolor='#111111' width='50%'><a href='viewplayer?playerid=$Username'>$Username</a></td>
<td bgcolor='#333333' width='45%'>$TotalCrimes</a></td></td>
</tr>
";
}
?>
I am going to assume that you already have a variable set to hold the current users ID number and total crimes, so in this case I will use $user as my variable.
Change yours to fit.
Now, I see 2 instances in which you could mean as your post wasn't very specific, so I will address both.
To show the number at the top of the page, you would use something like;
<?php
$sql = "SELECT * FROM `players` WHERE `totalcrimes` > '{$user['totalcrimes']}'";
$run = mysql_query($sql);
$rank = mysql_num_rows($run) + 1;
echo 'Your rank: ' . $rank;
Other than that, I see it's possibly being used to highlight your row, so something like this would suffice;
<?php
$i = 0;
$FindCrimes = mysql_query("SELECT * FROM players WHERE status='Alive' AND robot = 0 ORDER BY `totalcrimes` DESC LIMIT 5");
while($Row = mysql_fetch_assoc($FindCrimes))
{
$Username = $Row['playername'];
$TotalCrimes = number_format($Row['totalcrimes']);
$i++;
$primary = '#111111';
$secondary = '#333333';
if ($Row['id'] == $user['id'])
{
$primary = '#222222';
$secondary = '#444444';
}
echo "<tr>
<td bgcolor='$primary' width='5%'>$i</td>
<td bgcolor='$primary' width='50%'><a href='viewplayer?playerid=$Username'>$Username</a></td>
<td bgcolor='$secondary' width='45%'>$TotalCrimes</a></td></td>
</tr>";
}
If neither of those give your requirements, please comment and I'll edit to suit.
edit: I've worked on games for a few years - care to share the link to yours?
This can do the trick
SELECT COUNT(*)+1 as rank
FROM users
WHERE totalcrimes > (SELECT totalcrimes
FROM users
WHERE user_id='12345' AND status='Alive' AND robot='0');
So it counts all rows with greater totalcrimes than selected user (in this example I have used user_id column and some id 12345), than adds 1 on that sum and returns as rank value.
Course, modify WHERE clause inside the brackets to make it work for you.
I assumed that table name is users and user's id is integer user_id.
Test preview (Navicat Premium):
What this query does? It returns number of selected rows + 1 as rank column, from the table users where totalcrimes is greater than totalcrimes of some user. That user's totalcrimes is selected by another query (by its user_id). If you have multiple users with same totalcrimes value, this query will return same rank for all of them.
I would like to do a search engine for my webpage.
I have several tables in my mysql database and i would like them
combined when user
Table users
id name age country vip profile_image
1 nick 23 sweden 1 yes
2 michael 20 germany 0 no
3 laura 19 usa 1 yes
4 gary 33 china 1 yes
Table online
id user_id online
1 1 1
2 2 1
3 4 1
user_id is connected to id in users table
Now i have checkboxes
[ ] Those which are online
[ ] Those which are vip
[ ] Those with profile image
Im coding my page in PHP and im trying to figure how to include certain
searches in a sql query if certain checkbox is checked.
I can have tons of options here. Example if no checkbox is checked,
iff on you want to search for those which are online, how do i go in to the second table?
I hope you get my point here. I really hope someone could help me
and give me an working example of the php & sql query.
Cheerz!
First you have to check which checkboxes have been checked. Then you must write MySQL-query with PHP based on that information. You must think in every checkbox, what information it needs to check. If your database is well written, there is seldom a problem that two options affect each other. If information is in users-table, you need just write line to where-clause. If you need to join table to users-table to get information you need to do that too. Here is an example
$query = "";
$query .= "SELECT users.* FROM users";
if ($include_online == 1) {
$query .= " LEFT JOIN online ON online.user_id = users.id";
}
$query .= " WHERE";
if ($include_vip == 1) {
$query .= " users.vip = 1 AND";
}
if ($include_image == 1) {
$query .= " users.profile_image = 'yes' AND";
}
if ($include_online == 1) {
$query .= " online.online = 1 AND";
}
$query .= " users.name LIKE '%".$search_string."%'";
You need to form a query something like the following:
SELECT users.name, users.age, users.country
FROM users
LEFT JOIN online ON user.id = online.user_id
WHERE ((user.vip = 1) && (online.online = 1))
I'm trying to come up with an efficient way of displaying some data but not succeeding at all.
The table is built dynamically from a few tables to show a row of headers with the columns populated showing the results by site e.g:
Site name | Column A | Column B | Column C => column headers continue from DB query
Site A | Result A | Result B | Result C
Site B | Result C | Result B | Result C
Site C | Result C | Result B | Result C
Results keep going vertically.
Here's the query I'm using
$risk_section=$row_risk_category['risksectid'];
mysql_select_db($database_auditing, $auditing);
$qry_selfsites = sprintf("SELECT
tblself.siteid AS selfsite,
tblsite.sitename AS sitename,
tblsite.address AS address,
tblpct.pctname AS pctname,
tblresultsnew.total,
tblresultsnew.auditid AS auditid,
tblriskcategories.risksectid AS risksectid,
tblriskcategories.risksection AS risksection
FROM tblself
LEFT JOIN tblresultsnew ON tblself.auditid = tblresultsnew.auditid
LEFT JOIN tblsite ON tblself.siteid = tblsite.siteid
LEFT JOIN tblpct ON tblsite.pctid = tblpct.pctid
LEFT JOIN tblriskcategories ON
tblresultsnew.risksectid=tblriskcategories.risksectid
WHERE tblsite.pctid IN (SELECT pctid FROM tblreportpcts WHERE
pctreportid='$pctreportid')
AND tblsite.sitetypeid IN (SELECT sitetypeid FROM tblreportsites WHERE
pctreportid='$pctreportid')
AND tblself.year = %s
ORDER BY tblsite.pctid,tblsite.sitename",
GetSQLValueString($yearofrpt, "int"));
$selfsites = mysql_query($qry_selfsites, $auditing) or die(mysql_error());
$totalRows_selfsites = mysql_num_rows($selfsites);
So the question is, is there a way to get the data from the above query (or an adapted version thereof) to build the table dynamically with all the results lining up correctly?
So far, I can only get it to build vertically.
Sorry, edit time (having worked with the answer below, I realised I hadn't got the question worded very well)
What I'm trying to get is a row of column headers from the query (tblriskcategories.risksection AS risksection) These populate horizontally to give the columns names.
Then underneath, the sitename is displayed with the result corresponding to the column header above i.e.
<table>
<tr>
<th>Sitename</th>
<?php while($row_selfsites=mysql_fetch_assoc($selfsites){
//loop through the section headers pulled from the DB (tblriskcategories)
<th><?php echo $row_selfsites['risksection'];//show the section headers?></th>
<?php }
//end header loop then start another loop to show a row for each site pulled
//out by the query and show the relevant results in the correct column
while($row_selfsites=mysql_fetch_assoc($selfsites)) {
//do the vertical drop matching the header rows with the sitenames from tblsite
//and the results from tblresultsnew
?>
<tr>
<td><?php echo $row_selfsites['sitename'];?></td>
<td><?php echo $row_selfsites['total'];
//these need to grow to fit the headers and each site?></td>
<tr>
<?php } //end displayed data loop?>
</table>
The relevant tables structure below:
tblresultsnew resultsid,auditid,risksectid,total
tblriskcategories risksectid, risksection
tblself selfauditid,siteid,auditid
tblsite siteid,sitename
So tblself holds the list of sites we need the data for and the relevant auditid,
tblresultsnew holds the results - the total column - for each risksectid and each auditid eg, one auditid can have approx 8 risksectid's each with corresponding total
tblriskcategories holds the column headings
tblsite holds the site data to make it mean something
I hope this explains the question a little further.
Thanks again for all the help.
Dave
$rows = array(
0 => array('headingA' => 'results1a', 'headingB' => 'results1b', ),
1 => array('headingA' => 'results2a', 'headingB' => 'results2b', ),
2 => array('headingA' => 'results3a', 'headingB' => 'results3b', ),
);
// $rows is spoofing a db result set as an array
//var_dump( $rows );
$first = true ;
$header_row = "START TABLE <br />" ;
$data_rows = "";
foreach( $rows as $row ) {
foreach( $row as $key=>$value ){
if( $first === true ){
$header_row .= "$key | ";
}
$data_rows .= "$value |";
}
if( $first ) $header_row .="<br />";
$data_rows .= "<br />";
$first = false;
}
echo $header_row . $data_rows . "END TABLE";
Gives:
START TABLE
headingA | headingB |
results1a |results1b |
results2a |results2b |
results3a |results3b |
END TABLE
Is that the kind of solution you are after?