You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
376 lines
10 KiB
376 lines
10 KiB
<?php |
|
|
|
namespace common\modules\blog\entities; |
|
|
|
use common\modules\blog\entities\queries\BlogPostQuery; |
|
use core\behaviors\LanguageBehavior; |
|
use core\behaviors\SluggableRelationBehavior; |
|
use lhs\Yii2SaveRelationsBehavior\SaveRelationsBehavior; |
|
use yii\behaviors\TimestampBehavior; |
|
use yii\db\ActiveQuery; |
|
use yii\db\ActiveRecord; |
|
use yii\web\UploadedFile; |
|
use yiidreamteam\upload\ImageUploadBehavior; |
|
use Yii; |
|
|
|
|
|
/** |
|
* This is the model class for table "posts". |
|
* |
|
* @property int $id |
|
* @property int $category_id |
|
* @property int $published_at |
|
* @property int $created_at |
|
* @property int $updated_at |
|
* @property string $image |
|
* @property string $video |
|
* @property int $status |
|
* @property int $comments_count |
|
* @property int $views |
|
* @property string $slug |
|
* @property int $type |
|
* @property int $revision_at |
|
* @property int $revision_id |
|
* |
|
* @method ActiveRecord findTranslation(string $language) |
|
* @method void saveTranslations($translations) |
|
* |
|
* @property ActiveRecord[] translations |
|
* @property ActiveRecord[] translation |
|
* |
|
* @property BlogComment[] $blogComments |
|
* @property BlogTagAssignment[] $blogTagAssignments |
|
* @property BlogTag[] $tags |
|
* @property BlogCategory $category |
|
* |
|
* @mixin ImageUploadBehavior |
|
*/ |
|
class BlogPost extends ActiveRecord |
|
{ |
|
const STATUS_DRAFT = 0; |
|
const STATUS_ACTIVE = 1; |
|
|
|
const TYPE_PUBLIC = 0; |
|
const TYPE_REVISION = 1; |
|
const TYPE_PREVIEW = 2; |
|
|
|
const FILE_ORIGINAL_PATH = '@staticRoot/origin/posts'; |
|
|
|
public $_form; |
|
|
|
public static function create($form, $categoryId, $slug, $published_at, $video, $type = BlogPost::TYPE_PUBLIC): self |
|
{ |
|
$post = new static(); |
|
$post->category_id = $categoryId; |
|
$post->slug = $slug; |
|
$post->status = self::STATUS_DRAFT; |
|
$post->created_at = time(); |
|
$post->comments_count = 0; |
|
$post->published_at = $published_at; |
|
$post->video = $video; |
|
$post->type = $type; |
|
$post->revision_at = time(); |
|
$post->_form = $form; |
|
return $post; |
|
} |
|
|
|
public function setImage(UploadedFile $image): void |
|
{ |
|
$this->image = $image; |
|
} |
|
|
|
|
|
public function edit($form, $categoryId, $slug, $published_at, $video, $type = BlogPost::TYPE_PUBLIC): void |
|
{ |
|
$this->category_id = $categoryId; |
|
$this->slug = $slug; |
|
$this->published_at = $published_at; |
|
$this->video = $video; |
|
$this->type = $type; |
|
$this->revision_at = time(); |
|
$this->_form = $form; |
|
} |
|
|
|
/** |
|
* @inheritdoc |
|
*/ |
|
public static function tableName() |
|
{ |
|
return 'blog_posts'; |
|
} |
|
|
|
/** |
|
* @inheritdoc |
|
*/ |
|
public function attributeLabels() |
|
{ |
|
return [ |
|
'id' => Yii::t('blog', 'ID'), |
|
'category_id' => Yii::t('blog', 'Category'), |
|
'published_at' => Yii::t('blog', 'Published At'), |
|
'created_at' => Yii::t('blog', 'Created At'), |
|
'updated_at' => Yii::t('blog', 'Updated At'), |
|
'title' => Yii::t('blog', 'Title'), |
|
'description' => Yii::t('blog', 'Description'), |
|
'content' => Yii::t('blog', 'Content'), |
|
'image' => Yii::t('blog', 'Image'), |
|
'video' => Yii::t('blog', 'Video'), |
|
'type' => Yii::t('blog', 'Type'), |
|
'revision_at' => Yii::t('blog', 'Revision At'), |
|
'status' => Yii::t('blog', 'Status'), |
|
'meta_json' => Yii::t('blog', 'Meta Json'), |
|
'comments_count' => Yii::t('blog', 'Comments Count'), |
|
'views' => Yii::t('blog', 'Views'), |
|
'slug' => Yii::t('blog', 'Slug'), |
|
'meta_title' => Yii::t('blog', 'META Title'), |
|
'meta_description' => Yii::t('blog', 'META Description'), |
|
'meta_keywords' => Yii::t('blog', 'META Keywords'), |
|
]; |
|
} |
|
|
|
public function activate(): void |
|
{ |
|
if ($this->isActive()) { |
|
throw new \DomainException('Post is already active.'); |
|
} |
|
$this->status = self::STATUS_ACTIVE; |
|
} |
|
|
|
public function draft(): void |
|
{ |
|
if ($this->isDraft()) { |
|
throw new \DomainException('Post is already draft.'); |
|
} |
|
$this->status = self::STATUS_DRAFT; |
|
} |
|
|
|
public function isActive(): bool |
|
{ |
|
return $this->status == self::STATUS_ACTIVE; |
|
} |
|
|
|
|
|
public function isDraft(): bool |
|
{ |
|
return $this->status == self::STATUS_DRAFT; |
|
} |
|
|
|
public function getSeoTitle(): string |
|
{ |
|
return $this->translation->meta_title ?: $this->translation->title; |
|
} |
|
|
|
// Tags |
|
|
|
public function assignTag($id): void |
|
{ |
|
$assignments = $this->blogTagAssignments; |
|
foreach ($assignments as $assignment) { |
|
if ($assignment->isForTag($id)) { |
|
return; |
|
} |
|
} |
|
$assignments[] = BlogTagAssignment::create($id); |
|
$this->blogTagAssignments = $assignments; |
|
} |
|
|
|
public function revokeTag($id): void |
|
{ |
|
$assignments = $this->blogTagAssignments; |
|
foreach ($assignments as $i => $assignment) { |
|
if ($assignment->isForTag($id)) { |
|
unset($assignments[$i]); |
|
$this->blogTagAssignments = $assignments; |
|
return; |
|
} |
|
} |
|
throw new \DomainException('Assignment is not found.'); |
|
} |
|
|
|
public function revokeTags(): void |
|
{ |
|
$this->blogTagAssignments = []; |
|
} |
|
|
|
// Comments |
|
|
|
public function addComment($userId, $parentId, $text): BlogComment |
|
{ |
|
$parent = $parentId ? $this->getComment($parentId) : null; |
|
if ($parent && !$parent->isActive()) { |
|
throw new \DomainException('Cannot add comment to inactive parent.'); |
|
} |
|
$comments = $this->blogComments; |
|
$comments[] = $comment = BlogComment::create($userId, $parent ? $parent->id : null, $text); |
|
$this->updateComments($comments); |
|
return $comment; |
|
} |
|
|
|
public function editComment($id, $parentId, $text): void |
|
{ |
|
$parent = $parentId ? $this->getComment($parentId) : null; |
|
$comments = $this->blogComments; |
|
foreach ($comments as $comment) { |
|
if ($comment->isIdEqualTo($id)) { |
|
$comment->edit($parent ? $parent->id : null, $text); |
|
$this->updateComments($comments); |
|
return; |
|
} |
|
} |
|
throw new \DomainException('Comment is not found.'); |
|
} |
|
|
|
public function activateComment($id): void |
|
{ |
|
$comments = $this->blogComments; |
|
foreach ($comments as $comment) { |
|
if ($comment->isIdEqualTo($id)) { |
|
$comment->activate(); |
|
$this->updateComments($comments); |
|
return; |
|
} |
|
} |
|
throw new \DomainException('Comment is not found.'); |
|
} |
|
|
|
public function removeComment($id): void |
|
{ |
|
$comments = $this->blogComments; |
|
foreach ($comments as $i => $comment) { |
|
if ($comment->isIdEqualTo($id)) { |
|
if ($this->hasChildren($comment->id)) { |
|
$comment->draft(); |
|
} else { |
|
unset($comments[$i]); |
|
} |
|
$this->updateComments($comments); |
|
return; |
|
} |
|
} |
|
throw new \DomainException('Comment is not found.'); |
|
} |
|
|
|
public function getComment($id): BlogComment |
|
{ |
|
foreach ($this->blogComments as $comment) { |
|
if ($comment->isIdEqualTo($id)) { |
|
return $comment; |
|
} |
|
} |
|
throw new \DomainException('Comment is not found.'); |
|
} |
|
|
|
private function hasChildren($id): bool |
|
{ |
|
foreach ($this->blogComments as $comment) { |
|
if ($comment->isChildOf($id)) { |
|
return true; |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
private function updateComments(array $comments): void |
|
{ |
|
$this->blogComments = $comments; |
|
$this->comments_count = count(array_filter($comments, function (BlogComment $comment) { |
|
return $comment->isActive(); |
|
})); |
|
} |
|
|
|
###################################### |
|
|
|
public function getBlogComments(): ActiveQuery |
|
{ |
|
return $this->hasMany(BlogComment::class, ['post_id' => 'id']); |
|
} |
|
|
|
public function getBlogTagAssignments(): ActiveQuery |
|
{ |
|
return $this->hasMany(BlogTagAssignment::class, ['post_id' => 'id']); |
|
} |
|
|
|
public function getTags(): ActiveQuery |
|
{ |
|
return $this->hasMany(BlogTag::class, ['id' => 'tag_id'])->viaTable('blog_tag_assignments', ['post_id' => 'id']); |
|
} |
|
|
|
public function getCategory(): ActiveQuery |
|
{ |
|
return $this->hasOne(BlogCategory::class, ['id' => 'category_id']); |
|
} |
|
|
|
###################################### |
|
|
|
public function behaviors(): array |
|
{ |
|
return [ |
|
TimestampBehavior::class, |
|
[ |
|
'class' => SaveRelationsBehavior::class, |
|
'relations' => ['blogTagAssignments', 'blogComments'], |
|
], |
|
/*[ |
|
'class' => SluggableBehavior::class, |
|
'attribute' => 'title', |
|
'ensureUnique' => true, |
|
'preserveNonEmptyValues' => true, |
|
],*/ |
|
[ |
|
'class' => LanguageBehavior::class, |
|
'virtualClassName' => 'BlogVirtualTranslate', |
|
'translatedLanguages' => \Yii::$app->params['translatedLanguages'], |
|
'relativeField' => 'blog_post_id', |
|
'tableName' => "{{%blog_posts_lng}}", |
|
'attributes' => ['title', 'description', 'content', 'meta_title', 'meta_description', 'meta_keywords'], |
|
//'defaultLanguage' => basename(Yii::$app->getBasePath()) === 'backend' ? Yii::$app->language : Yii::$app->params['defaultLanguage'], |
|
'defaultLanguage' => \Yii::$app->params['defaultLanguage'], |
|
], |
|
[ |
|
'class' => SluggableRelationBehavior::class, |
|
'attribute' => 'title', |
|
'relation' => 'translation', |
|
], |
|
[ |
|
// todo Image Sizes to settings or theme settings |
|
'class' => ImageUploadBehavior::class, |
|
'attribute' => 'image', |
|
'createThumbsOnRequest' => true, |
|
//'filePath' => $this::FILE_ORIGINAL_PATH . '/[[id]].[[extension]]', |
|
'filePath' => '@staticRoot/origin/posts/[[id]].[[extension]]', |
|
'fileUrl' => '@static/origin/posts/[[id]].[[extension]]', |
|
'thumbPath' => '@staticRoot/cache/posts/[[profile]]_[[id]].[[extension]]', |
|
'thumbUrl' => '@static/cache/posts/[[profile]]_[[id]].[[extension]]', |
|
'thumbs' => [ |
|
'blog_list' => ['width' => 750, 'height' => 300, 'resizeUp' => true], |
|
'blog_post' => ['width' => 900, 'height' => 300], |
|
|
|
'admin' => ['width' => 60, 'height' => 60], |
|
'thumb' => ['width' => 150, 'height' => 150], |
|
'list' => ['width' => 200, 'height' => 200], |
|
'home_slider' => ['width' => 369, 'height' => 343], |
|
'94_94' => ['width' => 94, 'height' => 94], |
|
'368_287' => ['width' => 368, 'height' => 287], |
|
'370_325' => ['width' => 370, 'height' => 325], |
|
'683_407' => ['width' => 683, 'height' => 407], |
|
'thumb_gallery_view' => ['width' => 300, 'height' => 170], |
|
//'widget_list' => ['width' => 228, 'height' => 228], |
|
//'origin' => ['processor' => [new WaterMarker(1024, 768, '@frontend/web/image/logo.png'), 'process']], |
|
'origin' => ['width' => 1024, 'height' => 768], |
|
], |
|
], |
|
]; |
|
} |
|
|
|
public function transactions(): array |
|
{ |
|
return [ |
|
self::SCENARIO_DEFAULT => self::OP_ALL, |
|
]; |
|
} |
|
|
|
public static function find(): BlogPostQuery |
|
{ |
|
return new BlogPostQuery(static::class); |
|
} |
|
}
|
|
|