I want to add a custom column in customer grid and want to show that if customer is online or offline in that column. For example, if customer is online show online in that column against that customer row and if it is offline shows offline in that column against that customer row
2 Answers
you are mentioning the customer grid: first of all, I will point you out on the entry point you may want to use to customise this place.
the model Magento\Customer\Ui\Component\Listing\Columns
defined in the file vendor/magento/module-customer/view/adminhtml/ui_component/customer_listing.xml
is the place to focus your work onto.
You may write a plugin or preference for it in a custom module.
Within this model, the function public function prepare()
creates the columns in your ui component.
I have a module written and public that does what you need; it is available at https://bitbucket.org/magstaging/backendscreen/src/master/ but it not on the customer grid. Using the above comment and my module as an example, you will likely find to do to adjust it all, thank you
Create Vendor/Module/view/adminhtml/ui_component/customer_listing.xml and add below 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"> <columns name="customer_columns"> <column name="online_status" class=" Vendor\Module\Ui\Component\Listing\Column\OnlineStatus"> <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> <item name="sortOrder" xsi:type="number">70</item> <item name="label" xsi:type="string" translate="true">Customer Online Status</item> </item> </argument> </column> </columns>
Create Vendor/Module/Ui/Component/Listing/Column/CustomerOnlineStatus.php and add below code
<?php namespace Vendor\Module\\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 Magento\Customer\Model\ResourceModel\Visitor\CollectionFactory as VisitorCollectionFactory; use Magento\Customer\Model\Visitor; class CustomerOnlineStatus extends Column { /** * @var Visitor */ protected Visitor $visitorModel; /** * @var VisitorCollectionFactory */ protected VisitorCollectionFactory $visitorCollectionFactory; /** * @param ContextInterface $context * @param UiComponentFactory $uiComponentFactory * @param Visitor $visitorModel * @param VisitorCollectionFactory $visitorCollectionFactory * @param array $components * @param array $data */ public function __construct( ContextInterface $context, UiComponentFactory $uiComponentFactory, Visitor $visitorModel, VisitorCollectionFactory $visitorCollectionFactory, array $components = [], array $data = [] ) { $this->visitorModel = $visitorModel; $this->visitorCollectionFactory = $visitorCollectionFactory; parent::__construct($context, $uiComponentFactory, $components, $data); } /** * @param array $dataSource * @return array */ public function prepareDataSource(array $dataSource): array { if (isset($dataSource['data']['items'])) { $entityIds = []; foreach ($dataSource['data']['items'] as $item) { $entityIds[] = $item['entity_id']; } $online = $this->getOnlineCustomers($entityIds); foreach ($dataSource['data']['items'] as &$item) { $item[$this->getName()] = isset($online[$item['entity_id']]) ? __('Online') : __('Offline'); } } return $dataSource; } /** * @param array $customerIds * @return array */ protected function getOnlineCustomers(array $customerIds): array { $collection = $this->visitorCollectionFactory->create(); $lastDate = gmdate('U') - $this->visitorModel->getOnlineInterval() * 60; $collection->addFieldToFilter('last_visit_at', [ 'from' => $collection->getConnection()->formatDate($lastDate), ]); $collection->addFieldToFilter('customer_id', [ 'in' => $customerIds, ]); $online = []; foreach ($collection as $visitor) { $online[$visitor->getCustomerId()] = true; } return $online; } }
Run php bin/magento cache:flush and check the result.
I hope it will work...