/**
  * Updates an existing Book model.
  * If update is successful, the browser will be redirected to the 'view' page.
  *
  * @var Author[] $modelsAuthorNew
  * @param string $id Book id
  * @return mixed
  */
 public function actionUpdate($id)
 {
     $modelBook = $this->findModel($id);
     $modelBookForm = new BookForm($modelBook);
     $authorsId = $modelBook->getAuthors()->select('id')->asArray()->all();
     $modelsAuthor = Author::findAll($authorsId);
     //$modelBook->getAuthors()->asArray()->all();
     if ($modelBook->load(Yii::$app->request->post())) {
         $modelsAuthorNew = Model::createMultiple(Author::className());
         Model::loadMultiple($modelsAuthorNew, Yii::$app->request->post());
         //process, separate book keyWords
         $modelsKeyWordsNew = [new KeyWord()];
         if ($wordsArray = $modelBookForm->prepareKeyWords(Yii::$app->request->post('KeyWord')['words'])) {
             $modelsKeyWordsNew = Model::createMultiple(KeyWord::className(), [], $wordsArray);
             // KeyWord[0]['word' =>'php']
             Model::loadMultiple($modelsKeyWordsNew, $wordsArray, '');
         }
         $valid = $modelBook->validate();
         $valid = Model::validateMultiple($modelsAuthorNew) && $valid;
         $valid = $wordsArray === false ? $valid : Model::validateMultiple($modelsKeyWordsNew) && $valid;
         if ($valid && $modelBookForm->updateBook($modelsAuthor, $modelsAuthorNew, $modelsKeyWordsNew)) {
             Yii::$app->session->setFlash('success', Yii::t('app', Yii::t('app', 'Book was updated successfully.')));
             Yii::info($id . '_update', 'book');
             return $this->redirect(['view', 'id' => $modelBook->id]);
         } else {
             //get all errors from multiple models
             if (($msg = BookForm::getErrorsMessages($modelsAuthorNew)) !== false) {
                 Yii::$app->session->addFlash('danger', $msg);
             }
             if (($msg = BookForm::getErrorsMessages($modelsKeyWordsNew)) !== false) {
                 Yii::$app->session->addFlash('danger', $msg);
             }
         }
         Yii::$app->session->addFlash('danger', Yii::t('app', 'Book was not updated.'));
     }
     return $this->render('update', ['modelBook' => $modelBook, 'modelsAuthor' => empty($modelsAuthor) ? [new Author()] : $modelsAuthor, 'keyWords' => $modelBookForm->getKeyWords()]);
 }
 /**
  * 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;
 }
Exemple #3
0
 /**
  * @return \yii\db\ActiveQuery
  */
 public function getKeyWords()
 {
     return $this->hasMany(KeyWord::className(), ['id' => 'key_word_id'])->viaTable('book_key_word', ['book_id' => 'id']);
 }