yiisoft / yii

Yii PHP Framework 1.1.x

Home Page:http://www.yiiframework.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

CActiveRecord: __construct(): Passing null to parameter #1 ($flags) of type int is deprecated

rija opened this issue · comments

What steps will reproduce the problem?

Hi, on PHP 8.2, using CActiveRecord to indirectly access a related object's property, causes an exception

client code:

 $toNameValueHash = function ($file_attribute) {
                return array( $file_attribute->attribute->attribute_name => $file_attribute->value);
            };

What is the expected result?

No error

What do you get instead?

Attribute::__construct(): Passing null to parameter #1 ($flags) of type int is deprecated (/var/www/vendor/yiisoft/yii/framework/db/ar/CActiveRecord.php:397)
2023-10-27 17:00:56 Stack trace:
2023-10-27 17:00:56 #0 /var/www/vendor/yiisoft/yii/framework/db/ar/CActiveRecord.php(397): Attribute->__construct()
2023-10-27 17:00:56 #1 /var/www/vendor/yiisoft/yii/framework/db/ar/CActiveFinder.php(182): model()
2023-10-27 17:00:56 #2 /var/www/vendor/yiisoft/yii/framework/db/ar/CActiveFinder.php(231): CActiveFinder->getModel()
2023-10-27 17:00:56 #3 /var/www/vendor/yiisoft/yii/framework/db/ar/CActiveFinder.php(48): CActiveFinder->buildJoinTree()
2023-10-27 17:00:56 #4 /var/www/vendor/yiisoft/yii/framework/db/ar/CActiveRecord.php(915): CActiveFinder->__construct()
2023-10-27 17:00:56 #5 /var/www/vendor/yiisoft/yii/framework/db/ar/CActiveRecord.php(282): FileAttributes->getActiveFinder()
2023-10-27 17:00:56 #6 /var/www/vendor/yiisoft/yii/framework/db/ar/CActiveRecord.php(143): FileAttributes->getRelated()
2023-10-27 17:00:56 #7 /app/public/protected/components/StoredDatasetFiles.php(55): FileAttributes->__get()

Additional info

  • Line 397 of CActiveRecord.php says:
$model=self::$_models[$className]=new $className(null);
  • The client code works fine with PHP 7.4.
Q A
Yii version 1.1.28
PHP version 8.2
Operating system Debian buster inside Docker

Have you overwritten constructor of your AR model?

Have you overwritten constructor of your AR model?

No, I haven't, below is the entire class, which looks quite standard to me:

class Attribute extends CActiveRecord
{
    const FUP = 'Fairly Use Policy';
        const AUTO_ATTRIBUTE = "'file_size', 'num_amino_acids', 'num_nucleotides', 'num_words', 'num_lines', 'num_rows', 'num_columns'";
    /**
     * Returns the static model of the specified AR class.
     * @return Attribute the static model class
     */
    public static function model($className = __CLASS__)
    {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'attribute';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('attribute_name, allowed_units', 'length', 'max' => 100),
            array('definition, ontology_link', 'length', 'max' => 1000),
            array('model', 'length', 'max' => 30),
            array('structured_comment_name, note', 'length', 'max' => 50),
            array('value_syntax', 'length', 'max' => 500),
            array('occurance', 'length', 'max' => 5),
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('id, attribute_name, definition, model, structured_comment_name, value_syntax, allowed_units, occurance, ontology_link, note', 'safe', 'on' => 'search'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
            'exp_attributes' => array(self::HAS_MANY, 'ExpAttributes', 'attribute_id'),
            'sample_attributes' => array(self::HAS_MANY, 'SampleAttribute', 'attribute_id'),
            'dataset_attributes' => array(self::HAS_MANY, 'DatasetAttributes', 'attribute_id'),
            'file_attributes' => array(self::HAS_MANY, 'FileAttributes', 'attribute_id'),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => 'Id',
            'attribute_name' => 'Attribute Name',
            'definition' => 'Definition',
            'model' => 'Model',
            'structured_comment_name' => 'Structured Comment Name',
            'value_syntax' => 'Value Syntax',
            'allowed_units' => 'Allowed Units',
            'occurance' => 'Occurance',
            'ontology_link' => 'Ontology Link',
            'note' => 'Note',
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search()
    {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria = new CDbCriteria();

        $criteria->compare('id', $this->id);

        $criteria->compare('attribute_name', $this->attribute_name, true);

        $criteria->compare('definition', $this->definition, true);

        $criteria->compare('model', $this->model, true);

        $criteria->compare('structured_comment_name', $this->structured_comment_name, true);

        $criteria->compare('value_syntax', $this->value_syntax, true);

        $criteria->compare('allowed_units', $this->allowed_units, true);

        $criteria->compare('occurance', $this->occurance, true);

        $criteria->compare('ontology_link', $this->ontology_link, true);

        $criteria->compare('note', $this->note, true);

        return new CActiveDataProvider('Attribute', array(
            'criteria' => $criteria,
        ));
    }
}

And here's the FileAttributes class that has relationship with the above class:

<?php


class FileAttributes extends CActiveRecord
{

    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return FileAttributes the static model class
     */
    public static function model($className = __CLASS__)
    {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'file_attributes';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('file_id, attribute_id', 'required'),
            array('file_id, attribute_id', 'numerical', 'integerOnly' => true),
            array('value', 'length', 'max' => 50),
            array('unit_id', 'length', 'max' => 30),
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('id, file_id, attribute_id, value, unit_id', 'safe', 'on' => 'search'),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
            'attribute' => array(self::BELONGS_TO, 'Attribute', 'attribute_id'),
            'file' => array(self::BELONGS_TO, 'File', 'file_id'),
            'unit' => array(self::BELONGS_TO, 'Unit', 'unit_id'),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => 'ID',
            'file_id' => 'File',
            'attribute_id' => 'Attribute',
            'value' => 'Value',
            'unit_id' => 'Unit',
        );
    }

    public function afterSave() {
        $log = new DatasetLog;
        $log->dataset_id = $this->file->dataset_id;
        if($this->isNewRecord) {
            $log->message = $this->file->name. ': additional file attribute added';
        }
        else
            $log->message = $this->file->name. ': file attribute updated';
        $log->model_id = $this->id;
        $log->model = get_class($this);
        $log->url = Yii::app()->createUrl('/adminFile/update', array('id'=>$this->file->id));
        if($this->file->dataset->isPublic) {
            $log->save();
        }
        return true;
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function search()
    {
        // Warning: Please modify the following code to remove attributes that
        // should not be searched.

        $criteria = new CDbCriteria;

        $criteria->compare('id', $this->id);
        $criteria->compare('file_id', $this->file_id);
        $criteria->compare('attribute_id', $this->attribute_id);
        $criteria->compare('value', $this->value, true);
        $criteria->compare('unit_id', $this->unit_id, true);

        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
        ));
    }

}

Then it looks like the problem is the name of your model - Attribute is already taken by https://www.php.net/manual/en/class.attribute.php

Then it looks like the problem is the name of your model - Attribute is already taken by https://www.php.net/manual/en/class.attribute.php

Ah, thank you for spotting that. We are going to rename our class then, it's actually not the first time that its quite generic name caused us problems.