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); | 
						|
	} | 
						|
}
 | 
						|
 |