diff --git a/civicrm.php b/civicrm.php index efe3a9e01ef1fbea0b80e1457426faf84931e7ef..08eadf7ef1c2d14811bbee4bf93fe2d6cfc988c7 100644 --- a/civicrm.php +++ b/civicrm.php @@ -204,6 +204,15 @@ class CiviCRM_For_WordPress { */ public $users; + /** + * Compatibility object. + * + * @since 5.24 + * @access public + * @var object CiviCRM_For_WordPress_Compat The plugin compatibility object. + */ + public $compat; + // --------------------------------------------------------------------------- // Setup @@ -527,6 +536,10 @@ class CiviCRM_For_WordPress { include_once CIVICRM_PLUGIN_DIR . 'includes/civicrm.basepage.php'; $this->basepage = new CiviCRM_For_WordPress_Basepage; + // Include compatibility class + include_once CIVICRM_PLUGIN_DIR . 'includes/civicrm.compat.php'; + $this->compat = new CiviCRM_For_WordPress_Compat; + if ( ! class_exists( 'CiviCRM_WP_REST\Autoloader' ) ) { // Include REST API autoloader class require_once( CIVICRM_PLUGIN_DIR . 'wp-rest/Autoloader.php' ); @@ -813,10 +826,12 @@ class CiviCRM_For_WordPress { * Broadcast the rewrite rules event. * * @since 5.7 + * @since 5.24 Added $basepage parameter. * * @param bool $flush_rewrite_rules True if rules flushed, false otherwise. + * @param WP_Post $basepage The Basepage post object. */ - do_action( 'civicrm_after_rewrite_rules', $flush_rewrite_rules ); + do_action( 'civicrm_after_rewrite_rules', $flush_rewrite_rules, $basepage ); } diff --git a/includes/civicrm.compat.php b/includes/civicrm.compat.php new file mode 100644 index 0000000000000000000000000000000000000000..151761de7cf99bfed6fd64765342d41c44e4c8dc --- /dev/null +++ b/includes/civicrm.compat.php @@ -0,0 +1,154 @@ +<?php +/* + +--------------------------------------------------------------------+ + | Copyright CiviCRM LLC. All rights reserved. | + | | + | This work is published under the GNU AGPLv3 license with some | + | permitted exceptions and without any warranty. For full license | + | and copyright information, see https://civicrm.org/licensing | + +--------------------------------------------------------------------+ +*/ + +/** + * + * @package CRM + * @copyright CiviCRM LLC https://civicrm.org/licensing + * + */ + + +// This file must not accessed directly +if ( ! defined( 'ABSPATH' ) ) exit; + + +/** + * Define CiviCRM_For_WordPress_Compat Class. + * + * @since 5.24 + */ +class CiviCRM_For_WordPress_Compat { + + /** + * Plugin object reference. + * + * @since 5.24 + * @access public + * @var object $civi The plugin object reference. + */ + public $civi; + + + /** + * Instance constructor. + * + * @since 5.24 + */ + public function __construct() { + + // Store reference to CiviCRM plugin object. + $this->civi = civi_wp(); + + // Register plugin compatibility hooks. + $this->register_hooks(); + + } + + + /** + * Register plugin compatibility hooks. + * + * This is called via the constructor during the "plugins_loaded" action which + * is much earlier that CiviCRM's own internal hooks. The reason for this is + * that compability may need callbacks for events that fire well before "init" + * which is when CiviCRM begins to load. + * + * @since 5.24 + */ + public function register_hooks() { + + // Bail if CiviCRM not installed yet. + if ( ! CIVICRM_INSTALLED ) { + return; + } + + // Support Clean URLs when Polylang is active. + add_action( 'civicrm_after_rewrite_rules', array( $this, 'rewrite_rules_polylang' ), 10, 2 ); + + } + + + /** + * Support Polylang. + * + * @since 5.24 + * + * @param bool $flush_rewrite_rules True if rules flushed, false otherwise. + * @param WP_Post $basepage The Basepage post object. + */ + public function rewrite_rules_polylang( $flush_rewrite_rules, $basepage ) { + + // Bail if Polylang is not present. + if (!function_exists('pll_languages_list')) { + return; + } + + /* + * Collect all rewrite rules into an array. + * + * Because the array of specific Post IDs is added *after* the array of + * paths for the Basepage ID, those specific rewrite rules will "win" over + * the more general Basepage rules. + */ + $collected_rewrites = []; + + // Support prefixes for a single Basepage. + $basepage_url = get_permalink( $basepage->ID ); + $basepage_raw_url = PLL()->links_model->remove_language_from_link( $basepage_url ); + $language_slugs = pll_languages_list(); + foreach ($language_slugs as $slug) { + $language = PLL()->model->get_language( $slug ); + $language_url = PLL()->links_model->add_language_to_link( $basepage_raw_url, $language ); + $parsed_url = wp_parse_url( $language_url, PHP_URL_PATH ); + $regex_path = substr( $parsed_url, 1 ); + $collected_rewrites[$basepage->ID][] = $regex_path; + $post_id = pll_get_post( $basepage->ID, $slug ); + if (!empty($post_id)) { + $collected_rewrites[$post_id][] = $regex_path; + } + }; + + // Support prefixes for Basepages in multiple languages. + foreach ($language_slugs as $slug) { + $post_id = pll_get_post( $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 . '&page=CiviCRM&q=civicrm%2F$matches[1]', + 'top' + ); + } + } + } + + // Maybe force flush + if ($flush_rewrite_rules) { + flush_rewrite_rules(); + } + + } + +} // Class CiviCRM_For_WordPress_Compat ends