diff --git a/civicrm.php b/civicrm.php index d79d2ea..e200fc7 100644 --- a/civicrm.php +++ b/civicrm.php @@ -30,30 +30,12 @@ * */ -/* - * ----------------------------------------------------------------------------- - * WordPress resources for developers - * ----------------------------------------------------------------------------- - * Not that they're ever adhered to anywhere other than core, but people do their - * best to comply... - * - * WordPress core coding standards: - * https://developer.wordpress.org/coding-standards/wordpress-coding-standards/php/ - * - * WordPress HTML standards: - * https://make.wordpress.org/core/handbook/best-practices/coding-standards/html/ - * - * WordPress JavaScript standards: - * https://developer.wordpress.org/coding-standards/wordpress-coding-standards/javascript/ - * ----------------------------------------------------------------------------- - */ - // This file must not accessed directly. if (!defined('ABSPATH')) { exit; } -// Set version here: when it changes, will force Javascript & CSS to reload. +// Set version here: changing it forces Javascript and CSS to reload. define('CIVICRM_PLUGIN_VERSION', '4.7'); // Store reference to this file. @@ -71,24 +53,26 @@ define('CIVICRM_PLUGIN_DIR', plugin_dir_path(CIVICRM_PLUGIN_FILE)); } +/* + * Minimum required PHP. + * + * Note: This duplicates `CRM_Upgrade_Incremental_General::MIN_INSTALL_PHP_VER`. + * The duplication helps avoid dependency issues. (Reading + * `CRM_Upgrade_Incremental_General::MIN_INSTALL_PHP_VER` requires loading + * `civicrm.settings.php`, but that triggers a parse-error on PHP 5.x.) + * + * @see CRM_Upgrade_Incremental_General::MIN_INSTALL_PHP_VER + * @see CiviWP\PhpVersionTest::testConstantMatch() + */ if (!defined('CIVICRM_WP_PHP_MINIMUM')) { - /** - * Minimum required PHP. - * - * Note: This duplicates `CRM_Upgrade_Incremental_General::MIN_INSTALL_PHP_VER`. - * The duplication helps avoid dependency issues. (Reading - * `CRM_Upgrade_Incremental_General::MIN_INSTALL_PHP_VER` requires loading - * `civicrm.settings.php`, but that triggers a parse-error on PHP 5.x.) - * - * @see CRM_Upgrade_Incremental_General::MIN_INSTALL_PHP_VER - * @see CiviWP\PhpVersionTest::testConstantMatch() - */ define('CIVICRM_WP_PHP_MINIMUM', '7.2.0'); } /* * The constant `CIVICRM_SETTINGS_PATH` is also defined in `civicrm.config.php` * and may already have been defined there - e.g. by cron or external scripts. + * These legacy routes should not be used because they try to bootstrap WordPress + * in unreliable ways. Use WP-CLI or WP-REST routes instead. */ if (!defined('CIVICRM_SETTINGS_PATH')) { @@ -98,14 +82,13 @@ * If the settings file is found in the 4.6 and prior location, use that as * `CIVICRM_SETTINGS_PATH`, otherwise use the new location. */ - $upload_dir = wp_upload_dir(); - $wp_civi_settings = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'civicrm.settings.php'; - $wp_civi_settings_deprectated = CIVICRM_PLUGIN_DIR . 'civicrm.settings.php'; - - if (file_exists($wp_civi_settings_deprectated)) { - define('CIVICRM_SETTINGS_PATH', $wp_civi_settings_deprectated); + $wp_civi_settings_deprecated = CIVICRM_PLUGIN_DIR . 'civicrm.settings.php'; + if (file_exists($wp_civi_settings_deprecated)) { + define('CIVICRM_SETTINGS_PATH', $wp_civi_settings_deprecated); } else { + $upload_dir = wp_upload_dir(); + $wp_civi_settings = implode(DIRECTORY_SEPARATOR, [$upload_dir['basedir'], 'civicrm', 'civicrm.settings.php']); define('CIVICRM_SETTINGS_PATH', $wp_civi_settings); } @@ -184,7 +167,7 @@ class CiviCRM_For_WordPress { /** * @var object - * Basepage management object. + * Base Page management object. * @since 4.4 * @access public */ @@ -234,6 +217,17 @@ public static function singleton() { // Create instance. self::$instance = new CiviCRM_For_WordPress(); + // Include legacy global scope functions. + include_once CIVICRM_PLUGIN_DIR . 'includes/civicrm.functions.php'; + + /* + * Incorporate WP-CLI Integration based on drush CiviCRM functionality. + * @see https://github.com/andy-walker/wp-cli-civicrm + */ + if (defined('WP_CLI') && WP_CLI) { + include_once CIVICRM_PLUGIN_DIR . 'wp-cli/civicrm.php'; + } + // Delay setup until 'plugins_loaded' to allow other plugins to load as well. add_action('plugins_loaded', [self::$instance, 'setup_instance']); @@ -272,9 +266,13 @@ public function __wakeup() { /** * Plugin activation. * - * This method is called only when CiviCRM plugin is activated. In order for - * other plugins to be able to interact with CiviCRM's activation, we wait until - * after the activation redirect to perform activation actions. + * This method is called only when CiviCRM plugin is activated. Other plugins + * are able to interact with CiviCRM's activation because "plugins_loaded" has + * already fired. + * + * Since CiviCRM has an Installer UI when activated via the WordPress Plugins + * screen, this method sets an option that can be read on the next page load + * allowing `self::activation()` to redirect to it when possible. * * @since 4.4 */ @@ -283,10 +281,25 @@ public function activate() { // Set a one-time-only option. add_option('civicrm_activation_in_progress', 'true'); + // Include and init classes because "plugins_loaded" has already fired. + include_once CIVICRM_PLUGIN_DIR . 'includes/civicrm.users.php'; + $this->users = new CiviCRM_For_WordPress_Users(); + + /** + * Broadcast that the CiviCRM plugin has been activated. + * + * Used internally by: + * + * - CiviCRM_For_WordPress_Users::activate() + * + * @since 5.44 + */ + do_action('civicrm_activate'); + } /** - * Run CiviCRM's plugin activation procedure. + * Runs the CiviCRM activation procedure when activated via the WordPress UI. * * @since 4.4 */ @@ -303,7 +316,10 @@ public function activation() { } /** - * Broadcast that activation actions need to happen now. + * Broadcast that activation via the WordPress UI has happened. + * + * This fires on the admin page load that happens directly after the CiviCRM + * plugin has been activated via the WordPress UI. * * @since 5.6 */ @@ -312,11 +328,12 @@ public function activation() { // Change option so this action never fires again. update_option('civicrm_activation_in_progress', 'false'); - // Try and redirect to the Installer page. + // When installed via the WordPress UI, try and redirect to the Installer page. if (!is_multisite() && !isset($_GET['activate-multi']) && !CIVICRM_INSTALLED) { wp_redirect(admin_url('admin.php?page=civicrm-install')); exit; } + } /** @@ -336,6 +353,10 @@ public function deactivate() { /** * Broadcast that deactivation actions need to happen now. * + * Used internally by: + * + * - CiviCRM_For_WordPress_Users::deactivate() + * * @since 5.6 */ do_action('civicrm_deactivation'); @@ -377,7 +398,7 @@ public function setup_instance() { $this->include_files(); $this->setup_objects(); - // Do plugin activation. + // Do plugin activation when activated via the WordPress UI. $this->activation(); // Use translation files. @@ -389,6 +410,10 @@ public function setup_instance() { /** * Broadcast that this plugin is now loaded. * + * Used internally by: + * + * - CiviCRM_For_WordPress_Basepage::maybe_create_basepage() + * * @since 4.4 */ do_action('civicrm_instance_loaded'); @@ -514,11 +539,11 @@ public function enable_translation() { * Setter for determining if CiviCRM is currently being displayed in WordPress. * This becomes true whe CiviCRM is called in the following contexts: * - * (a) in the WordPress back-end - * (b) when CiviCRM content is being displayed on the front-end via wpBasePage - * (c) when an AJAX request is made to CiviCRM + * (a) In the WordPress back-end. + * (b) When CiviCRM content is being displayed on the front-end via the Base Page. + * (c) When an AJAX request is made to CiviCRM. * - * It is NOT true when CiviCRM is called via a shortcode. + * It is NOT true when CiviCRM is called via a Shortcode. * * @since 4.4 */ @@ -549,7 +574,6 @@ public function civicrm_in_wordpress() { * @since 4.4 * * @param bool $in_wordpress True if CiviCRM is displayed in WordPress, false otherwise. - * @return bool $in_wordpress True if CiviCRM is displayed in WordPress, false otherwise. */ return apply_filters('civicrm_in_wordpress', self::$in_wordpress); @@ -561,10 +585,10 @@ public function civicrm_in_wordpress() { * Setter for determining how CiviCRM is currently being displayed in WordPress. * This can be one of the following contexts: * - * (a) in the WordPress back-end - * (b) when CiviCRM content is being displayed on the front-end via wpBasePage - * (c) when a "non-page" request is made to CiviCRM - * (d) when CiviCRM is called via a shortcode + * (a) In the WordPress back-end. + * (b) When CiviCRM content is being displayed on the front-end via the Base Page. + * (c) When a "non-page" request is made to CiviCRM. + * (d) When CiviCRM is called via a Shortcode. * * The following codes correspond to the different contexts: * @@ -600,10 +624,13 @@ public function civicrm_context_get() { /** * Allow specific context to be filtered. * + * Used internally by: + * + * - CiviCRM_For_WordPress_Shortcodes::get_context() + * * @since 4.4 * * @param bool $context The existing context in which CiviCRM is displayed in WordPress. - * @return bool $context The modified context in which CiviCRM is displayed in WordPress. */ return apply_filters('civicrm_context', self::$context); @@ -632,7 +659,7 @@ public function register_hooks() { // Handle WordPress Admin context. $this->admin->register_hooks(); - // Enable shortcode modal. + // Enable Shortcode modal. $this->modal->register_hooks(); return; @@ -813,7 +840,7 @@ public function rewrite_rules($flush_rewrite_rules = FALSE) { // Get config. $config = CRM_Core_Config::singleton(); - // Get basepage object. + // Get Base Page object. $basepage = get_page_by_path($config->wpBasePage); // Sanity check. @@ -821,7 +848,7 @@ public function rewrite_rules($flush_rewrite_rules = FALSE) { return; } - // Let's add rewrite rule when viewing the basepage. + // Let's add Rewrite Rule when viewing the Base Page. add_rewrite_rule( '^' . $config->wpBasePage . '/([^?]*)?', 'index.php?page_id=' . $basepage->ID . '&civiwp=CiviCRM&q=civicrm%2F$matches[1]', @@ -836,11 +863,15 @@ public function rewrite_rules($flush_rewrite_rules = FALSE) { /** * Broadcast the rewrite rules event. * + * Used internally by: + * + * - CiviCRM_For_WordPress_Compat::rewrite_rules_polylang() + * * @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. + * @param WP_Post $basepage The Base Page post object. */ do_action('civicrm_after_rewrite_rules', $flush_rewrite_rules, $basepage); @@ -879,7 +910,6 @@ public function query_vars($query_vars) { * @since 5.7 * * @param array $civicrm_query_vars The default set of query vars. - * @return array $civicrm_query_vars The modified set of query vars. */ $civicrm_query_vars = apply_filters('civicrm_query_vars', $civicrm_query_vars); @@ -1390,7 +1420,7 @@ public function get_request_args() { * Get base URL. * * 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 + * private. Until it is public, we cannot access the URL of the Base Page since * CRM_Utils_System_WordPress::url(). * * 27-09-2016 @@ -1466,19 +1496,3 @@ function civi_wp() { * * @see https://developer.wordpress.org/reference/functions/register_uninstall_hook/ */ - -// Include legacy global scope functions. -include_once CIVICRM_PLUGIN_DIR . 'includes/civicrm.functions.php'; - -/** - * Incorporate WP-CLI Integration. - * - * Based on drush CiviCRM functionality, work done by Andy Walker. - * https://github.com/andy-walker/wp-cli-civicrm - * - * @since 4.5 - */ -if (defined('WP_CLI') && WP_CLI) { - // Changed from __DIR__ because of possible symlink issues. - include_once CIVICRM_PLUGIN_DIR . 'wp-cli/civicrm.php'; -} diff --git a/includes/admin-metaboxes/civicrm.metabox.contact.add.php b/includes/admin-metaboxes/civicrm.metabox.contact.add.php index ce80294..0bb9a21 100644 --- a/includes/admin-metaboxes/civicrm.metabox.contact.add.php +++ b/includes/admin-metaboxes/civicrm.metabox.contact.add.php @@ -213,7 +213,7 @@ public function meta_box_add() { * @param mixed $unused Unused param. * @param array $metabox Array containing id, title, callback, and args elements. */ - public function meta_box_render($unused = NULL, $metabox) { + public function meta_box_render($unused, $metabox) { if (!$this->civi->initialize()) { return; @@ -295,7 +295,7 @@ public function form_submitted() { } /** - * Save the CiviCRM Basepage Setting. + * Save the CiviCRM Base Page Setting. * * @since 5.34 */ diff --git a/includes/admin-pages/civicrm.page.error.php b/includes/admin-pages/civicrm.page.error.php index 1f164ca..20106f0 100644 --- a/includes/admin-pages/civicrm.page.error.php +++ b/includes/admin-pages/civicrm.page.error.php @@ -83,7 +83,6 @@ public function access_capability() { * @since 5.40 * * @param str The default access capability. - * @return str The modified access capability. */ return apply_filters('civicrm/admin/error/cap', 'manage_options'); @@ -170,6 +169,10 @@ public function page_error() { * * The Screen ID to use is: "civicrm_page_civi_error". * + * Used internally by: + * + * - self::meta_boxes_error_add() + * * @since 5.40 * * @param str $screen_id The ID of the current screen. @@ -283,7 +286,7 @@ public function meta_boxes_error_add($screen_id) { * @param mixed $unused Unused param. * @param array $metabox Array containing id, title, callback, and args elements. */ - public function meta_box_error_help_render($unused = NULL, $metabox) { + public function meta_box_error_help_render($unused, $metabox) { // Include template file. include CIVICRM_PLUGIN_DIR . 'assets/templates/metaboxes/metabox.error.help.php'; @@ -298,7 +301,7 @@ public function meta_box_error_help_render($unused = NULL, $metabox) { * @param mixed $unused Unused param. * @param array $metabox Array containing id, title, callback, and args elements. */ - public function meta_box_error_php_render($unused = NULL, $metabox) { + public function meta_box_error_php_render($unused, $metabox) { global $civicrm_root; @@ -315,7 +318,7 @@ public function meta_box_error_php_render($unused = NULL, $metabox) { * @param mixed $unused Unused param. * @param array $metabox Array containing id, title, callback, and args elements. */ - public function meta_box_error_path_render($unused = NULL, $metabox) { + public function meta_box_error_path_render($unused, $metabox) { global $civicrm_root; diff --git a/includes/admin-pages/civicrm.page.integration.php b/includes/admin-pages/civicrm.page.integration.php index 683830d..511bf6f 100644 --- a/includes/admin-pages/civicrm.page.integration.php +++ b/includes/admin-pages/civicrm.page.integration.php @@ -106,7 +106,6 @@ public function access_capability() { * @since 5.37 * * @param str The default access capability. - * @return str The modified access capability. */ return apply_filters('civicrm/admin/integration/cap', 'manage_options'); @@ -194,6 +193,10 @@ public function page_integration() { * * The Screen ID to use is: "civicrm_page_cwps_settings". * + * Used internally by: + * + * - self::meta_boxes_integration_add() + * * @since 5.34 * * @param str $screen_id The ID of the current screen. @@ -295,7 +298,7 @@ public function meta_boxes_integration_add($screen_id) { * @param mixed $unused Unused param. * @param array $metabox Array containing id, title, callback, and args elements. */ - public function meta_box_integration_wordpress_render($unused = NULL, $metabox) { + public function meta_box_integration_wordpress_render($unused, $metabox) { // First check our transient for the data. $plugins = get_site_transient('civicrm_plugins_by_tag'); @@ -345,7 +348,7 @@ public function meta_box_integration_wordpress_render($unused = NULL, $metabox) * @param mixed $unused Unused param. * @param array $metabox Array containing id, title, callback, and args elements. */ - public function meta_box_integration_git_render($unused = NULL, $metabox) { + public function meta_box_integration_git_render($unused, $metabox) { // First check our transient for the data. $plugins = get_site_transient('civicrm_plugins_by_repo'); @@ -393,7 +396,7 @@ public function meta_box_integration_git_render($unused = NULL, $metabox) { * @param mixed $unused Unused param. * @param array $metabox Array containing id, title, callback, and args elements. */ - public function meta_box_integration_ext_render($unused = NULL, $metabox) { + public function meta_box_integration_ext_render($unused, $metabox) { if (!$this->civi->initialize()) { return; diff --git a/includes/admin-pages/civicrm.page.options.php b/includes/admin-pages/civicrm.page.options.php index 7483ac4..49c2f1e 100644 --- a/includes/admin-pages/civicrm.page.options.php +++ b/includes/admin-pages/civicrm.page.options.php @@ -109,7 +109,6 @@ public function access_capability() { * @since 5.37 * * @param str The default access capability. - * @return str The modified access capability. */ return apply_filters('civicrm/admin/settings/cap', 'manage_options'); @@ -229,6 +228,10 @@ public function page_options() { * * The Screen ID to use is: "civicrm_page_cwps_settings". * + * Used internally by: + * + * - self::meta_boxes_options_add() + * * @since 5.34 * * @param str $screen_id The ID of the current screen. @@ -370,7 +373,7 @@ public function meta_boxes_options_add($screen_id) { * @param mixed $unused Unused param. * @param array $metabox Array containing id, title, callback, and args elements. */ - public function meta_box_options_basepage_render($unused = NULL, $metabox) { + public function meta_box_options_basepage_render($unused, $metabox) { // Get the setting. $basepage_slug = civicrm_api3('Setting', 'getvalue', [ @@ -439,7 +442,6 @@ public function meta_box_options_basepage_render($unused = NULL, $metabox) { * @since 5.34 * * @param array $options_post The existing button attributes. - * @return array $options_post The modified button attributes. */ $options_post = apply_filters('civicrm/metabox/basepage/submit/options', $options_post); @@ -456,7 +458,7 @@ public function meta_box_options_basepage_render($unused = NULL, $metabox) { * @param mixed $unused Unused param. * @param array $metabox Array containing id, title, callback, and args elements. */ - public function meta_box_options_shortcode_render($unused = NULL, $metabox) { + public function meta_box_options_shortcode_render($unused, $metabox) { if (!$this->civi->initialize()) { return; @@ -487,7 +489,6 @@ public function meta_box_options_shortcode_render($unused = NULL, $metabox) { * @since 5.44 * * @param array $options_post The existing button attributes. - * @return array $options_post The modified button attributes. */ $options_post = apply_filters('civicrm/metabox/shortcode/submit/options', $options_post); @@ -504,7 +505,7 @@ public function meta_box_options_shortcode_render($unused = NULL, $metabox) { * @param mixed $unused Unused param. * @param array $metabox Array containing id, title, callback, and args elements. */ - public function meta_box_options_email_render($unused = NULL, $metabox) { + public function meta_box_options_email_render($unused, $metabox) { if (!$this->civi->initialize()) { return; @@ -538,7 +539,6 @@ public function meta_box_options_email_render($unused = NULL, $metabox) { * @since 5.34 * * @param array $options_post The existing button attributes. - * @return array $options_post The modified button attributes. */ $options_post = apply_filters('civicrm/metabox/email_sync/submit/options', $options_post); @@ -555,7 +555,7 @@ public function meta_box_options_email_render($unused = NULL, $metabox) { * @param mixed $unused Unused param. * @param array $metabox Array containing id, title, callback, and args elements. */ - public function meta_box_options_cache_render($unused = NULL, $metabox) { + public function meta_box_options_cache_render($unused, $metabox) { // Set submit button options. $options = [ @@ -576,7 +576,7 @@ public function meta_box_options_cache_render($unused = NULL, $metabox) { * @param mixed $unused Unused param. * @param array $metabox Array containing id, title, callback, and args elements. */ - public function meta_box_options_links_render($unused = NULL, $metabox) { + public function meta_box_options_links_render($unused, $metabox) { if (!$this->civi->initialize()) { return; @@ -608,7 +608,6 @@ public function meta_box_options_links_render($unused = NULL, $metabox) { * @since 5.34 * * @param array $admin_links The default array of admin links. - * @return array $admin_links The modified array of admin links. */ $admin_links = apply_filters('civicrm/metabox/links/admin', $admin_links); @@ -635,7 +634,6 @@ public function meta_box_options_links_render($unused = NULL, $metabox) { * @since 5.34 * * @param array $maintenance_links The default array of admin links. - * @return array $maintenance_links The modified array of admin links. */ $maintenance_links = apply_filters('civicrm/metabox/links/maintenance', $maintenance_links); @@ -683,7 +681,7 @@ public function form_submitted() { } /** - * Save the CiviCRM Basepage Setting. + * Save the CiviCRM Base Page Setting. * * @since 5.34 */ @@ -784,7 +782,7 @@ private function form_redirect() { // --------------------------------------------------------------------------- /** - * Save the CiviCRM Basepage Setting. + * Save the CiviCRM Base Page Setting. * * @since 5.34 */ diff --git a/includes/civicrm.admin.php b/includes/civicrm.admin.php index 1e0dd65..7cef08d 100644 --- a/includes/civicrm.admin.php +++ b/includes/civicrm.admin.php @@ -90,6 +90,9 @@ public function __construct() { $this->include_files(); $this->setup_objects(); + // Always check setting for path to "wp-load.php". + add_action('civicrm_initialized', [$this, 'add_wpload_setting']); + // Filter Heartbeat on CiviCRM admin pages as late as is practical. add_filter('heartbeat_settings', [$this, 'heartbeat'], 1000, 1); @@ -149,7 +152,7 @@ public function register_hooks() { } else { - // Listen for changes to the basepage setting. + // Listen for changes to the Base Page setting. add_action('civicrm_postSave_civicrm_setting', [$this, 'settings_change'], 10); // Set page title. @@ -160,6 +163,12 @@ public function register_hooks() { /** * Broadcast that this object has registered its callbacks. * + * Used internally by: + * + * - CiviCRM_For_WordPress_Admin_Metabox_Contact_Add::register_hooks() + * - CiviCRM_For_WordPress_Admin_Page_Integration::register_hooks() + * - CiviCRM_For_WordPress_Admin_Page_Options::register_hooks() + * * @since 5.34 */ do_action('civicrm/admin/hooks/registered'); @@ -442,6 +451,9 @@ public function initialize() { } + // Success! Set static flag. + $initialized = TRUE; + /** * Broadcast that CiviCRM is now initialized. * @@ -449,8 +461,6 @@ public function initialize() { */ do_action('civicrm_initialized'); - // Success! Set and return static flag. - $initialized = TRUE; return $initialized; } @@ -595,7 +605,6 @@ public function add_menu_items() { * @since 4.4 * * @param str The default menu position expressed as a float. - * @return str The modified menu position expressed as a float. */ $position = apply_filters('civicrm_menu_item_position', '3.904981'); @@ -648,10 +657,11 @@ public function add_menu_items() { ); /* - // Add scripts and styles like this. - add_action('admin_print_scripts-' . $this->menu_page, [$this, 'admin_installer_js']); - add_action('admin_print_styles-' . $this->menu_page, [$this, 'admin_installer_css']); - add_action('admin_head-' . $this->menu_page, [$this, 'admin_installer_head'], 50); + * Add scripts and styles like this if needed: + * + * add_action('admin_print_scripts-' . $this->menu_page, [$this, 'admin_installer_js']); + * add_action('admin_print_styles-' . $this->menu_page, [$this, 'admin_installer_css']); + * add_action('admin_head-' . $this->menu_page, [$this, 'admin_installer_head'], 50); */ } @@ -739,9 +749,6 @@ public function admin_page_load() { // Add resources for back end. $this->civi->add_core_resources(FALSE); - // Check setting for path to wp-load.php. - $this->add_wpload_setting(); - } /** @@ -761,11 +768,6 @@ public function admin_page_load() { * 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'); * @@ -774,7 +776,11 @@ public function admin_page_load() { */ public function add_wpload_setting() { - if (!$this->civi->initialize()) { + if (!CIVICRM_INSTALLED) { + return; + } + + if (!$this->initialize()) { return; } @@ -782,16 +788,16 @@ public function add_wpload_setting() { $path = ABSPATH . 'wp-load.php'; // Get the setting, if it exists. - $setting = CRM_Core_BAO_Setting::getItem('CiviCRM Preferences', 'wpLoadPhp'); - - // If we don't have one, create it. - if (is_null($setting)) { - CRM_Core_BAO_Setting::setItem($path, 'CiviCRM Preferences', 'wpLoadPhp'); - } + $setting = civicrm_api3('Setting', 'getvalue', [ + 'name' => 'wpLoadPhp', + 'group' => 'CiviCRM Preferences', + ]); - // Is it different to the one we've stored? - if ($setting !== $path) { - // Yes - set new path (this could be because we've changed server or location) + /* + * If we don't have a setting, create it. Also set it if it's different to + * what's stored. This could be because we've changed server or location. + */ + if (empty($setting) || $setting !== $path) { CRM_Core_BAO_Setting::setItem($path, 'CiviCRM Preferences', 'wpLoadPhp'); } @@ -811,7 +817,7 @@ public function get_admin_link($path = '', $params = NULL) { // Init link. $link = ''; - if (!$this->civi->initialize()) { + if (!$this->initialize()) { return $link; } @@ -841,7 +847,7 @@ public function get_admin_link($path = '', $params = NULL) { */ public function clear_caches() { - if (!$this->civi->initialize()) { + if (!$this->initialize()) { return; } @@ -878,7 +884,7 @@ public function get_by_dedupe_unsupervised($contact, $contact_type = 'Individual return FALSE; } - if (!$this->civi->initialize()) { + if (!$this->initialize()) { return FALSE; } diff --git a/includes/civicrm.basepage.php b/includes/civicrm.basepage.php index 70506d1..297b3f4 100644 --- a/includes/civicrm.basepage.php +++ b/includes/civicrm.basepage.php @@ -52,13 +52,13 @@ public function __construct() { // Always listen for deactivation action. add_action('civicrm_deactivation', [$this, 'deactivate']); - // Always check if the basepage needs to be created. + // Always check if the Base Page needs to be created. add_action('civicrm_instance_loaded', [$this, 'maybe_create_basepage']); } /** - * Register hooks to handle CiviCRM in a WordPress wpBasePage context. + * Register hooks to handle CiviCRM in a WordPress Base Page context. * * @since 4.6 */ @@ -69,22 +69,22 @@ public function register_hooks() { return; } - // Cache CiviCRM base page markup. + // Cache CiviCRM Base Page markup. add_action('wp', [$this, 'basepage_handler'], 10, 1); } /** - * Trigger the process whereby the WordPress basepage is created. + * Triggers the process whereby the WordPress Base Page is created. * - * Sets a one-time-only option to flag that we need to create a basepage - + * Sets a one-time-only option to flag that we need to create a Base Page - * it will not update the option once it has been set to another value nor * create a new option with the same name. * - * As a result of doing this, we know that a basepage needs to be created, but - * the moment to do so is once CiviCRM has been successfully installed. + * As a result of doing this, we know that a Base Page needs to be created, + * but the moment to do so is once CiviCRM has been successfully installed. * - * @see do_basepage_creation() + * @see self::maybe_create_basepage() * * @since 5.6 */ @@ -108,11 +108,11 @@ public function deactivate() { } /** - * Register the hook to create the WordPress basepage, if necessary. + * Auto-creates the WordPress Base Page if necessary. * - * Changes the one-time-only option so that the basepage can only be created + * Changes the one-time-only option so that the Base Page can only be created * once. Thereafter, we're on our own until there's a 'delete_post' callback - * to prevent the basepage from being deleted. + * to prevent the Base Page from being deleted. * * @since 5.6 */ @@ -128,12 +128,7 @@ public function maybe_create_basepage() { return; } - // Bail if not WordPress admin. - if (!is_admin()) { - return; - } - - // Create basepage. + // Create the Base Page. add_action('wp_loaded', [$this, 'create_wp_basepage']); // Change option so the callback above never runs again. @@ -142,71 +137,64 @@ public function maybe_create_basepage() { } /** - * Create WordPress basepage and save setting. + * Creates the WordPress Base Page and saves the CiviCRM "wpBasePage" setting. * * @since 4.6 * @since 5.6 Relocated from CiviCRM_For_WordPress to here. + * @since 5.44 Returns success or failure. + * + * @return bool TRUE if successful, FALSE otherwise. */ public function create_wp_basepage() { if (!$this->civi->initialize()) { - return; + return FALSE; } + // Bail if we already have a Base Page setting. $config = CRM_Core_Config::singleton(); - - // Bail if we already have a basepage setting. if (!empty($config->wpBasePage)) { - return; + return TRUE; } /** - * Filter the default page slug. + * Filter the default Base Page slug. * * @since 4.6 * - * @param str The default basepage slug. - * @return str The modified basepage slug. + * @param str The default Base Page slug. */ $slug = apply_filters('civicrm_basepage_slug', 'civicrm'); - // Get existing page with that slug. + // Get existing Page with that slug. $page = get_page_by_path($slug); - // Does it exist? - if ($page) { - - // We already have a basepage. + // Get the ID if the Base Page already exists. + $result = 0; + if ($page instanceof WP_Post) { $result = $page->ID; - } - else { - // Create the basepage. + // Create the Base Page if it's missing. + if ($result === 0) { $result = $this->create_basepage($slug); - } - // Were we successful? + // Save the Page slug as the setting if we have one. if ($result !== 0 && !is_wp_error($result)) { - - // Get the post object. $post = get_post($result); - - $params = [ - 'version' => 3, + civicrm_api3('Setting', 'create', [ 'wpBasePage' => $post->post_name, - ]; - - // Save the setting. - civicrm_api3('setting', 'create', $params); - + ]); + return TRUE; } + return FALSE; + } /** - * Create a WordPress page to act as the CiviCRM base page. + * Create a WordPress page to act as the CiviCRM Base Page. * * @since 4.6 * @since 5.6 Relocated from CiviCRM_For_WordPress to here. @@ -219,16 +207,40 @@ private function create_basepage($slug) { // If multisite, switch to main site. if (is_multisite() && !is_main_site()) { - // Store this site. - $original_site = get_current_blog_id(); + /** + * Allow plugins to override the switch to the main site. + * + * This filter changes the default behaviour on WordPress Multisite so + * that the Base Page *is* created on every site on which CiviCRM is + * activated. This is a more sensible and inclusive default, since the + * absence of the Base Page on a sub-site often leads to confusion. + * + * To restore the previous functionality, return boolean TRUE. + * + * The previous functionality may be the desired behaviour when the + * WordPress Multisite instance in question is one where sub-sites aren't + * truly "separate" e.g. sites built on frameworks such as "Commons in + * a Box" or "MultilingualPress". + * + * @since 5.44 + * + * @param bool False by default prevents the switch to the main site. + */ + $switch = apply_filters('civicrm/basepage/main_site_only', FALSE); + + if ($switch !== FALSE) { + + // Store this site. + $original_site = get_current_blog_id(); - // Switch. - global $current_site; - switch_to_blog($current_site->blog_id); + // Switch to main site. + switch_to_blog(get_main_site_id()); + + } } - // Define basepage. + // Define Base Page. $page = [ 'post_status' => 'publish', 'post_type' => 'page', @@ -248,12 +260,11 @@ private function create_basepage($slug) { ]; /** - * Filter the default page title. + * Filter the default Base Page title. * * @since 4.6 * - * @param str The default base page title. - * @return str The modified base page title. + * @param str The default Base Page title. */ $page['post_title'] = apply_filters('civicrm_basepage_title', __('CiviCRM', 'civicrm')); @@ -261,12 +272,12 @@ private function create_basepage($slug) { $content = __('Do not delete this page. Page content is generated by CiviCRM.', 'civicrm'); /** - * Filter the default page content. + * Filter the default Base Page content. * * @since 4.6 * - * @param str $content The default base page content. - * @return str $content The modified base page content. + * @param str $content The default Base Page content. + * @return str $content The modified Base Page content. */ $page['post_content'] = apply_filters('civicrm_basepage_content', $content); @@ -286,7 +297,7 @@ private function create_basepage($slug) { } /** - * Build CiviCRM base page content. + * Build CiviCRM Base Page content. * * Callback method for 'wp' hook, always called from WordPress front-end. * @@ -350,7 +361,6 @@ public function basepage_handler($wp) { * * @param bool By default "Base Page mode" should not be triggered. * @param WP_Post $post The current WordPress Post object. - * @return bool Whether or not to force "Base Page mode" - FALSE by default. */ $basepage_mode = (bool) apply_filters('civicrm_force_basepage_mode', FALSE, $post); @@ -362,7 +372,7 @@ public function basepage_handler($wp) { // Start buffering. ob_start(); - // Now, instead of echoing, base page output ends up in buffer. + // Now, instead of echoing, Base Page output ends up in buffer. $this->civi->invoke(); // Save the output and flush the buffer. $this->basepage_markup = ob_get_clean(); @@ -433,7 +443,7 @@ public function basepage_handler($wp) { // Add compatibility with Yoast SEO plugin's Open Graph title. add_filter('wpseo_opengraph_title', [$this, 'wpseo_page_title'], 100, 1); - // Don't let the Yoast SEO plugin parse the basepage title. + // Don't let the Yoast SEO plugin parse the Base Page title. if (class_exists('WPSEO_Frontend')) { $frontend = WPSEO_Frontend::get_instance(); remove_filter('pre_get_document_title', [$frontend, 'title'], 15); @@ -460,11 +470,11 @@ public function basepage_handler($wp) { } - // Flag that we have parsed the base page. + // Flag that we have parsed the Base Page. $this->basepage_parsed = TRUE; /** - * Broadcast that the base page is parsed. + * Broadcast that the Base Page is parsed. * * @since 4.4 */ @@ -473,7 +483,7 @@ public function basepage_handler($wp) { } /** - * Get CiviCRM basepage title for element. + * Get CiviCRM Base Page title for <title> element. * * Callback method for 'wp_title' hook, called at the end of function wp_title. * @@ -518,7 +528,7 @@ public function wp_page_title($title, $separator = '»', $separator_locatio } /** - * Get CiviCRM basepage title for <title> element. + * Get CiviCRM Base Page title for <title> element. * * Callback method for 'document_title_parts' hook. This filter was introduced * in WordPress 3.8 but it depends on whether the theme has implemented that @@ -542,7 +552,7 @@ public function wp_page_title_parts($parts) { } /** - * Get CiviCRM base page title for Open Graph elements. + * Get CiviCRM Base Page title for Open Graph elements. * * Callback method for 'wpseo_opengraph_title' hook, to provide compatibility * with the WordPress SEO plugin. @@ -554,30 +564,30 @@ public function wp_page_title_parts($parts) { */ public function wpseo_page_title($post_title) { - // Hand back our base page title. + // Hand back our Base Page title. return $this->basepage_title; } /** - * Get CiviCRM base page content. + * Get CiviCRM Base Page content. * * Callback method for 'the_content' hook, always called from WordPress * front-end. * * @since 4.6 * - * @return str $basepage_markup The base page markup. + * @return str $basepage_markup The Base Page markup. */ public function basepage_render() { - // Hand back our base page markup. + // Hand back our Base Page markup. return $this->basepage_markup; } /** - * Provide the canonical URL for a page accessed through a basepage. + * Provide the canonical URL for a page accessed through a Base Page. * * WordPress will default to saying the canonical URL is the URL of the base * page itself, but we need to indicate that in this case, the whole thing @@ -630,14 +640,14 @@ public function basepage_canonical_url($canonical) { /* * We should, however, build the URL the way that CiviCRM expects it to be - * (rather than through some other funny base page). + * (rather than through some other funny Base Page). */ return CRM_Utils_System::url($path, $query); } /** - * Get CiviCRM base page template. + * Get CiviCRM Base Page template. * * Callback method for 'template_include' hook, always called from WordPress * front-end. @@ -663,7 +673,7 @@ public function basepage_template($template) { } /** - * Allow base page template to be overridden. + * Allow Base Page template to be overridden. * * In most cases, the logic will not progress beyond here. Shortcodes in * posts and pages will have a template set, so we leave them alone unless @@ -672,11 +682,10 @@ public function basepage_template($template) { * @since 4.6 * * @param string $template_name The provided template name. - * @return string The overridden template name. */ $basepage_template = apply_filters('civicrm_basepage_template', $template_name); - // Find the base page template. + // Find the Base Page template. $page_template = locate_template([$basepage_template]); // If not homepage and template is found. @@ -687,20 +696,19 @@ public function basepage_template($template) { /** * Override the template, but allow plugins to amend. * - * This filter handles the scenario where no basepage has been set, in + * This filter handles the scenario where no Base Page has been set, in * which case CiviCRM will try to load its content in the site's homepage. * Many themes, however, do not have a call to "the_content()" on the * homepage - it is often used as a gateway page to display widgets, * archives and so forth. * * Be aware that if the homepage is set to show latest posts, then this - * template override will not have the desired effect. A basepage *must* + * template override will not have the desired effect. A Base Page *must* * be set if this is the case. * * @since 4.6 * * @param string The template name (set to the default page template). - * @return string The overridden template name. */ $home_template_name = apply_filters('civicrm_basepage_home_template', 'page.php'); @@ -718,10 +726,10 @@ public function basepage_template($template) { } /** - * Add classes to body element when on basepage. + * Add classes to body element when on Base Page. * * This allows selectors to be written for particular CiviCRM "pages" despite - * them all being rendered on the one WordPress basepage. + * them all being rendered on the one WordPress Base Page. * * @since 4.7.18 * diff --git a/includes/civicrm.compat.php b/includes/civicrm.compat.php index 8acae0c..4457a51 100644 --- a/includes/civicrm.compat.php +++ b/includes/civicrm.compat.php @@ -79,7 +79,7 @@ public function register_hooks() { * @since 5.24 * * @param bool $flush_rewrite_rules True if rules flushed, false otherwise. - * @param WP_Post $basepage The Basepage post object. + * @param WP_Post $basepage The Base Page post object. */ public function rewrite_rules_polylang($flush_rewrite_rules, $basepage) { @@ -92,12 +92,12 @@ public function rewrite_rules_polylang($flush_rewrite_rules, $basepage) { * 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. + * paths for the Base Page ID, those specific rewrite rules will "win" over + * the more general Base Page rules. */ $collected_rewrites = []; - // Support prefixes for a single Basepage. + // Support prefixes for a single Base Page. $basepage_url = get_permalink($basepage->ID); $basepage_raw_url = PLL()->links_model->remove_language_from_link($basepage_url); $language_slugs = pll_languages_list(); @@ -113,7 +113,7 @@ public function rewrite_rules_polylang($flush_rewrite_rules, $basepage) { } }; - // Support prefixes for Basepages in multiple languages. + // Support prefixes for Base Pages in multiple languages. foreach ($language_slugs as $slug) { $post_id = pll_get_post($basepage->ID, $slug); if (empty($post_id)) { diff --git a/includes/civicrm.shortcodes.modal.php b/includes/civicrm.shortcodes.modal.php index ae894a7..0d7f765 100644 --- a/includes/civicrm.shortcodes.modal.php +++ b/includes/civicrm.shortcodes.modal.php @@ -140,7 +140,6 @@ public function post_type_has_button() { * * @param bool $allowed True if the button is allowed, false otherwise. * @param object $screen The current WordPress screen object. - * @return bool $allowed True if the button is allowed, false otherwise. */ $allowed = apply_filters('civicrm_restrict_button_appearance', $allowed, $screen); diff --git a/includes/civicrm.shortcodes.php b/includes/civicrm.shortcodes.php index c7fd2b5..7811409 100644 --- a/includes/civicrm.shortcodes.php +++ b/includes/civicrm.shortcodes.php @@ -38,7 +38,7 @@ class CiviCRM_For_WordPress_Shortcodes { /** * @var array - * The stored shortcodes. + * The stored Shortcodes. * @since 4.6 * @access public */ @@ -46,7 +46,7 @@ class CiviCRM_For_WordPress_Shortcodes { /** * @var array - * The array of rendered shortcode markup. + * The array of rendered Shortcode markup. * @since 4.6 * @access public */ @@ -73,13 +73,13 @@ public function __construct() { } /** - * Register hooks to handle the presence of shortcodes in content. + * Register hooks to handle the presence of Shortcodes in content. * * @since 4.6 */ public function register_hooks() { - // Register the CiviCRM shortcode. + // Register the CiviCRM Shortcode. add_shortcode('civicrm', [$this, 'render_single']); // Pre-render CiviCRM content when one or more Shortcodes are detected. @@ -88,7 +88,7 @@ public function register_hooks() { } /** - * Determine if a CiviCRM shortcode is present in any of the posts about to be displayed. + * Determine if a CiviCRM Shortcode is present in any of the posts about to be displayed. * * Callback method for 'wp' hook, always called from WordPress front-end. * @@ -128,10 +128,10 @@ public function prerender($wp) { global $post; - // Check for existence of shortcode in content. + // Check for existence of Shortcode in content. if (has_shortcode($post->post_content, 'civicrm')) { - // Get CiviCRM shortcodes in this post. + // Get CiviCRM Shortcodes in this post. $shortcodes_array = $this->get_for_post($post->post_content); // Sanity check. @@ -140,7 +140,7 @@ public function prerender($wp) { // Add it to our property. $this->shortcodes[$post->ID] = $shortcodes_array; - // Bump shortcode counter. + // Bump Shortcode counter. $shortcodes_present += count($this->shortcodes[$post->ID]); } @@ -164,12 +164,12 @@ public function prerender($wp) { // Did we get any? if ($shortcodes_present) { - // We need CiviCRM initialised prior to parsing shortcodes. + // We need CiviCRM initialised prior to parsing Shortcodes. if (!$this->civi->initialize()) { return; } - // How should we handle multiple shortcodes? + // How should we handle multiple Shortcodes? if ($shortcodes_present > 1) { // Add CSS resources for front end. @@ -178,12 +178,12 @@ public function prerender($wp) { // Let's add dummy markup. foreach ($this->shortcodes as $post_id => $shortcode_array) { - // Set flag if there are multple shortcodes in this post. + // Set flag if there are multple Shortcodes in this post. $multiple = (count($shortcode_array) > 1) ? 1 : 0; foreach ($shortcode_array as $shortcode) { - // Mimic invoke in multiple shortcode context. + // Mimic invoke in multiple Shortcode context. $this->shortcode_markup[$post_id][] = $this->render_multiple($post_id, $shortcode, $multiple); } @@ -197,7 +197,7 @@ public function prerender($wp) { add_action('wp', [$this->civi, 'front_end_page_load'], 100); /* - * Since we have only one shortcode, run the_loop again. + * Since we have only one Shortcode, run the_loop again. * The DB query has already been done, so this has no significant impact. */ if (have_posts()) { @@ -212,10 +212,10 @@ public function prerender($wp) { continue; } - // The shortcode must be the first item in the shortcodes array. + // The Shortcode must be the first item in the Shortcodes array. $shortcode = $this->shortcodes[$post->ID][0]; - // Check to see if a shortcode component has been repeated? + // Check to see if a Shortcode component has been repeated? $atts = $this->get_atts($shortcode); // Test for hijacking. @@ -254,11 +254,11 @@ public function prerender($wp) { } - // Flag that we have parsed shortcodes. + // Flag that we have parsed Shortcodes. $this->shortcodes_parsed = TRUE; /** - * Broadcast that shortcodes have been parsed. + * Broadcast that Shortcodes have been parsed. * * @since 4.6 */ @@ -267,7 +267,7 @@ public function prerender($wp) { } /** - * Handles CiviCRM-defined shortcodes. + * Handles CiviCRM-defined Shortcodes. * * @since 4.6 * @@ -276,9 +276,9 @@ public function prerender($wp) { */ public function render_single($atts) { - // Do not parse shortcodes in REST context for PUT, POST and DELETE methods. + // Do not parse Shortcodes in REST context for PUT, POST and DELETE methods. if (defined('REST_REQUEST') && REST_REQUEST && (isset($_PUT) || isset($_POST) || isset($_DELETE))) { - // Return the original shortcode. + // Return the original Shortcode. $shortcode = '[civicrm'; foreach ($atts as $att => $val) { $shortcode .= ' ' . $att . '="' . $val . '"'; @@ -287,7 +287,7 @@ public function render_single($atts) { return $shortcode; } - // Check if we've already parsed this shortcode. + // Check if we've already parsed this Shortcode. global $post; if (is_object($post)) { if (!empty($this->shortcode_markup)) { @@ -301,14 +301,14 @@ public function render_single($atts) { $this->shortcode_in_post[$post->ID]++; } - // This shortcode must have been rendered. + // This Shortcode must have been rendered. return $this->shortcode_markup[$post->ID][$this->shortcode_in_post[$post->ID]]; } } } - // Preprocess shortcode attributes. + // Preprocess Shortcode attributes. $args = $this->preprocess_atts($atts); // Check for pathless Shortcode. @@ -320,18 +320,21 @@ public function render_single($atts) { * Get the markup for "pathless" Shortcodes. * * This filter allows plugins or CiviCRM Extensions to modify the markup used - * to display a shortcode that has no CiviCRM route/path. This may be: + * to display a Shortcode that has no CiviCRM route/path. This may be: * - * * Accidental due to an improperly constructed shortcode or + * * Accidental due to an improperly constructed Shortcode or * * Deliberate because a component may not require a route/path * + * Used internally by: + * + * - afform_shortcode_content() + * * @since 5.37 * - * @param str $content The default markup for an improperly constructed shortcode. - * @param array $atts The shortcode attributes array. - * @param array $args The shortcode arguments array. + * @param str $content The default markup for an improperly constructed Shortcode. + * @param array $atts The Shortcode attributes array. + * @param array $args The Shortcode arguments array. * @param str Context flag - value is either 'single' or 'multiple'. - * @return str The modified shortcode markup. */ return apply_filters('civicrm_shortcode_get_markup', $content, $atts, $args, 'single'); @@ -368,7 +371,7 @@ public function render_single($atts) { // Check permission. $argdata = $this->civi->get_request_args(); if (!$this->civi->users->check_permission($argdata['args'])) { - return $this->civi->users->get_permission_denied();; + return $this->civi->users->get_permission_denied(); } // Start buffering. @@ -383,13 +386,13 @@ public function render_single($atts) { } /** - * Return a generic display for a shortcode instead of a CiviCRM invocation. + * Return a generic display for a Shortcode instead of a CiviCRM invocation. * * @since 4.6 * * @param int $post_id The containing WordPress post ID. - * @param string $shortcode The shortcode being parsed. - * @param bool $multiple Boolean flag, TRUE if post has multiple shortcodes, FALSE otherwise. + * @param string $shortcode The Shortcode being parsed. + * @param bool $multiple Boolean flag, TRUE if post has multiple Shortcodes, FALSE otherwise. * @return string $markup Generic markup for multiple instances. */ private function render_multiple($post_id = FALSE, $shortcode = FALSE, $multiple = 0) { @@ -397,7 +400,7 @@ private function render_multiple($post_id = FALSE, $shortcode = FALSE, $multiple // Get attributes. $atts = $this->get_atts($shortcode); - // Pre-process shortcode and retrieve args. + // Pre-process Shortcode and retrieve args. $args = $this->preprocess_atts($atts); // Get pathless markup from filter callback. @@ -407,7 +410,7 @@ private function render_multiple($post_id = FALSE, $shortcode = FALSE, $multiple return apply_filters('civicrm_shortcode_get_markup', $markup, $atts, $args, 'multiple'); } - // Get data for this shortcode. + // Get data for this Shortcode. $data = $this->get_data($atts, $args); // Sanity check. @@ -433,7 +436,7 @@ private function render_multiple($post_id = FALSE, $shortcode = FALSE, $multiple // Access CiviCRM config object. $config = CRM_Core_Config::singleton(); - // Do we have multiple shortcodes? + // Do we have multiple Shortcodes? if ($multiple != 0) { $links = []; @@ -522,12 +525,11 @@ private function render_multiple($post_id = FALSE, $shortcode = FALSE, $multiple $link, /** - * Filter the CiviCRM shortcode more link text. + * Filter the CiviCRM Shortcode more link text. * * @since 4.6 * - * @param str The existing shortcode more link text. - * @return str The modified shortcode more link text. + * @param str The existing Shortcode more link text. */ apply_filters('civicrm_shortcode_more_link', __('Find out more...', 'civicrm')) @@ -547,12 +549,11 @@ private function render_multiple($post_id = FALSE, $shortcode = FALSE, $multiple $empowered = sprintf(__('Empowered by %s', 'civicrm'), $civi_link); /** - * Filter the CiviCRM shortcode footer text. + * Filter the CiviCRM Shortcode footer text. * * @since 4.6 * - * @param str $empowered The existing shortcode footer. - * @return str $empowered The modified shortcode footer. + * @param str $empowered The existing Shortcode footer. */ $footer = apply_filters('civicrm_shortcode_footer', $empowered); @@ -570,14 +571,13 @@ private function render_multiple($post_id = FALSE, $shortcode = FALSE, $multiple $markup = ob_get_clean(); /** - * Filter the computed CiviCRM shortcode markup. + * Filter the computed CiviCRM Shortcode markup. * * @since 4.6 * - * @param str $markup The computed shortcode markup. + * @param str $markup The computed Shortcode markup. * @param int $post_id The numeric ID of the WordPress post. - * @param string $shortcode The shortcode being parsed. - * @return str $markup The modified shortcode markup. + * @param string $shortcode The Shortcode being parsed. */ return apply_filters('civicrm_shortcode_render_multiple', $markup, $post_id, $shortcode); @@ -610,7 +610,7 @@ public function get_content($content) { return $content; } - // Bail if it has multiple shortcodes. + // Bail if it has multiple Shortcodes. if (count($this->shortcode_markup[$post->ID]) > 1) { return $content; } @@ -635,7 +635,7 @@ public function get_title($title, $post_id) { return $title; } - // Bail if it has multiple shortcodes. + // Bail if it has multiple Shortcodes. if (count($this->shortcode_markup[$post_id]) > 1) { return $title; } @@ -724,12 +724,12 @@ private function get_for_post($content) { } /** - * Return attributes for a given CiviCRM shortcode. + * Return attributes for a given CiviCRM Shortcode. * * @since 4.6 * - * @param $shortcode The shortcode to parse. - * @return array $shortcode_atts Array of shortcode attributes. + * @param $shortcode The Shortcode to parse. + * @return array $shortcode_atts Array of Shortcode attributes. */ private function get_atts($shortcode) { @@ -745,7 +745,7 @@ private function get_atts($shortcode) { } /** - * Preprocess CiviCRM-defined shortcodes. + * Preprocess CiviCRM-defined Shortcodes. * * @since 4.6 * @@ -882,30 +882,29 @@ public function preprocess_atts($atts) { } /** - * Filter the CiviCRM shortcode arguments. + * Filter the CiviCRM Shortcode arguments. * * This filter allows plugins or CiviCRM Extensions to modify the attributes - * that the 'civicrm' shortcode allows. Injected attributes and their values + * that the 'civicrm' Shortcode allows. Injected attributes and their values * will also become available in the $_REQUEST and $_GET arrays. * * @since 4.7.28 * - * @param array $args Existing shortcode arguments. + * @param array $args Existing Shortcode arguments. * @param array $shortcode_atts Shortcode attributes. - * @return array $args Modified shortcode arguments. */ return apply_filters('civicrm_shortcode_preprocess_atts', $args, $shortcode_atts); } /** - * Post-process CiviCRM-defined shortcodes. + * Post-process CiviCRM-defined Shortcodes. * * @since 4.6 * * @param array $atts Shortcode attributes array. * @param array $args Shortcode arguments array. - * @return array|bool $data The array data used to build the shortcode markup, or false on failure. + * @return array|bool $data The array data used to build the Shortcode markup, or false on failure. */ public function get_data($atts, $args) { @@ -920,18 +919,16 @@ public function get_data($atts, $args) { * Filter the base CiviCRM API parameters. * * This filter allows plugins or CiviCRM Extensions to modify the API call - * when there are multiple shortcodes being rendered. + * when there are multiple Shortcodes being rendered. * * @since 4.7.28 * * @param array $params Existing API params. * @param array $atts Shortcode attributes array. * @param array $args Shortcode arguments array. - * @return array $params Modified API params. */ $params = apply_filters('civicrm_shortcode_api_params', [ - 'version' => 3, - 'sequential' => '1', + 'sequential' => 1, ], $atts, $args); // Get the CiviCRM entity via the API. @@ -943,7 +940,7 @@ public function get_data($atts, $args) { $params['id'] = $args['id']; // Call API. - $civi_entity = civicrm_api('contribution_page', 'getsingle', $params); + $civi_entity = civicrm_api3('ContributionPage', 'getsingle', $params); // Set title. $data['title'] = $civi_entity['title']; @@ -962,7 +959,7 @@ public function get_data($atts, $args) { $params['id'] = $args['id']; // Call API. - $civi_entity = civicrm_api('event', 'getsingle', $params); + $civi_entity = civicrm_api3('Event', 'getsingle', $params); // Set title. switch ($atts['action']) { @@ -1006,7 +1003,7 @@ public function get_data($atts, $args) { $params['id'] = $args['gid']; // Call API. - $civi_entity = civicrm_api('uf_group', 'getsingle', $params); + $civi_entity = civicrm_api3('UFGroup', 'getsingle', $params); // Set title. $data['title'] = $civi_entity['title']; @@ -1021,7 +1018,7 @@ public function get_data($atts, $args) { $params['id'] = $atts['id']; // Call API. - $civi_entity = civicrm_api('survey', 'getsingle', $params); + $civi_entity = civicrm_api3('Survey', 'getsingle', $params); // Set title. $data['title'] = $civi_entity['title']; @@ -1035,23 +1032,22 @@ public function get_data($atts, $args) { break; default: - // Do we need to protect against malformed shortcodes? + // Do we need to protect against malformed Shortcodes? break; } /** - * Filter the CiviCRM shortcode data array. + * Filter the CiviCRM Shortcode data array. * * This filter allows plugins or CiviCRM Extensions to modify the data used - * to display the shortcode when there are multiple shortcodes being rendered. + * to display the Shortcode when there are multiple Shortcodes being rendered. * * @since 4.7.28 * - * @param array $data The existing shortcode data. + * @param array $data The existing Shortcode data. * @param array $atts Shortcode attributes array. * @param array $args Shortcode arguments array. - * @return array $data The modified shortcode data. */ return apply_filters('civicrm_shortcode_get_data', $data, $atts, $args); diff --git a/includes/civicrm.users.php b/includes/civicrm.users.php index e4ee2f7..14a384f 100644 --- a/includes/civicrm.users.php +++ b/includes/civicrm.users.php @@ -47,7 +47,7 @@ public function __construct() { $this->civi = civi_wp(); // Always listen for activation action. - add_action('civicrm_activation', [$this, 'activate']); + add_action('civicrm_activate', [$this, 'activate']); } @@ -59,7 +59,7 @@ public function __construct() { public function activate() { /* - * Assign minimum capabilities for all WordPress roles and create + * Assign minimum capabilities to all WordPress roles and create * 'anonymous_user' role. */ $this->set_wp_user_capabilities(); @@ -86,14 +86,22 @@ public function register_hooks() { add_action('profile_update', [$this, 'update_user']); // Delete ufMatch record when a WordPress user is deleted. - add_action('deleted_user', [$this, 'delete_user_ufmatch'], 10, 1); + add_action('deleted_user', [$this, 'delete_user_ufmatch']); } /** * Check permissions. * - * Authentication function used by basepage_register_hooks() + * This method only denies permission when the CiviCRM path that is requested + * begins with "civicrm/admin". Its intention seems to be to exclude admin + * requests from display on the front-end. + * + * Used internally by: + * + * - CiviCRM_For_WordPress_Basepage::basepage_handler() + * - CiviCRM_For_WordPress_Shortcodes::render_single() + * - civicrm_check_permission() * * @since 4.6 * @@ -113,7 +121,7 @@ public function check_permission($args) { require_once 'CRM/Utils/Array.php'; - // All profile and file urls, as well as user dashboard and tell-a-friend are valid. + // All profile and file URLs, as well as user dashboard and tell-a-friend are valid. $arg1 = CRM_Utils_Array::value(1, $args); $invalidPaths = ['admin']; if (in_array($arg1, $invalidPaths)) { @@ -195,8 +203,8 @@ public function update_user($user_id) { */ public function sync_user($user = FALSE) { - // Sanity check - if ($user === FALSE || !is_a($user, 'WP_User')) { + // Sanity check. + if ($user === FALSE || !($user instanceof WP_User)) { return; } @@ -258,11 +266,6 @@ public function delete_user_ufmatch($user_id) { */ public function set_wp_user_capabilities() { - global $wp_roles; - if (!isset($wp_roles)) { - $wp_roles = new WP_Roles(); - } - // Define minimum capabilities (CiviCRM permissions). $default_min_capabilities = [ 'access_civimail_subscribe_unsubscribe_pages' => 1, @@ -284,11 +287,11 @@ public function set_wp_user_capabilities() { * @since 4.6 * * @param array $default_min_capabilities The minimum capabilities. - * @return array $default_min_capabilities The modified capabilities. */ $min_capabilities = apply_filters('civicrm_min_capabilities', $default_min_capabilities); // Assign the minimum capabilities to all WordPress roles. + $wp_roles = wp_roles(); foreach ($wp_roles->role_names as $role => $name) { $roleObj = $wp_roles->get_role($role); foreach ($min_capabilities as $capability_name => $capability_value) { @@ -298,11 +301,7 @@ public function set_wp_user_capabilities() { // Add the 'anonymous_user' role with minimum capabilities. if (!in_array('anonymous_user', $wp_roles->roles)) { - add_role( - 'anonymous_user', - __('Anonymous User', 'civicrm'), - $min_capabilities - ); + add_role('anonymous_user', __('Anonymous User', 'civicrm'), $min_capabilities); } } @@ -319,11 +318,7 @@ public function set_wp_user_capabilities() { */ public function set_access_capabilities() { - // Test for existing global - global $wp_roles; - if (!isset($wp_roles)) { - $wp_roles = new WP_Roles(); - } + $wp_roles = wp_roles(); /** * Filter the default roles with access to CiviCRM. @@ -334,7 +329,6 @@ public function set_access_capabilities() { * @since 4.6 * * @param array The default roles with access to CiviCRM. - * @return array The modified roles with access to CiviCRM. */ $roles = apply_filters('civicrm_access_roles', ['super admin', 'administrator']); diff --git a/uninstall.php b/uninstall.php index 4dfde30..ae999bb 100644 --- a/uninstall.php +++ b/uninstall.php @@ -24,3 +24,8 @@ // Delete options that this plugin has set. delete_option('civicrm_activation_in_progress'); +delete_option('civicrm_rules_flushed'); + +// TODO: Remove the CiviCRM Base Page(s). +// TODO: Remove the directory/directories that "civicrm.settings.php" lives in. +// TODO: Remove the CiviCRM database(s). diff --git a/wp-cli/LICENSE b/wp-cli/LICENSE deleted file mode 100644 index 3ffc567..0000000 --- a/wp-cli/LICENSE +++ /dev/null @@ -1,661 +0,0 @@ -GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU Affero General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - -Also add information on how to contact you by electronic and paper mail. - - If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see -<http://www.gnu.org/licenses/>. \ No newline at end of file diff --git a/wp-cli/civicrm.php b/wp-cli/civicrm.php index e13d2b2..fe93a39 100644 --- a/wp-cli/civicrm.php +++ b/wp-cli/civicrm.php @@ -9,15 +9,22 @@ +--------------------------------------------------------------------+ */ +/** + * + * @package CRM + * @copyright CiviCRM LLC https://civicrm.org/licensing + * + */ + if (!defined('CIVICRM_WPCLI_LOADED')) { define('CIVICRM_WPCLI_LOADED', 1); /** - * WP-CLI port of drush-civicrm integration - * andyw@circle, 08/03/2014 + * WP-CLI port of drush-civicrm integration. + * + * @see https://github.com/andy-walker/wp-cli-civicrm * - * Distributed under the GNU Affero General Public License, version 3 - * http://www.gnu.org/licenses/agpl-3.0.html + * @since 4.5 */ class CiviCRM_Command extends WP_CLI_Command { @@ -28,27 +35,27 @@ class CiviCRM_Command extends WP_CLI_Command { * WP-CLI integration with CiviCRM. * * wp civicrm api - * =============== - * Command for accessing CiviCRM APIs. Syntax is identical to drush cvap. + * ============== + * Command for accessing the CiviCRM API. Syntax is identical to `drush cvap`. * * wp civicrm cache-clear - * =============== - * Command for accessing clearing cache. Equivilant of running civicrm/admin/setting/updateConfigBackend&reset=1 + * ====================== + * Command for accessing clearing cache. Equivilant of running `civicrm/admin/setting/updateConfigBackend&reset=1`. * * wp civicrm enable-debug - * =============== + * ======================= * Command for to turn debug on. * * wp civicrm disable-debug - * =============== + * ======================== * Command for to turn debug off. * * wp civicrm member-records - * =============== + * ========================= * Run the CiviMember UpdateMembershipRecord cron (civicrm member-records). * * wp civicrm process-mail-queue - * =============== + * ============================= * Process pending CiviMail mailing jobs. * Example: * wp civicrm process-mail-queue -u admin @@ -59,15 +66,15 @@ class CiviCRM_Command extends WP_CLI_Command { * * wp civicrm restore * ================== - * Restore CiviCRM codebase and database back from the specified backup directory + * Restore CiviCRM codebase and database back from the specified backup directory. * * wp civicrm sql-conf * =================== - * Show civicrm database connection details. + * Show CiviCRM database connection details. * * wp civicrm sql-connect * ====================== - * A string which connects to the civicrm database. + * A string which connects to the CiviCRM database. * * wp civicrm sql-cli * ================== @@ -80,11 +87,11 @@ class CiviCRM_Command extends WP_CLI_Command { * wp civicrm sql-query * ==================== * Usage: wp civicrm sql-query <query> <options>... - * <query> is a SQL statement, which can alternatively be passed via STDIN. Any additional arguments are passed to the mysql command directly."; + * <query> is a SQL statement, which can alternatively be passed via STDIN. Any additional arguments are passed to the mysql command directly. * * wp civicrm update-cfg * ===================== - * Update config_backend to correct config settings, especially when the CiviCRM site has been cloned / migrated. + * Update config_backend to correct config settings, especially when the CiviCRM site has been cloned or migrated. * * wp civicrm upgrade * ================== @@ -95,7 +102,7 @@ class CiviCRM_Command extends WP_CLI_Command { * Run civicrm/upgrade?reset=1 just as a web browser would. * * wp civicrm install - * =============== + * ================== * Command for to install CiviCRM. The install command requires that you have downloaded a tarball or zip file first. * Options: * --dbhost MySQL host for your WordPress/CiviCRM database. Defaults to localhost. @@ -107,6 +114,7 @@ class CiviCRM_Command extends WP_CLI_Command { * --site_url Base Url for your WordPress/CiviCRM website without http (e.g. mysite.com) * --ssl Using ssl for your WordPress/CiviCRM website if set to on (e.g. --ssl=on) * --tarfile Path to your CiviCRM tar.gz file. + * --zipfile Path to your CiviCRM zip file. * */ public function __invoke($args, $assoc_args) { @@ -114,7 +122,7 @@ public function __invoke($args, $assoc_args) { $this->args = $args; $this->assoc_args = $assoc_args; - # define command router + // Define command router. $command_router = [ 'api' => 'api', 'cache-clear' => 'cacheClear', @@ -135,26 +143,33 @@ public function __invoke($args, $assoc_args) { 'upgrade-db' => 'upgradeDB', ]; - # get command + // Get the command. $command = array_shift($args); - # check for existence of Civi (except for command 'install') - if (!function_exists('civicrm_initialize') and 'install' != $command) { + // Allow help to pass. + if ('help' === $command) { + return; + } + + // Check for existence of CiviCRM (except for command 'install'). + if (!function_exists('civicrm_initialize') && 'install' != $command) { return WP_CLI::error('Unable to find CiviCRM install.'); } - # check existence of router entry / handler method - if (!isset($command_router[$command]) or !method_exists($this, $command_router[$command])) { - return WP_CLI::error("Unrecognized command - '$command'"); + // Check existence of router entry / handler method. + if (!isset($command_router[$command]) || !method_exists($this, $command_router[$command])) { + return WP_CLI::error(sprintf('Unrecognized command: %s', $command)); } - # run command + // Run command. return $this->{$command_router[$command]}(); } /** - * Implementation of command 'api' + * Implementation of command 'api'. + * + * @since 4.5 */ private function api() { @@ -164,11 +179,11 @@ private function api() { list($entity, $action) = explode('.', $this->args[0]); array_shift($this->args); - # parse $params + // Parse params. $format = $this->getOption('in', 'args'); switch ($format) { - # input params supplied via args .. + // Input params supplied via args. case 'args': $params = $defaults; foreach ($this->args as $arg) { @@ -177,20 +192,21 @@ private function api() { } break; - # input params supplied via json .. + // Input params supplied via json. case 'json': $json = stream_get_contents(STDIN); $params = (empty($json) ? $defaults : array_merge($defaults, json_decode($json, TRUE))); break; default: - WP_CLI::error('Unknown format: ' . $format); + WP_CLI::error(sprintf('Unknown format: %s', $format)); break; + } civicrm_initialize(); - // CRM-18062: Set CiviCRM timezone if any + // CRM-18062: Set CiviCRM timezone if any. $wp_base_timezone = date_default_timezone_get(); $wp_user_timezone = $this->getOption('timezone', get_option('timezone_string')); if ($wp_user_timezone) { @@ -200,32 +216,34 @@ private function api() { $result = civicrm_api($entity, $action, $params); - // restore WP's timezone + // Restore WordPress's timezone. if ($wp_base_timezone) { date_default_timezone_set($wp_base_timezone); } switch ($this->getOption('out', 'pretty')) { - # pretty-print output (default) + // Pretty-print output (default). case 'pretty': WP_CLI::line(print_r($result, TRUE)); break; - # display output as json + // Display output as json. case 'json': WP_CLI::line(json_encode($result)); break; default: - return WP_CLI::error('Unknown format: ' . $format); + return WP_CLI::error(sprintf('Unknown format: %s', $format)); } } /** - * Implementation of command 'cache-clear' + * Implementation of command 'cache-clear'. + * + * @since 4.5 */ private function cacheClear() { @@ -233,20 +251,22 @@ private function cacheClear() { require_once 'CRM/Core/Config.php'; $config = CRM_Core_Config::singleton(); - # clear db caching + // Clear db caching. $config->clearDBCache(); - # also cleanup the templates_c directory + // Also cleanup the templates_c directory. $config->cleanup(1, FALSE); - # also cleanup the session object + // Also cleanup the session object. $session = CRM_Core_Session::singleton(); $session->reset(1); } /** - * Implementation of command 'enable-debug' + * Implementation of command 'enable-debug'. + * + * @since 4.5 */ private function enableDebug() { civicrm_initialize(); @@ -258,7 +278,9 @@ private function enableDebug() { } /** - * Implementation of command 'disable-debug' + * Implementation of command 'disable-debug'. + * + * @since 4.7 */ private function disableDebug() { civicrm_initialize(); @@ -270,34 +292,30 @@ private function disableDebug() { } /** - * Implementation of command 'install' + * Implementation of command 'install'. + * + * @since 4.5 */ private function install() { - # validate - + // Validate. if (!$dbuser = $this->getOption('dbuser', FALSE)) { return WP_CLI::error('CiviCRM database username not specified.'); } - if (!$dbpass = $this->getOption('dbpass', FALSE)) { return WP_CLI::error('CiviCRM database password not specified.'); } - if (!$dbhost = $this->getOption('dbhost', FALSE)) { return WP_CLI::error('CiviCRM database host not specified.'); } - if (!$dbname = $this->getOption('dbname', FALSE)) { return WP_CLI::error('CiviCRM database name not specified.'); } - - if ($lang = $this->getOption('lang', FALSE) and !$langtarfile = $this->getOption('langtarfile', FALSE)) { + if ($lang = $this->getOption('lang', FALSE) && !$langtarfile = $this->getOption('langtarfile', FALSE)) { return WP_CLI::error('CiviCRM language tarfile not specified.'); } - # begin install - + // Begin install. if ($plugin_path = $this->getOption('destination', FALSE)) { $plugin_path = ABSPATH . $plugin_path; } @@ -309,10 +327,10 @@ private function install() { $crmPath = "$plugin_path/civicrm"; $crm_files_present = is_dir($crmPath); - # extract the archive + // Extract the archive. if ($this->getOption('tarfile', FALSE)) { - # should probably never get to here as Wordpress Civi comes in a zip file, but - # just in case that ever changes .. + // Should probably never get to here as WordPress CiviCRM comes as a zip file. + // Check anyway just in case that ever changes. if ($crm_files_present) { return WP_CLI::error('Existing CiviCRM found. No action taken.'); } @@ -327,19 +345,18 @@ private function install() { } if (!$this->unzip(dirname($plugin_path))) { - return WP_CLI::error('Error extracting zipfile'); + return WP_CLI::error('Error extracting zipfile.'); } } elseif ($crm_files_present) { - // Site is already extracted (which is how we're running this - // script); we just need to run the installer. - + // Site is already extracted - which is how we're running this script. + // We just need to run the installer. } else { - return WP_CLI::error('No zipfile specified, use --zipfile=path/to/zipfile or extract file ahead of time'); + return WP_CLI::error('No zipfile specified, use "--zipfile=path/to/zipfile" or extract file ahead of time.'); } - # include civicrm installer helper file + // Include CiviCRM Installer helper file. $civicrm_installer_helper = "$crmPath/install/civicrm.php"; if (!file_exists($civicrm_installer_helper)) { @@ -351,25 +368,25 @@ private function install() { WP_CLI::success('Using installer files found on the site.'); } else { - // We must've just unpacked the archive because it wasn't there - // before. + // We must've just unpacked the archive because it wasn't there before. WP_CLI::success('Archive unpacked.'); } + require_once $civicrm_installer_helper; if ('' != $lang) { if (!$this->untar($plugin_path, 'langtarfile')) { - return WP_CLI::error('No language tarfile specified, use --langtarfile=path/to/tarfile'); + return WP_CLI::error('No language tarfile specified, use "--langtarfile=path/to/tarfile".'); } } - # create files dirs + // Create files dirs. $upload_dir = wp_upload_dir(); $settings_dir = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR; civicrm_setup($upload_dir['basedir'] . DIRECTORY_SEPARATOR); WP_CLI::launch("chmod -R 0755 " . escapeshellarg($settings_dir)); - # now we've got some files in place, require PEAR DB and check db setup + // Now we've got some files in place, require PEAR DB and check db setup. $dsn = "mysql://{$dbuser}:{$dbpass}@{$dbhost}/{$dbname}?new_link=true"; $dsn_nodb = "mysql://{$dbuser}:{$dbpass}@{$dbhost}"; @@ -392,29 +409,28 @@ private function install() { $db->disconnect(); } - # install db + // Install database. global $sqlPath; - # setup database with civicrm structure and data - WP_CLI::line('Loading CiviCRM database structure ..'); + // Setup database with CiviCRM structure and data. + WP_CLI::line('Loading CiviCRM database structure...'); civicrm_source($dsn, $sqlPath . '/civicrm.mysql'); - WP_CLI::line('Loading CiviCRM database with required data ..'); + WP_CLI::line('Loading CiviCRM database with required data...'); - # testing the translated sql files availability + // Testing the translated sql files availability. $data_file = $sqlPath . '/civicrm_data.mysql'; $acl_file = $sqlPath . '/civicrm_acl.mysql'; if ('' != $lang) { - if (file_exists($sqlPath . '/civicrm_data.' . $lang . '.mysql') - and file_exists($sqlPath . '/civicrm_acl.' . $lang . '.mysql') - and '' != $lang + && file_exists($sqlPath . '/civicrm_acl.' . $lang . '.mysql') + && '' != $lang ) { $data_file = $sqlPath . '/civicrm_data.' . $lang . '.mysql'; $acl_file = $sqlPath . '/civicrm_acl.' . $lang . '.mysql'; } else { - WP_CLI::warning("No sql files could be retrieved for '$lang' using default language."); + WP_CLI::warning(sprintf('No SQL files could be retrieved for "%s" using default language.', $lang)); } } @@ -423,13 +439,13 @@ private function install() { WP_CLI::success('CiviCRM database loaded successfully.'); - # generate civicrm.settings.php file + // Generate "civicrm.settings.php" file. global $tplPath; if (!file_exists($tplPath . 'civicrm.settings.php.template')) { return WP_CLI::error('Could not find CiviCRM settings template and therefore could not create settings file.'); } - WP_CLI::line('Generating civicrm settings file ..'); + WP_CLI::line('Generating CiviCRM settings file...'); if ($base_url = $this->getOption('site_url', FALSE)) { $ssl = $this->getOption('ssl', FALSE); @@ -474,14 +490,34 @@ private function install() { WP_CLI::launch("chmod 0644 $config_file"); WP_CLI::success(sprintf('Settings file generated: %s', $config_file)); - # activate plugin and we're done + // Activate plugin. @WP_CLI::run_command(['plugin', 'activate', 'civicrm'], []); + + // Bootstrap the plugin. + $civicrm = civi_wp(); + $civicrm->include_files(); + $civicrm->setup_objects(); + $civicrm->enable_translation(); + + // Add the "wpLoadPhp" setting. + $civicrm->admin->add_wpload_setting(); + + // Add Base Page and "wpBasePage" setting. + $basepage = $civicrm->basepage->create_wp_basepage(); + if (!$basepage) { + return WP_CLI::error('Could not create the Base Page.'); + } + WP_CLI::success('Base Page created successfully.'); + + // Now we're done. WP_CLI::success('CiviCRM installed.'); } /** - * Implementation of command 'member-records' + * Implementation of command 'member-records'. + * + * @since 4.5 */ private function memberRecords() { @@ -491,7 +527,7 @@ private function memberRecords() { $job = new CRM_Core_JobManager(); $job->executeJobByAction('job', 'process_membership'); - WP_CLI::success("Executed 'process_membership' job."); + WP_CLI::success('Executed "process_membership" job.'); } else { @@ -520,7 +556,9 @@ private function memberRecords() { } /** - * Implementation of command 'process-mail-queue' + * Implementation of command 'process-mail-queue'. + * + * @since 4.5 */ private function processMailQueue() { @@ -544,7 +582,9 @@ private function processMailQueue() { } /** - * Implementation of command 'rest' + * Implementation of command 'rest'. + * + * @since 4.5 */ private function rest() { @@ -570,7 +610,7 @@ private function rest() { $config = CRM_Core_Config::singleton(); global $civicrm_root; - // adding dummy script, since based on this api file path is computed. + // Adding dummy script, since based on this api file path is computed. $_SERVER['SCRIPT_FILENAME'] = "$civicrm_root/extern/rest.php"; if (isset($_GET['json']) && $_GET['json']) { @@ -585,31 +625,33 @@ private function rest() { } /** - * Implementation of command 'restore' + * Implementation of command 'restore'. + * + * @since 4.5 */ private function restore() { - # validate .. + // Validate. $restore_dir = $this->getOption('restore-dir', FALSE); $restore_dir = rtrim($restore_dir, '/'); if (!$restore_dir) { - return WP_CLI::error('Restore-dir not specified.'); + return WP_CLI::error('"restore-dir" not specified.'); } $sql_file = $restore_dir . '/civicrm.sql'; if (!file_exists($sql_file)) { - return WP_CLI::error('Could not locate civicrm.sql file in the restore directory.'); + return WP_CLI::error('Could not locate "civicrm.sql" file in the restore directory.'); } $code_dir = $restore_dir . '/civicrm'; if (!is_dir($code_dir)) { - return WP_CLI::error('Could not locate civicrm directory inside restore-dir.'); + return WP_CLI::error('Could not locate the CiviCRM directory inside "restore-dir".'); } - elseif (!file_exists("$code_dir/civicrm/civicrm-version.txt") and !file_exists("$code_dir/civicrm/civicrm-version.php")) { - return WP_CLI::error('civicrm directory inside restore-dir, doesn\'t look to be a valid civicrm codebase.'); + elseif (!file_exists("$code_dir/civicrm/civicrm-version.txt") && !file_exists("$code_dir/civicrm/civicrm-version.php")) { + return WP_CLI::error('The CiviCRM directory inside "restore-dir" does not seem to be a valid CiviCRM codebase.'); } - # prepare to restore .. + // Prepare to restore. $date = date('YmdHis'); civicrm_initialize(); @@ -632,7 +674,7 @@ private function restore() { $restore_backup_dir = $this->getOption('backup-dir', $wp_root . '/../backup'); $restore_backup_dir = rtrim($restore_backup_dir, '/'); - # get confirmation from user - + // Get confirmation from user. if (!defined('CIVICRM_DSN')) { WP_CLI::error('CIVICRM_DSN is not defined.'); @@ -645,7 +687,7 @@ private function restore() { WP_CLI::line(sprintf("2. Dropping and creating '%s' database.", $db_spec['database'])); WP_CLI::line("3. Loading '\$restore-dir/civicrm.sql' file into the database."); WP_CLI::line(''); - WP_CLI::line(sprintf("Note: Before restoring a backup will be taken in '%s' directory.", "$restore_backup_dir/plugins/restore")); + WP_CLI::line(sprintf("Note: Before restoring, a backup will be taken in '%s' directory.", "$restore_backup_dir/plugins/restore")); WP_CLI::line(''); WP_CLI::confirm('Do you really want to continue?'); @@ -653,22 +695,22 @@ private function restore() { $restore_backup_dir .= '/plugins/restore/' . $date; if (!mkdir($restore_backup_dir, 0755, TRUE)) { - return WP_CLI::error('Failed creating directory: ' . $restore_backup_dir); + return WP_CLI::error(sprintf('Failed to create directory: %s', $restore_backup_dir)); } - # 1. backup and restore codebase - WP_CLI::line('Restoring civicrm codebase ..'); + // 1. Backup and restore codebase. + WP_CLI::line('Restoring CiviCRM codebase...'); if (is_dir($project_path) && !rename($project_path, $restore_backup_dir . '/civicrm')) { return WP_CLI::error(sprintf("Failed to take backup for '%s' directory", $project_path)); } if (!rename($code_dir, $project_path)) { - return WP_CLI::error("Failed to restore civicrm directory '%s' to '%s'", $code_dir, $project_path); + return WP_CLI::error(sprintf("Failed to restore CiviCRM directory '%s' to '%s'", $code_dir, $project_path)); } WP_CLI::success('Codebase restored.'); - # 2. backup, drop and create database + // 2. Backup, drop and create database. WP_CLI::run_command( ['civicrm', 'sql-dump'], ['result-file' => $restore_backup_dir . '/civicrm.sql'] @@ -676,8 +718,7 @@ private function restore() { WP_CLI::success('Database backed up.'); - # prepare a mysql command-line string for issuing - # db drop / create commands + // Prepare a mysql command-line string for issuing db drop/create commands. $command = sprintf( 'mysql --user=%s --password=%s', $db_spec['username'], @@ -688,31 +729,31 @@ private function restore() { $command .= ' --host=' . $db_spec['hostspec']; } - if (isset($dsn['port']) and !mpty($dsn['port'])) { + if (isset($dsn['port']) && !mpty($dsn['port'])) { $command .= ' --port=' . $db_spec['port']; } - # attempt to drop old database + // Attempt to drop old database. if (system($command . sprintf(' --execute="DROP DATABASE IF EXISTS %s"', $db_spec['database']))) { - return WP_CLI::error('Could not drop database: ' . $db_spec['database']); + return WP_CLI::error(sprintf('Could not drop database: %s', $db_spec['database'])); } WP_CLI::success('Database dropped.'); - # attempt to create new database + // Attempt to create new database. if (system($command . sprintf(' --execute="CREATE DATABASE %s"', $db_spec['database']))) { - WP_CLI::error('Could not create new database: ' . $db_spec['database']); + WP_CLI::error(sprintf('Could not create new database: %s', $db_spec['database'])); } WP_CLI::success('Database created.'); - # 3. restore database - WP_CLI::line('Loading civicrm.sql file from restore-dir ..'); + // 3. Restore database. + WP_CLI::line('Loading "civicrm.sql" file from "restore-dir"...'); system($command . ' ' . $db_spec['database'] . ' < ' . $sql_file); WP_CLI::success('Database restored.'); - WP_CLI::line('Clearing caches..'); + WP_CLI::line('Clearing caches...'); WP_CLI::run_command(['civicrm', 'cache-clear']); WP_CLI::success('Restore process completed.'); @@ -720,7 +761,9 @@ private function restore() { } /** - * Implementation of command 'sql-conf' + * Implementation of command 'sql-conf'. + * + * @since 4.5 */ private function sqlConf() { @@ -734,7 +777,9 @@ private function sqlConf() { } /** - * Implementation of command 'sql-connect' + * Implementation of command 'sql-connect'. + * + * @since 4.5 */ private function sqlConnect() { @@ -753,7 +798,7 @@ private function sqlConnect() { $dsn['password'] ); - if (isset($dsn['port']) and !empty($dsn['port'])) { + if (isset($dsn['port']) && !empty($dsn['port'])) { $command .= ' --port=' . $dsn['port']; } @@ -762,16 +807,18 @@ private function sqlConnect() { } /** - * Implementation of command 'sql-dump' + * Implementation of command 'sql-dump'. + * + * @since 4.5 */ private function sqlDump() { - # bootstrap Civi when we're not being called as part of an upgrade + // Bootstrap CiviCRM when we're not being called as part of an upgrade. if (!defined('CIVICRM_UPGRADE_ACTIVE')) { civicrm_initialize(); } - if (!defined('CIVICRM_DSN') and !defined('CIVICRM_OLD_DSN')) { + if (!defined('CIVICRM_DSN') && !defined('CIVICRM_OLD_DSN')) { WP_CLI::error('DSN is not defined.'); } @@ -809,7 +856,9 @@ private function sqlDump() { } /** - * Implementation of command 'sql-query' + * Implementation of command 'sql-query'. + * + * @since 4.5 */ private function sqlQuery() { @@ -840,7 +889,9 @@ private function sqlQuery() { } /** - * Implementation of command 'sql-cli' + * Implementation of command 'sql-cli'. + * + * @since 4.5 */ private function sqlCLI() { @@ -863,7 +914,9 @@ private function sqlCLI() { } /** - * Implementation of command 'update-cfg' + * Implementation of command 'update-cfg'. + * + * @since 4.5 */ private function updateConfig() { @@ -891,8 +944,8 @@ private function updateConfig() { if ($result) { - # attempt to preserve webserver ownership of templates_c, civicrm/upload - if ($webserver_user and $webserver_group) { + // Attempt to preserve webserver ownership of templates_c, civicrm/upload. + if ($webserver_user && $webserver_group) { $upload_dir = wp_upload_dir(); $civicrm_files_dir = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR; system(sprintf('chown -R %s:%s %s/templates_c', $webserver_user, $webserver_group, $civicrm_files_dir)); @@ -909,17 +962,19 @@ private function updateConfig() { } /** - * Implementation of command 'upgrade' + * Implementation of command 'upgrade'. + * + * @since 4.5 */ private function upgrade() { - # todo: use wp-cli to download tarfile. - # todo: if tarfile is not specified, see if the code already exists and use that instead. - if (!$this->getOption('tarfile', FALSE) and !$this->getOption('zipfile', FALSE)) { + // TODO: Use wp-cli to download tarfile. + // TODO: If tarfile is not specified, see if the code already exists and use that instead. + if (!$this->getOption('tarfile', FALSE) && !$this->getOption('zipfile', FALSE)) { return WP_CLI::error('Must specify either --tarfile or --zipfile'); } - # fixme: throw error if tarfile is not in a valid format. + // FIXME: Throw error if tarfile is not in a valid format. if (!defined('CIVICRM_UPGRADE_ACTIVE')) { define('CIVICRM_UPGRADE_ACTIVE', 1); } @@ -930,18 +985,20 @@ private function upgrade() { $upload_dir = wp_upload_dir(); $settings_file = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'civicrm.settings.php'; if (!file_exists($legacy_settings_file) && !file_exists($settings_file)) { - return WP_CLI::error('Unable to locate settings file at ' . $legacy_settings_file . 'or at ' . $settings_file); + return WP_CLI::error(sprintf('Unable to locate settings file at "%s" or at "%s"', $legacy_settings_file, $settings_file)); } - # nb: we don't want to require civicrm.settings.php here, because .. - # - # a) this is the old environment we're going to replace - # b) upgrade-db needs to bootstrap the new environment, so requiring the file - # now will create multiple inclusion problems later on - # - # however, all we're really after is $civicrm_root and CIVICRM_DSN, so we're going to - # pull out the lines we need using a regex and run them - yes, it's pretty silly .. - # don't try this at home, kids. + /* + * We don't want to require "civicrm.settings.php" here, because: + * + * a) This is the old environment we're going to replace. + * b) upgrade-db needs to bootstrap the new environment, so requiring the file + * now will create multiple inclusion problems later on. + * + * However, all we're really after is $civicrm_root and CIVICRM_DSN, so we're going to + * pull out the lines we need using a regex and run them - yes, it's pretty silly. + * Don't try this at home, kids. + */ $legacy_settings = file_get_contents($legacy_settings_file); $legacy_settings = str_replace("\r", '', $legacy_settings); @@ -975,7 +1032,7 @@ private function upgrade() { } if (!defined('CIVICRM_OLD_DSN')) { - return WP_CLI::error('Unable to set CIVICRM_OLD_DSN'); + return WP_CLI::error('Unable to set CIVICRM_OLD_DSN.'); } $date = date('YmdHis'); @@ -995,29 +1052,26 @@ private function upgrade() { $backup_dir = $this->getOption('backup-dir', $wp_root . '../backup'); $backup_dir = rtrim($backup_dir, '/'); - WP_CLI::line("\nThe upgrade process involves - "); + WP_CLI::line(); + WP_CLI::line('The upgrade process involves:'); WP_CLI::line(sprintf('1. Backing up current CiviCRM code as => %s', "$backup_dir/plugins/$date/$backup_file")); WP_CLI::line(sprintf('2. Backing up database as => %s', "$backup_dir/plugins/$date/$backup_file.sql")); WP_CLI::line(sprintf('3. Unpacking tarfile to => %s', $plugin_path)); - WP_CLI::line("4. Executing civicrm/upgrade?reset=1 just as a browser would.\n"); + WP_CLI::line('4. Executing "civicrm/upgrade?reset=1" just as a browser would.'); + WP_CLI::line(); WP_CLI::confirm('Do you really want to continue?'); - # begin upgrade - + // Begin upgrade. $backup_dir .= '/plugins/' . $date; if (!mkdir($backup_dir, 0755, TRUE)) { - return WP_CLI::error('Failed creating directory: ' . $backup_dir); + return WP_CLI::error(sprintf('Failed to create directory: %s', $backup_dir)); } $backup_target = $backup_dir . '/' . $backup_file; if (!rename($project_path, $backup_target)) { - return WP_CLI::error(sprintf( - 'Failed to backup CiviCRM project directory %s to %s', - $project_path, - $backup_target - )); + return WP_CLI::error(sprintf('Failed to backup CiviCRM project directory %s to %s', $project_path, $backup_target)); } WP_CLI::line(); @@ -1030,10 +1084,9 @@ private function upgrade() { WP_CLI::success('2. Database backed up.'); - # decompress + // Decompress. if ($this->getOption('tarfile', FALSE)) { - # should probably never get to here, as looks like Wordpress Civi comes - # in a zip file + // Should probably never get to here, because WordPress CiviCRM comes in a zip file. if (!$this->untar($plugin_path)) { return WP_CLI::error('Error extracting tarfile'); } @@ -1053,10 +1106,10 @@ private function upgrade() { define('CIVICRM_SETTINGS_PATH', $project_path . 'civicrm.settings.php'); if (!copy($backup_dir . '/civicrm/civicrm.settings.php', CIVICRM_SETTINGS_PATH)) { - return WP_CLI::error('Failed to copy file'); + return WP_CLI::error('Failed to copy file.'); } - WP_CLI::success('4. '); + WP_CLI::success('4. Settings file copied.'); WP_CLI::run_command(['civicrm', 'upgrade-db'], []); @@ -1065,7 +1118,9 @@ private function upgrade() { } /** - * Implementation of command 'upgrade-db' + * Implementation of command 'upgrade-db'. + * + * @since 4.5 */ private function upgradeDB() { @@ -1076,11 +1131,12 @@ private function upgradeDB() { } if (class_exists('CRM_Upgrade_Headless')) { - # Note: CRM_Upgrade_Headless introduced in 4.2 -- at the same time as class auto-loading + + // CRM_Upgrade_Headless introduced in 4.2 - at the same time as class auto-loading. try { $upgrade_headless = new CRM_Upgrade_Headless(); $result = $upgrade_headless->run(); - WP_CLI::line('Upgrade outputs: ' . '"' . $result['message'] . '"'); + WP_CLI::line(sprintf('Upgrade outputs: "%s"', $result['message'])); } catch (Exception $e) { WP_CLI::error($e->getMessage()); @@ -1095,18 +1151,18 @@ private function upgradeDB() { require_once 'CRM/Upgrade/Page/Upgrade.php'; $upgrade = new CRM_Upgrade_Page_Upgrade(); - // new since CiviCRM 4.1 + // New since CiviCRM 4.1. if (is_callable([$upgrade, 'setPrint'])) { $upgrade->setPrint(TRUE); } - # to suppress html output /w source code. + // To suppress HTML output with source code. ob_start(); $upgrade->run(); - # capture the required message. + // Capture the required message. $result = $template->get_template_vars('message'); ob_end_clean(); - WP_CLI::line('Upgrade outputs: ' . "\"$result\""); + WP_CLI::line(sprintf('Upgrade outputs: "%s"', $result)); } @@ -1114,9 +1170,12 @@ private function upgradeDB() { /** * DSN parser - this has been stolen from PEAR DB since we don't always have a - * bootstrapped environment we can access this from, eg: when doing an upgrade - * @param $dsn (string) - * @return array containing db connection details + * bootstrapped environment we can access this from, eg: when doing an upgrade. + * + * @since 4.5 + * + * @param string|array $dsn + * @return array $parsed The arry containing db connection details. */ private static function parseDSN($dsn) { @@ -1140,7 +1199,7 @@ private static function parseDSN($dsn) { return $dsn; } - // Find phptype and dbsyntax + // Find phptype and dbsyntax. if (($pos = strpos($dsn, '://')) !== FALSE) { $str = substr($dsn, 0, $pos); $dsn = substr($dsn, $pos + 3); @@ -1150,7 +1209,7 @@ private static function parseDSN($dsn) { $dsn = NULL; } - // Get phptype and dbsyntax + // Get phptype and dbsyntax. // $str => phptype(dbsyntax) if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) { $parsed['phptype'] = $arr[1]; @@ -1165,7 +1224,7 @@ private static function parseDSN($dsn) { return $parsed; } - // Get (if found): username and password + // Get (if found): username and password. // $dsn => username:password@protocol+hostspec/database if (($at = strrpos($dsn, '@')) !== FALSE) { $str = substr($dsn, 0, $at); @@ -1179,7 +1238,7 @@ private static function parseDSN($dsn) { } } - // Find protocol and hostspec + // Find protocol and hostspec. if (preg_match('|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match)) { // $dsn => proto(proto_opts)/database @@ -1202,7 +1261,7 @@ private static function parseDSN($dsn) { } } - // process the different protocol options + // Process the different protocol options. $parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp'; $proto_opts = rawurldecode($proto_opts); if (strpos($proto_opts, ':') !== FALSE) { @@ -1215,7 +1274,7 @@ private static function parseDSN($dsn) { $parsed['socket'] = $proto_opts; } - // Get dabase if any + // Get dabase if any. // $dsn => database if ($dsn) { if (($pos = strpos($dsn, '?')) === FALSE) { @@ -1236,7 +1295,7 @@ private static function parseDSN($dsn) { foreach ($opts as $opt) { list($key, $value) = explode('=', $opt); if (!isset($parsed[$key])) { - // don't allow params overwrite + // Don't allow params overwrite. $parsed[$key] = rawurldecode($value); } } @@ -1244,10 +1303,13 @@ private static function parseDSN($dsn) { } return $parsed; + } /** - * Helper function to replicate functionality of drush_get_option + * Helper function to replicate functionality of 'drush_get_option'. + * + * @since 4.5 * * @param string $name * @param string $default @@ -1258,17 +1320,23 @@ private function getOption($name, $default) { } /** - * Get the user the web server runs as, used to preserve file permissions on templates_c, civicrm/upload - * etc when running as root. This is not a very good check, but is good enough for what we want to do, - * which is preserve file permissions - * @return string - the user which owns templates_c / empty string if not found + * Get the user the web server runs as - used to preserve file permissions on + * templates_c, civicrm/upload etc when running as root. This is not a very + * good check, but is good enough for what we want to do, which is to preserve + * file permissions. + * + * @since 4.5 + * + * @return string The user which owns templates_c. Empty string if not found. */ private function getWebServerUser() { + $plugins_dir = plugin_dir_path(__FILE__); $plugins_dir_root = WP_PLUGIN_DIR; $upload_dir = wp_upload_dir(); $tpl_path = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'templates_c'; $legacy_tpl_path = $plugins_dir_root . '/files/civicrm/templates_c'; + if (is_dir($legacy_tpl_path)) { $owner = posix_getpwuid(fileowner($legacy_tpl_path)); if (isset($owner['name'])) { @@ -1281,19 +1349,26 @@ private function getWebServerUser() { return $owner['name']; } } + return ''; } /** - * Get the group the webserver runs as - as above, but for group + * Get the group the webserver runs as - as above, but for group. + * + * @since 4.5 + * + * @return string The group the webserver runs as. Empty string if not found. */ private function getWebServerGroup() { + $plugins_dir = plugin_dir_path(__FILE__); $plugins_dir_root = WP_PLUGIN_DIR; $upload_dir = wp_upload_dir(); $tpl_path = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'templates_c'; $legacy_tpl_path = $plugins_dir_root . '/files/civicrm/templates_c'; + if (is_dir($legacy_tpl_path)) { $group = posix_getgrgid(filegroup($legacy_tpl_path)); if (isset($group['name'])) { @@ -1306,19 +1381,24 @@ private function getWebServerGroup() { return $group['name']; } } + return ''; } /** - * Extract a tar.gz archive - * @param $destination_path - the path to extract to - * @param $option - command line option to get input filename from, defaults to 'tarfile' - * @return bool + * Extracts a tar.gz archive. + * + * @since 4.5 + * + * @param string $destination_path The path to extract to. + * @param string $option The command line option to get input filename from, defaults to 'tarfile'. + * @return bool True if successful, false otherwise. */ private function untar($destination_path, $option = 'tarfile') { if ($tarfile = $this->getOption($option, FALSE)) { + WP_CLI::line('Extracting tar.gz archive...'); WP_CLI::launch("gzip -d $tarfile"); $tarfile = substr($tarfile, 0, strlen($tarfile) - 3); WP_CLI::launch("tar -xf $tarfile -C \"$destination_path\""); @@ -1331,15 +1411,18 @@ private function untar($destination_path, $option = 'tarfile') { } /** - * Extract a zip archive - * @param $destination_path - the path to extract to - * @param $option - command line option to get zip filename from, defaults to 'zipfile' - * @return bool + * Extracts a zip archive. + * + * @since 4.5 + * + * @param string $destination_path The path to extract to. + * @param string $option The command line option to get zip filename from, defaults to 'zipfile'. + * @return bool True if successful, false otherwise. */ private function unzip($destination_path, $option = 'zipfile') { if ($zipfile = $this->getOption($option, FALSE)) { - WP_CLI::line('Extracting zip archive ...'); + WP_CLI::line('Extracting zip archive...'); WP_CLI::launch("unzip -q $zipfile -d $destination_path"); return TRUE; } @@ -1354,17 +1437,18 @@ private function unzip($destination_path, $option = 'zipfile') { WP_CLI::add_command('civicrm', 'CiviCRM_Command'); WP_CLI::add_command('cv', 'CiviCRM_Command'); - # Set path early. + // Set path early. WP_CLI::add_hook('before_wp_load', function() { - # If --path is set, save for later use by CiviCRM. global $civicrm_paths; $wp_cli_config = WP_CLI::get_config(); + + // If --path is set, save for later use by CiviCRM. if (!empty($wp_cli_config['path'])) { $civicrm_paths['cms.root']['path'] = $wp_cli_config['path']; } - # If --url is set, save for later use by CiviCRM. + // If --url is set, save for later use by CiviCRM. if (!empty($wp_cli_config['url'])) { $civicrm_paths['cms.root']['url'] = $wp_cli_config['url']; }