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.
		
		
		
		
		
			
		
			
				
					
					
						
							361 lines
						
					
					
						
							9.6 KiB
						
					
					
				
			
		
		
	
	
							361 lines
						
					
					
						
							9.6 KiB
						
					
					
				| <?php | |
|  | |
| namespace common\modules\blog\entities; | |
|  | |
| use common\modules\blog\entities\queries\BlogPostQuery; | |
| use core\behaviors\MetaBehavior; | |
| use core\behaviors\RevisionBehavior; | |
| use core\entities\Meta; | |
| 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 $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 $views | |
|  * @property string $slug | |
|  * @property int $type | |
|  * @property int $revision_at | |
|  * @property int $revision_id | |
|  * | |
|  * @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 $meta; | |
|  | |
| 	public static function create($categoryId, $title, $slug, $description, $content, $published_at, $video, $type = 0, 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->published_at = $published_at; | |
| 		$post->video = $video; | |
| 		$post->type = $type; | |
| 		$post->revision_at = time(); | |
| 		return $post; | |
| 	} | |
|  | |
| 	public function setImage(UploadedFile $image): void | |
| 	{ | |
| 		$this->image = $image; | |
| 	} | |
|  | |
|  | |
| 	public function edit($categoryId, $title, $slug, $description, $content, $published_at, $video, $type = 0, 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; | |
| 		$this->type = $type; | |
| 		$this->revision_at = time(); | |
| 	} | |
|  | |
|     /** | |
|      * @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->meta->title ?: $this->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, | |
| 			MetaBehavior::class, | |
| 			[ | |
| 				'class' => SaveRelationsBehavior::class, | |
| 				'relations' => ['blogTagAssignments', 'blogComments'], | |
| 			], | |
| 			[ | |
| 				// 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); | |
| 	} | |
| }
 | |
| 
 |