Skip to content

Product Feed Generation (XML)

Flow ID: IN-01 Module(s): feeds Complexity: Very High Last Updated: 2026-04-03

Business Context

The feed system generates XML product catalogs for 19 marketplace and advertising platforms. Each feed has a controller (in ecommercen/feeds/controllers/) that extends AdvXml base class, and an output class (in src/Feeds/Output/) that renders the XML format. Feeds are URL-accessible, protected by registry-managed enable flags and optional token authentication.

Entry Points

Note: The paths shown are internal controller routes. Public-facing URLs use the /xml/ prefix (e.g., /xml/skroutz, /xml/google-catalog). See the URL Format Note below for hyphen vs underscore conventions.

TypePath / TriggerFeedOutput Class
URL/feeds/skroutzSkroutzOutputSkroutzXml
URL/feeds/google_catalogGoogle MerchantOutputGoogleMerchantXml
URL/feeds/facebook_catalogFacebook CatalogOutputGoogleMerchantXml (inherited)
URL/feeds/criteo_catalogCriteoOutputGoogleMerchantXml (inherited)
URL/feeds/managoManagoOutputGoogleMerchantXml (inherited)
URL/feeds/bestpriceBestPriceOutputBestPriceXml
URL/feeds/emageMAGOutputEmagXml
URL/feeds/glamiGlamiOutputGlamiXml
URL/feeds/agora_catalogProject AgoraOutputAgoraXml
URL/feeds/linkwiseLinkWiseOutputLinkWiseXml
URL/feeds/wellcommWellcommOutputWellcommXml
URL/feeds/contactpigeonContactPigeonOutputXml
URL/feeds/public_marketplacePublic MarketplaceOutputPublicMarketplaceXml
URL/feeds/api_searchAPI SearchOutputGoogleMerchantXml
URL/feeds/blog_rssBlog RSSOutputRss
URL/feeds/lines_catalogProduct LinesOutputLinesXml
URL/feeds/vendors_catalogVendorsOutputVendorsXml
URL/feeds/generic_productGenericOutputGenericXml
URL/feeds/google_product_reviewGoogle ReviewsOutputGoogleProductReviewXml

Code Path Trace

Base class: ecommercen/feeds/core/AdvXml.php — template method pattern:

  1. secureXml() — checks XML_FEEDS.IS_ENABLED_{FEED} registry flag + optional token validation via XML_FEEDS.{FEED}_TOKEN
  2. getDbData() — product model query filtered by brand/category/top sellers/stock params
  3. getProductData() — enriches with getLiveProductsParsed() (prices/stock), getProductsCodesParsed() (SKUs), getProductsCodeImagesParsed() (images)
  4. parseForXml() — loads attribute/variation value caches, category hierarchy
  5. parseItem() — formats each product for the specific feed format (availability, pricing, images, size/color attributes)
  6. Output class ->output($data) — renders XML with proper headers

Feed-Specific Features

FeedSpecial Handling
SkroutzColor splitting (separate item per color), multiple images, availability text from language file
GoogleRSS format with g: namespace, sale_price for discounted items, multi-image support
FacebookExtends Google, adds productIdToFaceBookId() conversion
GlamiProduct-code level items (item_id/item_group_id), PARAM elements for size/color in Greek
eMAGFilters out negative stock items, numeric fields not CDATA-wrapped
Public Marketplaceoffer-additional-fields for VAT, SKU mapping
API SearchGreek/English transliteration, top_seller/top_stock flags

Pricing

  • Standard: final_price from live data (after discounts + VAT)
  • Custom price modifier: If XML_FEEDS.CUSTOM_PRICE_{FEED} enabled → final_price + (final_price * priceModifier / 100)
  • Currency conversion: applyCurrencyRate(price, currency->rate) when ?curr= param provided
  • Sale price: Google feeds output both g:price (original) and g:sale_price (discounted)

Security

Each feed has two registry controls:

  • Enable: XML_FEEDS.IS_ENABLED_{FEEDNAME} — boolean, disables feed URL entirely
  • Token protect: XML_FEEDS.IS_PROTECTED_{FEEDNAME} + XML_FEEDS.{FEEDNAME}_TOKEN — requires ?token=xyz query param

Query Parameters

ParamPurpose
brandFilter by vendor IDs (comma-separated)
categoryFilter by category IDs (comma-separated)
topLimit to top N sellers
stockLimit to top N by stock
currCurrency code for price conversion
tokenAuthentication token

