Wednesday, August 22, 2018

Grails on Groovy > Way in Grails to Eager Fetch the Whole Record | Load Related Entity With Single Query

I am trying to find if there is any way in Grails to eager fetch complete records instead of a left Join.
For example, let you have domain named Tabel1 with following structure and another domain named Table3 below:
package com.pkm

class Table1 {
    Long id
    String name
    String roll

    static mapping = {
        table("table1")
    }

    static belongsTo = [
            table3: Table3
    ]

    static constraints = {
        table3 nullable: true
    }
}



package com.pkm

class Table3 {
    Long id
    String name
}
So when you get/list Table1, what will be the default behavior? It will load only Table1 data, not other associated data like Table3.
There is a procedure to load selected associated by joining them. See the below example, enabled eager face data when creating criteria:
package com.pkm

import grails.transaction.Transactional
import org.hibernate.FetchMode
import org.hibernate.sql.JoinType
import org.springframework.transaction.TransactionStatus

@Transactional
class HomeService {
    TransactionStatus transactionStatus

    void callMe() {
        List list = Table1.createCriteria().list {
            createCriteria("table3", "j3", JoinType.LEFT_OUTER_JOIN)
            setFetchMode("j3", FetchMode.JOIN)
            order("id", "desc")
            setMaxResults(20)
        }
        list.each { Table1 table1 ->
            println("Name=${table1.name}, Table3=${table1.table3?.name}")
        }
    }
}
Now we will print the query generated:
select this_.id as id1_0_1_, this_.name as name2_0_1_, this_.roll as roll3_0_1_, this_.table3_id as table4_0_1_, j3x1_.id as id1_2_0_, j3x1_.name as name2_2_0_ from table1 this_ left outer join table3 j3x1_ on this_.table3_id=j3x1_.id order by this_.id desc limit ?
You observed that in select query, both Table1 and Table3 exists. And this is how we can implement eager face data when creating criteria builder to get data.

Saturday, August 11, 2018

Setting Up Recaptcha 2.0 with JavaScript and PHP

reCAPTCHA need to verify bots (automatic system) can't take advantage of your site. reCAPTCHA 2.0 is somewhat different than the old reCAPTCHA. In version 1.0 it required to type text but now in 2.0 it’s simply a click of a button as below image.

The term of verifying front end users is a bit different. A variable named "g-recaptcha-response" is sent through a POST request to your server-side script, and along with your reCAPTCHA secret key that you get when you sign up for your website, you need to pass that secret key along to Google to tell that the user is a bot or not to determine by system. The response from Google is a JSON response on success for failure both case, so that we will be using file_get_contents() and json_decode() to fetch and parse the response and decide that front user is valid or not.


The below is just a HTML form you should create to see captcha in your desired page. The div element with the class of "g-recaptcha" is the element where we want to place our Google captcha (reCAPTCHA). You need to replace data-sitekey with the key you get from google when you sign up for reCAPTCHA (https://www.google.com/recaptcha/intro/index.html).
<form method="post" enctype="multipart/form-data">
    <div class="g-recaptcha" data-sitekey="YOUR_KEY"></div>
    <button type="submit">CHECK RECAPTCHA</button>
</form>
But I will show another technique how to show reCAPTCHA using JavaScript. Below is a simple script to show how you can integrate reCAPTCHA using JavaScript. But server side validation using PHP. Use need to create an div with ID (suppose, you can create your div with other ID) captcha_container
<script src='https://www.google.com/recaptcha/api.js'></script>

var captchaContainer = grecaptcha.render('captcha_container', {
    'sitekey' : 'Your sitekey',
    'callback' : function(response) {
        console.log(response);
    }
});
Now time to validate reCAPTCHA from server side.
<?php
$url = 'https://www.google.com/recaptcha/api/siteverify';

$data = array(
    'secret' => 'YOUR_SECRET',
    'response' => $_POST["g-recaptcha-response"]
);

$options = array(
    'http' => array(
        'method' => 'POST',
        'content' => http_build_query($data)
    )
);

$context = stream_context_create($options);
$verify = file_get_contents($url, false, $context);
$captcha_success = json_decode($verify);

if ($captcha_success->success == false) {
    echo "<p>You are a bot! Go away!</p>";
}
else if ($captcha_success->success == true) {
    echo "<p>You are not not a bot!</p>";
}