In Magento 2 this is handled by the \Magento\Framework\Config\Reader\Filesystem
class. This class allows you specify the xml file you want to merge.
The following part will merge all files found in the available modules and merge the output (snippet from \Magento\Framework\Config\Reader\Filesystem
)
/**
* Load configuration scope
*
* @param string|null $scope
* @return array
*/
public function read($scope = null)
{
$scope = $scope ?: $this->_defaultScope;
$fileList = $this->_fileResolver->get($this->_fileName, $scope);
if (!count($fileList)) {
return [];
}
$output = $this->_readFiles($fileList);
return $output;
}
/**
* Read configuration files
*
* @param array $fileList
* @return array
* @throws \Magento\Framework\Exception
*/
protected function _readFiles($fileList)
{
/** @var \Magento\Framework\Config\Dom $configMerger */
$configMerger = null;
foreach ($fileList as $key => $content) {
try {
if (!$configMerger) {
$configMerger = $this->_createConfigMerger($this->_domDocumentClass, $content);
} else {
$configMerger->merge($content);
}
} catch (\Magento\Framework\Config\Dom\ValidationException $e) {
throw new \Magento\Framework\Exception("Invalid XML in file " . $key . ":\n" . $e->getMessage());
}
}
if ($this->_isValidated) {
$errors = [];
if ($configMerger && !$configMerger->validate($this->_schemaFile, $errors)) {
$message = "Invalid Document \n";
throw new \Magento\Framework\Exception($message . implode("\n", $errors));
}
}
$output = [];
if ($configMerger) {
$output = $this->_converter->convert($configMerger->getDom());
}
return $output;
}
In the solution I created the class above is extended to supply the xml file needed and specify where the xsd file to validate can be found (see https://github.com/Genmato/MageStackTable for complete example):
namespace Genmato\TableXml\Model\Table;
class Reader extends \Magento\Framework\Config\Reader\Filesystem
{
protected $_idAttributes = [
'/table/row' => 'id',
'/table/row/column' => 'id',
];
/**
* @param \Magento\Framework\Config\FileResolverInterface $fileResolver
* @param \Magento\Framework\Config\ConverterInterface $converter
* @param \Genmato\TableXml\Model\Table\SchemaLocator $schemaLocator
* @param \Magento\Framework\Config\ValidationStateInterface $validationState
* @param string $fileName
* @param array $idAttributes
* @param string $domDocumentClass
* @param string $defaultScope
*/
public function __construct(
\Magento\Framework\Config\FileResolverInterface $fileResolver,
\Magento\Framework\Config\ConverterInterface $converter,
\Genmato\TableXml\Model\Table\SchemaLocator $schemaLocator,
\Magento\Framework\Config\ValidationStateInterface $validationState,
$fileName = 'table.xml',
$idAttributes = [],
$domDocumentClass = 'Magento\Framework\Config\Dom',
$defaultScope = 'global'
) {
parent::__construct(
$fileResolver,
$converter,
$schemaLocator,
$validationState,
$fileName,
$idAttributes,
$domDocumentClass,
$defaultScope
);
}
To get the merged data you can then call:
$output = $this->_objectManager->get('Genmato\TableXml\Model\Table\Reader')->read();
The output is then an array representation of the merged xml.
EDIT:
To test the way the files are read I created a working example (see https://github.com/Genmato/MageStackTable). Updated the answer with the solution build.
You could get the data collection being used by the sales order grid, extract the field data, and create an option for each unique result:
class CcTypes implements OptionSourceInterface
{
/**
* @var \Magento\Sales\Model\ResourceModel\Order\Grid\Collection
*/
protected $salesCollection;
protected $options;
public function __construct(
\Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory $collectionFactory
) {
$this->salesCollection = $collectionFactory->getReport("sales_order_grid_data_source");
}
public function toOptionArray()
{
if ($this->options === null) {
foreach ($this->salesCollection->addOrder('cc_type')->addFieldToSelect('cc_type')->distinct(true) as $order) {
$ccType = $order->getCcType();
$this->options[] = [
'value' => $ccType,
'label' => $ccType
];
}
}
return $this->options;
}
}
Best Answer
I think that this is bug in magento2.
I usually clean ui_bookmark table after adding new columns by any modules.
Magento2 save columns positions even if there are no any modification in columns ordering.
But if columns positions will be stored only after user modifications, we will have same problem with new columns.
If will be added relative ordering like as
name column after id
ormy_column before actions
, we will have ugly dragging of columns in UI.If you will clear
ui_bookmark
table during module installation - you can clear custom user settings for the listing.Maybe, core developers need to fix actions column as last as partial solution.
I think, that this question has not the only right decision