Aller au contenu

omnibase/social Référence de l’API

Étage
Structure préparée · Omnibase
Version
main
Vérifié en réel
Son README ne le dit pas
Licence
MIT
composer require omnibase/social:dev-main

Lue dans les fichiers PHP du paquet au commit 65254200acc7 : 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é.

Base\Social

  • SocialBundle class

    Social publishing on top of glitchr/omnipost: a reel rendered from the site's own template (ffmpeg), sent to each network with its variant, and the account's feed kept for a wall on the site.

    3 methods

Base\Social\Admin\Widget

  • SocialWidgetType class

    The dashboard's tile: per network, the last post that left and what became of it, when the feed was last read, and a word when the token dies soon.

    4 methods

Base\Social\Command

  • RefreshTokensCommand class

    A fresh token for every account whose token dies within ten days (Instagram's lives sixty, and is refreshed only while alive): the account stays connected without anyone thinking of it. Suggested cron: daily.

    1 method

  • SyncCommand class

    Reads the accounts' last posts for the wall (all the providers that have a feed, or one). Suggested cron: hourly.

    1 method

Base\Social\Controller\Admin

  • AccountsController class

    The accounts on the networks, in the back office (Social): per provider the account connected - its name, its picture, its followers -, when its token dies, and the buttons: connect (the network's consent page, then back at /connect/social/{provider}), refresh the token, read the feed now, disconnect. A reading key (YouTube's) is typed here too.

    8 methods

Base\Social\Controller\Admin\Crud

  • SocialMediaCrudController class

    The account's posts as the last sync read them: what the wall shows.

    6 methods

  • SocialPostCrudController class

    Writing a post for the networks: the film as shot (or a picture), the caption and its hashtags, a title for the networks that want one, the template, the hour; below, each network it goes to and what it says there. Then: render (the reels made, to look at in the preview), publish (checked first against what each network takes), retry a network that failed.

    12 methods

  • TemplateCrudController class

    The site's identity on a reel: the logo and its corner, the band and its name, the colours, the font, the clips before and after, how a film that is not upright is fitted. One is the site's (default); another may be a network's alone.

    6 methods

Base\Social\Controller\Client

  • MediaController class

    A rendered film (or its cover) at the public address the network fetches it from (Service\MediaUrls): the signature must name this target and this file, and the publication must be on its way - or have ended less than social.media_url_ttl seconds ago. Ranges are answered (BinaryFileResponse), as the networks' fetchers ask for them.

    2 methods

Base\Social\DependencyInjection

Base\Social\Entity

  • SocialMedia class

    One of the account's own posts, as the network listed it at the last sync: what the wall of the site shows. The thumbnail is a local copy - the networks' own addresses expire within days -, the film stays where it is (videoUrl, played muted on hover while it still answers).

    33 methods

  • SocialPost class

    What goes out: a film (or a picture), a caption, its hashtags, a title for the networks that want one - and, per network, a target that may say it otherwise. The film is rendered once per target from the template (the target's, the post's, the network's, the site's), then handed over.

    42 methods

  • SocialPostTarget class

    A post on one network: whether it goes there, what it says there when it is not what the post says (a shorter caption, a title, other hashtags, a template of its own), the network's extras (share_to_feed, privacy), then what the pipeline wrote - the rendered file and its measures, the network's id, the permalink, the error.

    45 methods

  • Template class

    The site's identity on a reel: its logo in a corner, a band across the lower third with a name on it, its colours, its font, a clip before and a clip after. One template is the site's (default); another may be kept for one network alone (platform), and a post or one of its networks may name its own.

    40 methods

Base\Social\Enum

  • Fit enum

    What becomes of a source that is not 9:16: cropped to fill the frame, or whole between two bands of the background.

    2 cases

  • LogoPosition enum

    Where the logo sits on the reel. A string enum, so the column reads plainly.

    1 method · 5 cases

  • PostState enum

    Where a post is, all its networks together.

    6 cases

  • TargetState enum

    Where a post is on one network: waiting, rendered, handed over, being processed there, online, or refused.

    2 methods · 6 cases

Base\Social\Exception

  • RenderingException class

    ffmpeg is missing, or refused the film: the message says which.

    2 methods

Base\Social\Form

  • TargetType class

    One network of a post in the back office: whether it goes there, and what it says there when not what the post says - left empty, the post's caption, title, hashtags and template stand. The network's extras below.

    3 methods

Base\Social\Message

  • CheckTargetMessage class

    A publication the network is still processing: its status to read again.

    1 method · 1 property

  • PublishTargetMessage class

    A rendered post to hand to one network.

    1 method · 1 property

  • RenderPostMessage class

    A post to render for each of its networks - and, when $publish says so, to send once rendered.

    1 method · 2 properties

Base\Social\MessageHandler

  • CheckTargetHandler class

    Reads a publication's status again, and again later while it is processing (Service\Publisher::check()).

    2 methods

  • PublishTargetHandler class

    Hands a rendered post to one network (Service\Publisher::publish()).

    2 methods

  • RenderPostHandler class

    Renders a post for each of its networks (Service\Publisher::render()).

    2 methods

Base\Social\Model

  • Rendering class

    What the renderer made: the film, its cover, and what ffprobe measured.

    1 method · 6 properties

Base\Social\Repository

Base\Social\Service

  • Accounts class

    The site's accounts on the networks, kept in omnibase's settings the way the back office's API keys are (api.*, in the vault):

    14 methods

  • FeedSync class

    The account's last posts read and kept (Entity\SocialMedia), for the wall: new ones added, known ones updated (caption, likes, the networks' fresh addresses), the thumbnail copied once into the storage.

    2 methods

  • MediaToken class

    The signature of a rendered file's public address: an HMAC of the target's id and the file's path with the kernel's secret. Nobody guesses it, it names one file, and a file rendered again gets another.

    3 methods · 1 constant

  • MediaUrls class

    The public address of a rendered file, for the network to fetch it: Instagram does not take an upload, it comes for the film at an address it is given. Signed (MediaToken), it opens on that one file only, and only while the publication is on its way (Controller\Client\MediaController).

    3 methods

  • Publisher class

    The pipeline, the handlers only call it: a post rendered for each of its networks, each rendering checked against what the network takes, handed over, then its status read again until the network says it is online - or why it is not.

    8 methods

  • Renderer class

    The reel made from the source film and the site's template, with ffmpeg: the source brought to 1080 x 1920 (cropped, or whole on the background), the logo laid in its corner, the band drawn across the lower third with its text, the film faded in and out, the intro before and the outro after, the sound kept. One H.264/AAC file per network, as they all take it, and a still for its cover.

    9 methods · 7 constants

