2

We have been using CMS blocks with the same identifiers (see image), to be able to use child themes and include the these CMS blocks to several store views.

CMS Block Identifier

After a upgrade to Magento 2.3.3 that's not working anymore.

Error

Anyone have a solution for this or can shed some light?

Thanks,

EDIT

Found This at GitHub:

https://github.com/magento/magento2/issues/4831

This question has an open bounty worth +50 reputation from Alldo ending in 4 days.

This question has not received enough attention.

I'm looking for a solution to this issue.

  • Please use unique identifiers and check it. It will work. – Dhaduk Mitesh 2 days ago
  • I really want continue using identifiers with the same names, as I have done in earlier versions of Magento. It's (was) a great feature when using a lot of child themes in a multistore setup. – Alldo 2 days ago
1

I could replicate the same issue in my m2 local instance and identified the reason that you had this issue, also provided below a quick fix for this.

Cause of the issue

There's a difference in code between 2.3.3. and 2.2.x versions in CMS Block ResourceModel Class vendor/magento/module-cms/Model/ResourceModel/Block.php in the method getIsUniqueBlockToStores

https://github.com/magento/magento2/blob/2.3.3/app/code/Magento/Cms/Model/ResourceModel/Block.php

In this method, they check for uniqueness of the block id to selected store(s). In your case, it fails because its not unique as you have same id for both store-view and all store views.

In the recent Magento 2.3.x. version it checks the database table cms_block_store to confirm whether the static block exists, only if its a default store.

Whereas in the prior versions it does check the cms_block_store irrespective of the store scope of the block saved.

A quick fix (dont make this change, find the module given below under solution and install this in your store to fix your issue.)

removed the condition to confirm whether its a default store to add the WHERE condition to check the cms_block_store always, as it was before, in CMS Block Resource Model.

vendor/magento/module-cms/Model/ResourceModel/Block.php

/**
     * Check for unique of identifier of block to selected store(s).
     *
     * @param AbstractModel $object
     * @return bool
     * @SuppressWarnings(PHPMD.BooleanGetMethodName)
     */
    public function getIsUniqueBlockToStores(AbstractModel $object)
    {
        $entityMetadata = $this->metadataPool->getMetadata(BlockInterface::class);
        $linkField = $entityMetadata->getLinkField();
        $stores = (array)$object->getData('store_id');
        $isDefaultStore = $this->_storeManager->isSingleStoreMode()
            || array_search(Store::DEFAULT_STORE_ID, $stores) !== false;
        if (!$isDefaultStore) {
            $stores[] = Store::DEFAULT_STORE_ID;
        }
        $select = $this->getConnection()->select()
            ->from(['cb' => $this->getMainTable()])
            ->join(
                ['cbs' => $this->getTable('cms_block_store')],
                'cb.' . $linkField . ' = cbs.' . $linkField,
                []
            )
            ->where('cb.identifier = ?  ', $object->getData('identifier'));

        // commented out the if condition below to check the `cms_block_Store` tale always   
        //if (!$isDefaultStore) {
            $select->where('cbs.store_id IN (?)', $stores);
        //}


        if ($object->getId()) {
            $select->where('cb.' . $entityMetadata->getIdentifierField() . ' <> ?', $object->getId());
        }
        if ($this->getConnection()->fetchRow($select)) {
            return false;
        }
        return true;
    }

Solution (Create and Enable this Module)

Create the following directories and files as given below

File

app/code/StackExchange/Override/Model/ResourceModel/Block.php

Code

<?php

/* @author Jerome Dennis <haijerome@gmail.com> */ 

namespace StackExchange\Override\Model\ResourceModel;
use Magento\Framework\Model\AbstractModel;
use Magento\Cms\Api\Data\BlockInterface;
use Magento\Store\Model\Store;
use Magento\Store\Model\StoreManagerInterface;

