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;
// commented out the if condition below to include the default store id 0 when we check the uniqueness of the block
//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 <[email protected]> */
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;
// commented out the if condition below to include the default store id 0 when we check the uniqueness of the block
//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 <[email protected]>
*/
-->
<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 <[email protected]>
*/
\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 !
identifiers
and check it. It will work.