How do I do the mark as Read or mark as Seen feature?


I want to show notification popup in management panel when data is added to database

How do I mark as read or seen?
What’s the logic in this?

Well, there are so many many ways to do this. Assuming that you are sending notifications to different users, you must have a table with notifications listing user id’s and the notice. You can just add a status col to the table and mark them as read or just delete them once viewed. This would need to be designed as needed by you.
For instance, if you need the users to re-read the notifications, you can mark as read in the status field and add a way to delete the notice when the user no longer needs them. If re-reading them are not needed, once the popup for the notice is show, you can just delete them from the table. This really depends on what you need logic-wise.
Not sure if this answers your question, but, hope it helps you.

I learned that a table is required for notification, thank you
There are two groups of members who will receive the notification

  1. Admin
  2. Registered Reseller

No need to read again


  1. New Price Offers produced
    a) aaaaaaaa
    b) bbbbbbbb
    c) cccccccc

  2. Price Offers Ordered
    a) aaaaaaaa
    b) bbbbbbbb
    c) cccccccc

3.Offers Confirmed
a) aaaaaaaa
b) bbbbbbbb
c) cccccccc

Good, you have a starting place. I see in you image above that you show various notices about system usage. (Google said it was Turkish) You also show times in them. I will assume this is just a display of something else, not the site you are working on.
Now, you should decide on a few other things. First, are the Admin and Resellers going to get the same offer notices. This is important because if they receive different notices, you will need to indicate this in the table. Meaning that you will have to have a col in the table to indicate who gets the notice. If both Admin’s and Resellers get all messages this is not important. Also, you show 3 groups and 3 items in your samples. I assume this can vary depending on your needs.
Lastly, you need to think about where this data comes from and how it is displayed. If it is a list that changes due to time, they can just view the data. If you need to insure that the users read them, you would need the process to have a way for them to mark them as read.
Think out these sections and let us know what you decide. It appears that you are starting to sort it out.

The notification in the picture is an example html is not active.
content is sample

It will only show in the administration panel
Dealers will only receive a notification that their price offer has been approved.

Managers will receive all notifications.

a sample table or suggestion

    user_id(member to receive notification)
    price_offer_was_produced(offer id: 25)
    price_offer_was_produced_read_seen(offer id: 25)
    on_offered(offer id: 12)
    on_offered_read_seen(offer id: 12)
    offer_approved(offer id: 33)
    offer_approved_read_seen(offer id: 33)
    new_seller_registered(seller id: 56)
    new_seller_registered_read_see(seller id: 56)

Will sql rows be added for each declaration?
Will sql rows be added for each member that will receive a notification?
How to determine the new notification after notifications read or seen?

Once the notification has been created, you would need to display them. You can select them in a query using the user id. In the image example you posted, it just shows a drop-down display with a list of items. This would not work well because you need a way to let the user remove them or accept them. You could do this like a post with buttons for accept or remove. Or, you could use a drop-down display and if one of the items are clicked on, they could pop-up a modal form for the user to read more details.
Once the user accepts or removes an offer, you would need to add code to handle marking the table as read or seen.
For the _offered_read_seen, you could just make it a status field instead and mark it as needed.
For example…
Then, mark the status as NEW meaning not read, once read and removed, mark it as READ and once they accept it, mark it as ACCEPTED. In that way, you could query only the NEW ones to show them since all the others have been read or accepted. Same for the other fields.
All of this requires some code to alter the values of the status of each item based on what button is pressed. You would need to add rows for each user_id and each new offer_id. In your examples, you show offers with ids of 25, 12, 33 and 56. Are all of these linked together? I mean, earlier you mentioned new_price_offers, price_offers_ordered and price_offers_confirmed. For that you would only need these items: id, user_id, offer_id, offer_status. Then, status would be NEW or ORDERED or CONFIRMED. Now, you are changing it to other things. I am confused on how to help you. It depends mostly on the actual data you have and need to track. Have you decided what data is needed in this table. Perhaps you can list the data and then we could help you further. I could create a test page for you, but, I would need to know what the data really is set up as first.
( I will not be available for a few hours, but, hope all these comments help you.)

