X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=CRM%2FUtils%2FHook%2FWordPress.php;h=b436a8ab6ca4d567932a7ad68eba01cb05b9152f;hb=5b7207898cb795d0e989949111773444a19afb62;hp=8a238881938fe2f714539bd29236f12470d30ad8;hpb=1789c269b1c68178c1f3de38d751a4e37f94db4c;p=civicrm-core.git diff --git a/CRM/Utils/Hook/WordPress.php b/CRM/Utils/Hook/WordPress.php index 8a23888193..b436a8ab6c 100644 --- a/CRM/Utils/Hook/WordPress.php +++ b/CRM/Utils/Hook/WordPress.php @@ -1,7 +1,7 @@ commonInvoke($numParams, - $arg1, $arg2, $arg3, $arg4, $arg5, $arg6, - $fnSuffix, 'wordpress' + + /** + * do_action_ref_array is the default way of calling WordPress hooks + * because for the most part no return value is wanted. However, this is + * only generally true, so using do_action_ref_array() is only called for those + * hooks which do not require a return value. We exclude the following, which + * are incompatible with the WordPress Plugin API: + * + * civicrm_upgrade + * http://wiki.civicrm.org/confluence/display/CRMDOC43/hook_civicrm_upgrade + * + * civicrm_caseSummary + * http://wiki.civicrm.org/confluence/display/CRMDOC43/hook_civicrm_caseSummary + * + * civicrm_dashboard + * http://wiki.civicrm.org/confluence/display/CRMDOC43/hook_civicrm_dashboard + */ + + // distinguish between types of hook + if (!in_array($fnSuffix, $this->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 'civicrmHooks.php'; + } + + // initialise with the pre-existing 'wordpress' prefix + $this->wordpressModules = array('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 = array(); + $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; + } + + } + } + +}