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′]

Pass value between components – Vue JS

In this article, we will teach you how to pass value between 2 components in Vue JS. We will be using Vuex for this.

Video tutorial

Create a store

First, you need to create a store. To do this, install a module named vuex. Run the following command in your terminal:

npm install vuex

After that, you must create a folder named “vuex” in your “src” folder. Then, create a file named “store.js” inside “vuex” folder. Following will be the content of store.js file:

import { createStore } from "vuex"

export default createStore({
	state() {
		return {
			variable: 123
		}
	},

	// [mutations goes here]

	// [getters goes here]
})

“variable” will be the variable that you need to pass between components. You can set its default value here.

Pass value to component 1

Let’s say you want to display the value in component 1. So I am going to create a simple paragraph tag to display a value.

<p v-text="variable"></p>

And we need to make this variable a computed property. So we will write the following Javascript code in component 1.

import store from "../vuex/store"

export default {
	computed: {
		variable: function () {
			return store.getters.getVariable
		}
	}
}

First, we are including the store file that we created in the previous step. Our component is in “src/components” folder, and store file is in “src/vuex”, so we have to move a step back using “../”.

Then we are created a computed property “variable”, and it returns the “getVariable” value from the store getters object. The getters is the built-in property in Vuex store. And “getVariable” will be a function that we need to create in our store file.

So write the following code in the [getters goes here] section of store.js file:

getters: {
	getVariable: function (state) {
		return state.variable
	}
}

It accepts a state object as an argument. And with this object, you can call the variables in the state() function create in the first step. Run the component 1 now and you will see the value “123” in your paragraph.

Pass value from component 2

Now support in your component 2, you want to change its value and it should reflect in component 1 as well. First, write the following code in the [mutations goes here] section of store.js file:

mutations: {
	setVariable: function (state, newValue) {
		state.variable = newValue
	}
}

It accepts state and newValue as arguments. With the state object, you can change the values. And newValue is simply the new value that will be passed to it.

To call this function, we are going to create a simple button in our component 2.

<button type="button" v-on:click="updateVariable">Update variable</button>

Then we are going to create this method in our Javascript and call the setVariable function from our store file.

import store from "../vuex/store"

export default {
	methods: {
		updateVariable: function () {
			store.commit("setVariable", 567)
		}
	}
}

commit function from Vuex store will call the function created in mutations object. Second parameter will be the new value. Run the app now and click on the button. As soon as you press the button, you will notice that the variable value in 1st component will automatically get updated.

Source code

[wpdm_package id=’1733′]

Conclusion

So you have learned how to create a Vuex store in Vue JS, and how to pass value between components in Vue JS. If you face any problems in following this, kindly do let me know. We also created a chat application where we implemented this technique, so you will know how it is used practically in projects.

Upload multiple images in Node JS and Mongo DB

In this article, we are going to teach you, how you can upload multiple images in Node JS and Mongo DB.

Video tutorial:

Initializing the project

First, you need to create an empty folder and open a command prompt or terminal in it. Then run the following command in that CMD:

> npm init

It will ask multiple questions, just press enter to set the default values.

Then you need to install the express and HTTP modules. So run the following command:

> npm install express http

Then create a file named server.js and write the following code in it:

const express = require("express")
const app = express()
const http = require("http").createServer(app)

// [include Mongo DB]

// [set view engine]

// [Express formidable and FS module]

// [recursive function to upload images]

const port = process.env.PORT || 3000
http.listen(port, function () {
    console.log("Server started running at port: " + port)

    // [connect Mongo DB]
})

If you open your CMD, you will see the message “Server started running at port: 3000”.

You can check your project from the URL: http://localhost:3000/

Installing Mongo DB

To install the Mongo DB module, first, run the following command in your terminal:

> npm install mongodb

Then include the Mongo DB module in your server.js file in the [include Mongo DB] section:

const mongoClient = require("mongodb").MongoClient

Then connect with the database by writing the following code in the [connect Mongo DB] section:

mongoClient.connect("mongodb://localhost:27017", async function (error, client) {
    if (error) {
        console.error(error)
        return
    }

    const db = client.db("multiple_images_upload")
    console.log("Database connected")

    // [routes]
})

To learn more about Mongo DB, check our tutorials on Mongo DB here.

Display form to upload multiple images

To display an HTML file in Node JS, we need to install a module named EJS. You can install it by running the following command:

> npm install ejs

Then we need to tell our app to use the EJS as the templating engine. So write the following code in the [set view engine] section:

app.set("view engine", "ejs")

Then create a GET route in the [routes] section of server.js file:

app.get("/", async function (request, result) {
    result.render("home")
})

Then create a folder named views and inside this folder create a new file named home.ejs. In this file, we will create a form with an input type file.

<!-- home.ejs -->

<form onsubmit="uploadImages()" enctype="multipart/form-data">
    <input type="file" multiple accept="image/*" name="images" required />

    <input type="submit" value="Upload images" />
</form>

multiple: This will allow multiple file uploads.

