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é.
SocialBundleclassSocial 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
SocialWidgetTypeclassThe 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
RefreshTokensCommandclassA 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
SyncCommandclassReads the accounts' last posts for the wall (all the providers that have a feed, or one). Suggested cron: hourly.
1 method
AccountsControllerclassThe 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
SocialMediaCrudControllerclassThe account's posts as the last sync read them: what the wall shows.
6 methods
SocialPostCrudControllerclassWriting 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
TemplateCrudControllerclassThe 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
MediaControllerclassA 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
SocialConfigurationclass1 method
SocialExtensionclass2 methods
SocialMediaclassOne 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
SocialPostclassWhat 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
SocialPostTargetclassA 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
TemplateclassThe 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
FitenumWhat becomes of a source that is not 9:16: cropped to fill the frame, or whole between two bands of the background.
2 cases
LogoPositionenumWhere the logo sits on the reel. A string enum, so the column reads plainly.
1 method · 5 cases
PostStateenumWhere a post is, all its networks together.
6 cases
TargetStateenumWhere a post is on one network: waiting, rendered, handed over, being processed there, online, or refused.
2 methods · 6 cases
RenderingExceptionclassffmpeg is missing, or refused the film: the message says which.
2 methods
TargetTypeclassOne 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
CheckTargetMessageclassA publication the network is still processing: its status to read again.
1 method · 1 property
PublishTargetMessageclassA rendered post to hand to one network.
1 method · 1 property
RenderPostMessageclassA post to render for each of its networks - and, when $publish says so, to send once rendered.
1 method · 2 properties
CheckTargetHandlerclassReads a publication's status again, and again later while it is processing (Service\Publisher::check()).
2 methods
PublishTargetHandlerclassHands a rendered post to one network (Service\Publisher::publish()).
2 methods
RenderPostHandlerclassRenders a post for each of its networks (Service\Publisher::render()).
2 methods
RenderingclassWhat the renderer made: the film, its cover, and what ffprobe measured.
1 method · 6 properties
SocialMediaRepositoryclass5 methods
SocialPostRepositoryclass1 method
SocialPostTargetRepositoryclass2 methods
TemplateRepositoryclass4 methods
AccountsclassThe 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
FeedSyncclassThe 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
MediaTokenclassThe 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
MediaUrlsclassThe 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
PublisherclassThe 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
RendererclassThe 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
SocialExtensionclassWhat 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(): stringModern layout: the class lives in src/, the bundle root is the package root.
SocialBundle::build()
public function build(ContainerBuilder $container): voidBase\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(): stringSocialWidgetType::getTemplate()
public function getTemplate(): stringSocialWidgetType::getTemplateVars()
public function getTemplateVars(MenuItem $widget): arrayBase\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(): ResponseAccountsController::connect()
public function connect(Request $request, string $provider): ResponseAccountsController::callback()
public function callback(Request $request, string $provider, ?string $code = null, ?string $state = null, ?string $error = null): ResponseWhere the network sends the administrator back: the code exchanged, the token kept (Service\Accounts).
AccountsController::refresh()
public function refresh(Request $request, string $provider): ResponseAccountsController::sync()
public function sync(Request $request, string $provider): ResponseAccountsController::disconnect()
public function disconnect(Request $request, string $provider): ResponseAccountsController::key()
public function key(Request $request, string $provider): ResponseA 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(): stringSocialMediaCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringSocialMediaCrudController::configureFilters()
public function configureFilters(Filters $filters): FiltersSocialMediaCrudController::configureFields()
public function configureFields(string $pageName): iterableSocialMediaCrudController::configureActions()
public function configureActions(Actions $actions): ActionsSocialMediaCrudController::visibility()
public function visibility(string $entityId): ResponseSocialPostCrudController 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): voidSocialPostCrudController::getEntityFqcn()
public static function getEntityFqcn(): stringSocialPostCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringSocialPostCrudController::configureFilters()
public function configureFilters(Filters $filters): FiltersSocialPostCrudController::configureFields()
public function configureFields(string $pageName): iterableSocialPostCrudController::configureActions()
public function configureActions(Actions $actions): ActionsSocialPostCrudController::createEntity()
public function createEntity(string $entityFqcn): objectA 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): ResponseThe reels made again (Messenger: the worker renders), to be looked at before they leave.
SocialPostCrudController::publish()
public function publish(string $entityId): ResponseSent 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): ResponseOne network sent again - its film rendered again first if it is gone.
SocialPostCrudController::preview()
public function preview(string $entityId): ResponseEach network: its reel, its cover, what the network would refuse, where it is.
SocialPostCrudController::reel()
public function reel(string $entityId, int $target, string $what): ResponseThe 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): voidTemplateCrudController::getEntityFqcn()
public static function getEntityFqcn(): stringTemplateCrudController::getPreferredIcon()
public static function getPreferredIcon(): ?stringTemplateCrudController::configureFields()
public function configureFields(string $pageName): iterableTemplateCrudController::persistEntity()
public function persistEntity(EntityManagerInterface $entityManager, object $entity): voidOne site's template: the one saved as such takes the place of the others.
TemplateCrudController::updateEntity()
public function updateEntity(EntityManagerInterface $entityManager, object $entity): voidBase\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): BinaryFileResponseBase\Social\DependencyInjection
SocialConfiguration class
class SocialConfiguration extends AbstractBaseConfiguration SocialConfiguration.php:8
SocialConfiguration::getConfigTreeBuilder()
public function getConfigTreeBuilder(): TreeBuilderSocialExtension class
class SocialExtension extends AbstractBaseExtension SocialExtension.php:11
SocialExtension::getConfiguration()
public function getConfiguration(array $config, ContainerBuilder $container): SocialConfigurationSocialExtension::load()
public function load(array $configs, ContainerBuilder $container): voidBase\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(): ?arraySocialMedia::__construct()
public function __construct(?string $provider = null, ?string $remoteId = null)SocialMedia::__toString()
public function __toString(): stringSocialMedia::getId()
public function getId(): ?intSocialMedia::getProvider()
public function getProvider(): ?stringSocialMedia::getProviderLabel()
public function getProviderLabel(): stringSocialMedia::getRemoteId()
public function getRemoteId(): ?stringSocialMedia::getKind()
public function getKind(): stringSocialMedia::setKind()
public function setKind(PostKind|string $kind): selfSocialMedia::isVideo()
public function isVideo(): boolSocialMedia::getPermalink()
public function getPermalink(): ?stringSocialMedia::setPermalink()
public function setPermalink(?string $permalink): selfSocialMedia::getCaption()
public function getCaption(): ?stringSocialMedia::setCaption()
public function setCaption(?string $caption): selfSocialMedia::getPublishedAt()
public function getPublishedAt(): ?\DateTimeInterfaceSocialMedia::setPublishedAt()
public function setPublishedAt(?\DateTimeInterface $at): selfSocialMedia::getThumbnail()
public function getThumbnail(): ?stringSocialMedia::getThumbnailFile()
public function getThumbnailFile(): ?FileSocialMedia::setThumbnail()
public function setThumbnail($thumbnail): selfSocialMedia::hasThumbnail()
public function hasThumbnail(): boolSocialMedia::getMediaUrl()
public function getMediaUrl(): ?stringSocialMedia::setMediaUrl()
public function setMediaUrl(?string $url): selfSocialMedia::getVideoUrl()
public function getVideoUrl(): ?stringSocialMedia::setVideoUrl()
public function setVideoUrl(?string $url): selfSocialMedia::getLikes()
public function getLikes(): ?intSocialMedia::setLikes()
public function setLikes(?int $likes): selfSocialMedia::getComments()
public function getComments(): ?intSocialMedia::setComments()
public function setComments(?int $comments): selfSocialMedia::isHidden()
public function isHidden(): boolSocialMedia::getHidden()
public function getHidden(): boolSocialMedia::setHidden()
public function setHidden(bool $hidden): selfSocialMedia::getFetchedAt()
public function getFetchedAt(): ?\DateTimeInterfaceSocialMedia::touch()
public function touch(): selfSocialPost 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(): ?arraySocialPost::__construct()
public function __construct()SocialPost::__toString()
public function __toString(): stringSocialPost::getId()
public function getId(): ?intSocialPost::getVideo()
public function getVideo(): ?stringSocialPost::getVideoFile()
public function getVideoFile(): ?FileSocialPost::setVideo()
public function setVideo($video): selfSocialPost::getImage()
public function getImage(): ?stringSocialPost::getImageFile()
public function getImageFile(): ?FileSocialPost::setImage()
public function setImage($image): selfSocialPost::getKind()
public function getKind(): stringSocialPost::getPostKind()
public function getPostKind(): PostKindSocialPost::setKind()
public function setKind(PostKind|string|null $kind): selfSocialPost::isImage()
public function isImage(): boolA picture goes out as it is: only a film is rendered.
SocialPost::getCaption()
public function getCaption(): ?stringSocialPost::setCaption()
public function setCaption(?string $caption): selfSocialPost::getTitle()
public function getTitle(): ?stringSocialPost::setTitle()
public function setTitle(?string $title): selfSocialPost::getTags()
public function getTags(): arraySocialPost::setTags()
public function setTags(?array $tags): selfSocialPost::getTemplate()
public function getTemplate(): ?TemplateSocialPost::setTemplate()
public function setTemplate(?Template $template): selfSocialPost::isUseTemplate()
public function isUseTemplate(): boolSocialPost::getUseTemplate()
public function getUseTemplate(): boolSocialPost::setUseTemplate()
public function setUseTemplate(bool $use): selfSocialPost::getCoverSecond()
public function getCoverSecond(): floatSocialPost::setCoverSecond()
public function setCoverSecond(?float $second): selfSocialPost::getScheduledAt()
public function getScheduledAt(): ?\DateTimeInterfaceSocialPost::setScheduledAt()
public function setScheduledAt(?\DateTimeInterface $at): selfSocialPost::getLink()
public function getLink(): ?stringSocialPost::setLink()
public function setLink(?string $link): selfSocialPost::getCreatedAt()
public function getCreatedAt(): ?\DateTimeInterfaceSocialPost::getState()
public function getState(): PostStateSocialPost::setState()
public function setState(PostState $state): selfSocialPost::getTargets()
public function getTargets(): CollectionSocialPost::addTarget()
public function addTarget(SocialPostTarget $target): selfSocialPost::removeTarget()
public function removeTarget(SocialPostTarget $target): selfSocialPost::getEnabledTargets()
public function getEnabledTargets(): array- Returns
the networks it goes to
SocialPost::getTarget()
public function getTarget(Platform|string $platform): ?SocialPostTargetSocialPost::refreshState()
public function refreshState(): selfThe 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): PostThe 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): arrayHashtags 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(): stringSocialPostTarget::getId()
public function getId(): ?intSocialPostTarget::getPost()
public function getPost(): ?SocialPostSocialPostTarget::setPost()
public function setPost(?SocialPost $post): selfSocialPostTarget::getPlatform()
public function getPlatform(): ?stringSocialPostTarget::setPlatform()
public function setPlatform(Platform|string|null $platform): selfSocialPostTarget::getPlatformLabel()
public function getPlatformLabel(): stringSocialPostTarget::isEnabled()
public function isEnabled(): boolSocialPostTarget::getEnabled()
public function getEnabled(): boolSocialPostTarget::setEnabled()
public function setEnabled(bool $enabled): selfSocialPostTarget::getCaption()
public function getCaption(): ?stringSocialPostTarget::setCaption()
public function setCaption(?string $caption): selfSocialPostTarget::getTitle()
public function getTitle(): ?stringSocialPostTarget::setTitle()
public function setTitle(?string $title): selfSocialPostTarget::getTags()
public function getTags(): ?arraySocialPostTarget::setTags()
public function setTags(?array $tags): selfSocialPostTarget::getTemplate()
public function getTemplate(): ?TemplateSocialPostTarget::setTemplate()
public function setTemplate(?Template $template): selfSocialPostTarget::getOptions()
public function getOptions(): arraySocialPostTarget::setOptions()
public function setOptions(?array $options): selfSocialPostTarget::getRenderedPath()
public function getRenderedPath(): ?stringSocialPostTarget::getCoverPath()
public function getCoverPath(): ?stringSocialPostTarget::getDuration()
public function getDuration(): ?floatSocialPostTarget::getWidth()
public function getWidth(): ?intSocialPostTarget::getHeight()
public function getHeight(): ?intSocialPostTarget::getSize()
public function getSize(): ?intSocialPostTarget::rendered()
public function rendered(Rendering $rendering): selfWhat the renderer made, written down; the target is RENDERED.
SocialPostTarget::hasRendering()
public function hasRendering(): boolSocialPostTarget::getPublicationId()
public function getPublicationId(): ?stringSocialPostTarget::setPublicationId()
public function setPublicationId(?string $id): selfSocialPostTarget::getPermalink()
public function getPermalink(): ?stringSocialPostTarget::setPermalink()
public function setPermalink(?string $permalink): selfSocialPostTarget::getState()
public function getState(): TargetStateSocialPostTarget::setState()
public function setState(TargetState $state): selfSocialPostTarget::getError()
public function getError(): ?stringSocialPostTarget::fail()
public function fail(string $error): selfSocialPostTarget::getAttempts()
public function getAttempts(): intSocialPostTarget::attempt()
public function attempt(): intSocialPostTarget::resetAttempts()
public function resetAttempts(): selfSocialPostTarget::getPublishedAt()
public function getPublishedAt(): ?\DateTimeInterfaceSocialPostTarget::setPublishedAt()
public function setPublishedAt(?\DateTimeInterface $at): selfSocialPostTarget::getUpdatedAt()
public function getUpdatedAt(): ?\DateTimeInterfaceSocialPostTarget::isMediaOpen()
public function isMediaOpen(int $ttl = 86400, ?\DateTimeInterface $now = null): boolWhether 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): ?MediaThe 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(): ?arrayTemplate::__toString()
public function __toString(): stringTemplate::getId()
public function getId(): ?intTemplate::getName()
public function getName(): ?stringTemplate::setName()
public function setName(?string $name): selfTemplate::isDefault()
public function isDefault(): boolTemplate::setDefault()
public function setDefault(bool $default): selfTemplate::getPlatform()
public function getPlatform(): ?stringTemplate::setPlatform()
public function setPlatform(Platform|string|null $platform): selfTemplate::getLogo()
public function getLogo(): ?stringTemplate::getLogoFile()
public function getLogoFile(): ?FileTemplate::setLogo()
public function setLogo($logo): selfTemplate::getLogoPosition()
public function getLogoPosition(): LogoPositionTemplate::setLogoPosition()
public function setLogoPosition(LogoPosition $position): selfTemplate::getLogoScale()
public function getLogoScale(): floatTemplate::setLogoScale()
public function setLogoScale(float $scale): selfTemplate::hasBand()
public function hasBand(): boolTemplate::getBand()
public function getBand(): boolTemplate::setBand()
public function setBand(bool $band): selfTemplate::getBandText()
public function getBandText(): ?stringTemplate::setBandText()
public function setBandText(?string $text): selfTemplate::getBandColor()
public function getBandColor(): stringTemplate::setBandColor()
public function setBandColor(?string $color): selfTemplate::getTextColor()
public function getTextColor(): stringTemplate::setTextColor()
public function setTextColor(?string $color): selfTemplate::getFont()
public function getFont(): ?stringTemplate::getFontFile()
public function getFontFile(): ?FileTemplate::setFont()
public function setFont($font): selfTemplate::getBackground()
public function getBackground(): stringTemplate::setBackground()
public function setBackground(?string $color): selfTemplate::getIntro()
public function getIntro(): ?stringTemplate::getIntroFile()
public function getIntroFile(): ?FileTemplate::setIntro()
public function setIntro($intro): selfTemplate::getOutro()
public function getOutro(): ?stringTemplate::getOutroFile()
public function getOutroFile(): ?FileTemplate::setOutro()
public function setOutro($outro): selfTemplate::getFit()
public function getFit(): FitTemplate::setFit()
public function setFit(Fit $fit): selfTemplate::getFadeSeconds()
public function getFadeSeconds(): floatTemplate::setFadeSeconds()
public function setFadeSeconds(float $seconds): selfBase\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.
LogoPosition enum
enum LogoPosition LogoPosition.php:6
Where the logo sits on the reel. A string enum, so the column reads plainly.
LogoPosition::overlay()
public function overlay(int $margin): stringThe 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.
TargetState enum
enum TargetState TargetState.php:9
Where a post is on one network: waiting, rendered, handed over, being processed there, online, or refused.
TargetState::isFinal()
public function isFinal(): boolTargetState::isInFlight()
public function isInFlight(): boolHanded 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): selfRenderingException::failed()
public static function failed(string $what, string $output): selfBase\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): voidTargetType::configureOptions()
public function configureOptions(OptionsResolver $resolver): voidBase\Social\Message
CheckTargetMessage class
final class CheckTargetMessage CheckTargetMessage.php:6
A publication the network is still processing: its status to read again.
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.
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.
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): voidPublishTargetHandler 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): voidRenderPostHandler 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): voidBase\Social\Model
Rendering class
final class Rendering Rendering.php:6
What the renderer made: the film, its cover, and what ffprobe measured.
seconds
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): arrayThe 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): ?SocialMediaSocialMediaRepository::lastSync()
public function lastSync(string $provider): ?\DateTimeInterfaceWhen the provider's feed was last read; null: never.
SocialMediaRepository::countFor()
public function countFor(string $provider): intSocialPostRepository 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): ?SocialPostTargetThe 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(): ?TemplateThe site's own template, if it has one.
TemplateRepository::findForPlatform()
public function findForPlatform(string $platform): ?TemplateThe template kept for one network alone.
TemplateRepository::resolve()
public function resolve(SocialPostTarget $target): ?TemplateThe 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(): arrayThe providers the site uses, in order: the configured ones that omnipost declares.
Accounts::has()
public function has(string $name): boolAccounts::connected()
public function connected(string $name): boolA token is kept for it (dead or alive), or omnipost's configuration carries one.
Accounts::token()
public function token(string $name): ?TokenAccounts::saveToken()
public function saveToken(string $name, Token $token): TokenKept; 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): arrayAccounts::saveAccount()
public function saveAccount(string $name, Account $account): voidAccounts::apiKey()
public function apiKey(string $name): ?stringAccounts::saveApiKey()
public function saveApiKey(string $name, ?string $key): voidAccounts::disconnect()
public function disconnect(string $name): voidThe token and the account forgotten: the back office's "Disconnect".
Accounts::provider()
public function provider(string $name): ProviderInterfaceThe 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): arrayAccounts::refresh()
public function refresh(string $name): ?TokenA 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.
MediaToken::__construct()
public function __construct(readonly string $secret)MediaToken::sign()
public function sign(int $targetId, string $path): stringMediaToken::verify()
public function verify(int $targetId, string $path, string $token): boolMediaUrls 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): stringThe film's address - or, $cover, its still's.
MediaUrls::callable()
public function callable(): \ClosureAs 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): voidEach 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): intThe 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): PostThe 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): arrayWhat 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): boolThe 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): voidA 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.
Pixels between the logo and the frame's edges.
The band: across the lower third, above what the networks lay over the bottom of a reel.
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): RenderingThe 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): arrayffmpeg'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): arrayffmpeg's arguments for the cover: one frame of $path at $second.
Renderer::probe()
public function probe(string $path): arrayWhat ffprobe measures of a film or a picture.
Renderer::measures()
public static function measures(array $json, string $path = ''): arrayffprobe'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): stringA 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): intThe 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(): arraySocialExtension::wall()
public function wall(Environment $twig, int $limit = 12, ?string $provider = null): stringSocialExtension::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): arrayWhat a public address is: an Instagram post (its permalink, cleaned), a YouTube film (its id), or neither.