0

I have added a new column with declarative schema found here: https://devdocs.magento.com/guides/v2.4/extension-dev-guide/declarative-schema/db-schema.html

Is all added to the table cms_page_store and the backend form but when I save I can see the data in post but is not populating the field in cms_page_store table.

My setup:

db_schema.xml

<?xml version="1.0"?>
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
 <table name="cms_page_store">
 <column xsi:type="varchar" name="ucri" nullable="true" length="50" comment="Unique Code Cmc Page Relation Identifier"/>
 <constraint xsi:type="unique" referenceId="CMS_PAGE_STORE_UCRI_STORE_ID">
 <column name="ucri"/>
 <column name="store_id"/>
 </constraint>
 </table>
</schema>

cms_page_form.xml

<?xml version="1.0" encoding="UTF-8"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
 <fieldset name="search_engine_optimisation">
 <field name="ucri" sortOrder="1">
 <argument name="data" xsi:type="array">
 <item name="config" xsi:type="array">
 <item name="dataType" xsi:type="string">text</item>
 <item name="label" xsi:type="string" translate="true">Unique Code</item>
 <item name="formElement" xsi:type="string">input</item>
 <item name="source" xsi:type="string">page</item>
 <item name="dataScope" xsi:type="string">ucri</item>
 </item>
 </argument>
 </field>
 </fieldset>
</form>

db_shcema_whitelist.json

{
 "cms_page_store": {
 "column": {
 "ucri": true
 },
 "constraint": {
 "CMS_PAGE_STORE_UCRI_STORE_ID": true
 }
 }
}

Any idea ami missing something else here ?

asked Mar 16, 2021 at 12:05
4
  • is there any specific requirement of storing data in "cms_page_store" table? you can create custom column in "cms_page" table and data will be automatically stored in table and populated in backend using this approach. Commented Mar 16, 2021 at 15:19
  • @RahulBarot Yes, I guess that would be the solution which I've already tried and work. But I have a problem with that as I need this custom field to be unique with store_id field. adding it to cms_page_store I have added unique key between them, But how can I do that adding to cms_page table? When I run setup:db-declaration:generate-whitelist gives error Table cms_page do not have column with name store_id. Commented Mar 16, 2021 at 15:26
  • Yes, it will show error because "cms_page" table does not contain the store_id column, on page save it checks for any new store is added to page then it will create entry to "cms_page_store" with page row_id and store_id. Commented Mar 16, 2021 at 15:31
  • Yes, unfortunately that's not possible as the Docs says: The primary and unique constraints are called "internal" constraints, because they can be applied only to the scope of the table where they are created. Internal constraints define one or more column subnodes. Each subnode defines a constrained column Commented Mar 16, 2021 at 15:36

1 Answer 1

0

You need to implement the logic to bind two fields as unique, below class is used to store data in the cms_page_store table.

You can override it using preference or you can add your custom logic in plugin and store custom column data.

Magento\Cms\Model\ResourceModel\Page\Relation\Store\SaveHandler

In the execute function you can find code for delete and insert record as below

For delete

$delete = array_diff($oldStores, $newStores);
if ($delete) {
 $where = [
 $linkField . ' = ?' => (int)$entity->getData($linkField),
 'store_id IN (?)' => $delete,
 ];
 $connection->delete($table, $where);
}

For insert

$insert = array_diff($newStores, $oldStores);
if ($insert) {
 $data = [];
 foreach ($insert as $storeId) {
 $data[] = [
 $linkField => (int)$entity->getData($linkField),
 'store_id' => (int)$storeId
 ];
 }
 $connection->insertMultiple($table, $data);
}

In above code you can add your custom column value in $data array

$data[] = [
 $linkField => (int)$entity->getData($linkField),
 'store_id' => (int)$storeId,
 'ucri' => $entity->getData('ucri')
];

Also in order to show it in backend you need to override the collection responsible for it, otherwise value will be store in db but it will not be visible on backend form.

answered Mar 16, 2021 at 15:52
2
  • Thanks, I guess there is a bit more work I have to not overwrite core function but to extend saveHandler using ExtensionPool? Like in this post magento.stackexchange.com/questions/146994/… Commented Mar 16, 2021 at 16:09
  • Yes you can do it via saveHandler. Commented Mar 17, 2021 at 9:26

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.