Base\Social\Twig

  • SocialExtension class

    What a host's own pages ask: the wall of the account's last posts, any public post embedded (an Instagram post, a YouTube film), whether an account is connected.

    5 methods

Base\Social

SocialBundle class

class SocialBundle extends AbstractBaseBundle SocialBundle.php:14

Social publishing on top of glitchr/omnipost: a reel rendered from the site's own template (ffmpeg), sent to each network with its variant, and the account's feed kept for a wall on the site.

SocialBundle::__construct()

public function __construct()

SocialBundle::getPath()

public function getPath(): string

Modern layout: the class lives in src/, the bundle root is the package root.

SocialBundle::build()

public function build(ContainerBuilder $container): void

Base\Social\Admin\Widget

SocialWidgetType class

final class SocialWidgetType implements DashboardWidgetTypeInterface SocialWidgetType.php:18

The dashboard's tile: per network, the last post that left and what became of it, when the feed was last read, and a word when the token dies soon.

yield MenuItem::block('social_overview', ...) in the dashboard's configureWidgetItems() places it.

SocialWidgetType::__construct()

public function __construct(readonly Accounts $accounts, readonly SocialPostTargetRepository $targets, readonly SocialMediaRepository $media)

SocialWidgetType::getName()

public static function getName(): string

SocialWidgetType::getTemplate()

public function getTemplate(): string

SocialWidgetType::getTemplateVars()

public function getTemplateVars(MenuItem $widget): array

Base\Social\Command

RefreshTokensCommand class

class RefreshTokensCommand extends Command RefreshTokensCommand.php:21