I created the notification panel

There are 3 notifications
I prepared notification pop-up screens for manager and dealer
Features See all AND Mark all read (“Mark all as read” is html only for now)

I will make these notifications from 3 tables

table_1, the table for which quotation is generated
This table contains this information
id, user_id, user_group, offer_number, and other information

table_2, products ordered at the table previously created price offer
This table contains this information
id, user_id, user_group, offer_date, offer_number, and other information

table_3, confirmation table of ordered products
This table contains this information
id, user_id, user_group, confirmation_date, offer_number, and other information

I don’t understand too much at a time I want to do it slowly step by step
(New members notification
I’ll do it later)

Should there be a separate table for each notification?
A table for the new Quote
A table for the New Offer
A table for the New Confirmed Offer

Can you write a table structure?

I have an idea

I have 3 tables

  1. price offer was issued.
  2. bid price was offered
    3.Order confirmed

User read at the end of these tables, let me add the column
reading or seeing user id, let’s enter this column as json
Let’s enter the IDs of the readers with the update
add reading user’s ID [“1”] add reading user’s ID [“1”,“3”] add reading user’s ID [“1”,“3”,“7”]…

IDs here will be excluded when showing in the notification
Is it possible?

Wow, you have been busy. It appears you have accomplished a lot of progress. Good for you!

One minor thing, you have displays of three notifications and you set them next to each other with icons of bells. The user has no idea which is which because they have the same icon. I suggest you should change the icons to three different icons as that would make it easier to know which is which. Do you understand that part? It is minor, but, from a user’s viewpoint it might make it easier for them.

It appears you are getting the tables in place and so far look good to me. I think three separate tables for each notification is a good idea. But, you need to have a table of offers that are displayed to the user so that you can mark it as read. Yes, you could do that with a json or simply an array. You can save PHP arrays into a database field. You just need to “serialize” them to save them. You can use json if that is easier for you. Either way will work. You have done well with your progress designing your system.

Before posting this, I did some research on the best way to store an array into a database. I was thinking of the best way to store an array of users ID marked as read or not-read. Most of the research that I read indicated to just store the array as a serialized data. They suggest setting the field as a BLOB format. Then, you can use one line to serialize the array and another line once it is read back. These commands are quite simple. Here they are:

// how to serialize an array to set up for storage in a BLOB field in an database
$SerializedData = base64_encode(serialize($theArrayName));
// how to un-serialize the data back into an array after it is read from the database
$theArrayName = unserialize(base64_decode($SerializedData));

This is just an example. For the first step, you would add that line just before saving to the database table and use the serialized name instead of the array name when you update the stored value. And, for the second step, you would retrieve your row of data from the table and then unserialize the field that holds the array. In this manner, you can update the table whenever a user marks their offer as been-read and it should work for you. You would just need to design what is held in the array itself. You could use the user-id and a value such as “NEW” and “READ” to tell which user had not read or has marked as read. Then, you would need to alter the notification system to check if an offer has been marked read or not and ignore ones that have been read. Does this make sense to you?

You are doing very well so far! Good luck with the rest.

I’m really a beginner, I’m trying to do something with trial and error, but I learned a lot from you, thank you.

Thank you for your warning,
Left, Order Confirmed
Middle, Order Available
The one on the right, New Price Offer (What should be the appropriate icon?)
I’m waiting for icon suggestions (<i class="fa fa-check">)

users_who_read_ids column, default content [],
Reading user’s ID is added as JSON

I don’t know this but I did it with JSON and it works fine
If there is no ID in the column, he did not read, That’s why one column is enough for the notification system.
I will share my sample codes, I have other works today

There is only one problem
I prepared a file called read.php
here are read marking codes for 3 tables
codes work fine no problem
The offer page clicked on the notification window opens
on this page, read with ajax.php page works

Ajax does not work on page with only PDF download codes

URL in notification window: pdf.php?offer_read=5
Codes on the pdf.php page

