PluginProbe
Tiered Pricing Table for WooCommerce / 6.4.0
Tiered Pricing Table for WooCommerce v6.4.0
8.0.2 7.1.7 7.1.5 7.1.4 7.1.1 6.5.0 6.4.0 6.1.0 trunk 1.0 1.1 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.3.0 2.3.1 2.3.2 2.3.3 All 91 releases
tier-pricing-table / src / Addons / GlobalTieredPricing / GlobalPricingRule.php

GlobalPricingRule.php in Tiered Pricing Table for WooCommerce 6.4.0, at src/Addons/GlobalTieredPricing/GlobalPricingRule.php

752 lines 25.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace TierPricingTable\Addons\GlobalTieredPricing;
4
5 use TierPricingTable\Addons\GlobalTieredPricing\PricingRule\RuleSettings;
6 use TierPricingTable\Forms\Form;
7 use Exception;
8 use WC_Product;
9 use WP_User;
10 class GlobalPricingRule {
11 /**
12 * Rule ID
13 *
14 * @var int
15 */
16 public $id;
17
18 /**
19 * Is suspended
20 *
21 * @var bool
22 */
23 public $isSuspended = false;
24
25 /**
26 * Regular pricing type
27 *
28 * @var string
29 */
30 public $pricingType;
31
32 /**
33 * Regular price
34 *
35 * @var ?float
36 */
37 public $regularPrice;
38
39 /**
40 * Sale price
41 *
42 * @var ?float
43 */
44 public $salePrice;
45
46 /**
47 * Percentage Discount
48 *
49 * @var ?float
50 */
51 public $discount;
52
53 /**
54 * Percentage Discount
55 *
56 * @var string
57 */
58 public $discountType = 'sale_price';
59
60 /**
61 * Applying type
62 *
63 * @var string
64 */
65 public $applyingType;
66
67 /**
68 * Tax status
69 *
70 * @var string
71 */
72 public $taxStatus = '';
73
74 /**
75 * Tax class
76 *
77 * @var string
78 */
79 public $taxClass = '';
80
81 /**
82 * Tiered Pricing type
83 *
84 * @var string
85 */
86 public $tieredPricingType;
87
88 /**
89 * Percentage Tiered Pricing Rules
90 *
91 * @var array
92 */
93 public $percentageTieredPricingRules = array();
94
95 /**
96 * Fixed Tiered Pricing Rules
97 *
98 * @var array
99 */
100 public $fixedTieredPricingRules = array();
101
102 /**
103 * Included categories
104 *
105 * @var array
106 */
107 public $includedProductCategories = array();
108
109 /**
110 * Excluded categories
111 *
112 * @var array
113 */
114 public $excludedProductCategories = array();
115
116 /**
117 * Included tags
118 *
119 * @var array
120 */
121 public $includedProductTags = array();
122
123 /**
124 * Excluded tags
125 *
126 * @var array
127 */
128 public $excludedProductTags = array();
129
130 /**
131 * Included brands
132 *
133 * @var array
134 */
135 public $includedProductBrands = array();
136
137 /**
138 * Excluded brands
139 *
140 * @var array
141 */
142 public $excludedProductBrands = array();
143
144 /**
145 * Included products
146 *
147 * @var array
148 */
149 public $includedProducts = array();
150
151 /**
152 * Excluded products
153 *
154 * @var array
155 */
156 public $excludedProducts = array();
157
158 /**
159 * Included product roles
160 *
161 * @var array
162 */
163 public $includedUsersRole = array();
164
165 /**
166 * Excluded product roles
167 *
168 * @var array
169 */
170 public $excludedUsersRole = array();
171
172 /**
173 * Included users
174 *
175 * @var array
176 */
177 public $includedUsers = array();
178
179 /**
180 * Excluded users
181 *
182 * @var array
183 */
184 public $excludedUsers = array();
185
186 /**
187 * Product minimum purchase quantity
188 *
189 * @var int
190 */
191 public $minimum;
192
193 public $priorityOptions;
194
195 /**
196 * Array with custom data from 3rd-party addons
197 *
198 * @var array
199 */
200 public $data = array();
201
202 public function getId() : int {
203 return $this->id;
204 }
205
206 public function setId( int $id ) {
207 $this->id = $id;
208 }
209
210 public function getDiscount() : ?float {
211 return $this->discount;
212 }
213
214 public function setDiscount( ?float $discount ) {
215 $this->discount = $discount;
216 }
217
218 public function getDiscountType() : string {
219 return $this->discountType;
220 }
221
222 public function setDiscountType( string $discountType ) {
223 $this->discountType = ( in_array( $discountType, array('sale_price', 'regular_price') ) ? $discountType : 'sale_price' );
224 }
225
226 public function getTieredPricingType() : string {
227 return 'fixed';
228 }
229
230 public function setTieredPricingType( string $tieredPricingType ) {
231 $this->tieredPricingType = ( in_array( $tieredPricingType, array('percentage', 'fixed') ) ? $tieredPricingType : 'fixed' );
232 }
233
234 public function getPercentageTieredPricingRules() : array {
235 return $this->percentageTieredPricingRules;
236 }
237
238 public function setPercentageTieredPricingRules( array $percentageTieredPricingRules ) {
239 $this->percentageTieredPricingRules = $percentageTieredPricingRules;
240 }
241
242 public function getFixedTieredPricingRules() : array {
243 return $this->fixedTieredPricingRules;
244 }
245
246 public function setFixedTieredPricingRules( array $fixedTieredPricingRules ) {
247 $this->fixedTieredPricingRules = $fixedTieredPricingRules;
248 }
249
250 public function getApplyingType() : string {
251 return $this->applyingType;
252 }
253
254 public function setApplyingType( string $applyingType ) {
255 $this->applyingType = ( in_array( $applyingType, array('individual', 'cross') ) ? $applyingType : 'cross' );
256 }
257
258 public function getPricingType() : string {
259 return $this->pricingType;
260 }
261
262 public function setPricingType( string $priceType ) {
263 $this->pricingType = ( in_array( $priceType, array('percentage', 'flat') ) ? $priceType : 'flat' );
264 }
265
266 public function getTieredPricingRules() : array {
267 return $this->getFixedTieredPricingRules();
268 }
269
270 public function getTaxStatus() : string {
271 return $this->taxStatus;
272 }
273
274 public function setTaxStatus( string $taxStatus ) {
275 $this->taxStatus = $taxStatus;
276 }
277
278 public function getTaxClass() : string {
279 return $this->taxClass;
280 }
281
282 public function setTaxClass( string $taxClass ) {
283 $this->taxClass = $taxClass;
284 }
285
286 public function getRegularPrice() : ?float {
287 return $this->regularPrice;
288 }
289
290 public function setRegularPrice( ?float $regularPrice ) {
291 $this->regularPrice = ( !Form::isEmpty( $regularPrice ) ? floatval( $regularPrice ) : null );
292 }
293
294 public function getSalePrice() : ?float {
295 return $this->salePrice;
296 }
297
298 public function setSalePrice( ?float $salePrice ) {
299 $this->salePrice = $salePrice;
300 }
301
302 /**
303 * Create instance from array
304 *
305 * @param array $data
306 *
307 * @return self
308 */
309 public static function fromArray( array $data ) : self {
310 $applyingType = $data['applying_type'] ?? 'individual';
311 $applyingType = ( in_array( $applyingType, array('individual', 'cross') ) ? $applyingType : 'cross' );
312 $tieredPricingType = $data['tiered_pricing_type'] ?? 'fixed';
313 $tieredPricingType = ( in_array( $tieredPricingType, array('flat', 'percentage') ) ? $tieredPricingType : 'fixed' );
314 $percentageRules = ( isset( $data['percentage_rules'] ) ? (array) $data['percentage_rules'] : array() );
315 $fixedRules = ( isset( $data['fixed_rules'] ) ? (array) $data['fixed_rules'] : array() );
316 $pricingType = $data['pricing_type'] ?? 'flat';
317 $pricingType = ( in_array( $pricingType, array('flat', 'percentage') ) ? $pricingType : 'flat' );
318 $regularPrice = $data['regular_price'] ?? null;
319 $salePrice = $data['sale_price'] ?? null;
320 $discount = $data['discount'] ?? null;
321 $discountType = $data['discount_type'] ?? 'sale_price';
322 $minimum = $data['minimum'] ?? null;
323 $taxStatus = $data['tax_status'] ?? '';
324 $taxClass = $data['tax_class'] ?? '';
325 $self = new self();
326 $self->setTaxStatus( $taxStatus );
327 $self->setTaxClass( $taxClass );
328 $self->setPricingType( (string) $pricingType );
329 $self->setRegularPrice( ( Form::isEmpty( $regularPrice ) ? null : (float) $regularPrice ) );
330 $self->setSalePrice( ( Form::isEmpty( $salePrice ) ? null : (float) $salePrice ) );
331 $self->setDiscount( ( Form::isEmpty( $discount ) ? null : (float) $discount ) );
332 $self->setDiscountType( (string) $discountType );
333 $self->setApplyingType( $applyingType );
334 $self->setTieredPricingType( $tieredPricingType );
335 $self->setPercentageTieredPricingRules( $percentageRules );
336 $self->setFixedTieredPricingRules( $fixedRules );
337 $self->setMinimum( ( Form::isEmpty( $minimum ) ? null : (int) $minimum ) );
338 return $self;
339 }
340
341 /**
342 * Validate
343 *
344 * @throws Exception
345 */
346 public function validatePricing() {
347 $valid = !Form::isEmpty( $this->getRegularPrice() );
348 $valid = $valid || !Form::isEmpty( $this->getSalePrice() );
349 $valid = $valid || !empty( $this->getTieredPricingRules() );
350 $valid = $valid || !Form::isEmpty( $this->getMinimum() );
351 $valid = $valid || !Form::isEmpty( $this->getDiscount() );
352 $valid = $valid || $this->getSettings()->getPriorityType() === 'flexible';
353 $valid = apply_filters( 'tiered_pricing_table/global_pricing/validation', $valid, $this );
354 if ( !$valid ) {
355 throw new Exception(esc_html__( 'The pricing rule does not affect either prices or product quantity. The rule will be skipped.', 'tier-pricing-table' ));
356 }
357 }
358
359 public function isValidPricing() : bool {
360 try {
361 $this->validatePricing();
362 } catch ( Exception $e ) {
363 return false;
364 }
365 return true;
366 }
367
368 public function getMinimum() : ?int {
369 return $this->minimum;
370 }
371
372 public function setMinimum( ?int $minimum ) {
373 $this->minimum = ( intval( $minimum ) > 1 ? $minimum : null );
374 }
375
376 public function getIncludedProductCategories() : array {
377 return $this->includedProductCategories;
378 }
379
380 public function getExcludedProductCategories() : array {
381 return $this->excludedProductCategories;
382 }
383
384 public function setIncludedProductCategories( array $includedProductCategories ) {
385 $this->includedProductCategories = $includedProductCategories;
386 }
387
388 public function setExcludedProductCategories( array $excludedProductCategories ) {
389 $this->excludedProductCategories = $excludedProductCategories;
390 }
391
392 public function getIncludedProductTags() : array {
393 return $this->includedProductTags;
394 }
395
396 public function getExcludedProductTags() : array {
397 return $this->excludedProductTags;
398 }
399
400 public function setIncludedProductTags( array $includedProductTags ) {
401 $this->includedProductTags = $includedProductTags;
402 }
403
404 public function setExcludedProductTags( array $excludedProductTags ) {
405 $this->excludedProductTags = $excludedProductTags;
406 }
407
408 public function getIncludedProductBrands() : array {
409 return $this->includedProductBrands;
410 }
411
412 public function getExcludedProductBrands() : array {
413 return $this->excludedProductBrands;
414 }
415
416 public function setIncludedProductBrands( array $includedProductBrands ) {
417 $this->includedProductBrands = $includedProductBrands;
418 }
419
420 public function setExcludedProductBrands( array $excludedProductBrands ) {
421 $this->excludedProductBrands = $excludedProductBrands;
422 }
423
424 public function getIncludedProducts() : array {
425 return $this->includedProducts;
426 }
427
428 public function getExcludedProducts() : array {
429 return $this->excludedProducts;
430 }
431
432 public function setIncludedProducts( array $includedProducts ) {
433 $this->includedProducts = $includedProducts;
434 }
435
436 public function setExcludedProducts( array $excludedProducts ) {
437 $this->excludedProducts = $excludedProducts;
438 }
439
440 public function getIncludedUserRoles() : array {
441 return $this->includedUsersRole;
442 }
443
444 public function getExcludedUserRoles() : array {
445 return $this->excludedUsersRole;
446 }
447
448 public function setIncludedUsersRole( array $includedUsersRole ) {
449 $this->includedUsersRole = $includedUsersRole;
450 }
451
452 public function setExcludedUsersRole( array $excludedUsersRole ) {
453 $this->excludedUsersRole = $excludedUsersRole;
454 }
455
456 public function getIncludedUsers() : array {
457 return $this->includedUsers;
458 }
459
460 public function getExcludedUsers() : array {
461 return $this->excludedUsers;
462 }
463
464 public function setIncludedUsers( array $includedUsers ) {
465 $this->includedUsers = $includedUsers;
466 }
467
468 public function setExcludedUsers( array $excludedUsers ) {
469 $this->excludedUsers = $excludedUsers;
470 }
471
472 public function getSettings() : RuleSettings {
473 if ( !$this->priorityOptions ) {
474 $this->priorityOptions = new RuleSettings($this);
475 }
476 return $this->priorityOptions;
477 }
478
479 public function asArray() : array {
480 return array(
481 'pricing_type' => $this->getPricingType(),
482 'regular_price' => $this->getRegularPrice(),
483 'sale_price' => $this->getSalePrice(),
484 'discount' => $this->getDiscount(),
485 'discount_type' => $this->getDiscountType(),
486 'applying_type' => $this->getApplyingType(),
487 'tiered_pricing_type' => $this->getTieredPricingType(),
488 'percentage_rules' => $this->getPercentageTieredPricingRules(),
489 'fixed_rules' => $this->getFixedTieredPricingRules(),
490 'minimum' => $this->getMinimum(),
491 'tax_status' => $this->getTaxStatus(),
492 'tax_class' => $this->getTaxClass(),
493 'included_categories' => $this->getIncludedProductCategories(),
494 'included_tags' => $this->getIncludedProductTags(),
495 'included_brands' => $this->getIncludedProductBrands(),
496 'included_products' => $this->getIncludedProducts(),
497 'included_users' => $this->getIncludedUsers(),
498 'included_users_role' => $this->getIncludedUserRoles(),
499 'excluded_categories' => $this->getExcludedProductCategories(),
500 'excluded_tags' => $this->getExcludedProductTags(),
501 'excluded_brands' => $this->getExcludedProductBrands(),
502 'excluded_products' => $this->getExcludedProducts(),
503 'excluded_users' => $this->getExcludedUsers(),
504 'excluded_users_role' => $this->getExcludedUserRoles(),
505 'rule_id' => $this->getId(),
506 'is_suspended' => $this->isSuspended(),
507 );
508 }
509
510 public function save() {
511 $dataToUpdate = array(
512 '_tpt_pricing_type' => $this->getPricingType(),
513 '_tpt_regular_price' => $this->getRegularPrice(),
514 '_tpt_sale_price' => $this->getSalePrice(),
515 '_tpt_discount' => $this->getDiscount(),
516 '_tpt_discount_type' => $this->getDiscountType(),
517 '_tpt_applying_type' => $this->getApplyingType(),
518 '_tpt_tiered_pricing_type' => $this->getTieredPricingType(),
519 '_tpt_percentage_rules' => $this->getPercentageTieredPricingRules(),
520 '_tpt_fixed_rules' => $this->getFixedTieredPricingRules(),
521 '_tpt_minimum' => $this->getMinimum(),
522 '_tpt_tax_status' => $this->getTaxStatus(),
523 '_tpt_tax_class' => $this->getTaxClass(),
524 '_tpt_included_categories' => $this->getIncludedProductCategories(),
525 '_tpt_included_tags' => $this->getIncludedProductTags(),
526 '_tpt_included_brands' => $this->getIncludedProductBrands(),
527 '_tpt_included_products' => $this->getIncludedProducts(),
528 '_tpt_included_users' => $this->getIncludedUsers(),
529 '_tpt_included_user_roles' => $this->getIncludedUserRoles(),
530 '_tpt_excluded_categories' => $this->getExcludedProductCategories(),
531 '_tpt_excluded_tags' => $this->getExcludedProductTags(),
532 '_tpt_excluded_brands' => $this->getExcludedProductBrands(),
533 '_tpt_excluded_products' => $this->getExcludedProducts(),
534 '_tpt_excluded_users' => $this->getExcludedUsers(),
535 '_tpt_excluded_user_roles' => $this->getExcludedUserRoles(),
536 '_tpt_is_suspended' => wc_bool_to_string( $this->isSuspended() ),
537 );
538 foreach ( $dataToUpdate as $key => $value ) {
539 update_post_meta( $this->getId(), $key, $value );
540 }
541 }
542
543 public static function build( $ruleId ) : self {
544 // Simple data to read
545 $dataToRead = array(
546 '_tpt_pricing_type' => 'pricing_type',
547 '_tpt_sale_price' => 'sale_price',
548 '_tpt_regular_price' => 'regular_price',
549 '_tpt_discount' => 'discount',
550 '_tpt_discount_type' => 'discount_type',
551 '_tpt_applying_type' => 'applying_type',
552 '_tpt_tiered_pricing_type' => 'tiered_pricing_type',
553 '_tpt_minimum' => 'minimum',
554 '_tpt_tax_status' => 'tax_status',
555 '_tpt_tax_class' => 'tax_class',
556 '_tpt_is_suspended' => 'is_suspended',
557 );
558 $data = array();
559 foreach ( $dataToRead as $key => $name ) {
560 $data[$name] = get_post_meta( $ruleId, $key, true );
561 }
562 $priceRule = self::fromArray( $data );
563 $existingRoles = wp_roles()->roles;
564 $includedCategoriesIds = array_filter( array_map( 'intval', (array) get_post_meta( $ruleId, '_tpt_included_categories', true ) ) );
565 $includedTagsIds = array_filter( array_map( 'intval', (array) get_post_meta( $ruleId, '_tpt_included_tags', true ) ) );
566 $includedBrandsIds = array_filter( array_map( 'intval', (array) get_post_meta( $ruleId, '_tpt_included_brands', true ) ) );
567 $includedProductsIds = array_filter( array_map( 'intval', (array) get_post_meta( $ruleId, '_tpt_included_products', true ) ) );
568 $includedUsersRole = array_filter( (array) get_post_meta( $ruleId, '_tpt_included_user_roles', true ), function ( $role ) use($existingRoles) {
569 return array_key_exists( $role, $existingRoles );
570 } );
571 $includedUsers = array_filter( array_map( 'intval', (array) get_post_meta( $ruleId, '_tpt_included_users', true ) ) );
572 $excludedCategoriesIds = array_filter( array_map( 'intval', (array) get_post_meta( $ruleId, '_tpt_excluded_categories', true ) ) );
573 $excludedTagsIds = array_filter( array_map( 'intval', (array) get_post_meta( $ruleId, '_tpt_excluded_tags', true ) ) );
574 $excludedBrandsIds = array_filter( array_map( 'intval', (array) get_post_meta( $ruleId, '_tpt_excluded_brands', true ) ) );
575 $excludedProductsIds = array_filter( array_map( 'intval', (array) get_post_meta( $ruleId, '_tpt_excluded_products', true ) ) );
576 $excludedUsersRole = array_filter( (array) get_post_meta( $ruleId, '_tpt_excluded_user_roles', true ), function ( $role ) use($existingRoles) {
577 return array_key_exists( $role, $existingRoles );
578 } );
579 $excludedUsers = array_filter( array_map( 'intval', (array) get_post_meta( $ruleId, '_tpt_excluded_users', true ) ) );
580 $isSuspended = get_post_meta( $ruleId, '_tpt_is_suspended', true ) === 'yes';
581 $priceRule->setPercentageTieredPricingRules( self::readPricingRules( 'percentage', $ruleId ) );
582 $priceRule->setFixedTieredPricingRules( self::readPricingRules( 'fixed', $ruleId ) );
583 $priceRule->setIncludedProductCategories( $includedCategoriesIds );
584 $priceRule->setIncludedProductTags( $includedTagsIds );
585 $priceRule->setIncludedProductBrands( $includedBrandsIds );
586 $priceRule->setIncludedUsers( $includedUsers );
587 $priceRule->setIncludedUsersRole( $includedUsersRole );
588 $priceRule->setIncludedProducts( $includedProductsIds );
589 $priceRule->setExcludedProductCategories( $excludedCategoriesIds );
590 $priceRule->setExcludedProductTags( $excludedTagsIds );
591 $priceRule->setExcludedProductBrands( $excludedBrandsIds );
592 $priceRule->setExcludedUsers( $excludedUsers );
593 $priceRule->setExcludedUsersRole( $excludedUsersRole );
594 $priceRule->setExcludedProducts( $excludedProductsIds );
595 $priceRule->setIsSuspended( $isSuspended );
596 $priceRule->setId( $ruleId );
597 return apply_filters( 'tiered_pricing_table/global_pricing/after_built_rule', $priceRule );
598 }
599
600 protected static function readPricingRules( $type, $id ) : array {
601 $type = ( in_array( $type, array('percentage', 'fixed') ) ? $type : 'fixed' );
602 $rules = get_post_meta( $id, "_tpt_{$type}_rules", true );
603 $rules = ( !empty( $rules ) ? $rules : array() );
604 $rules = ( is_array( $rules ) ? array_filter( $rules ) : array() );
605 ksort( $rules );
606 return $rules;
607 }
608
609 public function setIsSuspended( bool $isSuspended ) {
610 $this->isSuspended = $isSuspended;
611 }
612
613 public function suspend() {
614 $this->setIsSuspended( true );
615 }
616
617 public function reactivate() {
618 $this->setIsSuspended( false );
619 }
620
621 public function isSuspended() : bool {
622 return $this->isSuspended;
623 }
624
625 /**
626 * Wrapper for the main "match" function to provide the hook for 3rd party devs
627 *
628 * @param WP_User $user
629 * @param WC_Product $product
630 *
631 * @return bool
632 */
633 public function matchRequirements( WP_User $user, WC_Product $product ) : bool {
634 $matched = $this->_matchRequirements( $user, $product );
635 return apply_filters(
636 'tiered_pricing_table/global_pricing/match_requirements',
637 $matched,
638 $this,
639 $user,
640 $product
641 );
642 }
643
644 protected function _matchRequirements( WP_User $user, WC_Product $product ) : bool {
645 $parentProduct = ( $product->is_type( array('variation', 'subscription-variation') ) ? wc_get_product( $product->get_parent_id() ) : $product );
646 /**
647 * 1. Check for product exclusion
648 *
649 * If the product in exclusion - pricing rule does not match immediately
650 */
651 if ( !empty( $this->getExcludedProducts() ) ) {
652 if ( in_array( $product->get_id(), $this->getExcludedProducts() ) || in_array( $parentProduct->get_id(), $this->getExcludedProducts() ) ) {
653 return false;
654 }
655 }
656 if ( !empty( $this->getExcludedProductCategories() ) ) {
657 if ( !empty( array_intersect( $parentProduct->get_category_ids(), $this->getExcludedProductCategories() ) ) ) {
658 return false;
659 }
660 }
661 if ( !empty( $this->getExcludedProductTags() ) ) {
662 if ( !empty( array_intersect( $parentProduct->get_tag_ids(), $this->getExcludedProductTags() ) ) ) {
663 return false;
664 }
665 }
666 if ( !empty( $this->getExcludedProductBrands() ) ) {
667 $productBrands = wp_get_post_terms( $parentProduct->get_id(), 'product_brand', array(
668 'fields' => 'ids',
669 ) );
670 if ( is_wp_error( $productBrands ) ) {
671 $productBrands = [];
672 }
673 if ( !empty( array_intersect( $productBrands, $this->getExcludedProductBrands() ) ) ) {
674 return false;
675 }
676 }
677 /**
678 * 2. Check for user exclusion
679 *
680 * If users in exclusion - pricing rule does not match immediately
681 */
682 if ( in_array( $user->ID, $this->getExcludedUsers() ) ) {
683 return false;
684 }
685 foreach ( $this->getExcludedUserRoles() as $role ) {
686 if ( in_array( $role, $user->roles ) ) {
687 return false;
688 }
689 }
690 /**
691 * 3. Check for rule limitation for specific products
692 *
693 * If yes - match rule only for selected product/product categories
694 */
695 $productMatched = false;
696 $productLimitations = false;
697 if ( !empty( $this->getIncludedProducts() ) ) {
698 $productLimitations = true;
699 if ( in_array( $product->get_id(), $this->getIncludedProducts() ) || in_array( $parentProduct->get_id(), $this->getIncludedProducts() ) ) {
700 $productMatched = true;
701 }
702 }
703 if ( !empty( $this->getIncludedProductCategories() ) ) {
704 $productLimitations = true;
705 if ( !empty( array_intersect( $parentProduct->get_category_ids(), $this->getIncludedProductCategories() ) ) ) {
706 $productMatched = true;
707 }
708 }
709 if ( !empty( $this->getIncludedProductTags() ) ) {
710 $productLimitations = true;
711 if ( !empty( array_intersect( $parentProduct->get_tag_ids(), $this->getIncludedProductTags() ) ) ) {
712 $productMatched = true;
713 }
714 }
715 if ( !empty( $this->getIncludedProductBrands() ) ) {
716 $productLimitations = true;
717 $productBrands = wp_get_post_terms( $parentProduct->get_id(), 'product_brand', array(
718 'fields' => 'ids',
719 ) );
720 if ( is_wp_error( $productBrands ) ) {
721 $productBrands = [];
722 }
723 if ( !empty( array_intersect( $productBrands, $this->getIncludedProductBrands() ) ) ) {
724 $productMatched = true;
725 }
726 }
727 // There is product limitation and the product/category does not match the rule
728 if ( $productLimitations && !$productMatched ) {
729 return false;
730 }
731 /**
732 * 4. If there are no user limits - match the rule immediately
733 */
734 if ( empty( $this->getIncludedUserRoles() ) && empty( $this->getIncludedUsers() ) ) {
735 return true;
736 }
737 /**
738 * 5. If there are user limits - check for user ID and user role.
739 */
740 if ( in_array( $user->ID, $this->getIncludedUsers() ) ) {
741 return true;
742 }
743 foreach ( $this->getIncludedUserRoles() as $role ) {
744 if ( in_array( $role, $user->roles ) ) {
745 return true;
746 }
747 }
748 return false;
749 }
750
751 }
752