Skip to content

Media Actions

7 unique action hooks currently map to this category, across 16 call sites.

Hook Inventory

HookEditionCall SitesFirst Source
fluent_community/check_rate_limit/media_uploadCore1fluent-community/app/Http/Controllers/FeedsController.php:878
fluent_community/delete_remote_media_{this}Core1fluent-community/app/Models/Media.php:153
fluent_community/document/local_file_accessPRO1fluent-community-pro/app/Modules/DocumentLibrary/DocumentModule.php:288
fluent_community/feed/media_deletedCore (also fired by Pro)5fluent-community-pro/app/Modules/DocumentLibrary/DocumentModule.php:33
fluent_community/maybe_delete_draft_mediasCore1fluent-community/app/Hooks/Handlers/Scheduler.php:17
fluent_community/remove_medias_by_urlCore (also fired by Pro)6fluent-community-pro/app/Modules/Quiz/QuizHelper.php:84
fluent_community/space_media/viewedPRO1fluent-community-pro/app/Modules/MediaGallery/Http/MediaGalleryController.php:51

fluent_community/check_rate_limit/media_upload

  • Type: action
  • Edition: Core
  • Call sites: 1
  • When it fires: Runs before an upload is validated so rate limiters can abort the request.

Core attaches RateLimitHandler::maybeLimitMediaUpload(), which throws once the member has created more media rows than fluent_community/rate_limit/media_upload_per_minute allows in the last 60 seconds. It runs after the PHP upload-size sanity check but before MIME validation, so nothing about the file is available yet. Site administrators are exempted inside the callback.

Parameters

#NameTypeDescription
1$user\FluentCommunity\App\Models\UserThe uploading member.

Call Sites

EditionSourceParameters
Corefluent-community/app/Http/Controllers/FeedsController.php:878$user (User)

Example

php
add_action('fluent_community/check_rate_limit/media_upload', function ($user) {
}, 10, 1);

Related: fluent_community/rate_limit/media_upload_per_minute

fluent_community/delete_remote_media_{this}

  • Type: action
  • Edition: Core
  • Call sites: 1
  • When it fires: Asks the owning storage driver to delete a media file it holds, named after the driver.

The suffix is $media->driver, so the live name is fluent_community/delete_remote_media_s3 for Pro's cloud storage. It is the else-branch of Media::deleteFile(): local files are unlinked directly and never reach a hook. Nothing verifies that a handler exists, so a media row on an unhandled driver has its database row removed while the remote object is left behind.

Parameters

#NameTypeDescription
1$media\FluentCommunity\App\Models\MediaThe media row whose remote file should be removed.

Call Sites

EditionSourceParameters
Corefluent-community/app/Models/Media.php:153$this (mixed)

Example

php
add_action('fluent_community/delete_remote_media_{this}', function ($media) {
}, 10, 1);

Related: fluent_community/media_public_url_{this} · fluent_community/handle_remove_bulk_media

fluent_community/document/local_file_access

  • Type: action
  • Edition: PRO
  • Call sites: 1
  • When it fires: Fires just before a locally stored document is streamed to the browser.

Runs after the permission check has passed, on the local-driver path only — documents on a cloud storage driver redirect to a signed URL and never reach this action. It fires for inline views as well as downloads, and headers have not been sent yet, so a callback can still short-circuit. Note this is a download of a document, not of a media-gallery item.

Parameters

#NameTypeDescription
1$document\FluentCommunity\App\Models\MediaThe media row being served (object_source is space_document or lesson_document).
2$forceDownloadstringThe raw force_download request value; empty means serve PDFs and raster images inline.

Call Sites

EditionSourceParameters
PROfluent-community-pro/app/Modules/DocumentLibrary/DocumentModule.php:288$document (mixed)
$forceDownload (mixed)

Example

php
add_action('fluent_community/document/local_file_access', function ($document, $forceDownload) {
}, 10, 2);

fluent_community/feed/media_deleted

  • Type: action
  • Edition: Core (also fired by Pro)
  • Call sites: 5
  • When it fires: Signals that one or more media rows attached to a post should be detached and cleaned up.

Despite the name this is a request to clean up, not a notification that a delete already happened: core's CleanupHandler::handleMediaDelete() is what actually queues the files for removal, and lesson documents are routed to the lesson-specific path instead. The only live callers are in the Pro Document Library, which passes documents being replaced or removed; the one core call site in FeedsController::deleteMediaPreview() is commented out, so deleting a post's preview image does not currently fire it.

Parameters

