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.

367 lines
9.4 KiB

7 years ago
<?php
namespace core\entities\post;
use core\behaviors\MetaBehavior;
use core\entities\Meta;
use core\entities\post\queries\PostQuery;
use lhs\Yii2SaveRelationsBehavior\SaveRelationsBehavior;
use yii\behaviors\TimestampBehavior;
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 $title
* @property string $description
* @property string $content
* @property string $image
* @property string $video
* @property int $status
* @property string $meta_json
* @property int $comments_count
* @property int $type_id
* @property int $views
* @property string $slug
*
* @property PostComment[] $postComments
* @property PostTagAssignment[] $postTagAssignments
* @property PostTag[] $tags
* @property PostCategory $category
* @property PostType $type
*
* @mixin ImageUploadBehavior
*/
class Post extends ActiveRecord
{
const STATUS_DRAFT = 0;
const STATUS_ACTIVE = 1;
const FILE_ORIGINAL_PATH = '@staticRoot/origin/posts';
public $meta;
public static function create($categoryId, $title, $slug, $description, $content, $type_id, $published_at, $video, Meta $meta): self
{
$post = new static();
$post->category_id = $categoryId;
$post->title = $title;
$post->slug = $slug;
$post->description = $description;
$post->content = $content;
$post->meta = $meta;
$post->status = self::STATUS_DRAFT;
$post->created_at = time();
$post->comments_count = 0;
$post->type_id = $type_id;
$post->published_at = $published_at;
$post->video = $video;
return $post;
}
public function setImage(UploadedFile $image): void
{
$this->image = $image;
}
public function edit($categoryId, $title, $slug, $description, $content, $published_at, $video, Meta $meta): void
{
$this->category_id = $categoryId;
$this->title = $title;
$this->slug = $slug;
$this->description = $description;
$this->content = $content;
$this->meta = $meta;
$this->published_at = $published_at;
$this->video = $video;
}
/**
* @inheritdoc
*/
public static function tableName()
{
return 'posts';
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => Yii::t('post', 'ID'),
'category_id' => Yii::t('post', 'Category'),
'published_at' => Yii::t('post', 'Published At'),
'created_at' => Yii::t('post', 'Created At'),
'updated_at' => Yii::t('post', 'Updated At'),
'title' => Yii::t('post', 'Title'),
'description' => Yii::t('post', 'Description'),
'content' => Yii::t('post', 'Content'),
'image' => Yii::t('post', 'Image'),
'video' => Yii::t('post', 'Video'),
'status' => Yii::t('post', 'Status'),
'meta_json' => Yii::t('post', 'Meta Json'),
'comments_count' => Yii::t('post', 'Comments Count'),
'type_id' => Yii::t('post', 'Type'),
'views' => Yii::t('post', 'Views'),
'slug' => Yii::t('post', 'Slug'),
'meta.title' => Yii::t('post', 'Meta Title'),
'meta.description' => Yii::t('post', 'Meta Description'),
'meta.keywords' => Yii::t('post', 'Meta Keywords'),
];
}
public function activate(): void
{
if ($this->isActive()) {
throw new \DomainException(Yii::t('post', '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->meta->title ?: $this->title;
}
// Tags
public function assignTag($id): void
{
$assignments = $this->postTagAssignments;
foreach ($assignments as $assignment) {
if ($assignment->isForTag($id)) {
return;
}
}
$assignments[] = PostTagAssignment::create($id);
$this->postTagAssignments = $assignments;
}
public function revokeTag($id): void
{
$assignments = $this->postTagAssignments;
foreach ($assignments as $i => $assignment) {
if ($assignment->isForTag($id)) {
unset($assignments[$i]);
$this->postTagAssignments = $assignments;
return;
}
}
throw new \DomainException('Assignment is not found.');
}
public function revokeTags(): void
{
$this->postTagAssignments = [];
}
// Comments
public function addComment($userId, $parentId, $text): PostComment
{
$parent = $parentId ? $this->getComment($parentId) : null;
if ($parent && !$parent->isActive()) {
throw new \DomainException('Cannot add comment to inactive parent.');
}
$comments = $this->postComments;
$comments[] = $comment = PostComment::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->postComments;
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->postComments;
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->postComments;
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): PostComment
{
foreach ($this->postComments as $comment) {
if ($comment->isIdEqualTo($id)) {
return $comment;
}
}
throw new \DomainException('Comment is not found.');
}
private function hasChildren($id): bool
{
foreach ($this->postComments as $comment) {
if ($comment->isChildOf($id)) {
return true;
}
}
return false;
}
private function updateComments(array $comments): void
{
$this->postComments = $comments;
$this->comments_count = count(array_filter($comments, function (PostComment $comment) {
return $comment->isActive();
}));
}
######################################
/**
* @return \yii\db\ActiveQuery
*/
public function getPostComments()
{
6 years ago
return $this->hasMany(PostComment::class, ['post_id' => 'id']);
7 years ago
}
/**
* @return \yii\db\ActiveQuery
*/
public function getPostTagAssignments()
{
6 years ago
return $this->hasMany(PostTagAssignment::class, ['post_id' => 'id']);
7 years ago
}
/**
* @return \yii\db\ActiveQuery
*/
public function getTags()
{
return $this->hasMany(PostTag::className(), ['id' => 'tag_id'])->viaTable('post_tag_assignments', ['post_id' => 'id']);
}
/**
* @return \yii\db\ActiveQuery
*/
public function getCategory()
{
return $this->hasOne(PostCategory::className(), ['id' => 'category_id']);
}
/**
* @return \yii\db\ActiveQuery
*/
public function getType()
{
return $this->hasOne(PostType::className(), ['id' => 'type_id']);
}
######################################
public function behaviors(): array
{
return [
TimestampBehavior::className(),
MetaBehavior::className(),
[
'class' => SaveRelationsBehavior::className(),
'relations' => ['postTagAssignments', 'postComments'],
],
[
'class' => ImageUploadBehavior::className(),
'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' => [
'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(): PostQuery
{
return new PostQuery(static::class);
}
}