Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/phoenix_kit/emails/archiver.ex
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ defmodule PhoenixKit.Emails.Archiver do
"""

require Logger
alias PhoenixKit.Settings
alias PhoenixKit.Emails.{Event, Log}
alias PhoenixKit.Settings
import Ecto.Query

## --- Body Compression ---
Expand Down
2 changes: 1 addition & 1 deletion lib/phoenix_kit/emails/rate_limiter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ defmodule PhoenixKit.Emails.RateLimiter do
- `PhoenixKit.Users.Auth` - User-based limits
"""

alias PhoenixKit.Settings
alias PhoenixKit.Emails.{EmailBlocklist, Log}
alias PhoenixKit.Settings
import Ecto.Query

## --- Rate Limit Checks ---
Expand Down
4 changes: 3 additions & 1 deletion lib/phoenix_kit/storage/url_signer.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
defmodule PhoenixKit.Storage.URLSigner do
import Bitwise

alias PhoenixKit.Utils.Routes

@moduledoc """
Token-based URL signing for secure file serving.

Expand Down Expand Up @@ -51,7 +53,7 @@ defmodule PhoenixKit.Storage.URLSigner do
def signed_url(file_id, instance_name) when is_binary(file_id) and is_binary(instance_name) do
token = generate_token(file_id, instance_name)
file_path = "/file/#{file_id}/#{instance_name}/#{token}"
PhoenixKit.Utils.Routes.path(file_path)
Routes.path(file_path)
end

@doc """
Expand Down
40 changes: 4 additions & 36 deletions lib/phoenix_kit_web/components/core/language_switcher.ex
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ defmodule PhoenixKitWeb.Components.Core.LanguageSwitcher do

use Phoenix.Component

alias Phoenix.LiveView.JS
alias PhoenixKit.Module.Languages
alias PhoenixKitWeb.Components.Core.Icon
alias Phoenix.LiveView.JS

@doc """
Renders a dropdown language switcher.
Expand Down Expand Up @@ -328,41 +328,9 @@ defmodule PhoenixKitWeb.Components.Core.LanguageSwitcher do
end

# Helper function to generate language switch URL
# Current implementation returns home page with new locale
# Future enhancement: parse current path and preserve it when available via assigns
defp generate_language_url(_current_locale, new_locale) do
# Get current path and replace locale if present
# This is a simple implementation - you may need to adjust based on your routing
case get_current_path_from_assigns() do
nil ->
# Fallback if path is not available
"/"

current_path ->
# Remove PhoenixKit prefix if present
normalized_path = String.replace_prefix(current_path, "/phoenix_kit", "")

# Remove existing locale prefix if it matches a language code
clean_path =
case String.split(normalized_path, "/", parts: 3) do
["", potential_locale, rest] ->
if Languages.valid_language?(potential_locale) do
"/" <> rest
else
normalized_path
end

_ ->
normalized_path
end

# Build new URL with new locale
"/#{new_locale}#{clean_path}"
end
end

# Helper to get current path - should be passed via socket assigns
defp get_current_path_from_assigns do
# This will be populated by the LiveView or template context
# For now, return nil - the actual path should be passed as an attribute
nil
"/#{new_locale}"
end
end
6 changes: 3 additions & 3 deletions lib/phoenix_kit_web/controllers/blog_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ defmodule PhoenixKitWeb.BlogController do
# Returns {detected_language, adjusted_params}
defp detect_language_or_blog(language_param, params) do
# Check if this looks like a valid language code
if is_valid_language?(language_param) do
if valid_language?(language_param) do
# It's a real language code - use as-is
{language_param, params}
else
Expand All @@ -130,14 +130,14 @@ defmodule PhoenixKitWeb.BlogController do
end
end

defp is_valid_language?(code) when is_binary(code) do
defp valid_language?(code) when is_binary(code) do
# Check if it's an enabled language code
Languages.language_enabled?(code)
rescue
_ -> false
end

defp is_valid_language?(_), do: false
defp valid_language?(_), do: false

# ============================================================================
# Path Parsing
Expand Down
4 changes: 2 additions & 2 deletions lib/phoenix_kit_web/live/dashboard.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ defmodule PhoenixKitWeb.Live.Dashboard do
use PhoenixKitWeb, :live_view
use Gettext, backend: PhoenixKitWeb.Gettext

alias PhoenixKit.Utils.IpAddress
alias PhoenixKit.Utils.Routes
alias PhoenixKit.Admin.{Events, Presence}
alias PhoenixKit.Settings
alias PhoenixKit.Users.Auth.Scope
alias PhoenixKit.Users.{Roles, Sessions}
alias PhoenixKit.Utils.IpAddress
alias PhoenixKit.Utils.Routes

def mount(params, session, socket) do
# Set locale for LiveView process - check params first, then socket assigns, then default
Expand Down
3 changes: 2 additions & 1 deletion lib/phoenix_kit_web/live/modules/blogging/blog.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ defmodule PhoenixKitWeb.Live.Modules.Blogging.Blog do
use PhoenixKitWeb, :live_view
use Gettext, backend: PhoenixKitWeb.Gettext

alias PhoenixKit.Blogging.Renderer
alias PhoenixKit.Settings
alias PhoenixKit.Utils.Routes
alias PhoenixKitWeb.BlogHTML
Expand Down Expand Up @@ -219,6 +220,6 @@ defmodule PhoenixKitWeb.Live.Modules.Blogging.Blog do
end

# Invalidate the render cache for this post
PhoenixKit.Blogging.Renderer.invalidate_cache(blog_slug, identifier, post.language)
Renderer.invalidate_cache(blog_slug, identifier, post.language)
end
end
3 changes: 2 additions & 1 deletion lib/phoenix_kit_web/live/modules/blogging/blogging.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ defmodule PhoenixKitWeb.Live.Modules.Blogging do
for creating timestamped markdown blog posts.
"""

