| @@ -101,9 +101,58 @@ | ||
| 101 | 101 | $status_matches = true; |
| 102 | 102 | } |
| 103 | 103 | |
| 104 | 104 | // Return the original return value if status matches, otherwise return false |
| 105 | - return $status_matches ? $return : false; | |
| 105 | + if (!$status_matches) { | |
| 106 | + return false; | |
| 107 | + } | |
| 108 | + | |
| 109 | + // Apply product / category filter so real-time orders respect each | |
| 110 | + // campaign's Selected Product / Exclude Product settings — matching the | |
| 111 | + // Regenerate path. Operates against the DB-loaded settings shape, where | |
| 112 | + // product_list / exclude_products / category_list / exclude_categories | |
| 113 | + // are flat arrays of slugs (flattened by async_select_remove_label). | |
| 114 | + $product_id = !empty($entry['data']['product_id']) ? $entry['data']['product_id'] : 0; | |
| 115 | + if ($product_id) { | |
| 116 | + $product_slug = get_post_field('post_name', $product_id); | |
| 117 | + $category_slugs = []; | |
| 118 | + $terms = get_the_terms($product_id, 'product-categories'); | |
| 119 | + if (is_array($terms)) { | |
| 120 | + foreach ($terms as $term) { | |
| 121 | + $category_slugs[] = $term->slug; | |
| 122 | + } | |
| 123 | + } | |
| 124 | + | |
| 125 | + // Show-purchase-of filter | |
| 126 | + $control = !empty($settings['product_control']) ? $settings['product_control'] : 'none'; | |
| 127 | + if ($control === 'manual_selection') { | |
| 128 | + $list = !empty($settings['product_list']) ? (array) $settings['product_list'] : []; | |
| 129 | + if (!in_array($product_slug, $list, true)) { | |
| 130 | + return false; | |
| 131 | + } | |
| 132 | + } elseif ($control === 'product_category') { | |
| 133 | + $list = !empty($settings['category_list']) ? (array) $settings['category_list'] : []; | |
| 134 | + if (empty(array_intersect($category_slugs, $list))) { | |
| 135 | + return false; | |
| 136 | + } | |
| 137 | + } | |
| 138 | + | |
| 139 | + // Exclude-product filter | |
| 140 | + $exclude_by = !empty($settings['product_exclude_by']) ? $settings['product_exclude_by'] : 'none'; | |
| 141 | + if ($exclude_by === 'manual_selection') { | |
| 142 | + $list = !empty($settings['exclude_products']) ? (array) $settings['exclude_products'] : []; | |
| 143 | + if (in_array($product_slug, $list, true)) { | |
| 144 | + return false; | |
| 145 | + } | |
| 146 | + } elseif ($exclude_by === 'product_category') { | |
| 147 | + $list = !empty($settings['exclude_categories']) ? (array) $settings['exclude_categories'] : []; | |
| 148 | + if (!empty(array_intersect($category_slugs, $list))) { | |
| 149 | + return false; | |
| 150 | + } | |
| 151 | + } | |
| 152 | + } | |
| 153 | + | |
| 154 | + return $return; | |
| 106 | 155 | } |
| 107 | 156 | |
| 108 | 157 | public function product_lists($products) { |
| 109 | 158 | $all_products = \FluentCart\App\Models\Product::published()->get(); |
| @@ -428,10 +477,10 @@ | ||
| 428 | 477 | if( empty( $post ) ) { |
| 429 | 478 | return; |
| 430 | 479 | } |
| 431 | 480 | |
| 432 | - $dateFrom = !empty( $post['display_from'] ) ? date('Y-m-d',strtotime('-'.$post['display_from'].' days',time())) : ''; | |
| 433 | - $dateTo = date('Y-m-d',strtotime('1 days',time())); | |
| 481 | + $dateFrom = !empty( $post['display_from'] ) ? gmdate('Y-m-d',strtotime('-'.$post['display_from'].' days',time())) : ''; | |
| 482 | + $dateTo = gmdate('Y-m-d',strtotime('1 days',time())); | |
| 434 | 483 | $amount = !empty( $post['display_last'] ) ? $post['display_last'] : 10; |
| 435 | 484 | |
| 436 | 485 | $get_orders = \FluentCart\App\Models\Order::with(['customer', 'order_items', 'billing_address', 'shipping_address']) |
| 437 | 486 | ->orderBy('created_at', 'desc') |
| @@ -618,8 +667,9 @@ | ||
| 618 | 667 | $args = array( |
| 619 | 668 | 'post_type' => $this->post_type, |
| 620 | 669 | 'post_status' => 'publish', |
| 621 | 670 | 'posts_per_page' => 20, |
| 671 | + // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query -- False positive: the query is prepared via $this->wpdb->prepare(), which this sniff does not recognise, and only $wpdb->prefix table names are interpolated. Audited 2026-07-16. | |
| 622 | 672 | 'tax_query' => array( |
| 623 | 673 | array( |
| 624 | 674 | 'taxonomy' => 'product-categories', |
| 625 | 675 | 'field' => 'slug', |
| @@ -711,8 +761,9 @@ | ||
| 711 | 761 | return $messages; |
| 712 | 762 | } |
| 713 | 763 | |
| 714 | 764 | public function doc(){ |
| 765 | + /* translators: %1$s: FluentCart WordPress plugin installed & configured link URL, %2$s: documentation link URL, %3$s: 👉 NotificationX Integration with FluentCart link URL */ | |
| 715 | 766 | return sprintf(__('<p>Make sure that you have the <a target="_blank" href="%1$s">FluentCart WordPress plugin installed & configured</a> to use its campaign and selling data. For detailed guidelines, check out the step-by-step <a target="_blank" href="%2$s">documentation</a>.</p> |
| 716 | 767 | <a target="_blank" href="%3$s">👉 NotificationX Integration with FluentCart</a>', 'notificationx'), |
| 717 | 768 | 'https://wordpress.org/plugins/fluent-cart/', |
| 718 | 769 | 'https://notificationx.com/docs/fluentcart-sales-notifications/', |