6

I'm stumped by the following:

I'm creating a custom storefinder that uses addresses of a 3rd type in the Mage_Customer_Model_Address_Abstract class:

eg:

class Mage_Customer_Model_Address_Abstract extends Mage_Core_Model_Abstract
{
    /**
     * Possible customer address types
     */
    const TYPE_BILLING  = 'billing';
    const TYPE_SHIPPING = 'shipping';
    // add a 3rd 
    const TYPE_STOREFINDER = 'storefinder';

However, I'm not sure how exactly this can be done, as it also requires an eav attribute:

enter image description here

I want this option to be available in the admin backend only, by displaying it with a checkbox - here is a quick photoshop:

the way it should look in the customer/address

  • the file to duplicate and edit for this checkbox and then place in ones module is: design/adminhtml/default/default/customer/tab/addresses.phtml

        <span class="address-type-line">
            <input type="checkbox"  <?php if ($this->isReadonly()):?> disabled="disabled"<?php endif;?> value="<?php echo $_address->getId() ?>" id="address_item_storefinder<?php echo $_address->getId() ?>" name="account[storefinder]" title="<?php echo Mage::helper('customer')->__('Set as Storefinder Address') ?>"<?php if($_address->getId()==$customer->getStorefinderAddress()): ?> checked="checked"<?php endif; ?>/>
            &nbsp;<label for="address_item_storefinder<?php echo $_address->getId() ?>"><?php echo Mage::helper('customer')->__('Default Storefinder Address') ?></label>
        </span>
    

I've created a frontend page block which should then grab all customer addresses of type 'storefinder' and display them on a google map.

-> define $customer->getStorefinderAddress() function - maybe done something like this:

/**
 * Get default customer storefinder address
 *
 * @return Mage_Customer_Model_Address
 */
 public function getStorefinderAddress()
 {
    $addresses = Mage::getResourceModel('customer/address_collection');
    foreach ($addresses as $address) {
      if($address->getAddressType() == 'storefinder') {
         $storefinderaddresses[] = $address;
      }
    }
    return $storefinderaddresses;
 }

I need to know how to:

-> define a 3rd address type and know if the function getStorefinderAddress() work to query these addresses by using:

$address->getAddressType() == 'storefinder'

-> save the value of the added checkbox in the database from the edit customer address in the adminhtml


Alternatively:

I've thought of an alternative way of doing this if adding a 3rd address type is too complex:

  • add an INT column to the customer/address table which simply stores true/false (0/1) for the checkbox field in the customer/tab/addresses.phtml

    ...
    
