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 Answer
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:
-
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?– DigitaqSep 5, 2018 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. Sep 5, 2018 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. Sep 5, 2018 at 11:56 -
Thanks, this solved the problem! However, data is not inserted in the database still, all values changed to 0 or null– DigitaqSep 5, 2018 at 12:05