Magento – Registration on Success Page

checkoutmagento-1.8magento-1.9PHPregister

I want to add the possibility to ask the guest customer to create an account on the success page, after the order has been received in magento.

enter image description here

Update: I think this function name is Register after Checkout.

Best Answer

Judging by your screenshot, you are using custom theme. That’s why you need to localize this page (success page) first. Make sure that it has the call getChildHtml. If there is not such a call, then you should add it for the block that we gonna create. I’ve taken rwd theme as basis.

If you don’t have a module for customizations, then create it. In my case, this is Test_Module. There are plenty of articles in the web, where you could find how to create modules.

We need one new block Test_Module_Block_Checkout_Success_Register where we place the main logic that could be expanded later.

<?php
/**
 * Created by PhpStorm.
 * User: usr
 * Date: 6/2/16
 * Time: 10:12 AM
 */

class Test_Module_Block_Checkout_Success_Register extends Mage_Core_Block_Template
{

    /**
     * @var Mage_Sales_Model_Order|null
     */
    protected $order;

    public function __construct()
    {
        parent::__construct();
    }

    /**
     * @param Mage_Sales_Model_Order $order
     * @return Test_Module_Block_Checkout_Success_Register
     */
    public function setOrder(Mage_Sales_Model_Order $order)
    {
        $this->order = $order;
        return $this;
    }

    /**
     * @return Mage_Sales_Model_Order|null
     */
    public function getOrder()
    {
        return $this->order;
    }

    /**
     * Prepare customer data for the register form
     *
     * @return mixed|Varien_Object
     */
    public function updateFormData()
    {
        $data = $this->getData('form_data');
        if (is_null($data)) {

            /** @var array $formData */
            $formData = Mage::getSingleton('customer/session')->getCustomerFormData(true);

            $order = $this->getOrder();
            $customerData = [
                'email' => $order->getCustomerEmail(),
                'firstname' => $order->getCustomerFirstname(),
                'lastname' => $order->getCustomerLastname(),
                'city' => $order->getBillingAddress()->getCity(),
                'country' => $order->getBillingAddress()->getCountry(),
                'region_id' => $order->getBillingAddress()->getRegionId(),
            ];

            $data = new Varien_Object();
            if ($formData) {
                $data->addData($formData);
                $data->setCustomerData(1);
            }
            $data->addData($customerData);

            if (isset($data['region_id'])) {
                $data['region_id'] = (int)$data['region_id'];
            }

            $this->setData('form_data', $data);
        }

        return $data;
    }

    /**
     * Prepare block data:
     * > Get order id
     * > load order
     * > set data to the block
     *
     * @return $this
     */
    protected function _beforeToHtml()
    {
        parent::_beforeToHtml();

        /** @var Mage_Checkout_Block_Onepage_Success|null $successBlock */
        $successBlock = $this->getLayout()->getBlock('checkout.success');
        if (!$successBlock) {
            return $this;
        }

        /** @var string $orderId order Increment Id here (not the real id!) */
        $orderId = $successBlock->getOrderId();
        /** @var Mage_Sales_Model_Order $order */
        $order = Mage::getModel('sales/order')->loadByIncrementId($orderId);

        $guest = $order->getCustomerIsGuest();
        if (!$guest) {
            return $this;
        }

        $this->setOrder($order);
        $this->updateFormData();

        return $this;
    }
}

?>

In this block we are using method _beforeTOHtml where the check for block drawing is held and the order with all required customers’ information is loaded. If you are a perfectionist, you can separate this part for different methods, but the overall way is clear. We are receiving the order icrement_id from the parental block where it should be.

Note! If your theme is using another system of order receiving, simple replace it in the block with your own.

Then, we need a copy of customer/form/register.phtml template that we will edit to get the desired result. Copy the file to the templates folder of your module. In my case this is app/design/frontend/base/default/template/test/customer/form/register.phtml. Next, delete all the unnecessary information from the template, but leave all the input fields and widget calls. This is my template:

