Packages

This is a CMS written in Elixir. Aims to be the great open-source ecommerce and/or startup solution for those who are searching for a performance and stability on top of modern technologies like React and Elixir.

Current section

Files

Jump to
lyn web controllers admin admin_controller.ex
Raw

web/controllers/admin/admin_controller.ex

defmodule Lyn.Admin.AdminController do
use Lyn.Web, :admin_controller
import Inflex
alias Lyn.Domain
alias Lyn.Language
alias Lyn.Object
alias Lyn.ObjectType
alias Lyn.Site
alias Lyn.User
def models, do: %{
"domains" => Domain,
"languages" => Language,
"objects" => Object,
"object_types" => ObjectType,
"sites" => Site,
"users" => User
}
plug :assign_languages
plug :object_tree
def dashboard(conn, _params, current_user, _claims) do
render(conn, "dashboard.html")
end
def index(conn, params, current_user, _claims) do
resource = params["resource"]
model = models[resource]
case model do
nil ->
render(conn, "dashboard.html")
model ->
sort = String.to_atom(params["sort"] || "id")
direction = params["direction"] || "asc"
entries = case conn.assigns[:entries] do
nil ->
query = case direction do
"asc" ->
from(m in model, order_by: [asc: ^sort])
_ ->
from(m in model, order_by: [desc: ^sort])
end
Repo.all(query)
entries ->
entries
end
columns = Enum.drop(Map.keys(model.__struct__), 2)
render(conn, "index.html", entries: entries,
columns: model.admin_fields,
model: model,
resource: resource,
sort: sort,
direction: direction)
end
end
def new(conn, params, current_user, _claims) do
resource = params["resource"]
case Map.has_key?(params, "site_id") do
true ->
site_id = params["site_id"]
model = models[resource]
model_map = generate_model_map(conn, model, site_id)
changeset = model.changeset(model_map)
render(conn, "new.html", changeset: changeset, model: model, resource: resource)
_ ->
redirect(conn, to: admin_admin_path(conn, :index, resource))
end
end
def create(conn, params, current_user, _claims) do
resource = params["resource"]
entry_params = params[singularize(resource)]
model = models[resource]
changeset = model.changeset(struct(model), entry_params)
case Repo.insert(changeset) do
{:ok, _entry} ->
conn
|> put_flash(:info, "Entry created successfully.")
|> redirect(to: admin_admin_path(conn, :index, resource))
{:error, changeset} ->
#throw changeset
render(conn, "new.html", changeset: changeset, model: model, resource: resource)
end
end
def edit(conn, %{"resource" => resource, "id" => id}, current_user, _claims) do
model = models[resource]
entry = case function_exported?(model, :admin_outer_texts, 0) do
true ->
Repo.get!(model, id)
|> Repo.preload(model.admin_outer_texts[:assoc])
_ ->
Repo.get!(model, id)
end
changeset = model.changeset(entry)
render(conn, "edit.html", entry: entry, changeset: changeset, model: model, resource: resource)
end
def update(conn, params, current_user, _claims) do
id = params["id"]
resource = params["resource"]
entry_params = params[singularize(resource)]
model = models[resource]
entry = case Kernel.function_exported?(model, :admin_outer_texts, 0) do
true ->
Repo.get!(model, id)
|> Repo.preload(model.admin_outer_texts[:assoc])
_ ->
Repo.get!(model, id)
end
changeset = model.changeset(entry, entry_params)
case Repo.update(changeset) do
{:ok, entry} ->
conn
|> put_flash(:info, "Entry updated successfully.")
|> redirect(to: admin_admin_path(conn, :edit, resource, entry.id))
{:error, changeset} ->
render(conn, "edit.html", entry: entry, changeset: changeset, model: model, resource: resource)
end
end
def delete(conn, %{"resource" => resource, "id" => id}, current_user, _claims) do
model = models[resource]
entry = Repo.get!(model, id)
# Here we use delete! (with a bang) because we expect
# it to always work (and if it does not, it will raise).
Repo.delete!(entry)
conn
|> put_flash(:info, "Entry deleted successfully.")
|> redirect(to: admin_admin_path(conn, :index, resource))
end
defp assign_languages(conn, _params) do
query = from(l in Language, order_by: l.sort_order)
languages = Repo.all(query)
assign(conn, :languages, languages)
end
defp object_tree(conn, _params) do
# Fetching all sites
sites = Repo.all(Site)
# Fetching all objects to build a tree
objects = Repo.all(Object)
object_tree_list = for site <- sites do
current = Enum.filter(objects, fn(x) -> x.site_id === site.id end)
current_size = Enum.count(current)
# If we don't have objects in current site,
# create one
if current_size === 0 do
changeset = Object.changeset(struct(Object), %{
"site_id" => site.id,
"parent_id" => 0,
"is_published" => true,
"is_show_on_site_map" => true,
"is_show_in_menu" => true,
"sort_order" => 0,
"path" => "/",
"url" => "/",
"full_path" => "/"
})
case Repo.insert(changeset) do
{:ok, entry} ->
current = [entry]
end
end
Map.put(site, :children, current)
end
# Throwing object_tree to frontend
assign(conn, :object_tree, object_tree_list)
end
defp generate_model_map(conn, model) do
generate_model_map(conn, model, 0)
end
# Generates specified model and checks if it has admin_outer_texts
# property. If so, it will fetch outer_texts by the number of languages
# specified.
defp generate_model_map(conn, model, site_id) do
case function_exported?(model, :admin_outer_texts, 0) do
true ->
outer_texts = for language <- conn.assigns[:languages] do
struct(model.admin_outer_texts.model, %{
:language_id => language.id
})
end
struct(model, %{
model.admin_outer_texts.assoc => outer_texts,
:site_id => site_id
})
_ ->
struct(model)
end
end
end