defmodule DaProductApp.MerchantDefaults do @moduledoc """ Load merchant default settings from the Blade template at runtime. This parser is intentionally conservative: it scans the `$defaults = [...]` PHP array in `priv/scripts/merchant-configuration.blade.php` and builds an Elixir map. """ require Logger @blade_path "priv/scripts/merchant-configuration.blade.php" @doc """ Return a map of defaults parsed from the Blade file. Returns an empty map on error. """ def load_from_blade do with {:ok, content} <- File.read(@blade_path), {:ok, block} <- extract_defaults_block(content) do parse_defaults_block(block) else {:error, reason} -> Logger.error("MerchantDefaults.load_from_blade failed: #{inspect(reason)}") %{} _ -> Logger.error("MerchantDefaults.load_from_blade unexpected failure") %{} end end # Extract the inner contents of $defaults = [ ... ]; defp extract_defaults_block(content) when is_binary(content) do regex = ~r/\$defaults\s*=\s*\[([\s\S]*?)\];/m case Regex.run(regex, content, return: :index) do nil -> {:error, :no_defaults_block} match -> {[_, {start, len}], _} = {match, nil} block = String.slice(content, start, len) {:ok, block} end end defp extract_defaults_block(_), do: {:error, :invalid_content} # Parse the PHP array inner block into an Elixir map. # Uses a forgiving regex to capture key => value pairs. Values supported: 'str', null, numbers. defp parse_defaults_block(block) when is_binary(block) do pair_regex = ~r/'([^']+)'\s*=>\s*(?:'([^']*)'|(null)|([^,\n\r]+))/m pairs = Regex.scan(pair_regex, block) Enum.reduce(pairs, %{}, fn [_, key, _val_str, "null", _], acc -> Map.put(acc, key, nil) [_, key, val_str, _null, _num], acc when is_binary(val_str) and val_str != "" -> Map.put(acc, key, val_str) [_, key, val_str, _null, _num], acc when is_binary(val_str) -> Map.put(acc, key, val_str) [_, key, _val_str, _null, num], acc -> v = num |> to_string() |> String.trim() v = String.replace_trailing(v, ",", "") |> String.trim() Map.put(acc, key, v) _, acc -> acc end) rescue e -> Logger.error("parse_defaults_block failed: #{inspect(e)}") %{} end end