magento / community-features

Magento Features Development is an Initiative to Allows Community Memebers Join to Development of Magento Features
46 stars 18 forks source link

Media Gallery Scopes #23

Open magento-engcom-team opened 6 years ago

magento-engcom-team commented 6 years ago

Terms and Concepts

Warning! This document uses simplified terms and concepts to explain products media gallery desired behavior and implementation. For more accurate terms definition please check out Magento Glossary.

Scope — set of data at Magento instance that may be accessible at the same time. Scopes are 4-level hierarchical structure and include global, websites, stores and store views. Each level of scope has access to underlying layer's data and my redefine it as well as may introduce own data (e.g. store level has access to all data defined at website level plus own data). Each level has own semantic meaning. In this document, we will consider only global and store view levels.

Global Scope — represents data itself. You may think about this scope as a place where all models are live.

Store View — represent data displaying options for a store front. Namely, store view defines what data from global scope will see a customer at your site and how it will see them.

Technically Global Scope is implemented as a default store view with id=0. Default store view also may be referenced as Admin store view.

Don't be confused! Magento 2 admin uses terms Store and Store view while in code Store is corresponding to Store Group and Store View to Store. After installation, Magento 2 has Default Store View which usually have id=1 and does not have any special meaning. When code refers to \Magento\Store\Model\Store::DEFAULT_STORE_ID it uses store view not visible in Admin panel and holding data of the Global scope.

Product — is a data of the things that are available for a customer to purchase. This is a model. As a result, products stored in the Global scope. You can not create a product that will exist in one store but will not exists in another. However, you may disable product for some website (product will exist on a website but will not be accessible by a customer).

Media Gallery — set of media resources related to a product. It's implemented as a product attribute. As for any model, data of media gallery must be stored on the global level.

Media Gallery Entry — is a media resource model (image or video). It must be stored on the global level as well. Meaningful are file path and media type properties.

In term of DDD Product is an Aggregation Root and holds Media Gallery that holds Media Gallery Entries. As this is the same aggregate all its parts are stored on the same (Global) level.

Product has image, small image and thumbnail attributes which define what images will be displayed to customer on store front at catalog and product pages. As this is data related to product displaying these options are store on the store view level. Image, small image and thumbnail attributes reference to media gallery entries by file path.

Displaying of Media Gallery Entry may be configured with options:

Role property displayed at Media Gallery Entry admin page, in fact, corresponds to Product attributes.

To summarize:

Media Gallery management

Media Gallery may be managed on an admin product page under Images and Videos tab. Any change to a media gallery applied after product save. Admin product page uses scope switcher to define what scope should be used for persisting data. In the switcher All store view value correspond to the default (admin) store view, which is equal to the global scope. Saving some value for All store view actually does not change value in all store views. Instead, value persisted in the default store view and this value may be used as fallback if it is missed for some store view.

Regardless of scope switcher value, some fields may be stored on more higher level of scopes hierarchy. Usually, this is reflected in UI.

As was discussed previously add and delete operations always [should be] executed on the global level. Update operation may be performed on a store view level respecting product save scope switcher.

To prevent errors in media gallery management system does not allow to delete image if it has special role in store view another then current edit scope.

Implementation details

Media Gallery uses 4 tables for data persisting:

  1. catalog_product_entity_media_gallery — holds data of media gallery entries which are stored on the global level (model data).
  2. catalog_product_entity_media_gallery_value — holds data of media gallery entries which are stored on a store view level (presentation data).
  3. catalog_product_entity_media_gallery_value_to_entity — links media gallery entry to product on a global level.
  4. catalog_product_entity_media_gallery_value_video — holds video specific data on a store view level.

Product image, small image and thumbnail attributes stored in catalog_product_entity_varchar table.

Media gallery and Content Staging

Media gallery supports Magento Content Staging. As a result schema for Magento Open Source (CE) and for Magento Commerce (EE) with Staging enabled are different. Schema without enabled Staging uses entity_id field for foreign key. Staging modifies schema and replace entity_id field with row_id. To use proper column name in PHP code Magento\Framework\EntityManager\EntityMetadataInterface::getLinkField should be used.

