MailQueueModel::attributesMap()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 12
nc 1
nop 0
1
<?php
2
3
namespace yiicod\mailqueue\models;
4
5
use Yii;
6
use yii\behaviors\TimestampBehavior;
7
use yii\db\ActiveRecord;
8
use yii\helpers\ArrayHelper;
9
use yii\helpers\Json;
10
use yiicod\base\models\behaviors\AttributesMapBehavior;
11
12
/**
13
 * This is the model class for table "MailQueue".
14
 *
15
 * The followings are the available columns in table 'mailQueue':
16
 *
17
 * @property string $id
18
 * @property string $to
19
 * @property string $subject
20
 * @property string $mailer
21
 * @property string $body
22
 * @property int $priority
23
 * @property string $status
24
 * @property string $dateCreate
25
 */
26
class MailQueueModel extends ActiveRecord implements MailRepositoryInterface
27
{
28
    /**
29
     * @inheritdoc
30
     */
31
    public static function tableName()
32
    {
33
        return 'mail_queue';
34
    }
35
36
    /**
37
     * @return array validation rules for model attributes
38
     */
39
    public function rules()
40
    {
41
        // NOTE: you should only define rules for those attributes that
42
        // will receive user inputs.
43
        return [
44
            [['to', 'subject', 'body'], 'required'],
45
            [['to', 'subject'], 'string', 'max' => 255],
46
            ['status', 'string', 'max' => 1],
47
            [array_values(static::attributesMap()), 'safe'],
48
        ];
49
    }
50
51
    /**
52
     * Set field attachs
53
     *
54
     * @param array $value
55
     */
56
    public function setAttaches(array $value)
57
    {
58
        if (in_array('attaches', $this->attributes())) {
59
            $this->attaches = Json::encode($value);
0 ignored issues
show
Documentation introduced by
The property attaches does not exist on object<yiicod\mailqueue\models\MailQueueModel>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
60
        }
61
    }
62
63
    /**
64
     * Get field attachs
65
     *
66
     * @return array
67
     */
68
    public function getAttaches(): array
69
    {
70
        $value = null;
71
        if (in_array('attaches', $this->attributes())) {
72
            $value = Json::decode($this->attaches);
0 ignored issues
show
Documentation introduced by
The property attaches does not exist on object<yiicod\mailqueue\models\MailQueueModel>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
73
        }
74
75
        return null === $value ? [] : $value;
76
    }
77
78
    public function getData(): array
79
    {
80
        return [
81
            'to' => $this->to,
82
            'subject' => $this->subject,
83
            'mailer' => $this->mailer,
84
            'body' => $this->body,
85
            'priority' => $this->priority,
86
            'status' => $this->status ?: 0, // @todo Think about this
87
            'attaches' => $this->getAttaches(),
88
        ];
89
    }
90
91
    public function push(): bool
92
    {
93
        $this->setAttributes($this->getData());
94
95
        return $this->save();
96
    }
97
98
    /**
99
     * @return array customized attribute labels (name=>label)
100
     */
101
    public function attributeLabels()
102
    {
103
        return [
104
            'id' => Yii::t('mailqueue', 'Id'),
105
            'to' => Yii::t('mailqueue', 'To'),
106
            'mailer' => Yii::t('mailqueue', 'Mailer'),
107
            'subject' => Yii::t('mailqueue', 'Subject'),
108
            'body' => Yii::t('mailqueue', 'Body'),
109
            'priority' => Yii::t('mailqueue', 'Priority'),
110
            'status' => Yii::t('mailqueue', 'Status'),
111
        ];
112
    }
113
114
    /**
115
     * Returns the static model of the specified AR class.
116
     * Please note that you should have this exact method in all your CActiveRecord descendants!
117
     *
118
     * @param string $className active record class name
119
     *
120
     * @return MailQueueModel the static model class
121
     */
122
    public static function model($className = __CLASS__)
123
    {
124
        return parent::model($className);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class yii\db\ActiveRecord as the method model() does only exist in the following sub-classes of yii\db\ActiveRecord: yiicod\mailqueue\models\MailQueueModel. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
125
    }
126
127
    public static function attributesMap()
128
    {
129
        return [
130
            'fieldFrom' => 'from',
131
            'fieldTo' => 'to',
132
            'fieldMailer' => 'mailer',
133
            'fieldSubject' => 'subject',
134
            'fieldBody' => 'body',
135
            'fieldPriority' => 'priority',
136
            'fieldAttaches' => 'attaches',
137
            'fieldStatus' => 'status',
138
            'fieldCreatedDate' => 'created_date',
139
            'fieldUpdatedDate' => 'updated_date',
140
        ];
141
    }
142
143
    public function behaviors()
144
    {
145
        $behaviors = [
146
            'attributesMapBehavior' => [
147
                'class' => AttributesMapBehavior::class,
148
                'attributesMap' => static::attributesMap(),
149
            ],
150
            'timestampBehavior' => [
151
                'class' => TimestampBehavior::className(),
152
                'createdAtAttribute' => static::attributesMap()['fieldCreatedDate'],
153
                'updatedAtAttribute' => static::attributesMap()['fieldUpdatedDate'],
154
                'value' => function () {
155
                    return date('Y-m-d H:i:s');
156
                },
157
            ],
158
            'XssBehavior' => [
159
                'class' => '\yiicod\base\models\behaviors\XssBehavior',
160
                'attributesExclude' => [static::attributesMap()['fieldBody']],
161
            ],
162
        ];
163
164
        return ArrayHelper::merge(parent::behaviors(), $behaviors);
165
    }
166
}
167