问题描述:

I have a requirement for a Magento project that accounts are hierarchical. That is one account can "own" multiple other accounts. If one account owns another account it is allowed to impersonate that account: create orders, view account information, and view previous orders.

I'm not sure where to begin. If you have any thoughts, could you please point me in the right direction?

网友答案:

One solution would be to set up a Multiple Select attribute and populate it with the user ids of the users allowed to impersonate. You could then create either a separate php file that runs magento and logs in the user based on who they select, or integrate it into the cms.

Here is my custom 'login' code that lets my sso users from my Microsoft Database login to magento.

You call this function and pass it a 'user' you want to login as. Seems to work pretty well, however you will need to modify it to your needs. Don't expect it to work out of the box!

FYI: if you don't pass in all the junk that magento needs about the dispatchevents() then the user will not login properly. I had to reverse engineer this whole dern thing, so don't expect to see it anywhere else besides here and bits and pieces of magento core :)

$userId = 5;
$user = Mage::getModel('customer/customer')->load($userId)->setWebsiteId(1);
$this->LoginToMagento($user, null);

function LoginToMagento($user, $noAddress) {

        // Must include this file in order to use the object
        include ('/var/www/app/code/core/Mage/Customer/controllers/AccountController.php');

        // Configure Magento to think its using the frontend
        Mage::getSingleton("core/session", array("name" => "frontend"));
        Mage::getConfig()->init();
        Mage::getConfig()->loadEventObservers('frontend');
        Mage::app()->addEventArea('frontend');
        Mage::app()->loadArea(Mage_Core_Model_App_Area::AREA_FRONTEND);

        // Grab the request and modify it with my emulated controller's information
        $request = Mage::app()->getRequest();
        $request->setRouteName('customer');
        $request->setControllerModule('Mage_Customer');
        $request->setRoutingInfo('');
        $request->setModuleName('customer');
        $request->setControllerName('account');
        $request->setModuleKey('module');
        $request->setControllerKey('account');
        $request->setActionName('loginPost');
        $request->setActionKey('action');

        // Grab the response
        $response = Mage::app()->getResponse();

        // Feed the request and response into a new accountcontroller object
        $accountControl = new Mage_Customer_AccountController($request, $response);

        // Dispatch events related to the controller actions for predispatch
        Mage::dispatchEvent('controller_action_predispatch', array('controller_action' => $accountControl));
        Mage::dispatchEvent('controller_action_predispatch_customer', array('controller_action' => $accountControl));
        Mage::dispatchEvent('controller_action_predispatch_customer_account_loginPost', array('controller_action' => $accountControl));

        // Grab an instance of the customer session model
        $session = Mage::getSingleton('customer/session');

        try{
            // Attempt to login the user
            $session->setCustomerAsLoggedIn($user);
            $session->renewSession();

        } catch (Mage_Core_Exception $e) {
            // Lets hope to never get here
            $message = $e->getMessage();
            error_log($message);
            Mage::getSingleton('core/session')->addError($message);
        }

// Perform the postdispatch events for 'after emulation of the controller'
        Mage::dispatchEvent('controller_action_postdispatch_customer_account_loginPost', array('controller_action'=>$accountControl));
        Mage::dispatchEvent('controller_action_postdispatch_customer', array('controller_action'=>$accountControl));
        Mage::dispatchEvent('controller_action_postdispatch', array('controller_action'=>$accountControl));

        $customer = Mage::getModel('customer/customer')
            ->getCollection()
            ->addAttributeToSelect('*')
            ->addAttributeToFilter('entity_id', array('eq' => $user->getId()))
            ->getFirstItem();

        try
        {
            // Prepare a collection of required values that the customer *should* have been set from netforum
            $collection = Mage::getModel('eav/entity_attribute')->getCollection();
            $collection->addFieldToFilter('entity_type_id', Mage::getModel('eav/entity')->setType('customer')->getTypeId());

            // The var representing if validation has failed
            $failedReq = false;

            // Loop through each user defined required attribute and if we find one
            // on the customer that is not set, forward the user to their account config page
            foreach ($collection as $attribute)
            {
                if ($attribute['is_required'] && $attribute['is_user_defined'])
                {
                    $attrCode = $attribute['attribute_code'];
                    if (!isset($customer[$attrCode]))
                    {
                        $failedReq = true;
                    }
                }
            }

            // Try to determine where we logged in from (URL)
            Mage::getSingleton("core/session", array("name" => "frontend"));
            $session = Mage::getSingleton("customer/session");
            $outputMessage = $session->getData('before_auth_url');


            // Proceeed differently based on the existence of addresses
            if ($noAddress == true)
            {
                if ($failedReq)
                {
                    // Customer failed login. To be expected if they are signing in with SSO and never have before
                    $redirect_to = 'https://' . $_SERVER['HTTP_HOST'] . '/customer/account/edit/';
                    Mage::getSingleton('core/session')->addError('<b>Please fill in the required fields marked with * and click "Save"</b>');
                    header("Location: $redirect_to");
                }
                else
                {
                    // Customer checks out ok, but has no addresses. Send them to the address setup screen
                    Mage::getSingleton('core/session')->addError('<b>Please fill in your address and phone number, then click "Save"</b>');
                    $redirect_to = 'https://' . $_SERVER['HTTP_HOST'] . '/customer/address/edit/';
                    header("Location: $redirect_to");
                }

            }
            else
{
                // Customer has addresses being passed from SSO
                $defaultBillingId = $customer->getDefaultBillingAddress()->getId();

                $hasPhoneNumber = false;

                foreach ($customer->getAddresses() as $address)
                {
                    $addrs = Mage::getModel('customer/address')->load($address->getId());
                    $magePhone = $addrs->getTelephone();
                    if ($magePhone)
                    {
                        $hasPhoneNumber = true;
                    }
                }

                if ($failedReq)
                {
                    // Customer failed login. To be expected if they are signing in with SSO and never have before
                    $redirect_to = 'https://' . $_SERVER['HTTP_HOST'] . '/customer/account/edit/';
                    Mage::getSingleton('core/session')->addError('<b>Please fill in the required fields marked with * and click "Save"</b>');
                    header("Location: $redirect_to");

                }
                else
                {
                    // Customer is has default values filled out
                    if (!$hasPhoneNumber)
                    {
                        // Phone number is missing for an address so redirect there and force em to enter it.
                        Mage::getSingleton('core/session')->addError('<b>Please fill in the required fields marked with * and click "Save Address"</b>');
                        $redirect_to = 'https://' . $_SERVER['HTTP_HOST'] . '/customer/address/edit/id/' . $defaultBillingId;
                        header("Location: $redirect_to");

                    }
                    else
                    {
                        // Everything is ok, so just try to send them back to where they came from, or the account screen
                        if ($outputMessage)
                        {
                            $redirect_to = $outputMessage;
                        }
                        else
                        {
                            $redirect_to = 'https://' . $_SERVER['HTTP_HOST'] . '/customer/account/';
                        }
                        header("Location: $redirect_to");
                    }
                }
            }
        }
        catch (Exception $e)
        {
            if ($outputMessage)
            {
                $redirect_to = $outputMessage;
            }
            else
            {
                $redirect_to = 'https://' . $_SERVER['HTTP_HOST'] . '/customer/account/';
            }
            header("Location: $redirect_to");
        }
    }
网友答案:

I know I am late but

http://amasty.com/sales-reps-and-dealers.html

This extension can be helpful to achieve what you are looking for. It will allow to create hierarchical accounts and assign the sales rep/sub admins to the orders and provide the access levels.

Hope this helps.

相关阅读:
Top