Em minhas aventuras pelo Magento tive que adicionar novos campos para o cadastro do usuário. O que pode parecer simples e rápido pode se tornar uma verdadeira Odisséia.
Nesse tutorial eu vou mostrar como eu fiz isso. Criei novos campos para o cadastro de usuário que funcionam tanto no formulário de cadastro padrão como no formulário do checkout. E isso vale tanto para atribulos do customer como para o endereço também.
Pra começar, a melhor maneira é você criar um módulo para criar suas customizações no Magento, com el evocê pode fazer sobrescrita nos controllers dos módulos do core e adicionar outras configurações na árvore do XML. Então, criei a estrutura padrão para um módulo local que chamei de Custom.

A primeira coisa que iremos fazer nem vamos utilizar ainda nosso módulo, ele nos servirá mais para adicionarmos as configurações dos campos em nossa árvore XML. Vamos criar os campos extras em nosso banco de dados.

A melhor maneira de fazer isso é pela própria API do Magento, que te fornece os métodos necessários para criar esses campos no esquema de EAV do banco. Vejam o código para criar um atributo no Customer:

$setup = Mage::getModel('customer/entity_setup', 'core_setup');
$setup->addAttribute('customer', 'cpf', array(
'type' => 'varchar',
'input' => 'text',
'label' => 'Número do CPF',
'global' => 1,
'visible' => 1,
'required' => 1,
'user_defined' => 1,
'default'        => '0',
'visible_on_front' => 1,
));
if (version_compare(Mage::getVersion(), '1.6.0', '<='))
{
$customer = Mage::getModel('customer/customer');
$attrSetId = $customer->getResource()->getEntityType()->getDefaultAttributeSetId();
$setup->addAttributeToSet('customer', $attrSetId, 'General', 'cpf');
}
if (version_compare(Mage::getVersion(), '1.4.2', '>='))
{
Mage::getSingleton('eav/config')
->getAttribute('customer', 'cpf')
->setData('used_in_forms', array('adminhtml_customer','customer_account_create','customer_account_edit','checkout_register'))
->save();
}
die("se não houver erros acima o atributo foi criado");

Caso você queira adicionar um atributo de endereço do usuário esse mesmo código, com algumas modificações, funciona. Fica ssim:

$setup = Mage::getModel('customer/entity_setup', 'core_setup');
$setup->addAttribute('customer_address', 'ponto_referencia', array(
'type' => 'varchar',
'input' => 'text',
'label' => 'Ponto de Referência',
'global' => 1,
'visible' => 1,
'required' => 0,
'user_defined' => 1,
//'default'        => '0',
'visible_on_front' => 1,
));
if (version_compare(Mage::getVersion(), '1.6.0', '<='))
{
$customer = Mage::getModel('customer/address');
$attrSetId = $customer->getResource()->getEntityType()->getDefaultAttributeSetId();
$setup->addAttributeToSet('customer_address', $attrSetId, 'Address', 'ponto_referencia');
}
if (version_compare(Mage::getVersion(), '1.4.2', '>='))
{
Mage::getSingleton('eav/config')
->getAttribute('customer_address', 'ponto_referencia')
->setData('used_in_forms', array('customer_register_address','customer_address_edit','adminhtml_customer_address'))
->save();
}
die("se não houver erros acima o atributo foi criado");

Esse código deve ser colocado em qualquer arquivo .phtml e ser executado apenas uma vez para criar sem problemas seus novos atributos.

Agora basta adicionar o field no arquivo .phtml que gera o formulário, no meu caso (utilizando a versão 1.7.0.2) esse arquivo encontra-se em app/design/frontend/base/default/template/customer/form/register.phtml

Eu copiei esse template da pasta /base/default e coloquei em default/default, para caso aconteça alguma atualização de template eu não perca essas modificações. Basta adicionar o campo extra no formulário para testar:

<li>
<?php
$cpf = Mage::getModel('eav/config')->getAttribute('customer','cpf');
?>
<div>
<label for="cpf"><em>*</em><?php echo $this->__('CPF') ?></label><br/>
<input type="text" name="cpf" id="cpf" value="<?php echo $this->htmlEscape($this->getFormData()->getCpf()) ?>" title="<?php echo $this->__('CPF') ?>" />
</div>
</li>

Com isso já temos nosso campo extra quase funcionando, pelo ao menos no cadastro. O problema é que se adicionarmos esse campos no formulário que temos durante o processo de checkout (app/design/frontend/base/default/template/checkout/onepage/billing.phtml) esse campo não vai funcionar. Isso porque os dados que fornecemos na fase de compra não é necessariamente dados destinados a criação de um usuário e sim de uma ordem de compra.

Vai ser meio complicado explicar detalhadamente aqui, mas o fato é que precisamos informar ao Magento quais campos do formulário irão se transformar em dados de um usuário, e isso se faz através dos abençoados XMLs de configuração e é pra isso que o módulo Custom funciona. Vou colocar aqui abaixo o XML que utilizo em meu módulo e você poderá modificá-lo de forma que ele atenda sua necessidade:

<config>
<modules>
<Mamura_Custom>
<version>1.2.0.1</version>
</Mamura_Custom>
</modules>
[...]
<global>
<fieldsets>
<checkout_onepage_quote>
<customer_cpf>
<to_customer>cpf</to_customer>
</customer_cpf>
</checkout_onepage_quote>
<sales_convert_quote_address>
<ponto_referencia>
<to_order_address>*</to_order_address>
<to_customer_address>*</to_customer_address>
</ponto_referencia>
</sales_convert_quote_address>
<customer_account>
<cpf>
<to_quote>customer_cpf</to_quote>
</cpf>
</customer_account>
<customer_address>
<ponto_referencia>
<to_quote_address>*</to_quote_address>
</ponto_referencia>
</customer_address>
</fieldsets>
</global>
<global>
<fieldsets>
<customer_account>
<cpf><create>1</create><update>1</update><name>1</name></cpf>
</customer_account>
</fieldsets>
</global>
</config>

Pronto, basta adicionar isso no XML de seu módulo, veja que eu ignorei aqui as tags do models, block, resources, etc, etc. Estou partindo do pré-suposto que quem está lendo esse artigo já sabe criar um módulo no Magento.

Além disso, temos que criar nas tabelas de compras os campos extras que criamos para que esses dados sejam salvos ali também, antes de se transformarem em dados de usuário. Para campos do usuário (Customer), adicionamos uma coluna na tabela sales_flat_quote com o prefixo customer_ antes do nome do seu campo:

<code>
ALTER TABLE `sales_flat_quote` ADD `customer_cpf` INT NOT NULL</code><code>

Para campos de endereço temos que adicionar nas tabelas sales_flat_quote_address e sales_flat_order_address:

ALTER TABLE  `sales_flat_quote_address` ADD  `ponto_referencia` varchar(255) NOT NULL
ALTER TABLE  `sales_flat_order_address` ADD  `ponto_referencia` varchar(255) NOT NULL

Qualquer coisa eu disponibilizei o código que uso no github, dá uma olhada lá: https://github.com/mamura/Magura.git