<?php echo $this->getChildHtml('form_fields_before') ?>
<?php echo $this->getChildHtml('customer.form.register.extra') ?>
<form action="<?php echo $this->getPostActionUrl() ?>" method="post" id="form-validate">
    <!--        Hide customer main data fields-->
    <div class="fieldset" hidden="hidden">
        <input type="hidden" name="success_url" value="<?php echo $this->getSuccessUrl() ?>"/>
        <input type="hidden" name="error_url" value="<?php echo $this->getErrorUrl() ?>"/>
        <ul class="form-list" hidden="hidden">
            <li class="fields">
                <?php echo $this->getLayout()->createBlock('customer/widget_name')->setObject($this->getFormData())->setForceUseCustomerAttributes(true)->toHtml() ?>
            </li>
            <li>
                <label for="email_address" class="required"><em>*</em><?php echo $this->__('Email Address') ?></label>

                <div class="input-box">
                    <input type="text" name="email" id="email_address"
                           value="<?php echo $this->escapeHtml($this->getFormData()->getEmail()) ?>"
                           title="<?php echo $this->__('Email Address') ?>"
                           class="input-text validate-email required-entry"/>
                </div>
            </li>
            <?php $_dob = $this->getLayout()->createBlock('customer/widget_dob') ?>
            <?php if ($_dob->isEnabled()): ?>
                <li><?php echo $_dob->setDate($this->getFormData()->getDob())->toHtml() ?></li>
            <?php endif ?>
            <?php $_taxvat = $this->getLayout()->createBlock('customer/widget_taxvat') ?>
            <?php if ($_taxvat->isEnabled()): ?>
                <li><?php echo $_taxvat->setTaxvat($this->getFormData()->getTaxvat())->toHtml() ?></li>
            <?php endif ?>
            <?php $_gender = $this->getLayout()->createBlock('customer/widget_gender') ?>
            <?php if ($_gender->isEnabled()): ?>
                <li><?php echo $_gender->setGender($this->getFormData()->getGender())->toHtml() ?></li>
            <?php endif ?>
        </ul>
    </div>
    <?php if ($this->getShowAddressFields()): ?>
        <!--        Hide address fields-->
        <div class="fieldset" hidden="hidden">
            <input type="hidden" name="create_address" value="1"/>

            <h2 class="legend"><?php echo $this->__('Address Information') ?></h2>
            <ul class="form-list">
                <li class="fields">
                    <div class="field">
                        <label for="company"><?php echo $this->__('Company') ?></label>

                        <div class="input-box">
                            <input type="text" name="company" id="company"
                                   value="<?php echo $this->escapeHtml($this->getFormData()->getCompany()) ?>"
                                   title="<?php echo $this->__('Company') ?>"
                                   class="input-text <?php echo $this->helper('customer/address')->getAttributeValidationClass('company') ?>"/>
                        </div>
                    </div>
                    <div class="field">
                        <label for="telephone" class="required"><em>*</em><?php echo $this->__('Telephone') ?></label>

                        <div class="input-box">
                            <input type="text" name="telephone" id="telephone"
                                   value="<?php echo $this->escapeHtml($this->getFormData()->getTelephone()) ?>"
                                   title="<?php echo $this->__('Telephone') ?>"
                                   class="input-text <?php echo $this->helper('customer/address')->getAttributeValidationClass('telephone') ?>"/>
                        </div>
                    </div>
                </li>
                <?php $_streetValidationClass = $this->helper('customer/address')->getAttributeValidationClass('street'); ?>
                <li class="wide">
                    <label for="street_1" class="required"><em>*</em><?php echo $this->__('Street Address') ?></label>

                    <div class="input-box">
                        <input type="text" name="street[]"
                               value="<?php echo $this->escapeHtml($this->getFormData()->getStreet(1)) ?>"
                               title="<?php echo $this->__('Street Address') ?>" id="street_1"
                               class="input-text <?php echo $_streetValidationClass ?>"/>
                    </div>
                </li>
                <?php $_streetValidationClass = trim(str_replace('required-entry', '', $_streetValidationClass)); ?>
                <?php for ($_i = 2, $_n = $this->helper('customer/address')->getStreetLines(); $_i <= $_n; $_i++): ?>
                    <li class="wide">
                        <div class="input-box">
                            <input type="text" name="street[]"
                                   value="<?php echo $this->escapeHtml($this->getFormData()->getStreet($_i)) ?>"
                                   title="<?php echo $this->__('Street Address %s', $_i) ?>"
                                   id="street_<?php echo $_i ?>"
                                   class="input-text <?php echo $_streetValidationClass ?>"/>
                        </div>
                    </li>
                <?php endfor; ?>
                <li class="fields">
                    <div class="field">
                        <label for="city" class="required"><em>*</em><?php echo $this->__('City') ?></label>

                        <div class="input-box">
                            <input type="text" name="city"
                                   value="<?php echo $this->escapeHtml($this->getFormData()->getCity()) ?>"
                                   title="<?php echo $this->__('City') ?>"
                                   class="input-text <?php echo $this->helper('customer/address')->getAttributeValidationClass('city') ?>"
                                   id="city"/>
                        </div>
                    </div>
                    <div class="field">
                        <label for="region_id" class="required"><em>*</em><?php echo $this->__('State/Province') ?>
                        </label>

                        <div class="input-box">
                            <select id="region_id" name="region_id" title="<?php echo $this->__('State/Province') ?>"
                                    class="validate-select" style="display:none;">
                                <option
                                    value=""><?php echo $this->__('Please select region, state or province') ?></option>
                            </select>
                            <script type="text/javascript">
                                //<![CDATA[
                                $('region_id').setAttribute('defaultValue', "<?php echo $this->getFormData()->getRegionId() ?>");
                                //]]>
                            </script>
                            <input type="text" id="region" name="region"
                                   value="<?php echo $this->escapeHtml($this->getRegion()) ?>"
                                   title="<?php echo $this->__('State/Province') ?>"
                                   class="input-text <?php echo $this->helper('customer/address')->getAttributeValidationClass('region') ?>"
                                   style="display:none;"/>
                        </div>
                    </div>
                </li>
                <li class="fields">
                    <div class="field">
                        <label for="zip" class="required"><em>*</em><?php echo $this->__('Zip/Postal Code') ?></label>

                        <div class="input-box">
                            <input type="text" name="postcode"
                                   value="<?php echo $this->escapeHtml($this->getFormData()->getPostcode()) ?>"
                                   title="<?php echo $this->__('Zip/Postal Code') ?>" id="zip"
                                   class="input-text validate-zip-international <?php echo $this->helper('customer/address')->getAttributeValidationClass('postcode') ?>"/>
                        </div>
                    </div>
                    <div class="field">
                        <label for="country" class="required"><em>*</em><?php echo $this->__('Country') ?></label>

                        <div class="input-box">
                            <?php echo $this->getCountryHtmlSelect() ?>
                        </div>
                    </div>
                </li>
            </ul>
            <input type="hidden" name="default_billing" value="1"/>
            <input type="hidden" name="default_shipping" value="1"/>
        </div>
    <?php endif; ?>
    <div class="fieldset">
        <h2 class="legend"><?php echo $this->__('Save Your Information For Next Time!') ?></h2>
        <ul class="form-list">
            <li class="fields">
                <div class="field">
                    <label for="password" class="required"><em>*</em><?php echo $this->__('Password') ?></label>

                    <div class="input-box">
                        <input type="password" name="password" id="password" title="<?php echo $this->__('Password') ?>"
                               class="input-text required-entry validate-password"/>
                    </div>
                </div>
                <div class="field">
                    <label for="confirmation" class="required"><em>*</em><?php echo $this->__('Confirm Password') ?>
                    </label>

                    <div class="input-box">
                        <input type="password" name="confirmation" title="<?php echo $this->__('Confirm Password') ?>"
                               id="confirmation" class="input-text required-entry validate-cpassword"/>
                    </div>
                </div>
            </li>
            <?php echo $this->getChildHtml('form.additional.info'); ?>
            <?php if ($this->isNewsletterEnabled()): ?>
                <li class="control">
                    <div class="input-box">
                        <input type="checkbox" name="is_subscribed"
                               title="<?php echo $this->__('Sign Up for Newsletter') ?>" value="1"
                               id="is_subscribed"<?php if ($this->getFormData()->getIsSubscribed()): ?> checked="checked"<?php endif; ?>
                               class="checkbox"/>
                    </div>
                    <label for="is_subscribed"><?php echo $this->__('Sign Up for Newsletter') ?></label>
                    <?php /* Extensions placeholder */ ?>
                    <?php echo $this->getChildHtml('customer.form.register.newsletter') ?>
                </li>
            <?php endif ?>
        </ul>
    </div>
    <div class="buttons-set">
        <p class="required"><?php echo $this->__('* Required Fields') ?></p>
        <button type="submit" title="<?php echo $this->__('Register') ?>" class="button">
            <span><span><?php echo $this->__('Register') ?></span></span></button>
    </div>
