feat: jedes Divi-Tool und lit/content-create erklärt seine Divi-Fähigkeiten (RequiresDiviFeatures, DeclaresRequirements, FeatureSets); Tabelle Tool → Fähigkeiten als Test
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
e387d8d29e
commit
fdbda8012c
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Integrations\Divi\Release;
|
||||
|
||||
use LIT\MCP\Abilities\Ability;
|
||||
use LIT\MCP\Abilities\DeclaresRequirements;
|
||||
use LIT\MCP\Integrations\Divi\Library\DiviLibraryStore;
|
||||
use LIT\MCP\Integrations\Divi\ThemeBuilder\DiviThemeBuilder;
|
||||
use LIT\MCP\Integrations\WordPress\PostGuard;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/** Helpers of RequiresDiviFeatures::diviFeatures(): joining lists and the capabilities an entry adds. */
|
||||
final class FeatureSets
|
||||
{
|
||||
/**
|
||||
* The capabilities $ability declares for $input: its own diviFeatures() (the Divi tools) or the IDs a core tool
|
||||
* names through DeclaresRequirements (lit/content-create with divi). Anything else declares none; an ID that is no
|
||||
* DiviFeature is ignored (the core may name capabilities of other integrations).
|
||||
*
|
||||
* @param array<string, mixed> $input
|
||||
* @return list<DiviFeature>
|
||||
*/
|
||||
public static function declaredBy(Ability $ability, array $input): array
|
||||
{
|
||||
if ($ability instanceof RequiresDiviFeatures) {
|
||||
return self::merge($ability->diviFeatures($input));
|
||||
}
|
||||
|
||||
if (! $ability instanceof DeclaresRequirements) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$features = [];
|
||||
foreach ($ability->requirements($input) as $id) {
|
||||
$feature = DiviFeature::tryFrom($id);
|
||||
if ($feature !== null) {
|
||||
$features[] = $feature;
|
||||
}
|
||||
}
|
||||
|
||||
return self::merge($features);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<DiviFeature> ...$lists
|
||||
* @return list<DiviFeature> Every capability once, in the order of first appearance.
|
||||
*/
|
||||
public static function merge(array ...$lists): array
|
||||
{
|
||||
$merged = [];
|
||||
foreach ($lists as $list) {
|
||||
foreach ($list as $feature) {
|
||||
$merged[$feature->value] ??= $feature;
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($merged);
|
||||
}
|
||||
|
||||
/**
|
||||
* What the entry $postId adds to a tool that loads it. A page or post adds nothing; a library entry needs the
|
||||
* Divi roles (LibraryAccess), written also the library check of global entries and the library save scope
|
||||
* (DiviSaver, D5); a Theme Builder layout needs the roles, written also the template lookup of
|
||||
* ThemeBuilderEdits and the Theme Builder save scope. An ID that names no entry, or one the caller may not edit,
|
||||
* adds nothing – the tool answers "not found" or "forbidden" itself, and a lock never tells which kind of entry
|
||||
* an ID is (ruling P12).
|
||||
*
|
||||
* @return list<DiviFeature>
|
||||
*/
|
||||
public static function ofEntry(mixed $postId, bool $write): array
|
||||
{
|
||||
$id = PostGuard::id($postId);
|
||||
$type = $id === null ? false : get_post_type($id);
|
||||
if ($id === null || ! is_string($type)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$isLibrary = $type === DiviLibraryStore::POST_TYPE;
|
||||
if (! $isLibrary && DiviThemeBuilder::areaOf($type) === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (! current_user_can('edit_post', $id)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($isLibrary) {
|
||||
return $write
|
||||
? [DiviFeature::Roles, DiviFeature::LibraryRead, DiviFeature::LibraryWrite]
|
||||
: [DiviFeature::Roles];
|
||||
}
|
||||
|
||||
return $write
|
||||
? [DiviFeature::Roles, DiviFeature::ThemeBuilderRead, DiviFeature::ThemeBuilderWrite]
|
||||
: [DiviFeature::Roles];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user