alias PhoenixKit.Module.Languages
alias PhoenixKit.Users.Auth.Scope
alias PhoenixKitWeb.Live.Modules.Blogging.Storage

Expand Down Expand Up @@ -354,7 +355,7 @@ defmodule PhoenixKitWeb.Live.Modules.Blogging do
# Get all available language codes dynamically from the language module
language_codes =
try do
PhoenixKit.Module.Languages.get_language_codes()
Languages.get_language_codes()
rescue
_ -> []
end
Expand Down
62 changes: 29 additions & 33 deletions lib/phoenix_kit_web/live/modules/blogging/context/storage.ex
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ defmodule PhoenixKitWeb.Live.Modules.Blogging.Storage do
defp reserved_language_code?(slug) do
language_codes =
try do
PhoenixKit.Module.Languages.get_language_codes()
Languages.get_language_codes()
rescue
_ -> []
end
Expand Down Expand Up @@ -135,20 +135,18 @@ defmodule PhoenixKitWeb.Live.Modules.Blogging.Storage do
slug when is_binary(slug) ->
sanitized = sanitize_slug(slug)

cond do
sanitized == "" ->
{:ok, generate_slug_from_title(title)}

true ->
# Validate the sanitized slug
case validate_slug(sanitized) do
{:ok, valid_slug} ->
{:ok, valid_slug}

{:error, reason} ->
# Return the specific error instead of falling back
{:error, reason}
end
if sanitized == "" do
{:ok, generate_slug_from_title(title)}
else
# Validate the sanitized slug
case validate_slug(sanitized) do
{:ok, valid_slug} ->
{:ok, valid_slug}

{:error, reason} ->
# Return the specific error instead of falling back
{:error, reason}
end
end
end

Expand Down Expand Up @@ -599,25 +597,23 @@ defmodule PhoenixKitWeb.Live.Modules.Blogging.Storage do
audit_meta = Map.new(audit_meta)
desired_slug = Map.get(params, "slug", post.slug)

cond do
desired_slug == post.slug ->
update_post_slug_in_place(blog_slug, post, params, audit_meta)

