Refactor plugin structure: replace master-file.php with siti-google-shopping-feed.php and update release workflow paths
All checks were successful
Build & Release Plugin / release (push) Successful in 8s
All checks were successful
Build & Release Plugin / release (push) Successful in 8s
This commit is contained in:
561
includes/SitiGoogleShoppingFeed.php
Normal file
561
includes/SitiGoogleShoppingFeed.php
Normal file
@@ -0,0 +1,561 @@
|
||||
<?php
|
||||
final class SitiGoogleShoppingFeed {
|
||||
const QUERY_VAR = 'livebetter_google_feed';
|
||||
const FEED_SLUG = 'google-shopping-feed.xml';
|
||||
const DEFAULT_PAGE_SIZE = 200;
|
||||
const EXTERNAL_STOCK_META_KEY_FALLBACK = '_siti_external_stock';
|
||||
const GENDER_META_KEY = '_lb_google_gender';
|
||||
const AGE_GROUP_META_KEY = '_lb_google_age_group';
|
||||
|
||||
public static function init() {
|
||||
add_action( 'init', array( __CLASS__, 'register_rewrite' ) );
|
||||
add_filter( 'query_vars', array( __CLASS__, 'register_query_var' ) );
|
||||
add_action( 'template_redirect', array( __CLASS__, 'maybe_render_feed' ) );
|
||||
add_filter( 'woocommerce_product_data_tabs', array( __CLASS__, 'register_product_data_tab' ) );
|
||||
add_action( 'woocommerce_product_data_panels', array( __CLASS__, 'render_product_data_panel' ) );
|
||||
add_action( 'woocommerce_process_product_meta', array( __CLASS__, 'save_product_data_fields' ) );
|
||||
}
|
||||
|
||||
public static function activate() {
|
||||
self::register_rewrite();
|
||||
flush_rewrite_rules();
|
||||
}
|
||||
|
||||
public static function deactivate() {
|
||||
flush_rewrite_rules();
|
||||
}
|
||||
|
||||
public static function register_rewrite() {
|
||||
add_rewrite_rule( '^' . preg_quote( self::FEED_SLUG, '/' ) . '$', 'index.php?' . self::QUERY_VAR . '=1', 'top' );
|
||||
}
|
||||
|
||||
public static function register_query_var( $vars ) {
|
||||
$vars[] = self::QUERY_VAR;
|
||||
return $vars;
|
||||
}
|
||||
|
||||
public static function maybe_render_feed() {
|
||||
if ( ! get_query_var( self::QUERY_VAR ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::render_feed();
|
||||
exit;
|
||||
}
|
||||
|
||||
private static function render_feed() {
|
||||
if ( ! function_exists( 'wc_get_products' ) ) {
|
||||
status_header( 503 );
|
||||
echo 'WooCommerce is required for this feed.';
|
||||
return;
|
||||
}
|
||||
|
||||
if ( function_exists( 'nocache_headers' ) ) {
|
||||
nocache_headers();
|
||||
}
|
||||
|
||||
header( 'Content-Type: application/xml; charset=UTF-8' );
|
||||
header( 'X-Robots-Tag: noindex, nofollow', true );
|
||||
|
||||
@set_time_limit( 0 );
|
||||
|
||||
$site_name = get_bloginfo( 'name' );
|
||||
$site_url = home_url( '/' );
|
||||
|
||||
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
||||
echo "<rss version=\"2.0\" xmlns:g=\"http://base.google.com/ns/1.0\">\n";
|
||||
echo "<channel>\n";
|
||||
self::output_tag( 'title', $site_name );
|
||||
self::output_tag( 'link', $site_url );
|
||||
self::output_tag( 'description', 'Google Shopping Feed' );
|
||||
|
||||
$page_size = (int) apply_filters( 'livebetter_google_feed_page_size', self::DEFAULT_PAGE_SIZE );
|
||||
$page_size = max( 1, $page_size );
|
||||
$page = 1;
|
||||
|
||||
do {
|
||||
$query_args = array(
|
||||
'status' => 'publish',
|
||||
'type' => array( 'simple', 'variation' ),
|
||||
'visibility' => array( 'visible', 'catalog', 'search' ),
|
||||
'limit' => $page_size,
|
||||
'page' => $page,
|
||||
);
|
||||
|
||||
$query_args = apply_filters( 'livebetter_google_feed_query_args', $query_args, $page, $page_size );
|
||||
|
||||
$products = wc_get_products( $query_args );
|
||||
|
||||
foreach ( $products as $product ) {
|
||||
self::render_item( $product );
|
||||
}
|
||||
|
||||
$page++;
|
||||
} while ( count( $products ) === $page_size );
|
||||
|
||||
echo "</channel>\n";
|
||||
echo "</rss>\n";
|
||||
}
|
||||
|
||||
private static function render_item( WC_Product $product ) {
|
||||
if ( 'publish' !== $product->get_status() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$parent = null;
|
||||
if ( $product->is_type( 'variation' ) ) {
|
||||
$parent_id = $product->get_parent_id();
|
||||
$parent = $parent_id ? wc_get_product( $parent_id ) : null;
|
||||
if ( $parent instanceof WC_Product && 'publish' !== $parent->get_status() ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$image_link = self::get_image_link( $product, $parent );
|
||||
if ( empty( $image_link ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( '' === $product->get_price() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$price_data = self::get_price_data( $product );
|
||||
if ( empty( $price_data['price'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$availability = self::get_availability( $product );
|
||||
$brand = self::get_brand( $product, $parent );
|
||||
$gtin = self::get_gtin( $product, $parent );
|
||||
$mpn = self::get_mpn( $product, $parent );
|
||||
$gender = self::get_gender( $product, $parent );
|
||||
$age_group = self::get_age_group( $product, $parent );
|
||||
$size = self::get_size( $product, $parent );
|
||||
$size_system = $size ? self::get_size_system() : '';
|
||||
$size_type = $size ? self::get_size_type() : '';
|
||||
$color = self::get_color( $product, $parent );
|
||||
$material = self::get_material( $product, $parent );
|
||||
|
||||
$identifier_exists = ( empty( $brand ) && empty( $gtin ) && empty( $mpn ) ) ? 'no' : 'yes';
|
||||
|
||||
$item_data = array(
|
||||
'id' => (string) $product->get_id(),
|
||||
'item_group_id' => $parent ? (string) $parent->get_id() : '',
|
||||
'title' => self::get_title( $product, $parent ),
|
||||
'description' => self::get_description( $product, $parent ),
|
||||
'link' => $product->get_permalink(),
|
||||
'image_link' => $image_link,
|
||||
'availability' => $availability,
|
||||
'price' => $price_data['price'],
|
||||
'sale_price' => $price_data['sale_price'],
|
||||
'condition' => 'new',
|
||||
'brand' => $brand,
|
||||
'gtin' => $gtin,
|
||||
'mpn' => $mpn,
|
||||
'gender' => $gender,
|
||||
'age_group' => $age_group,
|
||||
'size' => $size,
|
||||
'size_system' => $size_system,
|
||||
'size_type' => $size_type,
|
||||
'color' => $color,
|
||||
'material' => $material,
|
||||
'identifier_exists' => $identifier_exists,
|
||||
);
|
||||
|
||||
$item_data = apply_filters( 'livebetter_google_feed_item_data', $item_data, $product, $parent );
|
||||
|
||||
echo "<item>\n";
|
||||
self::output_tag( 'g:id', $item_data['id'] );
|
||||
if ( ! empty( $item_data['item_group_id'] ) ) {
|
||||
self::output_tag( 'g:item_group_id', $item_data['item_group_id'] );
|
||||
}
|
||||
self::output_tag( 'title', $item_data['title'] );
|
||||
self::output_tag( 'description', $item_data['description'] );
|
||||
self::output_tag( 'link', $item_data['link'] );
|
||||
self::output_tag( 'g:image_link', $item_data['image_link'] );
|
||||
self::output_tag( 'g:availability', $item_data['availability'] );
|
||||
self::output_tag( 'g:price', $item_data['price'] );
|
||||
if ( ! empty( $item_data['sale_price'] ) ) {
|
||||
self::output_tag( 'g:sale_price', $item_data['sale_price'] );
|
||||
}
|
||||
self::output_tag( 'g:condition', $item_data['condition'] );
|
||||
if ( ! empty( $item_data['brand'] ) ) {
|
||||
self::output_tag( 'g:brand', $item_data['brand'] );
|
||||
}
|
||||
if ( ! empty( $item_data['gender'] ) ) {
|
||||
self::output_tag( 'g:gender', $item_data['gender'] );
|
||||
}
|
||||
if ( ! empty( $item_data['age_group'] ) ) {
|
||||
self::output_tag( 'g:age_group', $item_data['age_group'] );
|
||||
}
|
||||
if ( ! empty( $item_data['size'] ) ) {
|
||||
self::output_tag( 'g:size', $item_data['size'] );
|
||||
}
|
||||
if ( ! empty( $item_data['size_system'] ) ) {
|
||||
self::output_tag( 'g:size_system', $item_data['size_system'] );
|
||||
}
|
||||
if ( ! empty( $item_data['size_type'] ) ) {
|
||||
self::output_tag( 'g:size_type', $item_data['size_type'] );
|
||||
}
|
||||
if ( ! empty( $item_data['color'] ) ) {
|
||||
self::output_tag( 'g:color', $item_data['color'] );
|
||||
}
|
||||
if ( ! empty( $item_data['material'] ) ) {
|
||||
self::output_tag( 'g:material', $item_data['material'] );
|
||||
}
|
||||
if ( ! empty( $item_data['gtin'] ) ) {
|
||||
self::output_tag( 'g:gtin', $item_data['gtin'] );
|
||||
}
|
||||
if ( ! empty( $item_data['mpn'] ) ) {
|
||||
self::output_tag( 'g:mpn', $item_data['mpn'] );
|
||||
}
|
||||
if ( 'no' === $item_data['identifier_exists'] ) {
|
||||
self::output_tag( 'g:identifier_exists', 'no' );
|
||||
}
|
||||
echo "</item>\n";
|
||||
}
|
||||
|
||||
private static function get_title( WC_Product $product, $parent ) {
|
||||
$title = $product->get_name();
|
||||
if ( empty( $title ) && $parent instanceof WC_Product ) {
|
||||
$title = $parent->get_name();
|
||||
}
|
||||
return $title;
|
||||
}
|
||||
|
||||
private static function get_description( WC_Product $product, $parent ) {
|
||||
$description = $product->get_description();
|
||||
if ( empty( $description ) ) {
|
||||
$description = $product->get_short_description();
|
||||
}
|
||||
if ( empty( $description ) && $parent instanceof WC_Product ) {
|
||||
$description = $parent->get_description();
|
||||
}
|
||||
if ( empty( $description ) && $parent instanceof WC_Product ) {
|
||||
$description = $parent->get_short_description();
|
||||
}
|
||||
|
||||
$description = strip_shortcodes( (string) $description );
|
||||
$description = wp_strip_all_tags( $description );
|
||||
$description = preg_replace( '/\\s+/', ' ', $description );
|
||||
$description = trim( $description );
|
||||
|
||||
if ( function_exists( 'mb_substr' ) ) {
|
||||
$description = mb_substr( $description, 0, 5000 );
|
||||
} else {
|
||||
$description = substr( $description, 0, 5000 );
|
||||
}
|
||||
|
||||
if ( '' === $description ) {
|
||||
$description = self::get_title( $product, $parent );
|
||||
}
|
||||
|
||||
return $description;
|
||||
}
|
||||
|
||||
private static function get_image_link( WC_Product $product, $parent ) {
|
||||
$image_id = $product->get_image_id();
|
||||
if ( ! $image_id && $parent instanceof WC_Product ) {
|
||||
$image_id = $parent->get_image_id();
|
||||
}
|
||||
|
||||
if ( ! $image_id ) {
|
||||
$gallery_ids = $product->get_gallery_image_ids();
|
||||
if ( empty( $gallery_ids ) && $parent instanceof WC_Product ) {
|
||||
$gallery_ids = $parent->get_gallery_image_ids();
|
||||
}
|
||||
$image_id = $gallery_ids ? (int) $gallery_ids[0] : 0;
|
||||
}
|
||||
|
||||
if ( ! $image_id ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$image_link = wp_get_attachment_image_url( $image_id, 'full' );
|
||||
|
||||
return $image_link ? $image_link : '';
|
||||
}
|
||||
|
||||
private static function get_price_data( WC_Product $product ) {
|
||||
$currency = get_woocommerce_currency();
|
||||
$decimals = wc_get_price_decimals();
|
||||
|
||||
$price = wc_get_price_to_display( $product );
|
||||
$price = wc_format_decimal( $price, $decimals ) . ' ' . $currency;
|
||||
|
||||
$sale_price = '';
|
||||
if ( $product->is_on_sale() && '' !== $product->get_sale_price() ) {
|
||||
$regular_price_value = wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) );
|
||||
$sale_price_value = wc_get_price_to_display( $product, array( 'price' => $product->get_sale_price() ) );
|
||||
$price = wc_format_decimal( $regular_price_value, $decimals ) . ' ' . $currency;
|
||||
$sale_price = wc_format_decimal( $sale_price_value, $decimals ) . ' ' . $currency;
|
||||
}
|
||||
|
||||
return array(
|
||||
'price' => $price,
|
||||
'sale_price' => $sale_price,
|
||||
);
|
||||
}
|
||||
|
||||
private static function get_availability( WC_Product $product ) {
|
||||
$stock_holder = self::get_stock_holder( $product );
|
||||
|
||||
if ( $stock_holder->managing_stock() ) {
|
||||
$combined_stock = self::get_combined_stock( $stock_holder );
|
||||
if ( $combined_stock > 0 ) {
|
||||
$availability = 'in_stock';
|
||||
} else {
|
||||
$availability = 'out_of_stock';
|
||||
if ( $stock_holder->backorders_allowed() ) {
|
||||
$availability = apply_filters( 'livebetter_google_feed_backorder_availability', $availability, $product, $stock_holder );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$availability = $stock_holder->is_in_stock() ? 'in_stock' : 'out_of_stock';
|
||||
}
|
||||
|
||||
return apply_filters( 'livebetter_google_feed_availability', $availability, $product, $stock_holder );
|
||||
}
|
||||
|
||||
private static function get_stock_holder( WC_Product $product ) {
|
||||
$managed_id = $product->get_stock_managed_by_id();
|
||||
if ( $managed_id && $managed_id !== $product->get_id() ) {
|
||||
$holder = wc_get_product( $managed_id );
|
||||
if ( $holder instanceof WC_Product ) {
|
||||
return $holder;
|
||||
}
|
||||
}
|
||||
|
||||
return $product;
|
||||
}
|
||||
|
||||
private static function get_combined_stock( WC_Product $product ) {
|
||||
$external_key = self::EXTERNAL_STOCK_META_KEY_FALLBACK;
|
||||
if ( class_exists( 'Siti_Stock_Plugin' ) ) {
|
||||
$external_key = Siti_Stock_Plugin::EXTERNAL_STOCK_META_KEY;
|
||||
}
|
||||
|
||||
$raw_stock = $product->get_stock_quantity( 'edit' );
|
||||
$base_stock = function_exists( 'wc_stock_amount' ) ? wc_stock_amount( $raw_stock ) : (int) $raw_stock;
|
||||
$external_stock = (int) $product->get_meta( $external_key, true );
|
||||
|
||||
return max( 0, (int) $base_stock ) + max( 0, $external_stock );
|
||||
}
|
||||
|
||||
private static function get_brand( WC_Product $product, $parent ) {
|
||||
$brand = self::get_taxonomy_terms_value( $product, $parent, array( 'product_brand', 'product_brands', 'brands', 'brand' ) );
|
||||
|
||||
if ( empty( $brand ) ) {
|
||||
$brand = $product->get_meta( '_wc_gla_brand', true );
|
||||
}
|
||||
|
||||
if ( empty( $brand ) && $parent instanceof WC_Product ) {
|
||||
$brand = $parent->get_meta( '_wc_gla_brand', true );
|
||||
}
|
||||
|
||||
if ( empty( $brand ) ) {
|
||||
$brand = self::get_attribute_value( $product, $parent, array( 'pa_merk', 'pa_brand', 'brand' ) );
|
||||
}
|
||||
|
||||
return apply_filters( 'livebetter_google_feed_brand', $brand, $product, $parent );
|
||||
}
|
||||
|
||||
private static function get_gtin( WC_Product $product, $parent ) {
|
||||
$gtin = '';
|
||||
if ( method_exists( $product, 'get_global_unique_id' ) ) {
|
||||
$gtin = preg_replace( '/[^0-9]/', '', (string) $product->get_global_unique_id() );
|
||||
}
|
||||
if ( empty( $gtin ) && $parent instanceof WC_Product && method_exists( $parent, 'get_global_unique_id' ) ) {
|
||||
$gtin = preg_replace( '/[^0-9]/', '', (string) $parent->get_global_unique_id() );
|
||||
}
|
||||
|
||||
return apply_filters( 'livebetter_google_feed_gtin', $gtin, $product, $parent );
|
||||
}
|
||||
|
||||
private static function get_mpn( WC_Product $product, $parent ) {
|
||||
$mpn = $product->get_sku();
|
||||
if ( empty( $mpn ) && $parent instanceof WC_Product ) {
|
||||
$mpn = $parent->get_sku();
|
||||
}
|
||||
|
||||
return apply_filters( 'livebetter_google_feed_mpn', $mpn, $product, $parent );
|
||||
}
|
||||
|
||||
private static function get_gender( WC_Product $product, $parent ) {
|
||||
$gender = (string) $product->get_meta( self::GENDER_META_KEY, true );
|
||||
if ( empty( $gender ) && $parent instanceof WC_Product ) {
|
||||
$gender = (string) $parent->get_meta( self::GENDER_META_KEY, true );
|
||||
}
|
||||
|
||||
return apply_filters( 'livebetter_google_feed_gender', $gender, $product, $parent );
|
||||
}
|
||||
|
||||
private static function get_age_group( WC_Product $product, $parent ) {
|
||||
$age_group = (string) $product->get_meta( self::AGE_GROUP_META_KEY, true );
|
||||
if ( empty( $age_group ) && $parent instanceof WC_Product ) {
|
||||
$age_group = (string) $parent->get_meta( self::AGE_GROUP_META_KEY, true );
|
||||
}
|
||||
if ( empty( $age_group ) ) {
|
||||
$age_group = 'adult';
|
||||
}
|
||||
|
||||
return apply_filters( 'livebetter_google_feed_age_group', $age_group, $product, $parent );
|
||||
}
|
||||
|
||||
private static function get_size( WC_Product $product, $parent ) {
|
||||
$size = self::get_attribute_value( $product, $parent, array( 'pa_maat', 'maat' ) );
|
||||
|
||||
return apply_filters( 'livebetter_google_feed_size', $size, $product, $parent );
|
||||
}
|
||||
|
||||
private static function get_size_system() {
|
||||
return apply_filters( 'livebetter_google_feed_size_system', 'EU' );
|
||||
}
|
||||
|
||||
private static function get_size_type() {
|
||||
return apply_filters( 'livebetter_google_feed_size_type', 'regular' );
|
||||
}
|
||||
|
||||
private static function get_color( WC_Product $product, $parent ) {
|
||||
$color = self::get_attribute_value( $product, $parent, array( 'pa_kleur', 'kleur', 'color' ) );
|
||||
|
||||
return apply_filters( 'livebetter_google_feed_color', $color, $product, $parent );
|
||||
}
|
||||
|
||||
private static function get_material( WC_Product $product, $parent ) {
|
||||
$material = self::get_attribute_value( $product, $parent, array( 'pa_materiaal', 'materiaal', 'material' ) );
|
||||
|
||||
return apply_filters( 'livebetter_google_feed_material', $material, $product, $parent );
|
||||
}
|
||||
|
||||
private static function get_attribute_value( WC_Product $product, $parent, array $keys ) {
|
||||
foreach ( $keys as $key ) {
|
||||
$value = trim( (string) $product->get_attribute( $key ) );
|
||||
if ( '' !== $value ) {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $parent instanceof WC_Product ) {
|
||||
foreach ( $keys as $key ) {
|
||||
$value = trim( (string) $parent->get_attribute( $key ) );
|
||||
if ( '' !== $value ) {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
private static function get_taxonomy_terms_value( WC_Product $product, $parent, array $taxonomies ) {
|
||||
foreach ( $taxonomies as $taxonomy ) {
|
||||
if ( ! taxonomy_exists( $taxonomy ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$terms = get_the_terms( $product->get_id(), $taxonomy );
|
||||
if ( empty( $terms ) && $parent instanceof WC_Product ) {
|
||||
$terms = get_the_terms( $parent->get_id(), $taxonomy );
|
||||
}
|
||||
if ( $terms && ! is_wp_error( $terms ) ) {
|
||||
return implode( ', ', wp_list_pluck( $terms, 'name' ) );
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function register_product_data_tab( $tabs ) {
|
||||
if ( ! is_array( $tabs ) ) {
|
||||
return $tabs;
|
||||
}
|
||||
|
||||
$tabs['livebetter_google_shopping'] = array(
|
||||
'label' => __( 'Google Shopping', 'livebetter-google-shopping-feed' ),
|
||||
'target' => 'livebetter_google_shopping_data',
|
||||
'class' => array( 'show_if_simple', 'show_if_variable' ),
|
||||
'priority' => 80,
|
||||
);
|
||||
|
||||
return $tabs;
|
||||
}
|
||||
|
||||
public static function render_product_data_panel() {
|
||||
if ( ! function_exists( 'woocommerce_wp_select' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
global $post;
|
||||
|
||||
if ( ! $post ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$product = wc_get_product( $post->ID );
|
||||
if ( ! $product instanceof WC_Product ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$gender = (string) $product->get_meta( self::GENDER_META_KEY, true );
|
||||
$age_group = (string) $product->get_meta( self::AGE_GROUP_META_KEY, true );
|
||||
if ( '' === $age_group ) {
|
||||
$age_group = 'adult';
|
||||
}
|
||||
|
||||
echo '<div id="livebetter_google_shopping_data" class="panel woocommerce_options_panel">';
|
||||
|
||||
woocommerce_wp_select(
|
||||
array(
|
||||
'id' => self::GENDER_META_KEY,
|
||||
'label' => __( 'Geslacht', 'livebetter-google-shopping-feed' ),
|
||||
'value' => $gender,
|
||||
'options' => array(
|
||||
'' => __( 'Niet ingesteld', 'livebetter-google-shopping-feed' ),
|
||||
'male' => __( 'Male (M)', 'livebetter-google-shopping-feed' ),
|
||||
'female' => __( 'Female (F)', 'livebetter-google-shopping-feed' ),
|
||||
'unisex' => __( 'Unisex (U)', 'livebetter-google-shopping-feed' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
woocommerce_wp_select(
|
||||
array(
|
||||
'id' => self::AGE_GROUP_META_KEY,
|
||||
'label' => __( 'Doelgroep', 'livebetter-google-shopping-feed' ),
|
||||
'value' => $age_group,
|
||||
'options' => array(
|
||||
'adult' => __( '18+ (Adult)', 'livebetter-google-shopping-feed' ),
|
||||
'kids' => __( 'Kids', 'livebetter-google-shopping-feed' ),
|
||||
'toddler' => __( 'Toddler', 'livebetter-google-shopping-feed' ),
|
||||
'infant' => __( 'Infant', 'livebetter-google-shopping-feed' ),
|
||||
'newborn' => __( 'Newborn', 'livebetter-google-shopping-feed' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
public static function save_product_data_fields( $post_id ) {
|
||||
if ( ! isset( $_POST[ self::GENDER_META_KEY ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
return;
|
||||
}
|
||||
|
||||
$gender = sanitize_text_field( wp_unslash( $_POST[ self::GENDER_META_KEY ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
$age_group = sanitize_text_field( wp_unslash( $_POST[ self::AGE_GROUP_META_KEY ] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
|
||||
update_post_meta( $post_id, self::GENDER_META_KEY, $gender );
|
||||
update_post_meta( $post_id, self::AGE_GROUP_META_KEY, $age_group );
|
||||
}
|
||||
|
||||
private static function output_tag( $tag, $value ) {
|
||||
$value = self::escape_xml( $value );
|
||||
echo '<' . $tag . '>' . $value . '</' . $tag . ">\n";
|
||||
}
|
||||
|
||||
private static function escape_xml( $value ) {
|
||||
return htmlspecialchars( (string) $value, ENT_XML1 | ENT_COMPAT, 'UTF-8' );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user