Best way to alert user - php

I have a database with a table called userbadges . All users have all badges at level 0 "locked" (greyed out) . They can unlock it at level 1 , all the way to level 3. Each level is worth points.
userbadges {user_id,badge_id,level,score,seen}
What would be the best way for me to alert the user that they
a) have unlocked a new badge
b) have leveled up a badge
I have this code , but it doesn't seem right. It counts the number of new badges ():
function countNewBadges() {
require "connect.php";
$newbadges = mysqli_query($connection,"SELECT users.studentid, individualbadges.badgename, ub.level, count(ub.seen) as total FROM userbadges ub
INNER JOIN users ON users.id = ub.user_id
INNER JOIN individualbadges ON individualbadges.id = ub.badge_id
WHERE studentid = '".$_SESSION["studentid"]."' && seen=0 && level!=0") or die(mysqli_error($connection));
while ($data = mysqli_fetch_array($newbadges)) {
echo $data['total'];
}
}
I also have code to set the seen field of the badges table to 1.

I would make a messaging system: Create a table message with text, title. (for every message you have or dynamicly) Then make a table user_has_message where you got the 2 Keys to join, and a boolean if read.
With a simple Select * from user JOIN user_has_message on ... and iduser = ... JOIN message on ... where read = false you get all your alerts/Messages for a specified user.
EDIT: Now you can simply add an entry to user_has_entry, in which you specify which user should get which message.
Now you have much possibilities: add the date with default NOW(), to know when the message occoured, give the user the possibility to delete this message (what only deletes the entry on the user_has_message), add tho option to mark a message as unread, etc etc ...
Shure you can also use those messages for other things like a Welcome-Message etc. Or add a cronjob to send an email to the users with open messages older than 5 days. Or even implement a chat-system...

Related

SQL order by datetime

I have 3 tables:
chatmsgs with the columns
itemid, sender, receiver, message, datetime, status
users with the columns
userid, username, phone, email, avatar, online, password
items with the columns
itemid, category, make, type, mainimage, title, price
I am trying to create a list of chats between the current user and some other user on a specific item and order the list by the chat with the most recent message (based on timestamp).
My current query is this:
<?php
$currentuser=$_SESSION['userid'];
$sqls="SELECT DISTINCT itemid,sender,receiver FROM chatmsgs ORDER BY datetime DESC";
$results=mysqli_query($db,$sqls);
while($rows=mysqli_fetch_assoc($results)){
$itemid=$rows['itemid']; $sender=$rows['sender']; $receiver=$rows['receiver']; #$message=$rows['message'];
$sqll="SELECT * FROM items WHERE itemid = '".$itemid."'";
$resultt=mysqli_query($db,$sqll);
while($roww=mysqli_fetch_assoc($resultt)){
$itemid=$roww['itemid']; $title=$roww['title']; $status=$roww['status']; $userid=$roww['userid'];
#$sqlx = "SELECT * FROM users WHERE userid = '".$userid."' AND userid != '".$currentuser."'";
$sqlx = "SELECT * FROM users WHERE userid = '".$userid."'";
$resultx=mysqli_query($db,$sqlx);
while($rowx=mysqli_fetch_assoc($resultx)){
$avatar=$rowx['avatar']; $username=$rowx['username']; $user=$rowx['userid'];
$sq="SELECT * FROM chatmsgs WHERE itemid = '".$itemid."' AND ((sender = '".$sender."' AND receiver = '".$receiver."') OR (sender = '".$receiver."' AND receiver = '".$sender."')) ORDER BY id ASC";
$resul=mysqli_query($db,$sq);
while($ro=mysqli_fetch_assoc($resul)){
$message=$ro['message'];
$ldate=date_format(date_create($ro['datetime']),"M d");
}
echo '
<li>
My list item
</li>
';
}
}
}
?>
I have so far been able to list the chats but I'm unable to sort it.
I know this is not the best way to do this but it's the only way I know how. Would appreciate better ways.
I would start by getting all chat messages associated with just the given user in question. By doing a UNION as both the sender and receiver, if you have an index on each column respectively, the query should be very fast. From that, you can now query the rest of the data all in one quick run something like below.
You can order the data by whatever... From your while loops, it looked like you were doing all things for a given Item ID before moving to the next, so I have the order by clause by the item ID. Now, from within each item, I have ordered by the date/time in descending order with newest chat message first, but you could change that.
Another possible change is you may want the items displayed based on which is the MOST RECENT item that has chat activity first. For example, if a chat from someone was from a year ago, vs one that was just this week, you might want the current first. I would alter the query slightly.
select
um.itemid,
cm.message,
cm.datetime,
cm.status,
uFrom.username senderName,
uFrom.avatar senderAvatar,
uTo.userName receiptName,
uTo.avatar receiptAvatar,
i.category,
i.make,
i.type,
i.mainImage,
i.title,
i.price
from
( select distinct itemid
from chatMsgs
where sender = $currentuser
UNION
select distinct itemid
from chatMsgs
where receiver = $currentuser ) UM
JOIN ChatMsgs ch
on UM.ItemID = ch.ItemID
JOIN Users uFrom
on ch.sender = uFrom.userid
JOIN Users uTo
on ch.receiver = uTo.userid
JOIN Items i
on ch.itemID = i.itemid
order by
um.itemid,
cm.datetime desc
The format is not in php format, but you can see the only place you need a parameter is where the user ID is. All the details come along in the results including the respective avatars, titles, messages, from user and recipient user too. Take what you need in one query.
I would expect two individual indexes on your chatmsgs table. One on the sender, one on the receiver.

How To Count Read and Unread message in PHP mysql

I want to make a read and Unread message count from Mysql.
This is my PHP code :
<?php
$dbdata = "SELECT * FROM users";
if ($result = mysqli_query($db, $dbdata)) {
if (mysqli_num_rows($result) > 0) {
while ($row = mysqli_fetch_array($result)) {
echo "<li class=online'><a href='?user=" .
$row['username'] .
"'><img alt='user pics' src='img/demo/av1.jpg' /> <span>" .
$row['fname'] . ' ' .
$row['lname'] . "</span><span class='msgcount'> 0</span></a></li>";
}
mysqli_free_result($result);
} else {
echo "No Students Found.";
}
} else {
echo "ERROR: Could not able to execute. ";
}
?>
I want <span class='msgcount'> 0</span> to display a count of the unread messages of that user. And if the user is already clicked, the messages unread becomes 0 because messages are shown upon click.
Can you help me solve this logic? I just want to notify that there is an unread message. Thank you masters please help me.
This is the Output image of the Chat Message:
I am new to php. So this can serve as an alternative till a better answer is tendered.
You could create a table that looks like that of your message. Then when you send a message insert the data into the two tables. Next, select your message in your normal way. And select the number of rows from your look alike table then print it in the span for unread messages. Then onclick let mysqli delete the messages from the look alike table. Autoupdate the span with jquery.
I'm assume that besided the users table, you alse have a messages table.
And I will boldly assume your messages table looks like this:
id int pk,
to_user_id int fk,
from_user_id int fk,
read bool default false,
title varcher(250),
body text,
created_at datetime,
updated_at datetime
So, users and messages have a 1:M relationship and rightfully so
You join, filter and count users and messages at every page load or at every few seconds
SELECT u.id, u.name as from, count(1) as total
FROM users AS u
JOIN messages AS m on u.id = m.from_user_id
WHERE
to_user_id = ? -- this is the authenticated user id!
AND `read` is false
GROUP BY from_user_id
This will give you tuples like so:
id, from, total
22, john, 1
124, frank, 3
523, bob, 1
11, david, 3
But this will require some more work, because this will only return the users with unread messages. So you can easily check if there are any messages by friends.
If you want just a general message count to show, for example on a banner:
SELECT count(1) FROM messages WHERE `read` is false and to_user_id = ? -- ? is the authenticated user id
Extra:
There are tons of fancier ways to go, like using redis to cache the message count.
What I've just describe is probably the simpler and uses zero auxiliar infrastructure, aka the burn mysql burn strategy.
pro tip:
if your application is going to rely heavily on messages like a slack type of app, it's not a good idea to store messages in a SQL database. But if you are just learning or tinkering, go ahead!
In your database create a column "Status" of datatype int(1) Default 0.
If I read the message update the status with 1, as by default we are using 0 that means its unread message.
Now at the time counting. Create two variables $total_read = 0 and $total_unread = 0.
Inside your while loop your can go with this
while($row = mysqli_fetch_array($result)) {
if($row['status'] == 0)
{
$total_unread = total_unread + 1
} else {
$total_read = total_read + 1
}
}

Show query result for logged in user

I got some great help in my last question, someone directed me to go learn about database tables and stuff, since then I blasted through most of the things I was stuck on!
Unfortunately I've reached another problem which I can't seem to fix.
I can merge two tables and get results, but I can't seem to get the results of the user that is logged in. For example, I display the amount of 'gold' the user has at the top left corner, I have 7 users that have 100 gold assigned to them and I only want them to be seen when the user that the gold belongs to is logged in, if you get me? Here's what it looks like all the time, whether logged in or not: http://imgur.com/kgqgnPc
here's the code
$sql = 'SELECT `stats`.`id`, `stats`.`gold`, `users`.`id` FROM stats, users WHERE username = username';
$con=mysqli_connect("localhost","root","","game");
mysqli_select_db($con,'game');
$retval = mysqli_query($con,$sql);
if(! $retval )
{
die('Could not get data: ' . mysql_error());
}
while($row = mysqli_fetch_array($retval, MYSQL_ASSOC))
{
echo "Gold :{$row['gold']} <br> ".
"--------------------------------<br>";
I'm 90% sure it's to do with the "select/from/where" part but I've done lots of research and can't get it right :(
Database structure: http://imgur.com/DR40iv8 (Sorry, I don't know how to get it without the command line)
I see that you have the gold in one table and the users in another. The gold in the gold table should point to what user owns the gold. Like for example owner_id pointing to the users id. Then you should be able to do like this:
$sql = "SELECT stats.id, stats.gold, users.id, users.username FROM stats, users WHERE users.username = '$username' AND stats.owner_id = users.id";
This tells to find user with the username specified in $username, and the gold with owner_id the same as the users id matching that username.
Hope this helps
Try:
SELECT `stats`.`id`, `stats`.`gold`, `users`.`id` FROM stats, users WHERE stats.username = users.username
Because username is common to both tables (I assume), it's important to explicitly state which table username is coming from.
Edited to add:
You would still need to specify which username you want from the results of the joined tables.
$sql = 'SELECT `stats`.`id`, `stats`.`gold`, `users`.`id` FROM stats, users WHERE `stats`.username = `users`.username AND `users`.`'.$yourUserVariable.'`;

Grocery Crud - Can't differentiate attribute in returning query table

I've been using Grocery Crud to develop a simple local application that allows users to register themselves and like bands and rate them and select people they know that are also registered in the application.
Entities:
Person(person_id,person_URL, fullname, hometown)
Band(band_id,band_URL,band_name,country,genre)
Relationships:
Likes(person_id,band_id,rate)
Knows(person_id,known_person_id)
My questions are:
1) I want to return a table of person and known person like below:
KNOWS
person_id | fullname | known_person_id | known_fullname
but I can't use *set_relation_n_n* function 'cause the relationship is (Person -> Likes -> Person), so it's giving me error. The other solution I came up with is making a custom table making a query to return the values I want and show it in the table (code below). The custom table returned is correct but when I render it to my Grocery Crud table, I need to specify $crud->columns('person_id', 'fullname', 'known_person_id', 'fullname'), and it cannot differentiate the fullname of the person and the fullname of the known person. How would I make it in order to be able to show the table that way?
2) I have the same issue in another table but could manage that using the function *set_relation_n_n* 'cause it's a relationship (Person -> Likes -> Band), so since it's 2 different entities it didn't return me a error. The problem is that the query (code below) returns me the whole table and I want only 25 records per page. When I try to use "LIMIT 25" in the query, it returns me ONLY 25 records and the "next page" button doesn't work. Any solutions?
Below, all the information:
CODE for question 1:
function knows_management()
{
$crud = new grocery_CRUD();
$crud->set_model('model_socialnetwork');
$crud->set_table('knows');
$crud->set_subject('Known');
$crud->basic_model->set_query_str('SELECT tb1.person_id, tb1.fullname, tb1.known_person_id, person.fullname FROM (SELECT person.person_id, person.fullname, knows.known_person_id FROM person INNER JOIN knows ON person.person_id = knows.person_id) tb1 INNER JOIN person ON tb1.known_person_id = person.person_id');<br>
$crud->columns('person_id','fullname','known_person_id','fullname');
$output = $crud->render();
$this->_socialnetwork_output($output);
}
CODE for question 2:
function likes_management()
{
$crud = new grocery_CRUD();
$crud->set_model('model_socialnetwork');
$crud->set_table('likes');
$crud->set_subject('Like');
$crud->columns('person_id','fullname','band_id','band_name', 'rate');
$crud->basic_model->set_query_str('SELECT tb2.person_id, tb2.fullname, tb2.band_id, band.band_name, tb2.rate FROM(SELECT tb1.person_id, person.fullname, tb1.band_id, tb1.rate FROM(SELECT person.person_id, likes.band_id, likes.rate FROM person INNER JOIN likes ON person.person_id = likes.person_id) tb1 INNER JOIN person ON tb1.person_id = person.person_id) tb2 INNER JOIN band ON tb2.band_id = band.band_id');
$output = $crud->render();
$this->_socialnetwork_output($output);
}
Question 1) What if you use an alias name in your query, for example
SELECT tb1.person_id, tb1.fullname as Tb1fullName, tb1.known_person_id, person.fullname as PersonFullName
Question 2) I would not recommend you to add LIMIT directly / manually in your query. In the file application/config/grocery_crud.php, you have two options directly related to pagination
You should use and configure them properly
// The default per page when a user firstly see a list page
$config['grocery_crud_default_per_page'] = 25;
....
//Having some options at the list paging. This is the default one that all the websites are using.
//Make sure that the number of grocery_crud_default_per_page variable is included to this array.
$config['grocery_crud_paging_options'] = array('10','25','50','100');

