Decode HTML entities in WordPress PHP

In this article, we are going to tell you, how you can decode HTML entities in your WordPress post using PHP. For example, if you write © in your blog post, it will be displayed as ©.

To do that, you need to create a simple WordPress plugin. Go to your “wp-content” folder, then to the “plugins” folder. Inside this folder, create a new folder named “decode-html-entities”. Inside this newly created folder, create a file named “index.php”. Inside this file, you only need to write the following code:

<?php

/**
 * Plugin Name: Decode HTML entities
 */

function decode_html_entities_from_content($content)
{
	return html_entity_decode($content);
}

function decode_html_entities()
{
	// to filter post by ID
	$post = get_post();
	if ($post->ID == 9)
	{
		add_filter("the_content", "decode_html_entities_from_content");
	}

	// to filter posts by category
	$categories = get_the_category();
	if (!empty($categories))
	{
		foreach ($categories as $category)
		{
			if (strtolower(esc_html($category->name)) == "php")
			{
				add_filter("the_content", "decode_html_entities_from_content");
			}
		}
	}
}

// this action hook executes just before WordPress determines which template page to load
add_action("template_redirect", "decode_html_entities");

After that, you need to go to your admin dashboard and activate the plugin. You will see the plugin named “Decode HTML entities” on your “plugins” page. If you want to know more about the “template_redirect” hook, you can learn it from its official documentation.

That’s how you can decode HTML entities from your WordPress posts in PHP. Check out our more free tutorials on WordPress.

[wpdm_package id=’1882′]

Mixed spaces and tabs issue fixed in Vue JS

If you ever encounter an error in Vue JS that says “mixed spaces and tabs”. You can fix it by simply running the following command:

npm remove @vue/cli-plugin-eslint

Removing the ESLint will fix this issue in your Vue JS app. Check out our more projects and tutorials on Vue JS here.

Video tutorial:

Ecommerce website in MEVN stack

It is a single-page ecommerce website developed in Vue JS. Vue JS is an open-source Javascript framework specifically built to design user interfaces and is widely used for creating single-page applications.

Node JS is a Javascript run-time environment developed for creating the backend of applications. Its framework Express is widely used for creating APIs. It is built to create scalable applications.

Mongo DB is a no-SQL database. It is a non-relational database system. It is easily scalable because the data is loosely coupled.

FeaturesFreePremium $100
Product management (admin panel)YesYes
Product listingYesYes
Product detailYesYes
Shopping cartYesYes
Checkout (PayPal & Stripe)YesYes
Order management (admin panel)YesYes
Order detailYesYes
Product specificationsYesYes
Stock managementYesYes
Search and sortYesYes
New order emailYesYes
Product reviewsNoYes
Shipping charges by countryNoYes
Product image compressionNoYes
Realtime chat between users and adminNoYes

Following is the feature list of this project:

  • Product management (admin panel)
  • Product listing
  • Product detail
  • Shopping cart
  • Checkout (PayPal & Stripe)
  • Order management (admin panel)
  • Order detail
  • Product specifications
  • Stock management
  • Product reviews
  • Search and sort
  • Shipping charges by country
  • Email to admin whenever a new order is placed
  • Product image compression
  • Realtime chat between users and admin

Add product

Admin will be able to add products. He will enter the name of the product. Add a little description of the product. And set the price of the product. The price will be in dollars. Along with them, the admin can upload one or more images of the product.

Product listing

Users will see the products added by the admin on their home page. The latest products are displayed first. Along with each product, a button will be displayed to view the detail of the product.

Product detail

Users can view the detail of the product. If the product contains more than one image, then it will be displayed as a beautiful slider. From this page, users will also be able to add products to the cart. If the product is already added to the cart, then he will be able to remove it from the cart.

Shopping cart

Users can add the product to the cart. From the cart’s page, he will be able to adjust the quantity of the product. There will be multiple products in the cart and you can set the quantity of each product separately. You will also see your total bill as soon as you change the quantity of any product added to the cart.

Checkout (Stripe & PayPal)

After adding the products to the cart and setting each product’s quantity, the user can go to the checkout page. Here, he can either pay via Stripe or PayPal. Both payment methods accept debit and master cards securely. When the user made the payment, his payment is verified from the server. If verified, then a new order will be created in the database.

Order management

