From 760d11e2bdc25830ed49523d75e647351048001c Mon Sep 17 00:00:00 2001 From: Kevin Cristiano <kcristiano@kcristiano.com> Date: Sun, 5 Apr 2020 13:41:49 -0400 Subject: [PATCH] civicrm release --- civicrm.php | 47 +- .../Incremental/php/FiveTwentyFour.php | 16 +- .../Upgrade/Incremental/sql/5.24.1.mysql.tpl | 1 + civicrm/CRM/Utils/Check/Component/Schema.php | 4 +- civicrm/CRM/Utils/System/WordPress.php | 65 +-- civicrm/civicrm-version.php | 2 +- civicrm/release-notes.md | 9 + civicrm/release-notes/5.24.1.md | 41 ++ civicrm/sql/civicrm_data.mysql | 2 +- civicrm/sql/civicrm_generated.mysql | 2 +- civicrm/vendor/autoload.php | 2 +- civicrm/vendor/composer/autoload_real.php | 14 +- civicrm/vendor/composer/autoload_static.php | 12 +- civicrm/xml/version.xml | 2 +- includes/civicrm.compat.php | 154 ------ wp-rest/.editorconfig | 9 - wp-rest/Autoloader.php | 115 ---- wp-rest/Civi/Mailing-Hooks.php | 197 ------- wp-rest/Controller/AuthorizeIPN.php | 123 ----- wp-rest/Controller/Base.php | 111 ---- wp-rest/Controller/Cxn.php | 125 ----- wp-rest/Controller/Open.php | 129 ----- wp-rest/Controller/PayPalIPN.php | 134 ----- wp-rest/Controller/PxIPN.php | 139 ----- wp-rest/Controller/Rest.php | 497 ------------------ wp-rest/Controller/Soap.php | 98 ---- wp-rest/Controller/Url.php | 216 -------- wp-rest/Controller/Widget.php | 214 -------- wp-rest/Endpoint/Endpoint-Interface.php | 35 -- wp-rest/Plugin.php | 379 ------------- wp-rest/README.md | 59 --- 31 files changed, 101 insertions(+), 2852 deletions(-) create mode 100644 civicrm/CRM/Upgrade/Incremental/sql/5.24.1.mysql.tpl create mode 100644 civicrm/release-notes/5.24.1.md delete mode 100644 includes/civicrm.compat.php delete mode 100644 wp-rest/.editorconfig delete mode 100644 wp-rest/Autoloader.php delete mode 100644 wp-rest/Civi/Mailing-Hooks.php delete mode 100644 wp-rest/Controller/AuthorizeIPN.php delete mode 100644 wp-rest/Controller/Base.php delete mode 100644 wp-rest/Controller/Cxn.php delete mode 100644 wp-rest/Controller/Open.php delete mode 100644 wp-rest/Controller/PayPalIPN.php delete mode 100644 wp-rest/Controller/PxIPN.php delete mode 100644 wp-rest/Controller/Rest.php delete mode 100644 wp-rest/Controller/Soap.php delete mode 100644 wp-rest/Controller/Url.php delete mode 100644 wp-rest/Controller/Widget.php delete mode 100644 wp-rest/Endpoint/Endpoint-Interface.php delete mode 100644 wp-rest/Plugin.php delete mode 100644 wp-rest/README.md diff --git a/civicrm.php b/civicrm.php index 3199ffe20d..18a0e8f559 100644 --- a/civicrm.php +++ b/civicrm.php @@ -2,7 +2,7 @@ /* Plugin Name: CiviCRM Description: CiviCRM - Growing and Sustaining Relationships -Version: 5.24.0 +Version: 5.24.1 Author: CiviCRM LLC Author URI: https://civicrm.org/ Plugin URI: https://docs.civicrm.org/sysadmin/en/latest/install/wordpress/ @@ -54,7 +54,7 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Set version here: when it changes, will force JS to reload -define( 'CIVICRM_PLUGIN_VERSION', '5.24.0' ); +define( 'CIVICRM_PLUGIN_VERSION', '5.24.1' ); // Store reference to this file if (!defined('CIVICRM_PLUGIN_FILE')) { @@ -121,17 +121,6 @@ if ( file_exists( CIVICRM_SETTINGS_PATH ) ) { // Prevent CiviCRM from rendering its own header define( 'CIVICRM_UF_HEAD', TRUE ); -/** - * Setting this to 'true' will replace all mailing URLs calls to 'extern/url.php' - * and 'extern/open.php' with their REST counterpart 'civicrm/v3/url' and 'civicrm/v3/open'. - * - * Use for test purposes, may affect mailing - * performance, see Plugin->replace_tracking_urls() method. - */ -if ( ! defined( 'CIVICRM_WP_REST_REPLACE_MAILING_TRACKING' ) ) { - define( 'CIVICRM_WP_REST_REPLACE_MAILING_TRACKING', false ); -} - /** * Define CiviCRM_For_WordPress Class. @@ -203,15 +192,6 @@ class CiviCRM_For_WordPress { */ public $users; - /** - * Compatibility object. - * - * @since 5.24 - * @access public - * @var object CiviCRM_For_WordPress_Compat The plugin compatibility object. - */ - public $compat; - // --------------------------------------------------------------------------- // Setup @@ -532,15 +512,6 @@ class CiviCRM_For_WordPress { include_once CIVICRM_PLUGIN_DIR . 'includes/civicrm.basepage.php'; $this->basepage = new CiviCRM_For_WordPress_Basepage; - // Include compatibility class - include_once CIVICRM_PLUGIN_DIR . 'includes/civicrm.compat.php'; - $this->compat = new CiviCRM_For_WordPress_Compat; - - if ( ! class_exists( 'CiviCRM_WP_REST\Autoloader' ) ) { - // Include REST API autoloader class - require_once( CIVICRM_PLUGIN_DIR . 'wp-rest/Autoloader.php' ); - } - } @@ -665,16 +636,6 @@ class CiviCRM_For_WordPress { // Register hooks for clean URLs. $this->register_hooks_clean_urls(); - if ( ! class_exists( 'CiviCRM_WP_REST\Plugin' ) ) { - - // Set up REST API. - CiviCRM_WP_REST\Autoloader::add_source( $source_path = trailingslashit( CIVICRM_PLUGIN_DIR . 'wp-rest' ) ); - - // Init REST API. - new CiviCRM_WP_REST\Plugin; - - } - } @@ -822,12 +783,10 @@ class CiviCRM_For_WordPress { * Broadcast the rewrite rules event. * * @since 5.7 - * @since 5.24 Added $basepage parameter. * * @param bool $flush_rewrite_rules True if rules flushed, false otherwise. - * @param WP_Post $basepage The Basepage post object. */ - do_action( 'civicrm_after_rewrite_rules', $flush_rewrite_rules, $basepage ); + do_action( 'civicrm_after_rewrite_rules', $flush_rewrite_rules ); } diff --git a/civicrm/CRM/Upgrade/Incremental/php/FiveTwentyFour.php b/civicrm/CRM/Upgrade/Incremental/php/FiveTwentyFour.php index 1b90c51619..e43e22d2dd 100644 --- a/civicrm/CRM/Upgrade/Incremental/php/FiveTwentyFour.php +++ b/civicrm/CRM/Upgrade/Incremental/php/FiveTwentyFour.php @@ -75,7 +75,21 @@ class CRM_Upgrade_Incremental_php_FiveTwentyFour extends CRM_Upgrade_Incremental * @throws \CiviCRM_API3_Exception */ public static function installCreditNotes(CRM_Queue_TaskContext $ctx) { - civicrm_api3('Extension', 'install', ['keys' => 'sequentialcreditnotes']); + // Install via direct SQL manipulation. Note that: + // (1) This extension has no activation logic. + // (2) On new installs, the extension is activated purely via default SQL INSERT. + // (3) Caches are flushed at the end of the upgrade. + // ($) Over long term, upgrade steps are more reliable in SQL. API/BAO sometimes don't work mid-upgrade. + $insert = CRM_Utils_SQL_Insert::into('civicrm_extension')->row([ + 'type' => 'module', + 'full_name' => 'sequentialcreditnotes', + 'name' => 'Sequential credit notes', + 'label' => 'Sequential credit notes', + 'file' => 'sequentialcreditnotes', + 'schema_version' => NULL, + 'is_active' => 1, + ]); + CRM_Core_DAO::executeQuery($insert->usingReplace()->toSQL()); return TRUE; } diff --git a/civicrm/CRM/Upgrade/Incremental/sql/5.24.1.mysql.tpl b/civicrm/CRM/Upgrade/Incremental/sql/5.24.1.mysql.tpl new file mode 100644 index 0000000000..ac16755fe3 --- /dev/null +++ b/civicrm/CRM/Upgrade/Incremental/sql/5.24.1.mysql.tpl @@ -0,0 +1 @@ +{* file to handle db changes in 5.24.1 during upgrade *} diff --git a/civicrm/CRM/Utils/Check/Component/Schema.php b/civicrm/CRM/Utils/Check/Component/Schema.php index 13803b63c8..fb4d253648 100644 --- a/civicrm/CRM/Utils/Check/Component/Schema.php +++ b/civicrm/CRM/Utils/Check/Component/Schema.php @@ -121,8 +121,8 @@ class CRM_Utils_Check_Component_Schema extends CRM_Utils_Check_Component { } foreach ($group['form_values'] as $formValues) { if (isset($formValues[0]) && (strpos($formValues[0], 'custom_') === 0)) { - list(, $customFieldID) = explode('custom_', $formValues[0]); - if (!in_array($customFieldID, $customFieldIds, TRUE)) { + list(, $customFieldID) = explode('_', $formValues[0]); + if (!in_array((int) $customFieldID, $customFieldIds, TRUE)) { $problematicSG[CRM_Contact_BAO_SavedSearch::getName($group['id'], 'id')] = [ 'title' => CRM_Contact_BAO_SavedSearch::getName($group['id'], 'title'), 'cfid' => $customFieldID, diff --git a/civicrm/CRM/Utils/System/WordPress.php b/civicrm/CRM/Utils/System/WordPress.php index 80cb3692af..6c215d2954 100644 --- a/civicrm/CRM/Utils/System/WordPress.php +++ b/civicrm/CRM/Utils/System/WordPress.php @@ -409,63 +409,22 @@ class CRM_Utils_System_WordPress extends CRM_Utils_System_Base { * @inheritDoc */ public function getUFLocale() { - // Bail early if method is called when WordPress isn't bootstrapped. - // Additionally, the function checked here is located in pluggable.php - // and is required by wp_get_referer() - so this also bails early if it is - // called too early in the request lifecycle. - // @see https://core.trac.wordpress.org/ticket/25294 - if (!function_exists('wp_validate_redirect')) { - return NULL; + // Polylang plugin + if (function_exists('pll_current_language')) { + $language = pll_current_language(); } - - // Default to WordPress User locale. - $locale = get_user_locale(); - - // Is this a "back-end" AJAX call? - $is_backend = FALSE; - if (wp_doing_ajax() && FALSE !== strpos(wp_get_referer(), admin_url())) { - $is_backend = TRUE; + // WPML plugin + elseif (defined('ICL_LANGUAGE_CODE')) { + $language = ICL_LANGUAGE_CODE; } - - // Ignore when in WordPress admin or it's a "back-end" AJAX call. - if (!(is_admin() || $is_backend)) { - - // Reaching here means it is very likely to be a front-end context. - - // Default to WordPress locale. - $locale = get_locale(); - - // Maybe override with the locale that Polylang reports. - if (function_exists('pll_current_language')) { - $pll_locale = pll_current_language('locale'); - if (!empty($pll_locale)) { - $locale = $pll_locale; - } - } - - // Maybe override with the locale that WPML reports. - elseif (defined('ICL_LANGUAGE_CODE')) { - $languages = apply_filters('wpml_active_languages', NULL); - foreach ($languages as $language) { - if ($language['active']) { - $locale = $language['default_locale']; - break; - } - } - } - - // TODO: Set locale for other WordPress plugins. - // @see https://wordpress.org/plugins/tags/multilingual/ - // A hook would be nice here. - + // Wordpress "standard" single language mode + // We still have to check if the function exists as it may not during bootstrap + elseif (function_exists('get_locale')) { + $language = get_locale(); } - if (!empty($locale)) { - // If for some reason only we get a language code, convert it to a locale. - if (2 === strlen($locale)) { - $locale = CRM_Core_I18n_PseudoConstant::longForShort($locale); - } - return $locale; + if (!empty($language)) { + return CRM_Core_I18n_PseudoConstant::longForShort(substr($language, 0, 2)); } else { return NULL; diff --git a/civicrm/civicrm-version.php b/civicrm/civicrm-version.php index a359310191..35a2eee967 100644 --- a/civicrm/civicrm-version.php +++ b/civicrm/civicrm-version.php @@ -1,7 +1,7 @@ <?php /** @deprecated */ function civicrmVersion( ) { - return array( 'version' => '5.24.0', + return array( 'version' => '5.24.1', 'cms' => 'Wordpress', 'revision' => '' ); } diff --git a/civicrm/release-notes.md b/civicrm/release-notes.md index 81534f59cb..ee897de18c 100644 --- a/civicrm/release-notes.md +++ b/civicrm/release-notes.md @@ -15,6 +15,15 @@ Other resources for identifying changes are: * https://github.com/civicrm/civicrm-joomla * https://github.com/civicrm/civicrm-wordpress +## CiviCRM 5.24.1 + +Released April 4, 2020 + +- **[Synopsis](release-notes/5.24.1.md#synopsis)** +- **[Bugs resolved](release-notes/5.24.1.md#bugs)** +- **[Credits](release-notes/5.24.1.md#credits)** +- **[Feedback](release-notes/5.24.1.md#feedback)** + ## CiviCRM 5.24.0 Released April 1, 2020 diff --git a/civicrm/release-notes/5.24.1.md b/civicrm/release-notes/5.24.1.md new file mode 100644 index 0000000000..48f57fa0df --- /dev/null +++ b/civicrm/release-notes/5.24.1.md @@ -0,0 +1,41 @@ +# CiviCRM 5.24.1 + +Released April 4, 2020. + +- **[Synopsis](#synopsis)** +- **[Bugs resolved](#bugs)** +- **[Credits](#credits)** +- **[Feedback](#feedback)** + +## <a name="synopsis"></a>Synopsis + +| *Does this version...?* | | +|:--------------------------------------------------------------- |:-------:| +| Fix security vulnerabilities? | no | +| Change the database schema? | no | +| Alter the API? | no | +| Require attention to configuration options? | no | +| Fix problems installing or upgrading to a previous version? | **yes** | +| Introduce features? | no | +| **Fix bugs?** | **yes** | + +## <a name="bugs"></a>Bugs resolved + +* **_Upgrade_: Web-based upgrader freezes after step "Upgrade DB to 5.24.alpha1: SQL" + ([dev/core#1689](https://lab.civicrm.org/dev/core/-/issues/1689), [dev/financial#84](https://lab.civicrm.org/dev/financial/-/issues/84#note_34262): [#16971](https://github.com/civicrm/civicrm-core/pull/16971))** +* **_Smart Groups_: Groups defined with certain custom fields fail ([dev/core#1688](https://lab.civicrm.org/dev/core/-/issues/1688): [#16961](https://github.com/civicrm/civicrm-core/pull/16961))** + +## <a name="credits"></a>Credits + +This release was developed by the following authors and reviewers: + +Wikimedia Foundation - Eileen McNaughton; Tadpole Collective - Kevin +Cristiano; Phil McKerracher; Megaphone Technology Consulting - Jon Goldberg; +JMA Consulting - Seamus Lee; Dave D; CiviCRM - Coleman Watts, Tim Otten; +Andy Clark + +## <a name="feedback"></a>Feedback + +These release notes are edited by Tim Otten and Andrew Hunt. If you'd like to +provide feedback on them, please login to https://chat.civicrm.org/civicrm and +contact `@agh1`. diff --git a/civicrm/sql/civicrm_data.mysql b/civicrm/sql/civicrm_data.mysql index 482608f3c8..28beab0c75 100644 --- a/civicrm/sql/civicrm_data.mysql +++ b/civicrm/sql/civicrm_data.mysql @@ -23895,4 +23895,4 @@ INSERT INTO `civicrm_report_instance` ( `domain_id`, `title`, `report_id`, `description`, `permission`, `form_values`) VALUES ( @domainID, 'Survey Details', 'survey/detail', 'Detailed report for canvassing, phone-banking, walk lists or other surveys.', 'access CiviReport', 'a:39:{s:6:"fields";a:2:{s:9:"sort_name";s:1:"1";s:6:"result";s:1:"1";}s:22:"assignee_contact_id_op";s:2:"eq";s:25:"assignee_contact_id_value";s:0:"";s:12:"sort_name_op";s:3:"has";s:15:"sort_name_value";s:0:"";s:17:"street_number_min";s:0:"";s:17:"street_number_max";s:0:"";s:16:"street_number_op";s:3:"lte";s:19:"street_number_value";s:0:"";s:14:"street_name_op";s:3:"has";s:17:"street_name_value";s:0:"";s:15:"postal_code_min";s:0:"";s:15:"postal_code_max";s:0:"";s:14:"postal_code_op";s:3:"lte";s:17:"postal_code_value";s:0:"";s:7:"city_op";s:3:"has";s:10:"city_value";s:0:"";s:20:"state_province_id_op";s:2:"in";s:23:"state_province_id_value";a:0:{}s:13:"country_id_op";s:2:"in";s:16:"country_id_value";a:0:{}s:12:"survey_id_op";s:2:"in";s:15:"survey_id_value";a:0:{}s:12:"status_id_op";s:2:"eq";s:15:"status_id_value";s:1:"1";s:11:"custom_1_op";s:2:"in";s:14:"custom_1_value";a:0:{}s:11:"custom_2_op";s:2:"in";s:14:"custom_2_value";a:0:{}s:17:"custom_3_relative";s:1:"0";s:13:"custom_3_from";s:0:"";s:11:"custom_3_to";s:0:"";s:11:"description";s:75:"Detailed report for canvassing, phone-banking, walk lists or other surveys.";s:13:"email_subject";s:0:"";s:8:"email_to";s:0:"";s:8:"email_cc";s:0:"";s:10:"permission";s:17:"access CiviReport";s:6:"groups";s:0:"";s:9:"domain_id";i:1;}'); -UPDATE civicrm_domain SET version = '5.24.0'; +UPDATE civicrm_domain SET version = '5.24.1'; diff --git a/civicrm/sql/civicrm_generated.mysql b/civicrm/sql/civicrm_generated.mysql index 6fcb64f481..c1e02b3ab6 100644 --- a/civicrm/sql/civicrm_generated.mysql +++ b/civicrm/sql/civicrm_generated.mysql @@ -399,7 +399,7 @@ UNLOCK TABLES; LOCK TABLES `civicrm_domain` WRITE; /*!40000 ALTER TABLE `civicrm_domain` DISABLE KEYS */; -INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,'5.24.0',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}'); +INSERT INTO `civicrm_domain` (`id`, `name`, `description`, `version`, `contact_id`, `locales`, `locale_custom_strings`) VALUES (1,'Default Domain Name',NULL,'5.24.1',1,NULL,'a:1:{s:5:\"en_US\";a:0:{}}'); /*!40000 ALTER TABLE `civicrm_domain` ENABLE KEYS */; UNLOCK TABLES; diff --git a/civicrm/vendor/autoload.php b/civicrm/vendor/autoload.php index feed9f6977..d7cbde47d5 100644 --- a/civicrm/vendor/autoload.php +++ b/civicrm/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInitbb7b93f0d2f02dd9e37ef3678d2bb56e::getLoader(); +return ComposerAutoloaderInit2dada1bbc48cad79553b40ac7e3c94cf::getLoader(); diff --git a/civicrm/vendor/composer/autoload_real.php b/civicrm/vendor/composer/autoload_real.php index 7af450fdea..6d3389a0ea 100644 --- a/civicrm/vendor/composer/autoload_real.php +++ b/civicrm/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInitbb7b93f0d2f02dd9e37ef3678d2bb56e +class ComposerAutoloaderInit2dada1bbc48cad79553b40ac7e3c94cf { private static $loader; @@ -19,9 +19,9 @@ class ComposerAutoloaderInitbb7b93f0d2f02dd9e37ef3678d2bb56e return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInitbb7b93f0d2f02dd9e37ef3678d2bb56e', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit2dada1bbc48cad79553b40ac7e3c94cf', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInitbb7b93f0d2f02dd9e37ef3678d2bb56e', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit2dada1bbc48cad79553b40ac7e3c94cf', 'loadClassLoader')); $includePaths = require __DIR__ . '/include_paths.php'; $includePaths[] = get_include_path(); @@ -31,7 +31,7 @@ class ComposerAutoloaderInitbb7b93f0d2f02dd9e37ef3678d2bb56e if ($useStaticLoader) { require_once __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInitbb7b93f0d2f02dd9e37ef3678d2bb56e::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit2dada1bbc48cad79553b40ac7e3c94cf::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { @@ -52,19 +52,19 @@ class ComposerAutoloaderInitbb7b93f0d2f02dd9e37ef3678d2bb56e $loader->register(true); if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInitbb7b93f0d2f02dd9e37ef3678d2bb56e::$files; + $includeFiles = Composer\Autoload\ComposerStaticInit2dada1bbc48cad79553b40ac7e3c94cf::$files; } else { $includeFiles = require __DIR__ . '/autoload_files.php'; } foreach ($includeFiles as $fileIdentifier => $file) { - composerRequirebb7b93f0d2f02dd9e37ef3678d2bb56e($fileIdentifier, $file); + composerRequire2dada1bbc48cad79553b40ac7e3c94cf($fileIdentifier, $file); } return $loader; } } -function composerRequirebb7b93f0d2f02dd9e37ef3678d2bb56e($fileIdentifier, $file) +function composerRequire2dada1bbc48cad79553b40ac7e3c94cf($fileIdentifier, $file) { if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { require $file; diff --git a/civicrm/vendor/composer/autoload_static.php b/civicrm/vendor/composer/autoload_static.php index 9430cc35c0..4d8550c2a5 100644 --- a/civicrm/vendor/composer/autoload_static.php +++ b/civicrm/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInitbb7b93f0d2f02dd9e37ef3678d2bb56e +class ComposerStaticInit2dada1bbc48cad79553b40ac7e3c94cf { public static $files = array ( '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', @@ -480,11 +480,11 @@ class ComposerStaticInitbb7b93f0d2f02dd9e37ef3678d2bb56e public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInitbb7b93f0d2f02dd9e37ef3678d2bb56e::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInitbb7b93f0d2f02dd9e37ef3678d2bb56e::$prefixDirsPsr4; - $loader->prefixesPsr0 = ComposerStaticInitbb7b93f0d2f02dd9e37ef3678d2bb56e::$prefixesPsr0; - $loader->fallbackDirsPsr0 = ComposerStaticInitbb7b93f0d2f02dd9e37ef3678d2bb56e::$fallbackDirsPsr0; - $loader->classMap = ComposerStaticInitbb7b93f0d2f02dd9e37ef3678d2bb56e::$classMap; + $loader->prefixLengthsPsr4 = ComposerStaticInit2dada1bbc48cad79553b40ac7e3c94cf::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit2dada1bbc48cad79553b40ac7e3c94cf::$prefixDirsPsr4; + $loader->prefixesPsr0 = ComposerStaticInit2dada1bbc48cad79553b40ac7e3c94cf::$prefixesPsr0; + $loader->fallbackDirsPsr0 = ComposerStaticInit2dada1bbc48cad79553b40ac7e3c94cf::$fallbackDirsPsr0; + $loader->classMap = ComposerStaticInit2dada1bbc48cad79553b40ac7e3c94cf::$classMap; }, null, ClassLoader::class); } diff --git a/civicrm/xml/version.xml b/civicrm/xml/version.xml index edcee6bc44..55e0e90165 100644 --- a/civicrm/xml/version.xml +++ b/civicrm/xml/version.xml @@ -1,4 +1,4 @@ <?xml version="1.0" encoding="iso-8859-1" ?> <version> - <version_no>5.24.0</version_no> + <version_no>5.24.1</version_no> </version> diff --git a/includes/civicrm.compat.php b/includes/civicrm.compat.php deleted file mode 100644 index 151761de7c..0000000000 --- a/includes/civicrm.compat.php +++ /dev/null @@ -1,154 +0,0 @@ -<?php -/* - +--------------------------------------------------------------------+ - | Copyright CiviCRM LLC. All rights reserved. | - | | - | This work is published under the GNU AGPLv3 license with some | - | permitted exceptions and without any warranty. For full license | - | and copyright information, see https://civicrm.org/licensing | - +--------------------------------------------------------------------+ -*/ - -/** - * - * @package CRM - * @copyright CiviCRM LLC https://civicrm.org/licensing - * - */ - - -// This file must not accessed directly -if ( ! defined( 'ABSPATH' ) ) exit; - - -/** - * Define CiviCRM_For_WordPress_Compat Class. - * - * @since 5.24 - */ -class CiviCRM_For_WordPress_Compat { - - /** - * Plugin object reference. - * - * @since 5.24 - * @access public - * @var object $civi The plugin object reference. - */ - public $civi; - - - /** - * Instance constructor. - * - * @since 5.24 - */ - public function __construct() { - - // Store reference to CiviCRM plugin object. - $this->civi = civi_wp(); - - // Register plugin compatibility hooks. - $this->register_hooks(); - - } - - - /** - * Register plugin compatibility hooks. - * - * This is called via the constructor during the "plugins_loaded" action which - * is much earlier that CiviCRM's own internal hooks. The reason for this is - * that compability may need callbacks for events that fire well before "init" - * which is when CiviCRM begins to load. - * - * @since 5.24 - */ - public function register_hooks() { - - // Bail if CiviCRM not installed yet. - if ( ! CIVICRM_INSTALLED ) { - return; - } - - // Support Clean URLs when Polylang is active. - add_action( 'civicrm_after_rewrite_rules', array( $this, 'rewrite_rules_polylang' ), 10, 2 ); - - } - - - /** - * Support Polylang. - * - * @since 5.24 - * - * @param bool $flush_rewrite_rules True if rules flushed, false otherwise. - * @param WP_Post $basepage The Basepage post object. - */ - public function rewrite_rules_polylang( $flush_rewrite_rules, $basepage ) { - - // Bail if Polylang is not present. - if (!function_exists('pll_languages_list')) { - return; - } - - /* - * Collect all rewrite rules into an array. - * - * Because the array of specific Post IDs is added *after* the array of - * paths for the Basepage ID, those specific rewrite rules will "win" over - * the more general Basepage rules. - */ - $collected_rewrites = []; - - // Support prefixes for a single Basepage. - $basepage_url = get_permalink( $basepage->ID ); - $basepage_raw_url = PLL()->links_model->remove_language_from_link( $basepage_url ); - $language_slugs = pll_languages_list(); - foreach ($language_slugs as $slug) { - $language = PLL()->model->get_language( $slug ); - $language_url = PLL()->links_model->add_language_to_link( $basepage_raw_url, $language ); - $parsed_url = wp_parse_url( $language_url, PHP_URL_PATH ); - $regex_path = substr( $parsed_url, 1 ); - $collected_rewrites[$basepage->ID][] = $regex_path; - $post_id = pll_get_post( $basepage->ID, $slug ); - if (!empty($post_id)) { - $collected_rewrites[$post_id][] = $regex_path; - } - }; - - // Support prefixes for Basepages in multiple languages. - foreach ($language_slugs as $slug) { - $post_id = pll_get_post( $basepage->ID, $slug ); - if (empty($post_id)) { - continue; - } - $url = get_permalink( $post_id ); - $parsed_url = wp_parse_url( $url, PHP_URL_PATH ); - $regex_path = substr( $parsed_url, 1 ); - $collected_rewrites[$basepage->ID][] = $regex_path; - $collected_rewrites[$post_id][] = $regex_path; - }; - - // Make collection unique and add remaining rewrite rules. - $rewrites = array_map('array_unique', $collected_rewrites); - if (!empty($rewrites)) { - foreach ($rewrites as $post_id => $rewrite) { - foreach ($rewrite as $path) { - add_rewrite_rule( - '^' . $path . '([^?]*)?', - 'index.php?page_id=' . $post_id . '&page=CiviCRM&q=civicrm%2F$matches[1]', - 'top' - ); - } - } - } - - // Maybe force flush - if ($flush_rewrite_rules) { - flush_rewrite_rules(); - } - - } - -} // Class CiviCRM_For_WordPress_Compat ends diff --git a/wp-rest/.editorconfig b/wp-rest/.editorconfig deleted file mode 100644 index 09dc3747d3..0000000000 --- a/wp-rest/.editorconfig +++ /dev/null @@ -1,9 +0,0 @@ -# EditorConfig is awesome: https://editorconfig.org - -# Not top-most EditorConfig file -root = false - -# Tab indentation -[*.php] -indent_style = tab -indent_size = 4 diff --git a/wp-rest/Autoloader.php b/wp-rest/Autoloader.php deleted file mode 100644 index 0111866615..0000000000 --- a/wp-rest/Autoloader.php +++ /dev/null @@ -1,115 +0,0 @@ -<?php -/** - * Autoloader class. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST; - -class Autoloader { - - /** - * Instance. - * - * @since 0.1 - * @var string - */ - private static $instance = null; - - /** - * Namespace. - * - * @since 0.1 - * @var string - */ - private $namespace = 'CiviCRM_WP_REST'; - - /** - * Autoloader directory sources. - * - * @since 0.1 - * @var array - */ - private static $source_directories = []; - - /** - * Constructor. - * - * @since 0.1 - */ - private function __construct() { - - $this->register_autoloader(); - - } - - /** - * Creates an instance of this class. - * - * @since 0.1 - */ - private static function instance() { - - if ( ! self::$instance ) self::$instance = new self; - - } - - /** - * Adds a directory source. - * - * @since 0.1 - * @param string $source The source path - */ - public static function add_source( string $source_path ) { - - // make sure we have an instance - self::instance(); - - if ( ! is_readable( trailingslashit( $source_path ) ) ) - return \WP_Error( 'civicrm_wp_rest_error', sprintf( __( 'The source %s is not readable.', 'civicrm' ), $source ) ); - - self::$source_directories[] = $source_path; - - } - - /** - * Registers the autoloader. - * - * @since 0.1 - * @return bool Wehather the autoloader has been registered or not - */ - private function register_autoloader() { - - return spl_autoload_register( [ $this, 'autoload' ] ); - - } - - /** - * Loads the classes. - * - * @since 0.1 - * @param string $class_name The class name to load - */ - private function autoload( $class_name ) { - - $parts = explode( '\\', $class_name ); - - if ( $this->namespace !== $parts[0] ) return; - - // remove namespace and join class path - $class_path = str_replace( '_', '-', implode( DIRECTORY_SEPARATOR, array_slice( $parts, 1 ) ) ); - - array_map( function( $source_path ) use ( $class_path ) { - - $path = $source_path . $class_path . '.php'; - - if ( ! file_exists( $path ) ) return; - - require $path; - - }, static::$source_directories ); - - } - -} diff --git a/wp-rest/Civi/Mailing-Hooks.php b/wp-rest/Civi/Mailing-Hooks.php deleted file mode 100644 index b765e1c911..0000000000 --- a/wp-rest/Civi/Mailing-Hooks.php +++ /dev/null @@ -1,197 +0,0 @@ -<?php -/** - * CiviCRM Mailing_Hooks class. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Civi; - -class Mailing_Hooks { - - /** - * Mailing Url endpoint. - * - * @since 0.1 - * @var string - */ - public $url_endpoint; - - /** - * Mailing Open endpoint. - * - * @since 0.1 - * @var string - */ - public $open_endpoint; - - /** - * The parsed WordPress REST url. - * - * @since 1.0 - * @var array - */ - public $parsed_rest_url; - - /** - * Constructor. - * - * @since 0.1 - */ - public function __construct() { - - $this->url_endpoint = rest_url( 'civicrm/v3/url' ); - - $this->open_endpoint = rest_url( 'civicrm/v3/open' ); - - $this->parsed_rest_url = parse_url( rest_url() ); - - } - - /** - * Register hooks. - * - * @since 0.1 - */ - public function register_hooks() { - - add_filter( 'civicrm_alterMailParams', [ $this, 'do_mailing_urls' ], 10, 2 ); - - add_filter( 'civicrm_alterExternUrl', [ $this, 'alter_mailing_extern_urls' ], 10, 6 ); - - } - - /** - * Replaces the open, and click - * tracking URLs for a mailing (CiviMail) - * with thier REST counterparts. - * - * @uses 'civicrm_alterExternUrl' filter - * - * @param \GuzzleHttp\Psr7\Uri $url - * @param string|null $path - * @param string|null $query - * @param string|null $fragment - * @param bool|null $absolute - * @param bool|null $isSSL - */ - public function alter_mailing_extern_urls( &$url, $path, $query, $fragment, $absolute, $isSSL ) { - - if ( $path == 'extern/url' ) { - $url = $url - ->withHost( $this->parsed_rest_url['host'] ) - ->withPath( "{$this->parsed_rest_url['path']}civicrm/v3/url" ); - } - - if ( $path == 'extern/open' ) { - $url = $url - ->withHost( $this->parsed_rest_url['host'] ) - ->withPath( "{$this->parsed_rest_url['path']}civicrm/v3/open" ); - } - - } - - /** - * Filters the mailing html and replaces calls to 'extern/url.php' and - * 'extern/open.php' with their REST counterparts 'civicrm/v3/url' and 'civicrm/v3/open'. - * - * @uses 'civicrm_alterMailParams' - * - * @since 0.1 - * @param array &$params Mail params - * @param string $context The Context - * @return array $params The filtered Mail params - */ - public function do_mailing_urls( &$params, $context ) { - - if ( in_array( $context, [ 'civimail', 'flexmailer' ] ) ) { - - $params['html'] = $this->is_mail_tracking_url_alterable( $params['html'] ) - ? $this->replace_html_mailing_tracking_urls( $params['html'] ) - : $params['html']; - - $params['text'] = $this->is_mail_tracking_url_alterable( $params['text'] ) - ? $this->replace_text_mailing_tracking_urls( $params['text'] ) - : $params['text']; - - } - - return $params; - - } - - /** - * Replace html mailing tracking urls. - * - * @since 0.1 - * @param string $contnet The mailing content - * @return string $content The mailing content - */ - public function replace_html_mailing_tracking_urls( string $content ) { - - $doc = \phpQuery::newDocument( $content ); - - foreach ( $doc[ '[href*="civicrm/extern/url.php"], [src*="civicrm/extern/open.php"]' ] as $element ) { - - $href = pq( $element )->attr( 'href' ); - $src = pq( $element )->attr( 'src' ); - - // replace extern/url - if ( strpos( $href, 'civicrm/extern/url.php' ) ) { - - $query_string = strstr( $href, '?' ); - pq( $element )->attr( 'href', $this->url_endpoint . $query_string ); - - } - - // replace extern/open - if ( strpos( $src, 'civicrm/extern/open.php' ) ) { - - $query_string = strstr( $src, '?' ); - pq( $element )->attr( 'src', $this->open_endpoint . $query_string ); - - } - - unset( $href, $src, $query_string ); - - } - - return $doc->html(); - - } - - /** - * Replace text mailing tracking urls. - * - * @since 0.1 - * @param string $contnet The mailing content - * @return string $content The mailing content - */ - public function replace_text_mailing_tracking_urls( string $content ) { - - // replace extern url - $content = preg_replace( '/http.*civicrm\/extern\/url\.php/i', $this->url_endpoint, $content ); - - // replace open url - $content = preg_replace( '/http.*civicrm\/extern\/open\.php/i', $this->open_endpoint, $content ); - - return $content; - - } - - /** - * Checks whether for a given mail - * content (text or html) the tracking URLs - * are alterable/need to be altered. - * - * @since 0.1 - * @param string $content The mail content (text or html) - * @return bool $is_alterable - */ - public function is_mail_tracking_url_alterable( string $content ) { - - return strpos( $content, 'civicrm/extern/url.php' ) || strpos( $content, 'civicrm/extern/open.php' ); - - } - -} diff --git a/wp-rest/Controller/AuthorizeIPN.php b/wp-rest/Controller/AuthorizeIPN.php deleted file mode 100644 index 4cd9da9a97..0000000000 --- a/wp-rest/Controller/AuthorizeIPN.php +++ /dev/null @@ -1,123 +0,0 @@ -<?php -/** - * AuthorizeIPN controller class. - * - * Replacement for CiviCRM's 'extern/authorizeIPN.php'. - * - * @see https://docs.civicrm.org/sysadmin/en/latest/setup/payment-processors/authorize-net/#shell-script-testing-method - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Controller; - -class AuthorizeIPN extends Base { - - /** - * The base route. - * - * @since 0.1 - * @var string - */ - protected $rest_base = 'authorizeIPN'; - - /** - * Registers routes. - * - * @since 0.1 - */ - public function register_routes() { - - register_rest_route( $this->get_namespace(), $this->get_rest_base(), [ - [ - 'methods' => \WP_REST_Server::ALLMETHODS, - 'callback' => [ $this, 'get_item' ] - ] - ] ); - - } - - /** - * Get items. - * - * @since 0.1 - * @param WP_REST_Request $request - */ - public function get_item( $request ) { - - /** - * Filter request params. - * - * @since 0.1 - * @param array $params - * @param WP_REST_Request $request - */ - $params = apply_filters( 'civi_wp_rest/controller/authorizeIPN/params', $request->get_params(), $request ); - - $authorize_IPN = new \CRM_Core_Payment_AuthorizeNetIPN( $params ); - - // log notification - \Civi::log()->alert( 'payment_notification processor_name=AuthNet', $params ); - - /** - * Filter AuthorizeIPN object. - * - * @param CRM_Core_Payment_AuthorizeNetIPN $authorize_IPN - * @param array $params - * @param WP_REST_Request $request - */ - $authorize_IPN = apply_filters( 'civi_wp_rest/controller/authorizeIPN/instance', $authorize_IPN, $params, $request ); - - try { - - if ( ! method_exists( $authorize_IPN, 'main' ) || ! $this->instance_of_crm_base_ipn( $authorize_IPN ) ) - return $this->civi_rest_error( sprintf( __( '%s must implement a "main" method.', 'civicrm' ), get_class( $authorize_IPN ) ) ); - - $result = $authorize_IPN->main(); - - } catch ( \CRM_Core_Exception $e ) { - - \Civi::log()->error( $e->getMessage() ); - \Civi::log()->error( 'error data ', [ 'data' => $e->getErrorData() ] ); - \Civi::log()->error( 'REQUEST ', [ 'params' => $params ] ); - - return $this->civi_rest_error( $e->getMessage() ); - - } - - return rest_ensure_response( $result ); - - } - - /** - * Checks whether object is an instance of CRM_Core_Payment_AuthorizeNetIPN or CRM_Core_Payment_BaseIPN. - * - * Needed because the instance is being filtered through 'civi_wp_rest/controller/authorizeIPN/instance'. - * - * @since 0.1 - * @param CRM_Core_Payment_AuthorizeNetIPN|CRM_Core_Payment_BaseIPN $object - * @return bool - */ - public function instance_of_crm_base_ipn( $object ) { - - return $object instanceof \CRM_Core_Payment_BaseIPN || $object instanceof \CRM_Core_Payment_AuthorizeNetIPN; - - } - - /** - * Item schema. - * - * @since 0.1 - * @return array $schema - */ - public function get_item_schema() {} - - /** - * Item arguments. - * - * @since 0.1 - * @return array $arguments - */ - public function get_item_args() {} - -} diff --git a/wp-rest/Controller/Base.php b/wp-rest/Controller/Base.php deleted file mode 100644 index 61ab9b3c63..0000000000 --- a/wp-rest/Controller/Base.php +++ /dev/null @@ -1,111 +0,0 @@ -<?php -/** - * Base controller class. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Controller; - -use CiviCRM_WP_REST\Endpoint\Endpoint_Interface; - -abstract class Base extends \WP_REST_Controller implements Endpoint_Interface { - - /** - * Route namespace. - * - * @since 0.1 - * @var string - */ - protected $namespace = 'civicrm/v3'; - - /** - * Gets the endpoint namespace. - * - * @since 0.1 - * @return string $namespace - */ - public function get_namespace() { - - return $this->namespace; - - } - - /** - * Gets the rest base route. - * - * @since 0.1 - * @return string $rest_base - */ - public function get_rest_base() { - - return '/' . $this->rest_base; - - } - - /** - * Retrieves the endpoint ie. '/civicrm/v3/rest'. - * - * @since 0.1 - * @return string $rest_base - */ - public function get_endpoint() { - - return '/' . $this->get_namespace() . $this->get_rest_base(); - - } - - /** - * Checks whether the requested route is equal to this endpoint. - * - * @since 0.1 - * @param WP_REST_Request $request - * @return bool $is_current_endpoint True if it's equal, false otherwise - */ - public function is_current_endpoint( $request ) { - - return $this->get_endpoint() == $request->get_route(); - - } - - /** - * Authorization status code. - * - * @since 0.1 - * @return int $status - */ - protected function authorization_status_code() { - - $status = 401; - - if ( is_user_logged_in() ) $status = 403; - - return $status; - - } - - /** - * Wrapper for WP_Error. - * - * @since 0.1 - * @param string|\CiviCRM_API3_Exception|\WP_Error $error - * @param mixed $data Error data - * @return WP_Error $error - */ - protected function civi_rest_error( $error, $data = [] ) { - - if ( $error instanceof \CiviCRM_API3_Exception ) { - - return $error->getExtraParams(); - - } elseif ( $error instanceof \WP_Error ) { - - return $error; - - } - - return new \WP_Error( 'civicrm_rest_api_error', $error, empty( $data ) ? [ 'status' => $this->authorization_status_code() ] : $data ); - - } - -} diff --git a/wp-rest/Controller/Cxn.php b/wp-rest/Controller/Cxn.php deleted file mode 100644 index 7f7cca5c56..0000000000 --- a/wp-rest/Controller/Cxn.php +++ /dev/null @@ -1,125 +0,0 @@ -<?php -/** - * Cxn controller class. - * - * CiviConnect endpoint, replacement for CiviCRM's 'extern/cxn.php'. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Controller; - -class Cxn extends Base { - - /** - * The base route. - * - * @since 0.1 - * @var string - */ - protected $rest_base = 'cxn'; - - /** - * Registers routes. - * - * @since 0.1 - */ - public function register_routes() { - - register_rest_route( $this->get_namespace(), $this->get_rest_base(), [ - [ - 'methods' => \WP_REST_Server::ALLMETHODS, - 'callback' => [ $this, 'get_item' ] - ] - ] ); - - } - - /** - * Get items. - * - * @since 0.1 - * @param WP_REST_Request $request - */ - public function get_item( $request ) { - - /** - * Filter request params. - * - * @since 0.1 - * @param array $params - * @param WP_REST_Request $request - */ - $params = apply_filters( 'civi_wp_rest/controller/cxn/params', $request->get_params(), $request ); - - // init connection server - $cxn = \CRM_Cxn_BAO_Cxn::createApiServer(); - - /** - * Filter connection server object. - * - * @param Civi\Cxn\Rpc\ApiServer $cxn - * @param array $params - * @param WP_REST_Request $request - */ - $cxn = apply_filters( 'civi_wp_rest/controller/cxn/instance', $cxn, $params, $request ); - - try { - - $result = $cxn->handle( $request->get_body() ); - - } catch ( Civi\Cxn\Rpc\Exception\CxnException $e ) { - - return $this->civi_rest_error( $e->getMessage() ); - - } catch ( Civi\Cxn\Rpc\Exception\ExpiredCertException $e ) { - - return $this->civi_rest_error( $e->getMessage() ); - - } catch ( Civi\Cxn\Rpc\Exception\InvalidCertException $e ) { - - return $this->civi_rest_error( $e->getMessage() ); - - } catch ( Civi\Cxn\Rpc\Exception\InvalidMessageException $e ) { - - return $this->civi_rest_error( $e->getMessage() ); - - } catch ( Civi\Cxn\Rpc\Exception\GarbledMessageException $e ) { - - return $this->civi_rest_error( $e->getMessage() ); - - } - - /** - * Bypass WP and send request from Cxn. - */ - add_filter( 'rest_pre_serve_request', function( $served, $response, $request, $server ) use ( $result ) { - - // Civi\Cxn\Rpc\Message->send() - $result->send(); - - return true; - - }, 10, 4 ); - - return rest_ensure_response( $result ); - - } - - /** - * Item schema. - * - * @since 0.1 - * @return array $schema - */ - public function get_item_schema() {} - - /** - * Item arguments. - * - * @since 0.1 - * @return array $arguments - */ - public function get_item_args() {} - -} diff --git a/wp-rest/Controller/Open.php b/wp-rest/Controller/Open.php deleted file mode 100644 index 450ef991a3..0000000000 --- a/wp-rest/Controller/Open.php +++ /dev/null @@ -1,129 +0,0 @@ -<?php -/** - * Open controller class. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Controller; - -class Open extends Base { - - /** - * The base route. - * - * @since 0.1 - * @var string - */ - protected $rest_base = 'open'; - - /** - * Registers routes. - * - * @since 0.1 - */ - public function register_routes() { - - register_rest_route( $this->get_namespace(), $this->get_rest_base(), [ - [ - 'methods' => \WP_REST_Server::READABLE, - 'callback' => [ $this, 'get_item' ], - 'args' => $this->get_item_args() - ], - 'schema' => [ $this, 'get_item_schema' ] - ] ); - - } - - /** - * Get item. - * - * @since 0.1 - * @param WP_REST_Request $request - */ - public function get_item( $request ) { - - $queue_id = $request->get_param( 'q' ); - - // track open - \CRM_Mailing_Event_BAO_Opened::open( $queue_id ); - - // serve tracker file - add_filter( 'rest_pre_serve_request', [ $this, 'serve_tracker_file' ], 10, 4 ); - - } - - /** - * Serves the tracker gif file. - * - * @since 0.1 - * @param bool $served Whether the request has been served - * @param WP_REST_Response $result - * @param WP_REST_Request $request - * @param WP_REST_Server $server - * @return bool $served Whether the request has been served - */ - public function serve_tracker_file( $served, $result, $request, $server ) { - - // tracker file path - $file = CIVICRM_PLUGIN_DIR . 'civicrm/i/tracker.gif'; - - // set headers - $server->send_header( 'Content-type', 'image/gif' ); - $server->send_header( 'Cache-Control', 'must-revalidate, post-check=0, pre-check=0' ); - $server->send_header( 'Content-Description', 'File Transfer' ); - $server->send_header( 'Content-Disposition', 'inline; filename=tracker.gif' ); - $server->send_header( 'Content-Length', filesize( $file ) ); - - $buffer = readfile( $file ); - - return true; - - } - - /** - * Item schema. - * - * @since 0.1 - * @return array $schema - */ - public function get_item_schema() { - - return [ - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'civicrm/v3/open', - 'description' => __( 'CiviCRM Open endpoint', 'civicrm' ), - 'type' => 'object', - 'required' => [ 'q' ], - 'properties' => [ - 'q' => [ - 'type' => 'integer' - ] - ] - ]; - - } - - /** - * Item arguments. - * - * @since 0.1 - * @return array $arguments - */ - public function get_item_args() { - - return [ - 'q' => [ - 'type' => 'integer', - 'required' => true, - 'validate_callback' => function( $value, $request, $key ) { - - return is_numeric( $value ); - - } - ] - ]; - - } - -} diff --git a/wp-rest/Controller/PayPalIPN.php b/wp-rest/Controller/PayPalIPN.php deleted file mode 100644 index 5b5c380045..0000000000 --- a/wp-rest/Controller/PayPalIPN.php +++ /dev/null @@ -1,134 +0,0 @@ -<?php -/** - * PayPalIPN controller class. - * - * PayPal IPN endpoint, replacement for CiviCRM's 'extern/ipn.php'. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Controller; - -class PayPalIPN extends Base { - - /** - * The base route. - * - * @since 0.1 - * @var string - */ - protected $rest_base = 'ipn'; - - /** - * Registers routes. - * - * @since 0.1 - */ - public function register_routes() { - - register_rest_route( $this->get_namespace(), $this->get_rest_base(), [ - [ - 'methods' => \WP_REST_Server::ALLMETHODS, - 'callback' => [ $this, 'get_item' ] - ] - ] ); - - } - - /** - * Get items. - * - * @since 0.1 - * @param WP_REST_Request $request - */ - public function get_item( $request ) { - - /** - * Filter request params. - * - * @since 0.1 - * @param array $params - * @param WP_REST_Request $request - */ - $params = apply_filters( 'civi_wp_rest/controller/ipn/params', $request->get_params(), $request ); - - if ( $request->get_method() == 'GET' ) { - - // paypal standard - $paypal_IPN = new \CRM_Core_Payment_PayPalIPN( $params ); - - // log notification - \Civi::log()->alert( 'payment_notification processor_name=PayPal_Standard', $params ); - - } else { - - // paypal pro - $paypal_IPN = new \CRM_Core_Payment_PayPalProIPN( $params ); - - // log notification - \Civi::log()->alert( 'payment_notification processor_name=PayPal', $params ); - - } - - /** - * Filter PayPalIPN object. - * - * @param CRM_Core_Payment_PayPalIPN|CRM_Core_Payment_PayPalProIPN $paypal_IPN - * @param array $params - * @param WP_REST_Request $request - */ - $paypal_IPN = apply_filters( 'civi_wp_rest/controller/ipn/instance', $paypal_IPN, $params, $request ); - - try { - - if ( ! method_exists( $paypal_IPN, 'main' ) || ! $this->instance_of_crm_base_ipn( $paypal_IPN ) ) - return $this->civi_rest_error( sprintf( __( '%s must implement a "main" method.', 'civicrm' ), get_class( $paypal_IPN ) ) ); - - $result = $paypal_IPN->main(); - - } catch ( \CRM_Core_Exception $e ) { - - \Civi::log()->error( $e->getMessage() ); - \Civi::log()->error( 'error data ', [ 'data' => $e->getErrorData() ] ); - \Civi::log()->error( 'REQUEST ', [ 'params' => $params ] ); - - return $this->civi_rest_error( $e->getMessage() ); - - } - - return rest_ensure_response( $result ); - - } - - /** - * Checks whether object is an instance of CRM_Core_Payment_BaseIPN|CRM_Core_Payment_PayPalProIPN|CRM_Core_Payment_PayPalIPN. - * - * Needed because the instance is being filtered through 'civi_wp_rest/controller/ipn/instance'. - * - * @since 0.1 - * @param CRM_Core_Payment_BaseIPN|CRM_Core_Payment_PayPalProIPN|CRM_Core_Payment_PayPalIPN $object - * @return bool - */ - public function instance_of_crm_base_ipn( $object ) { - - return $object instanceof \CRM_Core_Payment_BaseIPN || $object instanceof \CRM_Core_Payment_PayPalProIPN || $object instanceof \CRM_Core_Payment_PayPalIPN; - - } - - /** - * Item schema. - * - * @since 0.1 - * @return array $schema - */ - public function get_item_schema() {} - - /** - * Item arguments. - * - * @since 0.1 - * @return array $arguments - */ - public function get_item_args() {} - -} diff --git a/wp-rest/Controller/PxIPN.php b/wp-rest/Controller/PxIPN.php deleted file mode 100644 index d68fc8d787..0000000000 --- a/wp-rest/Controller/PxIPN.php +++ /dev/null @@ -1,139 +0,0 @@ -<?php -/** - * PxIPN controller class. - * - * PxPay IPN endpoint, replacement for CiviCRM's 'extern/pxIPN.php'. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Controller; - -class PxIPN extends Base { - - /** - * The base route. - * - * @since 0.1 - * @var string - */ - protected $rest_base = 'pxIPN'; - - /** - * Registers routes. - * - * @since 0.1 - */ - public function register_routes() { - - register_rest_route( $this->get_namespace(), $this->get_rest_base(), [ - [ - 'methods' => \WP_REST_Server::ALLMETHODS, - 'callback' => [ $this, 'get_item' ] - ] - ] ); - - } - - /** - * Get items. - * - * @since 0.1 - * @param WP_REST_Request $request - */ - public function get_item( $request ) { - - /** - * Filter payment processor params. - * - * @since 0.1 - * @param array $params - * @param WP_REST_Request $request - */ - $params = apply_filters( - 'civi_wp_rest/controller/pxIPN/params', - $this->get_payment_processor_args( $request ), - $request - ); - - // log notification - \Civi::log()->alert( 'payment_notification processor_name=Payment_Express', $params ); - - try { - - $result = \CRM_Core_Payment_PaymentExpressIPN::main( ...$params ); - - } catch ( \CRM_Core_Exception $e ) { - - \Civi::log()->error( $e->getMessage() ); - \Civi::log()->error( 'error data ', [ 'data' => $e->getErrorData() ] ); - \Civi::log()->error( 'REQUEST ', [ 'params' => $params ] ); - - return $this->civi_rest_error( $e->getMessage() ); - - } - - return rest_ensure_response( $result ); - - } - - /** - * Get payment processor necessary params. - * - * @since 0.1 - * @param WP_REST_Resquest $request - * @return array $args - */ - public function get_payment_processor_args( $request ) { - - // get payment processor types - $payment_processor_types = civicrm_api3( 'PaymentProcessor', 'getoptions', [ - 'field' => 'payment_processor_type_id' - ] ); - - // payment processor params - $params = apply_filters( 'civi_wp_rest/controller/pxIPN/payment_processor_params', [ - 'user_name' => $request->get_param( 'userid' ), - 'payment_processor_type_id' => array_search( - 'DPS Payment Express', - $payment_processor_types['values'] - ), - 'is_active' => 1, - 'is_test' => 0 - ] ); - - // get payment processor - $payment_processor = civicrm_api3( 'PaymentProcessor', 'get', $params ); - - $args = $payment_processor['values'][$payment_processor['id']]; - - $method = empty( $args['signature'] ) ? 'pxpay' : 'pxaccess'; - - return [ - $method, - $request->get_param( 'result' ), - $args['url_site'], - $args['user_name'], - $args['password'], - $args['signature'] - ]; - - } - - /** - * Item schema. - * - * @since 0.1 - * @return array $schema - */ - public function get_item_schema() {} - - /** - * Item arguments. - * - * @since 0.1 - * @return array $arguments - */ - public function get_item_args() {} - -} diff --git a/wp-rest/Controller/Rest.php b/wp-rest/Controller/Rest.php deleted file mode 100644 index 68b669895b..0000000000 --- a/wp-rest/Controller/Rest.php +++ /dev/null @@ -1,497 +0,0 @@ -<?php -/** - * Rest controller class. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Controller; - -class Rest extends Base { - - /** - * The base route. - * - * @since 0.1 - * @var string - */ - protected $rest_base = 'rest'; - - /** - * Registers routes. - * - * @since 0.1 - */ - public function register_routes() { - - register_rest_route( $this->get_namespace(), $this->get_rest_base(), [ - [ - 'methods' => \WP_REST_Server::ALLMETHODS, - 'callback' => [ $this, 'get_items' ], - 'permission_callback' => [ $this, 'permissions_check' ], - 'args' => $this->get_item_args() - ], - 'schema' => [ $this, 'get_item_schema' ] - ] ); - - } - - /** - * Check get permission. - * - * @since 0.1 - * @param WP_REST_Request $request - * @return bool - */ - public function permissions_check( $request ) { - - /** - * Opportunity to bypass CiviCRM's - * authentication ('api_key' and 'site_key'), - * return 'true' or 'false' to grant - * or deny access to this endpoint. - * - * To deny and throw an error, return either - * a string, an array, or a \WP_Error. - * - * NOTE: if you use your won authentication, - * you still must log in the user in order - * to respect/apply CiviCRM ACLs. - * - * @since 0.1 - * @param null|bool|string|array|\WP_Error $grant_auth Grant, deny, or error - * @param \WP_REST_Request $request The request - */ - $grant_auth = apply_filters( 'civi_wp_rest/controller/rest/permissions_check', null, $request ); - - if ( is_bool( $grant_auth ) ) { - - return $grant_auth; - - } elseif ( is_string( $grant_auth ) ) { - - return $this->civi_rest_error( $grant_auth ); - - } elseif ( is_array( $grant_auth ) ) { - - return $this->civi_rest_error( __( 'CiviCRM WP REST permission check error.', 'civicrm' ), $grant_auth ); - - } elseif ( $grant_auth instanceof \WP_Error ) { - - return $grant_auth; - - } else { - - if ( ! $this->is_valid_api_key( $request ) ) - return $this->civi_rest_error( __( 'Param api_key is not valid.', 'civicrm' ) ); - - if ( ! $this->is_valid_site_key() ) - return $this->civi_rest_error( __( 'Param key is not valid.', 'civicrm' ) ); - - return true; - - } - - } - - /** - * Get items. - * - * @since 0.1 - * @param WP_REST_Request $request - */ - public function get_items( $request ) { - - /** - * Filter formatted api params. - * - * @since 0.1 - * @param array $params - * @param WP_REST_Request $request - */ - $params = apply_filters( 'civi_wp_rest/controller/rest/api_params', $this->get_formatted_api_params( $request ), $request ); - - try { - - $items = civicrm_api3( ...$params ); - - } catch ( \CiviCRM_API3_Exception $e ) { - - $items = $this->civi_rest_error( $e ); - - } - - if ( ! isset( $items ) || empty( $items ) ) - return rest_ensure_response( [] ); - - /** - * Filter civi api result. - * - * @since 0.1 - * @param array $items - * @param WP_REST_Request $request - */ - $data = apply_filters( 'civi_wp_rest/controller/rest/api_result', $items, $params, $request ); - - // only collections of items, ie any action but 'getsingle' - if ( isset( $data['values'] ) ) { - - $data['values'] = array_reduce( $items['values'] ?? $items, function( $items, $item ) use ( $request ) { - - $response = $this->prepare_item_for_response( $item, $request ); - - $items[] = $this->prepare_response_for_collection( $response ); - - return $items; - - }, [] ); - - } - - $response = rest_ensure_response( $data ); - - // check wheather we need to serve xml or json - if ( ! in_array( 'json', array_keys( $request->get_params() ) ) ) { - - /** - * Adds our response holding Civi data before dispatching. - * - * @since 0.1 - * @param WP_HTTP_Response $result Result to send to client - * @param WP_REST_Server $server The REST server - * @param WP_REST_Request $request The request - * @return WP_HTTP_Response $result Result to send to client - */ - add_filter( 'rest_post_dispatch', function( $result, $server, $request ) use ( $response ) { - - return $response; - - }, 10, 3 ); - - // serve xml - add_filter( 'rest_pre_serve_request', [ $this, 'serve_xml_response' ], 10, 4 ); - - } else { - - // return json - return $response; - - } - - } - - /** - * Get formatted api params. - * - * @since 0.1 - * @param WP_REST_Resquest $request - * @return array $params - */ - public function get_formatted_api_params( $request ) { - - $args = $request->get_params(); - - $entity = $args['entity']; - $action = $args['action']; - - // unset unnecessary args - unset( $args['entity'], $args['action'], $args['key'], $args['api_key'] ); - - if ( ! isset( $args['json'] ) || is_numeric( $args['json'] ) ) { - - $params = $args; - - } else { - - $params = is_string( $args['json'] ) ? json_decode( $args['json'], true ) : []; - - } - - // ensure check permissions is enabled - $params['check_permissions'] = true; - - return [ $entity, $action, $params ]; - - } - - /** - * Matches the item data to the schema. - * - * @since 0.1 - * @param object $item - * @param WP_REST_Request $request - */ - public function prepare_item_for_response( $item, $request ) { - - return rest_ensure_response( $item ); - - } - - /** - * Serves XML response. - * - * @since 0.1 - * @param bool $served Whether the request has already been served - * @param WP_REST_Response $result - * @param WP_REST_Request $request - * @param WP_REST_Server $server - */ - public function serve_xml_response( $served, $result, $request, $server ) { - - // get xml from response - $xml = $this->get_xml_formatted_data( $result->get_data() ); - - // set content type header - $server->send_header( 'Content-Type', 'text/xml' ); - - echo $xml; - - return true; - - } - - /** - * Formats CiviCRM API result to XML. - * - * @since 0.1 - * @param array $data The CiviCRM api result - * @return string $xml The formatted xml - */ - protected function get_xml_formatted_data( array $data ) { - - // xml document - $xml = new \DOMDocument(); - - // result set element <ResultSet> - $result_set = $xml->createElement( 'ResultSet' ); - - // xmlns:xsi attribute - $result_set->setAttribute( 'xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance' ); - - // count attribute - if ( isset( $data['count'] ) ) $result_set->setAttribute( 'count', $data['count'] ); - - // build result from result => values - if ( isset( $data['values'] ) ) { - - array_map( function( $item ) use ( $result_set, $xml ) { - - // result element <Result> - $result = $xml->createElement( 'Result' ); - - // format item - $result = $this->get_xml_formatted_item( $item, $result, $xml ); - - // append result to result set - $result_set->appendChild( $result ); - - }, $data['values'] ); - - } else { - - // result element <Result> - $result = $xml->createElement( 'Result' ); - - // format item - $result = $this->get_xml_formatted_item( $data, $result, $xml ); - - // append result to result set - $result_set->appendChild( $result ); - - } - - // append result set - $xml->appendChild( $result_set ); - - return $xml->saveXML(); - - } - - /** - * Formats a single api result to xml. - * - * @since 0.1 - * @param array $item The single api result - * @param DOMElement $parent The parent element to append to - * @param DOMDocument $doc The document - * @return DOMElement $parent The parent element - */ - public function get_xml_formatted_item( array $item, \DOMElement $parent, \DOMDocument $doc ) { - - // build field => values - array_map( function( $field, $value ) use ( $parent, $doc ) { - - // entity field element - $element = $doc->createElement( $field ); - - // handle array values - if ( is_array( $value ) ) { - - array_map( function( $key, $val ) use ( $element, $doc ) { - - // child element, append underscore '_' otherwise createElement - // will throw an Invalid character exception as elements cannot start with a number - $child = $doc->createElement( '_' . $key, $val ); - - // append child - $element->appendChild( $child ); - - }, array_keys( $value ), $value ); - - } else { - - // assign value - $element->nodeValue = $value; - - } - - // append element - $parent->appendChild( $element ); - - }, array_keys( $item ), $item ); - - return $parent; - - } - - /** - * Item schema. - * - * @since 0.1 - * @return array $schema - */ - public function get_item_schema() { - - return [ - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'civicrm/v3/rest', - 'description' => __( 'CiviCRM API3 WP rest endpoint wrapper', 'civicrm' ), - 'type' => 'object', - 'required' => [ 'entity', 'action', 'params' ], - 'properties' => [ - 'is_error' => [ - 'type' => 'integer' - ], - 'version' => [ - 'type' => 'integer' - ], - 'count' => [ - 'type' => 'integer' - ], - 'values' => [ - 'type' => 'array' - ] - ] - ]; - - } - - /** - * Item arguments. - * - * @since 0.1 - * @return array $arguments - */ - public function get_item_args() { - - return [ - 'key' => [ - 'type' => 'string', - 'required' => false, - 'validate_callback' => function( $value, $request, $key ) { - - return $this->is_valid_site_key(); - - } - ], - 'api_key' => [ - 'type' => 'string', - 'required' => false, - 'validate_callback' => function( $value, $request, $key ) { - - return $this->is_valid_api_key( $request ); - - } - ], - 'entity' => [ - 'type' => 'string', - 'required' => true, - 'validate_callback' => function( $value, $request, $key ) { - - return is_string( $value ); - - } - ], - 'action' => [ - 'type' => 'string', - 'required' => true, - 'validate_callback' => function( $value, $request, $key ) { - - return is_string( $value ); - - } - ], - 'json' => [ - 'type' => ['integer', 'string', 'array'], - 'required' => false, - 'validate_callback' => function( $value, $request, $key ) { - - return is_numeric( $value ) || is_array( $value ) || $this->is_valid_json( $value ); - - } - ] - ]; - - } - - /** - * Checks if string is a valid json. - * - * @since 0.1 - * @param string $param - * @return bool - */ - public function is_valid_json( $param ) { - - $param = json_decode( $param, true ); - - if ( ! is_array( $param ) ) return false; - - return ( json_last_error() == JSON_ERROR_NONE ); - - } - - /** - * Validates the site key. - * - * @since 0.1 - * @return bool $is_valid_site_key - */ - public function is_valid_site_key() { - - return \CRM_Utils_System::authenticateKey( false ); - - } - - /** - * Validates the api key. - * - * @since 0.1 - * @param WP_REST_Resquest $request - * @return bool $is_valid_api_key - */ - public function is_valid_api_key( $request ) { - - $api_key = $request->get_param( 'api_key' ); - - if ( ! $api_key ) return false; - - $contact_id = \CRM_Core_DAO::getFieldValue( 'CRM_Contact_DAO_Contact', $api_key, 'id', 'api_key' ); - - if ( ! $contact_id ) return false; - - return true; - - } - -} diff --git a/wp-rest/Controller/Soap.php b/wp-rest/Controller/Soap.php deleted file mode 100644 index 17402cc579..0000000000 --- a/wp-rest/Controller/Soap.php +++ /dev/null @@ -1,98 +0,0 @@ -<?php -/** - * Soap controller class. - * - * Soap endpoint, replacement for CiviCRM's 'extern/soap.php'. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Controller; - -class Soap extends Base { - - /** - * The base route. - * - * @since 0.1 - * @var string - */ - protected $rest_base = 'soap'; - - /** - * Registers routes. - * - * @since 0.1 - */ - public function register_routes() { - - register_rest_route( $this->get_namespace(), $this->get_rest_base(), [ - [ - 'methods' => \WP_REST_Server::ALLMETHODS, - 'callback' => [ $this, 'get_item' ] - ] - ] ); - - } - - /** - * Get items. - * - * @since 0.1 - * @param WP_REST_Request $request - */ - public function get_item( $request ) { - - /** - * Filter request params. - * - * @since 0.1 - * @param array $params - * @param WP_REST_Request $request - */ - $params = apply_filters( 'civi_wp_rest/controller/soap/params', $request->get_params(), $request ); - - // init soap server - $soap_server = new \SoapServer( - NULL, - [ - 'uri' => 'urn:civicrm', - 'soap_version' => SOAP_1_2, - ] - ); - - $crm_soap_server = new \CRM_Utils_SoapServer(); - - $soap_server->setClass( 'CRM_Utils_SoapServer', \CRM_Core_Config::singleton()->userFrameworkClass ); - $soap_server->setPersistence( SOAP_PERSISTENCE_SESSION ); - - /** - * Bypass WP and send request from Soap server. - */ - add_filter( 'rest_pre_serve_request', function( $served, $response, $request, $server ) use ( $soap_server ) { - - $soap_server->handle(); - - return true; - - }, 10, 4 ); - - } - - /** - * Item schema. - * - * @since 0.1 - * @return array $schema - */ - public function get_item_schema() {} - - /** - * Item arguments. - * - * @since 0.1 - * @return array $arguments - */ - public function get_item_args() {} - -} diff --git a/wp-rest/Controller/Url.php b/wp-rest/Controller/Url.php deleted file mode 100644 index 6f1009f8fd..0000000000 --- a/wp-rest/Controller/Url.php +++ /dev/null @@ -1,216 +0,0 @@ -<?php -/** - * Url controller class. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Controller; - -class Url extends Base { - - /** - * The base route. - * - * @since 0.1 - * @var string - */ - protected $rest_base = 'url'; - - /** - * Registers routes. - * - * @since 0.1 - */ - public function register_routes() { - - register_rest_route( $this->get_namespace(), $this->get_rest_base(), [ - [ - 'methods' => \WP_REST_Server::READABLE, - 'callback' => [ $this, 'get_item' ], - 'args' => $this->get_item_args() - ], - 'schema' => [ $this, 'get_item_schema' ] - ] ); - - } - - /** - * Get items. - * - * @since 0.1 - * @param WP_REST_Request $request - */ - public function get_item( $request ) { - - /** - * Filter formatted api params. - * - * @since 0.1 - * @param array $params - * @param WP_REST_Request $request - */ - $params = apply_filters( 'civi_wp_rest/controller/url/params', $this->get_formatted_params( $request ), $request ); - - // track url - $url = \CRM_Mailing_Event_BAO_TrackableURLOpen::track( $params['queue_id'], $params['url_id'] ); - - /** - * Filter url. - * - * @param string $url - * @param array $params - * @param WP_REST_Request $request - */ - $url = apply_filters( 'civi_wp_rest/controller/url/before_parse_url', $url, $params, $request ); - - // parse url - $url = $this->parse_url( $url, $params ); - - $this->do_redirect( $url ); - - } - - /** - * Get formatted api params. - * - * @since 0.1 - * @param WP_REST_Resquest $request - * @return array $params - */ - protected function get_formatted_params( $request ) { - - $args = $request->get_params(); - - $params = [ - 'queue_id' => isset( $args['qid'] ) ? $args['qid'] ?? '' : $args['q'] ?? '', - 'url_id' => $args['u'] - ]; - - // unset unnecessary args - unset( $args['qid'], $args['u'], $args['q'] ); - - if ( ! empty( $args ) ) { - - $params['query'] = http_build_query( $args ); - - } - - return $params; - - } - - /** - * Parses the url. - * - * @since 0.1 - * @param string $url - * @param array $params - * @return string $url - */ - protected function parse_url( $url, $params ) { - - // CRM-18320 - Fix encoded ampersands - $url = str_replace( '&', '&', $url ); - - // CRM-7103 - Look for additional query variables and append them - if ( isset( $params['query'] ) && strpos( $url, '?' ) ) { - - $url .= '&' . $params['query']; - - } elseif ( isset( $params['query'] ) ) { - - $url .= '?' . $params['query']; - - } - - if ( strpos( $url, 'mailto' ) ) $url = strstr( $url, 'mailto' ); - - return apply_filters( 'civi_wp_rest/controller/url/parsed_url', $url, $params ); - - } - - /** - * Do redirect. - * - * @since 0.1 - * @param string $url - */ - protected function do_redirect( $url ) { - - wp_redirect( $url ); - - exit; - - } - - /** - * Item schema. - * - * @since 0.1 - * @return array $schema - */ - public function get_item_schema() { - - return [ - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'civicrm_api3/v3/url', - 'description' => __( 'CiviCRM API3 wrapper', 'civicrm' ), - 'type' => 'object', - 'required' => [ 'qid', 'u' ], - 'properties' => [ - 'qid' => [ - 'type' => 'integer' - ], - 'q' => [ - 'type' => 'integer' - ], - 'u' => [ - 'type' => 'integer' - ] - ] - ]; - - } - - /** - * Item arguments. - * - * @since 0.1 - * @return array $arguments - */ - public function get_item_args() { - - return [ - 'qid' => [ - 'type' => 'integer', - 'required' => false, - 'validate_callback' => function( $value, $request, $key ) { - - return is_numeric( $value ); - - } - ], - 'q' => [ - 'type' => 'integer', - 'required' => false, - 'validate_callback' => function( $value, $request, $key ) { - - return is_numeric( $value ); - - } - ], - 'u' => [ - 'type' => 'integer', - 'required' => true, - 'validate_callback' => function( $value, $request, $key ) { - - return is_numeric( $value ); - - } - ] - ]; - - } - -} diff --git a/wp-rest/Controller/Widget.php b/wp-rest/Controller/Widget.php deleted file mode 100644 index 13fa1e2add..0000000000 --- a/wp-rest/Controller/Widget.php +++ /dev/null @@ -1,214 +0,0 @@ -<?php -/** - * Widget controller class. - * - * Widget endpoint, replacement for CiviCRM's 'extern/widget.php' - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Controller; - -class Widget extends Base { - - /** - * The base route. - * - * @since 0.1 - * @var string - */ - protected $rest_base = 'widget'; - - /** - * Registers routes. - * - * @since 0.1 - */ - public function register_routes() { - - register_rest_route( $this->get_namespace(), $this->get_rest_base(), [ - [ - 'methods' => \WP_REST_Server::READABLE, - 'callback' => [ $this, 'get_item' ], - 'args' => $this->get_item_args() - ], - 'schema' => [ $this, 'get_item_schema' ] - ] ); - - } - - /** - * Get item. - * - * @since 0.1 - * @param WP_REST_Request $request - */ - public function get_item( $request ) { - - /** - * Filter mandatory params. - * - * @since 0.1 - * @param array $params - * @param WP_REST_Request $request - */ - $params = apply_filters( - 'civi_wp_rest/controller/widget/params', - $this->get_mandatory_params( $request ), - $request - ); - - $jsonvar = 'jsondata'; - - if ( ! empty( $request->get_param( 'format' ) ) ) $jsonvar .= $request->get_param( 'cpageId' ); - - $data = \CRM_Contribute_BAO_Widget::getContributionPageData( ...$params ); - - $response = 'var ' . $jsonvar . ' = ' . json_encode( $data ) . ';'; - - /** - * Adds our response data before dispatching. - * - * @since 0.1 - * @param WP_HTTP_Response $result Result to send to client - * @param WP_REST_Server $server The REST server - * @param WP_REST_Request $request The request - * @return WP_HTTP_Response $result Result to send to client - */ - add_filter( 'rest_post_dispatch', function( $result, $server, $request ) use ( $response ) { - - return rest_ensure_response( $response ); - - }, 10, 3 ); - - // serve javascript - add_filter( 'rest_pre_serve_request', [ $this, 'serve_javascript' ], 10, 4 ); - - } - - /** - * Get mandatory params from request. - * - * @since 0.1 - * @param WP_REST_Resquest $request - * @return array $params The widget params - */ - protected function get_mandatory_params( $request ) { - - $args = $request->get_params(); - - return [ - $args['cpageId'], - $args['widgetId'], - $args['includePending'] ?? false - ]; - - } - - /** - * Serve jsondata response. - * - * @since 0.1 - * @param bool $served Whether the request has already been served - * @param WP_REST_Response $result - * @param WP_REST_Request $request - * @param WP_REST_Server $server - * @return bool $served - */ - public function serve_javascript( $served, $result, $request, $server ) { - - // set content type header - $server->send_header( 'Expires', gmdate( 'D, d M Y H:i:s \G\M\T', time() + 60 ) ); - $server->send_header( 'Content-Type', 'application/javascript' ); - $server->send_header( 'Cache-Control', 'max-age=60, public' ); - - echo $result->get_data(); - - return true; - - } - - /** - * Item schema. - * - * @since 0.1 - * @return array $schema - */ - public function get_item_schema() { - - return [ - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'civicrm_api3/v3/widget', - 'description' => __( 'CiviCRM API3 wrapper', 'civicrm' ), - 'type' => 'object', - 'required' => [ 'cpageId', 'widgetId' ], - 'properties' => [ - 'cpageId' => [ - 'type' => 'integer', - 'minimum' => 1 - ], - 'widgetId' => [ - 'type' => 'integer', - 'minimum' => 1 - ], - 'format' => [ - 'type' => 'integer' - ], - 'includePending' => [ - 'type' => 'boolean' - ] - ] - ]; - - } - - /** - * Item arguments. - * - * @since 0.1 - * @return array $arguments - */ - public function get_item_args() { - - return [ - 'cpageId' => [ - 'type' => 'integer', - 'required' => true, - 'validate_callback' => function( $value, $request, $key ) { - - return is_numeric( $value ); - - } - ], - 'widgetId' => [ - 'type' => 'integer', - 'required' => true, - 'validate_callback' => function( $value, $request, $key ) { - - return is_numeric( $value ); - - } - ], - 'format' => [ - 'type' => 'integer', - 'required' => false, - 'validate_callback' => function( $value, $request, $key ) { - - return is_numeric( $value ); - - } - ], - 'includePending' => [ - 'type' => 'boolean', - 'required' => false, - 'validate_callback' => function( $value, $request, $key ) { - - return is_string( $value ); - - } - ] - ]; - - } - -} diff --git a/wp-rest/Endpoint/Endpoint-Interface.php b/wp-rest/Endpoint/Endpoint-Interface.php deleted file mode 100644 index 9497cde509..0000000000 --- a/wp-rest/Endpoint/Endpoint-Interface.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * Endpoint Interface class. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST\Endpoint; - -interface Endpoint_Interface { - - /** - * Registers routes. - * - * @since 0.1 - */ - public function register_routes(); - - /** - * Item schema. - * - * @since 0.1 - * @return array $schema - */ - public function get_item_schema(); - - /** - * Item arguments. - * - * @since 0.1 - * @return array $arguments - */ - public function get_item_args(); - -} diff --git a/wp-rest/Plugin.php b/wp-rest/Plugin.php deleted file mode 100644 index 3531e597e4..0000000000 --- a/wp-rest/Plugin.php +++ /dev/null @@ -1,379 +0,0 @@ -<?php -/** - * Main plugin class. - * - * @since 0.1 - */ - -namespace CiviCRM_WP_REST; - -use CiviCRM_WP_REST\Civi\Mailing_Hooks; - -class Plugin { - - /** - * Constructor. - * - * @since 0.1 - */ - public function __construct() { - - $this->register_hooks(); - - $this->setup_objects(); - - } - - /** - * Register hooks. - * - * @since 1.0 - */ - protected function register_hooks() { - - add_action( 'rest_api_init', [ $this, 'register_rest_routes' ] ); - - add_filter( 'rest_pre_dispatch', [ $this, 'bootstrap_civi' ], 10, 3 ); - - add_filter( 'rest_post_dispatch', [ $this, 'maybe_reset_wp_timezone' ], 10, 3); - - } - - /** - * Bootstrap CiviCRM when hitting a the 'civicrm' namespace. - * - * @since 0.1 - * @param mixed $result - * @param WP_REST_Server $server REST server instance - * @param WP_REST_Request $request The request - * @return mixed $result - */ - public function bootstrap_civi( $result, $server, $request ) { - - if ( false !== strpos( $request->get_route(), 'civicrm' ) ) { - - $this->maybe_set_user_timezone( $request ); - - civi_wp()->initialize(); - - // rest calls need a wp user, do login - if ( false !== strpos( $request->get_route(), 'rest' ) ) { - - $logged_in_wp_user = $this->do_user_login( $request ); - - // return error - if ( is_wp_error( $logged_in_wp_user ) ) { - return $logged_in_wp_user; - } - } - - } - - return $result; - - } - - /** - * Setup objects. - * - * @since 0.1 - */ - private function setup_objects() { - - /** - * Filter to replace the mailing tracking URLs. - * - * @since 0.1 - * @param bool $replace_mailing_tracking_urls - */ - $replace_mailing_tracking_urls = apply_filters( 'civi_wp_rest/plugin/replace_mailing_tracking_urls', false ); - - // keep CIVICRM_WP_REST_REPLACE_MAILING_TRACKING for backwards compatibility - if ( - $replace_mailing_tracking_urls - || ( defined( 'CIVICRM_WP_REST_REPLACE_MAILING_TRACKING' ) && CIVICRM_WP_REST_REPLACE_MAILING_TRACKING ) - ) { - // register mailing hooks - $mailing_hooks = ( new Mailing_Hooks )->register_hooks(); - - } - - } - - /** - * Registers Rest API routes. - * - * @since 0.1 - */ - public function register_rest_routes() { - - // rest endpoint - $rest_controller = new Controller\Rest; - $rest_controller->register_routes(); - - // url controller - $url_controller = new Controller\Url; - $url_controller->register_routes(); - - // open controller - $open_controller = new Controller\Open; - $open_controller->register_routes(); - - // authorizenet controller - $authorizeIPN_controller = new Controller\AuthorizeIPN; - $authorizeIPN_controller->register_routes(); - - // paypal controller - $paypalIPN_controller = new Controller\PayPalIPN; - $paypalIPN_controller->register_routes(); - - // pxpay controller - $paypalIPN_controller = new Controller\PxIPN; - $paypalIPN_controller->register_routes(); - - // civiconnect controller - $cxn_controller = new Controller\Cxn; - $cxn_controller->register_routes(); - - // widget controller - $widget_controller = new Controller\Widget; - $widget_controller->register_routes(); - - // soap controller - $soap_controller = new Controller\Soap; - $soap_controller->register_routes(); - - /** - * Opportunity to add more rest routes. - * - * @since 0.1 - */ - do_action( 'civi_wp_rest/plugin/rest_routes_registered' ); - - } - - /** - * Sets the timezone to the users timezone when - * calling the civicrm/v3/rest endpoint. - * - * @since 0.1 - * @param WP_REST_Request $request The request - */ - private function maybe_set_user_timezone( $request ) { - - if ( $request->get_route() != '/civicrm/v3/rest' ) return; - - $timezones = [ - 'wp_timezone' => date_default_timezone_get(), - 'user_timezone' => get_option( 'timezone_string', false ) - ]; - - // filter timezones - add_filter( 'civi_wp_rest/plugin/timezones', function() use ( $timezones ) { - - return $timezones; - - } ); - - if ( empty( $timezones['user_timezone'] ) ) return; - - /** - * CRM-12523 - * CRM-18062 - * CRM-19115 - */ - date_default_timezone_set( $timezones['user_timezone'] ); - \CRM_Core_Config::singleton()->userSystem->setMySQLTimeZone(); - - } - - /** - * Resets the timezone to the original WP - * timezone after calling the civicrm/v3/rest endpoint. - * - * @since 0.1 - * @param mixed $result - * @param WP_REST_Server $server REST server instance - * @param WP_REST_Request $request The request - * @return mixed $result - */ - public function maybe_reset_wp_timezone( $result, $server, $request ) { - - if ( $request->get_route() != '/civicrm/v3/rest' ) return $result; - - $timezones = apply_filters( 'civi_wp_rest/plugin/timezones', null ); - - if ( empty( $timezones['wp_timezone'] ) ) return $result; - - // reset wp timezone - date_default_timezone_set( $timezones['wp_timezone'] ); - - return $result; - - } - - /** - * Performs the necessary checks and - * data retrieval to login a WordPress user. - * - * @since 0.1 - * @param \WP_REST_Request $request The request - * @return \WP_User|\WP_Error|void $logged_in_wp_user The logged in WordPress user object, \Wp_Error, or nothing - */ - public function do_user_login( $request ) { - - /** - * Filter and opportunity to bypass - * the default user login. - * - * @since 0.1 - * @param bool $login - */ - $logged_in = apply_filters( 'civi_wp_rest/plugin/do_user_login', false, $request ); - - if ( $logged_in ) return; - - // default login based on contact's api_key - if ( ! ( new Controller\Rest )->is_valid_api_key( $request ) ) { - return new \WP_Error( - 'civicrm_rest_api_error', - __( 'Missing or invalid param "api_key".', 'civicrm' ) - ); - } - - $contact_id = \CRM_Core_DAO::getFieldValue( - 'CRM_Contact_DAO_Contact', - $request->get_param( 'api_key' ), - 'id', - 'api_key' - ); - - $wp_user = $this->get_wp_user( $contact_id ); - - if ( is_wp_error( $wp_user ) ) { - return $wp_user; - } - - return $this->login_wp_user( $wp_user, $request ); - - } - - /** - * Get WordPress user data. - * - * @since 0.1 - * @param int $contact_id The contact id - * @return WP_User|WP_Error $user The WordPress user data or WP_Error object - */ - public function get_wp_user( int $contact_id ) { - - try { - - // Call API. - $uf_match = civicrm_api3( 'UFMatch', 'getsingle', [ - 'contact_id' => $contact_id, - 'domain_id' => $this->get_civi_domain_id(), - ] ); - - } catch ( \CiviCRM_API3_Exception $e ) { - - return new \WP_Error( - 'civicrm_rest_api_error', - __( 'A WordPress user must be associated with the contact for the provided API key.', 'civicrm' ) - ); - - } - - // filter uf_match - add_filter( 'civi_wp_rest/plugin/uf_match', function() use ( $uf_match ) { - - return ! empty( $uf_match ) ? $uf_match : null; - - } ); - - return get_userdata( $uf_match['uf_id'] ); - - } - - /** - * Logs in the WordPress user, and - * syncs it with it's CiviCRM contact. - * - * @since 0.1 - * @param \WP_User $user The WordPress user object - * @param \WP_REST_Request|null $request The request object or null - * @return \WP_User|void $wp_user The logged in WordPress user object or nothing - */ - public function login_wp_user( \WP_User $wp_user, $request = null ) { - - /** - * Filter the user about to be logged in. - * - * @since 0.1 - * @param \WP_User $user The WordPress user object - * @param \WP_REST_Request|null $request The request object or null - */ - $wp_user = apply_filters( 'civi_wp_rest/plugin/wp_user_login', $wp_user, $request ); - - wp_set_current_user( $wp_user->ID, $wp_user->user_login ); - - wp_set_auth_cookie( $wp_user->ID ); - - do_action( 'wp_login', $wp_user->user_login, $wp_user ); - - $this->set_civi_user_session( $wp_user ); - - return $wp_user; - - } - - /** - * Sets the necessary user - * session variables for CiviCRM. - * - * @since 0.1 - * @param \WP_User $wp_user The WordPress user - * @return void - */ - public function set_civi_user_session( $wp_user ): void { - - $uf_match = apply_filters( 'civi_wp_rest/plugin/uf_match', null ); - - if ( ! $uf_match ) { - - // Call API. - $uf_match = civicrm_api3( 'UFMatch', 'getsingle', [ - 'uf_id' => $wp_user->ID, - 'domain_id' => $this->get_civi_domain_id(), - ] ); - } - - // Set necessary session variables. - $session = \CRM_Core_Session::singleton(); - $session->set( 'ufID', $wp_user->ID ); - $session->set( 'userID', $uf_match['contact_id'] ); - $session->set( 'ufUniqID', $uf_match['uf_name'] ); - - } - - /** - * Retrieves the CiviCRM domain_id. - * - * @since 0.1 - * @return int $domain_id The domain id - */ - public function get_civi_domain_id(): int { - - // Get CiviCRM domain group ID from constant, if set. - $domain_id = defined( 'CIVICRM_DOMAIN_ID' ) ? CIVICRM_DOMAIN_ID : 0; - - // If this fails, get it from config. - if ( $domain_id === 0 ) { - $domain_id = \CRM_Core_Config::domainID(); - } - - return $domain_id; - - } - -} diff --git a/wp-rest/README.md b/wp-rest/README.md deleted file mode 100644 index 77234de84a..0000000000 --- a/wp-rest/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# CiviCRM WP REST API Wrapper - -This is a WordPress plugin that aims to expose CiviCRM's [extern](https://github.com/civicrm/civicrm-core/tree/master/extern) scripts as WordPress REST endpoints. - -This plugin requires: - -- PHP 7.1+ -- WordPress 4.7+ -- CiviCRM to be installed and activated. - -### Endpoints - -1. `civicrm/v3/rest` - a wrapper around `civicrm_api3()` - - **Parameters**: - - - `key` - **required**, the site key - - `api_key` - **required**, the contact api key - - `entity` - **required**, the API entity - - `action` - **required**, the API action - - `json` - **optional**, json formatted string with the API parameters/argumets, or `1` as in `json=1` - - By default all calls to `civicrm/v3/rest` return XML formatted results, to get `json` formatted result pass `json=1` or a json formatted string with the API parameters, like in the example 2 below. - - **Examples**: - - 1. `https://example.com/wp-json/civicrm/v3/rest?entity=Contact&action=get&key=<site_key>&api_key=<api_key>&group=Administrators` - - 2. `https://example.com/wp-json/civicrm/v3/rest?entity=Contact&action=get&key=<site_key>&api_key=<api_key>&json={"group": "Administrators"}` - -2. `civicrm/v3/url` - a substition for `civicrm/extern/url.php` mailing tracking - -3. `civicrm/v3/open` - a substition for `civicrm/extern/open.php` mailing tracking - -4. `civicrm/v3/authorizeIPN` - a substition for `civicrm/extern/authorizeIPN.php` (for testing Authorize.net as per [docs](https://docs.civicrm.org/sysadmin/en/latest/setup/payment-processors/authorize-net/#shell-script-testing-method)) - - **_Note_**: this endpoint has **not been tested** - -5. `civicrm/v3/ipn` - a substition for `civicrm/extern/ipn.php` (for PayPal Standard and Pro live transactions) - - **_Note_**: this endpoint has **not been tested** - -6. `civicrm/v3/cxn` - a substition for `civicrm/extern/cxn.php` - -7. `civicrm/v3/pxIPN` - a substition for `civicrm/extern/pxIPN.php` - - **_Note_**: this endpoint has **not been tested** - -8. `civicrm/v3/widget` - a substition for `civicrm/extern/widget.php` - -9. `civicrm/v3/soap` - a substition for `civicrm/extern/soap.php` - - **_Note_**: this endpoint has **not been tested** - -### Settings - -Set the `CIVICRM_WP_REST_REPLACE_MAILING_TRACKING` constant to `true` to replace mailing url and open tracking calls with their counterpart REST endpoints, `civicrm/v3/url` and `civicrm/v3/open`. - -_Note: use this setting with caution, it may affect performance on large mailings, see `CiviCRM_WP_REST\Civi\Mailing_Hooks` class._ -- GitLab