简体   繁体   中英

yii2 function issue called with null value

i'm trying to copy some values from a table that contain a column that relates to another table to copy too. the problem is that if i call the function createNew() of the model Email.php

<?php

namespace app\models;

use Yii;

/**
* This is the model class for table "email".
*
* @property integer $id
* @property integer $provider_id
* @property integer $sender_id
* @property string $recipient
* @property string $name
* @property string $cc
* @property string $ccn
* @property string $subject
* @property string $body
* @property integer $type
* @property string $created
*
* @property Emailaccount $sender
* @property Provider $provider
*/
class Email extends \yii\db\ActiveRecord
{
/**
 * @inheritdoc
 */
public static function tableName()
{
    return 'email';
}

/**
 * @inheritdoc
 */
public function rules()
{
    return [
        [['provider_id', 'sender_id', 'name', 'subject', 'body', 'type'], 'required'],
        [['provider_id', 'sender_id', 'type'], 'integer'],
        [['body'], 'string'],
        [['created'], 'safe'],
        [['recipient'], 'string', 'max' => 200],
        [['name', 'cc', 'ccn', 'subject'], 'string', 'max' => 100],
        [['sender_id'], 'exist', 'skipOnError' => true, 'targetClass' => Emailaccount::className(), 'targetAttribute' => ['sender_id' => 'id']],
        [['provider_id'], 'exist', 'skipOnError' => true, 'targetClass' => Provider::className(), 'targetAttribute' => ['provider_id' => 'id']],
    ];
}

/**
 * @inheritdoc
 */
public function attributeLabels()
{
    return [
        'id' => 'ID',
        'provider_id' => 'Provider ID',
        'sender_id' => 'Sender ID',
        'recipient' => 'Recipient',
        'name' => 'Name',
        'cc' => 'Cc',
        'ccn' => 'Ccn',
        'subject' => 'Subject',
        'body' => 'Body',
        'type' => 'Type',
        'created' => 'Created',
    ];
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getSender()
{
    return $this->hasOne(Emailaccount::className(), ['id' => 'sender_id']);
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getProvider()
{
    return $this->hasOne(Provider::className(), ['id' => 'provider_id']);
}

public function createNew ($id,$new_id){
    $model = Email::findOne(['id'=>$id]);
    $model->id = null;
    $model->provider_id = $new_id;
    $model->isNewRecord = true;
    $model->save();
    return $model->id;


}

}

from the model Service.php

namespace app\models;

use Yii;
use app\models\Email; 
use app\models\Question;

/**
* This is the model class for table "service".
*
* @property integer $id
* @property integer $provider_id
* @property string $token
* @property string $name
* @property string $description
* @property integer $parent_id
* @property string $reference
* @property integer $reference_id
* @property integer $depth
* @property integer $isleaf
* @property string $color
* @property string $icon
* @property integer $type
* @property string $type_label
* @property integer $totem_reference_id
*
* @property Service $parent
* @property Service[] $services
*/
class Service extends \yii\db\ActiveRecord
{
/**
 * @inheritdoc
 */
public static function tableName()
{
    return 'service';
}

/**
 * @inheritdoc
 */
public function rules()
{
    return [
        [['provider_id', 'token', 'name'], 'required'],
        [['provider_id', 'parent_id', 'reference_id', 'depth', 'isleaf', 'type', 'totem_reference_id'], 'integer'],
        [['reference', 'color'], 'string'],
        [['token', 'type_label'], 'string', 'max' => 45],
        [['name', 'description'], 'string', 'max' => 255],
        [['icon'], 'string', 'max' => 30],
        [['token'], 'unique'],
        [['parent_id'], 'exist', 'skipOnError' => true, 'targetClass' => Service::className(), 'targetAttribute' => ['parent_id' => 'id']],
    ];
}

/**
 * @inheritdoc
 */
public function attributeLabels()
{
    return [
        'id' => 'ID',
        'provider_id' => 'Provider ID',
        'token' => 'Token',
        'name' => 'Name',
        'description' => 'Description',
        'parent_id' => 'Parent ID',
        'reference' => 'Reference',
        'reference_id' => 'Reference ID',
        'depth' => 'Depth',
        'isleaf' => 'Isleaf',
        'color' => 'Color',
        'icon' => 'Icon',
        'type' => 'Type',
        'type_label' => 'Type Label',
        'totem_reference_id' => 'Totem Reference ID',
    ];
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getParent()
{
    return $this->hasOne(Service::className(), ['id' => 'parent_id']);
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getServices()
{
    return $this->hasMany(Service::className(), ['parent_id' => 'id']);
}

public function mostraService($id,$new_id){
$service = Service::find()
->where(['provider_id'=>$id])
->all();
foreach ($service as $s) {    
if ($s->parent_id==NULL) {
   $o_id= $s->id; //ID ORIGINALE
   $s->id= null;
   $s->token= Yii::$app->getSecurity()->generateRandomString(45);
   $s->isNewRecord = true;
   $s->provider_id = $new_id; //ID_NUOVO
   $s->save();
   $p_id=$s->id;
   $copy = $this->recursiveCopy($o_id,$new_id,$p_id);

} else {
   //do something
}
}    


}

public function recursiveCopy ($id_s,$id_pr,$id_p){
    $children = Service::find()
    ->where(['parent_id'=>$id_s])
    ->all();
   foreach ($children as $c) {
       if ($c->reference == null){
        $o_id=$c->id;
        $c->id= null;
        $c->token= Yii::$app->getSecurity()->generateRandomString(45);
        $c->isNewRecord = true;
        $c->parent_id = $id_p;
        $c->provider_id = $id_pr;
        $c->save();
        $c_id=$c->id;
        $copy = $this->recursiveCopy($o_id,$id_pr,$c_id);
       }else {
           if ($c->reference =='email') {
               $email = new Email();
               $e_id=$email->createNew($c->reference_id, $id_pr);
               $c->id= null;
               $c->token = Yii::$app->getSecurity()->generateRandomString(45);
               $c->reference_id = $e_id;
               $c->provider_id = $id_pr;
               $c->parent_id = $id_p;
               $c->isNewRecord = true;
               $c->save();
           } else if ($c->reference =='question'){
               $question = new Question();
               $q_id = $question->createNew($c->reference_id, $id_pr);
           } else {
               $c->id= null;
               $c->token = Yii::$app->getSecurity()->generateRandomString(45);
               $c->reference_id = $id_p;
               $c->provider_id = $id_pr;
               $c->parent_id = $id_p;
               $c->isNewRecord = true;
               $c->save();

           }
       }
   }
}
}

it work perfectly but if i call in the same way in the Question.php

namespace app\models;

use Yii;
use app\models\Email;

/**
* This is the model class for table "question".
*
* @property integer $id
*@property integer $provider_id
* @property string $title
* @property string $description
* @property string $children
* @property integer $parent_id
* @property string $reference
* @property integer $reference_id
* @property integer $depth
* @property integer $type
*
* @property Provider $provider
* @property Question $parent
* @property Question[] $questions
*/
class Question extends \yii\db\ActiveRecord
{
/**
 * @inheritdoc
 */
public static function tableName()
{
    return 'question';
}

/**
 * @inheritdoc
 */
public function rules()
{
    return [
        [['provider_id', 'title'], 'required'],
        [['provider_id', 'parent_id', 'reference_id', 'depth', 'type'], 'integer'],
        [['reference'], 'string'],
        [['title'], 'string', 'max' => 150],
        [['description'], 'string', 'max' => 1000],
        [['children'], 'string', 'max' => 300],
        [['provider_id'], 'exist', 'skipOnError' => true, 'targetClass' => Provider::className(), 'targetAttribute' => ['provider_id' => 'id']],
        [['parent_id'], 'exist', 'skipOnError' => true, 'targetClass' => Question::className(), 'targetAttribute' => ['parent_id' => 'id']],
    ];
}

/**
 * @inheritdoc
 */
public function attributeLabels()
{
    return [
        'id' => 'ID',
        'provider_id' => 'Provider ID',
        'title' => 'Title',
        'description' => 'Description',
        'children' => 'Children',
        'parent_id' => 'Parent ID',
        'reference' => 'Reference',
        'reference_id' => 'Reference ID',
        'depth' => 'Depth',
        'type' => 'Type',
    ];
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getProvider()
{
    return $this->hasOne(Provider::className(), ['id' => 'provider_id']);
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getParent()
{
    return $this->hasOne(Question::className(), ['id' => 'parent_id']);
}

/**
 * @return \yii\db\ActiveQuery
 */
public function getQuestions()
{
    return $this->hasMany(Question::className(), ['parent_id' => 'id']);
}

public function createNew ($id,$new_id){
    $model = Question::findOne(['id'=>$id]);
    $model->id= null;
    $model->provider_id = $new_id;
    $model->isNewRecord = true;
    $model->save();
    $child= explode(",", $model->children);
    $sons= '';
    foreach ($child as $c) {
       $model_c = Question::findOne(['id'=>$c]);
       $email = new Email();
       $e_id=$email->createNew($model_c->reference_id,$new_id);
       $model_c->id= null;
       $model_c->provider_id = $new_id;
       $model_c->parent_id = $model->id;
       $model_c->isNewRecord = true;
       $model_c->save();
       $sons=$sons.$model_c->id.',';
    }
    $model->children =$sons;



}
}

it pass a null value and of course throw an exception. exception 1 exception 2 i tried to echo the value before pass it to the function and it print the right value. i really don't understand, someone can help me?

The problem is you are not checking if Model::findOne() has actually returned a valid result model. It could be false / null if the record with $id doesn't exist.

The second error you are getting usually happens in following case:

$object = null;
$object->prop = 'a value';

aka whey you try to set a value of an object property which doesn't exist.

And your first error message is saying that above case is true.

app\models\Email::createNew(null, 51) <-- notice the null here

So when you are finding a model always check before using it. You can do following:

foreach ($child as $c) {
   $model_c = Question::findOne(['id'=>$c]);
   if( $model_c ) { // check the model is valid
       $email = new Email();
       $e_id=$email->createNew($model_c->reference_id,$new_id);
       $model_c->id= null;
       $model_c->provider_id = $new_id;
       $model_c->parent_id = $model->id;
       $model_c->isNewRecord = true;
       $model_c->save();
       $sons=$sons.$model_c->id.',';
   }
}

Just showed you one, do the rest. :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM