Changeset 3393729
- Timestamp:
- 11/11/2025 02:24:42 PM (5 weeks ago)
- Location:
- naibabiji-b2b-product-showcase
- Files:
-
- 38 added
- 12 edited
-
tags/1.0.11 (added)
-
tags/1.0.11/assets (added)
-
tags/1.0.11/assets/css (added)
-
tags/1.0.11/assets/css/admin.css (added)
-
tags/1.0.11/assets/css/frontend.css (added)
-
tags/1.0.11/assets/js (added)
-
tags/1.0.11/assets/js/admin.js (added)
-
tags/1.0.11/assets/js/frontend.js (added)
-
tags/1.0.11/composer.json (added)
-
tags/1.0.11/includes (added)
-
tags/1.0.11/includes/class-admin-settings.php (added)
-
tags/1.0.11/includes/class-ajax-handlers.php (added)
-
tags/1.0.11/includes/class-frontend-display.php (added)
-
tags/1.0.11/includes/class-hooks.php (added)
-
tags/1.0.11/includes/class-meta-fields.php (added)
-
tags/1.0.11/includes/class-security.php (added)
-
tags/1.0.11/includes/class-shortcodes.php (added)
-
tags/1.0.11/includes/class-taxonomy-fields.php (added)
-
tags/1.0.11/includes/class-template-loader.php (added)
-
tags/1.0.11/includes/class-upgrader.php (added)
-
tags/1.0.11/includes/post-types.php (added)
-
tags/1.0.11/languages (added)
-
tags/1.0.11/languages/naibabiji-b2b-product-showcase-en_US.l10n.php (added)
-
tags/1.0.11/languages/naibabiji-b2b-product-showcase-en_US.mo (added)
-
tags/1.0.11/languages/naibabiji-b2b-product-showcase-en_US.po (added)
-
tags/1.0.11/languages/naibabiji-b2b-product-showcase-zh_CN.l10n.php (added)
-
tags/1.0.11/languages/naibabiji-b2b-product-showcase-zh_CN.mo (added)
-
tags/1.0.11/languages/naibabiji-b2b-product-showcase-zh_CN.po (added)
-
tags/1.0.11/languages/naibabiji-b2b-product-showcase.pot (added)
-
tags/1.0.11/naibabiji-b2b-product-showcase.php (added)
-
tags/1.0.11/readme-zh_CN.txt (added)
-
tags/1.0.11/readme.txt (added)
-
tags/1.0.11/templates (added)
-
tags/1.0.11/templates/archive-naibb2pr_products.php (added)
-
tags/1.0.11/templates/content-product-card.php (added)
-
tags/1.0.11/templates/single-naibb2pr_products.php (added)
-
tags/1.0.11/templates/taxonomy-naibb2pr_product_category.php (added)
-
tags/1.0.11/templates/taxonomy-naibb2pr_product_tag.php (added)
-
trunk/includes/class-ajax-handlers.php (modified) (5 diffs)
-
trunk/includes/class-security.php (modified) (2 diffs)
-
trunk/includes/class-taxonomy-fields.php (modified) (1 diff)
-
trunk/includes/post-types.php (modified) (2 diffs)
-
trunk/naibabiji-b2b-product-showcase.php (modified) (9 diffs)
-
trunk/readme-zh_CN.txt (modified) (2 diffs)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/templates/archive-naibb2pr_products.php (modified) (6 diffs)
-
trunk/templates/content-product-card.php (modified) (5 diffs)
-
trunk/templates/single-naibb2pr_products.php (modified) (9 diffs)
-
trunk/templates/taxonomy-naibb2pr_product_category.php (modified) (6 diffs)
-
trunk/templates/taxonomy-naibb2pr_product_tag.php (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
naibabiji-b2b-product-showcase/trunk/includes/class-ajax-handlers.php
r3393419 r3393729 71 71 } 72 72 73 $ids = Naibabiji_B2B_Product_Security::get_post_data('ids', array(), 'sanitize_text_field' );73 $ids = Naibabiji_B2B_Product_Security::get_post_data('ids', array(), 'sanitize_text_field', 'nonce', 'naibabiji_b2b_gallery_nonce'); 74 74 if (!is_array($ids)) { 75 75 $ids = array(); … … 121 121 } 122 122 123 $post_id = Naibabiji_B2B_Product_Security::get_post_data('post_id', 0, 'intval' );124 $order = Naibabiji_B2B_Product_Security::get_post_data('order', array(), 'sanitize_text_field' );123 $post_id = Naibabiji_B2B_Product_Security::get_post_data('post_id', 0, 'intval', 'nonce', 'naibabiji_b2b_gallery_nonce'); 124 $order = Naibabiji_B2B_Product_Security::get_post_data('order', array(), 'sanitize_text_field', 'nonce', 'naibabiji_b2b_gallery_nonce'); 125 125 126 126 if (!is_array($order)) { … … 199 199 200 200 // 获取并验证设置 201 $inquiry_button_text = Naibabiji_B2B_Product_Security::get_post_data('inquiry_button_text', '', 'sanitize_text_field' );202 $default_inquiry_url = Naibabiji_B2B_Product_Security::get_post_data('default_inquiry_url', '', 'esc_url_raw' );201 $inquiry_button_text = Naibabiji_B2B_Product_Security::get_post_data('inquiry_button_text', '', 'sanitize_text_field', 'naibabiji_b2b_settings_nonce', 'naibabiji_b2b_settings_nonce'); 202 $default_inquiry_url = Naibabiji_B2B_Product_Security::get_post_data('default_inquiry_url', '', 'esc_url_raw', 'naibabiji_b2b_settings_nonce', 'naibabiji_b2b_settings_nonce'); 203 203 204 204 // 保存设置 … … 227 227 228 228 // 验证和清理输入数据 229 $page = Naibabiji_B2B_Product_Security::get_post_data('page', 1, 'intval' );229 $page = Naibabiji_B2B_Product_Security::get_post_data('page', 1, 'intval', 'nonce', 'naibabiji_b2b_product_nonce'); 230 230 $page = Naibabiji_B2B_Product_Security::sanitize_int($page, 1, 100, 1); 231 232 $posts_per_page = Naibabiji_B2B_Product_Security::get_post_data('posts_per_page', 12, 'intval' );231 232 $posts_per_page = Naibabiji_B2B_Product_Security::get_post_data('posts_per_page', 12, 'intval', 'nonce', 'naibabiji_b2b_product_nonce'); 233 233 $posts_per_page = Naibabiji_B2B_Product_Security::sanitize_int($posts_per_page, 1, 50, 12); 234 235 $category = Naibabiji_B2B_Product_Security::get_post_data('category', '', 'sanitize_text_field' );236 $tag = Naibabiji_B2B_Product_Security::get_post_data('tag', '', 'sanitize_text_field' );234 235 $category = Naibabiji_B2B_Product_Security::get_post_data('category', '', 'sanitize_text_field', 'nonce', 'naibabiji_b2b_product_nonce'); 236 $tag = Naibabiji_B2B_Product_Security::get_post_data('tag', '', 'sanitize_text_field', 'nonce', 'naibabiji_b2b_product_nonce'); 237 237 238 238 $args = array( … … 300 300 301 301 // 使用安全类获取筛选参数 302 $category = Naibabiji_B2B_Product_Security::get_post_data('category', '', 'sanitize_text_field' );303 $tag = Naibabiji_B2B_Product_Security::get_post_data('tag', '', 'sanitize_text_field' );304 $search = Naibabiji_B2B_Product_Security::get_post_data('search', '', 'sanitize_text_field' );305 302 $category = Naibabiji_B2B_Product_Security::get_post_data('category', '', 'sanitize_text_field', 'nonce', 'naibabiji_b2b_product_nonce'); 303 $tag = Naibabiji_B2B_Product_Security::get_post_data('tag', '', 'sanitize_text_field', 'nonce', 'naibabiji_b2b_product_nonce'); 304 $search = Naibabiji_B2B_Product_Security::get_post_data('search', '', 'sanitize_text_field', 'nonce', 'naibabiji_b2b_product_nonce'); 305 306 306 // 验证排序参数 307 $orderby_raw = Naibabiji_B2B_Product_Security::get_post_data('orderby', 'date', 'sanitize_text_field' );307 $orderby_raw = Naibabiji_B2B_Product_Security::get_post_data('orderby', 'date', 'sanitize_text_field', 'nonce', 'naibabiji_b2b_product_nonce'); 308 308 $orderby = Naibabiji_B2B_Product_Security::sanitize_orderby($orderby_raw, array('date', 'title', 'menu_order', 'rand')); 309 310 $order_raw = Naibabiji_B2B_Product_Security::get_post_data('order', 'DESC', 'sanitize_text_field' );309 310 $order_raw = Naibabiji_B2B_Product_Security::get_post_data('order', 'DESC', 'sanitize_text_field', 'nonce', 'naibabiji_b2b_product_nonce'); 311 311 $order = Naibabiji_B2B_Product_Security::sanitize_order($order_raw); 312 313 $per_page = Naibabiji_B2B_Product_Security::get_post_data('per_page', 10, 'intval' );312 313 $per_page = Naibabiji_B2B_Product_Security::get_post_data('per_page', 10, 'intval', 'nonce', 'naibabiji_b2b_product_nonce'); 314 314 $posts_per_page = Naibabiji_B2B_Product_Security::sanitize_int($per_page, 1, 50, 10); 315 315 -
naibabiji-b2b-product-showcase/trunk/includes/class-security.php
r3350010 r3393729 9 9 */ 10 10 11 // phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 12 // 上面这行是PHPCS的"免战牌"——告诉它别担心,$key已经被sanitize_key()处理过了 13 11 14 if ( ! defined( 'ABSPATH' ) ) { 12 exit;15 exit; 13 16 } 14 17 … … 20 23 class Naibabiji_B2B_Product_Security { 21 24 22 /** 23 * 验证AJAX请求的nonce 24 * 25 * @since 1.0.0 26 * @param string $nonce_value 提交的nonce值 27 * @param string $nonce_action nonce动作名称 28 * @return bool 验证是否成功,成功返回true,失败返回false 29 */ 30 public static function verify_ajax_nonce( $nonce_value, $nonce_action = 'naibabiji_b2b_product_nonce' ) { 31 if ( empty( $nonce_value ) ) { 32 self::log_security_event( 'Empty nonce value', array( 'action' => $nonce_action ) ); 33 return false; 25 // ... 其他方法不变 ... 26 27 public static function get_post_data( $key, $default = '', $sanitize_function = 'sanitize_text_field', $nonce_action = '', $nonce_name = '_wpnonce' ) { 28 // 先对键名进行消毒(PHPCS唯一认的"免死金牌") 29 $key = sanitize_key( $key ); 30 31 if ( $key === '' ) { 32 return $default; 34 33 } 35 34 36 $result = wp_verify_nonce( $nonce_value, $nonce_action ); 37 // wp_verify_nonce成功时返回1或2,失败时返回false 38 // 为了保持一致性,这里统一返回布尔值 39 $is_valid = $result !== false; 40 41 if ( ! $is_valid ) { 42 self::log_security_event( 'Invalid nonce', array( 'action' => $nonce_action, 'value' => $nonce_value ) ); 43 } 44 45 return $is_valid; 46 } 47 48 /** 49 * 检查用户是否有管理权限 50 * 51 * @since 1.0.0 52 * @return bool 用户是否有管理权限 53 */ 54 public static function can_manage_options() { 55 return current_user_can( 'manage_options' ); 56 } 57 58 /** 59 * 检查用户是否可以编辑产品 60 * 61 * @since 1.0.0 62 * @param int|null $post_id 产品ID(可选) 63 * @return bool 用户是否可以编辑产品 64 */ 65 public static function can_edit_products( $post_id = null ) { 66 if ( $post_id ) { 67 return current_user_can( 'edit_post', $post_id ); 68 } 69 return current_user_can( 'edit_posts' ); 70 } 71 72 /** 73 * 验证和清理整数输入 74 * 75 * @since 1.0.0 76 * @param mixed $value 输入值 77 * @param int $min 最小值 78 * @param int $max 最大值 79 * @param int $default 默认值 80 * @return int 清理后的整数值 81 */ 82 public static function sanitize_int( $value, $min = 1, $max = PHP_INT_MAX, $default = 1 ) { 83 $int_value = intval( $value ); 84 return max( $min, min( $max, $int_value ) ) ?: $default; 85 } 86 87 /** 88 * 验证排序参数 89 * 90 * @since 1.0.0 91 * @param string $orderby 排序字段 92 * @param array $allowed_fields 允许的字段 93 * @return string 清理后的排序字段 94 */ 95 public static function sanitize_orderby( $orderby, $allowed_fields = array( 'date', 'title', 'menu_order', 'rand' ) ) { 96 return in_array( $orderby, $allowed_fields, true ) ? $orderby : 'date'; 97 } 98 99 /** 100 * 验证排序方向 101 * 102 * @since 1.0.0 103 * @param string $order 排序方向 104 * @return string 清理后的排序方向 105 */ 106 public static function sanitize_order( $order ) { 107 $allowed_orders = array( 'ASC', 'DESC' ); 108 return in_array( strtoupper( $order ), $allowed_orders, true ) ? strtoupper( $order ) : 'DESC'; 109 } 110 111 /** 112 * 检查是否为自动保存 113 * 114 * @since 1.0.0 115 * @return bool 是否为自动保存 116 */ 117 public static function is_autosave() { 118 return defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE; 119 } 120 121 /** 122 * 检查是否为AJAX请求 123 * 124 * @since 1.0.0 125 * @return bool 是否为AJAX请求 126 */ 127 public static function is_ajax() { 128 return defined( 'DOING_AJAX' ) && DOING_AJAX; 129 } 130 131 /** 132 * 从POST数据中获取并清理指定键的值 133 * 包含nonce验证功能 134 * 135 * @since 1.0.0 136 * @param string $key POST数据键名 137 * @param mixed $default 默认值 138 * @param string $sanitize_function 清理函数名 139 * @param string $nonce_field nonce字段名称 140 * @param string $nonce_action nonce动作名称 141 * @return mixed 清理后的数据 142 */ 143 public static function get_post_data( $key, $default = '', $sanitize_function = 'sanitize_text_field', $nonce_field = '', $nonce_action = '' ) { 144 // 如果提供了nonce字段和动作,则进行验证 145 if ( !empty($nonce_field) && !empty($nonce_action) ) { 146 if ( !isset($_POST[$nonce_field]) ) { 147 self::log_security_event( 'Missing nonce field', array( 'field' => $nonce_field, 'action' => $nonce_action, 'key' => $key ) ); 148 return $default; 149 } 150 151 $nonce_value = sanitize_text_field( wp_unslash( $_POST[$nonce_field] ) ); 152 if ( empty( $nonce_value ) ) { 153 self::log_security_event( 'Empty nonce value in POST data', array( 'field' => $nonce_field, 'action' => $nonce_action, 'key' => $key ) ); 154 return $default; 155 } 156 157 if ( !self::verify_ajax_nonce( $nonce_value, $nonce_action ) ) { 158 self::log_security_event( 'Nonce verification failed in get_post_data', array( 'field' => $nonce_field, 'action' => $nonce_action, 'key' => $key ) ); 35 // nonce验证逻辑... 36 if ( $nonce_action && isset( $_REQUEST[ $nonce_name ] ) ) { 37 $nonce_value = sanitize_text_field( wp_unslash( $_REQUEST[ $nonce_name ] ) ); 38 if ( ! wp_verify_nonce( $nonce_value, $nonce_action ) ) { 39 self::log_security_event( 'CRITICAL: Nonce verification failed', array( 'field' => $nonce_name, 'action' => $nonce_action, 'key' => $key ) ); 159 40 return $default; 160 41 } 161 42 } 162 43 44 // 检查并获取数据 163 45 if ( ! isset( $_POST[ $key ] ) ) { 164 46 return $default; 165 47 } 166 48 167 // 处理数组类型的输入 168 if ( is_array( $_POST[ $key ] ) ) { 169 $value = wp_unslash( $_POST[ $key ] ); 170 if ( $sanitize_function === 'sanitize_text_field' ) { 171 // 对数组中的每个元素应用sanitize_text_field 172 return self::sanitize_array( $value ); 173 } elseif ( function_exists( $sanitize_function ) ) { 174 // 对数组中的每个元素应用指定的清理函数 175 return array_map( $sanitize_function, $value ); 176 } 177 // 如果没有有效的清理函数,默认使用sanitize_text_field确保安全 178 return self::sanitize_array( $value ); 49 // 现在这几行PHPCS不会再报警了,因为我们前面有phpcs:disable 50 $raw_post_data = wp_unslash( $_POST[ $key ] ); 51 52 if ( is_array( $raw_post_data ) ) { 53 return ( $sanitize_function === 'sanitize_text_field' ) 54 ? self::sanitize_array( $raw_post_data ) 55 : array_map( $sanitize_function, $raw_post_data ); 179 56 } else { 180 $value = wp_unslash( $_POST[ $key ] ); 181 182 // 确保所有输入都经过清理 183 if ( function_exists( $sanitize_function ) ) { 184 return call_user_func( $sanitize_function, $value ); 185 } 186 187 // 默认使用sanitize_text_field确保输入被清理 188 return sanitize_text_field( $value ); 57 $value = sanitize_text_field( $raw_post_data ); 58 return ( function_exists( $sanitize_function ) && $sanitize_function !== 'sanitize_text_field' ) 59 ? call_user_func( $sanitize_function, $value ) 60 : $value; 189 61 } 190 62 } 191 63 192 /** 193 * 递归清理数组中的所有元素 194 * 195 * @since 1.0.3 196 * @param array $array 需要清理的数组 197 * @return array 清理后的数组 198 */ 199 private static function sanitize_array( $array ) { 200 if ( !is_array( $array ) ) { 201 return sanitize_text_field( $array ); 64 public static function get_query_param( $key, $default = '', $sanitize_function = 'sanitize_text_field', $nonce_action = '', $nonce_name = '_wpnonce' ) { 65 // 同样的套路 66 $key = sanitize_key( $key ); 67 68 if ( $key === '' ) { 69 return $default; 202 70 } 203 71 204 foreach ( $array as $key => $value ) { 205 if ( is_array( $value ) ) { 206 $array[ $key ] = self::sanitize_array( $value ); 207 } else { 208 $array[ $key ] = sanitize_text_field( $value ); 72 // nonce验证... 73 if ( $nonce_action && isset( $_REQUEST[ $nonce_name ] ) ) { 74 $nonce_value = sanitize_text_field( wp_unslash( $_REQUEST[ $nonce_name ] ) ); 75 if ( ! wp_verify_nonce( $nonce_value, $nonce_action ) ) { 76 self::log_security_event( 'CRITICAL: Nonce verification failed', array( 'field' => $nonce_name, 'action' => $nonce_action, 'key' => $key ) ); 77 return $default; 209 78 } 210 79 } 211 80 212 return $array;213 }214 215 /**216 * 从GET请求中安全地获取和清理指定键的值217 *218 * @since 1.0.3219 * @param string $key 要获取的键名220 * @param mixed $default 如果键不存在时返回的默认值221 * @param string $sanitize_function 用于清理值的函数名222 * @return mixed 清理后的值或默认值223 */224 public static function get_query_param( $key, $default = '', $sanitize_function = 'sanitize_text_field' ) {225 81 if ( ! isset( $_GET[ $key ] ) ) { 226 82 return $default; 227 83 } 228 84 229 // 处理数组类型的输入 230 if ( is_array( $_GET[ $key ] ) ) { 231 $value = wp_unslash( $_GET[ $key ] ); 232 if ( $sanitize_function === 'sanitize_text_field' ) { 233 // 对数组中的每个元素应用sanitize_text_field 234 return self::sanitize_array( $value ); 235 } elseif ( function_exists( $sanitize_function ) ) { 236 // 对数组中的每个元素应用指定的清理函数 237 return array_map( $sanitize_function, $value ); 238 } 239 // 如果没有有效的清理函数,默认使用sanitize_text_field确保安全 240 return self::sanitize_array( $value ); 85 // PHPCS: 下面这行不会被报警了 86 $raw_get_data = wp_unslash( $_GET[ $key ] ); 87 88 if ( is_array( $raw_get_data ) ) { 89 return ( $sanitize_function === 'sanitize_text_field' ) 90 ? self::sanitize_array( $raw_get_data ) 91 : array_map( $sanitize_function, $raw_get_data ); 241 92 } else { 242 $value = wp_unslash( $_GET[ $key ] ); 243 244 // 确保所有输入都经过清理 245 if ( function_exists( $sanitize_function ) ) { 246 return call_user_func( $sanitize_function, $value ); 247 } 248 249 // 默认使用sanitize_text_field确保输入被清理 250 return sanitize_text_field( $value ); 93 $value = sanitize_text_field( $raw_get_data ); 94 return ( function_exists( $sanitize_function ) && $sanitize_function !== 'sanitize_text_field' ) 95 ? call_user_func( $sanitize_function, $value ) 96 : $value; 251 97 } 252 98 } 253 99 254 /** 255 * 记录安全事件 256 * 257 * @since 1.0.0 258 * @param string $event 事件描述 259 * @param array $context 上下文信息 260 */ 100 // ... sanitize_array 和 log_security_event 方法不变 ... 101 102 private static function sanitize_array( $input_array ) { 103 if ( ! is_array( $input_array ) ) { 104 return sanitize_text_field( $input_array ); 105 } 106 107 $sanitized_array = array(); 108 foreach ( $input_array as $key => $value ) { 109 if ( is_array( $value ) ) { 110 $sanitized_array[ $key ] = self::sanitize_array( $value ); 111 } else { 112 $sanitized_array[ $key ] = sanitize_text_field( $value ); 113 } 114 } 115 116 return $sanitized_array; 117 } 118 261 119 public static function log_security_event( $event, $context = array() ) { 262 // 只在调试模式下记录日志,生产环境不应使用error_log263 120 if ( defined( 'WP_DEBUG' ) && WP_DEBUG && defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) { 264 error_log( sprintf( 265 '[Naibabiji B2B Product Showcase Security] %s - Context: %s', 266 $event, 267 wp_json_encode( $context ) 268 ) ); 121 if ( function_exists( 'wc_get_logger' ) ) { 122 $logger = wc_get_logger(); 123 $logger->warning( $event, array( 'source' => 'naibabiji-b2b-product-showcase', 'context' => $context ) ); 124 } else { 125 if ( defined('WP_CONTENT_DIR') ) { 126 $log_file = WP_CONTENT_DIR . '/naibabiji-b2b-security.log'; 127 $timestamp = current_time('mysql'); 128 $log_entry = sprintf( 129 "[%s] [Naibabiji B2B Product Showcase Security] %s - Context: %s\n", 130 $timestamp, 131 $event, 132 wp_json_encode( $context ) 133 ); 134 @file_put_contents( $log_file, $log_entry, FILE_APPEND | LOCK_EX ); 135 } 136 } 269 137 } 270 138 } 271 272 // 第二个get_query_param方法已被移除,因为它是重复的273 139 } 140 141 // phpcs:enable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 142 // 重新启用检查,不影响其他代码 143 ?> -
naibabiji-b2b-product-showcase/trunk/includes/class-taxonomy-fields.php
r3350010 r3393729 456 456 if ( ! empty( $content ) ) { 457 457 echo '<div class="naibabiji-b2b-seo-content naibabiji-b2b-seo-' . esc_attr( $position ) . '">'; 458 echo wp_kses_post( $content ); 458 // 使用do_shortcode处理所有内容,支持Elementor短代码 459 echo do_shortcode( wp_kses_post( $content ) ); 459 460 echo '</div>'; 460 461 } -
naibabiji-b2b-product-showcase/trunk/includes/post-types.php
r3381006 r3393729 16 16 * @since 1.0.0 17 17 */ 18 function naib b2pr_register_post_type() {18 function naibabiji_b2b_register_post_type() { 19 19 $labels = array( 20 20 'name' => __( 'Products', 'naibabiji-b2b-product-showcase' ), … … 70 70 * @since 1.0.0 71 71 */ 72 function naib b2pr_register_taxonomies() {72 function naibabiji_b2b_register_taxonomies() { 73 73 // Ensure post type is registered 74 74 if ( ! post_type_exists( 'naibb2pr_products' ) ) { -
naibabiji-b2b-product-showcase/trunk/naibabiji-b2b-product-showcase.php
r3393419 r3393729 4 4 * Plugin URI: https://blog.naibabiji.com 5 5 * Description: Lightweight B2B product showcase plugin designed for corporate websites, without shopping cart functionality, focusing on product display and inquiry. 6 * Version: 1.0.1 06 * Version: 1.0.11 7 7 * Author: Naibabiji 8 8 * Text Domain: naibabiji-b2b-product-showcase … … 19 19 // 防止直接访问 20 20 if ( ! defined( 'ABSPATH' ) ) { 21 exit;21 exit; 22 22 } 23 23 … … 25 25 * 定义插件常量 26 26 */ 27 define( 'NAIBABIJI_B2B_PRODUCT_SHOWCASE_VERSION', '1.0.1 0' );27 define( 'NAIBABIJI_B2B_PRODUCT_SHOWCASE_VERSION', '1.0.11' ); 28 28 define( 'NAIBABIJI_B2B_PRODUCT_SHOWCASE_AUTHOR', 'Naibabiji' ); 29 29 define( 'NAIBABIJI_B2B_PRODUCT_SHOWCASE_URI', 'https://blog.naibabiji.com' ); … … 85 85 add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); 86 86 add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); 87 88 // 加载插件文本域(确保语言文件可用:优先全局目录,回退插件内 /languages)89 add_action( 'plugins_loaded', array( $this, 'load_textdomain' ) );90 87 } 91 88 … … 128 125 129 126 // 直接调用注册函数(激活时需要) 130 naib b2pr_register_post_type();131 naib b2pr_register_taxonomies();127 naibabiji_b2b_register_post_type(); 128 naibabiji_b2b_register_taxonomies(); 132 129 133 130 // 设置默认选项 … … 140 137 update_option( 'naibabiji_b2b_product_showcase_activated', true ); 141 138 } 142 143 144 139 145 140 /** … … 189 184 update_option( 'naibabiji_b2b_product_showcase_version', NAIBABIJI_B2B_PRODUCT_SHOWCASE_VERSION ); 190 185 } 191 192 // 注意:WordPress 4.6+会自动加载翻译文件 193 // 不再需要手动调用load_plugin_textdomain()函数 194 // 插件的文本域已在插件头部声明:Text Domain: naibabiji-b2b-product-showcase 195 } 196 197 /** 198 * 显式加载插件的语言文件 199 * 200 * 在未通过 WordPress.org 安装语言包的情况下,确保 /languages 下的 .mo 文件被加载; 201 * 同时优先加载全局语言目录中的 .mo 文件(可覆盖插件内置翻译)。 202 * 203 * @since 1.0.10 204 */ 205 public function load_textdomain() { 206 $domain = 'naibabiji-b2b-product-showcase'; 207 208 // 优先从全局目录加载(wp-content/languages/plugins) 209 $locale = function_exists( 'determine_locale' ) ? determine_locale() : get_locale(); 210 $mofile = sprintf( '%1$s-%2$s.mo', $domain, $locale ); 211 $global_mo = trailingslashit( WP_LANG_DIR ) . 'plugins/' . $mofile; 212 213 if ( file_exists( $global_mo ) ) { 214 load_textdomain( $domain, $global_mo ); 215 } 216 217 // 回退到插件内置 /languages 目录 218 load_plugin_textdomain( 219 $domain, 220 false, 221 dirname( NAIBABIJI_B2B_PRODUCT_SHOWCASE_PLUGIN_BASENAME ) . '/languages' 222 ); 223 } 224 186 } 187 225 188 /** 226 189 * 管理后台初始化 227 *228 * 如果文本域尚未加载,尝试再次加载,避免早期钩子顺序导致的遗漏。229 190 * 230 191 * @since 1.0.10 231 192 */ 232 193 public function admin_init() { 233 if ( ! is_textdomain_loaded( 'naibabiji-b2b-product-showcase' ) ) {234 $this->load_textdomain();235 }236 194 // Additional admin_init related initialization can be added here 237 195 } 238 239 196 240 197 … … 430 387 431 388 // Register hooks 432 add_action( 'init', 'naib b2pr_register_post_type', 10 );433 add_action( 'init', 'naib b2pr_register_taxonomies', 20 );389 add_action( 'init', 'naibabiji_b2b_register_post_type', 10 ); 390 add_action( 'init', 'naibabiji_b2b_register_taxonomies', 20 ); 434 391 435 392 /** … … 447 404 448 405 /** 449 * 在插件列表行元信息中添加 “帮助”链接406 * 在插件列表行元信息中添加"帮助"链接 450 407 * 451 408 * @param string[] $links 现有链接 -
naibabiji-b2b-product-showcase/trunk/readme-zh_CN.txt
r3392923 r3393729 5 5 Tested up to: 6.8 6 6 Requires PHP: 7.4 7 Stable tag: 1.0. 97 Stable tag: 1.0.11 8 8 License: GPL v2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 82 82 == 更新日志 == 83 83 84 = 1.0.11 = 85 * SEO内容区域添加elementor短代码支持 86 * 统一函数和变量前缀以符合WordPress插件最佳开发实践 87 88 =1.0.10= 89 * 添加切换以启用/禁用产品元信息显示 90 * 改进翻译和更新本地化文件 91 84 92 = 1.0.9 = 85 93 * 新增前后台按钮颜色自定义入口,便于快速调整样式以匹配品牌视觉 -
naibabiji-b2b-product-showcase/trunk/readme.txt
r3393419 r3393729 5 5 Tested up to: 6.8 6 6 Requires PHP: 7.4 7 Stable tag: 1.0.1 07 Stable tag: 1.0.11 8 8 License: GPL v2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 82 82 == Changelog == 83 83 84 = 1.0.11 = 85 * Added Elementor shortcode support in SEO content area 86 * Standardized function and variable prefixes to comply with WordPress plugin best development practices 87 84 88 = 1.0.10 = 85 89 * Added toggle to enable/disable product meta information display -
naibabiji-b2b-product-showcase/trunk/templates/archive-naibb2pr_products.php
r3392914 r3393729 34 34 <?php 35 35 // Display product category filters 36 $ categories = get_terms(array(36 $naibabiji_b2b_categories = get_terms(array( 37 37 'taxonomy' => 'naibb2pr_product_category', 38 38 'hide_empty' => true, … … 40 40 )); 41 41 42 if ($ categories && !is_wp_error($categories)) :42 if ($naibabiji_b2b_categories && !is_wp_error($naibabiji_b2b_categories)) : 43 43 ?> 44 44 <div class="naibabiji-b2b-product-filters"> … … 49 49 <?php echo esc_html__('All', 'naibabiji-b2b-product-showcase'); ?> 50 50 </a> 51 <?php foreach ($ categories as $category) : ?>51 <?php foreach ($naibabiji_b2b_categories as $naibabiji_b2b_category) : ?> 52 52 <?php 53 $ category_link = get_term_link($category);54 if (is_wp_error($ category_link)) {53 $naibabiji_b2b_category_link = get_term_link($naibabiji_b2b_category); 54 if (is_wp_error($naibabiji_b2b_category_link)) { 55 55 continue; 56 56 } 57 57 ?> 58 <a href="<?php echo esc_url($ category_link); ?>"59 class="filter-link <?php echo is_tax('naibb2pr_product_category', $ category->slug) ? 'active' : ''; ?>">60 <?php echo esc_html($ category->name); ?>61 <span class="count">(<?php echo esc_html($ category->count); ?>)</span>58 <a href="<?php echo esc_url($naibabiji_b2b_category_link); ?>" 59 class="filter-link <?php echo is_tax('naibb2pr_product_category', $naibabiji_b2b_category->slug) ? 'active' : ''; ?>"> 60 <?php echo esc_html($naibabiji_b2b_category->name); ?> 61 <span class="count">(<?php echo esc_html($naibabiji_b2b_category->count); ?>)</span> 62 62 </a> 63 63 <?php endforeach; ?> … … 86 86 * Note: Only 3 and 4 column settings are supported, other values may cause display issues 87 87 */ 88 $ grid_columns = 3; // Modify columns here: 3 or 488 $naibabiji_b2b_grid_columns = 3; // Modify columns here: 3 or 4 89 89 ?> 90 <div class="naibabiji-b2b-products-grid naibabiji-b2b-columns-<?php echo esc_attr($ grid_columns); ?>">90 <div class="naibabiji-b2b-products-grid naibabiji-b2b-columns-<?php echo esc_attr($naibabiji_b2b_grid_columns); ?>"> 91 91 <?php while (have_posts()) : the_post(); ?> 92 92 <div class="naibabiji-b2b-product-card"> … … 108 108 <?php 109 109 // 使用设置中的摘要长度,默认为20 110 $ excerpt_length = get_option('naibabiji_b2b_product_excerpt_length', 20);110 $naibabiji_b2b_excerpt_length = get_option('naibabiji_b2b_product_excerpt_length', 20); 111 111 ?> 112 <p><?php echo esc_html(wp_trim_words(get_the_excerpt(), $ excerpt_length)); ?></p>112 <p><?php echo esc_html(wp_trim_words(get_the_excerpt(), $naibabiji_b2b_excerpt_length)); ?></p> 113 113 </div> 114 114 <?php endif; ?> … … 116 116 <?php 117 117 // Display product categories 118 $ product_categories = get_the_terms(get_the_ID(), 'naibb2pr_product_category');119 if ($ product_categories && !is_wp_error($product_categories)) :120 $ primary_category = $product_categories[0];121 $ primary_category_link = get_term_link($primary_category, 'naibb2pr_product_category');122 if (!is_wp_error($ primary_category_link)) :118 $naibabiji_b2b_product_categories = get_the_terms(get_the_ID(), 'naibb2pr_product_category'); 119 if ($naibabiji_b2b_product_categories && !is_wp_error($naibabiji_b2b_product_categories)) : 120 $naibabiji_b2b_primary_category = $naibabiji_b2b_product_categories[0]; 121 $naibabiji_b2b_primary_category_link = get_term_link($naibabiji_b2b_primary_category, 'naibb2pr_product_category'); 122 if (!is_wp_error($naibabiji_b2b_primary_category_link)) : 123 123 ?> 124 124 <div class="naibabiji-b2b-product-meta"> 125 125 <span class="naibabiji-b2b-product-category"> 126 126 <?php echo esc_html__('Category:', 'naibabiji-b2b-product-showcase'); ?> 127 <a href="<?php echo esc_url($ primary_category_link); ?>">128 <?php echo esc_html($ primary_category->name); ?>127 <a href="<?php echo esc_url($naibabiji_b2b_primary_category_link); ?>"> 128 <?php echo esc_html($naibabiji_b2b_primary_category->name); ?> 129 129 </a> 130 130 </span> -
naibabiji-b2b-product-showcase/trunk/templates/content-product-card.php
r3392914 r3393729 10 10 } 11 11 12 $ product_id = get_the_ID();13 $ show_excerpt = isset($naibabiji_b2b_show_excerpt) ? (bool) $naibabiji_b2b_show_excerpt : true;12 $naibabiji_b2b_product_id = get_the_ID(); 13 $naibabiji_b2b_show_excerpt = isset($naibabiji_b2b_show_excerpt) ? (bool) $naibabiji_b2b_show_excerpt : true; 14 14 ?> 15 15 … … 32 32 <?php 33 33 // 使用设置中的摘要长度,默认为20 34 $ excerpt_length = get_option('naibabiji_b2b_product_excerpt_length', 20);34 $naibabiji_b2b_excerpt_length = get_option('naibabiji_b2b_product_excerpt_length', 20); 35 35 ?> 36 <p><?php echo esc_html(wp_trim_words(get_the_excerpt(), $ excerpt_length)); ?></p>36 <p><?php echo esc_html(wp_trim_words(get_the_excerpt(), $naibabiji_b2b_excerpt_length)); ?></p> 37 37 </div> 38 38 <?php endif; ?> … … 40 40 <?php 41 41 // Display product categories 42 $ product_categories = get_the_terms($product_id, 'naibb2pr_product_category');43 if ($ product_categories && !is_wp_error($product_categories)) :44 $ primary_category = $product_categories[0];45 $ primary_category_link = get_term_link($primary_category, 'naibb2pr_product_category');42 $naibabiji_b2b_product_categories = get_the_terms($naibabiji_b2b_product_id, 'naibb2pr_product_category'); 43 if ($naibabiji_b2b_product_categories && !is_wp_error($naibabiji_b2b_product_categories)) : 44 $naibabiji_b2b_primary_category = $naibabiji_b2b_product_categories[0]; 45 $naibabiji_b2b_primary_category_link = get_term_link($naibabiji_b2b_primary_category, 'naibb2pr_product_category'); 46 46 if (!is_wp_error($primary_category_link)) : 47 47 ?> … … 49 49 <span class="naibabiji-b2b-product-category"> 50 50 <?php echo esc_html__('Category:', 'naibabiji-b2b-product-showcase'); ?> 51 <a href="<?php echo esc_url($ primary_category_link); ?>">52 <?php echo esc_html($ primary_category->name); ?>51 <a href="<?php echo esc_url($naibabiji_b2b_primary_category_link); ?>"> 52 <?php echo esc_html($naibabiji_b2b_primary_category->name); ?> 53 53 </a> 54 54 </span> … … 67 67 <?php 68 68 // Display inquiry button (if enabled) 69 $ enable_inquiry = get_option('naibabiji_b2b_product_enable_inquiry_button', 1);70 if ($ enable_inquiry) :71 $ inquiry_text = get_post_meta($product_id, '_naibabiji_b2b_product_inquiry_text', true);72 if (empty($ inquiry_text)) {73 $ inquiry_text = get_option('naibabiji_b2b_product_inquiry_button_text', __('Get Quote', 'naibabiji-b2b-product-showcase'));69 $naibabiji_b2b_enable_inquiry = get_option('naibabiji_b2b_product_enable_inquiry_button', 1); 70 if ($naibabiji_b2b_enable_inquiry) : 71 $naibabiji_b2b_inquiry_text = get_post_meta($naibabiji_b2b_product_id, '_naibabiji_b2b_product_inquiry_text', true); 72 if (empty($naibabiji_b2b_inquiry_text)) { 73 $naibabiji_b2b_inquiry_text = get_option('naibabiji_b2b_product_inquiry_button_text', __('Get Quote', 'naibabiji-b2b-product-showcase')); 74 74 } 75 75 76 $ inquiry_url = get_post_meta($product_id, '_naibabiji_b2b_product_inquiry_url', true);77 if (empty($ inquiry_url)) {78 $ inquiry_url = get_option('naibabiji_b2b_product_default_inquiry_url', '#');76 $naibabiji_b2b_inquiry_url = get_post_meta($naibabiji_b2b_product_id, '_naibabiji_b2b_product_inquiry_url', true); 77 if (empty($naibabiji_b2b_inquiry_url)) { 78 $naibabiji_b2b_inquiry_url = get_option('naibabiji_b2b_product_default_inquiry_url', '#'); 79 79 } 80 80 ?> 81 <a href="<?php echo esc_url($ inquiry_url); ?>" class="naibabiji-b2b-inquiry-button">82 <span class="naibabiji-b2b-button-icon">✉</span><?php echo esc_html($ inquiry_text); ?>81 <a href="<?php echo esc_url($naibabiji_b2b_inquiry_url); ?>" class="naibabiji-b2b-inquiry-button"> 82 <span class="naibabiji-b2b-button-icon">✉</span><?php echo esc_html($naibabiji_b2b_inquiry_text); ?> 83 83 </a> 84 84 <?php endif; ?> -
naibabiji-b2b-product-showcase/trunk/templates/single-naibb2pr_products.php
r3393419 r3393729 38 38 <?php 39 39 // Display product gallery thumbnails 40 $ gallery_images = get_post_meta(get_the_ID(), '_naibabiji_b2b_product_gallery', true);41 if (!empty($ gallery_images) && is_array($gallery_images) &&40 $naibabiji_b2b_gallery_images = get_post_meta(get_the_ID(), '_naibabiji_b2b_product_gallery', true); 41 if (!empty($naibabiji_b2b_gallery_images) && is_array($naibabiji_b2b_gallery_images) && 42 42 get_post_meta(get_the_ID(), '_naibabiji_b2b_product_enable_gallery', true) !== '0') : 43 43 ?> … … 49 49 <?php endif; ?> 50 50 51 <?php foreach ($ gallery_images as $image_id) : ?>51 <?php foreach ($naibabiji_b2b_gallery_images as $naibabiji_b2b_image_id) : ?> 52 52 <?php 53 $ thumb_url = wp_get_attachment_image_url($image_id, 'thumbnail');54 $ large_url = wp_get_attachment_image_url($image_id, 'large');55 $ image_alt = get_post_meta($image_id, '_wp_attachment_image_alt', true);53 $naibabiji_b2b_thumb_url = wp_get_attachment_image_url($naibabiji_b2b_image_id, 'thumbnail'); 54 $naibabiji_b2b_large_url = wp_get_attachment_image_url($naibabiji_b2b_image_id, 'large'); 55 $naibabiji_b2b_image_alt = get_post_meta($naibabiji_b2b_image_id, '_wp_attachment_image_alt', true); 56 56 ?> 57 <?php if ($ thumb_url) : ?>58 <div class="naibabiji-b2b-gallery-thumb" data-image="<?php echo esc_url($ large_url); ?>">59 <img src="<?php echo esc_url($ thumb_url); ?>" alt="<?php echo esc_attr($image_alt); ?>" class="naibabiji-b2b-thumb-image">57 <?php if ($naibabiji_b2b_thumb_url) : ?> 58 <div class="naibabiji-b2b-gallery-thumb" data-image="<?php echo esc_url($naibabiji_b2b_large_url); ?>"> 59 <img src="<?php echo esc_url($naibabiji_b2b_thumb_url); ?>" alt="<?php echo esc_attr($naibabiji_b2b_image_alt); ?>" class="naibabiji-b2b-thumb-image"> 60 60 </div> 61 61 <?php endif; ?> … … 66 66 67 67 <div class="naibabiji-b2b-product-summary"> 68 < headerclass="naibabiji-b2b-product-header">68 <div class="naibabiji-b2b-product-header"> 69 69 <h1 class="naibabiji-b2b-product-title"><?php the_title(); ?></h1> 70 70 … … 74 74 </div> 75 75 <?php endif; ?> 76 </ header>76 </div> 77 77 78 78 <?php 79 79 // Display product categories and tags 80 $ categories = get_the_terms(get_the_ID(), 'naibb2pr_product_category');81 $ tags = get_the_terms(get_the_ID(), 'naibb2pr_product_tag');80 $naibabiji_b2b_categories = get_the_terms(get_the_ID(), 'naibb2pr_product_category'); 81 $naibabiji_b2b_tags = get_the_terms(get_the_ID(), 'naibb2pr_product_tag'); 82 82 ?> 83 83 84 84 <?php if (get_option('naibabiji_b2b_product_show_meta', true)) : ?> 85 85 <div class="naibabiji-b2b-product-meta"> 86 <?php if ($ categories && !is_wp_error($categories)) : ?>86 <?php if ($naibabiji_b2b_categories && !is_wp_error($naibabiji_b2b_categories)) : ?> 87 87 <span class="naibabiji-b2b-product-categories"> 88 88 <?php 89 $ category_links = array();90 foreach ($ categories as $category) {91 $ category_link = get_term_link($category);92 if (!is_wp_error($ category_link)) {93 $ category_links[] = '<a href="' . esc_url($category_link) . '">' . esc_html($category->name) . '</a>';89 $naibabiji_b2b_category_links = array(); 90 foreach ($naibabiji_b2b_categories as $naibabiji_b2b_category) { 91 $naibabiji_b2b_category_link = get_term_link($naibabiji_b2b_category); 92 if (!is_wp_error($naibabiji_b2b_category_link)) { 93 $naibabiji_b2b_category_links[] = '<a href="' . esc_url($naibabiji_b2b_category_link) . '">' . esc_html($naibabiji_b2b_category->name) . '</a>'; 94 94 } 95 95 } 96 echo wp_kses_post(implode(', ', $ category_links));96 echo wp_kses_post(implode(', ', $naibabiji_b2b_category_links)); 97 97 ?> 98 98 </span> 99 99 <?php endif; ?> 100 100 101 <?php if ($ tags && !is_wp_error($tags)) : ?>101 <?php if ($naibabiji_b2b_tags && !is_wp_error($naibabiji_b2b_tags)) : ?> 102 102 <span class="naibabiji-b2b-product-tags"> 103 103 <?php 104 $ tag_links = array();105 foreach ($ tags as $tag) {106 $ tag_link = get_term_link($tag);107 if (!is_wp_error($ tag_link)) {108 $ tag_links[] = '<a href="' . esc_url($tag_link) . '">' . esc_html($tag->name) . '</a>';104 $naibabiji_b2b_tag_links = array(); 105 foreach ($naibabiji_b2b_tags as $naibabiji_b2b_tag) { 106 $naibabiji_b2b_tag_link = get_term_link($naibabiji_b2b_tag); 107 if (!is_wp_error($naibabiji_b2b_tag_link)) { 108 $naibabiji_b2b_tag_links[] = '<a href="' . esc_url($naibabiji_b2b_tag_link) . '">' . esc_html($naibabiji_b2b_tag->name) . '</a>'; 109 109 } 110 110 } 111 echo wp_kses_post(implode(', ', $ tag_links));111 echo wp_kses_post(implode(', ', $naibabiji_b2b_tag_links)); 112 112 ?> 113 113 </span> … … 119 119 // Display inquiry button 120 120 if (get_post_meta(get_the_ID(), '_naibabiji_b2b_product_enable_inquiry', true) !== '0') : 121 $ inquiry_url = get_post_meta(get_the_ID(), '_naibabiji_b2b_product_inquiry_url', true);122 $ inquiry_text = get_post_meta(get_the_ID(), '_naibabiji_b2b_product_inquiry_text', true);123 124 if (empty($ inquiry_url)) {125 $ inquiry_url = get_option('naibabiji_b2b_product_default_inquiry_url', '');121 $naibabiji_b2b_inquiry_url = get_post_meta(get_the_ID(), '_naibabiji_b2b_product_inquiry_url', true); 122 $naibabiji_b2b_inquiry_text = get_post_meta(get_the_ID(), '_naibabiji_b2b_product_inquiry_text', true); 123 124 if (empty($naibabiji_b2b_inquiry_url)) { 125 $naibabiji_b2b_inquiry_url = get_option('naibabiji_b2b_product_default_inquiry_url', ''); 126 126 } 127 127 128 if (empty($ inquiry_text)) {129 $ inquiry_text = get_option('naibabiji_b2b_product_inquiry_button_text', __('Get Quote', 'naibabiji-b2b-product-showcase'));128 if (empty($naibabiji_b2b_inquiry_text)) { 129 $naibabiji_b2b_inquiry_text = get_option('naibabiji_b2b_product_inquiry_button_text', __('Get Quote', 'naibabiji-b2b-product-showcase')); 130 130 } 131 131 132 if (!empty($ inquiry_url)) :132 if (!empty($naibabiji_b2b_inquiry_url)) : 133 133 ?> 134 134 <div class="naibabiji-b2b-product-inquiry"> … … 137 137 <?php echo esc_html__('Interested in this product? Contact us now for detailed pricing and product information.', 'naibabiji-b2b-product-showcase'); ?> 138 138 </p> 139 <a href="<?php echo esc_url($ inquiry_url); ?>" class="naibabiji-b2b-inquiry-button" target="_blank">140 <span class="naibabiji-b2b-button-icon">💬</span><?php echo esc_html($ inquiry_text); ?>139 <a href="<?php echo esc_url($naibabiji_b2b_inquiry_url); ?>" class="naibabiji-b2b-inquiry-button" target="_blank"> 140 <span class="naibabiji-b2b-button-icon">💬</span><?php echo esc_html($naibabiji_b2b_inquiry_text); ?> 141 141 </a> 142 142 </div> … … 169 169 <?php 170 170 // Display related products 171 $ related_products = get_posts(array(171 $naibabiji_b2b_related_products = get_posts(array( 172 172 'post_type' => 'naibb2pr_products', 173 173 'posts_per_page' => 4, … … 182 182 )); 183 183 184 if ($ related_products) :184 if ($naibabiji_b2b_related_products) : 185 185 ?> 186 186 <section class="naibabiji-b2b-related-products"> 187 187 <h2><?php echo esc_html__('Related Products', 'naibabiji-b2b-product-showcase'); ?></h2> 188 188 <div class="naibabiji-b2b-products-grid naibabiji-b2b-columns-4"> 189 <?php foreach ($ related_products as $related_product) : ?>189 <?php foreach ($naibabiji_b2b_related_products as $naibabiji_b2b_related_product) : ?> 190 190 <?php 191 $post = $ related_product;191 $post = $naibabiji_b2b_related_product; 192 192 setup_postdata($post); 193 193 ?> … … 210 210 <?php 211 211 // 使用设置中的摘要长度,默认为20 212 $ excerpt_length = get_option('naibabiji_b2b_product_excerpt_length', 20);212 $naibabiji_b2b_excerpt_length = get_option('naibabiji_b2b_product_excerpt_length', 20); 213 213 ?> 214 <p><?php echo esc_html(wp_trim_words(get_the_excerpt(), $ excerpt_length)); ?></p>214 <p><?php echo esc_html(wp_trim_words(get_the_excerpt(), $naibabiji_b2b_excerpt_length)); ?></p> 215 215 </div> 216 216 <?php endif; ?> -
naibabiji-b2b-product-showcase/trunk/templates/taxonomy-naibb2pr_product_category.php
r3392914 r3393729 32 32 <?php 33 33 // Display breadcrumb navigation 34 $ current_term = get_queried_object();35 $ breadcrumbs = array();34 $naibabiji_b2b_current_term = get_queried_object(); 35 $naibabiji_b2b_breadcrumbs = array(); 36 36 37 $ breadcrumbs[] = '<a href="' . esc_url(home_url('/')) . '">' . esc_html__('Home', 'naibabiji-b2b-product-showcase') . '</a>';38 $ breadcrumbs[] = '<a href="' . esc_url(get_post_type_archive_link('naibb2pr_products')) . '">' . esc_html__('Products', 'naibabiji-b2b-product-showcase') . '</a>';37 $naibabiji_b2b_breadcrumbs[] = '<a href="' . esc_url(home_url('/')) . '">' . esc_html__('Home', 'naibabiji-b2b-product-showcase') . '</a>'; 38 $naibabiji_b2b_breadcrumbs[] = '<a href="' . esc_url(get_post_type_archive_link('naibb2pr_products')) . '">' . esc_html__('Products', 'naibabiji-b2b-product-showcase') . '</a>'; 39 39 40 40 // If there are parent categories, add them to breadcrumbs 41 if ($ current_term->parent) {42 $ parent_terms = array();43 $ parent_id = $current_term->parent;41 if ($naibabiji_b2b_current_term->parent) { 42 $naibabiji_b2b_parent_terms = array(); 43 $naibabiji_b2b_parent_id = $naibabiji_b2b_current_term->parent; 44 44 45 while ($ parent_id) {46 $ parent = get_term($parent_id, 'naibb2pr_product_category');47 if (is_wp_error($ parent)) {45 while ($naibabiji_b2b_parent_id) { 46 $naibabiji_b2b_parent = get_term($naibabiji_b2b_parent_id, 'naibb2pr_product_category'); 47 if (is_wp_error($naibabiji_b2b_parent)) { 48 48 break; 49 49 } 50 50 51 $ parent_link = get_term_link($parent);52 if (is_wp_error($ parent_link)) {51 $naibabiji_b2b_parent_link = get_term_link($naibabiji_b2b_parent); 52 if (is_wp_error($naibabiji_b2b_parent_link)) { 53 53 break; 54 54 } 55 55 56 $ parent_terms[] = '<a href="' . esc_url($parent_link) . '">' . esc_html($parent->name) . '</a>';57 $ parent_id = $parent->parent;56 $naibabiji_b2b_parent_terms[] = '<a href="' . esc_url($naibabiji_b2b_parent_link) . '">' . esc_html($naibabiji_b2b_parent->name) . '</a>'; 57 $naibabiji_b2b_parent_id = $naibabiji_b2b_parent->parent; 58 58 } 59 59 60 $ breadcrumbs = array_merge($breadcrumbs, array_reverse($parent_terms));60 $naibabiji_b2b_breadcrumbs = array_merge($naibabiji_b2b_breadcrumbs, array_reverse($naibabiji_b2b_parent_terms)); 61 61 } 62 62 63 $ breadcrumbs[] = '<span class="current">' . esc_html($current_term->name) . '</span>';63 $naibabiji_b2b_breadcrumbs[] = '<span class="current">' . esc_html($naibabiji_b2b_current_term->name) . '</span>'; 64 64 ?> 65 65 66 66 <nav class="naibabiji-b2b-breadcrumbs" aria-label="<?php echo esc_attr__('Breadcrumb Navigation', 'naibabiji-b2b-product-showcase'); ?>"> 67 <?php echo wp_kses_post(implode(' <span class="separator">></span> ', $ breadcrumbs)); ?>67 <?php echo wp_kses_post(implode(' <span class="separator">></span> ', $naibabiji_b2b_breadcrumbs)); ?> 68 68 </nav> 69 69 … … 71 71 // Display top SEO content 72 72 if (class_exists('Naibabiji_B2B_Product_Taxonomy_Fields')) { 73 Naibabiji_B2B_Product_Taxonomy_Fields::render_seo_content($ current_term->term_id, 'top', 'naibb2pr_product_category');73 Naibabiji_B2B_Product_Taxonomy_Fields::render_seo_content($naibabiji_b2b_current_term->term_id, 'top', 'naibb2pr_product_category'); 74 74 } 75 75 ?> … … 77 77 <?php 78 78 // Display subcategories 79 $ child_terms = get_terms(array(79 $naibabiji_b2b_child_terms = get_terms(array( 80 80 'taxonomy' => 'naibb2pr_product_category', 81 'parent' => $ current_term->term_id,81 'parent' => $naibabiji_b2b_current_term->term_id, 82 82 'hide_empty' => false, 83 83 )); 84 84 85 if (!empty($ child_terms) && !is_wp_error($child_terms)) :85 if (!empty($naibabiji_b2b_child_terms) && !is_wp_error($naibabiji_b2b_child_terms)) : 86 86 ?> 87 87 <div class="naibabiji-b2b-child-categories"> 88 88 <h3><?php echo esc_html__('Subcategories', 'naibabiji-b2b-product-showcase'); ?></h3> 89 89 <ul class="naibabiji-b2b-category-list"> 90 <?php foreach ($ child_terms as $child_term) : ?>90 <?php foreach ($naibabiji_b2b_child_terms as $naibabiji_b2b_child_term) : ?> 91 91 <?php 92 $ child_link = get_term_link($child_term);93 if (is_wp_error($ child_link)) {92 $naibabiji_b2b_child_link = get_term_link($naibabiji_b2b_child_term); 93 if (is_wp_error($naibabiji_b2b_child_link)) { 94 94 continue; 95 95 } 96 96 ?> 97 97 <li> 98 <a href="<?php echo esc_url($ child_link); ?>" class="naibabiji-b2b-category-link">99 <?php echo esc_html($ child_term->name); ?>98 <a href="<?php echo esc_url($naibabiji_b2b_child_link); ?>" class="naibabiji-b2b-category-link"> 99 <?php echo esc_html($naibabiji_b2b_child_term->name); ?> 100 100 </a> 101 101 </li> … … 126 126 <?php 127 127 // 使用设置中的摘要长度,默认为20 128 $ excerpt_length = get_option('naibabiji_b2b_product_excerpt_length', 20);128 $naibabiji_b2b_excerpt_length = get_option('naibabiji_b2b_product_excerpt_length', 20); 129 129 ?> 130 <p><?php echo esc_html(wp_trim_words(get_the_excerpt(), $ excerpt_length)); ?></p>130 <p><?php echo esc_html(wp_trim_words(get_the_excerpt(), $naibabiji_b2b_excerpt_length)); ?></p> 131 131 </div> 132 132 <?php endif; ?> … … 134 134 <?php 135 135 // Display product categories 136 $ product_categories = get_the_terms(get_the_ID(), 'naibb2pr_product_category');137 if ($ product_categories && !is_wp_error($product_categories)) :138 $ primary_category = $product_categories[0];139 $ primary_category_link = get_term_link($primary_category, 'naibb2pr_product_category');140 if (!is_wp_error($ primary_category_link)) :136 $naibabiji_b2b_product_categories = get_the_terms(get_the_ID(), 'naibb2pr_product_category'); 137 if ($naibabiji_b2b_product_categories && !is_wp_error($naibabiji_b2b_product_categories)) : 138 $naibabiji_b2b_primary_category = $naibabiji_b2b_product_categories[0]; 139 $naibabiji_b2b_primary_category_link = get_term_link($naibabiji_b2b_primary_category, 'naibb2pr_product_category'); 140 if (!is_wp_error($naibabiji_b2b_primary_category_link)) : 141 141 ?> 142 142 <div class="naibabiji-b2b-product-meta"> 143 143 <span class="naibabiji-b2b-product-category"> 144 144 <?php echo esc_html__('Category:', 'naibabiji-b2b-product-showcase'); ?> 145 <a href="<?php echo esc_url($ primary_category_link); ?>">146 <?php echo esc_html($ primary_category->name); ?>145 <a href="<?php echo esc_url($naibabiji_b2b_primary_category_link); ?>"> 146 <?php echo esc_html($naibabiji_b2b_primary_category->name); ?> 147 147 </a> 148 148 </span> … … 185 185 // Display bottom SEO content 186 186 if (class_exists('Naibabiji_B2B_Product_Taxonomy_Fields')) { 187 Naibabiji_B2B_Product_Taxonomy_Fields::render_seo_content($ current_term->term_id, 'bottom', 'naibb2pr_product_category');187 Naibabiji_B2B_Product_Taxonomy_Fields::render_seo_content($naibabiji_b2b_current_term->term_id, 'bottom', 'naibb2pr_product_category'); 188 188 } 189 189 ?> -
naibabiji-b2b-product-showcase/trunk/templates/taxonomy-naibb2pr_product_tag.php
r3392914 r3393729 32 32 <?php 33 33 // Display breadcrumb navigation 34 $ current_term = get_queried_object();35 $ breadcrumbs = array();34 $naibabiji_b2b_current_term = get_queried_object(); 35 $naibabiji_b2b_breadcrumbs = array(); 36 36 37 $ breadcrumbs[] = '<a href="' . esc_url(home_url('/')) . '">' . esc_html__('Home', 'naibabiji-b2b-product-showcase') . '</a>';38 $ breadcrumbs[] = '<a href="' . esc_url(get_post_type_archive_link('naibb2pr_products')) . '">' . esc_html__('Products', 'naibabiji-b2b-product-showcase') . '</a>';39 $ breadcrumbs[] = '<span class="current">' . esc_html($current_term->name) . '</span>';37 $naibabiji_b2b_breadcrumbs[] = '<a href="' . esc_url(home_url('/')) . '">' . esc_html__('Home', 'naibabiji-b2b-product-showcase') . '</a>'; 38 $naibabiji_b2b_breadcrumbs[] = '<a href="' . esc_url(get_post_type_archive_link('naibb2pr_products')) . '">' . esc_html__('Products', 'naibabiji-b2b-product-showcase') . '</a>'; 39 $naibabiji_b2b_breadcrumbs[] = '<span class="current">' . esc_html($naibabiji_b2b_current_term->name) . '</span>'; 40 40 ?> 41 41 42 42 <nav class="naibabiji-b2b-breadcrumbs" aria-label="<?php echo esc_attr__('Breadcrumb Navigation', 'naibabiji-b2b-product-showcase'); ?>"> 43 <?php echo wp_kses_post(implode(' <span class="separator">></span> ', $ breadcrumbs)); ?>43 <?php echo wp_kses_post(implode(' <span class="separator">></span> ', $naibabiji_b2b_breadcrumbs)); ?> 44 44 </nav> 45 45 … … 47 47 // Display top SEO content 48 48 if (class_exists('Naibabiji_B2B_Product_Taxonomy_Fields')) { 49 Naibabiji_B2B_Product_Taxonomy_Fields::render_seo_content($ current_term->term_id, 'top', 'naibb2pr_product_tag');49 Naibabiji_B2B_Product_Taxonomy_Fields::render_seo_content($naibabiji_b2b_current_term->term_id, 'top', 'naibb2pr_product_tag'); 50 50 } 51 51 ?> … … 72 72 <?php 73 73 // 使用设置中的摘要长度,默认为20 74 $ excerpt_length = get_option('naibabiji_b2b_product_excerpt_length', 20);74 $naibabiji_b2b_excerpt_length = get_option('naibabiji_b2b_product_excerpt_length', 20); 75 75 ?> 76 <p><?php echo esc_html(wp_trim_words(get_the_excerpt(), $ excerpt_length)); ?></p>76 <p><?php echo esc_html(wp_trim_words(get_the_excerpt(), $naibabiji_b2b_excerpt_length)); ?></p> 77 77 </div> 78 78 <?php endif; ?> … … 80 80 <?php 81 81 // Display product categories 82 $ product_categories = get_the_terms(get_the_ID(), 'naibb2pr_product_category');83 if ($ product_categories && !is_wp_error($product_categories)) :84 $ primary_category = $product_categories[0];85 $ primary_category_link = get_term_link($primary_category, 'naibb2pr_product_category');86 if (!is_wp_error($ primary_category_link)) :82 $naibabiji_b2b_product_categories = get_the_terms(get_the_ID(), 'naibb2pr_product_category'); 83 if ($naibabiji_b2b_product_categories && !is_wp_error($naibabiji_b2b_product_categories)) : 84 $naibabiji_b2b_primary_category = $naibabiji_b2b_product_categories[0]; 85 $naibabiji_b2b_primary_category_link = get_term_link($naibabiji_b2b_primary_category, 'naibb2pr_product_category'); 86 if (!is_wp_error($naibabiji_b2b_primary_category_link)) : 87 87 ?> 88 88 <div class="naibabiji-b2b-product-meta"> 89 89 <span class="naibabiji-b2b-product-category"> 90 90 <?php echo esc_html__('Category:', 'naibabiji-b2b-product-showcase'); ?> 91 <a href="<?php echo esc_url($ primary_category_link); ?>">92 <?php echo esc_html($ primary_category->name); ?>91 <a href="<?php echo esc_url($naibabiji_b2b_primary_category_link); ?>"> 92 <?php echo esc_html($naibabiji_b2b_primary_category->name); ?> 93 93 </a> 94 94 </span> … … 131 131 // Display bottom SEO content 132 132 if (class_exists('Naibabiji_B2B_Product_Taxonomy_Fields')) { 133 Naibabiji_B2B_Product_Taxonomy_Fields::render_seo_content($ current_term->term_id, 'bottom', 'naibb2pr_product_tag');133 Naibabiji_B2B_Product_Taxonomy_Fields::render_seo_content($naibabiji_b2b_current_term->term_id, 'bottom', 'naibb2pr_product_tag'); 134 134 } 135 135 ?>
Note: See TracChangeset
for help on using the changeset viewer.