/**
 * CMS block model
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 */
class Block extends \Magento\Cms\Model\ResourceModel\Block
{
    /**
     * Check for unique of identifier of block to selected store(s).
     *
     * @param AbstractModel $object
     * @return bool
     * @SuppressWarnings(PHPMD.BooleanGetMethodName)
     */
    public function getIsUniqueBlockToStores(AbstractModel $object)
    {
        $entityMetadata = $this->metadataPool->getMetadata(BlockInterface::class);
        $linkField = $entityMetadata->getLinkField();

        $stores = (array)$object->getData('store_id');
        $isDefaultStore = $this->_storeManager->isSingleStoreMode()
            || array_search(Store::DEFAULT_STORE_ID, $stores) !== false;
        if (!$isDefaultStore) {
            $stores[] = Store::DEFAULT_STORE_ID;
        }

        $select = $this->getConnection()->select()
            ->from(['cb' => $this->getMainTable()])
            ->join(
                ['cbs' => $this->getTable('cms_block_store')],
                'cb.' . $linkField . ' = cbs.' . $linkField,
                []
            )
            ->where('cb.identifier = ?  ', $object->getData('identifier'));

            $select->where('cbs.store_id IN (?)', $stores);

        if ($object->getId()) {
            $select->where('cb.' . $entityMetadata->getIdentifierField() . ' <> ?', $object->getId());
        }

        if ($this->getConnection()->fetchRow($select)) {
            return false;
        }

        return true;
    }
}

File

app/code/StackExchange/Override/etc/adminhtml/di.xml

Code

<?xml version="1.0"?>
<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Cms\Model\ResourceModel\Block" type="StackExchange\Override\Model\ResourceModel\Block" />
</config>

File

app/code/StackExchange/Override/etc/module.xml

Code

<?xml version="1.0"?>
<!--
/**
 *   StackExchange_Override
 *   Jerome Dennis <haijerome@gmail.com>
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="StackExchange_Override" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Cms"/>
        </sequence>
    </module>
</config>

File

app/code/StackExchange/Override/registration.php

Code

<?php
/**
 *   StackExchange_Override
 *   Jerome Dennis <haijerome@gmail.com>
 */

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'StackExchange_Override',
    __DIR__
);

I assume that you have a development / staging instance and you are on developer mode. (dont try this on production before you try this on development or staging server)

  • enable the module (php bin/magento module:enable StackExchange_Override)
  • register the module in the set up table (php bin/magento setup:upgrade)
  • remove the generated files generated\code and regenrate (php bin/magento setup:di:compile)
  • clean the cache types

This will certainly fix the issue that you face (tested and verified on my local instance). Thank You !

enter image description here enter image description here

  • I have tried your fix, and I can save the blocks in "All Store Views" now, that's great. But I can't save the blocks in specific "Store Views", they still show the error about the identifier properties. Am I missing something? Thanks, – Alldo 15 hours ago
  • Note that this is when editing already created CMS blocks in store views, not creating new ones (haven't tested that yet). – Alldo 15 hours ago
0

The first block is set to store view "All Store Views".

Change this to a different store view and you can save the block.

  • But I want that block identifier name for "All Store Views", that's the point. Since upgrading Magento to version 2.3.3, that feature has stopped working. – Alldo 2 days ago
  • You can use the same block identifier name. You can't use All Store Views and another store view for a block with the same identifier name. – Peter Stuifzand 2 days ago
  • No not right now, but I could before, that's the problem. Look at the image in the post, its a real image taken from the actual store, not an example what I want to achieve. – Alldo 2 days ago
0

Please remove the first block from the site mentioned in your screenshot.

Then create blocks with same identifier for all available stores and save. Voila, now the site will have same identifier across all store views, hope this is enough?

Additionally, one thing to let you know is that same identifier cant be used if its set for "all store views" in a block. This is the default property of Magento and it should be. Otherwise, it wont make any sense i think. Good luck.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.