2

Been banging my head on this for 8 hours now...

I have a need (or rather, my company does, being a B2B) to request extra attributes at customer registration. Of course Magento doesn't do this natively, so we're forced down wildly convoluted build path to make it so. I bought a module to do this, but found the code to be a hot mess (not to mention simply not working).

Whatever. I guess I'll just roll my own.

So I found a tutorial that seemed clear and to the point. So I, spends a few minutes putting it together. And.... nothing.

Further google-fu leads me here and here for that extra hot wisdom sauce.


Here's what I've got (running Magento Professional v1.11 ):

File structure:

    WACI
    - Customer
    -- etc
    --- config.xml
    -- Model
    --- Resource
    ---- Eav
    ----- Mysql4
    ------ Setup.php
    -- sql
    --- customer_setup
    ---- mysql4-install-0.1.0.php

etc/modules/WACI_All.xml

<config>
    <modules>
        <WACI_Customer>
            <active>true</active>
            <codePool>local</codePool>
        </WACI_Customer>
    </modules>
</config>



config.xml

<config>

    <modules>
        <WACI_Customer>
            <version>0.1.0</version>
        </WACI_Customer>
    </modules>

    <global>

        <fieldsets>
            <customer_account>
                <title><create>1</create><update>1</update></title>
                <phone><create>1</create><update>1</update></phone>
                <agency><create>1</create><update>1</update></agency>
                <fed_id><create>1</create><update>1</update></fed_id>
                <ubi><create>1</create><update>1</update></ubi>
            </customer_account>
        </fieldsets>

        <!--<models>
            <customer>
                <class>WACI_Customer_Model</class>
            </customer>
        </models> -->

        <resources>
            <customer_setup>
                <setup>
                    <module>WACI_Customer</module>
                    <class>WACI_Customer_Model_Resource_Eav_Mysql4_Setup</class>
                </setup>
                <connection>
                    <use>core_setup</use>
                </connection>
            </customer_setup>
            <customer_write>
                <connection>
                    <use>core_write</use>
                </connection>
            </customer_write>
            <customer_read>
                <connection>
                    <use>core_read</use>
                </connection>
            </customer_read>
        </resources>

    </global>
</config>



Setup.php

<?php

    class WACI_Customer_Model_Resource_Eav_Mysql4_Setup extends Mage_Eav_Model_Entity_Setup
    {
        public function getDefaultEntities()
        {
            return array(
                    'customer' => array(
                        'entity_model'          => 'customer/customer',
                        'table'                 => 'customer/entity',
                        'increment_model'       => 'eav/entity_increment_numeric',
                        'increment_per_store'   => false,
                        'attribute_model'       => 'customer/attribute', 
                        'attributes' => array(
                            'title' => array(
                                'type'          => 'varchar',
                                'input'         => 'text',
                                'label'         => 'Title / Position',
                                'visible'       => true,
                                'required'      => false,
                                'position'      => 63,
                            ),
                            'phone' => array(
                                'type'          => 'varchar',
                                'input'         => 'text',
                                'label'         => 'Telephone',
                                'visible'       => true,
                                'required'      => true,
                                'position'      => 64,
                            ),
                            'agency' => array(
                                'type'          => 'varchar',
                                'input'         => 'text',
                                'label'         => 'Agency / Organization',
                                'visible'       => true,
                                'required'      => false,
                                'position'      => 65,
                            ),
                            'fed_id' => array(
                                'type'          => 'varchar',
                                'input'         => 'text',
                                'label'         => 'Fed ID',
                                'visible'       => true,
                                'required'      => false,
                                'position'      => 66,
                            ),
                            'ubi' => array(
                                'type'          => 'varchar',
                                'input'         => 'text',
                                'label'         => 'UBI',
                                'visible'       => true,
                                'required'      => false,
                                'position'      => 67,
                            ),
                        ),
                    ),
                );
        }
    }

    ?>



mysql4-install-0.1.0.php

<?php

Mage::log('Installing WACI_Customer');

// die ( echo 'Running This Upgrade: '.get_class($this)."\n <br /> \n";   );

$installer = $this;
$installer->installEntities();

$eavConfig          = Mage::getSingleton(‘eav/config’);
$attribute_title    = $eavConfig->getAttribute(‘customer’, 'title');
$attribute_phone    = $eavConfig->getAttribute(‘customer’, 'phone');
$attribute_agency   = $eavConfig->getAttribute(‘customer’, 'agency');
$attribute_fedid    = $eavConfig->getAttribute(‘customer’, 'fed_id');
$attribute_ubi      = $eavConfig->getAttribute(‘customer’, 'ubi');