Whenever a user made a payment via Stripe or PayPal, an order will be created. All orders will be displayed on the admin panel ordered by latest to oldest. By default, the status of the order is “Processing”. But admin can change the status of the order to “Completed” when the product is delivered to the customer.

Admin will also be able to view the total amount of the order, the payment method customer has used, and the user’s shipping details.

Order detail

Admin can view all the products that were included in each order. He can manually verify the payment by clicking the payment method. If he clicks “Stripe”, he will be redirected to the Stripe payments page. If he clicks “PayPal”, then he will be redirected to the PayPal business page. Admin can check the name, email, and phone of the user and also his shipping address.

Product specifications

Admin can add the specifications of each product and the user will be able to see it on the product detail page.

Stock management

Admin can set the number of units in stock for each product. When the user makes an order, then the number of units he has selected will be subtracted.

Product reviews

User can give reviews on a product and it will be displayed to all users who visit that product. Admin will have the ability to remove any review, for example, spamming, etc.

Search and sort

Users can search by product by its name, description, category, or specifications. Users can also sort the products by date or by price.

Shipping charges by country

Admin can set the shipping charges by each country because, in a global eCommerce website, users place orders from all over the world. For example, if your store is located in USA and someone places an order from the UK. Then you charge the shipping fee differently than other countries.

Email to admin whenever a new order is placed

Admin will receive an email whenever a new order has been placed by the user.

Product image compression

Now you can compress the product images from the admin panel. The 3 MB image can be reduced to just 182 KB and the image will still be of great quality.

Realtime chat between users and admin

Users will be able to have a chat with the admin to know more about a product before placing an order. I believe every eCommerce website should have this feature.

We are constantly updating this project and adding more features and enhancements to it. Following are all the builds that are released till today.

  • In the very first release, we build the basic E-commerce version where the admin can add products and users can see them. Add them to carts and order them. We also added Stripe and PayPal payment methods.
  • In the second release, we added more features. Allowing users to give reviews about a product. Allowing admin to charge a different shipping fee for each country and many more.
  • In the third release, we added functionality to compress product images and to have real-time chat between users and admin.

Free version

https://github.com/adnanafzal565/ecommerce-mevn-stack

Share local storage between websites – Javascript

In this article, we are going to teach you, how you can share local storage between websites using Javascript. Local storage is not accessible even within subdomains. So if I set the value in one subdomain, it will not be accessible in another subdomain.

Video tutorial:

To share the local storage value between websites, first, we need to create an iframe tag in the source website.

<iframe src="http://destination-website.com/saveLocalStorage.php" style="display: none;"></iframe>

The value of src attribute will be the path of the destination website. And we will hide the iframe using the CSS property display: none; so it will not be visible on the source website.

Then we will create a script tag and call a function that will be called when the page is loaded. You can also call it on any function you want, for example, when the user is logged in, you want to share the user’s authentication token to another website. In that case, you can write the below code inside your login function, but for the sake of simplicity, we are calling it inside the page load function.

<script>
    window.addEventListener("load", function () {
        // [code goes here]
    })
</script>

The following code will go inside the section. First, we will get the iframe DOM object.

const iframe = document.querySelector("iframe")

Then we will get the iframe content window.

const wind = iframe.contentWindow

Then we will set the data that needs to be sent.

const data = {
    name: "adnan-tech.com"
}

After that, we will call the postMessage function from the iframe content window object i.e. wind. The second parameter of the postMessage will be * in double quotes which means there is no preference for target origin.

wind.postMessage(JSON.stringify(data), "*")

You can learn more about it here.

Now we will come to the destination website, the file name will be saveLocalStorage.php. Create a script tag and attach a listener that will be called when the message is received. The second parameter will be a function and it will have an argument event (e).

<script>
    window.addEventListener("message", function (e) {
        // [destination code goes here]
    })
</script>

The following code goes in the [destination code goes here] section. First, we will check if the origin of the message is our source website because otherwise, any other website can also send post messages as well. If the origin of the message is not from our source website, then we will do nothing and stop the function.

if (e.origin !== "http://source-website.com") {
    return
}

// [parse data object]

If the message is from our source website, then we will first parse the data from a JSON string to a javascript object. Write the code in the [parse data object] section.

const data = JSON.parse(e.data)

Then we will check if the message has a name field.

if (typeof data.name !== "undefined") {
    // [save in local storage]
}

If it has, then we will set it in the destination website's local storage. Also, we will log the message that will be displayed in the source website's console tab. The following code goes in the [save in local storage] section:

