In this article, we are going to show you how you can display a beautiful message in a browser console using Javascript. You just need to download a library called Figlet.
After download, you need to extract the zip file and copy the file lib/figlet.js in your project. You also need to copy the fonts folder too.
Then you need to include that library in your project using the script tag:
<script src="figlet.js"></script>
Right after that, you can display the message you want in the browser console:
<script>
// initialize the library
const textDisplay = "adnan-tech.com";
const font = "Speed";
figlet(textDisplay, font, function (error, text) {
// display the text in console
console.log(text);
});
</script>
An email marketing tool is created in Laravel and Vue JS. It is a single-page application. It allows you to send bulk emails to a large group of people. The database used for this project is MySQL.
The first step is to add an SMTP account. You can add your hosting SMTP account or even your personal Gmail account as well. To add an SMTP account, you need to enter your hostname, usually, it is like this mail.yourdomain.com. But you need to visit your hosting cPanel and go to the “Email Accounts” to confirm.
Then you need to enter the “Display name“. This is the name that will be displayed to the recipients when you start sending emails through campaigns. And finally, the email and password of your email account. Your credentials are stored securely in our server and you can delete the SMTP account at any time and it will be deleted permanently (no trash can or backup).
Contact us to get help in this step.
Note: If you delete the SMTP account, all campaigns where that account is used, will be deleted as well.
2. Create a list
Then you need to create a list. In this list, you can add as many people as you want. You only need to enter the name of the list, for example, “USA Subscribers” etc. You can add multiple lists as well. Then while running the campaign, you can simply select the list and it will automatically send emails to all the users in that list.
3. Add subscribers in a list
Now that you have created a list, you can start adding subscribers to it. Adding a subscriber is super easy, simply enter the name and email of the person. Then select the list where he wanted to be added. You can add the same subscriber in multiple lists as well. There is no such restriction.
4. Create a campaign for email marketing
Creating a campaign is also super simple. You just need to enter the name of the campaign like “Black Friday Sales” etc. Then you need to write the content of the email that needs to be sent. The content of the email can be HTML too so you can use HTML tags and CSS properties as well.
Then you need to select the list for that campaign. The campaign will send emails to all the subscribers that are added to that list. And finally, you need to select the SMTP account from whom the email should be sent. Since you might have multiple SMTP accounts like:
sales@yourwebsite.com
support@yourwebsite.com
info@yourwebsite.com
no-reply@yourwebsite.com
You can select the SMTP account of your choice to use as a “Sender” of that particular campaign.
5. Run an email marketing campaign
The final step is to run the campaign and sit and relax. You will see all your added campaigns with a status. We have 3 statuses for each campaign:
draft: The campaign is created and ready to start sending emails.
active: The campaign has been started and is sending emails to the selected list of subscribers. You can check every 30 minutes to check the progress.
done: The campaign has sent emails to all the subscribers added to that list.
Dynamic variables in email
Since in email marketing you will be sending emails in bulk, you might want to address each user differently. For example, it is better to have an email that starts with “Hello Mr. John” rather than just “Hello”. Personalizing your email has a higher chance of getting more sales.
Track each email
The email will be sent to a large number of people and the content of each email can be different like the recipient name etc. So you can see the content of each email sent to subscribers so you can know if your users have received the email correctly.
Send single email
Campaigns are used to send bulk emails, but sometimes you just want to send an email to a single person only. We have added a feature that allows you to do that. You can simply enter the name and email address of the recipient, and enter the subject and body of the email. Again the body of the email can be HTML too.
Email with attachments
When sending single emails, you can also attach multiple documents to them. The documents will be attached to the email and the recipient will be able to download it directly from their mail client, for example, Gmail, Outlook, Webmail, Thunderbird, etc.
Business model
If you buy this project, you can also make money from it. Just give a trial period of 3 days with all features to your users, after that you can charge per day. You can see the pricing from here, you can set the pricing as you desire. Check the below video to find out how the trial period works:
Google one-tap sign in and sign up
You can sign in or sign-up with your Google account with just one click. If the user’s account is not created, then it will be created automatically and the user will be logged-in. Otherwise, it will simply log in to the user.
In this article, we will show you how you can password protect your zip file in Mac OS X. To create a ZIP file and set the password to it using Mac, you simply need to follow the following steps:
Open Terminal
Open folder where target file is located by running the command:
cd “path of folder”
Run the following command:
zip -er “my-file.zip” “target file or folder”
It will ask password twice.
It may take longer for large files. You can then use the encrypted file on all iOS-based devices like Mac, iPhone, iPad, etc.
Learn how to password protect a ZIP file in PHP from this tutorial.
If you are a windows user, you can use the 7-zip software to password-protect the files.
In this tutorial, we are going to create a simple WordPress plugin that allows you to signin with google to your website. Here is the demo of what we are going to create.
Demo
Table of content
Creating and Activating the Plugin.
Displaying Google One-tap Sign In Popup.
Calling an AJAX in WordPress.
Show Popup to Non-authenticated Users Only.
Replace User Gravatar with Your Image.
Let’s get started
So let’s start allowing your users to signin with google on your WordPress website.
First, go to your wp-content content at the root of your WordPress website. And inside this, go to the plugins folder. Then create a new folder named signin-with-google. This will be our plugin folder, you are free to name it as you like.
Inside this newly created folder, create a new file named signin-with-google.php. This will be our main file. By setting the same name as the folder name, WordPress will automatically pick it up as the main file. Write the following code in this file to view it on the “Plugins” page in the admin panel.
<?php
/**
* Plugin Name: Sign in With Google
* Description: This plugin is for one-tap google sign in.
* Version: 1.0
* Author: adnan-tech.com
**/
Go to your “Plugins” page in your WordPress admin dashboard and you will see your plugin as “Sign in With Google”. You can find the direct link to the plugins folder from the following URL:
https://{your_domain}/wp-admin/plugins.php
You need to “Activate” your plugin in order to make it work.
Displaying google one-tap sign-in popup
To display the Google one-tap Sign-in popup on each page, you first need to generate a Google OAuth client ID. You can generate it from here. Or you can follow our tutorial that will help you set this up.
After the client ID is generated, write the following code in your plugin’s main file:
function SIWG_init()
{
// [user authentication is checked here]
// [JS scripts will be included here]
echo '<script src="https://accounts.google.com/gsi/client" async defer></script>
<div id="g_id_onload"
data-client_id="{your_google_client_id}"
data-context="signin"
data-callback="SIWG_googleLoginEndpoint"
data-close_on_tap_outside="false">
</div>';
}
add_action('wp_footer', 'SIWG_init');
Make sure to write your own Google Client ID in place of {your_google_client_id} code. Refresh your frontend side and open your browser console window. You will see an error that you need to create a Javascript function. So we will create a Javascript function that will be called when the user clicks the “Sign in” button on the popup.
So write the following code in the [JS scripts will be included here] section:
Then create the file named SIWG-script.js at the root of your plugin folder. We are appending “?v=1” at the end of the path of the file, it is to prevent the browser from caching this file. If you are making changes in your Javascript code and your changes are not being reflected when you refresh the page, simply increment the “?v=1” counter and it will work fine.
Following will be the code of SIWG-script.js file:
function SIWG_googleLoginEndpoint(googleUser) {
console.log(googleUser);
// [ajax code goes here]
}
Now refresh the page and this time there will be no error. Click the “Sign in” button in the popup and you will see the credential object in the browser console. On the client-side, Google only returns this credential also known as ID Token. We will send this ID Token to the server to verify the user.
Calling an AJAX in WordPress
To send an AJAX in WordPress, we need to include a built-in WordPress library called wp-util. So write the following code in the [include WP util] section:
// Manually enqueue the wp-util library.
wp_enqueue_script( 'wp-util' );
After that, we need to call an AJAX from Javascript. So replace the [ajax code goes here] section with the following code:
Now we need to create an API in our plugin’s main PHP file that will handle this request.
// a function that will handle the AJAX request
function SIWG_google_login()
{
// secure credential value from AJAX
$credential = sanitize_text_field($_POST["credential"]);
// verify the ID token
$curl = curl_init( 'https://oauth2.googleapis.com/tokeninfo?id_token=' . $credential );
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
$response = curl_exec( $curl );
curl_close( $curl );
// convert the response from JSON string to object
$response = json_decode($response);
// if there is any error, send the error back to client
if (isset($response->error))
{
wp_send_json_error($response->error_description);
}
else
{
// check if user already exists in WordPress users
$user_id = username_exists( $response->email );
if ( ! $user_id && !email_exists( $response->email ) )
{
// user does not exists
// generate a random hashed password
$random_password = wp_generate_password( $length = 12, $include_standard_special_chars = false );
// insert the user as WordPress user
$user_id = wp_insert_user([
"user_email" => $response->email,
"user_pass" => $random_password,
"user_login" => $response->email,
"display_name" => $response->name,
"nickname" => $response->name,
"first_name" => $response->given_name,
"last_name" => $response->family_name
]);
}
// do login
$user = get_user_by('login', $response->email );
if ( !is_wp_error( $user ) )
{
wp_clear_auth_cookie();
wp_set_current_user ( $user->ID );
wp_set_auth_cookie ( $user->ID );
// set user profile picture
update_user_meta($user->ID, "SIWG_profile_picture", $response->picture);
}
// send the success response back
wp_send_json_success( $response );
}
}
add_action( 'wp_ajax_nopriv_SIWG-google-login', 'SIWG_google_login' );
Comments have been added with each line for an explanation. Refresh the page now and when the popup is displayed, click on the “Sign in” button. Your browser page will refresh automatically after a few seconds. And you will see that the user is now logged-in.
You can also see the user in the admin panel dashboard.
Show popup to non-authenticated users only
Users who are already logged in to your site should not be seeing the popup as they are already logged in. So we need to show this popup only for users who are not logged in. So write the following code in the [user authentication is checked here] section:
if (is_user_logged_in())
{
return false;
}
It will simply stop the function from executing if the user is already logged in.
Replace user gravatar with your image
We are saving the user profile picture URL from google in our user metadata using the key “SIWG_profile_picture“. Now we need to display it. To do that, we need to add a filter that will update the WordPress Gravatar image with the URL saved in the database. Add the following code in your plugin’s main PHP file.
function SIWG_override_avatar( $avatar, $id_or_email, $size, $default, $alt )
{
//If is email, try and find user ID
if( ! is_numeric( $id_or_email ) && is_email( $id_or_email ) )
{
$user = get_user_by( 'email', $id_or_email );
if( $user )
{
$id_or_email = $user->ID;
}
}
//if not user ID, return
if( ! is_numeric( $id_or_email ) )
{
return $avatar;
}
//Find URL of saved avatar in user meta
$saved = get_user_meta( $id_or_email, 'SIWG_profile_picture', true );
//check if it is a URL
if( filter_var( $saved, FILTER_VALIDATE_URL ) )
{
//return saved image
return '<img src="' . esc_url( $saved ) . '" alt="' . esc_attr( $alt ) . '" />';
}
//return normal
return $avatar;
}
add_filter( 'get_avatar', 'SIWG_override_avatar', 10, 5 );
By adding the above code, if the user is logged-in and is registered by Google, then his profile picture will be displayed as in his google account. Otherwise, it will be displayed by WordPress gravatar.
So that’s how you can enable your site’s visitors to signin with google on your wordpress website. This will definitely increase the number of daily registrations. Because it is a quicker way for the users to join.
MEVN stands for Mongo DB, Express JS, Vue JS, and Node JS. In this tutorial, we will teach you how you can create a picture competition web app using Node JS as a back-end server, Mongo DB as a database, and Vue JS as a front-end.
Although you do not need the assets to run this project. But if you want to have a beautiful bootstrap user interface, then you must download the required assets from this Github repo.
Setup the Project
First, you need to download and install Node JS, you can download it from their official site. Then you need to download and install Mongo DB, you can download this from their official site as well. To view the data in Mongo DB you need to download a software called “Mongo DB Compass“, you can download it from here.
Then create a new folder anywhere on your PC and rename it to “picture-competition“. Create a new folder “public” where we will place all our CSS and JS files including Bootstrap and jQuery etc. Create another folder “views” and leave it empty for now, we will place all our HTML files in it.
Node JS
Open a command prompt at the root folder of your project and run the following command:
npm init
And press “enter” for each question asked, it will set the default values. Then run the following command:
npm install express http
This will install the Express framework which we will use for routing and API calls. HTTP module will be used to start the server at a specific port. Then we need to run the following command:
sudo npm install -g nodemon
sudo is used to get admin privileges, nodemon module is used to restart the server automatically if there is any change in the server file. Then create a file named “server.js” and write the following code in it:
var express = require("express");
var app = express();
var http = require("http").createServer(app);
// [set EJS engine]
// [mongo db initialization code goes here]
http.listen(process.env.PORT || 3000, function () {
console.log("Server started");
// [mongo db connection goes here]
});
Now run the following command to start the server:
nodemon server.js
If you open the terminal, you will see the message that the server has been started.
User Registration
Login and Registration
Now we need to display a registration form, when submitted should save the record in Mongo DB. To display HTML pages in Node JS, we need to include a module named “EJS“. So run the following command to install it:
npm install ejs
Make sure to restart the server by running the nodemon server.js command. Then write the following code in your server.js by replacing the [set EJS engine] section:
Now you need to install the Mongo DB module, so run the following command:
npm install mongodb
After that, you need to write the following code in place of the [mongo db initialization code goes here] section:
var mongodb = require("mongodb");
var MongoClient = mongodb.MongoClient;
var ObjectId = mongodb.ObjectId;
After that, replace the section [mongo db connection goes here] with the following code:
MongoClient.connect("mongodb://localhost:27017", function (error, client) {
if (error) {
console.error(error);
return false;
}
var db = client.db("picture_competition");
console.log("Database connected");
// [routes goes here]
});
Check your command prompt and you will see a message that the database has been connected as well. Now we need to create a route that will be called when accessed from the browser. Write the following code in the [routes goes here] section:
app.get("/", function (request, result) {
result.render("home");
});
This will render the EJS file, so we need to create a file named “home.ejs” in your “views” folder and write the following code in it:
<%- include ("includes/header") %>
<%- include ("includes/footer") %>
Create a new folder includes inside views folder and create 2 files in it, header.ejs and footer.ejs. Following should be the content of the header.ejs file:
And following should be the content of the footer.ejs:
</body>
</html>
We will be creating multiple Vue JS apps, so right now we will create a Vue JS app for this navigation bar. Write the following lines in your footer.ejs:
<script>
var navApp = new Vue({
el: "#navApp",
data: {
baseUrl: mainURL,
login: false,
}
});
</script>
Access your project from the browser from this URL: http://localhost:3000/ and you will see the login and signup button at the top navigation bar. Because right now the user is not logged in. Click on the signup link and you will be redirected to the “404 not found” page.
Show Signup Form
Now we need to create that route in our server.js:
Then create a new file named signup.ejs inside the views folder. We will be using AJAX many times in this project, so we will place it in a separate file so we can re-use it later easily.
Create a file named app.js inside the public folder and write the following code in it:
var myApp = {
callAjax: function (url, formData, callBack = null) {
var ajax = new XMLHttpRequest();
ajax.open("POST", url, true);
ajax.onreadystatechange = function () {
if (this.readyState == 4) {
if (this.status == 200) {
if (callBack != null) {
callBack(this.responseText);
}
}
if (this.status == 500) {
console.log(this.responseText);
}
}
};
ajax.send(formData);
}
};
Then in your header.ejs you need to include that file as Javascript.
<script src="/app.js"></script>
We need to display an alert message when the user is signed up or when there is an error during sign-up. We will be using the Sweetalert library to display alerts. Include that in your header.ejs:
<script src="/sweetalert.min.js"></script>
Finally, we will write the following code in our signup.ejs:
<%- include ("includes/header") %>
<div class="container margin-container" id="registerApp">
<div class="row">
<div class="offset-md-3 col-md-6">
<h2 class="text-center">Register</h2>
<form method="POST" v-bind:action="baseUrl + '/signup'" v-on:submit.prevent="doRegister">
<div class="form-group">
<label>Name</label>
<input type="text" name="name" class="form-control" required />
</div>
<div class="form-group">
<label>Email</label>
<input type="email" name="email" class="form-control" required />
</div>
<div class="form-group">
<label>Password</label>
<input type="password" name="password" class="form-control" required />
</div>
<input type="submit" name="submit" value="Register" class="btn btn-primary" />
</form>
</div>
</div>
</div>
<script>
var registerApp = new Vue({
el: "#registerApp",
data: {
baseUrl: mainURL
},
methods: {
doRegister: async function () {
const form = event.target;
// disable the submit button and show "Loading..." text
form.submit.setAttribute("disabled", "disabled");
form.submit.value = "Loading...";
var formData = new FormData(form);
myApp.callAjax(form.getAttribute("action"), formData, function (response) {
// convert the JSON string into Javascript object
var response = JSON.parse(response);
// enable the submit button
form.submit.removeAttribute("disabled");
form.submit.value = "Register";
// if the user is created, then redirect to login
if (response.status == "success") {
swal("Registered", response.message, "success");
} else {
swal("Error", response.message, "error");
}
});
}
}
});
</script>
<%- include ("includes/footer") %>
Refresh the page and you will see a signup form. But nothing happens when you click the submit button, it is because we need to create an API for signup.
Saving the Data in Mongo DB
We will be sending AJAX requests with a form data object in this project. To parse that form data object on the server-side, we need to install a module named express-formidable.
And we need to encrypt plain text password fields into a hashed string before saving them in Mongo DB. So we need to install a module named bcrypt.
After the user successfully registered, we need to send a verification link to his email address to verify the account. He will only be able to log in if the account is verified. To send an email we will be using a module named nodemailer.
Note: Please enable the “less secure apps” option from your google account from this page.
Then open your command prompt and run the following commands at the root of your project folder to install the above-discussed modules:
npm install express-formidable bcrypt nodemailer
Then open your server.js file and include the above-installed module at the top:
Enter your correct email and password of your Google account of whom you have enabled “less secure apps”. Then create a post route for “signup” by chaining it with GET route we created earlier.
// route for signup requests
app.route("/signup")
// get request accessed from browser
.get(function (request, result) {
// render signup.ejs file inside "views" folder
result.render("signup");
})
// post request called from AJAX
.post(async function (request, result) {
// get values from signup form
var name = request.fields.name;
var email = request.fields.email;
var password = request.fields.password;
var verificationToken = new Date().getTime();
var createdAt = new Date().getTime();
// check if email already exists
var user = await db.collection("users").findOne({
"email": email
});
if (user != null) {
result.json({
"status": "error",
"message": "Email already exists."
});
return true;
}
// encrypt the password
bcrypt.hash(password, 10, async function (error, hash) {
// insert in database
await db.collection("users").insertOne({
"name": name,
"email": email,
"password": hash,
"picture": "",
"accessToken": "",
"notifications": [],
"bio": "",
"dob": "",
"country": "",
"phone": "",
"website": "",
"twitter": "",
"facebook": "",
"googlePlus": "",
"linkedIn": "",
"instagram": "",
"resetToken": "",
"isVerified": false,
"verificationToken": verificationToken,
"createdAt": createdAt
});
var transporter = nodemailer.createTransport(nodemailerObject);
var html = "Please verify your account by click the following link: <br><br> <a href='" + mainURL + "/verifyEmail/" + email + "/" + verificationToken + "'>Confirm Email</a> <br><br> Thank you.";
transporter.sendMail({
from: nodemailerFrom,
to: email,
subject: "Email Verification",
text: html,
html: html
}, function (error, info) {
if (error) {
console.error(error);
} else {
console.log("Email sent: " + info.response);
}
// send the response back to client
result.json({
"status": "success",
"message": "Signed up successfully. Kindly check your email to verify your account."
});
});
});
});
Refresh the browser and try to signup. Fill the signup form and hit submit. You will see a Sweetalert that an account has been created and you will also receive an email of account confirmation.
Email Verification
Email Verification
Now we need to create a route to verify the email address because without this, the user will not be able to log in. So we just need to create a GET route in our server.js:
app.get("/verifyEmail/:email/:verificationToken", async function (request, result) {
const email = request.params.email;
const verificationToken = request.params.verificationToken;
var user = await db.collection("users").findOne({
$and: [{
"email": email,
}, {
"verificationToken": parseInt(verificationToken)
}]
});
if (user == null) {
result.render("verify-email", {
"status": "error",
"message": "Email does not exists. Or verification link is expired."
});
return false;
}
await db.collection("users").findOneAndUpdate({
$and: [{
"email": email,
}, {
"verificationToken": parseInt(verificationToken)
}]
}, {
$set: {
"verificationToken": "",
"isVerified": true
}
});
result.render("verify-email", {
"status": "success",
"message": "Account has been verified. Please try login."
});
});
If the account is confirmed successfully or if there is an error in the confirmation like we will add the expiry time to the link. So the user has to resend a verification email if a certain time is passed. In either case, we need to create a new file verify-email.ejs inside your views folder to display a success or an error message.
Click on the link you receive in your provided email address, you will see a success message using a Bootstrap alert if the account is confirmed successfully.
In this article, we are going to show you how you can use a Laravel debugbar library in your production website. Debug Bar is used mainly for debugging environments but there can be situations where you might face an error in production. But debug bar displays all the queries and models of your Laravel application. So you do not want to show it to all of your live users. It should only be displayed to you, the owner of the website.
What we will do:
Install Laravel
Install Debug bar
Enable for a specific user only
Video tutorial:
Install Laravel Debugbar in production website
Download debug bar library (Github) by running the following command in your terminal:
This will take a few minutes but once installed, you can refresh your browser. The debug bar will not be displayed because the app is in production, so we have to manually display it. But we also want it to be displayed on all pages, throughout the application.
So we will go to the app > providers > AppServiceProvider.php and update it as per the following code:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Auth;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
if (Auth::check() && Auth::user()->email == "your_email@gmail.com")
{
\Debugbar::enable();
}
else
{
\Debugbar::disable();
}
}
}
Make sure to add the backslash before it, otherwise, it will generate an error because Laravel works in namespaces. Enter your email address in the if condition. Now you will start seeing a debug bar in your production but only when you are logged in with the above-provided email address.
Conclusion
So that was all, if you face any problems in following this, kindly do let me know in the comments section below.
In this tutorial, we are going to give you a fix to an error that prevents you from creating an iCloud account. Ever run into this error while creating an @icloud email?
“your account cannot be created at this time”
I recently faced this error and this is how I have solved it:
If you prefer a video tutorial, you can check our YouTube tutorial.
In this article, we are going to show you, how you can change title text of an HTML page using simple Javascript. We will show a real-time notification to your users in their title bar using PHP, MySQL, and Node JS. You can show a notification in a title bar with just PHP and MySQL. But the “real-time” effect can only be achieved with Node JS.
We can change title text using Javascript’s document.title object, but we will show you with a real-world example.
What we will do:
Save notification in the database
Display counter in the title bar
Show all unread notifications to the user
Mark notification as read
Make notifications real-time
1. Save notifications in the MySQL database
First, we need to save the notifications in the database. Notifications can be of any type, for example, “a new message is received” or “your account has been activated” etc. We will create a new file named “send-notification.php“.
<?php
// connect with database
$conn = new PDO("mysql:host=localhost;dbname=test", "root", "");
// create table if not exists
$sql = "CREATE TABLE IF NOT EXISTS notifications (
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
user_id INTEGER,
message TEXT,
is_read BOOLEAN,
created_at DATETIME
)";
// prepare the query
$statement = $conn->prepare($sql);
// execute the statement
$statement->execute();
// user who needs to receive the notification
$user_id = 565; // replace this your user ID
$message = "You have received a new message " . time() . ".";
$is_read = 0;
// insert in notifications table
$sql = "INSERT INTO notifications (user_id, message, is_read, created_at) VALUES (?, ?, ?, NOW())";
$statement = $conn->prepare($sql);
$statement->execute([
$user_id, $message, $is_read
]);
Comments have been added with each line for an explanation. Run the above code and check your database, you will see a new table named “notifications” and also a new row is inserted in that table. Now we need to display this on the user side.
2. Display the counter in the title bar
We just need to fetch the total number of unread notifications from the database and display them in the user’s title bar. Create a new file named “index.php” and it will have the following code:
<?php
// start session and login the user
session_start();
// you might be saving the session during login,
// I am hard-coding the value for testing purpose
$_SESSION["user_id"] = 565;
// connect with database
$conn = new PDO("mysql:host=localhost;dbname=test", "root", "");
// get number of unread notifications
$sql = "SELECT COUNT(*) AS total_unread_notifications FROM notifications WHERE user_id = ? AND is_read = 0";
$statement = $conn->prepare($sql);
$statement->execute([
$_SESSION["user_id"]
]);
$row = $statement->fetch();
$total_unread_notifications = $row["total_unread_notifications"];
Then we need to fetch this variable in Javascript and prepend it in the title bar. First, we need to create a title tag and a hidden input field where we will put the above variable value.
<!-- title where notification number will be displayed -->
<title>My Website</title>
<!-- save variables in hidden input field to access in Javascript -->
<input type="hidden" id="total-unread-notifications" value="<?php echo $total_unread_notifications; ?>" />
Then we need to get this input field value in Javascript and render it in the title tag. We will create a separate Javascript function to render the title bar because we will need it in multiple situations when:
The page is loaded
There is a new notification (increment)
A notification is read by the user (decrement)
<script>
// get variables in Javascript
var totalUnreadNotifications = document.getElementById("total-unread-notifications").value;
totalUnreadNotifications = parseInt(totalUnreadNotifications);
// show count in title bar
showTitleBarNotifications();
function showTitleBarNotifications() {
// pattern to check if there is any counter number at the start of title bar
var pattern = /^\(\d+\)/;
if (totalUnreadNotifications == 0) {
document.title = document.title.replace(pattern, "");
return;
}
if (pattern.test(document.title)) {
// update the counter
document.title = document.title.replace(pattern, "(" + totalUnreadNotifications + ")");
} else {
// prepend the counter
document.title = "(" + totalUnreadNotifications + ") " + document.title;
}
}
</script>
This will first check if the value of variable totalUnreadNotifications is greater than 0. If it is 0, then we will not show any number at all (not even 0). Then we will check if there is already any value in the title bar. If there is any value, then we will simply increment the counter value and re-render the title bar.
If there isn’t any value already in the title bar, then we will simply prepend the counter before the title tag content.
Here, the document.title is the only line that change title text.
This does change title text because initially, it was only “My Website”. After a notification is fetched from database, it prepends the value in the <title> tag.
At this point, you are seeing the number of unread notifications in your title bar. Now you need to find a way to mark notifications as “read” and decrement the counter.
3. Show all unread notifications to the user
To mark notifications as “read”, we first must show all the notifications to the user which when clicked will be marked as “read”. After that, the counter will be decremented and the title tag will be re-rendered. We will create a new file named “notifications.php” to display all notifications to the user.
<?php
// start session
session_start();
// connect with database
$conn = new PDO("mysql:host=localhost;dbname=test", "root", "");
// get all notifications sorting by unread goes first
$sql = "SELECT * FROM notifications WHERE user_id = ? ORDER BY is_read ASC";
$statement = $conn->prepare($sql);
$statement->execute([
$_SESSION["user_id"]
]);
$notifications = $statement->fetchAll();
This will fetch all the notifications of the logged-in user. Now we need to display them in an HTML table. We will simply by displaying a notification message and a button to mark that notification as read.
<!-- show all notifications in a table -->
<table>
<tr>
<th>Message</th>
<th>Action</th>
</tr>
<?php foreach ($notifications as $notification): ?>
<tr>
<td><?php echo $notification['message']; ?></td>
<td>
<!-- show 'read' button only if the notification is un-read -->
<?php if (!$notification['is_read']): ?>
<form onsubmit="return markAsRead();">
<input type="hidden" name="id" value="<?php echo $notification['id']; ?>" />
<input type="hidden" name="user_id" value="<?php echo $notification['user_id']; ?>" />
<input type="submit" value="Read" />
</form>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</table>
If you refresh the page now, you will see a list of all notifications with the button “read”. On clicking that button, we need to call an AJAX request to the server to mark this notification as “read” in the MySQL database. We will be using Vanilla JS to do that, no jQuery or any other external library is being used.
Now we need to create this Javascript function that will actually send the AJAX request. We will be using AJAX because there will be a lot of notifications and it will not be a good idea to keep refreshing the page for each notification to be marked as read.
<script>
// when the read button is clicked
function markAsRead() {
// prevent the form from submitting
event.preventDefault();
// get the form node
var form = event.target;
// create AJAX object
var ajax = new XMLHttpRequest();
// set method and URL of request
ajax.open("POST", "read-notification.php", true);
// when the status of request changes
ajax.onreadystatechange = function () {
// when the response is received from server
if (this.readyState == 4) {
// if the response is successful
if (this.status == 200) {
// convert the JSON string into Javascript object
var data = JSON.parse(this.responseText);
console.log(data);
// if there is no error
if (data.status == "success") {
// remove the 'read' button
form.remove();
// [emit read notification event here]
}
}
}
};
// create form data object with the form
var formData = new FormData(form);
// send the AJAX request with the form data
ajax.send(formData);
}
</script>
This will prevent the form from redirecting and calling our Javascript code. After the notification is successfully marked as read from the server, we will remove the “read” button. The last thing we need is a server-side PHP file that will handle this request.
4. Mark notification as read
Now we need to create a new file named “read-notification.php” that will mark this notification as “read”. In this file, we will also check the user_id along with the notification ID to make sure that the notification we are marking is “read” is actually sent to the logged-in user.
<?php
// start the session
session_start();
// connect with database
$conn = new PDO("mysql:host=localhost;dbname=test", "root", "");
// get ID from AJAX
$id = $_POST["id"];
// mark notification as read
$sql = "UPDATE notifications SET is_read = 1 WHERE id = ? AND user_id = ?";
$statement = $conn->prepare($sql);
$statement->execute([
$id,
$_SESSION["user_id"]
]);
// send the response back to client
echo json_encode([
"status" => "success"
]);
exit();
This file will first check that the notification ID sent from AJAX actually refers to the logged-in user. Because someone can try to tamper with the client-side code and mark any other user’s notification as “read”. So we must do server-side validation like above.
At this point, if you run the code now, you will be able to see all the notifications in an HTML table with a “Read” button. When clicked, will mark the notification as read and also will remove the “read” button.
If you refresh the “index.php” file, you will now see the counter in the title bar will be decremented. One more thing you can do is to make it real-time, so when there is any notification added, the counter will be incremented in the title bar. And also when the notification is read by the user, then the counter should be decremented automatically.
5. Make notifications real-time
Making these notifications in real-time is crucial. You might have used the WhatsApp Web where you will see that the counter in the title bar automatically gets incremented and decremented based on the number of new notifications you received and the notifications have you read.
Now we need to learn how you can implement this functionality in your project. We will be using the Socket IO JS library for this and we will also create a small Node JS server for this purpose. You can download Socket IO JS from their official site.
After downloading, you need to paste the JS file into your project. You also need to download and install Node JS in your system, you can download it from here.
Setting up Node JS server
After Node JS installation, open the command prompt or terminal in your project root directory and run the following command:
npm init
This will ask a couple of questions, you can press “enter” for all questions and it will automatically set the default answer. Then we need to install the required modules for this feature. Run the following command in your terminal:
npm install express http socket.io
This will install the Express, HTTP, and Socket IO module in your Node JS app. To start the server, we need to install another module globally named “nodemon“. So again, run the following command in your terminal:
npm install -g nodemon
Typically when you made changes in your code, you need to manually restart the Node JS server. But it slows down the process during development. So this module automatically restarts the server if there is any change in the server file.
Create a new file named “server.js“, this will be our Node JS server file. Paste the following code in that file, we will explain this in the next step:
// initialize express server
var express = require("express");
var app = express();
// create http server from express instance
var http = require("http").createServer(app);
// include socket IO
var socketIO = require("socket.io")(http, {
cors: {
origin: ["http://localhost"]
}
});
// start the HTTP server at port 3000
http.listen(process.env.PORT || 3000, function () {
console.log("Server started running...");
// an array to save all connected users IDs
var users = [];
// called when the io() is called from client
socketIO.on("connection", function (socket) {
// called manually from client to connect the user with server
socket.on("connected", function (id) {
users[id] = socket.id;
});
});
});
In this file we are:
Initializing the Express framework and also HTTP module.
Including the Socket IO module. You can place your own server URL in the CORS origin array.
Then we are starting the server at port 3000. We use process.env.PORT on deployment.
When a new user is connected with a server, a unique socket ID is generated. We are saving each user’s socket ID in a local array along with his ID from the database.
Now is the time to start the server. Run the following command in your terminal to start the server.
nodemon server.js
If you check the terminal, you will see a message “Server started running…” this means that you are ready to send connect your client-side with this server.
Increment counter on new notification
Whenever a new notification is sent to the server, we need to automatically increment the counter in the title bar. We have already created a function in “index.php” that displays the counter in the title bar.
To add this feature we need to perform the following tasks:
Connect socket IO JS on the “send-notification.php” file.
Then emit (send) the notification event to the Node JS server along with the ID of the user.
On the Node JS server-side, listen to that event and emit the event to the relative user.
Connect socket IO JS on the “index.php” file.
Listener for that new notification event.
When that event is received, increment the counter and re-render the title.
The following code goes in the “send-notification.php” file after the notification is inserted in the database:
<!-- save user id -->
<input type="hidden" id="user-id" value="<?php echo $user_id; ?>" />
<!-- include socket IO JS -->
<script src="socket.io.js"></script>
<script>
// connect with Node JS server
var socketIO = io("http://localhost:3000");
// get user ID
var userId = document.getElementById("user-id").value;
// send notification to the server
socketIO.emit("newNotification", userId);
</script>
We are already creating the $user_id variable in the first step. Then we are simply including the socket IO JS library and connect with the Node JS server. Getting the user ID from the hidden input field. And finally emitting an event to the server with a user ID.
In your “server.js” listen to this event and emit the event to the user with the same ID.
// when a new notification is received
socket.on("newNotification", function (userId) {
// send notification to the selected user
socketIO.to(users[userId]).emit("newNotification", userId);
});
The event has been dispatched from the server to the client. Now the client must listen to this event and when received should increment the counter and re-render the title. The following code goes in your “index.php“:
<!-- include socket IO JS -->
<script src="socket.io.js"></script>
<script>
// connect with Node JS server
var socketIO = io("http://localhost:3000");
// connect user with Node JS server
var userId = document.getElementById("user-id").value;
socketIO.emit("connected", userId);
// when a new notification is received
socketIO.on("newNotification", function (data) {
totalUnreadNotifications++;
showTitleBarNotifications();
});
</script>
Open “index.php” and “send-notification.php” in separate tabs and refresh both of these pages. Every time you refresh the send notification page, you will see the title of the index file gets incremented. Now we need to do the same for reading notifications, except that the title bar will be decremented whenever a notification is marked as read.
Decrement counter on reading notification
In “notifications.php” first, we need to include the socket IO JS library and connect with the server.
<!-- include socket IO JS -->
<script src="socket.io.js"></script>
<script>
// connect with Node JS server
var socketIO = io("http://localhost:3000");
</script>
Following code goes in the [emit read notification event here] section:
// send notification to the server
socketIO.emit("notificationRead", form.user_id.value);
Now we need to create a listener for this in our “server.js” file.
socket.on("notificationRead", function (userId) {
socketIO.to(users[userId]).emit("notificationRead", userId);
});
Similarly, you need to create a listener on the user side too in the index.php file.
socketIO.on("notificationRead", function (data) {
totalUnreadNotifications--;
showTitleBarNotifications();
});
This also change title text, but this time it decrements the counter value.
Run the code now and refresh both of your browsers. And try to read some notifications, as soon as you read them, you will see that the counter in the title bar will be decremented too.
So that’s how you can change title text of an HTML page using vanilla Javascript.
Conclusion
So that’s how you can implement a real-time notification system in your website with an unread notification counter in the title bar using simple PHP, Javascript, and Node JS. There is no PHP or Javascript framework used in this tutorial, so you can work with it with any framework in your existing project.
That’s how you can change the title text of the browser tab. If you face any problems in following this, kindly do let me know in the comments section below.
In this article, we are going to show you how you can implement a Google sign in on your website using Javascript and PHP. We will use Javascript to render the button. And we will use PHP to verify the token generated by the Google client because anyone can try to tamper with the client-side code.
Follow this tutorial to create an OAuth Client ID on the Google developer console.
2. Install Google OAuth Library
You can install the Google OAuth library by running the following command at the root of your project:
composer require google/apiclient
3. Render Google sign in button
Then we need to create a container where we will display the sign-in button at the appropriate place on your website.
<!-- include bootstrap -->
<link rel="stylesheet" type="text/css" href="css/bootstrap.css" />
<!-- google signin button -->
<div class="container" style="margin-top: 50px;">
<div class="row">
<div class="col-md-12">
<div id="myGoogleButton" onclick="googleSigninClick();"></div>
</div>
</div>
</div>
<!-- initialize google API -->
<script src="https://apis.google.com/js/platform.js?onload=googleInit" async defer></script>
Then we need to render the <div> tag with the sign in button. Make sure to replace the {your_google_client_id} code with your Google client ID generated from 1st step.
<script>
// variable to check that the button must be clicked manually
var googleSigninClicked = false;
// when the button is clicked by user
function googleSigninClick() {
googleSigninClicked = true;
}
// called when the google API is initialized
function googleInit() {
// load the auth API
gapi.load('auth2', () => {
// initialize the auth library
gapi.auth2.init({ client_id: "{your_google_client_id}" }).then(() => {
// render the google sign in button
gapi.signin2.render('myGoogleButton', {
'scope': 'profile email',
'width': 240,
'height': 40,
'longtitle': true,
'theme': 'dark',
onsuccess: (googleUser) => {
// this function is called when the page is loaded too,
// so we must login the user when the button is manually clicked
if (!googleSigninClicked) {
return false;
}
googleSigninClicked = false;
// get user profile
console.log(googleUser);
var profile = googleUser.getBasicProfile();
console.log({
"id": profile.getId(),
"name": profile.getName(),
"picture": profile.getImageUrl(),
"email": profile.getEmail()
});
// get token to be verified from server
var id_token = googleUser.getAuthResponse().id_token;
// send an AJAX request to the server to verify the token
var ajax = new XMLHttpRequest();
ajax.open("POST", "google-sign-in.php", true);
// when the status of request is changed
ajax.onreadystatechange = function () {
// when the response is received from server
if (this.readyState == 4) {
// if the server is successfull
if (this.status == 200) {
// the response will be a JSON string, convert that into javascript object
var data = JSON.parse(this.responseText);
console.log(data);
}
// if there is any internal server error
if (this.status == 500) {
console.log(this.responseText);
}
}
};
// create form data object
var formData = new FormData();
// append the token in the request
formData.append("id_token", id_token);
// send the request
ajax.send(formData);
},
onfailure: (error) => {
console.log(error);
}
});
});
});
}
</script>
Refresh the page now and you will be able to see a Google sign-in button. By default, you will see the message “Sign-in with Google”. Once you click the button and sign in with your Google account, you will see your profile information in the browser console.
4. Verify token
The token generated from the sign-in button must be verified from the server-side because anyone can tamper with the client-side code. To verify this token we are already sending an AJAX request. Now we need to create a new file named “google-sign-in.php” and paste the following code into it.
Make sure to replace the value of $google_oauth_client_id variable with your own client ID.
<?php
// include google API client
require_once "vendor/autoload.php";
// set google client ID
$google_oauth_client_id = "";
// create google client object with client ID
$client = new Google_Client([
'client_id' => $google_oauth_client_id
]);
// verify the token sent from AJAX
$id_token = $_POST["id_token"];
$payload = $client->verifyIdToken($id_token);
if ($payload && $payload['aud'] == $google_oauth_client_id)
{
// get user information from Google
$user_google_id = $payload['sub'];
$name = $payload["name"];
$email = $payload["email"];
$picture = $payload["picture"];
// send the response back to client side
echo json_encode([
"status" => "success"
]);
}
else
{
// token is not verified or expired
echo json_encode([
"status" => "error"
]);
}
Refresh the page now and try to log in again. Now we will also see a success response in your browser console, that is because of an AJAX request. On the server side, you can register the user if he is not already registered or you can start his session if he is already registered.
So that’s how you can implement a Google sign-in button in your website using plain Javascript and PHP. Try to implement this in your live site and let us know in the comments section if there is any problem.