query->query_vars ) ) { $query_vars = $woocommerce->query->query_vars; foreach ( $query_vars as $key => $val ) { if ( isset( $query[ $key ] ) ) { $query['do_not_redirect'] = 1; break; } } } return $query; } /** * Redirects the user from the Shop archive to the Shop page if the user is not searching for anything * Disable canonical redirect on "thank you" & another WooCommerce pages */ function woocommerce_checkout_fix() { global $wp_query, $pm_query, $permalink_manager_options; // Redirect from Shop archive to selected page if ( is_shop() && empty( $pm_query['id'] ) ) { $redirect_mode = ( ! empty( $permalink_manager_options['general']['redirect'] ) ) ? $permalink_manager_options['general']['redirect'] : false; $redirect_shop = apply_filters( 'permalink_manager_redirect_shop_archive', false ); $shop_page = get_option( 'woocommerce_shop_page_id' ); if ( $redirect_mode && $redirect_shop && $shop_page && empty( $wp_query->query_vars['s'] ) ) { $shop_url = get_permalink( $shop_page ); wp_safe_redirect( $shop_url, $redirect_mode ); exit(); } } if ( is_checkout() || ( function_exists( 'is_wc_endpoint_url' ) && is_wc_endpoint_url() ) ) { $wp_query->query_vars['do_not_redirect'] = 1; } } /** * Separate WooCommerce custom post types & taxonomies in "Permastructures" screen * * @param array $fields * * @return array */ public function woocommerce_permastructs_fields( $fields ) { if ( is_array( $fields ) ) { $woocommerce_fields = array( 'product' => 'post_types', 'product_tag' => 'taxonomies', 'product_cat' => 'taxonomies', 'product_brand' => 'taxonomies' ); $woocommerce_attributes = wc_get_attribute_taxonomies(); foreach ( $woocommerce_attributes as $woocommerce_attribute ) { $woocommerce_fields["pa_{$woocommerce_attribute->attribute_name}"] = 'taxonomies'; } foreach ( $woocommerce_fields as $field => $field_type ) { if ( empty( $fields[ $field_type ]["fields"][ $field ] ) ) { continue; } $fields["woocommerce"]["fields"][ $field ] = $fields[ $field_type ]["fields"][ $field ]; unset( $fields[ $field_type ]["fields"][ $field ] ); } } return $fields; } /** * Add "Coupons" to the list of excluded post types * * @param array $post_types * * @return array */ public function woocommerce_coupon_uris( $post_types ) { if ( is_array( $post_types ) ) { $post_types[] = 'shop_coupon'; } return $post_types; } /** * Generate a new custom permalink for duplicated product * * @param WC_Product $new_product The new product object. * @param WC_Product $old_product The product that was duplicated. */ function woocommerce_generate_permalinks_after_duplicate( $new_product, $old_product ) { if ( ! empty( $new_product ) ) { $product_id = $new_product->get_id(); // Ignore variations if ( $new_product->get_type() === 'variation' || Permalink_Manager_Helper_Functions::is_post_excluded( $product_id, true ) ) { return; } $custom_uri = Permalink_Manager_URI_Functions_Post::get_default_post_uri( $product_id, false, true ); Permalink_Manager_URI_Functions::save_single_uri( $product_id, $custom_uri, false, true ); } } /** * If the URI contains %pa_attribute_name% tag, replace it with the value of the attribute * * @param string $default_uri The default custom permalink that WordPress would use for the post. * @param string $slug The post slug. * @param WP_Post $post The post object. * @param string $post_name The post slug. * @param bool $native_uri true if the URI is a native URI, false if it's a custom URI * * @return string The default custom permalink */ function woocommerce_product_attributes( $default_uri, $slug, $post, $post_name, $native_uri ) { // Do not affect native URIs if ( $native_uri ) { return $default_uri; } // Use only for products if ( empty( $post->post_type ) || $post->post_type !== 'product' ) { return $default_uri; } preg_match_all( "/%pa_(.[^\%]+)%/", $default_uri, $custom_fields ); if ( ! empty( $custom_fields[1] ) ) { $product = wc_get_product( $post->ID ); foreach ( $custom_fields[1] as $i => $custom_field ) { $attribute_name = sanitize_title( $custom_field ); $attribute_value = $product->get_attribute( $attribute_name ); $default_uri = str_replace( $custom_fields[0][ $i ], Permalink_Manager_Helper_Functions::sanitize_title( $attribute_value ), $default_uri ); } } return $default_uri; } /** * Stop the plugin from generating the custom permalink for new WooCommerce product prematurely. * * @param WC_Data $data The product object. * @param WP_REST_Request $request The REST API request object. * @param bool $is_new_post Whether the product is newly created. */ function woocommerce_delay_product_custom_permalink( $data, $request, $is_new_post ) { add_filter( 'permalink_manager_pre_update_post_uri', '__return_null', 100 ); return $data; } /** * Sets a custom permalink for a WooCommerce product after it is inserted via the REST API. * * @param WC_Product $product The product object. * @param WP_REST_Request $request The REST API request object. * @param bool $is_new_post Whether the product is newly created. */ function woocommerce_set_custom_uri_after_rest_insert( $product, $request, $is_new_post ) { if ( $is_new_post && class_exists( 'Permalink_Manager_URI_Functions_Post' ) && method_exists( $product, 'get_id' ) ) { $product_id = $product->get_id(); remove_filter( 'permalink_manager_pre_update_post_uri', '__return_null', 100 ); $new_uri = Permalink_Manager_URI_Functions_Post::get_default_post_uri( $product_id ); Permalink_Manager_URI_Functions_Post::save_uri( $product_id, $new_uri, $is_new_post ); } } /** * Check the current request is a WooCommerce AJAX request. If it is, check the translated page's URL should be returned * * @param string $permalink The full URL of the post * @param WP_Post $post The post object * @param string $old_permalink The original URL of the post. * * @return string The permalink is being returned. */ function woocommerce_translate_ajax_fragments_urls( $permalink, $post, $old_permalink ) { // Use it only if the permalinks are different if ( $permalink == $old_permalink || $post->post_type !== 'page' ) { return $permalink; } // A. Native WooCommerce AJAX events if ( ! empty( $_REQUEST['wc-ajax'] ) ) { $action = sanitize_title( $_REQUEST['wc-ajax'] ); } // B. Shoptimizer theme else if ( ! empty( $_REQUEST['action'] ) ) { $action = sanitize_title( $_REQUEST['action'] ); } // Allowed action names $allowed_actions = array( 'shoptimizer_pdp_ajax_atc', 'get_refreshed_fragments' ); if ( ! empty( $action ) && in_array( $action, $allowed_actions ) ) { $translated_post_id = apply_filters( 'wpml_object_id', $post->ID, 'page' ); $permalink = ( $translated_post_id !== $post->ID ) ? get_permalink( $translated_post_id ) : $permalink; } return $permalink; } /** * 4FA. Add a new column to the WooCommerce CSV Import/Export tool * * @param array $columns The array of columns to be displayed. * * @return array The $columns array. */ function woocommerce_csv_custom_uri_column( $columns ) { if ( ! is_array( $columns ) ) { return $columns; } $label = __( 'Custom URI', 'permalink-manager' ); $key = 'custom_uri'; if ( current_filter() == 'woocommerce_csv_product_import_mapping_default_columns' ) { $columns[ $label ] = $key; } else { $columns[ $key ] = $label; } return $columns; } /** * 4FB. Return the custom permalink of the product if it exists, otherwise return the default URI * * @param string $value The value of the column. * @param WC_Product $product The product object. * @param mixed $column_id The column ID. * * @return string The custom permalink or default permalink */ function woocommerce_export_custom_uri_value( $value, $product, $column_id ) { if ( empty( $value ) && ! empty( $product ) ) { $product_id = $product->get_id(); // Get custom permalink or default permalink $value = Permalink_Manager_URI_Functions_Post::get_post_uri( $product_id ); } return $value; } /** * 4FC. Set the custom URI for the product using the value from CSV file, if not set use the default permalink * * @param WC_Product $product The product object. * @param array $data The data array for the current row being imported. */ function woocommerce_csv_import_custom_uri( $product, $data ) { if ( ! empty( $product ) ) { $product_id = $product->get_id(); // Ignore variations if ( $product->get_type() == 'variation' ) { return; } $current_uri = Permalink_Manager_URI_Functions::get_single_uri( $product_id, false, true ); // A. Use default permalink if "Custom URI" is not set and did not exist before if ( empty( $current_uri ) && empty( $data['custom_uri'] ) ) { $custom_uri = Permalink_Manager_URI_Functions_Post::get_default_post_uri( $product_id, false, true ); } else if ( ! empty( $data['custom_uri'] ) ) { $custom_uri = Permalink_Manager_Helper_Functions::sanitize_title( $data['custom_uri'] ); } else { return; } Permalink_Manager_URI_Functions::save_single_uri( $product_id, $custom_uri, false, true ); } } /** * Declare support for 'High-Performance order storage (COT)' and other features in WooCommerce */ function woocommerce_declare_compatibility() { $features_util_class = '\Automattic\WooCommerce\Utilities\FeaturesUtil'; if ( class_exists( $features_util_class ) && method_exists( $features_util_class, 'declare_compatibility' ) ) { $features = method_exists( $features_util_class, 'get_features' ) ? $features_util_class::get_features( true ) : array(); foreach ( array_keys( $features ) as $feature ) { $features_util_class::declare_compatibility( $feature, PERMALINK_MANAGER_BASENAME ); } } } /** * Extract the Wishlist ID from the URI and add it to the $uri_parts array (WooCommerce Wishlist Plugin) * * @param array $uri_parts An array of the URI parts. * @param string $request_url The URL that was requested. * @param array $endpoints An array of all the endpoints that are currently registered. * * @return array The URI parts. */ function ti_woocommerce_wishlist_uris( $uri_parts, $request_url, $endpoints ) { $wishlist_pid = function_exists( 'tinv_get_option' ) ? tinv_get_option( 'general', 'page_wishlist' ) : ''; // Find the Wishlist page URI if ( is_numeric( $wishlist_pid ) ) { $current_uri = Permalink_Manager_URI_Functions::get_single_uri( $wishlist_pid, false, true ); if ( ! empty( $current_uri ) ) { $wishlist_uri = preg_quote( $current_uri, '/' ); // Extract the Wishlist ID preg_match( "/^({$wishlist_uri})\/([^\/]+)\/?$/", $uri_parts['uri'], $output_array ); if ( ! empty( $output_array[2] ) ) { $uri_parts['uri'] = $output_array[1]; $uri_parts['endpoint'] = 'tinvwlID'; $uri_parts['endpoint_value'] = $output_array[2]; } } } return $uri_parts; } /** * Keep the query strings appended to the product permalinks by WooCommerce Subscriptions * * @param string $permalink * @param WP_Post $post * @param string $old_permalink * * @return string */ function wcs_fix_subscription_links( $permalink, $post, $old_permalink ) { if ( ! empty( $post->post_type ) && $post->post_type == 'product' && strpos( $old_permalink, 'switch-subscription=' ) !== false ) { $query_arg = parse_url( $old_permalink, PHP_URL_QUERY ); $permalink = "{$permalink}?{$query_arg}"; } return $permalink; } }