Business Rules

  1. Active products only -- active=1, soft_delete=0, price>0 always enforced in getDbData() query. (ecommercen/feeds/core/AdvXml.php, getDbData())
  2. Stock-based availability -- Each feed interprets stock differently (in-stock/pre-order/out-of-stock). Availability text from language files. (ecommercen/feeds/core/AdvXml.php, parseItem())
  3. Color splitting optional -- Some feeds (Skroutz, LinkWise, Wellcomm) create separate items per color attribute value. (ecommercen/feeds/controllers/AdvSkroutz.php, parseItem())
  4. Category path built from hierarchy -- Categories loaded via get_childs_combo() cache, built into breadcrumb paths. (ecommercen/feeds/core/AdvXml.php, parseForXml())
  5. Attribute groups for size/color -- Registry AFFILIATION_ATTRS_GROUPS.GROUPS_FOR_SIZE and GROUPS_FOR_COLOR determine which attribute groups map to size and color in feeds. (ecommercen/feeds/core/AdvXml.php)
  6. CDATA wrapping -- All text fields wrapped in CDATA by default (except eMAG numerics). (src/Feeds/Output/OutputGenericXml.php)
  7. Feed enable/disable via registry -- Each feed has XML_FEEDS.IS_ENABLED_{FEEDNAME} registry flag. Disabled feeds return 403. (ecommercen/feeds/core/AdvXml.php, secureXml())
  8. Token protection -- When XML_FEEDS.IS_PROTECTED_{FEEDNAME} is enabled, the feed URL requires a ?token= parameter matching XML_FEEDS.{FEEDNAME}_TOKEN. (ecommercen/feeds/core/AdvXml.php, secureXml())
  9. Custom price modifiers -- If XML_FEEDS.CUSTOM_PRICE_{FEED} enabled, prices are adjusted by the per-product price_modifier from shop_product_feed_lp. (ecommercen/feeds/core/AdvXml.php, parseItem())
  10. Currency conversion -- applyCurrencyRate(price, currency->rate) when ?curr= param provided. (ecommercen/feeds/core/AdvXml.php)
  11. Product-feed junction -- Products are assigned to feeds via shop_product_feed_lp junction table with optional price modifier. Managed via AD-02 Product Management batch actions.

Client Customization Points

Override TypeBase FileOverride InWhat Can Change
Feed controllerecommercen/feeds/controllers/Adv*.phpapplication/modules/feeds/controllers/Query filters, item parsing, custom fields
Output classsrc/Feeds/Output/Output*.phpcustom/Feeds/Output/ (client repo)XML structure, field mapping
Base XML classecommercen/feeds/core/AdvXml.phpClient overrideData pipeline, enrichment steps
Registry valuesregistry tablePer-client DBEnable/disable feeds, tokens, custom pricing

Live Feed Status

Live testing against a client database with ~53,000 products revealed three categories of feed behavior:

Fully Working (4 feeds)

Feed URLSizeNotes
/xml/vendors311KBXML structure: <vendors><vendor><id><title><url><discount><items></vendor></vendors>
/xml/lines307KBProduct lines catalog
/xml/google-product-reviews626KBGoogle product review XML
/xml/doofinder/blog2.5MBIncludes transliterated fields: title_el_to_en, title_en_to_el

Memory Limit Failures (14 feeds)

All product-based feeds (Skroutz, Google Merchant, BestPrice, Glami, etc.) fail with PHP's default memory_limit=128MB. Processing ~53,000 products with enrichment (prices, stock, SKUs, images, attributes) requires at minimum 256MB. Production environments should set memory_limit=256M or higher for feed URLs.

Currency Configuration Failures (3 feeds)

The google-catalog, facebook-catalog, and criteo feeds fail with a null return from getDefaultCurrency(). These feeds rely on currency configuration loaded by Adv_front_controller, which initializes the currency registry during storefront bootstrap. Feed controllers extending AdvXml (which extends Adv_front_controller) must have a valid default currency configured in the database.

URL Format Note

Feed URLs use hyphens, not underscores: /xml/google-catalog (not /xml/google_catalog). The entry points table above shows internal controller paths; the public-facing URLs are hyphenated as defined in the route configuration.

Customer Flows

Admin Flows

Integration Flows

System Flows

Wiki Guides: REST API Modules Guide