Mysql query: How can I get the number of the users who sent messages to my specific user with status =1?

I have a problem with (for me to complicated) MySql query.
Okay, here is what I need to do:
First I need to check messages that some specific user received
$mid=$_SESSION['user'];
$stat1=mysql_query("SELECT id, fromid, toid, subject FROM messages WHERE
toid = '".$mid."' AND subject != 'not readed' GROUP BY fromid ")
or die(mysql_error());
while ($h = mysql_fetch_array($stat1))
{
$whosend=$h['fromid'];
Second thing that I need to do is check the status of the users (deleted or not) who sent the messages ("fromid") to my specific user ("toid"). This I must do from another table:
$stat2=mysql_query("SELECT id, status FROM members WHERE id='".$whosend."' AND
status ='1'")or die(mysql_error());
while ($s = mysql_fetch_array($stat))
{
Then my problems begin to show up.
How can I get the number of the users who sent messages to my specific user with status =1? Not the number of the messages but the total number of the users who sent them.
Is there any easier way to do this query? I tried with join tables like
$stat=mysql_query("SELECT memebers.id, memebers.status, messages.toid,
messages.fromid,messages.subject,messages.id FROM members, messages
WHERE messages.toid='".$mid."' AND members.status ='7' ....
But even in this query I need to have id's of the user who sent messages before this query so there will be another query before this join tables.
So you are looking for the number of members with status = 1 that sent this other member ($mid) a message?
Something like this?
$sql = "select count(distinct messages.fromid) From messages Inner Join members on members.id = messages.fromid Where messages.toid = '" . $mid . "' AND members.`status` = 1";
SELECT id, fromid, toid, subject FROM messages WHERE toid = '".$mid."' AND subject != 'not readed' GROUP BY fromid
can't be right as you have GROUP BY formid and no aggregation in the select clause.

Categories