Написал поведение для построения цепочек вложенностей, для метода POST работает, а для метода PATCH не точно работает. Для метода PATCH если не заполнены поля связей, то они же и остаются (- и это правильно для патча), но если вводится новое ИД связей то поля должны заново собираться, и в тех у которых нет значений должны быть равны NULL , но метод ПАТЧ null оставляет старым значением.
вот как выглядят связи:
Код: Выделить всё
"data": {
"code": "23ddf5527t1111411",
"locality__id": null,
"district__id": "d39c47e9-aef6-4acb-9122-bced6afde4d5",
"region__id": null,
"country__id": "7189a63c-d36f-4b81-8721-0b10d9392f0a",
"parts_of_world__id": "85ef4763-5e79-42e7-b13b-03f7cc34b62b",
"name": "fddf",
"language": "en",
"id": "5d96d46c-8aa5-4f0a-b127-6f970d4d5e6e"
}
Код: Выделить всё
"locality__id": null,
"district__id": "d39c47e9-aef6-4acb-9122-bced6afde4d5",
"region__id": null,
"country__id": "7189a63c-d36f-4b81-8721-0b10d9392f0a",
"parts_of_world__id": "85ef4763-5e79-42e7-b13b-03f7cc34b62b",
Код: Выделить всё
class GeoAttributesBehavior extends Behavior
{
public $rules;
public $tableName;
private $treeModels = [];
private $treeModelsAttributes = [];
private $__attr;
public function init()
{
$this->treeModels = [
1 => PartsOfWorld::className(),
2 => Country::className(),
3 => Region::className(),
4 => District::className(),
5 => Locality::className(),
6 => Section::className()
];
$this->treeModelsAttributes = [
1 => 'parts_of_world__id',
2 => 'country__id',
3 => 'region__id',
4 => 'district__id',
5 => 'locality__id',
6 => 'section__id'
];
parent::init();
}
public function events()
{
return [
ActiveRecord::EVENT_BEFORE_UPDATE => 'beforeUpdate',
ActiveRecord::EVENT_AFTER_UPDATE => 'afterUpdate',
ActiveRecord::EVENT_BEFORE_INSERT => 'beforeInsert',
];
}
public function afterUpdate($event)
{
}
public function beforeUpdate($event)
{
$params = Yii::$app->request->post();
if (!empty($params['geo_level']) && !empty($params['geo_level__id'])) {
if(UuidHelper::isValid($params['geo_level__id'])) {
$this->clearAttributes($event);
//$event = ($this->owner)::findOne($event->sender->id);
}
}
$attributes = [];
$valid_attribute = null;
$count_values = 0;
foreach ($this->rules[0] as $geoAttribute) {
if (!empty($event->sender->{$geoAttribute})) {
$count_values++;
$valid_attribute = $geoAttribute;
} else {
$this->__attr[] = $geoAttribute;
$attributes[$geoAttribute] = null;
}
}
if ($count_values > 0) {
$this->fieldsAttribute($event, $valid_attribute);
}
}
public function beforeInsert($event)
{
$valid_attribute = null;
foreach ($this->rules[0] as $geoAttribute) {
if (!empty($event->sender->{$geoAttribute})) {
$valid_attribute = $geoAttribute;
} else {
$this->__attr[] = $geoAttribute;
}
}
$this->fieldsAttribute($event, $valid_attribute);
}
public function fieldsAttribute($event, $attribute)
{
if (!$attribute) {
return false;
}
$level = array_search($attribute, $this->treeModelsAttributes);
$findValue = $event->sender->{$this->treeModelsAttributes[$level]};
if (!empty($findValue)) {
$__model = $this->treeModels[$level]::findOne($findValue);
foreach ($this->__attr as $attr) {
$event->sender->{$attr} = (!empty($__model->{$attr})) ? $__model->{$attr} : null;
}
$event->sender->{$attribute} = $findValue;
}
}
private function clearAttributes($event)
{
$Obj = $this->owner;
//$level = array_search(($Obj::className()), $this->treeModels);
$model = ($this->owner)::findOne($event->sender->id);
$attributes = [];
foreach ($this->treeModelsAttributes as $key => $att) {
if (!empty($model->{$att})) {
$attributes[$att] = null;
}
}
//echo "\n<pre>" . print_r($attributes,1) . "</pre>";
if (count($attributes)) {
Yii::$app->db->createCommand()
->update($this->tableName, $attributes, ['id' => $event->sender->id])
->execute();
// $event = ($this->owner)::findOne($event->sender->id);
}
}
}