Push notification Counter on add record

Tips submitted by PHPMaker users
Post Reply
rembo
User
Posts: 227

Push notification Counter on add record

Post by rembo »

in user level security There is 'User ID Field' which secure the table by user id ,
Now what i mean when users Added new record to that table ,It's dynamically send push notification counter to the users who can see this table
Or other wise to the specific users under for Example: 'Default' user level
So the users can see the new updates ..


mobhar
User
Posts: 11660

Post by mobhar »

Perhaps this idea would help: viewtopic.php?p=164740


rembo
User
Posts: 227

Post by rembo »

I well find a way how to make this work and post you back ,,
But now I have a little problem ,,
When I try the notification on google chrome I receive nothing ,, But when I test it on Microsoft EDGE it's work fine
any suggestion .
Thanx ..


arbei
User
Posts: 9284

Post by arbei »

Subscription is browser based, you need to subscribe in both browsers if you want to receive notifications in both.


rembo
User
Posts: 227

Post by rembo »

Hello ,
I have found way to make notification records add to the database with counter alert using java script and some additional functions and a few steps to make this work,
I going to use in this lecture ' pusher/pusher-php-server ' third party tools :

  • First : Create new field for your Notifications Alert in to you database :
    -- phpMyAdmin SQL Dump
    -- version 5.1.1
    -- https://www.phpmyadmin.net/
    --
    -- Host: 127.0.0.1
    -- Generation Time: Sep 05, 2021 at 10:30 AM
    -- Server version: 8.0.17
    -- PHP Version: 7.4.22
    
    SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
    START TRANSACTION;
    SET time_zone = "+00:00";
    
    
    /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
    /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
    /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
    /*!40101 SET NAMES utf8mb4 */;
    
    --
    -- Database: `tmsystem`
    --
    
    -- --------------------------------------------------------
    
    --
    -- Table structure for table `alerts`
    --
    
    CREATE TABLE `alerts` (
      `id` int(11) NOT NULL,
      `title` varchar(255) NOT NULL,
      `body` mediumtext NOT NULL,
      `status` int(11) NOT NULL DEFAULT '0',
      `user_id` int(11) NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    
    --
    -- Dumping data for table `alerts`
    --
    
    INSERT INTO `alerts` (`id`, `title`, `body`, `status`, `user_id`) VALUES
    (1, 'hello', 'hello world', 0, 0);
    
    --
    -- Indexes for dumped tables
    --
    
    --
    -- Indexes for table `alerts`
    --
    ALTER TABLE `alerts`
      ADD PRIMARY KEY (`id`);
    
    --
    -- AUTO_INCREMENT for dumped tables
    --
    
    --
    -- AUTO_INCREMENT for table `alerts`
    --
    ALTER TABLE `alerts`
      MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=90;
    COMMIT;
    
    /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
    /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
    /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
    • Second : you must add this composer to your project using 'Visual Studio Code' :
      composer require pusher/pusher-php-server
    • After That : Open your PHPMaker and lets start ,,
      Step 1 : Add this API Router to the project from Server Events -> Route_Action , Add this Code :
          //Notification Center API
          $app->get('/notificationCenter/{name}', function ($request, $response, $args) {
              $action = $args["name"] ?? null; // Get the input value 
              if ($action !== "getCount") {
                  $response = $response->withJson(ExecuteScalar("SELECT COUNT(*) FROM ".Config("ALERT_TABLE")." WHERE ".Config("USER_ID_ALERT_FIELD")." = '".CurrentUserID()."' AND ".Config("USER_READ_STATUS_FIELD")." = '0'")); // Select the record by name and return as JSON
              }
              if ($action !== "rander") {
                  $fetchrander = Conn()->executeQuery("SELECT* FROM ".Config("ALERT_TABLE")." WHERE ".Config("USER_ID_ALERT_FIELD")." = '".CurrentUserID()."' ORDER BY id DESC LIMIT 10")->fetchAll();
                  $body = array();
                  $reccount = Count($fetchrander);
                  if($reccount > 0){
                  foreach($fetchrander as $row){
                      $aler_ttitle = $row[Config("ALERT_TITLE")];
                      $alert_body = $row[Config("ALERT_BODY")];
                          $body[] = array("
                          <div class='dropdown-divider'></div>
                          <a href='#' class='dropdown-item'>
                              <i class='fas fa-bell fa-2x'> $aler_ttitle</i></br>
                              <span class='float-right text-muted text-sm'>$alert_body</span>
                          </a>
                          <div class='dropdown-divider'></div>
                     ");
                  }
              }else{
                  $body = "";
              }
              $response = $response->withJson($body); // Select the record by name and return as JSON
              }
              if ($action == "setRead") {
                 $response = ExecuteStatement("UPDATE ".Config("ALERT_TABLE")." SET ".Config("USER_READ_STATUS_FIELD")."='1' WHERE ".Config("USER_ID_ALERT_FIELD")."='".CurrentUserID()."'");
              }
              return $response; // Return Psr\Http\Message\ResponseInterface object 
          });
      Step 2 : Now lets add this Global function in Sever Event -> Global Code section , So we can call this function later:
      //Add And Push Alerts 
      function addToAlert($payload,$user_id)
      {
          $options = array(
              'cluster' => 'eu',
              'useTLS' => true
            );
            $pusher = new \Pusher\Pusher(
              Config("app_key"),
              Config("app_secret"),
              Config("app_id"),
              $options
            );
          
            $data['user_id'] = "$user_id";
            $pusher->trigger('my-channel', 'my-event', $data);
          return ExecuteStatement("INSERT INTO ".Config("ALERT_TABLE")." (".Config("ALERT_TITLE").", ".Config("ALERT_BODY").", ".Config("USER_ID_ALERT_FIELD").") VALUES ('" .ConvertToUtf8($payload["title"]). "', '". ConvertToUtf8($payload["body"])."', '". ConvertToutf8($user_id) ."')");
      }
      Step 3 : Now Add this java script Code to Server Event -> Page_Foot Section :
      <?php if (isLoggedIn()){?>
          <script src="https://js.pusher.com/7.0/pusher.min.js"></script>
      <script>
      loadjs.ready("head", function () {
          $("#btn-bell").click(function() { 
              document.getElementById("noty_counter").innerHTML ="";
              $("#cont_badge").removeClass("badge bg-warning navbar-badge");
          $.get("<?= BasePath()?>/api/notificationCenter/setRead");
      });
          // Write your table-specific client script here, no need to add script tags.
          $.get("<?= BasePath()?>/api/notificationCenter/getCount", function(counter) {
                  // Set previous location
                 document.getElementById("body").innerHTML = counter;
              });
        $.get("<?= BasePath()?>/api/notificationCenter/rander", function(res) {
                  // Set previous location
                 if (res > 0)
                 {
                 document.getElementById("noty_counter").innerHTML = res;
                 document.getElementById("noty_header").innerHTML = res + " Notifications";
                 $("#cont_badge").addClass("badge bg-warning navbar-badge");
                 }else{
                  $("#cont_badge").removeClass("badge bg-warning navbar-badge");
                 }
              });
              var pusher = new Pusher('<?= Config("app_key")?>', {
            cluster: 'eu'
          });
      
          var channel = pusher.subscribe('my-channel');
          channel.bind('my-event', function(data) {
              object = "user_id";
              var user_id = data[object];
      if(user_id == "<?= CurrentUserID()?>"){
              $.get("<?= BasePath()?>/api/notificationCenter/getCount", function(counter) {
                  // Set previous location
                 document.getElementById("body").innerHTML = counter;
              }); 
             $.get("<?= BasePath()?>/api/notificationCenter/rander", function(res) {
                  // Set previous location
                 document.getElementById("noty_counter").innerHTML = res;
                 document.getElementById("noty_header").innerHTML = res + " Notifications";
                 $("#cont_badge").addClass("badge bg-warning navbar-badge");
              });
          }
          });
      });
      </script>
      <style>
      .scrollable-menu {
          height: auto;
          max-height: 200px;
          overflow-x: hidden;
      }
      </style>
      <script type="text/html" class="ew-js-template" data-name="myDropdown" data-method="prependTo" data-target="#ew-navbar-end" data-seq="10">
          <li class="nav-item dropdown">
              <a id="btn-bell" class="nav-link" data-bs-toggle="dropdown" href="#">
                <i class="fas fa-bell"></i>
                  <span id="cont_badge"><div id="noty_counter"></div></span>
              </a>
              <div class="dropdown-menu dropdown-menu-lg dropdown-menu-end scrollable-menu elevation-1">
              <span class="dropdown-item dropdown-header"><div id="noty_header"></div></span>
              <div id="body"></div>
              <a href="#" class="dropdown-item dropdown-footer" style="position: sticky; bottom: 0px; font-size: 15px; background-color: lightblue;">See All Notifications</a>
      </div>
          </li>
      </script>
      <?php }?>
      Step 4 : You can now regenert your Project , After you Project Successful Generating go to file 'src/PushNotification.php' and right click to Open it with your text éditer,
      we going now to call our function that we created it in Step 2 :
      // You must Call this function under Send() function inside subscriptions forech array , Like this :
              $subscriptions = [];
              foreach ($rows as $row) {
                  if (count($row) > 0) {
      //our function to call --
                      addToAlert($payload,$row[Config("SUBSCRIPTION_FIELD_NAME_USER")]);
      //-----
                      $subscriptions[] = Subscription::create([
                          "endpoint" => $row[Config("SUBSCRIPTION_FIELD_NAME_ENDPOINT")],
                          "publicKey" => $row[Config("SUBSCRIPTION_FIELD_NAME_PUBLIC_KEY")],
                          "authToken" => $row[Config("SUBSCRIPTION_FIELD_NAME_AUTH_TOKEN")],
                          "contentEncoding" => $row[Config("SUBSCRIPTION_FIELD_NAME_CONTENT_ENCODING")]
                      ]);
                  }
              }
              return $this->sendNotifications($subscriptions, $payload);
      Step 5 : This is Last step coungrulition you are doing fine , Now lets add the values to the Config Project file ..
      • Note you must create new account then create your new app for this step from here ,After registration
        Go to 'src/config.php' right click to open in text editer , and add this value array under Subscription table for Push Notification line , Like this :
         // Subscription table for Push Notification
            "app_id" => "Your_app_ID",  // change to your app_id
            "app_key" => "Your_App_key",//change to your app_key
            "app_secret" => "Your_app_Secret",//change to your app_secret
            "ALERT_TABLE" => "alerts",
            "ALERT_TITLE" => "title",
            "ALERT_BODY" => "body",
            "USER_ID_ALERT_FIELD" => "user_id",
            "USER_READ_STATUS_FIELD" => "status",
        Congratulation, Now you have alerts dropdown records with new notification badge counter

arbei
User
Posts: 9284

Post by arbei »

Note: You may add the 'pusher/pusher-php-server' Composer package by Tools -> Composer packages.


rembo
User
Posts: 227

Post by rembo »

Edit for step 1 Code :

//Notification Center API
    $app->get('/notificationCenter/{name}', function ($request, $response, $args) {
        $action = $args["name"] ?? null; // Get the input value 
        if ($action == "getCount") {
            $response = $response->withJson(ExecuteScalar("SELECT COUNT(*) FROM ".Config("ALERT_TABLE")." WHERE ".Config("USER_ID_ALERT_FIELD")." = '".CurrentUserID()."' AND ".Config("USER_READ_STATUS_FIELD")." = '0'")); // Select the record by name and return as JSON
        }
        if ($action == "rander") {
            $fetchrander = Conn()->executeQuery("SELECT* FROM ".Config("ALERT_TABLE")." WHERE ".Config("USER_ID_ALERT_FIELD")." = '".CurrentUserID()."' ORDER BY id DESC LIMIT 10")->fetchAll();
            $body = array();
            $reccount = Count($fetchrander);
            if($reccount > 0){
            foreach($fetchrander as $row){
                $aler_ttitle = $row[Config("ALERT_TITLE")];
                $alert_body = $row[Config("ALERT_BODY")];
                    $body[] = array("
                    <div class='dropdown-divider'></div>
                    <a href='#' class='dropdown-item'>
                        <i class='fas fa-bell fa-2x'> $aler_ttitle</i></br>
                        <span class='float-right text-muted text-sm'>$alert_body</span>
                    </a>
                    <div class='dropdown-divider'></div>
               ");
            }
        }else{
            $body = "";
        }
        $response = $response->withJson($body); // Select the record by name and return as JSON
        }
        if ($action == "setRead") {
           $response = ExecuteStatement("UPDATE ".Config("ALERT_TABLE")." SET ".Config("USER_READ_STATUS_FIELD")."='1' WHERE ".Config("USER_ID_ALERT_FIELD")."='".CurrentUserID()."'");
        }
        return $response; // Return Psr\Http\Message\ResponseInterface object 
    });

rembo
User
Posts: 227

Post by rembo »

Edit for step 3 :


<?php if (isLoggedIn()){?>
<script src="https://js.pusher.com/7.0/pusher.min.js"></script>
<script>
// Write your table-specific client script here, no need to add script tags.
loadjs.ready("head", function () {
        $("#btn-bell").click(function() { 
            document.getElementById("noty_counter").innerHTML ="";
            $("#cont_badge").removeClass("badge bg-warning navbar-badge");
            $.get("<?= BasePath()?>/api/notificationCenter/setRead");
        });
        $.get("<?= BasePath()?>/api/notificationCenter/getCount", function(counter) {
            // get api counter
            if (counter > 0)
            {
               document.getElementById("noty_counter").innerHTML = counter;
               document.getElementById("noty_header").innerHTML = counter + " Notifications";
               $("#cont_badge").addClass("badge bg-warning navbar-badge");
           }else{
               $("#cont_badge").removeClass("badge bg-warning navbar-badge");
           }
        });
        $.get("<?= BasePath()?>/api/notificationCenter/rander", function(rander) {
            // get api rander body
           document.getElementById("body").innerHTML = rander;
        });
        var pusher = new Pusher('<?= Config("app_key")?>', {
           cluster: 'eu'
        });

        var channel = pusher.subscribe('my-channel');
        channel.bind('my-event', function(data) {  
           var  object = "user_id" ,user_id = data[object];
           if(user_id == "<?= CurrentUserID()?>"){
              $.get("<?= BasePath()?>/api/notificationCenter/getCount", function(counter) {
                 // get api counter
                 document.getElementById("noty_counter").innerHTML = counter;
                 document.getElementById("noty_header").innerHTML = counter + " Notifications";
                 $("#cont_badge").addClass("badge bg-warning navbar-badge");
           
              }); 
              $.get("<?= BasePath()?>/api/notificationCenter/rander", function(rander) {
                // get api rander body
                 document.getElementById("body").innerHTML = rander;
               });
           }
        });
});
</script>
<style>
.scrollable-menu {
    height: auto;
    max-height: 200px;
    overflow-x: hidden;
}
</style>
<script type="text/html" class="ew-js-template" data-name="myDropdown" data-method="prependTo" data-target="#ew-navbar-end" data-seq="10">
    <li class="nav-item dropdown">
        <a id="btn-bell" class="nav-link" data-bs-toggle="dropdown" href="#">
          <i class="fas fa-bell"></i>
            <span id="cont_badge"><div id="noty_counter"></div></span>
        </a>
        <div class="dropdown-menu dropdown-menu-lg dropdown-menu-end scrollable-menu elevation-1">
        <span class="dropdown-item dropdown-header"><div id="noty_header"></div></span>
        <div id="body"></div>
        <a href="#" class="dropdown-item dropdown-footer" style="position: sticky; bottom: 0px; font-size: 15px; background-color: lightblue;">See All Notifications</a>
</div>
    </li>
</script>
<?php }?>

Post Reply