Customizing Magento’s Native Captcha (Advanced)

If you implemented native Magento captcha before (potentially using this tutorial Magento Captcha Contact Form) you’ll notice that captcha image is fairly small in height, has a lot of dots (also knows as noise level), some random lines, and very small font.

native captcha on contact form

Luckily, all these attributes (as well as background) can be changed. Magento has a block class Mage_Captcha_Model_Zend located in “app/code/core/Mage/Captcha/Model/Zend.php” which extends Zend_Captcha_Image class.

Zend_Captcha_Image class contains functions we need to modify properties like noise level, lines, and font height. We’re not going to touch this class because the class which renders our captcha using _toHtml() function is Mage_Captcha_Model_Zend.

Note: This example is a continuation (or builds on top of) primary tutorial on setting up native captcha on contact page.

Overview: We will extend Mage_Captcha_Model_Zend model, make necessary changes to captcha settings, and modify our config.xml to indicate to Magento that we’re rewriting Magento’s core file with our’s.

Step 1: Create a new block class inside “app/code/local/Tutorial/Captcha/Block/Captcha/” called Zend.php, and paste the following code.

Yellow lines outline new addition on top of core _toHtml() function found inside Mage_Captcha_Model_Zend. Functions used in this piece of code are self-explanatory so I’ll just list default values Magento uses when generating native captcha.

In our new _toHtml() function we reduce noise level from 200 to 50, set line noise level from 5 to 0, and increase font-size from 24 to 30.

Step 2: Modify config.xml to ensure Magento uses our Block class to generate new captcha image. Below is the complete config.xml used in initial tutorial with additions of new block override code highlight in yellow.

In this snippet we override Mage_Captcha_Model_Zend class with our own Tutorial_Captcha_Block_Captcha_Zend. In result, you get the following captcha which is far more readable then native captcha generation. Keep in mind, captcha is meant to be hard to read but not impossible. How readable you make captcha is up to your and your requirements, this is just an example and is not used in practice.

magento modified captcha image

This is it for this example but not the end to allowed modifications. Further, you can modify captcha image background, font style used to generate text, font text color and more. This can be achieved by extending and overriding “_generateImage($id, $word)” function inside Zend’s Zend_Captcha_Image class.

Update: GitHub repository now available

Magento Captcha For Contact Us Form

Magento comes with a built-in Captcha which you can utilize in your own pages. For this tutorial I’m using Magento 1.9.2.1 and default theme so template files (.phtml) modifications will reside in “app/design/frontend/base/default/“.

Overview: We will create our own module to avoid overriding core Magento files, add our form label (and ID) to CAPTCHA Form section in adminhtml,specify where and how captcha will be rendered on our page, and lastly add an observe to trigger validation when the form is submitted.

Step 1: Create a new module called Captcha under Tutorial namespace (Tutorial_Captcha).

Step 2: Add our form to adminhtml in System->Configuration->Customers->Customer Configuration->Captcha->Forms.

Refresh your adminhtml page to see “Contact Page” show up as one of the options under CAPTCHA->Forms area. Select “Contact Page” as an option by highlighting it, update Display Mode to “Always“, and click “Save“.

Adminhtml Captcha Contact Form

Step 3: Create local.xml file with the following code, path “app/design/frontend/base/default/layout/local.xml“:

First thing to notice is the <formId> node contains the same value as what we used for key node in Step 2. Overall this piece of code targets Contacts module, Index controller and Index action. Then we reference a block name “contactForm” (which is defined inside “app/design/frontend/base/default/layout/contacts.xml” on line 45) and insert our new captcha child block. New child block adds “captcha.js” into website’s head section for generating new captcha images. Rest is captcha width/height settings which you can modify according to your needs.

Step 4: Modify “app/design/frontend/base/default/template/contacts/form.phtml” file to include our new captcha child block.

This will output captcha block if all conditions are met which were outlined in adminhtml CAPTCHA settings. Refresh the page and you should see captcha added to your form.

