/**
  * update book and all related parameters
  * if unchanged Author already exist do nothing, otherwise delete all old authors and create new
  * the same with KeyWord-s
  * - if author or key word already exist new book is assigned to him, if not they are created
  * - transaction is for consistent data (book, authors, key words)
  *
  * @param Author[] $modelsAuthor
  * @param Author[] $modelsAuthorNew
  * @var KeyWord[] $modelsKeyWordsNew
  * @return bool - true if transaction(update) is successful otherwise false
  * @throws \yii\db\Exception
  */
 public function updateBook($modelsAuthor, &$modelsAuthorNew, &$modelsKeyWordsNew)
 {
     $db = \Yii::$app->db;
     $transaction = $db->beginTransaction();
     try {
         if ($flag = $this->modelBook->save(false)) {
             //Authors - filter unchanged Authors
             foreach ($modelsAuthorNew as $authorNewKey => $authorNew) {
                 foreach ($modelsAuthor as $authorKey => $author) {
                     if ($authorNew->first_name === $author->first_name && $authorNew->last_name === $author->last_name) {
                         unset($modelsAuthorNew[$authorNewKey], $modelsAuthor[$authorKey]);
                     }
                 }
             }
             //delete all unused (old) Authors(link table record), if model Author is the last one, delete Author itself too
             foreach ($modelsAuthor as $ma) {
                 $maid = $ma->id;
                 if (($count = $db->createCommand('SELECT COUNT(*) FROM book_author WHERE author_id = :author_id')->bindParam(':author_id', $maid)->queryScalar()) !== false) {
                     $db->createCommand()->delete('book_author', ['author_id' => $ma->id, 'book_id' => $this->modelBook->id])->execute();
                     if ($count == 1) {
                         $ma->delete();
                     }
                 }
             }
             //add new Authors
             foreach ($modelsAuthorNew as $authorNew) {
                 if (($existA = Author::findOne(['first_name' => $authorNew->first_name, 'last_name' => $authorNew->last_name])) !== null) {
                     $this->modelBook->link('authors', $existA);
                 } else {
                     if (!($flag = $authorNew->save(false))) {
                         throw new Exception("Failed save new Authors in update book model action.");
                     }
                     $this->modelBook->link('authors', $authorNew);
                 }
             }
             //KeyWords - filter unchanged words
             $keyWordIds = $this->modelBook->getKeyWords()->select('id')->asArray()->all();
             $modelsKeyWords = KeyWord::findAll($keyWordIds);
             foreach ($modelsKeyWordsNew as $keyWordNewKey => $keyWordNew) {
                 foreach ($modelsKeyWords as $keyWordKey => $keyWord) {
                     if ($keyWordNew->word === $keyWord->word) {
                         unset($modelsKeyWordsNew[$keyWordNewKey], $modelsKeyWords[$keyWordKey]);
                     }
                 }
             }
             //delete all old KeyWords
             foreach ($modelsKeyWords as $mkw) {
                 $mkwid = $mkw->id;
                 if (($count = $db->createCommand('SELECT COUNT(*) FROM book_key_word WHERE key_word_id = :key_word_id')->bindParam(':key_word_id', $mkwid)->queryScalar()) !== false) {
                     $db->createCommand()->delete('book_key_word', ['key_word_id' => $mkw->id, 'book_id' => $this->modelBook->id])->execute();
                     if ($count == 1) {
                         $mkw->delete();
                     }
                 }
             }
             //save new keys
             if ($flag) {
                 foreach ($modelsKeyWordsNew as $keyWordNew) {
                     if (($existKey = KeyWord::findOne(['word' => $keyWordNew->word])) !== null) {
                         $this->modelBook->link('keyWords', $existKey);
                     } else {
                         if (!($flag = $keyWordNew->save(false))) {
                             throw new Exception("Failed save key words in update book action.");
                         }
                         $this->modelBook->link('keyWords', $keyWordNew);
                     }
                 }
             }
         }
         if ($flag) {
             $transaction->commit();
             return true;
         }
     } catch (\Exception $e) {
         \Yii::warning($e->getMessage());
         $transaction->rollBack();
         return false;
     }
     return false;
 }