Magento – Magento 2: get customer().lastname in header.phtml

customerheadermagento-2.1magento2

I don't get how this works. I'm trying to edit the header of my Magento 2 store (Magento_Theme/templates/html/header.phtml) and I'm trying to retrieve my customers lastname like this:

<span data-bind="text: new String('<?php echo $block->escapeHtml(__('Welcome %1', '%1'));?>').replace('%1', customer().lastname)"></span>

It works fine when it says 'fullname' instead of lastname: this shows my full name. It also works fine when I replace it with 'firstname': this shows my first name. Why doesn't it work with last name and what is the right way to get all the customer data here?

Best Answer

TLDR;

You need to create a plugin in a custom module to override the Magento\Customer\CustomerData\Customer class. In your module's di.xml file:

app/code/Vendor/LastName/Plugin/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Customer\CustomerData\Customer">
        <plugin name="vendor_lastnameplugin"
                type="Vendor\LastName\Plugin\CustomerData\Customer"
                sortOrder="10"
                disabled="false"/>
    </type>
</config>

And then in your override file:

app/code/Vendor/LastName/Plugin/CustomerData/Customer.php

<?php
namespace ForeverNew\Criteo\Plugin\CustomerData;
use Magento\Customer\Helper\Session\CurrentCustomer;

class Customer
{
    protected $currentCustomer;

    public function __construct(
        CurrentCustomer $currentCustomer
    ) {
        $this->currentCustomer = $currentCustomer;
    }

    public function afterGetSectionData(\Magento\Customer\CustomerData\Customer $subject, $result)
    {
        $customer = $this->currentCustomer->getCustomer();
        $result['lastname'] = $customer->getLastname();
        return $result;
    }
}

This will create a customer().lastname for you to use in your template file.

More Background

There isn't a customer().lastname, and it's a bit convoluted as to how to add that in. The template (magento/module-theme/view/frontend/templates/html/header.phtml) is calling in the customer component with this script:

<script type="text/x-magento-init">
    {
        "*": {
            "Magento_Ui/js/core/app": {
                "components": {
                    "customer": {
                        "component": "Magento_Customer/js/view/customer"
                    }
                }
            }
        }
    }
</script>

But looking that file (after all the preamble) you will find only this line:

this.customer = customerData.get('customer');

But even following that call, you still don't get to the right file you need to edit. Turns out that the array that is defining the values for the customer() element is coming from a php file that is populating an array that is then getting used to define these values:

vendor/magento/module-customer/CustomerData/Customer.php

public function getSectionData()
{
    if (!$this->currentCustomer->getCustomerId()) {
        return [];
    }
    $customer = $this->currentCustomer->getCustomer();
    return [
        'fullname' => $this->customerViewHelper->getCustomerName($customer),
        'firstname' => $customer->getFirstname(),
    ];
}

Adding into the return array will add in any value that you can then access in the knockout template with dot notation, i.e. customer().anythingYouWant. So in this case you need to create a plugin to add to the return array with that value populated. It's just by luck that you already have access to $customer->getLastname() in that class, so you don't have to import any other class or data to get what you are looking for.

As a side note, this is a pain to test in the browser. Since the data that is set here is stored in the session, you have to clear that when testing out values. If customer().lastname is set, even if you change it in the php, the value that is set will persist. So you can log out or just clear mage-cache-storage in the browser and go on with your day.

Related Topic