Magento Contact Us Captcha
Step 5: Now that Captcha is showing up on our page, the last thing we need to do is add an observer model and specify an event to trigger observer to validate captcha input.

This file defines a function which is used to validate our captcha input. You’ll notice the $formId variable reflects the same key node we’ve been using throughout this tutorial. Body of this function uses exactly the same validation code as default Magento captcha on pages like registration, login, forgotpassword, admin login, admin forgot password, etc.

Highlighted section is our new addition. Models node defines our model folder. Events node is for watching for specific events. We want to target only one specific action and that’s post action of our contacts controller, so the key node of our event is “controller_action_predispatch_contacts_index_post“. The rest is basic observer definition which declared type of our observer (model in this case), class definition. For <class> node, you can specify full class name “Tutorial_Captcha_Model_Observer” or like in the code above (Magento style).

That’s it, happy coding.

Update: GitHub repository now available

PHP – PDO dynamic parameter binding

If you’re not using large frameworks and rely on your own skills and expertise to get the job done, then you’ve probably written many queries and used the same database handler to execute your query, while always making sure your data is properly escaped before saving into the database.

While writing custom functions, I found myself escaping data manually every time I have to insert new data into the database. It was hectic. After writing functions to clean the data, it still required a redundant amount of work to apply it against all user input.

I ended up writing two small functions which allow me to pass the parameters I need for the query and dynamically bind each parameter to the query. Dynamic binding became very useful when you’re dealing with forms and lots of input fields to process.

Here’s the example:

Explanation: I manually throw PHP exceptions because if I know ahead of time that the function will break while someone else uses it incorrectly, then I don’t want the system to work at all and the code should be fixed immediately. Continuing, we use the “prepare()” function to set everything up, following by a “foreach” loop to cycle through the $params array and bind $key to $value to the previously created statement ($stm). Note, $value is passed by a reference. Lastly, we execute the query and return the count of affected rows. That way in your model you can check if the SQL statement you created has executed properly.

This function would reside in your database file (or class) which contains a database handler. The usage part would ideally be another function which processes a request, usually from a model, but it all depends how you structure your code.

The function can be customized in any way you want. Let me know if this was helpful or you have a better approach to automating the process of dynamically binding parameters while using PDO.

 

Javascript match find all occurrences

The Javascript’s function .match() will return an array of results matching your regular expression.

If you run into the case where only the first occurrence is returned from the match function then you’ll probably missing a “g” flag at the end of your regular expression.

That’s all you need.

jQuery: How to exit $.each loop

If you wrote your code and tried using the “break;” command to exit the “each loop” you may have noticed that it’s not working, thus is why you’re here.

The “break” command actually acts exactly what the “continue” command does in Javascript. The “continue” command skips the current iteration and continues to the next one.

To exit jQuery’s $.each loop, you have to use the “return false;” method, like so:

Happy coding 🙂

Javascript: Event.target and Event.srcElement

When working with events and making your code compatible with other browsers it’s important to remember to use the right target property depending what browser you are in.

For example if you are using Firefox then you can simple do this:

This will output an element which trigger the event. Now if you want to achieve the same thing in Internet Explorer (versions 6-8) you have to use different approach because event listeners are attached using a non-standard element.attachEvent() method.

To make things shorter and better, I recommend using a short notation to target both situations at the same time depending on the browser the client is using, like this:

You can read up more about this here.

PHP – Number of days in a current month [date(“t”)]

We often need to get start date and end date while executing database queries. Many of us waste time with complex and nested functions to achieve such simple solution.

PHP has a built-in function date(), and this function is very useful in figuring out date as well as selecting proper format. Many developers utilize the selectors such as ‘Y‘, ‘m‘, ‘d‘, ‘h‘, ‘i‘, ‘s‘ to get a generic datetime value but not everyone knows that there’s another selector, called ‘t‘.

The ‘t‘ inside date() function returns total number of days in a current month.

Example:

Very simple.

Zend Framework 2 – Create New Project From Scratch

