3

So where should I begin. In the last couple of days i've been working on showing custom attributes in the customer grid. There a couple of thing i would like to discuss since I don't really know the background.

Okay first things first. How does it work.

In Vendor/Customer/Setup/InstallData.php the following keys and values must be specified in the attribute array:

'is_used_in_grid' => true,
'is_visible_in_grid' => true,
'is_filterable_in_grid' => true,
'is_searchable_in_grid' => false

Here we stumble up the first problem. If we set 'is_searchable_in_grid' to true and reindex the grid with "php bin/magento indexer:reindex" it will fail because the indexer looks for the columns in the customer_entity table. Since we created an eav attribute for this it isn't available and thus does not exist in the customer_entity table. But you're able to this manually later on in the customer_eav_attribute table by chaning the is_searchable_in_grid value from 0 to 1.

Okay the next thing we want to do is extend the customer_listing ui component in the Vendor/Customer/view/adminhtml/ui_component/customer_listing.xml

Here we have the following code

<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <listingToolbar name="listing_top"/>
    <columns name="customer_columns" class="Magento\Customer\Ui\Component\Listing\Columns">
        <column name="example" class="Vendor\Customer\Ui\Component\Listing\Column\Example">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="filter" xsi:type="string">text</item>
                    <item name="editor" xsi:type="string">text</item>
                    <item name="label" xsi:type="string" translate="true">Example</item>
                    <item name="sortOrder" xsi:type="number">30</item>
                </item>
            </argument>
        </column>
    </columns>
</listing>

This allows the original customer_listing to be merged with the new attributes. The next example show the code of the example column object:

<?php

namespace Vendor\Customer\Ui\Component\Listing\Column;

use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Ui\Component\Listing\Columns\Column;
use Vendor\Customer\Model\CustomerRepository;

class Example extends Column
{
    /**
     * @var CustomerRepository
     */
    private $customerRepository;

    /**
     * Constructor
     *
     * @param CustomerRepository $customerRepository
     * @param ContextInterface $context
     * @param UiComponentFactory $uiComponentFactory
     * @param array $components
     * @param array $data
     */
    public function __construct(
        CustomerRepository $customerRepository,
        ContextInterface $context,
        UiComponentFactory $uiComponentFactory,
        array $components = [],
        array $data = []
    ) {
        parent::__construct($context, $uiComponentFactory, $components, $data);
        $this->customerRepository = $customerRepository;
    }

    /**
     * Prepare Data Source
     *
     * @param array $dataSource
     * @return array
     */
    public function prepareDataSource(array $dataSource)
    {
        if (isset($dataSource['data']['items'])) {
            foreach ($dataSource['data']['items'] as & $item) {
                $customer = $this->customerRepository->getById($item['entity_id']);
                $item[$this->getData('name')] = $customer
                    ->getCustomAttribute('example')
                    ->getValue();
            }
        }
        return $dataSource;
    }
}

As shown above we prepare a new datasource which will fill the newly created columns in the customer_grid. This file is located in Vendor\Customer\Ui\Component\Listing\Column.

Next we create the indexer where we define our new columns for the customer grid in Vendor\Customer\etc\indexer.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Indexer/etc/indexer.xsd">
    <indexer id="customer_grid" class="Magento\Framework\Indexer\Action\Entity" primary="customer">
        <fieldset name="customer" source="Magento\Customer\Model\ResourceModel\Customer\Collection" provider="Magento\Customer\Model\Indexer\AttributeProvider">
            <field name="example" xsi:type="filterable" dataType="int"/>
        </fieldset>
    </indexer>
</config>

The file above is being merged by magento with the original indexer.xml and adds a new filterable column to the grid. Okay so now here is my real question. When i install magento it searches for the column mentioned in the indexer.xml file in this case "example" but it doesn't exist in the customer_entity table. Is this a bug, or is this expected behaviour? If so, how can we add the customer attribute to the grid, without adding these columns to the customer_entity table?

Some things to mention. You can get this working by adding the missing columns you want in the grid by using the Install or UpgradeSchema file in your Setup folder.

The rule which causes the error is actually the indexer being reindex and causing the error because the columns do not exist. In Magento/Customer/Setup/UpgradeData.php you will find the following code on line 163:

$indexer->reindexAll();

If this line is commented, the setup will also work.

Don't get me wrong i can get this thing to work. And there is actually no problem when adding the indexer.xml when the setup is already done, no errors wil occur. But for a clean setup when installing the module on a fresh install it will fail and i would like a solution for that.

For more questions and detailed information about the errors i'm getting please ask for it in a reply i will provide the necessary errors but when using this you will most likely experience these errors yourself.

I hope this is helpfull to someone, since it took me some time to get my head around this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.