// put into customer_form_attribute table so field will show in admin.
$attribute_title->setData(‘used_in_forms’, array(‘adminhtml_customer’));
$attribute_phone->setData(‘used_in_forms’, array(‘adminhtml_customer’));
$attribute_agency->setData(‘used_in_forms’, array(‘adminhtml_customer’));
$attribute_fedid->setData(‘used_in_forms’, array(‘adminhtml_customer’));
$attribute_ubi->setData(‘used_in_forms’, array(‘adminhtml_customer’));

?>

Assuming I understand it correctly, I have everything in place... but nothing, nothing and more nothing.

notably:

  • If I remove the setup class, I get a fatal error, so I think everything is in place.
  • the module shows up in admin/system/configuration/advanced/ (enabled); it is written to core_config_data
  • I ripped out all code and just used empty containers (with debug stuff) - the install script never runs; it never gets written to core_resource

Question, then is two part:

1. What is preventing my install script from running?
2. Is the logic for creating new customer attributes sound?

Assuming it is - i think getting it onto the registration page / customer account / admin account should be fairly straightforward...




... Gonna go drink beer now.

Cheers.




update


as @AlexeiYerofeyev thought, the customer name itself was the issue. Changed to CustomerAttr, and the script ran immediately.

The module then functioned about as expected, but @benmarks's solution seems cleaner, so I rewrote to match:

config.xml 0.1.0

    <global>
        <resources>
            <customerattr_setup>
                <setup>
                    <module>WACI_CustomerAttr</module>
                    <class>Mage_Customer_Model_Entity_Setup</class>
                </setup>
                <connection>
                    <use>core_setup</use>
                </connection>
            </customerattr_setup>
        </resources>
        <fieldsets>
            <customer_account>
                <title><create>1</create><update>1</update></title>
                <phone><create>1</create><update>1</update></phone>
                <agency><create>1</create><update>1</update></agency>
                <fed_id><create>1</create><update>1</update></fed_id>
                <ubi><create>1</create><update>1</update></ubi>
            </customer_account>
        </fieldsets>
    </global>
</config>

setup.php

<?php


    Mage::log('Installing WACI_CustomerAttr');

    echo 'Running Upgrade: '.get_class($this)."\n <br /> \n"; 

    //die ( 'its running' );


    $installer = $this;
    /* @var $installer Mage_Customer_Model_Entity_Setup */

    $installer->startSetup();


    $installer->addAttribute('customer','agency',
                array(
                    'type'          => 'varchar',
                    'label'         => 'Agency / Organization',
                    'input'         => 'text',
                    'required'      => false,
                    'visible'       => true,
                    'position'      => 62,
                )
            );

    $installer->addAttribute('customer','title',
                array(
                    'type'          => 'varchar',
                    'label'         => 'Title / Position',
                    'input'         => 'text',
                    'required'      => false,
                    'visible'       => true,
                    'position'      => 63,
                )
            );

    $installer->addAttribute('customer','phone',
                array(
                    'type'          => 'varchar',
                    'label'         => 'Telephone',
                    'input'         => 'text',
                    'required'      => false,
                    'visible'       => true,
                    'position'      => 64,
                )
            );


    $installer->addAttribute('customer','fed_id',
                array(
                    'type'          => 'varchar',
                    'label'         => 'Fed ID',
                    'input'         => 'text',
                    'required'      => false,
                    'visible'       => true,
                    'position'      => 65,
                )
            );


    $installer->addAttribute('customer','ubi',
                array(
                    'type'          => 'varchar',
                    'label'         => 'UBI',
                    'input'         => 'text',
                    'required'      => false,
                    'visible'       => true,
                    'position'      => 66,
                )
            );


    $attrs = array('agency','title','phone','fed_id','ubi');

    foreach ($attrs as $item) {
        $attr = Mage::getSingleton('eav/config')->getAttribute('customer', $item);
        $attr->setIsUsedInForms(array('adminhtml_customer','customer_account_edit','customer_account_create'))->save();
    }

    $installer->endSetup();

    ?>

The module (and version) gets successfully written to core_resource, and attributes are successfully getting added to eav_attribute.

I can call the field up in

theme/template/customer/form/edit.phtml

<div class="input-box">
    <label for="agency"><?php echo $this->__('Agency / Organization') ?><span class="required">*</span></label><br />
    <input type="text" name="agency" id="agency" value="<?php echo $this->htmlEscape($this->getCustomer()->getAgency()) ?>" title="<?php echo $this->__('Agency') ?>" class="required-entry input-text" />
</div>