I’ve noticed many users are still incapable of getting Zend Framework 2 going on there local machine. I’m going to run a very thorough explanation of how I got it working.

Information and tools used throughout this tutorial:
Zend Framework 2 online tutorial
Windows 7 (64 bit)
EasyPHP DevServer 13.1 (everything that comes with it)

Let’s begin.

Step 1: Download and install EasyPHP DevServer 13.1

(If you installed PHP and MySQL some other way then just follow the instructions and make sure all your settings are identical to get Zend Framework 2 working)

Step 2: Make sure your PHP variable is working correctly. To do so, open Terminal by clicking Start, type “cmd“, click on “cmd.exe“. Once the terminal is open, type “php -v” and press Enter. If setup correctly, you will see PHP version and some other information, if not you will get an error along the lines of “php is not a recognizable command …“.

If PHP variable is working correctly then skip directly to Step 3, otherwise read on.

(EasyPHP should setup this correctly on install, if you used something else to install PHP then perform the following procedures:
– Find and the copy your full path to php.exe, (ex. C:\Program Files (x86)\EasyPHP-DevServer-13.1VC9\binaries\php\php_runningversion)
– Open Environment variables settings (Right-click “Computer” icon, click Properties, then click “Advanced System Settings” on the left side panel, then click “Environment Variables” button at the very bottom.)
– In the bottom list, find PATH in the first column and click Edit button.
– Place the pointer to the beginning of the line and paste the previously copied full path to PHP.exe.
– Add a semi-colon “;” after the path)

Step 3: Download Zend Framework 2 skeleton application from here.

Step 4: Inside your working directory (where you keep all your PHP projects, ex. “www”) create a folder “zf2-tutorial” and unzip the contents of Zend Framework 2 downloaded file in there.

In my case (because I’m using EasyPHP), the local working directory is “C:\Program Files (x86)\EasyPHP-DevServer-13.1VC9\data\localweb\projects“, so I placed my “zf2-tutorial” folder inside the “projects” folder.

End path where “zf2-tutorial” is placed is: C:\Program Files (x86)\EasyPHP-DevServer-13.1VC9\data\localweb\projects\zf2-tutorial

Step 5: Now onto the fun stuff with Zend Framework 2. Open the Terminal again, type the following command to switch inside “zf2-tutorial” folder:

In your case, you place the path to your “zf2-tutorial” folder.

Step 6: Type the following command and press Enter:

Let the process complete.

Step 7: Type the following command and press Enter:

Let this process complete before you proceed. It may take a while. (I got an error here because EasyPHP comes with OpenSSL is disabled and I couldn’t proceed. If you did too, just open php.ini file and un-comment openssl extension.

Step 8: Now let’s add virtual hosts to httpd.conf file. Open httpd.conf file and find (commented out) example of Virtual Hosts setup. Now paste the following below the example but don’t comment it out like the examples:

The only 2 things you have to change is the path to your zf2-tutorial project. First is on the DocumentRoot line and second is inside the first Directory tag. If you are using EasyPHP then just replicate the path to the example I provided.

Step 9: Modify your hosts file. (You won’t be able to save your hosts’ file changes unless you open it in Notepad (or other editor) as Administrator).

Before:

After:

I kind of wish I had a step 10 but I don’t. Your Zend Framework 2 setup should be working flawlessly right now. Let me know if you have any questions and I’ll do my best to try and assist you in your setup.

Cheers.

Javascript – how to stop/terminate execution

When debugging I often find myself printing many values to the screen and ending script execution (in PHP) to verify that I got the right values. Well, since JavaScript loads last and you will get most of your page loaded, you can use the combination of console.log() function and throw statement.

The throw statement will intentionally throw an error or a specified statement, but most of all it will terminate your JavaScript code.

Quick and easy.

Git – how to discard unstaged/committed changes

If you’ve done some work on the project but still want to trash all the changes and start fresh, use the following commands back-to-back:

I used this command and it completes the task of my intentions.

Reference: How do you discard unstaged changes?