Skip to content

Commit

Permalink
Add WPML integration for proper CiviCRM language generation civicrm#133
Browse files Browse the repository at this point in the history
  • Loading branch information
shaneonabike committed Feb 13, 2023
1 parent 18e6317 commit b2daa62
Showing 1 changed file with 177 additions and 0 deletions.
177 changes: 177 additions & 0 deletions includes/civicrm.compat.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ public function register_hooks() {
// Support Clean URLs when Polylang is active.
add_action('civicrm_after_rewrite_rules', [$this, 'rewrite_rules_polylang'], 10, 2);

// Support Clean URLs when WPML is active.
add_action('civicrm_after_rewrite_rules', [$this, 'rewrite_rules_wpml'], 10, 2);
add_filter('icl_ls_languages', [$this, 'rewrite_civicrm_urls_wpml']);

// Prevent AIOSEO from stomping on CiviCRM Shortcodes.
add_filter('aioseo_conflicting_shortcodes', [$this, 'aioseo_resolve_conflict']);

Expand Down Expand Up @@ -150,6 +154,179 @@ public function rewrite_rules_polylang($flush_rewrite_rules, $basepage) {

}

/**
* Support WPML.
*
* @since 5.55.0
*
* @param bool $flush_rewrite_rules True if rules flushed, false otherwise.
* @param WP_Post $basepage The Base Page post object.
*/
public function rewrite_rules_wpml($flush_rewrite_rules, $basepage) {

// Bail if WPML is not present.
if (!defined('ICL_SITEPRESS_VERSION')) {
return;
}

/*
* Collect all rewrite rules into an array.
*
* Because the array of specific Post IDs is added *after* the array of
* paths for the Base Page ID, those specific rewrite rules will "win" over
* the more general Base Page rules.
*/
global $sitepress;
$collected_rewrites = [];

// Grab information about configuration
$wpml_active = apply_filters('wpml_active_languages', NULL);

// Obtain lagnuage negotiation setting
$wpml_negotiation = apply_filters('wpml_setting', NULL, 'language_negotiation_type');

// Support prefixes for a single Base Page.
$basepage_url = get_permalink($basepage->ID);

$basepage_raw_url = $this->wpml_remove_language_from_url($basepage_url, $sitepress, $wpml_negotiation);
foreach ($wpml_active as $slug => $data) {
$language_url = $sitepress->convert_url($basepage_raw_url, $slug);
$parsed_url = wp_parse_url($language_url, PHP_URL_PATH);
$regex_path = substr($parsed_url, 1);
$collected_rewrites[$basepage->ID][] = $regex_path;
$post_id = apply_filters('wpml_object_id', $basepage->ID, $slug);
if (!empty($post_id)) {
continue;
}

$url = get_permalink($post_id);
$parsed_url = wp_parse_url($url, PHP_URL_PATH);
$regex_path = substr($parsed_url, 1);
$collected_rewrites[$basepage->ID][] = $regex_path;
$collected_rewrites[$post_id][] = $regex_path;
};

// Make collection unique and add remaining rewrite rules.
$rewrites = array_map('array_unique', $collected_rewrites);
if (!empty($rewrites)) {
foreach ($rewrites as $post_id => $rewrite) {
foreach ($rewrite as $path) {
add_rewrite_rule(
'^' . $path . '([^?]*)?',
'index.php?page_id=' . $post_id . '&civiwp=CiviCRM&q=civicrm%2F$matches[1]',
'top'
);
}
}
}

// Maybe force flush.
if ($flush_rewrite_rules) {
flush_rewrite_rules();
}
}

/**
* icl_ls_languages WPML Filter
*
* Modify all CiviCRM URLs to contain the proper language structure based on the WPML settings
*
* @param array $languages passed by WPML to modify current path
*/
public function rewrite_civicrm_urls_wpml($languages) {

// Get the post slug
global $post;
$post_slug = isset($post->post_name) ? $post->post_name : '';
if (empty($post_slug) && isset($post->post_name)) {
$post_slug = $post->post_name;
}

// Get CiviCRM basepage slug
$civicrm_slug = apply_filters('civicrm_basepage_slug', 'civicrm');

// If this is a CiviCRM Page then let's modify the actual path
if ($post_slug == $civicrm_slug) {
global $sitepress;
$current_url = explode("?", $_SERVER['REQUEST_URI']);
$civicrm_url = get_site_url(NULL, $current_url[0]);

// Remove lang from path
$wpml_negotiation = apply_filters('wpml_setting', NULL, 'language_negotiation_type');
$civicrm_url = $this->wpml_remove_language_from_url($civicrm_url, $sitepress, $wpml_negotiation);

// Build query string
$qs = [];
parse_str($_SERVER["QUERY_STRING"], $qs);

// Strip any WPML languages if they exist
unset($qs['lang']);
$query = http_build_query($qs);

// Rebuild CiviCRM links for each language
foreach ($languages as &$language) {
$url = apply_filters('wpml_permalink', $civicrm_url, $language['language_code']);

if (!empty($query)) {
if ($wpml_lang_conf == 3 && strpos($url, '?') !== FALSE) {
$language['url'] = $url . '&' . $query;
}
else {
$language['url'] = $url . '?' . $query;
}
}
}
}

return $languages;
}

/**
* Remove Language from URL based on WPML configuration
*
* @param $url passed URL to strip language from
* @param object $sitepress WPML class
* @param int $wpml_lang_config language negotiation setting in WPML
*
* @return $url base page url without language
*/
private function wpml_remove_language_from_url($url, $sitepress, $wpml_lang_config) {
$lang = $this->wpml_get_language_param_for_convert_url($sitepress);
if ($lang) {
if ($wpml_lang_config == 1) {
$url = str_replace('/' . $lang . '/', '/', $url);
}
elseif ($wpml_lang_config == 3) {
$url = str_replace('lang=' . $lang, '', $url);
}
}

return $url;
}

/**
* Get Language for WPML.
* This code was taken from the WPML source, because it couldn't be referenced directly
*
* @param object $sitepress reference to WPML class
*/
private function wpml_get_language_param_for_convert_url($sitepress) {
if (!empty($sitepress)) {
if (isset($_GET['lang'])) {
return filter_var($_GET['lang'], FILTER_SANITIZE_STRING);
}

if (is_multisite() && isset($_POST['lang'])) {
return filter_var($_POST['lang'], FILTER_SANITIZE_STRING);
}

if (is_multisite() && defined('SUBDOMAIN_INSTALL') && SUBDOMAIN_INSTALL) {
return $sitepress->get_current_language();
}
}
return NULL;
}

/**
* Fixes AIOSEO's attempt to modify Shortcodes.
*
Expand Down

0 comments on commit b2daa62

Please sign in to comment.