Как я могу сохранить настраиваемое поле атрибута в Woocommerce?
старый
Я пытаюсь создать настраиваемое поле в атрибутах продукта в Woocommerce. Это можно выбрать, если атрибут выделен или нет. Например:
Что я хочу сделать, так это чтобы поле, указанное в бэкэнде как выделенное, было определенным образом отображено в веб-интерфейсе.
Пока я смог добавить поле, но мне не удалось выяснить, как его сохранить. Вот что у меня есть:
add_action('woocommerce_after_product_attribute_settings','wcb_add_product_attribute_is_highlighted', 10, 2);
add_filter( 'woocommerce_admin_meta_boxes_prepare_attribute', 'wcb_admin_meta_boxes_prepare_attribute', 10, 3);
function get_attribute_highlighted($id, $i) {
return get_post_meta( 1, "attribute_".$id."_highlighted_".$i, true);
}
function wcb_add_product_attribute_is_highlighted($attribute, $i=0) {
$value = get_attribute_highlighted($attribute->get_id(), $i); ?>
<tr>
<td>
<div class="enable_variation show_if_canopytour show_if_variable_canopytour">
<label><input type="checkbox" class="checkbox" <?php checked( $value, true ); ?> name="attribute_highlighted[<?php echo esc_attr( $i ); ?>]" value="1" /> <?php esc_html_e( 'Highlight attribute', $this->wcb ); ?></label>
</div>
</td>
</tr>
<?php
}
function wcb_admin_meta_boxes_prepare_attribute($attribute, $data, $i=0) {
// updated
if(array_key_exists("attribute_highlighted", $data) && is_array($data["attribute_highlighted"])) {
update_post_meta( 1, "attribute_".$attribute->get_id()."_highlighted_".$i, wc_string_to_bool($data["attribute_highlighted"][$i]) );
}
}
Я попробовал woocommerce_admin_meta_boxes_prepare_attribute
фильтровать с помощью offsetSet
а также offsetGet
методы WC_Product_Attribute
класс но не могу понять как это работает. Я не мог заставить его сохранить свое значение.
Любая помощь будет приветствоваться, спасибо.
Обновить
Я изменил woocommerce_admin_meta_boxes_prepare_attribute
фильтровать по wp_ajax_woocommerce_save_attributes
действие и похоже на работу. Теперь у меня проблема, что он не обновляется после сохранения в первый раз.
Я объясняю текущую проблему: у меня есть флажок, который при нажатии активируется, я сохраняю и при перезагрузке состояние сохраняется. Если сейчас я хочу деактивировать его, после сохранения состояния оно не сохраняется как отключенное, оно возвращается как активированное.
Это обновленный код:
add_action('woocommerce_after_product_attribute_settings', 'wcb_add_product_attribute_is_highlighted', 10, 2);
add_action('wp_ajax_woocommerce_save_attributes', 'wcb_ajax_woocommerce_save_attributes', 10);
function get_attribute_highlighted($id, $i) {
global $post;
$id = sanitize_title($id);
$id = strtolower($id);
$val = get_post_meta( $post->ID, "attribute_".$id."_highlighted_".$i, true);
return !empty($val) ? $val : false;
}
function wcb_add_product_attribute_is_highlighted($attribute, $i=0) {
$value = get_attribute_highlighted($attribute->get_name(), $i); ?>
<tr>
<td>
<div class="enable_highlighted show_if_canopytour show_if_variable_canopytour">
<label><input type="checkbox" class="checkbox" <?php checked( $value, true ); ?> name="attribute_highlighted[<?php echo esc_attr( $i ); ?>]" value="1" /> <?php esc_html_e( 'Highlight attribute', $this->wcb ); ?></label>
</div>
</td>
</tr>
<?php
}
function wcb_ajax_woocommerce_save_attributes() {
check_ajax_referer( 'save-attributes', 'security' );
parse_str( $_POST['data'], $data );
$post_id = absint( $_POST['post_id'] );
if(array_key_exists("attribute_highlighted", $data) && is_array($data["attribute_highlighted"])) {
foreach($data["attribute_highlighted"] as $i => $val) {
$attr_name = sanitize_title($data["attribute_names"][$i]);
$attr_name = strtolower($attr_name);
update_post_meta( $post_id, "attribute_".$attr_name."_highlighted_".$i, wc_string_to_bool($val) );
}
}
}
5 ответов
Я нашел решение своей проблемы. Я делюсь кодом на случай, если кому-то пригодится. С уважением!
add_action('woocommerce_after_product_attribute_settings', 'wcb_add_product_attribute_is_highlighted', 10, 2);
add_action('wp_ajax_woocommerce_save_attributes', 'wcb_ajax_woocommerce_save_attributes', 10);
function get_attribute_highlighted($id, $i) {
global $post;
$id = sanitize_title($id);
$id = strtolower($id);
$val = get_post_meta( $post->ID, "attribute_".$id."_highlighted_".$i, true);
return !empty($val) ? $val : false;
}
function wcb_add_product_attribute_is_highlighted($attribute, $i=0) {
$value = get_attribute_highlighted($attribute->get_name(), $i); ?>
<tr>
<td>
<div class="enable_highlighted">
<label><input type="hidden" name="attribute_highlighted[<?php echo esc_attr( $i ); ?>]" value="0" /><input type="checkbox" class="checkbox" <?php checked( $value, true ); ?> name="attribute_highlighted[<?php echo esc_attr( $i ); ?>]" value="1" /> <?php esc_html_e( 'Highlight attribute', $this->wcb ); ?></label>
</div>
</td>
</tr>
<?php
}
function wcb_ajax_woocommerce_save_attributes() {
check_ajax_referer( 'save-attributes', 'security' );
parse_str( $_POST['data'], $data );
$post_id = absint( $_POST['post_id'] );
if(array_key_exists("attribute_highlighted", $data) && is_array($data["attribute_highlighted"])) {
foreach($data["attribute_highlighted"] as $i => $val) {
$attr_name = sanitize_title($data["attribute_names"][$i]);
$attr_name = strtolower($attr_name);
update_post_meta( $post_id, "attribute_".$attr_name."_highlighted_".$i, wc_string_to_bool($val) );
}
}
}
В конце концов, единственное, что мне пришлось добавить в свой код, это скрытый ввод с тем же именем, что и у флажка, но со значением 0: <input type="hidden" name="attribute_highlighted[<?php echo esc_attr( $i ); ?>]" value="0" />
Вот изображение результата ( ). При нажатии на кнопку сохранить значение флажка сохраняется. Значение сохраняется в post_meta сообщения, которое вы изменяете. Это полезно, если вы хотите выделить определенный атрибут в интерфейсе.
Я ценю помощь @LoicTheAztec:)
Когда я боролся с той же проблемой, я попытался использовать код от Иисуса Магаллона. Однако это не сработало.
Я узнал, что приоритет
wp_ajax_woocommerce_save_attributes
должен быть установлен в 0, иначе обратный вызов по какой-то причине не запускается.
Кроме того, если мы используем только
$post->ID
за
get_post_meta()
правильное состояние результатов флажка будет видно только при перезагрузке страницы. Чтобы убедиться, что выбранное состояние также видно сразу после сохранения/перезагрузки ajax, нам нужно использовать
$post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : $post->ID;
вместо.
Вот окончательная версия, которая должна работать идеально для всех:
add_action( 'woocommerce_after_product_attribute_settings', 'wcb_add_product_attribute_is_highlighted', 10, 2);
add_action( 'wp_ajax_woocommerce_save_attributes', 'wcb_ajax_woocommerce_save_attributes', 0);
function get_attribute_highlighted( $attribute_name, $i ) {
global $post;
// ID for either from ajax or from post
$post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : $post->ID ;
$attribute_name = strtolower( sanitize_title( $attribute_name ) );
$val = get_post_meta( $post_id, 'attribute_' . $attribute_name . '_highlighted_' . $i, true );
return !empty( $val ) ? $val : false;
}
function wcb_add_product_attribute_is_highlighted( $attribute, $i=0 ) {
$value = get_attribute_highlighted($attribute->get_name(), $i); ?>
<tr>
<td>
<div class="enable_highlighted">
<label>
<input type="hidden" name="attribute_highlighted[<?php echo esc_attr( $i ); ?>]" value="0" />
<input type="checkbox" class="checkbox" <?php checked( $value, true ); ?> name="attribute_highlighted[<?php echo esc_attr( $i ); ?>]" value="1" />
<?php esc_html_e( 'Highlight attribute', 'textdomain' ); ?>
</label>
</div>
</td>
</tr>
<?php
}
function wcb_ajax_woocommerce_save_attributes() {
check_ajax_referer( 'save-attributes', 'security' );
parse_str( $_POST['data'], $data );
$post_id = absint( $_POST['post_id'] );
if( array_key_exists( 'attribute_highlighted', $data ) && is_array( $data['attribute_highlighted'] ) ) {
foreach( $data['attribute_highlighted'] as $i => $val ) {
$attr_name = sanitize_title( $data['attribute_names'][$i] );
$attr_name = strtolower( $attr_name );
update_post_meta( $post_id, 'attribute_' . $attr_name . '_highlighted_' . absint( $i ), wc_string_to_bool( $val ) );
}
}
}
@ink почти понял, но он не работает, когда вы нажимаете кнопку всего продукта напрямую. Всегда нужно нажиматьSave attributes
кнопку во-первых, и это неправильно, потому что, когда вы попробуете другие флажки, вы увидите, что это работает также наUpdate
нажмите.
Так что я бы полностью удалил этоadd_action( 'wp_ajax_woocommerce_save_attributes', 'wcb_ajax_woocommerce_save_attributes', 0);
иwcb_ajax_woocommerce_save_attributes
функцию и используйте это вместо этого:
add_filter( 'woocommerce_admin_meta_boxes_prepare_attribute', function( $attribute, $data, $i ){
global $post;
if( is_object( $post ) && isset( $post->ID ) ){
$post_id = $post->ID;
}else{
$post_id = absint( $_POST['post_id'] );
}
if( array_key_exists( 'attribute_highlighted', $data ) && is_array( $data['attribute_highlighted'] ) ){
foreach( $data['attribute_highlighted'] as $i => $value ){
$attr_name = sanitize_title( $data['attribute_names'][ $i ] );
update_post_meta( $post_id, 'attribute_' . $attr_name . '_highlighted_' . absint( $i ), wc_string_to_bool( $value ) );
}
}
return $attribute;
}, 10, 3 );
Идеальный код, но поменяйте крючок
add_action('wp_ajax_woocommerce_save_attributes', 'wcb_ajax_woocommerce_save_attributes', 10);
в
add_action('wp_ajax_woocommerce_save_attributes', 'wcb_ajax_woocommerce_save_attributes', 0);
Ответ требует небольших изменений. Удалить функциюget_attribute_highlighted()
и замените эту строку
$value = get_attribute_highlighted($attribute->get_name(), $i);
К
global $post;
$post_id = isset($_POST['post_id']) ? absint($_POST['post_id']) : $post->ID ;
$value = get_post_meta($post_id , "attribute_description".$i, true);
Он покажет экземпляр сохраненного значения ajax пустого;
И изменить крючки
add_action('wp_ajax_woocommerce_save_attributes', 'wcb_ajax_woocommerce_save_attributes', 10);
К
add_action('wp_ajax_woocommerce_save_attributes', 'wcb_ajax_woocommerce_save_attributes', 0);