Current section

Files

Jump to
plato lib plato_web controllers content_controller.ex
Raw

lib/plato_web/controllers/content_controller.ex

defmodule PlatoWeb.ContentController do
use Phoenix.Controller, formats: [:html]
def index(conn, _params) do
schemas = repo(conn).all(Plato.Schema)
contents =
repo(conn).all(Plato.Content)
|> repo(conn).preload(:schema)
# Get count of content instances per schema
content_counts =
contents
|> Enum.group_by(& &1.schema_id)
|> Enum.map(fn {schema_id, contents} -> {schema_id, length(contents)} end)
|> Map.new()
render(conn, :index, schemas: schemas, contents: contents, content_counts: content_counts, base_path: base_path(conn))
end
def new(conn, %{"schema_id" => schema_id}) do
case repo(conn).get(Plato.Schema, schema_id) do
nil ->
conn
|> put_flash(:error, "Schema not found")
|> redirect(to: "#{base_path(conn)}/content")
schema ->
schema = repo(conn).preload(schema, [fields: :referenced_schema])
all_contents = repo(conn).all(Plato.Content) |> repo(conn).preload(:schema)
render(conn, :new, schema: schema, all_contents: all_contents, base_path: base_path(conn))
end
end
def create(conn, %{"schema_id" => schema_id, "content" => content_params}) do
schema = repo(conn).get(Plato.Schema, schema_id)
# Check if schema is unique and already has content
if schema && schema.unique do
existing_content =
repo(conn).get_by(Plato.Content, schema_id: schema_id)
if existing_content do
conn
|> put_flash(:error, "This schema is unique and already has content. You can only create one instance.")
|> redirect(to: "#{base_path(conn)}/content")
else
create_content(conn, schema_id, content_params)
end
else
create_content(conn, schema_id, content_params)
end
end
defp create_content(conn, schema_id, content_params) do
field_values =
content_params
|> Map.delete("schema_id")
|> Enum.reduce(%{}, fn {key, value}, acc ->
# Convert field IDs to strings and store values
Map.put(acc, key, value)
end)
attrs = %{
schema_id: schema_id,
field_values: field_values
}
case Plato.Content.create(attrs, repo(conn)) do
{:ok, _content} ->
conn
|> put_flash(:info, "Content created successfully!")
|> redirect(to: "#{base_path(conn)}/content")
{:error, _changeset} ->
conn
|> put_flash(:error, "Failed to create content")
|> redirect(to: "#{base_path(conn)}/content/new?schema_id=#{schema_id}")
end
end
def show(conn, %{"id" => id}) do
case repo(conn).get(Plato.Content, id) do
nil ->
conn
|> put_flash(:error, "Content not found")
|> redirect(to: "#{base_path(conn)}/content")
content ->
content = repo(conn).preload(content, [schema: [fields: :referenced_schema]])
all_contents = repo(conn).all(Plato.Content) |> repo(conn).preload(:schema)
render(conn, :show, content: content, all_contents: all_contents, base_path: base_path(conn))
end
end
def edit(conn, %{"id" => id}) do
case repo(conn).get(Plato.Content, id) do
nil ->
conn
|> put_flash(:error, "Content not found")
|> redirect(to: "#{base_path(conn)}/content")
content ->
content = repo(conn).preload(content, [schema: [fields: :referenced_schema]])
all_contents = repo(conn).all(Plato.Content) |> repo(conn).preload(:schema)
render(conn, :edit, content: content, all_contents: all_contents, base_path: base_path(conn))
end
end
def update(conn, %{"id" => id, "content" => content_params}) do
case repo(conn).get(Plato.Content, id) do
nil ->
conn
|> put_flash(:error, "Content not found")
|> redirect(to: "#{base_path(conn)}/content")
content ->
field_values =
content_params
|> Map.delete("schema_id")
|> Enum.reduce(%{}, fn {key, value}, acc ->
Map.put(acc, key, value)
end)
attrs = %{field_values: field_values}
case content |> Plato.Content.changeset(attrs) |> repo(conn).update() do
{:ok, updated_content} ->
conn
|> put_flash(:info, "Content updated successfully!")
|> redirect(to: "#{base_path(conn)}/content/#{updated_content.id}")
{:error, _changeset} ->
conn
|> put_flash(:error, "Failed to update content")
|> redirect(to: "#{base_path(conn)}/content/#{id}/edit")
end
end
end
# Private helper to get repo from conn assigns
defp repo(conn) do
otp_app = conn.assigns[:plato_otp_app] || :plato
otp_app
|> Application.get_env(:plato, [])
|> Keyword.get(:repo, Plato.Repo)
end
# Private helper to get base_path from conn assigns
defp base_path(conn), do: conn.assigns[:plato_base_path] || "/"
end