localStorage.setItem("name", data.name)
console.log("Name is set: " + data.name)

Save the destination website file and refresh the source website. The name will be set, and you will see that message in your source's browser console. If you open your destination website's browser console and type localStorage.getItem("name"), you will see the name that you can send from the source website. Then you can use that value in the destination website in any way you like.

Complete code: Share local storage between websites in Javascript

<!-- source.php -->

<iframe src="http://destination-website.com/saveLocalStorage.php" style="display: none;"></iframe>

<script>
    window.addEventListener("load", function () {
        const iframe = document.querySelector("iframe")
        const wind = iframe.contentWindow
        
        const data = {
            name: "adnan-tech.com"
        }
        
        wind.postMessage(JSON.stringify(data), "*")
    })
</script>
<!-- http://destination-website.com/saveLocalStorage.php -->

<script>
    window.addEventListener("message", function (e) {
        if (e.origin !== "http://source-website.com") {
            return
        }
        
        const data = JSON.parse(e.data)
        
        if (typeof data.name !== "undefined") {
            localStorage.setItem("name", data.name)
            console.log("Name is set: " + data.name)
        }
    })
</script>

So that's how you can share local storage value from one website to another using Javascript. If you face any problems in following this, kindly do let me know. Check out our more tutorials on Javascript.

[wpdm_package id='1801']

Dynamic constra template – Vue JS & Laravel

“Constra” is an HTML static template in HTML & CSS. It is an HTML template designed for the construction website. The businesses that allow construction-related services. We have converted to a dynamic website using Vue JS and Laravel.

You can check out the following tutorials. In these tutorials, we have shown you, how to convert a static HTML template into a dynamic construction website.

Part 1:

You will learn in this part:

  • How to convert an HTML template into a Vue JS app
  • Create single-page applications in Vue JS
  • Use the vue-router module
  • Use internal CSS, JS, and image files from the “assets” folder
  • How to fix the “Mixed spaces and tabs” error
  • Remove ESLint from the Vue JS app
  • Use Bootstrap, jQuery, and other JS libraries in the Vue JS app
  • How to fix “Can’t resolve popper.js”
  • Use the “background-image” property in Vue JS
  • Use slider library (Shuffle) in Vue JS

Part 2:

In this part, you will learn:

  • How to pass parameters in URL in Vue JS
  • How to fetch a single record in Laravel eloquent
  • How to call AJAX using Axios in Vue JS
  • Using “slick” JS library in Vue JS
  • Create a foreign key in Laravel migration
  • Create a has-many relationship in Laravel
  • Upload file in Laravel storage

You can download the complete source code from Github as well.

You can also check out our chat website developed in Vue JS, Node JS, and Mongo DB.

Deploy Node JS app on VPS or Dedicated server

In this article, we are going to teach you how you can deploy the Node JS app on a VPS (Virtual Private Server) or a dedicated server. Make sure you have Node JS, NPM (Node Package Manager), and PM2 (Process Manager) installed, you can run the following commands to see if they are installed.

node -v
npm -v
pm2

If any of them is not installed on your server, you can simply chat with your hosting provider’s customer support center or open a ticket and ask them to install these for you. The main thing you are going to need for deployment is pm2.

Install Node JS

To install specific version of Node JS, first you need to install NVM (Node Version Manager).

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash

Then you need to reload your shell configurations.

source ~/.bashrc

You can verify your installation of NVM by running the following command.

nvm -v

It will show you your NVM version (0.39.5 at the time of writing this). Then run the following command to list all available Node JS versions.

nvm ls-remote

You can install the specific version of Node JS by running:

nvm install 22.11.0

Here, 22.11.0 is the latest LTS version at the time of writing this post. You can set it accordingly. In order to make your NVM to use the installed version by default, you can run the following 2 commands.

nvm default 22.11.0
nvm alias default 22.11.0

If everything goes well, you can run the following command to verify that the Node JS has been successfully installed in your VPS or dedicated server.

node -v

Install PM2 (Process Manager)

If pm2 is not installed in your server, you can install is by running the following command:

npm install -g pm2

Creating a Node JS server

First, create a sub-domain for example “node.adnan-tech.com”. It will also create a directory for this sub-domain. Then create a simple Node JS app in it by running the following command in your cPanel terminal:

npm init

Press Enter key for all questions to set the default values. Then install the following modules:

npm install express http cors express-formidable socket.io

Inside the directory created for the sub-domain, create a file named “server.js” and write the following code in it:

server.js

const express = require("express")
const app = express()

const cors = require("cors")
app.use(cors())

const expressFormidable = require("express-formidable")
app.use(expressFormidable())

const http = require("http").createServer(app)
const socketIO = require("socket.io")(http, {
	cors: {
		origin: "*"
	}
})

const port = process.env.PORT || 3000

http.listen(port, function () {
	console.log("Server started at port: " + port)

	socketIO.on("connection", function (socket) {
		console.log("User connected: " + socket.id)

		// [listen events here]
	})
	
	app.get("/", function (request, result) {
	    result.send("Hello world !")
	})
	
	// [create API here]
})

Then you need to tell your Node JS app that you will be using server.js as the main file. So open your package.json file and set the main key’s value to “server.js” as follows:

package.json

"main": "server.js",

Deploy the Node JS app

Now to start the server, first, open your “Terminal” from cPanel, and go to your subdomain by running the command:

cd yoursubdomain.com

Or whatever your subdomain path is. Then run the following command to start the server:

pm2 start server.js --name "Name of your app" --watch

–name is used to set a specific name for your app.

–watch is used to automatically restart the server if there is any change in the server.js file.

List all processes using pm2

You can view the list of all processed from the command:

pm2 list

If the write the URL https://yoursubdomain:3000/ in the browser, you will see the text “Hello world”. It means your Node JS server is successfully deployed on your VPS or dedicated server.

Create an API in Node JS

Now write the following code to create an API in the [create API here] section:

app.post("/myAPI", function (request, result) {
    const name = request.fields.name
    
    result.json({
        status: "success",
        message: "API has been called.",
        data: "Your name is " + name
    })
})

Then create an index.html file anywhere in your domain and write the following code to it to call an AJAX to this Node JS server.

index.html

<script>
	const ajax = new XMLHttpRequest()
	ajax.open("POST", "https://yoursubdomain:3000/myAPI", true)

	ajax.onreadystatechange = function () {
		if (this.readyState == 4) {
			if (this.status == 200) {
				console.log(this.responseText)
			}
		}
	}

	const formData = new FormData()
	formData.append("name", "Adnan")
	ajax.send(formData)
</script>

Open your browser console tab and you will see the message “Adnan”. Try changing the value in the “name” field in the formData object and refresh the page, you will now see your updated value.

Socket IO

You can also connect sockets to this Node JS server. In your index.html file, first, include the socket IO JS library using CDN:

<script src="https://cdn.socket.io/4.5.0/socket.io.min.js"></script>

Then write the following Javascript code to connect the client with the server:

<script>
	const socketIO = io("https://yoursubdomain:3000")
</script>

After that, emit a simple event to the server:

// index.html

socketIO.emit("newEvent", { name: "Adnan" })

Then in your server.js, write the following code in place of the [listen events here] section:

// server.js

socket.on("newEvent", function (data) {
	socket.emit("newEvent", data)
})

And finally, on your client side, you need to listen to this event and display a message in the browser console:

// index.html

socketIO.on("newEvent", function (data) {
	console.log(data)
})

Refresh your page now and open your browser console. You will now see an object in the console. It means that your Node JS server’s sockets are running fine.

Stop the pm2 process

By default, the pm2 process will keep on running forever. If you want to stop the process, you can simply enter the following command in your cPanel terminal:

pm2 stop "Name of your app"

Run pm2 list and you will now see the status of your process as stopped.

Remove the pm2 process

Similarly, you can remove the pm2 process by running the following command:

pm2 delete "Name of your app"

Run pm2 list and you will no longer see your process in the list.

So that’s how you can deploy a Node JS app on your VPS or dedicated server. Check our tutorial to deploy Node JS app on the Heroku server. If you face any problems in following this, kindly do let me know.

Show WordPress posts in PHP website

In this tutorial, we will teach you how to show WordPress posts in your PHP website. Make sure you run this code from inside your server where the WordPress blog is hosted. This means that if your WordPress blog is hosted on the main domain like “adnan-tech.com”, then this code should be on any of the sub-domain like “web.adnan-tech.com”.

And vice versa, if your WordPress blog is hosted on a sub-domain like “blog.adnan-tech.com”, then this code should be on the main domain like “adnan-tech.com”. This script will not work on localhost because many of the WordPress blogs have some security plugins installed, that prevent any external host to fetch data from it.

