The media_types closure validator called $value->toArray(), but the
value is a plain PHP array (built via explode()), causing a fatal
'Call to a member function toArray() on array' and a 500 when opening
the Directory admin view.
Normalize to an array before in_array() checks, handling both array
and Collection inputs.
Fixes#7311
Empty lang/x/web.php values (untranslated Crowdin placeholders) were
being exported as empty strings, overriding the English UI fallback and
breaking non-English languages. Recursively strip empty strings before
writing the JSON build files, then regenerate all language files.
Larastan v3.12.0 added the larastan.relationExistence rule, which
detects Eloquent relations by their declared return type. statuses()
defined the hasMany relation but lacked the ': HasMany' return type, so
the rule could not recognize it and flagged $filter->load([...,
'statuses']) in CustomFilterController.php as referencing a missing
relation. Add the return type to match the sibling keywords() method.
Verified with larastan/larastan v3.12.0 (No errors).
For the rare cases where SQL must differ between MySQL and MariaDB,
add DatabaseDriver::isMysql()/isMariadb() and db_is_mysql()/db_is_mariadb()
alongside the existing grouped isMysqlMaria()/db_is_mysql_maria().
Laravel 11 exposes MariaDB as a dedicated 'mariadb' driver, so
config('database.default') === 'mysql' checks silently misclassified
MariaDB as the non-mysql (postgres) branch.
- Add App\Util\Database\DatabaseDriver with isMysqlLike()/isPgsql()
plus db_is_mysql_like()/db_is_pgsql() global helpers.
- Route all database.default driver checks through the helpers so
MySQL and MariaDB are treated as one group.
- Use '' (not null) for share/compose caption+rendered, valid whether
the column is nullable or NOT NULL (it is NOT NULL on MySQL/MariaDB).
- Guard pgsql strtolower() in registration against missing fields.
- Scope CustomEmoji::duplicateShortcodes to the grouped column for
Postgres GROUP BY validity.
- Remove stale Postgres guard in status:dedup; use havingRaw for
cross-driver HAVING.
queueDelivery() runs synchronously from the v1 follow/unfollow endpoints
(via Helpers::sendSignedObject), which commit local state before delivery
and have no try/catch. After the Http::send() rewrite, a ConnectionException
from a momentarily-unreachable remote was rethrown out of queueDelivery(),
turning a best-effort delivery into a 500 for the user after the follow/
unfollow was already persisted. For unfollows, a retry then hit the
isFollowing==false branch and never re-sent the Undo, diverging state.
Treat transport failures (ConnectionException) as best-effort on this
single-delivery path: log, record host health, and return without
propagating. Other exception types (invalid sender/destination, signing,
serialization) still throw, matching pre-rewrite precondition behavior.
Also widen SendUpdateActor's per-user catch from HttpException to Throwable
so a single bad host no longer aborts a fleet-wide actor update (the old
HttpException catch is dead for ConnectionException/invalid-destination).