PageRenderTime 42ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/BlockTypesController.php

https://gitlab.com/campus-academy/krowkaramel
PHP | 233 lines | 197 code | 8 blank | 28 comment | 0 complexity | 6c3e11cf984cc7c0101a55a27578f15c MD5 | raw file
  1. <?php
  2. namespace Automattic\WooCommerce\Blocks;
  3. use Automattic\WooCommerce\Blocks\BlockTypes\AtomicBlock;
  4. use Automattic\WooCommerce\Blocks\Package;
  5. use Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry;
  6. use Automattic\WooCommerce\Blocks\Assets\Api as AssetApi;
  7. use Automattic\WooCommerce\Blocks\Integrations\IntegrationRegistry;
  8. /**
  9. * BlockTypesController class.
  10. *
  11. * @since 5.0.0
  12. * @internal
  13. */
  14. final class BlockTypesController {
  15. /**
  16. * Instance of the asset API.
  17. *
  18. * @var AssetApi
  19. */
  20. protected $asset_api;
  21. /**
  22. * Instance of the asset data registry.
  23. *
  24. * @var AssetDataRegistry
  25. */
  26. protected $asset_data_registry;
  27. /**
  28. * Constructor.
  29. *
  30. * @param AssetApi $asset_api Instance of the asset API.
  31. * @param AssetDataRegistry $asset_data_registry Instance of the asset data registry.
  32. */
  33. public function __construct( AssetApi $asset_api, AssetDataRegistry $asset_data_registry ) {
  34. $this->asset_api = $asset_api;
  35. $this->asset_data_registry = $asset_data_registry;
  36. $this->init();
  37. }
  38. /**
  39. * Initialize class features.
  40. */
  41. protected function init() {
  42. add_action( 'init', array( $this, 'register_blocks' ) );
  43. add_filter( 'render_block', array( $this, 'add_data_attributes' ), 10, 2 );
  44. add_action( 'woocommerce_login_form_end', array( $this, 'redirect_to_field' ) );
  45. add_filter( 'widget_types_to_hide_from_legacy_widget_block', array( $this, 'hide_legacy_widgets_with_block_equivalent' ) );
  46. }
  47. /**
  48. * Register blocks, hooking up assets and render functions as needed.
  49. */
  50. public function register_blocks() {
  51. $block_types = $this->get_block_types();
  52. foreach ( $block_types as $block_type ) {
  53. $block_type_class = __NAMESPACE__ . '\\BlockTypes\\' . $block_type;
  54. $block_type_instance = new $block_type_class( $this->asset_api, $this->asset_data_registry, new IntegrationRegistry() );
  55. }
  56. foreach ( self::get_atomic_blocks() as $block_type ) {
  57. $block_type_instance = new AtomicBlock( $this->asset_api, $this->asset_data_registry, new IntegrationRegistry(), $block_type );
  58. }
  59. }
  60. /**
  61. * Add data- attributes to blocks when rendered if the block is under the woocommerce/ namespace.
  62. *
  63. * @param string $content Block content.
  64. * @param array $block Parsed block data.
  65. * @return string
  66. */
  67. public function add_data_attributes( $content, $block ) {
  68. $block_name = $block['blockName'];
  69. $block_namespace = strtok( $block_name ?? '', '/' );
  70. /**
  71. * Filters the list of allowed block namespaces.
  72. *
  73. * This hook defines which block namespaces should have block name and attribute `data-` attributes appended on render.
  74. *
  75. * @param array $allowed_namespaces List of namespaces.
  76. */
  77. $allowed_namespaces = array_merge( [ 'woocommerce', 'woocommerce-checkout' ], (array) apply_filters( '__experimental_woocommerce_blocks_add_data_attributes_to_namespace', [] ) );
  78. /**
  79. * Filters the list of allowed Block Names
  80. *
  81. * This hook defines which block names should have block name and attribute data- attributes appended on render.
  82. *
  83. * @param array $allowed_namespaces List of namespaces.
  84. */
  85. $allowed_blocks = (array) apply_filters( '__experimental_woocommerce_blocks_add_data_attributes_to_block', [] );
  86. if ( ! in_array( $block_namespace, $allowed_namespaces, true ) && ! in_array( $block_name, $allowed_blocks, true ) ) {
  87. return $content;
  88. }
  89. $attributes = (array) $block['attrs'];
  90. $exclude_attributes = [ 'className', 'align' ];
  91. $escaped_data_attributes = [
  92. 'data-block-name="' . esc_attr( $block['blockName'] ) . '"',
  93. ];
  94. foreach ( $attributes as $key => $value ) {
  95. if ( in_array( $key, $exclude_attributes, true ) ) {
  96. continue;
  97. }
  98. if ( is_bool( $value ) ) {
  99. $value = $value ? 'true' : 'false';
  100. }
  101. if ( ! is_scalar( $value ) ) {
  102. $value = wp_json_encode( $value );
  103. }
  104. $escaped_data_attributes[] = 'data-' . esc_attr( strtolower( preg_replace( '/(?<!\ )[A-Z]/', '-$0', $key ) ) ) . '="' . esc_attr( $value ) . '"';
  105. }
  106. return preg_replace( '/^<div /', '<div ' . implode( ' ', $escaped_data_attributes ) . ' ', trim( $content ) );
  107. }
  108. /**
  109. * Adds a redirect field to the login form so blocks can redirect users after login.
  110. */
  111. public function redirect_to_field() {
  112. // phpcs:ignore WordPress.Security.NonceVerification
  113. if ( empty( $_GET['redirect_to'] ) ) {
  114. return;
  115. }
  116. echo '<input type="hidden" name="redirect" value="' . esc_attr( esc_url_raw( wp_unslash( $_GET['redirect_to'] ) ) ) . '" />'; // phpcs:ignore WordPress.Security.NonceVerification
  117. }
  118. /**
  119. * Hide legacy widgets with a feature complete block equivalent in the inserter
  120. * and prevent them from showing as an option in the Legacy Widget block.
  121. *
  122. * @param array $widget_types An array of widgets hidden in core.
  123. * @return array $widget_types An array inluding the WooCommerce widgets to hide.
  124. */
  125. public function hide_legacy_widgets_with_block_equivalent( $widget_types ) {
  126. array_push( $widget_types, 'woocommerce_product_search', 'woocommerce_product_categories', 'woocommerce_recent_reviews' );
  127. return $widget_types;
  128. }
  129. /**
  130. * Get list of block types.
  131. *
  132. * @return array
  133. */
  134. protected function get_block_types() {
  135. global $wp_version, $pagenow;
  136. $block_types = [
  137. 'AllReviews',
  138. 'FeaturedCategory',
  139. 'FeaturedProduct',
  140. 'HandpickedProducts',
  141. 'ProductBestSellers',
  142. 'ProductCategories',
  143. 'ProductCategory',
  144. 'ProductNew',
  145. 'ProductOnSale',
  146. 'ProductsByAttribute',
  147. 'ProductTopRated',
  148. 'ReviewsByProduct',
  149. 'ReviewsByCategory',
  150. 'ProductSearch',
  151. 'ProductTag',
  152. 'AllProducts',
  153. 'PriceFilter',
  154. 'AttributeFilter',
  155. 'StockFilter',
  156. 'ActiveFilters',
  157. 'LegacyTemplate',
  158. 'ProductTitle',
  159. 'ProductSummary',
  160. 'ProductStockIndicator',
  161. ];
  162. if ( Package::feature()->is_feature_plugin_build() ) {
  163. $block_types[] = 'Checkout';
  164. $block_types[] = 'Cart';
  165. }
  166. if ( Package::feature()->is_experimental_build() ) {
  167. $block_types[] = 'SingleProduct';
  168. $block_types[] = 'MiniCart';
  169. $block_types[] = 'MiniCartContents';
  170. }
  171. /**
  172. * This disables specific blocks in Widget Areas by not registering them.
  173. */
  174. if ( in_array( $pagenow, [ 'widgets.php', 'themes.php', 'customize.php' ], true ) && ( empty( $_GET['page'] ) || 'gutenberg-edit-site' !== $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
  175. $block_types = array_diff(
  176. $block_types,
  177. [
  178. 'AllProducts',
  179. 'PriceFilter',
  180. 'AttributeFilter',
  181. 'StockFilter',
  182. 'ActiveFilters',
  183. 'Cart',
  184. 'Checkout',
  185. ]
  186. );
  187. }
  188. return $block_types;
  189. }
  190. /**
  191. * Get atomic blocks types.
  192. *
  193. * @return array
  194. */
  195. protected function get_atomic_blocks() {
  196. return [
  197. 'product-button',
  198. 'product-image',
  199. 'product-price',
  200. 'product-rating',
  201. 'product-sale-badge',
  202. 'product-sku',
  203. 'product-category-list',
  204. 'product-tag-list',
  205. 'product-add-to-cart',
  206. ];
  207. }
  208. }