moveLangAttributes(); }); static::saved(function ($model) { $model->moveLangAttributes(false); }); } /** * Join language data * * @param QueryBuilder $query * @param array $columns * @return array result columns */ public function joinLangs($query, array $columns = ['*']) { $lang = $this->langDefault(); if ($columns === ['*']) { if ($query->hasColumns()) { $columns = $query->getColumns(); } } else { if ($query->hasColumns()) { $columns = array_merge($query->getColumns(), $columns); } } if ($columns === ['*'] || in_array($this->getTable() . '.*', $columns, true)) { foreach ($this->langColumns() as $column) { $columns[] = $column; } } foreach ($columns as $key => $column) { if ($this->isLangColumn($column)) { $columns[$key] = $this->prefixColumn($column . '_' . $lang) . ' as ' . $column; } else { $columns[$key] = $this->prefixColumn($column); } } return $columns; } /** * Transforms translatable data key_lang=>value to key=>[lang=>value, ...] * * @param bool $removeOriginals * @return void */ public function langDataTransform($removeOriginals = true) { $columns = $this->langColumns(); if (empty($columns) || $columns === ['*']) { return; } $langs = $this->langsList(); $langsFill = array_fill_keys($langs, ''); $attr = $this->attributesToArray(); foreach ($columns as $col) { $values = $langsFill; foreach ($langs as $lang) { $key = $col . '_' . $lang; if (array_key_exists($key, $attr)) { $values[$lang] = $attr[$key]; } if ($removeOriginals) { unset($this->attributes[$key]); } } parent::setAttribute($col, $values); } } /** * Covers translatable attributes * * @param string $key * @param mixed $value * @return mixed */ public function setAttribute($key, $value) { if ($this->isLangColumn($key)) { $langs = $this->langsList(); if (is_string($value)) { $value = [$this->langDefault() => $value]; } if (is_array($value)) { foreach ($value as $lang => $v) { if (in_array($lang, $langs, true)) { $col = $key . '_' . $lang; if ($v !== ($this->attributes[$key][$lang] ?? '')) { $this->changes[$col] = $v; parent::setAttribute($col, $v); } } } } return $this; } return parent::setAttribute($key, $value); } }