1. #1
    Ext JS Premium Member mikegiddens's Avatar
    Join Date
    Mar 2007
    Location
    Denver, Colorado
    Posts
    273
    Vote Rating
    1
    mikegiddens will become famous soon enough

      1  

    Default [2.x] Ext.ux.reCAPTCHA Form Plugin

    [2.x] Ext.ux.reCAPTCHA Form Plugin


    Well I put this togeather for a form that was doing some emailing and didn't want it to get slamed with spam so I added a reCaptcha and thought I would share. I like the distributed computer model a hope that others will use this to help translate our public books.

    More info on reCaptcha at: http://recaptcha.net


    File: Ext.ux.recaptcha
    PHP Code:
    /**
     * @class Ext.ux.form.Recaptcha
     * @extends Ext.BoxComponent
     * Recaptcha field.
     * @constructor
     * Creates a new Recaptcha field
     * @param {Ext.Element/String/Object} config The configuration options.  If an element is passed, it is set as the internal
     * element and its id used as the component id.  If a string is passed, it is assumed to be the id of an existing element
     * and is used as the component id.  Otherwise, it is assumed to be a standard config object and is applied to the component.
     *
     * More information can be found about reCAPTCHA and lib files at: http://recaptcha.net
     */
    Ext.ux.Recaptcha Ext.extend(Ext.BoxComponent, {
        
    /**
         * @cfg {String} publickey The key to generate your recaptcha
         */
        /**
         * @cfg {String} theme The name of the theme
         */

        
    onRender : function(ctposition){
            if(!
    this.el){
                
    this.el document.createElement('div');
                
    this.el.id this.getId();

                            
    Recaptcha.create(this.publickeythis.el, {
                                    
    themethis.theme
                                
    ,    langthis.lang
                                
    ,    callbackRecaptcha.focus_response_field
                            
    });
            }
            
    Ext.ux.Recaptcha.superclass.onRender.call(thisctposition);
        }
    });

    Ext.reg('recaptcha'Ext.ux.Recaptcha); 
    Sample form:
    PHP Code:
            var email_form = new Ext.FormPanel({
            
    labelWidth60
                
    ,    region'center'
                
    ,    labelAlign'left'
          
    bodyStyle'padding: 5px 5px 0'
          
    borderfalse
                
    ,    items: [{
                            
    xtype'textfield'
                        
    ,    fieldLabelLang.Get('Core','email','email')
                        ,    
    name'email'
                        
    ,    vtype:'email'
                        
    ,    allowBlank:false
                        
    ,    width240
                    
    }, {
                            
    xtype'textarea'
                        
    ,    fieldLabelLang.Get('Core','email','message')
                        , 
    id'msg'
                        
    width240
                        
    ,    maxLength4000
                    
    }, {
                            
    xtype'recaptcha'
                        
    ,    name'recaptcha'
                        
    ,    id'recaptcha'
                        
    ,    publickey'6LcLzAEAAAAAAIaTeQnKjOKF-InrzAVQXFOErXhg'
                        
    ,    theme'white'
                        
    ,    lang'en'
                    
    }]
        }); 
    Sample PHP auth:
    PHP Code:
                        // ReCaptcha Check
                        
    require_once('classes/recaptchalib.php');
                        
    $privatekey "6LcLzAEAAAAAALvbNOZAPIKPnZ3KiT9ZY-SqWqqf";
                        
    $resp recaptcha_check_answer ($privatekey,
                                                                                        
    $_SERVER["REMOTE_ADDR"],
                                                                                        
    $recaptcha_challenge_field,
                                                                                        
    $recaptcha_response_field);
                        
                        if (!
    $resp->is_valid) {
                            die(
    "{success: false, errorMsg: 'The reCAPTCHA was not entered correctly. (" $resp->error ")'}");
                        } 
    Attached Images
    Mike Giddens
    =======================
    Opportunity is missed by most people because it is dressed in overalls and looks like work - Thomas Edison

  2. #2
    Sencha User
    Join Date
    Mar 2007
    Posts
    117
    Vote Rating
    0
    gizzmo is on a distinguished road

      0  

    Default


    Cool,

    I use reCaptcha on my site. I will try your implementation at once.
    Will be back with feedback.

    Johan

  3. #3
    Ext User
    Join Date
    Sep 2007
    Posts
    59
    Vote Rating
    0
    chemist458 is on a distinguished road

      0  

    Smile Awesome Work

    Awesome Work


    Wicked work, looks awesome, i will be adding that for sure
    George
    Last edited by chemist458; 8 May 2008 at 5:29 PM. Reason: typo

  4. #4
    Ext User
    Join Date
    Aug 2007
    Posts
    23
    Vote Rating
    0
    Comma is on a distinguished road

      0  

    Default


    I have an error using your extension... Ext 2.1
    Code:
    sp is undefined
    getViewWidth()()ext-base.js (line 9)
    Ext.ux.reCaptcha.js()()Ext.ux.r...aptcha.js (line 42)
    [Break on this error] Ext={version:"2.1"};window["undefined"]=...|new Date()).getTime()-this.getTime())};

  5. #5
    Sencha User
    Join Date
    Jan 2008
    Posts
    93
    Vote Rating
    0
    incaic is on a distinguished road

      0  

    Default


    reCAPTCHA adds js code when it loads and everytime
    a reload of a new challenge and DOES NOT clean up after
    itself. This is not good if one pops open a form in a
    window then either it is closed or form is sent.

    Anyone have a workaround for this? Don't really want
    to dig into the recaptcha_ajax.js code.

  6. #6
    Sencha User Hani79's Avatar
    Join Date
    Dec 2007
    Location
    Santa Barbara, California
    Posts
    52
    Vote Rating
    0
    Hani79 is on a distinguished road

      0  

    Default


    Just wanted to make a quick note that if you want to use this extension, you'll need to use the reCaptcha AJAX API by including their AJAX script on the page:

    <script type="text/javascript" src="http://api.recaptcha.net/js/recaptcha_ajax.js"></script>

  7. #7
    Sencha User Hani79's Avatar
    Join Date
    Dec 2007
    Location
    Santa Barbara, California
    Posts
    52
    Vote Rating
    0
    Hani79 is on a distinguished road

      0  

    Default


    I was curious how I should go about destroying the reCaptcha and then recreating it instead of reloading it. Anyone have any tips?

    The reason I am forced to do it that way is because should the reCaptcha need to be reloaded, it steals focus. Based on the Q & A found at this url:
    http://groups.google.com/group/recap...a447f6667cf61c

    I shouldn't be reloading it - I need to destroy/recreate. How do I go about that when I am rendering the reCaptcha directly into a form?

    Thanks in advance, for any help.

  8. #8
    Ext JS Premium Member rule3's Avatar
    Join Date
    Apr 2008
    Posts
    152
    Vote Rating
    0
    rule3 is on a distinguished road

      0  

    Default What id doing wrong

    What id doing wrong


    What id doing wrong
    http://mattikiviharju.name/zf-ext-defect/
    Does not work..

    EDIT: Work now.. I made my own PHP script from manual and now works..

  9. #9
    Ext User
    Join Date
    Feb 2009
    Location
    Slovenia
    Posts
    4
    Vote Rating
    0
    mihat is on a distinguished road

      0  

    Default


    I'm trying to use this with ExtJS 3.1.1 and I'm getting " types[config.xtype || defaultType] is not a constructor " error.

    Can anyone please direct me what I'm doing wrong?

  10. #10
    Ext JS Premium Member NoahK17's Avatar
    Join Date
    Apr 2008
    Location
    Atlanta, GA
    Posts
    518
    Vote Rating
    1
    NoahK17 is on a distinguished road

      0  

    Default


    Alright guys, here is what I did to get this working with ExtJS 3

    Recaptcha.js
    Code:
    /* Copyright (C) 2007 reCAPTCHA. Please contact us if you are thinking of modifying & hosting this file. */
    
    var RecaptchaTemplates = {
    	VertHtml : '<table id="recaptcha_table" class="recaptchatable" >\n<tr>\n<td colspan="6" class=\'recaptcha_r1_c1\'></td>\n</tr>\n<tr>\n<td class=\'recaptcha_r2_c1\'></td>\n<td colspan="4" class=\'recaptcha_image_cell\'><div id="recaptcha_image"></div></td>\n<td class=\'recaptcha_r2_c2\'></td>\n</tr>\n<tr>\n<td rowspan="6" class=\'recaptcha_r3_c1\'></td>\n<td colspan="4" class=\'recaptcha_r3_c2\'></td>\n<td rowspan="6" class=\'recaptcha_r3_c3\'></td>\n</tr>\n<tr>\n<td rowspan="3" class=\'recaptcha_r4_c1\' height="49">\n<div class="recaptcha_input_area">\n<label for="recaptcha_response_field" class="recaptcha_input_area_text"><span id="recaptcha_instructions_image" class="recaptcha_only_if_image recaptcha_only_if_no_incorrect_sol"></span><span id="recaptcha_instructions_audio" class="recaptcha_only_if_no_incorrect_sol recaptcha_only_if_audio"></span><span id="recaptcha_instructions_error" class="recaptcha_only_if_incorrect_sol"></span></label><br/>\n<input name="recaptcha_response_field" id="recaptcha_response_field" type="text" />\n</div>\n</td>\n<td rowspan="4" class=\'recaptcha_r4_c2\'></td>\n<td><a id=\'recaptcha_reload_btn\'><img id=\'recaptcha_reload\' width="25" height="17" /></a></td>\n<td rowspan="4" class=\'recaptcha_r4_c4\'></td>\n</tr>\n<tr>\n<td><a id=\'recaptcha_switch_audio_btn\' class="recaptcha_only_if_image"><img id=\'recaptcha_switch_audio\' width="25" height="16" alt="" /></a><a id=\'recaptcha_switch_img_btn\' class="recaptcha_only_if_audio"><img id=\'recaptcha_switch_img\' width="25" height="16" alt=""/></a></td>\n</tr>\n<tr>\n<td><a id=\'recaptcha_whatsthis_btn\'><img id=\'recaptcha_whatsthis\' width="25" height="16" /></a></td>\n</tr>\n<tr>\n<td class=\'recaptcha_r7_c1\'></td>\n<td class=\'recaptcha_r8_c1\'></td>\n</tr>\n</table>\n',
    	VertCss : '.recaptchatable td img {\n/* see http://developer.mozilla.org/en/docs/Images%2C_Tables%2C_and_Mysterious_Gaps */\ndisplay: block;\n}\n.recaptchatable .recaptcha_r1_c1 { background: url(IMGROOT/sprite.png) -0px -63px no-repeat; width: 318px; height: 9px; }\n.recaptchatable .recaptcha_r2_c1 { background: url(IMGROOT/sprite.png) -18px -0px no-repeat; width: 9px; height: 57px; }\n.recaptchatable .recaptcha_r2_c2 { background: url(IMGROOT/sprite.png) -27px -0px no-repeat; width: 9px; height: 57px; }\n.recaptchatable .recaptcha_r3_c1 { background: url(IMGROOT/sprite.png) -0px -0px no-repeat; width: 9px; height: 63px; }\n.recaptchatable .recaptcha_r3_c2 { background: url(IMGROOT/sprite.png) -18px -57px no-repeat; width: 300px; height: 6px; }\n.recaptchatable .recaptcha_r3_c3 { background: url(IMGROOT/sprite.png) -9px -0px no-repeat; width: 9px; height: 63px; }\n.recaptchatable .recaptcha_r4_c1 { background: url(IMGROOT/sprite.png) -43px -0px no-repeat; width: 171px; height: 49px; }\n.recaptchatable .recaptcha_r4_c2 { background: url(IMGROOT/sprite.png) -36px -0px no-repeat; width: 7px; height: 57px; }\n.recaptchatable .recaptcha_r4_c4 { background: url(IMGROOT/sprite.png) -214px -0px no-repeat; width: 97px; height: 57px; }\n.recaptchatable .recaptcha_r7_c1 { background: url(IMGROOT/sprite.png) -43px -49px no-repeat; width: 171px; height: 8px; }\n.recaptchatable .recaptcha_r8_c1 { background: url(IMGROOT/sprite.png) -43px -49px no-repeat; width: 25px; height: 8px; }\n.recaptchatable .recaptcha_image_cell center img { height:57px;}\n.recaptchatable .recaptcha_image_cell center { height:57px;}\n.recaptchatable .recaptcha_image_cell {\nbackground-color:white; height:57px;\n}\n/* some people break their style sheet, we need to clean up after them */\n#recaptcha_area, #recaptcha_table {\nwidth: 318px !important;\n}\n.recaptchatable, #recaptcha_area tr, #recaptcha_area td, #recaptcha_area th {\nmargin:0px !important;\nborder:0px !important;\npadding:0px !important;\nborder-collapse: collapse !important;\nvertical-align: middle !important;\n}\n.recaptchatable * {\nmargin:0px;\npadding:0px;\nborder:0px;\nfont-family:helvetica,sans-serif;\nfont-size:8pt;\ncolor:black;\nposition:static;\ntop:auto;\nleft:auto;\nright:auto;\nbottom:auto;\ntext-align:left !important;\n}\n.recaptchatable #recaptcha_image {\nmargin:auto;\n}\n.recaptchatable img {\nborder:0px !important;\nmargin:0px !important;\npadding:0px !important;\n}\n.recaptchatable a, .recaptchatable a:hover {\n-moz-outline:none;\nborder:0px !important;\npadding:0px !important;\ntext-decoration:none;\ncolor:blue;\nbackground:none !important;\nfont-weight: normal;\n}\n.recaptcha_input_area {\nposition:relative !important;\nwidth:146px !important;\nheight:45px !important;\nmargin-left:20px !important;\nmargin-right:5px !important;\nmargin-top:4px !important;\nbackground:none !important;\n}\n.recaptchatable label.recaptcha_input_area_text {\nmargin:0px !important;  \npadding:0px !important;\nposition:static !important;\ntop:auto !important;\nleft:auto !important;\nright:auto !important;\nbottom:auto !important;\nbackground:none !important;\nheight:auto !important;\nwidth:auto !important;\n}\n.recaptcha_theme_red label.recaptcha_input_area_text,\n.recaptcha_theme_white label.recaptcha_input_area_text {\ncolor:black !important;\n}\n.recaptcha_theme_blackglass label.recaptcha_input_area_text {\ncolor:white !important;\n}\n.recaptchatable #recaptcha_response_field  {\nwidth:145px !important;\nposition:absolute !important;\nbottom:7px !important;\npadding:0px !important;\nmargin:0px !important;\nfont-size:10pt;\n}\n.recaptcha_theme_blackglass #recaptcha_response_field,\n.recaptcha_theme_white #recaptcha_response_field {\nborder: 1px solid gray;\n}\n.recaptcha_theme_red #recaptcha_response_field {\nborder:1px solid #cca940;\n}\n.recaptcha_audio_cant_hear_link {\nfont-size:7pt;\ncolor:black;\n}\n.recaptchatable {\nline-height:1em;\n}\n#recaptcha_instructions_error {\ncolor:red !important;\n}\n',
    	CleanHtml : '<table id="recaptcha_table" class="recaptchatable">\n<tr height="73">\n<td class=\'recaptcha_image_cell\' width="302"><center><div id="recaptcha_image"></div></center></td>\n<td style="padding: 10px 7px 7px 7px;">\n<a id=\'recaptcha_reload_btn\'><img id=\'recaptcha_reload\' width="25" height="18" alt="" /></a>\n<a id=\'recaptcha_switch_audio_btn\' class="recaptcha_only_if_image"><img id=\'recaptcha_switch_audio\' width="25" height="15" alt="" /></a><a id=\'recaptcha_switch_img_btn\' class="recaptcha_only_if_audio"><img id=\'recaptcha_switch_img\' width="25" height="15" alt=""/></a>\n<a id=\'recaptcha_whatsthis_btn\'><img id=\'recaptcha_whatsthis\' width="25" height="16" /></a>\n</td>\n<td style="padding: 18px 7px 18px 7px;">\n<img id=\'recaptcha_logo\' alt="" width="71" height="36" />\n</td>\n</tr>\n<tr>\n<td style="padding-left: 7px;">\n<div class="recaptcha_input_area" style="padding-top: 2px; padding-bottom: 7px;">\n<input style="border: 1px solid #3c3c3c; width: 302px;" name="recaptcha_response_field" id="recaptcha_response_field" type="text" />\n</div>\n</td>\n<td></td>\n<td style="padding: 4px 7px 12px 7px;">\n<img id="recaptcha_tagline" width="71" height="17" />\n</td>\n</tr>\n</table>\n',
    	CleanCss : '.recaptchatable td img {\ndisplay: block;\n}\n.recaptchatable .recaptcha_image_cell center img { height:57px;}\n.recaptchatable .recaptcha_image_cell center { height:57px;}\n.recaptchatable .recaptcha_image_cell {\nbackground-color:white; height:57px; \npadding: 7px !important;\n}\n.recaptchatable, #recaptcha_area tr, #recaptcha_area td, #recaptcha_area th {\nmargin:0px !important;\nborder:0px !important;\nborder-collapse: collapse !important;\nvertical-align: middle !important;\n}\n.recaptchatable * {\nmargin:0px;\npadding:0px;\nborder:0px;\ncolor:black;\nposition:static;\ntop:auto;\nleft:auto;\nright:auto;\nbottom:auto;\ntext-align:left !important;\n}\n.recaptchatable #recaptcha_image {\nmargin:auto;\nborder: 1px solid #dfdfdf !important;\n}\n.recaptchatable a img {\nborder:0px;\n}\n.recaptchatable a, .recaptchatable a:hover {\n-moz-outline:none;\nborder:0px !important;\npadding:0px !important;\ntext-decoration:none;\ncolor:blue;\nbackground:none !important;\nfont-weight: normal;\n}\n.recaptcha_input_area {\nposition:relative !important;\nbackground:none !important;\n}\n.recaptchatable label.recaptcha_input_area_text {\nborder:1px solid #dfdfdf !important;\nmargin:0px !important;  \npadding:0px !important;\nposition:static !important;\ntop:auto !important;\nleft:auto !important;\nright:auto !important;\nbottom:auto !important;\n}\n.recaptcha_theme_red label.recaptcha_input_area_text,\n.recaptcha_theme_white label.recaptcha_input_area_text {\ncolor:black !important;\n}\n.recaptcha_theme_blackglass label.recaptcha_input_area_text {\ncolor:white !important;\n}\n.recaptchatable #recaptcha_response_field  {\nfont-size:11pt;\n}\n.recaptcha_theme_blackglass #recaptcha_response_field,\n.recaptcha_theme_white #recaptcha_response_field {\nborder: 1px solid gray;\n}\n.recaptcha_theme_red #recaptcha_response_field {\nborder:1px solid #cca940;\n}\n.recaptcha_audio_cant_hear_link {\nfont-size:7pt;\ncolor:black;\n}\n.recaptchatable {\nline-height:1em;\nborder: 1px solid #dfdfdf !important;\n}\n.recaptcha_error_text {\ncolor:red;\n}\n'
    };
    var RecaptchaStr_en = {
    	visual_challenge : "Get a visual challenge",
    	audio_challenge : "Get an audio challenge",
    	refresh_btn : "Get a new challenge",
    	instructions_visual : "Type the two words:",
    	instructions_audio : "Type what you hear:",
    	help_btn : "Help",
    	play_again : "Play sound again",
    	cant_hear_this : "Download sound as MP3",
    	incorrect_try_again : "Incorrect. Try again."
    };
    var RecaptchaStr_de = {
    	visual_challenge : "Visuelle Aufgabe generieren",
    	audio_challenge : "Audio-Aufgabe generieren",
    	refresh_btn : "Neue Aufgabe generieren",
    	instructions_visual : "Gib die 2 W\u00f6rter ein:",
    	instructions_audio : "Gib die 8 Ziffern ein:",
    	help_btn : "Hilfe",
    	incorrect_try_again : "Falsch. Nochmals versuchen!"
    };
    var RecaptchaStr_es = {
    	visual_challenge : "Obt\u00e9n un reto visual",
    	audio_challenge : "Obt\u00e9n un reto audible",
    	refresh_btn : "Obt\u00e9n un nuevo reto",
    	instructions_visual : "Escribe las 2 palabras:",
    	instructions_audio : "Escribe los 8 n\u00fameros:",
    	help_btn : "Ayuda",
    	incorrect_try_again : "Incorrecto. Otro intento."
    };
    var RecaptchaStr_fr = {
    	visual_challenge : "D\u00e9fi visuel",
    	audio_challenge : "D\u00e9fi audio",
    	refresh_btn : "Nouveau d\u00e9fi",
    	instructions_visual : "Entrez les deux mots:",
    	instructions_audio : "Entrez les huit chiffres:",
    	help_btn : "Aide",
    	incorrect_try_again : "Incorrect."
    };
    var RecaptchaStr_nl = {
    	visual_challenge : "Test me via een afbeelding",
    	audio_challenge : "Test me via een geluidsfragment",
    	refresh_btn : "Nieuwe uitdaging",
    	instructions_visual : "Type de twee woorden:",
    	instructions_audio : "Type de acht cijfers:",
    	help_btn : "Help",
    	incorrect_try_again : "Foute invoer."
    };
    var RecaptchaStr_pt = {
    	visual_challenge : "Obter um desafio visual",
    	audio_challenge : "Obter um desafio sonoro",
    	refresh_btn : "Obter um novo desafio",
    	instructions_visual : "Escreva as 2 palavras:",
    	instructions_audio : "Escreva os 8 numeros:",
    	help_btn : "Ajuda",
    incorrect_try_again: "Incorrecto. Tenta outra vez."
    };
    var RecaptchaStr_ru = {
    	visual_challenge : "\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443",
    	audio_challenge : "\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0437\u0432\u0443\u043a\u043e\u0432\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443",
    	refresh_btn : "\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443",
    	instructions_visual : "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0434\u0432\u0430 \u0441\u043b\u043e\u0432\u0430:",
    	instructions_audio : "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0432\u043e\u0441\u0435\u043c\u044c \u0447\u0438\u0441\u0435\u043b:",
    	help_btn : "\u041f\u043e\u043c\u043e\u0449\u044c",
    	incorrect_try_again : "\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e."
    };
    var RecaptchaStr_tr = {
    	visual_challenge : "G\u00f6rsel deneme",
    	audio_challenge : "\u0130\u015Fitsel deneme",
    	refresh_btn : "Yeni deneme",
    	instructions_visual : "\u0130ki kelimeyi yaz\u0131n:",
    	instructions_audio : "Sekiz numaray\u0131 yaz\u0131n:",
    	help_btn : "Yard\u0131m (\u0130ngilizce)",
    	incorrect_try_again : "Yanl\u0131\u015f. Bir daha deneyin."
    };
    var RecaptchaLangMap = {
    	en : RecaptchaStr_en,
    	de : RecaptchaStr_de,
    	es : RecaptchaStr_es,
    	fr : RecaptchaStr_fr,
    	nl : RecaptchaStr_nl,
    	pt : RecaptchaStr_pt,
    	ru : RecaptchaStr_ru,
    	tr : RecaptchaStr_tr
    };
    var RecaptchaStr = RecaptchaStr_en;
    var RecaptchaOptions;
    var RecaptchaDefaultOptions = {
    tabindex: 0,
    theme: 'red',
    callback: null,
    lang: 'en',
    custom_theme_widget : null,
    custom_translations : null
    };
    var Recaptcha = {
    	widget : null,
    	timer_id : -1,
    	style_set : false,
    	theme : null,
    	type : 'image',
    	ajax_verify_cb : null,
    	$ : function(id) {
    		if (typeof (id) == "string") {
    			return document.getElementById(id);
    		} else {
    			return id;
    		}
    	},
    	create : function(public_key, element, options) {
    		Recaptcha.destroy();
    		if (element) {
    			Recaptcha.widget = Recaptcha.$(element);
    		}
    		Recaptcha._init_options(options);
    		Recaptcha._call_challenge(public_key);
    	},
    	destroy : function() {
    		var challengefield = Recaptcha.$('recaptcha_challenge_field');
    		if (challengefield) {
    			challengefield.parentNode.removeChild(challengefield);
    		}
    		if (Recaptcha.timer_id != -1) {
    			clearInterval(Recaptcha.timer_id);
    		}
    		Recaptcha.timer_id = -1;
    		var imagearea = Recaptcha.$('recaptcha_image');
    		if (imagearea) {
    			imagearea.innerHTML = "";
    		}
    		// don't clear the area if it's custom, the caller might want to
    		// reuse the dom elements.
    		if (Recaptcha.widget) {
    			if (Recaptcha.theme != "custom") {
    				Recaptcha.widget.innerHTML = "";
    			} else {
    				Recaptcha.widget.style.display = "none";
    			}
    			Recaptcha.widget = null;
    		}
    	},
    	focus_response_field : function() {
    		var $ = Recaptcha.$;
    		var field = $('recaptcha_response_field');
    		field.focus();
    	},
    	get_challenge : function() {
    		if (typeof (RecaptchaState) == "undefined") {
    			return null;
    		}
    		return RecaptchaState.challenge;
    	},
    	get_response : function() {
    		var $ = Recaptcha.$;
    		var field = $('recaptcha_response_field');
    		if (!field) {
    			return null;
    		}
    		return field.value;
    	},
    	ajax_verify : function(callback) {
    		Recaptcha.ajax_verify_cb = callback;
    		var scriptURL = Recaptcha._get_api_server() + "/ajaxverify" + "?c="
    				+ encodeURIComponent(Recaptcha.get_challenge()) + "&response="
    				+ encodeURIComponent(Recaptcha.get_response());
    		Recaptcha._add_script(scriptURL);
    	},
    	_ajax_verify_callback : function(data) {
    		Recaptcha.ajax_verify_cb(data);
    	},
    	_get_api_server : function() {
    		var protocol = window.location.protocol;
    		var server;
    		if (typeof (_RecaptchaOverrideApiServer) != "undefined") {
    			server = _RecaptchaOverrideApiServer;
    		} else if (protocol == 'https:') {
    			server = "api-secure.recaptcha.net";
    		} else {
    			server = "api.recaptcha.net";
    		}
    		return protocol + "//" + server;
    	},
    	_call_challenge : function(public_key) {
    		var scriptURL = Recaptcha._get_api_server() + "/challenge?k="
    				+ public_key + "&ajax=1&cachestop=" + Math.random();
    		if (typeof (RecaptchaOptions.extra_challenge_params) != "undefined") {
    			scriptURL += "&" + RecaptchaOptions.extra_challenge_params;
    		}
    		Recaptcha._add_script(scriptURL);
    	},
    	_add_script : function(scriptURL) {
    		var scriptTag = document.createElement("script");
    		scriptTag.type = "text/javascript";
    		scriptTag.src = scriptURL;
    		Recaptcha._get_script_area().appendChild(scriptTag);
    	},
    	_get_script_area : function() {
    		var parentElement = document.getElementsByTagName("head");
    		if (!parentElement || parentElement.length < 1) {
    			parentElement = document.body;
    		} else {
    			parentElement = parentElement[0];
    		}
    		return parentElement;
    	},
    	_hash_merge : function(hashes) {
    		var r = {};
    		for ( var h in hashes) {
    			for ( var k in hashes[h]) {
    				r[k] = hashes[h][k]
    			}
    		}
    		return r;
    	},
    	_init_options : function(opts) {
    		RecaptchaOptions = Recaptcha._hash_merge( [ RecaptchaDefaultOptions,
    				opts || {} ]);
    	},
    	challenge_callback : function() {
    		var element = Recaptcha.widget;
    		Recaptcha._reset_timer();
    		RecaptchaStr = Recaptcha._hash_merge( [ RecaptchaStr_en,
    				RecaptchaLangMap[RecaptchaOptions.lang] || {},
    				RecaptchaOptions.custom_translations || {} ]);
    		/* Try to avoid back/forward cache problems */
    		// firefox
    		if (window.addEventListener) {
    			window.addEventListener('unload', function(e) {
    				Recaptcha.destroy();
    			}, false);
    		}
    		// IE
    		if (Recaptcha._is_ie() && window.attachEvent) {
    			window.attachEvent('onbeforeunload', function() {
    				// I think this may be causing some errors -- it seems
    					// that sometimes IE isn't submitting the form fully
    					// This may be breaking the back button functionality
    					// :-(
    					// Recaptcha.destroy();
    				});
    		}
    		// safari
    		if (navigator.userAgent.indexOf("KHTML") > 0) {
    			var iframe = document.createElement('iframe');
    			iframe.src = "about:blank";
    			iframe.style.height = "0px";
    			iframe.style.width = "0px";
    			iframe.style.visibility = "hidden";
    			iframe.style.border = "none";
    			var textNode = document
    					.createTextNode("This frame prevents back/forward cache problems in Safari.");
    			iframe.appendChild(textNode);
    			document.body.appendChild(iframe);
    		}
    		Recaptcha._finish_widget();
    	},
    	_add_css : function(css) {
    		var styleTag = document.createElement("style");
    		styleTag.type = "text/css";
    		if (styleTag.styleSheet) { // IE only
    			if (navigator.appVersion.indexOf("MSIE 5") != -1) { // IE 5 crashes
    																// if we add a
    																// style tag to
    																// the DOM
    				document.write("<style type='text/css'>" + css + "</style>");
    			} else {
    				styleTag.styleSheet.cssText = css;
    			}
    		} else if (navigator.appVersion.indexOf("MSIE 5") != -1) {
    			document.write("<style type='text/css'>" + css + "</style>");
    		} else {
    			var textNode = document.createTextNode(css);
    			styleTag.appendChild(textNode);
    		}
    		Recaptcha._get_script_area().appendChild(styleTag);
    	},
    	_set_style : function(css) {
    		// We only allow the style to be set once, because IE behaves
    		// poorly otherwise. Same goes for Recaptcha.theme.
    		if (Recaptcha.style_set) {
    			return;
    		}
    		Recaptcha.style_set = true;
    		Recaptcha
    				._add_css(css
    						+ "\n\n"
    						+ ".recaptcha_is_showing_audio .recaptcha_only_if_image,"
    						+ ".recaptcha_isnot_showing_audio .recaptcha_only_if_audio,"
    						+ ".recaptcha_had_incorrect_sol .recaptcha_only_if_no_incorrect_sol,"
    						+ ".recaptcha_nothad_incorrect_sol .recaptcha_only_if_incorrect_sol"
    						+ "{display:none !important}");
    	},
    	_init_builtin_theme : function() {
    		var $ = Recaptcha.$;
    		var $_ = RecaptchaStr;
    		var $ST = RecaptchaState;
    		var css, html, imgfmt;
    		var server_no_slash = $ST.server;
    		if (server_no_slash[server_no_slash.length - 1] == "/")
    			server_no_slash = server_no_slash.substring(0,
    					server_no_slash.length - 1);
    		var IMGROOT = server_no_slash + "/img/" + Recaptcha.theme;
    		if (Recaptcha.theme == 'clean') {
    			css = RecaptchaTemplates.CleanCss;
    			html = RecaptchaTemplates.CleanHtml;
    			imgfmt = 'png';
    		} else {
    			css = RecaptchaTemplates.VertCss;
    			html = RecaptchaTemplates.VertHtml;
    			imgfmt = 'gif';
    		}
    		css = css.replace(/IMGROOT/g, IMGROOT);
    		Recaptcha._set_style(css);
    		Recaptcha.widget.innerHTML = "<div id='recaptcha_area'>" + html
    				+ "</div>";
    		$('recaptcha_reload').src = IMGROOT + "/refresh." + imgfmt;
    		$('recaptcha_switch_audio').src = IMGROOT + "/audio." + imgfmt;
    		$('recaptcha_switch_img').src = IMGROOT + "/text." + imgfmt;
    		$('recaptcha_whatsthis').src = IMGROOT + "/help." + imgfmt;
    		if (Recaptcha.theme == 'clean') {
    			$('recaptcha_logo').src = IMGROOT + "/logo." + imgfmt;
    			$('recaptcha_tagline').src = IMGROOT + "/tagline." + imgfmt;
    		}
    		$('recaptcha_reload').alt = $_.refresh_btn;
    		$('recaptcha_switch_audio').alt = $_.audio_challenge;
    		$('recaptcha_switch_img').alt = $_.visual_challenge;
    		$('recaptcha_whatsthis').alt = $_.help_btn;
    		$('recaptcha_reload_btn').href = "javascript:Recaptcha.reload ();";
    		$('recaptcha_reload_btn').title = $_.refresh_btn;
    		$('recaptcha_switch_audio_btn').href = "javascript:Recaptcha.switch_type('audio');";
    		$('recaptcha_switch_audio_btn').title = $_.audio_challenge;
    		$('recaptcha_switch_img_btn').href = "javascript:Recaptcha.switch_type('image');";
    		$('recaptcha_switch_img_btn').title = $_.visual_challenge;
    		$('recaptcha_whatsthis_btn').href = Recaptcha._get_help_link();
    		$('recaptcha_whatsthis_btn').target = "_blank";
    		$('recaptcha_whatsthis_btn').title = $_.help_btn;
    		$('recaptcha_whatsthis_btn').onclick = function() {
    			Recaptcha.showhelp();
    			return false;
    		};
    		$('recaptcha_table').className = "recaptchatable " + "recaptcha_theme_"
    				+ Recaptcha.theme;
    		if ($("recaptcha_instructions_image")) {
    			$("recaptcha_instructions_image").appendChild(
    					document.createTextNode($_.instructions_visual));
    		}
    		if ($("recaptcha_instructions_audio")) {
    			$("recaptcha_instructions_audio").appendChild(
    					document.createTextNode($_.instructions_audio));
    		}
    		if ($("recaptcha_instructions_error")) {
    			$("recaptcha_instructions_error").appendChild(
    					document.createTextNode($_.incorrect_try_again));
    		}
    	},
    	_finish_widget : function() {
    		var $ = Recaptcha.$;
    		var $_ = RecaptchaStr;
    		var $ST = RecaptchaState;
    		var $OPT = RecaptchaOptions;
    		var theme = $OPT.theme;
    		switch (theme) {
    		case 'red':
    		case 'white':
    		case 'blackglass':
    		case 'clean':
    		case 'custom':
    			break;
    		default:
    			theme = 'red';
    			break;
    		}
    		if (!Recaptcha.theme) {
    			Recaptcha.theme = theme;
    		}
    		if (Recaptcha.theme != "custom") {
    			Recaptcha._init_builtin_theme();
    		} else {
    			// get the rules for audio/visual error/no error
    			Recaptcha._set_style("");
    		}
    		var challengeFieldHolder = document.createElement("span");
    		challengeFieldHolder.id = "recaptcha_challenge_field_holder";
    		challengeFieldHolder.style.display = "none";
    		$('recaptcha_response_field').parentNode.insertBefore(
    				challengeFieldHolder, $('recaptcha_response_field'));
    		$('recaptcha_response_field').setAttribute("autocomplete", "off");
    		$('recaptcha_image').style.width = '300px';
    		$('recaptcha_image').style.height = '57px';
    		Recaptcha.should_focus = false;
    		Recaptcha._set_challenge($ST.challenge, 'image');
    		if ($OPT.tabindex) {
    			$('recaptcha_response_field').tabIndex = $OPT.tabindex;
    			if (Recaptcha.theme != "custom") {
    				$('recaptcha_whatsthis_btn').tabIndex = $OPT.tabindex;
    				$('recaptcha_switch_img_btn').tabIndex = $OPT.tabindex;
    				$('recaptcha_switch_audio_btn').tabIndex = $OPT.tabindex;
    				$('recaptcha_reload_btn').tabIndex = $OPT.tabindex;
    			}
    		}
    		if (Recaptcha.widget) {
    			Recaptcha.widget.style.display = '';
    		}
    		if ($OPT.callback) {
    			$OPT.callback();
    		}
    	},
    	switch_type : function(new_type) {
    		var $C = Recaptcha;
    		$C.type = new_type;
    		$C.reload($C.type == 'audio' ? 'a' : 'v');
    	},
    	reload : function(reason) {
    		var $C = Recaptcha;
    		var $ = $C.$;
    		var $ST = RecaptchaState;
    		if (typeof (reason) == "undefined")
    			reason = 'r';
    		var scriptURL = $ST.server + "reload?c=" + $ST.challenge + "&k="
    				+ $ST.site + "&reason=" + reason + "&type=" + $C.type
    				+ "&lang=" + RecaptchaOptions.lang;
    		if (typeof (RecaptchaOptions.extra_challenge_params) != "undefined") {
    			scriptURL += "&" + RecaptchaOptions.extra_challenge_params;
    		}
    		if ($C.type == 'audio') {
    			if (RecaptchaOptions.audio_beta_12_08) {
    				scriptURL += "&audio_beta_12_08=1";
    			} else {
    				scriptURL += "&new_audio_default=1";
    			}
    		}
    		$C.should_focus = reason != 't';
    		$C._add_script(scriptURL);
    	},
    	finish_reload : function(new_challenge, type) {
    		RecaptchaState.is_incorrect = false;
    		Recaptcha._set_challenge(new_challenge, type);
    	},
    	_set_challenge : function(new_challenge, type) {
    		var $C = Recaptcha;
    		var $ST = RecaptchaState;
    		var $ = $C.$;
    		$ST.challenge = new_challenge;
    		// this should really be the case already...
    		$C.type = type;
    		// using innerHTML prevents back/forward from caching this
    		$('recaptcha_challenge_field_holder').innerHTML = "<input type='hidden' name='recaptcha_challenge_field' id='recaptcha_challenge_field' value='"
    				+ $ST.challenge + "'/>";
    		if (type == 'audio') {
    			$("recaptcha_image").innerHTML = Recaptcha.getAudioCaptchaHtml();
    		} else if (type == 'image') {
    			var imageurl = $ST.server + 'image?c=' + $ST.challenge;
    			// display:block due to
    			// http://developer.mozilla.org/en/docs/Images%2C_Tables%2C_and_Mysterious_Gap
    			// use innerHTML to avoid triggering a firefox dom preference
    			$('recaptcha_image').innerHTML = "<img style='display:block;' height='57' width='300' src='"
    					+ imageurl + "'/>";
    		}
    		Recaptcha._css_toggle("recaptcha_had_incorrect_sol",
    				"recaptcha_nothad_incorrect_sol", $ST.is_incorrect);
    		Recaptcha._css_toggle("recaptcha_is_showing_audio",
    				"recaptcha_isnot_showing_audio", type == 'audio');
    		$C._clear_input();
    		if ($C.should_focus) {
    			$C.focus_response_field();
    		}
    		$C._reset_timer();
    	},
    	_reset_timer : function() {
    		var $ST = RecaptchaState;
    		clearInterval(Recaptcha.timer_id);
    		Recaptcha.timer_id = setInterval("Recaptcha.reload('t');",
    				($ST.timeout - 60 * 5) * 1000);
    	},
    	showhelp : function() {
    		window
    				.open(
    						Recaptcha._get_help_link(),
    						"recaptcha_popup",
    						"width=460,height=570,location=no,menubar=no,status=no,toolbar=no,scrollbars=yes,resizable=yes");
    	},
    	_clear_input : function() {
    		var resp = Recaptcha.$('recaptcha_response_field');
    		resp.value = "";
    	},
    	_displayerror : function(msg) {
    		var $ = Recaptcha.$;
    		$('recaptcha_image').innerHTML = '';
    		$('recaptcha_image').appendChild(document.createTextNode(msg));
    	},
    	reloaderror : function(msg) {
    		Recaptcha._displayerror(msg);
    	},
    	_is_ie : function() {
    		return (navigator.userAgent.indexOf("MSIE") > 0) && !window.opera;
    	},
    	_css_toggle : function(classT, classF, isset) {
    		// try to do these CSS toggles just on the recaptcha widget. But,
    		// if that wasn't passed in, go for the document body.
    		var element = Recaptcha.widget;
    		if (!element)
    			element = document.body;
    		var classname = element.className;
    		classname = classname.replace(new RegExp("(^|\\s+)" + classT
    				+ "(\\s+|$)"), ' ');
    		classname = classname.replace(new RegExp("(^|\\s+)" + classF
    				+ "(\\s+|$)"), ' ');
    		classname += " " + (isset ? classT : classF);
    		element.className = classname;
    	},
    	_get_help_link : function() {
    		var lang = RecaptchaOptions.lang;
    		return 'http://recaptcha.net/popuphelp/' + (lang == 'en' ? ""
    				: (lang + ".html"));
    	},
    	playAgain : function() {
    		var $ = Recaptcha.$;
    		$("recaptcha_image").innerHTML = Recaptcha.getAudioCaptchaHtml();
    	},
    	getAudioCaptchaHtml : function() {
    		var $C = Recaptcha;
    		var $ST = RecaptchaState;
    		var $ = Recaptcha.$;
    		var httpwavurl = $ST.server + "image?c=" + $ST.challenge;
    		if (httpwavurl.indexOf("https://") == 0) {
    			httpwavurl = "http://" + httpwavurl.substring(8);
    		}
    		var swfUrl = $ST.server + "/img/audiocaptcha.swf?v2";
    		var embedCode;
    		if ($C._is_ie()) {
    			embedCode = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="audiocaptcha" width="0" height="0" codebase="https://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab"><param name="movie" value="' + swfUrl + '" /><param name="quality" value="high" /><param name="bgcolor" value="#869ca7" /><param name="allowScriptAccess" value="always" /></object><br/>';
    		} else {
    			embedCode = '<embed src="' + swfUrl + '" quality="high" bgcolor="#869ca7" width="0" height="0" name="audiocaptcha" align="middle" play="true" loop="false" quality="high" allowScriptAccess="always" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer"></embed> ';
    		}
    		var cantHearCode = (Recaptcha.checkFlashVer() ? '<br/><a class="recaptcha_audio_cant_hear_link" href="#" onclick="Recaptcha.playAgain(); return false;">' + RecaptchaStr.play_again + '</a>'
    				: '')
    				+ '<br/><a class="recaptcha_audio_cant_hear_link" target="_blank" href="'
    				+ httpwavurl + '">' + RecaptchaStr.cant_hear_this + '</a>';
    		return embedCode + cantHearCode;
    	},
    	gethttpwavurl : function() {
    		var $ST = RecaptchaState;
    		if (Recaptcha.type == 'audio') {
    			var httpwavurl = $ST.server + "image?c=" + $ST.challenge;
    			if (httpwavurl.indexOf("https://") == 0) {
    				httpwavurl = "http://" + httpwavurl.substring(8);
    			}
    			return httpwavurl;
    		}
    		return "";
    	},
    	checkFlashVer : function() {
    		var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
    		var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true
    				: false;
    		var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true
    				: false;
    		var flashVer = -1;
    		if (navigator.plugins != null && navigator.plugins.length > 0) {
    			if (navigator.plugins["Shockwave Flash 2.0"]
    					|| navigator.plugins["Shockwave Flash"]) {
    				var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0"
    						: "";
    				var flashDescription = navigator.plugins["Shockwave Flash"
    						+ swVer2].description;
    				var descArray = flashDescription.split(" ");
    				var tempArrayMajor = descArray[2].split(".");
    				flashVer = tempArrayMajor[0];
    			}
    		} else if (isIE && isWin && !isOpera) {
    			try {
    				// version will be set for 7.X or greater players
    				var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
    				var flashVerStr = axo.GetVariable("$version");
    				flashVer = flashVerStr.split(" ")[1].split(",")[0];
    			} catch (e) {
    			}
    		}
    		return flashVer >= 9;
    	},
    	getlang : function() {
    		return RecaptchaOptions.lang;
    	}
    };
    
    /**
     * @class Ext.ux.form.Recaptcha
     * @extends Ext.BoxComponent Recaptcha field.
     * @constructor Creates a new Recaptcha field
     * @param {Ext.Element/String/Object}
     *            config The configuration options. If an element is passed, it is
     *            set as the internal element and its id used as the component id.
     *            If a string is passed, it is assumed to be the id of an existing
     *            element and is used as the component id. Otherwise, it is assumed
     *            to be a standard config object and is applied to the component.
     * 
     * More information can be found about reCAPTCHA and lib files at:
     * http://recaptcha.net
     */
    Ext.ux.Recaptcha = Ext.extend(Ext.BoxComponent, {
    	/**
    	 * @cfg {String} publickey The key to generate your recaptcha
    	 */
    	/**
    	 * @cfg {String} theme The name of the theme
    	 */
    
    	onRender : function(ct, position) {
    		if (!this.el) {
    			this.el = document.createElement('div');
    			this.el.id = this.getId();
    
    			Recaptcha.create(this.publickey, this.el, {
    				theme : 'clean'
    				, callback : Recaptcha.focus_response_field
    			});
    		}
    		Ext.ux.Recaptcha.superclass.onRender.call(this, ct, position);
    	}
    });
    
    Ext.reg('recaptcha', Ext.ux.Recaptcha);
    FormPanel item:
    Code:
    {
        xtype:'recaptcha',
        name:'recaptcha',
        id:'recaptcha',
        fieldLabel: 'Captcha',
        publickey:'YOUR PUBLIC KEY'
    }
    FormPanel submit handler:
    Code:
    var challenge = Recaptcha.get_challenge();
    var response = Recaptcha.get_response();
        Ext.Ajax.request({   
            waitMsg: 'One moment...',
            url: 'www.example.com/email/recaptcha/',
            params: { challenge: String(challenge), response: String(response)},
      								
            success:function(form, action){
                obj = Ext.util.JSON.decode(form.responseText);
                if(obj.data[0].success === false){
                    /* captcha failed, reload */
                    Recaptcha.reload();
                    Ext.Msg.show({
                        title:'Oops!',
                        msg: obj.data[0].message,
                        buttons: Ext.Msg.OK,
                        animEl: 'elId',
                        icon: Ext.MessageBox.WARNING,
                        fn: function(btn, text) {
                            if (btn == 'ok') {
                                /* re-focus on the captcha field */
                                Recaptcha.focus_response_field();
                            }
                        }
                    });
                }
                else{
                    /* success, continue on */
                    emailForm.getForm().submit({
                        method: 'POST',
                        url: 'http://www.example.com',
                    });
                }
            }
        });
    PHP Code containing Captcha method/function using Zend Framework (JSON) and CodeIgniter:
    Code:
    function recaptcha() {
    		/* load some ZF classes */
    		$this->load->library ( 'zend' );
    		$this->zend->load ( 'Zend/Json' );
    		/* define the return array */
    		$successMessage = array ();
    		/* get the POST variables */
    		$challenge = isset ( $_REQUEST ["challenge"] ) ? ( string ) $_REQUEST ["challenge"] : null;
    		$response = isset ( $_REQUEST ["response"] ) ? ( string ) $_REQUEST ["response"] : null;
    		$remote_ip = $_SERVER['REMOTE_ADDR'];
    		$private_key = 'YOUR PRIVATE KEY';
    		/* error handling */
    		if ((isset ( $response ) && $response == '')) {
    			$successMessage ['data'] [] = array ("success" => false, "message" => 'Please type the letters depicted in the Captcha image above to continue with your Request. Alternatively, you can log in to bypass the Captcha.' );
    			$json = Zend_Json::encode ( $successMessage );
    			die ( $json );
    		}
    		/* build the sql querys */
    		try {
    			require_once('recaptchalib.php'); // download from recaptcha.com
    			$resp = recaptcha_check_answer(
    			    $private_key,
                	            $remote_ip,
                	            $challenge,
                	            $response
                            );
               	if (!$resp->is_valid) {
                	    $successMessage ['data'] [] = array ("success" => false, "message" => 'The Captcha text you entered did not match the image! Please try again with a new Captcha...' );
                        $json = Zend_Json::encode ( $successMessage );
                        die ( $json );
               	}
               	else{
               		$successMessage ['data'] [] = array ("success" => true, "message" => 'Success!' );
               	}
    		} catch ( Exception $e ) {
    			/* was there an error? */
    			$successMessage ['data'] [] = array ("success" => false, "message" => 'If this is the first time you have seen this error, please try submitting your request again. If you continue to see this error, please contact xxx@xxx.com directly with your question.' );
    			$json = Zend_Json::encode ( $successMessage );
    			die ( $json );
    		} // end try/catch
    		/* return the data to the app */
    		$json = Zend_Json::encode ( $successMessage );
    		die ( $json );
    	} // end fn: recaptcha
    That should take care of everything! Don't forget to download the PHP lib from recaptcha.com, cheers!
    Noah
    Senior Web Developer
    NBA.com

film izle

hd film izle

film sitesi

takipci kazanma sitesi

takipci kazanma sitesi

güzel olan herşey

takipci alma sitesi

komik eğlenceli videolar