PhoenixKitEcommerce.ProductSource behaviour (PhoenixKitEcommerce v0.5.0)

Copy Markdown View Source

Behaviour for the storefront's product/category read path.

Two adapters implement it: PhoenixKitEcommerce.ProductSource.Legacy (today's phoenix_kit_shop_products/phoenix_kit_shop_categories tables, unchanged) and, once phoenix_kit_catalogue is present, PhoenixKitEcommerce.ProductSource.Catalogue (reads catalogue items and returns hand-built %Product{}/%Category{} view-structs so the facade, guards, CartItem, Options and sitemap need no changes).

current/0 picks the adapter at runtime; PhoenixKitEcommerce's public read functions delegate to it so callers never choose an adapter themselves.

Summary

Functions

Returns the adapter module for the currently active product source.

Callbacks

aggregate_filter_values(keyword)

@callback aggregate_filter_values(keyword()) :: map()

get_category(t, keyword)

@callback get_category(String.t(), keyword()) :: PhoenixKitEcommerce.Category.t() | nil

get_category_by_any_slug(t, keyword)

@callback get_category_by_any_slug(String.t(), keyword()) ::
  {:ok, PhoenixKitEcommerce.Category.t(), String.t()} | {:error, :not_found}

get_category_by_slug_localized(t, t, keyword)

@callback get_category_by_slug_localized(String.t(), String.t(), keyword()) ::
  {:ok, PhoenixKitEcommerce.Category.t()} | {:error, :not_found}

get_price_range_for(keyword)

@callback get_price_range_for(keyword()) :: {Decimal.t() | nil, Decimal.t() | nil}

get_product(t, keyword)

@callback get_product(String.t(), keyword()) :: PhoenixKitEcommerce.Product.t() | nil

get_product_by_any_slug(t, keyword)

@callback get_product_by_any_slug(String.t(), keyword()) ::
  {:ok, PhoenixKitEcommerce.Product.t(), String.t()} | {:error, :not_found}

get_product_by_slug_localized(t, t, keyword)

@callback get_product_by_slug_localized(String.t(), String.t(), keyword()) ::
  {:ok, PhoenixKitEcommerce.Product.t()} | {:error, :not_found}

list_categories(keyword)

@callback list_categories(keyword()) :: [PhoenixKitEcommerce.Category.t()]

list_products(keyword)

@callback list_products(keyword()) :: [PhoenixKitEcommerce.Product.t()]

list_products_by_ids(list)

@callback list_products_by_ids([String.t()]) :: [PhoenixKitEcommerce.Product.t()]

list_products_with_count(keyword)

@callback list_products_with_count(keyword()) ::
  {[PhoenixKitEcommerce.Product.t()], non_neg_integer()}

product_counts_by_category()

@callback product_counts_by_category() :: %{required(String.t()) => non_neg_integer()}

Functions

current()

Returns the adapter module for the currently active product source.

Catalogue only when phoenix_kit_catalogue is loaded AND the shop_product_source config key (phoenix_kit_shop_config) is "catalogue"; Legacy otherwise — including when the key is absent or the catalogue module isn't loaded, so a host without the optional phoenix_kit_catalogue dependency always gets Legacy regardless of the stored key.

Reads the config on every call rather than caching it here: PhoenixKitEcommerce.get_config/1 is a plain repo().get/2 against phoenix_kit_shop_config (no ETS/settings-cache layer sits in front of it today), so this is a real extra query per call — accepted so that the switch takes effect without a restart, rather than adding process state here that could make it lag behind the stored value.