Web Development

How to save related models using Yii2?

1 – Create formModel
2 – Add related table as a property to original model
3 – Override setAttribute in formModel
4 – Override afterSave in original model

public function loadAttributes(User $user) {
parent::loadAttributes($user);

// here is the magic happens
/** @var UsersMultimedia $multimedia */
$multimedia = \yii::createObject(\common\models\UsersMultimedia::className());
$multimedia->setAttributes($this->attributes);
$user->setMultimedia($multimedia);
}

/** @inheritdoc */
public function afterSave($insert, $changedAttributes)
{
parent::afterSave($insert, $changedAttributes);
if ($insert) {
if ($this->_users_multimedia == null) {
$this->_users_multimedia = Yii::createObject(UsersMultimedia::className());
}
$this->_users_multimedia->link(‘user’, $this);

$this->_users_multimedia->trigger(self::EVENT_AFTER_INSERT);
}
}

<?php

/**
 * A nifty way of calling a component from inside a console task
 *
 * Long description for ConsoleTask (if any)...
 *
 * PHP version 5
 *
 * LICENSE: This source file is subject to version 3.01 of the PHP license
 * that is available through the world-wide-web at the following URI:
 * http://www.php.net/license/3_01.txt.  If you did not receive a copy of
 * the PHP License and are unable to obtain it through the web, please
 * send a note to license@php.net so we can mail you a copy immediately.
 *
 * @category   CategoryName
 * @package    PackageName
 * @author     Mustafa Qamar-ud-Din <m.qamaruddin@nilecode.com>
 * @author     Another Author <another@example.com>
 * @copyright  1997-2005 The PHP Group
 * @license    http://www.php.net/license/3_01.txt  PHP License 3.01
 * @version    SVN: $Id$
 * @link       http://pear.php.net/package/PackageName
 * @see        NetOther, Net_Sample::Net_Sample()
 * @since      File available since Release 1.2.0
 * @deprecated File deprecated in Release 2.0.0
 * @copyright (c) 2016, Nilecode
 */

namespace common\forms;

use yii;
use yii\web\UploadedFile;
use common\models\Categories as CategoriesModel;
use common\models\CategoriesImages;
use common\models\SuggestAttachments;
use common\models\Suggest;

class ClaimForm extends \common\models\_BaseModel {

    public $place_id;
    public $place_url;
    public $subject;
    public $body;
    public $attachments;
    public $email;
    public $mobile;
    public $user_id;

    /**
     * @inherentdoc
     */
    public function init() {
        parent::init();
    }

    /**
     * @inherentdoc
     */
    public function attributeLabels() {
        $labels = parent::attributeLabels();
        return $labels;
    }

    /**
     * @inherentdoc
     */
    public function rules() {
        $rules = parent::rules();
        $rules[] = [['subject', 'body', 'email', 'mobile'], 'required'];
        $rules[] = [
            ['attachments'], 'file',
            'skipOnEmpty' => true,
            'extensions' => yii::$app->params['allowed_file_extensions'],
            'maxFiles' => yii::$app->params['num_place_extra_images']
        ];
        $rules[] = [['user_id', 'place_id'], 'safe'];
        $rules[] = [['email'], 'email'];
        return $rules;
    }

    /**
     * @inherentdoc
     */
    public function load($data, $formName = null) {
        $ret = parent::load($data, $formName);

        return $ret;
    }

    /**
     * create a claim model
     * and fills attachments also
     * @return ['success'=>Boolean, 'errors'=>[]]
     */
    public function claim() {
        if (!$this->validate())
            return;

        $suggest = new Suggest();
        $this->setSuggest($suggest);
        if (!$suggest->save()) {
            return [
                'success' => false,
                'errors' => $suggest->getErrors()
            ];
        }

        $ret = $this->saveAttachments($suggest->id);
        if (!$ret['success']) {
            return $ret;
        }

        return [
            'success' => true,
            'message' => yii::t('app', 'Thank you for your suggestion!')
        ];
    }

    /**
     * 
     * @param Suggest $suggest
     */
    public function setSuggest(Suggest $suggest) {
        // save suggest
        $suggest->place_id = $this->place_id;
        $suggest->user_id = $this->user_id;
        $suggest->email = $this->email;
        $suggest->subject = $this->subject;
        $suggest->body = $this->body;
    }

    /**
     * 
     * @param integer $suggest_id
     * @return ['success'=>Boolean, 'errors'=>[]]
     */
    public function saveAttachments($suggest_id) {
        // save related attachments
        $uploads = UploadedFile::getInstances($this, 'attachments');

        foreach ($uploads as $upload) {

            $attachment = new SuggestAttachments();
            $attachment->file_name = $upload;
            $attachment->suggest_id = $suggest_id;

            if (!$attachment->save()) {
                return [
                    'success' => false,
                    'errors' => $attachment->getErrors()
                ];
            }
        }

        return ['success' => TRUE];
    }

}

References:
1 – https://github.com/dektrium/yii2-user
2 – https://github.com/yiisoft/yii2/issues/569

3 – http://stackoverflow.com/questions/28009601/checkboxes-from-another-table-yii2-and-retaining-checked-values

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s