Skip to content
Snippets Groups Projects
civicrm.php 57.8 KiB
Newer Older
  • Learn to ignore specific revisions
  • Kevin Cristiano's avatar
    Kevin Cristiano committed
         */
        $civicrm_query_vars = apply_filters( 'civicrm_query_vars', $civicrm_query_vars );
    
        // Now add them to WordPress
        foreach( $civicrm_query_vars as $civicrm_query_var ) {
          $query_vars[] = $civicrm_query_var;
        }
    
        return $query_vars;
    
      }
    
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
      /**
       * Filters the request right after WP's
       * parsed it and replaces the 'page' query
       * variable with 'civiwp' if applicable.
       *
       * Prevents old URLs like example.org/civicrm/?page=CiviCRM&q=what/ever/path&reset=1
       * being redirected to example.org/civicrm/?civiwp=CiviCRM&q=what/ever/path&reset=1
       *
       * @see https://lab.civicrm.org/dev/wordpress/-/issues/49
       *
       * @since 5.26
       *
       * @param array $query_vars The existing query vars.
       * @return array $query_vars The modified query vars.
       */
      public function maybe_replace_page_query_var( $query_vars ) {
    
        $civi_query_arg = array_search( 'CiviCRM', $query_vars );
    
        // Bail if the query var is not 'page'.
        if ( false === $civi_query_arg || $civi_query_arg !== 'page' ) return $query_vars;
    
        unset( $query_vars['page'] );
        $query_vars['civiwp'] = 'CiviCRM';
    
        return $query_vars;
    
      }
    
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
      // ---------------------------------------------------------------------------
      // CiviCRM Initialisation
      // ---------------------------------------------------------------------------
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
      /**
       * Check that the PHP version is supported. If not, raise a fatal error with a pointed message.
       *
       * One should check this before bootstrapping Civi - after we start the class-loader, the
       * PHP-compatibility errors will become more ugly.
       */
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
      protected function assertPhpSupport() {
        if ( version_compare( PHP_VERSION, CIVICRM_WP_PHP_MINIMUM ) < 0 ) {
          echo '<p>' .
             sprintf(
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
              __( 'CiviCRM requires PHP version %1$s or greater. You are running PHP version %2$s', 'civicrm' ),
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
              CIVICRM_WP_PHP_MINIMUM,
              PHP_VERSION
             ) .
             '<p>';
          exit();
        }
      }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
      /**
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Initialize CiviCRM.
       *
       * @since 4.4
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @return bool $success True if CiviCRM is initialized, false otherwise.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function initialize() {
    
        static $initialized = FALSE;
        static $failure = FALSE;
    
        if ( $failure ) {
          return FALSE;
        }
    
        if ( ! $initialized ) {
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $this->assertPhpSupport();
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // Check for settings
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if ( ! CIVICRM_INSTALLED ) {
            $error = FALSE;
          } elseif ( file_exists( CIVICRM_SETTINGS_PATH) ) {
            $error = include_once ( CIVICRM_SETTINGS_PATH );
          }
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // Autoload
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          require_once 'CRM/Core/ClassLoader.php';
          CRM_Core_ClassLoader::singleton()->register();
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // Get ready for problems
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $installLink    = admin_url() . "options-general.php?page=civicrm-install";
    
          $docLinkInstall = "https://wiki.civicrm.org/confluence/display/CRMDOC/Installing+CiviCRM+for+WordPress";
          $docLinkTrouble = "https://wiki.civicrm.org/confluence/display/CRMDOC/Installation+and+Upgrades";
          $forumLink      = "https://civicrm.stackexchange.com/";
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // Construct message
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $errorMsgAdd = sprintf(
            __( 'Please review the <a href="%s">WordPress Installation Guide</a> and the <a href="%s">Trouble-shooting page</a> for assistance. If you still need help installing, you can often find solutions to your issue by searching for the error message in the <a href="%s">installation support section of the community forum</a>.', 'civicrm' ),
            $docLinkInstall,
            $docLinkTrouble,
            $forumLink
          );
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // Does install message get used?
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $installMessage = sprintf(
            __( 'Click <a href="%s">here</a> for fresh install.', 'civicrm' ),
            $installLink
          );
    
          if ($error == FALSE) {
            header( 'Location: ' . admin_url() . 'options-general.php?page=civicrm-install' );
            return FALSE;
          }
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // Access global defined in civicrm.settings.php
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          global $civicrm_root;
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // This does pretty much all of the civicrm initialization
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if ( ! file_exists( $civicrm_root . 'CRM/Core/Config.php' ) ) {
            $error = FALSE;
          } else {
            $error = include_once ( 'CRM/Core/Config.php' );
          }
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // Have we got it?
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if ( $error == FALSE ) {
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
            // Set static flag
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
            $failure = TRUE;
    
            // FIX ME - why?
            wp_die(
              "<strong><p class='error'>" .
              sprintf(
                __( 'Oops! - The path for including CiviCRM code files is not set properly. Most likely there is an error in the <em>civicrm_root</em> setting in your CiviCRM settings file (%s).', 'civicrm' ),
                CIVICRM_SETTINGS_PATH
              ) .
              "</p><p class='error'> &raquo; " .
              sprintf(
                __( 'civicrm_root is currently set to: <em>%s</em>.', 'civicrm' ),
                $civicrm_root
              ) .
              "</p><p class='error'>" . $errorMsgAdd . "</p></strong>"
            );
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
            // Won't reach here!
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
            return FALSE;
    
          }
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // Set static flag
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $initialized = TRUE;
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // Initialize the system by creating a config object
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $config = CRM_Core_Config::singleton();
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // Sync the logged in user with WP
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          global $current_user;
          if ( $current_user ) {
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
            // Sync procedure sets session values for logged in users
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
            require_once 'CRM/Core/BAO/UFMatch.php';
            CRM_Core_BAO_UFMatch::synchronize(
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
              $current_user, // User object
              FALSE, // Do not update
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
              'WordPress', // CMS
              $this->users->get_civicrm_contact_type('Individual')
            );
    
          }
    
        }
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        /**
         * Broadcast that CiviCRM is now initialized.
         *
         * @since 4.4
         */
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        do_action( 'civicrm_initialized' );
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Success!
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        return TRUE;
    
      }
    
    
      // ---------------------------------------------------------------------------
      // Plugin setup
      // ---------------------------------------------------------------------------
    
    
      /**
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Load translation files.
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * A good reference on how to implement translation in WordPress:
       * http://ottopress.com/2012/internationalization-youre-probably-doing-it-wrong/
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @since 4.4
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function enable_translation() {
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Load translations
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        load_plugin_textdomain(
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          'civicrm', // Unique name
          FALSE, // Deprecated argument
          dirname( plugin_basename( __FILE__ ) ) . '/languages/' // Relative path to translation files
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Adds menu items to WordPress admin menu.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Callback method for 'admin_menu' hook as set in register_hooks().
       *
       * @since 4.4
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function add_menu_items() {
    
    
        $civilogo = file_get_contents( plugin_dir_path( __FILE__ ) . 'assets/civilogo.svg.b64' );
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        /**
         * Filter the position of the CiviCRM menu item.
         *
         * Currently set to 3.9 + some random digits to reduce risk of conflict.
         *
         * @since 4.4
         *
         * @param float The default menu position.
         * @return float The modified menu position..
         */
        $position = apply_filters( 'civicrm_menu_item_position', '3.904981' );
    
        // Check for settings file
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        if ( CIVICRM_INSTALLED ) {
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // Add top level menu item
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $menu_page = add_menu_page(
            __( 'CiviCRM', 'civicrm' ),
            __( 'CiviCRM', 'civicrm' ),
            'access_civicrm',
            'CiviCRM',
            array( $this, 'invoke' ),
            $civilogo,
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
            $position
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // Add core resources prior to page load
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          add_action( 'load-' . $menu_page, array( $this, 'admin_page_load' ) );
    
        } else {
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // Add top level menu item
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $menu_page = add_menu_page(
            __( 'CiviCRM Installer', 'civicrm' ),
            __( 'CiviCRM Installer', 'civicrm' ),
            'manage_options',
            'civicrm-install',
            array( $this, 'run_installer' ),
            $civilogo,
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
            $position
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // Add scripts and styles like this
          add_action( 'admin_print_scripts-' . $menu_page, array( $this, 'admin_installer_js' ) );
          add_action( 'admin_print_styles-' . $menu_page, array( $this, 'admin_installer_css' ) );
          add_action( 'admin_head-' . $menu_page, array( $this, 'admin_installer_head' ), 50 );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          */
    
        }
    
      }
    
    
      // ---------------------------------------------------------------------------
      // Installation
      // ---------------------------------------------------------------------------
    
    
      /**
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Callback method for add_options_page() that runs the CiviCRM installer.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @since 4.4
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function run_installer() {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $this->assertPhpSupport();
    
        $civicrmCore = CIVICRM_PLUGIN_DIR . 'civicrm';
    
        $setupPaths = array(
          implode(DIRECTORY_SEPARATOR, ['vendor', 'civicrm', 'civicrm-setup']),
          implode(DIRECTORY_SEPARATOR, ['packages', 'civicrm-setup',]),
          implode(DIRECTORY_SEPARATOR, ['setup']),
        );
        foreach ($setupPaths as $setupPath) {
          $loader = implode(DIRECTORY_SEPARATOR, [$civicrmCore, $setupPath, 'civicrm-setup-autoload.php']);
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if (file_exists($loader)) {
    
            require_once $loader;
            require_once implode(DIRECTORY_SEPARATOR, [$civicrmCore, 'CRM', 'Core', 'ClassLoader.php']);
            CRM_Core_ClassLoader::singleton()->register();
            \Civi\Setup::assertProtocolCompatibility(1.0);
            \Civi\Setup::init([
              'cms' => 'WordPress',
              'srcPath' => $civicrmCore,
            ]);
            $ctrl = \Civi\Setup::instance()->createController()->getCtrl();
            $ctrl->setUrls(array(
              'ctrl' => admin_url() . "options-general.php?page=civicrm-install",
              'res' => CIVICRM_PLUGIN_URL . 'civicrm/' . strtr($setupPath, DIRECTORY_SEPARATOR, '/') . '/res/',
              'jquery.js' => CIVICRM_PLUGIN_URL . 'civicrm/bower_components/jquery/dist/jquery.min.js',
              'font-awesome.css' => CIVICRM_PLUGIN_URL . 'civicrm/bower_components/font-awesome/css/font-awesome.min.css',
              'finished' => admin_url('admin.php?page=CiviCRM&q=civicrm&reset=1'),
            ));
            \Civi\Setup\BasicRunner::run($ctrl);
            return;
          }
        }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        wp_die( __( 'Installer unavailable. Failed to locate CiviCRM libraries.', 'civicrm' ) );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Callback method for missing settings file in register_hooks().
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @since 4.4
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function show_setup_warning() {
    
        $installLink = admin_url() . "options-general.php?page=civicrm-install";
        echo '<div id="civicrm-warning" class="updated fade">' .
           '<p><strong>' .
           __( 'CiviCRM is almost ready.', 'civicrm' ) .
           '</strong> ' .
           sprintf(
            __( 'You must <a href="%s">configure CiviCRM</a> for it to work.', 'civicrm' ),
            $installLink
           ) .
           '</p></div>';
    
      }
    
    
      // ---------------------------------------------------------------------------
      // HTML head
      // ---------------------------------------------------------------------------
    
    
      /**
       * Perform necessary stuff prior to CiviCRM's admin page being loaded
       * This needs to be a method because it can then be hooked into WP at the
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * right time.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @since 4.6
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function admin_page_load() {
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // This is required for AJAX calls in WordPress admin
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $_REQUEST['noheader'] = $_GET['noheader'] = TRUE;
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
        // Add resources for back end
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $this->add_core_resources( FALSE );
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Check setting for path to wp-load.php
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $this->add_wpload_setting();
    
      }
    
    
      /**
       * When CiviCRM is loaded in WP Admin, check for the existence of a setting
       * which holds the path to wp-load.php. This is the only reliable way to
       * bootstrap WordPress from CiviCRM.
       *
       * CMW: I'm not entirely happy with this approach, because the value will be
       * different for different installs (e.g. when a dev site is migrated to live)
       * A better approach would be to store this setting in civicrm.settings.php as
       * a constant, but doing that involves a complicated process of getting a new
       * setting registered in the installer.
       *
       * Also, it needs to be decided whether this value should be tied to a CiviCRM
       * 'domain', since a single CiviCRM install could potentially be used by a
       * number of WordPress installs. This is not relevant to its use in WordPress
       * Multisite, because the path to wp-load.php is common to all sites on the
       * network.
       *
       * My final concern is that the value will only be set *after* someone visits
       * CiviCRM in the back end. I have restricted it to this so as not to add
       * overhead to the front end, but there remains the possibility that the value
       * could be missing. To repeat: this would be better in civicrm.settings.php.
       *
       * To get the path to wp-load.php, use:
       * $path = CRM_Core_BAO_Setting::getItem('CiviCRM Preferences', 'wpLoadPhp');
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @since 4.6.3
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function add_wpload_setting() {
    
        if (!$this->initialize()) {
          return;
        }
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Get path to wp-load.php
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $path = ABSPATH . 'wp-load.php';
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Get the setting, if it exists
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $setting = CRM_Core_BAO_Setting::getItem('CiviCRM Preferences', 'wpLoadPhp');
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // If we don't have one, create it
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        if ( is_null( $setting ) ) {
          CRM_Core_BAO_Setting::setItem($path, 'CiviCRM Preferences', 'wpLoadPhp');
        }
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Is it different to the one we've stored?
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        if ( $setting !== $path ) {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // Yes - set new path (this could be because we've changed server or location)
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          CRM_Core_BAO_Setting::setItem($path, 'CiviCRM Preferences', 'wpLoadPhp');
        }
    
      }
    
    
      /**
       * Perform necessary stuff prior to CiviCRM being loaded on the front end
       * This needs to be a method because it can then be hooked into WP at the
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * right time.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @since 4.6
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function front_end_page_load() {
    
        static $frontend_loaded = FALSE;
        if ( $frontend_loaded ) {
          return;
        }
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Add resources for front end
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $this->add_core_resources( TRUE );
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Merge CiviCRM's HTML header with the WordPress theme's header
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        add_action( 'wp_head', array( $this, 'wp_head' ) );
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Set flag so this only happens once
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $frontend_loaded = TRUE;
    
      }
    
    
      /**
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Load only the CiviCRM CSS.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * This is needed because $this->front_end_page_load() is only called when
       * there is a single CiviCRM entity present on a page or archive and, whilst
       * we don't want all the Javascript to load, we do want stylesheets.
       *
       * @since 4.6
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function front_end_css_load() {
    
        static $frontend_css_loaded = FALSE;
        if ( $frontend_css_loaded ) {
          return;
        }
    
        if (!$this->initialize()) {
          return;
        }
    
        $config = CRM_Core_Config::singleton();
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Default custom CSS to standalone
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $dependent = NULL;
    
        // Load core CSS
        if (!CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'disable_core_css')) {
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // Enqueue stylesheet
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          wp_enqueue_style(
            'civicrm_css',
            $config->resourceBase . 'css/civicrm.css',
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
            NULL, // Dependencies
            CIVICRM_PLUGIN_VERSION, // Version
            'all' // Media
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // Custom CSS is dependent
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $dependent = array( 'civicrm_css' );
    
        }
    
        // Load custom CSS
        if (!empty($config->customCSSURL)) {
          wp_enqueue_style(
            'civicrm_custom_css',
            $config->customCSSURL,
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
            $dependent, // Dependencies
            CIVICRM_PLUGIN_VERSION, // Version
            'all' // Media
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Set flag so this only happens once
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $frontend_css_loaded = TRUE;
    
      }
    
    
      /**
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Add CiviCRM core resources.
       *
       * @since 4.6
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @param bool $front_end True if on WP front end, false otherwise.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function add_core_resources( $front_end = TRUE ) {
    
        if (!$this->initialize()) {
          return;
        }
    
        $config = CRM_Core_Config::singleton();
        $config->userFrameworkFrontend = $front_end;
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Add CiviCRM core resources
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        CRM_Core_Resources::singleton()->addCoreResources();
    
      }
    
    
      /**
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Merge CiviCRM's HTML header with the WordPress theme's header.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Callback from WordPress 'admin_head' and 'wp_head' hooks.
       *
       * @since 4.4
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function wp_head() {
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // CRM-11823 - If CiviCRM bootstrapped, then merge its HTML header with the CMS's header
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        global $civicrm_root;
        if ( empty( $civicrm_root ) ) {
          return;
        }
    
        $region = CRM_Core_Region::instance('html-header', FALSE);
        if ( $region ) {
          echo '<!-- CiviCRM html header -->';
          echo $region->render( '' );
        }
    
      }
    
    
      // ---------------------------------------------------------------------------
      // CiviCRM Invocation (this outputs Civi's markup)
      // ---------------------------------------------------------------------------
    
    
      /**
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Invoke CiviCRM in a WordPress context.
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Callback function from add_menu_page()
       * Callback from WordPress 'init' and 'the_content' hooks
       * Also called by shortcode_render() and _civicrm_update_user()
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @since 4.4
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function invoke() {
    
        static $alreadyInvoked = FALSE;
        if ( $alreadyInvoked ) {
          return;
        }
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Bail if this is called via a content-preprocessing plugin
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        if ( $this->is_page_request() && !in_the_loop() && !is_admin() ) {
          return;
        }
    
        if (!$this->initialize()) {
          return;
        }
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        /*
         * CRM-12523
         * WordPress has it's own timezone calculations
         * CiviCRM relies on the php default timezone which WP
         * overrides with UTC in wp-settings.php
         */
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $wpBaseTimezone = date_default_timezone_get();
        $wpUserTimezone = get_option('timezone_string');
        if ($wpUserTimezone) {
          date_default_timezone_set($wpUserTimezone);
          CRM_Core_Config::singleton()->userSystem->setMySQLTimeZone();
        }
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        /*
         * CRM-95XX
         * At this point we are calling a CiviCRM function
         * WP always quotes the request, CiviCRM needs to reverse what it just did.
         */
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $this->remove_wp_magic_quotes();
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Required for AJAX calls
        if ($this->civicrm_in_wordpress()) {
          $_REQUEST['noheader'] = $_GET['noheader'] = TRUE;
        }
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Code inside invoke() requires the current user to be set up
        $current_user = wp_get_current_user();
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
         * Bypass synchronize if running upgrade to avoid any serious non-recoverable
         * error which might hinder the upgrade process.
         */
        if ( CRM_Utils_Array::value('q', $_GET) != 'civicrm/upgrade' ) {
          $this->users->sync_user( $current_user );
        }
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Set flag
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $alreadyInvoked = TRUE;
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Get args
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $argdata = $this->get_request_args();
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Set dashboard as default if args are empty
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        if ( empty( $argdata['argString'] ) ) {
          $_GET['q'] = 'civicrm/dashboard';
          $_GET['reset'] = 1;
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $argdata['args'] = array('civicrm', 'dashboard');
        }
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Do the business
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        CRM_Core_Invoke::invoke($argdata['args']);
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Restore WP's timezone
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        if ($wpBaseTimezone) {
          date_default_timezone_set($wpBaseTimezone);
        }
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Restore WP's arrays
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $this->restore_wp_magic_quotes();
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        /**
         * Broadcast that CiviCRM has been invoked.
         *
         * @since 4.4
         */
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        do_action( 'civicrm_invoked' );
    
      }
    
    
      /**
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Non-destructively override WordPress magic quotes.
       *
       * Only called by invoke() to undo WordPress default behaviour.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @since 4.4
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @since 5.7 Rewritten to work with query vars.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
      private function remove_wp_magic_quotes() {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Save original arrays
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $this->wp_get     = $_GET;
        $this->wp_post    = $_POST;
        $this->wp_cookie  = $_COOKIE;
        $this->wp_request = $_REQUEST;
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Reassign globals
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $_GET     = stripslashes_deep( $_GET );
        $_POST    = stripslashes_deep( $_POST );
        $_COOKIE  = stripslashes_deep( $_COOKIE );
        $_REQUEST = stripslashes_deep( $_REQUEST );
    
        // Test for query var
        $q = get_query_var( 'q' );
        if (!empty($q)) {
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $page = get_query_var( 'civiwp' );
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $reset = get_query_var( 'reset' );
          $id = get_query_var( 'id' );
          $html = get_query_var( 'html' );
          $snippet = get_query_var( 'snippet' );
    
          $action = get_query_var( 'action' );
          $mode = get_query_var( 'mode' );
          $cid = get_query_var( 'cid' );
          $gid = get_query_var( 'gid' );
          $sid = get_query_var( 'sid' );
          $cs = get_query_var( 'cs' );
          $force = get_query_var( 'force' );
    
          $_REQUEST['q'] = $_GET['q'] = $q;
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $_REQUEST['civiwp'] = $_GET['civiwp'] = 'CiviCRM';
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          if (!empty($reset)) { $_REQUEST['reset'] = $_GET['reset'] = $reset; }
          if (!empty($id)) { $_REQUEST['id'] = $_GET['id'] = $id; }
          if (!empty($html)) { $_REQUEST['html'] = $_GET['html'] = $html; }
          if (!empty($snippet)) { $_REQUEST['snippet'] = $_GET['snippet'] = $snippet; }
    
          if (!empty($action)) { $_REQUEST['action'] = $_GET['action'] = $action; }
          if (!empty($mode)) { $_REQUEST['mode'] = $_GET['mode'] = $mode; }
          if (!empty($cid)) { $_REQUEST['cid'] = $_GET['cid'] = $cid; }
          if (!empty($gid)) { $_REQUEST['gid'] = $_GET['gid'] = $gid; }
          if (!empty($sid)) { $_REQUEST['sid'] = $_GET['sid'] = $sid; }
          if (!empty($cs)) { $_REQUEST['cs'] = $_GET['cs'] = $cs; }
          if (!empty($force)) { $_REQUEST['force'] = $_GET['force'] = $force; }
    
          /**
           * Broadcast that CiviCRM query vars have been assigned.
           *
           * Use in combination with `civicrm_query_vars` filter to ensure that any
           * other query vars are included in the assignment to the super-global
           * arrays.
           *
           * @since 5.7
           */
          do_action( 'civicrm_query_vars_assigned' );
    
        }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Restore WordPress magic quotes.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Only called by invoke() to redo WordPress default behaviour.
       *
       * @since 4.4
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
      private function restore_wp_magic_quotes() {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Restore original arrays
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $_GET     = $this->wp_get;
        $_POST    = $this->wp_post;
        $_COOKIE  = $this->wp_cookie;
        $_REQUEST = $this->wp_request;
    
      }
    
    
      /**
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Detect Ajax, snippet, or file requests.
       *
       * @since 4.4
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @return boolean True if request is for a CiviCRM page, false otherwise.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function is_page_request() {
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Assume not a CiviCRM page
        $return = FALSE;
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Kick out if not CiviCRM
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        if (!$this->initialize()) {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          return $return;
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Get args
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $argdata = $this->get_request_args();
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Grab query var
        $html = get_query_var( 'html' );
        if (empty($html)) {
          $html = isset($_GET['html']) ? $_GET['html'] : '';
        }
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        /*
         * FIXME: It's not sustainable to hardcode a whitelist of all of non-HTML
         * pages. Maybe the menu-XML should include some metadata to make this
         * unnecessary?
         */
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        if (CRM_Utils_Array::value('HTTP_X_REQUESTED_WITH', $_SERVER) == 'XMLHttpRequest'
            || ($argdata['args'][0] == 'civicrm' && in_array($argdata['args'][1], array('ajax', 'file')) )
            || !empty($_REQUEST['snippet'])
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
            || strpos($argdata['argString'], 'civicrm/event/ical') === 0 && empty($html)
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
            || strpos($argdata['argString'], 'civicrm/contact/imagefile') === 0
        ) {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $return = FALSE;
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        }
        else {
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $return = TRUE;
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        }
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
        return $return;
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Get arguments and request string from query vars.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @since 4.6
       *
       * @return array $argdata Array containing request arguments and request string.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function get_request_args() {
    
        $argString = NULL;
        $args = array();
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
        // Get path from query vars
        $q = get_query_var( 'q' );
        if (empty($q)) {
          $q = isset($_GET['q']) ? $_GET['q'] : '';
        }
    
        // Fix 'civicrm/civicrm' elements derived from CRM:url()
        // @see https://lab.civicrm.org/dev/rc/issues/5#note_16205
        if (defined('CIVICRM_CLEANURL') && CIVICRM_CLEANURL) {
          if (substr($q, 0, 16) === 'civicrm/civicrm/') {
            $q = str_replace('civicrm/civicrm/', 'civicrm/', $q);
            $_REQUEST['q'] = $_GET['q'] = $q;
            set_query_var( 'q', $q );
          }
        }
    
        if (!empty($q)) {
          $argString = trim($q);
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          // remove / from the beginning and ending of query string.
          $argString = trim($argString, '/');
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
          $args = explode('/', $argString);
        }
        $args = array_pad($args, 2, '');
    
        return array(
          'args' => $args,
          'argString' => $argString
        );
    
      }
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
      /**
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Add CiviCRM's title to the header's <title> tag.
       *
       * @since 4.6
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @param string $title The title to set.
       * @return string The computed title.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function set_admin_title($title) {
        global $civicrm_wp_title;
        if (!$civicrm_wp_title) {
          return $title;
        }
        // Replace 1st occurance of "CiviCRM" in the title
        $pos = strpos($title, 'CiviCRM');
        if ($pos !== FALSE) {
          return substr_replace($title, $civicrm_wp_title, $pos, 7);
        }
        return $civicrm_wp_title;
      }
    
    
      /**
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Override a WordPress page title with the CiviCRM entity title.
       *
       * Callback method for 'single_page_title' hook, always called from WP front-end.
       *
       * @since 4.6
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @param string $post_title The title of the WordPress page or post.
       * @param object $post The WordPress post object the title applies to.
       * @return string $civicrm_wp_title The title of the CiviCRM entity.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function single_page_title( $post_title, $post ) {
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Sanity check and override
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        global $civicrm_wp_title;
        if (!empty($civicrm_wp_title)) {
          return $civicrm_wp_title;
        }
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Fallback
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        return $post_title;
    
      }
    
    
      /**
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Remove edit link from page content.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Callback from 'edit_post_link' hook.
       *
       * @since 4.6
       *
       * @return string Always empty.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function clear_edit_post_link() {
        return '';
      }
    
    
      /**
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Remove edit link in WP Admin Bar.
       *
       * Callback from 'wp_before_admin_bar_render' hook.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @since 4.6
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       */
      public function clear_edit_post_menu_item() {
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Access object
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        global $wp_admin_bar;
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Bail if in admin
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        if ( is_admin() ) return;
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        // Remove the menu item from front end
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        $wp_admin_bar->remove_menu( 'edit' );
    
      }
    
    
      /**
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Get base URL.
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * Clone of CRM_Utils_System_WordPress::getBaseUrl() whose access is set to
       * private. Until it is public, we cannot access the URL of the basepage since
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * CRM_Utils_System_WordPress::url().
       *
    
       * 27-09-2016
       * CRM-16421 CRM-17633 WIP Changes to support WP in it's own directory
       * https://wiki.civicrm.org/confluence/display/CRM/WordPress+installed+in+its+own+directory+issues
       * For now leave hard coded wp-admin references.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * TODO: remove wp-admin references and replace with admin_url() in the future.
       * TODO: Look at best way to get path to admin_url.
       *
       * @since 4.4
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @param bool $absolute Passing TRUE prepends the scheme and domain, FALSE doesn't.
       * @param bool $frontend Passing FALSE returns the admin URL.
       * @param $forceBackend Passing TRUE overrides $frontend and returns the admin URL.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
       * @return mixed|null|string
       */
      public function get_base_url($absolute, $frontend, $forceBackend) {
    
        $config = CRM_Core_Config::singleton();
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        if ((is_admin() && !$frontend) || $forceBackend) {
    
          return Civi::paths()->getUrl('[wp.backend]/.', $absolute ? 'absolute' : 'relative');
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
        }
    
        else {
          return Civi::paths()->getUrl('[wp.frontend]/.', $absolute ? 'absolute' : 'relative');
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    } // Class CiviCRM_For_WordPress ends
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    
    
    /*
    --------------------------------------------------------------------------------
    Procedures start here
    --------------------------------------------------------------------------------
    */
    
    
    /**
     * The main function responsible for returning the CiviCRM_For_WordPress instance
     * to functions everywhere.
     *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
     * Use this function like you would a global variable, except without needing to
     * declare the global.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
     *
     * Example: $civi = civi_wp();
     *
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
     * @since 4.4
     *
     * @return CiviCRM_For_WordPress The plugin instance.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
     */
    function civi_wp() {
      return CiviCRM_For_WordPress::singleton();
    }
    
    
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    /*
     * Instantiate CiviCRM_For_WordPress immediately.
     * See CiviCRM_For_WordPress::setup_instance()
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
     */
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
    civi_wp();
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
     * Tell WordPress to call plugin activation method - no longer calls legacy
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
     * global scope function.
    
    Kevin Cristiano's avatar
    Kevin Cristiano committed
     */
    register_activation_hook( CIVICRM_PLUGIN_FILE, array( civi_wp(), 'activate' ) );