philomena/lib/philomena_web/controllers/comment_controller.ex
2019-11-17 23:47:09 -05:00

89 lines
2.4 KiB
Elixir

defmodule PhilomenaWeb.CommentController do
use PhilomenaWeb, :controller
alias Philomena.{Images.Image, Comments.Comment, Textile.Renderer}
alias Philomena.Repo
import Ecto.Query
def index(conn, params) do
comments =
Comment.search_records(
%{
query: %{
bool: %{
must: parse_search(conn, params) ++ [%{term: %{hidden_from_users: false}}],
must_not: %{terms: %{image_tag_ids: conn.assigns.current_filter.hidden_tag_ids}}
}
},
sort: parse_sort(params)
},
conn.assigns.pagination,
Comment |> preload([image: [:tags], user: [awards: :badge]])
)
rendered =
comments.entries
|> Renderer.render_collection()
comments =
%{comments | entries: Enum.zip(comments.entries, rendered)}
render(conn, "index.html", comments: comments, layout_class: "layout--wide")
end
defp parse_search(conn, %{"comment" => comment_params}) do
parse_author(comment_params) ++
parse_image_id(conn, comment_params) ++
parse_body(comment_params)
end
defp parse_search(_conn, _params), do: [%{match_all: %{}}]
defp parse_author(%{"author" => author}) when is_binary(author) and author not in [nil, ""] do
case String.contains?(author, ["*", "?"]) do
true ->
[
%{wildcard: %{author: author}},
%{term: %{anonymous: false}}
]
false ->
[
%{term: %{author: author}},
%{term: %{anonymous: false}}
]
end
end
defp parse_author(_params), do: []
defp parse_image_id(conn, %{"image_id" => image_id}) when is_binary(image_id) and image_id not in [nil, ""] do
with {image_id, _rest} <- Integer.parse(image_id),
true <- valid_image?(conn.assigns.current_user, image_id)
do
[%{term: %{image_id: image_id}}]
else
_error ->
[]
end
end
defp parse_image_id(_conn, _params), do: []
defp parse_body(%{"body" => body}) when is_binary(body) and body not in [nil, ""],
do: [%{match: %{body: body}}]
defp parse_body(_params), do: []
defp parse_sort(%{"comment" => %{"sf" => sf, "sd" => sd}}) when sf in ["posted_at", "_score"] and sd in ["desc", "asc"] do
%{sf => sd}
end
defp parse_sort(_params) do
%{posted_at: :desc}
end
defp valid_image?(user, image_id) do
image =
Image
|> where(id: ^image_id)
|> Repo.one()
Canada.Can.can?(user, :show, image)
end
end