Magento. We are writing our module. Add CAPTCHA and additional fields to the registration

    I want to share my experience in programming modules for Magento. Many thanks to jeje for inviting me .
    The article describes in detail the creation of a module that implements additional functions of customer registration. Objectives - to give an idea of ​​development for Magento using a specific example from beginning to end, show the main approaches, the organization of the code, and point out some features. The article is aimed more at beginners, but those familiar with Magento can make something useful for themselves. Of course, it is impossible to describe everything in one article, but if the topic is in demand, this may be the beginning of a series of articles.
    The following points are mentioned:
    • module creation
    • work with blocks, templates and layouts (layout)
    • controller override
    • module installation scripts

    As a result, we will receive registration with a CAPTCHA check, a group selection field and saving the invitation code.



    Registration Page

    What are you thinking


    There is a registration page / magento / customer / account / create. We want to add a CAPTCHA check, as well as ask clients for a group and invitation code. Received data is stored in the database. By default, Magento defines three customer groups, General, Wholesale, and Retailer. Of these, we will offer to choose a future client. Magento knows nothing about the invitation code - we’ll create a new attribute.

    I want to note that this is not a ready-made solution , but just an example drawn up for ease of presentation.

    Search


    We are looking for where the template files are, where and how the registration data is stored.
    1. Customer Registration Form Templates
      /magento/app/design/frontend/default/default/template/customer/form/register.phtml- Registration Form
    2. Attributes are added to the module installer, for example: the
      /magento/app/code/core/Mage/Customer/sql/customer_setup/mysql4-upgrade-0.8.7-0.8.8.php
      details will be lower when we write the installer for our module.
    3. We find a description of mutable fields (attributes) in the module configuration:
      /magento/app/code/core/Mage/Customer/etc/config.xml
      inside tags
    4. The registration form post data to the address:
      http://localhost/magento/customer/account/createpost/

      Accordingly, the request is processed by the controller Mage_ Customer _ Account Controller method createPost Action (line # 234)


    Implementation


    We do not consider the option of changing the found files. Create your own theme and your module.
    The theme is simple:
    1. create a new folder in / magento / app / design / frontend / default / mytheme
      default - interface name
      mytheme - name of our theme
    2. copy files while maintaining the directory structure to a new topic
    3. edit / create templates as you wish

    Templates of the same name overlap the templates of the standard theme. Thus, we do not make changes to the "native" Magento files.

    With the module a little more interesting:
    We create a new module - CustomerMod . The folder structure of all modules is the same:
    magento / app / code / local /
    	Examples
    		CustomerMod
    			- Block
    			- etc
    			- Helper
    			- Model
    			- sql
    


    do not forget to add a file with a description of our modules:
    magento / app / etc / modules / Examples_All.xml
    truelocal


    Fields on the registration page


    Let's start by adding a group selection field to the registration page (“General”, “Wholesale”, “Retailer”). Magento uses blocks and templates to display information. A block can be called a template renderer. Each page consists of blocks, a template is specified for each block.
    We will add our block with our template inside the block of the registration form. In other words, our block will be a child of the form block.

    1. Actually a new template


    Group selection template in a separate file:
    /magento/app/design/frontend/default/example_theme/template/customer/form/register/groupselect.phtml

    with simple content:

    getGroups () -> toOptionArray (); ?>
    

    __ ('Customer Group')?>

    • />


    Note the name of the field "group_id" should match the name of the attribute.

    2. Adjustment of layout


    The mutual arrangement of blocks and binding to templates are described in layout. These are the xml files that are in the folder magento/app/design/ИМЯ_ИНТЕРФЕЙСА/ИМЯ_ТЕМЫ/layout.

    In our case it will be:
    /magento/app/design/frontend/default/example_theme/layout/customermod.xml


    We refer to the block customer_form_register. We describe our child block inside it:
    type is the class of the block that ultimately renders the template. In this case, “core / template”, which means Mage_Core_Block_Template.
    name - the name can be anything. It is necessary to refer to the block, for example in reference.
    template - block template
    Do not forget to specify layout updates in the module’s configs so that Magento takes into account the changes indicated in customermod.xml:

    /magento/app/code/local/Examples/CustomerMod/etc/config.xml
    customermod.xml


    3. Block output by the parent block.


    Our block is not yet visible, because we must “call” the child block in the parent using the getChildHtml (BLOCK_NAME) method.
    Copy register.phtmlto our theme from the default theme and add the necessary call before the Login Information section :

    /magento/app/design/frontend/default/example_theme/template/customer/form/register.phtml
    ...
     getChildHtml ('customergroups-select')?>
     

    __ ('Login Information')?>

    ...


    4. Saving data


    Now in the registration form the group selection should appear.
    “But wait, the buyer is registered, indicating“ Retailer ”- and in the admin panel he is still in the General group!” - yes, the field is group_idnot saved.
    To save the entered fields, you need to specify them in the fieldsets in the configuration:

    /magento/app/code/local/Examples/CustomerMod/etc/config.xml
    11


    Why - ask Magento developers - but this is how the Customer controller is designed. Who cares - see the /magento/app/code/core/Mage/Customer/controllers/AccountController.phpmethodcreatePostAction.

    New attribute


    Attributes are described in the eav_attributes table ; accordingly, working with attributes is reduced to editing the entries in the eav_attributes table .
    There are also static attributes whose values ​​are stored in separate columns (for example sales_order).

    1. Installation scripts


    All actions to modify the model are performed in installation scripts stored in the sql folder inside each module.
    /magento/app/code/core/Mage/Customer/sql/customer_setup
    Scripts come in two forms - setup and upgrade . Magento runs the appropriate script once when installing or updating a module. After installation , an entry appears in the core_resource table , for example:
    'customermod_setup', '0.1.0'

    In other words, scripts are run for two reasons:
    1. lack of module entry in core_resource table
    2. the version of the module specified in core_resource is lower than in the config.xml of the module


    It is worth noting that the uninstallation mechanism is not provided . You will have to delete the created attributes with your hands if something happens.

    Scripts are executed by the installer. By default, the installer class Mage_Core_Model_Resource_Setup, but it does not contain methods for working with the EAV model (and we are going to create attributes), so in our case we need it Mage_Eav_Model_Entity_Setup.

    setup class hierarchy

    2. Attribute creation script


    Examples of installation scripts can be found in standard modules. Sometimes there is just a run of SQL commands. But it is advisable to use the methods of the installer classes to the maximum, and SQL commands should be resorted to last.

    $ installer = $ this;
    / * @var $ installer Mage_Customer_Model_Entity_Setup * /
    $ installer-> startSetup ();
    $ installer-> addAttribute ('customer', 'invitation_code', array (
    	'type' => 'varchar',
    	'input' => 'text',
    	'label' => 'Invitation Code',
    	'global' => 1,
    	'visible' => 1,
    	'required' => 1,
    	'user_defined' => 1,
    	'default' => null,
    	'visible_on_front' => 1
    ));
    $ installer-> endSetup ();
    

    I think after so many prefaces, comments on the script itself are not required.

    3. Updating the template


    Add a new field to the registration form template:

    /magento/app/design/frontend/default/example_theme/template/customer/form/register.phtml



    4. Updating the configuration


    Add a description of the installation script:
    /magento/app/code/local/Examples/CustomerMod/etc/config.xml
    Examples_CustomerModMage_Eav_Model_Entity_Setupcore_setupcore_writecore_read

    And do not forget to specify a new field in fieldsets
    1111

    Now in the registration form there is an Invitation Code field , the value of which is stored in the attribute invitation_codefor each client. Also, a new field appeared in the admin panel on the client account page in the Account Information tab .

    Admin Customer Account Screenshot

    Captcha



    To implement a captcha, take reCAPTCHA . Further, there may be many ways: include the functionality of the captcha in the existing module, make it separate, you can generally push everything into the template and edit the standard controller.

    In my opinion it is better to issue in a separate module. The steps to create a new module, a separate template, modify layout (layout) are the same as described above. Let us dwell on what has not yet been affected: the controller and the helper.
    Values ​​from the registration form are transferred to the controller Mage_Customer_AccountController. Magento provides a mechanism for redefining the controllers (the mechanism has changed somewhat since version 1.3 ). Instead of changes in the standard controller, create a new one inherited from the standard.

    So in order.

    Download the recaptcha-php library and copy it to the / magento / lib folder.

    1. Controller



    In the configuration of the CustomerMod module, we describe the controller:
    
        ...
        
        ...
         Examples_CustomerMod
        ...
    


    Actually the controller itself.
    /magento/app/code/local/Examples/CustomerMod/controllers/AccountController.php
    require_once ("Mage / Customer / controllers / AccountController.php");
    require_once ('recaptcha / recaptchalib.php');
    class Examples_CustomerMod_AccountController extends Mage_Customer_AccountController {
    	public function createPostAction () {		
    		$ request = $ this-> getRequest ();		
    		$ captchaIsValid = Mage :: helper ('captcha') -> captchaIsValid ($ request);
    		if ($ captchaIsValid) {
    			parent :: createPostAction ();
    		} else {
    			$ this -> _ getSession () -> setCustomerFormData ($ this-> getRequest () -> getPost ());
    			$ this -> _ getSession () -> addError ($ this -> __ ('Verification code was not correct. Please try again.'));
    			$ this -> _ redirectError (Mage :: getUrl ('* / * / create', array ('_ secure' => true)));
    		}
    	}
    }
    


    Unlike all other classes defined in Magento, for controllers, you must explicitly point to a file containing the parent class and third-party libraries, and therefore require two require_once. The code is minimal, we use the standard function from recaptchalib. But the verification of the entered captcha itself is made in a separate helper class. If you need to add the same check to other controllers, then it all comes down to checking the result. Mage::helper('captcha')->captchaIsValid($request).
    Here you can also add, for example, the authenticity of the invitation code.

    2. Helper


    The helper in Magento is a singleton class, which usually contains a set of helper methods. The helper is accessed using the method Mage::helper()with the module name as a parameter. In our case, it Examples_Captcha_Helper_Datawill contain captcha verification functions.

    /magento/app/code/local/Examples/Captcha/Helper/Data.php
    require_once ('recaptcha / recaptchalib.php');
    class Examples_Captcha_Helper_Data extends Mage_Core_Helper_Abstract
    {	
    	const CAPTCHA_PUBLIC_KEY = "public-key-for-the-website";
    	const CAPTCHA_PRIVATE_KEY = "private-key-for-the-website";
    	public function captchaIsValid (Mage_Core_Controller_Request_Http $ request) {	
    		if ($ request) {
    			$ resp = recaptcha_check_answer (self :: CAPTCHA_PRIVATE_KEY,
    		                           $ _SERVER ["REMOTE_ADDR"],
    		                           $request->getParam("recaptcha_challenge_field"),
    		                           $request->getParam("recaptcha_response_field") );		
    			return $resp->is_valid;
    		} 
    		return false;						
    	}
    	public function captchaGetError(Mage_Core_Controller_Request_Http $request) {
    		if ($request) {
    			$resp = recaptcha_check_answer (self::CAPTCHA_PRIVATE_KEY,
    			                           $_SERVER["REMOTE_ADDR"],
    			                           $request->getParam("recaptcha_challenge_field"),
    			                           $request->getParam("recaptcha_response_field") );
    			return $resp->error;
    		}
    		return false;
    	}
    	public function getPublicKey() { return  Examples_Captcha_Helper_Data::CAPTCHA_PUBLIC_KEY; }
    }
    


    3. Блок CAPTCHA


    It would be nice to display a picture of the captcha itself on the page. There is a function for this recaptcha_get_html (). Despite the fact that the function can be called from the template (phtml), we will follow the ideas and architecture of Magento - we will create a new type of block, and at the same time we will learn how the block can be without a template. To do this, we describe the class Examples_Captcha_Block_Recaptcha. We call the function call recaptcha_get_html()in the method _toHtml. This method is called when rendering a block in HTML. (see /magento/app/code/core/Mage/Core/Block/Abstract.phpline # 643 )

    /magento/app/code/local/Examples/Captcha/Block/Recaptcha.php
    require_once ('recaptcha / recaptchalib.php');
    class Examples_Captcha_Block_Recaptcha extends Mage_Core_Block_Abstract {		
    	public function _toHtml () {
    		$ html = recaptcha_get_html (Mage :: helper ('captcha') -> getPublicKey ());
    		return $ html;
    	}
    }
    


    Add a new block to the layout. A template for this block is not needed, it already displays the finished captcha.

    /magento/app/design/frontend/default/example_theme/layout/customermod.xml


    4. Configuration


    It remains only to indicate in the configuration of the Captcha module that it contains a block and a helper

    /magento/app/code/local/Examples/Captcha/etc/config.xml
    0.1.0Examples_Captcha_BlockExamples_Captcha_Helper


    And the captcha is ready.

    CAPTCHA screenshot

    Conclusion



    Thanks to the read to the end! I hope it was interesting or at least useful :). You can download a ready-made example . Magento version 1.3.2.4 was used to write the article.
    If the topic discussed is interesting on the hub, then I will gladly listen to the wishes on the new article.
    There are ideas and some materials for articles on the topic:
    • Review of Magento Gingerbread Cookies and Rakes
    • Events and listeners in Magento by the example of adding an email notification.
    • Debugging in Magento (about the test page, about Firebug, about Mage :: log)
    • Models in Magento. Add your entities and attributes.
    • How I added blocks to Magento email templates
    • PDF in Magento. Bitter truth
    • Working with collections in Magento using the example of creating a report
    • selecting / configuring an IDE for development in Magento


    Also popular now: