_owner_key )) { return $this->_owner_key; } else { return $this->owner->primaryKey()[ 0 ]; } } /** * Set which attribute to use as $owner primary key to link language model * * @param string $value */ public function setOwnerKey(string $value) { $this->_owner_key = $value; } /** * Get language model attribute that is used as foreign key to $owner * @return string */ public function getLangKey():string { if(!empty( $this->_lang_key )) { return $this->_lang_key; } else { $owner = $this->owner; return $owner::getTableSchema()->name . '_id'; } } /** * Set which attribute to use as language model foreign key to $owner * * @param $value */ public function setLangKey(string $value) { $this->_lang_key = $value; } /** * Additional checks to attach this behavior * * @param ActiveRecord $owner * * @throws InvalidConfigException */ public function attach($owner) { if(empty( $this->object_lang )) { $this->object_lang = $owner::className() . 'Lang'; } elseif(!is_string($this->object_lang)) { throw new InvalidConfigException('Object lang must be fully classified namespaced classname'); } try { $this->object_lang = \Yii::createObject($this->object_lang); } catch(\ReflectionException $exception) { throw new InvalidConfigException('Object lang must be fully classified namespaced classname'); } if(( !$owner instanceof ActiveRecord ) || ( !$this->object_lang instanceof ActiveRecord )) { throw new InvalidConfigException('Object lang must be fully classified namespaced classname'); } parent::attach($owner); } /** * Get query to get all language models for $owner indexed by language_id * @return ActiveQuery */ public function getLangs() { $object_lang = $this->object_lang; $owner = $this->owner; return $owner->hasMany($object_lang::className(), [ $this->getLangKey() => $this->getOwnerKey() ]) ->indexBy('language_id'); } /** * Get query to get language model for $owner for language_id, default to * Language::getCurrent() * * @param int $language_id * * @return ActiveQuery */ public function getLang(int $language_id = NULL) { if(empty( $language_id )) { $language_id = Language::getCurrent()->language_id; } $object_lang = $this->object_lang; $table_name = $object_lang::getTableSchema()->name; $owner = $this->owner; return $owner->hasOne($object_lang::className(), [ $this->getLangKey() => $this->getOwnerKey() ]) ->where([ $table_name.'.language_id' => $language_id ]); } /** * Generate language models for $owner for active languages. If $owner not new and language * models already inserted, models will be filled with them. * @return ActiveRecord[] */ public function generateLangs() { $owner = $this->owner; $languages = Language::find() ->where([ 'status' => true ]) ->asArray() ->column(); $object_lang = $this->object_lang; $owner_key = $this->getOwnerKey(); $langs = []; if(!$owner->isNewRecord) { $langs = $this->getLangs() ->andFilterWhere([ 'language_id' => $languages ]) ->all(); } foreach($languages as $language) { if(!array_key_exists($language, $langs)) { $langs[ $language ] = \Yii::createObject([ 'class' => $object_lang::className(), 'language_id' => $language, $this->getLangKey() => ( $owner->isNewRecord ? NULL : $owner->$owner_key ), ]); } } return $langs; } /** * Load language models with post data. * * @param Request $request * @param ActiveRecord[] $model_langs */ public function loadLangs(Request $request, array $model_langs) { foreach($request->post($this->object_lang->formName(), []) as $lang => $value) { if(!empty( $model_langs[ $lang ] )) { $model_langs[ $lang ]->attributes = $value; $model_langs[ $lang ]->language_id = $lang; } } } /** * Link language models with $owner by setting language model language key to owner key of * owner * * @param ActiveRecord[] $model_langs * * @return bool If $owner is new record then return false else true */ public function linkLangs(array $model_langs) { $owner = $this->owner; if($owner->isNewRecord) { return false; } $lang_key = $this->getLangKey(); $owner_key = $this->getOwnerKey(); foreach($model_langs as $model_lang) { $model_lang->$lang_key = $owner->$owner_key; } return true; } /** * Try to save all language models to the db. Validation function is run for all models. * * @param ActiveRecord[] $model_langs * * @return bool Whether all models are valid */ public function saveLangs(array $model_langs) { $success = true; foreach($model_langs as $model_lang) { if(!$model_lang->save()) { $success = false; } } return $success; } }