0

I have created a custom admin form using a UI component and added a multi-select shipping method field. I've successfully retrieved the selected values in an array and stored them as a string in my custom table. However, when I retrieve the values in edit mode, they are displayed in an array format with double quotes. This makes it difficult to fetch the shipping methods with their codes while editing existing records. I need to store the values without double quotes in the database table. Can you please review my code and provide suggestions on how I can achieve this?

app/code/MyModule/CustomForm/etc/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="custom_form" resource="default" engine="innodb" comment="Custom Table">
        ....
        <column xsi:type="varchar" name="shipping_methods" nullable="true" length="255" comment="Shipping Methods"/>
        ....
    </table>
</schema>

app/code/MyModule/CustomForm/view/adminhtml/ui_component/custom_form.xml

<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    ....

    <fieldset name="general">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="label" xsi:type="string" translate="true">General Information</item>
            </item>
        </argument>
        ....
        <!-- Other form fields goes here -->
        ....
        <!-- Shipping Method form fields code START -->
        <field name="shipping_methods">
            <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">Shipping Carriers and Methods</item>
                    <item name="formElement" xsi:type="string">multiselect</item>
                    <item name="source" xsi:type="string">shipping_methods</item>
                    <item name="dataScope" xsi:type="string">shipping_methods</item>
                </item>
                <item name="options" xsi:type="object">Magento\Shipping\Model\Config\Source\Allmethods</item>
            </argument>
        </field>
        <!-- Shipping Method form fields code END -->
    </fieldset>
</form>

app/code/MyModule/CustomForm/Controller/Adminhtml/Edit/Save.php

<?php

namespace MyModule\CustomForm\Controller\Adminhtml\Edit;

use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
....

class Save extends Action
{
    protected $_resultPageFactory;

    public function __construct(Context $context, PageFactory $resultPageFactory)
    {
        parent::__construct($context);
        $this->_resultPageFactory = $resultPageFactory;
    }

    public function execute()
    {
        if (!$this->getRequest()->getPostValue()) {
            $this->_redirect('mymodule_customform/*/');
        }
    
        ....
            $data = $this->getRequest()->getPostValue();
            
            $id = (int)$this->getRequest()->getParam('id');
            if ($id) {
                /** @var $model \MyModule\CustomForm\Model\Form */
                $model = $this->formRepository->getById($id);
            } else {
                /** @var $model \MyModule\CustomForm\Model\Form */
                $model = $this->formRepository->getEmptyEntity();
            }

            $data = $this->prepareData($data);
            $model->loadPost($data);
            $this->_session->setPageData($model->getData());

            $this->formRepository->save($model);
            $this->messageManager->addSuccessMessage(__('Form Record saved.'));
            $this->_session->setPageData(false);

            return $resultPage;
        }
    
        /**
        * Prepares specific data
        *
        * @param array $data
        * @return array
        */
        protected function prepareData($data)
        {
                ....
                if (isset($data['shipping_methods']) && !empty($data['shipping_methods']))
                {
                        $data['shipping_methods'] = implode(',', $data['shipping_methods']);
                } else {
                    $data['shipping_methods'] = null;
                }
                ....
                return $data;
            }
}

app/code/MyModule/CustomForm/Model/Form.php

<?php
namespace MyModule\CustomForm\Model;

use Magento\Framework\DataObject;
use Magento\Quote\Model\Quote\Address;
use Magento\Quote\Model\Quote\Address\Rate;
use Magento\Quote\Model\Quote\Address\RateResult\Method;
use MyModule\CustomForm\Api\Data\FormInterface;
use MyModule\CustomForm\Api\FormEntityInterface;

class Form extends \Magento\Backend\Model\AbstractModel implements FormInterface, FormEntityInterface
{
    ....
public function __construct(
Context $context,
....
)
    {
        parent::__construct($context);
        ....
    }

    /**
     * Retrive ID
     *
     * @return int
     */
    public function getId()
    {
        return $this->getData(self::ID);
    }

    /**
     * Set ID
     *
     * @param int $id id
     *
     * @return int
     */
    public function setId()
    {
        return $this->setData(self::ID, $id);
    }
    
    ....
    
    /**
     * Retrieve Shipping Methods
     *
     * @return string
     */
    public function getShippingMethods()
    {
        return $this->getData(self::SHIPPING_METHODS);
    }

    /**
     * Set Shipping Methods
     *
     * @param string $shippingMethods
     * 
     * @return string
     */
    public function setShippingMethods($shippingMethods)
    {
        return $this->setData(self::SHIPPING_METHODS, $shippingMethods);
    }
}

This stores the Shipping Methods as below in db table rows:

id name shipping_methods
1 Test "flatrate_flatrate,tablerate_bestway,freeshipping_freeshipping"

Till here working fine, but when I fetch the Shipping Methods and convert it to array in Edit form. Then it gives me array values as below (with double quotes):

shipping_methods => Array
    (
        [0] => "flatrate_flatrate
        [1] => tablerate_bestway
        [2] => freeshipping_freeshipping"
    )

Due to the double quotes I'm unable to fetch the shipping methods with codes when editing existing record.

I want the values to be stored without double quotes in the db table.

Can you guys please review and suggest me how can I fix this?

2 Answers 2

1

Your value which is store in database is wrong, it should be like this

"flatrate_flatrate","tablerate_bestway","freeshipping_freeshipping"

instead of this

"flatrate_flatrate,tablerate_bestway,freeshipping_freeshipping"

First try to print/log the value of $data['shipping_method'] you'll get the idea then and try to debug before and after implode() function

1
  • I tried to debug in the same way and found that my values are passing with commas only, such as flatrate_flatrate, tablerate_bestway, freeshipping_freeshipping. I also tried to add values using serialize and unserialize methods, but the values are always saved within double quotes, like this: - With quotes form: ""flatrate_flatrate", "tablerate_bestway", "freeshipping_freeshipping"" - In serialized form: "[\"flatrate_flatrate\", \"tablerate_bestway\", \"freeshipping_freeshipping\"]" It always adds double quotes before and after the stored values. Commented Dec 28, 2023 at 14:45
1

You can use str_replace function for remove double quotes, like this

str_replace('"', '', $data['shipping_methods']);

echo str_replace('"', '', "flatrate_flatrate, tablerate_bestway, freeshipping_freeshipping");
1
  • The shipping_method values are being passed without double quotes from my save controller. However, when they are inserted into the database, they are stored within double quotes. This is causing an issue. I have tried using str_replace, but the value is still being stored with double quotes. Commented Dec 29, 2023 at 9:28

Your Answer

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

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