Download the PHP package ekumanov/flarum-ext-link-preview without Composer

On this page you can find all versions of the php package ekumanov/flarum-ext-link-preview. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package flarum-ext-link-preview

Link Preview for Flarum

Turns plain <a href> links in posts into Discord/Slack-style preview cards. Fetches OpenGraph / Twitter Card metadata server-side, caches it, and renders the card client-side with zero layout shift. Links written with their own title get an on-hover preview instead of a full card, and authors/moderators can pin or dismiss any card per post.

[!IMPORTANT] You need a queue worker or cron. Link metadata is fetched server-side, off the request thread:

  • Queue worker (recommended) — a real redis/database queue with a supervised php flarum queue:work fetches cards within seconds.
  • Cron only — on Flarum's default sync queue (no worker) the fetch is not run inline (that would block the save); it's deferred to the 5-minute scheduled sweep, so all you need is php flarum schedule:run on cron. Cards appear within a few minutes — a fixed-size skeleton holds their place until then, so there's no layout shift.
  • Neither — external-link cards won't appear. (Links to your own forum still work — resolved instantly from the DB.)

See Install.

Scope

This fills the gap between Flarum's other auto-embedders, rather than competing with them:

How it works

The post-save request thread never blocks on a remote fetch. If the queue is backed up or a worker is down, posts still go in immediately; cards just appear later as the worker drains. A scheduler sweep (5-minute interval) re-dispatches any rows whose job was lost — and on the default sync queue (no worker) that same sweep is the primary fetcher: the listener writes the placeholder row but leaves the actual fetch for the sweep, so it never blocks the save. See Background fetching.

What this does NOT do (intentional)

Security model

Fetching user-supplied URLs server-side can leak internal network access (SSRF), expose cloud metadata services, or turn the forum into a bandwidth amplifier. This extension layers eleven defenses:

# Defense What it stops
1 Scheme allowlist (http/https only) file://, gopher://, javascript:
2 Port allowlist (80/443) SSH probes, port-scan-by-redirect
3 Reject credentials in URL Forwarded-auth leak
4 Resolve A + AAAA, filter every IP Naïve filter bypass via AAAA
5 RFC1918 / loopback / link-local / ULA / multicast / test-net + v4-mapped IPv6 unwrap All non-public address space, incl. ::ffff:127.0.0.1
6 Reject host if ANY resolved IP is private DNS rebinding (mixed public/private answers)
7 CURLOPT_RESOLVE pins the vetted IP for the connect TOCTOU between resolve and connect
8 Manual redirect handling — every Location re-runs the full validation chain Public-decoy → private-IP redirect
9 CURLOPT_PROTOCOLS_STR locks the wire protocol http:// redirect to dict://
10 WRITEFUNCTION aborts over 2 MB Slowloris / bandwidth flood
11 Per-user hourly URL rate limit + per-post URL cap Logged-in attacker abusing the fetch queue

The full chain is exercised end-to-end by tests/Integration/Http/SafeHttpClientLiveTest.php, which hits 127.0.0.1, localhost, and 169.254.169.254 against real curl and asserts all three are blocked.

Card visibility: raw links, titled links, hover previews

How a link is written decides its default presentation:

Either default can be overridden per (post, preview) by the post author or any moderator/admin:

Detection is DOM-based (anchor text vs href), so every authoring syntax is covered without storing anything; the two overrides live in dismissed_at / pinned_at on the pivot table (mutually exclusive). Hover previews are shown to all readers — a "hidden" card de-emphasizes, it doesn't censor.

On touch devices there is no hover, and hijacking a link's first tap is the classic iOS double-tap anti-pattern (a link must navigate on first tap). Instead, a link with a hidden preview gets a small eye icon after it: tap it → the preview opens (with Pin preview for authors/mods); tap the preview → the URL opens; tap elsewhere → it closes.

Permissions: $actor->can('edit', $post) — Flarum's standard policy, which grants discussion.editOwnPost to the author (only while the forum's edit-time window is open) and discussion.editPost to mods/admins.

API:

CLS (Cumulative Layout Shift) posture

Cards have fixed CSS dimensions:

Image loading doesn't reflow the card (the slot is reserved by CSS). An image that 404s swaps to a same-dimension placeholder instead of being removed — the card stays exactly as wide and tall as it was.

A card that's still being fetched renders as a fixed-size skeleton in the same slot, so when the real card lands — on the next page load, the author's first paint after saving, or a live flarum/realtime update — it fills the reserved space without shifting the content below. (A fetch that ultimately yields nothing usable removes the skeleton — a comparatively rare upward shift.)

Install

Then enable Link Preview in Admin → Extensions. Enabling runs the extension's migration and creates its tables for you — there's no separate php flarum migrate step on a fresh install.

Background fetching: queue worker or cron

Preview metadata is fetched in the background. When a link is posted the forum has to reach out to that other website, which can take a few seconds, so the fetch happens after the post is saved rather than making the author wait — the card then appears a moment later. Two pieces make that work:

Flarum can provide those in a couple of ways; pick whichever fits your forum:

With neither a worker nor cron, external-link cards won't appear. Links to your own forum still work either way — those are read straight from your database, no fetching needed.

Scheduler

Flarum's scheduler runs recurring tasks on a clock (this is separate from the queue, which carries one-off background jobs). It's driven by a single system-cron line you most likely already have:

This extension's 5-minute sweep runs on that scheduler. On a worker-backed queue the sweep is only a safety net (it re-dispatches any fetch job that got dropped — worker restart, Redis flush, etc.); on the cron-only (sync) setup it's the primary fetch path, so the cron line is required there.

On the database queue driver, Flarum itself uses this same scheduler to run the worker (queue:work --stop-when-empty) every minute — so the one cron line doubles as your queue worker, with no Supervisor needed. Redis queues aren't auto-scheduled; they need their own supervised daemon.

Update

Unlike a fresh install, an update does need php flarum migrate — it applies any new schema the new version introduces (a harmless no-op when there's none). php flarum cache:clear then drops stale compiled assets so the new front-end is served.

Configuration

Admin → Extensions → Link Preview exposes every setting. The underlying keys live under the ekumanov-link-preview. prefix in the settings table; you can also set them directly via SQL:

whitelist / blacklist

Both default to empty — every URL gets a fetch + card unless the admin curates exclusions. Comma-, space-, or semicolon-separated hostnames, case-insensitive.

Authors/mods can also dismiss individual cards per post via the ✕ button — the right tool for "this one card is ugly", whereas the blacklist is for "I never want cards from this host."

Console commands

refresh-self rebuilds self-link previews that were cached before the local resolver shipped (they were fetched over HTTP and may carry a cropped forum logo) into clean, image-less title + first-post-excerpt cards. Supports --dry-run.

Development

The PHPUnit suite covers the SSRF chain, URL extraction, mention/quote filtering, OpenGraph parsing, self-link parsing, and host matching. The dismiss/pin controllers are thin permission-gate + UPDATE wrappers. The live SSRF integration test hits real loopback / cloud-metadata / RFC1918 endpoints to verify the guards.

Future work

License

MIT. An independent implementation built against the public OpenGraph spec.


All versions of flarum-ext-link-preview with dependencies

PHP Build Version
Package Version
Requires flarum/core Version ^2.0
php Version ^8.2
ext-curl Version *
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package ekumanov/flarum-ext-link-preview contains the following files

Loading the files please wait ...