Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot use field(s) from source processor (beforeLoad) #45

Closed
advocat opened this issue May 12, 2021 · 5 comments
Closed

Cannot use field(s) from source processor (beforeLoad) #45

advocat opened this issue May 12, 2021 · 5 comments
Labels
bug Something isn't working

Comments

@advocat
Copy link

advocat commented May 12, 2021

Example: You are want to join some field (stored in separate table) to product grid
You can use native collection and processor with join data on beforeLoad

    <source>
        <collection>\Magento\Catalog\Model\ResourceModel\Product\Collection</collection>
        <processors>
            <processor class="\Your\Extension\Model\Hyva\GridSource\ProductGridProcessor"/>
        </processors>
    </source>

But you cannot use field in grid definition like

    <columns>
        <include>
            <column name="custom_filed"/>
        </include>
    </columns>

As Result: Exception #0 (OutOfBoundsException): Column(s) not found on source: custom_filed

Please advise designed solution for?

I can define own collection and join this field in init select, but looking for some easy way, which allows to easy extend data from different extensions

Also, if you want to use plugin for \Hyva\Admin\Model\GridSourceType\CollectionGridSourceType - you cannot access to gridName variable

Ideally, if we have defined excluded fields - not extract them, especially linked products, etc

@Vinai
Copy link
Collaborator

Vinai commented May 13, 2021

Hi Victor,

thanks for opening the issue!
So far I never had to deal with this scenario, so it isn't supported yet. I've only worked with the collection provider with custom collections that joined tables in the init select, but the scenario you describe should be absolutely supported.
I'll add a bug label to this issue and hope to have a solution this week.

Also, if you want to use plugin for \Hyva\Admin\Model\GridSourceType\CollectionGridSourceType - you cannot access to gridName variable

Time to add a getGridName() method.

Ideally, if we have defined excluded fields - not extract them, especially linked products, etc

I' not sure I understand correctly, but what I think you are saying is to not load the data for excluded fields, right?
This is actually something that was done on purpose. It should be possible to exclude fields, so they are not rendered in the grid automatically, and still render them in combined columns using custom templates. I've had to do that a few times.

Does that answer this question?

@Vinai Vinai added the bug Something isn't working label May 13, 2021
@advocat
Copy link
Author

advocat commented May 13, 2021

Vinai, let me explain more details about exclude scenario. This is more related to performance and extra data that are never use in grid. Maybe more correct request here is extract only included fields if they are specified.

Precondition: you have a real catalog (not sample data) with 100 custom attributes, with assigned related, upsell, crosssell. You create a grid and specify only 20 attributes that are requires for you with includes.

Expected Result: the system processes (extract) only your specified attributes for render

Actual Result: the system processes all EAV attributes for each product individually and in case 50 products per page - try to load related, upsell, crosssell collections for each row.

Possible workaround: Defines event for hyva_grid_column_definition_build_after and remove all heavy columns or just keep specified in includes node.

I didn't check scenario (saw in examples) when specified additional filters which are not present in includes in columns

@Vinai
Copy link
Collaborator

Vinai commented May 14, 2021

@advocat I've opened a separate issue #46 to track the exclude columns topic.

@Vinai
Copy link
Collaborator

Vinai commented May 14, 2021

Regarding the join field, I've decided to introduce a new interface that is specific for collection source type processors:
\Hyva\Admin\Api\HyvaGridCollectionProcessorInterface

It declares a method afterInitSelect that can be used to join fields before the available columns are extracted or the search criteria is applied.

public function afterInitSelect(AbstractDbCollection $source, string $gridName): void

The new interface extends the HyvaGridSourceProcessorInterface.

Here is the test I used to reproduce the issue and to confirm the new interface works as intended:

    /**
     * @magentoDataFixture Magento/Catalog/_files/product_simple.php
     * @magentoDataFixture Magento/Catalog/_files/products_list.php
     */
    public function testAfterInitSelectProcessorCanJoinFieldsForGrid(): void
    {
        $processor = new class() extends AbstractGridSourceProcessor implements HyvaGridCollectionProcessorInterface {

            public function afterInitSelect(AbstractDbCollection $source, string $gridName): void
            {
                $select = $source->getSelect();

                // add select expression
                $select->columns(['foo' => new \Zend_Db_Expr('foo')]);

                // add field from joined table
                $source->getSelect()->joinLeft(
                    'catalog_category_product',
                    'e.entity_id = catalog_category_product.product_id',
                    ['test_field' => 'catalog_category_product.entity_id']
                );
            }
        };

        $args = [
            'gridName'            => 'test',
            'processors'          => [$processor],
            'sourceConfiguration' => ['collection' => ProductCollection::class],
        ];

        /** @var CollectionGridSourceType $sut */
        $sut = ObjectManager::getInstance()->create(CollectionGridSourceType::class, $args);

        $columnKeys = $sut->getColumnKeys();

        $this->assertContains('foo', $columnKeys); // select expression
        $this->assertContains('test_field', $columnKeys); // joined field
        $this->assertContains('sku', $columnKeys); // entity table attribute
        $this->assertContains('color', $columnKeys); // eav attribute
    }

I'll roll a release shortly and hope that solves that issue for you.
I'll also add the getter for the grid name in the release.

Vinai added a commit that referenced this issue May 14, 2021
Add collection specific source type processor to allow joining fields
before the available grid columns are extracted.

Fixes issue #45.
@Vinai Vinai closed this as completed May 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants