← All changes
|
includes/Editors/BlockEditor/TemplatesController.php
+296
-270
3.3.4
→
4.9.2
View file →
| @@ -1,7 +1,12 @@ | ||
| 1 | 1 | <?php |
| 2 | +namespace WPDeveloper\BetterDocs\Editors\BlockEditor; | |
| 2 | 3 | |
| 3 | -namespace WPDeveloper\BetterDocs\Editors\BlockEditor; | |
| 4 | +if ( ! defined( 'ABSPATH' ) ) { | |
| 5 | + exit; | |
| 6 | +} | |
| 7 | + | |
| 8 | + | |
| 4 | 9 | use WPDeveloper\BetterDocs\Utils\Base; |
| 5 | 10 | use WPDeveloper\BetterDocs\Utils\BlockTemplate; |
| 6 | 11 | |
| 7 | 12 | /** |
| @@ -9,315 +14,336 @@ | ||
| 9 | 14 | * |
| 10 | 15 | * @internal |
| 11 | 16 | */ |
| 12 | 17 | class TemplatesController extends Base { |
| 13 | - protected $blockTemplate; | |
| 18 | + protected $blockTemplate; | |
| 14 | 19 | |
| 15 | - /** | |
| 16 | - * Constructor. | |
| 17 | - */ | |
| 18 | - public function __construct( BlockTemplate $blockTemplate ) { | |
| 19 | - $this->blockTemplate = $blockTemplate; | |
| 20 | - $this->init(); | |
| 21 | - } | |
| 20 | + /** | |
| 21 | + * Constructor. | |
| 22 | + */ | |
| 23 | + public function __construct( BlockTemplate $blockTemplate ) { | |
| 24 | + $this->blockTemplate = $blockTemplate; | |
| 25 | + $this->init(); | |
| 26 | + } | |
| 22 | 27 | |
| 23 | - /** | |
| 24 | - * Initialization method. | |
| 25 | - */ | |
| 26 | - protected function init() { | |
| 27 | - if (! betterdocs()->helper->current_theme_is_fse_theme() ) { | |
| 28 | - return; | |
| 29 | - } | |
| 30 | - add_filter( 'pre_get_block_template', [ $this, 'get_block_template_fallback' ], 10, 3 ); | |
| 31 | - add_filter( 'pre_get_block_file_template', [ $this, 'get_block_file_template' ], 10, 3 ); | |
| 32 | - add_filter( 'get_block_templates', [ $this, 'add_block_templates' ], 10, 3 ); | |
| 33 | - add_filter( 'taxonomy_template_hierarchy', [ $this, 'add_doc_archive_to_eligible_for_fallback_templates' ], 10, 1 ); | |
| 34 | - } | |
| 28 | + /** | |
| 29 | + * Initialization method. | |
| 30 | + */ | |
| 31 | + protected function init() { | |
| 32 | + if ( ! betterdocs()->helper->current_theme_is_fse_theme() ) { | |
| 33 | + return; | |
| 34 | + } | |
| 35 | + add_filter( 'pre_get_block_template', [ $this, 'get_block_template_fallback' ], 10, 3 ); | |
| 36 | + add_filter( 'pre_get_block_file_template', [ $this, 'get_block_file_template' ], 10, 3 ); | |
| 37 | + add_filter( 'get_block_templates', [ $this, 'add_block_templates' ], 10, 3 ); | |
| 38 | + add_filter( 'taxonomy_template_hierarchy', [ $this, 'add_doc_archive_to_eligible_for_fallback_templates' ], 10, 1 ); | |
| 39 | + add_filter( 'admin_bar_menu', [ $this, 'betterdocs_update_site_editor_menu_name' ], 999 ); | |
| 40 | + //add_filter( 'wp_insert_post_data', [ $this, 'betterdocs_preserve_template_author' ], 10, 2 ); | |
| 41 | + } | |
| 35 | 42 | |
| 36 | - /** | |
| 37 | - * This function is used on the `pre_get_block_template` hook to return the fallback template from the db in case | |
| 38 | - * the template is eligible for it. | |
| 39 | - * | |
| 40 | - * @param \WP_Block_Template|null $template Block template object to short-circuit the default query, | |
| 41 | - * or null to allow WP to run its normal queries. | |
| 42 | - * @param string $id Template unique identifier (example: theme_slug//template_slug). | |
| 43 | - * @param string $template_type wp_template or wp_template_part. | |
| 44 | - * | |
| 45 | - * @return object|null | |
| 46 | - */ | |
| 47 | - public function get_block_template_fallback( $template, $id, $template_type ) { | |
| 48 | - $template_name_parts = explode( '//', $id ); | |
| 49 | - list( $theme, $slug ) = $template_name_parts; | |
| 43 | + public function betterdocs_preserve_template_author( $data, $postarr ) { | |
| 44 | + if ( 'wp_template' === $data['post_type'] && ( 'taxonomy-doc_category' === $postarr['post_name'] || 'taxonomy-knowledge_base' === $postarr['post_name'] || 'taxonomy-doc_tag' === $postarr['post_name'] ) ) { | |
| 45 | + $data['post_author'] = get_current_user_id(); // Keep the current user as author | |
| 46 | + $data['post_name'] = 'betterdocs'; // Maintain correct menu slug | |
| 47 | + // Add any other fields you need to enforce here | |
| 48 | + } | |
| 49 | + return $data; | |
| 50 | + } | |
| 50 | 51 | |
| 51 | - if ( ! $this->blockTemplate->template_is_eligible_for_docs_archive_fallback( $slug ) ) { | |
| 52 | - return null; | |
| 53 | - } | |
| 52 | + public function betterdocs_update_site_editor_menu_name( $wp_admin_bar ) { | |
| 53 | + // Target the site editor menu item by ID and rename it | |
| 54 | + $node = $wp_admin_bar->get_node( 'betterdocs/betterdocs' ); | |
| 55 | + if ( $node ) { | |
| 56 | + $node->title = 'BetterDocs'; // Update the display name | |
| 57 | + $wp_admin_bar->add_node( $node ); // Apply the updated node | |
| 58 | + } | |
| 59 | + } | |
| 54 | 60 | |
| 55 | - $wp_query_args = [ | |
| 56 | - 'post_name__in' => [ 'archive-docs', $slug ], | |
| 57 | - 'post_type' => $template_type, | |
| 58 | - 'post_status' => [ 'auto-draft', 'draft', 'publish', 'trash' ], | |
| 59 | - 'no_found_rows' => true, | |
| 60 | - 'tax_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query | |
| 61 | - [ | |
| 62 | - 'taxonomy' => 'wp_theme', | |
| 63 | - 'field' => 'name', | |
| 64 | - 'terms' => $theme | |
| 65 | - ] | |
| 66 | - ] | |
| 67 | - ]; | |
| 68 | - $template_query = new \WP_Query( $wp_query_args ); | |
| 69 | - $posts = $template_query->posts; | |
| 70 | 61 | |
| 71 | - // If we have more than one result from the query, it means that the current template is present in the db (has | |
| 72 | - // been customized by the user) and we should not return the `archive-docs` template. | |
| 73 | - if ( count( $posts ) > 1 ) { | |
| 74 | - return null; | |
| 75 | - } | |
| 62 | + /** | |
| 63 | + * This function is used on the `pre_get_block_template` hook to return the fallback template from the db in case | |
| 64 | + * the template is eligible for it. | |
| 65 | + * | |
| 66 | + * @param \WP_Block_Template|null $template Block template object to short-circuit the default query, | |
| 67 | + * or null to allow WP to run its normal queries. | |
| 68 | + * @param string $id Template unique identifier (example: theme_slug//template_slug). | |
| 69 | + * @param string $template_type wp_template or wp_template_part. | |
| 70 | + * | |
| 71 | + * @return object|null | |
| 72 | + */ | |
| 73 | + public function get_block_template_fallback( $template, $id, $template_type ) { | |
| 74 | + $template_name_parts = explode( '//', $id ); | |
| 75 | + list( $theme, $slug ) = $template_name_parts; | |
| 76 | 76 | |
| 77 | - if ( count( $posts ) > 0 ) { | |
| 78 | - $template = _build_block_template_result_from_post( $posts[0] ); | |
| 77 | + if ( ! $this->blockTemplate->template_is_eligible_for_docs_archive_fallback( $slug ) ) { | |
| 78 | + return null; | |
| 79 | + } | |
| 79 | 80 | |
| 80 | - if ( ! is_wp_error( $template ) ) { | |
| 81 | - $template->id = $theme . '//' . $slug; | |
| 82 | - $template->slug = $slug; | |
| 83 | - $template->title = $this->blockTemplate->get_block_template_title( $slug ); | |
| 84 | - $template->description = $this->blockTemplate->get_block_template_description( $slug ); | |
| 85 | - unset( $template->source ); | |
| 81 | + $wp_query_args = [ | |
| 82 | + 'post_name__in' => [ 'archive-docs', $slug ], | |
| 83 | + 'post_type' => $template_type, | |
| 84 | + 'post_status' => [ 'auto-draft', 'draft', 'publish', 'trash' ], | |
| 85 | + 'no_found_rows' => true, | |
| 86 | + 'tax_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query | |
| 87 | + [ | |
| 88 | + 'taxonomy' => 'wp_theme', | |
| 89 | + 'field' => 'name', | |
| 90 | + 'terms' => $theme | |
| 91 | + ] | |
| 92 | + ] | |
| 93 | + ]; | |
| 94 | + $template_query = new \WP_Query( $wp_query_args ); | |
| 95 | + $posts = $template_query->posts; | |
| 86 | 96 | |
| 87 | - return $template; | |
| 88 | - } | |
| 89 | - } | |
| 90 | - return $template; | |
| 91 | - } | |
| 97 | + // If we have more than one result from the query, it means that the current template is present in the db (has | |
| 98 | + // been customized by the user) and we should not return the `archive-docs` template. | |
| 99 | + if ( count( $posts ) > 1 ) { | |
| 100 | + return null; | |
| 101 | + } | |
| 92 | 102 | |
| 93 | - /** | |
| 94 | - * Adds the `archive-docs` template to the `taxonomy-doc_category`, `taxonomy-doc_tag` | |
| 95 | - * templates to be able to fall back to it. | |
| 96 | - * | |
| 97 | - * @param array $template_hierarchy A list of template candidates, in descending order of priority. | |
| 98 | - */ | |
| 99 | - public function add_doc_archive_to_eligible_for_fallback_templates( $template_hierarchy ) { | |
| 100 | - $template_slugs = array_map( | |
| 101 | - '_strip_template_file_suffix', | |
| 102 | - $template_hierarchy | |
| 103 | - ); | |
| 103 | + if ( count( $posts ) > 0 ) { | |
| 104 | + $template = _build_block_template_result_from_post( $posts[0] ); | |
| 104 | 105 | |
| 105 | - $templates_eligible_for_fallback = array_filter( | |
| 106 | - $template_slugs, | |
| 107 | - [ $this->blockTemplate, 'template_is_eligible_for_docs_archive_fallback' ] | |
| 108 | - ); | |
| 106 | + if ( ! is_wp_error( $template ) ) { | |
| 107 | + $template->id = $theme . '//' . $slug; | |
| 108 | + $template->slug = $slug; | |
| 109 | + $template->title = $this->blockTemplate->get_block_template_title( $slug ); | |
| 110 | + $template->description = $this->blockTemplate->get_block_template_description( $slug ); | |
| 111 | + // unset( $template->source ); #creates issue when saving templates for FSE, the issue is randomly when props are set for each blocks, the props does not reflect on the front-end #issue-url:- https://projects.startise.com/fbs-63129 | |
| 109 | 112 | |
| 110 | - if ( count( $templates_eligible_for_fallback ) > 0 ) { | |
| 111 | - $template_hierarchy[] = 'archive-docs'; | |
| 112 | - } | |
| 113 | + return $template; | |
| 114 | + } | |
| 115 | + } | |
| 116 | + return $template; | |
| 117 | + } | |
| 113 | 118 | |
| 114 | - return $template_hierarchy; | |
| 115 | - } | |
| 119 | + /** | |
| 120 | + * Adds the `archive-docs` template to the `taxonomy-doc_category`, `taxonomy-doc_tag` | |
| 121 | + * templates to be able to fall back to it. | |
| 122 | + * | |
| 123 | + * @param array $template_hierarchy A list of template candidates, in descending order of priority. | |
| 124 | + */ | |
| 125 | + public function add_doc_archive_to_eligible_for_fallback_templates( $template_hierarchy ) { | |
| 126 | + $template_slugs = array_map( | |
| 127 | + '_strip_template_file_suffix', | |
| 128 | + $template_hierarchy | |
| 129 | + ); | |
| 116 | 130 | |
| 117 | - /** | |
| 118 | - * This function checks if there's a block template file in `betterdocs/includes/blocks/templates/` | |
| 119 | - * to return to pre_get_posts short-circuiting the query in Gutenberg. | |
| 120 | - * | |
| 121 | - * @param \WP_Block_Template|null $template Return a block template object to short-circuit the default query, | |
| 122 | - * or null to allow WP to run its normal queries. | |
| 123 | - * @param string $id Template unique identifier (example: theme_slug//template_slug). | |
| 124 | - * @param string $template_type wp_template or wp_template_part. | |
| 125 | - * | |
| 126 | - * @return mixed|\WP_Block_Template|\WP_Error | |
| 127 | - */ | |
| 128 | - public function get_block_file_template( $template, $id, $template_type ) { | |
| 131 | + $templates_eligible_for_fallback = array_filter( | |
| 132 | + $template_slugs, | |
| 133 | + [ $this->blockTemplate, 'template_is_eligible_for_docs_archive_fallback' ] | |
| 134 | + ); | |
| 129 | 135 | |
| 130 | - $template_name_parts = explode( '//', $id ); | |
| 136 | + if ( count( $templates_eligible_for_fallback ) > 0 ) { | |
| 137 | + $template_hierarchy[] = 'archive-docs'; | |
| 138 | + } | |
| 131 | 139 | |
| 132 | - if ( count( $template_name_parts ) < 2 ) { | |
| 133 | - return $template; | |
| 134 | - } | |
| 140 | + return $template_hierarchy; | |
| 141 | + } | |
| 135 | 142 | |
| 136 | - list( $template_id, $template_slug ) = $template_name_parts; | |
| 143 | + /** | |
| 144 | + * This function checks if there's a block template file in `betterdocs/includes/blocks/templates/` | |
| 145 | + * to return to pre_get_posts short-circuiting the query in Gutenberg. | |
| 146 | + * | |
| 147 | + * @param \WP_Block_Template|null $template Return a block template object to short-circuit the default query, | |
| 148 | + * or null to allow WP to run its normal queries. | |
| 149 | + * @param string $id Template unique identifier (example: theme_slug//template_slug). | |
| 150 | + * @param string $template_type wp_template or wp_template_part. | |
| 151 | + * | |
| 152 | + * @return mixed|\WP_Block_Template|\WP_Error | |
| 153 | + */ | |
| 154 | + public function get_block_file_template( $template, $id, $template_type ) { | |
| 137 | 155 | |
| 138 | - // If we are not dealing with a BetterDocs template let's return early and let it continue through the process. | |
| 139 | - if ( BlockTemplate::PLUGIN_SLUG !== $template_id ) { | |
| 140 | - return $template; | |
| 141 | - } | |
| 156 | + $template_name_parts = explode( '//', $id ); | |
| 142 | 157 | |
| 143 | - // If we don't have a template let Gutenberg do its thing. | |
| 144 | - if ( ! $this->block_template_is_available( $template_slug, $template_type ) ) { | |
| 145 | - return $template; | |
| 146 | - } | |
| 158 | + if ( count( $template_name_parts ) < 2 ) { | |
| 159 | + return $template; | |
| 160 | + } | |
| 147 | 161 | |
| 148 | - $directory = $this->blockTemplate->get_templates_directory( $template_type ); | |
| 162 | + list( $template_id, $template_slug ) = $template_name_parts; | |
| 149 | 163 | |
| 150 | - $template_file_path = $directory . '/' . $template_slug . '.html'; | |
| 164 | + // If we are not dealing with a BetterDocs template let's return early and let it continue through the process. | |
| 165 | + if ( BlockTemplate::PLUGIN_SLUG !== $template_id ) { | |
| 166 | + return $template; | |
| 167 | + } | |
| 151 | 168 | |
| 152 | - $template_object = $this->blockTemplate->create_new_block_template_object( $template_file_path, $template_type, $template_slug ); | |
| 169 | + // If we don't have a template let Gutenberg do its thing. | |
| 170 | + if ( ! $this->block_template_is_available( $template_slug, $template_type ) ) { | |
| 171 | + return $template; | |
| 172 | + } | |
| 153 | 173 | |
| 154 | - $template_built = $this->blockTemplate->build_template_result_from_file( $template_object, $template_type ); | |
| 174 | + $directory = $this->blockTemplate->get_templates_directory( $template_type ); | |
| 155 | 175 | |
| 156 | - if ( null !== $template_built ) { | |
| 157 | - return $template_built; | |
| 158 | - } | |
| 159 | - error_log(print_r($template, 1)); | |
| 160 | - // Hand back over to Gutenberg if we can't find a template. | |
| 161 | - return $template; | |
| 162 | - } | |
| 176 | + $template_file_path = $directory . '/' . $template_slug . '.html'; | |
| 163 | 177 | |
| 164 | - /** | |
| 165 | - * Add the block template objects to be used. | |
| 166 | - * | |
| 167 | - * @param array $query_result Array of template objects. | |
| 168 | - * @param array $query Optional. Arguments to retrieve templates. | |
| 169 | - * @param string $template_type wp_template or wp_template_part. | |
| 170 | - * @return array | |
| 171 | - */ | |
| 172 | - public function add_block_templates( $query_result, $query, $template_type ) { | |
| 173 | - if ( ! $this->blockTemplate->supports_block_templates() ) { | |
| 174 | - return $query_result; | |
| 175 | - } | |
| 178 | + $template_object = $this->blockTemplate->create_new_block_template_object( $template_file_path, $template_type, $template_slug ); | |
| 176 | 179 | |
| 177 | - $post_type = isset( $query['post_type'] ) ? $query['post_type'] : ''; | |
| 178 | - $slugs = isset( $query['slug__in'] ) ? $query['slug__in'] : []; | |
| 180 | + $template_built = $this->blockTemplate->build_template_result_from_file( $template_object, $template_type ); | |
| 179 | 181 | |
| 180 | - $template_files = $this->get_block_templates( $slugs, $template_type ); | |
| 182 | + if ( null !== $template_built ) { | |
| 183 | + return $template_built; | |
| 184 | + } | |
| 181 | 185 | |
| 182 | - // @todo: Add apply_filters to _gutenberg_get_template_files() in Gutenberg to prevent duplication of logic. | |
| 183 | - foreach ( $template_files as $template_file ) { | |
| 184 | - // If we have a template which is eligible for a fallback, we need to explicitly tell Gutenberg that | |
| 185 | - // it has a theme file (because it is using the fallback template file). And then `continue` to avoid | |
| 186 | - // adding duplicates. | |
| 187 | - if ( $this->blockTemplate->set_has_theme_file_if_fallback_is_available( $query_result, $template_file ) ) { | |
| 188 | - continue; | |
| 189 | - } | |
| 186 | + // Hand back over to Gutenberg if we can't find a template. | |
| 187 | + return $template; | |
| 188 | + } | |
| 190 | 189 | |
| 191 | - // If the current $post_type is set (e.g. on an Edit Post screen), and isn't included in the available post_types | |
| 192 | - // on the template file, then lets skip it so that it doesn't get added. This is typically used to hide templates | |
| 193 | - // in the template dropdown on the Edit Post page. | |
| 194 | - if ( $post_type && | |
| 195 | - isset( $template_file->post_types ) && | |
| 196 | - ! in_array( $post_type, $template_file->post_types, true ) | |
| 197 | - ) { | |
| 198 | - continue; | |
| 199 | - } | |
| 190 | + /** | |
| 191 | + * Add the block template objects to be used. | |
| 192 | + * | |
| 193 | + * @param array $query_result Array of template objects. | |
| 194 | + * @param array $query Optional. Arguments to retrieve templates. | |
| 195 | + * @param string $template_type wp_template or wp_template_part. | |
| 196 | + * @return array | |
| 197 | + */ | |
| 198 | + public function add_block_templates( $query_result, $query, $template_type ) { | |
| 199 | + if ( ! $this->blockTemplate->supports_block_templates() ) { | |
| 200 | + return $query_result; | |
| 201 | + } | |
| 200 | 202 | |
| 201 | - // It would be custom if the template was modified in the editor, so if it's not custom we can load it from | |
| 202 | - // the filesystem. | |
| 203 | - if ( 'custom' !== $template_file->source ) { | |
| 204 | - $template = $this->blockTemplate->build_template_result_from_file( $template_file, $template_type ); | |
| 205 | - } else { | |
| 206 | - $template_file->title = $this->blockTemplate->get_block_template_title( $template_file->slug ); | |
| 207 | - $template_file->description = $this->blockTemplate->get_block_template_description( $template_file->slug ); | |
| 208 | - $query_result[] = $template_file; | |
| 209 | - continue; | |
| 210 | - } | |
| 203 | + $post_type = isset( $query['post_type'] ) ? $query['post_type'] : ''; | |
| 204 | + $slugs = isset( $query['slug__in'] ) ? $query['slug__in'] : []; | |
| 211 | 205 | |
| 212 | - $is_not_custom = false === array_search( | |
| 213 | - wp_get_theme()->get_stylesheet() . '//' . $template_file->slug, | |
| 214 | - array_column( $query_result, 'id' ), | |
| 215 | - true | |
| 216 | - ); | |
| 217 | - $fits_slug_query = | |
| 218 | - ! isset( $query['slug__in'] ) || in_array( $template_file->slug, $query['slug__in'], true ); | |
| 219 | - $fits_area_query = | |
| 220 | - ! isset( $query['area'] ) || $template_file->area === $query['area']; | |
| 221 | - $should_include = $is_not_custom && $fits_slug_query && $fits_area_query; | |
| 222 | - if ( $should_include ) { | |
| 223 | - $query_result[] = $template; | |
| 224 | - } | |
| 225 | - } | |
| 206 | + $template_files = $this->get_block_templates( $slugs, $template_type ); | |
| 226 | 207 | |
| 227 | - // We need to remove theme (i.e. filesystem) templates that have the same slug as a customised one. | |
| 228 | - // This only affects saved templates that were saved BEFORE a theme template with the same slug was added. | |
| 229 | - $query_result = BlockTemplate::remove_theme_templates_with_custom_alternative( $query_result ); | |
| 208 | + // @todo: Add apply_filters to _gutenberg_get_template_files() in Gutenberg to prevent duplication of logic. | |
| 209 | + foreach ( $template_files as $template_file ) { | |
| 210 | + // If we have a template which is eligible for a fallback, we need to explicitly tell Gutenberg that | |
| 211 | + // it has a theme file (because it is using the fallback template file). And then `continue` to avoid | |
| 212 | + // adding duplicates. | |
| 213 | + if ( $this->blockTemplate->set_has_theme_file_if_fallback_is_available( $query_result, $template_file ) ) { | |
| 214 | + continue; | |
| 215 | + } | |
| 230 | 216 | |
| 231 | - /** | |
| 232 | - * WC templates from theme aren't included in `$this->get_block_templates()` but are handled by Gutenberg. | |
| 233 | - * We need to do additional search through all templates file to update title and description for WC | |
| 234 | - * templates that aren't listed in theme.json. | |
| 235 | - */ | |
| 236 | - $query_result = array_map( | |
| 237 | - function ( $template ) { | |
| 238 | - if ( 'theme' === $template->origin ) { | |
| 239 | - return $template; | |
| 240 | - } | |
| 241 | - if ( $template->title === $template->slug ) { | |
| 242 | - $template->title = $this->blockTemplate->get_block_template_title( $template->slug ); | |
| 243 | - } | |
| 244 | - if ( ! $template->description ) { | |
| 245 | - $template->description = $this->blockTemplate->get_block_template_description( $template->slug ); | |
| 246 | - } | |
| 247 | - return $template; | |
| 248 | - }, | |
| 249 | - $query_result | |
| 250 | - ); | |
| 217 | + // If the current $post_type is set (e.g. on an Edit Post screen), and isn't included in the available post_types | |
| 218 | + // on the template file, then lets skip it so that it doesn't get added. This is typically used to hide templates | |
| 219 | + // in the template dropdown on the Edit Post page. | |
| 220 | + if ( $post_type && | |
| 221 | + isset( $template_file->post_types ) && | |
| 222 | + ! in_array( $post_type, $template_file->post_types, true ) | |
| 223 | + ) { | |
| 224 | + continue; | |
| 225 | + } | |
| 251 | 226 | |
| 252 | - return $query_result; | |
| 253 | - } | |
| 227 | + // It would be custom if the template was modified in the editor, so if it's not custom we can load it from | |
| 228 | + // the filesystem. | |
| 229 | + if ( 'custom' !== $template_file->source ) { | |
| 230 | + $template = $this->blockTemplate->build_template_result_from_file( $template_file, $template_type ); | |
| 231 | + } else { | |
| 232 | + $template_file->title = $this->blockTemplate->get_block_template_title( $template_file->slug ); | |
| 233 | + $template_file->description = $this->blockTemplate->get_block_template_description( $template_file->slug ); | |
| 234 | + $query_result[] = $template_file; | |
| 235 | + continue; | |
| 236 | + } | |
| 254 | 237 | |
| 255 | - /** | |
| 256 | - * Gets the templates saved in the database. | |
| 257 | - * | |
| 258 | - * @param array $slugs An array of slugs to retrieve templates for. | |
| 259 | - * @param string $template_type wp_template or wp_template_part. | |
| 260 | - * | |
| 261 | - * @return int[]|\WP_Post[] An array of found templates. | |
| 262 | - */ | |
| 263 | - public function get_block_templates_from_db( $slugs = [], $template_type = 'wp_template' ) { | |
| 264 | - $check_query_args = [ | |
| 265 | - 'post_type' => $template_type, | |
| 266 | - 'posts_per_page' => -1, | |
| 267 | - 'no_found_rows' => true, | |
| 268 | - 'tax_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query | |
| 269 | - [ | |
| 270 | - 'taxonomy' => 'wp_theme', | |
| 271 | - 'field' => 'name', | |
| 272 | - 'terms' => [ BlockTemplate::PLUGIN_SLUG, get_stylesheet() ] | |
| 273 | - ] | |
| 274 | - ] | |
| 275 | - ]; | |
| 238 | + $is_not_custom = false === array_search( | |
| 239 | + wp_get_theme()->get_stylesheet() . '//' . $template_file->slug, | |
| 240 | + array_column( $query_result, 'id' ), | |
| 241 | + true | |
| 242 | + ); | |
| 243 | + $fits_slug_query = | |
| 244 | + ! isset( $query['slug__in'] ) || in_array( $template_file->slug, $query['slug__in'], true ); | |
| 245 | + $fits_area_query = | |
| 246 | + ! isset( $query['area'] ) || $template_file->area === $query['area']; | |
| 247 | + $should_include = $is_not_custom && $fits_slug_query && $fits_area_query; | |
| 248 | + if ( $should_include ) { | |
| 249 | + $query_result[] = $template; | |
| 250 | + } | |
| 251 | + } | |
| 276 | 252 | |
| 277 | - if ( is_array( $slugs ) && count( $slugs ) > 0 ) { | |
| 278 | - $check_query_args['post_name__in'] = $slugs; | |
| 279 | - } | |
| 253 | + // We need to remove theme (i.e. filesystem) templates that have the same slug as a customised one. | |
| 254 | + // This only affects saved templates that were saved BEFORE a theme template with the same slug was added. | |
| 255 | + $query_result = BlockTemplate::remove_theme_templates_with_custom_alternative( $query_result ); | |
| 280 | 256 | |
| 281 | - $check_query = new \WP_Query( $check_query_args ); | |
| 282 | - $saved_betterdocs_templates = $check_query->posts; | |
| 257 | + /** | |
| 258 | + * WC templates from theme aren't included in `$this->get_block_templates()` but are handled by Gutenberg. | |
| 259 | + * We need to do additional search through all templates file to update title and description for WC | |
| 260 | + * templates that aren't listed in theme.json. | |
| 261 | + */ | |
| 262 | + $query_result = array_map( | |
| 263 | + function ( $template ) { | |
| 264 | + if ( 'theme' === $template->origin ) { | |
| 265 | + return $template; | |
| 266 | + } | |
| 267 | + if ( $template->title === $template->slug ) { | |
| 268 | + $template->title = $this->blockTemplate->get_block_template_title( $template->slug ); | |
| 269 | + } | |
| 270 | + if ( ! $template->description ) { | |
| 271 | + $template->description = $this->blockTemplate->get_block_template_description( $template->slug ); | |
| 272 | + } | |
| 273 | + return $template; | |
| 274 | + }, | |
| 275 | + $query_result | |
| 276 | + ); | |
| 283 | 277 | |
| 284 | - return array_map( | |
| 285 | - function ( $saved_betterdocs_template ) { | |
| 286 | - return $this->blockTemplate->build_template_result_from_post( $saved_betterdocs_template ); | |
| 287 | - }, | |
| 288 | - $saved_betterdocs_templates | |
| 289 | - ); | |
| 290 | - } | |
| 278 | + return $query_result; | |
| 279 | + } | |
| 291 | 280 | |
| 292 | - /** | |
| 293 | - * Get and build the block template objects from the block template files. | |
| 294 | - * | |
| 295 | - * @param array $slugs An array of slugs to retrieve templates for. | |
| 296 | - * @param string $template_type wp_template or wp_template_part. | |
| 297 | - * | |
| 298 | - * @return array WP_Block_Template[] An array of block template objects. | |
| 299 | - */ | |
| 300 | - public function get_block_templates( $slugs = [], $template_type = 'wp_template' ) { | |
| 301 | - $templates_from_db = $this->get_block_templates_from_db( $slugs, $template_type ); | |
| 302 | - $templates_from_betterdocs = $this->blockTemplate->get_block_templates_from_betterdocs( $slugs, $templates_from_db, $template_type ); | |
| 303 | - $templates = array_merge( $templates_from_db, $templates_from_betterdocs ); | |
| 304 | - return $templates; | |
| 305 | - } | |
| 281 | + /** | |
| 282 | + * Gets the templates saved in the database. | |
| 283 | + * | |
| 284 | + * @param array $slugs An array of slugs to retrieve templates for. | |
| 285 | + * @param string $template_type wp_template or wp_template_part. | |
| 286 | + * | |
| 287 | + * @return int[]|\WP_Post[] An array of found templates. | |
| 288 | + */ | |
| 289 | + public function get_block_templates_from_db( $slugs = [], $template_type = 'wp_template' ) { | |
| 290 | + $check_query_args = [ | |
| 291 | + 'post_type' => $template_type, | |
| 292 | + 'posts_per_page' => -1, | |
| 293 | + 'no_found_rows' => true, | |
| 294 | + 'tax_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query | |
| 295 | + [ | |
| 296 | + 'taxonomy' => 'wp_theme', | |
| 297 | + 'field' => 'name', | |
| 298 | + 'terms' => [ BlockTemplate::PLUGIN_SLUG, get_stylesheet() ] | |
| 299 | + ] | |
| 300 | + ] | |
| 301 | + ]; | |
| 306 | 302 | |
| 307 | - /** | |
| 308 | - * Checks whether a block template with that name exists in BetterDocs Blocks | |
| 309 | - * | |
| 310 | - * @param string $template_name Template to check. | |
| 311 | - * @param string $template_type wp_template or wp_template_part. | |
| 312 | - * | |
| 313 | - * @return boolean | |
| 314 | - */ | |
| 315 | - public function block_template_is_available( $template_name, $template_type = 'wp_template' ) { | |
| 316 | - if ( ! $template_name ) { | |
| 317 | - return false; | |
| 318 | - } | |
| 319 | - $directory = $this->blockTemplate->get_templates_directory( $template_type ) . '/' . $template_name . '.html'; | |
| 303 | + if ( is_array( $slugs ) && count( $slugs ) > 0 ) { | |
| 304 | + $check_query_args['post_name__in'] = $slugs; | |
| 305 | + } | |
| 320 | 306 | |
| 321 | - return is_readable( $directory ) || $this->get_block_templates( [ $template_name ], $template_type ); | |
| 322 | - } | |
| 307 | + $check_query = new \WP_Query( $check_query_args ); | |
| 308 | + $saved_betterdocs_templates = $check_query->posts; | |
| 309 | + | |
| 310 | + return array_map( | |
| 311 | + function ( $saved_betterdocs_template ) { | |
| 312 | + return $this->blockTemplate->build_template_result_from_post( $saved_betterdocs_template ); | |
| 313 | + }, | |
| 314 | + $saved_betterdocs_templates | |
| 315 | + ); | |
| 316 | + } | |
| 317 | + | |
| 318 | + /** | |
| 319 | + * Get and build the block template objects from the block template files. | |
| 320 | + * | |
| 321 | + * @param array $slugs An array of slugs to retrieve templates for. | |
| 322 | + * @param string $template_type wp_template or wp_template_part. | |
| 323 | + * | |
| 324 | + * @return array WP_Block_Template[] An array of block template objects. | |
| 325 | + */ | |
| 326 | + public function get_block_templates( $slugs = [], $template_type = 'wp_template' ) { | |
| 327 | + $templates_from_db = $this->get_block_templates_from_db( $slugs, $template_type ); | |
| 328 | + $templates_from_betterdocs = $this->blockTemplate->get_block_templates_from_betterdocs( $slugs, $templates_from_db, $template_type ); | |
| 329 | + $templates = array_merge( $templates_from_db, $templates_from_betterdocs ); | |
| 330 | + return $templates; | |
| 331 | + } | |
| 332 | + | |
| 333 | + /** | |
| 334 | + * Checks whether a block template with that name exists in BetterDocs Blocks | |
| 335 | + * | |
| 336 | + * @param string $template_name Template to check. | |
| 337 | + * @param string $template_type wp_template or wp_template_part. | |
| 338 | + * | |
| 339 | + * @return boolean | |
| 340 | + */ | |
| 341 | + public function block_template_is_available( $template_name, $template_type = 'wp_template' ) { | |
| 342 | + if ( ! $template_name ) { | |
| 343 | + return false; | |
| 344 | + } | |
| 345 | + $directory = $this->blockTemplate->get_templates_directory( $template_type ) . '/' . $template_name . '.html'; | |
| 346 | + | |
| 347 | + return is_readable( $directory ) || $this->get_block_templates( [ $template_name ], $template_type ); | |
| 348 | + } | |
| 323 | 349 | } |