Shopify手机端和电脑端显示不同的海报banner以及产品尺寸和位置

{% schema %}
{
  "name": "Hotends_Bulk_Sale_hengfu",
  "tag": "section",
  "class": "promotional-banner",
  "settings": [
    {
      "type": "image_picker",
      "id": "custom_background",
      "label": "上传背景图片"
    },
    {
      "type": "image_picker",
      "id": "mobile_background",
      "label": "上传手机端背景图片"
    },
    {
      "type": "range",
      "id": "section_height",
      "min": 100,
      "max": 1000,
      "step": 10,
      "unit": "px",
      "label": "模块高度",
      "default": 400
    },
    {
      "type": "range",
      "id": "mobile_section_height",
      "min": 100,
      "max": 1000,
      "step": 10,
      "unit": "px",
      "label": "手机端模块高度",
      "default": 280
    },
    {
      "type": "select",
      "id": "background_position",
      "label": "背景图片位置",
      "options": [
        { "value": "top left", "label": "左上" },
        { "value": "top center", "label": "顶部居中" },
        { "value": "top right", "label": "右上" },
        { "value": "center left", "label": "左中" },
        { "value": "center center", "label": "正中" },
        { "value": "center right", "label": "右中" },
        { "value": "bottom left", "label": "左下" },
        { "value": "bottom center", "label": "底部居中" },
        { "value": "bottom right", "label": "右下" }
      ],
      "default": "center center"
    },
    {
      "type": "select",
      "id": "background_size",
      "label": "背景图片尺寸",
      "options": [
        { "value": "cover", "label": "填充" },
        { "value": "contain", "label": "适应" },
        { "value": "auto", "label": "原始大小" }
      ],
      "default": "cover"
    },
    {
      "type": "range",
      "id": "background_opacity",
      "min": 0,
      "max": 100,
      "step": 10,
      "unit": "%",
      "label": "背景透明度",
      "default": 100
    }
  ],
  "presets": [
    {
      "name": "Hotends_Bulk_Sale_hengfu"
    }
  ]
}
{% endschema %}

<style>
.promotional-banner {
  position: relative;
  width: 100%;
  height: {{ section.settings.section_height }}px;
  overflow: hidden;
}
.promotional-banner__background,
.promotional-banner__background-mobile {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  object-fit: {{ section.settings.background_size }};
  object-position: {{ section.settings.background_position }};
  opacity: {{ section.settings.background_opacity | divided_by: 100.0 }};
  z-index: 1;
  display: block;
}
.promotional-banner__background-mobile {
  display: none;
}

@media screen and (max-width: 749px) {
  .promotional-banner {
    height: {{ section.settings.mobile_section_height }}px;
  }
  .promotional-banner__background {
    display: none !important;
  }
  .promotional-banner__background-mobile {
    display: block !important;
  }
}
</style>

<div class="promotional-banner">
  {% if section.settings.custom_background %}
    {{ section.settings.custom_background | image_url: width: 2000 | image_tag: 
      class: 'promotional-banner__background',
      loading: 'lazy',
      sizes: '100vw'
    }}
  {% endif %}
  {% if section.settings.mobile_background %}
    {{ section.settings.mobile_background | image_url: width: 1000 | image_tag: 
      class: 'promotional-banner__background-mobile',
      loading: 'lazy',
      sizes: '100vw'
    }}
  {% endif %}
</div>

重点说明

  • 电脑端只显示 custom_background,手机端只显示 mobile_background。
  • 高度分别用 section_height 和 mobile_section_height 控制。
  • 所有文字内容已删除,只保留背景图片。
  • 你可以在 Shopify 后台分别上传 PC 和手机端图片,并设置不同高度。
... 阅读更多

安卓微信客户端保留数据强制降级的方法

