Here is a quick answer to your first question:
The configuration for virtual type isn't required. If you look into Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider
you'll find that none of those two arguments are used ("collection" as well as "filterPool").
We'll remove this unused configuration as soon as we can.
So, result declaration of data providers virtual types should be as simple as this:
for CMS Pages:
<virtualType name="PageGridDataProvider" type="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider"/>
and for CMS Blocks
<virtualType name="PageGridDataProvider" type="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider"/>
And as now you can see, in UI Components configuration files you are not enforced to use data provider virtual type and you can refer to generic data provider Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider
. We've decided to use virtual type, just to provide yet another extension point for developers.
Solution 2(better, can filter): join table in collection
In the Vendor\Module\Model\ResourceModel\ModelName\Collection
, add the _initSelect() function like below
protected function _initSelect()
{
parent::_initSelect();
$this->getSelect()->joinLeft(
['secondTable' => $this->getTable('admin_user')],
'main_table.creator_id = secondTable.user_id',
['username']
);
}
If you want to join more tables or know more details about join tables, you could see my another answer join multiple table in collection which build Admin Grid
In the UI Componet, add the username
column
<column name="username">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="label" xsi:type="string" translate="true">User Name</item>
</item>
</argument>
</column>
I think this is a better solution than solution 1. Because you could use the username
column to filter collection.
Solution 1(cannot filter): add class in UI Componet
In the UI Componet, add class for the creator_id:
<column name="creator_id" class="Vendor\Module\Ui\Component\Listing\Column\CreatorName">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="label" xsi:type="string" translate="true">Creator Id</item>
</item>
</argument>
</column>
Create the class Vendor\Module\Ui\Component\Listing\Column\CreatorName
, add the user name in the public function prepareDataSource(array $dataSource)
. Whole codes is shown below:
<?php
namespace Vendor\Module\Ui\Component\Listing\Column;
use Magento\Ui\Component\Listing\Columns\Column;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\User\Model\UserFactory;
class CreatorName extends Column
{
protected $userFactory;
/**
* @param ContextInterface $context
* @param UiComponentFactory $uiComponentFactory
* @param array $components
* @param array $data
* @param UserFactory $userFactory
*/
public function __construct(
ContextInterface $context,
UiComponentFactory $uiComponentFactory,
array $components = [],
array $data = [],
UserFactory $userFactory
) {
parent::__construct($context, $uiComponentFactory, $components, $data);
$this->userFactory = $userFactory;
}
/**
* Prepare Data Source
*
* @param array $dataSource
* @return array
*/
public function prepareDataSource(array $dataSource)
{
if (isset($dataSource['data']['items'])) {
$fieldName = $this->getData('name');
foreach ($dataSource['data']['items'] as & $item) {
if ($item[$fieldName] != '') {
$adminName = $this->getAdminName($item[$fieldName]);
$item[$fieldName] = $item[$fieldName].' ('.$adminName.')';
}
}
}
return $dataSource;
}
/**
* @param $userId
* @return string
*/
private function getAdminName($userId)
{
$user = $this->userFactory->create()->load($userId);
$name = $user->getName();
return $name;
}
}
Best Answer
With ui components you just add another column and specify the class where your array is returned, i.e:
and in
Vendor\Module\Ui\Component\Listing\Column\MyArray.php
you extend fromMagento\Ui\Component\Listing\Columns\Column
and return your array insideprepareDataSource
method: