PhoenixKit.Settings (phoenix_kit v1.6.15)

View Source

The Settings context for system configuration management.

This module provides functions for managing system-wide settings in PhoenixKit. Settings are stored in the database and can be updated through the admin panel.

Core Functions

Settings Management

JSON Settings Management

Default Settings

The system includes core settings:

  • project_title: Application/project title
  • site_url: Website URL for the application (optional)
  • allow_registration: Allow public user registration (default: true)
  • oauth_enabled: Enable OAuth authentication (default: false)
  • time_zone: System timezone offset
  • date_format: Date display format
  • time_format: Time display format
  • track_registration_geolocation: Enable IP geolocation tracking during registration (default: false)

Usage Examples

# Get a simple string setting with default
timezone = PhoenixKit.Settings.get_setting("time_zone", "0")

# Update a simple string setting
{:ok, setting} = PhoenixKit.Settings.update_setting("time_zone", "+1")

# Get a JSON setting with default
config = PhoenixKit.Settings.get_json_setting("app_config", %{})

# Update a JSON setting
app_config = %{
  "theme" => %{"primary" => "#3b82f6", "secondary" => "#64748b"},
  "features" => ["notifications", "dark_mode"],
  "limits" => %{"max_users" => 1000}
}
{:ok, setting} = PhoenixKit.Settings.update_json_setting("app_config", app_config)

# Get all settings as a map
settings = PhoenixKit.Settings.list_all_settings()
# => %{"time_zone" => "0", "date_format" => "Y-m-d", "time_format" => "H:i"}

Configuration

The context uses PhoenixKit's configured repository and respects table prefixes set during installation.

Summary

Functions

Creates a changeset for settings form validation.

Gets a boolean setting value by key with a default fallback.

Gets the site content language.

Gets content language with full details.

Gets default values for all settings.

Gets an integer setting value by key, with fallback to default.

Gets a JSON setting value by key.

Gets a JSON setting value by key with a default fallback.

Gets a JSON setting value from cache with fallback to database.

Gets multiple JSON settings from cache in a single operation.

Gets OAuth credentials for a specific provider.

Gets OAuth credentials directly from database, bypassing cache.

Gets the display label for a setting option value.

Gets the available role options for the new user default role setting.

Gets a setting value by key.

Gets a setting value by key with a default fallback.

Gets a setting value from cache with fallback to database.

Gets the available options for each setting type.

Gets multiple settings from cache in a single operation.

Gets multiple settings directly from database, bypassing cache.

Gets the display label for a timezone value.

Checks if OAuth credentials are configured for a provider.

Checks if OAuth credentials are configured for a provider, reading directly from database.

Lists all settings as a map with keys as setting names and values as setting values.

Gets all settings with their full details (including timestamps).

Check if the repository is available and ready to accept queries.

Sets the site content language.

Updates or creates a boolean setting with the given key and boolean value.

Updates or creates a boolean setting with module association.

Updates or creates a JSON setting with the given key and value.

Updates or creates a JSON setting with module association.

Updates or creates a setting with the given key and value.

Updates or creates a setting with module association.

Updates multiple settings at once using form parameters.

Updates or creates multiple settings in a single transaction.

Validates settings parameters and returns a changeset.

Warms the cache by loading all settings from database.

Warm cache with critical settings only.

Functions

change_settings(settings \\ %{})

Creates a changeset for settings form validation.

Takes a map of settings and returns a changeset that can be used in Phoenix forms. This function handles the conversion from string keys to atoms and creates the proper embedded schema structure for form validation.

Examples

iex> settings = %{"project_title" => "My App", "time_zone" => "0"}
iex> PhoenixKit.Settings.change_settings(settings)
%Ecto.Changeset{data: %SettingsForm{}, valid?: true}

iex> PhoenixKit.Settings.change_settings(%{})
%Ecto.Changeset{data: %SettingsForm{}, valid?: false}

get_boolean_setting(key, default \\ false)

Gets a boolean setting value by key with a default fallback.

Converts string values "true"/"false" to actual boolean values. Returns the default if the setting is not found or has an invalid value.

Examples

iex> PhoenixKit.Settings.get_boolean_setting("feature_enabled", false)
false

iex> PhoenixKit.Settings.get_boolean_setting("feature_enabled", true)
true

get_content_language()

Gets the site content language.

This represents the primary language of website content (not UI language). Falls back to "en" if not configured or Languages module is disabled.

This function uses batch caching for optimal performance when called alongside other settings queries.

Examples

iex> PhoenixKit.Settings.get_content_language()
"en"

iex> PhoenixKit.Settings.get_content_language()
"es"  # if configured as Spanish

get_content_language_details()

Gets content language with full details.

Returns a map with code, name, and native name if Languages module is enabled.

Examples

iex> PhoenixKit.Settings.get_content_language_details()
%{
  code: "en",
  name: "English",
  native: "English",
  from_languages_module: false
}

get_defaults()

Gets default values for all settings.

Returns a map with setting keys and their default values. These defaults match the ones defined in the V03 migration.

Examples

iex> PhoenixKit.Settings.get_defaults()
%{
  "time_zone" => "0",
  "date_format" => "Y-m-d",
  "time_format" => "H:i"
}

get_integer_setting(key, default \\ 0)

Gets an integer setting value by key, with fallback to default.

Converts the stored string value to an integer. If the setting doesn't exist or cannot be converted to an integer, returns the default value.

Examples

iex> PhoenixKit.Settings.get_integer_setting("max_items", 10)
10

iex> PhoenixKit.Settings.get_integer_setting("existing_number", 5)
25  # if "25" is stored in database

get_json_setting(key)

Gets a JSON setting value by key.

Returns the JSON value as a map/list/primitive, or nil if not found.

Examples

iex> PhoenixKit.Settings.get_json_setting("app_config")
%{"theme" => "dark", "features" => ["auth", "admin"]}

iex> PhoenixKit.Settings.get_json_setting("non_existent")
nil

get_json_setting(key, default)

Gets a JSON setting value by key with a default fallback.

Returns the JSON value as a map/list/primitive, or the default if not found.

Examples

iex> PhoenixKit.Settings.get_json_setting("app_config", %{})
%{"theme" => "dark", "features" => ["auth", "admin"]}

iex> PhoenixKit.Settings.get_json_setting("non_existent", %{"default" => true})
%{"default" => true}

get_json_setting_cached(key, default \\ nil)

Gets a JSON setting value from cache with fallback to database.

This is the preferred method for getting JSON settings as it provides significant performance improvements over direct database queries.

Examples

iex> PhoenixKit.Settings.get_json_setting_cached("app_config", %{})
%{"theme" => "dark", "features" => ["auth", "admin"]}

iex> PhoenixKit.Settings.get_json_setting_cached("non_existent", %{"default" => true})
%{"default" => true}

get_json_settings_cached(keys, defaults \\ %{})

Gets multiple JSON settings from cache in a single operation.

More efficient than multiple individual get_json_setting_cached/2 calls when you need several JSON settings at once.

Examples

iex> PhoenixKit.Settings.get_json_settings_cached(["app_config", "feature_flags"])
%{"app_config" => %{"theme" => "dark"}, "feature_flags" => %{"auth" => true}}

iex> defaults = %{"app_config" => %{}, "feature_flags" => %{}}
iex> PhoenixKit.Settings.get_json_settings_cached(["app_config", "feature_flags"], defaults)
%{"app_config" => %{"theme" => "dark"}, "feature_flags" => %{"auth" => true}}

get_oauth_credentials(provider)

Gets OAuth credentials for a specific provider.

Returns a map with all credentials for the given provider. Uses cache for performance - suitable for non-critical reads.

Examples

iex> PhoenixKit.Settings.get_oauth_credentials(:google)
%{client_id: "google-client-id", client_secret: "google-client-secret"}

iex> PhoenixKit.Settings.get_oauth_credentials(:apple)
%{
  client_id: "apple-client-id",
  team_id: "apple-team-id",
  key_id: "apple-key-id",
  private_key: "-----BEGIN PRIVATE KEY-----..."
}

get_oauth_credentials_direct(provider)

Gets OAuth credentials directly from database, bypassing cache.

Use this for security-critical operations where fresh data is required, such as configuring OAuth providers after settings update.

This prevents race conditions where cache invalidation hasn't completed before the credentials are read.

Examples

iex> PhoenixKit.Settings.get_oauth_credentials_direct(:google)
%{client_id: "google-client-id", client_secret: "google-client-secret"}

get_option_label(value, options)

Gets the display label for a setting option value.

Examples

iex> options = [{"YYYY-MM-DD", "Y-m-d"}, {"MM/DD/YYYY", "m/d/Y"}]
iex> PhoenixKit.Settings.get_option_label("Y-m-d", options)
"YYYY-MM-DD"

get_role_options()

Gets the available role options for the new user default role setting.

Returns all roles from database except Owner, ordered by system roles first, then custom roles.

Examples

iex> PhoenixKit.Settings.get_role_options()
[{"User", "User"}, {"Admin", "Admin"}, {"Manager", "Manager"}]

get_setting(key)

Gets a setting value by key.

Returns the setting value as a string, or nil if not found.

Examples

iex> PhoenixKit.Settings.get_setting("time_zone")
"0"

iex> PhoenixKit.Settings.get_setting("non_existent")
nil

get_setting(key, default)

Gets a setting value by key with a default fallback.

Returns the setting value as a string, or the default if not found.

Examples

iex> PhoenixKit.Settings.get_setting("time_zone", "0")
"0"

iex> PhoenixKit.Settings.get_setting("non_existent", "default")
"default"

get_setting_cached(key, default \\ nil)

Gets a setting value from cache with fallback to database.

This is the preferred method for getting settings as it provides significant performance improvements over direct database queries.

Examples

iex> PhoenixKit.Settings.get_setting_cached("date_format", "Y-m-d")
"F j, Y"

iex> PhoenixKit.Settings.get_setting_cached("non_existent", "default")
"default"

get_setting_options()

Gets the available options for each setting type.

Returns a map with setting keys and their available options as {label, value} tuples. Used to populate dropdown menus in the admin interface.

Examples

iex> PhoenixKit.Settings.get_setting_options()
%{
  "time_zone" => [{"UTC-12", "-12"}, {"UTC+0 (GMT)", "0"}, {"UTC+8", "8"}],
  "date_format" => [{"YYYY-MM-DD", "Y-m-d"}, {"MM/DD/YYYY", "m/d/Y"}],
  "time_format" => [{"24 Hour (15:30)", "H:i"}, {"12 Hour (3:30 PM)", "h:i A"}]
}

get_settings_cached(keys, defaults \\ %{})

Gets multiple settings from cache in a single operation.

More efficient than multiple individual get_setting_cached/2 calls when you need several settings at once.

Examples

iex> PhoenixKit.Settings.get_settings_cached(["date_format", "time_format"])
%{"date_format" => "F j, Y", "time_format" => "h:i A"}

iex> defaults = %{"date_format" => "Y-m-d", "time_format" => "H:i"}
iex> PhoenixKit.Settings.get_settings_cached(["date_format", "time_format"], defaults)
%{"date_format" => "F j, Y", "time_format" => "h:i A"}

get_settings_direct(keys)

Gets multiple settings directly from database, bypassing cache.

Use this for security-critical operations where fresh data is required. Returns a map with setting keys and their values.

Examples

iex> PhoenixKit.Settings.get_settings_direct(["oauth_google_client_id", "oauth_google_client_secret"])
%{"oauth_google_client_id" => "client-id", "oauth_google_client_secret" => "secret"}

get_timezone_label(value, setting_options)

Gets the display label for a timezone value.

Examples

iex> PhoenixKit.Settings.get_timezone_label("0", get_setting_options())
"UTC+0 (GMT/London)"

has_oauth_credentials?(provider)

Checks if OAuth credentials are configured for a provider.

Uses cache for performance - suitable for non-critical checks.

Examples

iex> PhoenixKit.Settings.has_oauth_credentials?(:google)
true

has_oauth_credentials_direct?(provider)

Checks if OAuth credentials are configured for a provider, reading directly from database.

Bypasses cache to ensure fresh data. Use this when configuring OAuth providers after settings update to avoid race conditions.

Examples

iex> PhoenixKit.Settings.has_oauth_credentials_direct?(:google)
true

list_all_settings()

Lists all settings as a map with keys as setting names and values as setting values.

Returns a map where keys are setting names and values are setting values. Useful for loading all settings at once for forms or configuration.

Examples

iex> PhoenixKit.Settings.list_all_settings()
%{
  "time_zone" => "0",
  "date_format" => "Y-m-d",
  "time_format" => "H:i"
}

list_settings()

Gets all settings with their full details (including timestamps).

Returns a list of Setting structs. Useful for admin interfaces that need to show when settings were created/updated.

Examples

iex> PhoenixKit.Settings.list_settings()
[
  %Setting{key: "time_zone", value: "0", date_added: ~U[2024-01-01 00:00:00.000000Z]},
  %Setting{key: "date_format", value: "Y-m-d", date_added: ~U[2024-01-01 00:00:00.000000Z]}
]

repo_available?()

Check if the repository is available and ready to accept queries.

Returns true if the repo is configured and running, false otherwise. Used to prevent errors during Mix tasks when repo might not be started.

set_content_language(language_code)

Sets the site content language.

Validates against enabled languages if Languages module is active. Broadcasts change event for live updates to connected admin sessions.

Examples

iex> PhoenixKit.Settings.set_content_language("es")
{:ok, %Setting{}}

iex> PhoenixKit.Settings.set_content_language("invalid")
{:error, "Language not enabled"}

update_boolean_setting(key, boolean_value)

Updates or creates a boolean setting with the given key and boolean value.

Converts boolean values to "true"/"false" strings for storage. If the setting exists, updates its value and timestamp. If the setting doesn't exist, creates a new one.

Returns {:ok, setting} on success, {:error, changeset} on failure.

Examples

iex> PhoenixKit.Settings.update_boolean_setting("feature_enabled", true)
{:ok, %Setting{key: "feature_enabled", value: "true"}}

