Files
hub-insurance/wp-content/plugins/permalink-manager-pro/includes/core/permalink-manager-pro-functions.php
T
2026-07-02 15:54:39 -06:00

486 lines
19 KiB
PHP

<?php
if ( ! defined( 'ABSPATH' ) ) exit;
/**
* Additional hooks for "Permalink Manager Pro"
*/
class Permalink_Manager_Pro_Functions {
public function __construct() {
// Stop words
add_filter( 'permalink_manager_filter_default_post_uri', array( $this, 'remove_stop_words' ), 9, 3 );
add_filter( 'permalink_manager_filter_default_term_uri', array( $this, 'remove_stop_words' ), 9, 3 );
// Custom fields in permalinks
add_filter( 'permalink_manager_filter_default_post_uri', array( $this, 'replace_custom_field_tags' ), 9, 5 );
add_filter( 'permalink_manager_filter_default_term_uri', array( $this, 'replace_custom_field_tags' ), 9, 5 );
// Save redirects
add_action( 'permalink_manager_updated_post_uri', array( $this, 'save_redirects' ), 9, 5 );
add_action( 'permalink_manager_updated_term_uri', array( $this, 'save_redirects' ), 9, 5 );
}
/**
* Get the list of languages where stop words are defined
*/
static function load_stop_words_languages() {
return array(
'ar' => __( 'Arabic', 'permalink-manager' ),
'zh' => __( 'Chinese', 'permalink-manager' ),
'da' => __( 'Danish', 'permalink-manager' ),
'nl' => __( 'Dutch', 'permalink-manager' ),
'en' => __( 'English', 'permalink-manager' ),
'fi' => __( 'Finnish', 'permalink-manager' ),
'fr' => __( 'French', 'permalink-manager' ),
'de' => __( 'German', 'permalink-manager' ),
'he' => __( 'Hebrew', 'permalink-manager' ),
'hi' => __( 'Hindi', 'permalink-manager' ),
'it' => __( 'Italian', 'permalink-manager' ),
'ja' => __( 'Japanese', 'permalink-manager' ),
'ko' => __( 'Korean', 'permalink-manager' ),
'no' => __( 'Norwegian', 'permalink-manager' ),
'fa' => __( 'Persian', 'permalink-manager' ),
'pl' => __( 'Polish', 'permalink-manager' ),
'pt' => __( 'Portuguese', 'permalink-manager' ),
'ru' => __( 'Russian', 'permalink-manager' ),
'es' => __( 'Spanish', 'permalink-manager' ),
'sv' => __( 'Swedish', 'permalink-manager' ),
'tr' => __( 'Turkish', 'permalink-manager' )
);
}
/**
* Load stop words for specific language (using ISO code)
*
* @param string $iso
*
* @return array
*/
static function load_stop_words( $iso = '' ) {
$json_dir = PERMALINK_MANAGER_DIR . "/includes/vendor/stopwords-json/dist/{$iso}.json";
$json_a = array();
if ( file_exists( $json_dir ) ) {
$string = file_get_contents( $json_dir );
$json_a = json_decode( $string, true );
}
return $json_a;
}
/**
* Remove the stop words from the default custom permalinks
*
* @param string $slug The slug that is being generated.
* @param stdClass $object The object that the slug is being generated for.
* @param string $name The name of the filter.
*
* @return string The slug.
*/
public function remove_stop_words( $slug, $object, $name ) {
global $permalink_manager_options;
if ( ! empty( $permalink_manager_options['stop-words']['stop-words-enable'] ) && ! empty( $permalink_manager_options['stop-words']['stop-words-list'] ) ) {
$stop_words = explode( ",", strtolower( stripslashes( $permalink_manager_options['stop-words']['stop-words-list'] ) ) );
foreach ( $stop_words as $stop_word ) {
$stop_word = trim( $stop_word );
$slug = preg_replace( "/([\/-]|^)({$stop_word})([\/-]|$)/", '$1$3', $slug );
}
// Clear the slug
$slug = preg_replace( "/(-+)/", "-", trim( $slug, "-" ) );
$slug = preg_replace( "/(-\/-)|(\/-)|(-\/)/", "/", $slug );
}
return $slug;
}
/**
* Replace custom field tags in the default custom permalinks
*
* @param string $default_uri
* @param string $native_slug
* @param WP_Post|WP_Term $element
* @param string $slug
* @param string $native_uri
*
* @return string
*/
function replace_custom_field_tags( $default_uri, $native_slug, $element, $slug, $native_uri ) {
// Do not affect native URIs
if ( $native_uri ) {
return $default_uri;
}
preg_match_all( "/%__(.[^\%]+)%/", $default_uri, $custom_fields );
if ( ! empty( $custom_fields[1] ) ) {
foreach ( $custom_fields[1] as $i => $custom_field ) {
// Reset custom field value
$custom_field_value = "";
// Check additional arguments (__custom_field.argument_value)
if ( strpos( $custom_field, '.' ) !== false ) {
$custom_field_split = preg_split( '/[\.]/', $custom_field );
if ( ! empty( $custom_field_split[1] ) ) {
$custom_field_arg = $custom_field_split[1];
$custom_field = $custom_field_split[0];
}
}
// 1. Use WooCommerce fields (SKU)
if ( class_exists( 'WooCommerce' ) && strtolower( $custom_field ) == 'sku' && ! empty( $element->ID ) ) {
$product = wc_get_product( $element->ID );
$custom_field_value = ( is_a( $product, 'WC_Product' ) ) ? $product->get_sku() : '';
} // 2. Try to get value using ACF API
else if ( function_exists( 'get_field_object' ) ) {
$acf_element_id = ( ! empty( $element->ID ) ) ? $element->ID : "{$element->taxonomy}_{$element->term_id}";
$field_object = get_field_object( $custom_field, $acf_element_id );
// A. Relationship field
if ( ! empty( $field_object['type'] ) && ( in_array( $field_object['type'], array( 'relationship', 'post_object', 'taxonomy' ) ) ) && ! empty( $field_object['value'] ) ) {
$rel_elements = $field_object['value'];
// B1. Terms
if ( $field_object['type'] == 'taxonomy' ) {
if ( ( is_array( $rel_elements ) ) ) {
if ( is_numeric( $rel_elements[0] ) && ! empty( $field_object['taxonomy'] ) ) {
$rel_elements = get_terms( array( 'include' => $rel_elements, 'taxonomy' => $field_object['taxonomy'], 'hide_empty' => false, 'orderby' => 'term_id', 'order' => 'DESC' ) );
}
// Get the lowest term
if ( ! is_wp_error( $rel_elements ) && ! empty( $rel_elements ) && is_object( $rel_elements[0] ) ) {
$rel_term = Permalink_Manager_Helper_Functions::get_lowest_element( $rel_elements[0], $rel_elements );
}
}
if ( ! empty( $rel_elements->term_id ) ) {
$rel_term = $rel_elements;
} else if ( ! empty( $rel_elements ) && is_numeric( $rel_elements ) ) {
$rel_term = get_term( $rel_elements, $field_object['taxonomy'] );
}
// Get the replacement slug
if ( ! empty( $rel_term->term_id ) ) {
if ( ! empty( $custom_field_arg ) && is_numeric( $custom_field_arg ) ) {
$custom_field_value = Permalink_Manager_Helper_Functions::force_custom_slugs( $rel_term->slug, $rel_term, false, $custom_field_arg );
} else if ( ! empty( $custom_field_arg ) && $custom_field_arg == 'id' ) {
$custom_field_value = $rel_term->term_id;
} else if ( ! empty( $custom_field_arg ) && $custom_field_arg == 'full_slug' ) {
$custom_field_value = Permalink_Manager_Helper_Functions::get_term_full_slug( $rel_term, $rel_elements );
} else if ( ! empty( $custom_field_arg ) && $custom_field_arg == 'custom_permalink' ) {
$custom_field_value = Permalink_Manager_URI_Functions::get_single_uri( $rel_term );
} else {
$custom_field_value = Permalink_Manager_Helper_Functions::force_custom_slugs( $rel_term->slug, $rel_term );
}
}
} // B2. Posts
else {
if ( ( is_array( $rel_elements ) ) ) {
if ( is_numeric( $rel_elements[0] ) ) {
$rel_elements = get_posts( array( 'include' => $rel_elements, 'post_type' => 'any', 'orderby' => 'post__in' ) );
}
// Get lowest element
if ( ! is_wp_error( $rel_elements ) && ! empty( $rel_elements ) && is_object( $rel_elements[0] ) ) {
$rel_post = Permalink_Manager_Helper_Functions::get_lowest_element( $rel_elements[0], $rel_elements );
}
} else if ( ! empty( $rel_elements->ID ) ) {
$rel_post = $rel_elements;
}
if ( ! empty( $rel_post->ID ) ) {
$rel_post_object = $rel_post;
} else if ( is_numeric( $rel_elements ) ) {
$rel_post_object = get_post( $rel_elements );
}
// Get the replacement slug
if ( ! empty( $rel_post_object->ID ) ) {
if ( ! empty( $custom_field_arg ) && is_numeric( $custom_field_arg ) ) {
$custom_field_value = Permalink_Manager_Helper_Functions::force_custom_slugs( $rel_post_object->post_name, $rel_post_object, false, $custom_field_arg );
} else if ( ! empty( $custom_field_arg ) && $custom_field_arg == 'id' ) {
$custom_field_value = $rel_post_object->ID;
} else if ( ! empty( $custom_field_arg ) && $custom_field_arg == 'full_slug' ) {
$custom_field_value = Permalink_Manager_Helper_Functions::get_post_full_slug( $rel_post_object );
} else if ( ! empty( $custom_field_arg ) && $custom_field_arg == 'custom_permalink' ) {
$custom_field_value = Permalink_Manager_URI_Functions::get_single_uri( $rel_post_object );
} else {
$custom_field_value = Permalink_Manager_Helper_Functions::force_custom_slugs( $rel_post_object->post_name, $rel_post_object );
}
}
}
} // C. Text field
else {
$custom_field_value = ( ! empty( $field_object['value'] ) ) ? $field_object['value'] : "";
$custom_field_value = ( ! empty( $custom_field_value['value'] ) ) ? $custom_field_value['value'] : $custom_field_value;
}
}
// 3. Use native method
if ( empty( $custom_field_value ) ) {
if ( ! empty( $element->ID ) ) {
$custom_field_value = get_post_meta( $element->ID, $custom_field, true );
// Toolset
if ( empty( $custom_field_value ) && ( defined( 'TYPES_VERSION' ) || defined( 'WPCF_VERSION' ) ) ) {
$custom_field_value = get_post_meta( $element->ID, "wpcf-{$custom_field}", true );
}
} else if ( ! empty( $element->term_id ) ) {
$custom_field_value = get_term_meta( $element->term_id, $custom_field, true );
} else {
$custom_field_value = "";
}
}
// Allow to filter the custom field value
$custom_field_value = apply_filters( 'permalink_manager_custom_field_value', $custom_field_value, $custom_field, $element );
// Make sure that custom field is a string
if ( ! empty( $custom_field_value ) && is_string( $custom_field_value ) ) {
// Do not sanitize the custom field if 'no-sanitize' argument is added (e.g. %__custom-field-name.no-sanitize%)
if ( empty( $custom_field_arg ) || strpos( $custom_field_arg, 'no-sanitize' ) === false ) {
$custom_field_value = Permalink_Manager_Helper_Functions::sanitize_title( $custom_field_value );
}
$default_uri = str_replace( $custom_fields[0][ $i ], $custom_field_value, $default_uri );
}
}
}
return $default_uri;
}
/**
* Save the custom, external redirects for specific post or term
*
* @param int|string $element_id The ID of the post (e.g. 123) or term (tax-456).
* @param string $new_uri The new custom permalink
* @param string $old_uri The previous custom permalink
* @param string $native_uri The native permalink
* @param string $default_uri The default custom permalink
*/
public function save_redirects( $element_id, $new_uri, $old_uri, $native_uri = '', $default_uri = '' ) {
global $permalink_manager_options, $permalink_manager_redirects;
// Do not trigger if "Extra redirects" option is turned off
if ( empty( $permalink_manager_options['general']['redirect'] ) || empty( $permalink_manager_options['general']['extra_redirects'] ) ) {
return;
}
// Terms IDs should be prepended with prefix
$element_id = ( current_filter() == 'permalink_manager_updated_term_uri' ) ? "tax-{$element_id}" : $element_id;
// Make sure that $permalink_manager_redirects variable is an array
$permalink_manager_redirects = ( is_array( $permalink_manager_redirects ) ) ? $permalink_manager_redirects : array();
// 1A. Post/term is saved or updated
if ( isset( $_POST['permalink-manager-redirects'] ) && is_array( $_POST['permalink-manager-redirects'] ) ) {
$permalink_manager_redirects[ $element_id ] = array_filter( $_POST['permalink-manager-redirects'] );
$redirects_updated = true;
} // 1B. All redirects are removed
else if ( isset( $_POST['permalink-manager-redirects'] ) ) {
$permalink_manager_redirects[ $element_id ] = array();
$redirects_updated = true;
}
// 1C. No longer needed
if ( isset( $_POST['permalink-manager-redirects'] ) ) {
unset( $_POST['permalink-manager-redirects'] );
}
// 2. Custom URI is updated
if ( get_option( 'page_on_front' ) !== $element_id && ! empty( $permalink_manager_options['general']['setup_redirects'] ) && ( $new_uri !== $old_uri ) ) {
// Make sure that the array with redirects exists
$permalink_manager_redirects[ $element_id ] = ( ! empty( $permalink_manager_redirects[ $element_id ] ) ) ? $permalink_manager_redirects[ $element_id ] : array();
// Append the old custom URI
$permalink_manager_redirects[ $element_id ][] = $old_uri;
$redirects_updated = true;
}
// 3. Save the custom redirects
if ( ! empty( $redirects_updated ) && is_array( $permalink_manager_redirects[ $element_id ] ) ) {
// Remove empty redirects
$permalink_manager_redirects[ $element_id ] = array_filter( $permalink_manager_redirects[ $element_id ] );
// Sanitize the array with redirects
foreach ( $permalink_manager_redirects[ $element_id ] as $i => $redirect ) {
$redirect = rawurldecode( $redirect );
$redirect = Permalink_Manager_Helper_Functions::sanitize_title( $redirect, true );
$permalink_manager_redirects[ $element_id ][ $i ] = $redirect;
}
// Reset the keys
$permalink_manager_redirects[ $element_id ] = array_values( $permalink_manager_redirects[ $element_id ] );
// Remove the duplicates
$permalink_manager_redirects[ $element_id ] = array_unique( $permalink_manager_redirects[ $element_id ] );
Permalink_Manager_Actions::clear_single_element_duplicated_redirect( $element_id, false, $new_uri );
// Remove empty subarray
$permalink_manager_redirects = array_filter( $permalink_manager_redirects );
update_option( 'permalink-manager-redirects', $permalink_manager_redirects );
}
// 4. Save the external redirect
if ( isset( $_POST['permalink-manager-external-redirect'] ) ) {
self::save_external_redirect( $_POST['permalink-manager-external-redirect'], $element_id );
}
}
/**
* Save external redirect
*
* @param string $url The full URL saved as external redirect
* @param string|int $element_id The ID of the post (e.g. 123) or term (tax-456).
*/
public static function save_external_redirect( $url, $element_id ) {
global $permalink_manager_external_redirects;
$url = filter_var( $url, FILTER_SANITIZE_URL );
if ( ( empty( $url ) || filter_var( $url, FILTER_VALIDATE_URL ) === false ) && ! empty( $permalink_manager_external_redirects[ $element_id ] ) && isset( $_POST['permalink-manager-external-redirect'] ) ) {
unset( $permalink_manager_external_redirects[ $element_id ] );
} else {
$permalink_manager_external_redirects[ $element_id ] = esc_url( $url );
}
update_option( 'permalink-manager-external-redirects', $permalink_manager_external_redirects );
}
/**
* Add a new tab to the WooCommerce coupon edit page
*
* @param array $tabs The tabs array.
*
* @return array The tabs array with the new tab added.
*/
public static function woocommerce_coupon_tabs( $tabs = array() ) {
$tabs['coupon-url'] = array(
'label' => __( 'Coupon Link', 'permalink-manager' ),
'target' => 'permalink-manager-coupon-url',
'class' => 'permalink-manager-coupon-url',
);
return $tabs;
}
/**
* Add a new panel to the WooCommerce coupon edit page
*/
public static function woocommerce_coupon_panel() {
global $permalink_manager_uris, $post;
$custom_uri = ( ! empty( $permalink_manager_uris[ $post->ID ] ) ) ? $permalink_manager_uris[ $post->ID ] : "";
$html = "<div id=\"permalink-manager-coupon-url\" class=\"panel woocommerce_options_panel custom_uri_container permalink-manager\">";
// URI field
ob_start();
wp_nonce_field( 'permalink-manager-coupon-uri-box', 'permalink-manager-nonce' );
woocommerce_wp_text_input( array(
'id' => 'custom_uri',
'label' => __( 'Coupon URI', 'permalink-manager' ),
'description' => '<span class="duplicated_uri_alert"></span>' . __( 'The URIs are case-insensitive, e.g. <strong>BLACKFRIDAY</strong> and <strong>blackfriday</strong> are equivalent.', 'permalink-manager' ),
'value' => $custom_uri,
'custom_attributes' => array( 'data-element-id' => $post->ID ),
//'desc_tip' => true
) );
$html .= ob_get_contents();
ob_end_clean();
// URI preview
$html .= "<p class=\"form-field coupon-full-url hidden\">";
$html .= sprintf( "<label>%s</label>", __( "Coupon Full URL", "permalink-manager" ) );
$html .= sprintf( "<code>%s/<span>%s</span></code>", trim( get_option( 'home' ), "/" ), $custom_uri );
$html .= "</p>";
$html .= "</div>";
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $html;
}
/**
* Save the custom permalink for specific coupon
*
* @param int $post_id
* @param WC_Coupon $coupon
*/
public static function woocommerce_save_coupon_uri( $post_id, $coupon ) {
// Verify nonce at first
if ( ! isset( $_POST['permalink-manager-nonce'] ) || ! wp_verify_nonce( $_POST['permalink-manager-nonce'], 'permalink-manager-coupon-uri-box' ) ) {
return;
}
// Do not do anything if post is auto-saved
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
$old_uri = Permalink_Manager_URI_Functions::get_single_uri( $post_id, false, true, false );
$new_uri = ( ! empty( $_POST['custom_uri'] ) ) ? $_POST['custom_uri'] : "";
if ( $old_uri !== $new_uri ) {
Permalink_Manager_URI_Functions::save_single_uri( $post_id, $new_uri, false, true );
}
}
/**
* Check the URL contains a coupon code, and if it does, it adds the coupon code to the cart and redirects to the cart page
*
* @param array $query The query array.
*
* @return array The query array.
*/
public static function woocommerce_detect_coupon_code( $query ) {
global $woocommerce, $pm_query;
// Check if custom URI with coupon URL is requested
if ( ! empty( $query['shop_coupon'] ) && ! empty( $pm_query['id'] ) ) {
// Check if cart/shop page is set & redirect to it
$shop_page_id = wc_get_page_id( 'shop' );
$cart_page_id = wc_get_page_id( 'cart' );
if ( ! empty( $cart_page_id ) && WC()->cart->get_cart_contents_count() > 0 ) {
$redirect_page = $cart_page_id;
} else if ( ! empty( $shop_page_id ) ) {
$redirect_page = $shop_page_id;
}
$coupon_code = get_the_title( $pm_query['id'] );
// Set-up session
if ( ! WC()->session->has_session() ) {
WC()->session->set_customer_session_cookie( true );
}
// Add the discount code
if ( ! WC()->cart->has_discount( $coupon_code ) ) {
$woocommerce->cart->add_discount( sanitize_text_field( $coupon_code ) );
}
// Do redirect
if ( ! empty( $redirect_page ) ) {
wp_safe_redirect( get_permalink( $redirect_page ) );
exit();
}
}
return $query;
}
}