verbb / vizy

A flexible visual editor for Craft CMS
Other
43 stars 8 forks source link

Craft 4 : Undefined array key "type" #181

Closed denisyilmaz closed 1 year ago

denisyilmaz commented 1 year ago

Describe the bug

Referencing Issue #168 for Craft 3 this bug is also appearing when adding a block to a vizy field which is part of a NEO Block.

Stacktrace:

Stack trace:
#0 /var/www/html/vendor/craftcms/cms/src/web/ErrorHandler.php(79): yii\base\ErrorHandler->handleError(2, 'Undefined array...', '/var/www/html/v...', 215)
#1 /var/www/html/vendor/verbb/vizy/src/models/NodeCollection.php(215): craft\web\ErrorHandler->handleError(2, 'Undefined array...', '/var/www/html/v...', 215)
#2 /var/www/html/vendor/verbb/vizy/src/models/NodeCollection.php(66): verbb\vizy\models\NodeCollection->_populateNodes(Array)
#3 /var/www/html/vendor/verbb/vizy/src/fields/VizyField.php(309): verbb\vizy\models\NodeCollection->__construct(Object(verbb\vizy\fields\VizyField), Array, Object(craft\elements\Entry))
#4 /var/www/html/vendor/craftcms/cms/src/base/Element.php(4774): verbb\vizy\fields\VizyField->normalizeValue(Array, Object(craft\elements\Entry))
#5 /var/www/html/vendor/craftcms/cms/src/base/Element.php(3947): craft\base\Element->normalizeFieldValue('text')
#6 /var/www/html/vendor/craftcms/cms/src/controllers/ElementsController.php(1655): craft\base\Element->setFieldValuesFromRequest('fields')
#7 /var/www/html/vendor/craftcms/cms/src/controllers/ElementsController.php(1245): craft\controllers\ElementsController->_applyParamsToElement(Object(craft\elements\Entry))
#8 [internal function]: craft\controllers\ElementsController->actionApplyDraft()
#9 /var/www/html/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array)
#10 /var/www/html/vendor/yiisoft/yii2/base/Controller.php(178): yii\base\InlineAction->runWithParams(Array)
#11 /var/www/html/vendor/yiisoft/yii2/base/Module.php(552): yii\base\Controller->runAction('apply-draft', Array)
#12 /var/www/html/vendor/craftcms/cms/src/web/Application.php(301): yii\base\Module->runAction('elements/apply-...', Array)
#13 /var/www/html/vendor/craftcms/cms/src/web/Application.php(625): craft\web\Application->runAction('elements/apply-...', Array)
#14 /var/www/html/vendor/craftcms/cms/src/web/Application.php(280): craft\web\Application->_processActionRequest(Object(craft\web\Request))
#15 /var/www/html/vendor/yiisoft/yii2/base/Application.php(384): craft\web\Application->handleRequest(Object(craft\web\Request))
#16 /var/www/html/web/index.php(12): yii\base\Application->run()
#17 {main}

Steps to reproduce

  1. Create a simple vizy text field with a single block
  2. Create a simple NEO field with a single block that uses the vizy text field.
  3. Try to save the entry with a block created in the vizy field

Craft CMS version

4.2.8

Plugin version

2.0.8

Multi-site?

No

Additional context

No response

engram-design commented 1 year ago

I can't seem to replicate this exactly as you've described. I was only able to replicate the issue with the database and project files for https://github.com/verbb/vizy/issues/168 - if that's something you could supply us with?

yoannisj commented 1 year ago

@engram-design I bumped into the same error and I think it's a conflicting issue when the same Vizy field is added both to a Neo block, and the element owning that Neo block's field.

I created a very simple craft project with ddev which you can use to reproduce the issue:


The Page entry type has the Vizy field Rich Content at the root-level, and inside the Content Blocks > Section Neo block and this seems to be causing the issue. Indeed, if you remove the root-level Rich Content field from that entry type and follow the steps to reproduce above, the error is not thrown.

In my attempt to debug, I looked at the form data sent in the request body upon Save, and noticed the Image block's image field data was submitted twice (see screenshot):

Maybe that data is not being parsed correctly and confuses Craft or Vizy when it's trying to populate the Entry it being saved?

craft-vizy-181-request-data

engram-design commented 1 year ago

Thanks for the reproduction @yoannisj that's super helpful!

What this comes down to is how Vizy serializes content within a block, and it being overridden. It's unfortunately complex, because we need to handle fields that use jQuery (element selects, Neo, Matrix, etc). For a Vizy field, we only care about overall serialized version of the field data, not any of the inner field data. The Vue component will serialize the content for us, so it's all compatible with TipTap/Vizy.

To illustrate what's going on, here's the POST request (these are 4 separate lines):

fields[richContent][blocks][vizy-block-X2y6Pysezv][fields][image]: 

fields[richContent][blocks][vizy-block-X2y6Pysezv][fields][image][]: 6

fields[richContent]: [{"type":"vizyBlock","attrs":{"id":"vizy-block-X2y6Pysezv","enabled":true,"collapsed":false,"values":{"type":"type-WDAor1xNrx","content":{"fields":{"image":[]}}}}}]

fields[richContent][blocks][vizy-block-nbvf2O5uEL][fields][image]: 

Because we're using Craft's element select control, they output input elements within the Vizy block. This is useful, because we then use that to serialize the content of that block in the Vizy field. You can see that in the fields[richContent] where everything within the Vizy block is turned into JSON, which is then saved to the database. That's all we care about.

The issue is that Craft will also add those inner input elements to the POST request. While Vizy normally ignores these, you can see the final line is setting fields[richContent][blocks][vizy-block-nbvf2O5uEL][fields][image] which completely overrides and replaces the former line data!

Long story short, should be fixed for the next release. To get this early, change your verbb/vizy requirement in composer.json to:

"require": {
  "verbb/vizy": "dev-craft-4 as 2.0.10",
  "...": "..."
}

Then run composer update.

In case you're interested in what we're doing now, to get around this, we're changing where the Vizy content is stored to somewhere it's not going to be overwritten:

fields[richContent][vizyData]: [{"type":"vizyBlock","attrs":{"id":"vizy-block-X2y6Pysezv","enabled":true,"collapsed":false,"values":{"type":"type-WDAor1xNrx","content":{"fields":{"image":[]}}}}}]
engram-design commented 1 year ago

Fixed in 2.0.11