2
I've made a custom module with a ui component in the admin. It's a grid that is filled with block data. 

When adding a block, and saving it in Controller/Adminhtml/Content/Save.php, exception
"Array to string conversion in /data/web/magento2/vendor/magento/framework/DB/Adapter/Pdo/Mysql.php on line 3028" is given.

> Controller/Adminhtml/Content/Save.php

<?php 

    use Magento\Framework\App\Filesystem\DirectoryList;
    use Digitaq\HomepageContent\Model\BlockContent;

    class Save extends \Magento\Backend\App\Action
    {  
        public function execute()
        {    
            $data = $this->getRequest()->getPostValue();
            if ($data) {    
                $id = $this->getRequest()->getParam('id');
                $model = $this->_objectManager->create('Digitaq\HomepageContent\Model\BlockContent')->load($id);

                if (!$model->getId() && $id) {
                    $this->messageManager->addError(__('This item no longer exists.'));
                    return $resultRedirect->setPath('*/*/');
                }    
                $model->setData($data);    
                try {

                    $model->save();
                    //Display success message
                    $this->messageManager->addSuccess(__('The Frist Grid Has been Saved.'));
                    //clear previous data from session
    //                $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData(false);

                    //If save & continue, head back
                    if ($this->getRequest()->getParam('back')) {
                        $this->_redirect('*/*/edit', array('id' => $model->getId(), '_current' => true));
                        return;
                    }
                    $this->_redirect('*/*/');
                    return;
                } catch (\Magento\Framework\Model\Exception $e) {
                    $this->messageManager->addError($e->getMessage());
                } catch (\RuntimeException $e) {
                    $this->messageManager->addError($e->getMessage());
                } catch (\Exception $e) {
                    $this->messageManager->addException($e, __('Something went wrong while saving the block.'));
                }

                $this->_getSession()->setFormData($data);
                $this->_redirect('*/*/edit', array('id' => $this->getRequest()->getParam('id')));
                return;
            }
            $this->_redirect('*/*/');
        }
    }

> Model/BlockContent.php

<?php

    class BlockContent extends \Magento\Framework\Model\AbstractModel
    {
        protected function _construct()
        {
            $this->_init('\Vendor\Module\Model\ResourceModel\BlockContent');
        }
    }

> Model/ResourceModel/BlockContent.php
<?php

    use Magento\Framework\DB\Select;
    use Magento\Framework\Model\ResourceModel\Db\AbstractDb;

    class BlockContent extends AbstractDb
    {
        protected function _construct()
        {
            $this->_init('homepagecontent_blocks', 'id');
        }
    }

> Model/ResourceModel/BlockContent/Collection.php

<?php

    class Collection extends \Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult
    {
        protected function _construct()
        {
            $this->_init(
                'Vendor\Module\Model\BlockContent',
                'Vendor\Module\Model\ResourceModel\BlockContent'
            );
        }
    }

> Model/ResourceModel/BlockContent/Grid/Collection.php

<?php


    use Magento\Framework\View\Element\UiComponent\DataProvider\Document;
    use Magento\Framework\Data\Collection\Db\FetchStrategyInterface as FetchStrategy;
    use Magento\Framework\Data\Collection\EntityFactoryInterface as EntityFactory;
    use Magento\Framework\Event\ManagerInterface as EventManager;
    use Psr\Log\LoggerInterface as Logger;

    class Collection extends \Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult
    {
        /**
         * @inheritdoc
         */
        protected $document = Document::class;

        /**
         * Initialize dependencies.
         *
         * @param EntityFactory $entityFactory
         * @param Logger $logger
         * @param FetchStrategy $fetchStrategy
         * @param EventManager $eventManager
         * @param string $mainTable
         * @param string $resourceModel
         */
        public function __construct(
            EntityFactory $entityFactory,
            Logger $logger,
            FetchStrategy $fetchStrategy,
            EventManager $eventManager,
            $mainTable = 'homepagecontent_blocks',
            $resourceModel = '\Vendor\Module\Model\ResourceModel\BlockContent'
        ) {
            parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $mainTable, $resourceModel);
        }
    }

A var_dump of $data displays: 

    array (size=2)
      'form_key' => string 'KGogknDar22zgria' (length=16)
      'content' => 
        array (size=8)
      'id' => string '1241' (length=4)
      'css_grid_column_from' => string '2' (length=1)
      'css_grid_column_to' => string '2' (length=1)
      'css_grid_row_from' => string '1' (length=1)
      'css_grid_row_to' => string '3' (length=1)
      'content_type' => string 'slider' (length=6)
      'status' => string '1' (length=1)
      'content' => string '<p>asdgsad</p>' (length=14)

Could anyone help me trying to debug this?
1

Some kind of data which should have string-type was not converted by your model before saving.

I can give you a way how to debug it:

Open a core file /data/web/magento2/vendor/magento/framework/DB/Adapter/Pdo/Mysql.php, find line 3028, and change line

$value = (string)$value;

to this one:

if (is_array($value)) {
    var_dump($value);
    die();
}
$value = (string)$value;

Note: preferred way is to use the xDebug for that purposes.

Reload a page. Now you can see a data which should be string but not an array. Find the corresponding column and modify your code: add data-convertor which will change data type to a desired one (string). Usually it is implode($value) or json_serrialize($value).

You can mark the content field as a serializable field in the corresponding resource model:

protected $_serializableFields = [ 'content' => [null, []] ]; 

This way magento resource model each time will convert this data during save\load process

PS: using xDebug you can add a conditional breakpoint:

conditional breakpoint

  • The form consists of two tabs, with on the second tab a WYSIWYG editor, the content of this editor should go in the content column in my database, as a string ofcourse, however the entire array is given again as a value? – Digitaq Sep 5 '18 at 11:48
  • @Digitaq when data used in form as an array-type, but stored in DB as a string - you should serialized\unserialize it each time when you saving it or after you load it. You can find example in the sales-rule midel, where conditions used in the form as an array, but stored in the database as a string. It is just converted from/to JSON each time. – Siarhey Uchukhlebau Sep 5 '18 at 11:51
  • @Digitaq you can mark the content field as a serializable field in the corresponding resource model: protected $_serializableFields = [ 'content' => [null, []] ] . This way magento resource model each time will convert this data during save\load process. – Siarhey Uchukhlebau Sep 5 '18 at 11:56
  • Thanks, this solved the problem! However, data is not inserted in the database still, all values changed to 0 or null – Digitaq Sep 5 '18 at 12:05

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.