thelia / facebook-feed-module
Generates the product feed (csv) of the Facebook and Meta catalog for Thelia 3
Package info
github.com/thelia-modules/FacebookFeed
Type:thelia-module
pkg:composer/thelia/facebook-feed-module
Requires
- php: >=8.3
- thelia/installer: ^1.6
- thelia/thelia-library-module: ^2.0.10
Requires (Dev)
- phpunit/phpunit: ^11.5
- roave/security-advisories: dev-latest
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Generates the product feed (csv, ; separated) of the Facebook and Meta catalog, one file for each active
language of the shop, and serves it at /facebookfeed/feed.
Thelia 3.2 or later, with the TheliaLibrary module (image links) and a theme that defines the image filter set used (default in Flexy). The 0.x line of this module is for Thelia 2.
Installation
composer require thelia/facebook-feed-module:^1.0
php bin/console module:refresh
php bin/console module:activate FacebookFeed
The activation creates the table of the exclusions (Config/TheliaMain.sql, CREATE TABLE IF NOT EXISTS): it drops
nothing, the exclusions of a 0.x installation are kept.
Usage
Generation
php bin/console facebook:feed:generate
Writes local/fluxFacebook/fluxfacebook_<locale>.csv for every active language. The file is written next to its
final name and renamed once complete: a reader never sees a half-written feed. The command is meant for a scheduled
task; the back-office only lists, downloads and deletes the generated files. Two optional arguments limit the
lines written for each language, for testing (limit, offset).
The combinations are read in batches of 500 ordered by id, with a fixed number of queries for each batch (brands, addresses, images, attributes and features are read for the whole batch), so the memory and the number of queries do not grow with the size of the catalog. The prices come from the tax rule of the product, loaded once for the feed (once for each product only for a rule that holds a tax read from a feature).
Feed address
/facebookfeed/feed answers the file of the language of the domain (the language of the session). Without a
generated file it answers a 404 in plain text, never a page of the shop.
Columns
id, item_group_ID, title, description, availability, condition, price, link, image_link,
additional_image_link, brand, quantity_to_sell_on_facebook, sale_price, color, size.
| Column | Value |
|---|---|
id |
product reference, -, id of the combination: unique for each combination |
item_group_ID |
reference of the product |
title |
150 characters at most (cut in characters, never in bytes) |
description |
text without tags, entities decoded (& reads &), 9999 characters at most |
price, sale_price |
taxed price of the default country, <amount> <currency code>; the sale price only when the combination is on sale |
link |
domain of the language when the shop has one domain for each language, else the shop URL, then the rewritten URL of the product |
image_link |
image of the combination, else the image of the product at position 1 |
additional_image_link |
the oldest image of the product placed at another position than 1 |
color |
first configured feature that has a value for the product; else the values of the configured attributes of the combination |
size |
values of the configured attributes of the combination, joined with , |
Image links are the browser path of the image library (TheliaLibrary, Liip Imagine) for the configured filter set,
put on the domain of the language; the images are not generated by the feed. The filter set must exist in the
liip_imagine configuration of the project: default (the image as uploaded) is defined by the Flexy theme, not by
the library. An unknown filter set stops the generation with an explicit message. Fields are escaped by fputcsv (delimiter, quote, line
break).
Visible products with a title in the language of the feed only; a combination excluded from the feed, or, when the option is checked, without stock, is left out.
Settings (module configuration screen)
| Setting | Meaning |
|---|---|
| Features that give the color | identifiers separated by commas |
| Attributes that give the color | identifiers separated by commas, used when no feature gives a color |
| Attributes that give the size | identifiers separated by commas |
| Only combinations in stock | leaves out the combinations without stock |
| Image filter set | filter set of the image library used for the image links |
Exclusions
The product edit page, tab "Modules", lists the combinations of the product with a box each: the boxes checked are kept out of the feed. A cloned product is excluded where its original is (same attribute values).
FacebookFeed\Service\ExclusionRepository (autowired) is the entry point for other code, an import for example:
| Method | |
|---|---|
save(array $excludedByCombinationId): array |
writes many exclusions in a few queries (array<int, bool>); returns the ids of the combinations that do not exist, left aside |
combinationsOfProduct(int $productId, string $locale): array |
reference, attribute values and state of each combination |
excludedCombinationIdsOfProduct(int $productId): array |
the ids excluded |
A combination with no row and a combination with a row at 0 are both in the feed. The API resource
FacebookFeedProductExcluded exposes isExcluded on /api/admin/product_sale_elements.
Changes in 1.0.0
- Thelia 3 only (PHP 8.3 or later). Smarty templates,
routing.xmland theconfig.xmldeclarations are gone. - Column
idis<reference>-<combination id>(it was the product reference, the same for every combination) and two columns are added:item_group_IDandadditional_image_link. A shop that already sends the 0.x feed to Facebook must keep the identifiers of its catalog: check them before the switch. - The color can come from a feature (
Features that give the color); the attributes remain for the color and the size. In 0.x the settingattribute_color_idheld attribute identifiers. - The image link is given by the image library (
/cache/images/product/<file>before) for a configurable filter set. - The feed is generated by batches and written then renamed. The generation runs in the command only (a lock refuses two overlapping runs): the back-office button that generated it in the web request is gone.
- The description no longer escapes its entities as XML (0.x wrote
&in the csv). - The title and the description are cut in characters, no more in bytes.
- Without a generated file, the feed address answers a
404in plain text (it redirected to the home page). - The back-office download and delete actions only reach feed files, and the delete one requires a token.
- The exclusion box is in the "Modules" tab of the product, for every combination; the boxes added to the price forms of the Smarty back-office are gone.
- The 0.x SQL query of the feed could not run (a comma before
FROM); it is rewritten.
Tests
Integration tests, run from the root of the Thelia project against its test database:
php bin/test-prepare
vendor/bin/phpunit --bootstrap vendor/thelia/modules/FacebookFeed/Tests/bootstrap.php vendor/thelia/modules/FacebookFeed/Tests