true ->
# Validate slug and return specific error
case validate_slug(desired_slug) do
{:ok, _valid_slug} ->
# Check if slug already exists
if slug_exists?(blog_slug, desired_slug) do
{:error, :slug_already_exists}
else
move_post_to_new_slug(blog_slug, post, desired_slug, params, audit_meta)
end
if desired_slug == post.slug do
update_post_slug_in_place(blog_slug, post, params, audit_meta)
else
# Validate slug and return specific error
case validate_slug(desired_slug) do
{:ok, _valid_slug} ->
# Check if slug already exists
if slug_exists?(blog_slug, desired_slug) do
{:error, :slug_already_exists}
else
move_post_to_new_slug(blog_slug, post, desired_slug, params, audit_meta)
end

{:error, reason} ->
# Return specific validation error
{:error, reason}
end
{:error, reason} ->
# Return specific validation error
{:error, reason}
end
end
end

Expand Down
56 changes: 3 additions & 53 deletions lib/phoenix_kit_web/live/modules/blogging/editor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ defmodule PhoenixKitWeb.Live.Modules.Blogging.Editor do
alias PhoenixKit.Utils.Routes
alias PhoenixKitWeb.BlogHTML
alias PhoenixKitWeb.Live.Modules.Blogging
alias PhoenixKitWeb.Live.Modules.Blogging.Metadata
alias PhoenixKitWeb.Live.Modules.Blogging.Storage

@impl true
Expand Down Expand Up @@ -200,7 +201,7 @@ defmodule PhoenixKitWeb.Live.Modules.Blogging.Editor do
new_slug =
if current_slug == "" and String.trim(content) != "" do
# Extract title from content and use it for slug
title = PhoenixKitWeb.Live.Modules.Blogging.Metadata.extract_title_from_content(content)
title = Metadata.extract_title_from_content(content)
Storage.generate_unique_slug(socket.assigns.blog_slug, title, nil)
else
current_slug
Expand Down Expand Up @@ -232,7 +233,7 @@ defmodule PhoenixKitWeb.Live.Modules.Blogging.Editor do

{new_form, slug_events} =
if socket.assigns.blog_mode == "slug" && is_new_unsaved && String.trim(content) != "" do
title = PhoenixKitWeb.Live.Modules.Blogging.Metadata.extract_title_from_content(content)
title = Metadata.extract_title_from_content(content)

case Storage.generate_unique_slug(socket.assigns.blog_slug, title, nil) do
{:ok, new_slug} ->
Expand Down Expand Up @@ -1039,57 +1040,6 @@ defmodule PhoenixKitWeb.Live.Modules.Blogging.Editor do
}
end

defp maybe_autofill_slug(params, %{assigns: %{blog_mode: "slug"} = assigns}) do
trimmed_params = normalize_slug_param(params)
slug_value = Map.get(trimmed_params, "slug")
current_slug = Map.get(assigns.form, "slug", "")
title = extract_and_normalize_title(trimmed_params, assigns)

new_slug = determine_slug_value(slug_value, current_slug, title, assigns)
Map.put(trimmed_params, "slug", new_slug)
end

defp maybe_autofill_slug(params, _socket) do
Map.delete(params, "slug")
end

defp normalize_slug_param(params) do
case Map.fetch(params, "slug") do
{:ok, slug} when is_binary(slug) -> Map.put(params, "slug", String.trim(slug))
{:ok, _} -> Map.put(params, "slug", "")
:error -> params
end
end

defp extract_and_normalize_title(params, assigns) do
title =
Map.get(params, "title") ||
Map.get(assigns.form, "title") ||
""

String.trim(to_string(title))
end

defp determine_slug_value(slug_value, current_slug, title, assigns) do
cond do
# User has manually entered a slug - keep it
is_binary(slug_value) and slug_value != "" ->
slug_value

# Current slug exists - use it
current_slug not in [nil, ""] ->
current_slug

# No slug but have title - auto-generate
title != "" ->
Storage.generate_unique_slug(assigns.blog_slug, title, nil)

# No slug and no title - keep empty
true ->
""
end
end

defp slug_base_dir(post, blog_slug) do
cond do
Map.get(post, :mode) == :slug and Map.get(post, :slug) ->
Expand Down
Loading