今天在 apkpure 下载软件的时候无意中看到微信有新版本了,秉着体验最新功能的想法没有查看版本,直接点击了升级,结果升级了五分钟还卡在升级中,发现情况不对,于是我看下了apkpure的版本, 结果发现特么这个版本只有100多M,最新的微信版本应该是200多M,情况不太对,于是仔细研究了下这个版本,特么是车载版,手机端是无法使用的,第一次见将不同版本的app放到正式版的。... 阅读更多

wordpress 独立站设置动态阶梯价格教程 可以根据客户订购的数量设置不通的优惠金额

// 添加后台菜单
add_action('admin_menu', 'add_bulk_discount_menu');
function add_bulk_discount_menu() {
    add_menu_page(
        '批量折扣设置',
        '批量折扣',
        'manage_options',
        'bulk-discount-settings',
        'bulk_discount_settings_page',
        'dashicons-tag',
        56
    );
}

// 注册设置
add_action('admin_init', 'register_bulk_discount_settings');
function register_bulk_discount_settings() {
    register_setting('bulk_discount_options', 'bulk_discount_rules');
}

// 创建设置页面
function bulk_discount_settings_page() {
    $rules = get_option('bulk_discount_rules', array(
        array(
            'min' => 1,
            'max' => 100,
            'discount' => 99,
            'label' => '1-100件'
        )
    ));
    ?>
    <div class="wrap">
        <h1>批量折扣设置</h1>
        <form method="post" action="options.php" id="bulk-discount-form">
            <?php settings_fields('bulk_discount_options'); ?>
            
            <div class="discount-rules-container">
                <h2>折扣规则</h2>
                <p class="description">设置不同数量范围的折扣百分比,例如:数量1-100,折扣99%表示99折</p>
                <table class="wp-list-table widefat fixed striped" id="discount-rules-table">
                    <thead>
                        <tr>
                            <th>最小数量</th>
                            <th>最大数量</th>
                            <th>折扣(%)</th>
                            <th>描述</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody id="discount-rules-body">
                        <?php foreach ($rules as $index => $rule): ?>
                        <tr class="rule-row">
                            <td>
                                <input type="number" name="bulk_discount_rules[<?php echo $index; ?>][min]" 
                                       value="<?php echo esc_attr($rule['min']); ?>" required min="1">
                            </td>
                            <td>
                                <input type="number" name="bulk_discount_rules[<?php echo $index; ?>][max]" 
                                       value="<?php echo esc_attr($rule['max']); ?>" required min="1">
                            </td>
                            <td>
                                <input type="number" name="bulk_discount_rules[<?php echo $index; ?>][discount]" 
                                       value="<?php echo esc_attr($rule['discount']); ?>" required min="1" max="100" step="0.1">
                            </td>
                            <td>
                                <input type="text" name="bulk_discount_rules[<?php echo $index; ?>][label]" 
                                       value="<?php echo esc_attr($rule['label']); ?>" required>
                            </td>
                            <td>
                                <button type="button" class="button delete-rule">删除</button>
                            </td>
                        </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
                
                <div class="rule-actions">
                    <button type="button" class="button button-secondary" id="add-rule">添加规则</button>
                    <button type="submit" class="button button-primary">保存设置</button>
                </div>
            </div>
        </form>
    </div>

    <style>
        .discount-rules-container {
            margin-top: 20px;
            max-width: 1000px;
        }
        .rule-row input {
            width: 100%;
        }
        .rule-actions {
            margin-top: 20px;
        }
        .delete-rule {
            color: #dc3232;
        }
        #discount-rules-table {
            margin-top: 10px;
        }
        #discount-rules-table th,
        #discount-rules-table td {
            padding: 10px;
        }
        .description {
            color: #666;
            font-style: italic;
            margin-bottom: 15px;
        }
    </style>

    <script>
    jQuery(document).ready(function($) {
        // 添加新规则
        $('#add-rule').click(function() {
            var rowCount = $('.rule-row').length;
            var newRow = `
                <tr class="rule-row">
                    <td>
                        <input type="number" name="bulk_discount_rules[${rowCount}][min]" required min="1">
                    </td>
                    <td>
                        <input type="number" name="bulk_discount_rules[${rowCount}][max]" required min="1">
                    </td>
                    <td>
                        <input type="number" name="bulk_discount_rules[${rowCount}][discount]" required min="1" max="100" step="0.1">
                    </td>
                    <td>
                        <input type="text" name="bulk_discount_rules[${rowCount}][label]" required>
                    </td>
                    <td>
                        <button type="button" class="button delete-rule">删除</button>
                    </td>
                </tr>
            `;
            $('#discount-rules-body').append(newRow);
        });

        // 删除规则
        $(document).on('click', '.delete-rule', function() {
            $(this).closest('tr').remove();
            reindexRows();
        });

        // 重新索引行
        function reindexRows() {
            $('.rule-row').each(function(index) {
                $(this).find('input').each(function() {
                    var name = $(this).attr('name');
                    $(this).attr('name', name.replace(/\[\d+\]/, '[' + index + ']'));
                });
            });
        }
    });
    </script>
    <?php
}

// 获取折扣规则
function get_quantity_discount_rules() {
    $rules = get_option('bulk_discount_rules', array());
    $formatted_rules = array();
    
    foreach ($rules as $rule) {
        $formatted_rules[] = array(
            'min' => intval($rule['min']),
            'max' => intval($rule['max']),
            'discount' => floatval($rule['discount']) / 100,
            'label' => $rule['label']
        );
    }
    
    return $formatted_rules;
}

// 获取特定数量对应的折扣
function get_discount_for_quantity($quantity) {
    $rules = get_quantity_discount_rules();
    foreach ($rules as $rule) {
        if ($quantity >= $rule['min'] && $quantity <= $rule['max']) {
            return $rule['discount'];
        }
    }
    return 1; // 如果没有匹配的规则,返回原价
}

// 在产品详情页显示价格表
add_action('woocommerce_single_product_summary', 'display_quantity_discount_table', 11);
function display_quantity_discount_table() {
    global $product;
    
    $price = $product->get_price();
    $rules = get_quantity_discount_rules();
    
    if (empty($rules)) {
        return;
    }
    
    echo '<div class="quantity-discount-table">';
    echo '<div class="discount-table-header">';
    echo '<span class="discount-title">Bulk Pricing</span>';
    echo '<span class="discount-info">Buy more, save more!</span>';
    echo '</div>';
    echo '<table class="discount-table">';
    echo '<thead>';
    echo '<tr>';
    echo '<th>Quantity</th>';
    echo '<th>Discount</th>';
    echo '<th>Price</th>';
    echo '</tr>';
    echo '</thead>';
    echo '<tbody>';
    
    foreach ($rules as $rule) {
        $discounted_price = number_format($price * $rule['discount'], 2);
        $discount_percentage = 100 - ($rule['discount'] * 100);
        echo '<tr>';
        echo '<td>' . esc_html($rule['label']) . '</td>';
        echo '<td>' . number_format($discount_percentage, 1) . '% OFF</td>';
        echo '<td>$' . $discounted_price . '</td>';
        echo '</tr>';
    }
    
    echo '</tbody>';
    echo '</table>';
    echo '</div>';
}

// 修改产品列表页的价格显示
add_filter('woocommerce_get_price_html', 'modify_price_range_display', 100, 2);
function modify_price_range_display($price_html, $product) {
    if (is_product()) {
        return $price_html;
    }
    
    $rules = get_quantity_discount_rules();
    if (empty($rules)) {
        return $price_html;
    }
    
    $price = $product->get_price();
    $prices = array();
    
    foreach ($rules as $rule) {
        $prices[] = $price * $rule['discount'];
    }
    
    if (!empty($prices)) {
        $min_price = min($prices);
        $max_price = max($prices);
        
        return sprintf(
            '<span class="woocs_price_code" data-currency="">
                <span class="woocommerce-Price-amount amount">
                    <bdi>%s-%s<span class="woocommerce-Price-currencySymbol">$</span></bdi>
                </span>
            </span>',
            number_format($min_price, 2),
            number_format($max_price, 2)
        );
    }
    
    return $price_html;
}

// 添加样式
add_action('wp_head', 'add_discount_table_styles');
function add_discount_table_styles() {
    ?>
    <style>
        /* 价格表样式优化 */
        .quantity-discount-table {
            margin: 15px 0;
            background: #fff;
            border: 1px solid #e1e1e1;
            border-radius: 6px;
            box-shadow: 0 1px 3px rgba(0,0,0,0.05);
            font-size: 14px;
            max-width: 400px;
        }
        
        .discount-table-header {
            padding: 10px 15px;
            border-bottom: 1px solid #e1e1e1;
            background: #f8f9fa;
            border-radius: 6px 6px 0 0;
        }
        
        .discount-title {
            display: block;
            font-weight: 600;
            color: #2c3338;
            font-size: 15px;
            margin-bottom: 2px;
        }
        
        .discount-info {
            display: block;
            color: #666;
            font-size: 12px;
        }
        
        .discount-table {
            width: 100%;
            border-collapse: collapse;
            margin: 0;
        }
        
        .discount-table th,
        .discount-table td {
            padding: 8px 12px;
            text-align: center;
            border: none;
            border-bottom: 1px solid #e1e1e1;
            font-size: 13px;
        }
        
        .discount-table th {
            background: #fff;
            color: #666;
            font-weight: 500;
            font-size: 12px;
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }
        
        .discount-table tr:last-child td {
            border-bottom: none;
        }
        
        .discount-table td:first-child {
            color: #2c3338;
            font-weight: 500;
        }
        
        .discount-table td:nth-child(2) {
            color: #28a745;
            font-weight: 500;
        }
        
        .discount-table td:last-child {
            color: #2c3338;
            font-weight: 600;
        }
        
        .discount-table tr:hover {
            background: #f8f9fa;
        }
        
        /* 购物车折扣信息样式 */
        .cart-discount-info {
            font-size: 12px;
            color: #28a745;
            margin-top: 4px;
            padding: 2px 6px;
            background: #e8f5e9;
            border-radius: 3px;
            display: inline-block;
        }
        
        /* 购物车顶部折扣提示样式 */
        .cart-discount-notice {
            background: #f8f9fa;
            padding: 12px 15px;
            border-radius: 6px;
            margin-bottom: 20px;
            border: 1px solid #e1e1e1;
            font-size: 14px;
        }
        
        .cart-discount-notice h4 {
            margin: 0 0 8px 0;
            color: #2c3338;
            font-size: 16px;
        }
        
        .cart-discount-notice table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 8px;
            font-size: 13px;
        }
        
        .cart-discount-notice th,
        .cart-discount-notice td {
            padding: 6px 8px;
            border: 1px solid #e1e1e1;
            text-align: center;
        }
        
        .cart-discount-notice th {
            background: #f0f0f0;
            font-weight: 500;
        }
        
        /* 移动端适配 */
        @media (max-width: 768px) {
            .quantity-discount-table {
                font-size: 13px;
                margin: 10px 0;
            }
            
            .discount-table th,
            .discount-table td {
                padding: 6px 8px;
            }
            
            .cart-discount-notice {
                font-size: 13px;
                padding: 10px;
            }
        }
    </style>
    <?php
}

// 修改购物车中的商品价格
add_action('woocommerce_before_calculate_totals', 'apply_quantity_based_discount', 20, 1);
function apply_quantity_based_discount($cart) {
    if (is_admin() && !defined('DOING_AJAX')) {
        return;
    }

    // 防止多次执行
    if (did_action('woocommerce_before_calculate_totals') >= 2) {
        return;
    }

    // 遍历购物车中的每个商品
    foreach ($cart->get_cart() as $cart_item) {
        $quantity = $cart_item['quantity'];
        $product = $cart_item['data'];

        // 获取产品的促销价格(如果有)
        $sale_price = $product->get_sale_price();
        $regular_price = $product->get_regular_price();

        // 如果产品有促销价格,则使用促销价格,否则使用原价
        $price_to_apply = $sale_price ? $sale_price : $regular_price;

        // 获取适用的折扣
        $discount = get_discount_for_quantity($quantity);

        // 根据折扣计算新的价格
        $discounted_price = $price_to_apply * $discount;

        // 更新购物车商品价格
        $cart_item['data']->set_price($discounted_price);
    }
}

// 在购物车页面显示折扣信息
add_action('woocommerce_after_cart_item_name', 'display_cart_item_discount', 10, 2);
function display_cart_item_discount($cart_item, $cart_item_key) {
    $quantity = $cart_item['quantity'];
    $discount = get_discount_for_quantity($quantity);
    $discount_percentage = (1 - $discount) * 100;
    
    if ($discount < 1) {
        echo '<div class="cart-discount-info">';
        echo sprintf('%.1f%% OFF applied for quantity of %d', $discount_percentage, $quantity);
        echo '</div>';
    }
}

// 在购物车页面显示数量变化时的价格更新提示
add_action('wp_footer', 'add_quantity_change_script');
function add_quantity_change_script() {
    if (!is_cart()) return;
    ?>
    <script>
    jQuery(document).ready(function($) {
        var timeout;
        
        $('.quantity input.qty').on('change', function() {
            clearTimeout(timeout);
            timeout = setTimeout(function() {
                $('[name="update_cart"]').trigger('click');
            }, 500);
        });
    });
    </script>
    <?php
}

// 添加购物车页面的折扣提示样式
add_action('wp_head', 'add_cart_discount_styles');
function add_cart_discount_styles() {
    if (!is_cart() && !is_checkout()) return;
    ?>
    <style>
        .cart-discount-info {
            font-size: 0.9em;
            color: #28a745;
            margin-top: 5px;
            padding: 3px 8px;
            background: #e8f5e9;
            border-radius: 3px;
            display: inline-block;
        }
        
        .cart-discount-notice {
            background: #f8f9fa;
            padding: 15px;
            border-radius: 5px;
            margin-bottom: 20px;
            border-left: 4px solid #28a745;
        }
        
        .cart-discount-notice h4 {
            margin: 0 0 10px 0;
            color: #333;
        }
        
        .cart-discount-notice table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 10px;
        }
        
        .cart-discount-notice th,
        .cart-discount-notice td {
            padding: 8px;
            border: 1px solid #ddd;
            text-align: center;
        }
        
        .cart-discount-notice th {
            background: #f0f0f0;
        }
        
        @media (max-width: 768px) {
            .cart-discount-notice {
                font-size: 14px;
                padding: 10px;
            }
        }
    </style>
    <?php
}

// 在购物车页面顶部显示折扣规则提示
add_action('woocommerce_before_cart', 'display_cart_discount_notice');
function display_cart_discount_notice() {
    $rules = get_quantity_discount_rules();
    if (empty($rules)) return;
    
    echo '<div class="cart-discount-notice">';
    echo '<h4>Volume Discount Available</h4>';
    echo '<p>Save more with our bulk pricing:</p>';
    echo '<table>';
    echo '<tr><th>Order Quantity</th><th>Discount</th></tr>';
    
    foreach ($rules as $rule) {
        $discount_percentage = 100 - ($rule['discount'] * 100);
        echo '<tr>';
        echo '<td>' . esc_html($rule['label']) . '</td>';
        echo '<td>' . number_format($discount_percentage, 1) . '% OFF</td>';
        echo '</tr>';
    }
    
    echo '</table>';
    echo '</div>';
}

// 在结算页面显示折扣信息
add_action('woocommerce_review_order_before_cart_contents', 'display_checkout_discount_notice');
function display_checkout_discount_notice() {
    echo '<tr class="checkout-discount-notice">';
    echo '<td colspan="2">';
    echo '<div class="checkout-discount-info">';
    echo 'Volume discounts have been automatically applied to eligible items';
    echo '</div>';
    echo '</td>';
    echo '</tr>';
}

// Mini Cart 更新
add_filter('woocommerce_cart_item_price', 'update_cart_item_price_display', 10, 3);
function update_cart_item_price_display($price, $cart_item, $cart_item_key) {
    // 获取购物车中商品的数量
    $quantity = $cart_item['quantity'];
    
    // 获取商品对象
    $product = $cart_item['data'];
    
    // 获取产品的促销价格(如果存在)
    $sale_price = $product->get_sale_price();
    $regular_price = $product->get_regular_price();
    
    // 如果存在促销价格,使用促销价格进行计算
    $price_to_apply = $sale_price ? $sale_price : $regular_price;

    // 获取适用的折扣
    $discount = get_discount_for_quantity($quantity);

    // 根据折扣计算新的价格
    $discounted_price = $price_to_apply * $discount;

    // 返回格式化的折扣后价格
    return sprintf(
        '<span class="woocs_special_price_code"><span class="woocommerce-Price-amount amount"><bdi>%s<span class="woocommerce-Price-currencySymbol">$</span></bdi></span></span>',
        number_format($discounted_price, 2)
    );
}


// 添加Ajax数量更新支持
add_action('wp_ajax_update_cart_item_discount', 'ajax_update_cart_item_discount');
add_action('wp_ajax_nopriv_update_cart_item_discount', 'ajax_update_cart_item_discount');
function ajax_update_cart_item_discount() {
    $quantity = isset($_POST['quantity']) ? intval($_POST['quantity']) : 0;
    $product_id = isset($_POST['product_id']) ? intval($_POST['product_id']) : 0;
    
    if ($quantity && $product_id) {
        $product = wc_get_product($product_id);
        $discount = get_discount_for_quantity($quantity);
        $discounted_price = $product->get_regular_price() * $discount;
        
        wp_send_json_success(array(
            'price' => wc_price($discounted_price),
            'discount' => number_format((1 - $discount) * 100, 1)
        ));
    }
    
    wp_send_json_error();
}   
... 阅读更多

wordpress产品详情页显示获取产品的运输物流信息

// 显示产品发货时间信息
function display_product_shipping_time() {
    global $product;
    
    // 获取产品配送类别
    $shipping_class_id = $product->get_shipping_class_id();
    if ($shipping_class_id) {
        $shipping_class = get_term($shipping_class_id, 'product_shipping_class');
        if ($shipping_class && !is_wp_error($shipping_class)) {
            echo '<div class="product-shipping-info">';
            // 显示配送类别名称
            if (!empty($shipping_class->name)) {
                echo '<div class="shipping-time"><i class="klb-icon-delivery"></i> ' . esc_html($shipping_class->name) . '</div>';
            }
            echo '</div>';
            
            // 添加样式
            echo '<style>
                .product-shipping-info {
                    margin: 15px 0;
                    padding: 10px 15px;
                    border: 1px solid #e5e5e5;
                    background: #f9f9f9;
                    border-radius: 4px;
                }
                .shipping-time {
                    display: flex;
                    align-items: center;
                    gap: 8px;
                    color: #333;
                }
                .shipping-time i {
                    color: #4CAF50;
                }
            </style>';
        }
    }
}
add_action('woocommerce_after_add_to_cart_form', 'display_product_shipping_time');
... 阅读更多

一键添加所有产品分类到wordpress的产品目录 直接获取产品分类的层级关系来构建菜单

// 添加一个自定义按钮到菜单页面
add_action('admin_footer-nav-menus.php', function() {
    ?>
    <script type="text/javascript">
    jQuery(document).ready(function($) {
        // 添加自定义按钮
        var button = $('<a href="#" class="button-secondary" style="margin: 10px;">一键添加所有产品分类</a>');
        $('.menu-settings').before(button);

        button.on('click', function(e) {
            e.preventDefault();
            
            // 显示加载状态
            button.text('正在添加...').prop('disabled', true);
            
            // 发送Ajax请求
            $.ajax({
                url: ajaxurl,
                type: 'POST',
                data: {
                    action: 'add_product_categories_to_menu',
                    menu_id: $('#menu').val(),
                    nonce: '<?php echo wp_create_nonce("add-product-cats"); ?>'
                },
                success: function(response) {
                    if(response.success) {
                        // 刷新页面显示新添加的菜单项
                        window.location.reload();
                    } else {
                        alert('添加失败: ' + response.data);
                    }
                },
                error: function() {
                    alert('操作失败,请重试');
                    button.text('一键添加所有产品分类').prop('disabled', false);
                }
            });
        });
    });
    </script>
    <?php
});

// 处理Ajax请求
add_action('wp_ajax_add_product_categories_to_menu', function() {
    // 验证nonce
    if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'add-product-cats')) {
        wp_send_json_error('安全验证失败');
    }

    // 获取菜单ID
    $menu_id = intval($_POST['menu_id']);
    if (!$menu_id) {
        wp_send_json_error('无效的菜单ID');
    }

    // 获取所有产品分类
    $categories = get_terms([
        'taxonomy' => 'product_cat',
        'hide_empty' => false,
        'hierarchical' => true,
        'parent' => 0
    ]);

    if (is_wp_error($categories)) {
        wp_send_json_error('获取分类失败');
    }

    // 递归添加分类到菜单
    function add_category_to_menu($category, $menu_id, $parent_id = 0) {
        // 添加当前分类
        $item_data = [
            'menu-item-title' => $category->name,
            'menu-item-url' => get_term_link($category),
            'menu-item-type' => 'taxonomy',
            'menu-item-object' => 'product_cat',
            'menu-item-object-id' => $category->term_id,
            'menu-item-status' => 'publish',
            'menu-item-parent-id' => $parent_id
        ];

        $item_id = wp_update_nav_menu_item($menu_id, 0, $item_data);

        // 获取并添加子分类
        $children = get_terms([
            'taxonomy' => 'product_cat',
            'hide_empty' => false,
            'hierarchical' => true,
            'parent' => $category->term_id
        ]);

        if (!is_wp_error($children) && !empty($children)) {
            foreach ($children as $child) {
                add_category_to_menu($child, $menu_id, $item_id);
            }
        }

        return $item_id;
    }

    // 添加所有一级分类及其子分类
    foreach ($categories as $category) {
        add_category_to_menu($category, $menu_id);
    }

    wp_send_json_success('分类已成功添加到菜单');
});

这个解决方案的特点:在菜单编辑页面添加一个”一键添加所有产品分类”按钮... 阅读更多

115 + alist + rclone 实现 emby 直链播放

前言

  1. 通过 alist 将 115 网盘资源转成可以通过网络编辑和管理 webdav 协议。
  2. 通过 rclone 将 webdav 协议的资源挂载到本地硬盘
  3. embyserver 读取、刮削、入库 「2」 挂载好的资源
  4. 安装 nginx 实现对访问 embyserver 的流量进行转发、重写。将: 静态资源转发到 embyserver 服务上,视频资源的访问直接转发到 alist,从而利用 alist 的 302 转发实现直接访问网盘资源。(如图,少走了 alist -> webdav -> rclone -> emby 的过程,实现不走主机流量,直连网盘)

教程

1、安装list

看官方文档:https://alist.nn.ci/zh/guide/install/script.html,不做赘述... 阅读更多

清理调整wordpress产品缩略图规格以及其他尺寸 避免占用过多和过大空间

实现目标

  1. 遍历所有 WooCommerce 产品
    • 查找每个产品的主图及画廊图片。
  2. 更新所有图片的缩略图元数据
    • 替换旧的缩略图规格(如 -650x650)为原始图片路径。
  3. 清理并刷新所有图片的缓存
    • 确保更新的图片立即生效。