Issues in current implementation

Current implementation has several issues that complicate understanding of desired behavior, leads to misunderstanding and bad user experience.

UI of Media Gallery does not reflect in what scope data is persisted

On images above fields that should be stored at different scope levels displayed together and user can not determine what scope will be modified.

New image may be stored not in the global scope

If gallery entry added not in All Store Views mode table catalog_product_entity_media_gallery_value does not contain record for store_id=0. As a result fallback mechanism for other store views is broken.

Missed possibility to use default store view options

To allow use default value provided by default scope product attributes uses Use Default value checkbox.

Media Gallery Entry attributes don't have same mechanism. As a result, image attributes always persisted in a scope defined by product scope switcher. That means, if product saved for some store view scope all media gallery attributes are copied from default store view even if there are no changes in images.

Duplication of image attributes on store view complicates gallery management:

  1. Admin create a product (global scope)
  2. Admin add images to product and set one as an image, small image and thumbnail (global scope)
  3. Admin switch to some store view and edit any field not related to gallery (store view scope)
  4. Admin save product. At this moment attributes for all images are copied from default (admin) store view to edited store view
  5. Admin switch back to global scope
  6. Admin can not properly manage gallery from global scope 6.1 Admin edit image attributes but they are not reflected on store front as store view already has own copy of attributes 6.2 Admin try to delete image with special role but system shows error message (edited scope has own information about image role so blocks image deletion)

Required fixes (in order of severity)

  1. Provide possibility to use default value for Media Gallery Entry attributes (should be enabled by default).
  2. Always persist new media gallery entry in default (admin) store view.
  3. Add scope labels to UI for media gallery entries.

Original Report: https://github.com/magento/magento2/issues/10863 by @vkublytskyi

sfblaauw commented 6 years ago

+1

grichards commented 4 years ago

+1

The current implementation seems like an important flaw in the system design. I cannot effectively manage images in a multi-store site if I have any attribute overrides at the store level.

gavinhoman commented 3 years ago

This MySQL command removes the store level gallery sort order / positions and they then observe the 'default/global' sort order. It needs a full-page cache flush to notice the effect on the frontend. If you subsequently edit a product on a certain store view, it can be any attribute like a description Magento will still duplicate the default store order for the media gallery and create one for that store view. We therefore have to run this command periodically to wipe them again.

DELETE FROM catalog_product_entity_media_gallery_value WHERE store_id != 0;

LiamKarlMitchell commented 3 years ago

Hi, kindly requesting if there is an update for these fixes or a backport for Magento 2.3.2..

Wutzl commented 3 years ago

any idea when this will be fixed? Makes it extremely inconvenient to manually change images for a product in a shop with a large amount of store views...

mackieee commented 3 years ago

This issue is destorying my ability to have automated image management for multiple store fronts :(

ryanisn commented 2 years ago

Who would vote for an option to force image scope to be global only? If you don't even need to manage different images in store scope.

mbautista commented 1 year ago

Hello, This issue this exists in 2023 with Magento 2.4. Could anyone please provide an update and/or some suggestions in order to avoid this ?

I have tried switching the current store to global in the front but without luck :

    // Temporarly switch store to global to fix the media gallery scope bug
    // @see https://github.com/magento/community-features/issues/23
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $storeManager = $objectManager->get('\Magento\Store\Model\StoreManagerInterface');
    $currentStoreId = $storeManager->getStore()->getStoreId();
    $storeManager->setCurrentStore(0);
    $galleryImages = $block->getGalleryImages(); // This should get gallery with global settings, but it doesn't
    $storeManager->setCurrentStore($currentStoreId);
    ...
    // Display gallery images...

For now I told my customer to systematically select the store scope when editing the media gallery, but this is very time consuming when handling a large catalog with several stores.

I have seen the SQL query to delete all store related media gallery settings, but I'm quite sure my customer already has some store specific settings.

We migrated the data from Magento 1, but it seems the problem is only present in Magento 2.

Thank you for your help :) Mathieu.