Lue dans les fichiers PHP du paquet au commit 8e95d40f1565 : ses espaces de noms, classes, interfaces et énumérations, leurs constantes, propriétés et méthodes publiques avec leur PHPDoc, et les options que prennent ses fabriques. Rien n’en est exécuté.
ApiclassReads a page the way a browser asks for it, and no more: http(s) only, at most max_bytes, a few redirects, and - addresses being pasted by anyone - never a machine of the local network unless allow_private says so.
3 methods · 2 constants
PageReaderclassA product page's HTML, read as an Omnitrade Product. In order of trust:
3 methods
WebGatewayFactoryclassAny shop's product page, read from its own markup: the JSON-LD Product (or ProductGroup and its variants) most shops publish for search engines, else the schema.org microdata, else the OpenGraph tags. No account, no key: fetchProduct() takes the page's address. Nothing is bought here.
9 options
AffiliateLinkActionclassThe page's address with the site's affiliate parameters, by host: the `affiliate` option maps a host - or a suffix of it, "amazon.fr" for www.amazon.fr - to the query parameters a partner programme reads ({tag: 'mysite-21'}). The request's tag, when given, replaces the value of a rule's only parameter. No rule for the host, or a rule left empty: null (no affiliate link; the plain address stays the one to use).
4 methods
FetchProductActionclassA product by the address of its page: read, then its markup read as a Product. A bare id means nothing to the web (no catalogue to look it up in): null, as for a page that describes no product.
3 methods
Omnitrade\Web
Api class
final class Api Api.php:23
Reads a page the way a browser asks for it, and no more: http(s) only, at most max_bytes, a few redirects, and - addresses being pasted by anyone - never a machine of the local network unless allow_private says so.
The redirects are followed here, not by the HTTP client: each address, the first and every Location, is checked before it is requested. A name is checked by every address it resolves to (IPv4 and IPv6), and the request is made to the address checked (the client's "resolve" option), so a second lookup cannot answer another one. Refused: loopback, private, shared (CGNAT), link-local, multicast, reserved and documentation ranges, IPv6's unique local, link-local and site-local, and an IPv4 address mapped into IPv6 (::ffff:, NAT64's 64:ff9b::, 6to4's 2002::) when the IPv4 address is refused.
const USER_AGENT = 'Mozilla/5.0 (compatible; Omnitrade/1.0; +https://github.com/glitchr-omnisense/omnitrade-web)'const MAX_REDIRECTS = 5
Api::__construct()
public function __construct(readonly HttpClientInterface $http, readonly string $userAgent = self::USER_AGENT, readonly int $timeout = 10, readonly int $maxBytes = 3000000, readonly bool $allowPrivate = false, ?\Closure $resolver = null)$resolvera host's addresses, IPv4 and IPv6 (tests); the system's resolver by default
Api::page()
public function page(string $url): arrayThe page's HTML and the address it was finally served from.
- Throws
ProviderException when an address is refused or does not answer a page
Api::assertReadable()
public function assertReadable(string $url): void- Throws
ProviderException
PageReader class
final class PageReader PageReader.php:27
A product page's HTML, read as an Omnitrade Product. In order of trust:
1. JSON-LD (<script type="application/ld+json">): a Product, a ProductGroup with its hasVariant, found at the top, in a list or in an @graph; offers as an Offer, a list of them or an AggregateOffer; 2. schema.org microdata (itemscope itemtype=".../Product", itemprop); 3. OpenGraph and its product: tags (og:title, og:image, product:price:amount / og:price:amount, product:brand...).
What a richer source leaves empty is taken from the next one (an image from og:image, the shop's name from og:site_name), then from the page itself (<title>, the canonical link). Nothing found: null.
PageReader::__construct()
public function __construct(readonly string $defaultCurrency = 'EUR')PageReader::read()
public function read(string $html, string $url): ?ProductPageReader::decimal()
public static function decimal(string $price): string"1 299,00", "1,299.00", "12.5" → "1299.00", "1299.00", "12.5".
WebGatewayFactory class
final class WebGatewayFactory extends GatewayFactory WebGatewayFactory.php:27
Any shop's product page, read from its own markup: the JSON-LD Product (or ProductGroup and its variants) most shops publish for search engines, else the schema.org microdata, else the OpenGraph tags. No account, no key: fetchProduct() takes the page's address. Nothing is bought here.
options: user_agent: 'Mozilla/5.0 (compatible; Omnitrade/1.0; +https://github.com/glitchr-omnisense/omnitrade-web)' timeout: 10 max_bytes: 3000000 # a page larger than this is cut there allow_private: false # true: addresses of the local network may be read (tests, an intranet) currency: EUR # a price found without a currency affiliate: # host (or a suffix of it) => query parameters added by affiliateLink() amazon.fr: { tag: 'mysite-21' } fnac.com: { awc: '1234_5678' }
Options
| Option | Default | |
|---|---|---|
user_agent | Api::USER_AGENT | |
timeout | 10 | |
max_bytes | 3000000 | |
allow_private | false | |
currency | 'EUR' | |
affiliate | [] | |
omnitrade.api | function (Config $c) {
return new Api($this->http ?? HttpClient::create(), (string) $c['user_agent'], (int) $c['timeout'], (int) $c['max_bytes'], (bool) … | |
omnitrade.action.product | static fn(Config $c) => new FetchProductAction(new PageReader((string) $c['currency'])) | |
omnitrade.action.affiliate | static fn(Config $c) => new AffiliateLinkAction((array) $c['affiliate']) |
Omnitrade\Web\Action
AffiliateLinkAction class
final class AffiliateLinkAction implements ActionInterface AffiliateLinkAction.php:21
The page's address with the site's affiliate parameters, by host: the
affiliate option maps a host - or a suffix of it, "amazon.fr" for
www.amazon.fr - to the query parameters a partner programme reads
({tag: 'mysite-21'}). The request's tag, when given, replaces the value
of a rule's only parameter. No rule for the host, or a rule left empty:
null (no affiliate link;
the plain address stays the one to use).
Tracking parameters other shops add (utm_*, ref, psc...) are dropped, so the link stays the product's.
AffiliateLinkAction::__construct()
public function __construct(readonly array $rules = [])AffiliateLinkAction::supports()
public function supports(Request $request): boolAffiliateLinkAction::execute()
public function execute(Request $request): voidAffiliateLinkAction::withQuery()
public static function withQuery(string $url, array $parameters): stringFetchProductAction class
final class FetchProductAction implements ActionInterface, ApiAwareInterface FetchProductAction.php:18
A product by the address of its page: read, then its markup read as a Product. A bare id means nothing to the web (no catalogue to look it up in): null, as for a page that describes no product.
FetchProductAction::__construct()
public function __construct(readonly PageReader $reader)FetchProductAction::supports()
public function supports(Request $request): boolFetchProductAction::execute()
public function execute(Request $request): void