iex> PhoenixKit.Settings.update_boolean_setting("feature_enabled", false)
{:ok, %Setting{key: "feature_enabled", value: "false"}}

update_boolean_setting_with_module(key, boolean_value, module)

Updates or creates a boolean setting with module association.

Combines boolean handling with module organization.

Examples

iex> PhoenixKit.Settings.update_boolean_setting_with_module("feature_enabled", true, "referral_codes")
{:ok, %Setting{key: "feature_enabled", value: "true", module: "referral_codes"}}

update_json_setting(key, json_value)

Updates or creates a JSON setting with the given key and value.

If the setting exists, updates its value_json and timestamp. If the setting doesn't exist, creates a new one. Clears any existing string value when setting JSON value.

Returns {:ok, setting} on success, {:error, changeset} on failure.

Examples

iex> config = %{"theme" => "dark", "features" => ["auth"]}
iex> PhoenixKit.Settings.update_json_setting("app_config", config)
{:ok, %Setting{key: "app_config", value_json: %{"theme" => "dark", "features" => ["auth"]}}}

iex> PhoenixKit.Settings.update_json_setting("", %{})
{:error, %Ecto.Changeset{}}

update_json_setting_with_module(key, json_value, module)

Updates or creates a JSON setting with module association.

Similar to update_json_setting/2 but allows specifying which module the setting belongs to. Useful for organizing feature-specific JSON settings.

Examples

iex> config = %{"enabled" => true, "options" => ["email", "sms"]}
iex> PhoenixKit.Settings.update_json_setting_with_module("notifications", config, "messaging")
{:ok, %Setting{key: "notifications", value_json: config, module: "messaging"}}

update_setting(key, value)

Updates or creates a setting with the given key and value.

If the setting exists, updates its value and timestamp. If the setting doesn't exist, creates a new one.

Returns {:ok, setting} on success, {:error, changeset} on failure.

Examples

iex> PhoenixKit.Settings.update_setting("time_zone", "+1")
{:ok, %Setting{key: "time_zone", value: "+1"}}

iex> PhoenixKit.Settings.update_setting("", "invalid")
{:error, %Ecto.Changeset{}}

update_setting_with_module(key, value, module)

Updates or creates a setting with module association.

Similar to update_setting/2 but allows specifying which module the setting belongs to. Useful for organizing feature-specific settings.

Examples

iex> PhoenixKit.Settings.update_setting_with_module("codes_enabled", "true", "referral_codes")
{:ok, %Setting{key: "codes_enabled", value: "true", module: "referral_codes"}}

update_settings(settings_params)

Updates multiple settings at once using form parameters.

Takes a map of settings parameters, validates them, and if valid, updates all settings in the database. This is typically used from the settings form in the admin panel.

Returns {:ok, updated_settings_map} on success or {:error, changeset} on failure.

Examples

iex> params = %{"project_title" => "My App", "time_zone" => "+1"}
iex> PhoenixKit.Settings.update_settings(params)
{:ok, %{"project_title" => "My App", "time_zone" => "+1"}}

iex> PhoenixKit.Settings.update_settings(%{"time_zone" => "invalid"})
{:error, %Ecto.Changeset{}}

update_settings_batch(settings_map)

Updates or creates multiple settings in a single transaction.

More efficient version for batch updating settings. Loads all settings in a single query and updates them in a transaction.

Accepts a map of key-value settings to update. Returns {:ok, results} on success, where results is a list of results. Returns {:error, reason} on transaction error.

Examples

iex> settings = %{"aws_region" => "eu-north-1", "aws_access_key_id" => "AKIAIOSFODNN7EXAMPLE"}
iex> PhoenixKit.Settings.update_settings_batch(settings)
{:ok, [ok: %Setting{}, ok: %Setting{}]}

iex> PhoenixKit.Settings.update_settings_batch(%{})
{:ok, []}

validate_settings(settings)

Validates settings parameters and returns a changeset.

Similar to change_settings/1 but sets the action to :validate to trigger error display in forms.

Examples

iex> settings = %{"project_title" => "", "time_zone" => "invalid"}
iex> changeset = PhoenixKit.Settings.validate_settings(settings)
iex> changeset.action
:validate
iex> changeset.valid?
false

warm_cache_data()

Warms the cache by loading all settings from database.

Called by PhoenixKit.Cache to pre-populate cache with all existing settings. Prioritizes JSON values over string values for cache storage.

warm_critical_cache()

Warm cache with critical settings only.

Returns map of critical settings for synchronous cache warming. This is used during startup to ensure essential configuration is available immediately.

Note: OAuth credentials are NOT cached here because they are read directly from the database via get_oauth_credentials_direct/1 to avoid race conditions when credentials are updated through the admin UI.