But, unfortunately, the value is not getting written to customer_entity_varchar (which was, ultimately, what my initial script did as well.

So, I've got the attribute in the table, but its not getting added to the customer entity as of yet.

Seems like once I have that working, I should be able to read and write that value at will, wherever required.

Any thoughts on how I might proceed at this point?




final update


ok, got this worked out:
$attr->setData('used_in_forms', array('adminhtml_customer','customer_account_edit','customer_account_create'))->save();

instead of

$attr->setIsUsedInForms(array('adminhtml_customer','customer_account_edit','customer_account_create'))->save();

For anyone who may need the info...

Turns out the array was not getting updated in the customer_form_attribute table with the prior code.




Community
  • 1
  • 1
Bosworth99
  • 4,206
  • 5
  • 37
  • 52
  • 4
    Info on debugging a setup resource script is here: http://stackoverflow.com/questions/4717535/my-magento-extension-install-script-will-not-run – Alana Storm Aug 29 '12 at 00:16
  • thanks alan - I definitely looked through that, but hadn't attempted it. BTW - when I went to make the changes you detail out, the class has apparently been rewritten, and it was no longer clear where your debugs were to be placed. I didn't spend the time to figure it out - but thought you'd like to know. (maybe the difference between community / pro / enterprise? ). – Bosworth99 Aug 29 '12 at 17:06
  • You ebook on layout was a godsend, btw. – Bosworth99 Aug 29 '12 at 17:06
  • 1
    Thanks for the heads up, it looks like that code's been re-factored in the year and half since I originally posted it. The _modifyResourceDb method is still the one you want. Dumping out the $files variable as well as the $fileName inside the "case 'php':" block would be useful. (Also, be careful using the term "rewritten" when talking about Magento. It's got a very specific meaning and might confuse people) – Alana Storm Aug 29 '12 at 18:26

3 Answers3

4

There is a chance that your install script doesn't run because of its setup resource name (customer_setup). Since core extension Mage_Customer has the same name of setup resource and it is already installed in core_resource table with version 1.6.2.0 or something like that, your install script with version 0.1.0 may be considered as too old and is being ignored. So you can try renaming your resource to something unique.

Alexei Yerofeyev
  • 2,093
  • 1
  • 17
  • 21
2

Unless I'm missing something:

In your install script, to install those attributes, you should just use the customer/setup class Mage_Customer_Model_Resource_Setup and call addAttribute() with each of your attribute configurations, (unfortunately) following up with the form setting logic.

<?php

$installer = Mage::getResourceModel('customer/setup', 'default_setup');
/* @var $installer Mage_Customer_Model_Resource_Setup */

$installer->startSetup();

$installer->addAttribute(
    'customer',
    'title',
    array(
        'type'          => 'varchar',
        'input'         => 'text',
        'label'         => 'Title / Position',
        'visible'       => true,
        'required'      => false,
        'position'      => 63,
    )
);

/**
  the same for others, then individually or in loop:
 */
$attr = Mage::getSingleton('eav/config')->getAttribute('customer_address', 'title');
$attr->setIsUsedInForms(array('adminhtml_customer'))->save();

//NB: that save() call is fairly important ;-)

$installer->endSetup();
benmarks
  • 23,384
  • 1
  • 62
  • 84
  • This is definitely a better method, although my original script did function, also. – Bosworth99 Aug 29 '12 at 17:02
  • Yes, but unless you call `save()` on those attribute instances, I'm fairly sure that the `used_in_forms` data won't be written. – benmarks Aug 29 '12 at 18:03
  • So - total guess here - but I've found basically two differing methods to do this: first being your method which directly calls addAttribute(), and the send (the one I first used) which just adds extra values into the default magento behavior (and probably, itself calls addattribute())... Whatever the case, both versions worked about as well. (see my update). – Bosworth99 Aug 29 '12 at 18:11
0

I don't know whether Magento actually runs setup scripts properly if you don't up the version number once in a while.

Consider popping your module up a version and using an upgrade script. Put a simple Mage::log in the update script and you will see if it actually gets called.

The version goes in the app/etc/module/blah_Blah.xml and in etc/config.xml plus there is the entry in core_Config saying what it thinks it is on.

Maybe just setup the tables in the original installer and then the insert data stuff in the upgrade script.

Alan's article has all you need on upgrade scripts: http://www.magentocommerce.com/knowledge-base/entry/magento-for-dev-part-6-magento-setup-resources

Theodores
  • 1,209
  • 1
  • 11
  • 15
  • A couple of points: 1) Version number is not evaluated by the app until after the each active module's `config.xml` has been merged, so having it in module declaration file is not necessary and somewhat unconventional 2) Manipulating the EAV config tables directly is likely more error-prone than working with them in the defined workflow through their respective classes. – benmarks Aug 29 '12 at 12:00