PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 5.34.2
MailPoet – Newsletters, Email Marketing, and Automation v5.34.2
5.34.2 5.34.1 5.34.0 5.33.1 5.33.0 5.32.0 5.31.0 5.30.0 5.29.0 5.28.1 5.28.0 5.27.0 5.26.0 5.26.1 5.25.0 5.24.0 4.43.0 4.43.1 4.44.0 4.44.1 4.45.0 4.46.0 4.47.0 4.48.0 4.48.1 4.48.2 4.49.0 4.49.1 4.5.0 4.5.1 4.5.2 4.50.0 4.50.1 4.51.0 4.51.1 4.51.2 4.52.0 4.53.0 4.54.0 4.55.0 4.56.0 4.57.0 4.58.0 4.58.1 4.58.2 4.6.0 4.6.1 4.6.2 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 5.0.0 5.0.1 5.0.2 5.1.0 5.1.1 5.10.0 5.10.1 5.11.0 5.12.0 5.12.1 5.12.10 5.12.11 5.12.12 5.12.13 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.12.7 5.12.8 5.12.9 5.13.0 5.13.1 5.13.2 5.14.0 5.14.1 5.14.2 5.14.3 5.15.0 5.15.1 5.16.0 5.16.1 5.16.2 5.16.3 5.16.4 5.17.0 5.17.1 5.17.2 5.17.3 5.17.4 5.17.5 5.17.6 5.18.0 5.19.0 5.2.0 5.2.1 5.2.2 5.2.3 5.20.0 5.21.0 5.21.1 5.21.2 5.21.3 5.22.0 5.22.1 5.22.2 5.22.3 5.22.4 5.23.0 5.23.1 5.23.2 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.6.3 5.6.4 5.7.0 5.7.1 5.8.0 5.8.1 5.9.0 3.0.0-beta.15 3.7.1 3.0.0-beta.16 3.7.2 3.0.0-beta.17 3.7.3 3.0.0-beta.18 3.7.4 3.0.0-beta.19 3.7.5 3.0.0-beta.2 3.7.6 3.0.0-beta.20 3.7.8 3.0.0-beta.21 3.70.0 3.0.0-beta.22 3.71.0 3.0.0-beta.23 3.71.1 3.0.0-beta.23.1 3.71.2 3.0.0-beta.23.2 3.71.3 3.0.0-beta.24 3.72.0 3.0.0-beta.25 3.73.0 3.0.0-beta.26 3.73.1 3.0.0-beta.27 3.73.2 3.0.0-beta.28 3.74.0 3.0.0-beta.29 3.74.1 3.0.0-beta.3 3.74.2 3.0.0-beta.30 3.74.3 3.0.0-beta.31 3.75.0 3.0.0-beta.32 3.75.1 3.0.0-beta.33 3.76.0 3.0.0-beta.33.1 3.77.0 3.0.0-beta.34.0.0 3.77.1 3.0.0-beta.36.0.0 3.78.0 3.0.0-beta.36.0.1 3.79.0 3.0.0-beta.36.2.0 3.8 3.0.0-beta.36.3.0 3.8.1 3.0.0-beta.36.3.1 3.8.2 3.0.0-beta.37.0.0 3.8.3 3.0.0-beta.4 3.8.4 3.0.0-beta.5 3.8.5 3.0.0-beta.6 3.8.6 3.0.0-beta.7 3.80.0 3.0.0-beta.7.1 3.81.0 3.0.0-beta.8 3.82.0 3.0.0-beta.9 3.83.0 3.0.0-rc.1.0.0 3.84.0 3.0.0-rc.1.0.1 3.84.1 3.0.0-rc.1.0.2 3.85.0 3.0.0-rc.1.0.3 3.85.1 3.0.0-rc.1.0.4 3.86.0 3.0.0-rc.2.0.0 3.87.0 3.0.0-rc.2.0.1 3.87.1 3.0.0-rc.2.0.2 3.87.2 3.0.0-rc.2.0.3 3.88.0 3.0.1 3.88.1 3.0.2 3.88.2 3.0.3 3.89.0 3.0.4 3.89.1 3.0.5 3.89.2 3.0.6 3.89.3 3.0.7 3.89.4 3.0.8 3.9.0 3.0.9 3.9.1 3.1.0 3.90.0 3.10 3.90.1 3.10.1 3.90.2 3.100.0 3.91.0 3.100.1 3.91.1 3.100.2 3.92.0 3.101.0 3.92.1 3.101.1 3.93.0 3.102.0 3.93.1 3.102.1 3.94.0 3.103.0 3.95.0 3.103.1 3.95.1 3.11.0 3.96.0 3.11.1 3.96.1 3.11.2 3.97.0 3.11.3 3.98.0 3.11.4 3.98.1 3.11.5 3.99.0 3.12.0 3.99.1 3.12.1 4.0.0 3.13.0 4.0.1 3.14.0 4.1.0 3.14.1 4.1.1 3.15.0 4.10.0 3.16.0 4.11.0 3.16.1 4.11.1 3.16.2 4.12.0 3.16.3 4.12.1 3.17.0 4.12.2 3.17.1 4.13.0 3.17.2 4.14.0 3.18.0 4.15.0 3.18.1 4.16.0 3.18.2 4.17.0 3.19.0 4.17.1 3.19.1 4.18.0 3.19.2 4.18.1 3.19.3 4.19.0 3.2.0 4.2.0 3.2.1 4.20.0 3.2.2 4.20.1 3.2.3 4.20.2 3.2.4 4.21.0 3.2.5 4.22.0 3.20.0 4.22.1 3.21.0 4.22.2 3.21.1 4.23.0 3.22.0 4.24.0 3.23.0 4.25.0 3.23.1 4.26.0 3.23.2 4.26.1 3.24.0 4.27.0 3.25.0 4.28.0 3.25.1 4.29.0 3.26.0 4.3.0 3.26.1 4.3.1 3.27.0 4.30.0 3.28.0 4.31.0 3.29.0 4.31.1 3.3.0 4.32.0 3.3.1 4.33.0 3.3.2 4.34.0 3.3.3 4.35.0 3.3.4 4.35.1 3.3.5 4.36.0 3.3.6 4.37.0 3.30.0 4.38.0 3.31.0 4.39.0 3.31.1 4.4.0 3.32.0 4.40.0 3.32.1 4.41.0 3.32.2 4.41.1 3.33.0 4.41.2 3.34.0 4.41.3 3.34.1 4.42.0 3.34.2 4.42.1 3.34.3 3.34.4 3.35.0 3.35.1 3.35.3 3.35.4 3.36.0 3.37.0 3.37.1 3.37.2 3.37.3 3.38.0 3.38.1 3.39.0 3.39.1 3.39.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.40.0 3.40.1 3.41.0 3.41.1 3.41.2 3.42.0 3.42.1 3.42.2 3.42.3 3.43.0 3.43.1 3.44.0 3.45.0 3.45.1 3.46.0 3.46.1 3.46.10 3.46.11 3.46.12 3.46.13 3.46.14 3.46.2 3.46.3 3.46.4 3.46.5 3.46.6 3.46.7 3.46.8 3.46.9 3.47.0 3.47.1 3.47.10 3.47.11 3.47.2 3.47.3 3.47.5 3.47.6 3.47.7 3.47.9 3.48.0 3.48.1 3.49.0 3.49.1 3.5.0 3.5.1 3.50.0 3.51.0 3.51.1 3.51.2 3.52.0 3.53.0 3.54.0 3.54.1 3.54.2 3.54.3 3.55.0 3.55.1 3.56.0 3.56.1 3.56.2 3.57.0 3.57.1 3.58.0 3.59.0 3.59.1 3.59.2 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.60.0 3.60.1 3.60.10 3.60.11 3.60.12 3.60.2 3.60.3 3.60.4 3.60.6 3.60.7 3.60.8 3.60.9 3.61.0 3.62.0 3.62.1 3.63.0 3.64.0 3.64.1 3.64.2 3.64.3 3.65.0 trunk 3.65.1 3.0.0 3.66.0 3.0.0-beta.1 3.67.0 3.0.0-beta.10 3.67.1 3.0.0-beta.11 3.68.0 3.0.0-beta.12 3.69.0 3.0.0-beta.13 3.69.1 3.0.0-beta.14 3.7.0
mailpoet / lib / WooCommerce / Helper.php
mailpoet / lib / WooCommerce Last commit date
Emails 2 months ago Integrations 2 months ago MultichannelMarketing 2 years ago TransactionalEmails 10 months ago WooCommerceBookings 1 month ago WooCommerceSubscriptions 2 months ago CouponPreProcessor.php 2 months ago Emails.php 8 months ago Helper.php 1 month ago MailPoetTask.php 2 years ago NonPersistablePreviewData.php 1 month ago OrderAttributionFields.php 1 month ago OrderAttributionRevenueReader.php 2 weeks ago OrderAttributionWriter.php 1 month ago RandomCouponCodeGenerator.php 2 months ago Settings.php 1 year ago SubscriberEngagement.php 3 years ago Subscription.php 2 months ago Tracker.php 2 years ago TransactionalEmailHooks.php 1 year ago TransactionalEmails.php 1 year ago WooSystemInfo.php 1 month ago WooSystemInfoController.php 1 year ago index.php 3 years ago
Helper.php
488 lines
1 <?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
2
3 namespace MailPoet\WooCommerce;
4
5 if (!defined('ABSPATH')) exit;
6
7
8 use Automattic\WooCommerce\Admin\API\Reports\Customers\Stats\DataStore;
9 use MailPoet\DI\ContainerWrapper;
10 use MailPoet\RuntimeException;
11 use MailPoet\WP\Functions as WPFunctions;
12
13 class Helper {
14 /** @var WPFunctions */
15 private $wp;
16
17 public function __construct(
18 WPFunctions $wp
19 ) {
20 $this->wp = $wp;
21 }
22
23 public function isWooCommerceActive() {
24 return class_exists('WooCommerce') && $this->wp->isPluginActive('woocommerce/woocommerce.php');
25 }
26
27 public function getWooCommerceVersion() {
28 return $this->isWooCommerceActive() ? get_plugin_data(WP_PLUGIN_DIR . '/woocommerce/woocommerce.php', false, false)['Version'] : null;
29 }
30
31 public function getPurchaseStates(): array {
32
33 return (array)$this->wp->applyFilters(
34 'mailpoet_purchase_order_states',
35 ['completed']
36 );
37 }
38
39 public function isWooCommerceBlocksActive($min_version = '') {
40 if (!class_exists('\Automattic\WooCommerce\Blocks\Package')) {
41 return false;
42 }
43 if ($min_version) {
44 return version_compare(\Automattic\WooCommerce\Blocks\Package::get_version(), $min_version, '>=');
45 }
46 return true;
47 }
48
49 public function isWooCommerceCustomOrdersTableEnabled(): bool {
50 if (
51 $this->isWooCommerceActive()
52 // Stubs reflect the current WC version; the runtime check guards older WooCommerce installs that lack this helper.
53 // @phpstan-ignore-next-line function.alreadyNarrowedType
54 && method_exists('\Automattic\WooCommerce\Utilities\OrderUtil', 'custom_orders_table_usage_is_enabled')
55 && \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled()
56 ) {
57 return true;
58 }
59
60 return false;
61 }
62
63 public function WC() {
64 return WC();
65 }
66
67 public function isWooCommerceRestApiRequest(): bool {
68 $wc = $this->WC();
69 return $wc instanceof \WooCommerce && $wc->is_rest_api_request();
70 }
71
72 public function isWooCommerceStoreApiRequest(): bool {
73 $wc = $this->WC();
74 return $wc instanceof \WooCommerce && $wc->is_store_api_request();
75 }
76
77 public function wcGetCustomerOrderCount($userId) {
78 return wc_get_customer_order_count($userId);
79 }
80
81 public function wcGetCustomer(int $userId): ?\WC_Customer {
82 if (!class_exists(\WC_Customer::class)) {
83 return null;
84 }
85 try {
86 return new \WC_Customer($userId);
87 } catch (\Throwable $e) {
88 return null;
89 }
90 }
91
92 public function wcGetOrder($order = false) {
93 return wc_get_order($order);
94 }
95
96 public function wcGetReviewOrderUrl(\WC_Order $order): string {
97 $callback = $this->getCallableFunction('wc_get_review_order_url');
98 if (!$callback) {
99 return '';
100 }
101
102 $url = $callback($order);
103 return is_string($url) ? $url : '';
104 }
105
106 public function wcSupportsOrderReviewUrl(): bool {
107 if ($this->getCallableFunction('wc_get_review_order_url') === null) {
108 return false;
109 }
110
111 if ($this->getOrderReviewItemEligibilityCallback() === null) {
112 return false;
113 }
114
115 if (!$this->isCustomerReviewRequestFeatureEnabled()) {
116 return false;
117 }
118
119 $pageId = $this->wcGetPageId('review_order');
120 if (!$pageId || $pageId < 1) {
121 return false;
122 }
123
124 $permalink = $this->wp->getPermalink($pageId);
125 return is_string($permalink) && $permalink !== '';
126 }
127
128 public function wcOrderHasActionableReviewItems(\WC_Order $order): bool {
129 $callback = $this->getOrderReviewItemEligibilityCallback();
130 if ($callback === null) {
131 return false;
132 }
133
134 return (bool)call_user_func($callback, $order);
135 }
136
137 private function getOrderReviewItemEligibilityCallback(): ?callable {
138 $callback = ['\Automattic\WooCommerce\Internal\OrderReviews\ItemEligibility', 'has_actionable_items'];
139 return is_callable($callback) ? $callback : null;
140 }
141
142 private function getCallableFunction(string $functionName): ?callable {
143 return is_callable($functionName) ? $functionName : null;
144 }
145
146 private function isCustomerReviewRequestFeatureEnabled(): bool {
147 if (!$this->canUseWooCommerceFeatureUtilities()) {
148 return false;
149 }
150
151 return \Automattic\WooCommerce\Utilities\FeaturesUtil::feature_is_enabled('customer_review_request');
152 }
153
154 public function wcGetOrders(array $args) {
155 return wc_get_orders($args);
156 }
157
158 public function wcCreateOrder(array $args) {
159 return wc_create_order($args);
160 }
161
162 public function wcPrice($price, array $args = []) {
163 return wc_price($price, $args);
164 }
165
166 public function wcGetProduct($theProduct = false) {
167 return wc_get_product($theProduct);
168 }
169
170 public function wcGetProducts(array $args) {
171 return wc_get_products($args);
172 }
173
174 public function wcGetFormattedVariation(\WC_Product_Variation $variation, bool $flat = false, bool $includeNames = true, bool $skipAttributesInName = false): string {
175 return wc_get_formatted_variation($variation, $flat, $includeNames, $skipAttributesInName);
176 }
177
178 public function wcGetPageId(string $page): ?int {
179 if ($this->isWooCommerceActive()) {
180 return (int)wc_get_page_id($page);
181 }
182 return null;
183 }
184
185 public function wcGetPriceDecimals(): int {
186 return wc_get_price_decimals();
187 }
188
189 public function wcGetPriceDecimalSeparator(): string {
190 return wc_get_price_decimal_separator();
191 }
192
193 public function wcGetPriceThousandSeparator(): string {
194 return wc_get_price_thousand_separator();
195 }
196
197 public function getWoocommercePriceFormat(): string {
198 return get_woocommerce_price_format();
199 }
200
201 public function getWoocommerceCurrency() {
202 return get_woocommerce_currency();
203 }
204
205 public function getWoocommerceCurrencySymbol() {
206 return get_woocommerce_currency_symbol();
207 }
208
209 public function woocommerceFormField($key, $args, $value) {
210 return woocommerce_form_field($key, $args, $value);
211 }
212
213 public function wcLightOrDark($color, $dark, $light) {
214 return wc_light_or_dark($color, $dark, $light);
215 }
216
217 public function wcHexIsLight($color) {
218 return wc_hex_is_light($color);
219 }
220
221 public function getOrdersCountCreatedBefore(string $dateTime): int {
222 $ordersCount = $this->wcGetOrders([
223 'status' => 'all',
224 'type' => 'shop_order',
225 'date_created' => '<' . $dateTime,
226 'limit' => 1,
227 'paginate' => true,
228 ])->total;
229
230 return intval($ordersCount);
231 }
232
233 public function getRawPrice($price, array $args = []) {
234 $htmlPrice = $this->wcPrice($price, $args);
235 return html_entity_decode(strip_tags($htmlPrice), ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401);
236 }
237
238 public function getAllowedCountries(): array {
239 return (new \WC_Countries)->get_allowed_countries() ?? [];
240 }
241
242 public function getCustomersCount(): int {
243 if (!$this->isWooCommerceActive() || !class_exists(DataStore::class)) {
244 return 0;
245 }
246
247 $dataStore = new DataStore();
248 $result = (array)$dataStore->get_data([
249 'fields' => ['customers_count'],
250 ]);
251 return isset($result['customers_count']) ? intval($result['customers_count']) : 0;
252 }
253
254 public function wasMailPoetInstalledViaWooCommerceOnboardingWizard(): bool {
255 $wp = ContainerWrapper::getInstance()->get(WPFunctions::class);
256 $installedViaWooCommerce = false;
257 $wooCommerceOnboardingProfile = $wp->getOption('woocommerce_onboarding_profile');
258
259 if (
260 is_array($wooCommerceOnboardingProfile)
261 && isset($wooCommerceOnboardingProfile['business_extensions'])
262 && is_array($wooCommerceOnboardingProfile['business_extensions'])
263 && in_array('mailpoet', $wooCommerceOnboardingProfile['business_extensions'])
264 ) {
265 $installedViaWooCommerce = true;
266 }
267
268 return $installedViaWooCommerce;
269 }
270
271 public function getOrdersTableName() {
272 // @phpstan-ignore function.impossibleType (WC stub omits this method; the runtime check is meaningful for older WC versions)
273 if (!method_exists('\Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore', 'get_orders_table_name')) {
274 throw new RuntimeException('Cannot get orders table name when running a WooCommerce version that doesn\'t support custom order tables.');
275 }
276
277 return \Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore::get_orders_table_name();
278 }
279
280 public function getAddressesTableName() {
281 // @phpstan-ignore function.impossibleType (WC stub omits this method; the runtime check is meaningful for older WC versions)
282 if (!method_exists('\Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore', 'get_addresses_table_name')) {
283 throw new RuntimeException('Cannot get addresses table name when running a WooCommerce version that doesn\'t support custom order tables.');
284 }
285
286 return \Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore::get_addresses_table_name();
287 }
288
289 public function wcGetCouponTypes(): array {
290 return wc_get_coupon_types();
291 }
292
293 public function wcGetCouponCodeById(int $id): string {
294 return wc_get_coupon_code_by_id($id);
295 }
296
297 public function wcGetCouponIdByCode(string $code): int {
298 return (int)wc_get_coupon_id_by_code($code);
299 }
300
301 /**
302 * @param mixed $data Coupon data, object, ID or code.
303 */
304 public function createWcCoupon($data) {
305 return new \WC_Coupon($data);
306 }
307
308 public function getOrderStatuses(): array {
309 return wc_get_order_statuses();
310 }
311
312 /**
313 * @return array|\WP_Post[]
314 */
315 public function getCouponList(
316 int $pageSize = 10,
317 int $pageNumber = 1,
318 ?string $discountType = null,
319 ?string $search = null,
320 array $includeCouponIds = []
321 ): array {
322 $args = [
323 'posts_per_page' => $pageSize,
324 'orderby' => 'name',
325 'order' => 'asc',
326 'post_type' => 'shop_coupon',
327 'post_status' => 'publish',
328 'paged' => $pageNumber,
329 ];
330 // Filtering coupons by discount type
331 if ($discountType) {
332 $args['meta_key'] = 'discount_type';
333 $args['meta_value'] = $discountType;
334 }
335 // Search coupon by a query string
336 if ($search) {
337 $args['s'] = $search;
338 }
339
340 $includeCoupons = [];
341 // We need to include the coupon with the given ID in the first page
342 if ($includeCouponIds && $pageNumber === 1) {
343 $includeArgs = $args;
344 $includeArgs['include'] = $includeCouponIds;
345 $includeCoupons = $this->wp->getPosts($includeArgs);
346 }
347
348 // We remove duplicates because one of the remaining pages might contain the coupon with the given ID
349 $result = array_merge($includeCoupons, $this->wp->getPosts($args));
350 $result = array_unique($result, SORT_REGULAR);
351 return array_values($result);
352 }
353
354 public function getLatestCoupon(): ?string {
355 $coupons = $this->wp->getPosts([
356 'numberposts' => 1,
357 'orderby' => 'date_created',
358 'order' => 'desc',
359 'post_type' => 'shop_coupon',
360 'post_status' => 'publish',
361 ]);
362 $coupon = reset($coupons);
363
364 return $coupon ? $coupon->post_title : null; // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
365 }
366
367 public function getPaymentGateways() {
368 return $this->WC()->payment_gateways();
369 }
370
371 /**
372 * Returns a list of all available shipping methods formatted
373 * in a way to be used in the 'used shipping method' segment.
374 */
375 public function getShippingMethodInstancesData(): array {
376 $shippingZones = \WC_Shipping_Zones::get_zones();
377 $formattedShippingMethodData = [];
378
379 foreach ($shippingZones as $shippingZone) {
380 $formattedShippingMethodData = array_merge(
381 $formattedShippingMethodData,
382 $this->formatShippingMethods($shippingZone['shipping_methods'], $shippingZone['zone_name'])
383 );
384 }
385
386 // special shipping zone that includes locations not covered by the configured shipping zones
387 $outOfCoverageShippingZone = new \WC_Shipping_Zone(0);
388 $formattedShippingMethodData = array_merge(
389 $formattedShippingMethodData,
390 $this->formatShippingMethods($outOfCoverageShippingZone->get_shipping_methods(), $outOfCoverageShippingZone->get_zone_name())
391 );
392
393 $keyedZones = [];
394
395 foreach ($formattedShippingMethodData as $shippingMethodArray) {
396 $keyedZones[$shippingMethodArray['instanceId']] = $shippingMethodArray;
397 }
398
399 return $keyedZones;
400 }
401
402 public function wcGetAttributeTaxonomies(): array {
403 return wc_get_attribute_taxonomies();
404 }
405
406 public function getWoocommerceStoreConfig(): array {
407 return [
408 'precision' => $this->wcGetPriceDecimals(),
409 'decimalSeparator' => $this->wcGetPriceDecimalSeparator(),
410 'thousandSeparator' => $this->wcGetPriceThousandSeparator(),
411 'code' => $this->getWoocommerceCurrency(),
412 'symbol' => html_entity_decode($this->getWoocommerceCurrencySymbol(), ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401),
413 'symbolPosition' => $this->wp->getOption('woocommerce_currency_pos'),
414 'priceFormat' => $this->getWoocommercePriceFormat(),
415
416 ];
417 }
418
419 protected function formatShippingMethods(array $shippingMethods, string $shippingZoneName): array {
420 $formattedShippingMethods = [];
421
422 foreach ($shippingMethods as $shippingMethod) {
423 $formattedShippingMethods[] = [
424 'instanceId' => (string)$shippingMethod->instance_id, // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
425 'name' => "{$shippingMethod->title} ({$shippingZoneName})",
426 ];
427 }
428
429 return $formattedShippingMethods;
430 }
431
432 /**
433 * Check whether the current request is processing a WooCommerce checkout.
434 * Works for both the normal checkout and the block checkout.
435 *
436 * This solution is not ideal, but I checked with a few WooCommerce developers,
437 * and it is what they suggested. There is no helper function provided by Woo
438 * for this.
439 *
440 * @return bool
441 */
442 public function isCheckoutRequest(): bool {
443 $requestUri = is_string($_SERVER['REQUEST_URI'] ?? null) && $_SERVER['REQUEST_URI'] !== ''
444 ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI']))
445 : '';
446 $isRegularCheckout = is_checkout();
447 $isBlockCheckout = WC()->is_rest_api_request()
448 && (strpos($requestUri, 'wc/store/checkout') !== false || strpos($requestUri, 'wc/store/v1/checkout') !== false);
449
450 return $isRegularCheckout || $isBlockCheckout;
451 }
452
453 public function isWooCommerceEmailImprovementsEnabled(): bool {
454 if (!$this->canUseWooCommerceFeatureUtilities()) {
455 return false;
456 }
457 return \Automattic\WooCommerce\Utilities\FeaturesUtil::feature_is_enabled('email_improvements');
458 }
459
460 private function canUseWooCommerceFeatureUtilities(): bool {
461 if (!$this->isWooCommerceActive()) {
462 return false;
463 }
464
465 if (!class_exists('\Automattic\WooCommerce\Utilities\FeaturesUtil')) {
466 return false;
467 }
468
469 return function_exists('wc_get_container');
470 }
471
472 public function wcPlaceholderImgSrc(string $size = 'woocommerce_thumbnail'): string {
473 if (!$this->isWooCommerceActive() || !function_exists('wc_placeholder_img_src')) {
474 return '';
475 }
476
477 return wc_placeholder_img_src($size);
478 }
479
480 public function wcGetPagePermalink(string $page): string {
481 if (!$this->isWooCommerceActive() || !function_exists('wc_get_page_permalink')) {
482 return '';
483 }
484
485 return wc_get_page_permalink($page);
486 }
487 }
488