PluginProbe
Tiered Pricing Table for WooCommerce / 7.1.1
Tiered Pricing Table for WooCommerce v7.1.1
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 7.1.1, at src/Addons/GlobalTieredPricing/GlobalPricingRule.php

773 lines 26.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|null
190 */
191 public $minimum;
192
193 /**
194 * Mix and match minimum quantity
195 *
196 * @var bool|null
197 */
198 public $mixAndMatchMinQuantity = null;
199
200 public $priorityOptions;
201
202 /**
203 * Array with custom data from 3rd-party addons
204 *
205 * @var array
206 */
207 public $data = array();
208
209 public function getId() : int {
210 return $this->id;
211 }
212
213 public function setId( int $id ) {
214 $this->id = $id;
215 }
216
217 public function getDiscount() : ?float {
218 return $this->discount;
219 }
220
221 public function setDiscount( ?float $discount ) {
222 $this->discount = $discount;
223 }
224
225 public function getDiscountType() : string {
226 return $this->discountType;
227 }
228
229 public function setDiscountType( string $discountType ) {
230 $this->discountType = ( in_array( $discountType, array('sale_price', 'regular_price') ) ? $discountType : 'sale_price' );
231 }
232
233 public function getTieredPricingType() : string {
234 return 'fixed';
235 }
236
237 public function setTieredPricingType( string $tieredPricingType ) {
238 $this->tieredPricingType = ( in_array( $tieredPricingType, array('percentage', 'fixed') ) ? $tieredPricingType : 'fixed' );
239 }
240
241 public function getPercentageTieredPricingRules() : array {
242 return $this->percentageTieredPricingRules;
243 }
244
245 public function setPercentageTieredPricingRules( array $percentageTieredPricingRules ) {
246 $this->percentageTieredPricingRules = $percentageTieredPricingRules;
247 }
248
249 public function getFixedTieredPricingRules() : array {
250 return $this->fixedTieredPricingRules;
251 }
252
253 public function setFixedTieredPricingRules( array $fixedTieredPricingRules ) {
254 $this->fixedTieredPricingRules = $fixedTieredPricingRules;
255 }
256
257 public function getApplyingType() : string {
258 return $this->applyingType;
259 }
260
261 public function setApplyingType( string $applyingType ) {
262 $this->applyingType = ( in_array( $applyingType, array('individual', 'cross') ) ? $applyingType : 'cross' );
263 }
264
265 public function getPricingType() : string {
266 return $this->pricingType;
267 }
268
269 public function setPricingType( string $priceType ) {
270 $this->pricingType = ( in_array( $priceType, array('percentage', 'flat') ) ? $priceType : 'flat' );
271 }
272
273 public function getTieredPricingRules() : array {
274 return $this->getFixedTieredPricingRules();
275 }
276
277 public function getTaxStatus() : string {
278 return $this->taxStatus;
279 }
280
281 public function setTaxStatus( string $taxStatus ) {
282 $this->taxStatus = $taxStatus;
283 }
284
285 public function getTaxClass() : string {
286 return $this->taxClass;
287 }
288
289 public function setTaxClass( string $taxClass ) {
290 $this->taxClass = $taxClass;
291 }
292
293 public function getRegularPrice() : ?float {
294 return $this->regularPrice;
295 }
296
297 public function setRegularPrice( ?float $regularPrice ) {
298 $this->regularPrice = ( !Form::isEmpty( $regularPrice ) ? floatval( $regularPrice ) : null );
299 }
300
301 public function getSalePrice() : ?float {
302 return $this->salePrice;
303 }
304
305 public function setSalePrice( ?float $salePrice ) {
306 $this->salePrice = $salePrice;
307 }
308
309 /**
310 * Create instance from array
311 *
312 * @param array $data
313 *
314 * @return self
315 */
316 public static function fromArray( array $data ) : self {
317 $applyingType = $data['applying_type'] ?? 'individual';
318 $applyingType = ( in_array( $applyingType, array('individual', 'cross') ) ? $applyingType : 'cross' );
319 $tieredPricingType = $data['tiered_pricing_type'] ?? 'fixed';
320 $tieredPricingType = ( in_array( $tieredPricingType, array('flat', 'percentage') ) ? $tieredPricingType : 'fixed' );
321 $percentageRules = ( isset( $data['percentage_rules'] ) ? (array) $data['percentage_rules'] : array() );
322 $fixedRules = ( isset( $data['fixed_rules'] ) ? (array) $data['fixed_rules'] : array() );
323 $pricingType = $data['pricing_type'] ?? 'flat';
324 $pricingType = ( in_array( $pricingType, array('flat', 'percentage') ) ? $pricingType : 'flat' );
325 $regularPrice = $data['regular_price'] ?? null;
326 $salePrice = $data['sale_price'] ?? null;
327 $discount = $data['discount'] ?? null;
328 $discountType = $data['discount_type'] ?? 'sale_price';
329 $minimum = $data['minimum'] ?? null;
330 $mixAndMatchValue = $data['mix_and_match_minimum'] ?? '';
331 $mixAndMatch = ( $mixAndMatchValue === '' ? null : $mixAndMatchValue === 'yes' );
332 $taxStatus = $data['tax_status'] ?? '';
333 $taxClass = $data['tax_class'] ?? '';
334 $self = new self();
335 $self->setTaxStatus( $taxStatus );
336 $self->setTaxClass( $taxClass );
337 $self->setPricingType( (string) $pricingType );
338 $self->setRegularPrice( ( Form::isEmpty( $regularPrice ) ? null : (float) $regularPrice ) );
339 $self->setSalePrice( ( Form::isEmpty( $salePrice ) ? null : (float) $salePrice ) );
340 $self->setDiscount( ( Form::isEmpty( $discount ) ? null : (float) $discount ) );
341 $self->setDiscountType( (string) $discountType );
342 $self->setApplyingType( $applyingType );
343 $self->setTieredPricingType( $tieredPricingType );
344 $self->setPercentageTieredPricingRules( $percentageRules );
345 $self->setFixedTieredPricingRules( $fixedRules );
346 $self->setMinimum( ( Form::isEmpty( $minimum ) ? null : (int) $minimum ) );
347 $self->setMixAndMatchMinQuantity( $mixAndMatch );
348 return $self;
349 }
350
351 /**
352 * Validate
353 *
354 * @throws Exception
355 */
356 public function validatePricing() {
357 $valid = !Form::isEmpty( $this->getRegularPrice() );
358 $valid = $valid || !Form::isEmpty( $this->getSalePrice() );
359 $valid = $valid || !empty( $this->getTieredPricingRules() );
360 $valid = $valid || !Form::isEmpty( $this->getMinimum() );
361 $valid = $valid || !Form::isEmpty( $this->getDiscount() );
362 $valid = $valid || $this->getSettings()->getPriorityType() === 'flexible';
363 $valid = apply_filters( 'tiered_pricing_table/global_pricing/validation', $valid, $this );
364 if ( !$valid ) {
365 throw new Exception(esc_html__( 'The pricing rule does not affect either prices or product quantity. The rule will be skipped.', 'tier-pricing-table' ));
366 }
367 }
368
369 public function isValidPricing() : bool {
370 try {
371 $this->validatePricing();
372 } catch ( Exception $e ) {
373 return false;
374 }
375 return true;
376 }
377
378 public function getMinimum() : ?int {
379 return $this->minimum;
380 }
381
382 public function setMinimum( ?int $minimum ) {
383 $this->minimum = ( intval( $minimum ) > 1 ? $minimum : null );
384 }
385
386 public function getMixAndMatchMinQuantity() : ?bool {
387 return $this->mixAndMatchMinQuantity;
388 }
389
390 public function setMixAndMatchMinQuantity( ?bool $mixAndMatch ) {
391 $this->mixAndMatchMinQuantity = $mixAndMatch;
392 }
393
394 public function getIncludedProductCategories() : array {
395 return $this->includedProductCategories;
396 }
397
398 public function getExcludedProductCategories() : array {
399 return $this->excludedProductCategories;
400 }
401
402 public function setIncludedProductCategories( array $includedProductCategories ) {
403 $this->includedProductCategories = $includedProductCategories;
404 }
405
406 public function setExcludedProductCategories( array $excludedProductCategories ) {
407 $this->excludedProductCategories = $excludedProductCategories;
408 }
409
410 public function getIncludedProductTags() : array {
411 return $this->includedProductTags;
412 }
413
414 public function getExcludedProductTags() : array {
415 return $this->excludedProductTags;
416 }
417
418 public function setIncludedProductTags( array $includedProductTags ) {
419 $this->includedProductTags = $includedProductTags;
420 }
421
422 public function setExcludedProductTags( array $excludedProductTags ) {
423 $this->excludedProductTags = $excludedProductTags;
424 }
425
426 public function getIncludedProductBrands() : array {
427 return $this->includedProductBrands;
428 }
429
430 public function getExcludedProductBrands() : array {
431 return $this->excludedProductBrands;
432 }
433
434 public function setIncludedProductBrands( array $includedProductBrands ) {
435 $this->includedProductBrands = $includedProductBrands;
436 }
437
438 public function setExcludedProductBrands( array $excludedProductBrands ) {
439 $this->excludedProductBrands = $excludedProductBrands;
440 }
441
442 public function getIncludedProducts() : array {
443 return $this->includedProducts;
444 }
445
446 public function getExcludedProducts() : array {
447 return $this->excludedProducts;
448 }
449
450 public function setIncludedProducts( array $includedProducts ) {
451 $this->includedProducts = $includedProducts;
452 }
453
454 public function setExcludedProducts( array $excludedProducts ) {
455 $this->excludedProducts = $excludedProducts;
456 }
457
458 public function getIncludedUserRoles() : array {
459 return $this->includedUsersRole;
460 }
461
462 public function getExcludedUserRoles() : array {
463 return $this->excludedUsersRole;
464 }
465
466 public function setIncludedUsersRole( array $includedUsersRole ) {
467 $this->includedUsersRole = $includedUsersRole;
468 }
469
470 public function setExcludedUsersRole( array $excludedUsersRole ) {
471 $this->excludedUsersRole = $excludedUsersRole;
472 }
473
474 public function getIncludedUsers() : array {
475 return $this->includedUsers;
476 }
477
478 public function getExcludedUsers() : array {
479 return $this->excludedUsers;
480 }
481
482 public function setIncludedUsers( array $includedUsers ) {
483 $this->includedUsers = $includedUsers;
484 }
485
486 public function setExcludedUsers( array $excludedUsers ) {
487 $this->excludedUsers = $excludedUsers;
488 }
489
490 public function getSettings() : RuleSettings {
491 if ( !$this->priorityOptions ) {
492 $this->priorityOptions = new RuleSettings($this);
493 }
494 return $this->priorityOptions;
495 }
496
497 public function asArray() : array {
498 return array(
499 'pricing_type' => $this->getPricingType(),
500 'regular_price' => $this->getRegularPrice(),
501 'sale_price' => $this->getSalePrice(),
502 'discount' => $this->getDiscount(),
503 'discount_type' => $this->getDiscountType(),
504 'applying_type' => $this->getApplyingType(),
505 'tiered_pricing_type' => $this->getTieredPricingType(),
506 'percentage_rules' => $this->getPercentageTieredPricingRules(),
507 'fixed_rules' => $this->getFixedTieredPricingRules(),
508 'minimum' => $this->getMinimum(),
509 'mix_and_match_minimum' => $this->getMixAndMatchMinQuantity(),
510 'tax_status' => $this->getTaxStatus(),
511 'tax_class' => $this->getTaxClass(),
512 'included_categories' => $this->getIncludedProductCategories(),
513 'included_tags' => $this->getIncludedProductTags(),
514 'included_brands' => $this->getIncludedProductBrands(),
515 'included_products' => $this->getIncludedProducts(),
516 'included_users' => $this->getIncludedUsers(),
517 'included_users_role' => $this->getIncludedUserRoles(),
518 'excluded_categories' => $this->getExcludedProductCategories(),
519 'excluded_tags' => $this->getExcludedProductTags(),
520 'excluded_brands' => $this->getExcludedProductBrands(),
521 'excluded_products' => $this->getExcludedProducts(),
522 'excluded_users' => $this->getExcludedUsers(),
523 'excluded_users_role' => $this->getExcludedUserRoles(),
524 'rule_id' => $this->getId(),
525 'is_suspended' => $this->isSuspended(),
526 );
527 }
528
529 public function save() {
530 $dataToUpdate = array(
531 '_tpt_pricing_type' => $this->getPricingType(),
532 '_tpt_regular_price' => $this->getRegularPrice(),
533 '_tpt_sale_price' => $this->getSalePrice(),
534 '_tpt_discount' => $this->getDiscount(),
535 '_tpt_discount_type' => $this->getDiscountType(),
536 '_tpt_applying_type' => $this->getApplyingType(),
537 '_tpt_tiered_pricing_type' => $this->getTieredPricingType(),
538 '_tpt_percentage_rules' => $this->getPercentageTieredPricingRules(),
539 '_tpt_fixed_rules' => $this->getFixedTieredPricingRules(),
540 '_tpt_minimum' => $this->getMinimum(),
541 '_tpt_mix_and_match_minimum' => ( is_null( $this->getMixAndMatchMinQuantity() ) ? '' : wc_bool_to_string( $this->getMixAndMatchMinQuantity() ) ),
542 '_tpt_tax_status' => $this->getTaxStatus(),
543 '_tpt_tax_class' => $this->getTaxClass(),
544 '_tpt_included_categories' => $this->getIncludedProductCategories(),
545 '_tpt_included_tags' => $this->getIncludedProductTags(),
546 '_tpt_included_brands' => $this->getIncludedProductBrands(),
547 '_tpt_included_products' => $this->getIncludedProducts(),
548 '_tpt_included_users' => $this->getIncludedUsers(),
549 '_tpt_included_user_roles' => $this->getIncludedUserRoles(),
550 '_tpt_excluded_categories' => $this->getExcludedProductCategories(),
551 '_tpt_excluded_tags' => $this->getExcludedProductTags(),
552 '_tpt_excluded_brands' => $this->getExcludedProductBrands(),
553 '_tpt_excluded_products' => $this->getExcludedProducts(),
554 '_tpt_excluded_users' => $this->getExcludedUsers(),
555 '_tpt_excluded_user_roles' => $this->getExcludedUserRoles(),
556 '_tpt_is_suspended' => wc_bool_to_string( $this->isSuspended() ),
557 );
558 foreach ( $dataToUpdate as $key => $value ) {
559 update_post_meta( $this->getId(), $key, $value );
560 }
561 }
562
563 public static function build( $ruleId ) : self {
564 // Simple data to read
565 $dataToRead = array(
566 '_tpt_pricing_type' => 'pricing_type',
567 '_tpt_sale_price' => 'sale_price',
568 '_tpt_regular_price' => 'regular_price',
569 '_tpt_discount' => 'discount',
570 '_tpt_discount_type' => 'discount_type',
571 '_tpt_applying_type' => 'applying_type',
572 '_tpt_tiered_pricing_type' => 'tiered_pricing_type',
573 '_tpt_minimum' => 'minimum',
574 '_tpt_mix_and_match_minimum' => 'mix_and_match_minimum',
575 '_tpt_tax_status' => 'tax_status',
576 '_tpt_tax_class' => 'tax_class',
577 '_tpt_is_suspended' => 'is_suspended',
578 );
579 $data = array();
580 foreach ( $dataToRead as $key => $name ) {
581 $data[$name] = get_post_meta( $ruleId, $key, true );
582 }
583 $priceRule = self::fromArray( $data );
584 $existingRoles = wp_roles()->roles;
585 $includedCategoriesIds = array_filter( array_map( 'intval', (array) get_post_meta( $ruleId, '_tpt_included_categories', true ) ) );
586 $includedTagsIds = array_filter( array_map( 'intval', (array) get_post_meta( $ruleId, '_tpt_included_tags', true ) ) );
587 $includedBrandsIds = array_filter( array_map( 'intval', (array) get_post_meta( $ruleId, '_tpt_included_brands', true ) ) );
588 $includedProductsIds = array_filter( array_map( 'intval', (array) get_post_meta( $ruleId, '_tpt_included_products', true ) ) );
589 $includedUsersRole = array_filter( (array) get_post_meta( $ruleId, '_tpt_included_user_roles', true ), function ( $role ) use($existingRoles) {
590 return array_key_exists( $role, $existingRoles );
591 } );
592 $includedUsers = array_filter( array_map( 'intval', (array) get_post_meta( $ruleId, '_tpt_included_users', true ) ) );
593 $excludedCategoriesIds = array_filter( array_map( 'intval', (array) get_post_meta( $ruleId, '_tpt_excluded_categories', true ) ) );
594 $excludedTagsIds = array_filter( array_map( 'intval', (array) get_post_meta( $ruleId, '_tpt_excluded_tags', true ) ) );
595 $excludedBrandsIds = array_filter( array_map( 'intval', (array) get_post_meta( $ruleId, '_tpt_excluded_brands', true ) ) );
596 $excludedProductsIds = array_filter( array_map( 'intval', (array) get_post_meta( $ruleId, '_tpt_excluded_products', true ) ) );
597 $excludedUsersRole = array_filter( (array) get_post_meta( $ruleId, '_tpt_excluded_user_roles', true ), function ( $role ) use($existingRoles) {
598 return array_key_exists( $role, $existingRoles );
599 } );
600 $excludedUsers = array_filter( array_map( 'intval', (array) get_post_meta( $ruleId, '_tpt_excluded_users', true ) ) );
601 $isSuspended = get_post_meta( $ruleId, '_tpt_is_suspended', true ) === 'yes';
602 $priceRule->setPercentageTieredPricingRules( self::readPricingRules( 'percentage', $ruleId ) );
603 $priceRule->setFixedTieredPricingRules( self::readPricingRules( 'fixed', $ruleId ) );
604 $priceRule->setIncludedProductCategories( $includedCategoriesIds );
605 $priceRule->setIncludedProductTags( $includedTagsIds );
606 $priceRule->setIncludedProductBrands( $includedBrandsIds );
607 $priceRule->setIncludedUsers( $includedUsers );
608 $priceRule->setIncludedUsersRole( $includedUsersRole );
609 $priceRule->setIncludedProducts( $includedProductsIds );
610 $priceRule->setExcludedProductCategories( $excludedCategoriesIds );
611 $priceRule->setExcludedProductTags( $excludedTagsIds );
612 $priceRule->setExcludedProductBrands( $excludedBrandsIds );
613 $priceRule->setExcludedUsers( $excludedUsers );
614 $priceRule->setExcludedUsersRole( $excludedUsersRole );
615 $priceRule->setExcludedProducts( $excludedProductsIds );
616 $priceRule->setIsSuspended( $isSuspended );
617 $priceRule->setId( $ruleId );
618 return apply_filters( 'tiered_pricing_table/global_pricing/after_built_rule', $priceRule );
619 }
620
621 protected static function readPricingRules( $type, $id ) : array {
622 $type = ( in_array( $type, array('percentage', 'fixed') ) ? $type : 'fixed' );
623 $rules = get_post_meta( $id, "_tpt_{$type}_rules", true );
624 $rules = ( !empty( $rules ) ? $rules : array() );
625 $rules = ( is_array( $rules ) ? array_filter( $rules ) : array() );
626 ksort( $rules );
627 return $rules;
628 }
629
630 public function setIsSuspended( bool $isSuspended ) {
631 $this->isSuspended = $isSuspended;
632 }
633
634 public function suspend() {
635 $this->setIsSuspended( true );
636 }
637
638 public function reactivate() {
639 $this->setIsSuspended( false );
640 }
641
642 public function isSuspended() : bool {
643 return $this->isSuspended;
644 }
645
646 /**
647 * Wrapper for the main "match" function to provide the hook for 3rd party devs
648 *
649 * @param WP_User $user
650 * @param WC_Product $product
651 *
652 * @return bool
653 */
654 public function matchRequirements( WP_User $user, WC_Product $product ) : bool {
655 $matched = $this->_matchRequirements( $user, $product );
656 return apply_filters(
657 'tiered_pricing_table/global_pricing/match_requirements',
658 $matched,
659 $this,
660 $user,
661 $product
662 );
663 }
664
665 protected function _matchRequirements( WP_User $user, WC_Product $product ) : bool {
666 $parentProduct = ( $product->is_type( array('variation', 'subscription-variation') ) ? wc_get_product( $product->get_parent_id() ) : $product );
667 /**
668 * 1. Check for product exclusion
669 *
670 * If the product in exclusion - pricing rule does not match immediately
671 */
672 if ( !empty( $this->getExcludedProducts() ) ) {
673 if ( in_array( $product->get_id(), $this->getExcludedProducts() ) || in_array( $parentProduct->get_id(), $this->getExcludedProducts() ) ) {
674 return false;
675 }
676 }
677 if ( !empty( $this->getExcludedProductCategories() ) ) {
678 if ( !empty( array_intersect( $parentProduct->get_category_ids(), $this->getExcludedProductCategories() ) ) ) {
679 return false;
680 }
681 }
682 if ( !empty( $this->getExcludedProductTags() ) ) {
683 if ( !empty( array_intersect( $parentProduct->get_tag_ids(), $this->getExcludedProductTags() ) ) ) {
684 return false;
685 }
686 }
687 if ( !empty( $this->getExcludedProductBrands() ) ) {
688 $productBrands = wp_get_post_terms( $parentProduct->get_id(), 'product_brand', array(
689 'fields' => 'ids',
690 ) );
691 if ( is_wp_error( $productBrands ) ) {
692 $productBrands = [];
693 }
694 if ( !empty( array_intersect( $productBrands, $this->getExcludedProductBrands() ) ) ) {
695 return false;
696 }
697 }
698 /**
699 * 2. Check for user exclusion
700 *
701 * If users in exclusion - pricing rule does not match immediately
702 */
703 if ( in_array( $user->ID, $this->getExcludedUsers() ) ) {
704 return false;
705 }
706 foreach ( $this->getExcludedUserRoles() as $role ) {
707 if ( in_array( $role, $user->roles ) ) {
708 return false;
709 }
710 }
711 /**
712 * 3. Check for rule limitation for specific products
713 *
714 * If yes - match rule only for selected product/product categories
715 */
716 $productMatched = false;
717 $productLimitations = false;
718 if ( !empty( $this->getIncludedProducts() ) ) {
719 $productLimitations = true;
720 if ( in_array( $product->get_id(), $this->getIncludedProducts() ) || in_array( $parentProduct->get_id(), $this->getIncludedProducts() ) ) {
721 $productMatched = true;
722 }
723 }
724 if ( !empty( $this->getIncludedProductCategories() ) ) {
725 $productLimitations = true;
726 if ( !empty( array_intersect( $parentProduct->get_category_ids(), $this->getIncludedProductCategories() ) ) ) {
727 $productMatched = true;
728 }
729 }
730 if ( !empty( $this->getIncludedProductTags() ) ) {
731 $productLimitations = true;
732 if ( !empty( array_intersect( $parentProduct->get_tag_ids(), $this->getIncludedProductTags() ) ) ) {
733 $productMatched = true;
734 }
735 }
736 if ( !empty( $this->getIncludedProductBrands() ) ) {
737 $productLimitations = true;
738 $productBrands = wp_get_post_terms( $parentProduct->get_id(), 'product_brand', array(
739 'fields' => 'ids',
740 ) );
741 if ( is_wp_error( $productBrands ) ) {
742 $productBrands = [];
743 }
744 if ( !empty( array_intersect( $productBrands, $this->getIncludedProductBrands() ) ) ) {
745 $productMatched = true;
746 }
747 }
748 // There is product limitation and the product/category does not match the rule
749 if ( $productLimitations && !$productMatched ) {
750 return false;
751 }
752 /**
753 * 4. If there are no user limits - match the rule immediately
754 */
755 if ( empty( $this->getIncludedUserRoles() ) && empty( $this->getIncludedUsers() ) ) {
756 return true;
757 }
758 /**
759 * 5. If there are user limits - check for user ID and user role.
760 */
761 if ( in_array( $user->ID, $this->getIncludedUsers() ) ) {
762 return true;
763 }
764 foreach ( $this->getIncludedUserRoles() as $role ) {
765 if ( in_array( $role, $user->roles ) ) {
766 return true;
767 }
768 }
769 return false;
770 }
771
772 }
773