Changeset 3744394
- Timestamp:
- 10/13/2026 04:02:40 PM (11 days ago)
- Location:
- discontinued-products
- Files:
-
- 16 edited
- 1 copied
-
tags/2.0.9 (copied) (copied from discontinued-products/trunk )
-
tags/2.0.9/includes/class-discontinued-products.php (modified) (4 diffs)
-
tags/2.0.9/includes/class-dp-csv-import-export.php (modified) (5 diffs)
-
tags/2.0.9/includes/class-dp-discontinued-product.php (modified) (5 diffs)
-
tags/2.0.9/includes/class-dp-settings.php (modified) (1 diff)
-
tags/2.0.9/includes/class-dp-taxonomy.php (modified) (1 diff)
-
tags/2.0.9/readme.txt (modified) (2 diffs)
-
tags/2.0.9/woocommerce-discontinued-products.php (modified) (3 diffs)
-
tags/2.0.9/woocommerce-template.php (modified) (3 diffs)
-
trunk/includes/class-discontinued-products.php (modified) (4 diffs)
-
trunk/includes/class-dp-csv-import-export.php (modified) (5 diffs)
-
trunk/includes/class-dp-discontinued-product.php (modified) (5 diffs)
-
trunk/includes/class-dp-settings.php (modified) (1 diff)
-
trunk/includes/class-dp-taxonomy.php (modified) (1 diff)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/woocommerce-discontinued-products.php (modified) (3 diffs)
-
trunk/woocommerce-template.php (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
discontinued-products/tags/2.0.9/includes/class-discontinued-products.php
r3467144 r3744394 6 6 * @since 1.0.0 7 7 */ 8 9 if ( ! defined( 'ABSPATH' ) ) { 10 exit; 11 } 8 12 9 13 if ( ! class_exists( 'Discontinued_Products' ) ) { … … 75 79 */ 76 80 public function maybe_run_data_updater() { 81 if ( ! is_admin() || ! current_user_can( 'manage_woocommerce' ) ) { 82 return; 83 } 77 84 if ( isset( $_GET['do_update_dp'] ) && check_admin_referer( 'dp_update_nonce', '_wpnonce' ) ) { 78 85 // Run the data updater. … … 81 88 return; 82 89 } 83 if ( isset( $_GET['wc-hide-notice'] ) && 'dp_updated' === $_GET['wc-hide-notice']) {90 if ( isset( $_GET['wc-hide-notice'], $_GET['_wc_notice_nonce'] ) && 'dp_updated' === $_GET['wc-hide-notice'] && wp_verify_nonce( sanitize_key( wp_unslash( $_GET['_wc_notice_nonce'] ) ), 'woocommerce_hide_notices_nonce' ) ) { 84 91 delete_transient( 'do_update_dp' ); 85 92 return; … … 94 101 */ 95 102 public static function update_notice() { 103 104 if ( ! current_user_can( 'manage_woocommerce' ) ) { 105 return; 106 } 96 107 97 108 $update_dp_transient = get_transient( 'do_update_dp' ); -
discontinued-products/tags/2.0.9/includes/class-dp-csv-import-export.php
r3467144 r3744394 28 28 add_filter( 'woocommerce_csv_product_import_mapping_default_columns', array( $this, 'add_column_to_mapping_screen' ) ); 29 29 add_filter( 'woocommerce_product_import_pre_insert_product_object', array( $this, 'process_import' ), 10, 2 ); 30 add_action( 'woocommerce_product_import_inserted_product_object', array( $this, 'process_import_terms' ), 10, 2 ); 30 31 add_filter( 'woocommerce_product_export_column_names', array( $this, 'add_export_column' ) ); 31 32 add_filter( 'woocommerce_product_export_product_default_columns', array( $this, 'add_export_column' ) ); … … 82 83 public function process_import( $product, $data ) { 83 84 84 if ( ! empty( $data['is_discontinued'] ) ) {85 $product->update_meta_data( '_is_discontinued', $data['is_discontinued'] );86 }87 85 if ( ! empty( $data['discontinued_product_text'] ) ) { 88 86 $product->update_meta_data( '_discontinued_product_text', $data['discontinued_product_text'] ); 89 87 } 90 88 if ( ! empty( $data['alt_products'] ) ) { 91 $product->update_meta_data( '_alt_products', explode( ', ', $data['alt_products']) );89 $product->update_meta_data( '_alt_products', array_values( array_filter( array_map( 'absint', explode( ',', $data['alt_products'] ) ) ) ) ); 92 90 } 93 91 if ( ! empty( $data['alt_product_text'] ) ) { 94 92 $product->update_meta_data( '_alt_product_text', $data['alt_product_text'] ); 95 93 } 96 if ( ! empty( $data['hide_from_shop'] ) ) {97 $product->update_meta_data( '_hide_from_shop', $data['hide_from_shop'] );98 }99 if ( ! empty( $data['hide_from_search'] ) ) {100 $product->update_meta_data( '_hide_from_search', $data['hide_from_search'] );101 }102 103 94 return $product; 95 } 96 97 /** 98 * Save the discontinued, shop and search flags as product_discontinued terms 99 * once the imported product has an ID. Only columns present in the file change. 100 * 101 * @since 2.0.9 102 * @param WC_Product $product Imported product. 103 * @param array $data CSV data read for the product. 104 */ 105 public function process_import_terms( $product, $data ) { 106 107 if ( ! is_a( $product, 'WC_Product' ) || ! $product->get_id() ) { 108 return; 109 } 110 $product_id = $product->get_id(); 111 $groups = array( 112 'is_discontinued' => array( 'yes' => 'dp-discontinued' ), 113 'hide_from_shop' => array( 114 'hide' => 'dp-hide-shop', 115 'show' => 'dp-show-shop', 116 ), 117 'hide_from_search' => array( 118 'hide' => 'dp-hide-search', 119 'show' => 'dp-show-search', 120 ), 121 ); 122 123 foreach ( $groups as $column => $map ) { 124 if ( ! array_key_exists( $column, $data ) ) { 125 continue; 126 } 127 $value = strtolower( trim( (string) $data[ $column ] ) ); 128 if ( 'is_discontinued' === $column && in_array( $value, array( '1', 'true' ), true ) ) { 129 $value = 'yes'; 130 } 131 wp_remove_object_terms( $product_id, array_values( $map ), 'product_discontinued' ); 132 if ( isset( $map[ $value ] ) ) { 133 wp_add_object_terms( $product_id, $map[ $value ], 'product_discontinued' ); 134 } 135 } 104 136 } 105 137 /** … … 129 161 */ 130 162 public function add_export_data_is_discontinued( $value, $product ) { 131 $value = $product->get_meta( '_is_discontinued', true, 'edit' ); 132 return $value; 163 return has_term( 'dp-discontinued', 'product_discontinued', $product->get_id() ) ? 'yes' : ''; 133 164 } 134 165 … … 177 208 */ 178 209 public function add_export_data_hide_from_shop( $value, $product ) { 179 $value = $product->get_meta( '_hide_from_shop', true, 'edit' ); 180 return $value; 210 return $this->get_visibility_value( $product->get_id(), 'shop' ); 181 211 } 182 212 … … 189 219 */ 190 220 public function add_export_data_hide_from_search( $value, $product ) { 191 $value = $product->get_meta( '_hide_from_search', true, 'edit' ); 192 return $value; 221 return $this->get_visibility_value( $product->get_id(), 'search' ); 222 } 223 224 /** 225 * Read the per product shop or search override from its terms. 226 * 227 * @since 2.0.9 228 * @param int $product_id Product ID. 229 * @param string $context Either shop or search. 230 * @return string hide, show or an empty string for the default. 231 */ 232 protected function get_visibility_value( $product_id, $context ) { 233 if ( has_term( 'dp-hide-' . $context, 'product_discontinued', $product_id ) ) { 234 return 'hide'; 235 } 236 if ( has_term( 'dp-show-' . $context, 'product_discontinued', $product_id ) ) { 237 return 'show'; 238 } 239 return ''; 193 240 } 194 241 -
discontinued-products/tags/2.0.9/includes/class-dp-discontinued-product.php
r3467166 r3744394 7 7 */ 8 8 9 if ( ! defined( 'ABSPATH' ) ) { 10 exit; 11 } 12 9 13 if ( ! class_exists( 'DP_Discontinued_Product' ) ) { 10 14 /** … … 34 38 add_action( 'init', array( $this, 'woocommerce_flush_rewrite_rules' ) ); 35 39 add_action( 'woocommerce_product_query', array( $this, 'exclude_discontinued_products' ), 1000 ); 40 add_action( 'pre_get_posts', array( $this, 'exclude_discontinued_from_site_search' ), 1000 ); 36 41 add_filter( 'woocommerce_get_shop_page_id', array( $this, 'override_shop_page_id' ), 1, 1 ); 37 42 add_action( 'template_redirect', array( $this, 'add_dp_alt_products' ) ); … … 211 216 public static function save( $post_id ) { 212 217 218 // WooCommerce verifies its meta box nonce before firing woocommerce_process_product_meta. 219 if ( ! current_user_can( 'edit_post', $post_id ) ) { 220 return; 221 } 222 213 223 $terms = array(); 214 update_post_meta( $post_id, '_discontinued_product_text', filter_input( INPUT_POST, '_discontinued_product_text' ) ); 215 $alt_products = filter_input( INPUT_POST, 'alt_products', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY ) ? filter_input( INPUT_POST, 'alt_products', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY ) : array(); 224 update_post_meta( $post_id, '_discontinued_product_text', sanitize_text_field( (string) filter_input( INPUT_POST, '_discontinued_product_text' ) ) ); 225 $alt_products = filter_input( INPUT_POST, 'alt_products', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY ); 226 $alt_products = is_array( $alt_products ) ? array_values( array_filter( array_map( 'absint', $alt_products ) ) ) : array(); 216 227 update_post_meta( $post_id, '_alt_products', $alt_products ); 217 update_post_meta( $post_id, '_alt_product_text', filter_input( INPUT_POST, '_alt_product_text') );228 update_post_meta( $post_id, '_alt_product_text', sanitize_text_field( (string) filter_input( INPUT_POST, '_alt_product_text' ) ) ); 218 229 $is_discontinued = filter_input( INPUT_POST, '_is_discontinued' ); 219 230 if ( $is_discontinued ) { … … 257 268 258 269 $dc_shop_page_id = (int) get_option( 'dp_shop_page_id' ); 259 return ( is_shop() || is_product_ category() ) && ( ! $dc_shop_page_id || $this->current_page_id !== $dc_shop_page_id ) && ! is_search();270 return ( is_shop() || is_product_taxonomy() ) && ( ! $dc_shop_page_id || $this->current_page_id !== $dc_shop_page_id ) && ! is_search(); 260 271 } 261 272 … … 374 385 } 375 386 387 /** 388 * Apply the hide from search setting to the general site search. 389 * WooCommerce only runs woocommerce_product_query for product searches, 390 * so a plain ?s= search would otherwise list hidden discontinued products. 391 * Posts and pages have no product_discontinued terms and are unaffected. 392 * 393 * @since 2.0.9 394 * @param WP_Query $q Main WP Query. 395 */ 396 public function exclude_discontinued_from_site_search( $q ) { 397 if ( is_admin() || wp_doing_ajax() || ! $q->is_main_query() || ! $q->is_search() ) { 398 return; 399 } 400 401 // Product searches are already handled through woocommerce_product_query. 402 $post_type = $q->get( 'post_type' ); 403 if ( 'product' === $post_type || ( is_array( $post_type ) && array( 'product' ) === array_values( $post_type ) ) ) { 404 return; 405 } 406 407 $tax_queries = $this->build_tax_query( $q ); 408 $q->set( 'tax_query', $tax_queries ); 409 } 410 376 411 377 412 /** -
discontinued-products/tags/2.0.9/includes/class-dp-settings.php
r3177606 r3744394 6 6 * @since 1.1.0 7 7 */ 8 9 if ( ! defined( 'ABSPATH' ) ) { 10 exit; 11 } 8 12 9 13 if ( ! class_exists( 'DP_Settings' ) ) { -
discontinued-products/tags/2.0.9/includes/class-dp-taxonomy.php
r3177606 r3744394 6 6 * @since 1.1.0 7 7 */ 8 9 if ( ! defined( 'ABSPATH' ) ) { 10 exit; 11 } 8 12 9 13 if ( ! class_exists( 'DP_Taxonomy' ) ) { -
discontinued-products/tags/2.0.9/readme.txt
r3483791 r3744394 5 5 Tags: woocommerce, woocommerce products, discontinued products, discontinued, ecommerce 6 6 Requires at least: 6.0 7 Tested up to: 6.97 Tested up to: 7.1 8 8 Requires PHP: 7.4 9 Stable tag: 2.0. 810 License: GPLv 2 or later11 License URI: http ://www.gnu.org/licenses/gpl-2.0.html9 Stable tag: 2.0.9 10 License: GPLv3 11 License URI: https://www.gnu.org/licenses/gpl-3.0.html 12 12 13 13 Enables WooCommerce Discontinued Products. … … 53 53 54 54 ## Changelog 55 56 = 2.0.9 10.13.2026 = 57 * Fixed - Hide from shop now also applies to product tag and attribute archive pages, not only the shop and category pages. 58 * Fixed - Hide from search now also applies to the general site search, not only the product search. 59 * Fixed - Product CSV export now includes the discontinued, hide from shop and hide from search values. 60 * Fixed - Product CSV import now saves the discontinued, hide from shop and hide from search values directly instead of requiring a data update afterwards. 61 * Fixed - The "discontinued" price class is only added to discontinued products. 62 * Security - Product discontinued text and alternative product fields are sanitized on save and escaped on output. 63 * Security - The data update notice and action now require the manage_woocommerce capability. 64 * Compatibility - Tested with WordPress 7.1.3 and WooCommerce 11.2.1. 55 65 56 66 = 2.0.8 03.16.2026 = -
discontinued-products/tags/2.0.9/woocommerce-discontinued-products.php
r3483791 r3744394 6 6 * Author: Leon @ 211J 7 7 * Author URI: http://211j.com/ 8 * Version: 2.0. 88 * Version: 2.0.9 9 9 * Requires at least: 6.0 10 10 * Requires PHP: 7.4 11 11 * Text Domain: discontinued-products 12 * Domain Path: /languages13 12 * WC requires at least: 8.0 14 * WC tested up to: 1 0.6.113 * WC tested up to: 11.2.1 15 14 16 15 * License: GNU General Public License v3.0 … … 19 18 * @package woocommerce 20 19 */ 20 21 if ( ! defined( 'ABSPATH' ) ) { 22 exit; 23 } 21 24 22 25 /** … … 40 43 41 44 if ( ! defined( 'DP_VER' ) ) { 42 define( 'DP_VER', '2.0. 8' );45 define( 'DP_VER', '2.0.9' ); 43 46 } 44 47 -
discontinued-products/tags/2.0.9/woocommerce-template.php
r3473146 r3744394 6 6 * @since 1.0.0 7 7 */ 8 9 if ( ! defined( 'ABSPATH' ) ) { 10 exit; 11 } 8 12 9 13 if ( ! function_exists( 'dp_is_discontinued' ) ) { … … 128 132 $text_option = get_option( 'dp_discontinued_text' ); 129 133 $text = dp_alt_products_text( $prod_text_option, $text_option, __( 'This product has been discontinued.', 'discontinued-products' ) ); 130 $price = $price . '<br>' . $text;134 $price = $price . '<br>' . esc_html( $text ); 131 135 } 132 136 return $price; … … 163 167 */ 164 168 function discontinued_template_price_class( $class ) { 165 $class = $class . ' discontinued'; 169 global $product; 170 if ( is_object( $product ) && is_callable( array( $product, 'get_id' ) ) && dp_is_discontinued( $product->get_id() ) ) { 171 $class = $class . ' discontinued'; 172 } 166 173 167 174 return $class; -
discontinued-products/trunk/includes/class-discontinued-products.php
r3467144 r3744394 6 6 * @since 1.0.0 7 7 */ 8 9 if ( ! defined( 'ABSPATH' ) ) { 10 exit; 11 } 8 12 9 13 if ( ! class_exists( 'Discontinued_Products' ) ) { … … 75 79 */ 76 80 public function maybe_run_data_updater() { 81 if ( ! is_admin() || ! current_user_can( 'manage_woocommerce' ) ) { 82 return; 83 } 77 84 if ( isset( $_GET['do_update_dp'] ) && check_admin_referer( 'dp_update_nonce', '_wpnonce' ) ) { 78 85 // Run the data updater. … … 81 88 return; 82 89 } 83 if ( isset( $_GET['wc-hide-notice'] ) && 'dp_updated' === $_GET['wc-hide-notice']) {90 if ( isset( $_GET['wc-hide-notice'], $_GET['_wc_notice_nonce'] ) && 'dp_updated' === $_GET['wc-hide-notice'] && wp_verify_nonce( sanitize_key( wp_unslash( $_GET['_wc_notice_nonce'] ) ), 'woocommerce_hide_notices_nonce' ) ) { 84 91 delete_transient( 'do_update_dp' ); 85 92 return; … … 94 101 */ 95 102 public static function update_notice() { 103 104 if ( ! current_user_can( 'manage_woocommerce' ) ) { 105 return; 106 } 96 107 97 108 $update_dp_transient = get_transient( 'do_update_dp' ); -
discontinued-products/trunk/includes/class-dp-csv-import-export.php
r3467144 r3744394 28 28 add_filter( 'woocommerce_csv_product_import_mapping_default_columns', array( $this, 'add_column_to_mapping_screen' ) ); 29 29 add_filter( 'woocommerce_product_import_pre_insert_product_object', array( $this, 'process_import' ), 10, 2 ); 30 add_action( 'woocommerce_product_import_inserted_product_object', array( $this, 'process_import_terms' ), 10, 2 ); 30 31 add_filter( 'woocommerce_product_export_column_names', array( $this, 'add_export_column' ) ); 31 32 add_filter( 'woocommerce_product_export_product_default_columns', array( $this, 'add_export_column' ) ); … … 82 83 public function process_import( $product, $data ) { 83 84 84 if ( ! empty( $data['is_discontinued'] ) ) {85 $product->update_meta_data( '_is_discontinued', $data['is_discontinued'] );86 }87 85 if ( ! empty( $data['discontinued_product_text'] ) ) { 88 86 $product->update_meta_data( '_discontinued_product_text', $data['discontinued_product_text'] ); 89 87 } 90 88 if ( ! empty( $data['alt_products'] ) ) { 91 $product->update_meta_data( '_alt_products', explode( ', ', $data['alt_products']) );89 $product->update_meta_data( '_alt_products', array_values( array_filter( array_map( 'absint', explode( ',', $data['alt_products'] ) ) ) ) ); 92 90 } 93 91 if ( ! empty( $data['alt_product_text'] ) ) { 94 92 $product->update_meta_data( '_alt_product_text', $data['alt_product_text'] ); 95 93 } 96 if ( ! empty( $data['hide_from_shop'] ) ) {97 $product->update_meta_data( '_hide_from_shop', $data['hide_from_shop'] );98 }99 if ( ! empty( $data['hide_from_search'] ) ) {100 $product->update_meta_data( '_hide_from_search', $data['hide_from_search'] );101 }102 103 94 return $product; 95 } 96 97 /** 98 * Save the discontinued, shop and search flags as product_discontinued terms 99 * once the imported product has an ID. Only columns present in the file change. 100 * 101 * @since 2.0.9 102 * @param WC_Product $product Imported product. 103 * @param array $data CSV data read for the product. 104 */ 105 public function process_import_terms( $product, $data ) { 106 107 if ( ! is_a( $product, 'WC_Product' ) || ! $product->get_id() ) { 108 return; 109 } 110 $product_id = $product->get_id(); 111 $groups = array( 112 'is_discontinued' => array( 'yes' => 'dp-discontinued' ), 113 'hide_from_shop' => array( 114 'hide' => 'dp-hide-shop', 115 'show' => 'dp-show-shop', 116 ), 117 'hide_from_search' => array( 118 'hide' => 'dp-hide-search', 119 'show' => 'dp-show-search', 120 ), 121 ); 122 123 foreach ( $groups as $column => $map ) { 124 if ( ! array_key_exists( $column, $data ) ) { 125 continue; 126 } 127 $value = strtolower( trim( (string) $data[ $column ] ) ); 128 if ( 'is_discontinued' === $column && in_array( $value, array( '1', 'true' ), true ) ) { 129 $value = 'yes'; 130 } 131 wp_remove_object_terms( $product_id, array_values( $map ), 'product_discontinued' ); 132 if ( isset( $map[ $value ] ) ) { 133 wp_add_object_terms( $product_id, $map[ $value ], 'product_discontinued' ); 134 } 135 } 104 136 } 105 137 /** … … 129 161 */ 130 162 public function add_export_data_is_discontinued( $value, $product ) { 131 $value = $product->get_meta( '_is_discontinued', true, 'edit' ); 132 return $value; 163 return has_term( 'dp-discontinued', 'product_discontinued', $product->get_id() ) ? 'yes' : ''; 133 164 } 134 165 … … 177 208 */ 178 209 public function add_export_data_hide_from_shop( $value, $product ) { 179 $value = $product->get_meta( '_hide_from_shop', true, 'edit' ); 180 return $value; 210 return $this->get_visibility_value( $product->get_id(), 'shop' ); 181 211 } 182 212 … … 189 219 */ 190 220 public function add_export_data_hide_from_search( $value, $product ) { 191 $value = $product->get_meta( '_hide_from_search', true, 'edit' ); 192 return $value; 221 return $this->get_visibility_value( $product->get_id(), 'search' ); 222 } 223 224 /** 225 * Read the per product shop or search override from its terms. 226 * 227 * @since 2.0.9 228 * @param int $product_id Product ID. 229 * @param string $context Either shop or search. 230 * @return string hide, show or an empty string for the default. 231 */ 232 protected function get_visibility_value( $product_id, $context ) { 233 if ( has_term( 'dp-hide-' . $context, 'product_discontinued', $product_id ) ) { 234 return 'hide'; 235 } 236 if ( has_term( 'dp-show-' . $context, 'product_discontinued', $product_id ) ) { 237 return 'show'; 238 } 239 return ''; 193 240 } 194 241 -
discontinued-products/trunk/includes/class-dp-discontinued-product.php
r3467166 r3744394 7 7 */ 8 8 9 if ( ! defined( 'ABSPATH' ) ) { 10 exit; 11 } 12 9 13 if ( ! class_exists( 'DP_Discontinued_Product' ) ) { 10 14 /** … … 34 38 add_action( 'init', array( $this, 'woocommerce_flush_rewrite_rules' ) ); 35 39 add_action( 'woocommerce_product_query', array( $this, 'exclude_discontinued_products' ), 1000 ); 40 add_action( 'pre_get_posts', array( $this, 'exclude_discontinued_from_site_search' ), 1000 ); 36 41 add_filter( 'woocommerce_get_shop_page_id', array( $this, 'override_shop_page_id' ), 1, 1 ); 37 42 add_action( 'template_redirect', array( $this, 'add_dp_alt_products' ) ); … … 211 216 public static function save( $post_id ) { 212 217 218 // WooCommerce verifies its meta box nonce before firing woocommerce_process_product_meta. 219 if ( ! current_user_can( 'edit_post', $post_id ) ) { 220 return; 221 } 222 213 223 $terms = array(); 214 update_post_meta( $post_id, '_discontinued_product_text', filter_input( INPUT_POST, '_discontinued_product_text' ) ); 215 $alt_products = filter_input( INPUT_POST, 'alt_products', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY ) ? filter_input( INPUT_POST, 'alt_products', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY ) : array(); 224 update_post_meta( $post_id, '_discontinued_product_text', sanitize_text_field( (string) filter_input( INPUT_POST, '_discontinued_product_text' ) ) ); 225 $alt_products = filter_input( INPUT_POST, 'alt_products', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY ); 226 $alt_products = is_array( $alt_products ) ? array_values( array_filter( array_map( 'absint', $alt_products ) ) ) : array(); 216 227 update_post_meta( $post_id, '_alt_products', $alt_products ); 217 update_post_meta( $post_id, '_alt_product_text', filter_input( INPUT_POST, '_alt_product_text') );228 update_post_meta( $post_id, '_alt_product_text', sanitize_text_field( (string) filter_input( INPUT_POST, '_alt_product_text' ) ) ); 218 229 $is_discontinued = filter_input( INPUT_POST, '_is_discontinued' ); 219 230 if ( $is_discontinued ) { … … 257 268 258 269 $dc_shop_page_id = (int) get_option( 'dp_shop_page_id' ); 259 return ( is_shop() || is_product_ category() ) && ( ! $dc_shop_page_id || $this->current_page_id !== $dc_shop_page_id ) && ! is_search();270 return ( is_shop() || is_product_taxonomy() ) && ( ! $dc_shop_page_id || $this->current_page_id !== $dc_shop_page_id ) && ! is_search(); 260 271 } 261 272 … … 374 385 } 375 386 387 /** 388 * Apply the hide from search setting to the general site search. 389 * WooCommerce only runs woocommerce_product_query for product searches, 390 * so a plain ?s= search would otherwise list hidden discontinued products. 391 * Posts and pages have no product_discontinued terms and are unaffected. 392 * 393 * @since 2.0.9 394 * @param WP_Query $q Main WP Query. 395 */ 396 public function exclude_discontinued_from_site_search( $q ) { 397 if ( is_admin() || wp_doing_ajax() || ! $q->is_main_query() || ! $q->is_search() ) { 398 return; 399 } 400 401 // Product searches are already handled through woocommerce_product_query. 402 $post_type = $q->get( 'post_type' ); 403 if ( 'product' === $post_type || ( is_array( $post_type ) && array( 'product' ) === array_values( $post_type ) ) ) { 404 return; 405 } 406 407 $tax_queries = $this->build_tax_query( $q ); 408 $q->set( 'tax_query', $tax_queries ); 409 } 410 376 411 377 412 /** -
discontinued-products/trunk/includes/class-dp-settings.php
r3177606 r3744394 6 6 * @since 1.1.0 7 7 */ 8 9 if ( ! defined( 'ABSPATH' ) ) { 10 exit; 11 } 8 12 9 13 if ( ! class_exists( 'DP_Settings' ) ) { -
discontinued-products/trunk/includes/class-dp-taxonomy.php
r3177606 r3744394 6 6 * @since 1.1.0 7 7 */ 8 9 if ( ! defined( 'ABSPATH' ) ) { 10 exit; 11 } 8 12 9 13 if ( ! class_exists( 'DP_Taxonomy' ) ) { -
discontinued-products/trunk/readme.txt
r3483791 r3744394 5 5 Tags: woocommerce, woocommerce products, discontinued products, discontinued, ecommerce 6 6 Requires at least: 6.0 7 Tested up to: 6.97 Tested up to: 7.1 8 8 Requires PHP: 7.4 9 Stable tag: 2.0. 810 License: GPLv 2 or later11 License URI: http ://www.gnu.org/licenses/gpl-2.0.html9 Stable tag: 2.0.9 10 License: GPLv3 11 License URI: https://www.gnu.org/licenses/gpl-3.0.html 12 12 13 13 Enables WooCommerce Discontinued Products. … … 53 53 54 54 ## Changelog 55 56 = 2.0.9 10.13.2026 = 57 * Fixed - Hide from shop now also applies to product tag and attribute archive pages, not only the shop and category pages. 58 * Fixed - Hide from search now also applies to the general site search, not only the product search. 59 * Fixed - Product CSV export now includes the discontinued, hide from shop and hide from search values. 60 * Fixed - Product CSV import now saves the discontinued, hide from shop and hide from search values directly instead of requiring a data update afterwards. 61 * Fixed - The "discontinued" price class is only added to discontinued products. 62 * Security - Product discontinued text and alternative product fields are sanitized on save and escaped on output. 63 * Security - The data update notice and action now require the manage_woocommerce capability. 64 * Compatibility - Tested with WordPress 7.1.3 and WooCommerce 11.2.1. 55 65 56 66 = 2.0.8 03.16.2026 = -
discontinued-products/trunk/woocommerce-discontinued-products.php
r3483791 r3744394 6 6 * Author: Leon @ 211J 7 7 * Author URI: http://211j.com/ 8 * Version: 2.0. 88 * Version: 2.0.9 9 9 * Requires at least: 6.0 10 10 * Requires PHP: 7.4 11 11 * Text Domain: discontinued-products 12 * Domain Path: /languages13 12 * WC requires at least: 8.0 14 * WC tested up to: 1 0.6.113 * WC tested up to: 11.2.1 15 14 16 15 * License: GNU General Public License v3.0 … … 19 18 * @package woocommerce 20 19 */ 20 21 if ( ! defined( 'ABSPATH' ) ) { 22 exit; 23 } 21 24 22 25 /** … … 40 43 41 44 if ( ! defined( 'DP_VER' ) ) { 42 define( 'DP_VER', '2.0. 8' );45 define( 'DP_VER', '2.0.9' ); 43 46 } 44 47 -
discontinued-products/trunk/woocommerce-template.php
r3473146 r3744394 6 6 * @since 1.0.0 7 7 */ 8 9 if ( ! defined( 'ABSPATH' ) ) { 10 exit; 11 } 8 12 9 13 if ( ! function_exists( 'dp_is_discontinued' ) ) { … … 128 132 $text_option = get_option( 'dp_discontinued_text' ); 129 133 $text = dp_alt_products_text( $prod_text_option, $text_option, __( 'This product has been discontinued.', 'discontinued-products' ) ); 130 $price = $price . '<br>' . $text;134 $price = $price . '<br>' . esc_html( $text ); 131 135 } 132 136 return $price; … … 163 167 */ 164 168 function discontinued_template_price_class( $class ) { 165 $class = $class . ' discontinued'; 169 global $product; 170 if ( is_object( $product ) && is_callable( array( $product, 'get_id' ) ) && dp_is_discontinued( $product->get_id() ) ) { 171 $class = $class . ' discontinued'; 172 } 166 173 167 174 return $class;
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)