    ->addColumn( // Alter table to add column
    
        $installer->getTable('customer/address'), // get the customer address modules table
    
        'in_storefinder', // column name
    
        array( // column info
            'type'      => Varien_Db_Ddl_Table::TYPE_INTEGER,
            'length'    => null,
            'unsigned'  => true,
            'nullable'  => true,
            'default'   => '0',
            'comment'   => ' added by the Storefinder',
        )
     );
     $installer->endSetup();
    

Any help would be greatly appreciated.

1
  • was you able to make this possible if so can you please drop out your module?
    – Zahirabbas
    Commented Jul 17, 2018 at 4:21

1 Answer 1

9
+150

First of all I want to say that the address_type is not used for customer addresses. It is used only for quote and order addresses, so there is no need to use that in order to flag your own address type.
if you need to retrieve only your store finder addresses I have an idea, but later on that.
First, you will need to create a new module to handle your new address type in order not to change the core code.
Let's call this module StackExchange_Storefinder.
You will need the following files:

app/etc/modules/StackExchange_Storefinder.xml - the declaration file:

<?xml version="1.0"?>
<config>
    <modules>
        <StackExchange_Storefinder>
            <codePool>local</codePool>
            <active>true</active>
            <depends>
                <Mage_Customer />
                <Mage_Adminhtml />
            </depends>
        </StackExchange_Storefinder>
    </modules>
</config>

app/code/local/StackExchange_Storefinder/etc/config.xml - the configuration file

<?xml version="1.0"?>
<config>
    <modules>
        <StackExchange_Storefinder>
            <version>1.0.0</version>
        </StackExchange_Storefinder>
    </modules>
    <global>
        <resources>
            <stackexchange_storefinder_setup>
                <setup>
                    <module>StackExchange_Storefinder</module>
                    <class>Mage_Customer_Model_Resource_Setup</class>
                </setup>
            </stackexchange_storefinder_setup>
        </resources>
        <models>
            <stackexchange_storefinder>
                <class>StackExchange_Storefinder_Model</class>
            </stackexchange_storefinder>
        </models>
        <helpers>
            <stackexchange_storefinder>
                <class>StackExchange_Storefinder_Helper</class>
            </stackexchange_storefinder>
        </helpers>
        <blocks>
            <stackexchange_storefinder>
                <class>StackExchange_Storefinder_Block</class>
            </stackexchange_storefinder>
            <adminhtml>
                <rewrite>
                    <customer_edit_tab_addresses>Stackexchange_Storefinder_Block_Adminhtml_Customer_Edit_Tab_Addresses</customer_edit_tab_addresses>
                </rewrite>
            </adminhtml>
        </blocks>
    </global>
    <adminhtml>
        <events>
            <adminhtml_customer_prepare_save>
                <observers>
                    <stackexchange_storefinder>
                        <class>stackexchange_storefinder/adminhtml_observer</class>
                        <method>checkStoreFinderAddress</method>
                    </stackexchange_storefinder>
                </observers>
            </adminhtml_customer_prepare_save>
        </events>
    </adminhtml>

</config>

app/code/local/StackExchange/Storefinder/sql/stackexchange_storefinder_setup/install-1.0.0.php - the install script that adds a new customer attribute to store the store finder address id (just like billing and shipping).

<?php
/** @var Mage_Customer_Model_Resource_Setup $this */
$this->addAttribute(
    'customer',
    'default_store_finder_id',
    array(
        'type'               => 'int',
        'label'              => 'Default Store Finder Address',
        'input'              => 'text',
        'backend'            => 'stackexchange_storefinder/customer_attribute_backend_storefinder',
        'required'           => false,
        'sort_order'         => 82,
        'visible'            => false,
    )
);

app/code/local/StackExchange/Storefinder/Model/Customer/Attribute/Backend/Storefinder.php - the backend model of the store finder attribute:

<?php
class StackExchange_Storefinder_Model_Customer_Attribute_Backend_Storefinder extends Mage_Eav_Model_Entity_Attribute_Backend_Abstract
{
    public function beforeSave($object)
    {
        $helper = $this->_getHelper();
        $defaultStoreFinder = $helper->getDefaultStorefinder($object);
        if (is_null($defaultStoreFinder)) {
            $object->setData('default_store_finder_id', null);
        }
    }
    public function afterSave($object)
    {
        if ($defaultStoreFinder = $this->_getHelper()->getDefaultStorefinder($object))
        {
            $addressId = false;
            /**
             * post_index set in customer save action for address
             * this is $_POST array index for address
             */
            foreach ($object->getAddresses() as $address) {
                if ($address->getPostIndex() == $defaultStoreFinder) {
                    $addressId = $address->getId();
                }
            }
            if ($addressId) {
                $object->setDefaultStoreFinderId($addressId);
                $this->getAttribute()->getEntity()
                    ->saveAttribute($object, $this->getAttribute()->getAttributeCode());
            }
        }
    }