A fresh token for every account whose token dies within ten days (Instagram's lives sixty, and is refreshed only while alive): the account stays connected without anyone thinking of it. Suggested cron: daily.

RefreshTokensCommand::__construct()

public function __construct(readonly Accounts $accounts)

SyncCommand class

class SyncCommand extends Command SyncCommand.php:21

Reads the accounts' last posts for the wall (all the providers that have a feed, or one). Suggested cron: hourly.

SyncCommand::__construct()

public function __construct(readonly Accounts $accounts, readonly FeedSync $sync)

Base\Social\Controller\Admin

AccountsController class

class AccountsController extends AbstractController AccountsController.php:31

The accounts on the networks, in the back office (Social): per provider the account connected - its name, its picture, its followers -, when its token dies, and the buttons: connect (the network's consent page, then back at /connect/social/{provider}), refresh the token, read the feed now, disconnect. A reading key (YouTube's) is typed here too.

AccountsController::__construct()

public function __construct(readonly Accounts $accounts, readonly FeedSync $sync, readonly SocialMediaRepository $media, readonly AdminContext $adminContext, readonly MenuBuilder $menuBuilder)

AccountsController::index()

public function index(): Response

AccountsController::connect()

public function connect(Request $request, string $provider): Response

AccountsController::callback()

public function callback(Request $request, string $provider, ?string $code = null, ?string $state = null, ?string $error = null): Response

Where the network sends the administrator back: the code exchanged, the token kept (Service\Accounts).

AccountsController::refresh()

public function refresh(Request $request, string $provider): Response

AccountsController::sync()

public function sync(Request $request, string $provider): Response

AccountsController::disconnect()

public function disconnect(Request $request, string $provider): Response

AccountsController::key()

public function key(Request $request, string $provider): Response

A reading key (YouTube's Data API key): kept in the settings, in the vault. Empty: the configuration's again.

Base\Social\Controller\Admin\Crud

SocialMediaCrudController class

class SocialMediaCrudController extends AbstractCrudController SocialMediaCrudController.php:25

The account's posts as the last sync read them: what the wall shows.

Nothing to write here - the network is the source -, only a post to keep off the wall, or to put back.

SocialMediaCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

SocialMediaCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

SocialMediaCrudController::configureFilters()

public function configureFilters(Filters $filters): Filters

SocialMediaCrudController::configureFields()

public function configureFields(string $pageName): iterable

SocialMediaCrudController::configureActions()

public function configureActions(Actions $actions): Actions

SocialMediaCrudController::visibility()

public function visibility(string $entityId): Response

SocialPostCrudController class

class SocialPostCrudController extends AbstractCrudController SocialPostCrudController.php:48

Writing a post for the networks: the film as shot (or a picture), the caption and its hashtags, a title for the networks that want one, the template, the hour; below, each network it goes to and what it says there. Then: render (the reels made, to look at in the preview), publish (checked first against what each network takes), retry a network that failed.

SocialPostCrudController::setSocialServices()

public function setSocialServices(MessageBusInterface $bus, Publisher $publisher, Accounts $accounts): void

SocialPostCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

SocialPostCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

SocialPostCrudController::configureFilters()

public function configureFilters(Filters $filters): Filters

SocialPostCrudController::configureFields()

public function configureFields(string $pageName): iterable

SocialPostCrudController::configureActions()

public function configureActions(Actions $actions): Actions

SocialPostCrudController::createEntity()

public function createEntity(string $entityFqcn): object

A post written gets the site's networks, each enabled: the author takes away what it does not go to.

SocialPostCrudController::renderReel()

public function renderReel(string $entityId): Response

The reels made again (Messenger: the worker renders), to be looked at before they leave.

SocialPostCrudController::publish()

public function publish(string $entityId): Response

Sent to every enabled network - after each was checked against what the network takes: one refusal and nothing leaves, the reasons shown.

Rendered first when it is not yet.

SocialPostCrudController::retry()

public function retry(string $entityId, int $target): Response

One network sent again - its film rendered again first if it is gone.

SocialPostCrudController::preview()

public function preview(string $entityId): Response

Each network: its reel, its cover, what the network would refuse, where it is.

SocialPostCrudController::reel()

public function reel(string $entityId, int $target, string $what): Response

The rendered film or its cover, for the preview: the back office's own way to it, open whatever the state.

TemplateCrudController class

class TemplateCrudController extends AbstractCrudController TemplateCrudController.php:31

The site's identity on a reel: the logo and its corner, the band and its name, the colours, the font, the clips before and after, how a film that is not upright is fitted. One is the site's (default); another may be a network's alone.

TemplateCrudController::setSocialServices()

public function setSocialServices(Accounts $accounts, TranslatorInterface $translator): void

TemplateCrudController::getEntityFqcn()

public static function getEntityFqcn(): string

TemplateCrudController::getPreferredIcon()

public static function getPreferredIcon(): ?string

TemplateCrudController::configureFields()

public function configureFields(string $pageName): iterable

TemplateCrudController::persistEntity()

public function persistEntity(EntityManagerInterface $entityManager, object $entity): void

One site's template: the one saved as such takes the place of the others.

TemplateCrudController::updateEntity()

public function updateEntity(EntityManagerInterface $entityManager, object $entity): void

Base\Social\Controller\Client

MediaController class

class MediaController extends AbstractController MediaController.php:20

A rendered film (or its cover) at the public address the network fetches it from (Service\MediaUrls): the signature must name this target and this file, and the publication must be on its way - or have ended less than social.media_url_ttl seconds ago. Ranges are answered (BinaryFileResponse), as the networks' fetchers ask for them.

MediaController::__construct()

public function __construct(readonly SocialPostTargetRepository $targets, readonly MediaToken $tokens, readonly int $ttl = 86400)

MediaController::media()

public function media(int $target, string $token, string $ext): BinaryFileResponse

Base\Social\DependencyInjection

SocialConfiguration class

class SocialConfiguration extends AbstractBaseConfiguration SocialConfiguration.php:8

SocialConfiguration::getConfigTreeBuilder()

public function getConfigTreeBuilder(): TreeBuilder

SocialExtension class

class SocialExtension extends AbstractBaseExtension SocialExtension.php:11

SocialExtension::getConfiguration()

public function getConfiguration(array $config, ContainerBuilder $container): SocialConfiguration

SocialExtension::load()

public function load(array $configs, ContainerBuilder $container): void

Base\Social\Entity

SocialMedia class

class SocialMedia SocialMedia.php:18

One of the account's own posts, as the network listed it at the last sync: what the wall of the site shows. The thumbnail is a local copy - the networks' own addresses expire within days -, the film stays where it is (videoUrl, played muted on hover while it still answers).

SocialMedia::__iconizeStatic()

public static function __iconizeStatic(): ?array

SocialMedia::__construct()

public function __construct(?string $provider = null, ?string $remoteId = null)

SocialMedia::__toString()

public function __toString(): string

SocialMedia::getId()

public function getId(): ?int

SocialMedia::getProvider()

public function getProvider(): ?string

SocialMedia::getProviderLabel()

public function getProviderLabel(): string

SocialMedia::getRemoteId()

public function getRemoteId(): ?string

SocialMedia::getKind()

public function getKind(): string

SocialMedia::setKind()

public function setKind(PostKind|string $kind): self

SocialMedia::isVideo()

public function isVideo(): bool
public function getPermalink(): ?string
public function setPermalink(?string $permalink): self

SocialMedia::getCaption()

public function getCaption(): ?string

SocialMedia::setCaption()

public function setCaption(?string $caption): self

SocialMedia::getPublishedAt()

public function getPublishedAt(): ?\DateTimeInterface

SocialMedia::setPublishedAt()

public function setPublishedAt(?\DateTimeInterface $at): self

SocialMedia::getThumbnail()

public function getThumbnail(): ?string

SocialMedia::getThumbnailFile()

public function getThumbnailFile(): ?File

SocialMedia::setThumbnail()

public function setThumbnail($thumbnail): self

SocialMedia::hasThumbnail()

public function hasThumbnail(): bool

SocialMedia::getMediaUrl()

public function getMediaUrl(): ?string

SocialMedia::setMediaUrl()

public function setMediaUrl(?string $url): self

SocialMedia::getVideoUrl()

public function getVideoUrl(): ?string

SocialMedia::setVideoUrl()

public function setVideoUrl(?string $url): self

SocialMedia::getLikes()

public function getLikes(): ?int

SocialMedia::setLikes()

public function setLikes(?int $likes): self

SocialMedia::getComments()

public function getComments(): ?int

SocialMedia::setComments()

public function setComments(?int $comments): self

SocialMedia::isHidden()

public function isHidden(): bool

SocialMedia::getHidden()

public function getHidden(): bool

SocialMedia::setHidden()

public function setHidden(bool $hidden): self

SocialMedia::getFetchedAt()

public function getFetchedAt(): ?\DateTimeInterface

SocialMedia::touch()

public function touch(): self

SocialPost class

class SocialPost SocialPost.php:25

What goes out: a film (or a picture), a caption, its hashtags, a title for the networks that want one - and, per network, a target that may say it otherwise. The film is rendered once per target from the template (the target's, the post's, the network's, the site's), then handed over.

SocialPost::__iconizeStatic()

public static function __iconizeStatic(): ?array

SocialPost::__construct()

public function __construct()

SocialPost::__toString()

public function __toString(): string

SocialPost::getId()

public function getId(): ?int

SocialPost::getVideo()

public function getVideo(): ?string

SocialPost::getVideoFile()

public function getVideoFile(): ?File

SocialPost::setVideo()

public function setVideo($video): self

SocialPost::getImage()

public function getImage(): ?string

SocialPost::getImageFile()

public function getImageFile(): ?File

SocialPost::setImage()

public function setImage($image): self

SocialPost::getKind()

public function getKind(): string

SocialPost::getPostKind()

public function getPostKind(): PostKind

SocialPost::setKind()

public function setKind(PostKind|string|null $kind): self

SocialPost::isImage()

public function isImage(): bool

A picture goes out as it is: only a film is rendered.

SocialPost::getCaption()

public function getCaption(): ?string

SocialPost::setCaption()

public function setCaption(?string $caption): self

SocialPost::getTitle()

public function getTitle(): ?string

SocialPost::setTitle()

public function setTitle(?string $title): self

SocialPost::getTags()

public function getTags(): array

SocialPost::setTags()

public function setTags(?array $tags): self

SocialPost::getTemplate()

public function getTemplate(): ?Template

SocialPost::setTemplate()

public function setTemplate(?Template $template): self

SocialPost::isUseTemplate()

public function isUseTemplate(): bool

SocialPost::getUseTemplate()

public function getUseTemplate(): bool

SocialPost::setUseTemplate()

public function setUseTemplate(bool $use): self

SocialPost::getCoverSecond()

public function getCoverSecond(): float

SocialPost::setCoverSecond()

public function setCoverSecond(?float $second): self

SocialPost::getScheduledAt()

public function getScheduledAt(): ?\DateTimeInterface

SocialPost::setScheduledAt()

public function setScheduledAt(?\DateTimeInterface $at): self
public function getLink(): ?string
public function setLink(?string $link): self

SocialPost::getCreatedAt()

public function getCreatedAt(): ?\DateTimeInterface

SocialPost::getState()

public function getState(): PostState

SocialPost::setState()

public function setState(PostState $state): self

SocialPost::getTargets()

public function getTargets(): Collection

SocialPost::addTarget()

public function addTarget(SocialPostTarget $target): self

SocialPost::removeTarget()

public function removeTarget(SocialPostTarget $target): self

SocialPost::getEnabledTargets()

public function getEnabledTargets(): array
Returns

the networks it goes to

SocialPost::getTarget()

public function getTarget(Platform|string $platform): ?SocialPostTarget

SocialPost::refreshState()

public function refreshState(): self

The post's state, read from its networks': one still on its way keeps it PUBLISHING, all online make it DONE, one refused (and none on its way) FAILED, all rendered READY.

SocialPost::toPost()

public function toPost(?callable $urls = null): Post

The canonical Omnipost post and, per enabled network, its variant: the target's own caption, title and hashtags where it has them, its own rendering of the film always. The networks fetch the media themselves, so $urls gives each target's public address - Service\MediaUrls::for(), signed and short-lived - fn (SocialPostTarget $target, bool $cover): string; without it the local path stands in (enough to validate, not to publish).

The hour (scheduledAt) is not passed on: the site keeps it itself, by holding the message back until then.

SocialPost::cleanTags()

public static function cleanTags(array $tags): array

Hashtags as they are kept: no '#', no blank, no double.

SocialPostTarget class

class SocialPostTarget SocialPostTarget.php:22

A post on one network: whether it goes there, what it says there when it is not what the post says (a shorter caption, a title, other hashtags, a template of its own), the network's extras (share_to_feed, privacy), then what the pipeline wrote - the rendered file and its measures, the network's id, the permalink, the error.

SocialPostTarget::__construct()

public function __construct(Platform|string|null $platform = null)

SocialPostTarget::__toString()

public function __toString(): string

SocialPostTarget::getId()

public function getId(): ?int

SocialPostTarget::getPost()

public function getPost(): ?SocialPost

SocialPostTarget::setPost()

public function setPost(?SocialPost $post): self

SocialPostTarget::getPlatform()

public function getPlatform(): ?string

SocialPostTarget::setPlatform()

public function setPlatform(Platform|string|null $platform): self

SocialPostTarget::getPlatformLabel()

public function getPlatformLabel(): string

SocialPostTarget::isEnabled()

public function isEnabled(): bool

SocialPostTarget::getEnabled()

public function getEnabled(): bool

SocialPostTarget::setEnabled()

public function setEnabled(bool $enabled): self

SocialPostTarget::getCaption()

public function getCaption(): ?string

SocialPostTarget::setCaption()

public function setCaption(?string $caption): self

SocialPostTarget::getTitle()

public function getTitle(): ?string

SocialPostTarget::setTitle()

public function setTitle(?string $title): self

SocialPostTarget::getTags()

public function getTags(): ?array

SocialPostTarget::setTags()

public function setTags(?array $tags): self

SocialPostTarget::getTemplate()

public function getTemplate(): ?Template

SocialPostTarget::setTemplate()

public function setTemplate(?Template $template): self

SocialPostTarget::getOptions()

public function getOptions(): array

SocialPostTarget::setOptions()

public function setOptions(?array $options): self

SocialPostTarget::getRenderedPath()

public function getRenderedPath(): ?string

SocialPostTarget::getCoverPath()

public function getCoverPath(): ?string

SocialPostTarget::getDuration()

public function getDuration(): ?float

SocialPostTarget::getWidth()

public function getWidth(): ?int

SocialPostTarget::getHeight()

public function getHeight(): ?int

SocialPostTarget::getSize()

public function getSize(): ?int

SocialPostTarget::rendered()

public function rendered(Rendering $rendering): self

What the renderer made, written down; the target is RENDERED.

SocialPostTarget::hasRendering()

public function hasRendering(): bool

SocialPostTarget::getPublicationId()

public function getPublicationId(): ?string

SocialPostTarget::setPublicationId()

public function setPublicationId(?string $id): self
public function getPermalink(): ?string
public function setPermalink(?string $permalink): self

SocialPostTarget::getState()

public function getState(): TargetState

SocialPostTarget::setState()

public function setState(TargetState $state): self

SocialPostTarget::getError()

public function getError(): ?string

SocialPostTarget::fail()

public function fail(string $error): self

SocialPostTarget::getAttempts()

public function getAttempts(): int

SocialPostTarget::attempt()

public function attempt(): int

SocialPostTarget::resetAttempts()

public function resetAttempts(): self

SocialPostTarget::getPublishedAt()

public function getPublishedAt(): ?\DateTimeInterface

SocialPostTarget::setPublishedAt()

public function setPublishedAt(?\DateTimeInterface $at): self

SocialPostTarget::getUpdatedAt()

public function getUpdatedAt(): ?\DateTimeInterface

SocialPostTarget::isMediaOpen()

public function isMediaOpen(int $ttl = 86400, ?\DateTimeInterface $now = null): bool

Whether the public address of its file answers: while the publication is on its way, and $ttl seconds after it ended - a network may come back for the file a little later, a stranger should not find it for long.

SocialPostTarget::toMedia()

public function toMedia(PostKind $kind, ?callable $urls = null): ?Media

The rendered file as Omnipost wants it: its public address from $urls (fn (SocialPostTarget $target, bool $cover): string), the local path for the providers that upload and for the Validator to measure.

Template class

class Template Template.php:21

The site's identity on a reel: its logo in a corner, a band across the lower third with a name on it, its colours, its font, a clip before and a clip after. One template is the site's (default); another may be kept for one network alone (platform), and a post or one of its networks may name its own.

Template::__iconizeStatic()

public static function __iconizeStatic(): ?array

Template::__toString()

public function __toString(): string

Template::getId()

public function getId(): ?int

Template::getName()

public function getName(): ?string

Template::setName()

public function setName(?string $name): self

Template::isDefault()

public function isDefault(): bool

Template::setDefault()

public function setDefault(bool $default): self

Template::getPlatform()

public function getPlatform(): ?string

Template::setPlatform()

public function setPlatform(Platform|string|null $platform): self
public function getLogo(): ?string

Template::getLogoFile()

public function getLogoFile(): ?File
public function setLogo($logo): self

Template::getLogoPosition()

public function getLogoPosition(): LogoPosition

Template::setLogoPosition()

public function setLogoPosition(LogoPosition $position): self

Template::getLogoScale()

public function getLogoScale(): float

Template::setLogoScale()

public function setLogoScale(float $scale): self

Template::hasBand()

public function hasBand(): bool

Template::getBand()

public function getBand(): bool

Template::setBand()

public function setBand(bool $band): self

Template::getBandText()

public function getBandText(): ?string

Template::setBandText()

public function setBandText(?string $text): self

Template::getBandColor()

public function getBandColor(): string

Template::setBandColor()

public function setBandColor(?string $color): self

Template::getTextColor()

public function getTextColor(): string

Template::setTextColor()

public function setTextColor(?string $color): self

Template::getFont()

public function getFont(): ?string

Template::getFontFile()

public function getFontFile(): ?File

Template::setFont()

public function setFont($font): self

Template::getBackground()

public function getBackground(): string

Template::setBackground()

public function setBackground(?string $color): self

Template::getIntro()

public function getIntro(): ?string

Template::getIntroFile()

public function getIntroFile(): ?File

Template::setIntro()

public function setIntro($intro): self

Template::getOutro()

public function getOutro(): ?string

Template::getOutroFile()

public function getOutroFile(): ?File

Template::setOutro()

public function setOutro($outro): self

Template::getFit()

public function getFit(): Fit

Template::setFit()

public function setFit(Fit $fit): self

Template::getFadeSeconds()

public function getFadeSeconds(): float

Template::setFadeSeconds()

public function setFadeSeconds(float $seconds): self

Base\Social\Enum

Fit enum

enum Fit Fit.php:6

What becomes of a source that is not 9:16: cropped to fill the frame, or whole between two bands of the background.

case COVER = 'cover'
case CONTAIN = 'contain'

LogoPosition enum

enum LogoPosition LogoPosition.php:6

Where the logo sits on the reel. A string enum, so the column reads plainly.

case TOP_LEFT = 'top_left'
case TOP_RIGHT = 'top_right'
case BOTTOM_LEFT = 'bottom_left'
case BOTTOM_RIGHT = 'bottom_right'
case CENTER = 'center'

LogoPosition::overlay()

public function overlay(int $margin): string

The overlay's x:y for ffmpeg (W, H: the frame; w, h: the logo), $margin pixels from the edges.

PostState enum

enum PostState PostState.php:6

Where a post is, all its networks together.

case DRAFT = 'draft'
case RENDERING = 'rendering'
case READY = 'ready'
case PUBLISHING = 'publishing'
case DONE = 'done'
case FAILED = 'failed'

TargetState enum

enum TargetState TargetState.php:9

Where a post is on one network: waiting, rendered, handed over, being processed there, online, or refused.

case PENDING = 'pending'
case RENDERED = 'rendered'
case SENT = 'sent'
case PROCESSING = 'processing'
case PUBLISHED = 'published'
case FAILED = 'failed'

TargetState::isFinal()

public function isFinal(): bool

TargetState::isInFlight()

public function isInFlight(): bool

Handed to the network and not settled yet: its status is still to be read.

Base\Social\Exception

RenderingException class

final class RenderingException extends RuntimeException RenderingException.php:6

ffmpeg is missing, or refused the film: the message says which.

RenderingException::missing()

public static function missing(string $binary): self

RenderingException::failed()

public static function failed(string $what, string $output): self

Base\Social\Form

TargetType class

class TargetType extends AbstractType TargetType.php:29

One network of a post in the back office: whether it goes there, and what it says there when not what the post says - left empty, the post's caption, title, hashtags and template stand. The network's extras below.

The texts name their domain (@social.…): base-bundle gives every field the "fields" domain, which the form's own translation_domain does not reach.

TargetType::__construct()

public function __construct(readonly array $providers = ['instagram'])

TargetType::buildForm()

public function buildForm(FormBuilderInterface $builder, array $options): void

TargetType::configureOptions()

public function configureOptions(OptionsResolver $resolver): void

Base\Social\Message

CheckTargetMessage class

final class CheckTargetMessage CheckTargetMessage.php:6

A publication the network is still processing: its status to read again.

public readonly int $targetId

CheckTargetMessage::__construct()

public function __construct(public readonly int $targetId)

PublishTargetMessage class

final class PublishTargetMessage PublishTargetMessage.php:6

A rendered post to hand to one network.

public readonly int $targetId

PublishTargetMessage::__construct()

public function __construct(public readonly int $targetId)

RenderPostMessage class

final class RenderPostMessage RenderPostMessage.php:6

A post to render for each of its networks - and, when $publish says so, to send once rendered.

public readonly int $postId
public readonly bool $publish

RenderPostMessage::__construct()

public function __construct(public readonly int $postId, public readonly bool $publish = false)

Base\Social\MessageHandler

CheckTargetHandler class

final class CheckTargetHandler CheckTargetHandler.php:11

Reads a publication's status again, and again later while it is processing (Service\Publisher::check()).

CheckTargetHandler::__construct()

public function __construct(readonly SocialPostTargetRepository $targets, readonly Publisher $publisher)

CheckTargetHandler::__invoke()

public function __invoke(CheckTargetMessage $message): void

PublishTargetHandler class

final class PublishTargetHandler PublishTargetHandler.php:11

Hands a rendered post to one network (Service\Publisher::publish()).

PublishTargetHandler::__construct()

public function __construct(readonly SocialPostTargetRepository $targets, readonly Publisher $publisher)

PublishTargetHandler::__invoke()

public function __invoke(PublishTargetMessage $message): void

RenderPostHandler class

final class RenderPostHandler RenderPostHandler.php:11

Renders a post for each of its networks (Service\Publisher::render()).

RenderPostHandler::__construct()

public function __construct(readonly SocialPostRepository $posts, readonly Publisher $publisher)

RenderPostHandler::__invoke()

public function __invoke(RenderPostMessage $message): void

Base\Social\Model

Rendering class

final class Rendering Rendering.php:6

What the renderer made: the film, its cover, and what ffprobe measured.

public readonly string $path
public readonly ?string $coverPath
public readonly float $duration

seconds

public readonly int $width
public readonly int $height
public readonly int $size

bytes

Rendering::__construct()

public function __construct(public readonly string $path, public readonly ?string $coverPath, public readonly float $duration, public readonly int $width, public readonly int $height, public readonly int $size)

Base\Social\Repository

SocialMediaRepository class

class SocialMediaRepository extends ServiceEntityRepository SocialMediaRepository.php:10

SocialMediaRepository::__construct()

public function __construct(ManagerRegistry $registry)

SocialMediaRepository::findWall()

public function findWall(int $limit = 12, ?string $provider = null): array

The wall: the account's last posts, the hidden ones left out - of one provider, or of all.

SocialMediaRepository::findOneRemote()

public function findOneRemote(string $provider, string $remoteId): ?SocialMedia

SocialMediaRepository::lastSync()

public function lastSync(string $provider): ?\DateTimeInterface

When the provider's feed was last read; null: never.

SocialMediaRepository::countFor()

public function countFor(string $provider): int

SocialPostRepository class

class SocialPostRepository extends ServiceEntityRepository SocialPostRepository.php:10

SocialPostRepository::__construct()

public function __construct(ManagerRegistry $registry)

SocialPostTargetRepository class

class SocialPostTargetRepository extends ServiceEntityRepository SocialPostTargetRepository.php:10

SocialPostTargetRepository::__construct()

public function __construct(ManagerRegistry $registry)

SocialPostTargetRepository::findLastFor()

public function findLastFor(string $platform): ?SocialPostTarget

The last target that left for a network, whatever became of it: the dashboard's line.

TemplateRepository class

class TemplateRepository extends ServiceEntityRepository TemplateRepository.php:11

TemplateRepository::__construct()

public function __construct(ManagerRegistry $registry)

TemplateRepository::findDefault()

public function findDefault(): ?Template

The site's own template, if it has one.

TemplateRepository::findForPlatform()

public function findForPlatform(string $platform): ?Template

The template kept for one network alone.

TemplateRepository::resolve()

public function resolve(SocialPostTarget $target): ?Template

The template a target is rendered with: its own, else its post's, else its network's, else the site's. Null: the post goes out untemplated (it says so, or the site has no template yet).

Base\Social\Service

Accounts class

class Accounts Accounts.php:25

The site's accounts on the networks, kept in omnibase's settings the way the back office's API keys are (api.*, in the vault):

api.social.<provider>.token the token, an Omnipost\Model\Token::toArray() as JSON api.social.<provider>.account who it is: username, picture, followers (JSON) api.social.<provider>.api_key a reading key, for the providers that take one (YouTube)

provider() builds the omnipost provider with them over its configured options (Registry::create()): the configuration holds the app's id and secret, the settings what the artist connected.

Accounts::__construct()

public function __construct(readonly Registry $registry, readonly SettingBagInterface $settings, readonly array $providers = ['instagram'])

Accounts::names()

public function names(): array

The providers the site uses, in order: the configured ones that omnipost declares.

Accounts::has()

public function has(string $name): bool

Accounts::connected()

public function connected(string $name): bool

A token is kept for it (dead or alive), or omnipost's configuration carries one.

Accounts::token()

public function token(string $name): ?Token

Accounts::saveToken()

public function saveToken(string $name, Token $token): Token

Kept; the refresh token and the account's id of the old one survive a new token that lacks them.

Accounts::account()

public function account(string $name): array

Accounts::saveAccount()

public function saveAccount(string $name, Account $account): void

Accounts::apiKey()

public function apiKey(string $name): ?string

Accounts::saveApiKey()

public function saveApiKey(string $name, ?string $key): void

Accounts::disconnect()

public function disconnect(string $name): void

The token and the account forgotten: the back office's "Disconnect".

Accounts::provider()

public function provider(string $name): ProviderInterface

The provider built with what the settings hold. An access token dead with a refresh token at hand is left out: the provider draws a new one from the refresh token (YouTube).

Accounts::overrides()

public function overrides(string $name): array

Accounts::refresh()

public function refresh(string $name): ?Token

A fresh token asked for and kept; null when the provider's tokens do not die.

FeedSync class

class FeedSync FeedSync.php:28

The account's last posts read and kept (Entity\SocialMedia), for the wall: new ones added, known ones updated (caption, likes, the networks' fresh addresses), the thumbnail copied once into the storage.

The copy is downloaded here rather than left to the Uploader's fetch: a picture that does not answer, or answers with something else, costs the row its thumbnail and nothing more - the Uploader would refuse the whole flush.

FeedSync::__construct()

public function __construct(readonly Accounts $accounts, readonly SocialMediaRepository $media, readonly EntityManagerInterface $entityManager, readonly HttpClientInterface $http, readonly LoggerInterface $logger = new NullLogger(), readonly int $limit = 24, readonly bool $cacheThumbnails = true)

FeedSync::sync()

public function sync(string $provider, ?int $limit = null): int
Returns

the posts read

Throws

Omnipost\Exception\OmnipostException the network refused, or the provider has no feed

MediaToken class

final class MediaToken MediaToken.php:12

The signature of a rendered file's public address: an HMAC of the target's id and the file's path with the kernel's secret. Nobody guesses it, it names one file, and a file rendered again gets another.

const LENGTH = 32

MediaToken::__construct()

public function __construct(readonly string $secret)

MediaToken::sign()

public function sign(int $targetId, string $path): string

MediaToken::verify()

public function verify(int $targetId, string $path, string $token): bool

MediaUrls class

final class MediaUrls MediaUrls.php:17

The public address of a rendered file, for the network to fetch it: Instagram does not take an upload, it comes for the film at an address it is given. Signed (MediaToken), it opens on that one file only, and only while the publication is on its way (Controller\Client\MediaController).

Absolute: from a Messenger worker there is no request to take the host from, so framework.router.default_uri must name the site.

MediaUrls::__construct()

public function __construct(readonly UrlGeneratorInterface $urls, readonly MediaToken $tokens)

MediaUrls::for()

public function for(SocialPostTarget $target, bool $cover = false): string

The film's address - or, $cover, its still's.

MediaUrls::callable()

public function callable(): \Closure

As SocialPost::toPost() takes it.

Publisher class

class Publisher Publisher.php:38

The pipeline, the handlers only call it: a post rendered for each of its networks, each rendering checked against what the network takes, handed over, then its status read again until the network says it is online - or why it is not.

Publisher::__construct()

public function __construct(readonly EntityManagerInterface $entityManager, readonly Renderer $renderer, readonly TemplateRepository $templates, readonly Accounts $accounts, readonly MediaUrls $urls, readonly Validator $validator, readonly MessageBusInterface $bus, readonly LoggerInterface $logger = new NullLogger(), readonly int $checkDelay = 30, readonly int $checkAttempts = 20)

Publisher::render()

public function render(SocialPost $post, bool $publish = false): void

Each network's film made with its template (the target's, else the post's, else the network's, else the site's). A rendering that fails fails its network alone. $publish: the rendered ones then handed over - at the post's hour when it has one to come.

Publisher::dispatchPublish()

public function dispatchPublish(SocialPost $post): int

The rendered networks handed over (Messenger), at the post's hour when it is to come.

Publisher::postFor()

public function postFor(SocialPostTarget $target, bool $publicUrls = true): Post

The post as $target's network will receive it - its own rendering, caption, title and hashtags - with the public addresses when the rendering exists, the local paths otherwise.

Publisher::validate()

public function validate(SocialPostTarget $target): array

What the network would refuse, before anything is sent: the post against its capabilities (Omnipost\Validator), and against the provider's own rules when it has some (a reel is 9:16 on Instagram).

A target not rendered yet is checked as it will be: the source's length, the template's frame.

Publisher::publish()

public function publish(SocialPostTarget $target): void

$target handed to its network. Refused by the checks: FAILED with the reasons, nothing sent. Taken: the network's id kept, SENT (or PROCESSING, or at once PUBLISHED), and its status to be read again in check.delay seconds.

Publisher::check()

public function check(SocialPostTarget $target): bool

The publication's status read again. Still processing: read again later, up to check.attempts times - then given up as FAILED.

Returns

whether it is to be read again

Publisher::retry()

public function retry(SocialPostTarget $target): void

A failed network sent again: rendered again first when its film is gone.

Renderer class

class Renderer Renderer.php:27

The reel made from the source film and the site's template, with ffmpeg: the source brought to 1080 x 1920 (cropped, or whole on the background), the logo laid in its corner, the band drawn across the lower third with its text, the film faded in and out, the intro before and the outro after, the sound kept. One H.264/AAC file per network, as they all take it, and a still for its cover.

command() only assembles ffmpeg's arguments - no file is touched -, so the filter graph is read and tested as it is.

const WIDTH = 1080
const HEIGHT = 1920
const MARGIN = 64

Pixels between the logo and the frame's edges.

const BAND_Y = 1380

The band: across the lower third, above what the networks lay over the bottom of a reel.

const BAND_HEIGHT = 140
const FONT_SIZE = 56
const MIN_FONT_SIZE = 28

Renderer::__construct()

public function __construct(readonly string $ffmpeg = 'ffmpeg', readonly string $ffprobe = 'ffprobe', readonly int $crf = 20, readonly int $fps = 30, readonly int $timeout = 900, readonly string $font = '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', readonly string $storage = '/tmp/social')

Renderer::render()

public function render(SocialPost $post, ?Template $template = null, ?Platform $platform = null): Rendering

The post rendered for $platform with $template, under <storage>/<post id>/<platform>.mp4, its cover beside it. Without a template - the post says "as it is", or the site has none - and for a picture, the source itself is measured and given back.

Renderer::command()

public function command(array $input): array

ffmpeg's arguments for one rendering. $input:

source, output paths (required) duration the source's, in seconds: where the fade out starts, how long a silence lasts audio whether the source has sound (true); without, a silence is laid fit Fit::COVER (crop to 9:16) or Fit::CONTAIN (whole, on the background) background "#rrggbb", behind a contained source logo path of a picture, or null; logoPosition (LogoPosition), logoScale (part of the width) band bool; bandText, bandColor, textColor, font (path of a TTF/OTF, or null) fade seconds in and out, 0 for none intro, outro ['path' => ..., 'duration' => ..., 'audio' => bool] or null fps, crf over the configured ones

Renderer::coverCommand()

public function coverCommand(string $path, float $second, string $output): array

ffmpeg's arguments for the cover: one frame of $path at $second.

Renderer::probe()

public function probe(string $path): array

What ffprobe measures of a film or a picture.

Renderer::measures()

public static function measures(array $json, string $path = ''): array

ffprobe's JSON read: the first video stream's size (turned when the film is - a phone's portrait film is stored lying down), the length, the weight, whether there is sound.

Renderer::escape()

public static function escape(string $text): string

A text (or a path) as a filter's option inside -filter_complex: first what the option's own reading takes (\ ' :), then what the graph's takes (\ ' [ ] , ;). drawtext is told expansion=none, so % and the rest stay what they are.

Renderer::fontSize()

public static function fontSize(string $text): int

The band's font size: FONT_SIZE, smaller for a long text so that it holds between the margins (a glyph is about 0.58 of the size wide in a sans), MIN_FONT_SIZE at the least.

Renderer::color()

public static function color(string $hex): string

"#rrggbb" (or "#rrggbbaa") as ffmpeg writes a colour: 0xrrggbb. Anything else: black.

Base\Social\Twig

SocialExtension class

final class SocialExtension extends AbstractExtension SocialExtension.php:16

What a host's own pages ask: the wall of the account's last posts, any public post embedded (an Instagram post, a YouTube film), whether an account is connected.

SocialExtension::__construct()

public function __construct(readonly SocialMediaRepository $media, readonly Accounts $accounts)

SocialExtension::getFunctions()

public function getFunctions(): array

SocialExtension::wall()

public function wall(Environment $twig, int $limit = 12, ?string $provider = null): string

SocialExtension::embed()

public function embed(Environment $twig, string $url, bool $consent = false): string

$consent: loaded at once, the visitor having said yes to the network's cookies already.

SocialExtension::recognize()

public static function recognize(string $url): array

What a public address is: an Instagram post (its permalink, cleaned), a YouTube film (its id), or neither.