请问before_filter是不是只能在action方法之前执行?

请问before_filter是不是只能在action方法之前执行,在非action方法之前不执行呢?
我试了在index action时执行,但如果我放在index的子方法前就不执行了,是这样吗?
例:

   index为action方法,subm为自定义非action方法。

1 这样可以正常执行。

  1. class TestController < ApplicationController 
  2.    before_filter :filterm,:only=>[:index]   
  3.   
  4.    def index   
  5.    end  
  6.   
  7.    def filterm   
  8.    end  
  9. end  

 2 这样不执行正常,在执行subm之前并不会执行filterm。

  1. class TestController < ApplicationController    
  2.    before_filter :filterm,:only=>[:subm]   
  3.   
  4.    def index   
  5.       subm   
  6.    end  
  7.   
  8.    def subm   
  9.    end  
  10.   
  11.    def filterm   
  12.    end  
  13. end  

请问各位知道的朋友,可不可以告诉为什么?

 

 

This is the full code in my cart.php <?php /** * Custom Cart Page for WooCommerce with Selective Checkout * Place this file in your child theme directory: /wp-content/themes/woodmart-child/cart.php */ if (!defined('ABSPATH')) { exit; // Exit if accessed directly } do_action('woocommerce_before_cart'); ?> <div class="cart-page-section container" style="max-width: 1200px; margin: 0 auto;"> <form class="woocommerce-cart-form" action="<?php echo esc_url(wc_get_cart_url()); ?>" method="post"> <?php do_action('woocommerce_before_cart_table'); ?> <table class="shop_table shop_table_responsive cart woocommerce-cart-form__contents"> <thead> <tr> <th class="product-select"> <input type="checkbox" id="select-all-items" /> <label for="select-all-items" style="display: inline-block; margin-left: 5px; cursor: pointer;">全选</label> </th> <th class="product-info"><?php esc_html_e('Product', 'woocommerce'); ?></th> <th class="product-params"><?php esc_html_e('Parameters', 'woocommerce'); ?></th> <th class="product-price"><?php esc_html_e('Price', 'woocommerce'); ?></th> <th class="product-quantity"><?php esc_html_e('Quantity', 'woocommerce'); ?></th> <th class="product-subtotal"><?php esc_html_e('Subtotal', 'woocommerce'); ?></th> <!-- 已移除 Action 列 --> </tr> </thead> <tbody> <?php do_action('woocommerce_before_cart_contents'); ?> <?php foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) : $_product = apply_filters('woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key); $product_id = apply_filters('woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key); if ($_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters('woocommerce_cart_item_visible', true, $cart_item, $cart_item_key)) : $product_permalink = apply_filters('woocommerce_cart_item_permalink', $_product->is_visible() ? $_product->get_permalink($cart_item) : '', $cart_item, $cart_item_key); ?> <tr class="woocommerce-cart-form__cart-item <?php echo esc_attr(apply_filters('woocommerce_cart_item_class', 'cart_item', $cart_item, $cart_item_key)); ?>"> <!-- Checkbox Column --> <td class="product-select" data-title="<?php esc_attr_e('Select', 'woocommerce'); ?>"> <input type="checkbox" class="item-checkbox" name="selected_items[]" value="<?php echo esc_attr($cart_item_key); ?>" data-price="<?php echo esc_attr($cart_item['line_total']); ?>" /> </td> <!-- Product Info Column --> <td class="product-info" data-title="<?php esc_attr_e('Product', 'woocommerce'); ?>"> <div class="product-image"> <?php $thumbnail = apply_filters('woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key); if (!$product_permalink) : echo $thumbnail; // PHPCS: XSS ok. else : printf('<a href="%s">%s</a>', esc_url($product_permalink), $thumbnail); // PHPCS: XSS ok. endif; ?> </div> <div class="product-name"> <?php if (!$product_permalink) : echo wp_kses_post(apply_filters('woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key) . ' '); else : echo wp_kses_post(apply_filters('woocommerce_cart_item_name', sprintf('<a href="%s">%s</a>', esc_url($product_permalink), $_product->get_name()), $cart_item, $cart_item_key)); endif; do_action('woocommerce_after_cart_item_name', $cart_item, $cart_item_key); // Meta data. echo wc_get_formatted_cart_item_data($cart_item); // PHPCS: XSS ok. ?> </div> </td> <!-- Product Parameters Column --> <td class="product-params" data-title="<?php esc_attr_e('Parameters', 'woocommerce'); ?>"> <?php if ($cart_item['variation_id']) { $variation_attributes = $_product->get_variation_attributes(); if (!empty($variation_attributes)) { foreach ($variation_attributes as $attribute => $value) { echo '<span class="param">' . esc_html(wc_attribute_label($attribute)) . ': ' . esc_html($value) . '</span><br>'; } } } else { $attributes = $_product->get_attributes(); if (!empty($attributes)) { foreach ($attributes as $attribute) { $values = wc_get_product_terms($product_id, $attribute['name'], array('fields' => 'names')); echo '<span class="param">' . esc_html(wc_attribute_label($attribute['name'])) . ': ' . esc_html(implode(', ', $values)) . '</span><br>'; } } } ?> </td> <!-- Price Column --> <td class="product-price" data-title="<?php esc_attr_e('Price', 'woocommerce'); ?>"> <?php echo apply_filters('woocommerce_cart_item_price', WC()->cart->get_product_price($_product), $cart_item, $cart_item_key); // PHPCS: XSS ok. ?> </td> <!-- Quantity Column --> <td class="product-quantity" data-title="<?php esc_attr_e('Quantity', 'woocommerce'); ?>"> <?php if ($_product->is_sold_individually()) : $product_quantity = sprintf('1 <input type="hidden" name="cart[%s][qty]" value="1" />', $cart_item_key); else : $product_quantity = woocommerce_quantity_input( array( 'input_name' => "cart[{$cart_item_key}][qty]", 'input_value' => $cart_item['quantity'], 'max_value' => $_product->get_max_purchase_quantity(), 'min_value' => '0', 'product_name' => $_product->get_name(), ), $_product, false ); endif; echo apply_filters('woocommerce_cart_item_quantity', $product_quantity, $cart_item_key, $cart_item); // PHPCS: XSS ok. ?> </td> <!-- Subtotal Column --> <td class="product-subtotal" data-title="<?php esc_attr_e('Subtotal', 'woocommerce'); ?>"> <?php echo apply_filters('woocommerce_cart_item_subtotal', WC()->cart->get_product_subtotal($_product, $cart_item['quantity']), $cart_item, $cart_item_key); // PHPCS: XSS ok. ?> </td> <!-- 已移除 Remove Item Column --> </tr> <?php endif; ?> <?php endforeach; ?> <?php do_action('woocommerce_after_cart_contents'); ?> </tbody> </table> <div class="actions"> <button type="submit" class="button" name="update_cart" value="<?php esc_attr_e('Update cart', 'woocommerce'); ?>"><?php esc_html_e('Update cart', 'woocommerce'); ?></button> <?php do_action('woocommerce_cart_actions'); ?> <?php wp_nonce_field('woocommerce-cart', 'woocommerce-cart-nonce'); ?> </div> <?php do_action('woocommerce_after_cart_table'); ?> </form> </div> <!-- Sticky Footer --> <div class="cart-footer-actions sticky-footer" style="position: sticky; bottom: 0; background: white; padding: 15px; border-top: 1px solid #ddd; max-width: 1200px; margin: 0 auto;"> <div style="display: flex; justify-content: space-between; align-items: center;"> <div> <input type="checkbox" id="footer-select-all"> <label for="footer-select-all" style="display: inline-block; margin-left: 5px; cursor: pointer;">全选</label> <button type="button" class="button" id="remove-selected-items">刪除選中的商品</button> <button type="button" class="button" id="clear-cart">清理購物車</button> </div> <div class="selected-summary" style="text-align: right;"> <p> 已选商品: <span id="selected-count">0</span> 件,共计: <span id="selected-total">RM0.00</span> </p> <a href="<?php echo esc_url(wc_get_checkout_url()); ?>" class="checkout-button button alt wc-forward" id="partial-checkout"> 结算 </a> </div> </div> </div> <?php do_action('woocommerce_after_cart'); ?> <style> /* Custom Styles for Cart Page */ .cart-page-section { background: white; padding: 30px; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1); margin-bottom: 30px; } .cart-page-section table.cart { width: 100%; border-collapse: collapse; margin-bottom: 20px; } .cart-page-section table.cart th, .cart-page-section table.cart td { padding: 15px; text-align: left; border-bottom: 1px solid #eee; } .cart-page-section table.cart th { background-color: #f8f8f8; font-weight: bold; } /* 调整列宽 */ .cart-page-section table.cart td.product-select { width: 10%; text-align: center; vertical-align: middle; } .cart-page-section table.cart td.product-info { width: 20%; vertical-align: top; } .cart-page-section table.cart .product-info .product-image { float: left; margin-right: 15px; width: 100px; height: 100px; } .cart-page-section table.cart .product-info .product-image img { max-width: 100%; height: auto; display: block; } .cart-page-section table.cart .product-info .product-name { overflow: hidden; } .cart-page-section table.cart td.product-params { width: 20%; vertical-align: top; } .cart-page-section table.cart .product-params .param { display: block; margin-bottom: 5px; font-size: 14px; color: #666; } /* 调整剩余列宽度 */ .cart-page-section table.cart td.product-price, .cart-page-section table.cart td.product-quantity, .cart-page-section table.cart td.product-subtotal { width: 16.67%; /* 三列平均分配剩余宽度 */ vertical-align: middle; } .cart-page-section .actions { text-align: right; margin-top: 20px; } .cart-page-section .actions .button { padding: 12px 24px; background-color: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; transition: background-color 0.3s; } .cart-page-section .actions .button:hover { background-color: #45a049; } .cart-footer-actions { position: sticky; bottom: 0; background: #fff; padding: 15px; border-top: 1px solid #ddd; box-shadow: 0 -2px 10px rgba(0,0,0,0.1); z-index: 100; } .cart-footer-actions .button { padding: 10px 20px; margin-left: 10px; background-color: #f44336; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; transition: background-color 0.3s; } .cart-footer-actions .button:hover { background-color: #d32f2f; } #partial-checkout { padding: 12px 24px; background-color: #2196F3; color: white; text-decoration: none; border-radius: 4px; display: inline-block; margin-top: 10px; transition: background-color 0.3s; } #partial-checkout:hover { background-color: #0b7dda; } .selected-summary { font-size: 16px; font-weight: bold; } .selected-summary p { margin: 0 0 10px 0; } /* Responsive styles */ @media (max-width: 768px) { .cart-page-section table.cart thead { display: none; } .cart-page-section table.cart td { display: block; width: 100% !important; text-align: right; padding: 10px; position: relative; padding-left: 50%; } .cart-page-section table.cart td::before { content: attr(data-title); position: absolute; left: 15px; font-weight: bold; text-align: left; } .cart-page-section table.cart .product-info .product-image { float: none; margin: 0 auto 10px; } .cart-footer-actions { position: relative; } .cart-footer-actions > div { flex-direction: column; align-items: flex-start; } .cart-footer-actions .selected-summary { margin-top: 20px; text-align: left; width: 100%; } } </style> <script> jQuery(document).ready(function($) { // Define our AJAX parameters var wc_cart_params = { ajax_url: '<?php echo admin_url('admin-ajax.php'); ?>', cart_nonce: '<?php echo wp_create_nonce('woocommerce-cart'); ?>' }; // Update selected items summary function updateSelectedSummary() { let total = 0; let count = 0; $('.item-checkbox:checked').each(function() { total += parseFloat($(this).data('price')); count++; }); $('#selected-count').text(count); $('#selected-total').text('RM' + total.toFixed(2)); } // Select all functionality $('#select-all-items, #footer-select-all').change(function() { const isChecked = $(this).prop('checked'); $('.item-checkbox').prop('checked', isChecked); updateSelectedSummary(); }); // Individual checkbox change $('.item-checkbox').change(updateSelectedSummary); // Remove selected items $('#remove-selected-items').click(function() { const selectedKeys = $('.item-checkbox:checked').map(function() { return this.value; }).get(); if (selectedKeys.length === 0) { alert('请选择要删除的商品'); return; } if (!confirm('确定要删除选中的商品吗?')) { return; } $.ajax({ type: 'POST', url: wc_cart_params.ajax_url, data: { action: 'remove_selected_cart_items', selected_items: selectedKeys, security: wc_cart_params.cart_nonce }, success: function(response) { if (response.success) { location.reload(); } }, error: function() { alert('删除失败,请重试'); } }); }); // Clear entire cart $('#clear-cart').click(function() { if (!confirm('确定要清空购物车吗?')) { return; } $.ajax({ type: 'POST', url: wc_cart_params.ajax_url, data: { action: 'clear_entire_cart', security: wc_cart_params.cart_nonce }, success: function(response) { if (response.success) { location.reload(); } }, error: function() { alert('清空购物车失败,请重试'); } }); }); // Partial checkout $('#partial-checkout').click(function(e) { e.preventDefault(); const selectedKeys = $('.item-checkbox:checked').map(function() { return this.value; }).get(); if (selectedKeys.length === 0) { alert('请至少选择一件商品结算'); return false; } // Show loading indicator $(this).html('处理中...').prop('disabled', true); // Store selected items in session $.ajax({ type: 'POST', url: wc_cart_params.ajax_url, data: { action: 'store_selected_items', selected_items: selectedKeys, security: wc_cart_params.cart_nonce }, success: function(response) { if (response.success) { window.location.href = '<?php echo esc_url(wc_get_checkout_url()); ?>'; } else { alert('结算失败,请重试'); $('#partial-checkout').html('结算').prop('disabled', false); } }, error: function() { alert('发生错误,请重试'); $('#partial-checkout').html('结算').prop('disabled', false); } }); }); // Initialize summary updateSelectedSummary(); }); </script> This is the full code in my functions.php // 完全删除旧的"部分结账"相关代码 // 替换为以下完整优化版本 // ===== 部分结账功能核心代码 ===== // // 存储选中商品到会话 add_action('wp_ajax_store_selected_items', 'store_selected_items'); add_action('wp_ajax_nopriv_store_selected_items', 'store_selected_items'); function store_selected_items() { check_ajax_referer('woocommerce-cart', 'security'); if (isset($_POST['selected_items'])) { $sanitized_items = array_map('sanitize_text_field', $_POST['selected_items']); WC()->session->set('selected_checkout_items', $sanitized_items); wp_send_json_success(); } wp_send_json_error(); } // 折扣计算应用购物车过滤 (解决折扣问题) add_action('woocommerce_before_calculate_totals', 'apply_partial_cart_before_discounts', 5); function apply_partial_cart_before_discounts() { if (!is_checkout() || is_wc_endpoint_url('order-received') || !WC()->session) { return; } $selected_items = WC()->session->get('selected_checkout_items'); if (!empty($selected_items)) { $cart = WC()->cart; $cart_contents = $cart->cart_contents; $filtered_contents = array(); foreach ($cart_contents as $key => $item) { if (in_array($key, $selected_items)) { $filtered_contents[$key] = $item; } } $cart->cart_contents = $filtered_contents; } } // 结账页面显示过滤 add_filter('woocommerce_get_cart_contents', 'filter_cart_contents_for_checkout', 20, 1); function filter_cart_contents_for_checkout($cart_contents) { if (is_checkout() && !is_wc_endpoint_url('order-received') && WC()->session) { $selected_items = WC()->session->get('selected_checkout_items'); if (!empty($selected_items)) { $filtered_contents = array(); foreach ($cart_contents as $key => $item) { if (in_array($key, $selected_items)) { $filtered_contents[$key] = $item; } } return $filtered_contents; } } return $cart_contents; } // 结账后恢复购物车 add_action('woocommerce_checkout_update_order_meta', 'restore_full_cart_after_checkout', 10, 2); function restore_full_cart_after_checkout($order_id, $data) { if (!WC()->session) return; // 备份完整购物车 $full_cart = WC()->cart->get_cart(); WC()->session->set('full_cart_backup', $full_cart); } // 订单感谢页处理 add_action('woocommerce_thankyou', 'remove_selected_items_after_checkout', 10, 1); function remove_selected_items_after_checkout($order_id) { if (!WC()->session) return; $selected_items = WC()->session->get('selected_checkout_items'); if (!empty($selected_items)) { // 恢复完整购物车 $full_cart = WC()->session->get('full_cart_backup'); if ($full_cart) { WC()->cart->cart_contents = $full_cart; WC()->session->__unset('full_cart_backup'); } WC()->session->__unset('selected_checkout_items'); WC()->cart->calculate_totals(); } } // AJAX移除选中商品 add_action('wp_ajax_remove_selected_cart_items', 'remove_selected_cart_items'); add_action('wp_ajax_nopriv_remove_selected_cart_items', 'remove_selected_cart_items'); function remove_selected_cart_items() { check_ajax_referer('woocommerce-cart', 'security'); if (isset($_POST['selected_items'])) { foreach ($_POST['selected_items'] as $cart_item_key) { $sanitized_key = sanitize_text_field($cart_item_key); if (WC()->cart->get_cart_item($sanitized_key)) { WC()->cart->remove_cart_item($sanitized_key); } } wp_send_json_success(); } wp_send_json_error(); } // 覆盖购物车清空方法 add_action('woocommerce_init', 'override_woocommerce_cart'); function override_woocommerce_cart() { if (!class_exists('WC_Cart') || !WC()->session) return; class WC_Cart_Custom extends WC_Cart { public function empty_cart($force_session = false) { if (WC()->session && WC()->session->get('selected_checkout_items')) { return; // 阻止清空 } parent::empty_cart($force_session); } } $GLOBALS['woocommerce']->cart = new WC_Cart_Custom(); } // ===== 辅助功能 ===== // // 移除购物车总计部分 add_action('template_redirect', 'remove_cart_totals_section'); function remove_cart_totals_section() { if (is_cart()) { remove_action('woocommerce_cart_collaterals', 'woocommerce_cart_totals', 10); } } // 加载必要脚本 add_action('wp_enqueue_scripts', 'partial_checkout_scripts'); function partial_checkout_scripts() { if (is_cart()) { wp_enqueue_script('wc-cart'); wp_localize_script('wc-cart', 'wc_cart_params', array( 'ajax_url' => admin_url('admin-ajax.php'), 'cart_nonce' => wp_create_nonce('woocommerce-cart') )); } } // 放弃结账时恢复原始购物车 add_action('template_redirect', 'restore_original_cart_if_abandoned'); function restore_original_cart_if_abandoned() { if (is_cart() && WC()->session && WC()->session->get('selected_checkout_items')) { WC()->session->__unset('selected_checkout_items'); } } the dynamic discount is not applied, Without changing the 成功了的 function, please check which part goes wrong and give me the full code to be replaced with the current one.
08-01
It says There has been a critical error on this website. Please review my code cart.php: <?php /** * The template for displaying the cart page. * * This file has been modified to support selective checkout with checkboxes. * * @package woodmart */ defined( 'ABSPATH' ) || exit; do_action( 'woocommerce_before_cart' ); ?> <form class="woocommerce-cart-form" action="<?php echo esc_url( wc_get_cart_url() ); ?>" method="post"> <?php do_action( 'woocommerce_before_cart_table' ); ?> <table class="shop_table shop_table_responsive cart woocommerce-cart-form__contents" cellspacing="0"> <thead> <tr> <th class="product-select"><input type="checkbox" id="select-all-items"> Select All</th> <th class="product-name"><?php esc_html_e( 'Product', 'woocommerce' ); ?></th> <th class="product-price"><?php esc_html_e( 'Price', 'woocommerce' ); ?></th> <th class="product-quantity"><?php esc_html_e( 'Quantity', 'woocommerce' ); ?></th> <th class="product-subtotal"><?php esc_html_e( 'Subtotal', 'woocommerce' ); ?></th> <th class="product-remove"> </th> </tr> </thead> <tbody> <?php do_action( 'woocommerce_before_cart_contents' ); ?> <?php foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) { $_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key ); $product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key ); if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_cart_item_visible', true, $cart_item, $cart_item_key ) ) { $product_permalink = apply_filters( 'woocommerce_cart_item_permalink', $_product->is_visible() ? $_product->get_permalink( $cart_item ) : '', $cart_item, $cart_item_key ); ?> <tr class="woocommerce-cart-form__cart-item <?php echo esc_attr( apply_filters( 'woocommerce_cart_item_class', 'cart_item', $cart_item, $cart_item_key ) ); ?>"> <td class="product-select" data-title="<?php esc_attr_e( 'Select', 'woocommerce' ); ?>"> <label> <input type="checkbox" name="selected_items[]" value="<?php echo esc_attr( $cart_item_key ); ?>" checked> </label> functions.php: // Add checkbox to each cart item add_filter('woocommerce_cart_item_name', 'add_checkbox_to_cart_item', 10, 3); function add_checkbox_to_cart_item($item_name, $cart_item, $cart_item_key) { $checked = WC()->session->__isset('selected_items') && in_array($cart_item_key, WC()->session->get('selected_items')) ? 'checked' : 'checked'; $checkbox = '<label><input type="checkbox" name="selected_items[]" value="' . esc_attr($cart_item_key) . '" ' . $checked . '> ' . $item_name . '</label>'; return $checkbox; } // Handle AJAX request to update selected items add_action('wp_ajax_update_selected_cart_items', 'handle_update_selected_cart_items'); add_action('wp_ajax_nopriv_update_selected_cart_items', 'handle_update_selected_cart_items'); function handle_update_selected_cart_items() { if (isset($_POST['selected_items']) && is_array($_POST['selected_items'])) { $selected_items = array_map('sanitize_text_field', $_POST['selected_items']); WC()->session->set('selected_items', $selected_items); foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) { if (!in_array($cart_item_key, $selected_items)) { WC()->cart->set_quantity($cart_item_key, 0); } else { WC()->cart->set_quantity($cart_item_key, $cart_item['quantity']); } } wp_send_json_success(); } wp_send_json_error(); } // Only include selected items in order add_filter('woocommerce_add_to_order_from_cart_item', 'filter_items_during_checkout', 10, 3); function filter_items_during_checkout($bool, $cart_item_key, $order) { $selected_items = WC()->session->get('selected_items', []); if (!in_array($cart_item_key, $selected_items)) { return false; } return $bool; } // Reset session after checkout add_action('woocommerce_thankyou', 'reset_selected_items_session'); function reset_selected_items_session($order_id) { WC()->session->__unset('selected_items'); } js/custom-cart.js jQuery(document).ready(function($) { // Add "Select All" checkbox dynamically to cart (only if not already present) if ($('#select-all-items').length === 0) { $('.woocommerce-cart-form__contents').before( '<div class="select-all-wrapper" style="margin: 15px 0;">' + ' <label><input type="checkbox" id="select-all-items"> Select All</label>' + '</div>' ); } // Handle checkbox changes for individual items $(document).on('change', 'input[name="selected_items[]"]', function() { updateSelectedItemsAndSyncCart(); }); // Handle "Select All" checkbox change $(document).on('change', '#select-all-items', function() { var isChecked = $(this).is(':checked'); $('input[name="selected_items[]"]').prop('checked', isChecked); updateSelectedItemsAndSyncCart(); }); // Function to collect selected items and send AJAX request function updateSelectedItemsAndSyncCart() { let selectedItems = []; // Collect selected item keys $('input[name="selected_items[]"]:checked').each(function() { selectedItems.push($(this).val()); }); // Send AJAX request to update cart $.ajax({ url: wc_cart_params.ajax_url, type: 'POST', data: { action: 'update_selected_cart_items', selected_items: selectedItems }, success: function(response) { if (response) { // Refresh cart fragments and update checkout $('body').trigger('wc_fragment_refresh'); $('body').trigger('update_checkout'); // Update "Select All" checkbox state const allCheckboxes = $('input[name="selected_items[]"]'); const checkedCheckboxes = allCheckboxes.filter(':checked'); $('#select-all-items').prop('checked', allCheckboxes.length === checkedCheckboxes.length); } } }); } }); whats wrong?
07-30
so the full code would be // Store selected items in session before checkout add_action('wp_ajax_store_selected_items', 'store_selected_items'); add_action('wp_ajax_nopriv_store_selected_items', 'store_selected_items'); function store_selected_items() { check_ajax_referer('woocommerce-cart', 'security'); if (isset($_POST['selected_items'])) { WC()->session->set('selected_checkout_items', $_POST['selected_items']); wp_send_json_success(); } wp_send_json_error(); } // Filter cart contents to only include selected items during checkout add_filter('woocommerce_get_cart_contents', 'filter_cart_contents_for_checkout', 20, 1); function filter_cart_contents_for_checkout($cart_contents) { // Only on checkout page if (is_checkout() && !is_wc_endpoint_url('order-received')) { $selected_items = WC()->session->get('selected_checkout_items'); if (!empty($selected_items)) { $filtered_contents = array(); foreach ($cart_contents as $key => $item) { if (in_array($key, $selected_items)) { $filtered_contents[$key] = $item; } } return $filtered_contents; } } return $cart_contents; } // 修改原 remove_selected_items_after_checkout 函数 function remove_selected_items_after_checkout($order_id) { $selected_items = WC()->session->get('selected_checkout_items'); if (!empty($selected_items)) { foreach ($selected_items as $cart_item_key) { WC()->cart->remove_cart_item($cart_item_key); } // 清除会话数据(关键!) WC()->session->__unset('selected_checkout_items'); // 手动触发购物车更新(确保未选中商品保留) WC()->cart->calculate_totals(); } } // Clear session data WC()->session->__unset('selected_checkout_items'); // AJAX remove selected items add_action('wp_ajax_remove_selected_cart_items', 'remove_selected_cart_items'); add_action('wp_ajax_nopriv_remove_selected_cart_items', 'remove_selected_cart_items'); function remove_selected_cart_items() { check_ajax_referer('woocommerce-cart', 'security'); if (isset($_POST['selected_items'])) { foreach ($_POST['selected_items'] as $cart_item_key) { WC()->cart->remove_cart_item(sanitize_text_field($cart_item_key)); } wp_send_json_success(); } wp_send_json_error(); } // Clear entire cart add_action('wp_ajax_clear_entire_cart', 'clear_entire_cart'); add_action('wp_ajax_nopriv_clear_entire_cart', 'clear_entire_cart'); function clear_entire_cart() { check_ajax_referer('woocommerce-cart', 'security'); WC()->cart->empty_cart(); wp_send_json_success(); } // Remove cart totals section add_action('template_redirect', 'remove_cart_totals_section'); function remove_cart_totals_section() { if (is_cart()) { remove_action('woocommerce_cart_collaterals', 'woocommerce_cart_totals', 10); } } // Enqueue necessary scripts add_action('wp_enqueue_scripts', 'partial_checkout_scripts'); function partial_checkout_scripts() { if (is_cart()) { wp_localize_script('wc-cart', 'wc_cart_params', array( 'ajax_url' => admin_url('admin-ajax.php'), 'cart_nonce' => wp_create_nonce('woocommerce-cart') )); } } // Restore original cart if checkout is abandoned add_action('template_redirect', 'restore_original_cart_if_abandoned'); function restore_original_cart_if_abandoned() { if (is_cart() && WC()->session->get('selected_checkout_items')) { // Clear the session to prevent filtering on next checkout attempt WC()->session->__unset('selected_checkout_items'); } } add_action('woocommerce_init', 'override_woocommerce_cart'); function override_woocommerce_cart() { if (!class_exists('WC_Cart') || !WC()->session) return; // 关键修复:检查 session 是否存在 class WC_Cart_Custom extends WC_Cart { public function empty_cart($force_session = false) { // 安全检查:确保 session 已初始化 if (WC()->session && WC()->session->get('selected_checkout_items')) { return; } parent::empty_cart($force_session); } } // 替换全局 cart 实例 $GLOBALS['woocommerce']->cart = new WC_Cart_Custom(); } correct?
08-01
我的代码: from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException, ElementClickInterceptedException import time class PageChangeDetector: def __init__(self, headless=False): chrome_options = Options() if headless: chrome_options.add_argument("--headless") self.driver = webdriver.Chrome(options=chrome_options) self.driver.get(login_url) self.action = ActionChains(self.driver) def login(self, email_1, password_1): try: email_input = WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.NAME, 'email')) ) email_input.send_keys(email_1) password_input = WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.NAME, 'current-password')) ) password_input.send_keys(password_1) login_button = self.driver.find_element(By.CSS_SELECTOR, 'button[type="submit"]') login_button.click() time.sleep(1) return True except TimeoutException: print("登录失败,元素未加载或超时") return False except Exception as e: print(f"登录过程中发生错误: {str(e)}") return False def get_page_state(self): return { "url": self.driver.current_url, "title": self.driver.title, "window_handles": len(self.driver.window_handles), "body_text": self.driver.find_element(By.TAG_NAME, "body").text, # 修改:获取字符串文本 "page_height": self.driver.execute_script("return document.body.scrollHeight;"), "html_hash": hash(self.driver.find_element(By.TAG_NAME, "html").get_attribute("outerHTML")) } def compare_states(self, before, after): changes = {} for key in before: if before[key] != after[key]: changes[key] = {"before": before[key], "after": after[key]} return changes def get_all_button_elements(self): """获取当页面中所有可见的 button 元素""" script = """ const buttons = Array.from(document.querySelectorAll('button')); return buttons.filter(btn => { const style = window.getComputedStyle(btn); return style.display !== 'none' && style.visibility !== 'hidden'; }); """ return self.driver.execute_script(script) def click_and_detect_changes(self, element): # 记录点击状态 before_state = self.get_page_state() before_buttons = self.get_all_button_elements() print("点击页面状态:", before_state) try: element.click() except Exception as e: print("点击失败:", e) return [] try: WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.TAG_NAME, 'button')) ) except TimeoutException: print("等待按钮加载超时") time.sleep(1) after_state = self.get_page_state() after_buttons = self.get_all_button_elements() print("点击后页面状态:", after_state) changes = self.compare_states(before_state, after_state) if changes: print("检测到页面变化:") for key, value in changes.items(): print(f" - {key}: {value['before']} → {value['after']}") else: print("页面无变化") #判断按钮是否是默认展开的 if len(after_buttons) < len(before_buttons): try: element.click() except Exception as e: print("点击失败:", e) return [] after_buttons_1 = self.get_all_button_elements() new_buttons = list(set(before_buttons) - set(after_buttons_1)) try: WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.TAG_NAME, 'button')) ) except TimeoutException: print("等待按钮加载超时") time.sleep(1) else: new_buttons = list(set(after_buttons) - set(before_buttons)) return new_buttons def safe_click(self, element): try: element.click() except ElementClickInterceptedException: print("元素被遮挡,尝试使用 JavaScript 点击") self.driver.execute_script("arguments[0].click();", element) def run_automation(self, email_1, password_1): try: login_success = self.login(email_1, password_1) if not login_success: print("登录失败,无法继续自动化操作") return print("登录成功,开始自动化操作...") # 点击“高级对话设置”按钮 advanced_settings_button = WebDriverWait(self.driver, 10).until( EC.element_to_be_clickable((By.XPATH, "//button[@aria-label='Controls']")) ) self.safe_click(advanced_settings_button) print("已点击“高级对话设置”按钮") link = WebDriverWait(self.driver, 10).until( EC.element_to_be_clickable((By.XPATH, "//div[text()='高度なパラメータ']")) ) new_buttons = self.click_and_detect_changes(link) if new_buttons: print(f"找到 {len(new_buttons)} 个新增按钮:", new_buttons) for btn_text in new_buttons: try: button_element = WebDriverWait(self.driver, 10).until( EC.element_to_be_clickable((By.XPATH, f"//button[normalize-space()='{btn_text}']")) ) button_element.click() print(f"已点击按钮: {btn_text}") time.sleep(0.5) except Exception as e: print(f"点击按钮 '{btn_text}' 时出错: {str(e)}") else: print("未检测到新增按钮") print("自动化操作完成") except Exception as e: print(f"自动化过程中发生错误: {str(e)}") finally: time.sleep(1) self.driver.quit() if __name__ == "__main__": login_url = "http://10.244.1.179:3000/" email_1 = "shengkai.qu@brother-bsh.com.cn" password_1 = "q123456.+" automator = PageChangeDetector(headless=False) automator.run_automation(email_1, password_1) 有问题的地方: 1.webElement被当作字符串 for btn_text in new_buttons: try: button_element = WebDriverWait(self.driver, 10).until( EC.element_to_be_clickable((By.XPATH, f"//button[normalize-space()='{btn_text}']")) ) 2.用selenium在点击后获取的失效 before_state = self.get_page_state() before_buttons = self.get_all_button_elements() print("点击页面状态:", before_state) try: element.click() except Exception as e: print("点击失败:", e) return [] try: WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.TAG_NAME, 'button')) ) except TimeoutException: print("等待按钮加载超时") time.sleep(1) after_state = self.get_page_state() after_buttons = self.get_all_button_elements() print("点击后页面状态:", after_state) changes = self.compare_states(before_state, after_state) if changes: print("检测到页面变化:") for key, value in changes.items(): print(f" - {key}: {value['before']} → {value['after']}") else: print("页面无变化") #判断按钮是否是默认展开的 if len(after_buttons) < len(before_buttons): try: element.click() except Exception as e: print("点击失败:", e) return [] after_buttons_1 = self.get_all_button_elements() new_buttons = list(set(before_buttons) - set(after_buttons_1)) try: WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.TAG_NAME, 'button')) ) except TimeoutException: print("等待按钮加载超时") time.sleep(1) else: new_buttons = list(set(after_buttons) - set(before_buttons)) return new_buttons 运行结果是元素无法点击,修改代码
最新发布
08-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值