英文:
Shopware 6 App - Twig Script causes memory overflow
问题
以下是代码部分的翻译:
We have written us a script that allows us in Shopware 6 badges per categories. With many products crashes sometime after 5 minutes shopware crashes with the log message that the memory at php is not enough.
Have we done anything wrong here?
We have already packed the elements in an array (the graphics) and fetch them bundled from the server.
{# @var services \Shopware\Core\Framework\Script\ServiceStubs #}
{% set page = hook.page %}
{# @var page \Shopware\Storefront\Page\Product\ProductPage #}
{% set products = [] %}
{% if hook.page.cmsPage.type === 'product_list' %}
{% foreach hook.page.cmsPage.sections as section %}
{% foreach section.blocks as sectionBlock %}
{% if sectionBlock.type !== 'product-listing' %}
{% continue %}
{% endif %}
{% foreach sectionBlock.slots as slot %}
{% if slot.type !== 'product-listing' %}
{% continue %}
{% endif %}
{% foreach slot.data.listing.entities as product %}
{% set products = products|merge([product]) %}
{% endforeach %}
{% endforeach %}
{% endforeach %}
{% endforeach %}
{% endif %}
{% set categoryIds = products|reduce((carry, v) => carry|merge(v.categoryTree), []) %}
{% if categoryIds %}
{% set categories = services.repository.search('category', {'ids': categoryIds}) %}
{% set mediaIds = [] %}
{# Loop through all products and collect media ids #}
{% foreach products as product %}
{% set badgeList = [] %}
{% foreach categories.entities.getList(product.categoryTree) as category %}
{% if category.customFields.minds_cd_show_badge %}
{% set badgeList = badgeList|merge([{
'priority': category.customFields.minds_cd_badge_priority,
'mediaId': category.customFields.minds_cd_badge
}]) %}
{% endif %}
{% endforeach %}
{% set badge = (badgeList|sort((a, b) => a.priority <=> b.priority))|last %}
{% if badge %}
{% set mediaIds = mediaIds|merge([ badge.mediaId ]) %}
{% endif %}
{% endforeach %}
{# Get all badge media ids in a performant way #}
{% set mediaCollection = services.repository.search('media', {'ids': mediaIds}) %}
{# Loop through all products again and attach the badge #}
{% foreach products as product %}
{% set badgeList = [] %}
{% foreach categories.entities.getList(product.categoryTree) as category %}
{% if category.customFields.minds_cd_show_badge %}
{% set badgeList = badgeList|merge([{
'priority': category.customFields.minds_cd_badge_priority,
'mediaId': category.customFields.minds_cd_badge
}]) %}
{% endif %}
{% endforeach %}
{% set badge = (badgeList|sort((a, b) => a.priority <=> b.priority))|last %}
{% if badge %}
{% set badgeMedia = mediaCollection.get(badge.mediaId) %}
{% do product.addArrayExtension('mcb', {
'badge': badgeMedia
}) %}
{% endif %}
{% endforeach %}
{% endif %}
希望对你有所帮助。
英文:
We have written us a script that allows us in Shopware 6 badges per categories. With many products crashes sometime after 5 minutes shopware crashes with the log message that the memory at php is not enough.
Have we done anything wrong here?
We have already packed the elements in an array (the graphics) and fetch them bundled from the server.
{# @var services \Shopware\Core\Framework\Script\ServiceStubs #}
{% set page = hook.page %}
{# @var page \Shopware\Storefront\Page\Product\ProductPage #}
{% set products = [] %}
{% if hook.page.cmsPage.type === 'product_list' %}
{% foreach hook.page.cmsPage.sections as section %}
{% foreach section.blocks as sectionBlock %}
{% if sectionBlock.type !== 'product-listing' %}
{% continue %}
{% endif %}
{% foreach sectionBlock.slots as slot %}
{% if slot.type !== 'product-listing' %}
{% continue %}
{% endif %}
{% foreach slot.data.listing.entities as product %}
{% set products = products|merge([product]) %}
{% endforeach %}
{% endforeach %}
{% endforeach %}
{% endforeach %}
{% endif %}
{% set categoryIds = products|reduce((carry, v) => carry|merge(v.categoryTree), []) %}
{% if categoryIds %}
{% set categories = services.repository.search('category', {'ids': categoryIds}) %}
{% set mediaIds = [] %}
{# Loop through all products and collect media ids #}
{% foreach products as product %}
{% set badgeList = [] %}
{% foreach categories.entities.getList(product.categoryTree) as category %}
{% if category.customFields.minds_cd_show_badge %}
{% set badgeList = badgeList|merge([{
'priority': category.customFields.minds_cd_badge_priority,
'mediaId': category.customFields.minds_cd_badge
}]) %}
{% endif %}
{% endforeach %}
{% set badge = (badgeList|sort((a, b) => a.priority <=> b.priority))|last %}
{% if badge %}
{% set mediaIds = mediaIds|merge([ badge.mediaId ]) %}
{% endif %}
{% endforeach %}
{# Get all badge media ids in a performant way #}
{% set mediaCollection = services.repository.search('media', {'ids': mediaIds}) %}
{# Loop through all products again and attach the badge #}
{% foreach products as product %}
{% set badgeList = [] %}
{% foreach categories.entities.getList(product.categoryTree) as category %}
{% if category.customFields.minds_cd_show_badge %}
{% set badgeList = badgeList|merge([{
'priority': category.customFields.minds_cd_badge_priority,
'mediaId': category.customFields.minds_cd_badge
}]) %}
{% endif %}
{% endforeach %}
{% set badge = (badgeList|sort((a, b) => a.priority <=> b.priority))|last %}
{% if badge %}
{% set badgeMedia = mediaCollection.get(badge.mediaId) %}
{% do product.addArrayExtension('mcb', {
'badge': badgeMedia
}) %}
{% endif %}
{% endforeach %}
{% endif %}
答案1
得分: 1
I think a real performance killer here might be that you potentially fetch a lot of categories. At least that could be the case if the category tree has many levels, with many categories on each level and products are assigned to multiple categories on different branches.
如果我理解正确,你实际上只对那些具有自定义字段 minds_cd_show_badge
设置为 true
的类别感兴趣。我认为这些类别可能比你当前获取的实体总数要少得多。
You could try setting a filter in your criteria targeting your custom field so you're only fetching the categories that are relevant in your case.
你可以尝试在标准中设置一个针对自定义字段的筛选器,这样你只获取与你的情况相关的类别。
英文:
I think a real performance killer here might be that you potentially fetch a lot of categories. At least that could be the case if the category tree has many levels, with many categories on each level and products are assigned to multiple categories on different branches.
If I read this correctly you're really only interested in categories that have the custom field minds_cd_show_badge
set to true
. I assume those would potentially far less categories than the total number of entities you're fetching right now.
You could try setting a filter in your criteria targeting your custom field so you're only fetching the categories that are relevant in your case.
{% set criteria = {
'ids': categoryIds,
'filter': [
{ 'field': 'customFields.minds_cd_show_badge', 'type': 'equals', 'value': true }
]
} %}
{% set categories = services.repository.search('category', criteria) %}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论