add_action('init', 'update_all_product_images');
function update_all_product_images() {
    if (!is_admin()) {
        return;
    }

    global $wpdb;

    // 调试开始
    error_log("=== Global Product Image Update Start ===");

    // 获取所有产品 ID
    $product_ids = $wpdb->get_col("
        SELECT ID 
        FROM {$wpdb->posts} 
        WHERE post_type = 'product' AND post_status = 'publish'
    ");

    if (empty($product_ids)) {
        error_log("No products found.");
        return;
    }

    error_log("Found product IDs: " . implode(', ', $product_ids));

    // 遍历每个产品
    foreach ($product_ids as $product_id) {
        error_log("Processing Product ID: {$product_id}");

        // 获取产品的所有图片附件 ID
        $attachment_ids = $wpdb->get_col($wpdb->prepare(
            "SELECT ID 
             FROM {$wpdb->posts} 
             WHERE post_parent = %d AND post_type = 'attachment' AND post_mime_type LIKE 'image/%%'",
            $product_id
        ));

        if (empty($attachment_ids)) {
            error_log("No attachments found for product ID: {$product_id}");
            continue;
        }

        error_log("Found attachment IDs for Product ID {$product_id}: " . implode(', ', $attachment_ids));

        // 遍历所有附件并更新元数据
        foreach ($attachment_ids as $attachment_id) {
            $sizes_to_replace = ['-650x650.', '-300x300.', '-150x150.'];
            foreach ($sizes_to_replace as $size) {
                $update_result = $wpdb->query($wpdb->prepare(
                    "UPDATE {$wpdb->postmeta} 
                     SET meta_value = REPLACE(meta_value, %s, '.') 
                     WHERE post_id = %d AND meta_value LIKE %s",
                    $size, $attachment_id, '%' . $size . '%'
                ));
                error_log("Updated Meta Data for Attachment ID {$attachment_id} with size {$size}: {$update_result}");
            }

            // 清除缓存
            clean_post_cache($attachment_id);
        }

        // 更新产品主图缩略图规格
        $thumbnail_id = get_post_thumbnail_id($product_id);
        if ($thumbnail_id) {
            error_log("Updating Thumbnail ID for Product ID {$product_id}: {$thumbnail_id}");

            foreach ($sizes_to_replace as $size) {
                $update_thumbnail_result = $wpdb->query($wpdb->prepare(
                    "UPDATE {$wpdb->postmeta} 
                     SET meta_value = REPLACE(meta_value, %s, '.') 
                     WHERE post_id = %d AND meta_value LIKE %s",
                    $size, $thumbnail_id, '%' . $size . '%'
                ));
                error_log("Updated Thumbnail ID {$thumbnail_id} with size {$size}: {$update_thumbnail_result}");
            }

            clean_post_cache($thumbnail_id);
        }
    }

    // 清理并刷新所有缩略图缓存
    wp_cache_flush();

    error_log("=== Global Product Image Update End ===");
}

代码解读

  1. 遍历所有产品
    • 从数据库中查询所有发布状态的 WooCommerce 产品。
  2. 获取图片附件
    • 查找每个产品关联的图片,包括主图和画廊图片。
  3. 更新图片元数据
    • 对每张图片元数据中的缩略图规格(如 -650x650)进行替换。
  4. 清理缓存
    • 调用 clean_post_cachewp_cache_flush 清理图片缓存,使更新生效。

使用方法

  1. 将代码添加到主题的 functions.php 文件
  2. 访问 WordPress 后台,代码会自动运行。
  3. 检查日志文件
    • 查看 debug.log 以确保所有图片均被成功处理。

注意事项

  1. 数据库操作安全
    • 修改前务必备份数据库,因为代码会直接更新 wp_postmeta 表中的数据。
  2. 处理大批量数据
    • 如果产品数量和图片较多,运行时间可能较长,建议分批处理或增加服务器执行时间限制。
  3. 缩略图重建
    • 若需确保所有图片规格更新无误,建议使用 Regenerate Thumbnails 插件重新生成缩略图。
... 阅读更多