mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-24 04:27:59 +01:00
124 lines
3.2 KiB
Elixir
124 lines
3.2 KiB
Elixir
defmodule Philomena.Topics.Topic do
|
|
use Ecto.Schema
|
|
import Ecto.Changeset
|
|
|
|
alias Philomena.Forums.Forum
|
|
alias Philomena.Users.User
|
|
alias Philomena.Polls.Poll
|
|
alias Philomena.Posts.Post
|
|
alias Philomena.Topics.Subscription
|
|
alias Philomena.Slug
|
|
|
|
@derive {Phoenix.Param, key: :slug}
|
|
schema "topics" do
|
|
belongs_to :user, User
|
|
belongs_to :deleted_by, User
|
|
belongs_to :locked_by, User
|
|
belongs_to :last_post, Post
|
|
belongs_to :forum, Forum
|
|
has_one :poll, Poll
|
|
has_many :posts, Post
|
|
has_many :subscriptions, Subscription
|
|
|
|
field :title, :string
|
|
field :post_count, :integer, default: 1
|
|
field :view_count, :integer, default: 0
|
|
field :sticky, :boolean, default: false
|
|
field :last_replied_to_at, :naive_datetime
|
|
field :locked_at, :utc_datetime
|
|
field :deletion_reason, :string
|
|
field :lock_reason, :string
|
|
field :slug, :string
|
|
field :anonymous, :boolean, default: false
|
|
field :hidden_from_users, :boolean, default: false
|
|
|
|
timestamps(inserted_at: :created_at)
|
|
end
|
|
|
|
@doc false
|
|
def changeset(topic, attrs) do
|
|
topic
|
|
|> cast(attrs, [])
|
|
|> validate_required([])
|
|
end
|
|
|
|
@doc false
|
|
def creation_changeset(topic, attrs, forum, attribution) do
|
|
changes =
|
|
topic
|
|
|> cast(attrs, [:title, :anonymous])
|
|
|> validate_required([:title, :anonymous])
|
|
|
|
anonymous? =
|
|
changes
|
|
|> get_field(:anonymous)
|
|
|
|
changes
|
|
|> validate_length(:title, min: 4, max: 96, count: :bytes)
|
|
|> put_slug()
|
|
|> change(forum: forum, user: attribution[:user])
|
|
|> validate_required(:forum)
|
|
|> cast_assoc(:poll, with: &Poll.creation_changeset/2)
|
|
|> cast_assoc(:posts, with: {Post, :topic_creation_changeset, [attribution, anonymous?]})
|
|
|> validate_length(:posts, is: 1)
|
|
|> unique_constraint(:slug, name: :index_topics_on_forum_id_and_slug)
|
|
end
|
|
|
|
def stick_changeset(topic) do
|
|
change(topic)
|
|
|> put_change(:sticky, true)
|
|
end
|
|
|
|
def unstick_changeset(topic) do
|
|
change(topic)
|
|
|> put_change(:sticky, false)
|
|
end
|
|
|
|
def lock_changeset(topic, attrs, user) do
|
|
now = DateTime.utc_now() |> DateTime.truncate(:second)
|
|
|
|
change(topic)
|
|
|> cast(attrs, [:lock_reason])
|
|
|> put_change(:locked_at, now)
|
|
|> put_change(:locked_by_id, user.id)
|
|
|> validate_required([:lock_reason])
|
|
end
|
|
|
|
def unlock_changeset(topic) do
|
|
change(topic)
|
|
|> put_change(:locked_at, nil)
|
|
|> put_change(:locked_by_id, nil)
|
|
|> put_change(:lock_reason, "")
|
|
end
|
|
|
|
def move_changeset(topic, new_forum_id) do
|
|
change(topic)
|
|
|> put_change(:forum_id, new_forum_id)
|
|
end
|
|
|
|
def hide_changeset(topic, deletion_reason, user) do
|
|
change(topic)
|
|
|> put_change(:hidden_from_users, true)
|
|
|> put_change(:deleted_by_id, user.id)
|
|
|> put_change(:deletion_reason, deletion_reason)
|
|
|> validate_required([:deletion_reason])
|
|
end
|
|
|
|
def unhide_changeset(topic) do
|
|
change(topic)
|
|
|> put_change(:hidden_from_users, false)
|
|
|> put_change(:deleted_by_id, nil)
|
|
|> put_change(:deletion_reason, "")
|
|
end
|
|
|
|
def put_slug(changeset) do
|
|
slug =
|
|
changeset
|
|
|> get_field(:title)
|
|
|> Slug.destructive_slug()
|
|
|
|
changeset
|
|
|> put_change(:slug, slug)
|
|
|> validate_required(:slug, message: "must be printable")
|
|
end
|
|
end
|