Show WordPress posts in PHP

To show all the blog posts from your WordPress website, we will be using WordPress posts API. Just write the following code in the file where you want to show the blog listing. Make sure to change your blog URL in $blog_api_url variable:

<?php
    $blog_api_url = "https://yourblogdomain/wp-json/wp/v2";

    $curl = curl_init();
    curl_setopt_array($curl, [
        CURLOPT_URL => $blog_api_url . "/posts",
        CURLOPT_RETURNTRANSFER => 1
    ]);
    $response = curl_exec($curl);
    curl_close($curl);
    
    $posts = json_decode($response);
    foreach ($posts as $post)
    {
        $id = $post->id;
        $date = date("d M, Y", strtotime($post->date));
        $slug = $post->slug;
        $status = $post->status; // "publish"
        if ($status != "publish")
        {
            continue;
        }
        $link = $post->link;
        $title = $post->title->rendered;
        $excerpt = $post->excerpt->rendered;
    
        $curlMedia = curl_init();
        curl_setopt_array($curlMedia, [
            CURLOPT_URL => $blog_api_url . "/media/" . $post->featured_media,
            CURLOPT_RETURNTRANSFER => 1
        ]);
        $responseMedia = curl_exec($curlMedia);
    
        $responseMedia = json_decode($responseMedia);
        $mediaTitle = $responseMedia->title->rendered;
        $altText = $responseMedia->alt_text;
        $mediaSourceUrl = $responseMedia->source_url;

        ?>

        <div style="border: 1px solid black; margin: 10px; padding: 10px;">
            <?php if (!empty($mediaSourceUrl)) { ?>
                <img src="<?php echo $mediaSourceUrl; ?>" alt="<?php echo $altText; ?>" title="<?php echo $mediaTitle; ?>" style="width: 100%;" />
            <?php } ?>
            
            <div>
                <p><?php echo $date; ?></p>
                <h2>
                    <a href="./show-post.php?slug=<?php echo $slug; ?>">
                        <?php echo $title; ?>
                    </a>
                </h2>
                <p><?php echo $excerpt; ?></p>
            </div>
        </div>

    <?php
    }
?>

This will fetch the latest posts from your WordPress blog. We are looping through all the posts and saving the necessary variables from the $post object. You can write print_r($post) inside the foreach loop to view an entire $post object. We are only displaying the published posts here. If you want to show the unpublished posts as well, simply comment out the continue; statement. Inside the foreach loop, we are calling another CURL request to get the featured image of the post.

Blog listing

Then, we are creating a <div> inside the foreach loop with a 1-pixel black border and a 10 pixels margin from all sides. We are also giving it a 10 pixels padding so it will margin from inside too. Inside this div, we display the post’s published date, title, and excerpt. An excerpt is a short text from the blog post, you can set it up from the WordPress admin panel for each post separately. If not specified, then it will be the first paragraph of the post.

We are making the title a hyperlink, so when clicked, it will redirect the user to a new page where we can show that post in detail. We are using “./” in the hyperlink because our post detail page is in the same directory. You can also redirect the user to the original post on the WordPress blog using the variable $link. We didn’t put the hyperlink on the image, because if the post does not have a featured image, then the link will not be created. And the user will have no option to redirect to the post detail page.

Single post

To show the post detail inside your website, simply create a file named show-post.php and write the following code in it:

<?php
    $slug = $_GET["slug"];
    $blog_api_url = "https://yourblogdomain/wp-json/wp/v2";

    $curl = curl_init();
    curl_setopt_array($curl, [
        CURLOPT_URL => $blog_api_url . "/posts?slug=" . $slug,
        CURLOPT_RETURNTRANSFER => 1
    ]);
    $response = curl_exec($curl);
    curl_close($curl);

    $posts = json_decode($response);
    if (count($posts) == 0)
    {
        die("Post not found.");
    }
    
    $date = date("d M, Y H:i:s", strtotime($posts[0]->date));
    $status = $posts[0]->status; // "publish"
    if ($status != "publish")
    {
        die("Post not published.");
    }
    $title = $posts[0]->title->rendered;
    $content = $posts[0]->content->rendered;

    $curlMedia = curl_init();
    curl_setopt_array($curlMedia, [
        CURLOPT_URL => $blog_api_url . "/media/" . $posts[0]->featured_media,
        CURLOPT_RETURNTRANSFER => 1
    ]);
    $responseMedia = curl_exec($curlMedia);

    $responseMedia = json_decode($responseMedia);
    $mediaTitle = $responseMedia->title->rendered;
    $altText = $responseMedia->alt_text;
    $mediaSourceUrl = $responseMedia->source_url;
