Sequenzia/app/models/ForumPost.php
2013-11-19 12:31:38 -05:00

189 lines
5.1 KiB
PHP
Executable File

<?php
class ForumPost extends Rails\ActiveRecord\Base
{
protected function associations()
{
return [
'belongs_to' => [
'creator' => ['class_name' => 'User', 'foreign_key' => 'creator_id'],
'updater' => ['class_name' => 'User', 'foreign_key' => 'last_updated_by'],
'parent' => ['class_name' => "ForumPost", 'foreign_key' => 'parent_id']
],
'has_many' => [
'children' => [function() { $this->order('id'); }, 'class_name' => "ForumPost", 'foreign_key' => 'parent_id']
]
];
}
protected function callbacks()
{
return [
'after_create' => ['initialize_last_updated_by', 'update_parent_on_create', 'clear_cache'],
'before_destroy' => ['update_parent_on_destroy'],
'before_validation' => ['validate_title', 'validate_lock']
];
}
protected function validations()
{
return [
'body' => [
'length' => ['minimum' => 1, 'message' => "You need to enter a body"]
]
];
}
/* LockMethods { */
static public function lock($id)
{
# Run raw SQL to skip the lock check
self::connection()->executeSql("UPDATE forum_posts SET is_locked = TRUE WHERE id = ?", $id);
}
static public function unlock($id)
{
# Run raw SQL to skip the lock check
self::connection()->executeSql("UPDATE forum_posts SET is_locked = FALSE WHERE id = ?", $id);
}
public function validate_lock()
{
if ($this->root()->is_locked) {
$this->errors()->add('base', "Thread is locked");
return false;
}
return true;
}
/* } StickyMethods { */
static public function stick($id)
{
# Run raw SQL to skip the lock check
self::connection()->executeSql("UPDATE forum_posts SET is_sticky = TRUE WHERE id = ?", $id);
}
static public function unstick($id)
{
# Run raw SQL to skip the lock check
self::connection()->executeSql("UPDATE forum_posts SET is_sticky = FALSE WHERE id = ?", $id);
}
/* } ParentMethods { */
public function update_parent_on_destroy()
{
if (!$this->is_parent()) {
$p = $this->parent;
$p->updateAttributes(['response_count' => $p->response_count - 1]);
}
}
public function update_parent_on_create()
{
if (!$this->is_parent()) {
$p = $this->parent;
$p->updateAttributes(['updated_at' => $this->updated_at, 'response_count' => $p->response_count + 1, 'last_updated_by' => $this->creator_id]);
}
}
public function is_parent()
{
return !(bool)$this->parent_id;
}
public function root()
{
if ($this->is_parent()) {
return $this;
} else {
return $this->parent;
}
}
public function root_id()
{
if ($this->is_parent()) {
return $this->id;
} else {
return $this->parent_id;
}
}
/* } ApiMethods { */
public function api_attributes()
{
return [
'body' => $this->body,
'creator' => $this->author(),
'creator_id' => $this->creator_id,
'id' => $this->id,
'parent_id' => $this->parent_id,
'title' => $this->title,
'updated_at' => $this->updated_at,
'pages' => ceil((!$this->response_count ? 1 : $this->response_count) / 30)
];
}
public function asJson(array $params = [])
{
return $this->api_attributes();
}
public function toXml(array $options = [])
{
return parent::toXml(array_merge($options, ['root' => "forum-post", 'attributes' => $this->api_attributes()]));
}
/* } */
static public function updated($user)
{
$query = ForumPost::none();
if (!$user->is_anonymous())
$query->where("creator_id <> " . $user->id);
$newest_topic = $query->order("id desc")->limit(1)->select("created_at")->first();
if (!$newest_topic)
return false;
return $newest_topic->created_at > $user->last_forum_topic_read_at;
}
public function validate_title()
{
if ($this->is_parent()) {
if (!$this->title || !preg_match('/\S/', $this->title)) {
$this->errors()->add('title', "missing");
return false;
}
}
return true;
}
public function initialize_last_updated_by()
{
if ($this->is_parent()) {
$this->updateAttribute('last_updated_by', $this->creator_id);
}
}
public function last_updater()
{
return $this->updater ? $this->updater->name : CONFIG()->default_guest_name;
}
public function author()
{
return $this->creator->name;
}
protected function clear_cache()
{
Rails::cache()->delete("forum_posts");
}
}