18 function remove_block_asset_path_prefix( $asset_handle_or_path ) { |
18 function remove_block_asset_path_prefix( $asset_handle_or_path ) { |
19 $path_prefix = 'file:'; |
19 $path_prefix = 'file:'; |
20 if ( 0 !== strpos( $asset_handle_or_path, $path_prefix ) ) { |
20 if ( 0 !== strpos( $asset_handle_or_path, $path_prefix ) ) { |
21 return $asset_handle_or_path; |
21 return $asset_handle_or_path; |
22 } |
22 } |
23 return substr( |
23 $path = substr( |
24 $asset_handle_or_path, |
24 $asset_handle_or_path, |
25 strlen( $path_prefix ) |
25 strlen( $path_prefix ) |
26 ); |
26 ); |
|
27 if ( strpos( $path, './' ) === 0 ) { |
|
28 $path = substr( $path, 2 ); |
|
29 } |
|
30 return $path; |
27 } |
31 } |
28 |
32 |
29 /** |
33 /** |
30 * Generates the name for an asset based on the name of the block |
34 * Generates the name for an asset based on the name of the block |
31 * and the field name provided. |
35 * and the field name provided. |
40 if ( 0 === strpos( $block_name, 'core/' ) ) { |
44 if ( 0 === strpos( $block_name, 'core/' ) ) { |
41 $asset_handle = str_replace( 'core/', 'wp-block-', $block_name ); |
45 $asset_handle = str_replace( 'core/', 'wp-block-', $block_name ); |
42 if ( 0 === strpos( $field_name, 'editor' ) ) { |
46 if ( 0 === strpos( $field_name, 'editor' ) ) { |
43 $asset_handle .= '-editor'; |
47 $asset_handle .= '-editor'; |
44 } |
48 } |
|
49 if ( 0 === strpos( $field_name, 'view' ) ) { |
|
50 $asset_handle .= '-view'; |
|
51 } |
45 return $asset_handle; |
52 return $asset_handle; |
46 } |
53 } |
47 |
54 |
48 $field_mappings = array( |
55 $field_mappings = array( |
49 'editorScript' => 'editor-script', |
56 'editorScript' => 'editor-script', |
50 'script' => 'script', |
57 'script' => 'script', |
|
58 'viewScript' => 'view-script', |
51 'editorStyle' => 'editor-style', |
59 'editorStyle' => 'editor-style', |
52 'style' => 'style', |
60 'style' => 'style', |
53 ); |
61 ); |
54 return str_replace( '/', '-', $block_name ) . |
62 return str_replace( '/', '-', $block_name ) . |
55 '-' . $field_mappings[ $field_name ]; |
63 '-' . $field_mappings[ $field_name ]; |
94 ), |
104 ), |
95 '5.5.0' |
105 '5.5.0' |
96 ); |
106 ); |
97 return false; |
107 return false; |
98 } |
108 } |
99 $script_asset = require $script_asset_path; |
109 // Path needs to be normalized to work in Windows env. |
100 $result = wp_register_script( |
110 $wpinc_path_norm = wp_normalize_path( realpath( ABSPATH . WPINC ) ); |
|
111 $theme_path_norm = wp_normalize_path( get_theme_file_path() ); |
|
112 $script_path_norm = wp_normalize_path( realpath( dirname( $metadata['file'] ) . '/' . $script_path ) ); |
|
113 $is_core_block = isset( $metadata['file'] ) && 0 === strpos( $metadata['file'], $wpinc_path_norm ); |
|
114 $is_theme_block = 0 === strpos( $script_path_norm, $theme_path_norm ); |
|
115 |
|
116 $script_uri = plugins_url( $script_path, $metadata['file'] ); |
|
117 if ( $is_core_block ) { |
|
118 $script_uri = includes_url( str_replace( $wpinc_path_norm, '', $script_path_norm ) ); |
|
119 } elseif ( $is_theme_block ) { |
|
120 $script_uri = get_theme_file_uri( str_replace( $theme_path_norm, '', $script_path_norm ) ); |
|
121 } |
|
122 |
|
123 $script_asset = require $script_asset_path; |
|
124 $script_dependencies = isset( $script_asset['dependencies'] ) ? $script_asset['dependencies'] : array(); |
|
125 $result = wp_register_script( |
101 $script_handle, |
126 $script_handle, |
102 plugins_url( $script_path, $metadata['file'] ), |
127 $script_uri, |
103 $script_asset['dependencies'], |
128 $script_dependencies, |
104 $script_asset['version'] |
129 isset( $script_asset['version'] ) ? $script_asset['version'] : false |
105 ); |
130 ); |
106 if ( ! $result ) { |
131 if ( ! $result ) { |
107 return false; |
132 return false; |
108 } |
133 } |
109 |
134 |
110 if ( ! empty( $metadata['textdomain'] ) ) { |
135 if ( ! empty( $metadata['textdomain'] ) && in_array( 'wp-i18n', $script_dependencies, true ) ) { |
111 wp_set_script_translations( $script_handle, $metadata['textdomain'] ); |
136 wp_set_script_translations( $script_handle, $metadata['textdomain'] ); |
112 } |
137 } |
113 |
138 |
114 return $script_handle; |
139 return $script_handle; |
115 } |
140 } |
147 |
174 |
148 $style_uri = plugins_url( $style_path, $metadata['file'] ); |
175 $style_uri = plugins_url( $style_path, $metadata['file'] ); |
149 if ( $is_core_block ) { |
176 if ( $is_core_block ) { |
150 $style_path = "style$suffix.css"; |
177 $style_path = "style$suffix.css"; |
151 $style_uri = includes_url( 'blocks/' . str_replace( 'core/', '', $metadata['name'] ) . "/style$suffix.css" ); |
178 $style_uri = includes_url( 'blocks/' . str_replace( 'core/', '', $metadata['name'] ) . "/style$suffix.css" ); |
|
179 } |
|
180 |
|
181 $style_path_norm = wp_normalize_path( realpath( dirname( $metadata['file'] ) . '/' . $style_path ) ); |
|
182 $is_theme_block = 0 === strpos( $style_path_norm, $theme_path_norm ); |
|
183 |
|
184 if ( $is_theme_block ) { |
|
185 $style_uri = get_theme_file_uri( str_replace( $theme_path_norm, '', $style_path_norm ) ); |
152 } |
186 } |
153 |
187 |
154 $style_handle = generate_block_asset_handle( $metadata['name'], $field_name ); |
188 $style_handle = generate_block_asset_handle( $metadata['name'], $field_name ); |
155 $block_dir = dirname( $metadata['file'] ); |
189 $block_dir = dirname( $metadata['file'] ); |
156 $style_file = realpath( "$block_dir/$style_path" ); |
190 $style_file = realpath( "$block_dir/$style_path" ); |
177 |
211 |
178 return $result ? $style_handle : false; |
212 return $result ? $style_handle : false; |
179 } |
213 } |
180 |
214 |
181 /** |
215 /** |
|
216 * Gets i18n schema for block's metadata read from `block.json` file. |
|
217 * |
|
218 * @since 5.9.0 |
|
219 * |
|
220 * @return object The schema for block's metadata. |
|
221 */ |
|
222 function get_block_metadata_i18n_schema() { |
|
223 static $i18n_block_schema; |
|
224 |
|
225 if ( ! isset( $i18n_block_schema ) ) { |
|
226 $i18n_block_schema = wp_json_file_decode( __DIR__ . '/block-i18n.json' ); |
|
227 } |
|
228 |
|
229 return $i18n_block_schema; |
|
230 } |
|
231 |
|
232 /** |
182 * Registers a block type from the metadata stored in the `block.json` file. |
233 * Registers a block type from the metadata stored in the `block.json` file. |
183 * |
234 * |
184 * @since 5.5.0 |
235 * @since 5.5.0 |
|
236 * @since 5.7.0 Added support for `textdomain` field and i18n handling for all translatable fields. |
|
237 * @since 5.9.0 Added support for `variations` and `viewScript` fields. |
185 * |
238 * |
186 * @param string $file_or_folder Path to the JSON file with metadata definition for |
239 * @param string $file_or_folder Path to the JSON file with metadata definition for |
187 * the block or path to the folder where the `block.json` file is located. |
240 * the block or path to the folder where the `block.json` file is located. |
|
241 * If providing the path to a JSON file, the filename must end with `block.json`. |
188 * @param array $args Optional. Array of block type arguments. Accepts any public property |
242 * @param array $args Optional. Array of block type arguments. Accepts any public property |
189 * of `WP_Block_Type`. See WP_Block_Type::__construct() for information |
243 * of `WP_Block_Type`. See WP_Block_Type::__construct() for information |
190 * on accepted arguments. Default empty array. |
244 * on accepted arguments. Default empty array. |
191 * @return WP_Block_Type|false The registered block type on success, or false on failure. |
245 * @return WP_Block_Type|false The registered block type on success, or false on failure. |
192 */ |
246 */ |
226 } |
280 } |
227 } |
281 } |
228 |
282 |
229 $settings = array(); |
283 $settings = array(); |
230 $property_mappings = array( |
284 $property_mappings = array( |
|
285 'apiVersion' => 'api_version', |
231 'title' => 'title', |
286 'title' => 'title', |
232 'category' => 'category', |
287 'category' => 'category', |
233 'parent' => 'parent', |
288 'parent' => 'parent', |
|
289 'ancestor' => 'ancestor', |
234 'icon' => 'icon', |
290 'icon' => 'icon', |
235 'description' => 'description', |
291 'description' => 'description', |
236 'keywords' => 'keywords', |
292 'keywords' => 'keywords', |
237 'attributes' => 'attributes', |
293 'attributes' => 'attributes', |
238 'providesContext' => 'provides_context', |
294 'providesContext' => 'provides_context', |
239 'usesContext' => 'uses_context', |
295 'usesContext' => 'uses_context', |
240 'supports' => 'supports', |
296 'supports' => 'supports', |
241 'styles' => 'styles', |
297 'styles' => 'styles', |
|
298 'variations' => 'variations', |
242 'example' => 'example', |
299 'example' => 'example', |
243 'apiVersion' => 'api_version', |
300 ); |
244 ); |
301 $textdomain = ! empty( $metadata['textdomain'] ) ? $metadata['textdomain'] : null; |
|
302 $i18n_schema = get_block_metadata_i18n_schema(); |
245 |
303 |
246 foreach ( $property_mappings as $key => $mapped_key ) { |
304 foreach ( $property_mappings as $key => $mapped_key ) { |
247 if ( isset( $metadata[ $key ] ) ) { |
305 if ( isset( $metadata[ $key ] ) ) { |
248 $value = $metadata[ $key ]; |
306 $settings[ $mapped_key ] = $metadata[ $key ]; |
249 if ( empty( $metadata['textdomain'] ) ) { |
307 if ( $textdomain && isset( $i18n_schema->$key ) ) { |
250 $settings[ $mapped_key ] = $value; |
308 $settings[ $mapped_key ] = translate_settings_using_i18n_schema( $i18n_schema->$key, $settings[ $key ], $textdomain ); |
251 continue; |
|
252 } |
|
253 $textdomain = $metadata['textdomain']; |
|
254 switch ( $key ) { |
|
255 case 'title': |
|
256 case 'description': |
|
257 // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralContext,WordPress.WP.I18n.NonSingularStringLiteralDomain |
|
258 $settings[ $mapped_key ] = translate_with_gettext_context( $value, sprintf( 'block %s', $key ), $textdomain ); |
|
259 break; |
|
260 case 'keywords': |
|
261 $settings[ $mapped_key ] = array(); |
|
262 if ( ! is_array( $value ) ) { |
|
263 continue 2; |
|
264 } |
|
265 |
|
266 foreach ( $value as $keyword ) { |
|
267 // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain |
|
268 $settings[ $mapped_key ][] = translate_with_gettext_context( $keyword, 'block keyword', $textdomain ); |
|
269 } |
|
270 |
|
271 break; |
|
272 case 'styles': |
|
273 $settings[ $mapped_key ] = array(); |
|
274 if ( ! is_array( $value ) ) { |
|
275 continue 2; |
|
276 } |
|
277 |
|
278 foreach ( $value as $style ) { |
|
279 if ( ! empty( $style['label'] ) ) { |
|
280 // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain |
|
281 $style['label'] = translate_with_gettext_context( $style['label'], 'block style label', $textdomain ); |
|
282 } |
|
283 $settings[ $mapped_key ][] = $style; |
|
284 } |
|
285 |
|
286 break; |
|
287 default: |
|
288 $settings[ $mapped_key ] = $value; |
|
289 } |
309 } |
290 } |
310 } |
291 } |
311 } |
292 |
312 |
293 if ( ! empty( $metadata['editorScript'] ) ) { |
313 if ( ! empty( $metadata['editorScript'] ) ) { |
811 * @param array $parsed_block A single parsed block object. |
838 * @param array $parsed_block A single parsed block object. |
812 * @return string String of rendered HTML. |
839 * @return string String of rendered HTML. |
813 */ |
840 */ |
814 function render_block( $parsed_block ) { |
841 function render_block( $parsed_block ) { |
815 global $post; |
842 global $post; |
|
843 $parent_block = null; |
816 |
844 |
817 /** |
845 /** |
818 * Allows render_block() to be short-circuited, by returning a non-null value. |
846 * Allows render_block() to be short-circuited, by returning a non-null value. |
819 * |
847 * |
820 * @since 5.1.0 |
848 * @since 5.1.0 |
821 * |
849 * @since 5.9.0 The `$parent_block` parameter was added. |
822 * @param string|null $pre_render The pre-rendered content. Default null. |
850 * |
823 * @param array $parsed_block The block being rendered. |
851 * @param string|null $pre_render The pre-rendered content. Default null. |
|
852 * @param array $parsed_block The block being rendered. |
|
853 * @param WP_Block|null $parent_block If this is a nested block, a reference to the parent block. |
824 */ |
854 */ |
825 $pre_render = apply_filters( 'pre_render_block', null, $parsed_block ); |
855 $pre_render = apply_filters( 'pre_render_block', null, $parsed_block, $parent_block ); |
826 if ( ! is_null( $pre_render ) ) { |
856 if ( ! is_null( $pre_render ) ) { |
827 return $pre_render; |
857 return $pre_render; |
828 } |
858 } |
829 |
859 |
830 $source_block = $parsed_block; |
860 $source_block = $parsed_block; |
831 |
861 |
832 /** |
862 /** |
833 * Filters the block being rendered in render_block(), before it's processed. |
863 * Filters the block being rendered in render_block(), before it's processed. |
834 * |
864 * |
835 * @since 5.1.0 |
865 * @since 5.1.0 |
836 * |
866 * @since 5.9.0 The `$parent_block` parameter was added. |
837 * @param array $parsed_block The block being rendered. |
867 * |
838 * @param array $source_block An un-modified copy of $parsed_block, as it appeared in the source content. |
868 * @param array $parsed_block The block being rendered. |
|
869 * @param array $source_block An un-modified copy of $parsed_block, as it appeared in the source content. |
|
870 * @param WP_Block|null $parent_block If this is a nested block, a reference to the parent block. |
839 */ |
871 */ |
840 $parsed_block = apply_filters( 'render_block_data', $parsed_block, $source_block ); |
872 $parsed_block = apply_filters( 'render_block_data', $parsed_block, $source_block, $parent_block ); |
841 |
873 |
842 $context = array(); |
874 $context = array(); |
843 |
875 |
844 if ( $post instanceof WP_Post ) { |
876 if ( $post instanceof WP_Post ) { |
845 $context['postId'] = $post->ID; |
877 $context['postId'] = $post->ID; |
983 * |
1016 * |
984 * @since 5.8.0 |
1017 * @since 5.8.0 |
985 * |
1018 * |
986 * @param WP_Block_Type $block_type Block type to check for support. |
1019 * @param WP_Block_Type $block_type Block type to check for support. |
987 * @param string $feature Name of the feature to check support for. |
1020 * @param string $feature Name of the feature to check support for. |
988 * @param mixed $default Fallback value for feature support, defaults to false. |
1021 * @param mixed $default Optional. Fallback value for feature support. Default false. |
989 * |
1022 * @return bool Whether the feature is supported. |
990 * @return boolean Whether or not the feature is supported. |
|
991 */ |
1023 */ |
992 function block_has_support( $block_type, $feature, $default = false ) { |
1024 function block_has_support( $block_type, $feature, $default = false ) { |
993 $block_support = $default; |
1025 $block_support = $default; |
994 if ( $block_type && property_exists( $block_type, 'supports' ) ) { |
1026 if ( $block_type && property_exists( $block_type, 'supports' ) ) { |
995 $block_support = _wp_array_get( $block_type->supports, $feature, $default ); |
1027 $block_support = _wp_array_get( $block_type->supports, $feature, $default ); |
1106 } |
1138 } |
1107 |
1139 |
1108 $query['offset'] = ( $per_page * ( $page - 1 ) ) + $offset; |
1140 $query['offset'] = ( $per_page * ( $page - 1 ) ) + $offset; |
1109 $query['posts_per_page'] = $per_page; |
1141 $query['posts_per_page'] = $per_page; |
1110 } |
1142 } |
1111 if ( ! empty( $block->context['query']['categoryIds'] ) ) { |
1143 // Migrate `categoryIds` and `tagIds` to `tax_query` for backwards compatibility. |
1112 $term_ids = array_map( 'intval', $block->context['query']['categoryIds'] ); |
1144 if ( ! empty( $block->context['query']['categoryIds'] ) || ! empty( $block->context['query']['tagIds'] ) ) { |
1113 $term_ids = array_filter( $term_ids ); |
1145 $tax_query = array(); |
1114 $query['category__in'] = $term_ids; |
1146 if ( ! empty( $block->context['query']['categoryIds'] ) ) { |
1115 } |
1147 $tax_query[] = array( |
1116 if ( ! empty( $block->context['query']['tagIds'] ) ) { |
1148 'taxonomy' => 'category', |
1117 $term_ids = array_map( 'intval', $block->context['query']['tagIds'] ); |
1149 'terms' => array_filter( array_map( 'intval', $block->context['query']['categoryIds'] ) ), |
1118 $term_ids = array_filter( $term_ids ); |
1150 'include_children' => false, |
1119 $query['tag__in'] = $term_ids; |
1151 ); |
|
1152 } |
|
1153 if ( ! empty( $block->context['query']['tagIds'] ) ) { |
|
1154 $tax_query[] = array( |
|
1155 'taxonomy' => 'post_tag', |
|
1156 'terms' => array_filter( array_map( 'intval', $block->context['query']['tagIds'] ) ), |
|
1157 'include_children' => false, |
|
1158 ); |
|
1159 } |
|
1160 $query['tax_query'] = $tax_query; |
|
1161 } |
|
1162 if ( ! empty( $block->context['query']['taxQuery'] ) ) { |
|
1163 $query['tax_query'] = array(); |
|
1164 foreach ( $block->context['query']['taxQuery'] as $taxonomy => $terms ) { |
|
1165 if ( is_taxonomy_viewable( $taxonomy ) && ! empty( $terms ) ) { |
|
1166 $query['tax_query'][] = array( |
|
1167 'taxonomy' => $taxonomy, |
|
1168 'terms' => array_filter( array_map( 'intval', $terms ) ), |
|
1169 'include_children' => false, |
|
1170 ); |
|
1171 } |
|
1172 } |
1120 } |
1173 } |
1121 if ( |
1174 if ( |
1122 isset( $block->context['query']['order'] ) && |
1175 isset( $block->context['query']['order'] ) && |
1123 in_array( strtoupper( $block->context['query']['order'] ), array( 'ASC', 'DESC' ), true ) |
1176 in_array( strtoupper( $block->context['query']['order'] ), array( 'ASC', 'DESC' ), true ) |
1124 ) { |
1177 ) { |
1137 $query['s'] = $block->context['query']['search']; |
1190 $query['s'] = $block->context['query']['search']; |
1138 } |
1191 } |
1139 } |
1192 } |
1140 return $query; |
1193 return $query; |
1141 } |
1194 } |
|
1195 |
|
1196 /** |
|
1197 * Helper function that returns the proper pagination arrow HTML for |
|
1198 * `QueryPaginationNext` and `QueryPaginationPrevious` blocks based |
|
1199 * on the provided `paginationArrow` from `QueryPagination` context. |
|
1200 * |
|
1201 * It's used in QueryPaginationNext and QueryPaginationPrevious blocks. |
|
1202 * |
|
1203 * @since 5.9.0 |
|
1204 * |
|
1205 * @param WP_Block $block Block instance. |
|
1206 * @param boolean $is_next Flag for handling `next/previous` blocks. |
|
1207 * |
|
1208 * @return string|null The pagination arrow HTML or null if there is none. |
|
1209 */ |
|
1210 function get_query_pagination_arrow( $block, $is_next ) { |
|
1211 $arrow_map = array( |
|
1212 'none' => '', |
|
1213 'arrow' => array( |
|
1214 'next' => '→', |
|
1215 'previous' => '←', |
|
1216 ), |
|
1217 'chevron' => array( |
|
1218 'next' => '»', |
|
1219 'previous' => '«', |
|
1220 ), |
|
1221 ); |
|
1222 if ( ! empty( $block->context['paginationArrow'] ) && array_key_exists( $block->context['paginationArrow'], $arrow_map ) && ! empty( $arrow_map[ $block->context['paginationArrow'] ] ) ) { |
|
1223 $pagination_type = $is_next ? 'next' : 'previous'; |
|
1224 $arrow_attribute = $block->context['paginationArrow']; |
|
1225 $arrow = $arrow_map[ $block->context['paginationArrow'] ][ $pagination_type ]; |
|
1226 $arrow_classes = "wp-block-query-pagination-$pagination_type-arrow is-arrow-$arrow_attribute"; |
|
1227 return "<span class='$arrow_classes'>$arrow</span>"; |
|
1228 } |
|
1229 return null; |
|
1230 } |
|
1231 |
|
1232 /** |
|
1233 * Allows multiple block styles. |
|
1234 * |
|
1235 * @since 5.9.0 |
|
1236 * |
|
1237 * @param array $metadata Metadata for registering a block type. |
|
1238 * @return array Metadata for registering a block type. |
|
1239 */ |
|
1240 function _wp_multiple_block_styles( $metadata ) { |
|
1241 foreach ( array( 'style', 'editorStyle' ) as $key ) { |
|
1242 if ( ! empty( $metadata[ $key ] ) && is_array( $metadata[ $key ] ) ) { |
|
1243 $default_style = array_shift( $metadata[ $key ] ); |
|
1244 foreach ( $metadata[ $key ] as $handle ) { |
|
1245 $args = array( 'handle' => $handle ); |
|
1246 if ( 0 === strpos( $handle, 'file:' ) && isset( $metadata['file'] ) ) { |
|
1247 $style_path = remove_block_asset_path_prefix( $handle ); |
|
1248 $theme_path_norm = wp_normalize_path( get_theme_file_path() ); |
|
1249 $style_path_norm = wp_normalize_path( realpath( dirname( $metadata['file'] ) . '/' . $style_path ) ); |
|
1250 $is_theme_block = isset( $metadata['file'] ) && 0 === strpos( $metadata['file'], $theme_path_norm ); |
|
1251 |
|
1252 $style_uri = plugins_url( $style_path, $metadata['file'] ); |
|
1253 |
|
1254 if ( $is_theme_block ) { |
|
1255 $style_uri = get_theme_file_uri( str_replace( $theme_path_norm, '', $style_path_norm ) ); |
|
1256 } |
|
1257 |
|
1258 $args = array( |
|
1259 'handle' => sanitize_key( "{$metadata['name']}-{$style_path}" ), |
|
1260 'src' => $style_uri, |
|
1261 ); |
|
1262 } |
|
1263 |
|
1264 wp_enqueue_block_style( $metadata['name'], $args ); |
|
1265 } |
|
1266 |
|
1267 // Only return the 1st item in the array. |
|
1268 $metadata[ $key ] = $default_style; |
|
1269 } |
|
1270 } |
|
1271 return $metadata; |
|
1272 } |
|
1273 add_filter( 'block_type_metadata', '_wp_multiple_block_styles' ); |
|
1274 |
|
1275 /** |
|
1276 * Helper function that constructs a comment query vars array from the passed |
|
1277 * block properties. |
|
1278 * |
|
1279 * It's used with the Comment Query Loop inner blocks. |
|
1280 * |
|
1281 * @since 6.0.0 |
|
1282 * |
|
1283 * @param WP_Block $block Block instance. |
|
1284 * |
|
1285 * @return array Returns the comment query parameters to use with the |
|
1286 * WP_Comment_Query constructor. |
|
1287 */ |
|
1288 function build_comment_query_vars_from_block( $block ) { |
|
1289 |
|
1290 $comment_args = array( |
|
1291 'orderby' => 'comment_date_gmt', |
|
1292 'order' => 'ASC', |
|
1293 'status' => 'approve', |
|
1294 'no_found_rows' => false, |
|
1295 ); |
|
1296 |
|
1297 if ( is_user_logged_in() ) { |
|
1298 $comment_args['include_unapproved'] = array( get_current_user_id() ); |
|
1299 } else { |
|
1300 $unapproved_email = wp_get_unapproved_comment_author_email(); |
|
1301 |
|
1302 if ( $unapproved_email ) { |
|
1303 $comment_args['include_unapproved'] = array( $unapproved_email ); |
|
1304 } |
|
1305 } |
|
1306 |
|
1307 if ( ! empty( $block->context['postId'] ) ) { |
|
1308 $comment_args['post_id'] = (int) $block->context['postId']; |
|
1309 } |
|
1310 |
|
1311 if ( get_option( 'thread_comments' ) ) { |
|
1312 $comment_args['hierarchical'] = 'threaded'; |
|
1313 } else { |
|
1314 $comment_args['hierarchical'] = false; |
|
1315 } |
|
1316 |
|
1317 if ( get_option( 'page_comments' ) === '1' || get_option( 'page_comments' ) === true ) { |
|
1318 $per_page = get_option( 'comments_per_page' ); |
|
1319 $default_page = get_option( 'default_comments_page' ); |
|
1320 if ( $per_page > 0 ) { |
|
1321 $comment_args['number'] = $per_page; |
|
1322 |
|
1323 $page = (int) get_query_var( 'cpage' ); |
|
1324 if ( $page ) { |
|
1325 $comment_args['paged'] = $page; |
|
1326 } elseif ( 'oldest' === $default_page ) { |
|
1327 $comment_args['paged'] = 1; |
|
1328 } elseif ( 'newest' === $default_page ) { |
|
1329 $max_num_pages = (int) ( new WP_Comment_Query( $comment_args ) )->max_num_pages; |
|
1330 if ( 0 !== $max_num_pages ) { |
|
1331 $comment_args['paged'] = $max_num_pages; |
|
1332 } |
|
1333 } |
|
1334 // Set the `cpage` query var to ensure the previous and next pagination links are correct |
|
1335 // when inheriting the Discussion Settings. |
|
1336 if ( 0 === $page && isset( $comment_args['paged'] ) && $comment_args['paged'] > 0 ) { |
|
1337 set_query_var( 'cpage', $comment_args['paged'] ); |
|
1338 } |
|
1339 } |
|
1340 } |
|
1341 |
|
1342 return $comment_args; |
|
1343 } |
|
1344 |
|
1345 /** |
|
1346 * Helper function that returns the proper pagination arrow HTML for |
|
1347 * `CommentsPaginationNext` and `CommentsPaginationPrevious` blocks based on the |
|
1348 * provided `paginationArrow` from `CommentsPagination` context. |
|
1349 * |
|
1350 * It's used in CommentsPaginationNext and CommentsPaginationPrevious blocks. |
|
1351 * |
|
1352 * @since 6.0.0 |
|
1353 * |
|
1354 * @param WP_Block $block Block instance. |
|
1355 * @param string $pagination_type Type of the arrow we will be rendering. |
|
1356 * Default 'next'. Accepts 'next' or 'previous'. |
|
1357 * |
|
1358 * @return string|null The pagination arrow HTML or null if there is none. |
|
1359 */ |
|
1360 function get_comments_pagination_arrow( $block, $pagination_type = 'next' ) { |
|
1361 $arrow_map = array( |
|
1362 'none' => '', |
|
1363 'arrow' => array( |
|
1364 'next' => '→', |
|
1365 'previous' => '←', |
|
1366 ), |
|
1367 'chevron' => array( |
|
1368 'next' => '»', |
|
1369 'previous' => '«', |
|
1370 ), |
|
1371 ); |
|
1372 if ( ! empty( $block->context['comments/paginationArrow'] ) && ! empty( $arrow_map[ $block->context['comments/paginationArrow'] ][ $pagination_type ] ) ) { |
|
1373 $arrow_attribute = $block->context['comments/paginationArrow']; |
|
1374 $arrow = $arrow_map[ $block->context['comments/paginationArrow'] ][ $pagination_type ]; |
|
1375 $arrow_classes = "wp-block-comments-pagination-$pagination_type-arrow is-arrow-$arrow_attribute"; |
|
1376 return "<span class='$arrow_classes'>$arrow</span>"; |
|
1377 } |
|
1378 return null; |
|
1379 } |