</form>
<script type="text/javascript">
    //<![CDATA[
    var dataForm = new VarienForm('form-validate', true);
    <?php if($this->getShowAddressFields()): ?>
    new RegionUpdater('country', 'region', 'region_id', <?php echo $this->helper('directory')->getRegionJson() ?>, undefined, 'zip');
    <?php endif; ?>
    //]]>
</script>

For the fieldsets that shouldn’t be displayed, but will be filled from the block by default, we should set the attribute hidden="hidden". If you delete them completely, the registration won’t be able to complete. Only the fieldset with a password and field with subscription stay visible.

Thus, we are using standard registration block for this form, then we need one intermediate template for our block, where this standard block with our template app/design/frontend/base/default/template/test/checkout/register.phtml will be called.

<?php
if (!$this->getOrder()) {
    return;
}
$this->getChild('customer_form_register')->setData('form_data', $this->getData('form_data'));
echo $this->getChildHtml('customer_form_register');
?>

Finally, we need a layout, where we mark all changes in app/design/frontend/base/default/layout/test.xml:

<?xml version="1.0"?>
<layout version="0.1.0">
    <checkout_onepage_success>
        <reference name="content">
            <block type="test/checkout_success_register" name="checkout.success.register.form" template="test/checkout/register.phtml">
                <block type="customer/form_register" name="customer_form_register" template="test/customer/form/register.phtml">
                    <block type="page/html_wrapper" name="customer.form.register.fields.before" as="form_fields_before" translate="label">
                        <label>Form Fields Before</label>
                    </block>
                </block>
            </block>
        </reference>
    </checkout_onepage_success>
</layout>

The result in the rwd theme should be the following:

enter image description here

All hidden fields are here with the values from the order:

enter image description here

Registration completed successfully:

enter image description here

Pay attention, that this is only a model, that you should customize to suit your theme and correct according to the desired result.

I hope this information will be useful. If you have any question – feel free to ask them.