hooksThatReturn)) { // only pass the arguments that have values $args = array_slice( array(&$arg1, &$arg2, &$arg3, &$arg4, &$arg5, &$arg6), 0, $numParams ); // Use WordPress Plugins API to modify $args // // Because $args are passed as references to the WordPress callbacks, // runHooks subsequently receives appropriately modified parameters. // protect from REST calls if (function_exists('do_action_ref_array')) { do_action_ref_array($fnSuffix, $args); } } // The following is based on the logic of the Joomla hook file by allowing // WordPress callbacks to do their stuff before runHooks gets called. // It also follows the logic of the Drupal hook file by building the "module" // (read "plugin") list and then calling runHooks directly. This should avoid // the need for the post-processing that the Joomla hook file does. // Note that hooks which require a return value are incompatible with the // signature of apply_filters_ref_array and must therefore be called in // global scope, like in Drupal. It's not ideal, but plugins can always route // these calls to methods in their classes. // At some point, those hooks could be pre-processed and called via the WordPress // Plugin API, but it would change their signature and require the CiviCRM docs // to be rewritten for those calls in WordPress. So it's been done this way for // now. Ideally these hooks will be deprecated in favour of hooks that do not // require return values. // build list of registered plugin codes $this->buildModuleList(); // Call runHooks the same way Drupal does $moduleResult = $this->runHooks( $this->allModules, $fnSuffix, $numParams, $arg1, $arg2, $arg3, $arg4, $arg5, $arg6 ); // finally, return return empty($moduleResult) ? TRUE : $moduleResult; } /** * Build the list of plugins ("modules" in CiviCRM terminology) to be processed for hooks. * * We need to do this to preserve the CiviCRM hook signatures for hooks that require * a return value, since the WordPress Plugin API seems to be incompatible with them. * * Copied and adapted from: CRM/Utils/Hook/Drupal6.php */ public function buildModuleList() { if ($this->isBuilt === FALSE) { if ($this->wordpressModules === NULL) { // include custom PHP file - copied from parent->commonBuildModuleList() $config = CRM_Core_Config::singleton(); if (!empty($config->customPHPPathDir) && file_exists("{$config->customPHPPathDir}/civicrmHooks.php") ) { @include_once "{$config->customPHPPathDir}/civicrmHooks.php"; } // initialise with the pre-existing 'wordpress' prefix $this->wordpressModules = ['wordpress']; // Use WordPress Plugin API to build list // a plugin simply needs to declare its "unique_plugin_code" thus: // add_filter('civicrm_wp_plugin_codes', 'function_that_returns_my_unique_plugin_code'); // protect from REST calls if (function_exists('apply_filters')) { $this->wordpressModules = apply_filters('civicrm_wp_plugin_codes', $this->wordpressModules); } } if ($this->civiModules === NULL) { $this->civiModules = []; $this->requireCiviModules($this->civiModules); } $this->allModules = array_merge((array) $this->wordpressModules, (array) $this->civiModules); if ($this->wordpressModules !== NULL && $this->civiModules !== NULL) { // both CRM and CMS have bootstrapped, so this is the final list $this->isBuilt = TRUE; } } } }