src/models/db/ThreadActiveRecord.php
<?php
namespace bizley\podium\models\db;
use bizley\podium\db\ActiveRecord;
use bizley\podium\helpers\Helper;
use bizley\podium\models\Forum;
use bizley\podium\models\Poll;
use bizley\podium\models\Post;
use bizley\podium\models\Subscription;
use bizley\podium\models\ThreadView;
use bizley\podium\models\User;
use bizley\podium\Podium;
use bizley\podium\slugs\PodiumSluggableBehavior;
use Yii;
use yii\behaviors\TimestampBehavior;
use yii\helpers\HtmlPurifier;
/**
* Thread AR
*
* @author Paweł Bizley Brzozowski <pawel@positive.codes>
* @since 0.6
*
* @property int $id
* @property string $name
* @property string $slug
* @property int $category_id
* @property int $forum_id
* @property int $author_id
* @property int $pinned
* @property int $locked
* @property int $posts
* @property int $views
* @property int $updated_at
* @property int $created_at
* @property int $new_post_at
* @property int $edited_post_at
*/
class ThreadActiveRecord extends ActiveRecord
{
/**
* @var string attached post content
*/
public $post;
/**
* @var bool thread subscription flag
*/
public $subscribe;
/**
* @var int poll added
* @since 0.6
*/
public $pollAdded = 0;
/**
* @var string poll question
* @since 0.6
*/
public $pollQuestion;
/**
* @var int number of possible poll votes
* @since 0.6
*/
public $pollVotes = 1;
/**
* @var string[] poll answers
* @since 0.6
*/
public $pollAnswers = [];
/**
* @var string poll closing date
* @since 0.6
*/
public $pollEnd;
/**
* @var int should poll results be hidden before voting
* @since 0.6
*/
public $pollHidden = 0;
/**
* @inheritdoc
*/
public static function tableName()
{
return '{{%podium_thread}}';
}
/**
* @inheritdoc
*/
public function behaviors()
{
return [
TimestampBehavior::className(),
[
'class' => Podium::getInstance()->slugGenerator,
'attribute' => 'name',
'type' => PodiumSluggableBehavior::THREAD
],
];
}
/**
* @inheritdoc
*/
public function rules()
{
return [
['name', 'required', 'message' => Yii::t('podium/view', 'Topic can not be blank.')],
['post', 'required', 'on' => ['new']],
['post', 'string', 'min' => 10, 'on' => ['new']],
['post', 'filter', 'filter' => function ($value) {
if (Podium::getInstance()->podiumConfig->get('use_wysiwyg') == '0') {
return HtmlPurifier::process(trim($value), Helper::podiumPurifierConfig('markdown'));
}
return HtmlPurifier::process(trim($value), Helper::podiumPurifierConfig('full'));
}, 'on' => ['new']],
['pinned', 'boolean'],
['subscribe', 'boolean'],
['name', 'filter', 'filter' => function ($value) {
return HtmlPurifier::process(trim($value));
}],
['pollQuestion', 'string', 'max' => 255],
['pollVotes', 'integer', 'min' => 1, 'max' => 10],
['pollAnswers', 'each', 'rule' => ['string', 'max' => 255]],
['pollEnd', 'date', 'format' => 'yyyy-MM-dd'],
[['pollHidden', 'pollAdded'], 'boolean'],
['pollAnswers', 'requiredPollAnswers'],
[['pollQuestion', 'pollVotes'], 'required', 'when' => function ($model) {
return $model->pollAdded;
}, 'whenClient' => 'function (attribute, value) { return $("#poll_added").val() == 1; }'],
];
}
/**
* Filters and validates poll answers.
* @since 0.5
*/
public function requiredPollAnswers()
{
if ($this->pollAdded) {
$this->pollAnswers = array_unique($this->pollAnswers);
$filtered = [];
foreach ($this->pollAnswers as $answer) {
if (!empty(trim($answer))) {
$filtered[] = trim($answer);
}
}
$this->pollAnswers = $filtered;
if (count($this->pollAnswers) < 2) {
$this->addError('pollAnswers', Yii::t('podium/view', 'You have to add at least 2 options.'));
}
}
}
/**
* Returns poll attribute labels.
* @return array
* @since 0.5
*/
public function attributeLabels()
{
return [
'pollAuestion' => Yii::t('podium/view', 'Question'),
'pollVotes' => Yii::t('podium/view', 'Number of votes'),
'pollHidden' => Yii::t('podium/view', 'Hide results before voting'),
'pollEnd' => Yii::t('podium/view', 'Poll ends at'),
];
}
/**
* Forum relation.
* @return Forum
*/
public function getForum()
{
return $this->hasOne(Forum::className(), ['id' => 'forum_id']);
}
/**
* Poll relation.
* @return Forum
* @since 0.5
*/
public function getPoll()
{
return $this->hasOne(Poll::className(), ['thread_id' => 'id']);
}
/**
* ThreadView relation for user.
* @return ThreadView
*/
public function getUserView()
{
return $this->hasOne(ThreadView::className(), ['thread_id' => 'id'])->where(['user_id' => User::loggedId()]);
}
/**
* ThreadView relation general.
* @return ThreadView[]
*/
public function getThreadView()
{
return $this->hasMany(ThreadView::className(), ['thread_id' => 'id']);
}
/**
* Subscription relation.
* @return Subscription
*/
public function getSubscription()
{
return $this->hasOne(Subscription::className(), ['thread_id' => 'id'])->where(['user_id' => User::loggedId()]);
}
/**
* Latest post relation.
* @return Post
*/
public function getLatest()
{
return $this->hasOne(Post::className(), ['thread_id' => 'id'])->orderBy(['id' => SORT_DESC]);
}
/**
* Posts count.
* @return int
* @since 0.2
*/
public function getPostsCount()
{
return Post::find()->where(['thread_id' => $this->id])->count('id');
}
/**
* First post relation.
* @return Post
*/
public function getPostData()
{
return $this->hasOne(Post::className(), ['thread_id' => 'id'])->orderBy(['id' => SORT_ASC]);
}
/**
* First new not seen post relation.
* @return Post
*/
public function getFirstNewNotSeen()
{
return $this
->hasOne(Post::className(), ['thread_id' => 'id'])
->where(['>', 'created_at', $this->userView ? $this->userView->new_last_seen : 0])
->orderBy(['id' => SORT_ASC]);
}
/**
* First edited not seen post relation.
* @return Post
*/
public function getFirstEditedNotSeen()
{
return $this
->hasOne(Post::className(), ['thread_id' => 'id'])
->where(['>', 'edited_at', $this->userView ? $this->userView->edited_last_seen : 0])
->orderBy(['id' => SORT_ASC]);
}
/**
* Author relation.
* @return User
*/
public function getAuthor()
{
return $this->hasOne(User::className(), ['id' => 'author_id']);
}
}