#NameTypeDescription
1$mediamixedEither a single \FluentCommunity\App\Models\Media model or a collection of them.

Call Sites

EditionSourceParameters
PROfluent-community-pro/app/Modules/DocumentLibrary/DocumentModule.php:33$documents (mixed)
PROfluent-community-pro/app/Modules/DocumentLibrary/DocumentModule.php:159$documents (mixed)
PROfluent-community-pro/app/Modules/DocumentLibrary/DocumentModule.php:175$deletedDocuments (mixed)
PROfluent-community-pro/app/Modules/DocumentLibrary/Http/DocumentController.php:205$media (mixed)
Corefluent-community/app/Http/Controllers/FeedsController.php:857$feed->media (Feed)

Example

php
add_action('fluent_community/feed/media_deleted', function ($media) {
}, 10, 1);

Related: fluent_community/remove_medias_by_url

fluent_community/maybe_delete_draft_medias

  • Type: action
  • Edition: Core
  • Call sites: 1
  • When it fires: Fires hourly to clean up media that was uploaded but never attached to anything.

Dispatched from the fluent_community_scheduled_hour_jobs handler. The core callback removes at most 30 inactive media rows older than two hours per run, so a large backlog drains over several hours. The two-hour grace period is what lets a member leave a composer open without losing their upload. It takes no arguments.

Call Sites

EditionSourceParameters
Corefluent-community/app/Hooks/Handlers/Scheduler.php:17No parameters

Example

php
add_action('fluent_community/maybe_delete_draft_medias', function () {
}, 10, 0);

Related: fluent_community_scheduled_hour_jobs · fluent_community/handle_remove_bulk_media

fluent_community/remove_medias_by_url

  • Type: action
  • Edition: Core (also fired by Pro)
  • Call sites: 6
  • When it fires: Requests deletion of media records matching a set of public URLs.

This is an action rather than a filter, and the work is done by core's CleanupHandler, which resolves the URLs to media rows and queues the files for removal. Fire it yourself when you replace an image that FluentCommunity owns — spaces, space groups, profiles, lockscreens and Pro quizzes all do. The optional $wheres array currently understands only sub_object_id, which scopes the lookup to one owning record and prevents deleting an identical URL used elsewhere; omit it and every matching row is removed.

Parameters

#NameTypeDescription
1$mediaUrlsarrayPublic media URLs to remove. An empty array is a no-op.
2$wheresarrayOptional constraints. Only sub_object_id is honoured.

Call Sites

EditionSourceParameters
PROfluent-community-pro/app/Modules/Quiz/QuizHelper.php:84$deleteMediaUrls (mixed)
[ 'sub_object_id' => $lessonId, ] (array)
Corefluent-community/app/Http/Controllers/ProfileController.php:236$deletedMedias (mixed)
array (2 keys: user_id, object_sources) (array)
Corefluent-community/app/Models/BaseSpace.php:360$deletePhotos (mixed)
[ 'sub_object_id' => $this->id, ] (array)
Corefluent-community/app/Models/SpaceGroup.php:129$deletePhotos (mixed)
[ 'sub_object_id' => $this->id, ] (array)
Corefluent-community/app/Services/Helper.php:425[$url] (array)
[ 'sub_object_id' => $subObjectId, ] (array)
Corefluent-community/app/Services/LockscreenService.php:189$deleteMediaUrls (mixed)
[ 'sub_object_id' => $spaceId, ] (array)

Example

php
add_action('fluent_community/remove_medias_by_url', function ($mediaUrls, $wheres) {
}, 10, 2);

Related: fluent_community/feed/media_deleted

fluent_community/space_media/viewed

  • Type: action
  • Edition: PRO
  • Call sites: 1
  • When it fires: Fires when a member loads a page of a space media gallery.

Fires once per request, including for each paged scroll, so it is a page-view signal rather than a first-visit signal. It runs only after the can_view_media permission check has passed.

Parameters

#NameTypeDescription
1$space\FluentCommunity\App\Models\SpaceThe space whose gallery was viewed.
2$user\FluentCommunity\App\Models\UserThe viewer, or null for a guest on a public space.
3$typestringThe tab viewed — photos, videos or audios.

Call Sites

EditionSourceParameters
PROfluent-community-pro/app/Modules/MediaGallery/Http/MediaGalleryController.php:51$space (Space)
$user (User)
$type (mixed)

Example

php
add_action('fluent_community/space_media/viewed', function ($space, $user, $type) {
}, 10, 3);

Related: fluent_community/space_media/api_response

FluentCommunity developer documentation