Issues (443)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

common/models/Post.php (9 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * @link http://www.writesdown.com/
4
 * @copyright Copyright (c) 2015 WritesDown
5
 * @license http://www.writesdown.com/license/
6
 */
7
8
namespace common\models;
9
10
use common\components\Json;
11
use Yii;
12
use yii\behaviors\SluggableBehavior;
13
use yii\db\ActiveRecord;
14
use yii\helpers\ArrayHelper;
15
use yii\helpers\Html;
16
17
/**
18
 * This is the model class for table "{{%post}}".
19
 *
20
 * @property integer $id
21
 * @property integer $author
22
 * @property integer $type
23
 * @property string $title
24
 * @property string $excerpt
25
 * @property string $content
26
 * @property string $date
27
 * @property string $modified
28
 * @property string $status
29
 * @property string $password
30
 * @property string $slug
31
 * @property string $comment_status
32
 * @property integer $comment_count
33
 * @property string $url
34
 *
35
 * @property Media[] $media
36
 * @property PostType $postType
37
 * @property User $postAuthor
38
 * @property PostComment[] $postComments
39
 * @property PostMeta[] $postMeta
40
 * @property TermRelationship[] $termRelationships
41
 * @property Term[] $terms
42
 *
43
 * @author Agiel K. Saputra <[email protected]>
44
 * @since 0.1.0
45
 */
46
class Post extends ActiveRecord
47
{
48
    public $username;
49
50
    const COMMENT_STATUS_OPEN = 'open';
51
    const COMMENT_STATUS_CLOSE = 'close';
52
    const STATUS_PUBLISH = 'publish';
53
    const STATUS_PRIVATE = 'private';
54
    const STATUS_DRAFT = 'draft';
55
    const STATUS_TRASH = 'trash';
56
    const STATUS_REVIEW = 'review';
57
58
    /**
59
     * @inheritdoc
60
     */
61
    public static function tableName()
62
    {
63
        return '{{%post}}';
64
    }
65
66
    /**
67
     * @inheritdoc
68
     */
69 View Code Duplication
    public function behaviors()
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
70
    {
71
        return [
72
            [
73
                'class' => SluggableBehavior::className(),
74
                'attribute' => 'title',
75
                'attributes' => [ActiveRecord::EVENT_BEFORE_INSERT => ['slug']],
76
            ],
77
        ];
78
    }
79
80
    /**
81
     * @inheritdoc
82
     */
83
    public function rules()
84
    {
85
        return [
86
            ['title', 'required'],
87
            [['author', 'type', 'comment_count'], 'integer'],
88
            [['title', 'excerpt', 'content'], 'string'],
89
            [['date', 'modified', 'author'], 'safe'],
90
            [['status', 'comment_status'], 'string', 'max' => 20],
91
            [['password', 'slug'], 'string', 'max' => 255],
92
            ['comment_status', 'in', 'range' => [self::COMMENT_STATUS_OPEN, self::COMMENT_STATUS_CLOSE]],
93
            ['comment_status', 'default', 'value' => self::COMMENT_STATUS_CLOSE],
94
            ['comment_count', 'default', 'value' => 0],
95
            [
96
                'status',
97
                'in',
98
                'range' => [
99
                    self::STATUS_PUBLISH,
100
                    self::STATUS_DRAFT,
101
                    self::STATUS_PRIVATE,
102
                    self::STATUS_REVIEW,
103
                    self::STATUS_TRASH,
104
                ],
105
            ],
106
            ['status', 'default', 'value' => self::STATUS_PUBLISH],
107
            [['title', 'slug'], 'unique'],
108
        ];
109
    }
110
111
    /**
112
     * @inheritdoc
113
     */
114
    public function attributeLabels()
115
    {
116
        return [
117
            'id' => Yii::t('writesdown', 'ID'),
118
            'author' => Yii::t('writesdown', 'Author'),
119
            'type' => Yii::t('writesdown', 'Type'),
120
            'title' => Yii::t('writesdown', 'Title'),
121
            'excerpt' => Yii::t('writesdown', 'Excerpt'),
122
            'content' => Yii::t('writesdown', 'Content'),
123
            'date' => Yii::t('writesdown', 'Date'),
124
            'modified' => Yii::t('writesdown', 'Modified'),
125
            'status' => Yii::t('writesdown', 'Status'),
126
            'password' => Yii::t('writesdown', 'Password'),
127
            'slug' => Yii::t('writesdown', 'Slug'),
128
            'comment_status' => Yii::t('writesdown', 'Comment Status'),
129
            'comment_count' => Yii::t('writesdown', 'Comment Count'),
130
            'username' => Yii::t('writesdown', 'Author'),
131
        ];
132
    }
133
134
    /**
135
     * @return \yii\db\ActiveQuery
136
     */
137
    public function getMedia()
138
    {
139
        return $this->hasMany(Media::className(), ['post_id' => 'id']);
140
    }
141
142
    /**
143
     * @return \yii\db\ActiveQuery
144
     */
145
    public function getPostType()
146
    {
147
        return $this->hasOne(PostType::className(), ['id' => 'type']);
148
    }
149
150
    /**
151
     * @return \yii\db\ActiveQuery
152
     */
153
    public function getPostAuthor()
154
    {
155
        return $this->hasOne(User::className(), ['id' => 'author']);
156
    }
157
158
    /**
159
     * @return \yii\db\ActiveQuery
160
     */
161
    public function getPostComments()
162
    {
163
        return $this->hasMany(PostComment::className(), ['post_id' => 'id']);
164
    }
165
166
    /**
167
     * @return \yii\db\ActiveQuery
168
     */
169
    public function getPostMeta()
170
    {
171
        return $this->hasMany(PostMeta::className(), ['post_id' => 'id']);
172
    }
173
174
    /**
175
     * @return \yii\db\ActiveQuery
176
     */
177
    public function getTermRelationships()
178
    {
179
        return $this->hasMany(TermRelationship::className(), ['post_id' => 'id']);
180
    }
181
182
    /**
183
     * @return \yii\db\ActiveQuery
184
     */
185
    public function getTerms()
186
    {
187
        return $this
188
            ->hasMany(Term::className(), ['id' => 'term_id'])
189
            ->viaTable('{{%term_relationship}}', ['post_id' => 'id']);
190
    }
191
192
    /**
193
     * Get post status as array.
194
     *
195
     * @return array
196
     */
197
    public function getPostStatuses()
198
    {
199
        return [
200
            self::STATUS_PUBLISH => Yii::t('writesdown', 'Publish'),
201
            self::STATUS_DRAFT => Yii::t('writesdown', 'Draft'),
202
            self::STATUS_PRIVATE => Yii::t('writesdown', 'Private'),
203
            self::STATUS_TRASH => Yii::t('writesdown', 'Trash'),
204
            self::STATUS_REVIEW => Yii::t('writesdown', 'Review'),
205
        ];
206
    }
207
208
    /**
209
     * Get comment status as array
210
     */
211 View Code Duplication
    public function getCommentStatuses()
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
212
    {
213
        return [
214
            self::COMMENT_STATUS_OPEN => Yii::t('writesdown', 'Open'),
215
            self::COMMENT_STATUS_CLOSE => Yii::t('writesdown', 'Close'),
216
        ];
217
    }
218
219
220
    /**
221
     * Get permalink of current post.
222
     *
223
     * @return string
224
     */
225
    public function getUrl()
226
    {
227
        return Yii::$app->urlManagerFront->createAbsoluteUrl(['/post/view', 'id' => $this->id]);
228
    }
229
230
    /**
231
     * Get meta for current post.
232
     *
233
     * @param string $name
234
     * @return mixed|null
235
     */
236 View Code Duplication
    public function getMeta($name)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
237
    {
238
        /* @var $model \common\models\PostMeta */
239
        $model = PostMeta::findOne(['name' => $name, 'post_id' => $this->id]);
240
241
        if ($model) {
242
            if (Json::isJson($model->value)) {
243
                return Json::decode($model->value);
244
            }
245
246
            return $model->value;
247
        }
248
249
        return null;
250
    }
251
252
    /**
253
     * Add new meta data for current post.
254
     *
255
     * @param string $name
256
     * @param string|array $value
257
     * @return bool
258
     */
259 View Code Duplication
    public function setMeta($name, $value)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
260
    {
261
        if (is_array($value) || is_object($value)) {
262
            $value = Json::encode($value);
263
        }
264
265
        if ($this->getMeta($name) !== null) {
266
            return $this->upMeta($name, $value);
267
        }
268
269
        $model = new PostMeta([
270
            'post_id' => $this->id,
271
            'name' => $name,
272
            'value' => $value,
273
        ]);
274
275
        return $model->save();
276
    }
277
278
    /**
279
     * Update meta data for current post.
280
     *
281
     * @param string $name
282
     * @param string|array $value
283
     * @return bool
284
     */
285 View Code Duplication
    public function upMeta($name, $value)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
286
    {
287
        /* @var $model \common\models\PostMeta */
288
        $model = PostMeta::findOne(['name' => $name, 'post_id' => $this->id]);
289
290
        if (is_array($value) || is_object($value)) {
291
            $value = Json::encode($value);
292
        }
293
294
        $model->value = $value;
295
296
        return $model->save();
297
    }
298
299
    /**
300
     * @param bool $sameType
301
     * @param bool $sameTerm
302
     * @return array|null|Post
303
     */
304 View Code Duplication
    public function getNextPost($sameType = true, $sameTerm = false)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
305
    {
306
        /* @var $query \yii\db\ActiveQuery */
307
        $query = static::find()
308
            ->from(['post' => $this->tableName()])
309
            ->andWhere(['>', 'post.id', $this->id])
310
            ->andWhere(['status' => 'publish'])
311
            ->orderBy(['post.id' => SORT_ASC]);
312
313
        if ($sameType) {
314
            $query->andWhere(['type' => $this->type]);
315
        }
316
317
        if ($sameTerm) {
318
            $query->innerJoinWith([
319
                'terms' => function ($query) {
320
                    /* @var $query \yii\db\ActiveQuery */
321
                    $query->from(['term' => Term::tableName()])->andWhere([
322
                        'IN',
323
                        'term.id',
324
                        implode(',', ArrayHelper::getColumn($this->terms, 'id')),
325
                    ]);
326
                },
327
            ]);
328
        }
329
330
        return $query->one();
331
    }
332
333
    /**
334
     * @param bool $sameType
335
     * @param bool $sameTerm
336
     * @param string $title
337
     * @param array $options
338
     * @return string
339
     */
340 View Code Duplication
    public function getNextPostLink($title = '{title}', $sameType = true, $sameTerm = false, $options = [])
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
341
    {
342
        if ($nextPost = $this->getNextPost($sameType, $sameTerm)) {
343
            $title = preg_replace_callback('/\\{([\w\-\/]+)\\}/', function ($matches) use ($nextPost) {
344
                $attribute = $matches[1];
345
346
                return $nextPost->{$attribute};
347
            }, $title);
348
349
            return Html::a($title, $nextPost->url, $options);
350
        }
351
352
        return '';
353
    }
354
355
    /**
356
     * @param bool $sameType
357
     * @param bool $sameTerm
358
     * @return array|null|Post
359
     */
360 View Code Duplication
    public function getPrevPost($sameType = true, $sameTerm = false)
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
361
    {
362
        /* @var $query \yii\db\ActiveQuery */
363
        $query = static::find()
364
            ->from(['post' => $this->tableName()])
365
            ->andWhere(['<', 'post.id', $this->id])
366
            ->andWhere(['status' => 'publish'])
367
            ->orderBy(['post.id' => SORT_DESC]);
368
369
        if ($sameType) {
370
            $query->andWhere(['type' => $this->type]);
371
        }
372
373
        if ($sameTerm) {
374
            $query->innerJoinWith([
375
                'terms' => function ($query) {
376
                    /* @var $query \yii\db\ActiveQuery */
377
                    $query->from(['term' => Term::tableName()])->andWhere([
378
                        'IN',
379
                        'term.id',
380
                        implode(',', ArrayHelper::getColumn($this->terms, 'id')),
381
                    ]);
382
                },
383
            ]);
384
        }
385
386
        return $query->one();
387
    }
388
389
    /**
390
     * @param bool $sameType
391
     * @param bool $sameTerm
392
     * @param string $title
393
     * @param array $options
394
     * @return string
395
     */
396 View Code Duplication
    public function getPrevPostLink($title = '{title}', $sameType = true, $sameTerm = false, $options = [])
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
397
    {
398
        if ($prevPost = $this->getPrevPost($sameType, $sameTerm)) {
399
            $title = preg_replace_callback('/\\{([\w\-\/]+)\\}/', function ($matches) use ($prevPost) {
400
                $attribute = $matches[1];
401
402
                return $prevPost->{$attribute};
403
            }, $title);
404
405
            return Html::a($title, $prevPost->url, $options);
406
        }
407
408
        return '';
409
    }
410
411
    /**
412
     * Generate excerpt of post model.
413
     *
414
     * @param int $limit
415
     * @return string
416
     */
417
    public function getExcerpt($limit = 55)
418
    {
419
        $excerpt = preg_replace('/\s{3,}/', ' ', strip_tags($this->content));
420
        $words = preg_split("/[\n\r\t ]+/", $excerpt, $limit + 1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
421
422
        if (count($words) > $limit) {
423
            end($words);
424
            $lastWord = prev($words);
425
426
            $excerpt = substr($excerpt, 0, $lastWord[1] + strlen($lastWord[0]));
427
        }
428
429
        return $excerpt;
430
    }
431
432
433
    /**
434
     * Get permission to access model by current user.
435
     * @return bool
436
     */
437
    public function getPermission()
438
    {
439
        if (!$this->postType
440
            || !Yii::$app->user->can($this->postType->permission)
441
            || (!Yii::$app->user->can('editor') && Yii::$app->user->id !== $this->author)
442
            || (!Yii::$app->user->can('author') && $this->status === self::STATUS_REVIEW)
443
        ) {
444
            return false;
445
        }
446
447
        return true;
448
    }
449
450
    /**
451
     * @inheritdoc
452
     */
453
    public function beforeSave($insert)
454
    {
455
        if (parent::beforeSave($insert)) {
456
            if ($this->isNewRecord) {
457
                $this->author = Yii::$app->user->id;
458
            }
459
            $this->modified = date('Y-m-d H:i:s');
460
            $this->excerpt = $this->getExcerpt();
461
462
            return true;
463
        }
464
465
        return false;
466
    }
467
}
468