Как загрузить JSON в поле объекта данных Silverstripe - PullRequest
0 голосов
/ 04 марта 2019

Недавнее обновление версии Silverstripe до 4.3.1, похоже, нарушило некоторые функциональные возможности, когда объект данных загружается как текстовое поле в формате JSON.

Объект выглядит следующим образом:

class Foo extends DataObject 

  private static $db = [
    'Name' => 'Varchar',
    'Description' => 'Text',
    'Models' => 'Text',
  ];

Затем есть функция для загрузки объекта с помощью JSON, сгенерированного из запроса формы:

$data = json_decode($request->getBody(), true);
$foo = new Foo();
$foo->update($data);

Вот пример JSON $data:

"Name":"Test",
"Description":"Wangle fangle blurble wurgle.",
"Models":{
   "fish":{"trout":10,"salmon":15,"sturgeon":20},
   "vegetable":{"carrot":1,"cabbage":2,"leek":3},
   "sauce":{"chipotle":6,"tomato":4,"soy":2}
 }

До недавнего времени «Модели»структура будет сохранена в поле «Модели» в виде текста:

 "fish":{"trout":10,"salmon":15,"sturgeon":20},
 "vegetable":{"carrot":1,"cabbage":2,"leek":3},
 "sauce":{"chipotle":6,"tomato":4,"soy":2}

Но теперь мы получаем следующую ошибку:

DataObject::setField: Models only accepts scalars at /var/www/example/vendor/silverstripe/framework/src/ORM/DataObject.php:2648

Строка 2640 в DataObject.php говорит:

If this is a proper database field, we shouldn't be getting non-DBField objects

Было ли последнее исправление безопасности, блокирующее попытку загрузки объекта JSON в поле?

Может кто-нибудь помочь с сохранением JSON моделей втекстовое поле?

1 Ответ

0 голосов
/ 05 марта 2019

@ wmk здесь, это ожидаемое поведение для предотвращения уязвимостей безопасности (см. SS-2018-021 ).Изменение в 4.3.1 состоит в том, чтобы предотвратить случайное разрешение пользователям вставлять нескалярные значения в ваши модели данных, когда вы указали в качестве значения поля БД скалярный тип.

В вашем случае выПопытка записи массива в текстовое поле, которое корректно блокируется silverstripe / framework.

Самый простой обходной путь для вас - перекодировать части массива данных, которые, как вы знаете, вы хотите сохранитькак текстовый BLOB-объект JSON, например:

$data = json_decode($request->getBody(), true);
$data['Models'] = json_encode($data['Models']); // re-encode as JSON before saving
$foo = new Foo();
$foo->update($data);

Это гарантирует, что вы все еще будете записывать JSON в виде текста в текстовое поле.

Также, как упоминалось @wmk, другой жизнеспособный параметр -написать свой собственный DBField, который принимает нескалярные значения и берет на себя ответственность за безопасную запись их в базу данных.Это было бы полезно, если вы пишете DBField, который имеет дело с ГИС или пространственными данными .В вашем конкретном примере я думаю, что вы можете обойтись без гарантии, что он все еще закодирован в виде строки, как мой пример.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...