accept=”image/*”: This allows only image files to be uploaded.

Then we will create this Javascript function to call an AJAX.

<script>
    function uploadImages() {
        // prevent the form from reloading the page
        event.preventDefault()

        // get form tag
        const form = event.target

        // create form data object from <form>
        const formData = new FormData(form)

        // create AJAX object
        const ajax = new XMLHttpRequest()

        // 1st parameter = method, GET/POST
        // 2nd parameter = path to server file
        // 3rd parameter = asynchronous
        ajax.open("POST", "/uploadImages", true)

        // when status of request changes
        ajax.onreadystatechange = function () {
            // operation is completed
            if (this.readyState == 4) {
                // response from server is okay
                if (this.status == 200) {
                    // response from server
                    console.log(this.responseText)
                }
            }
        }

        // send AJAX request
        ajax.send(formData)
    }
</script>

Comments have been added with each line for the explanation.

Upload multiple images in Node JS

To handle the form data object, we must first install the express-formidable and fs modules. FS stands for File System. To install these modules, run the following command:

> npm install express-formidable fs

Then you need to include these modules in your server.js file, in the [Express formidable and FS module] section:

const formidable = require("express-formidable")
app.use(formidable({
    multiples: true, // request.files to be arrays of files
}))

const fileSystem = require("fs")
app.use("/uploads", express.static(__dirname + "/uploads"))

Then create a folder named uploads at the root of your project.

After that, create the following POST route to handle that AJAX request:

app.post("/uploadImages", async function (request, result) {
    const images = []
    if (Array.isArray(request.files.images)) {
        for (let a = 0; a < request.files.images.length; a++) {
            images.push(request.files.images[a])
        }
    } else {
        images.push(request.files.images)
    }

    callbackFileUpload(images, 0, [], async function (savedPaths) {
        await db.collection("images").insertOne({
            images: savedPaths
        })

        result.send("Images has been uploaded.")
    })
})

To upload images, we will be using a recursive function. So create a recursive function in the [recursive function to upload images] section:

function callbackFileUpload(images, index, savedPaths = [], success = null) {
	const self = this

	if (images.length > index) {

		fileSystem.readFile(images[index].path, function (error, data) {
			if (error) {
				console.error(error)
				return
			}

			const filePath = "uploads/" + new Date().getTime() + "-" + images[index].name
			
			fileSystem.writeFile(filePath, data, async function (error) {
				if (error) {
					console.error(error)
					return
				}

				savedPaths.push(filePath)

				if (index == (images.length - 1)) {
					success(savedPaths)
				} else {
					index++
					callbackFileUpload(images, index, savedPaths, success)
				}
			})

			fileSystem.unlink(images[index].path, function (error) {
				if (error) {
					console.error(error)
					return
				}
			})
		})
	} else {
		success(savedPaths)
	}
}

Run the project now and you see a form with an input file and a submit button. Select multiple images from your computer and hit submit. Once submitted, you will see your uploaded images in the “uploads” folder and a new document will be created in the Mongo DB images collection.

Show uploaded images

Now we need to show all uploaded images. First, change your home route in server.js to the following:

app.get("/", async function (request, result) {
    const images = await db.collection("images").find({}).toArray()
    result.render("home", {
        images: images.length > 0 ? images[0].images : []
    })
})

This will pass all the images from the first document of images collection to the home file. Now go to your home.ejs and write the following for loop to display all images:

<%for (let a = 0; a < images.length; a++) { %>
    <img src="<%= images[a] %>" style="width: 100%;" />
<% } %>

Refresh the page now and you will be able to view all uploaded images.

If you face any problem in this, please do not hesitate to get in touch with me.

To run the following downloaded files, run the following command in your terminal first:

> npm update

[wpdm_package id=’1727′]

Promise and async await in Javascript

Promises are created in Javascript to prevent the callback hell. But it came with its own problems and complexities. To deal with them, we were introduced to async and await commands. So today, we are going to teach you, how you can create a promise in Javascript, and how to call it using async/await command.

Video tutorial

Basic example of promise with async await

Let’s start with a basic example. We are going to create a simple Javascript function that will return a promise. The promise will call the callback function with a string value.

function doSomething() {
	return new Promise(function (callBack) {
		callBack("Response")
	})
}

To use the async and await commands, we need to create another function that will use these commands.

async function callDoSomething() {
	const response = await doSomething()
	console.log(response)
}

The function name will be prepended with async and the function that returns a promise i.e. doSomething() will be prepended with await command. In this case, the response variable should print “Response” that was called at line 3 of previous code.

Finally, we simply need to call the callDoSomething() to run the code.

callDoSomething()

Run the code now, and you will see “Response” in your browser console. Try change the string value of callBack parameter and you will see that it will be reflected in response variable in callDoSomething() function.

Practical example

Let’s move to a more practical example. Let’s say you want to call an AJAX request from the promise. And instead of receiving the response in a callback, you want to receive it using async/await command.

So go ahead and change the doSomething() function to the following:

function doSomething() {
	return new Promise(function (callBack) {
		const ajax = new XMLHttpRequest()
		ajax.open("POST", "server.php", true)

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

		const formData = new FormData()
		ajax.send(formData)
	})
}

The code is self-explanatory but if you want to know more about the XMLHttpRequest, we have created a separate detailed tutorial on this.

Then we will create a simple PHP file that will return a simple string as response. Create a new file named server.php and write the following code in it:

<?php

sleep(1);

echo "Response from server";
exit();

We are calling the sleep() function just to give it 1 second delay. If you run the code now, you will start seeing “Response from server” in the browser console.

[wpdm_package id=’1720′]