Lue dans les fichiers PHP du paquet au commit 9bbeeac27fb8 : 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é.
ConfigclassA provider's configuration while its factory builds it: the options given, the factory's defaults under them, and the keys that must be filled.
3 methods
DistributorInterfaceinterfaceReserved: delivering a release to the streaming platforms through a distributor (DDEX). No provider implements it yet - the labels distribute - and the contract is kept narrow until one does: a release (its audio, artwork and metadata) is created, delivered, and its state read back by id.
3 methods
FeedInterfaceinterfaceReading one's own account: who it is, what it posted.
2 methods
PlatformenumThe networks a post may go to.
1 method · 10 cases
ProviderFactoryclassThe Omnibus way: a network's factory fills a Config - its name ("omnipost.factory_name"), the options it cannot do without ("omnipost.required_options") and the defaults of the others - and builds its provider from it.
4 methods
ProviderFactoryInterfaceinterfaceBuilds a provider from its options (a token, an app id, a channel...).
2 methods
ProviderInterfaceinterfaceA network's provider. It implements PublisherInterface and/or FeedInterface, and Auth\RefreshableInterface when its token dies.
2 methods
PublisherInterfaceinterfacePublishing on one network. publish() hands the post over and answers with the network's id and a state that may not be final yet (Instagram processes a reel for a while): status() reads it again. A post that breaks capabilities() is refused before anything is sent (InvalidPostException).
4 methods
RegistryclassThe providers by name, each built once from its factory and options:
10 methods
ValidatorclassA post against a network's capabilities, before anything is sent: the kind, the number of media, the video's length and ratio, the caption's length, the hashtags, the title. Readable violations, by field, for a back office to show.
1 method
OAuthInterfaceinterfaceConnecting the account from a back office: the URL to send the user to, the code exchanged on the way back.
2 methods
RefreshableInterfaceinterfaceA provider whose token dies: the site asks for a fresh one before it does (a cron).
2 methods
OmnipostBundleclassOmnipost in a Symfony application: the provider packages installed (omnipost/instagram, omnipost/youtube) registered, the site's providers built from configuration, Omnipost\Registry and Omnipost\Validator autowired, and each provider injectable by its name:
2 methods
InvalidConfigExceptionclassA provider misconfigured: a credential missing, an unknown factory.
InvalidPostExceptionclassThe post breaks the network's capabilities: nothing was sent.
1 method · 2 properties
InvalidShareableExceptionclassA share link's Shareable (Share\Shareable) given an address that is not whole (no http(s) scheme or no host).
NotSupportedExceptionclassThe provider does not do that (no feed, no deletion, no scheduling...).
1 method
OmnipostExceptioninterfaceEvery exception Omnipost throws.
ProviderExceptionclassThe network refused, or could not be reached.
1 method · 3 properties
UnauthorizedExceptionclassThe token is dead, or lacks a permission: the account must be connected again.
UnknownNetworkExceptionclassA share network asked of a Share\Registry by a name it does not hold.
RedactionclassWhat a failed call may carry of its credentials, taken out before the failure leaves the package: an HTTP client's exception quotes the URL called (a key in its query, a password in its user part), and every exception's trace keeps the arguments of the calls under it (the request options, headers and query with the key) unless PHP runs with zend.exception_ignore_args.
5 methods · 1 constant
AccountclassThe connected account: who the posts go out as.
1 method · 9 properties
CapabilitiesclassWhat a network accepts, for the Validator to check a post before it is sent: the kinds, the video's bounds, the ratios, the caption's length, the hashtags, whether a title is required.
3 methods · 18 properties
FeedclassA page of the account's posts, newest first, and the cursor of the next page.
1 method · 2 properties
FeedItemclassOne of the account's own posts, as the network lists it: a picture, a video (its thumbnail), a carousel (its children). What a site caches to show a wall.
1 method · 13 properties
MediaclassA picture or a video to post. The networks fetch it themselves, so $url must be public (a site exposes a signed URL for the time of the publication); $path is the local file, for the providers that upload (YouTube) and for the Validator to measure.
5 methods · 10 properties
MediaKindenum2 cases
PostclassThe canonical post - one reel (or picture, carousel), one caption, its hashtags, a title for the networks that want one - and its variants per network. for(Platform) gives the post as that network receives it.
10 methods · 10 properties
PostKindenumWhat a post is. REEL is the one every network takes - a vertical short video (Instagram Reel, YouTube Short, Facebook Reel, TikTok) - and the one a site renders from its template; the others are what a network also offers.
5 cases
PublicationclassWhat became of a post on one network: the network's id for it, its state, its permalink once published, the error otherwise. A provider's status() reads it again by $id until the state is final.
3 methods · 7 properties
PublicationStateenum1 method · 4 cases
TokenclassAn access token and when it dies: a site stores it and asks the provider to refresh it in time.
5 methods · 5 properties
VariantclassWhat one network gets instead of the canonical post: its own caption (shorter, other hashtags), a title (YouTube), another cover, another rendering of the video (a template of its own). Null keeps the post's.
1 method · 7 properties
ViolationclassOne thing a network would refuse: where (caption, media[0].duration...) and why, readable.
2 methods · 2 properties
LabelsclassThe share links' own labels (Share/translations/<locale>.php, plain PHP arrays by label key), for an application that has none of its own: English and French. An application with a translator imports these files into it, or keeps its own words under its own keys.
3 methods
LinkclassOne network's link for one Shareable, with all a template needs to draw it.
4 methods · 6 properties
NetworkInterfaceinterfaceOmnipost's share contract: a place a visitor can share a page to - a network's own share page, an e-mail, the clipboard, the device's share sheet. A network builds an address from a Shareable and says how it is shown; it calls nothing and holds no credential (publishing from an account is PublisherInterface's part). The core holds every network that has a share page (Registry::defaults()); an application, or a provider package, adds its own with Registry::add().
7 methods
RegistryclassThe networks by name, and the links of a Shareable to those an application shows, in its order.
7 methods
ShareclassA Shareable and its links, in the order they were asked for: what a template draws. toArray() is the one JSON Twig, Blade and React read alike:
5 methods · 2 properties
ShareableclassWhat is shared: a page, by its canonical address, with what the networks show of it. Each network takes the part it knows (NetworkInterface::uses()): Facebook and LinkedIn the address alone (they read the page's og:* tags themselves), X the address, the message, the hashtags and the account to credit, Pinterest the picture as well, and so on.
3 methods · 6 properties
AbstractNetworkclassWhat most networks share: the label key and the icon named after the network, no brand colour, a plain link; and the query string they build.
4 methods
BlueskyclassBluesky's compose intent: one text, the message, the hashtags and the address; Bluesky draws the link's card from it. Its app opens the composer for a visitor signed in at bsky.app and drops the intent for one signed out (social-app's useComposeIntent: nothing kept for after the sign-in).
4 methods
CopyLinkclassThe page's address copied to the clipboard (the share script, action "copy"; hidden where the browser has no clipboard). Its link is the address itself, so a visitor without the script can still copy it from the link.
5 methods
EmailclassAn e-mail from the visitor's own mail client: the title as its subject, the text (when there is one) and the address as its body.
4 methods
FacebookclassFacebook's sharer: the address alone; Facebook reads the title and the picture from the page's og:* tags.
4 methods
LinkedInclassLinkedIn's share-offsite: the address alone (it no longer takes a title nor a summary); LinkedIn reads the page's og:* tags.
4 methods
MastodonclassMastodon's share page, on one instance: one text, the message, the hashtags and the address. Mastodon has no central site: the instance is configured, or - when none is - the visitor gives theirs (the share script asks it on a click, action "instance"; without the script the link goes to mastodon.social).
7 methods · 1 constant
NativeclassThe device's own share sheet (navigator.share: the title, the text and the address; the share script, action "share"), hidden where the browser has none. Its link is the page's address.
5 methods
PinterestclassPinterest's pin: the address, the picture pinned and its description; without a picture Pinterest offers the page's own.
4 methods
RedditclassReddit's submit page: a link post, its address and its title; the visitor picks the community.
4 methods
TelegramclassTelegram's share page: the address and the message apart; the visitor picks the chat.
4 methods
ThreadsclassThreads' post intent: the message (with the hashtags) and the address apart, which Threads shows as the link's card.
4 methods
WhatsAppclassWhatsApp's click-to-chat: one text, the message and the address; the visitor picks the chat.
4 methods
XclassX's (Twitter's) post intent: the address, the message, the hashtags and the account to credit. twitter.com's intent, which x.com serves the same.
4 methods
Omnipost
Config class
final class Config extends ArrayObject Config.php:13
A provider's configuration while its factory builds it: the options given, the factory's defaults under them, and the keys that must be filled.
Config::defaults()
public function defaults(array $defaults): selfSets each key not set yet.
Config::validateNotEmpty()
public function validateNotEmpty(array $keys): voidConfig::get()
public function get(string $key, mixed $default = null): mixedDistributorInterface interface
interface DistributorInterface extends ProviderInterface DistributorInterface.php:12
Reserved: delivering a release to the streaming platforms through a distributor (DDEX). No provider implements it yet - the labels distribute - and the contract is kept narrow until one does: a release (its audio, artwork and metadata) is created, delivered, and its state read back by id.
DistributorInterface::createRelease()
public function createRelease(array $release): string$releasethe distributor's own shape, for now
- Returns
the distributor's id of the release
DistributorInterface::deliver()
public function deliver(string $releaseId): voidDistributorInterface::deliveryStatus()
public function deliveryStatus(string $releaseId): array- Returns
the distributor's own status shape, for now
FeedInterface interface
interface FeedInterface extends ProviderInterface FeedInterface.php:9
Reading one's own account: who it is, what it posted.
FeedInterface::account()
public function account(): AccountFeedInterface::feed()
public function feed(?string $cursor = null, int $limit = 25): FeedNewest first; $cursor from the previous page's $next.
Platform enum
enum Platform Platform.php:6
The networks a post may go to.
case INSTAGRAM = 'instagram'case YOUTUBE = 'youtube'case FACEBOOK = 'facebook'case TIKTOK = 'tiktok'case THREADS = 'threads'case X = 'x'case LINKEDIN = 'linkedin'case BLUESKY = 'bluesky'case MASTODON = 'mastodon'case PINTEREST = 'pinterest'
Platform::label()
public function label(): stringProviderFactory class
abstract class ProviderFactory implements ProviderFactoryInterface ProviderFactory.php:18
The Omnibus way: a network's factory fills a Config - its name ("omnipost.factory_name"), the options it cannot do without ("omnipost.required_options") and the defaults of the others - and builds its provider from it.
Options left empty (null, '': an environment variable not set) are as if not given: the defaults stand. A credential is best not required here but asked for when a call needs it, so that a provider without its token still answers what needs none (capabilities(), authorizationUrl()).
ProviderFactory::__construct()
public function __construct(protected readonly ?HttpClientInterface $http = null)ProviderFactory::getName()
public function getName(): stringProviderFactory::create()
public function create(array $options = []): ProviderInterfaceProviderFactory::createConfig()
public function createConfig(array $options = []): ConfigProviderFactoryInterface interface
interface ProviderFactoryInterface ProviderFactoryInterface.php:6
Builds a provider from its options (a token, an app id, a channel...).
ProviderFactoryInterface::getName()
public function getName(): stringThe name providers are configured with: "instagram", "youtube".
..
ProviderFactoryInterface::create()
public function create(array $options = []): ProviderInterfaceProviderInterface interface
interface ProviderInterface ProviderInterface.php:9
A network's provider. It implements PublisherInterface and/or FeedInterface, and Auth\RefreshableInterface when its token dies.
ProviderInterface::getName()
public function getName(): stringThe name it is configured as: "instagram", "youtube".
..
ProviderInterface::getPlatform()
public function getPlatform(): PlatformPublisherInterface interface
interface PublisherInterface extends ProviderInterface PublisherInterface.php:16
Publishing on one network. publish() hands the post over and answers with the network's id and a state that may not be final yet (Instagram processes a reel for a while): status() reads it again. A post that breaks capabilities() is refused before anything is sent (InvalidPostException).
PublisherInterface::capabilities()
public function capabilities(): CapabilitiesPublisherInterface::publish()
public function publish(Post $post): PublicationPublisherInterface::status()
public function status(string $publicationId): PublicationPublisherInterface::delete()
public function delete(string $publicationId): voidTakes the post down; NotSupportedException where the network's API cannot.
Registry class
final class Registry Registry.php:14
The providers by name, each built once from its factory and options:
new Registry([new InstagramProviderFactory($http)], [ 'instagram' => ['factory' => 'instagram', 'options' => ['access_token' => '...']], ]);
Registry::__construct()
public function __construct(iterable $factories, readonly array $config)Registry::get()
public function get(string $name): ProviderInterfaceRegistry::create()
public function create(string $name, array $overrides = []): ProviderInterfaceA provider built afresh, its configured options with $overrides over them - a token kept in a database, say. Not kept: get() still gives the configured one.
Registry::has()
public function has(string $name): boolRegistry::options()
public function options(string $name): arrayRegistry::names()
public function names(): arrayRegistry::all()
public function all(): arrayRegistry::publishers()
public function publishers(): arrayRegistry::feeds()
public function feeds(): arrayRegistry::factories()
public function factories(): array- Returns
the factories installed
Validator class
final class Validator Validator.php:17
A post against a network's capabilities, before anything is sent: the kind, the number of media, the video's length and ratio, the caption's length, the hashtags, the title. Readable violations, by field, for a back office to show.
Validator::validate()
public function validate(Post $post, Capabilities $c): arrayOmnipost\Auth
OAuthInterface interface
interface OAuthInterface OAuthInterface.php:8
Connecting the account from a back office: the URL to send the user to, the code exchanged on the way back.
OAuthInterface::authorizationUrl()
public function authorizationUrl(string $redirectUri, string $state, array $scopes = []): stringOAuthInterface::exchange()
public function exchange(string $code, string $redirectUri): TokenRefreshableInterface interface
interface RefreshableInterface RefreshableInterface.php:8
A provider whose token dies: the site asks for a fresh one before it does (a cron).
RefreshableInterface::token()
public function token(): ?TokenRefreshableInterface::refresh()
public function refresh(): TokenOmnipost\Bridge\Symfony
OmnipostBundle class
final class OmnipostBundle extends AbstractBundle OmnipostBundle.php:43
Omnipost in a Symfony application: the provider packages installed (omnipost/instagram, omnipost/youtube) registered, the site's providers built from configuration, Omnipost\Registry and Omnipost\Validator autowired, and each provider injectable by its name:
omnipost: providers: instagram: { factory: instagram, options: { access_token: '%env(default::INSTAGRAM_ACCESS_TOKEN)%', app_id: '%env(default::INSTAGRAM_APP_ID)%', app_secret: '%env(default::INSTAGRAM_APP_SECRET)%' } } youtube: { factory: youtube, options: { api_key: '%env(default::YOUTUBE_API_KEY)%', channel_id: '%env(default::YOUTUBE_CHANNEL_ID)%' } }
public function __construct(PublisherInterface $instagram, FeedInterface $youtube) }Nothing is built, nor checked, when the container compiles: a provider is built the first time it is asked for, and a token left empty only shows when a call needs it (InvalidConfigException). So a site with no keys yet still boots; Registry::has() says a provider is declared, and a call inside try/catch InvalidConfigException says whether it is configured.
An application's own factories (a ProviderFactoryInterface) are registered too, autoconfigured.
OmnipostBundle::configure()
public function configure(DefinitionConfigurator $definition): voidOmnipostBundle::loadExtension()
public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): voidOmnipost\Exception
InvalidConfigException class
final class InvalidConfigException extends LogicException implements OmnipostException InvalidConfigException.php:6
A provider misconfigured: a credential missing, an unknown factory.
InvalidPostException class
final class InvalidPostException extends InvalidArgumentException implements OmnipostException InvalidPostException.php:8
The post breaks the network's capabilities: nothing was sent.
public readonly string $providerpublic readonly array $violations
InvalidPostException::__construct()
public function __construct(public readonly string $provider, public readonly array $violations)InvalidShareableException class
final class InvalidShareableException extends InvalidArgumentException implements OmnipostException InvalidShareableException.php:6
A share link's Shareable (Share\Shareable) given an address that is not whole (no http(s) scheme or no host).
NotSupportedException class
final class NotSupportedException extends LogicException implements OmnipostException NotSupportedException.php:6
The provider does not do that (no feed, no deletion, no scheduling...).
NotSupportedException::operation()
public static function operation(string $provider, string $operation): selfOmnipostException interface
interface OmnipostException extends Throwable OmnipostException.php:6
Every exception Omnipost throws.
ProviderException class
class ProviderException extends RuntimeException implements OmnipostException ProviderException.php:6
The network refused, or could not be reached.
public readonly string $providerpublic readonly ?int $statuspublic readonly ?string $providerCodeThe network's own error code, when it gave one
ProviderException::__construct()
public function __construct(public readonly string $provider, string $message, public readonly ?int $status = null, public readonly ?string $providerCode = null, ?\Throwable $previous = null)UnauthorizedException class
final class UnauthorizedException extends ProviderException UnauthorizedException.php:6
The token is dead, or lacks a permission: the account must be connected again.
UnknownNetworkException class
final class UnknownNetworkException extends OutOfBoundsException implements OmnipostException UnknownNetworkException.php:6
A share network asked of a Share\Registry by a name it does not hold.
Omnipost\Http
Redaction class
final class Redaction Redaction.php:22
What a failed call may carry of its credentials, taken out before the failure leaves the package: an HTTP client's exception quotes the URL called (a key in its query, a password in its user part), and every exception's trace keeps the arguments of the calls under it (the request options, headers and query with the key) unless PHP runs with zend.exception_ignore_args.
copy() gives the previous exception to wrap instead of the client's own: the same class and code, its message with the key's parameters, the user part and every secret value replaced by ***, its trace without arguments, its own previous copied the same way. Properties of the client's class beyond those of \Exception are not copied (a Symfony HttpException's response, a PSR-18 exception's request: their URL holds the key). withoutArguments() takes the arguments out of the trace of the exception thrown in its place.
const MASK = '***'
Redaction::secrets()
public static function secrets(string $url, array $options = []): arrayThe secrets a request carries: the values of its query parameters, headers and body fields named as credentials (key, token, secret, password, signature, auth...), a bearer token, a basic password, the URL's user part.
$optionsthe HTTP client's options
Redaction::sensitive()
public static function sensitive(string $name): boolWhether a parameter, header or field of this name holds a credential.
Redaction::text()
public static function text(string $text, array $secrets = []): stringA text without credentials: in every address, the user part and the parameters named as credentials masked (api_key=***); then every secret given, raw or URL-encoded, masked wherever it stands.
Redaction::copy()
public static function copy(\Throwable $failure, array $secrets = []): \ThrowableA copy of a failure to wrap in its place: its class, code, file and line, its message through text(), its trace without arguments, its previous copied the same way.
Redaction::withoutArguments()
public static function withoutArguments(\Throwable $failure): \ThrowableThe failure given, the arguments out of its trace (and out of its previous ones'), as zend.exception_ignore_args would have left it.
Omnipost\Model
Account class
final class Account Account.php:8
The connected account: who the posts go out as.
public readonly Platform $platformpublic readonly string $idpublic readonly string $usernamepublic readonly ?string $namepublic readonly ?string $urlpublic readonly ?string $pictureUrlpublic readonly ?int $followerspublic readonly ?int $postspublic readonly ?string $kind
Account::__construct()
public function __construct(public readonly Platform $platform, public readonly string $id, public readonly string $username, public readonly ?string $name = null, public readonly ?string $url = null, public readonly ?string $pictureUrl = null, public readonly ?int $followers = null, public readonly ?int $posts = null, public readonly ?string $kind = null)Capabilities class
final class Capabilities Capabilities.php:15
What a network accepts, for the Validator to check a post before it is sent: the kinds, the video's bounds, the ratios, the caption's length, the hashtags, whether a title is required.
public readonly array $kindspublic readonly ?float $minDurationpublic readonly ?float $maxDurationpublic readonly array $aspectRatiospublic readonly float $ratioTolerancetolerance on the ratio, as a fraction (0.01 = 1 %)
public readonly ?int $maxVideoSizebytes
public readonly ?int $maxImageSizepublic readonly ?int $captionMaxLengthpublic readonly bool $titleRequiredpublic readonly ?int $titleMaxLengthpublic readonly int $mediaMaxCountpublic readonly array $videoFormatspublic readonly array $imageFormatspublic readonly ?int $minWidthpublic readonly ?int $minHeightpublic readonly bool $schedulingpublic readonly bool $linkInCaptionthe post's link written into its caption (Post::text()), where the network makes it a link
Capabilities::__construct()
public function __construct(public readonly array $kinds, public readonly ?float $minDuration = null, public readonly ?float $maxDuration = null, public readonly array $aspectRatios = [], public readonly float $ratioTolerance = 0.01, public readonly ?int $maxVideoSize = null, public readonly ?int $maxImageSize = null, public readonly ?int $captionMaxLength = null, public readonly ?int $maxTags = null, public readonly bool $titleRequired = false, public readonly ?int $titleMaxLength = null, public readonly int $mediaMaxCount = 1, public readonly array $videoFormats = [], public readonly array $imageFormats = [], public readonly ?int $minWidth = null, public readonly ?int $minHeight = null, public readonly bool $scheduling = false, public readonly bool $linkInCaption = true)Capabilities::supports()
public function supports(PostKind $kind): boolCapabilities::acceptsRatio()
public function acceptsRatio(float $ratio): boolWhether $ratio (width / height) is one of the accepted ratios, within the tolerance.
Feed class
final class Feed Feed.php:6
A page of the account's posts, newest first, and the cursor of the next page.
public readonly array $itemspublic readonly ?string $next
Feed::__construct()
public function __construct(public readonly array $items, public readonly ?string $next = null)FeedItem class
final class FeedItem FeedItem.php:12
One of the account's own posts, as the network lists it: a picture, a video (its thumbnail), a carousel (its children). What a site caches to show a wall.
public readonly string $idpublic readonly PostKind $kindpublic readonly string $permalinkpublic readonly ?string $urlpublic readonly ?string $thumbnailUrlpublic readonly ?string $captionpublic readonly ?\DateTimeImmutable $publishedAtpublic readonly ?float $durationpublic readonly array $childrenpublic readonly ?int $likespublic readonly ?int $commentspublic readonly ?int $viewspublic readonly array $raw
FeedItem::__construct()
public function __construct(public readonly string $id, public readonly PostKind $kind, public readonly string $permalink, public readonly ?string $url = null, public readonly ?string $thumbnailUrl = null, public readonly ?string $caption = null, public readonly ?\DateTimeImmutable $publishedAt = null, public readonly ?float $duration = null, public readonly array $children = [], public readonly ?int $likes = null, public readonly ?int $comments = null, public readonly ?int $views = null, public readonly array $raw = [])Media class
final class Media Media.php:11
A picture or a video to post. The networks fetch it themselves, so $url must be public (a site exposes a signed URL for the time of the publication); $path is the local file, for the providers that upload (YouTube) and for the Validator to measure.
public readonly MediaKind $kindpublic readonly string $urlpublic readonly ?string $pathpublic readonly ?string $mimepublic readonly ?int $widthpublic readonly ?int $heightpublic readonly ?float $durationseconds
public readonly ?int $sizebytes
public readonly ?string $coverUrlA still for a video: shown before it plays
public readonly ?string $alt
Media::__construct()
public function __construct(public readonly MediaKind $kind, public readonly string $url, public readonly ?string $path = null, public readonly ?string $mime = null, public readonly ?int $width = null, public readonly ?int $height = null, public readonly ?float $duration = null, public readonly ?int $size = null, public readonly ?string $coverUrl = null, public readonly ?string $alt = null)Media::image()
public static function image(string $url, ?string $path = null, ?int $width = null, ?int $height = null, ?string $alt = null): selfMedia::video()
public static function video(string $url, ?string $path = null, ?float $duration = null, ?int $width = null, ?int $height = null, ?string $coverUrl = null): selfMedia::aspectRatio()
public function aspectRatio(): ?string"9:16", "1:1", "16:9"... null when the size is unknown.
Media::ratio()
public function ratio(): ?floatwidth / height, null when unknown.
MediaKind enum
enum MediaKind MediaKind.php:5
case IMAGE = 'image'case VIDEO = 'video'
Post class
final class Post Post.php:12
The canonical post - one reel (or picture, carousel), one caption, its hashtags, a title for the networks that want one - and its variants per network. for(Platform) gives the post as that network receives it.
public readonly PostKind $kindpublic readonly array $mediapublic readonly string $captionpublic readonly ?string $titlehashtags without the '#'
public readonly ?string $coverUrlpublic readonly ?\DateTimeImmutable $scheduledAtpublic readonly array $variantsplatform value => variant
public readonly array $optionsprovider-specific extras (a variant's win)
public readonly ?string $linkA link to carry (the site's page): written into the caption where the network makes it a link (Capabilities::$linkInCaption: YouTube's description), left out elsewhere (Instagram)
Post::__construct()
public function __construct(public readonly PostKind $kind, public readonly array $media, public readonly string $caption = '', public readonly ?string $title = null, public readonly array $tags = [], public readonly ?string $coverUrl = null, public readonly ?\DateTimeImmutable $scheduledAt = null, public readonly array $variants = [], public readonly array $options = [], public readonly ?string $link = null)$tagshashtags without the '#'
$variantsplatform value => variant
$optionsprovider-specific extras (a variant's win)
Post::reel()
public static function reel(Media $video, string $caption = '', ?string $title = null, array $tags = []): selfPost::image()
public static function image(Media $image, string $caption = '', array $tags = []): selfPost::carousel()
public static function carousel(array $media, string $caption = '', array $tags = []): selfPost::withVariant()
public function withVariant(Variant $variant): selfPost::withScheduledAt()
public function withScheduledAt(?\DateTimeImmutable $at): selfPost::variant()
public function variant(Platform $platform): ?VariantPost::for()
public function for(Platform $platform): selfThe post as $platform receives it: the variant's fields over the canonical ones, no variants left.
Post::text()
public function text(bool $withLink = false): stringThe caption as sent: the caption, the link on its own line when $withLink (a network whose captions make it a link: Capabilities::$linkInCaption), then the hashtags.
Post::video()
public function video(): ?MediaPostKind enum
enum PostKind PostKind.php:11
What a post is. REEL is the one every network takes - a vertical short video (Instagram Reel, YouTube Short, Facebook Reel, TikTok) - and the one a site renders from its template; the others are what a network also offers.
case REEL = 'reel'case IMAGE = 'image'case CAROUSEL = 'carousel'case VIDEO = 'video'case STORY = 'story'
Publication class
final class Publication Publication.php:12
What became of a post on one network: the network's id for it, its state, its permalink once published, the error otherwise. A provider's status() reads it again by $id until the state is final.
public readonly Platform $platformpublic readonly string $idpublic readonly PublicationState $statepublic readonly ?string $permalinkpublic readonly ?string $errorpublic readonly ?\DateTimeImmutable $publishedAtpublic readonly array $rawThe network's own answer, for the record
Publication::__construct()
public function __construct(public readonly Platform $platform, public readonly string $id, public readonly PublicationState $state, public readonly ?string $permalink = null, public readonly ?string $error = null, public readonly ?\DateTimeImmutable $publishedAt = null, public readonly array $raw = [])Publication::isPublished()
public function isPublished(): boolPublication::isFailed()
public function isFailed(): boolPublicationState enum
enum PublicationState PublicationState.php:5
case PENDING = 'pending'Handed to the network, not yet processed (Instagram's container, a scheduled Short)
case PROCESSING = 'processing'The network is working on it (transcoding)
case PUBLISHED = 'published'case FAILED = 'failed'
PublicationState::isFinal()
public function isFinal(): boolToken class
final class Token Token.php:6
An access token and when it dies: a site stores it and asks the provider to refresh it in time.
public readonly string $accessTokenpublic readonly ?\DateTimeImmutable $expiresAtpublic readonly ?string $refreshTokenpublic readonly array $scopespublic readonly ?string $accountId
Token::__construct()
public function __construct(public readonly string $accessToken, public readonly ?\DateTimeImmutable $expiresAt = null, public readonly ?string $refreshToken = null, public readonly array $scopes = [], public readonly ?string $accountId = null)Token::isExpired()
public function isExpired(?\DateTimeImmutable $now = null): boolToken::isExpiring()
public function isExpiring(int $days = 10, ?\DateTimeImmutable $now = null): boolTrue within $days of the end: time to refresh.
Token::toArray()
public function toArray(): arrayToken::fromArray()
public static function fromArray(array $data): selfVariant class
final class Variant Variant.php:15
What one network gets instead of the canonical post: its own caption (shorter, other hashtags), a title (YouTube), another cover, another rendering of the video (a template of its own). Null keeps the post's.
public readonly Platform $platformpublic readonly ?string $captionpublic readonly ?string $titlepublic readonly ?array $mediapublic readonly ?string $coverUrlpublic readonly array $optionsProvider-specific extras: YouTube's privacy, Instagram's share_to_feed.
..
Variant::__construct()
public function __construct(public readonly Platform $platform, public readonly ?string $caption = null, public readonly ?string $title = null, public readonly ?array $tags = null, public readonly ?array $media = null, public readonly ?string $coverUrl = null, public readonly array $options = [])Violation class
final class Violation Violation.php:6
One thing a network would refuse: where (caption, media[0].duration...) and why, readable.
public readonly string $pathpublic readonly string $message
Violation::__construct()
public function __construct(public readonly string $path, public readonly string $message)Violation::__toString()
public function __toString(): stringOmnipost\Share
Labels class
final class Labels Labels.php:11
The share links' own labels (Share/translations/<locale>.php, plain PHP arrays by label key), for an application that has none of its own: English and French. An application with a translator imports these files into it, or keeps its own words under its own keys.
Labels::locales()
public static function locales(): array- Returns
the locales there are labels in
Labels::catalogue()
public static function catalogue(string $locale): array- Returns
the labels of a locale ("fr", "fr_FR", "fr-CA"...), English when there are none in it
Labels::get()
public static function get(string $key, string $locale = 'en'): stringA label, its key itself when there is none.
Link class
final readonly class Link Link.php:11
One network's link for one Shareable, with all a template needs to draw it.
A web share page opens in a new tab (rel="noopener") - Mastodon's without an instance too, which the script sends to the visitor's own instance; a mailto: and the script's share and copy do not (their address is the page's).
Link::__construct()
public function __construct(public string $network, public string $url, public string $labelKey, public string $icon, public ?string $color = null, public ?string $action = null)Link::of()
public static function of(NetworkInterface $network, Shareable $shareable): selfLink::newTab()
public function newTab(): boolTrue for a share page on the web, which opens in a new tab: no action, or the instance's (Mastodon's share page, wherever the script sends it).
Link::toArray()
public function toArray(): arrayNetworkInterface interface
interface NetworkInterface NetworkInterface.php:14
Omnipost's share contract: a place a visitor can share a page to - a network's own share page, an e-mail, the clipboard, the device's share sheet. A network builds an address from a Shareable and says how it is shown; it calls nothing and holds no credential (publishing from an account is PublisherInterface's part). The core holds every network that has a share page (Registry::defaults()); an application, or a provider package, adds its own with Registry::add().
NetworkInterface::name()
public function name(): stringIts name in a Registry and in the JSON: "facebook", "x", "copy".
..
NetworkInterface::labelKey()
public function labelKey(): stringThe key of its label in the share labels' catalogues (Share/translations/<locale>.php): "omnipost.share.facebook".
..
NetworkInterface::icon()
public function icon(): stringAn icon's name, for the application's own icon set: "facebook", "x", "envelope", "link", "share".
..
NetworkInterface::color()
public function color(): ?stringThe network's brand colour (#rrggbb), null for the ones without a brand (e-mail, copy, share sheet).
NetworkInterface::uses()
public function uses(): arrayWhat it takes of a Shareable.
NetworkInterface::shareUrl()
public function shareUrl(Shareable $shareable): stringIts address for this Shareable: the share page, a mailto:, or the page's own address for copy and share.
NetworkInterface::action()
public function action(): ?stringWhat the share script (assets/omnipost-share.js) does on a click, null for a plain link: "share" (navigator.share), "copy" (the clipboard), "instance" (asks the visitor's Mastodon instance first).
Registry class
final class Registry Registry.php:16
The networks by name, and the links of a Shareable to those an application shows, in its order.
$registry = Registry::defaults(); $share = $registry->share(new Shareable($url, $title, image: $picture), ['facebook', 'x', 'pinterest', 'email']); $share->url('x'); // https://twitter.com/intent/tweet?url=...&text=... $share->toArray(); // the JSON a template reads
Registry::__construct()
public function __construct(iterable $networks = [])Registry::defaults()
public static function defaults(?string $mastodonInstance = null): selfEvery share network the core knows, in this order: facebook, x, pinterest, linkedin, bluesky, mastodon, threads, whatsapp, telegram, reddit, email, copy, native.
$mastodonInstancethe instance Mastodon's link goes to (e.g. "mastodon.social"); null lets the visitor give theirs
Registry::add()
public function add(NetworkInterface $network): selfAdds a network, or replaces the one of the same name.
Registry::has()
public function has(string $name): boolRegistry::get()
public function get(string $name): NetworkInterfaceRegistry::names()
public function names(): arrayRegistry::share()
public function share(Shareable $shareable, ?array $networks = null): ShareThe links of a Shareable.
$networksthe names, in the order they are shown; null for every network
Share class
final readonly class Share implements JsonSerializable Share.php:13
A Shareable and its links, in the order they were asked for: what a template draws. toArray() is the one JSON Twig, Blade and React read alike:
{"url": ..., "title": ..., "text": ..., "image": ..., "hashtags": [...], "via": ..., "links": {"facebook": {"network": "facebook", "url": ..., "label": "omnipost.share.facebook", "icon": "facebook", "color": "#1877f2", "newTab": true, "action": null}, ...}}
by network name
Share::__construct()
public function __construct(public Shareable $shareable, public array $links)$linksby network name
Share::link()
public function link(string $network): ?LinkShare::url()
public function url(string $network): ?stringThe address of one network's link, null when it was not asked for.
Share::toArray()
public function toArray(): arrayShare::jsonSerialize()
public function jsonSerialize(): arrayShareable class
final readonly class Shareable Shareable.php:17
What is shared: a page, by its canonical address, with what the networks show of it. Each network takes the part it knows (NetworkInterface::uses()): Facebook and LinkedIn the address alone (they read the page's og:* tags themselves), X the address, the message, the hashtags and the account to credit, Pinterest the picture as well, and so on.
Addresses are whole (scheme and host): a share page opens on another site, where a path means nothing.
the page's canonical address, whole
the page's title: the e-mail's subject, Reddit's title, the message when there is no text
a sentence to post with the link; the title is posted when null
the page's share picture, whole (Pinterest's pin)
an account to credit, without its "@" (X)
Shareable::__construct()
public function __construct(public string $url, public string $title, public ?string $text = null, public ?string $image = null, array $hashtags = [], public ?string $via = null)$urlthe page's canonical address, whole
$titlethe page's title: the e-mail's subject, Reddit's title, the message when there is no text
$texta sentence to post with the link; the title is posted when null
$imagethe page's share picture, whole (Pinterest's pin)
$hashtagswithout their "#"
$viaan account to credit, without its "@" (X)
Shareable::message()
public function message(): stringWhat a network posts: the text when there is one, the title otherwise.
Shareable::toArray()
public function toArray(): arrayOmnipost\Share\Network
AbstractNetwork class
abstract class AbstractNetwork implements NetworkInterface AbstractNetwork.php:12
What most networks share: the label key and the icon named after the network, no brand colour, a plain link; and the query string they build.
AbstractNetwork::labelKey()
public function labelKey(): stringAbstractNetwork::icon()
public function icon(): stringAbstractNetwork::color()
public function color(): ?stringAbstractNetwork::action()
public function action(): ?stringBluesky class
final class Bluesky extends AbstractNetwork Bluesky.php:12
Bluesky's compose intent: one text, the message, the hashtags and the address; Bluesky draws the link's card from it. Its app opens the composer for a visitor signed in at bsky.app and drops the intent for one signed out (social-app's useComposeIntent: nothing kept for after the sign-in).
Bluesky::name()
public function name(): stringBluesky::color()
public function color(): stringBluesky::uses()
public function uses(): arrayBluesky::shareUrl()
public function shareUrl(Shareable $shareable): stringCopyLink class
final class CopyLink extends AbstractNetwork CopyLink.php:12
The page's address copied to the clipboard (the share script, action "copy"; hidden where the browser has no clipboard). Its link is the address itself, so a visitor without the script can still copy it from the link.
CopyLink::name()
public function name(): stringCopyLink::icon()
public function icon(): stringCopyLink::uses()
public function uses(): arrayCopyLink::shareUrl()
public function shareUrl(Shareable $shareable): stringCopyLink::action()
public function action(): stringEmail class
final class Email extends AbstractNetwork Email.php:8
An e-mail from the visitor's own mail client: the title as its subject, the text (when there is one) and the address as its body.
Email::name()
public function name(): stringEmail::icon()
public function icon(): stringEmail::uses()
public function uses(): arrayEmail::shareUrl()
public function shareUrl(Shareable $shareable): stringFacebook class
final class Facebook extends AbstractNetwork Facebook.php:8
Facebook's sharer: the address alone; Facebook reads the title and the picture from the page's og:* tags.
Facebook::name()
public function name(): stringFacebook::color()
public function color(): stringFacebook::uses()
public function uses(): arrayFacebook::shareUrl()
public function shareUrl(Shareable $shareable): stringLinkedIn class
final class LinkedIn extends AbstractNetwork LinkedIn.php:8
LinkedIn's share-offsite: the address alone (it no longer takes a title nor a summary); LinkedIn reads the page's og:* tags.
LinkedIn::name()
public function name(): stringLinkedIn::color()
public function color(): stringLinkedIn::uses()
public function uses(): arrayLinkedIn::shareUrl()
public function shareUrl(Shareable $shareable): stringMastodon class
final class Mastodon extends AbstractNetwork Mastodon.php:14
Mastodon's share page, on one instance: one text, the message, the hashtags and the address. Mastodon has no central site: the instance is configured, or - when none is - the visitor gives theirs (the share script asks it on a click, action "instance"; without the script the link goes to mastodon.social).
Mastodon::__construct()
public function __construct(?string $instance = null)$instancea host ("mastodon.social", "piaille.fr"), or an address whose host is taken
Mastodon::name()
public function name(): stringMastodon::color()
public function color(): stringMastodon::uses()
public function uses(): arrayMastodon::instance()
public function instance(): ?stringThe instance configured, null when the visitor gives theirs.
Mastodon::shareUrl()
public function shareUrl(Shareable $shareable): stringMastodon::action()
public function action(): ?stringNative class
final class Native extends AbstractNetwork Native.php:12
The device's own share sheet (navigator.share: the title, the text and the address; the share script, action "share"), hidden where the browser has none. Its link is the page's address.
Native::name()
public function name(): stringNative::icon()
public function icon(): stringNative::uses()
public function uses(): arrayNative::shareUrl()
public function shareUrl(Shareable $shareable): stringNative::action()
public function action(): stringPinterest class
final class Pinterest extends AbstractNetwork Pinterest.php:8
Pinterest's pin: the address, the picture pinned and its description; without a picture Pinterest offers the page's own.
Pinterest::name()
public function name(): stringPinterest::color()
public function color(): stringPinterest::uses()
public function uses(): arrayPinterest::shareUrl()
public function shareUrl(Shareable $shareable): stringReddit class
final class Reddit extends AbstractNetwork Reddit.php:8
Reddit's submit page: a link post, its address and its title; the visitor picks the community.
Reddit::name()
public function name(): stringReddit::color()
public function color(): stringReddit::uses()
public function uses(): arrayReddit::shareUrl()
public function shareUrl(Shareable $shareable): stringTelegram class
final class Telegram extends AbstractNetwork Telegram.php:8
Telegram's share page: the address and the message apart; the visitor picks the chat.
Telegram::name()
public function name(): stringTelegram::color()
public function color(): stringTelegram::uses()
public function uses(): arrayTelegram::shareUrl()
public function shareUrl(Shareable $shareable): stringThreads class
final class Threads extends AbstractNetwork Threads.php:8
Threads' post intent: the message (with the hashtags) and the address apart, which Threads shows as the link's card.
Threads::name()
public function name(): stringThreads::color()
public function color(): stringThreads::uses()
public function uses(): arrayThreads::shareUrl()
public function shareUrl(Shareable $shareable): stringWhatsApp class
final class WhatsApp extends AbstractNetwork WhatsApp.php:8
WhatsApp's click-to-chat: one text, the message and the address; the visitor picks the chat.
WhatsApp::name()
public function name(): stringWhatsApp::color()
public function color(): stringWhatsApp::uses()
public function uses(): arrayWhatsApp::shareUrl()
public function shareUrl(Shareable $shareable): stringX class
final class X extends AbstractNetwork X.php:11
X's (Twitter's) post intent: the address, the message, the hashtags and the account to credit. twitter.com's intent, which x.com serves the same.
X::name()
public function name(): stringX::color()
public function color(): stringX::uses()
public function uses(): arrayX::shareUrl()
public function shareUrl(Shareable $shareable): string