As all know every big system has a way to index the catalog on flat tables , not logic to make query for example directly on oro_proudct because they has many complex relation with other tables , So to get fast frontend display with best performance using a simple tables as source of data .
OroCommerce System has a website indexer tasks which you can done with oro command :
bin/console oro:website-search:reindex
Your catalog data will pushed in some flat tables is:
oro_website
oro_website_search_datetime
oro_website_search_decimal
oro_website_search_integer
oro_website_search_item
oro_website_search_text
For example oro_website_search_text stock data of type text or string …
Let’s start explore how the image get showed in frontend product list page firstly we shuld know who’s the datagird responsible , go to vendor/oro/commerce/src/Oro/Bundle/ProductBundle/Resources/config/oro/datagrids.yml , So search for frontend-product-search-grid :
frontend-product-search-grid: options: entityHint: oro.product.entity_plural_label displayOptions: selector: '.catalog__filter-controls__item_display-options' jsmodules: - oroproduct/js/app/datagrid/frontend-product-display-options-builder - oroproduct/js/app/datagrid/frontend-product-filters-events-dispatcher-builder frontend: true source: type: search search_index: website query: select: - text.sku as sku - integer.newArrival as newArrival - text.names_LOCALIZATION_ID as name - text.shortDescriptions_LOCALIZATION_ID as shortDescription - text.type as type - text.image_product_medium as image_product_medium - text.image_product_large as image_product_large - text.product_units as product_units - text.primary_unit as unit from: - oro_product_WEBSITE_ID
You can see that the query select the collection from flat tables but the more important fields :
- text.image_product_medium as image_product_medium - text.image_product_large as image_product_large
We select image_product_medium and image_product_large but why ? And how it’s get pushed to array represent the product So shoud explore the event listener vendor/oro/commerce/src/Oro/Bundle/ProductBundle/EventListener/FrontendProductDatagridListener.php
and see the function onResultAfter :
public function onResultAfter(SearchResultAfter $event) { /** @var ResultRecord[] $records */ $records = $event->getRecords(); $this->addProductUnits($records); $this->addProductImages($event, $records); }
You should know datagrid offering many event pre Build ,after build and after result ….
- { name: kernel.event_listener, event: oro_datagrid.search_datasource.result.after.frontend-product-search-grid, method: onResultAfter }
result.after : after building the datagrid and get collection from db you have the ability to make some change like change some data of datagrid records.
So let’s explore the function addProductImages($event, $records) :
{ $gridName = $event->getDatagrid()->getName(); $theme = $this->themeHelper->getTheme($gridName); switch ($theme) { case DataGridThemeHelper::VIEW_LIST: $imageFilter = self::PRODUCT_IMAGE_FILTER_MEDIUM; break; case DataGridThemeHelper::VIEW_GRID: $imageFilter = self::PRODUCT_IMAGE_FILTER_LARGE; break; case DataGridThemeHelper::VIEW_TILES: $imageFilter = self::PRODUCT_IMAGE_FILTER_MEDIUM; break; default: return; } $noImagePath = $this->imagePlaceholderProvider->getPath($imageFilter); foreach ($records as $record) { $productImageUrl = $record->getValue('image_' . $imageFilter) ?: $noImagePath; $record->addData(['image' => $productImageUrl]); } }
So related the row view if grid or list add data to records large or medium:
foreach ($records as $record) { $productImageUrl = $record->getValue('image_' . $imageFilter) ?: $noImagePath; $record->addData(['image' => $productImageUrl]); }
Watch video for more infos.
Comments