fix: check WordPress meta capabilities per field key
Fields from the meta/sample sources need edit_post_meta (update, checked in PostWriter::prepare) or add_post_meta (create, checked right after the insert; a refusal deletes the new draft again) for their key; a refusal is a fields.<key> validation error. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
This commit is contained in:
@@ -118,6 +118,11 @@ final class ContentCreateAbility implements Ability
|
||||
}
|
||||
|
||||
$postId = (int) $postId;
|
||||
$denied = $this->writer->deniedMeta($postId, $postType, $prepared['fields'], 'add_post_meta');
|
||||
if ($denied !== []) {
|
||||
return $this->refuse($postId, $postType, $denied);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->writer->writeExtras($postId, $postType, $prepared, $input);
|
||||
} catch (Throwable $e) {
|
||||
@@ -187,6 +192,37 @@ final class ContentCreateAbility implements Ability
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Meta rights can only be checked once the draft exists (add_post_meta needs its ID): a
|
||||
* refused field removes the brand-new draft again and is reported like any invalid input.
|
||||
*
|
||||
* @param array<string, string> $denied fields.<key> => error
|
||||
* @throws WriteFailed When the draft cannot be deleted.
|
||||
*/
|
||||
private function refuse(int $postId, string $postType, array $denied): WP_Error
|
||||
{
|
||||
try {
|
||||
$deleted = (bool) wp_delete_post($postId, true);
|
||||
} catch (Throwable $e) {
|
||||
$deleted = false;
|
||||
}
|
||||
|
||||
if (! $deleted) {
|
||||
$summary = sprintf('Entwurf %d: Anlegen nicht zurückgenommen', $postId);
|
||||
$this->logPartial($postType, (string) $postId, $summary);
|
||||
throw new WriteFailed(
|
||||
'Keine Berechtigung für ' . implode(', ', array_keys($denied)) . '.',
|
||||
false,
|
||||
$postId,
|
||||
null,
|
||||
null,
|
||||
sprintf('Meta rights denied for new post %d; draft could not be deleted', $postId)
|
||||
);
|
||||
}
|
||||
|
||||
return Errors::invalidInput('Eingaben sind ungültig; nichts wurde gespeichert.', $denied);
|
||||
}
|
||||
|
||||
private function logPartial(string $postType, string $postId, string $summary): void
|
||||
{
|
||||
$this->log->recordPartial($this->name(), $postType, $postId, $summary);
|
||||
|
||||
Reference in New Issue
Block a user