PluginProbe
WooCommerce / 11.1.0-rc.2
WooCommerce v11.1.0-rc.2
11.1.0 11.1.0-rc.2 11.1.0-rc.1 11.1.0-beta.2 11.1.0-beta.1 11.0.1 11.0.0 11.0.0-rc.3 11.0.0-rc.2 11.0.0-rc.1 11.0.0-beta.2 11.0.0-beta.1 10.9.4 10.9.3 10.9.2 10.9.1 10.9.0 10.9.0-rc.1 10.9.0-beta.2 10.9.0-beta.1 10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 All 648 releases
woocommerce / src / Internal / ShopperLists / ShopperListsController.php
ShopperListsController.php
175 lines 5.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 declare( strict_types = 1 );
3
4 namespace Automattic\WooCommerce\Internal\ShopperLists;
5
6 use Automattic\WooCommerce\Internal\Features\FeaturesController;
7 use Automattic\WooCommerce\Internal\RegisterHooksInterface;
8 use Automattic\WooCommerce\Internal\ShopperLists\Privacy\Privacy;
9 use Automattic\WooCommerce\Utilities\FeaturesUtil;
10
11 /**
12 * Tracks which shopper-list types are turned on and registers the
13 * user-facing pieces that depend on each.
14 *
15 * @internal Just for internal use.
16 */
17 final class ShopperListsController implements RegisterHooksInterface {
18
19 /**
20 * Known list slugs and the feature flag that controls each.
21 */
22 private const SUPPORTED_LISTS = array(
23 'saved-for-later' => 'cart_save_for_later',
24 'wishlist' => 'product_wishlist',
25 );
26
27 /**
28 * Wishlist My Account endpoint slug. Wrapped in a method (rather than
29 * a constant) so a future filter or settings hook can override it
30 * without touching every call site.
31 */
32 public function get_wishlist_endpoint(): string {
33 return 'wishlist';
34 }
35
36 /**
37 * Whether a given list type is on, or whether any list type is on
38 * when no slug is passed.
39 *
40 * @param string|null $list_slug List slug, or null to ask about any type.
41 */
42 public function is_enabled( ?string $list_slug = null ): bool {
43 if ( null === $list_slug ) {
44 foreach ( self::SUPPORTED_LISTS as $feature ) {
45 if ( FeaturesUtil::feature_is_enabled( $feature ) ) {
46 return true;
47 }
48 }
49 return false;
50 }
51 $feature = self::SUPPORTED_LISTS[ $list_slug ] ?? null;
52 return null !== $feature && FeaturesUtil::feature_is_enabled( $feature );
53 }
54
55 /**
56 * Slugs of all currently-enabled lists, in declaration order.
57 *
58 * @return string[]
59 */
60 public function get_enabled_slugs(): array {
61 return array_keys(
62 array_filter(
63 self::SUPPORTED_LISTS,
64 static fn( string $feature ): bool => FeaturesUtil::feature_is_enabled( $feature )
65 )
66 );
67 }
68
69 /**
70 * Slugs of every supported list type, regardless of feature-flag state.
71 *
72 * @return string[]
73 *
74 * @since 10.9.0
75 */
76 public function get_supported_slugs(): array {
77 return array_keys( self::SUPPORTED_LISTS );
78 }
79
80 /**
81 * Register hooks and instantiate sibling services that set up hooks on construction.
82 */
83 public function register(): void {
84 add_action( FeaturesController::FEATURE_ENABLED_CHANGED_ACTION, array( $this, 'maybe_flush_rewrite_rules' ), 10, 1 );
85 add_action( 'init', array( $this, 'maybe_register_wishlist_endpoint' ), 5 );
86
87 wc_get_container()->get( Privacy::class );
88 }
89
90 /**
91 * Register the wishlist endpoint.
92 */
93 public function maybe_register_wishlist_endpoint(): void {
94 if ( ! $this->is_enabled( 'wishlist' ) ) {
95 return;
96 }
97
98 $endpoint = $this->get_wishlist_endpoint();
99 add_filter( 'woocommerce_get_query_vars', array( $this, 'add_wishlist_query_var' ) );
100 add_filter( 'woocommerce_account_menu_items', array( $this, 'add_wishlist_menu_item' ) );
101 add_filter( 'woocommerce_endpoint_' . $endpoint . '_title', array( $this, 'wishlist_endpoint_title' ) );
102 add_action( 'woocommerce_account_' . $endpoint . '_endpoint', array( $this, 'render_wishlist_endpoint' ) );
103 }
104
105 /**
106 * Flush rewrite rules when the wishlist feature is turned on or off.
107 *
108 * @param string $feature_id The feature that changed.
109 */
110 public function maybe_flush_rewrite_rules( string $feature_id ): void {
111 if ( 'product_wishlist' === $feature_id ) {
112 update_option( 'woocommerce_queue_flush_rewrite_rules', 'yes' );
113 }
114 }
115
116 /**
117 * Register the `wishlist` query var.
118 *
119 * @param array $vars Existing query vars keyed by slug.
120 */
121 public function add_wishlist_query_var( $vars ): array {
122 if ( ! is_array( $vars ) ) {
123 return array();
124 }
125
126 $endpoint = $this->get_wishlist_endpoint();
127 $vars[ $endpoint ] = $endpoint;
128 return $vars;
129 }
130
131 /**
132 * Insert the Wishlist link just before the logout link.
133 *
134 * @param array $items Existing menu items keyed by slug.
135 */
136 public function add_wishlist_menu_item( $items ): array {
137 if ( ! is_array( $items ) ) {
138 return array();
139 }
140
141 $wishlist_endpoint = $this->get_wishlist_endpoint();
142 $wishlist_label = __( 'Wishlist', 'woocommerce' );
143
144 // Insert the wishlist item before the logout item, or at the end if not present.
145 $logout_pos = array_search( 'customer-logout', array_keys( $items ), true );
146 if ( false === $logout_pos ) {
147 $items[ $wishlist_endpoint ] = $wishlist_label;
148 } else {
149 $items = array_slice( $items, 0, $logout_pos, true )
150 + array( $wishlist_endpoint => $wishlist_label )
151 + array_slice( $items, $logout_pos, null, true );
152 }
153 return $items;
154 }
155
156 /**
157 * Wishlist endpoint page title.
158 *
159 * @param string $title Default title.
160 */
161 public function wishlist_endpoint_title( $title ): string {
162 return __( 'Wishlist', 'woocommerce' );
163 }
164
165 /**
166 * Render the wishlist endpoint by dispatching to the
167 * `woocommerce/wishlist` block. The block handles the empty state,
168 * logged-out guard, asset enqueues, and item rendering.
169 */
170 public function render_wishlist_endpoint(): void {
171 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- the block string is a static literal; `do_blocks()` invokes the registered block's render callback, which is responsible for its own escaping.
172 echo do_blocks( '<!-- wp:woocommerce/wishlist /-->' );
173 }
174 }
175