?>

<!-- Post title -->
<h1><?php echo $title; ?></h1>

<!-- Post meta content -->
<p>Posted on <?php echo $date; ?></p>

<!-- Preview featured image -->
<?php if (!empty($mediaSourceUrl)) { ?>
    <img src="<?php echo $mediaSourceUrl; ?>" alt="<?php echo $altText; ?>" title="<?php echo $mediaTitle; ?>" style="width: 100%;" />
<?php } ?>

<!-- Post content-->
<section>
    <?php echo $content; ?>
</section>

This will show the post title in the heading. Date the post was published. Featured image if available, the featured image will also have an alt text that will be displayed in case the image is not found. It will also have a title attribute that will be visible when the user moves the mouse over the image (hover effect). Finally, we are displaying the complete content of the post.

Show comments of the post

To show the comments of the post, first, we need to fetch all the comments of the post. We are again going to use the CURL request on WordPress comments API. Write the following code below post content:

<?php
    $curlComments = curl_init();
    curl_setopt_array($curlComments, [
        CURLOPT_URL => $blog_api_url . "/comments/?post=" . $posts[0]->id,
        CURLOPT_RETURNTRANSFER => 1
    ]);
    $responseComments = curl_exec($curlComments);
    $responseComments = json_decode($responseComments);

    foreach ($responseComments as $comment) {
        if ($comment->status != "approved") {
            continue;
        }
?>
    <div style="border: 1px solid black; margin: 10px; padding: 10px;">
        <?php foreach (((array) $comment->author_avatar_urls) as $avatar_url) { ?>
            <img src="<?php echo $avatar_url; ?>" style="width: 100px;" />
        <?php break; } ?>

        <p><?php echo $comment->author_name; ?></p>
        <p><?php echo $comment->content->rendered; ?></p>
    </div>
<?php } ?>

This will first fetch all the comments of that post. Then it will loop through each comment and will skip the loop iteration if the comment is not approved yet. Then, it will create a <div> tag with styles the same as we did for the blog listing. The author_avatar_urls object in each $comment is an object. So we need to convert that to an array using (array) typecasting. Then we will loop through it, and display the profile image of the user who posted that comment. After that, we are using a break statement so it will not show multiple images, it will stop the loop after displaying one image. User profile images are in different dimensions, but we need to show only one. And finally, we display the name of the person who posted the comment and the comment itself.

Check out our more tutorials on WordPress.

Source code – Show WordPress posts in PHP

[wpdm_package id=’1747′]

Or you can also download it from Github.

Adult image validation – PHP

In this article, we will teach you how to have adult image validation in your PHP website. Suppose you are creating a website where you allow people to upload images. And some people start uploading nudity images. Now you want to stop them.

Video tutorial:

For the sake of simplicity, we are creating a simple HTML form that allows users to upload images.

<form method="POST" action="upload.php" enctype="multipart/form-data">
	<input type="file" name="image" accept="image/*" />
	<input type="submit" />
</form>

This shows an input file and a submit button. Then we need to download a class named “class.ImageFilter.php”. You can download it from here. I am also writing the class here:

<?php

// class.ImageFilter.php

class ImageFilter
{                              #R  G  B
    var $colorA = 7944996;     #79 3B 24
    var $colorB = 16696767;    #FE C5 BF


    var $arA = array();
    var $arB = array();
    
    public function __construct()
    {
        $this->arA['R'] = ($this->colorA >> 16) & 0xFF;
        $this->arA['G'] = ($this->colorA >> 8) & 0xFF;
        $this->arA['B'] = $this->colorA & 0xFF;
        
        $this->arB['R'] = ($this->colorB >> 16) & 0xFF;
        $this->arB['G'] = ($this->colorB >> 8) & 0xFF;
        $this->arB['B'] = $this->colorB & 0xFF;
    }
    
