-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Knowledge: Introduce the wp_knowledge custom post type
#12201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Changes from all commits
d008aaa
32cfc1d
ce880e5
782e260
bc904a0
71f5938
a531231
8e264d1
b3e53ec
78932e6
ba0bfaa
6afed88
3a9144e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,146 @@ | ||
| <?php | ||
| /** | ||
| * Knowledge API: Public functions for the `wp_knowledge` post type. | ||
| * | ||
| * The Knowledge post type is a private-by-default storage primitive. Individual | ||
| * rows are classified by one or more terms in the `wp_knowledge_type` taxonomy | ||
| * (for example "guideline", "memory", or "note"). This file holds the type | ||
| * registry, the default-term fallback applied on save, and the helper that | ||
| * gives lazily created type terms a human-readable label. | ||
| * | ||
| * @package WordPress | ||
| * @subpackage Knowledge | ||
| * @since 7.1.0 | ||
| */ | ||
|
|
||
| /** | ||
| * Retrieves the registered knowledge types, keyed by slug. | ||
| * | ||
| * Plugins can register their own types via the {@see 'wp_knowledge_types'} filter. | ||
| * | ||
| * @since 7.1.0 | ||
| * | ||
| * @return array { | ||
| * Slug-keyed map of knowledge types. | ||
| * | ||
| * @type array ...$0 { | ||
| * Data for a single knowledge type. | ||
| * | ||
| * @type string $title The human-readable label for the type. | ||
| * } | ||
| * } | ||
| * @phpstan-return array<non-empty-string, array{title: non-empty-string}> | ||
| */ | ||
| function wp_knowledge_types(): array { | ||
| /** | ||
| * Filters the knowledge types available on this site. | ||
| * | ||
| * @since 7.1.0 | ||
| * | ||
| * @param array $types { | ||
| * Slug-keyed map of knowledge types. | ||
| * | ||
| * @type array ...$0 { | ||
| * Data for a single knowledge type. | ||
| * | ||
| * @type string $title The human-readable label for the type. | ||
| * } | ||
| * } | ||
| * @phpstan-param array<non-empty-string, array{title: non-empty-string}> $types | ||
| */ | ||
| return apply_filters( | ||
| 'wp_knowledge_types', | ||
| array( | ||
| 'guideline' => array( | ||
| 'title' => _x( 'Guideline', 'knowledge type' ), | ||
| ), | ||
| 'memory' => array( | ||
| 'title' => _x( 'Memory', 'knowledge type' ), | ||
| ), | ||
| 'note' => array( | ||
| 'title' => _x( 'Note', 'knowledge type' ), | ||
| ), | ||
| ) | ||
| ); | ||
| } | ||
|
|
||
| /** | ||
| * Assigns the `note` fallback term when a knowledge post is saved without a type. | ||
| * | ||
| * Hooked to the `save_post_wp_knowledge` action so that every knowledge row has | ||
| * at least one `wp_knowledge_type` term. Uses get_the_terms() so the check is | ||
| * served by the object term cache. | ||
| * | ||
| * @since 7.1.0 | ||
| * @access private | ||
| * | ||
| * @param int $post_id Saved post ID. | ||
| */ | ||
| function wp_knowledge_ensure_default_type_term( int $post_id ): void { | ||
| if ( wp_is_post_revision( $post_id ) ) { | ||
| return; | ||
| } | ||
|
|
||
| $terms = get_the_terms( $post_id, 'wp_knowledge_type' ); | ||
| if ( is_wp_error( $terms ) || ! empty( $terms ) ) { | ||
| return; | ||
| } | ||
|
|
||
| /* | ||
| * Resolve to a term ID up front, creating the term on first use: | ||
| * wp_set_object_terms() interprets strings as names for hierarchical | ||
| * taxonomies, not slugs. | ||
| */ | ||
| $term = term_exists( 'note', 'wp_knowledge_type' ); | ||
| if ( ! $term ) { | ||
| $term = wp_insert_term( 'note', 'wp_knowledge_type' ); | ||
| if ( is_wp_error( $term ) ) { | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| wp_set_object_terms( $post_id, (int) $term['term_id'], 'wp_knowledge_type' ); | ||
| } | ||
|
|
||
| /** | ||
| * Swaps a raw knowledge-type slug for its registered label on term creation. | ||
| * | ||
| * Hooked to the `wp_insert_term_data` filter. When wp_set_object_terms() is | ||
| * called with a slug that does not yet exist, wp_insert_term() fires and this | ||
| * filter runs after WordPress has computed both `name` and `slug`. A `name` | ||
| * equal to `slug` indicates the term was created from a raw slug (for example by | ||
| * wp_set_object_terms()) rather than from a user-provided label, so the label is | ||
| * replaced with the title from wp_knowledge_types(). Because term names are | ||
| * persisted in the database, the translated title is stored in the locale active | ||
| * when the term is created. | ||
| * | ||
| * @since 7.1.0 | ||
| * @access private | ||
| * | ||
| * @param array $data Term data to be inserted (keyed by column name). | ||
| * @param string $taxonomy Taxonomy slug. | ||
| * @return array Possibly modified term data. | ||
| * | ||
| * @phpstan-param array{ name: string, slug: string } $data | ||
| * @phpstan-return array{ name: string, slug: string } | ||
| */ | ||
| function wp_knowledge_maybe_map_term_label( $data, string $taxonomy ): array { | ||
| if ( ! is_array( $data ) ) { | ||
| $data = array_fill_keys( array( 'name', 'slug' ), '' ); | ||
| } | ||
|
|
||
| if ( 'wp_knowledge_type' !== $taxonomy ) { | ||
| return $data; | ||
| } | ||
|
|
||
| if ( $data['name'] !== $data['slug'] ) { | ||
| return $data; | ||
| } | ||
|
|
||
| $types = wp_knowledge_types(); | ||
| if ( isset( $types[ $data['slug'] ] ) ) { | ||
| $data['name'] = $types[ $data['slug'] ]['title']; | ||
| } | ||
|
|
||
| return $data; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,7 @@ | |
| * See {@see 'init'}. | ||
| * | ||
| * @since 2.9.0 | ||
| * @since 7.1.0 Added the `wp_knowledge` post type. | ||
| */ | ||
| function create_initial_post_types() { | ||
| WP_Post_Type::reset_default_labels(); | ||
|
|
@@ -657,6 +658,47 @@ function create_initial_post_types() { | |
| ) | ||
| ); | ||
|
|
||
| register_post_type( | ||
| 'wp_knowledge', | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are not setting delete_with_user, so we use the default and knowledge created by an user is deleted when that user is deleted. I guess that behaviour is correct if the knowledge is private, but it may have unintended consequences for knowledge memory shared between users.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. I'd lean toward keeping the default (unset) here:
So I'd rather not special-case it. Happy to revisit if we later allow non-admins to create shared (non-private) knowledge. |
||
| array( | ||
| 'labels' => array( | ||
| 'name' => _x( 'Knowledge', 'post type general name' ), | ||
| 'singular_name' => _x( 'Knowledge Item', 'post type singular name' ), | ||
| ), | ||
| 'public' => false, | ||
| '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ | ||
| 'hierarchical' => false, | ||
| /* | ||
| * Knowledge rows have no native post-type screens. They are managed | ||
| * through the REST API and consuming features, not the wp-admin UI. | ||
| */ | ||
| 'show_ui' => false, | ||
| 'map_meta_cap' => true, | ||
| 'capability_type' => array( 'knowledge_item', 'knowledge_items' ), | ||
| /* | ||
| * `read` is remapped so that subscribers (who hold the base `read` | ||
| * capability) are stopped at the post-type door. Every other | ||
| * primitive defaults to a `knowledge_items`-suffixed capability granted | ||
| * by `wp_maybe_grant_knowledge_caps()`. | ||
| */ | ||
| 'capabilities' => array( | ||
| 'read' => 'read_knowledge_items', | ||
| ), | ||
| 'query_var' => false, | ||
| 'rewrite' => false, | ||
| 'show_in_rest' => true, | ||
| 'rest_base' => 'knowledge', | ||
|
jorgefilipecosta marked this conversation as resolved.
|
||
| 'rest_controller_class' => 'WP_REST_Knowledge_Controller', | ||
| 'supports' => array( 'title', 'editor', 'excerpt', 'author', 'revisions' ), | ||
| ) | ||
| ); | ||
| /* | ||
| * Disable autosave endpoints for knowledge. 'editor' support implies | ||
| * 'autosave', but knowledge is headless storage with no editor session, so | ||
| * the autosave REST routes have no consumer. Revision history is retained. | ||
| */ | ||
| remove_post_type_support( 'wp_knowledge', 'autosave' ); | ||
|
|
||
| register_post_status( | ||
| 'publish', | ||
| array( | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This return is currently failing in PHPStan. This will be fixed with a PHPStan extension that passes through the types for filters. See #12022