fix: P8a blocks Theme Builder layouts without Divi's theme_builder role (L6)

et_header_layout, et_body_layout, et_footer_layout and et_template showing a
global entry now block a confirmed edit unless et_pb_is_allowed('theme_builder'),
like Divi's own check for TB layouts.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-27 04:13:14 +02:00
co-authored by Claude Opus 5.5
parent e8f69f67ea
commit 8aacc5dc4f
7 changed files with 49 additions and 8 deletions
+17 -4
View File
@@ -15,7 +15,8 @@ defined('ABSPATH') || exit;
* audit L1); the rights of the caller are then checked in chunks with a bounded post cache:
* - readable posts are listed (at most LIMIT, with title); unreadable ones only count (audit L4);
* - live posts (ruling P8a) the caller may not edit_post block a confirmed edit – by ID when
* readable, else as a count; above HARD_CAP live posts the edit is refused as a whole.
* readable, else as a count; Theme Builder layouts also without Divi's theme_builder role option
* (audit L6); above HARD_CAP live posts the edit is refused as a whole.
* Not final so tests can mock rows().
*/
class GlobalUsages
@@ -38,8 +39,14 @@ class GlobalUsages
/** Every post that exists for the user: listed in the dry run. */
private const LISTED = "post_status NOT IN ('trash', 'auto-draft', 'inherit')";
public function __construct(private ?\wpdb $db = null)
/** Theme Builder post types (Divi's et_theme_builder_get_layout_post_types() plus the templates). */
public const THEME_BUILDER_TYPES = ['et_header_layout', 'et_body_layout', 'et_footer_layout', 'et_template'];
private DiviRoles $roles;
public function __construct(private ?\wpdb $db = null, ?DiviRoles $roles = null)
{
$this->roles = $roles ?? new DiviRoles();
}
/**
@@ -142,12 +149,18 @@ class GlobalUsages
}
/**
* Ruling P8a: whether the caller may edit_post the live post $row.
* Ruling P8a: whether the caller may edit_post the live post $row; a Theme Builder layout or
* template additionally needs Divi's role option theme_builder (audit L6 – as Divi's own
* et_pb_is_allowed check for TB layouts, builder/functions.php).
*
* @param array{id: int, status: string, type: string} $row
*/
protected function editable(array $row): bool
private function editable(array $row): bool
{
if (in_array($row['type'], self::THEME_BUILDER_TYPES, true) && ! $this->roles->allows('theme_builder')) {
return false;
}
return current_user_can('edit_post', $row['id']);
}