Appearance
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.
| Type | Path / Trigger | Feed | Output Class |
|---|---|---|---|
| URL | /feeds/skroutz | Skroutz | OutputSkroutzXml |
| URL | /feeds/google_catalog | Google Merchant | OutputGoogleMerchantXml |
| URL | /feeds/facebook_catalog | Facebook Catalog | OutputGoogleMerchantXml (inherited) |
| URL | /feeds/criteo_catalog | Criteo | OutputGoogleMerchantXml (inherited) |
| URL | /feeds/manago | Manago | OutputGoogleMerchantXml (inherited) |
| URL | /feeds/bestprice | BestPrice | OutputBestPriceXml |
| URL | /feeds/emag | eMAG | OutputEmagXml |
| URL | /feeds/glami | Glami | OutputGlamiXml |
| URL | /feeds/agora_catalog | Project Agora | OutputAgoraXml |
| URL | /feeds/linkwise | LinkWise | OutputLinkWiseXml |
| URL | /feeds/wellcomm | Wellcomm | OutputWellcommXml |
| URL | /feeds/contactpigeon | ContactPigeon | OutputXml |
| URL | /feeds/public_marketplace | Public Marketplace | OutputPublicMarketplaceXml |
| URL | /feeds/api_search | API Search | OutputGoogleMerchantXml |
| URL | /feeds/blog_rss | Blog RSS | OutputRss |
| URL | /feeds/lines_catalog | Product Lines | OutputLinesXml |
| URL | /feeds/vendors_catalog | Vendors | OutputVendorsXml |
| URL | /feeds/generic_product | Generic | OutputGenericXml |
| URL | /feeds/google_product_review | Google Reviews | OutputGoogleProductReviewXml |
Code Path Trace
Base class: ecommercen/feeds/core/AdvXml.php — template method pattern:
secureXml()— checksXML_FEEDS.IS_ENABLED_{FEED}registry flag + optional token validation viaXML_FEEDS.{FEED}_TOKENgetDbData()— product model query filtered by brand/category/top sellers/stock paramsgetProductData()— enriches withgetLiveProductsParsed()(prices/stock),getProductsCodesParsed()(SKUs),getProductsCodeImagesParsed()(images)parseForXml()— loads attribute/variation value caches, category hierarchyparseItem()— formats each product for the specific feed format (availability, pricing, images, size/color attributes)- Output class
->output($data)— renders XML with proper headers
Feed-Specific Features
| Feed | Special Handling |
|---|---|
| Skroutz | Color splitting (separate item per color), multiple images, availability text from language file |
RSS format with g: namespace, sale_price for discounted items, multi-image support | |
Extends Google, adds productIdToFaceBookId() conversion | |
| Glami | Product-code level items (item_id/item_group_id), PARAM elements for size/color in Greek |
| eMAG | Filters out negative stock items, numeric fields not CDATA-wrapped |
| Public Marketplace | offer-additional-fields for VAT, SKU mapping |
| API Search | Greek/English transliteration, top_seller/top_stock flags |
Pricing
- Standard:
final_pricefrom 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) andg: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=xyzquery param
Query Parameters
| Param | Purpose |
|---|---|
brand | Filter by vendor IDs (comma-separated) |
category | Filter by category IDs (comma-separated) |
top | Limit to top N sellers |
stock | Limit to top N by stock |
curr | Currency code for price conversion |
token | Authentication token |
Business Rules
- Active products only --
active=1, soft_delete=0, price>0always enforced ingetDbData()query. (ecommercen/feeds/core/AdvXml.php,getDbData()) - 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()) - Color splitting optional -- Some feeds (Skroutz, LinkWise, Wellcomm) create separate items per color attribute value. (
ecommercen/feeds/controllers/AdvSkroutz.php,parseItem()) - Category path built from hierarchy -- Categories loaded via
get_childs_combo()cache, built into breadcrumb paths. (ecommercen/feeds/core/AdvXml.php,parseForXml()) - Attribute groups for size/color -- Registry
AFFILIATION_ATTRS_GROUPS.GROUPS_FOR_SIZEandGROUPS_FOR_COLORdetermine which attribute groups map to size and color in feeds. (ecommercen/feeds/core/AdvXml.php) - CDATA wrapping -- All text fields wrapped in CDATA by default (except eMAG numerics). (
src/Feeds/Output/OutputGenericXml.php) - 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()) - Token protection -- When
XML_FEEDS.IS_PROTECTED_{FEEDNAME}is enabled, the feed URL requires a?token=parameter matchingXML_FEEDS.{FEEDNAME}_TOKEN. (ecommercen/feeds/core/AdvXml.php,secureXml()) - Custom price modifiers -- If
XML_FEEDS.CUSTOM_PRICE_{FEED}enabled, prices are adjusted by the per-productprice_modifierfromshop_product_feed_lp. (ecommercen/feeds/core/AdvXml.php,parseItem()) - Currency conversion --
applyCurrencyRate(price, currency->rate)when?curr=param provided. (ecommercen/feeds/core/AdvXml.php) - Product-feed junction -- Products are assigned to feeds via
shop_product_feed_lpjunction table with optional price modifier. Managed via AD-02 Product Management batch actions.
Client Customization Points
| Override Type | Base File | Override In | What Can Change |
|---|---|---|---|
| Feed controller | ecommercen/feeds/controllers/Adv*.php | application/modules/feeds/controllers/ | Query filters, item parsing, custom fields |
| Output class | src/Feeds/Output/Output*.php | custom/Feeds/Output/ (client repo) | XML structure, field mapping |
| Base XML class | ecommercen/feeds/core/AdvXml.php | Client override | Data pipeline, enrichment steps |
| Registry values | registry table | Per-client DB | Enable/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 URL | Size | Notes |
|---|---|---|
/xml/vendors | 311KB | XML structure: <vendors><vendor><id><title><url><discount><items></vendor></vendors> |
/xml/lines | 307KB | Product lines catalog |
/xml/google-product-reviews | 626KB | Google product review XML |
/xml/doofinder/blog | 2.5MB | Includes 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.
Related Flows
Customer Flows
- CF-01 Product Browsing -- product data shared between storefront and feeds
- CF-02 Product Detail -- product data model shared with feeds
Admin Flows
- AD-02 Product Management -- XML feed assignment per product (batch
set_{feed}_xmlactions,shop_product_feed_lp) - AD-05 Category Management -- category hierarchy used for feed breadcrumb paths
- AD-15 Attributes & Tags -- attribute groups for size/color feed fields
- AD-16 Variations Admin -- variation values used in Glami and Skroutz feeds
- AD-19 Vendor Management -- vendor/brand data included in feed items
- AD-13 Settings -- registry settings for feed enable/disable and tokens
Integration Flows
- IN-02 Skroutz Marketplace -- Skroutz feed + order integration
- IN-04 Public Marketplace -- Public marketplace feed + order integration
- IN-05 eMAG Marketplace -- eMAG feed integration
- IN-10 Doofinder -- Doofinder search feed alternative
System Flows
- SY-07 Cache Management -- cache clearing may affect feed data freshness
- SY-19 Config Registry -- registry values controlling feed enable/disable and tokens
- SY-28 Storage Abstraction -- product media file URLs used in feed image fields
- SY-30 Client Features Reference -- per-client feed customization patterns and feature flags
Wiki Guides: REST API Modules Guide