store; } public function roles(): DiviRoles { return $this->roles; } /** * The library entry $postId after the checks for reading, or their refusal; null when $postId * names no library entry (the caller goes on with PostGuard). With the library hidden (ruling * P9) or without the library right at all (ruling P12), an entry is refused exactly like an ID * that does not exist, so its type and existence stay unknown; only a user with the library * right who lacks edit_post on the entry gets forbidden (like pages). $forWrite adds canEdit(). */ public function item(mixed $postId, bool $forWrite): WP_Post|WP_Error|null { $id = PostGuard::id($postId); $post = $id === null ? null : get_post($id); if (! $post instanceof WP_Post || $post->post_type !== DiviLibraryStore::POST_TYPE) { return null; } if (($this->visible !== null && ! ($this->visible)()) || $this->canList() !== null) { return PostGuard::notFound((int) $post->ID); } return ($forWrite ? $this->canEdit($post) : $this->canRead($post)) ?? $post; } /** Listing the library: edit_posts and the Divi role option divi_library. */ public function canList(): ?WP_Error { if (! current_user_can('edit_posts')) { return Errors::forbidden('Keine Berechtigung, die Divi-Bibliothek zu nutzen.'); } return $this->roles->refusal('divi_library'); } /** Reading one entry: canList() and edit_post on the entry. */ public function canRead(WP_Post $item): ?WP_Error { $refusal = $this->canList(); if ($refusal !== null) { return $refusal; } return current_user_can('edit_post', (int) $item->ID) ? null : Errors::forbidden(sprintf('Keine Berechtigung, Bibliothekseintrag %d zu bearbeiten.', (int) $item->ID)); } /** * Changing one entry: canRead(), the role option save_library, the Tools-tab gate and a live * entry; a global entry additionally needs edit_global_library (E3 – Divi's builder route * does not check edit_post on the entry, F9; LIT MCP does). */ public function canEdit(WP_Post $item): ?WP_Error { $refusal = $this->canRead($item) ?? $this->roles->refusal('save_library') ?? $this->writableGate(); if ($refusal !== null) { return $refusal; } if ((string) $item->post_status !== 'publish') { return Errors::invalidInput( sprintf( 'Bibliothekseintrag %d ist nicht aktiv (Status „%s“); nichts wurde gespeichert.', (int) $item->ID, (string) $item->post_status ), ['post_id' => 'nur aktive Bibliothekseinträge'], 'Den Eintrag zuerst in der Divi-Bibliothek wiederherstellen.' ); } return $this->isGlobal($item) ? $this->roles->refusal('edit_global_library') : null; } /** * Creating an entry: canList(), publish_posts of et_pb_layout (library entries are always * published, F2), the role option save_library and the Tools-tab gate; a global entry * additionally edit_global_library (ruling P7 – the same option as for editing one, F12). */ public function canSave(bool $global = false): ?WP_Error { $refusal = $this->canList(); if ($refusal !== null) { return $refusal; } $type = get_post_type_object(DiviLibraryStore::POST_TYPE); $publish = is_object($type) && isset($type->cap->publish_posts) ? (string) $type->cap->publish_posts : 'publish_posts'; if (! current_user_can($publish)) { return Errors::forbidden('Keine Berechtigung, Einträge der Divi-Bibliothek anzulegen (publish_posts).'); } $refusal = $this->roles->refusal('save_library') ?? $this->writableGate(); if ($refusal !== null || ! $global) { return $refusal; } return $this->roles->refusal('edit_global_library'); } /** * Inserting from the library into a page (E3): canList(), the role option add_library (Divi's * "Aus der Bibliothek hinzufügen") and a group "Divi-Bibliothek" that is not read-only or * disabled (E9). Reading the entry itself stays item() (ruling P5). */ public function canInsert(): ?WP_Error { return $this->canList() ?? $this->roles->refusal('add_library') ?? $this->writableGate(); } /** Refusal while the Tools tab keeps this connection from writing to the library. */ public function writableGate(): ?WP_Error { if ($this->writable === null || ($this->writable)()) { return null; } return Errors::forbidden( 'Schreiben in die Divi-Bibliothek ist für diese Verbindung abgeschaltet (Gruppe „Divi-Bibliothek“ auf ' . '„nur lesen“ oder deaktiviert).', 'Einen Administrator fragen: Einstellungen → LIT MCP → Tools.' ); } public function isGlobal(WP_Post $item): bool { return $this->store->isGlobal((int) $item->ID); } }