Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Blank order details page - @mdanilowicz (#4382)
- upadate cart hash after sync with backend - @gibkigonzo (#4387)
- exit from errorHandler after redirection - @gibkigonzo (#4246)
- add redirection in component for simple product related to configurable product - @gibkigonzo (#4359)

## [1.11.3] - 2020.04.27

Expand Down
26 changes: 26 additions & 0 deletions core/modules/catalog/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus'
import { PRODUCT_SET_CURRENT_CONFIGURATION, PRODUCT_SET_CURRENT } from './store/product/mutation-types'
import omit from 'lodash-es/omit'
import config from 'config'
import { AsyncDataLoader } from '@vue-storefront/core/lib/async-data-loader';
import { currentStoreView } from '@vue-storefront/core/lib/multistore';
import { formatProductLink } from '@vue-storefront/core/modules/url/helpers';
import { Logger } from '@vue-storefront/core/lib/logger';
import { isServer } from '@vue-storefront/core/helpers';
import { router } from '@vue-storefront/core/app'

// Listeners moved from Product.js

Expand Down Expand Up @@ -110,3 +116,23 @@ export const onUserPricesRefreshed = async (store, router) => {
}, { root: true })
}
}

export const checkParentRedirection = (currentProduct, parentProduct) => {
if (parentProduct && parentProduct.id !== currentProduct.id && config.products.preventConfigurableChildrenDirectAccess) {
Logger.log('Redirecting to parent, configurable product', parentProduct.sku)()
parentProduct.parentSku = parentProduct.sku
parentProduct.sku = currentProduct.sku
const parentUrl = formatProductLink(parentProduct, currentStoreView().storeCode)
if (isServer) {
AsyncDataLoader.push({
execute: async ({ context }) => {
if (context && !context.url.includes(parentUrl)) {
context.server.response.redirect(301, parentUrl)
}
}
})
} else {
router.replace(parentUrl as string)
}
}
}
14 changes: 7 additions & 7 deletions core/modules/catalog/store/product/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import EventBus from '@vue-storefront/core/compatibility/plugins/event-bus'
import { StorageManager } from '@vue-storefront/core/lib/storage-manager'
import { quickSearchByQuery } from '@vue-storefront/core/lib/search'
import { formatProductLink } from 'core/modules/url/helpers'
import { checkParentRedirection } from '@vue-storefront/core/modules/catalog/events'

const PRODUCT_REENTER_TIMEOUT = 20000

Expand Down Expand Up @@ -640,7 +641,12 @@ const actions: ActionTree<ProductState, RootState> = {
throw new Error(`Product query returned empty result product status = ${product.status}`)
}
if (product.visibility === 1) { // not visible individually (https://magento.stackexchange.com/questions/171584/magento-2-table-name-for-product-visibility)
throw new Error(`Product query returned empty result product visibility = ${product.visibility}`)
if (config.products.preventConfigurableChildrenDirectAccess) {
const parentProduct = await dispatch('findConfigurableParent', { product })
checkParentRedirection(product, parentProduct)
} else {
throw new Error(`Product query returned empty result product visibility = ${product.visibility}`)
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The redirect itself seems to work fine. However, I'm thinking whether it would be good to decouple this setting from the visibility configuration.

Having them uncoupled would allow showing a child product on category page, but the link would take you to the parent product.

But this is just my thought. I'm not sure how may shops would actually find this useful.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This action is called only on PDP. So with that you can still show simple product on category page and after going on PDP you will be redirected.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also coupled it with visibility because we should check this only when its needed. Right now we are making request for every simple product. With this change it will be done only when you want to get on PDP where simple product shouldn't be visible

}

await dispatch('loadProductAttributes', { product })
Expand All @@ -651,12 +657,6 @@ const actions: ActionTree<ProductState, RootState> = {
syncPromises.push(variantsFilter)
syncPromises.push(gallerySetup)
}
if (config.products.preventConfigurableChildrenDirectAccess) {
const parentChecker = dispatch('checkConfigurableParent', { product })
if (isServer) {
syncPromises.push(parentChecker)
}
}
await Promise.all(syncPromises)
await EventBus.$emitFilter('product-after-load', { store: rootStore, route: route })
return product
Expand Down