$pdffiletime = $_GET['time'];
$file = PDFDIR."/".$read['pdf_name']."-updated";     
$operation = fopen($file, "rb");     
$content = fread($operation, filesize($file));            
header('Content-Type: application/pdf');
header('Content-Transfer-Encoding: binary');
$pdffiletimeupdated = $general['pdf_prefix'].$pdffiletime.'-updated.pdf';                          
header('Content-Disposition: attachment; filename='.$pdffiletimeupdated.'');
header('Content-Disposition: filename='.$pdffiletimeupdated.'');            
echo base64_decode($content);            

        data:{ "offer_read" : "<?php echo $_GET['offer_read']; ?>" },

directly from the browser URL field, pdf.php?offer_read=2 is marked as read
However, ajax does not work when the pdf download link is clicked
How can I fix this problem

Well, Adem, you are doing very well. You thanked me for helping. You are welcome. I enjoy helping others on this site.

I am short on time tonight, but, tomorrow, meaning about 12-13 hours from now, I have a lot of time to look at your code further. Right now, I must head to bed soon. I think the three icons you are using will work well for you. The bell is just fine. The only reason I mentioned that is with three different icons the users will understand they are for different items. It make it easier from a user viewpoint.

More tomorrow! Nice going so far! Remember, when designing your site, think from three different viewpoints… The data design, the admin usage and the user viewpoint. All three are important to review and alter to make all sections work correctly. The icons are minor, but, not to a user who is wondering which usage each is for. That is why I mentioned that one. Goodnight for now!

@ErnieAlex, We are not in a hurry

The codes for the notification are as follows
Renamed to share

// For notification, When New Price Offer Is Produced
$user_id = [$_SESSION['user_id']];
if($_SESSION['user_group'] == "seller"){
    $new_price_offers = $PDO->prepare("SELECT * FROM price_offers WHERE user_group=? AND user_id=?");
    $new_price_offers->execute(['seller', $_SESSION['user_id']]);
  }elseif($_SESSION['user_group'] == "admin"){
    $new_price_offers = $PDO->prepare("SELECT * FROM price_offers");

  $new_price_offers_ids = [];
  $i = 1;
  while($rows = $new_price_offers->fetch()) {

    $read_price_offer = json_decode($rows['reading_IDs'], true);
    // If the reader does not have an ID
    if(count(array_intersect($user_id, $read_price_offer)) == 0){

    //For the notification list
    $new_price_offers_ids[] = $rows['id']."=".$rows['user_id']."=".$rows['name_surname'];
    //For the notification list. 5 New Price Offer
    $new_price_offers_number = $i++;

  // For notification, New Purchaseorders
$user_id = [$_SESSION['user_id']];
if($_SESSION['user_group'] == "seller"){
    $new_purchaseorders = $PDO->prepare("SELECT * FROM purchaseorders
    WHERE offer_id NOT IN (SELECT offer_id FROM confirmed_purchaseorders) AND user_group=? AND user_id=?");
    $new_purchaseorders->execute(['seller', $_SESSION['user_id']]);
}elseif($_SESSION['user_group'] == "admin"){
    $new_purchaseorders = $PDO->prepare("SELECT * FROM purchaseorders
    WHERE offer_id NOT IN (SELECT offer_id FROM confirmed_purchaseorders)");

$new_purchaseorders_ids = [];
$i = 1;
while($rows = $new_purchaseorders->fetch()) {

  $readind_purchaseorders = json_decode($rows['reading_IDs'], true);
    // If the reader does not have an ID
  if(count(array_intersect($user_id, $readind_purchaseorders)) == 0){
//For the notification list.
  $new_purchaseorders_ids[] = $rows['offer_id']."=".$rows['user_id']."=".$rows['name_username'];
//For the notification list. 5 New Purchaseorder
  $new_purchaseorders_number = $i++;

    // For notification, New Confirmed Purchaseorders
  $user_id = [$_SESSION['user_id']];
if($_SESSION['user_group'] == "seller"){
    $new_confirmed_purchaseorders = $PDO->prepare("SELECT * FROM confirmed_purchaseorders WHERE user_group=? AND user_id=?");
    $new_confirmed_purchaseorders->execute(['seller', $_SESSION['user_id']]);
}elseif($_SESSION['user_group'] == "admin"){
    $new_confirmed_purchaseorders = $PDO->prepare("SELECT * FROM confirmed_purchaseorders");

  $new_confirmed_purchaseorders_ids = [];
  $i = 1;
  while($rows = $new_confirmed_purchaseorders->fetch()) {
    $readind_confirmed_purchaseorders = json_decode($rows['reading_IDs'], true);
    // If the reader does not have an ID
    if(count(array_intersect($user_id, $readind_confirmed_purchaseorders)) == 0){

    $new_confirmed_purchaseorders_ids[] = $rows['id']."=".$rows['user_id']."=".$rows['name_username'];
    $new_confirmed_purchaseorders_number = $i++;


// Notification listing html codes
$xxxxx_xxxxx_ids = [];
foreach($xxxxx_xxxxx_ids AS $key => $value){
  $text = explode('=', $value);
  if($_SESSION['user_group'] == "seller"){
      echo $text[0];
      echo $text[1];
      echo $text[2];
      // Notification listing html codes
  }elseif($_SESSION['user_group'] == "admin"){
    echo $text[0];
    echo $text[1];
    echo $text[2];
    // Notification listing html codes
  $yyyyy_yyyyy_ids[] = $text[0];

<a class="red" href="xxxxx.php?reading_xxxx_xxxx=<?php echo implode(',', $yyyyy_yyyyy_ids); ?>">Mark All Read</a>

Codes on page marking all or one as read

if(isset($_GET['readind_xxxxxxxxxx']) && !empty($_GET['readind_xxxxxxxxxx'])){

    $readind_xxxxxxxxxx_ids = array_map('trim', explode(',',$_GET['readind_xxxxxxxxxx']));

    $in  = str_repeat('?,', count($readind_xxxxxxxxxx_ids) - 1) . '?';
    $sql = "SELECT * FROM xxxxxxxxxx WHERE id IN ($in)";
    $stm = $PDO->prepare($sql);

    $readings = [];
    $user_id = [$_SESSION['user_id']];

    $query = $PDO->prepare("UPDATE xxxxxxxxxx SET reading_IDs=? WHERE id=? ");

    while($rows = $stm->fetch()){

        $readings = json_decode($rows['reading_IDs'], true);

        if(count(array_intersect($user_id, $readings)) == 0){
            $add_user_id = array_merge($user_id, $readings);
            $reading_IDs = json_encode($add_user_id);

            $query->bindParam(1, $reading_IDs, PDO::PARAM_STR);
            $query->bindParam(2, $rows['id'], PDO::PARAM_STR);



An idea came to my mind again
If the user visits the item from outside the Notification window, it will mark it as read.
Therefore, I added read markup code into pdf download codes, and no ajax code needed
Visitors to new item pages will be marked as read
I think it’s better this way

Sounds good. You did not mention that you wanted to use a separate page. That does make it easier!
You said you wanted a notification pop-up. A separate page to show the new offers is easier and should
work well for you.

I may have said it wrong in English expression

I mean the notification panel window is the screen in the picture

The IDs of the selected products are saved in the database when a quote is issued.
AND PDF file is created and saved to server (original file)
When this original PDF file is viewed, it is removed from the notification, meaning it is marked as seen.
To see the quotation produced, it is necessary to look at the PDF file.
If you want to view the price quote from the database, all prices or exchange rates are updated and displayed.

There is an order table / page to order the products in the offer
The products selected here are listed on the orders page when ordered.
When the order clicked on the Orders page is opened on a separate page, it is deleted from the notification and marked as read.
ANDThe manager approves the order and a PDF file is created as an approved order

Confirmed orders work like orders
To see the approved order, either the PDF file or the approved orders are displayed on the table / page.
AND When any option is displayed, the notification is also deleted and marked as read.

I ran into a problem now:
I use paging to list all items in my script, There is no problem here, it works exactly as I want it
From the notification panel, I need to filter when clicking the show all in x notifications option
page.php?ids=1,5,7,9,45,62 as

I don’t want to break the paging and search code below, I want to add listing feature by filtering IDs coming with get.
if get came with ID
var query = ‘1,5,7,9,45,62’;

Listing pages


html table
<div id="rows">(lines of content)</div>
<div id="links">(pagination number links)</div>
<td><select name="number_per_page" id="number_per_page"><input type="text" id="search"></td>

  <script type='text/javascript'>
  var row = "orders_placed";
  var query = '';
  <script src="js/pagination.js"></script>


    $limit = $_POST['per'];
    $limit = '10';
    $search_keyword = " '%%' ";
    if(!empty($_POST['query'])) {
      $search_keyword = $_POST['query'];
    // Search in double quotes
    $pattern = '/^".+"$/i';
    if(preg_match($pattern, $search_keyword))
      $searchkeyword = str_replace('"','',$search_keyword);
      $search_keyword = " '$searchkeyword' ";
    $search_keyword = " '%$search_keyword%' ";
    $n = 4; 
    $search_params = array_fill(0, $n, $search_keyword);
    $sql = 'SELECT,
      FROM confirmed_orders 
      LEFT JOIN members ON confirmed_orders.member_id = members.member_id
      confirmed_orders.offer_no LIKE '.$search_keyword.' OR 
      confirmed_orders.offer_id LIKE '.$search_keyword.' OR 
      confirmed_orders.offer_date LIKE '.$search_keyword.' OR 
      confirmed_orders.member_id LIKE '.$search_keyword.'
      ORDER BY ASC ';
    $page = 1;
    $start = 0;
    if(!empty($_POST["page"])) {
      $page = $_POST["page"];
      $start = ($page-1) * $limit;
    $limit_code = " LIMIT " . $start . "," . $limit;
    $pagination_statement = $PDO->prepare($sql);
    $total_page = $pagination_statement->rowCount();
    $query = $sql.$limit_code;
    $pdo_statement = $PDO->prepare($query);
    $result = $pdo_statement->fetchAll();

    foreach($result as $row){
        $rows .= "";


load_data(1, 10, row, query);

function load_data(page, per, row, query = ''){
    dataType: "json",
    data:{ page:page, query:query, per:per, "sayfala" : "1", "product" : row },

      for(let i = 0; i < emails.length; i++){
        $('input[value="' + emails[i] + '"]').attr('checked', true);

$(document).on('click', '.page-link', function(){
  var page = $(this).data('page_number');
  var per = $(this).data('per_number');
  var query = $('#search').val();
  load_data(page, per, row, query);

$('#number_per_page').change(function() {
  var per = $(this).val();
  var query = $('#search').val();
  load_data(1, per, row, query);

$('#search').bind("keyup change", function(){
  var query = $('#search').val();
  var per = $('select[name=number_per_page] option').filter(':selected').val();
  if(query != '""' && query != '"'){  
  load_data(1, per, row, query);

I am not sure what you are asking. Normally filtering is handled inside the query. You would need to pass what you want to filter to the data.php file and alter the query to filter out items you do not need. And, pagination is always handled using the LIMIT function in queries. If you set a filter of something, you do it in the database query.

I am not sure if this is what you are asking. If you are asking how to add only certain id’s in a query, you can use something like this:
var query = ‘1,5,7,9,45,62’
In the query use AND id IN(1,5,7,9,45,62)
This would check if the id is in a list of id numbers. Is that what you need?

1 Like

Yes, this is what I want, I did it like you said and it worked

    $ids = 'AND IN('.$_POST['ids'].')';
    $ids = "";

`$sql = 'SELECT, 
FROM confirmed_orders 
LEFT JOIN members ON confirmed_orders.member_id = members.member_id 
(confirmed_orders.offer_no LIKE '.$search_keyword.' OR 
confirmed_orders.offer_id LIKE '.$search_keyword.' OR 
confirmed_orders.offer_date LIKE '.$search_keyword.' OR 
confirmed_orders.member_id LIKE '.$search_keyword.') 
'.$ids.' ORDER BY ASC ';`

Thank you

Great! Always nice to solve a programming puzzle !

Sorry I did not understand your question earlier. Glad we figured it out! See you in your next question…

1 Like
Sponsor our Newsletter | Privacy Policy | Terms of Service