Файл: protected/models/Post.php
Строк: 166
<?php
/*
* Модель статьи
*/
class Post extends CActiveRecord
{
/*
* Статус опубликованной записи
*/
const STATUS_PUBLISHED = 'published';
/*
* Статус черновика
*/
const STATUS_DRAFT = 'draft';
/*
* Допустимые символы в тегах
*/
const TAGS_MATCH = 'а-яa-z0-9_- .!';
/*
* Эту хрень надо передавать из-за особенностей языка и фреймворка...
*/
public static function model ($className = __CLASS__)
{
return parent::model ($className);
}
/*
* Имя таблицы, соответствующей классу
*/
public function tableName ()
{
return '{{post}}';
}
/*
* Связь с другими таблицами
*/
public function relations ()
{
return array (
// Имя категории, в которой находится статья
'category' => array (self::BELONGS_TO, 'Category', 'id_category'),
// Количество комментариев
'commentCount' => array (self::STAT, 'Comment', 'id_post'),
// Данные об авторе статьи
'user' => array (self::BELONGS_TO, 'User', 'id_user')
);
}
/*
* Сохранение системных данных
*/
public function beforeSave()
{
if ($this->isNewRecord) $this->create_time = time ();
$this->update_time = time ();
// Определяем тип статьи: Обычная или Новость
switch (Yii::app ()->controller->id)
{
default: case 'post':
$this->type = 'post';
break;
case 'news':
$this->type = 'news';
break;
}
if (Yii::app ()->controller->action->id == 'createNews') $this->id_category = Category::ID_NEWS;
if ($this->isNewRecord) $this->id_user = Yii::app ()->user->id;
return parent::beforeSave ();
}
/*
* Правила проверки (валидации)
*/
public function rules ()
{
$rules = array (
array ('title', 'required',
'message' => 'Вы не ввели заголовок статьи'),
array ('title', 'length', 'min'=>2, 'max'=>100, 'encoding' => 'utf8',
'tooShort' => 'Заголовок статьи должен быть длиной не менее 2 символов',
'tooLong' => 'Заголовок статьи должен быть длиной не более 100 символов'),
array ('status', 'default', 'value' => self::STATUS_PUBLISHED),
array ('status', 'in', 'range' => array (self::STATUS_PUBLISHED, self::STATUS_DRAFT)),
array ('info_content', 'required',
'message' => 'Вы не ввели аннотацию статьи'),
array ('info_content', 'length', 'min'=>2, 'max'=>500, 'encoding' => 'utf8',
'tooShort' => 'Аннотация статьи должна быть длиной не менее 2 символов',
'tooLong' => 'Аннотация статьи должна быть длиной не более 500 символов'),
array ('cut_content', 'required',
'message' => 'Вы не ввели содержимое статьи'),
array ('cut_content', 'length', 'min'=>2, 'max'=>1024*100, 'encoding' => 'utf8',
'tooShort' => 'Содержимое статьи должно быть длиной не менее 2 символов',
'tooLong' => 'Содержимое статьи должно быть длиной не более 100 килобайт'),
array ('tags', 'match', 'pattern' => '#^[' . self::TAGS_MATCH . ']+(' . Tag::RAZD . '[' . self::TAGS_MATCH . ']+)*$#iu',
'message' => 'Теги должны быть словами или цифрами, перечисленными через запятую (Tag1, tag2, tag3 и т.д.)')
);
if (Yii::app ()->controller->action->id == 'create')
{
$rules = CMap::mergeArray ($rules, array (
array ('id_category', 'required',
'message' => 'Вы не выбрали категорию'),
array ('id_category', 'numerical', 'integerOnly' => '',
'message' => 'Категория должна быть числом'),
));
}
return $rules;
}
/*
* Загрузка статей из определенной категории
*/
public function loadPostsFromCategory ($id)
{
$criteria = array (
'condition' => '`id_category` = :id_category' . ((Yii::app ()->user->isGuest) ? ' AND `status`= :status' : ''),
'params' => array (
':id_category' => (int)$id
),
'order' => '`create_time` DESC',
'with' => array ('commentCount')
);
// Если юзер - гость, добавляем дополнительное условие
if (Yii::app ()->user->isGuest) {
$criteria = CMap::mergeArray ($criteria, array (
'params' => array (':status' => self::STATUS_PUBLISHED)
));
}
return new CActiveDataProvider (get_class ($this), array (
'criteria' => new CDbCriteria ($criteria),
// Постраничная навигация
'pagination' => array (
'pageSize' => Yii::app ()->config->page_count_categories
)
));
}
/*
* Загрузка статей для RSS
*/
public function loadToRss ()
{
$criteria = new CDbCriteria (array (
'order' => '`create_time` DESC',
'with' => 'commentCount',
'condition' => '`status` = :status',
'params' => array (':status' => self::STATUS_PUBLISHED)
));
return new CActiveDataProvider (get_class ($this), array (
'criteria' => $criteria,
// Постраничная навигация
'pagination' => array (
'pageSize' => Yii::app ()->config->rss_item_count
)
));
}
/*
* Загрузка статей для RSS из определенной категории
*/
public function loadToRssFromCategory ($id)
{
$criteria = new CDbCriteria;
$criteria->condition = (Yii::app ()->user->isGuest) ? '`id_category` = :id_category AND `status` = "' . self::STATUS_PUBLISHED . '"' : '`id_category` = :id_category';//! без параметров
$criteria->params = array (
':id_category' => (int)$id
);
$criteria->order = '`create_time` DESC';
$criteria->with = array ('commentCount');
return new CActiveDataProvider (get_class ($this), array (
'criteria' => $criteria,
// Постраничная навигация
'pagination' => array (
'pageSize' => Yii::app ()->config->rss_item_count
)
));
}
/*
* Загрузка последних статей
*/
public function loadLastPosts ()
{
$criteria = array (
'order' => '`create_time` DESC',
'with' => 'commentCount',
);
// Если юзер - гость, добавляем дополнительное условие
if (Yii::app ()->user->isGuest) {
$criteria = CMap::mergeArray ($criteria, array (
'condition' => '`status` = :status',
'params' => array (':status' => self::STATUS_PUBLISHED)
));
}
return new CActiveDataProvider (get_class ($this), array (
'criteria' => new CDbCriteria ($criteria),
'pagination' => array (
'pageSize' => Yii::app ()->config->page_count_last_posts
)
));
}
/*
* Загрузка черновиков
*/
public function loadDrafts ()
{
$criteria = new CDbCriteria (array (
'order' => '`create_time` DESC',
'with' => 'commentCount',
'condition' => '`status` = :status',
'params' => array (':status' => self::STATUS_DRAFT)
));
return new CActiveDataProvider (get_class ($this), array (
'criteria' => $criteria,
// Постраничная навигация
'pagination' => array (
'pageSize' => Yii::app ()->config->page_count_categories
)
));
}
/*
* Загрузка статей с определенным тегом
* @param $pageSize object Костыль для того, чтобы юзать этот метод в RSS
*/
public function loadByTag ($tag, $pageSize = NULL)
{
if (empty ($tag)) throw new CHttpException (500, 'Неправильный запрос');
if ($pageSize === NULL) $pageSize = Yii::app ()->config->page_count_categories;
$criteria = array (
'order' => '`create_time` DESC',
'with' => 'commentCount',
'condition' => ((Yii::app ()->user->isGuest) ? '`status` = :status AND ' : '') . '(`tags` = :tag1 OR `tags` LIKE :tag2 OR `tags` LIKE :tag3 OR `tags` LIKE :tag4)',
'params' => array (
':tag1' => $tag, // Когда в статье 1 тег
':tag2' => $tag . Tag::RAZD . '%', // Когда тег стоит первым
':tag3' => '%' . Tag::RAZD . $tag, // Когда тег стоит последним
':tag4' => '%' . Tag::RAZD . $tag . Tag::RAZD . '%' // Когда тег где-то среди других тегов
)
);
// Если юзер - гость, добавляем дополнительное условие
if (Yii::app ()->user->isGuest) {
$criteria = CMap::mergeArray ($criteria, array (
'params' => array (':status' => self::STATUS_PUBLISHED)
));
}
return new CActiveDataProvider (get_class ($this), array (
'criteria' => new CDbCriteria ($criteria),
// Постраничная навигация
'pagination' => array (
'pageSize' => $pageSize
)
));
}
/*
* Загрузка статей по рейтингу (для топа)
*/
public function loadByRating ()
{
$criteria = array(
'order' => '`positive_votes` - `negative_votes` DESC',
'with' => 'commentCount'
);
// Если юзер - гость, добавляем дополнительное условие
if (Yii::app ()->user->isGuest) {
$criteria = CMap::mergeArray ($criteria, array (
'condition' => '`status` = :status',
'params' => array (':status' => self::STATUS_PUBLISHED)
));
}
return new CActiveDataProvider (get_class ($this), array (
'criteria' => new CDbCriteria ($criteria),
'pagination' => array (
'pageSize' => Yii::app ()->config->page_count_categories
)
));
}
/*
* Получение количества черновиков
*/
public function getCountDrafts ()
{
return self::model ()->count ('`status` = :status', array (':status' => self::STATUS_DRAFT));
}
}