Skip to content

omnitrade/web API reference

Floor
Provider · Omnitrade
Version
1.x
Conformance suite
runs, no CI read
Verified for real
Its README does not say
Licence
MIT
composer require omnitrade/web:1.x-dev

Read from the package's own PHP files at the commit 8e95d40f1565: its namespaces, classes, interfaces and enums, their public constants, properties and methods with their PHPDoc, and the options its factories take. Nothing of it is run.

Omnitrade\Web

  • Api class

    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.

    3 methods · 2 constants

  • PageReader class

    A product page's HTML, read as an Omnitrade Product. In order of trust:

    3 methods

  • WebGatewayFactory class

    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.

    9 options

Omnitrade\Web\Action

  • AffiliateLinkAction class

    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).

    4 methods

  • FetchProductAction class

    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.

    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)
$resolver

a host's addresses, IPv4 and IPv6 (tests); the system's resolver by default

Api::page()

public function page(string $url): array

The 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): ?Product

PageReader::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

OptionDefault
user_agentApi::USER_AGENT
timeout10
max_bytes3000000
allow_privatefalse
currency'EUR'
affiliate[]
omnitrade.apifunction (Config $c) { return new Api($this->http ?? HttpClient::create(), (string) $c['user_agent'], (int) $c['timeout'], (int) $c['max_bytes'], (bool) …
omnitrade.action.productstatic fn(Config $c) => new FetchProductAction(new PageReader((string) $c['currency']))
omnitrade.action.affiliatestatic 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): bool

AffiliateLinkAction::execute()

public function execute(Request $request): void

AffiliateLinkAction::withQuery()

public static function withQuery(string $url, array $parameters): string

FetchProductAction 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): bool

FetchProductAction::execute()

public function execute(Request $request): void