/common/models/Post.php
PHP | 467 lines | 267 code | 57 blank | 143 comment | 22 complexity | 639711fe91ca2921ae875f7c3753d75f MD5 | raw file
- <?php
- /**
- * @link http://www.writesdown.com/
- * @copyright Copyright (c) 2015 WritesDown
- * @license http://www.writesdown.com/license/
- */
- namespace common\models;
- use common\components\Json;
- use Yii;
- use yii\behaviors\SluggableBehavior;
- use yii\db\ActiveRecord;
- use yii\helpers\ArrayHelper;
- use yii\helpers\Html;
- /**
- * This is the model class for table "{{%post}}".
- *
- * @property integer $id
- * @property integer $author
- * @property integer $type
- * @property string $title
- * @property string $excerpt
- * @property string $content
- * @property string $date
- * @property string $modified
- * @property string $status
- * @property string $password
- * @property string $slug
- * @property string $comment_status
- * @property integer $comment_count
- * @property string $url
- *
- * @property Media[] $media
- * @property PostType $postType
- * @property User $postAuthor
- * @property PostComment[] $postComments
- * @property PostMeta[] $postMeta
- * @property TermRelationship[] $termRelationships
- * @property Term[] $terms
- *
- * @author Agiel K. Saputra <13nightevil@gmail.com>
- * @since 0.1.0
- */
- class Post extends ActiveRecord
- {
- public $username;
- const COMMENT_STATUS_OPEN = 'open';
- const COMMENT_STATUS_CLOSE = 'close';
- const STATUS_PUBLISH = 'publish';
- const STATUS_PRIVATE = 'private';
- const STATUS_DRAFT = 'draft';
- const STATUS_TRASH = 'trash';
- const STATUS_REVIEW = 'review';
- /**
- * @inheritdoc
- */
- public static function tableName()
- {
- return '{{%post}}';
- }
- /**
- * @inheritdoc
- */
- public function behaviors()
- {
- return [
- [
- 'class' => SluggableBehavior::className(),
- 'attribute' => 'title',
- 'attributes' => [ActiveRecord::EVENT_BEFORE_INSERT => ['slug']],
- ],
- ];
- }
- /**
- * @inheritdoc
- */
- public function rules()
- {
- return [
- ['title', 'required'],
- [['author', 'type', 'comment_count'], 'integer'],
- [['title', 'excerpt', 'content'], 'string'],
- [['date', 'modified', 'author'], 'safe'],
- [['status', 'comment_status'], 'string', 'max' => 20],
- [['password', 'slug'], 'string', 'max' => 255],
- ['comment_status', 'in', 'range' => [self::COMMENT_STATUS_OPEN, self::COMMENT_STATUS_CLOSE]],
- ['comment_status', 'default', 'value' => self::COMMENT_STATUS_CLOSE],
- ['comment_count', 'default', 'value' => 0],
- [
- 'status',
- 'in',
- 'range' => [
- self::STATUS_PUBLISH,
- self::STATUS_DRAFT,
- self::STATUS_PRIVATE,
- self::STATUS_REVIEW,
- self::STATUS_TRASH,
- ],
- ],
- ['status', 'default', 'value' => self::STATUS_PUBLISH],
- [['title', 'slug'], 'unique'],
- ];
- }
- /**
- * @inheritdoc
- */
- public function attributeLabels()
- {
- return [
- 'id' => Yii::t('writesdown', 'ID'),
- 'author' => Yii::t('writesdown', 'Author'),
- 'type' => Yii::t('writesdown', 'Type'),
- 'title' => Yii::t('writesdown', 'Title'),
- 'excerpt' => Yii::t('writesdown', 'Excerpt'),
- 'content' => Yii::t('writesdown', 'Content'),
- 'date' => Yii::t('writesdown', 'Date'),
- 'modified' => Yii::t('writesdown', 'Modified'),
- 'status' => Yii::t('writesdown', 'Status'),
- 'password' => Yii::t('writesdown', 'Password'),
- 'slug' => Yii::t('writesdown', 'Slug'),
- 'comment_status' => Yii::t('writesdown', 'Comment Status'),
- 'comment_count' => Yii::t('writesdown', 'Comment Count'),
- 'username' => Yii::t('writesdown', 'Author'),
- ];
- }
- /**
- * @return \yii\db\ActiveQuery
- */
- public function getMedia()
- {
- return $this->hasMany(Media::className(), ['post_id' => 'id']);
- }
- /**
- * @return \yii\db\ActiveQuery
- */
- public function getPostType()
- {
- return $this->hasOne(PostType::className(), ['id' => 'type']);
- }
- /**
- * @return \yii\db\ActiveQuery
- */
- public function getPostAuthor()
- {
- return $this->hasOne(User::className(), ['id' => 'author']);
- }
- /**
- * @return \yii\db\ActiveQuery
- */
- public function getPostComments()
- {
- return $this->hasMany(PostComment::className(), ['post_id' => 'id']);
- }
- /**
- * @return \yii\db\ActiveQuery
- */
- public function getPostMeta()
- {
- return $this->hasMany(PostMeta::className(), ['post_id' => 'id']);
- }
- /**
- * @return \yii\db\ActiveQuery
- */
- public function getTermRelationships()
- {
- return $this->hasMany(TermRelationship::className(), ['post_id' => 'id']);
- }
- /**
- * @return \yii\db\ActiveQuery
- */
- public function getTerms()
- {
- return $this
- ->hasMany(Term::className(), ['id' => 'term_id'])
- ->viaTable('{{%term_relationship}}', ['post_id' => 'id']);
- }
- /**
- * Get post status as array.
- *
- * @return array
- */
- public function getPostStatuses()
- {
- return [
- self::STATUS_PUBLISH => Yii::t('writesdown', 'Publish'),
- self::STATUS_DRAFT => Yii::t('writesdown', 'Draft'),
- self::STATUS_PRIVATE => Yii::t('writesdown', 'Private'),
- self::STATUS_TRASH => Yii::t('writesdown', 'Trash'),
- self::STATUS_REVIEW => Yii::t('writesdown', 'Review'),
- ];
- }
- /**
- * Get comment status as array
- */
- public function getCommentStatuses()
- {
- return [
- self::COMMENT_STATUS_OPEN => Yii::t('writesdown', 'Open'),
- self::COMMENT_STATUS_CLOSE => Yii::t('writesdown', 'Close'),
- ];
- }
- /**
- * Get permalink of current post.
- *
- * @return string
- */
- public function getUrl()
- {
- return Yii::$app->urlManagerFront->createAbsoluteUrl(['/post/view', 'id' => $this->id]);
- }
- /**
- * Get meta for current post.
- *
- * @param string $name
- * @return mixed|null
- */
- public function getMeta($name)
- {
- /* @var $model \common\models\PostMeta */
- $model = PostMeta::findOne(['name' => $name, 'post_id' => $this->id]);
- if ($model) {
- if (Json::isJson($model->value)) {
- return Json::decode($model->value);
- }
- return $model->value;
- }
- return null;
- }
- /**
- * Add new meta data for current post.
- *
- * @param string $name
- * @param string|array $value
- * @return bool
- */
- public function setMeta($name, $value)
- {
- if (is_array($value) || is_object($value)) {
- $value = Json::encode($value);
- }
- if ($this->getMeta($name) !== null) {
- return $this->upMeta($name, $value);
- }
- $model = new PostMeta([
- 'post_id' => $this->id,
- 'name' => $name,
- 'value' => $value,
- ]);
- return $model->save();
- }
- /**
- * Update meta data for current post.
- *
- * @param string $name
- * @param string|array $value
- * @return bool
- */
- public function upMeta($name, $value)
- {
- /* @var $model \common\models\PostMeta */
- $model = PostMeta::findOne(['name' => $name, 'post_id' => $this->id]);
- if (is_array($value) || is_object($value)) {
- $value = Json::encode($value);
- }
- $model->value = $value;
- return $model->save();
- }
- /**
- * @param bool $sameType
- * @param bool $sameTerm
- * @return array|null|Post
- */
- public function getNextPost($sameType = true, $sameTerm = false)
- {
- /* @var $query \yii\db\ActiveQuery */
- $query = static::find()
- ->from(['post' => $this->tableName()])
- ->andWhere(['>', 'post.id', $this->id])
- ->andWhere(['status' => 'publish'])
- ->orderBy(['post.id' => SORT_ASC]);
- if ($sameType) {
- $query->andWhere(['type' => $this->type]);
- }
- if ($sameTerm) {
- $query->innerJoinWith([
- 'terms' => function ($query) {
- /* @var $query \yii\db\ActiveQuery */
- $query->from(['term' => Term::tableName()])->andWhere([
- 'IN',
- 'term.id',
- implode(',', ArrayHelper::getColumn($this->terms, 'id')),
- ]);
- },
- ]);
- }
- return $query->one();
- }
- /**
- * @param bool $sameType
- * @param bool $sameTerm
- * @param string $title
- * @param array $options
- * @return string
- */
- public function getNextPostLink($title = '{title}', $sameType = true, $sameTerm = false, $options = [])
- {
- if ($nextPost = $this->getNextPost($sameType, $sameTerm)) {
- $title = preg_replace_callback('/\\{([\w\-\/]+)\\}/', function ($matches) use ($nextPost) {
- $attribute = $matches[1];
- return $nextPost->{$attribute};
- }, $title);
- return Html::a($title, $nextPost->url, $options);
- }
- return '';
- }
- /**
- * @param bool $sameType
- * @param bool $sameTerm
- * @return array|null|Post
- */
- public function getPrevPost($sameType = true, $sameTerm = false)
- {
- /* @var $query \yii\db\ActiveQuery */
- $query = static::find()
- ->from(['post' => $this->tableName()])
- ->andWhere(['<', 'post.id', $this->id])
- ->andWhere(['status' => 'publish'])
- ->orderBy(['post.id' => SORT_DESC]);
- if ($sameType) {
- $query->andWhere(['type' => $this->type]);
- }
- if ($sameTerm) {
- $query->innerJoinWith([
- 'terms' => function ($query) {
- /* @var $query \yii\db\ActiveQuery */
- $query->from(['term' => Term::tableName()])->andWhere([
- 'IN',
- 'term.id',
- implode(',', ArrayHelper::getColumn($this->terms, 'id')),
- ]);
- },
- ]);
- }
- return $query->one();
- }
- /**
- * @param bool $sameType
- * @param bool $sameTerm
- * @param string $title
- * @param array $options
- * @return string
- */
- public function getPrevPostLink($title = '{title}', $sameType = true, $sameTerm = false, $options = [])
- {
- if ($prevPost = $this->getPrevPost($sameType, $sameTerm)) {
- $title = preg_replace_callback('/\\{([\w\-\/]+)\\}/', function ($matches) use ($prevPost) {
- $attribute = $matches[1];
- return $prevPost->{$attribute};
- }, $title);
- return Html::a($title, $prevPost->url, $options);
- }
- return '';
- }
- /**
- * Generate excerpt of post model.
- *
- * @param int $limit
- * @return string
- */
- public function getExcerpt($limit = 55)
- {
- $excerpt = preg_replace('/\s{3,}/', ' ', strip_tags($this->content));
- $words = preg_split("/[\n\r\t ]+/", $excerpt, $limit + 1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
- if (count($words) > $limit) {
- end($words);
- $lastWord = prev($words);
- $excerpt = substr($excerpt, 0, $lastWord[1] + strlen($lastWord[0]));
- }
- return $excerpt;
- }
- /**
- * Get permission to access model by current user.
- * @return bool
- */
- public function getPermission()
- {
- if (!$this->postType
- || !Yii::$app->user->can($this->postType->permission)
- || (!Yii::$app->user->can('editor') && Yii::$app->user->id !== $this->author)
- || (!Yii::$app->user->can('author') && $this->status === self::STATUS_REVIEW)
- ) {
- return false;
- }
- return true;
- }
- /**
- * @inheritdoc
- */
- public function beforeSave($insert)
- {
- if (parent::beforeSave($insert)) {
- if ($this->isNewRecord) {
- $this->author = Yii::$app->user->id;
- }
- $this->modified = date('Y-m-d H:i:s');
- $this->excerpt = $this->getExcerpt();
- return true;
- }
- return false;
- }
- }