    function GetScore($image)
    {
        $x = 0; $y = 0;
        $img = $this->_GetImageResource($image, $x, $y);
        if(!$img) return false;

        $score = 0;
        
        $xPoints = array($x/8, $x/4, ($x/8 + $x/4), $x-($x/8 + $x/4), $x-($x/4), $x-($x/8));
        $yPoints = array($y/8, $y/4, ($y/8 + $y/4), $y-($y/8 + $y/4), $y-($y/8), $y-($y/8));
        $zPoints = array($xPoints[2], $yPoints[1], $xPoints[3], $y);

        
        for($i=0; $i<=$x; $i++)
        {
            for($j=0; $j<=$y; $j++)
            {
                $color = imagecolorat($img, $i, $j);
                if($color >= $this->colorA && $color <= $this->colorB)
                {
                    $color = array('R'=> ($color >> 16) & 0xFF, 'G'=> ($color >> 8) & 0xFF, 'B'=> $color & 0xFF);
                    if($color['G'] >= $this->arA['G'] && $color['G'] <= $this->arB['G'] && $color['B'] >= $this->arA['B'] && $color['B'] <= $this->arB['B'])
                    {
                        if($i >= $zPoints[0] && $j >= $zPoints[1] && $i <= $zPoints[2] && $j <= $zPoints[3])
                        {
                            $score += 3;
                        }
                        elseif($i <= $xPoints[0] || $i >=$xPoints[5] || $j <= $yPoints[0] || $j >= $yPoints[5])
                        {
                            $score += 0.10;
                        }
                        elseif($i <= $xPoints[0] || $i >=$xPoints[4] || $j <= $yPoints[0] || $j >= $yPoints[4])
                        {
                            $score += 0.40;
                        }
                        else
                        {
                            $score += 1.50;
                        }
                    }
                }
            }
        }
        
        imagedestroy($img);
        
        $score = sprintf('%01.2f', ($score * 100) / ($x * $y));
        if($score > 100) $score = 100;
        return $score;
    }
    
    function GetScoreAndFill($image, $outputImage)
    {
        $x = 0; $y = 0;
        $img = $this->_GetImageResource($image, $x, $y);
        if(!$img) return false;

        $score = 0;

        $xPoints = array($x/8, $x/4, ($x/8 + $x/4), $x-($x/8 + $x/4), $x-($x/4), $x-($x/8));
        $yPoints = array($y/8, $y/4, ($y/8 + $y/4), $y-($y/8 + $y/4), $y-($y/8), $y-($y/8));
        $zPoints = array($xPoints[2], $yPoints[1], $xPoints[3], $y);


        for($i=1; $i<=$x; $i++)
        {
            for($j=1; $j<=$y; $j++)
            {
                $color = imagecolorat($img, $i, $j);
                if($color >= $this->colorA && $color <= $this->colorB)
                {
                    $color = array('R'=> ($color >> 16) & 0xFF, 'G'=> ($color >> 8) & 0xFF, 'B'=> $color & 0xFF);
                    if($color['G'] >= $this->arA['G'] && $color['G'] <= $this->arB['G'] && $color['B'] >= $this->arA['B'] && $color['B'] <= $this->arB['B'])
                    {
                        if($i >= $zPoints[0] && $j >= $zPoints[1] && $i <= $zPoints[2] && $j <= $zPoints[3])
                        {
                            $score += 3;
                            imagefill($img, $i, $j, 16711680);
                        }
                        elseif($i <= $xPoints[0] || $i >=$xPoints[5] || $j <= $yPoints[0] || $j >= $yPoints[5])
                        {
                            $score += 0.10;
                            imagefill($img, $i, $j, 14540253);
                        }
                        elseif($i <= $xPoints[0] || $i >=$xPoints[4] || $j <= $yPoints[0] || $j >= $yPoints[4])
                        {
                            $score += 0.40;
                            imagefill($img, $i, $j, 16514887);
                        }
                        else
                        {
                            $score += 1.50;
                            imagefill($img, $i, $j, 512);
                        }
                    }
                }
            }
        }
        imagejpeg($img, $outputImage);

        imagedestroy($img);

        $score = sprintf('%01.2f', ($score * 100) / ($x * $y));
        if($score > 100) $score = 100;
        return $score;
    }
    
    function _GetImageResource($image, &$x, &$y)
    {
        $info = GetImageSize($image);
        
        $x = $info[0];
        $y = $info[1];
        
        switch( $info[2] )
        {
            case IMAGETYPE_GIF:
                return @ImageCreateFromGif($image);
                
            case IMAGETYPE_JPEG:
                return @ImageCreateFromJpeg($image);
                
            case IMAGETYPE_PNG:
                return @ImageCreateFromPng($image);
                
            default:
                return false;
        }
    }
}

Now to handle the input file uploaded from the form, we need to create a file named “upload.php”. Following will be the code of this file.

<?php

require_once "class.ImageFilter.php";

if (isset($_FILES["image"])
	&& $_FILES["image"]["size"] > 0)
{
	$type = strtolower($_FILES["image"]["type"]);

	if (in_array($type, ["image/jpeg", "image/jpg", "image/png"]))
	{
		$temp_path = "image.png";
		move_uploaded_file($_FILES["image"]["tmp_name"], $temp_path);

		$filter = new ImageFilter();
		$score = $filter->GetScore($temp_path);

		echo $score;

		if ($score > 60)
		{
			echo "<p>Image contains adult content.</p>";
			exit;
		}
		else
		{
			$file_path = basename($_FILES["image"]["name"]);
			copy($temp_path, $file_path);
		}

		unlink($temp_path);
	}
}
  1. First, we are including the class in our PHP file.
  2. Then we save the image file as “image.png”, you can set any name of your choice.
  3. Then we are creating an instance of ImageFilter class.
  4. Then we are getting the score of the newly created image file. A score of 61 and above is considered to contain nudity content.
  5. Then we are removing the image file we saved.
  6. And display the score to the user, you can remove this line if you do not want to show the scores to the user.
  7. Finally, we are putting a condition that says “if the score is greater than 60, then display an error message.”

So that’s how you can add an adult image validation feature to your PHP website. If you want to see this feature in action, we implemented this feature in our social network project. If you face any difficulty in implementing this in your project, feel free to contact us.

Source code – Adult image validation

[wpdm_package id=’1740′]

How to create nested modules – Node JS

In this article, we are going to teach you, how you can have nested modules in your Node JS project. Nested modules help in splitting a large code-base into smaller files. This helps in debugging and scaling easily.

Video tutorial

Let’s say that you want to access the following URL:

http://localhost:3000/users/social

You want to have a “users” module where all user code will go. And you want the user’s module to be further divided into “social” module where all the code for user’s social networks will go, for example.

If you do not know how to create and set up a Node JS application, please check our this tutorial first.

So we will start by creating a user module. Create a new folder named “modules” at the root of your project. Then in this folder, create a file named “users.js”. The following code will go in the users.js file.

const express = require("express")

// [include social.js module]

module.exports = {
	init: function (app) {
		const userRouter = express.Router()

		userRouter.get("/", function (request, result) {
			result.send("Inside users.js")
		})

		app.use("/users", userRouter)

		// [call init method of social.js here]
	}
}

It creates a router object, named userRouter, from the express object. Then it tells the app to use this userRouter object for every route starting from “/users” in the URL. The init function accepts an app object which we will send from our main “server.js” file.

So go to your main “server.js” file and include the users module in it by writing the following line at the top.

const users = require("./modules/users")

const express = require("express")
const app = express()

Then, we need to call the init function of it and pass the app instance to it.

users.init(app)

If you access the following URL now, you will see a message “Inside users.js” in the browser:

http://localhost:3000/users

Now we need to create another file named “social.js” inside modules folder. The following will be the code for social.js file:

const express = require("express")

module.exports = {
	init: function (userRouter) {
		const socialRouter = express.Router()

		socialRouter.get("/", function (request, result) {
			result.send("Inside social.js")
		})

		userRouter.use("/social", socialRouter)
	}
}

This module’s init method accepts userRouter as an argument that we had created in our “users.js” file. And it is using that userRouter object instead of app object because this module will be used only when the “/social” path is appended after the “/users” path.

The final thing you need to do is to call the init method of the “social.js” file inside our “users.js” file. So go to your “users.js” file and first include the social module in it. Write the following line in the [include social.js module] section:

const social = require("./social")

Then write the following code in the [call init method of social.js here] section:

social.init(userRouter)

So if you access the following URL now, you will be able to see “Inside social.js” in your browser.

http://localhost:3000/users/social

We created an E-commerce application in Node JS and Mongo DB where we used nested modules to have admin > products and orders. You can check that project from here.

So that’s how you can have nested modules in Node JS express framework. If you face any problems in following this, kindly do let me know.

Source code – How to create nested modules in Node JS

[wpdm_package id=’1736′]