Threads posts over 500 chars were saved + scheduled successfully and only failed inside the publish job. The frontend already showed the 537|500 badge but `canSchedule` ignored content length, so Schedule and Post Now stayed enabled. Backend `UpdatePostRequest` only capped at 63206 (Facebook's max), not per-platform. - Add `Platform::contentOverflow()` as the single source of truth and reuse it from `HasSocialHttpClient::validateContentLength` (publish-time). - New `ContentFitsPlatformLimits` rule applied to the `content` field on `App\\UpdatePostRequest`, `Api\\UpdatePostRequest`, and `Api\\StorePostRequest` via `Rule::when(...)` so drafts are not blocked. - Rule dedupes per platform (two Threads accounts -> one error) and reports the platform label, hard cap, and overage via i18n. - Edit.vue feeds `contentLengthOverflows` into `canSchedule` and lists each offending platform in `postActionTooltip` using the existing `getPlatformLabel` resolver.
56 lines
1.6 KiB
PHP
56 lines
1.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Rules;
|
|
|
|
use App\Enums\SocialAccount\Platform;
|
|
use Closure;
|
|
use Illuminate\Contracts\Validation\ValidationRule;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Translation\PotentiallyTranslatedString;
|
|
|
|
/**
|
|
* Fails the content field once per platform whose hard `maxContentLength()` is
|
|
* exceeded by the submitted text. Pre-resolve the platforms the post is bound
|
|
* to (App: from `post_platforms.id`; API store: from `social_accounts.id`) and
|
|
* pass them in — keeps the rule decoupled from the FormRequest payload shape.
|
|
*/
|
|
class ContentFitsPlatformLimits implements ValidationRule
|
|
{
|
|
/**
|
|
* @param Collection<int|string, Platform> $platforms
|
|
*/
|
|
public function __construct(private Collection $platforms) {}
|
|
|
|
/**
|
|
* @param Closure(string, ?string=): PotentiallyTranslatedString $fail
|
|
*/
|
|
public function validate(string $attribute, mixed $value, Closure $fail): void
|
|
{
|
|
$content = (string) $value;
|
|
$reported = [];
|
|
|
|
foreach ($this->platforms as $platform) {
|
|
if (! $platform instanceof Platform) {
|
|
continue;
|
|
}
|
|
|
|
if (isset($reported[$platform->value])) {
|
|
continue;
|
|
}
|
|
|
|
$over = $platform->contentOverflow($content);
|
|
if ($over === null) {
|
|
continue;
|
|
}
|
|
|
|
$reported[$platform->value] = true;
|
|
$fail(trans('posts.form.content_exceeds_platform', [
|
|
'platform' => $platform->label(),
|
|
'limit' => $platform->maxContentLength(),
|
|
'over' => $over,
|
|
]));
|
|
}
|
|
}
|
|
}
|