    /**
     * @return StackExchange_Storefinder_Helper_Address
     */
    protected function _getHelper()
    {
        return Mage::helper('stackexchange_storefinder/address');
    }
}

app/code/local/StackExchange/Storefinder/Helper/Address.php - a helper so you won't rewrite the customer model:

<?php
class StackExchange_Storefinder_Helper_Address extends Mage_Core_Helper_Abstract
{
    public function getDefaultStorefinder(Mage_Customer_Model_Customer $customer)
    {
        return $customer->getData('default_store_finder_id');
    }
    public function getDefaultStorefinderAddress(Mage_Customer_Model_Customer $customer)
    {
        return $customer->getPrimaryAddress($customer->getData('default_store_finder_id'));
    }
}

app/code/local/StackExchange/Storefinder/Block/Adminhtml/Customer/Edit/Tab/Addresses.php - rewrite the admin address block to add the new radio button

<?php
class Stackexchange_Storefinder_Block_Adminhtml_Customer_Edit_Tab_Addresses
    extends Mage_Adminhtml_Block_Customer_Edit_Tab_Addresses
{
    public function __construct()
    {
        parent::__construct();
        $this->setTemplate('stackexchange_storefinder/tab/addresses.phtml');
    }
}

app/design/adminhtml/default/default/template/stackexchange_storefinder/tab/addresses.phtml - the new address admin template. Same as the default one but with one extra radio button. I wrote this in a gist because it's too big to put in here

app/code/local/StackExchange/Storefinder/Model/Adminhtml/Observer.php - an observer for the customer save event so the new address flag will be recognized:

<?php
class StackExchange_Storefinder_Model_Adminhtml_Observer
{
    public function checkStoreFinderAddress($observer)
    {
        /** @var Mage_Customer_Model_Customer $customer */
        $customer = $observer->getCustomer();
        /** @var Mage_Core_Controller_Request_Http $request */
        $request = $observer->getRequest();
        $data = $request->getPost();
        if (isset($data['account']['default_storefinder'])) {
            $customer->setData('default_store_finder_id', $data['account']['default_storefinder']);
        }
    }
}

app/code/local/StackExchange/Storefinder/Helper/Data.php - the module default helper. Not sure this is needed.

<?php
class StackExchange_Storefinder_Helper_Data extends Mage_Core_Helper_Abstract
{

}

When you are done clear the cache.

Now, in order to get all addresses that have this new flag set, you first need to get all the customers and get the value of $customer->getDefaultStoreFinderId() and then get the address collection where the id is in the values collected above.

But from my point of view, these is a totally different question. First check if you can add a third address type by using the code above.

[EDIT]

To get all the addresses that are marked as store finder you need to do something like this:

$customerCollection = Mage::getModel('customer/customer')->getCollection()
     ->addAttributeToSelect('default_store_finder_id');
$addressIds = array();
foreach ($customerCollection as $customer) {
    $addressId = $customer->getDefaultStoreFinderId();
    if ($addressId) {
        $addressIds[] = $addressId;
    }
}

if (count($addressIds)) {
    $addresses = Mage::getModel('customer/address')->getCollection()
        ->addAttributeToSelect('*')
        ->addAttributeToFilter('entity_id', array('in' => $addressIds));
    //do what you need with $addresses.
}
16
  • Hi Marius, thanks for the great detailed guide. I followed it step by step, but now my customer edit page only shows the addresses, no navigation and at the new input element I receive a fatal error: Class 'Mage_Stackexchange_Storefinder_Helper_Address' not found in ... Please see the following screenshot: pbrd.co/1FSgQXY
    – tecjam
    Commented Feb 24, 2015 at 9:00
  • @tecjam.This is really strange. Magento should not look for the helper in Mage_Stackexchange_Storefinder_Helper_Address It should look for StackExchange_Storefinder_Helper_Address because I declared the helper alias stackexchange_storefinder to map to StackExchange_Storefinder_Helper class name prefix. Try clearing the cache. Also, are you usin a unix OS? I developed this on windows and I make have missed a case sensitivity somewhere.
    – Marius
    Commented Feb 24, 2015 at 9:11
  • Yes, I have to use an apple at work. I cleared the cache (it's off actually). Here is the module code: s000.tinyupload.com/index.php?file_id=00641953372370414025
    – tecjam
    Commented Feb 24, 2015 at 9:17
  • What is strange though, it seems to work fine for customer that have no address set. But if you select a customer that already had an address defined, it gives me the above screenshot and errors.
    – tecjam
    Commented Feb 24, 2015 at 9:20
  • @tecjam. Ok. I will take a second look and get back to you.
    – Marius
    Commented Feb 24, 2015 at 9:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.