diff --git a/CHANGELOG.md b/CHANGELOG.md index 14745414..5a87bdd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,24 @@ +# [2.24.0-alpha.3](https://github.com/Automattic/newspack-popups/compare/v2.24.0-alpha.2...v2.24.0-alpha.3) (2023-09-29) + + +### Bug Fixes + +* **data-api:** handle errored default donation settings ([#1224](https://github.com/Automattic/newspack-popups/issues/1224)) ([76b70b6](https://github.com/Automattic/newspack-popups/commit/76b70b636b3f45f7fa7826073afc5eabaadaa461)) + +# [2.24.0-alpha.2](https://github.com/Automattic/newspack-popups/compare/v2.24.0-alpha.1...v2.24.0-alpha.2) (2023-09-29) + + +### Features + +* newsletter subscription list criteria ([#1218](https://github.com/Automattic/newspack-popups/issues/1218)) ([22961a3](https://github.com/Automattic/newspack-popups/commit/22961a39db38d5d64a2839091497aee8fa6f40e5)) + +# [2.24.0-alpha.1](https://github.com/Automattic/newspack-popups/compare/v2.23.1...v2.24.0-alpha.1) (2023-09-28) + + +### Features + +* remove GA related code ([#1220](https://github.com/Automattic/newspack-popups/issues/1220)) ([cb2ce82](https://github.com/Automattic/newspack-popups/commit/cb2ce82919cca4ca9f6812cf445d71982b8e3cab)) + ## [2.23.1](https://github.com/Automattic/newspack-popups/compare/v2.23.0...v2.23.1) (2023-09-13) diff --git a/composer.lock b/composer.lock index b3a75318..3bc5cb5a 100644 --- a/composer.lock +++ b/composer.lock @@ -918,16 +918,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.27", + "version": "9.2.29", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "b0a88255cb70d52653d80c890bd7f38740ea50d1" + "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/b0a88255cb70d52653d80c890bd7f38740ea50d1", - "reference": "b0a88255cb70d52653d80c890bd7f38740ea50d1", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76", "shasum": "" }, "require": { @@ -984,7 +984,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.27" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29" }, "funding": [ { @@ -992,7 +992,7 @@ "type": "github" } ], - "time": "2023-07-26T13:44:30+00:00" + "time": "2023-09-19T04:57:46+00:00" }, { "name": "phpunit/php-file-iterator", @@ -1237,16 +1237,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.11", + "version": "9.6.13", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "810500e92855eba8a7a5319ae913be2da6f957b0" + "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/810500e92855eba8a7a5319ae913be2da6f957b0", - "reference": "810500e92855eba8a7a5319ae913be2da6f957b0", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f3d767f7f9e191eab4189abe41ab37797e30b1be", + "reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be", "shasum": "" }, "require": { @@ -1261,7 +1261,7 @@ "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.13", + "phpunit/php-code-coverage": "^9.2.28", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.3", @@ -1320,7 +1320,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.11" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.13" }, "funding": [ { @@ -1336,7 +1336,7 @@ "type": "tidelift" } ], - "time": "2023-08-19T07:10:56+00:00" + "time": "2023-09-19T05:39:22+00:00" }, { "name": "psr/container", diff --git a/includes/class-newspack-popups-data-api.php b/includes/class-newspack-popups-data-api.php index e48ecd27..fbe5d98f 100644 --- a/includes/class-newspack-popups-data-api.php +++ b/includes/class-newspack-popups-data-api.php @@ -113,9 +113,12 @@ function( $block ) use ( $block_name ) { )[0]; if ( $donate_block && method_exists( '\Newspack\Donations', 'get_donation_settings' ) ) { - $is_manual = $donate_block['attrs']['manual'] ?? false; - $is_layout_tiers = isset( $donate_block['attrs']['layoutOption'] ) && 'tiers' === $donate_block['attrs']['layoutOption']; - $default_settings = \Newspack\Donations::get_donation_settings(); + $is_manual = $donate_block['attrs']['manual'] ?? false; + $is_layout_tiers = isset( $donate_block['attrs']['layoutOption'] ) && 'tiers' === $donate_block['attrs']['layoutOption']; + $default_settings = \Newspack\Donations::get_donation_settings(); + if ( ! $default_settings || is_wp_error( $default_settings ) ) { + $default_settings = []; + } $donation_settings = $is_manual ? \wp_parse_args( $donate_block['attrs'], $default_settings ) : $default_settings; $is_tiered = $donation_settings['tiered'] ?? false; $suggested_amounts = $donation_settings['amounts'] ?? []; diff --git a/includes/class-newspack-popups-model.php b/includes/class-newspack-popups-model.php index d605e53e..77ea051a 100644 --- a/includes/class-newspack-popups-model.php +++ b/includes/class-newspack-popups-model.php @@ -826,113 +826,6 @@ private static function get_form_class( $type, $element_id ) { return $element_id . $type_index; // Use a unique class name. } - /** - * Add tracked analytics events to use in Newspack Plugin's newspack_analytics_events filter. - * - * @param object $popup The popup object. - * @param string $body Post body. - * @param string $element_id The id of the popup element. - */ - private static function get_analytics_events( $popup, $body, $element_id ) { - if ( Newspack_Popups::is_preview_request() || ! Newspack_Popups::is_tracking() ) { - return []; - } - - $popup_id = $popup['id']; - $segments = array_reduce( - $popup['segments'], - function( $acc, $segment ) { - if ( $segment instanceof \WP_Term ) { - $acc[] = $segment->name; - } - return $acc; - }, - [] - ); - $event_category = __( 'Newspack Announcement', 'newspack-popups' ); - $formatted_placement = ucwords( str_replace( '_', ' ', $popup['options']['placement'] ) ); - $default_event_label = sprintf( - // Translators: Analytics label with prompt details (placement, title, ID, targeted segments). - __( '%1$s: %2$s (%3$s) - %4$s', 'newspack-popups' ), - $formatted_placement, - $popup['title'], - $popup_id, - 0 < count( $segments ) ? implode( '; ', $segments ) : __( 'Everyone', 'newspack-popups' ) - ); - $has_link = preg_match( '/ 'ini-load', - 'element' => '#' . esc_attr( $element_id ), - 'event_name' => __( 'Load', 'newspack-popups' ), - 'non_interaction' => true, - ], - [ - 'on' => 'visible', - 'element' => '#' . esc_attr( $element_id ), - 'event_name' => __( 'Seen', 'newspack-popups' ), - 'non_interaction' => true, - 'visibilitySpec' => [ - 'totalTimeMin' => 500, - ], - ], - ]; - - if ( $has_link ) { - $analytics_events[] = [ - 'on' => 'click', - 'element' => '#' . esc_attr( $element_id ) . ' a', - 'amp_element' => '#' . esc_attr( $element_id ) . ' a', - 'event_name' => __( 'Link Click', 'newspack-popups' ), - ]; - } - - if ( $has_form ) { - $analytics_events[] = [ - 'amp_on' => 'amp-form-submit', - 'on' => 'submit', - 'element' => '#' . esc_attr( $element_id ) . ' form:not(.popup-dismiss-form)', // Not a dismissal form. - 'event_name' => __( 'Form Submission', 'newspack-popups' ), - ]; - } - if ( $has_dismiss_form ) { - $analytics_events[] = [ - 'amp_on' => 'amp-form-submit-success', - 'on' => 'submit', - 'element' => '#' . esc_attr( $element_id ) . ' .popup-dismiss-form', - 'event_name' => __( 'Dismissal', 'newspack-popups' ), - 'non_interaction' => true, - ]; - } - - foreach ( $analytics_events as &$event ) { - $event_label = $default_event_label; - - // If a form submission and the form contains registration + list info, append that to the event label. - if ( isset( $event['amp_on'] ) && 'amp-form-submit' === $event['amp_on'] && $has_register_form ) { - $event_label .= ' | ${formId}'; - - // If the reg form has a lists[] field, append the value to the event label. - if ( $has_lists_field ) { - $event_label .= ' - ${formFields[lists[]]}'; - } - } - - $event['id'] = self::get_uniqid(); - $event['event_category'] = esc_attr( $event_category ); - $event['event_label'] = esc_attr( $event_label ); - } - - return $analytics_events; - } - /** * Canonise popups id. The id from WP will be an integer, but AMP does not play well with that and needs a string. * @@ -1044,7 +937,6 @@ private static function get_frequency_config( $popup ) { public static function generate_inline_popup( $popup ) { global $wp; - do_action( 'newspack_campaigns_before_campaign_render', $popup ); $blocks = parse_blocks( $popup['content'] ); $body = ''; self::add_form_hooks( $popup ); @@ -1069,16 +961,6 @@ public static function generate_inline_popup( $popup ) { $assigned_segments = Newspack_Segments_Model::get_popup_segments_ids_string( $popup['id'] ); $frequency_config = self::get_frequency_config( $popup ); - $analytics_events = self::get_analytics_events( $popup, $body, $element_id ); - if ( ! empty( $analytics_events ) ) { - add_filter( - 'newspack_analytics_events', - function ( $evts ) use ( $analytics_events ) { - return array_merge( $evts, $analytics_events ); - } - ); - } - ob_start(); ?>
self::CUSTOM_DIMENSIONS_OPTION_NAME_READER_FREQUENCY, - 'option' => [ - 'value' => self::CUSTOM_DIMENSIONS_OPTION_NAME_READER_FREQUENCY, - 'label' => __( 'Reader frequency', 'newspack' ), - ], - ], - [ - 'role' => self::CUSTOM_DIMENSIONS_OPTION_NAME_IS_SUBSCRIBER, - 'option' => [ - 'value' => self::CUSTOM_DIMENSIONS_OPTION_NAME_IS_SUBSCRIBER, - 'label' => __( 'Is a subcriber', 'newspack' ), - ], - ], - [ - 'role' => self::CUSTOM_DIMENSIONS_OPTION_NAME_IS_DONOR, - 'option' => [ - 'value' => self::CUSTOM_DIMENSIONS_OPTION_NAME_IS_DONOR, - 'label' => __( 'Is a donor', 'newspack' ), - ], - ], - ] - ); - return $default_dimensions; - } - - /** - * Add custom custom dimensions to Newspack Plugin's Analytics reporting. - * - * @param array $custom_dimensions_values Existing custom dimensions payload. - */ - public static function report_custom_dimensions( $custom_dimensions_values ) { - $custom_dimensions = []; - if ( class_exists( 'Newspack\Analytics_Wizard' ) ) { - $custom_dimensions = Newspack\Analytics_Wizard::list_configured_custom_dimensions(); - } - if ( empty( $custom_dimensions ) ) { - return $custom_dimensions_values; - } - - $campaigns_custom_dimensions = [ - self::CUSTOM_DIMENSIONS_OPTION_NAME_READER_FREQUENCY, - self::CUSTOM_DIMENSIONS_OPTION_NAME_IS_SUBSCRIBER, - self::CUSTOM_DIMENSIONS_OPTION_NAME_IS_DONOR, - ]; - $all_campaign_dimensions = array_values( - array_map( - function( $custom_dimension ) { - return $custom_dimension['role']; - }, - $custom_dimensions - ) - ); - - // No need to proceed if the configured custom dimensions do not include any Campaigns data. - if ( 0 === count( array_intersect( $campaigns_custom_dimensions, $all_campaign_dimensions ) ) ) { - return $custom_dimensions_values; - } - - foreach ( $custom_dimensions as $custom_dimension ) { - // Strip the `ga:` prefix from gaID. - $dimension_id = substr( $custom_dimension['gaID'], 3 ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase - switch ( $custom_dimension['role'] ) { - case self::CUSTOM_DIMENSIONS_OPTION_NAME_READER_FREQUENCY: - $read_count = 0; // TODO: get article view count from user meta/reader data - // Tiers mimick NCI's – https://news-consumer-insights.appspot.com. - $read_count_tier = 'casual'; - if ( $read_count > 1 && $read_count <= 14 ) { - $read_count_tier = 'loyal'; - } elseif ( $read_count > 14 ) { - $read_count_tier = 'brand_lover'; - } - $custom_dimensions_values[ $dimension_id ] = $read_count_tier; - break; - case self::CUSTOM_DIMENSIONS_OPTION_NAME_IS_SUBSCRIBER: - $custom_dimensions_values[ $dimension_id ] = false; // TODO: get is_subscriber from reader data. - break; - case self::CUSTOM_DIMENSIONS_OPTION_NAME_IS_DONOR: - $custom_dimensions_values[ $dimension_id ] = false; // TODO: get is_donor from reader data. - break; - } - } - - return $custom_dimensions_values; - } - /** * Permission callback for the API calls. */ diff --git a/includes/class-newspack-popups.php b/includes/class-newspack-popups.php index 324ce720..227d05f2 100644 --- a/includes/class-newspack-popups.php +++ b/includes/class-newspack-popups.php @@ -876,17 +876,6 @@ public static function is_account_related_post( $post ) { return has_shortcode( $post->post_content, 'woocommerce_my_account' ); } - /** - * Should tracking code be inserted? - * We shouldn't be tracking analytics in the dashboard or on the front-end by admin/editor users. - */ - public static function is_tracking() { - if ( is_admin() || self::is_user_admin() ) { - return false; - } - return true; - } - /** * Create campaign. * diff --git a/newspack-popups.php b/newspack-popups.php index d79e7894..eea9ec76 100755 --- a/newspack-popups.php +++ b/newspack-popups.php @@ -7,7 +7,7 @@ * Author URI: https://newspack.com * Text Domain: newspack-popups * Domain Path: /languages - * Version: 2.23.1 + * Version: 2.24.0-alpha.3 * * @package Newspack_Popups */ diff --git a/package-lock.json b/package-lock.json index 4385f625..092d5bd9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "newspack-popups", - "version": "2.23.1", + "version": "2.24.0-alpha.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "newspack-popups", - "version": "2.23.1", + "version": "2.24.0-alpha.3", "dependencies": { "classnames": "^2.3.2", "intersection-observer": "^0.12.2", @@ -16,11 +16,11 @@ "qs": "^6.11.2" }, "devDependencies": { - "@rushstack/eslint-patch": "^1.3.3", + "@rushstack/eslint-patch": "^1.4.0", "eslint": "^7.32.0", "lint-staged": "^13.2.3", "newspack-scripts": "^5.1.0", - "postcss-scss": "^4.0.7", + "postcss-scss": "^4.0.8", "prettier": "npm:wp-prettier@^2.2.1-beta-1", "stylelint": "^15.10.3" } @@ -4390,9 +4390,9 @@ } }, "node_modules/@rushstack/eslint-patch": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.3.3.tgz", - "integrity": "sha512-0xd7qez0AQ+MbHatZTlI1gu5vkG8r7MYRUJAHPAHJBmGLs16zpkrpAVLvjQKQOqaXPDUBwOiJzNc00znHSCVBw==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.4.0.tgz", + "integrity": "sha512-cEjvTPU32OM9lUFegJagO0mRnIn+rbqrG89vV8/xLnLFX0DoR0r1oy5IlTga71Q7uT3Qus7qm7wgeiMT/+Irlg==", "dev": true }, "node_modules/@semantic-release/changelog": { @@ -24623,9 +24623,9 @@ } }, "node_modules/postcss": { - "version": "8.4.28", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.28.tgz", - "integrity": "sha512-Z7V5j0cq8oEKyejIKfpD8b4eBy9cwW2JWPk0+fB1HOAMsfHbnAXLLS+PfVWlzMSLQaWttKDt607I0XHmpE67Vw==", + "version": "8.4.29", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", + "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", "dev": true, "funding": [ { @@ -26098,9 +26098,9 @@ } }, "node_modules/postcss-scss": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.7.tgz", - "integrity": "sha512-xPv2GseoyXPa58Nro7M73ZntttusuCmZdeOojUFR5PZDz2BR62vfYx1w9TyOnp1+nYFowgOMipsCBhxzVkAEPw==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.8.tgz", + "integrity": "sha512-Cr0X8Eu7xMhE96PJck6ses/uVVXDtE5ghUTKNUYgm8ozgP2TkgV3LWs3WgLV1xaSSLq8ZFiXaUrj0LVgG1fGEA==", "dev": true, "funding": [ { @@ -26120,7 +26120,7 @@ "node": ">=12.0" }, "peerDependencies": { - "postcss": "^8.4.19" + "postcss": "^8.4.29" } }, "node_modules/postcss-selector-parser": { @@ -35286,9 +35286,9 @@ } }, "@rushstack/eslint-patch": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.3.3.tgz", - "integrity": "sha512-0xd7qez0AQ+MbHatZTlI1gu5vkG8r7MYRUJAHPAHJBmGLs16zpkrpAVLvjQKQOqaXPDUBwOiJzNc00znHSCVBw==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.4.0.tgz", + "integrity": "sha512-cEjvTPU32OM9lUFegJagO0mRnIn+rbqrG89vV8/xLnLFX0DoR0r1oy5IlTga71Q7uT3Qus7qm7wgeiMT/+Irlg==", "dev": true }, "@semantic-release/changelog": { @@ -50766,9 +50766,9 @@ "dev": true }, "postcss": { - "version": "8.4.28", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.28.tgz", - "integrity": "sha512-Z7V5j0cq8oEKyejIKfpD8b4eBy9cwW2JWPk0+fB1HOAMsfHbnAXLLS+PfVWlzMSLQaWttKDt607I0XHmpE67Vw==", + "version": "8.4.29", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", + "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", "dev": true, "requires": { "nanoid": "^3.3.6", @@ -51884,9 +51884,9 @@ "requires": {} }, "postcss-scss": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.7.tgz", - "integrity": "sha512-xPv2GseoyXPa58Nro7M73ZntttusuCmZdeOojUFR5PZDz2BR62vfYx1w9TyOnp1+nYFowgOMipsCBhxzVkAEPw==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.8.tgz", + "integrity": "sha512-Cr0X8Eu7xMhE96PJck6ses/uVVXDtE5ghUTKNUYgm8ozgP2TkgV3LWs3WgLV1xaSSLq8ZFiXaUrj0LVgG1fGEA==", "dev": true, "requires": {} }, diff --git a/package.json b/package.json index 6c353e27..a6722f83 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "newspack-popups", - "version": "2.23.1", + "version": "2.24.0-alpha.3", "main": "Gruntfile.js", "author": "Automattic", "scripts": { @@ -36,11 +36,11 @@ "qs": "^6.11.2" }, "devDependencies": { - "@rushstack/eslint-patch": "^1.3.3", + "@rushstack/eslint-patch": "^1.4.0", "eslint": "^7.32.0", "lint-staged": "^13.2.3", "newspack-scripts": "^5.1.0", - "postcss-scss": "^4.0.7", + "postcss-scss": "^4.0.8", "prettier": "npm:wp-prettier@^2.2.1-beta-1", "stylelint": "^15.10.3" } diff --git a/src/criteria/default/index.php b/src/criteria/default/index.php index a1d2cdf7..44d47355 100644 --- a/src/criteria/default/index.php +++ b/src/criteria/default/index.php @@ -52,6 +52,20 @@ ], ], ], + 'subscribed_lists' => [ + 'name' => __( 'Subscribed to newsletter lists', 'newspack-popups' ), + 'description' => __( 'Whether the reader subscribed to any of the selected newsletter lists', 'newspack-popups' ), + 'category' => 'reader_activity', + 'matching_function' => 'list__in', + 'matching_attribute' => 'newsletter_subscribed_lists', + ], + 'not_subscribed_lists' => [ + 'name' => __( 'Not subscribed to newsletter lists', 'newspack-popups' ), + 'description' => __( 'Whether the reader is not subscribed to any of the selected newsletter lists', 'newspack-popups' ), + 'category' => 'reader_activity', + 'matching_function' => 'list__not_in', + 'matching_attribute' => 'newsletter_subscribed_lists', + ], 'donation' => [ 'name' => __( 'Donation', 'newspack-popups' ), 'description' => __( '(if checkout happens on-site)', 'newspack-popups' ), diff --git a/src/criteria/index.test.js b/src/criteria/index.test.js index 3ed4a44f..f4791cae 100644 --- a/src/criteria/index.test.js +++ b/src/criteria/index.test.js @@ -92,6 +92,18 @@ describe( 'criteria matching', () => { expect( criteria.matches( { value: '' } ) ).toEqual( false ); expect( criteria.matches( { value: [] } ) ).toEqual( false ); } ); + it( 'should match "list__in" matching function with array value', () => { + setMatchingAttribute( criteriaId, () => [ 'foo', 'bar' ] ); + setMatchingFunction( criteriaId, 'list__in' ); + const criteria = getCriteria( criteriaId ); + expect( criteria.matches( { value: [ 'foo', 'bar' ] } ) ).toEqual( true ); + expect( criteria.matches( { value: 'foo, bar' } ) ).toEqual( true ); + expect( criteria.matches( { value: 'bar' } ) ).toEqual( true ); + expect( criteria.matches( { value: [ 'foo', 'baz' ] } ) ).toEqual( true ); + expect( criteria.matches( { value: [ 'baz' ] } ) ).toEqual( false ); + expect( criteria.matches( { value: '' } ) ).toEqual( false ); + expect( criteria.matches( { value: [] } ) ).toEqual( false ); + } ); it( 'should match "list__not_in" matching function', () => { setMatchingAttribute( criteriaId, () => 'bar' ); setMatchingFunction( criteriaId, 'list__not_in' ); @@ -104,6 +116,18 @@ describe( 'criteria matching', () => { expect( criteria.matches( { value: '' } ) ).toEqual( true ); expect( criteria.matches( { value: [] } ) ).toEqual( true ); } ); + it( 'should match "list__not_in" matching function with array value', () => { + setMatchingAttribute( criteriaId, () => [ 'foo', 'bar' ] ); + setMatchingFunction( criteriaId, 'list__not_in' ); + const criteria = getCriteria( criteriaId ); + expect( criteria.matches( { value: [ 'foo', 'bar' ] } ) ).toEqual( false ); + expect( criteria.matches( { value: 'foo, bar' } ) ).toEqual( false ); + expect( criteria.matches( { value: 'bar' } ) ).toEqual( false ); + expect( criteria.matches( { value: 'baz' } ) ).toEqual( true ); + expect( criteria.matches( { value: [ 'fuu', 'baz' ] } ) ).toEqual( true ); + expect( criteria.matches( { value: '' } ) ).toEqual( true ); + expect( criteria.matches( { value: [] } ) ).toEqual( true ); + } ); it( 'should match custom matching function', () => { setMatchingFunction( criteriaId, segmentConfig => { return segmentConfig.value === 'foo'; diff --git a/src/criteria/matching-functions.js b/src/criteria/matching-functions.js index 8032c8c6..b2b35ed9 100644 --- a/src/criteria/matching-functions.js +++ b/src/criteria/matching-functions.js @@ -9,6 +9,9 @@ export default { /** * Matches the criteria value against a list provided by the segment config, * returns true if the value is on the list. + * + * If the criteria value is an array, it returns true if any of the values + * are on the list. */ list__in: ( criteria, config ) => { let list = config.value; @@ -18,6 +21,9 @@ export default { if ( ! Array.isArray( list ) ) { return false; } + if ( Array.isArray( criteria.value ) ) { + return criteria.value.some( value => list.includes( value ) ); + } if ( ! criteria.value || ! list.includes( criteria.value ) ) { return false; } @@ -26,6 +32,9 @@ export default { /** * Matches the criteria value against a list provided by the segment config, * returns true if the value is empty or not on the list. + * + * If the criteria value is an array, it returns true if none of the values + * are on the list. */ list__not_in: ( criteria, config ) => { let list = config.value; @@ -35,6 +44,9 @@ export default { if ( ! Array.isArray( list ) ) { return true; } + if ( Array.isArray( criteria.value ) ) { + return ! criteria.value.some( value => list.includes( value ) ); + } if ( ! criteria.value || ! list.includes( criteria.value ) ) { return true; } diff --git a/src/view/README.md b/src/view/README.md index 02062909..c456f5be 100644 --- a/src/view/README.md +++ b/src/view/README.md @@ -14,7 +14,7 @@ Real-time reader data handling is enabled through the [Reader Data Library](http 2. **Reader views a new page** - Any pageview request. This is tracked in the Reader Data store as a simple aggregated count in day, week, and month periods so that Campaigns prompts can be shown at different frequencies, e.g. every other pageview. -3. **Reader signs up for a newsletter** - When a reader signs up for a newsletter via the [Newspack Newsletters](https://github.com/Automattic/newspack-newsletters/) signup form block, the Data Events API dispatches a [`newsletter_subscribed` event](https://github.com/Automattic/newspack-plugin/blob/master/includes/data-events/README.md#newsletter_subscribed) which updates the Reader Data object with an `is_newsletter_subscriber` key. If [Reader Activation](https://help.newspack.com/engagement/reader-activation-system/) is enabled for the site, this action also results in a reader account registration. +3. **Reader signs up for a newsletter** - When a reader signs up for a newsletter via the [Newspack Newsletters](https://github.com/Automattic/newspack-newsletters/) signup form block, the Data Events API dispatches a [`newsletter_subscribed` event](https://github.com/Automattic/newspack-plugin/blob/master/includes/data-events/README.md#newsletter_subscribed) which updates the `is_newsletter_subscriber` and the `newsletter_subscribed_lists` reader data items, which consists of the lists the reader is subscribed to. If [Reader Activation](https://help.newspack.com/engagement/reader-activation-system/) is enabled for the site, this action also results in a reader account registration. 4. **Reader makes a donation** - When a reader completes a one-time or recurring donation via the [Newspack Donation block](https://github.com/Automattic/newspack-blocks/tree/master/src/blocks/donate), Data Events dispatches a [`donation_new` event](https://github.com/Automattic/newspack-plugin/blob/master/includes/data-events/README.md#donation_new) which updates the Reader Data object with an `is_donor` key. If [Reader Activation](https://help.newspack.com/engagement/reader-activation-system/) is enabled for the site, this action also results in a reader account registration.